ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/marvell/uboot/drivers/net/4xx_enet.c b/marvell/uboot/drivers/net/4xx_enet.c
new file mode 100644
index 0000000..381ec42
--- /dev/null
+++ b/marvell/uboot/drivers/net/4xx_enet.c
@@ -0,0 +1,2059 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
+ */
+/*-----------------------------------------------------------------------------+
+ *
+ *  File Name:	enetemac.c
+ *
+ *  Function:	Device driver for the ethernet EMAC3 macro on the 405GP.
+ *
+ *  Author:	Mark Wisner
+ *
+ *  Change Activity-
+ *
+ *  Date	Description of Change					    BY
+ *  ---------	---------------------					    ---
+ *  05-May-99	Created							    MKW
+ *  27-Jun-99	Clean up						    JWB
+ *  16-Jul-99	Added MAL error recovery and better IP packet handling	    MKW
+ *  29-Jul-99	Added Full duplex support				    MKW
+ *  06-Aug-99	Changed names for Mal CR reg				    MKW
+ *  23-Aug-99	Turned off SYE when running at 10Mbs			    MKW
+ *  24-Aug-99	Marked descriptor empty after call_xlc			    MKW
+ *  07-Sep-99	Set MAL RX buffer size reg to ENET_MAX_MTU_ALIGNED / 16	    MCG
+ *		to avoid chaining maximum sized packets. Push starting
+ *		RX descriptor address up to the next cache line boundary.
+ *  16-Jan-00	Added support for booting with IP of 0x0		    MKW
+ *  15-Mar-00	Updated enetInit() to enable broadcast addresses in the
+ *		EMAC0_RXM register.					    JWB
+ *  12-Mar-01	anne-sophie.harnois@nextream.fr
+ *		 - Variables are compatible with those already defined in
+ *		  include/net.h
+ *		- Receive buffer descriptor ring is used to send buffers
+ *		  to the user
+ *		- Info print about send/received/handled packet number if
+ *		  INFO_405_ENET is set
+ *  17-Apr-01	stefan.roese@esd-electronics.com
+ *		- MAL reset in "eth_halt" included
+ *		- Enet speed and duplex output now in one line
+ *  08-May-01	stefan.roese@esd-electronics.com
+ *		- MAL error handling added (eth_init called again)
+ *  13-Nov-01	stefan.roese@esd-electronics.com
+ *		- Set IST bit in EMAC0_MR1 reg upon 100MBit or full duplex
+ *  04-Jan-02	stefan.roese@esd-electronics.com
+ *		- Wait for PHY auto negotiation to complete added
+ *  06-Feb-02	stefan.roese@esd-electronics.com
+ *		- Bug fixed in waiting for auto negotiation to complete
+ *  26-Feb-02	stefan.roese@esd-electronics.com
+ *		- rx and tx buffer descriptors now allocated (no fixed address
+ *		  used anymore)
+ *  17-Jun-02	stefan.roese@esd-electronics.com
+ *		- MAL error debug printf 'M' removed (rx de interrupt may
+ *		  occur upon many incoming packets with only 4 rx buffers).
+ *-----------------------------------------------------------------------------*
+ *  17-Nov-03	travis.sawyer@sandburst.com
+ *		- ported from 405gp_enet.c to utilized upto 4 EMAC ports
+ *		  in the 440GX.	 This port should work with the 440GP
+ *		  (2 EMACs) also
+ *  15-Aug-05	sr@denx.de
+ *		- merged 405gp_enet.c and 440gx_enet.c to generic 4xx_enet.c
+		  now handling all 4xx cpu's.
+ *-----------------------------------------------------------------------------*/
+
+#include <config.h>
+#include <common.h>
+#include <net.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/cache.h>
+#include <asm/mmu.h>
+#include <commproc.h>
+#include <asm/ppc4xx.h>
+#include <asm/ppc4xx-emac.h>
+#include <asm/ppc4xx-mal.h>
+#include <miiphy.h>
+#include <malloc.h>
+#include <linux/compiler.h>
+
+#if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
+#error "CONFIG_MII has to be defined!"
+#endif
+
+#define EMAC_RESET_TIMEOUT 1000 /* 1000 ms reset timeout */
+#define PHY_AUTONEGOTIATE_TIMEOUT 5000	/* 5000 ms autonegotiate timeout */
+
+/* Ethernet Transmit and Receive Buffers */
+/* AS.HARNOIS
+ * In the same way ENET_MAX_MTU and ENET_MAX_MTU_ALIGNED are set from
+ * PKTSIZE and PKTSIZE_ALIGN (include/net.h)
+ */
+#define ENET_MAX_MTU	       PKTSIZE
+#define ENET_MAX_MTU_ALIGNED   PKTSIZE_ALIGN
+
+/*-----------------------------------------------------------------------------+
+ * Defines for MAL/EMAC interrupt conditions as reported in the UIC (Universal
+ * Interrupt Controller).
+ *-----------------------------------------------------------------------------*/
+#define ETH_IRQ_NUM(dev)	(VECNUM_ETH0 + ((dev) * VECNUM_ETH1_OFFS))
+
+#if defined(CONFIG_HAS_ETH3)
+#if !defined(CONFIG_440GX)
+#define UIC_ETHx	(UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1)) || \
+			 UIC_MASK(ETH_IRQ_NUM(2)) || UIC_MASK(ETH_IRQ_NUM(3)))
+#else
+/* Unfortunately 440GX spreads EMAC interrupts on multiple UIC's */
+#define UIC_ETHx	(UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1)))
+#define UIC_ETHxB	(UIC_MASK(ETH_IRQ_NUM(2)) || UIC_MASK(ETH_IRQ_NUM(3)))
+#endif /* !defined(CONFIG_440GX) */
+#elif defined(CONFIG_HAS_ETH2)
+#define UIC_ETHx	(UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1)) || \
+			 UIC_MASK(ETH_IRQ_NUM(2)))
+#elif defined(CONFIG_HAS_ETH1)
+#define UIC_ETHx	(UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1)))
+#else
+#define UIC_ETHx	UIC_MASK(ETH_IRQ_NUM(0))
+#endif
+
+/*
+ * Define a default version for UIC_ETHxB for non 440GX so that we can
+ * use common code for all 4xx variants
+ */
+#if !defined(UIC_ETHxB)
+#define UIC_ETHxB	0
+#endif
+
+#define UIC_MAL_SERR	UIC_MASK(VECNUM_MAL_SERR)
+#define UIC_MAL_TXDE	UIC_MASK(VECNUM_MAL_TXDE)
+#define UIC_MAL_RXDE	UIC_MASK(VECNUM_MAL_RXDE)
+#define UIC_MAL_TXEOB	UIC_MASK(VECNUM_MAL_TXEOB)
+#define UIC_MAL_RXEOB	UIC_MASK(VECNUM_MAL_RXEOB)
+
+#define MAL_UIC_ERR	(UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE)
+#define MAL_UIC_DEF	(UIC_MAL_RXEOB | MAL_UIC_ERR)
+
+/*
+ * We have 3 different interrupt types:
+ * - MAL interrupts indicating successful transfer
+ * - MAL error interrupts indicating MAL related errors
+ * - EMAC interrupts indicating EMAC related errors
+ *
+ * All those interrupts can be on different UIC's, but since
+ * now at least all interrupts from one type are on the same
+ * UIC. Only exception is 440GX where the EMAC interrupts are
+ * spread over two UIC's!
+ */
+#if defined(CONFIG_440GX)
+#define UIC_BASE_MAL	UIC1_DCR_BASE
+#define UIC_BASE_MAL_ERR UIC2_DCR_BASE
+#define UIC_BASE_EMAC	UIC2_DCR_BASE
+#define UIC_BASE_EMAC_B	UIC3_DCR_BASE
+#else
+#define UIC_BASE_MAL	(UIC0_DCR_BASE + (UIC_NR(VECNUM_MAL_TXEOB) * 0x10))
+#define UIC_BASE_MAL_ERR (UIC0_DCR_BASE + (UIC_NR(VECNUM_MAL_SERR) * 0x10))
+#define UIC_BASE_EMAC	(UIC0_DCR_BASE + (UIC_NR(ETH_IRQ_NUM(0)) * 0x10))
+#define UIC_BASE_EMAC_B	(UIC0_DCR_BASE + (UIC_NR(ETH_IRQ_NUM(0)) * 0x10))
+#endif
+
+#undef INFO_4XX_ENET
+
+#define BI_PHYMODE_NONE	 0
+#define BI_PHYMODE_ZMII	 1
+#define BI_PHYMODE_RGMII 2
+#define BI_PHYMODE_GMII  3
+#define BI_PHYMODE_RTBI  4
+#define BI_PHYMODE_TBI   5
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_405EX)
+#define BI_PHYMODE_SMII  6
+#define BI_PHYMODE_MII   7
+#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
+#define BI_PHYMODE_RMII  8
+#endif
+#endif
+#define BI_PHYMODE_SGMII 9
+
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_405EX)
+#define SDR0_MFR_ETH_CLK_SEL_V(n)	((0x01<<27) / (n+1))
+#endif
+
+#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
+#define SDR0_ETH_CFG_CLK_SEL_V(n)	(0x01 << (8 + n))
+#endif
+
+#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
+#define MAL_RX_CHAN_MUL	8	/* 460EX/GT uses MAL channel 8 for EMAC1 */
+#else
+#define MAL_RX_CHAN_MUL	1
+#endif
+
+/*--------------------------------------------------------------------+
+ * Fixed PHY (PHY-less) support for Ethernet Ports.
+ *--------------------------------------------------------------------*/
+
+/*
+ * Some boards do not have a PHY for each ethernet port. These ports
+ * are known as Fixed PHY (or PHY-less) ports. For such ports, set
+ * the appropriate CONFIG_PHY_ADDR equal to CONFIG_FIXED_PHY and
+ * then define CONFIG_SYS_FIXED_PHY_PORTS to define what the speed and
+ * duplex should be for these ports in the board configuration
+ * file.
+ *
+ * For Example:
+ *     #define CONFIG_FIXED_PHY   0xFFFFFFFF
+ *
+ *     #define CONFIG_PHY_ADDR    CONFIG_FIXED_PHY
+ *     #define CONFIG_PHY1_ADDR   1
+ *     #define CONFIG_PHY2_ADDR   CONFIG_FIXED_PHY
+ *     #define CONFIG_PHY3_ADDR   3
+ *
+ *     #define CONFIG_SYS_FIXED_PHY_PORT(devnum,speed,duplex) \
+ *                     {devnum, speed, duplex},
+ *
+ *     #define CONFIG_SYS_FIXED_PHY_PORTS \
+ *                     CONFIG_SYS_FIXED_PHY_PORT(0,1000,FULL) \
+ *                     CONFIG_SYS_FIXED_PHY_PORT(2,100,HALF)
+ */
+
+#ifndef CONFIG_FIXED_PHY
+#define CONFIG_FIXED_PHY	0xFFFFFFFF /* Fixed PHY (PHY-less) */
+#endif
+
+#ifndef CONFIG_SYS_FIXED_PHY_PORTS
+#define CONFIG_SYS_FIXED_PHY_PORTS	/* default is an empty array */
+#endif
+
+struct fixed_phy_port {
+	unsigned int devnum;	/* ethernet port */
+	unsigned int speed;	/* specified speed 10,100 or 1000 */
+	unsigned int duplex;	/* specified duplex FULL or HALF */
+};
+
+static const struct fixed_phy_port fixed_phy_port[] = {
+	CONFIG_SYS_FIXED_PHY_PORTS	/* defined in board configuration file */
+};
+
+/*-----------------------------------------------------------------------------+
+ * Global variables. TX and RX descriptors and buffers.
+ *-----------------------------------------------------------------------------*/
+
+/*
+ * Get count of EMAC devices (doesn't have to be the max. possible number
+ * supported by the cpu)
+ *
+ * CONFIG_BOARD_EMAC_COUNT added so now a "dynamic" way to configure the
+ * EMAC count is possible. As it is needed for the Kilauea/Haleakala
+ * 405EX/405EXr eval board, using the same binary.
+ */
+#if defined(CONFIG_BOARD_EMAC_COUNT)
+#define LAST_EMAC_NUM	board_emac_count()
+#else /* CONFIG_BOARD_EMAC_COUNT */
+#if defined(CONFIG_HAS_ETH3)
+#define LAST_EMAC_NUM	4
+#elif defined(CONFIG_HAS_ETH2)
+#define LAST_EMAC_NUM	3
+#elif defined(CONFIG_HAS_ETH1)
+#define LAST_EMAC_NUM	2
+#else
+#define LAST_EMAC_NUM	1
+#endif
+#endif /* CONFIG_BOARD_EMAC_COUNT */
+
+/* normal boards start with EMAC0 */
+#if !defined(CONFIG_EMAC_NR_START)
+#define CONFIG_EMAC_NR_START	0
+#endif
+
+#define MAL_RX_DESC_SIZE	2048
+#define MAL_TX_DESC_SIZE	2048
+#define MAL_ALLOC_SIZE		(MAL_TX_DESC_SIZE + MAL_RX_DESC_SIZE)
+
+/*-----------------------------------------------------------------------------+
+ * Prototypes and externals.
+ *-----------------------------------------------------------------------------*/
+static void enet_rcv (struct eth_device *dev, unsigned long malisr);
+
+int enetInt (struct eth_device *dev);
+static void mal_err (struct eth_device *dev, unsigned long isr,
+		     unsigned long uic, unsigned long maldef,
+		     unsigned long mal_errr);
+static void emac_err (struct eth_device *dev, unsigned long isr);
+
+extern int phy_setup_aneg (char *devname, unsigned char addr);
+extern int emac4xx_miiphy_read (const char *devname, unsigned char addr,
+		unsigned char reg, unsigned short *value);
+extern int emac4xx_miiphy_write (const char *devname, unsigned char addr,
+		unsigned char reg, unsigned short value);
+
+int board_emac_count(void);
+
+static void emac_loopback_enable(EMAC_4XX_HW_PST hw_p)
+{
+#if defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_405EX)
+	u32 val;
+
+	mfsdr(SDR0_MFR, val);
+	val |= SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum);
+	mtsdr(SDR0_MFR, val);
+#elif defined(CONFIG_460EX) || defined(CONFIG_460GT)
+	u32 val;
+
+	mfsdr(SDR0_ETH_CFG, val);
+	val |= SDR0_ETH_CFG_CLK_SEL_V(hw_p->devnum);
+	mtsdr(SDR0_ETH_CFG, val);
+#endif
+}
+
+static void emac_loopback_disable(EMAC_4XX_HW_PST hw_p)
+{
+#if defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_405EX)
+	u32 val;
+
+	mfsdr(SDR0_MFR, val);
+	val &= ~SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum);
+	mtsdr(SDR0_MFR, val);
+#elif defined(CONFIG_460EX) || defined(CONFIG_460GT)
+	u32 val;
+
+	mfsdr(SDR0_ETH_CFG, val);
+	val &= ~SDR0_ETH_CFG_CLK_SEL_V(hw_p->devnum);
+	mtsdr(SDR0_ETH_CFG, val);
+#endif
+}
+
+/*-----------------------------------------------------------------------------+
+| ppc_4xx_eth_halt
+| Disable MAL channel, and EMACn
++-----------------------------------------------------------------------------*/
+static void ppc_4xx_eth_halt (struct eth_device *dev)
+{
+	EMAC_4XX_HW_PST hw_p = dev->priv;
+	u32 val = 10000;
+
+	out_be32((void *)EMAC0_IER + hw_p->hw_addr, 0x00000000);	/* disable emac interrupts */
+
+	/* 1st reset MAL channel */
+	/* Note: writing a 0 to a channel has no effect */
+#if defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
+	mtdcr (MAL0_TXCARR, (MAL_CR_MMSR >> (hw_p->devnum * 2)));
+#else
+	mtdcr (MAL0_TXCARR, (MAL_CR_MMSR >> hw_p->devnum));
+#endif
+	mtdcr (MAL0_RXCARR, (MAL_CR_MMSR >> hw_p->devnum));
+
+	/* wait for reset */
+	while (mfdcr (MAL0_RXCASR) & (MAL_CR_MMSR >> hw_p->devnum)) {
+		udelay (1000);	/* Delay 1 MS so as not to hammer the register */
+		val--;
+		if (val == 0)
+			break;
+	}
+
+	/* provide clocks for EMAC internal loopback  */
+	emac_loopback_enable(hw_p);
+
+	/* EMAC RESET */
+	out_be32((void *)EMAC0_MR0 + hw_p->hw_addr, EMAC_MR0_SRST);
+
+	/* remove clocks for EMAC internal loopback  */
+	emac_loopback_disable(hw_p);
+
+#ifndef CONFIG_NETCONSOLE
+	hw_p->print_speed = 1;	/* print speed message again next time */
+#endif
+
+#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
+	/* don't bypass the TAHOE0/TAHOE1 cores for Linux */
+	mfsdr(SDR0_ETH_CFG, val);
+	val &= ~(SDR0_ETH_CFG_TAHOE0_BYPASS | SDR0_ETH_CFG_TAHOE1_BYPASS);
+	mtsdr(SDR0_ETH_CFG, val);
+#endif
+
+	return;
+}
+
+#if defined (CONFIG_440GX)
+int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
+{
+	unsigned long pfc1;
+	unsigned long zmiifer;
+	unsigned long rmiifer;
+
+	mfsdr(SDR0_PFC1, pfc1);
+	pfc1 = SDR0_PFC1_EPS_DECODE(pfc1);
+
+	zmiifer = 0;
+	rmiifer = 0;
+
+	switch (pfc1) {
+	case 1:
+		zmiifer |= ZMII_FER_RMII << ZMII_FER_V(0);
+		zmiifer |= ZMII_FER_RMII << ZMII_FER_V(1);
+		zmiifer |= ZMII_FER_RMII << ZMII_FER_V(2);
+		zmiifer |= ZMII_FER_RMII << ZMII_FER_V(3);
+		bis->bi_phymode[0] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[1] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[2] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[3] = BI_PHYMODE_ZMII;
+		break;
+	case 2:
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V(0);
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V(1);
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V(2);
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V(3);
+		bis->bi_phymode[0] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[1] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[2] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[3] = BI_PHYMODE_ZMII;
+		break;
+	case 3:
+		zmiifer |= ZMII_FER_RMII << ZMII_FER_V(0);
+		rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(2);
+		bis->bi_phymode[0] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[1] = BI_PHYMODE_NONE;
+		bis->bi_phymode[2] = BI_PHYMODE_RGMII;
+		bis->bi_phymode[3] = BI_PHYMODE_NONE;
+		break;
+	case 4:
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V(0);
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V(1);
+		rmiifer |= RGMII_FER_RGMII << RGMII_FER_V (2);
+		rmiifer |= RGMII_FER_RGMII << RGMII_FER_V (3);
+		bis->bi_phymode[0] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[1] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[2] = BI_PHYMODE_RGMII;
+		bis->bi_phymode[3] = BI_PHYMODE_RGMII;
+		break;
+	case 5:
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V (0);
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V (1);
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V (2);
+		rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(3);
+		bis->bi_phymode[0] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[1] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[2] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[3] = BI_PHYMODE_RGMII;
+		break;
+	case 6:
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V (0);
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V (1);
+		rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(2);
+		bis->bi_phymode[0] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[1] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[2] = BI_PHYMODE_RGMII;
+		break;
+	case 0:
+	default:
+		zmiifer = ZMII_FER_MII << ZMII_FER_V(devnum);
+		rmiifer = 0x0;
+		bis->bi_phymode[0] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[1] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[2] = BI_PHYMODE_ZMII;
+		bis->bi_phymode[3] = BI_PHYMODE_ZMII;
+		break;
+	}
+
+	/* Ensure we setup mdio for this devnum and ONLY this devnum */
+	zmiifer |= (ZMII_FER_MDI) << ZMII_FER_V(devnum);
+
+	out_be32((void *)ZMII0_FER, zmiifer);
+	out_be32((void *)RGMII_FER, rmiifer);
+
+	return ((int)pfc1);
+}
+#endif	/* CONFIG_440_GX */
+
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
+{
+	unsigned long zmiifer=0x0;
+	unsigned long pfc1;
+
+	mfsdr(SDR0_PFC1, pfc1);
+	pfc1 &= SDR0_PFC1_SELECT_MASK;
+
+	switch (pfc1) {
+	case SDR0_PFC1_SELECT_CONFIG_2:
+		/* 1 x GMII port */
+		out_be32((void *)ZMII0_FER, 0x00);
+		out_be32((void *)RGMII_FER, 0x00000037);
+		bis->bi_phymode[0] = BI_PHYMODE_GMII;
+		bis->bi_phymode[1] = BI_PHYMODE_NONE;
+		break;
+	case SDR0_PFC1_SELECT_CONFIG_4:
+		/* 2 x RGMII ports */
+		out_be32((void *)ZMII0_FER, 0x00);
+		out_be32((void *)RGMII_FER, 0x00000055);
+		bis->bi_phymode[0] = BI_PHYMODE_RGMII;
+		bis->bi_phymode[1] = BI_PHYMODE_RGMII;
+		break;
+	case SDR0_PFC1_SELECT_CONFIG_6:
+		/* 2 x SMII ports */
+		out_be32((void *)ZMII0_FER,
+			 ((ZMII_FER_SMII) << ZMII_FER_V(0)) |
+			 ((ZMII_FER_SMII) << ZMII_FER_V(1)));
+		out_be32((void *)RGMII_FER, 0x00000000);
+		bis->bi_phymode[0] = BI_PHYMODE_SMII;
+		bis->bi_phymode[1] = BI_PHYMODE_SMII;
+		break;
+	case SDR0_PFC1_SELECT_CONFIG_1_2:
+		/* only 1 x MII supported */
+		out_be32((void *)ZMII0_FER, (ZMII_FER_MII) << ZMII_FER_V(0));
+		out_be32((void *)RGMII_FER, 0x00000000);
+		bis->bi_phymode[0] = BI_PHYMODE_MII;
+		bis->bi_phymode[1] = BI_PHYMODE_NONE;
+		break;
+	default:
+		break;
+	}
+
+	/* Ensure we setup mdio for this devnum and ONLY this devnum */
+	zmiifer = in_be32((void *)ZMII0_FER);
+	zmiifer |= (ZMII_FER_MDI) << ZMII_FER_V(devnum);
+	out_be32((void *)ZMII0_FER, zmiifer);
+
+	return ((int)0x0);
+}
+#endif	/* CONFIG_440EPX */
+
+#if defined(CONFIG_405EX)
+int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
+{
+	u32 rgmiifer = 0;
+
+	/*
+	 * The 405EX(r)'s RGMII bridge can operate in one of several
+	 * modes, only one of which (2 x RGMII) allows the
+	 * simultaneous use of both EMACs on the 405EX.
+	 */
+
+	switch (CONFIG_EMAC_PHY_MODE) {
+
+	case EMAC_PHY_MODE_NONE:
+		/* No ports */
+		rgmiifer |= RGMII_FER_DIS	<< 0;
+		rgmiifer |= RGMII_FER_DIS	<< 4;
+		out_be32((void *)RGMII_FER, rgmiifer);
+		bis->bi_phymode[0] = BI_PHYMODE_NONE;
+		bis->bi_phymode[1] = BI_PHYMODE_NONE;
+		break;
+	case EMAC_PHY_MODE_NONE_RGMII:
+		/* 1 x RGMII port on channel 0 */
+		rgmiifer |= RGMII_FER_RGMII	<< 0;
+		rgmiifer |= RGMII_FER_DIS	<< 4;
+		out_be32((void *)RGMII_FER, rgmiifer);
+		bis->bi_phymode[0] = BI_PHYMODE_RGMII;
+		bis->bi_phymode[1] = BI_PHYMODE_NONE;
+		break;
+	case EMAC_PHY_MODE_RGMII_NONE:
+		/* 1 x RGMII port on channel 1 */
+		rgmiifer |= RGMII_FER_DIS	<< 0;
+		rgmiifer |= RGMII_FER_RGMII	<< 4;
+		out_be32((void *)RGMII_FER, rgmiifer);
+		bis->bi_phymode[0] = BI_PHYMODE_NONE;
+		bis->bi_phymode[1] = BI_PHYMODE_RGMII;
+		break;
+	case EMAC_PHY_MODE_RGMII_RGMII:
+		/* 2 x RGMII ports */
+		rgmiifer |= RGMII_FER_RGMII	<< 0;
+		rgmiifer |= RGMII_FER_RGMII	<< 4;
+		out_be32((void *)RGMII_FER, rgmiifer);
+		bis->bi_phymode[0] = BI_PHYMODE_RGMII;
+		bis->bi_phymode[1] = BI_PHYMODE_RGMII;
+		break;
+	case EMAC_PHY_MODE_NONE_GMII:
+		/* 1 x GMII port on channel 0 */
+		rgmiifer |= RGMII_FER_GMII	<< 0;
+		rgmiifer |= RGMII_FER_DIS	<< 4;
+		out_be32((void *)RGMII_FER, rgmiifer);
+		bis->bi_phymode[0] = BI_PHYMODE_GMII;
+		bis->bi_phymode[1] = BI_PHYMODE_NONE;
+		break;
+	case EMAC_PHY_MODE_NONE_MII:
+		/* 1 x MII port on channel 0 */
+		rgmiifer |= RGMII_FER_MII	<< 0;
+		rgmiifer |= RGMII_FER_DIS	<< 4;
+		out_be32((void *)RGMII_FER, rgmiifer);
+		bis->bi_phymode[0] = BI_PHYMODE_MII;
+		bis->bi_phymode[1] = BI_PHYMODE_NONE;
+		break;
+	case EMAC_PHY_MODE_GMII_NONE:
+		/* 1 x GMII port on channel 1 */
+		rgmiifer |= RGMII_FER_DIS	<< 0;
+		rgmiifer |= RGMII_FER_GMII	<< 4;
+		out_be32((void *)RGMII_FER, rgmiifer);
+		bis->bi_phymode[0] = BI_PHYMODE_NONE;
+		bis->bi_phymode[1] = BI_PHYMODE_GMII;
+		break;
+	case EMAC_PHY_MODE_MII_NONE:
+		/* 1 x MII port on channel 1 */
+		rgmiifer |= RGMII_FER_DIS	<< 0;
+		rgmiifer |= RGMII_FER_MII	<< 4;
+		out_be32((void *)RGMII_FER, rgmiifer);
+		bis->bi_phymode[0] = BI_PHYMODE_NONE;
+		bis->bi_phymode[1] = BI_PHYMODE_MII;
+		break;
+	default:
+		break;
+	}
+
+	/* Ensure we setup mdio for this devnum and ONLY this devnum */
+	rgmiifer = in_be32((void *)RGMII_FER);
+	rgmiifer |= (1 << (19-devnum));
+	out_be32((void *)RGMII_FER, rgmiifer);
+
+	return ((int)0x0);
+}
+#endif  /* CONFIG_405EX */
+
+#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
+int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
+{
+	u32 eth_cfg;
+	u32 zmiifer;		/* ZMII0_FER reg. */
+	u32 rmiifer;		/* RGMII0_FER reg. Bridge 0 */
+	u32 rmiifer1;		/* RGMII0_FER reg. Bridge 1 */
+	int mode;
+
+	zmiifer  = 0;
+	rmiifer  = 0;
+	rmiifer1 = 0;
+
+#if defined(CONFIG_460EX)
+	mode = 9;
+	mfsdr(SDR0_ETH_CFG, eth_cfg);
+	if (((eth_cfg & SDR0_ETH_CFG_SGMII0_ENABLE) > 0) &&
+	    ((eth_cfg & SDR0_ETH_CFG_SGMII1_ENABLE) > 0))
+		mode = 11; /* config SGMII */
+#else
+	mode = 10;
+	mfsdr(SDR0_ETH_CFG, eth_cfg);
+	if (((eth_cfg & SDR0_ETH_CFG_SGMII0_ENABLE) > 0) &&
+	    ((eth_cfg & SDR0_ETH_CFG_SGMII1_ENABLE) > 0) &&
+	    ((eth_cfg & SDR0_ETH_CFG_SGMII2_ENABLE) > 0))
+		mode = 12; /* config SGMII */
+#endif
+
+	/* TODO:
+	 * NOTE: 460GT has 2 RGMII bridge cores:
+	 *		emac0 ------ RGMII0_BASE
+	 *		           |
+	 *		emac1 -----+
+	 *
+	 *		emac2 ------ RGMII1_BASE
+	 *		           |
+	 *		emac3 -----+
+	 *
+	 *	460EX has 1 RGMII bridge core:
+	 *	and RGMII1_BASE is disabled
+	 *		emac0 ------ RGMII0_BASE
+	 *		           |
+	 *		emac1 -----+
+	 */
+
+	/*
+	 * Right now only 2*RGMII is supported. Please extend when needed.
+	 * sr - 2008-02-19
+	 * Add SGMII support.
+	 * vg - 2008-07-28
+	 */
+	switch (mode) {
+	case 1:
+		/* 1 MII - 460EX */
+		/* GMC0 EMAC4_0, ZMII Bridge */
+		zmiifer |= ZMII_FER_MII << ZMII_FER_V(0);
+		bis->bi_phymode[0] = BI_PHYMODE_MII;
+		bis->bi_phymode[1] = BI_PHYMODE_NONE;
+		bis->bi_phymode[2] = BI_PHYMODE_NONE;
+		bis->bi_phymode[3] = BI_PHYMODE_NONE;
+		break;
+	case 2:
+		/* 2 MII - 460GT */
+		/* GMC0 EMAC4_0, GMC1 EMAC4_2, ZMII Bridge */
+		zmiifer |= ZMII_FER_MII << ZMII_FER_V(0);
+		zmiifer |= ZMII_FER_MII << ZMII_FER_V(2);
+		bis->bi_phymode[0] = BI_PHYMODE_MII;
+		bis->bi_phymode[1] = BI_PHYMODE_NONE;
+		bis->bi_phymode[2] = BI_PHYMODE_MII;
+		bis->bi_phymode[3] = BI_PHYMODE_NONE;
+		break;
+	case 3:
+		/* 2 RMII - 460EX */
+		/* GMC0 EMAC4_0, GMC0 EMAC4_1, ZMII Bridge */
+		zmiifer |= ZMII_FER_RMII << ZMII_FER_V(0);
+		zmiifer |= ZMII_FER_RMII << ZMII_FER_V(1);
+		bis->bi_phymode[0] = BI_PHYMODE_RMII;
+		bis->bi_phymode[1] = BI_PHYMODE_RMII;
+		bis->bi_phymode[2] = BI_PHYMODE_NONE;
+		bis->bi_phymode[3] = BI_PHYMODE_NONE;
+		break;
+	case 4:
+		/* 4 RMII - 460GT */
+		/* GMC0 EMAC4_0, GMC0 EMAC4_1, GMC1 EMAC4_2, GMC1, EMAC4_3 */
+		/* ZMII Bridge */
+		zmiifer |= ZMII_FER_RMII << ZMII_FER_V(0);
+		zmiifer |= ZMII_FER_RMII << ZMII_FER_V(1);
+		zmiifer |= ZMII_FER_RMII << ZMII_FER_V(2);
+		zmiifer |= ZMII_FER_RMII << ZMII_FER_V(3);
+		bis->bi_phymode[0] = BI_PHYMODE_RMII;
+		bis->bi_phymode[1] = BI_PHYMODE_RMII;
+		bis->bi_phymode[2] = BI_PHYMODE_RMII;
+		bis->bi_phymode[3] = BI_PHYMODE_RMII;
+		break;
+	case 5:
+		/* 2 SMII - 460EX */
+		/* GMC0 EMAC4_0, GMC0 EMAC4_1, ZMII Bridge */
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V(0);
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V(1);
+		bis->bi_phymode[0] = BI_PHYMODE_SMII;
+		bis->bi_phymode[1] = BI_PHYMODE_SMII;
+		bis->bi_phymode[2] = BI_PHYMODE_NONE;
+		bis->bi_phymode[3] = BI_PHYMODE_NONE;
+		break;
+	case 6:
+		/* 4 SMII - 460GT */
+		/* GMC0 EMAC4_0, GMC0 EMAC4_1, GMC0 EMAC4_3, GMC0 EMAC4_3 */
+		/* ZMII Bridge */
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V(0);
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V(1);
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V(2);
+		zmiifer |= ZMII_FER_SMII << ZMII_FER_V(3);
+		bis->bi_phymode[0] = BI_PHYMODE_SMII;
+		bis->bi_phymode[1] = BI_PHYMODE_SMII;
+		bis->bi_phymode[2] = BI_PHYMODE_SMII;
+		bis->bi_phymode[3] = BI_PHYMODE_SMII;
+		break;
+	case 7:
+		/* This is the default mode that we want for board bringup - Maple */
+		/* 1 GMII - 460EX */
+		/* GMC0 EMAC4_0, RGMII Bridge 0 */
+		rmiifer |= RGMII_FER_MDIO(0);
+
+		if (devnum == 0) {
+			rmiifer |= RGMII_FER_GMII << RGMII_FER_V(2); /* CH0CFG - EMAC0 */
+			bis->bi_phymode[0] = BI_PHYMODE_GMII;
+			bis->bi_phymode[1] = BI_PHYMODE_NONE;
+			bis->bi_phymode[2] = BI_PHYMODE_NONE;
+			bis->bi_phymode[3] = BI_PHYMODE_NONE;
+		} else {
+			rmiifer |= RGMII_FER_GMII << RGMII_FER_V(3); /* CH1CFG - EMAC1 */
+			bis->bi_phymode[0] = BI_PHYMODE_NONE;
+			bis->bi_phymode[1] = BI_PHYMODE_GMII;
+			bis->bi_phymode[2] = BI_PHYMODE_NONE;
+			bis->bi_phymode[3] = BI_PHYMODE_NONE;
+		}
+		break;
+	case 8:
+		/* 2 GMII - 460GT */
+		/* GMC0 EMAC4_0, RGMII Bridge 0 */
+		/* GMC1 EMAC4_2, RGMII Bridge 1 */
+		rmiifer |= RGMII_FER_GMII << RGMII_FER_V(2);	/* CH0CFG - EMAC0 */
+		rmiifer1 |= RGMII_FER_GMII << RGMII_FER_V(2);	/* CH0CFG - EMAC2 */
+		rmiifer |= RGMII_FER_MDIO(0);			/* enable MDIO - EMAC0 */
+		rmiifer1 |= RGMII_FER_MDIO(0);			/* enable MDIO - EMAC2 */
+
+		bis->bi_phymode[0] = BI_PHYMODE_GMII;
+		bis->bi_phymode[1] = BI_PHYMODE_NONE;
+		bis->bi_phymode[2] = BI_PHYMODE_GMII;
+		bis->bi_phymode[3] = BI_PHYMODE_NONE;
+		break;
+	case 9:
+		/* 2 RGMII - 460EX */
+		/* GMC0 EMAC4_0, GMC0 EMAC4_1, RGMII Bridge 0 */
+		rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(2);
+		rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(3);
+		rmiifer |= RGMII_FER_MDIO(0);			/* enable MDIO - EMAC0 */
+
+		bis->bi_phymode[0] = BI_PHYMODE_RGMII;
+		bis->bi_phymode[1] = BI_PHYMODE_RGMII;
+		bis->bi_phymode[2] = BI_PHYMODE_NONE;
+		bis->bi_phymode[3] = BI_PHYMODE_NONE;
+		break;
+	case 10:
+		/* 4 RGMII - 460GT */
+		/* GMC0 EMAC4_0, GMC0 EMAC4_1, RGMII Bridge 0 */
+		/* GMC1 EMAC4_2, GMC1 EMAC4_3, RGMII Bridge 1 */
+		rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(2);
+		rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(3);
+		rmiifer1 |= RGMII_FER_RGMII << RGMII_FER_V(2);
+		rmiifer1 |= RGMII_FER_RGMII << RGMII_FER_V(3);
+		bis->bi_phymode[0] = BI_PHYMODE_RGMII;
+		bis->bi_phymode[1] = BI_PHYMODE_RGMII;
+		bis->bi_phymode[2] = BI_PHYMODE_RGMII;
+		bis->bi_phymode[3] = BI_PHYMODE_RGMII;
+		break;
+	case 11:
+		/* 2 SGMII - 460EX */
+		bis->bi_phymode[0] = BI_PHYMODE_SGMII;
+		bis->bi_phymode[1] = BI_PHYMODE_SGMII;
+		bis->bi_phymode[2] = BI_PHYMODE_NONE;
+		bis->bi_phymode[3] = BI_PHYMODE_NONE;
+		break;
+	case 12:
+		/* 3 SGMII - 460GT */
+		bis->bi_phymode[0] = BI_PHYMODE_SGMII;
+		bis->bi_phymode[1] = BI_PHYMODE_SGMII;
+		bis->bi_phymode[2] = BI_PHYMODE_SGMII;
+		bis->bi_phymode[3] = BI_PHYMODE_NONE;
+		break;
+	default:
+		break;
+	}
+
+	/* Set EMAC for MDIO */
+	mfsdr(SDR0_ETH_CFG, eth_cfg);
+	eth_cfg |= SDR0_ETH_CFG_MDIO_SEL_EMAC0;
+	mtsdr(SDR0_ETH_CFG, eth_cfg);
+
+	out_be32((void *)RGMII_FER, rmiifer);
+#if defined(CONFIG_460GT)
+	out_be32((void *)RGMII_FER + RGMII1_BASE_OFFSET, rmiifer1);
+#endif
+
+	/* bypass the TAHOE0/TAHOE1 cores for U-Boot */
+	mfsdr(SDR0_ETH_CFG, eth_cfg);
+	eth_cfg |= (SDR0_ETH_CFG_TAHOE0_BYPASS | SDR0_ETH_CFG_TAHOE1_BYPASS);
+	mtsdr(SDR0_ETH_CFG, eth_cfg);
+
+	return 0;
+}
+#endif /* CONFIG_460EX || CONFIG_460GT */
+
+static inline void *malloc_aligned(u32 size, u32 align)
+{
+	return (void *)(((u32)malloc(size + align) + align - 1) &
+			~(align - 1));
+}
+
+static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
+{
+	int i;
+	unsigned long reg = 0;
+	unsigned long msr;
+	unsigned long speed;
+	unsigned long duplex;
+	unsigned long failsafe;
+	unsigned mode_reg;
+	unsigned short devnum;
+	unsigned short reg_short;
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_405EX)
+	u32 opbfreq;
+	sys_info_t sysinfo;
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_405EX)
+	__maybe_unused int ethgroup = -1;
+#endif
+#endif
+	u32 bd_cached;
+	u32 bd_uncached = 0;
+#ifdef CONFIG_4xx_DCACHE
+	static u32 last_used_ea = 0;
+#endif
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_405EX)
+	int rgmii_channel;
+#endif
+
+	EMAC_4XX_HW_PST hw_p = dev->priv;
+
+	/* before doing anything, figure out if we have a MAC address */
+	/* if not, bail */
+	if (memcmp (dev->enetaddr, "\0\0\0\0\0\0", 6) == 0) {
+		printf("ERROR: ethaddr not set!\n");
+		return -1;
+	}
+
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_405EX)
+	/* Need to get the OPB frequency so we can access the PHY */
+	get_sys_info (&sysinfo);
+#endif
+
+	msr = mfmsr ();
+	mtmsr (msr & ~(MSR_EE));	/* disable interrupts */
+
+	devnum = hw_p->devnum;
+
+#ifdef INFO_4XX_ENET
+	/* AS.HARNOIS
+	 * We should have :
+	 * hw_p->stats.pkts_handled <=	hw_p->stats.pkts_rx <= hw_p->stats.pkts_handled+PKTBUFSRX
+	 * In the most cases hw_p->stats.pkts_handled = hw_p->stats.pkts_rx, but it
+	 * is possible that new packets (without relationship with
+	 * current transfer) have got the time to arrived before
+	 * netloop calls eth_halt
+	 */
+	printf ("About preceeding transfer (eth%d):\n"
+		"- Sent packet number %d\n"
+		"- Received packet number %d\n"
+		"- Handled packet number %d\n",
+		hw_p->devnum,
+		hw_p->stats.pkts_tx,
+		hw_p->stats.pkts_rx, hw_p->stats.pkts_handled);
+
+	hw_p->stats.pkts_tx = 0;
+	hw_p->stats.pkts_rx = 0;
+	hw_p->stats.pkts_handled = 0;
+	hw_p->print_speed = 1;	/* print speed message again next time */
+#endif
+
+	hw_p->tx_err_index = 0; /* Transmit Error Index for tx_err_log */
+	hw_p->rx_err_index = 0; /* Receive Error Index for rx_err_log */
+
+	hw_p->rx_slot = 0;	/* MAL Receive Slot */
+	hw_p->rx_i_index = 0;	/* Receive Interrupt Queue Index */
+	hw_p->rx_u_index = 0;	/* Receive User Queue Index */
+
+	hw_p->tx_slot = 0;	/* MAL Transmit Slot */
+	hw_p->tx_i_index = 0;	/* Transmit Interrupt Queue Index */
+	hw_p->tx_u_index = 0;	/* Transmit User Queue Index */
+
+#if defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)
+	/* set RMII mode */
+	/* NOTE: 440GX spec states that mode is mutually exclusive */
+	/* NOTE: Therefore, disable all other EMACS, since we handle */
+	/* NOTE: only one emac at a time */
+	reg = 0;
+	out_be32((void *)ZMII0_FER, 0);
+	udelay (100);
+
+#if defined(CONFIG_440GP) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
+	out_be32((void *)ZMII0_FER, (ZMII_FER_RMII | ZMII_FER_MDI) << ZMII_FER_V (devnum));
+#elif defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT)
+	ethgroup = ppc_4xx_eth_setup_bridge(devnum, bis);
+#endif
+
+	out_be32((void *)ZMII0_SSR, ZMII0_SSR_SP << ZMII0_SSR_V(devnum));
+#endif /* defined(CONFIG_440) && !defined(CONFIG_440SP) */
+#if defined(CONFIG_405EX)
+	ethgroup = ppc_4xx_eth_setup_bridge(devnum, bis);
+#endif
+
+	sync();
+
+	/* provide clocks for EMAC internal loopback  */
+	emac_loopback_enable(hw_p);
+
+	/* EMAC RESET */
+	out_be32((void *)EMAC0_MR0 + hw_p->hw_addr, EMAC_MR0_SRST);
+
+	/* remove clocks for EMAC internal loopback  */
+	emac_loopback_disable(hw_p);
+
+	failsafe = 1000;
+	while ((in_be32((void *)EMAC0_MR0 + hw_p->hw_addr) & (EMAC_MR0_SRST)) && failsafe) {
+		udelay (1000);
+		failsafe--;
+	}
+	if (failsafe <= 0)
+		printf("\nProblem resetting EMAC!\n");
+
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_405EX)
+	/* Whack the M1 register */
+	mode_reg = 0x0;
+	mode_reg &= ~0x00000038;
+	opbfreq = sysinfo.freqOPB / 1000000;
+	if (opbfreq <= 50);
+	else if (opbfreq <= 66)
+		mode_reg |= EMAC_MR1_OBCI_66;
+	else if (opbfreq <= 83)
+		mode_reg |= EMAC_MR1_OBCI_83;
+	else if (opbfreq <= 100)
+		mode_reg |= EMAC_MR1_OBCI_100;
+	else
+		mode_reg |= EMAC_MR1_OBCI_GT100;
+
+	out_be32((void *)EMAC0_MR1 + hw_p->hw_addr, mode_reg);
+#endif /* defined(CONFIG_440GX) || defined(CONFIG_440SP) */
+
+#if defined(CONFIG_GPCS_PHY_ADDR) || defined(CONFIG_GPCS_PHY1_ADDR) || \
+    defined(CONFIG_GPCS_PHY2_ADDR) || defined(CONFIG_GPCS_PHY3_ADDR)
+	if (bis->bi_phymode[devnum] == BI_PHYMODE_SGMII) {
+		/*
+		 * In SGMII mode, GPCS access is needed for
+		 * communication with the internal SGMII SerDes.
+		 */
+		switch (devnum) {
+#if defined(CONFIG_GPCS_PHY_ADDR)
+		case 0:
+			reg = CONFIG_GPCS_PHY_ADDR;
+			break;
+#endif
+#if defined(CONFIG_GPCS_PHY1_ADDR)
+		case 1:
+			reg = CONFIG_GPCS_PHY1_ADDR;
+			break;
+#endif
+#if defined(CONFIG_GPCS_PHY2_ADDR)
+		case 2:
+			reg = CONFIG_GPCS_PHY2_ADDR;
+			break;
+#endif
+#if defined(CONFIG_GPCS_PHY3_ADDR)
+		case 3:
+			reg = CONFIG_GPCS_PHY3_ADDR;
+			break;
+#endif
+		}
+
+		mode_reg = in_be32((void *)EMAC0_MR1 + hw_p->hw_addr);
+		mode_reg |= EMAC_MR1_MF_1000GPCS | EMAC_MR1_IPPA_SET(reg);
+		out_be32((void *)EMAC0_MR1 + hw_p->hw_addr, mode_reg);
+
+		/* Configure GPCS interface to recommended setting for SGMII */
+		miiphy_reset(dev->name, reg);
+		miiphy_write(dev->name, reg, 0x04, 0x8120); /* AsymPause, FDX */
+		miiphy_write(dev->name, reg, 0x07, 0x2801); /* msg_pg, toggle */
+		miiphy_write(dev->name, reg, 0x00, 0x0140); /* 1Gbps, FDX     */
+	}
+#endif /* defined(CONFIG_GPCS_PHY_ADDR) */
+
+	/* wait for PHY to complete auto negotiation */
+	reg_short = 0;
+	switch (devnum) {
+	case 0:
+		reg = CONFIG_PHY_ADDR;
+		break;
+#if defined (CONFIG_PHY1_ADDR)
+	case 1:
+		reg = CONFIG_PHY1_ADDR;
+		break;
+#endif
+#if defined (CONFIG_PHY2_ADDR)
+	case 2:
+		reg = CONFIG_PHY2_ADDR;
+		break;
+#endif
+#if defined (CONFIG_PHY3_ADDR)
+	case 3:
+		reg = CONFIG_PHY3_ADDR;
+		break;
+#endif
+	default:
+		reg = CONFIG_PHY_ADDR;
+		break;
+	}
+
+	bis->bi_phynum[devnum] = reg;
+
+	if (reg == CONFIG_FIXED_PHY)
+		goto get_speed;
+
+#if defined(CONFIG_PHY_RESET)
+	/*
+	 * Reset the phy, only if its the first time through
+	 * otherwise, just check the speeds & feeds
+	 */
+	if (hw_p->first_init == 0) {
+#if defined(CONFIG_M88E1111_PHY)
+		miiphy_write (dev->name, reg, 0x14, 0x0ce3);
+		miiphy_write (dev->name, reg, 0x18, 0x4101);
+		miiphy_write (dev->name, reg, 0x09, 0x0e00);
+		miiphy_write (dev->name, reg, 0x04, 0x01e1);
+#if defined(CONFIG_M88E1111_DISABLE_FIBER)
+		miiphy_read(dev->name, reg, 0x1b, &reg_short);
+		reg_short |= 0x8000;
+		miiphy_write(dev->name, reg, 0x1b, reg_short);
+#endif
+#endif
+#if defined(CONFIG_M88E1112_PHY)
+		if (bis->bi_phymode[devnum] == BI_PHYMODE_SGMII) {
+			/*
+			 * Marvell 88E1112 PHY needs to have the SGMII MAC
+			 * interace (page 2) properly configured to
+			 * communicate with the 460EX/GT GPCS interface.
+			 */
+
+			/* Set access to Page 2 */
+			miiphy_write(dev->name, reg, 0x16, 0x0002);
+
+			miiphy_write(dev->name, reg, 0x00, 0x0040); /* 1Gbps */
+			miiphy_read(dev->name, reg, 0x1a, &reg_short);
+			reg_short |= 0x8000; /* bypass Auto-Negotiation */
+			miiphy_write(dev->name, reg, 0x1a, reg_short);
+			miiphy_reset(dev->name, reg); /* reset MAC interface */
+
+			/* Reset access to Page 0 */
+			miiphy_write(dev->name, reg, 0x16, 0x0000);
+		}
+#endif /* defined(CONFIG_M88E1112_PHY) */
+		miiphy_reset (dev->name, reg);
+
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_405EX)
+
+#if defined(CONFIG_CIS8201_PHY)
+		/*
+		 * Cicada 8201 PHY needs to have an extended register whacked
+		 * for RGMII mode.
+		 */
+		if (((devnum == 2) || (devnum == 3)) && (4 == ethgroup)) {
+#if defined(CONFIG_CIS8201_SHORT_ETCH)
+			miiphy_write (dev->name, reg, 23, 0x1300);
+#else
+			miiphy_write (dev->name, reg, 23, 0x1000);
+#endif
+			/*
+			 * Vitesse VSC8201/Cicada CIS8201 errata:
+			 * Interoperability problem with Intel 82547EI phys
+			 * This work around (provided by Vitesse) changes
+			 * the default timer convergence from 8ms to 12ms
+			 */
+			miiphy_write (dev->name, reg, 0x1f, 0x2a30);
+			miiphy_write (dev->name, reg, 0x08, 0x0200);
+			miiphy_write (dev->name, reg, 0x1f, 0x52b5);
+			miiphy_write (dev->name, reg, 0x02, 0x0004);
+			miiphy_write (dev->name, reg, 0x01, 0x0671);
+			miiphy_write (dev->name, reg, 0x00, 0x8fae);
+			miiphy_write (dev->name, reg, 0x1f, 0x2a30);
+			miiphy_write (dev->name, reg, 0x08, 0x0000);
+			miiphy_write (dev->name, reg, 0x1f, 0x0000);
+			/* end Vitesse/Cicada errata */
+		}
+#endif /* defined(CONFIG_CIS8201_PHY) */
+
+#if defined(CONFIG_ET1011C_PHY)
+		/*
+		 * Agere ET1011c PHY needs to have an extended register whacked
+		 * for RGMII mode.
+		 */
+		if (((devnum == 2) || (devnum ==3)) && (4 == ethgroup)) {
+			miiphy_read (dev->name, reg, 0x16, &reg_short);
+			reg_short &= ~(0x7);
+			reg_short |= 0x6;	/* RGMII DLL Delay*/
+			miiphy_write (dev->name, reg, 0x16, reg_short);
+
+			miiphy_read (dev->name, reg, 0x17, &reg_short);
+			reg_short &= ~(0x40);
+			miiphy_write (dev->name, reg, 0x17, reg_short);
+
+			miiphy_write(dev->name, reg, 0x1c, 0x74f0);
+		}
+#endif /* defined(CONFIG_ET1011C_PHY) */
+
+#endif /* defined(CONFIG_440GX) ... */
+		/* Start/Restart autonegotiation */
+		phy_setup_aneg (dev->name, reg);
+		udelay (1000);
+	}
+#endif /* defined(CONFIG_PHY_RESET) */
+
+	miiphy_read (dev->name, reg, MII_BMSR, &reg_short);
+
+	/*
+	 * Wait if PHY is capable of autonegotiation and autonegotiation is not complete
+	 */
+	if ((reg_short & BMSR_ANEGCAPABLE)
+	    && !(reg_short & BMSR_ANEGCOMPLETE)) {
+		puts ("Waiting for PHY auto negotiation to complete");
+		i = 0;
+		while (!(reg_short & BMSR_ANEGCOMPLETE)) {
+			/*
+			 * Timeout reached ?
+			 */
+			if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
+				puts (" TIMEOUT !\n");
+				break;
+			}
+
+			if ((i++ % 1000) == 0) {
+				putc ('.');
+			}
+			udelay (1000);	/* 1 ms */
+			miiphy_read (dev->name, reg, MII_BMSR, &reg_short);
+		}
+		puts (" done\n");
+		udelay (500000);	/* another 500 ms (results in faster booting) */
+	}
+
+get_speed:
+	if (reg == CONFIG_FIXED_PHY) {
+		for (i = 0; i < ARRAY_SIZE(fixed_phy_port); i++) {
+			if (devnum == fixed_phy_port[i].devnum) {
+				speed = fixed_phy_port[i].speed;
+				duplex = fixed_phy_port[i].duplex;
+				break;
+			}
+		}
+
+		if (i == ARRAY_SIZE(fixed_phy_port)) {
+			printf("ERROR: PHY (%s) not configured correctly!\n",
+				dev->name);
+			return -1;
+		}
+	} else {
+		speed = miiphy_speed(dev->name, reg);
+		duplex = miiphy_duplex(dev->name, reg);
+	}
+
+	if (hw_p->print_speed) {
+		hw_p->print_speed = 0;
+		printf ("ENET Speed is %d Mbps - %s duplex connection (EMAC%d)\n",
+			(int) speed, (duplex == HALF) ? "HALF" : "FULL",
+			hw_p->devnum);
+	}
+
+#if defined(CONFIG_440) && \
+    !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
+    !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX) && \
+    !defined(CONFIG_460EX) && !defined(CONFIG_460GT)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+	mfsdr(SDR0_MFR, reg);
+	if (speed == 100) {
+		reg = (reg & ~SDR0_MFR_ZMII_MODE_MASK) | SDR0_MFR_ZMII_MODE_RMII_100M;
+	} else {
+		reg = (reg & ~SDR0_MFR_ZMII_MODE_MASK) | SDR0_MFR_ZMII_MODE_RMII_10M;
+	}
+	mtsdr(SDR0_MFR, reg);
+#endif
+
+	/* Set ZMII/RGMII speed according to the phy link speed */
+	reg = in_be32((void *)ZMII0_SSR);
+	if ( (speed == 100) || (speed == 1000) )
+		out_be32((void *)ZMII0_SSR, reg | (ZMII0_SSR_SP << ZMII0_SSR_V (devnum)));
+	else
+		out_be32((void *)ZMII0_SSR, reg & (~(ZMII0_SSR_SP << ZMII0_SSR_V (devnum))));
+
+	if ((devnum == 2) || (devnum == 3)) {
+		if (speed == 1000)
+			reg = (RGMII_SSR_SP_1000MBPS << RGMII_SSR_V (devnum));
+		else if (speed == 100)
+			reg = (RGMII_SSR_SP_100MBPS << RGMII_SSR_V (devnum));
+		else if (speed == 10)
+			reg = (RGMII_SSR_SP_10MBPS << RGMII_SSR_V (devnum));
+		else {
+			printf("Error in RGMII Speed\n");
+			return -1;
+		}
+		out_be32((void *)RGMII_SSR, reg);
+	}
+#endif /* defined(CONFIG_440) && !defined(CONFIG_440SP) */
+
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_405EX)
+	if (devnum >= 2)
+		rgmii_channel = devnum - 2;
+	else
+		rgmii_channel = devnum;
+
+	if (speed == 1000)
+		reg = (RGMII_SSR_SP_1000MBPS << RGMII_SSR_V(rgmii_channel));
+	else if (speed == 100)
+		reg = (RGMII_SSR_SP_100MBPS << RGMII_SSR_V(rgmii_channel));
+	else if (speed == 10)
+		reg = (RGMII_SSR_SP_10MBPS << RGMII_SSR_V(rgmii_channel));
+	else {
+		printf("Error in RGMII Speed\n");
+		return -1;
+	}
+	out_be32((void *)RGMII_SSR, reg);
+#if defined(CONFIG_460GT)
+	if ((devnum == 2) || (devnum == 3))
+		out_be32((void *)RGMII_SSR + RGMII1_BASE_OFFSET, reg);
+#endif
+#endif
+
+	/* set the Mal configuration reg */
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_405EX)
+	mtdcr (MAL0_CFG, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA |
+	       MAL_CR_PLBLT_DEFAULT | MAL_CR_EOPIE | 0x00330000);
+#else
+	mtdcr (MAL0_CFG, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT);
+	/* Errata 1.12: MAL_1 -- Disable MAL bursting */
+	if (get_pvr() == PVR_440GP_RB) {
+		mtdcr (MAL0_CFG, mfdcr(MAL0_CFG) & ~MAL_CR_PLBB);
+	}
+#endif
+
+	/*
+	 * Malloc MAL buffer desciptors, make sure they are
+	 * aligned on cache line boundary size
+	 * (401/403/IOP480 = 16, 405 = 32)
+	 * and doesn't cross cache block boundaries.
+	 */
+	if (hw_p->first_init == 0) {
+		debug("*** Allocating descriptor memory ***\n");
+
+		bd_cached = (u32)malloc_aligned(MAL_ALLOC_SIZE, 4096);
+		if (!bd_cached) {
+			printf("%s: Error allocating MAL descriptor buffers!\n", __func__);
+			return -1;
+		}
+
+#ifdef CONFIG_4xx_DCACHE
+		flush_dcache_range(bd_cached, bd_cached + MAL_ALLOC_SIZE);
+		if (!last_used_ea)
+#if defined(CONFIG_SYS_MEM_TOP_HIDE)
+			bd_uncached = bis->bi_memsize + CONFIG_SYS_MEM_TOP_HIDE;
+#else
+			bd_uncached = bis->bi_memsize;
+#endif
+		else
+			bd_uncached = last_used_ea + MAL_ALLOC_SIZE;
+
+		last_used_ea = bd_uncached;
+		program_tlb(bd_cached, bd_uncached, MAL_ALLOC_SIZE,
+			    TLB_WORD2_I_ENABLE);
+#else
+		bd_uncached = bd_cached;
+#endif
+		hw_p->tx_phys = bd_cached;
+		hw_p->rx_phys = bd_cached + MAL_TX_DESC_SIZE;
+		hw_p->tx = (mal_desc_t *)(bd_uncached);
+		hw_p->rx = (mal_desc_t *)(bd_uncached + MAL_TX_DESC_SIZE);
+		debug("hw_p->tx=%p, hw_p->rx=%p\n", hw_p->tx, hw_p->rx);
+	}
+
+	for (i = 0; i < NUM_TX_BUFF; i++) {
+		hw_p->tx[i].ctrl = 0;
+		hw_p->tx[i].data_len = 0;
+		if (hw_p->first_init == 0)
+			hw_p->txbuf_ptr = malloc_aligned(MAL_ALLOC_SIZE,
+							 L1_CACHE_BYTES);
+		hw_p->tx[i].data_ptr = hw_p->txbuf_ptr;
+		if ((NUM_TX_BUFF - 1) == i)
+			hw_p->tx[i].ctrl |= MAL_TX_CTRL_WRAP;
+		hw_p->tx_run[i] = -1;
+		debug("TX_BUFF %d @ 0x%08x\n", i, (u32)hw_p->tx[i].data_ptr);
+	}
+
+	for (i = 0; i < NUM_RX_BUFF; i++) {
+		hw_p->rx[i].ctrl = 0;
+		hw_p->rx[i].data_len = 0;
+		hw_p->rx[i].data_ptr = (char *)NetRxPackets[i];
+		if ((NUM_RX_BUFF - 1) == i)
+			hw_p->rx[i].ctrl |= MAL_RX_CTRL_WRAP;
+		hw_p->rx[i].ctrl |= MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR;
+		hw_p->rx_ready[i] = -1;
+		debug("RX_BUFF %d @ 0x%08x\n", i, (u32)hw_p->rx[i].data_ptr);
+	}
+
+	reg = 0x00000000;
+
+	reg |= dev->enetaddr[0];	/* set high address */
+	reg = reg << 8;
+	reg |= dev->enetaddr[1];
+
+	out_be32((void *)EMAC0_IAH + hw_p->hw_addr, reg);
+
+	reg = 0x00000000;
+	reg |= dev->enetaddr[2];	/* set low address  */
+	reg = reg << 8;
+	reg |= dev->enetaddr[3];
+	reg = reg << 8;
+	reg |= dev->enetaddr[4];
+	reg = reg << 8;
+	reg |= dev->enetaddr[5];
+
+	out_be32((void *)EMAC0_IAL + hw_p->hw_addr, reg);
+
+	switch (devnum) {
+	case 1:
+		/* setup MAL tx & rx channel pointers */
+#if defined (CONFIG_405EP) || defined (CONFIG_440EP) || defined (CONFIG_440GR)
+		mtdcr (MAL0_TXCTP2R, hw_p->tx_phys);
+#else
+		mtdcr (MAL0_TXCTP1R, hw_p->tx_phys);
+#endif
+#if defined(CONFIG_440)
+		mtdcr (MAL0_TXBADDR, 0x0);
+		mtdcr (MAL0_RXBADDR, 0x0);
+#endif
+
+#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
+		mtdcr (MAL0_RXCTP8R, hw_p->rx_phys);
+		/* set RX buffer size */
+		mtdcr (MAL0_RCBS8, ENET_MAX_MTU_ALIGNED / 16);
+#else
+		mtdcr (MAL0_RXCTP1R, hw_p->rx_phys);
+		/* set RX buffer size */
+		mtdcr (MAL0_RCBS1, ENET_MAX_MTU_ALIGNED / 16);
+#endif
+		break;
+#if defined (CONFIG_440GX)
+	case 2:
+		/* setup MAL tx & rx channel pointers */
+		mtdcr (MAL0_TXBADDR, 0x0);
+		mtdcr (MAL0_RXBADDR, 0x0);
+		mtdcr (MAL0_TXCTP2R, hw_p->tx_phys);
+		mtdcr (MAL0_RXCTP2R, hw_p->rx_phys);
+		/* set RX buffer size */
+		mtdcr (MAL0_RCBS2, ENET_MAX_MTU_ALIGNED / 16);
+		break;
+	case 3:
+		/* setup MAL tx & rx channel pointers */
+		mtdcr (MAL0_TXBADDR, 0x0);
+		mtdcr (MAL0_TXCTP3R, hw_p->tx_phys);
+		mtdcr (MAL0_RXBADDR, 0x0);
+		mtdcr (MAL0_RXCTP3R, hw_p->rx_phys);
+		/* set RX buffer size */
+		mtdcr (MAL0_RCBS3, ENET_MAX_MTU_ALIGNED / 16);
+		break;
+#endif /* CONFIG_440GX */
+#if defined (CONFIG_460GT)
+	case 2:
+		/* setup MAL tx & rx channel pointers */
+		mtdcr (MAL0_TXBADDR, 0x0);
+		mtdcr (MAL0_RXBADDR, 0x0);
+		mtdcr (MAL0_TXCTP2R, hw_p->tx_phys);
+		mtdcr (MAL0_RXCTP16R, hw_p->rx_phys);
+		/* set RX buffer size */
+		mtdcr (MAL0_RCBS16, ENET_MAX_MTU_ALIGNED / 16);
+		break;
+	case 3:
+		/* setup MAL tx & rx channel pointers */
+		mtdcr (MAL0_TXBADDR, 0x0);
+		mtdcr (MAL0_RXBADDR, 0x0);
+		mtdcr (MAL0_TXCTP3R, hw_p->tx_phys);
+		mtdcr (MAL0_RXCTP24R, hw_p->rx_phys);
+		/* set RX buffer size */
+		mtdcr (MAL0_RCBS24, ENET_MAX_MTU_ALIGNED / 16);
+		break;
+#endif /* CONFIG_460GT */
+	case 0:
+	default:
+		/* setup MAL tx & rx channel pointers */
+#if defined(CONFIG_440)
+		mtdcr (MAL0_TXBADDR, 0x0);
+		mtdcr (MAL0_RXBADDR, 0x0);
+#endif
+		mtdcr (MAL0_TXCTP0R, hw_p->tx_phys);
+		mtdcr (MAL0_RXCTP0R, hw_p->rx_phys);
+		/* set RX buffer size */
+		mtdcr (MAL0_RCBS0, ENET_MAX_MTU_ALIGNED / 16);
+		break;
+	}
+
+	/* Enable MAL transmit and receive channels */
+#if defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
+	mtdcr (MAL0_TXCASR, (MAL_TXRX_CASR >> (hw_p->devnum*2)));
+#else
+	mtdcr (MAL0_TXCASR, (MAL_TXRX_CASR >> hw_p->devnum));
+#endif
+	mtdcr (MAL0_RXCASR, (MAL_TXRX_CASR >> hw_p->devnum));
+
+	/* set transmit enable & receive enable */
+	out_be32((void *)EMAC0_MR0 + hw_p->hw_addr, EMAC_MR0_TXE | EMAC_MR0_RXE);
+
+	mode_reg = in_be32((void *)EMAC0_MR1 + hw_p->hw_addr);
+
+	/* set rx-/tx-fifo size */
+	mode_reg = (mode_reg & ~EMAC_MR1_FIFO_MASK) | EMAC_MR1_FIFO_SIZE;
+
+	/* set speed */
+	if (speed == _1000BASET) {
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+		unsigned long pfc1;
+
+		mfsdr (SDR0_PFC1, pfc1);
+		pfc1 |= SDR0_PFC1_EM_1000;
+		mtsdr (SDR0_PFC1, pfc1);
+#endif
+		mode_reg = mode_reg | EMAC_MR1_MF_1000MBPS | EMAC_MR1_IST;
+	} else if (speed == _100BASET)
+		mode_reg = mode_reg | EMAC_MR1_MF_100MBPS | EMAC_MR1_IST;
+	else
+		mode_reg = mode_reg & ~0x00C00000;	/* 10 MBPS */
+	if (duplex == FULL)
+		mode_reg = mode_reg | 0x80000000 | EMAC_MR1_IST;
+
+	out_be32((void *)EMAC0_MR1 + hw_p->hw_addr, mode_reg);
+
+	/* Enable broadcast and indvidual address */
+	/* TBS: enabling runts as some misbehaved nics will send runts */
+	out_be32((void *)EMAC0_RXM + hw_p->hw_addr, EMAC_RMR_BAE | EMAC_RMR_IAE);
+
+	/* we probably need to set the tx mode1 reg? maybe at tx time */
+
+	/* set transmit request threshold register */
+	out_be32((void *)EMAC0_TRTR + hw_p->hw_addr, 0x18000000);	/* 256 byte threshold */
+
+	/* set receive	low/high water mark register */
+#if defined(CONFIG_440)
+	/* 440s has a 64 byte burst length */
+	out_be32((void *)EMAC0_RX_HI_LO_WMARK + hw_p->hw_addr, 0x80009000);
+#else
+	/* 405s have a 16 byte burst length */
+	out_be32((void *)EMAC0_RX_HI_LO_WMARK + hw_p->hw_addr, 0x0f002000);
+#endif /* defined(CONFIG_440) */
+	out_be32((void *)EMAC0_TMR1 + hw_p->hw_addr, 0xf8640000);
+
+	/* Set fifo limit entry in tx mode 0 */
+	out_be32((void *)EMAC0_TMR0 + hw_p->hw_addr, 0x00000003);
+	/* Frame gap set */
+	out_be32((void *)EMAC0_I_FRAME_GAP_REG + hw_p->hw_addr, 0x00000008);
+
+	/* Set EMAC IER */
+	hw_p->emac_ier = EMAC_ISR_PTLE | EMAC_ISR_BFCS | EMAC_ISR_ORE | EMAC_ISR_IRE;
+	if (speed == _100BASET)
+		hw_p->emac_ier = hw_p->emac_ier | EMAC_ISR_SYE;
+
+	out_be32((void *)EMAC0_ISR + hw_p->hw_addr, 0xffffffff);	/* clear pending interrupts */
+	out_be32((void *)EMAC0_IER + hw_p->hw_addr, hw_p->emac_ier);
+
+	if (hw_p->first_init == 0) {
+		/*
+		 * Connect interrupt service routines
+		 */
+		irq_install_handler(ETH_IRQ_NUM(hw_p->devnum),
+				    (interrupt_handler_t *) enetInt, dev);
+	}
+
+	mtmsr (msr);		/* enable interrupts again */
+
+	hw_p->bis = bis;
+	hw_p->first_init = 1;
+
+	return 0;
+}
+
+
+static int ppc_4xx_eth_send(struct eth_device *dev, void *ptr, int len)
+{
+	struct enet_frame *ef_ptr;
+	ulong time_start, time_now;
+	unsigned long temp_txm0;
+	EMAC_4XX_HW_PST hw_p = dev->priv;
+
+	ef_ptr = (struct enet_frame *) ptr;
+
+	/*-----------------------------------------------------------------------+
+	 *  Copy in our address into the frame.
+	 *-----------------------------------------------------------------------*/
+	(void) memcpy (ef_ptr->source_addr, dev->enetaddr, ENET_ADDR_LENGTH);
+
+	/*-----------------------------------------------------------------------+
+	 * If frame is too long or too short, modify length.
+	 *-----------------------------------------------------------------------*/
+	/* TBS: where does the fragment go???? */
+	if (len > ENET_MAX_MTU)
+		len = ENET_MAX_MTU;
+
+	/*   memcpy ((void *) &tx_buff[tx_slot], (const void *) ptr, len); */
+	memcpy ((void *) hw_p->txbuf_ptr, (const void *) ptr, len);
+	flush_dcache_range((u32)hw_p->txbuf_ptr, (u32)hw_p->txbuf_ptr + len);
+
+	/*-----------------------------------------------------------------------+
+	 * set TX Buffer busy, and send it
+	 *-----------------------------------------------------------------------*/
+	hw_p->tx[hw_p->tx_slot].ctrl = (MAL_TX_CTRL_LAST |
+					EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP) &
+		~(EMAC_TX_CTRL_ISA | EMAC_TX_CTRL_RSA);
+	if ((NUM_TX_BUFF - 1) == hw_p->tx_slot)
+		hw_p->tx[hw_p->tx_slot].ctrl |= MAL_TX_CTRL_WRAP;
+
+	hw_p->tx[hw_p->tx_slot].data_len = (short) len;
+	hw_p->tx[hw_p->tx_slot].ctrl |= MAL_TX_CTRL_READY;
+
+	sync();
+
+	out_be32((void *)EMAC0_TMR0 + hw_p->hw_addr,
+		 in_be32((void *)EMAC0_TMR0 + hw_p->hw_addr) | EMAC_TMR0_GNP0);
+#ifdef INFO_4XX_ENET
+	hw_p->stats.pkts_tx++;
+#endif
+
+	/*-----------------------------------------------------------------------+
+	 * poll unitl the packet is sent and then make sure it is OK
+	 *-----------------------------------------------------------------------*/
+	time_start = get_timer (0);
+	while (1) {
+		temp_txm0 = in_be32((void *)EMAC0_TMR0 + hw_p->hw_addr);
+		/* loop until either TINT turns on or 3 seconds elapse */
+		if ((temp_txm0 & EMAC_TMR0_GNP0) != 0) {
+			/* transmit is done, so now check for errors
+			 * If there is an error, an interrupt should
+			 * happen when we return
+			 */
+			time_now = get_timer (0);
+			if ((time_now - time_start) > 3000) {
+				return (-1);
+			}
+		} else {
+			return (len);
+		}
+	}
+}
+
+int enetInt (struct eth_device *dev)
+{
+	int serviced;
+	int rc = -1;		/* default to not us */
+	u32 mal_isr;
+	u32 emac_isr = 0;
+	u32 mal_eob;
+	u32 uic_mal;
+	u32 uic_mal_err;
+	u32 uic_emac;
+	u32 uic_emac_b;
+	EMAC_4XX_HW_PST hw_p;
+
+	/*
+	 * Because the mal is generic, we need to get the current
+	 * eth device
+	 */
+	dev = eth_get_dev();
+
+	hw_p = dev->priv;
+
+	/* enter loop that stays in interrupt code until nothing to service */
+	do {
+		serviced = 0;
+
+		uic_mal = mfdcr(UIC_BASE_MAL + UIC_MSR);
+		uic_mal_err = mfdcr(UIC_BASE_MAL_ERR + UIC_MSR);
+		uic_emac = mfdcr(UIC_BASE_EMAC + UIC_MSR);
+		uic_emac_b = mfdcr(UIC_BASE_EMAC_B + UIC_MSR);
+
+		if (!(uic_mal & (UIC_MAL_RXEOB | UIC_MAL_TXEOB))
+		    && !(uic_mal_err & (UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE))
+		    && !(uic_emac & UIC_ETHx) && !(uic_emac_b & UIC_ETHxB)) {
+			/* not for us */
+			return (rc);
+		}
+
+		/* get and clear controller status interrupts */
+		/* look at MAL and EMAC error interrupts */
+		if (uic_mal_err & (UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE)) {
+			/* we have a MAL error interrupt */
+			mal_isr = mfdcr(MAL0_ESR);
+			mal_err(dev, mal_isr, uic_mal_err,
+				 MAL_UIC_DEF, MAL_UIC_ERR);
+
+			/* clear MAL error interrupt status bits */
+			mtdcr(UIC_BASE_MAL_ERR + UIC_SR,
+			      UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE);
+
+			return -1;
+		}
+
+		/* look for EMAC errors */
+		if ((uic_emac & UIC_ETHx) || (uic_emac_b & UIC_ETHxB)) {
+			emac_isr = in_be32((void *)EMAC0_ISR + hw_p->hw_addr);
+			emac_err(dev, emac_isr);
+
+			/* clear EMAC error interrupt status bits */
+			mtdcr(UIC_BASE_EMAC + UIC_SR, UIC_ETHx);
+			mtdcr(UIC_BASE_EMAC_B + UIC_SR, UIC_ETHxB);
+
+			return -1;
+		}
+
+		/* handle MAX TX EOB interrupt from a tx */
+		if (uic_mal & UIC_MAL_TXEOB) {
+			/* clear MAL interrupt status bits */
+			mal_eob = mfdcr(MAL0_TXEOBISR);
+			mtdcr(MAL0_TXEOBISR, mal_eob);
+			mtdcr(UIC_BASE_MAL + UIC_SR, UIC_MAL_TXEOB);
+
+			/* indicate that we serviced an interrupt */
+			serviced = 1;
+			rc = 0;
+		}
+
+		/* handle MAL RX EOB interrupt from a receive */
+		/* check for EOB on valid channels	     */
+		if (uic_mal & UIC_MAL_RXEOB) {
+			mal_eob = mfdcr(MAL0_RXEOBISR);
+			if (mal_eob &
+			    (0x80000000 >> (hw_p->devnum * MAL_RX_CHAN_MUL))) {
+				/* push packet to upper layer */
+				enet_rcv(dev, emac_isr);
+
+				/* clear MAL interrupt status bits */
+				mtdcr(UIC_BASE_MAL + UIC_SR, UIC_MAL_RXEOB);
+
+				/* indicate that we serviced an interrupt */
+				serviced = 1;
+				rc = 0;
+			}
+		}
+#if defined(CONFIG_405EZ)
+		/*
+		 * On 405EZ the RX-/TX-interrupts are coalesced into
+		 * one IRQ bit in the UIC. We need to acknowledge the
+		 * RX-/TX-interrupts in the SDR0_ICINTSTAT reg as well.
+		 */
+		mtsdr(SDR0_ICINTSTAT,
+		      SDR_ICRX_STAT | SDR_ICTX0_STAT | SDR_ICTX1_STAT);
+#endif  /* defined(CONFIG_405EZ) */
+	} while (serviced);
+
+	return (rc);
+}
+
+/*-----------------------------------------------------------------------------+
+ *  MAL Error Routine
+ *-----------------------------------------------------------------------------*/
+static void mal_err (struct eth_device *dev, unsigned long isr,
+		     unsigned long uic, unsigned long maldef,
+		     unsigned long mal_errr)
+{
+	EMAC_4XX_HW_PST hw_p = dev->priv;
+
+	mtdcr (MAL0_ESR, isr);	/* clear interrupt */
+
+	/* clear DE interrupt */
+	mtdcr (MAL0_TXDEIR, 0xC0000000);
+	mtdcr (MAL0_RXDEIR, 0x80000000);
+
+#ifdef INFO_4XX_ENET
+	printf ("\nMAL error occured.... ISR = %lx UIC = = %lx	MAL_DEF = %lx  MAL_ERR= %lx \n", isr, uic, maldef, mal_errr);
+#endif
+
+	eth_init (hw_p->bis);	/* start again... */
+}
+
+/*-----------------------------------------------------------------------------+
+ *  EMAC Error Routine
+ *-----------------------------------------------------------------------------*/
+static void emac_err (struct eth_device *dev, unsigned long isr)
+{
+	EMAC_4XX_HW_PST hw_p = dev->priv;
+
+	printf ("EMAC%d error occured.... ISR = %lx\n", hw_p->devnum, isr);
+	out_be32((void *)EMAC0_ISR + hw_p->hw_addr, isr);
+}
+
+/*-----------------------------------------------------------------------------+
+ *  enet_rcv() handles the ethernet receive data
+ *-----------------------------------------------------------------------------*/
+static void enet_rcv (struct eth_device *dev, unsigned long malisr)
+{
+	unsigned long data_len;
+	unsigned long rx_eob_isr;
+	EMAC_4XX_HW_PST hw_p = dev->priv;
+
+	int handled = 0;
+	int i;
+	int loop_count = 0;
+
+	rx_eob_isr = mfdcr (MAL0_RXEOBISR);
+	if ((0x80000000 >> (hw_p->devnum * MAL_RX_CHAN_MUL)) & rx_eob_isr) {
+		/* clear EOB */
+		mtdcr (MAL0_RXEOBISR, rx_eob_isr);
+
+		/* EMAC RX done */
+		while (1) {	/* do all */
+			i = hw_p->rx_slot;
+
+			if ((MAL_RX_CTRL_EMPTY & hw_p->rx[i].ctrl)
+			    || (loop_count >= NUM_RX_BUFF))
+				break;
+
+			loop_count++;
+			handled++;
+			data_len = (unsigned long) hw_p->rx[i].data_len & 0x0fff;	/* Get len */
+			if (data_len) {
+				if (data_len > ENET_MAX_MTU)	/* Check len */
+					data_len = 0;
+				else {
+					if (EMAC_RX_ERRORS & hw_p->rx[i].ctrl) {	/* Check Errors */
+						data_len = 0;
+						hw_p->stats.rx_err_log[hw_p->
+								       rx_err_index]
+							= hw_p->rx[i].ctrl;
+						hw_p->rx_err_index++;
+						if (hw_p->rx_err_index ==
+						    MAX_ERR_LOG)
+							hw_p->rx_err_index =
+								0;
+					}	/* emac_erros */
+				}	/* data_len < max mtu */
+			}	/* if data_len */
+			if (!data_len) {	/* no data */
+				hw_p->rx[i].ctrl |= MAL_RX_CTRL_EMPTY;	/* Free Recv Buffer */
+
+				hw_p->stats.data_len_err++;	/* Error at Rx */
+			}
+
+			/* !data_len */
+			/* AS.HARNOIS */
+			/* Check if user has already eaten buffer */
+			/* if not => ERROR */
+			else if (hw_p->rx_ready[hw_p->rx_i_index] != -1) {
+				if (hw_p->is_receiving)
+					printf ("ERROR : Receive buffers are full!\n");
+				break;
+			} else {
+				hw_p->stats.rx_frames++;
+				hw_p->stats.rx += data_len;
+#ifdef INFO_4XX_ENET
+				hw_p->stats.pkts_rx++;
+#endif
+				/* AS.HARNOIS
+				 * use ring buffer
+				 */
+				hw_p->rx_ready[hw_p->rx_i_index] = i;
+				hw_p->rx_i_index++;
+				if (NUM_RX_BUFF == hw_p->rx_i_index)
+					hw_p->rx_i_index = 0;
+
+				hw_p->rx_slot++;
+				if (NUM_RX_BUFF == hw_p->rx_slot)
+					hw_p->rx_slot = 0;
+
+				/*  AS.HARNOIS
+				 * free receive buffer only when
+				 * buffer has been handled (eth_rx)
+				 rx[i].ctrl |= MAL_RX_CTRL_EMPTY;
+				 */
+			}	/* if data_len */
+		}		/* while */
+	}			/* if EMACK_RXCHL */
+}
+
+
+static int ppc_4xx_eth_rx (struct eth_device *dev)
+{
+	int length;
+	int user_index;
+	unsigned long msr;
+	EMAC_4XX_HW_PST hw_p = dev->priv;
+
+	hw_p->is_receiving = 1; /* tell driver */
+
+	for (;;) {
+		/* AS.HARNOIS
+		 * use ring buffer and
+		 * get index from rx buffer desciptor queue
+		 */
+		user_index = hw_p->rx_ready[hw_p->rx_u_index];
+		if (user_index == -1) {
+			length = -1;
+			break;	/* nothing received - leave for() loop */
+		}
+
+		msr = mfmsr ();
+		mtmsr (msr & ~(MSR_EE));
+
+		length = hw_p->rx[user_index].data_len & 0x0fff;
+
+		/* Pass the packet up to the protocol layers. */
+		/*	 NetReceive(NetRxPackets[rxIdx], length - 4); */
+		/*	 NetReceive(NetRxPackets[i], length); */
+		invalidate_dcache_range((u32)hw_p->rx[user_index].data_ptr,
+					(u32)hw_p->rx[user_index].data_ptr +
+					length - 4);
+		NetReceive (NetRxPackets[user_index], length - 4);
+		/* Free Recv Buffer */
+		hw_p->rx[user_index].ctrl |= MAL_RX_CTRL_EMPTY;
+		/* Free rx buffer descriptor queue */
+		hw_p->rx_ready[hw_p->rx_u_index] = -1;
+		hw_p->rx_u_index++;
+		if (NUM_RX_BUFF == hw_p->rx_u_index)
+			hw_p->rx_u_index = 0;
+
+#ifdef INFO_4XX_ENET
+		hw_p->stats.pkts_handled++;
+#endif
+
+		mtmsr (msr);	/* Enable IRQ's */
+	}
+
+	hw_p->is_receiving = 0; /* tell driver */
+
+	return length;
+}
+
+int ppc_4xx_eth_initialize (bd_t * bis)
+{
+	static int virgin = 0;
+	struct eth_device *dev;
+	int eth_num = 0;
+	EMAC_4XX_HW_PST hw = NULL;
+	u8 ethaddr[4 + CONFIG_EMAC_NR_START][6];
+	u32 hw_addr[4];
+	u32 mal_ier;
+
+#if defined(CONFIG_440GX)
+	unsigned long pfc1;
+
+	mfsdr (SDR0_PFC1, pfc1);
+	pfc1 &= ~(0x01e00000);
+	pfc1 |= 0x01200000;
+	mtsdr (SDR0_PFC1, pfc1);
+#endif
+
+	/* first clear all mac-addresses */
+	for (eth_num = 0; eth_num < LAST_EMAC_NUM; eth_num++)
+		memcpy(ethaddr[eth_num], "\0\0\0\0\0\0", 6);
+
+	for (eth_num = 0; eth_num < LAST_EMAC_NUM; eth_num++) {
+		int ethaddr_idx = eth_num + CONFIG_EMAC_NR_START;
+		switch (eth_num) {
+		default:		/* fall through */
+		case 0:
+			eth_getenv_enetaddr("ethaddr", ethaddr[ethaddr_idx]);
+			hw_addr[eth_num] = 0x0;
+			break;
+#ifdef CONFIG_HAS_ETH1
+		case 1:
+			eth_getenv_enetaddr("eth1addr", ethaddr[ethaddr_idx]);
+			hw_addr[eth_num] = 0x100;
+			break;
+#endif
+#ifdef CONFIG_HAS_ETH2
+		case 2:
+			eth_getenv_enetaddr("eth2addr", ethaddr[ethaddr_idx]);
+#if defined(CONFIG_460GT)
+			hw_addr[eth_num] = 0x300;
+#else
+			hw_addr[eth_num] = 0x400;
+#endif
+			break;
+#endif
+#ifdef CONFIG_HAS_ETH3
+		case 3:
+			eth_getenv_enetaddr("eth3addr", ethaddr[ethaddr_idx]);
+#if defined(CONFIG_460GT)
+			hw_addr[eth_num] = 0x400;
+#else
+			hw_addr[eth_num] = 0x600;
+#endif
+			break;
+#endif
+		}
+	}
+
+	/* set phy num and mode */
+	bis->bi_phynum[0] = CONFIG_PHY_ADDR;
+	bis->bi_phymode[0] = 0;
+
+#if defined(CONFIG_PHY1_ADDR)
+	bis->bi_phynum[1] = CONFIG_PHY1_ADDR;
+	bis->bi_phymode[1] = 0;
+#endif
+#if defined(CONFIG_440GX)
+	bis->bi_phynum[2] = CONFIG_PHY2_ADDR;
+	bis->bi_phynum[3] = CONFIG_PHY3_ADDR;
+	bis->bi_phymode[2] = 2;
+	bis->bi_phymode[3] = 2;
+#endif
+
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_405EX)
+	ppc_4xx_eth_setup_bridge(0, bis);
+#endif
+
+	for (eth_num = 0; eth_num < LAST_EMAC_NUM; eth_num++) {
+		/*
+		 * See if we can actually bring up the interface,
+		 * otherwise, skip it
+		 */
+		if (memcmp (ethaddr[eth_num], "\0\0\0\0\0\0", 6) == 0) {
+			bis->bi_phymode[eth_num] = BI_PHYMODE_NONE;
+			continue;
+		}
+
+		/* Allocate device structure */
+		dev = (struct eth_device *) malloc (sizeof (*dev));
+		if (dev == NULL) {
+			printf ("ppc_4xx_eth_initialize: "
+				"Cannot allocate eth_device %d\n", eth_num);
+			return (-1);
+		}
+		memset(dev, 0, sizeof(*dev));
+
+		/* Allocate our private use data */
+		hw = (EMAC_4XX_HW_PST) malloc (sizeof (*hw));
+		if (hw == NULL) {
+			printf ("ppc_4xx_eth_initialize: "
+				"Cannot allocate private hw data for eth_device %d",
+				eth_num);
+			free (dev);
+			return (-1);
+		}
+		memset(hw, 0, sizeof(*hw));
+
+		hw->hw_addr = hw_addr[eth_num];
+		memcpy (dev->enetaddr, ethaddr[eth_num], 6);
+		hw->devnum = eth_num;
+		hw->print_speed = 1;
+
+		sprintf (dev->name, "ppc_4xx_eth%d", eth_num - CONFIG_EMAC_NR_START);
+		dev->priv = (void *) hw;
+		dev->init = ppc_4xx_eth_init;
+		dev->halt = ppc_4xx_eth_halt;
+		dev->send = ppc_4xx_eth_send;
+		dev->recv = ppc_4xx_eth_rx;
+
+		eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+		miiphy_register(dev->name,
+				emac4xx_miiphy_read, emac4xx_miiphy_write);
+#endif
+
+		if (0 == virgin) {
+			/* set the MAL IER ??? names may change with new spec ??? */
+#if defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_405EX)
+			mal_ier =
+				MAL_IER_PT | MAL_IER_PRE | MAL_IER_PWE |
+				MAL_IER_DE | MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE ;
+#else
+			mal_ier =
+				MAL_IER_DE | MAL_IER_NE | MAL_IER_TE |
+				MAL_IER_OPBE | MAL_IER_PLBE;
+#endif
+			mtdcr (MAL0_ESR, 0xffffffff);	/* clear pending interrupts */
+			mtdcr (MAL0_TXDEIR, 0xffffffff);	/* clear pending interrupts */
+			mtdcr (MAL0_RXDEIR, 0xffffffff);	/* clear pending interrupts */
+			mtdcr (MAL0_IER, mal_ier);
+
+			/* install MAL interrupt handler */
+			irq_install_handler (VECNUM_MAL_SERR,
+					     (interrupt_handler_t *) enetInt,
+					     dev);
+			irq_install_handler (VECNUM_MAL_TXEOB,
+					     (interrupt_handler_t *) enetInt,
+					     dev);
+			irq_install_handler (VECNUM_MAL_RXEOB,
+					     (interrupt_handler_t *) enetInt,
+					     dev);
+			irq_install_handler (VECNUM_MAL_TXDE,
+					     (interrupt_handler_t *) enetInt,
+					     dev);
+			irq_install_handler (VECNUM_MAL_RXDE,
+					     (interrupt_handler_t *) enetInt,
+					     dev);
+			virgin = 1;
+		}
+	}			/* end for each supported device */
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/8390.h b/marvell/uboot/drivers/net/8390.h
new file mode 100644
index 0000000..f087217
--- /dev/null
+++ b/marvell/uboot/drivers/net/8390.h
@@ -0,0 +1,124 @@
+/*
+
+Ported to U-Boot  by Christian Pellegrin <chri@ascensit.com>
+
+Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
+eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
+are GPL, so this is, of course, GPL.
+
+*/
+
+/* Generic NS8390 register definitions. */
+/* This file is part of Donald Becker's 8390 drivers, and is distributed
+   under the same license. Auto-loading of 8390.o only in v2.2 - Paul G.
+   Some of these names and comments originated from the Crynwr
+   packet drivers, which are distributed under the GPL. */
+
+#ifndef _8390_h
+#define _8390_h
+
+/* Some generic ethernet register configurations. */
+#define E8390_TX_IRQ_MASK	0xa	/* For register EN0_ISR */
+#define E8390_RX_IRQ_MASK	0x5
+#define E8390_RXCONFIG		0x4	/* EN0_RXCR: broadcasts, no multicast,errors */
+#define E8390_RXOFF		0x20	/* EN0_RXCR: Accept no packets */
+#define E8390_TXCONFIG		0x00	/* EN0_TXCR: Normal transmit mode */
+#define E8390_TXOFF		0x02	/* EN0_TXCR: Transmitter off */
+
+/*  Register accessed at EN_CMD, the 8390 base addr.  */
+#define E8390_STOP	0x01	/* Stop and reset the chip */
+#define E8390_START	0x02	/* Start the chip, clear reset */
+#define E8390_TRANS	0x04	/* Transmit a frame */
+#define E8390_RREAD	0x08	/* Remote read */
+#define E8390_RWRITE	0x10	/* Remote write  */
+#define E8390_NODMA	0x20	/* Remote DMA */
+#define E8390_PAGE0	0x00	/* Select page chip registers */
+#define E8390_PAGE1	0x40	/* using the two high-order bits */
+#define E8390_PAGE2	0x80	/* Page 3 is invalid. */
+
+/*
+ *	Only generate indirect loads given a machine that needs them.
+ *      - removed AMIGA_PCMCIA from this list, handled as ISA io now
+ */
+
+#define n2k_inb(port)   (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE)))
+#define n2k_outb(val,port)  (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE)) = val)
+
+#define EI_SHIFT(x)	(x)
+
+#define E8390_CMD	EI_SHIFT(0x00)  /* The command register (for all pages) */
+/* Page 0 register offsets. */
+#define EN0_CLDALO	EI_SHIFT(0x01)	/* Low byte of current local dma addr  RD */
+#define EN0_STARTPG	EI_SHIFT(0x01)	/* Starting page of ring bfr WR */
+#define EN0_CLDAHI	EI_SHIFT(0x02)	/* High byte of current local dma addr  RD */
+#define EN0_STOPPG	EI_SHIFT(0x02)	/* Ending page +1 of ring bfr WR */
+#define EN0_BOUNDARY	EI_SHIFT(0x03)	/* Boundary page of ring bfr RD WR */
+#define EN0_TSR		EI_SHIFT(0x04)	/* Transmit status reg RD */
+#define EN0_TPSR	EI_SHIFT(0x04)	/* Transmit starting page WR */
+#define EN0_NCR		EI_SHIFT(0x05)	/* Number of collision reg RD */
+#define EN0_TCNTLO	EI_SHIFT(0x05)	/* Low  byte of tx byte count WR */
+#define EN0_FIFO	EI_SHIFT(0x06)	/* FIFO RD */
+#define EN0_TCNTHI	EI_SHIFT(0x06)	/* High byte of tx byte count WR */
+#define EN0_ISR		EI_SHIFT(0x07)	/* Interrupt status reg RD WR */
+#define EN0_CRDALO	EI_SHIFT(0x08)	/* low byte of current remote dma address RD */
+#define EN0_RSARLO	EI_SHIFT(0x08)	/* Remote start address reg 0 */
+#define EN0_CRDAHI	EI_SHIFT(0x09)	/* high byte, current remote dma address RD */
+#define EN0_RSARHI	EI_SHIFT(0x09)	/* Remote start address reg 1 */
+#define EN0_RCNTLO	EI_SHIFT(0x0a)	/* Remote byte count reg WR */
+#define EN0_RCNTHI	EI_SHIFT(0x0b)	/* Remote byte count reg WR */
+#define EN0_RSR		EI_SHIFT(0x0c)	/* rx status reg RD */
+#define EN0_RXCR	EI_SHIFT(0x0c)	/* RX configuration reg WR */
+#define EN0_TXCR	EI_SHIFT(0x0d)	/* TX configuration reg WR */
+#define EN0_COUNTER0	EI_SHIFT(0x0d)	/* Rcv alignment error counter RD */
+#define EN0_DCFG	EI_SHIFT(0x0e)	/* Data configuration reg WR */
+#define EN0_COUNTER1	EI_SHIFT(0x0e)	/* Rcv CRC error counter RD */
+#define EN0_IMR		EI_SHIFT(0x0f)	/* Interrupt mask reg WR */
+#define EN0_COUNTER2	EI_SHIFT(0x0f)	/* Rcv missed frame error counter RD */
+
+/* Bits in EN0_ISR - Interrupt status register */
+#define ENISR_RX	0x01	/* Receiver, no error */
+#define ENISR_TX	0x02	/* Transmitter, no error */
+#define ENISR_RX_ERR	0x04	/* Receiver, with error */
+#define ENISR_TX_ERR	0x08	/* Transmitter, with error */
+#define ENISR_OVER	0x10	/* Receiver overwrote the ring */
+#define ENISR_COUNTERS	0x20	/* Counters need emptying */
+#define ENISR_RDC	0x40	/* remote dma complete */
+#define ENISR_RESET	0x80	/* Reset completed */
+#define ENISR_ALL	0x3f	/* Interrupts we will enable */
+
+/* Bits in EN0_DCFG - Data config register */
+#define ENDCFG_WTS	0x01	/* word transfer mode selection */
+#define ENDCFG_BOS	0x02	/* byte order selection */
+#define ENDCFG_AUTO_INIT   0x10        /* Auto-init to remove packets from ring */
+#define ENDCFG_FIFO		0x40	/* 8 bytes */
+
+/* Page 1 register offsets. */
+#define EN1_PHYS   EI_SHIFT(0x01)	/* This board's physical enet addr RD WR */
+#define EN1_PHYS_SHIFT(i)  EI_SHIFT(i+1) /* Get and set mac address */
+#define EN1_CURPAG EI_SHIFT(0x07)	/* Current memory page RD WR */
+#define EN1_MULT   EI_SHIFT(0x08)	/* Multicast filter mask array (8 bytes) RD WR */
+#define EN1_MULT_SHIFT(i)  EI_SHIFT(8+i) /* Get and set multicast filter */
+
+/* Bits in received packet status byte and EN0_RSR*/
+#define ENRSR_RXOK	0x01	/* Received a good packet */
+#define ENRSR_CRC	0x02	/* CRC error */
+#define ENRSR_FAE	0x04	/* frame alignment error */
+#define ENRSR_FO	0x08	/* FIFO overrun */
+#define ENRSR_MPA	0x10	/* missed pkt */
+#define ENRSR_PHY	0x20	/* physical/multicast address */
+#define ENRSR_DIS	0x40	/* receiver disable. set in monitor mode */
+#define ENRSR_DEF	0x80	/* deferring */
+
+/* Transmitted packet status, EN0_TSR. */
+#define ENTSR_PTX 0x01	/* Packet transmitted without error */
+#define ENTSR_ND  0x02	/* The transmit wasn't deferred. */
+#define ENTSR_COL 0x04	/* The transmit collided at least once. */
+#define ENTSR_ABT 0x08  /* The transmit collided 16 times, and was deferred. */
+#define ENTSR_CRS 0x10	/* The carrier sense was lost. */
+#define ENTSR_FU  0x20  /* A "FIFO underrun" occurred during transmit. */
+#define ENTSR_CDH 0x40	/* The collision detect "heartbeat" signal was lost. */
+#define ENTSR_OWC 0x80  /* There was an out-of-window collision. */
+
+#define NIC_RECEIVE_MONITOR_MODE 0x20
+
+#endif /* _8390_h */
diff --git a/marvell/uboot/drivers/net/Makefile b/marvell/uboot/drivers/net/Makefile
new file mode 100644
index 0000000..7f9ce90
--- /dev/null
+++ b/marvell/uboot/drivers/net/Makefile
@@ -0,0 +1,65 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o
+obj-$(CONFIG_ALTERA_TSE) += altera_tse.o
+obj-$(CONFIG_ARMADA100_FEC) += armada100_fec.o
+obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
+obj-$(CONFIG_DRIVER_AX88180) += ax88180.o
+obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
+obj-$(CONFIG_CALXEDA_XGMAC) += calxedaxgmac.o
+obj-$(CONFIG_CS8900) += cs8900.o
+obj-$(CONFIG_TULIP) += dc2114x.o
+obj-$(CONFIG_DESIGNWARE_ETH) += designware.o
+obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o
+obj-$(CONFIG_DNET) += dnet.o
+obj-$(CONFIG_E1000) += e1000.o
+obj-$(CONFIG_E1000_SPI) += e1000_spi.o
+obj-$(CONFIG_EEPRO100) += eepro100.o
+obj-$(CONFIG_ENC28J60) += enc28j60.o
+obj-$(CONFIG_EP93XX) += ep93xx_eth.o
+obj-$(CONFIG_ETHOC) += ethoc.o
+obj-$(CONFIG_FEC_MXC) += fec_mxc.o
+obj-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o
+obj-$(CONFIG_FTGMAC100) += ftgmac100.o
+obj-$(CONFIG_FTMAC110) += ftmac110.o
+obj-$(CONFIG_FTMAC100) += ftmac100.o
+obj-$(CONFIG_GRETH) += greth.o
+obj-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
+obj-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
+obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o
+obj-$(CONFIG_LAN91C96) += lan91c96.o
+obj-$(CONFIG_MACB) += macb.o
+obj-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
+obj-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o
+obj-$(CONFIG_MPC512x_FEC) += mpc512x_fec.o
+obj-$(CONFIG_MVGBE) += mvgbe.o
+obj-$(CONFIG_NATSEMI) += natsemi.o
+obj-$(CONFIG_DRIVER_NE2000) += ne2000.o ne2000_base.o
+obj-$(CONFIG_DRIVER_AX88796L) += ax88796.o ne2000_base.o
+obj-$(CONFIG_NETCONSOLE) += netconsole.o
+obj-$(CONFIG_NS8382X) += ns8382x.o
+obj-$(CONFIG_PCNET) += pcnet.o
+obj-$(CONFIG_PLB2800_ETHER) += plb2800_eth.o
+obj-$(CONFIG_RTL8139) += rtl8139.o
+obj-$(CONFIG_RTL8169) += rtl8169.o
+obj-$(CONFIG_SH_ETHER) += sh_eth.o
+obj-$(CONFIG_SMC91111) += smc91111.o
+obj-$(CONFIG_SMC911X) += smc911x.o
+obj-$(CONFIG_SUNXI_WEMAC) += sunxi_wemac.o
+obj-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o
+obj-$(CONFIG_TSEC_ENET) += tsec.o fsl_mdio.o
+obj-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o
+obj-$(CONFIG_FMAN_ENET) += fsl_mdio.o
+obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
+obj-$(CONFIG_ULI526X) += uli526x.o
+obj-$(CONFIG_VSC7385_ENET) += vsc7385.o
+obj-$(CONFIG_XILINX_AXIEMAC) += xilinx_axi_emac.o
+obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
+obj-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \
+		xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o
+obj-$(CONFIG_ZYNQ_GEM) += zynq_gem.o
diff --git a/marvell/uboot/drivers/net/altera_tse.c b/marvell/uboot/drivers/net/altera_tse.c
new file mode 100644
index 0000000..de517f8
--- /dev/null
+++ b/marvell/uboot/drivers/net/altera_tse.c
@@ -0,0 +1,971 @@
+/*
+ * Altera 10/100/1000 triple speed ethernet mac driver
+ *
+ * Copyright (C) 2008 Altera Corporation.
+ * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <command.h>
+#include <asm/cache.h>
+#include <asm/dma-mapping.h>
+#include <miiphy.h>
+#include "altera_tse.h"
+
+/* sgdma debug - print descriptor */
+static void alt_sgdma_print_desc(volatile struct alt_sgdma_descriptor *desc)
+{
+	debug("SGDMA DEBUG :\n");
+	debug("desc->source : 0x%x \n", (unsigned int)desc->source);
+	debug("desc->destination : 0x%x \n", (unsigned int)desc->destination);
+	debug("desc->next : 0x%x \n", (unsigned int)desc->next);
+	debug("desc->source_pad : 0x%x \n", (unsigned int)desc->source_pad);
+	debug("desc->destination_pad : 0x%x \n",
+	      (unsigned int)desc->destination_pad);
+	debug("desc->next_pad : 0x%x \n", (unsigned int)desc->next_pad);
+	debug("desc->bytes_to_transfer : 0x%x \n",
+	      (unsigned int)desc->bytes_to_transfer);
+	debug("desc->actual_bytes_transferred : 0x%x \n",
+	      (unsigned int)desc->actual_bytes_transferred);
+	debug("desc->descriptor_status : 0x%x \n",
+	      (unsigned int)desc->descriptor_status);
+	debug("desc->descriptor_control : 0x%x \n",
+	      (unsigned int)desc->descriptor_control);
+}
+
+/* This is a generic routine that the SGDMA mode-specific routines
+ * call to populate a descriptor.
+ * arg1	    :pointer to first SGDMA descriptor.
+ * arg2	    :pointer to next  SGDMA descriptor.
+ * arg3	    :Address to where data to be written.
+ * arg4	    :Address from where data to be read.
+ * arg5	    :no of byte to transaction.
+ * arg6	    :variable indicating to generate start of packet or not
+ * arg7	    :read fixed
+ * arg8	    :write fixed
+ * arg9	    :read burst
+ * arg10    :write burst
+ * arg11    :atlantic_channel number
+ */
+static void alt_sgdma_construct_descriptor_burst(
+	volatile struct alt_sgdma_descriptor *desc,
+	volatile struct alt_sgdma_descriptor *next,
+	unsigned int *read_addr,
+	unsigned int *write_addr,
+	unsigned short length_or_eop,
+	int generate_eop,
+	int read_fixed,
+	int write_fixed_or_sop,
+	int read_burst,
+	int write_burst,
+	unsigned char atlantic_channel)
+{
+	/*
+	 * Mark the "next" descriptor as "not" owned by hardware. This prevents
+	 * The SGDMA controller from continuing to process the chain. This is
+	 * done as a single IO write to bypass cache, without flushing
+	 * the entire descriptor, since only the 8-bit descriptor status must
+	 * be flushed.
+	 */
+	if (!next)
+		debug("Next descriptor not defined!!\n");
+
+	next->descriptor_control = (next->descriptor_control &
+		~ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK);
+
+	desc->source = (unsigned int *)((unsigned int)read_addr & 0x1FFFFFFF);
+	desc->destination =
+	    (unsigned int *)((unsigned int)write_addr & 0x1FFFFFFF);
+	desc->next = (unsigned int *)((unsigned int)next & 0x1FFFFFFF);
+	desc->source_pad = 0x0;
+	desc->destination_pad = 0x0;
+	desc->next_pad = 0x0;
+	desc->bytes_to_transfer = length_or_eop;
+	desc->actual_bytes_transferred = 0;
+	desc->descriptor_status = 0x0;
+
+	/* SGDMA burst not currently supported */
+	desc->read_burst = 0;
+	desc->write_burst = 0;
+
+	/*
+	 * Set the descriptor control block as follows:
+	 * - Set "owned by hardware" bit
+	 * - Optionally set "generate EOP" bit
+	 * - Optionally set the "read from fixed address" bit
+	 * - Optionally set the "write to fixed address bit (which serves
+	 *   serves as a "generate SOP" control bit in memory-to-stream mode).
+	 * - Set the 4-bit atlantic channel, if specified
+	 *
+	 * Note this step is performed after all other descriptor information
+	 * has been filled out so that, if the controller already happens to be
+	 * pointing at this descriptor, it will not run (via the "owned by
+	 * hardware" bit) until all other descriptor has been set up.
+	 */
+
+	desc->descriptor_control =
+	    ((ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK) |
+	     (generate_eop ?
+	      ALT_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK : 0x0) |
+	     (read_fixed ?
+	      ALT_SGDMA_DESCRIPTOR_CONTROL_READ_FIXED_ADDRESS_MSK : 0x0) |
+	     (write_fixed_or_sop ?
+	      ALT_SGDMA_DESCRIPTOR_CONTROL_WRITE_FIXED_ADDRESS_MSK : 0x0) |
+	     (atlantic_channel ? ((atlantic_channel & 0x0F) << 3) : 0)
+		    );
+}
+
+static int alt_sgdma_do_sync_transfer(volatile struct alt_sgdma_registers *dev,
+			       volatile struct alt_sgdma_descriptor *desc)
+{
+	unsigned int status;
+	int counter = 0;
+
+	/* Wait for any pending transfers to complete */
+	alt_sgdma_print_desc(desc);
+	status = dev->status;
+
+	counter = 0;
+	while (dev->status & ALT_SGDMA_STATUS_BUSY_MSK) {
+		if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR)
+			break;
+	}
+
+	if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR)
+		debug("Timeout waiting sgdma in do sync!\n");
+
+	/*
+	 * Clear any (previous) status register information
+	 * that might occlude our error checking later.
+	 */
+	dev->status = 0xFF;
+
+	/* Point the controller at the descriptor */
+	dev->next_descriptor_pointer = (unsigned int)desc & 0x1FFFFFFF;
+	debug("next desc in sgdma 0x%x\n",
+	      (unsigned int)dev->next_descriptor_pointer);
+
+	/*
+	 * Set up SGDMA controller to:
+	 * - Disable interrupt generation
+	 * - Run once a valid descriptor is written to controller
+	 * - Stop on an error with any particular descriptor
+	 */
+	dev->control = (ALT_SGDMA_CONTROL_RUN_MSK |
+			ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK);
+
+	/* Wait for the descriptor (chain) to complete */
+	status = dev->status;
+	debug("wait for sgdma....");
+	while (dev->status & ALT_SGDMA_STATUS_BUSY_MSK)
+		;
+	debug("done\n");
+
+	/* Clear Run */
+	dev->control = (dev->control & (~ALT_SGDMA_CONTROL_RUN_MSK));
+
+	/* Get & clear status register contents */
+	status = dev->status;
+	dev->status = 0xFF;
+
+	/* we really should check if the transfer completes properly */
+	debug("tx sgdma status = 0x%x", status);
+	return 0;
+}
+
+static int alt_sgdma_do_async_transfer(volatile struct alt_sgdma_registers *dev,
+				volatile struct alt_sgdma_descriptor *desc)
+{
+	unsigned int status;
+	int counter = 0;
+
+	/* Wait for any pending transfers to complete */
+	alt_sgdma_print_desc(desc);
+	status = dev->status;
+
+	counter = 0;
+	while (dev->status & ALT_SGDMA_STATUS_BUSY_MSK) {
+		if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR)
+			break;
+	}
+
+	if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR)
+		debug("Timeout waiting sgdma in do async!\n");
+
+	/*
+	 * Clear the RUN bit in the control register. This is needed
+	 * to restart the SGDMA engine later on.
+	 */
+	dev->control = 0;
+
+	/*
+	 * Clear any (previous) status register information
+	 * that might occlude our error checking later.
+	 */
+	dev->status = 0xFF;
+
+	/* Point the controller at the descriptor */
+	dev->next_descriptor_pointer = (unsigned int)desc & 0x1FFFFFFF;
+
+	/*
+	 * Set up SGDMA controller to:
+	 * - Disable interrupt generation
+	 * - Run once a valid descriptor is written to controller
+	 * - Stop on an error with any particular descriptor
+	 */
+	dev->control = (ALT_SGDMA_CONTROL_RUN_MSK |
+			ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK);
+
+	/* we really should check if the transfer completes properly */
+	return 0;
+}
+
+/* u-boot interface */
+static int tse_adjust_link(struct altera_tse_priv *priv)
+{
+	unsigned int refvar;
+
+	refvar = priv->mac_dev->command_config.image;
+
+	if (!(priv->duplexity))
+		refvar |= ALTERA_TSE_CMD_HD_ENA_MSK;
+	else
+		refvar &= ~ALTERA_TSE_CMD_HD_ENA_MSK;
+
+	switch (priv->speed) {
+	case 1000:
+		refvar |= ALTERA_TSE_CMD_ETH_SPEED_MSK;
+		refvar &= ~ALTERA_TSE_CMD_ENA_10_MSK;
+		break;
+	case 100:
+		refvar &= ~ALTERA_TSE_CMD_ETH_SPEED_MSK;
+		refvar &= ~ALTERA_TSE_CMD_ENA_10_MSK;
+		break;
+	case 10:
+		refvar &= ~ALTERA_TSE_CMD_ETH_SPEED_MSK;
+		refvar |= ALTERA_TSE_CMD_ENA_10_MSK;
+		break;
+	}
+	priv->mac_dev->command_config.image = refvar;
+
+	return 0;
+}
+
+static int tse_eth_send(struct eth_device *dev, void *packet, int length)
+{
+	struct altera_tse_priv *priv = dev->priv;
+	volatile struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx;
+	volatile struct alt_sgdma_descriptor *tx_desc =
+	    (volatile struct alt_sgdma_descriptor *)priv->tx_desc;
+
+	volatile struct alt_sgdma_descriptor *tx_desc_cur =
+	    (volatile struct alt_sgdma_descriptor *)&tx_desc[0];
+
+	flush_dcache_range((unsigned long)packet,
+			(unsigned long)packet + length);
+	alt_sgdma_construct_descriptor_burst(
+		(volatile struct alt_sgdma_descriptor *)&tx_desc[0],
+		(volatile struct alt_sgdma_descriptor *)&tx_desc[1],
+		(unsigned int *)packet,	/* read addr */
+		(unsigned int *)0,
+		length,	/* length or EOP ,will change for each tx */
+		0x1,	/* gen eop */
+		0x0,	/* read fixed */
+		0x1,	/* write fixed or sop */
+		0x0,	/* read burst */
+		0x0,	/* write burst */
+		0x0	/* channel */
+		);
+	debug("TX Packet @ 0x%x,0x%x bytes", (unsigned int)packet, length);
+
+	/* send the packet */
+	debug("sending packet\n");
+	alt_sgdma_do_sync_transfer(tx_sgdma, tx_desc_cur);
+	debug("sent %d bytes\n", tx_desc_cur->actual_bytes_transferred);
+	return tx_desc_cur->actual_bytes_transferred;
+}
+
+static int tse_eth_rx(struct eth_device *dev)
+{
+	int packet_length = 0;
+	struct altera_tse_priv *priv = dev->priv;
+	volatile struct alt_sgdma_descriptor *rx_desc =
+	    (volatile struct alt_sgdma_descriptor *)priv->rx_desc;
+	volatile struct alt_sgdma_descriptor *rx_desc_cur = &rx_desc[0];
+
+	if (rx_desc_cur->descriptor_status &
+	    ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) {
+		debug("got packet\n");
+		packet_length = rx_desc->actual_bytes_transferred;
+		NetReceive(NetRxPackets[0], packet_length);
+
+		/* start descriptor again */
+		flush_dcache_range((unsigned long)(NetRxPackets[0]),
+			(unsigned long)(NetRxPackets[0]) + PKTSIZE_ALIGN);
+		alt_sgdma_construct_descriptor_burst(
+			(volatile struct alt_sgdma_descriptor *)&rx_desc[0],
+			(volatile struct alt_sgdma_descriptor *)&rx_desc[1],
+			(unsigned int)0x0,	/* read addr */
+			(unsigned int *)NetRxPackets[0],
+			0x0,	/* length or EOP */
+			0x0,	/* gen eop */
+			0x0,	/* read fixed */
+			0x0,	/* write fixed or sop */
+			0x0,	/* read burst */
+			0x0,	/* write burst */
+			0x0	/* channel */
+		    );
+
+		/* setup the sgdma */
+		alt_sgdma_do_async_transfer(priv->sgdma_rx, &rx_desc[0]);
+
+		return packet_length;
+	}
+
+	return -1;
+}
+
+static void tse_eth_halt(struct eth_device *dev)
+{
+	/* don't do anything! */
+	/* this gets called after each uboot  */
+	/* network command.  don't need to reset the thing all of the time */
+}
+
+static void tse_eth_reset(struct eth_device *dev)
+{
+	/* stop sgdmas, disable tse receive */
+	struct altera_tse_priv *priv = dev->priv;
+	volatile struct alt_tse_mac *mac_dev = priv->mac_dev;
+	volatile struct alt_sgdma_registers *rx_sgdma = priv->sgdma_rx;
+	volatile struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx;
+	int counter;
+	volatile struct alt_sgdma_descriptor *rx_desc =
+	    (volatile struct alt_sgdma_descriptor *)&priv->rx_desc[0];
+
+	/* clear rx desc & wait for sgdma to complete */
+	rx_desc->descriptor_control = 0;
+	rx_sgdma->control = 0;
+	counter = 0;
+	while (rx_sgdma->status & ALT_SGDMA_STATUS_BUSY_MSK) {
+		if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR)
+			break;
+	}
+
+	if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) {
+		debug("Timeout waiting for rx sgdma!\n");
+		rx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
+		rx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
+	}
+
+	counter = 0;
+	tx_sgdma->control = 0;
+	while (tx_sgdma->status & ALT_SGDMA_STATUS_BUSY_MSK) {
+		if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR)
+			break;
+	}
+
+	if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) {
+		debug("Timeout waiting for tx sgdma!\n");
+		tx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
+		tx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK;
+	}
+	/* reset the mac */
+	mac_dev->command_config.bits.transmit_enable = 1;
+	mac_dev->command_config.bits.receive_enable = 1;
+	mac_dev->command_config.bits.software_reset = 1;
+
+	counter = 0;
+	while (mac_dev->command_config.bits.software_reset) {
+		if (counter++ > ALT_TSE_SW_RESET_WATCHDOG_CNTR)
+			break;
+	}
+
+	if (counter >= ALT_TSE_SW_RESET_WATCHDOG_CNTR)
+		debug("TSEMAC SW reset bit never cleared!\n");
+}
+
+static int tse_mdio_read(struct altera_tse_priv *priv, unsigned int regnum)
+{
+	volatile struct alt_tse_mac *mac_dev;
+	unsigned int *mdio_regs;
+	unsigned int data;
+	u16 value;
+
+	mac_dev = priv->mac_dev;
+
+	/* set mdio address */
+	mac_dev->mdio_phy1_addr = priv->phyaddr;
+	mdio_regs = (unsigned int *)&mac_dev->mdio_phy1;
+
+	/* get the data */
+	data = mdio_regs[regnum];
+
+	value = data & 0xffff;
+
+	return value;
+}
+
+static int tse_mdio_write(struct altera_tse_priv *priv, unsigned int regnum,
+		   unsigned int value)
+{
+	volatile struct alt_tse_mac *mac_dev;
+	unsigned int *mdio_regs;
+	unsigned int data;
+
+	mac_dev = priv->mac_dev;
+
+	/* set mdio address */
+	mac_dev->mdio_phy1_addr = priv->phyaddr;
+	mdio_regs = (unsigned int *)&mac_dev->mdio_phy1;
+
+	/* get the data */
+	data = (unsigned int)value;
+
+	mdio_regs[regnum] = data;
+
+	return 0;
+}
+
+/* MDIO access to phy */
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) && !defined(BITBANGMII)
+static int altera_tse_miiphy_write(const char *devname, unsigned char addr,
+				   unsigned char reg, unsigned short value)
+{
+	struct eth_device *dev;
+	struct altera_tse_priv *priv;
+	dev = eth_get_dev_by_name(devname);
+	priv = dev->priv;
+
+	tse_mdio_write(priv, (uint) reg, (uint) value);
+
+	return 0;
+}
+
+static int altera_tse_miiphy_read(const char *devname, unsigned char addr,
+				  unsigned char reg, unsigned short *value)
+{
+	struct eth_device *dev;
+	struct altera_tse_priv *priv;
+	volatile struct alt_tse_mac *mac_dev;
+	unsigned int *mdio_regs;
+
+	dev = eth_get_dev_by_name(devname);
+	priv = dev->priv;
+
+	mac_dev = priv->mac_dev;
+	mac_dev->mdio_phy1_addr = (int)addr;
+	mdio_regs = (unsigned int *)&mac_dev->mdio_phy1;
+
+	*value = 0xffff & mdio_regs[reg];
+
+	return 0;
+
+}
+#endif
+
+/*
+ * Also copied from tsec.c
+ */
+/* Parse the status register for link, and then do
+ * auto-negotiation
+ */
+static uint mii_parse_sr(uint mii_reg, struct altera_tse_priv *priv)
+{
+	/*
+	 * Wait if the link is up, and autonegotiation is in progress
+	 * (ie - we're capable and it's not done)
+	 */
+	mii_reg = tse_mdio_read(priv, MIIM_STATUS);
+
+	if (!(mii_reg & MIIM_STATUS_LINK) && (mii_reg & BMSR_ANEGCAPABLE)
+	    && !(mii_reg & BMSR_ANEGCOMPLETE)) {
+		int i = 0;
+
+		puts("Waiting for PHY auto negotiation to complete");
+		while (!(mii_reg & BMSR_ANEGCOMPLETE)) {
+			/*
+			 * Timeout reached ?
+			 */
+			if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
+				puts(" TIMEOUT !\n");
+				priv->link = 0;
+				return 0;
+			}
+
+			if ((i++ % 1000) == 0)
+				putc('.');
+			udelay(1000);	/* 1 ms */
+			mii_reg = tse_mdio_read(priv, MIIM_STATUS);
+		}
+		puts(" done\n");
+		priv->link = 1;
+		udelay(500000);	/* another 500 ms (results in faster booting) */
+	} else {
+		if (mii_reg & MIIM_STATUS_LINK) {
+			debug("Link is up\n");
+			priv->link = 1;
+		} else {
+			debug("Link is down\n");
+			priv->link = 0;
+		}
+	}
+
+	return 0;
+}
+
+/* Parse the 88E1011's status register for speed and duplex
+ * information
+ */
+static uint mii_parse_88E1011_psr(uint mii_reg, struct altera_tse_priv *priv)
+{
+	uint speed;
+
+	mii_reg = tse_mdio_read(priv, MIIM_88E1011_PHY_STATUS);
+
+	if ((mii_reg & MIIM_88E1011_PHYSTAT_LINK) &&
+	    !(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) {
+		int i = 0;
+
+		puts("Waiting for PHY realtime link");
+		while (!(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) {
+			/* Timeout reached ? */
+			if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
+				puts(" TIMEOUT !\n");
+				priv->link = 0;
+				break;
+			}
+
+			if ((i++ == 1000) == 0) {
+				i = 0;
+				puts(".");
+			}
+			udelay(1000);	/* 1 ms */
+			mii_reg = tse_mdio_read(priv, MIIM_88E1011_PHY_STATUS);
+		}
+		puts(" done\n");
+		udelay(500000);	/* another 500 ms (results in faster booting) */
+	} else {
+		if (mii_reg & MIIM_88E1011_PHYSTAT_LINK)
+			priv->link = 1;
+		else
+			priv->link = 0;
+	}
+
+	if (mii_reg & MIIM_88E1011_PHYSTAT_DUPLEX)
+		priv->duplexity = 1;
+	else
+		priv->duplexity = 0;
+
+	speed = (mii_reg & MIIM_88E1011_PHYSTAT_SPEED);
+
+	switch (speed) {
+	case MIIM_88E1011_PHYSTAT_GBIT:
+		priv->speed = 1000;
+		debug("PHY Speed is 1000Mbit\n");
+		break;
+	case MIIM_88E1011_PHYSTAT_100:
+		debug("PHY Speed is 100Mbit\n");
+		priv->speed = 100;
+		break;
+	default:
+		debug("PHY Speed is 10Mbit\n");
+		priv->speed = 10;
+	}
+
+	return 0;
+}
+
+static uint mii_m88e1111s_setmode_sr(uint mii_reg, struct altera_tse_priv *priv)
+{
+	uint mii_data = tse_mdio_read(priv, mii_reg);
+	mii_data &= 0xfff0;
+	if ((priv->flags >= 1) && (priv->flags <= 4))
+		mii_data |= 0xb;
+	else if (priv->flags == 5)
+		mii_data |= 0x4;
+
+	return mii_data;
+}
+
+static uint mii_m88e1111s_setmode_cr(uint mii_reg, struct altera_tse_priv *priv)
+{
+	uint mii_data = tse_mdio_read(priv, mii_reg);
+	mii_data &= ~0x82;
+	if ((priv->flags >= 1) && (priv->flags <= 4))
+		mii_data |= 0x82;
+
+	return mii_data;
+}
+
+/*
+ * Returns which value to write to the control register.
+ * For 10/100, the value is slightly different
+ */
+static uint mii_cr_init(uint mii_reg, struct altera_tse_priv *priv)
+{
+	return MIIM_CONTROL_INIT;
+}
+
+/*
+ * PHY & MDIO code
+ * Need to add SGMII stuff
+ *
+ */
+
+static struct phy_info phy_info_M88E1111S = {
+	0x01410cc,
+	"Marvell 88E1111S",
+	4,
+	(struct phy_cmd[]){	/* config */
+			   /* Reset and configure the PHY */
+			   {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+			   {MIIM_88E1111_PHY_EXT_SR, 0x848f,
+			    &mii_m88e1111s_setmode_sr},
+			   /* Delay RGMII TX and RX */
+			   {MIIM_88E1111_PHY_EXT_CR, 0x0cd2,
+			    &mii_m88e1111s_setmode_cr},
+			   {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
+			   {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
+			   {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+			   {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+			   {miim_end,}
+			   },
+	(struct phy_cmd[]){	/* startup */
+			   /* Status is read once to clear old link state */
+			   {MIIM_STATUS, miim_read, NULL},
+			   /* Auto-negotiate */
+			   {MIIM_STATUS, miim_read, &mii_parse_sr},
+			   /* Read the status */
+			   {MIIM_88E1011_PHY_STATUS, miim_read,
+			    &mii_parse_88E1011_psr},
+			   {miim_end,}
+			   },
+	(struct phy_cmd[]){	/* shutdown */
+			   {miim_end,}
+			   },
+};
+
+/* a generic flavor.  */
+static struct phy_info phy_info_generic = {
+	0,
+	"Unknown/Generic PHY",
+	32,
+	(struct phy_cmd[]){	/* config */
+			   {MII_BMCR, BMCR_RESET, NULL},
+			   {MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART, NULL},
+			   {miim_end,}
+			   },
+	(struct phy_cmd[]){	/* startup */
+			   {MII_BMSR, miim_read, NULL},
+			   {MII_BMSR, miim_read, &mii_parse_sr},
+			   {miim_end,}
+			   },
+	(struct phy_cmd[]){	/* shutdown */
+			   {miim_end,}
+			   }
+};
+
+static struct phy_info *phy_info[] = {
+	&phy_info_M88E1111S,
+	NULL
+};
+
+ /* Grab the identifier of the device's PHY, and search through
+  * all of the known PHYs to see if one matches.	 If so, return
+  * it, if not, return NULL
+  */
+static struct phy_info *get_phy_info(struct eth_device *dev)
+{
+	struct altera_tse_priv *priv = (struct altera_tse_priv *)dev->priv;
+	uint phy_reg, phy_ID;
+	int i;
+	struct phy_info *theInfo = NULL;
+
+	/* Grab the bits from PHYIR1, and put them in the upper half */
+	phy_reg = tse_mdio_read(priv, MIIM_PHYIR1);
+	phy_ID = (phy_reg & 0xffff) << 16;
+
+	/* Grab the bits from PHYIR2, and put them in the lower half */
+	phy_reg = tse_mdio_read(priv, MIIM_PHYIR2);
+	phy_ID |= (phy_reg & 0xffff);
+
+	/* loop through all the known PHY types, and find one that */
+	/* matches the ID we read from the PHY. */
+	for (i = 0; phy_info[i]; i++) {
+		if (phy_info[i]->id == (phy_ID >> phy_info[i]->shift)) {
+			theInfo = phy_info[i];
+			break;
+		}
+	}
+
+	if (theInfo == NULL) {
+		theInfo = &phy_info_generic;
+		debug("%s: No support for PHY id %x; assuming generic\n",
+		      dev->name, phy_ID);
+	} else
+		debug("%s: PHY is %s (%x)\n", dev->name, theInfo->name, phy_ID);
+
+	return theInfo;
+}
+
+/* Execute the given series of commands on the given device's
+ * PHY, running functions as necessary
+ */
+static void phy_run_commands(struct altera_tse_priv *priv, struct phy_cmd *cmd)
+{
+	int i;
+	uint result;
+
+	for (i = 0; cmd->mii_reg != miim_end; i++) {
+		if (cmd->mii_data == miim_read) {
+			result = tse_mdio_read(priv, cmd->mii_reg);
+
+			if (cmd->funct != NULL)
+				(*(cmd->funct)) (result, priv);
+
+		} else {
+			if (cmd->funct != NULL)
+				result = (*(cmd->funct)) (cmd->mii_reg, priv);
+			else
+				result = cmd->mii_data;
+
+			tse_mdio_write(priv, cmd->mii_reg, result);
+
+		}
+		cmd++;
+	}
+}
+
+/* Phy init code */
+static int init_phy(struct eth_device *dev)
+{
+	struct altera_tse_priv *priv = (struct altera_tse_priv *)dev->priv;
+	struct phy_info *curphy;
+
+	/* Get the cmd structure corresponding to the attached
+	 * PHY */
+	curphy = get_phy_info(dev);
+
+	if (curphy == NULL) {
+		priv->phyinfo = NULL;
+		debug("%s: No PHY found\n", dev->name);
+
+		return 0;
+	} else
+		debug("%s found\n", curphy->name);
+	priv->phyinfo = curphy;
+
+	phy_run_commands(priv, priv->phyinfo->config);
+
+	return 1;
+}
+
+static int tse_set_mac_address(struct eth_device *dev)
+{
+	struct altera_tse_priv *priv = dev->priv;
+	volatile struct alt_tse_mac *mac_dev = priv->mac_dev;
+
+	debug("Setting MAC address to 0x%02x%02x%02x%02x%02x%02x\n",
+	      dev->enetaddr[5], dev->enetaddr[4],
+	      dev->enetaddr[3], dev->enetaddr[2],
+	      dev->enetaddr[1], dev->enetaddr[0]);
+	mac_dev->mac_addr_0 = ((dev->enetaddr[3]) << 24 |
+			       (dev->enetaddr[2]) << 16 |
+			       (dev->enetaddr[1]) << 8 | (dev->enetaddr[0]));
+
+	mac_dev->mac_addr_1 = ((dev->enetaddr[5] << 8 |
+				(dev->enetaddr[4])) & 0xFFFF);
+
+	/* Set the MAC address */
+	mac_dev->supp_mac_addr_0_0 = mac_dev->mac_addr_0;
+	mac_dev->supp_mac_addr_0_1 = mac_dev->mac_addr_1;
+
+	/* Set the MAC address */
+	mac_dev->supp_mac_addr_1_0 = mac_dev->mac_addr_0;
+	mac_dev->supp_mac_addr_1_1 = mac_dev->mac_addr_1;
+
+	/* Set the MAC address */
+	mac_dev->supp_mac_addr_2_0 = mac_dev->mac_addr_0;
+	mac_dev->supp_mac_addr_2_1 = mac_dev->mac_addr_1;
+
+	/* Set the MAC address */
+	mac_dev->supp_mac_addr_3_0 = mac_dev->mac_addr_0;
+	mac_dev->supp_mac_addr_3_1 = mac_dev->mac_addr_1;
+	return 0;
+}
+
+static int tse_eth_init(struct eth_device *dev, bd_t * bd)
+{
+	int dat;
+	struct altera_tse_priv *priv = dev->priv;
+	volatile struct alt_tse_mac *mac_dev = priv->mac_dev;
+	volatile struct alt_sgdma_descriptor *tx_desc = priv->tx_desc;
+	volatile struct alt_sgdma_descriptor *rx_desc = priv->rx_desc;
+	volatile struct alt_sgdma_descriptor *rx_desc_cur =
+	    (volatile struct alt_sgdma_descriptor *)&rx_desc[0];
+
+	/* stop controller */
+	debug("Reseting TSE & SGDMAs\n");
+	tse_eth_reset(dev);
+
+	/* start the phy */
+	debug("Configuring PHY\n");
+	phy_run_commands(priv, priv->phyinfo->startup);
+
+	/* need to create sgdma */
+	debug("Configuring tx desc\n");
+	alt_sgdma_construct_descriptor_burst(
+		(volatile struct alt_sgdma_descriptor *)&tx_desc[0],
+		(volatile struct alt_sgdma_descriptor *)&tx_desc[1],
+		(unsigned int *)NULL,	/* read addr */
+		(unsigned int *)0,
+		0,	/* length or EOP ,will change for each tx */
+		0x1,	/* gen eop */
+		0x0,	/* read fixed */
+		0x1,	/* write fixed or sop */
+		0x0,	/* read burst */
+		0x0,	/* write burst */
+		0x0	/* channel */
+		);
+	debug("Configuring rx desc\n");
+	flush_dcache_range((unsigned long)(NetRxPackets[0]),
+			(unsigned long)(NetRxPackets[0]) + PKTSIZE_ALIGN);
+	alt_sgdma_construct_descriptor_burst(
+		(volatile struct alt_sgdma_descriptor *)&rx_desc[0],
+		(volatile struct alt_sgdma_descriptor *)&rx_desc[1],
+		(unsigned int)0x0,	/* read addr */
+		(unsigned int *)NetRxPackets[0],
+		0x0,	/* length or EOP */
+		0x0,	/* gen eop */
+		0x0,	/* read fixed */
+		0x0,	/* write fixed or sop */
+		0x0,	/* read burst */
+		0x0,	/* write burst */
+		0x0	/* channel */
+		);
+	/* start rx async transfer */
+	debug("Starting rx sgdma\n");
+	alt_sgdma_do_async_transfer(priv->sgdma_rx, rx_desc_cur);
+
+	/* start TSE */
+	debug("Configuring TSE Mac\n");
+	/* Initialize MAC registers */
+	mac_dev->max_frame_length = PKTSIZE_ALIGN;
+	mac_dev->rx_almost_empty_threshold = 8;
+	mac_dev->rx_almost_full_threshold = 8;
+	mac_dev->tx_almost_empty_threshold = 8;
+	mac_dev->tx_almost_full_threshold = 3;
+	mac_dev->tx_sel_empty_threshold =
+	    CONFIG_SYS_ALTERA_TSE_TX_FIFO - 16;
+	mac_dev->tx_sel_full_threshold = 0;
+	mac_dev->rx_sel_empty_threshold =
+	    CONFIG_SYS_ALTERA_TSE_TX_FIFO - 16;
+	mac_dev->rx_sel_full_threshold = 0;
+
+	/* NO Shift */
+	mac_dev->rx_cmd_stat.bits.rx_shift16 = 0;
+	mac_dev->tx_cmd_stat.bits.tx_shift16 = 0;
+
+	/* enable MAC */
+	dat = 0;
+	dat = ALTERA_TSE_CMD_TX_ENA_MSK | ALTERA_TSE_CMD_RX_ENA_MSK;
+
+	mac_dev->command_config.image = dat;
+
+	/* configure the TSE core  */
+	/*  -- output clocks,  */
+	/*  -- and later config stuff for SGMII */
+	if (priv->link) {
+		debug("Adjusting TSE to link speed\n");
+		tse_adjust_link(priv);
+	}
+
+	return priv->link ? 0 : -1;
+}
+
+/* TSE init code */
+int altera_tse_initialize(u8 dev_num, int mac_base,
+			  int sgdma_rx_base, int sgdma_tx_base,
+			  u32 sgdma_desc_base, u32 sgdma_desc_size)
+{
+	struct altera_tse_priv *priv;
+	struct eth_device *dev;
+	struct alt_sgdma_descriptor *rx_desc;
+	struct alt_sgdma_descriptor *tx_desc;
+	unsigned long dma_handle;
+
+	dev = (struct eth_device *)malloc(sizeof *dev);
+
+	if (NULL == dev)
+		return 0;
+
+	memset(dev, 0, sizeof *dev);
+
+	priv = malloc(sizeof(*priv));
+
+	if (!priv) {
+		free(dev);
+		return 0;
+	}
+	if (sgdma_desc_size) {
+		if (sgdma_desc_size < (sizeof(*tx_desc) * (3 + PKTBUFSRX))) {
+			printf("ALTERA_TSE-%hu: "
+			       "descriptor memory is too small\n", dev_num);
+			free(priv);
+			free(dev);
+			return 0;
+		}
+		tx_desc = (struct alt_sgdma_descriptor *)sgdma_desc_base;
+	} else {
+		tx_desc = dma_alloc_coherent(sizeof(*tx_desc) * (3 + PKTBUFSRX),
+					     &dma_handle);
+	}
+
+	rx_desc = tx_desc + 2;
+	debug("tx desc: address = 0x%x\n", (unsigned int)tx_desc);
+	debug("rx desc: address = 0x%x\n", (unsigned int)rx_desc);
+
+	if (!tx_desc) {
+		free(priv);
+		free(dev);
+		return 0;
+	}
+	memset(rx_desc, 0, (sizeof *rx_desc) * (PKTBUFSRX + 1));
+	memset(tx_desc, 0, (sizeof *tx_desc) * 2);
+
+	/* initialize tse priv */
+	priv->mac_dev = (volatile struct alt_tse_mac *)mac_base;
+	priv->sgdma_rx = (volatile struct alt_sgdma_registers *)sgdma_rx_base;
+	priv->sgdma_tx = (volatile struct alt_sgdma_registers *)sgdma_tx_base;
+	priv->phyaddr = CONFIG_SYS_ALTERA_TSE_PHY_ADDR;
+	priv->flags = CONFIG_SYS_ALTERA_TSE_FLAGS;
+	priv->rx_desc = rx_desc;
+	priv->tx_desc = tx_desc;
+
+	/* init eth structure */
+	dev->priv = priv;
+	dev->init = tse_eth_init;
+	dev->halt = tse_eth_halt;
+	dev->send = tse_eth_send;
+	dev->recv = tse_eth_rx;
+	dev->write_hwaddr = tse_set_mac_address;
+	sprintf(dev->name, "%s-%hu", "ALTERA_TSE", dev_num);
+
+	eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) && !defined(BITBANGMII)
+	miiphy_register(dev->name, altera_tse_miiphy_read,
+			altera_tse_miiphy_write);
+#endif
+
+	init_phy(dev);
+
+	return 1;
+}
diff --git a/marvell/uboot/drivers/net/altera_tse.h b/marvell/uboot/drivers/net/altera_tse.h
new file mode 100644
index 0000000..8880bfc
--- /dev/null
+++ b/marvell/uboot/drivers/net/altera_tse.h
@@ -0,0 +1,492 @@
+/*
+ * Altera 10/100/1000 triple speed ethernet mac
+ *
+ * Copyright (C) 2008 Altera Corporation.
+ * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _ALTERA_TSE_H_
+#define _ALTERA_TSE_H_
+
+#define __packed_1_    __attribute__ ((packed, aligned(1)))
+
+/* PHY Stuff */
+#define miim_end -2
+#define miim_read -1
+
+#define PHY_AUTONEGOTIATE_TIMEOUT	5000	/* in ms */
+
+#ifndef CONFIG_SYS_TBIPA_VALUE
+#define CONFIG_SYS_TBIPA_VALUE	0x1f
+#endif
+#define MIIMCFG_INIT_VALUE	0x00000003
+#define MIIMCFG_RESET		0x80000000
+
+#define MIIMIND_BUSY		0x00000001
+#define MIIMIND_NOTVALID	0x00000004
+
+#define MIIM_CONTROL		0x00
+#define MIIM_CONTROL_RESET	0x00009140
+#define MIIM_CONTROL_INIT	0x00001140
+#define MIIM_CONTROL_RESTART	0x00001340
+#define MIIM_ANEN		0x00001000
+
+#define MIIM_CR		0x00
+#define MIIM_CR_RST		0x00008000
+#define MIIM_CR_INIT		0x00001000
+
+#define MIIM_STATUS		0x1
+#define MIIM_STATUS_AN_DONE	0x00000020
+#define MIIM_STATUS_LINK	0x0004
+
+#define MIIM_PHYIR1		0x2
+#define MIIM_PHYIR2		0x3
+
+#define MIIM_ANAR		0x4
+#define MIIM_ANAR_INIT		0x1e1
+
+#define MIIM_TBI_ANLPBPA	0x5
+#define MIIM_TBI_ANLPBPA_HALF	0x00000040
+#define MIIM_TBI_ANLPBPA_FULL	0x00000020
+
+#define MIIM_TBI_ANEX		0x6
+#define MIIM_TBI_ANEX_NP	0x00000004
+#define MIIM_TBI_ANEX_PRX	0x00000002
+
+#define MIIM_GBIT_CONTROL	0x9
+#define MIIM_GBIT_CONTROL_INIT	0xe00
+
+#define MIIM_EXT_PAGE_ACCESS	0x1f
+
+/* 88E1011 PHY Status Register */
+#define MIIM_88E1011_PHY_STATUS	0x11
+#define MIIM_88E1011_PHYSTAT_SPEED	0xc000
+#define MIIM_88E1011_PHYSTAT_GBIT	0x8000
+#define MIIM_88E1011_PHYSTAT_100	0x4000
+#define MIIM_88E1011_PHYSTAT_DUPLEX	0x2000
+#define MIIM_88E1011_PHYSTAT_SPDDONE	0x0800
+#define MIIM_88E1011_PHYSTAT_LINK	0x0400
+
+#define MIIM_88E1011_PHY_SCR		0x10
+#define MIIM_88E1011_PHY_MDI_X_AUTO	0x0060
+
+#define MIIM_88E1111_PHY_EXT_CR	0x14
+#define MIIM_88E1111_PHY_EXT_SR	0x1b
+
+/* 88E1111 PHY LED Control Register */
+#define MIIM_88E1111_PHY_LED_CONTROL	24
+#define MIIM_88E1111_PHY_LED_DIRECT	0x4100
+#define MIIM_88E1111_PHY_LED_COMBINE	0x411C
+
+#define MIIM_READ_COMMAND	0x00000001
+
+/* struct phy_info: a structure which defines attributes for a PHY
+ * id will contain a number which represents the PHY.  During
+ * startup, the driver will poll the PHY to find out what its
+ * UID--as defined by registers 2 and 3--is.  The 32-bit result
+ * gotten from the PHY will be shifted right by "shift" bits to
+ * discard any bits which may change based on revision numbers
+ * unimportant to functionality
+ *
+ * The struct phy_cmd entries represent pointers to an arrays of
+ * commands which tell the driver what to do to the PHY.
+ */
+struct phy_info {
+	uint id;
+	char *name;
+	uint shift;
+	/* Called to configure the PHY, and modify the controller
+	 * based on the results */
+	struct phy_cmd *config;
+
+	/* Called when starting up the controller */
+	struct phy_cmd *startup;
+
+	/* Called when bringing down the controller */
+	struct phy_cmd *shutdown;
+};
+
+/* SGDMA Stuff */
+#define ALT_SGDMA_STATUS_ERROR_MSK			(0x00000001)
+#define ALT_SGDMA_STATUS_EOP_ENCOUNTERED_MSK		(0x00000002)
+#define ALT_SGDMA_STATUS_DESC_COMPLETED_MSK		(0x00000004)
+#define ALT_SGDMA_STATUS_CHAIN_COMPLETED_MSK		(0x00000008)
+#define ALT_SGDMA_STATUS_BUSY_MSK			(0x00000010)
+
+#define ALT_SGDMA_CONTROL_IE_ERROR_MSK			(0x00000001)
+#define ALT_SGDMA_CONTROL_IE_EOP_ENCOUNTERED_MSK	(0x00000002)
+#define ALT_SGDMA_CONTROL_IE_DESC_COMPLETED_MSK	(0x00000004)
+#define ALT_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK	(0x00000008)
+#define ALT_SGDMA_CONTROL_IE_GLOBAL_MSK		(0x00000010)
+#define ALT_SGDMA_CONTROL_RUN_MSK			(0x00000020)
+#define ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK		(0x00000040)
+#define ALT_SGDMA_CONTROL_IE_MAX_DESC_PROCESSED_MSK	(0x00000080)
+#define ALT_SGDMA_CONTROL_MAX_DESC_PROCESSED_MSK	(0x0000FF00)
+#define ALT_SGDMA_CONTROL_SOFTWARERESET_MSK		(0x00010000)
+#define ALT_SGDMA_CONTROL_PARK_MSK			(0x00020000)
+#define ALT_SGDMA_CONTROL_CLEAR_INTERRUPT_MSK		(0x80000000)
+
+#define ALTERA_TSE_SGDMA_INTR_MASK  (ALT_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK \
+			| ALT_SGDMA_STATUS_DESC_COMPLETED_MSK \
+			| ALT_SGDMA_CONTROL_IE_GLOBAL_MSK)
+
+/*
+ * Descriptor control bit masks & offsets
+ *
+ * Note: The control byte physically occupies bits [31:24] in memory.
+ *	 The following bit-offsets are expressed relative to the LSB of
+ *	 the control register bitfield.
+ */
+#define ALT_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK		(0x00000001)
+#define ALT_SGDMA_DESCRIPTOR_CONTROL_READ_FIXED_ADDRESS_MSK	(0x00000002)
+#define ALT_SGDMA_DESCRIPTOR_CONTROL_WRITE_FIXED_ADDRESS_MSK	(0x00000004)
+#define ALT_SGDMA_DESCRIPTOR_CONTROL_ATLANTIC_CHANNEL_MSK	(0x00000008)
+#define ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK		(0x00000080)
+
+/*
+ * Descriptor status bit masks & offsets
+ *
+ * Note: The status byte physically occupies bits [23:16] in memory.
+ *	 The following bit-offsets are expressed relative to the LSB of
+ *	 the status register bitfield.
+ */
+#define ALT_SGDMA_DESCRIPTOR_STATUS_E_CRC_MSK			(0x00000001)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_E_PARITY_MSK		(0x00000002)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_E_OVERFLOW_MSK		(0x00000004)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_E_SYNC_MSK			(0x00000008)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_E_UEOP_MSK			(0x00000010)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_E_MEOP_MSK			(0x00000020)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_E_MSOP_MSK			(0x00000040)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK	(0x00000080)
+#define ALT_SGDMA_DESCRIPTOR_STATUS_ERROR_MSK			(0x0000007F)
+
+/*
+ * The SGDMA controller buffer descriptor allocates
+ * 64 bits for each address. To support ANSI C, the
+ * struct implementing a descriptor places 32-bits
+ * of padding directly above each address; each pad must
+ * be cleared when initializing a descriptor.
+ */
+
+/*
+ * Buffer Descriptor data structure
+ *
+ */
+struct alt_sgdma_descriptor {
+	unsigned int *source;	/* the address of data to be read. */
+	unsigned int source_pad;
+
+	unsigned int *destination;	/* the address to write data */
+	unsigned int destination_pad;
+
+	unsigned int *next;	/* the next descriptor in the list. */
+	unsigned int next_pad;
+
+	unsigned short bytes_to_transfer; /* the number of bytes to transfer */
+	unsigned char read_burst;
+	unsigned char write_burst;
+
+	unsigned short actual_bytes_transferred;/* bytes transferred by DMA */
+	unsigned char descriptor_status;
+	unsigned char descriptor_control;
+
+} __packed_1_;
+
+/* SG-DMA Control/Status Slave registers map */
+
+struct alt_sgdma_registers {
+	unsigned int status;
+	unsigned int status_pad[3];
+	unsigned int control;
+	unsigned int control_pad[3];
+	unsigned int next_descriptor_pointer;
+	unsigned int descriptor_pad[3];
+};
+
+/* TSE Stuff */
+#define ALTERA_TSE_CMD_TX_ENA_MSK		(0x00000001)
+#define ALTERA_TSE_CMD_RX_ENA_MSK		(0x00000002)
+#define ALTERA_TSE_CMD_XON_GEN_MSK		(0x00000004)
+#define ALTERA_TSE_CMD_ETH_SPEED_MSK		(0x00000008)
+#define ALTERA_TSE_CMD_PROMIS_EN_MSK		(0x00000010)
+#define ALTERA_TSE_CMD_PAD_EN_MSK		(0x00000020)
+#define ALTERA_TSE_CMD_CRC_FWD_MSK		(0x00000040)
+#define ALTERA_TSE_CMD_PAUSE_FWD_MSK		(0x00000080)
+#define ALTERA_TSE_CMD_PAUSE_IGNORE_MSK	(0x00000100)
+#define ALTERA_TSE_CMD_TX_ADDR_INS_MSK		(0x00000200)
+#define ALTERA_TSE_CMD_HD_ENA_MSK		(0x00000400)
+#define ALTERA_TSE_CMD_EXCESS_COL_MSK		(0x00000800)
+#define ALTERA_TSE_CMD_LATE_COL_MSK		(0x00001000)
+#define ALTERA_TSE_CMD_SW_RESET_MSK		(0x00002000)
+#define ALTERA_TSE_CMD_MHASH_SEL_MSK		(0x00004000)
+#define ALTERA_TSE_CMD_LOOPBACK_MSK		(0x00008000)
+/* Bits (18:16) = address select */
+#define ALTERA_TSE_CMD_TX_ADDR_SEL_MSK		(0x00070000)
+#define ALTERA_TSE_CMD_MAGIC_ENA_MSK		(0x00080000)
+#define ALTERA_TSE_CMD_SLEEP_MSK		(0x00100000)
+#define ALTERA_TSE_CMD_WAKEUP_MSK		(0x00200000)
+#define ALTERA_TSE_CMD_XOFF_GEN_MSK		(0x00400000)
+#define ALTERA_TSE_CMD_CNTL_FRM_ENA_MSK	(0x00800000)
+#define ALTERA_TSE_CMD_NO_LENGTH_CHECK_MSK	(0x01000000)
+#define ALTERA_TSE_CMD_ENA_10_MSK		(0x02000000)
+#define ALTERA_TSE_CMD_RX_ERR_DISC_MSK		(0x04000000)
+/* Bits (30..27) reserved */
+#define ALTERA_TSE_CMD_CNT_RESET_MSK		(0x80000000)
+
+#define ALTERA_TSE_TX_CMD_STAT_TX_SHIFT16	(0x00040000)
+#define ALTERA_TSE_TX_CMD_STAT_OMIT_CRC	(0x00020000)
+
+#define ALTERA_TSE_RX_CMD_STAT_RX_SHIFT16	(0x02000000)
+
+#define ALT_TSE_SW_RESET_WATCHDOG_CNTR		10000
+#define ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR	90000000
+
+/* Command_Config Register Bit Definitions */
+
+typedef volatile union __alt_tse_command_config {
+	unsigned int image;
+	struct {
+		unsigned int
+		 transmit_enable:1,		/* bit 0 */
+		 receive_enable:1,		/* bit 1 */
+		 pause_frame_xon_gen:1,	/* bit 2 */
+		 ethernet_speed:1,		/* bit 3 */
+		 promiscuous_enable:1,		/* bit 4 */
+		 pad_enable:1,			/* bit 5 */
+		 crc_forward:1,		/* bit 6 */
+		 pause_frame_forward:1,	/* bit 7 */
+		 pause_frame_ignore:1,		/* bit 8 */
+		 set_mac_address_on_tx:1,	/* bit 9 */
+		 halfduplex_enable:1,		/* bit 10 */
+		 excessive_collision:1,	/* bit 11 */
+		 late_collision:1,		/* bit 12 */
+		 software_reset:1,		/* bit 13 */
+		 multicast_hash_mode_sel:1,	/* bit 14 */
+		 loopback_enable:1,		/* bit 15 */
+		 src_mac_addr_sel_on_tx:3,	/* bit 18:16 */
+		 magic_packet_detect:1,	/* bit 19 */
+		 sleep_mode_enable:1,		/* bit 20 */
+		 wake_up_request:1,		/* bit 21 */
+		 pause_frame_xoff_gen:1,	/* bit 22 */
+		 control_frame_enable:1,	/* bit 23 */
+		 payload_len_chk_disable:1,	/* bit 24 */
+		 enable_10mbps_intf:1,		/* bit 25 */
+		 rx_error_discard_enable:1,	/* bit 26 */
+		 reserved_bits:4,		/* bit 30:27 */
+		 self_clear_counter_reset:1;	/* bit 31 */
+	} __packed_1_ bits;
+} __packed_1_ alt_tse_command_config;
+
+/* Tx_Cmd_Stat Register Bit Definitions */
+
+typedef volatile union __alt_tse_tx_cmd_stat {
+	unsigned int image;
+	struct {
+		unsigned int reserved_lsbs:17,	/* bit 16:0  */
+		 omit_crc:1,			/* bit 17 */
+		 tx_shift16:1,			/* bit 18 */
+		 reserved_msbs:13;		/* bit 31:19 */
+
+	} __packed_1_ bits;
+} alt_tse_tx_cmd_stat;
+
+/* Rx_Cmd_Stat Register Bit Definitions */
+
+typedef volatile union __alt_tse_rx_cmd_stat {
+	unsigned int image;
+	struct {
+		unsigned int reserved_lsbs:25,	/* bit 24:0  */
+		 rx_shift16:1,			/* bit 25 */
+		 reserved_msbs:6;		/* bit 31:26 */
+
+	} __packed_1_ bits;
+} alt_tse_rx_cmd_stat;
+
+struct alt_tse_mdio {
+	unsigned int control;	/*PHY device operation control register */
+	unsigned int status;	/*PHY device operation status register */
+	unsigned int phy_id1;	/*Bits 31:16 of PHY identifier. */
+	unsigned int phy_id2;	/*Bits 15:0 of PHY identifier. */
+	unsigned int auto_negotiation_advertisement;
+	unsigned int remote_partner_base_page_ability;
+
+	unsigned int reg6;
+	unsigned int reg7;
+	unsigned int reg8;
+	unsigned int reg9;
+	unsigned int rega;
+	unsigned int regb;
+	unsigned int regc;
+	unsigned int regd;
+	unsigned int rege;
+	unsigned int regf;
+	unsigned int reg10;
+	unsigned int reg11;
+	unsigned int reg12;
+	unsigned int reg13;
+	unsigned int reg14;
+	unsigned int reg15;
+	unsigned int reg16;
+	unsigned int reg17;
+	unsigned int reg18;
+	unsigned int reg19;
+	unsigned int reg1a;
+	unsigned int reg1b;
+	unsigned int reg1c;
+	unsigned int reg1d;
+	unsigned int reg1e;
+	unsigned int reg1f;
+};
+
+/* MAC register Space */
+
+struct alt_tse_mac {
+	unsigned int megacore_revision;
+	unsigned int scratch_pad;
+	alt_tse_command_config command_config;
+	unsigned int mac_addr_0;
+	unsigned int mac_addr_1;
+	unsigned int max_frame_length;
+	unsigned int pause_quanta;
+	unsigned int rx_sel_empty_threshold;
+	unsigned int rx_sel_full_threshold;
+	unsigned int tx_sel_empty_threshold;
+	unsigned int tx_sel_full_threshold;
+	unsigned int rx_almost_empty_threshold;
+	unsigned int rx_almost_full_threshold;
+	unsigned int tx_almost_empty_threshold;
+	unsigned int tx_almost_full_threshold;
+	unsigned int mdio_phy0_addr;
+	unsigned int mdio_phy1_addr;
+
+	/* only if 100/1000 BaseX PCS, reserved otherwise */
+	unsigned int reservedx44[5];
+
+	unsigned int reg_read_access_status;
+	unsigned int min_tx_ipg_length;
+
+	/* IEEE 802.3 oEntity Managed Object Support */
+	unsigned int aMACID_1;	/*The MAC addresses */
+	unsigned int aMACID_2;
+	unsigned int aFramesTransmittedOK;
+	unsigned int aFramesReceivedOK;
+	unsigned int aFramesCheckSequenceErrors;
+	unsigned int aAlignmentErrors;
+	unsigned int aOctetsTransmittedOK;
+	unsigned int aOctetsReceivedOK;
+
+	/* IEEE 802.3 oPausedEntity Managed Object Support */
+	unsigned int aTxPAUSEMACCtrlFrames;
+	unsigned int aRxPAUSEMACCtrlFrames;
+
+	/* IETF MIB (MIB-II) Object Support */
+	unsigned int ifInErrors;
+	unsigned int ifOutErrors;
+	unsigned int ifInUcastPkts;
+	unsigned int ifInMulticastPkts;
+	unsigned int ifInBroadcastPkts;
+	unsigned int ifOutDiscards;
+	unsigned int ifOutUcastPkts;
+	unsigned int ifOutMulticastPkts;
+	unsigned int ifOutBroadcastPkts;
+
+	/* IETF RMON MIB Object Support */
+	unsigned int etherStatsDropEvent;
+	unsigned int etherStatsOctets;
+	unsigned int etherStatsPkts;
+	unsigned int etherStatsUndersizePkts;
+	unsigned int etherStatsOversizePkts;
+	unsigned int etherStatsPkts64Octets;
+	unsigned int etherStatsPkts65to127Octets;
+	unsigned int etherStatsPkts128to255Octets;
+	unsigned int etherStatsPkts256to511Octets;
+	unsigned int etherStatsPkts512to1023Octets;
+	unsigned int etherStatsPkts1024to1518Octets;
+
+	unsigned int etherStatsPkts1519toXOctets;
+	unsigned int etherStatsJabbers;
+	unsigned int etherStatsFragments;
+
+	unsigned int reservedxE4;
+
+	/*FIFO control register. */
+	alt_tse_tx_cmd_stat tx_cmd_stat;
+	alt_tse_rx_cmd_stat rx_cmd_stat;
+
+	unsigned int ipaccTxConf;
+	unsigned int ipaccRxConf;
+	unsigned int ipaccRxStat;
+	unsigned int ipaccRxStatSum;
+
+	/*Multicast address resolution table */
+	unsigned int hash_table[64];
+
+	/*Registers 0 to 31 within PHY device 0/1 */
+	struct alt_tse_mdio mdio_phy0;
+	struct alt_tse_mdio mdio_phy1;
+
+	/*4 Supplemental MAC Addresses */
+	unsigned int supp_mac_addr_0_0;
+	unsigned int supp_mac_addr_0_1;
+	unsigned int supp_mac_addr_1_0;
+	unsigned int supp_mac_addr_1_1;
+	unsigned int supp_mac_addr_2_0;
+	unsigned int supp_mac_addr_2_1;
+	unsigned int supp_mac_addr_3_0;
+	unsigned int supp_mac_addr_3_1;
+
+	unsigned int reservedx320[56];
+};
+
+/* flags: TSE MII modes */
+/* GMII/MII	= 0 */
+/* RGMII	= 1 */
+/* RGMII_ID	= 2 */
+/* RGMII_TXID	= 3 */
+/* RGMII_RXID	= 4 */
+/* SGMII	= 5 */
+struct altera_tse_priv {
+	char devname[16];
+	volatile struct alt_tse_mac *mac_dev;
+	volatile struct alt_sgdma_registers *sgdma_rx;
+	volatile struct alt_sgdma_registers *sgdma_tx;
+	unsigned int rx_sgdma_irq;
+	unsigned int tx_sgdma_irq;
+	unsigned int has_descriptor_mem;
+	unsigned int descriptor_mem_base;
+	unsigned int descriptor_mem_size;
+	volatile struct alt_sgdma_descriptor *rx_desc;
+	volatile struct alt_sgdma_descriptor *tx_desc;
+	volatile unsigned char *rx_buf;
+	struct phy_info *phyinfo;
+	unsigned int phyaddr;
+	unsigned int flags;
+	unsigned int link;
+	unsigned int duplexity;
+	unsigned int speed;
+};
+
+/* Phy stuff continued */
+/*
+ * struct phy_cmd:  A command for reading or writing a PHY register
+ *
+ * mii_reg:  The register to read or write
+ *
+ * mii_data:  For writes, the value to put in the register.
+ *	A value of -1 indicates this is a read.
+ *
+ * funct: A function pointer which is invoked for each command.
+ *	For reads, this function will be passed the value read
+ *	from the PHY, and process it.
+ *	For writes, the result of this function will be written
+ *	to the PHY register
+ */
+struct phy_cmd {
+	uint mii_reg;
+	uint mii_data;
+	uint(*funct) (uint mii_reg, struct altera_tse_priv *priv);
+};
+#endif /* _ALTERA_TSE_H_ */
diff --git a/marvell/uboot/drivers/net/armada100_fec.c b/marvell/uboot/drivers/net/armada100_fec.c
new file mode 100644
index 0000000..a8da6b1
--- /dev/null
+++ b/marvell/uboot/drivers/net/armada100_fec.c
@@ -0,0 +1,726 @@
+/*
+ * (C) Copyright 2011
+ * eInfochips Ltd. <www.einfochips.com>
+ * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
+ *
+ * (C) Copyright 2010
+ * Marvell Semiconductor <www.marvell.com>
+ * Contributor: Mahavir Jain <mjain@marvell.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <net.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <netdev.h>
+#include <asm/types.h>
+#include <asm/byteorder.h>
+#include <linux/err.h>
+#include <linux/mii.h>
+#include <asm/io.h>
+#include <asm/arch/armada100.h>
+#include "armada100_fec.h"
+
+#define  PHY_ADR_REQ     0xFF	/* Magic number to read/write PHY address */
+
+#ifdef DEBUG
+static int eth_dump_regs(struct eth_device *dev)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	unsigned int i = 0;
+
+	printf("\noffset: phy_adr, value: 0x%x\n", readl(&regs->phyadr));
+	printf("offset: smi, value: 0x%x\n", readl(&regs->smi));
+	for (i = 0x400; i <= 0x4e4; i += 4)
+		printf("offset: 0x%x, value: 0x%x\n",
+			i, readl(ARMD1_FEC_BASE + i));
+	return 0;
+}
+#endif
+
+static int armdfec_phy_timeout(u32 *reg, u32 flag, int cond)
+{
+	u32 timeout = PHY_WAIT_ITERATIONS;
+	u32 reg_val;
+
+	while (--timeout) {
+		reg_val = readl(reg);
+		if (cond && (reg_val & flag))
+			break;
+		else if (!cond && !(reg_val & flag))
+			break;
+		udelay(PHY_WAIT_MICRO_SECONDS);
+	}
+	return !timeout;
+}
+
+static int smi_reg_read(const char *devname, u8 phy_addr, u8 phy_reg,
+			u16 *value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	u32 val;
+
+	if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) {
+		val = readl(&regs->phyadr);
+		*value = val & 0x1f;
+		return 0;
+	}
+
+	/* check parameters */
+	if (phy_addr > PHY_MASK) {
+		printf("ARMD100 FEC: (%s) Invalid phy address: 0x%X\n",
+				__func__, phy_addr);
+		return -EINVAL;
+	}
+	if (phy_reg > PHY_MASK) {
+		printf("ARMD100 FEC: (%s) Invalid register offset: 0x%X\n",
+				__func__, phy_reg);
+		return -EINVAL;
+	}
+
+	/* wait for the SMI register to become available */
+	if (armdfec_phy_timeout(&regs->smi, SMI_BUSY, false)) {
+		printf("ARMD100 FEC: (%s) PHY busy timeout\n",	__func__);
+		return -1;
+	}
+
+	writel((phy_addr << 16) | (phy_reg << 21) | SMI_OP_R, &regs->smi);
+
+	/* now wait for the data to be valid */
+	if (armdfec_phy_timeout(&regs->smi, SMI_R_VALID, true)) {
+		val = readl(&regs->smi);
+		printf("ARMD100 FEC: (%s) PHY Read timeout, val=0x%x\n",
+				__func__, val);
+		return -1;
+	}
+	val = readl(&regs->smi);
+	*value = val & 0xffff;
+
+	return 0;
+}
+
+static int smi_reg_write(const char *devname,
+	 u8 phy_addr, u8 phy_reg, u16 value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+
+	if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) {
+		clrsetbits_le32(&regs->phyadr, 0x1f, value & 0x1f);
+		return 0;
+	}
+
+	/* check parameters */
+	if (phy_addr > PHY_MASK) {
+		printf("ARMD100 FEC: (%s) Invalid phy address\n", __func__);
+		return -EINVAL;
+	}
+	if (phy_reg > PHY_MASK) {
+		printf("ARMD100 FEC: (%s) Invalid register offset\n", __func__);
+		return -EINVAL;
+	}
+
+	/* wait for the SMI register to become available */
+	if (armdfec_phy_timeout(&regs->smi, SMI_BUSY, false)) {
+		printf("ARMD100 FEC: (%s) PHY busy timeout\n",	__func__);
+		return -1;
+	}
+
+	writel((phy_addr << 16) | (phy_reg << 21) | SMI_OP_W | (value & 0xffff),
+			&regs->smi);
+	return 0;
+}
+
+/*
+ * Abort any transmit and receive operations and put DMA
+ * in idle state. AT and AR bits are cleared upon entering
+ * in IDLE state. So poll those bits to verify operation.
+ */
+static void abortdma(struct eth_device *dev)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	int delay;
+	int maxretries = 40;
+	u32 tmp;
+
+	while (--maxretries) {
+		writel(SDMA_CMD_AR | SDMA_CMD_AT, &regs->sdma_cmd);
+		udelay(100);
+
+		delay = 10;
+		while (--delay) {
+			tmp = readl(&regs->sdma_cmd);
+			if (!(tmp & (SDMA_CMD_AR | SDMA_CMD_AT)))
+				break;
+			udelay(10);
+		}
+		if (delay)
+			break;
+	}
+
+	if (!maxretries)
+		printf("ARMD100 FEC: (%s) DMA Stuck\n", __func__);
+}
+
+static inline u32 nibble_swapping_32_bit(u32 x)
+{
+	return ((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4);
+}
+
+static inline u32 nibble_swapping_16_bit(u32 x)
+{
+	return ((x & 0x0000f0f0) >> 4) | ((x & 0x00000f0f) << 4);
+}
+
+static inline u32 flip_4_bits(u32 x)
+{
+	return ((x & 0x01) << 3) | ((x & 0x002) << 1)
+		| ((x & 0x04) >> 1) | ((x & 0x008) >> 3);
+}
+
+/*
+ * This function will calculate the hash function of the address.
+ * depends on the hash mode and hash size.
+ * Inputs
+ * mach             - the 2 most significant bytes of the MAC address.
+ * macl             - the 4 least significant bytes of the MAC address.
+ * Outputs
+ * return the calculated entry.
+ */
+static u32 hash_function(u32 mach, u32 macl)
+{
+	u32 hashresult;
+	u32 addrh;
+	u32 addrl;
+	u32 addr0;
+	u32 addr1;
+	u32 addr2;
+	u32 addr3;
+	u32 addrhswapped;
+	u32 addrlswapped;
+
+	addrh = nibble_swapping_16_bit(mach);
+	addrl = nibble_swapping_32_bit(macl);
+
+	addrhswapped = flip_4_bits(addrh & 0xf)
+		+ ((flip_4_bits((addrh >> 4) & 0xf)) << 4)
+		+ ((flip_4_bits((addrh >> 8) & 0xf)) << 8)
+		+ ((flip_4_bits((addrh >> 12) & 0xf)) << 12);
+
+	addrlswapped = flip_4_bits(addrl & 0xf)
+		+ ((flip_4_bits((addrl >> 4) & 0xf)) << 4)
+		+ ((flip_4_bits((addrl >> 8) & 0xf)) << 8)
+		+ ((flip_4_bits((addrl >> 12) & 0xf)) << 12)
+		+ ((flip_4_bits((addrl >> 16) & 0xf)) << 16)
+		+ ((flip_4_bits((addrl >> 20) & 0xf)) << 20)
+		+ ((flip_4_bits((addrl >> 24) & 0xf)) << 24)
+		+ ((flip_4_bits((addrl >> 28) & 0xf)) << 28);
+
+	addrh = addrhswapped;
+	addrl = addrlswapped;
+
+	addr0 = (addrl >> 2) & 0x03f;
+	addr1 = (addrl & 0x003) | (((addrl >> 8) & 0x7f) << 2);
+	addr2 = (addrl >> 15) & 0x1ff;
+	addr3 = ((addrl >> 24) & 0x0ff) | ((addrh & 1) << 8);
+
+	hashresult = (addr0 << 9) | (addr1 ^ addr2 ^ addr3);
+	hashresult = hashresult & 0x07ff;
+	return hashresult;
+}
+
+/*
+ * This function will add an entry to the address table.
+ * depends on the hash mode and hash size that was initialized.
+ * Inputs
+ * mach - the 2 most significant bytes of the MAC address.
+ * macl - the 4 least significant bytes of the MAC address.
+ * skip - if 1, skip this address.
+ * rd   - the RD field in the address table.
+ * Outputs
+ * address table entry is added.
+ * 0 if success.
+ * -ENOSPC if table full
+ */
+static int add_del_hash_entry(struct armdfec_device *darmdfec, u32 mach,
+			      u32 macl, u32 rd, u32 skip, int del)
+{
+	struct addr_table_entry_t *entry, *start;
+	u32 newhi;
+	u32 newlo;
+	u32 i;
+
+	newlo = (((mach >> 4) & 0xf) << 15)
+		| (((mach >> 0) & 0xf) << 11)
+		| (((mach >> 12) & 0xf) << 7)
+		| (((mach >> 8) & 0xf) << 3)
+		| (((macl >> 20) & 0x1) << 31)
+		| (((macl >> 16) & 0xf) << 27)
+		| (((macl >> 28) & 0xf) << 23)
+		| (((macl >> 24) & 0xf) << 19)
+		| (skip << HTESKIP) | (rd << HTERDBIT)
+		| HTEVALID;
+
+	newhi = (((macl >> 4) & 0xf) << 15)
+		| (((macl >> 0) & 0xf) << 11)
+		| (((macl >> 12) & 0xf) << 7)
+		| (((macl >> 8) & 0xf) << 3)
+		| (((macl >> 21) & 0x7) << 0);
+
+	/*
+	 * Pick the appropriate table, start scanning for free/reusable
+	 * entries at the index obtained by hashing the specified MAC address
+	 */
+	start = (struct addr_table_entry_t *)(darmdfec->htpr);
+	entry = start + hash_function(mach, macl);
+	for (i = 0; i < HOP_NUMBER; i++) {
+		if (!(entry->lo & HTEVALID)) {
+			break;
+		} else {
+			/* if same address put in same position */
+			if (((entry->lo & 0xfffffff8) == (newlo & 0xfffffff8))
+					&& (entry->hi == newhi))
+				break;
+		}
+		if (entry == start + 0x7ff)
+			entry = start;
+		else
+			entry++;
+	}
+
+	if (((entry->lo & 0xfffffff8) != (newlo & 0xfffffff8)) &&
+		(entry->hi != newhi) && del)
+		return 0;
+
+	if (i == HOP_NUMBER) {
+		if (!del) {
+			printf("ARMD100 FEC: (%s) table section is full\n",
+					__func__);
+			return -ENOSPC;
+		} else {
+			return 0;
+		}
+	}
+
+	/*
+	 * Update the selected entry
+	 */
+	if (del) {
+		entry->hi = 0;
+		entry->lo = 0;
+	} else {
+		entry->hi = newhi;
+		entry->lo = newlo;
+	}
+
+	return 0;
+}
+
+/*
+ *  Create an addressTable entry from MAC address info
+ *  found in the specifed net_device struct
+ *
+ *  Input : pointer to ethernet interface network device structure
+ *  Output : N/A
+ */
+static void update_hash_table_mac_address(struct armdfec_device *darmdfec,
+					  u8 *oaddr, u8 *addr)
+{
+	u32 mach;
+	u32 macl;
+
+	/* Delete old entry */
+	if (oaddr) {
+		mach = (oaddr[0] << 8) | oaddr[1];
+		macl = (oaddr[2] << 24) | (oaddr[3] << 16) |
+			(oaddr[4] << 8) | oaddr[5];
+		add_del_hash_entry(darmdfec, mach, macl, 1, 0, HASH_DELETE);
+	}
+
+	/* Add new entry */
+	mach = (addr[0] << 8) | addr[1];
+	macl = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];
+	add_del_hash_entry(darmdfec, mach, macl, 1, 0, HASH_ADD);
+}
+
+/* Address Table Initialization */
+static void init_hashtable(struct eth_device *dev)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	memset(darmdfec->htpr, 0, HASH_ADDR_TABLE_SIZE);
+	writel((u32)darmdfec->htpr, &regs->htpr);
+}
+
+/*
+ * This detects PHY chip from address 0-31 by reading PHY status
+ * registers. PHY chip can be connected at any of this address.
+ */
+static int ethernet_phy_detect(struct eth_device *dev)
+{
+	u32 val;
+	u16 tmp, mii_status;
+	u8 addr;
+
+	for (addr = 0; addr < 32; addr++) {
+		if (miiphy_read(dev->name, addr, MII_BMSR, &mii_status)	!= 0)
+			/* try next phy */
+			continue;
+
+		/* invalid MII status. More validation required here... */
+		if (mii_status == 0 || mii_status == 0xffff)
+			/* try next phy */
+			continue;
+
+		if (miiphy_read(dev->name, addr, MII_PHYSID1, &tmp) != 0)
+			/* try next phy */
+			continue;
+
+		val = tmp << 16;
+		if (miiphy_read(dev->name, addr, MII_PHYSID2, &tmp) != 0)
+			/* try next phy */
+			continue;
+
+		val |= tmp;
+
+		if ((val & 0xfffffff0) != 0)
+			return addr;
+	}
+	return -1;
+}
+
+static void armdfec_init_rx_desc_ring(struct armdfec_device *darmdfec)
+{
+	struct rx_desc *p_rx_desc;
+	int i;
+
+	/* initialize the Rx descriptors ring */
+	p_rx_desc = darmdfec->p_rxdesc;
+	for (i = 0; i < RINGSZ; i++) {
+		p_rx_desc->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT;
+		p_rx_desc->buf_size = PKTSIZE_ALIGN;
+		p_rx_desc->byte_cnt = 0;
+		p_rx_desc->buf_ptr = darmdfec->p_rxbuf + i * PKTSIZE_ALIGN;
+		if (i == (RINGSZ - 1)) {
+			p_rx_desc->nxtdesc_p = darmdfec->p_rxdesc;
+		} else {
+			p_rx_desc->nxtdesc_p = (struct rx_desc *)
+			    ((u32)p_rx_desc + ARMDFEC_RXQ_DESC_ALIGNED_SIZE);
+			p_rx_desc = p_rx_desc->nxtdesc_p;
+		}
+	}
+	darmdfec->p_rxdesc_curr = darmdfec->p_rxdesc;
+}
+
+static int armdfec_init(struct eth_device *dev, bd_t *bd)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	int phy_adr;
+	u32 temp;
+
+	armdfec_init_rx_desc_ring(darmdfec);
+
+	/* Disable interrupts */
+	writel(0, &regs->im);
+	writel(0, &regs->ic);
+	/* Write to ICR to clear interrupts. */
+	writel(0, &regs->iwc);
+
+	/*
+	 * Abort any transmit and receive operations and put DMA
+	 * in idle state.
+	 */
+	abortdma(dev);
+
+	/* Initialize address hash table */
+	init_hashtable(dev);
+
+	/* SDMA configuration */
+	writel(SDCR_BSZ8 |	/* Burst size = 32 bytes */
+		SDCR_RIFB |	/* Rx interrupt on frame */
+		SDCR_BLMT |	/* Little endian transmit */
+		SDCR_BLMR |	/* Little endian receive */
+		SDCR_RC_MAX_RETRANS,	/* Max retransmit count */
+		&regs->sdma_conf);
+	/* Port Configuration */
+	writel(PCR_HS, &regs->pconf);	/* Hash size is 1/2kb */
+
+	/* Set extended port configuration */
+	writel(PCXR_2BSM |		/* Two byte suffix aligns IP hdr */
+		PCXR_DSCP_EN |		/* Enable DSCP in IP */
+		PCXR_MFL_1536 |		/* Set MTU = 1536 */
+		PCXR_FLP |		/* do not force link pass */
+		PCXR_TX_HIGH_PRI,	/* Transmit - high priority queue */
+		&regs->pconf_ext);
+
+	update_hash_table_mac_address(darmdfec, NULL, dev->enetaddr);
+
+	/* Update TX and RX queue descriptor register */
+	temp = (u32)&regs->txcdp[TXQ];
+	writel((u32)darmdfec->p_txdesc, temp);
+	temp = (u32)&regs->rxfdp[RXQ];
+	writel((u32)darmdfec->p_rxdesc, temp);
+	temp = (u32)&regs->rxcdp[RXQ];
+	writel((u32)darmdfec->p_rxdesc_curr, temp);
+
+	/* Enable Interrupts */
+	writel(ALL_INTS, &regs->im);
+
+	/* Enable Ethernet Port */
+	setbits_le32(&regs->pconf, PCR_EN);
+
+	/* Enable RX DMA engine */
+	setbits_le32(&regs->sdma_cmd, SDMA_CMD_ERD);
+
+#ifdef DEBUG
+	eth_dump_regs(dev);
+#endif
+
+#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
+
+#if defined(CONFIG_PHY_BASE_ADR)
+	miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ, CONFIG_PHY_BASE_ADR);
+#else
+	/* Search phy address from range 0-31 */
+	phy_adr = ethernet_phy_detect(dev);
+	if (phy_adr < 0) {
+		printf("ARMD100 FEC: PHY not detected at address range 0-31\n");
+		return -1;
+	} else {
+		debug("ARMD100 FEC: PHY detected at addr %d\n", phy_adr);
+		miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ, phy_adr);
+	}
+#endif
+
+#if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
+	/* Wait up to 5s for the link status */
+	for (i = 0; i < 5; i++) {
+		u16 phy_adr;
+
+		miiphy_read(dev->name, 0xFF, 0xFF, &phy_adr);
+		/* Return if we get link up */
+		if (miiphy_link(dev->name, phy_adr))
+			return 0;
+		udelay(1000000);
+	}
+
+	printf("ARMD100 FEC: No link on %s\n", dev->name);
+	return -1;
+#endif
+#endif
+	return 0;
+}
+
+static void armdfec_halt(struct eth_device *dev)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+
+	/* Stop RX DMA */
+	clrbits_le32(&regs->sdma_cmd, SDMA_CMD_ERD);
+
+	/*
+	 * Abort any transmit and receive operations and put DMA
+	 * in idle state.
+	 */
+	abortdma(dev);
+
+	/* Disable interrupts */
+	writel(0, &regs->im);
+	writel(0, &regs->ic);
+	writel(0, &regs->iwc);
+
+	/* Disable Port */
+	clrbits_le32(&regs->pconf, PCR_EN);
+}
+
+static int armdfec_send(struct eth_device *dev, void *dataptr, int datasize)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	struct tx_desc *p_txdesc = darmdfec->p_txdesc;
+	void *p = (void *)dataptr;
+	int retry = PHY_WAIT_ITERATIONS * PHY_WAIT_MICRO_SECONDS;
+	u32 cmd_sts, temp;
+
+	/* Copy buffer if it's misaligned */
+	if ((u32)dataptr & 0x07) {
+		if (datasize > PKTSIZE_ALIGN) {
+			printf("ARMD100 FEC: Non-aligned data too large (%d)\n",
+					datasize);
+			return -1;
+		}
+		memcpy(darmdfec->p_aligned_txbuf, p, datasize);
+		p = darmdfec->p_aligned_txbuf;
+	}
+
+	p_txdesc->cmd_sts = TX_ZERO_PADDING | TX_GEN_CRC;
+	p_txdesc->cmd_sts |= TX_FIRST_DESC | TX_LAST_DESC;
+	p_txdesc->cmd_sts |= BUF_OWNED_BY_DMA;
+	p_txdesc->cmd_sts |= TX_EN_INT;
+	p_txdesc->buf_ptr = p;
+	p_txdesc->byte_cnt = datasize;
+
+	/* Apply send command using high priority TX queue */
+	temp = (u32)&regs->txcdp[TXQ];
+	writel((u32)p_txdesc, temp);
+	writel(SDMA_CMD_TXDL | SDMA_CMD_TXDH | SDMA_CMD_ERD, &regs->sdma_cmd);
+
+	/*
+	 * wait for packet xmit completion
+	 */
+	cmd_sts = readl(&p_txdesc->cmd_sts);
+	while (cmd_sts & BUF_OWNED_BY_DMA) {
+		/* return fail if error is detected */
+		if ((cmd_sts & (TX_ERROR | TX_LAST_DESC)) ==
+			(TX_ERROR | TX_LAST_DESC)) {
+			printf("ARMD100 FEC: (%s) in xmit packet\n", __func__);
+			return -1;
+		}
+		cmd_sts = readl(&p_txdesc->cmd_sts);
+		if (!(retry--)) {
+			printf("ARMD100 FEC: (%s) xmit packet timeout!\n",
+					__func__);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int armdfec_recv(struct eth_device *dev)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct rx_desc *p_rxdesc_curr = darmdfec->p_rxdesc_curr;
+	u32 cmd_sts;
+	u32 timeout = 0;
+	u32 temp;
+
+	/* wait untill rx packet available or timeout */
+	do {
+		if (timeout < PHY_WAIT_ITERATIONS * PHY_WAIT_MICRO_SECONDS) {
+			timeout++;
+		} else {
+			debug("ARMD100 FEC: %s time out...\n", __func__);
+			return -1;
+		}
+	} while (readl(&p_rxdesc_curr->cmd_sts) & BUF_OWNED_BY_DMA);
+
+	if (p_rxdesc_curr->byte_cnt != 0) {
+		debug("ARMD100 FEC: %s: Received %d byte Packet @ 0x%x"
+				"(cmd_sts= %08x)\n", __func__,
+				(u32)p_rxdesc_curr->byte_cnt,
+				(u32)p_rxdesc_curr->buf_ptr,
+				(u32)p_rxdesc_curr->cmd_sts);
+	}
+
+	/*
+	 * In case received a packet without first/last bits on
+	 * OR the error summary bit is on,
+	 * the packets needs to be dropeed.
+	 */
+	cmd_sts = readl(&p_rxdesc_curr->cmd_sts);
+
+	if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
+			(RX_FIRST_DESC | RX_LAST_DESC)) {
+		printf("ARMD100 FEC: (%s) Dropping packet spread on"
+			" multiple descriptors\n", __func__);
+	} else if (cmd_sts & RX_ERROR) {
+		printf("ARMD100 FEC: (%s) Dropping packet with errors\n",
+				__func__);
+	} else {
+		/* !!! call higher layer processing */
+		debug("ARMD100 FEC: (%s) Sending Received packet to"
+			" upper layer (NetReceive)\n", __func__);
+
+		/*
+		 * let the upper layer handle the packet, subtract offset
+		 * as two dummy bytes are added in received buffer see
+		 * PORT_CONFIG_EXT register bit TWO_Byte_Stuff_Mode bit.
+		 */
+		NetReceive((p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET),
+			   (int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET));
+	}
+	/*
+	 * free these descriptors and point next in the ring
+	 */
+	p_rxdesc_curr->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT;
+	p_rxdesc_curr->buf_size = PKTSIZE_ALIGN;
+	p_rxdesc_curr->byte_cnt = 0;
+
+	temp = (u32)&darmdfec->p_rxdesc_curr;
+	writel((u32)p_rxdesc_curr->nxtdesc_p, temp);
+
+	return 0;
+}
+
+int armada100_fec_register(unsigned long base_addr)
+{
+	struct armdfec_device *darmdfec;
+	struct eth_device *dev;
+
+	darmdfec = malloc(sizeof(struct armdfec_device));
+	if (!darmdfec)
+		goto error;
+
+	memset(darmdfec, 0, sizeof(struct armdfec_device));
+
+	darmdfec->htpr = memalign(8, HASH_ADDR_TABLE_SIZE);
+	if (!darmdfec->htpr)
+		goto error1;
+
+	darmdfec->p_rxdesc = memalign(PKTALIGN,
+			ARMDFEC_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1);
+
+	if (!darmdfec->p_rxdesc)
+		goto error1;
+
+	darmdfec->p_rxbuf = memalign(PKTALIGN, RINGSZ * PKTSIZE_ALIGN + 1);
+	if (!darmdfec->p_rxbuf)
+		goto error1;
+
+	darmdfec->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
+	if (!darmdfec->p_aligned_txbuf)
+		goto error1;
+
+	darmdfec->p_txdesc = memalign(PKTALIGN, sizeof(struct tx_desc) + 1);
+	if (!darmdfec->p_txdesc)
+		goto error1;
+
+	dev = &darmdfec->dev;
+	/* Assign ARMADA100 Fast Ethernet Controller Base Address */
+	darmdfec->regs = (void *)base_addr;
+
+	/* must be less than sizeof(dev->name) */
+	strcpy(dev->name, "armd-fec0");
+
+	dev->init = armdfec_init;
+	dev->halt = armdfec_halt;
+	dev->send = armdfec_send;
+	dev->recv = armdfec_recv;
+
+	eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	miiphy_register(dev->name, smi_reg_read, smi_reg_write);
+#endif
+	return 0;
+
+error1:
+	free(darmdfec->p_aligned_txbuf);
+	free(darmdfec->p_rxbuf);
+	free(darmdfec->p_rxdesc);
+	free(darmdfec->htpr);
+error:
+	free(darmdfec);
+	printf("AMD100 FEC: (%s) Failed to allocate memory\n", __func__);
+	return -1;
+}
diff --git a/marvell/uboot/drivers/net/armada100_fec.h b/marvell/uboot/drivers/net/armada100_fec.h
new file mode 100644
index 0000000..5a0a3d9
--- /dev/null
+++ b/marvell/uboot/drivers/net/armada100_fec.h
@@ -0,0 +1,209 @@
+/*
+ * (C) Copyright 2011
+ * eInfochips Ltd. <www.einfochips.com>
+ * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
+ *
+ * (C) Copyright 2010
+ * Marvell Semiconductor <www.marvell.com>
+ * Contributor: Mahavir Jain <mjain@marvell.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __ARMADA100_FEC_H__
+#define __ARMADA100_FEC_H__
+
+#define PORT_NUM		0x0
+
+/* RX & TX descriptor command */
+#define BUF_OWNED_BY_DMA        (1<<31)
+
+/* RX descriptor status */
+#define RX_EN_INT               (1<<23)
+#define RX_FIRST_DESC           (1<<17)
+#define RX_LAST_DESC            (1<<16)
+#define RX_ERROR                (1<<15)
+
+/* TX descriptor command */
+#define TX_EN_INT               (1<<23)
+#define TX_GEN_CRC              (1<<22)
+#define TX_ZERO_PADDING         (1<<18)
+#define TX_FIRST_DESC           (1<<17)
+#define TX_LAST_DESC            (1<<16)
+#define TX_ERROR                (1<<15)
+
+/* smi register */
+#define SMI_BUSY                (1<<28)	/* 0 - Write, 1 - Read  */
+#define SMI_R_VALID             (1<<27)	/* 0 - Write, 1 - Read  */
+#define SMI_OP_W                (0<<26)	/* Write operation      */
+#define SMI_OP_R                (1<<26)	/* Read operation */
+
+#define HASH_ADD                0
+#define HASH_DELETE             1
+#define HASH_ADDR_TABLE_SIZE    0x4000	/* 16K (1/2K address - PCR_HS == 1) */
+#define HOP_NUMBER              12
+
+#define PHY_WAIT_ITERATIONS     1000	/* 1000 iterations * 10uS = 10mS max */
+#define PHY_WAIT_MICRO_SECONDS  10
+
+#define ETH_HW_IP_ALIGN         2	/* hw aligns IP header */
+#define ETH_EXTRA_HEADER        (6+6+2+4)
+					/* dest+src addr+protocol id+crc */
+#define MAX_PKT_SIZE            1536
+
+
+/* Bit definitions of the SDMA Config Reg */
+#define SDCR_BSZ_OFF            12
+#define SDCR_BSZ8               (3<<SDCR_BSZ_OFF)
+#define SDCR_BSZ4               (2<<SDCR_BSZ_OFF)
+#define SDCR_BSZ2               (1<<SDCR_BSZ_OFF)
+#define SDCR_BSZ1               (0<<SDCR_BSZ_OFF)
+#define SDCR_BLMR               (1<<6)
+#define SDCR_BLMT               (1<<7)
+#define SDCR_RIFB               (1<<9)
+#define SDCR_RC_OFF             2
+#define SDCR_RC_MAX_RETRANS     (0xf << SDCR_RC_OFF)
+
+/* SDMA_CMD */
+#define SDMA_CMD_AT             (1<<31)
+#define SDMA_CMD_TXDL           (1<<24)
+#define SDMA_CMD_TXDH           (1<<23)
+#define SDMA_CMD_AR             (1<<15)
+#define SDMA_CMD_ERD            (1<<7)
+
+
+/* Bit definitions of the Port Config Reg */
+#define PCR_HS                  (1<<12)
+#define PCR_EN                  (1<<7)
+#define PCR_PM                  (1<<0)
+
+/* Bit definitions of the Port Config Extend Reg */
+#define PCXR_2BSM               (1<<28)
+#define PCXR_DSCP_EN            (1<<21)
+#define PCXR_MFL_1518           (0<<14)
+#define PCXR_MFL_1536           (1<<14)
+#define PCXR_MFL_2048           (2<<14)
+#define PCXR_MFL_64K            (3<<14)
+#define PCXR_FLP                (1<<11)
+#define PCXR_PRIO_TX_OFF        3
+#define PCXR_TX_HIGH_PRI        (7<<PCXR_PRIO_TX_OFF)
+
+/*
+ *  * Bit definitions of the Interrupt Cause Reg
+ *   * and Interrupt MASK Reg is the same
+ *    */
+#define ICR_RXBUF               (1<<0)
+#define ICR_TXBUF_H             (1<<2)
+#define ICR_TXBUF_L             (1<<3)
+#define ICR_TXEND_H             (1<<6)
+#define ICR_TXEND_L             (1<<7)
+#define ICR_RXERR               (1<<8)
+#define ICR_TXERR_H             (1<<10)
+#define ICR_TXERR_L             (1<<11)
+#define ICR_TX_UDR              (1<<13)
+#define ICR_MII_CH              (1<<28)
+
+#define ALL_INTS (ICR_TXBUF_H  | ICR_TXBUF_L  | ICR_TX_UDR |\
+				ICR_TXERR_H  | ICR_TXERR_L |\
+				ICR_TXEND_H  | ICR_TXEND_L |\
+				ICR_RXBUF | ICR_RXERR  | ICR_MII_CH)
+
+#define PHY_MASK               0x0000001f
+
+#define to_darmdfec(_kd) container_of(_kd, struct armdfec_device, dev)
+/* Size of a Tx/Rx descriptor used in chain list data structure */
+#define ARMDFEC_RXQ_DESC_ALIGNED_SIZE \
+	(((sizeof(struct rx_desc) / PKTALIGN) + 1) * PKTALIGN)
+
+#define RX_BUF_OFFSET		0x2
+#define RXQ			0x0	/* RX Queue 0 */
+#define TXQ			0x1	/* TX Queue 1 */
+
+struct addr_table_entry_t {
+	u32 lo;
+	u32 hi;
+};
+
+/* Bit fields of a Hash Table Entry */
+enum hash_table_entry {
+	HTEVALID = 1,
+	HTESKIP = 2,
+	HTERD = 4,
+	HTERDBIT = 2
+};
+
+struct tx_desc {
+	u32 cmd_sts;		/* Command/status field */
+	u16 reserved;
+	u16 byte_cnt;		/* buffer byte count */
+	u8 *buf_ptr;		/* pointer to buffer for this descriptor */
+	struct tx_desc *nextdesc_p;	/* Pointer to next descriptor */
+};
+
+struct rx_desc {
+	u32 cmd_sts;		/* Descriptor command status */
+	u16 byte_cnt;		/* Descriptor buffer byte count */
+	u16 buf_size;		/* Buffer size */
+	u8 *buf_ptr;		/* Descriptor buffer pointer */
+	struct rx_desc *nxtdesc_p;	/* Next descriptor pointer */
+};
+
+/*
+ * Armada100 Fast Ethernet controller Registers
+ * Refer Datasheet Appendix A.22
+ */
+struct armdfec_reg {
+	u32 phyadr;			/* PHY Address */
+	u32 pad1[3];
+	u32 smi;			/* SMI */
+	u32 pad2[0xFB];
+	u32 pconf;			/* Port configuration */
+	u32 pad3;
+	u32 pconf_ext;			/* Port configuration extend */
+	u32 pad4;
+	u32 pcmd;			/* Port Command */
+	u32 pad5;
+	u32 pstatus;			/* Port Status */
+	u32 pad6;
+	u32 spar;			/* Serial Parameters */
+	u32 pad7;
+	u32 htpr;			/* Hash table pointer */
+	u32 pad8;
+	u32 fcsal;			/* Flow control source address low */
+	u32 pad9;
+	u32 fcsah;			/* Flow control source address high */
+	u32 pad10;
+	u32 sdma_conf;			/* SDMA configuration */
+	u32 pad11;
+	u32 sdma_cmd;			/* SDMA command */
+	u32 pad12;
+	u32 ic;				/* Interrupt cause */
+	u32 iwc;			/* Interrupt write to clear */
+	u32 im;				/* Interrupt mask */
+	u32 pad13;
+	u32 *eth_idscpp[4];		/* Eth0 IP Differentiated Services Code
+					   Point to Priority 0 Low */
+	u32 eth_vlan_p;			/* Eth0 VLAN Priority Tag to Priority */
+	u32 pad14[3];
+	struct rx_desc *rxfdp[4];	/* Ethernet First Rx Descriptor
+					   Pointer */
+	u32 pad15[4];
+	struct rx_desc *rxcdp[4];	/* Ethernet Current Rx Descriptor
+					   Pointer */
+	u32 pad16[0x0C];
+	struct tx_desc *txcdp[2];	/* Ethernet Current Tx Descriptor
+					   Pointer */
+};
+
+struct armdfec_device {
+	struct eth_device dev;
+	struct armdfec_reg *regs;
+	struct tx_desc *p_txdesc;
+	struct rx_desc *p_rxdesc;
+	struct rx_desc *p_rxdesc_curr;
+	u8 *p_rxbuf;
+	u8 *p_aligned_txbuf;
+	u8 *htpr;		/* hash pointer */
+};
+
+#endif /* __ARMADA100_FEC_H__ */
diff --git a/marvell/uboot/drivers/net/at91_emac.c b/marvell/uboot/drivers/net/at91_emac.c
new file mode 100644
index 0000000..64d4c56
--- /dev/null
+++ b/marvell/uboot/drivers/net/at91_emac.c
@@ -0,0 +1,508 @@
+/*
+ * Copyright (C) 2009 BuS Elektronik GmbH & Co. KG
+ * Jens Scharsig (esw@bus-elektronik.de)
+ *
+ * (C) Copyright 2003
+ * Author : Hamid Ikdoumi (Atmel)
+
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/at91_emac.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91_pio.h>
+#include <net.h>
+#include <netdev.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <linux/mii.h>
+
+#undef MII_DEBUG
+#undef ET_DEBUG
+
+#if (CONFIG_SYS_RX_ETH_BUFFER > 1024)
+#error AT91 EMAC supports max 1024 RX buffers. \
+	Please decrease the CONFIG_SYS_RX_ETH_BUFFER value
+#endif
+
+#ifndef CONFIG_DRIVER_AT91EMAC_PHYADDR
+#define CONFIG_DRIVER_AT91EMAC_PHYADDR	0
+#endif
+
+/* MDIO clock must not exceed 2.5 MHz, so enable MCK divider */
+#if (AT91C_MASTER_CLOCK > 80000000)
+	#define HCLK_DIV	AT91_EMAC_CFG_MCLK_64
+#elif (AT91C_MASTER_CLOCK > 40000000)
+	#define HCLK_DIV	AT91_EMAC_CFG_MCLK_32
+#elif (AT91C_MASTER_CLOCK > 20000000)
+	#define HCLK_DIV	AT91_EMAC_CFG_MCLK_16
+#else
+	#define HCLK_DIV	AT91_EMAC_CFG_MCLK_8
+#endif
+
+#ifdef ET_DEBUG
+#define DEBUG_AT91EMAC	1
+#else
+#define DEBUG_AT91EMAC	0
+#endif
+
+#ifdef MII_DEBUG
+#define DEBUG_AT91PHY	1
+#else
+#define DEBUG_AT91PHY	0
+#endif
+
+#ifndef CONFIG_DRIVER_AT91EMAC_QUIET
+#define VERBOSEP	1
+#else
+#define VERBOSEP	0
+#endif
+
+#define RBF_ADDR      0xfffffffc
+#define RBF_OWNER     (1<<0)
+#define RBF_WRAP      (1<<1)
+#define RBF_BROADCAST (1<<31)
+#define RBF_MULTICAST (1<<30)
+#define RBF_UNICAST   (1<<29)
+#define RBF_EXTERNAL  (1<<28)
+#define RBF_UNKNOWN   (1<<27)
+#define RBF_SIZE      0x07ff
+#define RBF_LOCAL4    (1<<26)
+#define RBF_LOCAL3    (1<<25)
+#define RBF_LOCAL2    (1<<24)
+#define RBF_LOCAL1    (1<<23)
+
+#define RBF_FRAMEMAX CONFIG_SYS_RX_ETH_BUFFER
+#define RBF_FRAMELEN 0x600
+
+typedef struct {
+	unsigned long addr, size;
+} rbf_t;
+
+typedef struct {
+	rbf_t 		rbfdt[RBF_FRAMEMAX];
+	unsigned long	rbindex;
+} emac_device;
+
+void at91emac_EnableMDIO(at91_emac_t *at91mac)
+{
+	/* Mac CTRL reg set for MDIO enable */
+	writel(readl(&at91mac->ctl) | AT91_EMAC_CTL_MPE, &at91mac->ctl);
+}
+
+void at91emac_DisableMDIO(at91_emac_t *at91mac)
+{
+	/* Mac CTRL reg set for MDIO disable */
+	writel(readl(&at91mac->ctl) & ~AT91_EMAC_CTL_MPE, &at91mac->ctl);
+}
+
+int  at91emac_read(at91_emac_t *at91mac, unsigned char addr,
+		unsigned char reg, unsigned short *value)
+{
+	unsigned long netstat;
+	at91emac_EnableMDIO(at91mac);
+
+	writel(AT91_EMAC_MAN_HIGH | AT91_EMAC_MAN_RW_R |
+		AT91_EMAC_MAN_REGA(reg) | AT91_EMAC_MAN_CODE_802_3 |
+		AT91_EMAC_MAN_PHYA(addr),
+		&at91mac->man);
+
+	do {
+		netstat = readl(&at91mac->sr);
+		debug_cond(DEBUG_AT91PHY, "poll SR %08lx\n", netstat);
+	} while (!(netstat & AT91_EMAC_SR_IDLE));
+
+	*value = readl(&at91mac->man) & AT91_EMAC_MAN_DATA_MASK;
+
+	at91emac_DisableMDIO(at91mac);
+
+	debug_cond(DEBUG_AT91PHY,
+		"AT91PHY read %p REG(%d)=%x\n", at91mac, reg, *value);
+
+	return 0;
+}
+
+int  at91emac_write(at91_emac_t *at91mac, unsigned char addr,
+		unsigned char reg, unsigned short value)
+{
+	unsigned long netstat;
+	debug_cond(DEBUG_AT91PHY,
+		"AT91PHY write %p REG(%d)=%p\n", at91mac, reg, &value);
+
+	at91emac_EnableMDIO(at91mac);
+
+	writel(AT91_EMAC_MAN_HIGH | AT91_EMAC_MAN_RW_W |
+		AT91_EMAC_MAN_REGA(reg) | AT91_EMAC_MAN_CODE_802_3 |
+		AT91_EMAC_MAN_PHYA(addr) | (value & AT91_EMAC_MAN_DATA_MASK),
+		&at91mac->man);
+
+	do {
+		netstat = readl(&at91mac->sr);
+		debug_cond(DEBUG_AT91PHY, "poll SR %08lx\n", netstat);
+	} while (!(netstat & AT91_EMAC_SR_IDLE));
+
+	at91emac_DisableMDIO(at91mac);
+
+	return 0;
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+
+at91_emac_t *get_emacbase_by_name(const char *devname)
+{
+	struct eth_device *netdev;
+
+	netdev = eth_get_dev_by_name(devname);
+	return (at91_emac_t *) netdev->iobase;
+}
+
+int  at91emac_mii_read(const char *devname, unsigned char addr,
+		unsigned char reg, unsigned short *value)
+{
+	at91_emac_t *emac;
+
+	emac = get_emacbase_by_name(devname);
+	at91emac_read(emac , addr, reg, value);
+	return 0;
+}
+
+
+int  at91emac_mii_write(const char *devname, unsigned char addr,
+		unsigned char reg, unsigned short value)
+{
+	at91_emac_t *emac;
+
+	emac = get_emacbase_by_name(devname);
+	at91emac_write(emac, addr, reg, value);
+	return 0;
+}
+
+#endif
+
+static int at91emac_phy_reset(struct eth_device *netdev)
+{
+	int i;
+	u16 status, adv;
+	at91_emac_t *emac;
+
+	emac = (at91_emac_t *) netdev->iobase;
+
+	adv = ADVERTISE_CSMA | ADVERTISE_ALL;
+	at91emac_write(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
+		MII_ADVERTISE, adv);
+	debug_cond(VERBOSEP, "%s: Starting autonegotiation...\n", netdev->name);
+	at91emac_write(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_BMCR,
+		(BMCR_ANENABLE | BMCR_ANRESTART));
+
+	for (i = 0; i < 30000; i++) {
+		at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
+			MII_BMSR, &status);
+		if (status & BMSR_ANEGCOMPLETE)
+			break;
+		udelay(100);
+	}
+
+	if (status & BMSR_ANEGCOMPLETE) {
+		debug_cond(VERBOSEP,
+			"%s: Autonegotiation complete\n", netdev->name);
+	} else {
+		printf("%s: Autonegotiation timed out (status=0x%04x)\n",
+		       netdev->name, status);
+		return -1;
+	}
+	return 0;
+}
+
+static int at91emac_phy_init(struct eth_device *netdev)
+{
+	u16 phy_id, status, adv, lpa;
+	int media, speed, duplex;
+	int i;
+	at91_emac_t *emac;
+
+	emac = (at91_emac_t *) netdev->iobase;
+
+	/* Check if the PHY is up to snuff... */
+	at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
+		MII_PHYSID1, &phy_id);
+	if (phy_id == 0xffff) {
+		printf("%s: No PHY present\n", netdev->name);
+		return -1;
+	}
+
+	at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
+		MII_BMSR, &status);
+
+	if (!(status & BMSR_LSTATUS)) {
+		/* Try to re-negotiate if we don't have link already. */
+		if (at91emac_phy_reset(netdev))
+			return -2;
+
+		for (i = 0; i < 100000 / 100; i++) {
+			at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
+				MII_BMSR, &status);
+			if (status & BMSR_LSTATUS)
+				break;
+			udelay(100);
+		}
+	}
+	if (!(status & BMSR_LSTATUS)) {
+		debug_cond(VERBOSEP, "%s: link down\n", netdev->name);
+		return -3;
+	} else {
+		at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
+			MII_ADVERTISE, &adv);
+		at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR,
+			MII_LPA, &lpa);
+		media = mii_nway_result(lpa & adv);
+		speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
+			 ? 1 : 0);
+		duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+		debug_cond(VERBOSEP, "%s: link up, %sMbps %s-duplex\n",
+		       netdev->name,
+		       speed ? "100" : "10",
+		       duplex ? "full" : "half");
+	}
+	return 0;
+}
+
+int at91emac_UpdateLinkSpeed(at91_emac_t *emac)
+{
+	unsigned short stat1;
+
+	at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_BMSR, &stat1);
+
+	if (!(stat1 & BMSR_LSTATUS))	/* link status up? */
+		return -1;
+
+	if (stat1 & BMSR_100FULL) {
+		/*set Emac for 100BaseTX and Full Duplex  */
+		writel(readl(&emac->cfg) |
+			AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD,
+			&emac->cfg);
+		return 0;
+	}
+
+	if (stat1 & BMSR_10FULL) {
+		/*set MII for 10BaseT and Full Duplex  */
+		writel((readl(&emac->cfg) &
+			~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD)
+			) | AT91_EMAC_CFG_FD,
+			&emac->cfg);
+		return 0;
+	}
+
+	if (stat1 & BMSR_100HALF) {
+		/*set MII for 100BaseTX and Half Duplex  */
+		writel((readl(&emac->cfg) &
+			~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD)
+			) | AT91_EMAC_CFG_SPD,
+			&emac->cfg);
+		return 0;
+	}
+
+	if (stat1 & BMSR_10HALF) {
+		/*set MII for 10BaseT and Half Duplex  */
+		writel((readl(&emac->cfg) &
+			~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD)),
+			&emac->cfg);
+		return 0;
+	}
+	return 0;
+}
+
+static int at91emac_init(struct eth_device *netdev, bd_t *bd)
+{
+	int i;
+	u32 value;
+	emac_device *dev;
+	at91_emac_t *emac;
+	at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIO;
+	at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;
+
+	emac = (at91_emac_t *) netdev->iobase;
+	dev = (emac_device *) netdev->priv;
+
+	/* PIO Disable Register */
+	value =	ATMEL_PMX_AA_EMDIO |	ATMEL_PMX_AA_EMDC |
+		ATMEL_PMX_AA_ERXER |	ATMEL_PMX_AA_ERX1 |
+		ATMEL_PMX_AA_ERX0 |	ATMEL_PMX_AA_ECRS |
+		ATMEL_PMX_AA_ETX1 |	ATMEL_PMX_AA_ETX0 |
+		ATMEL_PMX_AA_ETXEN |	ATMEL_PMX_AA_EREFCK;
+
+	writel(value, &pio->pioa.pdr);
+	writel(value, &pio->pioa.asr);
+
+#ifdef CONFIG_RMII
+	value = ATMEL_PMX_BA_ERXCK;
+#else
+	value = ATMEL_PMX_BA_ERXCK |	ATMEL_PMX_BA_ECOL |
+		ATMEL_PMX_BA_ERXDV |	ATMEL_PMX_BA_ERX3 |
+		ATMEL_PMX_BA_ERX2 |	ATMEL_PMX_BA_ETXER |
+		ATMEL_PMX_BA_ETX3 |	ATMEL_PMX_BA_ETX2;
+#endif
+	writel(value, &pio->piob.pdr);
+	writel(value, &pio->piob.bsr);
+
+	writel(1 << ATMEL_ID_EMAC, &pmc->pcer);
+	writel(readl(&emac->ctl) | AT91_EMAC_CTL_CSR, &emac->ctl);
+
+	/* Init Ethernet buffers */
+	for (i = 0; i < RBF_FRAMEMAX; i++) {
+		dev->rbfdt[i].addr = (unsigned long) NetRxPackets[i];
+		dev->rbfdt[i].size = 0;
+	}
+	dev->rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP;
+	dev->rbindex = 0;
+	writel((u32) &(dev->rbfdt[0]), &emac->rbqp);
+
+	writel(readl(&emac->rsr) &
+		~(AT91_EMAC_RSR_OVR | AT91_EMAC_RSR_REC | AT91_EMAC_RSR_BNA),
+		&emac->rsr);
+
+	value = AT91_EMAC_CFG_CAF |	AT91_EMAC_CFG_NBC |
+		HCLK_DIV;
+#ifdef CONFIG_RMII
+	value |= AT91_EMAC_CFG_RMII;
+#endif
+	writel(value, &emac->cfg);
+
+	writel(readl(&emac->ctl) | AT91_EMAC_CTL_TE | AT91_EMAC_CTL_RE,
+		&emac->ctl);
+
+	if (!at91emac_phy_init(netdev)) {
+		at91emac_UpdateLinkSpeed(emac);
+		return 0;
+	}
+	return -1;
+}
+
+static void at91emac_halt(struct eth_device *netdev)
+{
+	at91_emac_t *emac;
+
+	emac = (at91_emac_t *) netdev->iobase;
+	writel(readl(&emac->ctl) & ~(AT91_EMAC_CTL_TE | AT91_EMAC_CTL_RE),
+		&emac->ctl);
+	debug_cond(DEBUG_AT91EMAC, "halt MAC\n");
+}
+
+static int at91emac_send(struct eth_device *netdev, void *packet, int length)
+{
+	at91_emac_t *emac;
+
+	emac = (at91_emac_t *) netdev->iobase;
+
+	while (!(readl(&emac->tsr) & AT91_EMAC_TSR_BNQ))
+		;
+	writel((u32) packet, &emac->tar);
+	writel(AT91_EMAC_TCR_LEN(length), &emac->tcr);
+	while (AT91_EMAC_TCR_LEN(readl(&emac->tcr)))
+		;
+	debug_cond(DEBUG_AT91EMAC, "Send %d\n", length);
+	writel(readl(&emac->tsr) | AT91_EMAC_TSR_COMP, &emac->tsr);
+	return 0;
+}
+
+static int at91emac_recv(struct eth_device *netdev)
+{
+	emac_device *dev;
+	at91_emac_t *emac;
+	rbf_t *rbfp;
+	int size;
+
+	emac = (at91_emac_t *) netdev->iobase;
+	dev = (emac_device *) netdev->priv;
+
+	rbfp = &dev->rbfdt[dev->rbindex];
+	while (rbfp->addr & RBF_OWNER)	{
+		size = rbfp->size & RBF_SIZE;
+		NetReceive(NetRxPackets[dev->rbindex], size);
+
+		debug_cond(DEBUG_AT91EMAC, "Recv[%ld]: %d bytes @ %lx\n",
+			dev->rbindex, size, rbfp->addr);
+
+		rbfp->addr &= ~RBF_OWNER;
+		rbfp->size = 0;
+		if (dev->rbindex < (RBF_FRAMEMAX-1))
+			dev->rbindex++;
+		else
+			dev->rbindex = 0;
+
+		rbfp = &(dev->rbfdt[dev->rbindex]);
+		if (!(rbfp->addr & RBF_OWNER))
+			writel(readl(&emac->rsr) | AT91_EMAC_RSR_REC,
+				&emac->rsr);
+	}
+
+	if (readl(&emac->isr) & AT91_EMAC_IxR_RBNA) {
+		/* EMAC silicon bug 41.3.1 workaround 1 */
+		writel(readl(&emac->ctl) & ~AT91_EMAC_CTL_RE, &emac->ctl);
+		writel(readl(&emac->ctl) | AT91_EMAC_CTL_RE, &emac->ctl);
+		dev->rbindex = 0;
+		printf("%s: reset receiver (EMAC dead lock bug)\n",
+			netdev->name);
+	}
+	return 0;
+}
+
+static int at91emac_write_hwaddr(struct eth_device *netdev)
+{
+	at91_emac_t *emac;
+	at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;
+	emac = (at91_emac_t *) netdev->iobase;
+
+	writel(1 << ATMEL_ID_EMAC, &pmc->pcer);
+	debug_cond(DEBUG_AT91EMAC,
+		"init MAC-ADDR %02x:%02x:%02x:%02x:%02x:%02x\n",
+		netdev->enetaddr[5], netdev->enetaddr[4], netdev->enetaddr[3],
+		netdev->enetaddr[2], netdev->enetaddr[1], netdev->enetaddr[0]);
+	writel( (netdev->enetaddr[0] | netdev->enetaddr[1] << 8 |
+			netdev->enetaddr[2] << 16 | netdev->enetaddr[3] << 24),
+			&emac->sa2l);
+	writel((netdev->enetaddr[4] | netdev->enetaddr[5] << 8), &emac->sa2h);
+	debug_cond(DEBUG_AT91EMAC, "init MAC-ADDR %x%x\n",
+		readl(&emac->sa2h), readl(&emac->sa2l));
+	return 0;
+}
+
+int at91emac_register(bd_t *bis, unsigned long iobase)
+{
+	emac_device *emac;
+	emac_device *emacfix;
+	struct eth_device *dev;
+
+	if (iobase == 0)
+		iobase = ATMEL_BASE_EMAC;
+	emac = malloc(sizeof(*emac)+512);
+	if (emac == NULL)
+		return -1;
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL) {
+		free(emac);
+		return -1;
+	}
+	/* alignment as per Errata (64 bytes) is insufficient! */
+	emacfix = (emac_device *) (((unsigned long) emac + 0x1ff) & 0xFFFFFE00);
+	memset(emacfix, 0, sizeof(emac_device));
+
+	memset(dev, 0, sizeof(*dev));
+	sprintf(dev->name, "emac");
+	dev->iobase = iobase;
+	dev->priv = emacfix;
+	dev->init = at91emac_init;
+	dev->halt = at91emac_halt;
+	dev->send = at91emac_send;
+	dev->recv = at91emac_recv;
+	dev->write_hwaddr = at91emac_write_hwaddr;
+
+	eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	miiphy_register(dev->name, at91emac_mii_read, at91emac_mii_write);
+#endif
+	return 1;
+}
diff --git a/marvell/uboot/drivers/net/ax88180.c b/marvell/uboot/drivers/net/ax88180.c
new file mode 100644
index 0000000..7f0cfe5
--- /dev/null
+++ b/marvell/uboot/drivers/net/ax88180.c
@@ -0,0 +1,757 @@
+/*
+ * ax88180: ASIX AX88180 Non-PCI Gigabit Ethernet u-boot driver
+ *
+ * This program is free software; you can distribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ * This program is distributed in the hope it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+ * USA.
+ */
+
+/*
+ * ========================================================================
+ * ASIX AX88180 Non-PCI 16/32-bit Gigabit Ethernet Linux Driver
+ *
+ * The AX88180 Ethernet controller is a high performance and highly
+ * integrated local CPU bus Ethernet controller with embedded 40K bytes
+ * SRAM and supports both 16-bit and 32-bit SRAM-Like interfaces for any
+ * embedded systems.
+ * The AX88180 is a single chip 10/100/1000Mbps Gigabit Ethernet
+ * controller that supports both MII and RGMII interfaces and is
+ * compliant to IEEE 802.3, IEEE 802.3u and IEEE 802.3z standards.
+ *
+ * Please visit ASIX's web site (http://www.asix.com.tw) for more
+ * details.
+ *
+ * Module Name	: ax88180.c
+ * Date		: 2008-07-07
+ * History
+ * 09/06/2006	: New release for AX88180 US2 chip.
+ * 07/07/2008	: Fix up the coding style and using inline functions
+ *		  instead of macros
+ * ========================================================================
+ */
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <malloc.h>
+#include <linux/mii.h>
+#include "ax88180.h"
+
+/*
+ * ===========================================================================
+ * Local SubProgram Declaration
+ * ===========================================================================
+ */
+static void ax88180_rx_handler (struct eth_device *dev);
+static int ax88180_phy_initial (struct eth_device *dev);
+static void ax88180_media_config (struct eth_device *dev);
+static unsigned long get_CicadaPHY_media_mode (struct eth_device *dev);
+static unsigned long get_MarvellPHY_media_mode (struct eth_device *dev);
+static unsigned short ax88180_mdio_read (struct eth_device *dev,
+					 unsigned long regaddr);
+static void ax88180_mdio_write (struct eth_device *dev,
+				unsigned long regaddr, unsigned short regdata);
+
+/*
+ * ===========================================================================
+ * Local SubProgram Bodies
+ * ===========================================================================
+ */
+static int ax88180_mdio_check_complete (struct eth_device *dev)
+{
+	int us_cnt = 10000;
+	unsigned short tmpval;
+
+	/* MDIO read/write should not take more than 10 ms */
+	while (--us_cnt) {
+		tmpval = INW (dev, MDIOCTRL);
+		if (((tmpval & READ_PHY) == 0) && ((tmpval & WRITE_PHY) == 0))
+			break;
+	}
+
+	return us_cnt;
+}
+
+static unsigned short
+ax88180_mdio_read (struct eth_device *dev, unsigned long regaddr)
+{
+	struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
+	unsigned long tmpval = 0;
+
+	OUTW (dev, (READ_PHY | (regaddr << 8) | priv->PhyAddr), MDIOCTRL);
+
+	if (ax88180_mdio_check_complete (dev))
+		tmpval = INW (dev, MDIODP);
+	else
+		printf ("Failed to read PHY register!\n");
+
+	return (unsigned short)(tmpval & 0xFFFF);
+}
+
+static void
+ax88180_mdio_write (struct eth_device *dev, unsigned long regaddr,
+		    unsigned short regdata)
+{
+	struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
+
+	OUTW (dev, regdata, MDIODP);
+
+	OUTW (dev, (WRITE_PHY | (regaddr << 8) | priv->PhyAddr), MDIOCTRL);
+
+	if (!ax88180_mdio_check_complete (dev))
+		printf ("Failed to write PHY register!\n");
+}
+
+static int ax88180_phy_reset (struct eth_device *dev)
+{
+	unsigned short delay_cnt = 500;
+
+	ax88180_mdio_write (dev, MII_BMCR, (BMCR_RESET | BMCR_ANENABLE));
+
+	/* Wait for the reset to complete, or time out (500 ms) */
+	while (ax88180_mdio_read (dev, MII_BMCR) & BMCR_RESET) {
+		udelay (1000);
+		if (--delay_cnt == 0) {
+			printf ("Failed to reset PHY!\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static void ax88180_mac_reset (struct eth_device *dev)
+{
+	unsigned long tmpval;
+	unsigned char i;
+
+	struct {
+		unsigned short offset, value;
+	} program_seq[] = {
+		{
+		MISC, MISC_NORMAL}, {
+		RXINDICATOR, DEFAULT_RXINDICATOR}, {
+		TXCMD, DEFAULT_TXCMD}, {
+		TXBS, DEFAULT_TXBS}, {
+		TXDES0, DEFAULT_TXDES0}, {
+		TXDES1, DEFAULT_TXDES1}, {
+		TXDES2, DEFAULT_TXDES2}, {
+		TXDES3, DEFAULT_TXDES3}, {
+		TXCFG, DEFAULT_TXCFG}, {
+		MACCFG2, DEFAULT_MACCFG2}, {
+		MACCFG3, DEFAULT_MACCFG3}, {
+		TXLEN, DEFAULT_TXLEN}, {
+		RXBTHD0, DEFAULT_RXBTHD0}, {
+		RXBTHD1, DEFAULT_RXBTHD1}, {
+		RXFULTHD, DEFAULT_RXFULTHD}, {
+		DOGTHD0, DEFAULT_DOGTHD0}, {
+	DOGTHD1, DEFAULT_DOGTHD1},};
+
+	OUTW (dev, MISC_RESET_MAC, MISC);
+	tmpval = INW (dev, MISC);
+
+	for (i = 0; i < ARRAY_SIZE(program_seq); i++)
+		OUTW (dev, program_seq[i].value, program_seq[i].offset);
+}
+
+static int ax88180_poll_tx_complete (struct eth_device *dev)
+{
+	struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
+	unsigned long tmpval, txbs_txdp;
+	int TimeOutCnt = 10000;
+
+	txbs_txdp = 1 << priv->NextTxDesc;
+
+	while (TimeOutCnt--) {
+
+		tmpval = INW (dev, TXBS);
+
+		if ((tmpval & txbs_txdp) == 0)
+			break;
+
+		udelay (100);
+	}
+
+	if (TimeOutCnt)
+		return 0;
+	else
+		return -TimeOutCnt;
+}
+
+static void ax88180_rx_handler (struct eth_device *dev)
+{
+	struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
+	unsigned long data_size;
+	unsigned short rxcurt_ptr, rxbound_ptr, next_ptr;
+	int i;
+#if defined (CONFIG_DRIVER_AX88180_16BIT)
+	unsigned short *rxdata = (unsigned short *)NetRxPackets[0];
+#else
+	unsigned long *rxdata = (unsigned long *)NetRxPackets[0];
+#endif
+	unsigned short count;
+
+	rxcurt_ptr = INW (dev, RXCURT);
+	rxbound_ptr = INW (dev, RXBOUND);
+	next_ptr = (rxbound_ptr + 1) & RX_PAGE_NUM_MASK;
+
+	debug ("ax88180: RX original RXBOUND=0x%04x,"
+	       " RXCURT=0x%04x\n", rxbound_ptr, rxcurt_ptr);
+
+	while (next_ptr != rxcurt_ptr) {
+
+		OUTW (dev, RX_START_READ, RXINDICATOR);
+
+		data_size = READ_RXBUF (dev) & 0xFFFF;
+
+		if ((data_size == 0) || (data_size > MAX_RX_SIZE)) {
+
+			OUTW (dev, RX_STOP_READ, RXINDICATOR);
+
+			ax88180_mac_reset (dev);
+			printf ("ax88180: Invalid Rx packet length!"
+				" (len=0x%04lx)\n", data_size);
+
+			debug ("ax88180: RX RXBOUND=0x%04x,"
+			       "RXCURT=0x%04x\n", rxbound_ptr, rxcurt_ptr);
+			return;
+		}
+
+		rxbound_ptr += (((data_size + 0xF) & 0xFFF0) >> 4) + 1;
+		rxbound_ptr &= RX_PAGE_NUM_MASK;
+
+		/* Comput access times */
+		count = (data_size + priv->PadSize) >> priv->BusWidth;
+
+		for (i = 0; i < count; i++) {
+			*(rxdata + i) = READ_RXBUF (dev);
+		}
+
+		OUTW (dev, RX_STOP_READ, RXINDICATOR);
+
+		/* Pass the packet up to the protocol layers. */
+		NetReceive (NetRxPackets[0], data_size);
+
+		OUTW (dev, rxbound_ptr, RXBOUND);
+
+		rxcurt_ptr = INW (dev, RXCURT);
+		rxbound_ptr = INW (dev, RXBOUND);
+		next_ptr = (rxbound_ptr + 1) & RX_PAGE_NUM_MASK;
+
+		debug ("ax88180: RX updated RXBOUND=0x%04x,"
+		       "RXCURT=0x%04x\n", rxbound_ptr, rxcurt_ptr);
+	}
+
+	return;
+}
+
+static int ax88180_phy_initial (struct eth_device *dev)
+{
+	struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
+	unsigned long tmp_regval;
+	unsigned short phyaddr;
+
+	/* Search for first avaliable PHY chipset */
+#ifdef CONFIG_PHY_ADDR
+	phyaddr = CONFIG_PHY_ADDR;
+#else
+	for (phyaddr = 0; phyaddr < 32; ++phyaddr)
+#endif
+	{
+		priv->PhyAddr = phyaddr;
+		priv->PhyID0 = ax88180_mdio_read(dev, MII_PHYSID1);
+		priv->PhyID1 = ax88180_mdio_read(dev, MII_PHYSID2);
+
+		switch (priv->PhyID0) {
+		case MARVELL_ALASKA_PHYSID0:
+			debug("ax88180: Found Marvell Alaska PHY family."
+			      " (PHY Addr=0x%x)\n", priv->PhyAddr);
+
+			switch (priv->PhyID1) {
+			case MARVELL_88E1118_PHYSID1:
+				ax88180_mdio_write(dev, M88E1118_PAGE_SEL, 2);
+				ax88180_mdio_write(dev, M88E1118_CR,
+					M88E1118_CR_DEFAULT);
+				ax88180_mdio_write(dev, M88E1118_PAGE_SEL, 3);
+				ax88180_mdio_write(dev, M88E1118_LEDCTL,
+					M88E1118_LEDCTL_DEFAULT);
+				ax88180_mdio_write(dev, M88E1118_LEDMIX,
+					M88E1118_LEDMIX_LED050 | M88E1118_LEDMIX_LED150 | 0x15);
+				ax88180_mdio_write(dev, M88E1118_PAGE_SEL, 0);
+			default: /* Default to 88E1111 Phy */
+				tmp_regval = ax88180_mdio_read(dev, M88E1111_EXT_SSR);
+				if ((tmp_regval & HWCFG_MODE_MASK) != RGMII_COPPER_MODE)
+					ax88180_mdio_write(dev, M88E1111_EXT_SCR,
+						DEFAULT_EXT_SCR);
+			}
+
+			if (ax88180_phy_reset(dev) < 0)
+				return 0;
+			ax88180_mdio_write(dev, M88_IER, LINK_CHANGE_INT);
+
+			return 1;
+
+		case CICADA_CIS8201_PHYSID0:
+			debug("ax88180: Found CICADA CIS8201 PHY"
+			      " chipset. (PHY Addr=0x%x)\n", priv->PhyAddr);
+
+			ax88180_mdio_write(dev, CIS_IMR,
+					    (CIS_INT_ENABLE | LINK_CHANGE_INT));
+
+			/* Set CIS_SMI_PRIORITY bit before force the media mode */
+			tmp_regval = ax88180_mdio_read(dev, CIS_AUX_CTRL_STATUS);
+			tmp_regval &= ~CIS_SMI_PRIORITY;
+			ax88180_mdio_write(dev, CIS_AUX_CTRL_STATUS, tmp_regval);
+
+			return 1;
+
+		case 0xffff:
+			/* No PHY at this addr */
+			break;
+
+		default:
+			printf("ax88180: Unknown PHY chipset %#x at addr %#x\n",
+			       priv->PhyID0, priv->PhyAddr);
+			break;
+		}
+	}
+
+	printf("ax88180: Unknown PHY chipset!!\n");
+	return 0;
+}
+
+static void ax88180_media_config (struct eth_device *dev)
+{
+	struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
+	unsigned long bmcr_val, bmsr_val;
+	unsigned long rxcfg_val, maccfg0_val, maccfg1_val;
+	unsigned long RealMediaMode;
+	int i;
+
+	/* Waiting 2 seconds for PHY link stable */
+	for (i = 0; i < 20000; i++) {
+		bmsr_val = ax88180_mdio_read (dev, MII_BMSR);
+		if (bmsr_val & BMSR_LSTATUS) {
+			break;
+		}
+		udelay (100);
+	}
+
+	bmsr_val = ax88180_mdio_read (dev, MII_BMSR);
+	debug ("ax88180: BMSR=0x%04x\n", (unsigned int)bmsr_val);
+
+	if (bmsr_val & BMSR_LSTATUS) {
+		bmcr_val = ax88180_mdio_read (dev, MII_BMCR);
+
+		if (bmcr_val & BMCR_ANENABLE) {
+
+			/*
+			 * Waiting for Auto-negotiation completion, this may
+			 * take up to 5 seconds.
+			 */
+			debug ("ax88180: Auto-negotiation is "
+			       "enabled. Waiting for NWay completion..\n");
+			for (i = 0; i < 50000; i++) {
+				bmsr_val = ax88180_mdio_read (dev, MII_BMSR);
+				if (bmsr_val & BMSR_ANEGCOMPLETE) {
+					break;
+				}
+				udelay (100);
+			}
+		} else
+			debug ("ax88180: Auto-negotiation is disabled.\n");
+
+		debug ("ax88180: BMCR=0x%04x, BMSR=0x%04x\n",
+		       (unsigned int)bmcr_val, (unsigned int)bmsr_val);
+
+		/* Get real media mode here */
+		switch (priv->PhyID0) {
+		case MARVELL_ALASKA_PHYSID0:
+			RealMediaMode = get_MarvellPHY_media_mode(dev);
+			break;
+		case CICADA_CIS8201_PHYSID0:
+			RealMediaMode = get_CicadaPHY_media_mode(dev);
+			break;
+		default:
+			RealMediaMode = MEDIA_1000FULL;
+			break;
+		}
+
+		priv->LinkState = INS_LINK_UP;
+
+		switch (RealMediaMode) {
+		case MEDIA_1000FULL:
+			debug ("ax88180: 1000Mbps Full-duplex mode.\n");
+			rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
+			maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0;
+			maccfg1_val = GIGA_MODE_EN | RXFLOW_EN |
+			    FULLDUPLEX | DEFAULT_MACCFG1;
+			break;
+
+		case MEDIA_1000HALF:
+			debug ("ax88180: 1000Mbps Half-duplex mode.\n");
+			rxcfg_val = DEFAULT_RXCFG;
+			maccfg0_val = DEFAULT_MACCFG0;
+			maccfg1_val = GIGA_MODE_EN | DEFAULT_MACCFG1;
+			break;
+
+		case MEDIA_100FULL:
+			debug ("ax88180: 100Mbps Full-duplex mode.\n");
+			rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
+			maccfg0_val = SPEED100 | TXFLOW_ENABLE
+			    | DEFAULT_MACCFG0;
+			maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1;
+			break;
+
+		case MEDIA_100HALF:
+			debug ("ax88180: 100Mbps Half-duplex mode.\n");
+			rxcfg_val = DEFAULT_RXCFG;
+			maccfg0_val = SPEED100 | DEFAULT_MACCFG0;
+			maccfg1_val = DEFAULT_MACCFG1;
+			break;
+
+		case MEDIA_10FULL:
+			debug ("ax88180: 10Mbps Full-duplex mode.\n");
+			rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
+			maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0;
+			maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1;
+			break;
+
+		case MEDIA_10HALF:
+			debug ("ax88180: 10Mbps Half-duplex mode.\n");
+			rxcfg_val = DEFAULT_RXCFG;
+			maccfg0_val = DEFAULT_MACCFG0;
+			maccfg1_val = DEFAULT_MACCFG1;
+			break;
+		default:
+			debug ("ax88180: Unknow media mode.\n");
+			rxcfg_val = DEFAULT_RXCFG;
+			maccfg0_val = DEFAULT_MACCFG0;
+			maccfg1_val = DEFAULT_MACCFG1;
+
+			priv->LinkState = INS_LINK_DOWN;
+			break;
+		}
+
+	} else {
+		rxcfg_val = DEFAULT_RXCFG;
+		maccfg0_val = DEFAULT_MACCFG0;
+		maccfg1_val = DEFAULT_MACCFG1;
+
+		priv->LinkState = INS_LINK_DOWN;
+	}
+
+	OUTW (dev, rxcfg_val, RXCFG);
+	OUTW (dev, maccfg0_val, MACCFG0);
+	OUTW (dev, maccfg1_val, MACCFG1);
+
+	return;
+}
+
+static unsigned long get_MarvellPHY_media_mode (struct eth_device *dev)
+{
+	unsigned long m88_ssr;
+	unsigned long MediaMode;
+
+	m88_ssr = ax88180_mdio_read (dev, M88_SSR);
+	switch (m88_ssr & SSR_MEDIA_MASK) {
+	case SSR_1000FULL:
+		MediaMode = MEDIA_1000FULL;
+		break;
+	case SSR_1000HALF:
+		MediaMode = MEDIA_1000HALF;
+		break;
+	case SSR_100FULL:
+		MediaMode = MEDIA_100FULL;
+		break;
+	case SSR_100HALF:
+		MediaMode = MEDIA_100HALF;
+		break;
+	case SSR_10FULL:
+		MediaMode = MEDIA_10FULL;
+		break;
+	case SSR_10HALF:
+		MediaMode = MEDIA_10HALF;
+		break;
+	default:
+		MediaMode = MEDIA_UNKNOWN;
+		break;
+	}
+
+	return MediaMode;
+}
+
+static unsigned long get_CicadaPHY_media_mode (struct eth_device *dev)
+{
+	unsigned long tmp_regval;
+	unsigned long MediaMode;
+
+	tmp_regval = ax88180_mdio_read (dev, CIS_AUX_CTRL_STATUS);
+	switch (tmp_regval & CIS_MEDIA_MASK) {
+	case CIS_1000FULL:
+		MediaMode = MEDIA_1000FULL;
+		break;
+	case CIS_1000HALF:
+		MediaMode = MEDIA_1000HALF;
+		break;
+	case CIS_100FULL:
+		MediaMode = MEDIA_100FULL;
+		break;
+	case CIS_100HALF:
+		MediaMode = MEDIA_100HALF;
+		break;
+	case CIS_10FULL:
+		MediaMode = MEDIA_10FULL;
+		break;
+	case CIS_10HALF:
+		MediaMode = MEDIA_10HALF;
+		break;
+	default:
+		MediaMode = MEDIA_UNKNOWN;
+		break;
+	}
+
+	return MediaMode;
+}
+
+static void ax88180_halt (struct eth_device *dev)
+{
+	/* Disable AX88180 TX/RX functions */
+	OUTW (dev, WAKEMOD, CMD);
+}
+
+static int ax88180_init (struct eth_device *dev, bd_t * bd)
+{
+	struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
+	unsigned short tmp_regval;
+
+	ax88180_mac_reset (dev);
+
+	/* Disable interrupt */
+	OUTW (dev, CLEAR_IMR, IMR);
+
+	/* Disable AX88180 TX/RX functions */
+	OUTW (dev, WAKEMOD, CMD);
+
+	/* Fill the MAC address */
+	tmp_regval =
+	    dev->enetaddr[0] | (((unsigned short)dev->enetaddr[1]) << 8);
+	OUTW (dev, tmp_regval, MACID0);
+
+	tmp_regval =
+	    dev->enetaddr[2] | (((unsigned short)dev->enetaddr[3]) << 8);
+	OUTW (dev, tmp_regval, MACID1);
+
+	tmp_regval =
+	    dev->enetaddr[4] | (((unsigned short)dev->enetaddr[5]) << 8);
+	OUTW (dev, tmp_regval, MACID2);
+
+	ax88180_media_config (dev);
+
+	OUTW (dev, DEFAULT_RXFILTER, RXFILTER);
+
+	/* Initial variables here */
+	priv->FirstTxDesc = TXDP0;
+	priv->NextTxDesc = TXDP0;
+
+	/* Check if there is any invalid interrupt status and clear it. */
+	OUTW (dev, INW (dev, ISR), ISR);
+
+	/* Start AX88180 TX/RX functions */
+	OUTW (dev, (RXEN | TXEN | WAKEMOD), CMD);
+
+	return 0;
+}
+
+/* Get a data block via Ethernet */
+static int ax88180_recv (struct eth_device *dev)
+{
+	unsigned short ISR_Status;
+	unsigned short tmp_regval;
+
+	/* Read and check interrupt status here. */
+	ISR_Status = INW (dev, ISR);
+
+	while (ISR_Status) {
+		/* Clear the interrupt status */
+		OUTW (dev, ISR_Status, ISR);
+
+		debug ("\nax88180: The interrupt status = 0x%04x\n",
+		       ISR_Status);
+
+		if (ISR_Status & ISR_PHY) {
+			/* Read ISR register once to clear PHY interrupt bit */
+			tmp_regval = ax88180_mdio_read (dev, M88_ISR);
+			ax88180_media_config (dev);
+		}
+
+		if ((ISR_Status & ISR_RX) || (ISR_Status & ISR_RXBUFFOVR)) {
+			ax88180_rx_handler (dev);
+		}
+
+		/* Read and check interrupt status again */
+		ISR_Status = INW (dev, ISR);
+	}
+
+	return 0;
+}
+
+/* Send a data block via Ethernet. */
+static int ax88180_send(struct eth_device *dev, void *packet, int length)
+{
+	struct ax88180_private *priv = (struct ax88180_private *)dev->priv;
+	unsigned short TXDES_addr;
+	unsigned short txcmd_txdp, txbs_txdp;
+	unsigned short tmp_data;
+	int i;
+#if defined (CONFIG_DRIVER_AX88180_16BIT)
+	volatile unsigned short *txdata = (volatile unsigned short *)packet;
+#else
+	volatile unsigned long *txdata = (volatile unsigned long *)packet;
+#endif
+	unsigned short count;
+
+	if (priv->LinkState != INS_LINK_UP) {
+		return 0;
+	}
+
+	priv->FirstTxDesc = priv->NextTxDesc;
+	txbs_txdp = 1 << priv->FirstTxDesc;
+
+	debug ("ax88180: TXDP%d is available\n", priv->FirstTxDesc);
+
+	txcmd_txdp = priv->FirstTxDesc << 13;
+	TXDES_addr = TXDES0 + (priv->FirstTxDesc << 2);
+
+	OUTW (dev, (txcmd_txdp | length | TX_START_WRITE), TXCMD);
+
+	/* Comput access times */
+	count = (length + priv->PadSize) >> priv->BusWidth;
+
+	for (i = 0; i < count; i++) {
+		WRITE_TXBUF (dev, *(txdata + i));
+	}
+
+	OUTW (dev, txcmd_txdp | length, TXCMD);
+	OUTW (dev, txbs_txdp, TXBS);
+	OUTW (dev, (TXDPx_ENABLE | length), TXDES_addr);
+
+	priv->NextTxDesc = (priv->NextTxDesc + 1) & TXDP_MASK;
+
+	/*
+	 * Check the available transmit descriptor, if we had exhausted all
+	 * transmit descriptor ,then we have to wait for at least one free
+	 * descriptor
+	 */
+	txbs_txdp = 1 << priv->NextTxDesc;
+	tmp_data = INW (dev, TXBS);
+
+	if (tmp_data & txbs_txdp) {
+		if (ax88180_poll_tx_complete (dev) < 0) {
+			ax88180_mac_reset (dev);
+			priv->FirstTxDesc = TXDP0;
+			priv->NextTxDesc = TXDP0;
+			printf ("ax88180: Transmit time out occurred!\n");
+		}
+	}
+
+	return 0;
+}
+
+static void ax88180_read_mac_addr (struct eth_device *dev)
+{
+	unsigned short macid0_val, macid1_val, macid2_val;
+	unsigned short tmp_regval;
+	unsigned short i;
+
+	/* Reload MAC address from EEPROM */
+	OUTW (dev, RELOAD_EEPROM, PROMCTRL);
+
+	/* Waiting for reload eeprom completion */
+	for (i = 0; i < 500; i++) {
+		tmp_regval = INW (dev, PROMCTRL);
+		if ((tmp_regval & RELOAD_EEPROM) == 0)
+			break;
+		udelay (1000);
+	}
+
+	/* Get MAC addresses */
+	macid0_val = INW (dev, MACID0);
+	macid1_val = INW (dev, MACID1);
+	macid2_val = INW (dev, MACID2);
+
+	if (((macid0_val | macid1_val | macid2_val) != 0) &&
+	    ((macid0_val & 0x01) == 0)) {
+		dev->enetaddr[0] = (unsigned char)macid0_val;
+		dev->enetaddr[1] = (unsigned char)(macid0_val >> 8);
+		dev->enetaddr[2] = (unsigned char)macid1_val;
+		dev->enetaddr[3] = (unsigned char)(macid1_val >> 8);
+		dev->enetaddr[4] = (unsigned char)macid2_val;
+		dev->enetaddr[5] = (unsigned char)(macid2_val >> 8);
+	}
+}
+
+/*
+===========================================================================
+<<<<<<			Exported SubProgram Bodies		>>>>>>
+===========================================================================
+*/
+int ax88180_initialize (bd_t * bis)
+{
+	struct eth_device *dev;
+	struct ax88180_private *priv;
+
+	dev = (struct eth_device *)malloc (sizeof *dev);
+
+	if (NULL == dev)
+		return 0;
+
+	memset (dev, 0, sizeof *dev);
+
+	priv = (struct ax88180_private *)malloc (sizeof (*priv));
+
+	if (NULL == priv)
+		return 0;
+
+	memset (priv, 0, sizeof *priv);
+
+	sprintf (dev->name, "ax88180");
+	dev->iobase = AX88180_BASE;
+	dev->priv = priv;
+	dev->init = ax88180_init;
+	dev->halt = ax88180_halt;
+	dev->send = ax88180_send;
+	dev->recv = ax88180_recv;
+
+	priv->BusWidth = BUS_WIDTH_32;
+	priv->PadSize = 3;
+#if defined (CONFIG_DRIVER_AX88180_16BIT)
+	OUTW (dev, (START_BASE >> 8), BASE);
+	OUTW (dev, DECODE_EN, DECODE);
+
+	priv->BusWidth = BUS_WIDTH_16;
+	priv->PadSize = 1;
+#endif
+
+	ax88180_mac_reset (dev);
+
+	/* Disable interrupt */
+	OUTW (dev, CLEAR_IMR, IMR);
+
+	/* Disable AX88180 TX/RX functions */
+	OUTW (dev, WAKEMOD, CMD);
+
+	ax88180_read_mac_addr (dev);
+
+	eth_register (dev);
+
+	return ax88180_phy_initial (dev);
+
+}
diff --git a/marvell/uboot/drivers/net/ax88180.h b/marvell/uboot/drivers/net/ax88180.h
new file mode 100644
index 0000000..daf18e0
--- /dev/null
+++ b/marvell/uboot/drivers/net/ax88180.h
@@ -0,0 +1,396 @@
+/* ax88180.h: ASIX AX88180 Non-PCI Gigabit Ethernet u-boot driver */
+/*
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _AX88180_H_
+#define _AX88180_H_
+
+#include <asm/io.h>
+#include <asm/types.h>
+#include <config.h>
+
+typedef enum _ax88180_link_state {
+	INS_LINK_DOWN,
+	INS_LINK_UP,
+	INS_LINK_UNKNOWN
+} ax88180_link_state;
+
+struct ax88180_private {
+	unsigned char BusWidth;
+	unsigned char PadSize;
+	unsigned short PhyAddr;
+	unsigned short PhyID0;
+	unsigned short PhyID1;
+	unsigned short FirstTxDesc;
+	unsigned short NextTxDesc;
+	ax88180_link_state LinkState;
+};
+
+#define BUS_WIDTH_16			1
+#define BUS_WIDTH_32			2
+
+#define ENABLE_JUMBO			1
+#define DISABLE_JUMBO			0
+
+#define ENABLE_BURST			1
+#define DISABLE_BURST			0
+
+#define NORMAL_RX_MODE		0
+#define RX_LOOPBACK_MODE		1
+#define RX_INIFINIT_LOOP_MODE		2
+#define TX_INIFINIT_LOOP_MODE		3
+
+#define DEFAULT_ETH_MTU		1500
+
+/* Jumbo packet size 4086 bytes included 4 bytes CRC*/
+#define MAX_JUMBO_MTU		4072
+
+/* Max Tx Jumbo size 4086 bytes included 4 bytes CRC */
+#define MAX_TX_JUMBO_SIZE		4086
+
+/* Max Rx Jumbo size is 15K Bytes */
+#define MAX_RX_SIZE			0x3C00
+
+#define MARVELL_ALASKA_PHYSID0	0x141
+#define MARVELL_88E1118_PHYSID1	0xE40
+
+#define CICADA_CIS8201_PHYSID0		0x000F
+
+#define MEDIA_AUTO			0
+#define MEDIA_1000FULL			1
+#define MEDIA_1000HALF			2
+#define MEDIA_100FULL			3
+#define MEDIA_100HALF			4
+#define MEDIA_10FULL			5
+#define MEDIA_10HALF			6
+#define MEDIA_UNKNOWN		7
+
+#define AUTO_MEDIA			0
+#define FORCE_MEDIA			1
+
+#define TXDP_MASK			3
+#define TXDP0				0
+#define TXDP1				1
+#define TXDP2				2
+#define TXDP3				3
+
+#define CMD_MAP_SIZE			0x100
+
+#if defined (CONFIG_DRIVER_AX88180_16BIT)
+  #define AX88180_MEMORY_SIZE		0x00004000
+  #define START_BASE			0x1000
+
+  #define RX_BUF_SIZE			0x1000
+  #define TX_BUF_SIZE			0x0F00
+
+  #define TX_BASE			START_BASE
+  #define CMD_BASE			(TX_BASE + TX_BUF_SIZE)
+  #define RX_BASE			(CMD_BASE + CMD_MAP_SIZE)
+#else
+  #define AX88180_MEMORY_SIZE	0x00010000
+
+  #define RX_BUF_SIZE			0x8000
+  #define TX_BUF_SIZE			0x7C00
+
+  #define RX_BASE			0x0000
+  #define TX_BASE			(RX_BASE + RX_BUF_SIZE)
+  #define CMD_BASE			(TX_BASE + TX_BUF_SIZE)
+#endif
+
+/* AX88180 Memory Mapping Definition */
+#define RXBUFFER_START			RX_BASE
+  #define RX_PACKET_LEN_OFFSET	0
+  #define RX_PAGE_NUM_MASK		0x7FF	/* RX pages 0~7FFh */
+#define TXBUFFER_START			TX_BASE
+
+/* AX88180 MAC Register Definition */
+#define DECODE		(0)
+  #define DECODE_EN		0x00000001
+#define BASE		(6)
+#define CMD		(CMD_BASE + 0x0000)
+  #define WAKEMOD		0x00000001
+  #define TXEN			0x00000100
+  #define RXEN			0x00000200
+  #define DEFAULT_CMD		WAKEMOD
+#define IMR		(CMD_BASE + 0x0004)
+  #define IMR_RXBUFFOVR	0x00000001
+  #define IMR_WATCHDOG	0x00000002
+  #define IMR_TX		0x00000008
+  #define IMR_RX		0x00000010
+  #define IMR_PHY		0x00000020
+  #define CLEAR_IMR		0x00000000
+  #define DEFAULT_IMR		(IMR_PHY | IMR_RX | IMR_TX |\
+					 IMR_RXBUFFOVR | IMR_WATCHDOG)
+#define ISR		(CMD_BASE + 0x0008)
+  #define ISR_RXBUFFOVR	0x00000001
+  #define ISR_WATCHDOG	0x00000002
+  #define ISR_TX			0x00000008
+  #define ISR_RX			0x00000010
+  #define ISR_PHY		0x00000020
+#define TXCFG		(CMD_BASE + 0x0010)
+  #define AUTOPAD_CRC		0x00000050
+  #define DEFAULT_TXCFG	AUTOPAD_CRC
+#define TXCMD		(CMD_BASE + 0x0014)
+  #define TXCMD_TXDP_MASK	0x00006000
+  #define TXCMD_TXDP0		0x00000000
+  #define TXCMD_TXDP1		0x00002000
+  #define TXCMD_TXDP2		0x00004000
+  #define TXCMD_TXDP3		0x00006000
+  #define TX_START_WRITE	0x00008000
+  #define TX_STOP_WRITE		0x00000000
+  #define DEFAULT_TXCMD	0x00000000
+#define TXBS		(CMD_BASE + 0x0018)
+  #define TXDP0_USED		0x00000001
+  #define TXDP1_USED		0x00000002
+  #define TXDP2_USED		0x00000004
+  #define TXDP3_USED		0x00000008
+  #define DEFAULT_TXBS		0x00000000
+#define TXDES0		(CMD_BASE + 0x0020)
+  #define TXDPx_ENABLE		0x00008000
+  #define TXDPx_LEN_MASK	0x00001FFF
+  #define DEFAULT_TXDES0	0x00000000
+#define TXDES1		(CMD_BASE + 0x0024)
+  #define TXDPx_ENABLE		0x00008000
+  #define TXDPx_LEN_MASK	0x00001FFF
+  #define DEFAULT_TXDES1	0x00000000
+#define TXDES2		(CMD_BASE + 0x0028)
+  #define TXDPx_ENABLE		0x00008000
+  #define TXDPx_LEN_MASK	0x00001FFF
+  #define DEFAULT_TXDES2	0x00000000
+#define TXDES3		(CMD_BASE + 0x002C)
+  #define TXDPx_ENABLE		0x00008000
+  #define TXDPx_LEN_MASK	0x00001FFF
+  #define DEFAULT_TXDES3	0x00000000
+#define RXCFG		(CMD_BASE + 0x0030)
+  #define RXBUFF_PROTECT	0x00000001
+  #define RXTCPCRC_CHECK	0x00000010
+  #define RXFLOW_ENABLE	0x00000100
+  #define DEFAULT_RXCFG	RXBUFF_PROTECT
+#define RXCURT		(CMD_BASE + 0x0034)
+  #define DEFAULT_RXCURT	0x00000000
+#define RXBOUND	(CMD_BASE + 0x0038)
+  #define DEFAULT_RXBOUND	0x7FF		/* RX pages 0~7FFh */
+#define MACCFG0	(CMD_BASE + 0x0040)
+  #define MACCFG0_BIT3_0	0x00000007
+  #define IPGT_VAL		0x00000150
+  #define TXFLOW_ENABLE	0x00001000
+  #define SPEED100		0x00008000
+  #define DEFAULT_MACCFG0	(IPGT_VAL | MACCFG0_BIT3_0)
+#define MACCFG1	(CMD_BASE + 0x0044)
+  #define RGMII_EN		0x00000002
+  #define RXFLOW_EN		0x00000020
+  #define FULLDUPLEX		0x00000040
+  #define MAX_JUMBO_LEN	0x00000780
+  #define RXJUMBO_EN		0x00000800
+  #define GIGA_MODE_EN	0x00001000
+  #define RXCRC_CHECK		0x00002000
+  #define RXPAUSE_DA_CHECK	0x00004000
+
+  #define JUMBO_LEN_4K		0x00000200
+  #define JUMBO_LEN_15K	0x00000780
+  #define DEFAULT_MACCFG1	(RXCRC_CHECK | RXPAUSE_DA_CHECK | \
+				 RGMII_EN)
+  #define CICADA_DEFAULT_MACCFG1	(RXCRC_CHECK | RXPAUSE_DA_CHECK)
+#define MACCFG2		(CMD_BASE + 0x0048)
+  #define MACCFG2_BIT15_8	0x00000100
+  #define JAM_LIMIT_MASK	0x000000FC
+  #define DEFAULT_JAM_LIMIT	0x00000064
+  #define DEFAULT_MACCFG2	MACCFG2_BIT15_8
+#define MACCFG3		(CMD_BASE + 0x004C)
+  #define IPGR2_VAL		0x0000000E
+  #define IPGR1_VAL		0x00000600
+  #define NOABORT		0x00008000
+  #define DEFAULT_MACCFG3	(IPGR1_VAL | IPGR2_VAL)
+#define TXPAUT		(CMD_BASE + 0x0054)
+  #define DEFAULT_TXPAUT	0x001FE000
+#define RXBTHD0		(CMD_BASE + 0x0058)
+  #define DEFAULT_RXBTHD0	0x00000300
+#define RXBTHD1		(CMD_BASE + 0x005C)
+  #define DEFAULT_RXBTHD1	0x00000600
+#define RXFULTHD	(CMD_BASE + 0x0060)
+  #define DEFAULT_RXFULTHD	0x00000100
+#define MISC		(CMD_BASE + 0x0068)
+  /* Normal operation mode */
+  #define MISC_NORMAL		0x00000003
+  /* Clear bit 0 to reset MAC */
+  #define MISC_RESET_MAC	0x00000002
+  /* Clear bit 1 to reset PHY */
+  #define MISC_RESET_PHY	0x00000001
+  /* Clear bit 0 and 1 to reset MAC and PHY */
+  #define MISC_RESET_MAC_PHY	0x00000000
+  #define DEFAULT_MISC		MISC_NORMAL
+#define MACID0		(CMD_BASE + 0x0070)
+#define MACID1		(CMD_BASE + 0x0074)
+#define MACID2		(CMD_BASE + 0x0078)
+#define TXLEN		(CMD_BASE + 0x007C)
+  #define DEFAULT_TXLEN	0x000005FC
+#define RXFILTER	(CMD_BASE + 0x0080)
+  #define RX_RXANY		0x00000001
+  #define RX_MULTICAST		0x00000002
+  #define RX_UNICAST		0x00000004
+  #define RX_BROADCAST	0x00000008
+  #define RX_MULTI_HASH	0x00000010
+  #define DISABLE_RXFILTER	0x00000000
+  #define DEFAULT_RXFILTER	(RX_BROADCAST + RX_UNICAST)
+#define MDIOCTRL	(CMD_BASE + 0x0084)
+  #define PHY_ADDR_MASK	0x0000001F
+  #define REG_ADDR_MASK	0x00001F00
+  #define READ_PHY		0x00004000
+  #define WRITE_PHY		0x00008000
+#define MDIODP		(CMD_BASE + 0x0088)
+#define GPIOCTRL	(CMD_BASE + 0x008C)
+#define RXINDICATOR	(CMD_BASE + 0x0090)
+  #define RX_START_READ	0x00000001
+  #define RX_STOP_READ		0x00000000
+  #define DEFAULT_RXINDICATOR	RX_STOP_READ
+#define TXST		(CMD_BASE + 0x0094)
+#define MDCCLKPAT	(CMD_BASE + 0x00A0)
+#define RXIPCRCCNT	(CMD_BASE + 0x00A4)
+#define RXCRCCNT	(CMD_BASE + 0x00A8)
+#define TXFAILCNT	(CMD_BASE + 0x00AC)
+#define PROMDP		(CMD_BASE + 0x00B0)
+#define PROMCTRL	(CMD_BASE + 0x00B4)
+  #define RELOAD_EEPROM	0x00000200
+#define MAXRXLEN	(CMD_BASE + 0x00B8)
+#define HASHTAB0	(CMD_BASE + 0x00C0)
+#define HASHTAB1	(CMD_BASE + 0x00C4)
+#define HASHTAB2	(CMD_BASE + 0x00C8)
+#define HASHTAB3	(CMD_BASE + 0x00CC)
+#define DOGTHD0	(CMD_BASE + 0x00E0)
+  #define DEFAULT_DOGTHD0	0x0000FFFF
+#define DOGTHD1	(CMD_BASE + 0x00E4)
+  #define START_WATCHDOG_TIMER	0x00008000
+  #define DEFAULT_DOGTHD1		0x00000FFF
+#define SOFTRST		(CMD_BASE + 0x00EC)
+  #define SOFTRST_NORMAL	0x00000003
+  #define SOFTRST_RESET_MAC	0x00000002
+
+/* Marvell 88E1111 Gigabit PHY Register Definition */
+#define M88_SSR		0x0011
+  #define SSR_SPEED_MASK	0xC000
+  #define SSR_SPEED_1000		0x8000
+  #define SSR_SPEED_100		0x4000
+  #define SSR_SPEED_10		0x0000
+  #define SSR_DUPLEX		0x2000
+  #define SSR_MEDIA_RESOLVED_OK	0x0800
+
+  #define SSR_MEDIA_MASK	(SSR_SPEED_MASK | SSR_DUPLEX)
+  #define SSR_1000FULL		(SSR_SPEED_1000 | SSR_DUPLEX)
+  #define SSR_1000HALF		SSR_SPEED_1000
+  #define SSR_100FULL		(SSR_SPEED_100 | SSR_DUPLEX)
+  #define SSR_100HALF		SSR_SPEED_100
+  #define SSR_10FULL		(SSR_SPEED_10 | SSR_DUPLEX)
+  #define SSR_10HALF		SSR_SPEED_10
+#define M88_IER		0x0012
+  #define LINK_CHANGE_INT	0x0400
+#define M88_ISR		0x0013
+  #define LINK_CHANGE_STATUS	0x0400
+#define M88E1111_EXT_SCR	0x0014
+  #define RGMII_RXCLK_DELAY	0x0080
+  #define RGMII_TXCLK_DELAY	0x0002
+  #define DEFAULT_EXT_SCR	(RGMII_TXCLK_DELAY | RGMII_RXCLK_DELAY)
+#define M88E1111_EXT_SSR	0x001B
+  #define HWCFG_MODE_MASK	0x000F
+  #define RGMII_COPPER_MODE	0x000B
+
+/* Marvell 88E1118 Gigabit PHY Register Definition */
+#define M88E1118_CR			0x14
+  #define M88E1118_CR_RGMII_RXCLK_DELAY	0x0020
+  #define M88E1118_CR_RGMII_TXCLK_DELAY	0x0010
+  #define M88E1118_CR_DEFAULT		(M88E1118_CR_RGMII_TXCLK_DELAY | \
+					 M88E1118_CR_RGMII_RXCLK_DELAY)
+#define M88E1118_LEDCTL		0x10		/* Reg 16 on page 3 */
+  #define M88E1118_LEDCTL_LED2INT			0x200
+  #define M88E1118_LEDCTL_LED2BLNK			0x400
+  #define M88E1118_LEDCTL_LED0DUALMODE1	0xc
+  #define M88E1118_LEDCTL_LED0DUALMODE2	0xd
+  #define M88E1118_LEDCTL_LED0DUALMODE3	0xe
+  #define M88E1118_LEDCTL_LED0DUALMODE4	0xf
+  #define M88E1118_LEDCTL_DEFAULT	(M88E1118_LEDCTL_LED2BLNK | \
+					 M88E1118_LEDCTL_LED0DUALMODE4)
+
+#define M88E1118_LEDMIX		0x11		/* Reg 17 on page 3 */
+  #define M88E1118_LEDMIX_LED050				0x4
+  #define M88E1118_LEDMIX_LED150				0x8
+
+#define M88E1118_PAGE_SEL	0x16		/* Reg page select */
+
+/* CICADA CIS8201 Gigabit PHY Register Definition */
+#define CIS_IMR		0x0019
+  #define CIS_INT_ENABLE	0x8000
+  #define CIS_LINK_CHANGE_INT	0x2000
+#define CIS_ISR		0x001A
+  #define CIS_INT_PENDING	0x8000
+  #define CIS_LINK_CHANGE_STATUS	0x2000
+#define CIS_AUX_CTRL_STATUS	0x001C
+  #define CIS_AUTONEG_COMPLETE	0x8000
+  #define CIS_SPEED_MASK	0x0018
+  #define CIS_SPEED_1000		0x0010
+  #define CIS_SPEED_100		0x0008
+  #define CIS_SPEED_10		0x0000
+  #define CIS_DUPLEX		0x0020
+
+  #define CIS_MEDIA_MASK	(CIS_SPEED_MASK | CIS_DUPLEX)
+  #define CIS_1000FULL		(CIS_SPEED_1000 | CIS_DUPLEX)
+  #define CIS_1000HALF		CIS_SPEED_1000
+  #define CIS_100FULL		(CIS_SPEED_100 | CIS_DUPLEX)
+  #define CIS_100HALF		CIS_SPEED_100
+  #define CIS_10FULL		(CIS_SPEED_10 | CIS_DUPLEX)
+  #define CIS_10HALF		CIS_SPEED_10
+  #define CIS_SMI_PRIORITY	0x0004
+
+static inline unsigned short INW (struct eth_device *dev, unsigned long addr)
+{
+	return le16_to_cpu(readw(addr + (void *)dev->iobase));
+}
+
+/*
+ Access RXBUFFER_START/TXBUFFER_START to read RX buffer/write TX buffer
+*/
+#if defined (CONFIG_DRIVER_AX88180_16BIT)
+static inline void OUTW (struct eth_device *dev, unsigned short command, unsigned long addr)
+{
+	writew(cpu_to_le16(command), addr + (void *)dev->iobase);
+}
+
+static inline unsigned short READ_RXBUF (struct eth_device *dev)
+{
+	return le16_to_cpu(readw(RXBUFFER_START + (void *)dev->iobase));
+}
+
+static inline void WRITE_TXBUF (struct eth_device *dev, unsigned short data)
+{
+	writew(cpu_to_le16(data), TXBUFFER_START + (void *)dev->iobase);
+}
+#else
+static inline void OUTW (struct eth_device *dev, unsigned short command, unsigned long addr)
+{
+	writel(cpu_to_le32(command), addr + (void *)dev->iobase);
+}
+
+static inline unsigned long READ_RXBUF (struct eth_device *dev)
+{
+	return le32_to_cpu(readl(RXBUFFER_START + (void *)dev->iobase));
+}
+
+static inline void WRITE_TXBUF (struct eth_device *dev, unsigned long data)
+{
+	writel(cpu_to_le32(data), TXBUFFER_START + (void *)dev->iobase);
+}
+#endif
+
+#endif /* _AX88180_H_ */
diff --git a/marvell/uboot/drivers/net/ax88796.c b/marvell/uboot/drivers/net/ax88796.c
new file mode 100644
index 0000000..c45f646
--- /dev/null
+++ b/marvell/uboot/drivers/net/ax88796.c
@@ -0,0 +1,144 @@
+/*
+ * (c) 2007 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include "ax88796.h"
+
+/*
+ * Set 1 bit data
+ */
+static void ax88796_bitset(u32 bit)
+{
+	/* DATA1 */
+	if( bit )
+		EEDI_HIGH;
+	else
+		EEDI_LOW;
+
+	EECLK_LOW;
+	udelay(1000);
+	EECLK_HIGH;
+	udelay(1000);
+	EEDI_LOW;
+}
+
+/*
+ * Get 1 bit data
+ */
+static u8 ax88796_bitget(void)
+{
+	u8 bit;
+
+	EECLK_LOW;
+	udelay(1000);
+	/* DATA */
+	bit = EEDO;
+	EECLK_HIGH;
+	udelay(1000);
+
+	return bit;
+}
+
+/*
+ * Send COMMAND to EEPROM
+ */
+static void ax88796_eep_cmd(u8 cmd)
+{
+	ax88796_bitset(BIT_DUMMY);
+	switch(cmd){
+		case MAC_EEP_READ:
+			ax88796_bitset(1);
+			ax88796_bitset(1);
+			ax88796_bitset(0);
+			break;
+
+		case MAC_EEP_WRITE:
+			ax88796_bitset(1);
+			ax88796_bitset(0);
+			ax88796_bitset(1);
+			break;
+
+		case MAC_EEP_ERACE:
+			ax88796_bitset(1);
+			ax88796_bitset(1);
+			ax88796_bitset(1);
+			break;
+
+		case MAC_EEP_EWEN:
+			ax88796_bitset(1);
+			ax88796_bitset(0);
+			ax88796_bitset(0);
+			break;
+
+		case MAC_EEP_EWDS:
+			ax88796_bitset(1);
+			ax88796_bitset(0);
+			ax88796_bitset(0);
+			break;
+		default:
+			break;
+	}
+}
+
+static void ax88796_eep_setaddr(u16 addr)
+{
+	int i ;
+
+	for( i = 7 ; i >= 0 ; i-- )
+		ax88796_bitset(addr & (1 << i));
+}
+
+/*
+ * Get data from EEPROM
+ */
+static u16 ax88796_eep_getdata(void)
+{
+	ushort data = 0;
+	int i;
+
+	ax88796_bitget();	/* DUMMY */
+	for( i = 0 ; i < 16 ; i++ ){
+		data <<= 1;
+		data |= ax88796_bitget();
+	}
+	return data;
+}
+
+static void ax88796_mac_read(u8 *buff)
+{
+	int i ;
+	u16 data;
+	u16 addr = 0;
+
+	for( i = 0 ; i < 3; i++ )
+	{
+		EECS_HIGH;
+		EEDI_LOW;
+		udelay(1000);
+		/* READ COMMAND */
+		ax88796_eep_cmd(MAC_EEP_READ);
+		/* ADDRESS */
+		ax88796_eep_setaddr(addr++);
+		/* GET DATA */
+		data = ax88796_eep_getdata();
+		*buff++ = (uchar)(data & 0xff);
+		*buff++ = (uchar)((data >> 8) & 0xff);
+		EECLK_LOW;
+		EEDI_LOW;
+		EECS_LOW;
+	}
+}
+
+int get_prom(u8* mac_addr, u8* base_addr)
+{
+	u8 prom[32];
+	int i;
+
+	ax88796_mac_read(prom);
+	for (i = 0; i < 6; i++){
+		mac_addr[i] = prom[i];
+	}
+	return 1;
+}
diff --git a/marvell/uboot/drivers/net/ax88796.h b/marvell/uboot/drivers/net/ax88796.h
new file mode 100644
index 0000000..2b4e05a
--- /dev/null
+++ b/marvell/uboot/drivers/net/ax88796.h
@@ -0,0 +1,67 @@
+/*
+ * AX88796L(NE2000) support
+ *
+ * (c) 2007 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __DRIVERS_AX88796L_H__
+#define __DRIVERS_AX88796L_H__
+
+#define DP_DATA		(0x10 << 1)
+#define START_PG	0x40	/* First page of TX buffer */
+#define START_PG2	0x48
+#define STOP_PG		0x80	/* Last page +1 of RX ring */
+#define TX_PAGES	12
+#define RX_START	(START_PG+TX_PAGES)
+#define RX_END		STOP_PG
+
+#define AX88796L_BASE_ADDRESS	CONFIG_DRIVER_NE2000_BASE
+#define AX88796L_BYTE_ACCESS	0x00001000
+#define AX88796L_OFFSET		0x00000400
+#define AX88796L_ADDRESS_BYTE	AX88796L_BASE_ADDRESS + \
+		AX88796L_BYTE_ACCESS + AX88796L_OFFSET
+#define AX88796L_REG_MEMR	AX88796L_ADDRESS_BYTE + (0x14<<1)
+#define AX88796L_REG_CR		AX88796L_ADDRESS_BYTE + (0x00<<1)
+
+#define AX88796L_CR		(*(vu_short *)(AX88796L_REG_CR))
+#define AX88796L_MEMR		(*(vu_short *)(AX88796L_REG_MEMR))
+
+#define EECS_HIGH		(AX88796L_MEMR |= 0x10)
+#define EECS_LOW		(AX88796L_MEMR &= 0xef)
+#define EECLK_HIGH		(AX88796L_MEMR |= 0x80)
+#define EECLK_LOW		(AX88796L_MEMR &= 0x7f)
+#define EEDI_HIGH		(AX88796L_MEMR |= 0x20)
+#define EEDI_LOW		(AX88796L_MEMR &= 0xdf)
+#define EEDO			((AX88796L_MEMR & 0x40)>>6)
+
+#define PAGE0_SET		(AX88796L_CR &= 0x3f)
+#define PAGE1_SET		(AX88796L_CR = (AX88796L_CR & 0x3f) | 0x40)
+
+#define BIT_DUMMY	0
+#define MAC_EEP_READ	1
+#define MAC_EEP_WRITE	2
+#define MAC_EEP_ERACE	3
+#define MAC_EEP_EWEN	4
+#define MAC_EEP_EWDS	5
+
+/* R7780MP Specific code */
+#if defined(CONFIG_R7780MP)
+#define ISA_OFFSET	0x1400
+#define DP_IN(_b_, _o_, _d_)	(_d_) = \
+	*( (vu_short *) ((_b_) + ((_o_) * 2) + ISA_OFFSET))
+#define DP_OUT(_b_, _o_, _d_) \
+	*((vu_short *)((_b_) + ((_o_) * 2) + ISA_OFFSET)) = (_d_)
+#define DP_IN_DATA(_b_, _d_)	(_d_) = *( (vu_short *) ((_b_) + ISA_OFFSET))
+#define DP_OUT_DATA(_b_, _d_)	*( (vu_short *) ((_b_)+ISA_OFFSET)) = (_d_)
+#else
+/* Please change for your target boards */
+#define ISA_OFFSET	0x0000
+#define DP_IN(_b_, _o_, _d_)	(_d_) = *( (vu_short *)((_b_)+(_o_ )+ISA_OFFSET))
+#define DP_OUT(_b_, _o_, _d_)	*((vu_short *)((_b_)+(_o_)+ISA_OFFSET)) = (_d_)
+#define DP_IN_DATA(_b_, _d_)	(_d_) = *( (vu_short *) ((_b_)+ISA_OFFSET))
+#define DP_OUT_DATA(_b_, _d_)	*( (vu_short *) ((_b_)+ISA_OFFSET)) = (_d_)
+#endif
+
+#endif /* __DRIVERS_AX88796L_H__ */
diff --git a/marvell/uboot/drivers/net/bfin_mac.c b/marvell/uboot/drivers/net/bfin_mac.c
new file mode 100644
index 0000000..0ffd59d
--- /dev/null
+++ b/marvell/uboot/drivers/net/bfin_mac.c
@@ -0,0 +1,495 @@
+/*
+ * Driver for Blackfin On-Chip MAC device
+ *
+ * Copyright (c) 2005-2008 Analog Device, Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <config.h>
+#include <net.h>
+#include <netdev.h>
+#include <command.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <linux/mii.h>
+
+#include <asm/blackfin.h>
+#include <asm/portmux.h>
+#include <asm/mach-common/bits/dma.h>
+#include <asm/mach-common/bits/emac.h>
+#include <asm/mach-common/bits/pll.h>
+
+#include "bfin_mac.h"
+
+#ifndef CONFIG_PHY_ADDR
+# define CONFIG_PHY_ADDR 1
+#endif
+#ifndef CONFIG_PHY_CLOCK_FREQ
+# define CONFIG_PHY_CLOCK_FREQ 2500000
+#endif
+
+#ifdef CONFIG_POST
+#include <post.h>
+#endif
+
+#define RXBUF_BASE_ADDR		0xFF900000
+#define TXBUF_BASE_ADDR		0xFF800000
+#define TX_BUF_CNT		1
+
+#define TOUT_LOOP		1000000
+
+static ADI_ETHER_BUFFER *txbuf[TX_BUF_CNT];
+static ADI_ETHER_BUFFER *rxbuf[PKTBUFSRX];
+static u16 txIdx;		/* index of the current RX buffer */
+static u16 rxIdx;		/* index of the current TX buffer */
+
+/* DMAx_CONFIG values at DMA Restart */
+static const union {
+	u16 data;
+	ADI_DMA_CONFIG_REG reg;
+} txdmacfg = {
+	.reg = {
+		.b_DMA_EN  = 1,	/* enabled */
+		.b_WNR     = 0,	/* read from memory */
+		.b_WDSIZE  = 2,	/* wordsize is 32 bits */
+		.b_DMA2D   = 0,
+		.b_RESTART = 0,
+		.b_DI_SEL  = 0,
+		.b_DI_EN   = 0,	/* no interrupt */
+		.b_NDSIZE  = 5,	/* 5 half words is desc size */
+		.b_FLOW    = 7	/* large desc flow */
+	},
+};
+
+static int bfin_miiphy_wait(void)
+{
+	/* poll the STABUSY bit */
+	while (bfin_read_EMAC_STAADD() & STABUSY)
+		continue;
+	return 0;
+}
+
+static int bfin_miiphy_read(const char *devname, uchar addr, uchar reg, ushort *val)
+{
+	if (bfin_miiphy_wait())
+		return 1;
+	bfin_write_EMAC_STAADD(SET_PHYAD(addr) | SET_REGAD(reg) | STABUSY);
+	if (bfin_miiphy_wait())
+		return 1;
+	*val = bfin_read_EMAC_STADAT();
+	return 0;
+}
+
+static int bfin_miiphy_write(const char *devname, uchar addr, uchar reg, ushort val)
+{
+	if (bfin_miiphy_wait())
+		return 1;
+	bfin_write_EMAC_STADAT(val);
+	bfin_write_EMAC_STAADD(SET_PHYAD(addr) | SET_REGAD(reg) | STAOP | STABUSY);
+	return 0;
+}
+
+int bfin_EMAC_initialize(bd_t *bis)
+{
+	struct eth_device *dev;
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL)
+		hang();
+
+	memset(dev, 0, sizeof(*dev));
+	strcpy(dev->name, "bfin_mac");
+
+	dev->iobase = 0;
+	dev->priv = 0;
+	dev->init = bfin_EMAC_init;
+	dev->halt = bfin_EMAC_halt;
+	dev->send = bfin_EMAC_send;
+	dev->recv = bfin_EMAC_recv;
+	dev->write_hwaddr = bfin_EMAC_setup_addr;
+
+	eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	miiphy_register(dev->name, bfin_miiphy_read, bfin_miiphy_write);
+#endif
+
+	return 0;
+}
+
+static int bfin_EMAC_send(struct eth_device *dev, void *packet, int length)
+{
+	int i;
+	int result = 0;
+
+	if (length <= 0) {
+		printf("Ethernet: bad packet size: %d\n", length);
+		goto out;
+	}
+
+	if (bfin_read_DMA2_IRQ_STATUS() & DMA_ERR) {
+		printf("Ethernet: tx DMA error\n");
+		goto out;
+	}
+
+	for (i = 0; (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN); ++i) {
+		if (i > TOUT_LOOP) {
+			puts("Ethernet: tx time out\n");
+			goto out;
+		}
+	}
+	txbuf[txIdx]->FrmData->NoBytes = length;
+	memcpy(txbuf[txIdx]->FrmData->Dest, (void *)packet, length);
+	txbuf[txIdx]->Dma[0].START_ADDR = (u32) txbuf[txIdx]->FrmData;
+	bfin_write_DMA2_NEXT_DESC_PTR(txbuf[txIdx]->Dma);
+	bfin_write_DMA2_CONFIG(txdmacfg.data);
+	bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);
+
+	for (i = 0; (txbuf[txIdx]->StatusWord & TX_COMP) == 0; i++) {
+		if (i > TOUT_LOOP) {
+			puts("Ethernet: tx error\n");
+			goto out;
+		}
+	}
+	result = txbuf[txIdx]->StatusWord;
+	txbuf[txIdx]->StatusWord = 0;
+	if ((txIdx + 1) >= TX_BUF_CNT)
+		txIdx = 0;
+	else
+		txIdx++;
+ out:
+	debug("BFIN EMAC send: length = %d\n", length);
+	return result;
+}
+
+static int bfin_EMAC_recv(struct eth_device *dev)
+{
+	int length = 0;
+
+	for (;;) {
+		if ((rxbuf[rxIdx]->StatusWord & RX_COMP) == 0) {
+			length = -1;
+			break;
+		}
+		if ((rxbuf[rxIdx]->StatusWord & RX_DMAO) != 0) {
+			printf("Ethernet: rx dma overrun\n");
+			break;
+		}
+		if ((rxbuf[rxIdx]->StatusWord & RX_OK) == 0) {
+			printf("Ethernet: rx error\n");
+			break;
+		}
+		length = rxbuf[rxIdx]->StatusWord & 0x000007FF;
+		if (length <= 4) {
+			printf("Ethernet: bad frame\n");
+			break;
+		}
+
+		debug("%s: len = %d\n", __func__, length - 4);
+
+		NetRxPackets[rxIdx] = rxbuf[rxIdx]->FrmData->Dest;
+		NetReceive(NetRxPackets[rxIdx], length - 4);
+		bfin_write_DMA1_IRQ_STATUS(DMA_DONE | DMA_ERR);
+		rxbuf[rxIdx]->StatusWord = 0x00000000;
+		if ((rxIdx + 1) >= PKTBUFSRX)
+			rxIdx = 0;
+		else
+			rxIdx++;
+	}
+
+	return length;
+}
+
+/**************************************************************
+ *
+ * Ethernet Initialization Routine
+ *
+ *************************************************************/
+
+/* MDC = SCLK / MDC_freq / 2 - 1 */
+#define MDC_FREQ_TO_DIV(mdc_freq) (get_sclk() / (mdc_freq) / 2 - 1)
+
+#ifndef CONFIG_BFIN_MAC_PINS
+# ifdef CONFIG_RMII
+#  define CONFIG_BFIN_MAC_PINS P_RMII0
+# else
+#  define CONFIG_BFIN_MAC_PINS P_MII0
+# endif
+#endif
+
+static int bfin_miiphy_init(struct eth_device *dev, int *opmode)
+{
+	const unsigned short pins[] = CONFIG_BFIN_MAC_PINS;
+	u16 phydat;
+	size_t count;
+
+	/* Enable PHY output */
+	bfin_write_VR_CTL(bfin_read_VR_CTL() | CLKBUFOE);
+
+	/* Set all the pins to peripheral mode */
+	peripheral_request_list(pins, "bfin_mac");
+
+	/* Odd word alignment for Receive Frame DMA word */
+	/* Configure checksum support and rcve frame word alignment */
+	bfin_write_EMAC_SYSCTL(RXDWA | RXCKS | SET_MDCDIV(MDC_FREQ_TO_DIV(CONFIG_PHY_CLOCK_FREQ)));
+
+	/* turn on auto-negotiation and wait for link to come up */
+	bfin_miiphy_write(dev->name, CONFIG_PHY_ADDR, MII_BMCR, BMCR_ANENABLE);
+	count = 0;
+	while (1) {
+		++count;
+		if (bfin_miiphy_read(dev->name, CONFIG_PHY_ADDR, MII_BMSR, &phydat))
+			return -1;
+		if (phydat & BMSR_LSTATUS)
+			break;
+		if (count > 30000) {
+			printf("%s: link down, check cable\n", dev->name);
+			return -1;
+		}
+		udelay(100);
+	}
+
+	/* see what kind of link we have */
+	if (bfin_miiphy_read(dev->name, CONFIG_PHY_ADDR, MII_LPA, &phydat))
+		return -1;
+	if (phydat & LPA_DUPLEX)
+		*opmode = FDMODE;
+	else
+		*opmode = 0;
+
+	bfin_write_EMAC_MMC_CTL(RSTC | CROLL);
+
+	/* Initialize the TX DMA channel registers */
+	bfin_write_DMA2_X_COUNT(0);
+	bfin_write_DMA2_X_MODIFY(4);
+	bfin_write_DMA2_Y_COUNT(0);
+	bfin_write_DMA2_Y_MODIFY(0);
+
+	/* Initialize the RX DMA channel registers */
+	bfin_write_DMA1_X_COUNT(0);
+	bfin_write_DMA1_X_MODIFY(4);
+	bfin_write_DMA1_Y_COUNT(0);
+	bfin_write_DMA1_Y_MODIFY(0);
+
+	return 0;
+}
+
+static int bfin_EMAC_setup_addr(struct eth_device *dev)
+{
+	bfin_write_EMAC_ADDRLO(
+		dev->enetaddr[0] |
+		dev->enetaddr[1] << 8 |
+		dev->enetaddr[2] << 16 |
+		dev->enetaddr[3] << 24
+	);
+	bfin_write_EMAC_ADDRHI(
+		dev->enetaddr[4] |
+		dev->enetaddr[5] << 8
+	);
+	return 0;
+}
+
+static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd)
+{
+	u32 opmode;
+	int dat;
+	int i;
+	debug("Eth_init: ......\n");
+
+	txIdx = 0;
+	rxIdx = 0;
+
+	/* Initialize System Register */
+	if (bfin_miiphy_init(dev, &dat) < 0)
+		return -1;
+
+	/* Initialize EMAC address */
+	bfin_EMAC_setup_addr(dev);
+
+	/* Initialize TX and RX buffer */
+	for (i = 0; i < PKTBUFSRX; i++) {
+		rxbuf[i] = SetupRxBuffer(i);
+		if (i > 0) {
+			rxbuf[i - 1]->Dma[1].NEXT_DESC_PTR = rxbuf[i]->Dma;
+			if (i == (PKTBUFSRX - 1))
+				rxbuf[i]->Dma[1].NEXT_DESC_PTR = rxbuf[0]->Dma;
+		}
+	}
+	for (i = 0; i < TX_BUF_CNT; i++) {
+		txbuf[i] = SetupTxBuffer(i);
+		if (i > 0) {
+			txbuf[i - 1]->Dma[1].NEXT_DESC_PTR = txbuf[i]->Dma;
+			if (i == (TX_BUF_CNT - 1))
+				txbuf[i]->Dma[1].NEXT_DESC_PTR = txbuf[0]->Dma;
+		}
+	}
+
+	/* Set RX DMA */
+	bfin_write_DMA1_NEXT_DESC_PTR(rxbuf[0]->Dma);
+	bfin_write_DMA1_CONFIG(rxbuf[0]->Dma[0].CONFIG_DATA);
+
+	/* Wait MII done */
+	bfin_miiphy_wait();
+
+	/* We enable only RX here */
+	/* ASTP   : Enable Automatic Pad Stripping
+	   PR     : Promiscuous Mode for test
+	   PSF    : Receive frames with total length less than 64 bytes.
+	   FDMODE : Full Duplex Mode
+	   LB	  : Internal Loopback for test
+	   RE     : Receiver Enable */
+	if (dat == FDMODE)
+		opmode = ASTP | FDMODE | PSF;
+	else
+		opmode = ASTP | PSF;
+	opmode |= RE;
+#ifdef CONFIG_RMII
+	opmode |= TE | RMII;
+#endif
+	/* Turn on the EMAC */
+	bfin_write_EMAC_OPMODE(opmode);
+	return 0;
+}
+
+static void bfin_EMAC_halt(struct eth_device *dev)
+{
+	debug("Eth_halt: ......\n");
+	/* Turn off the EMAC */
+	bfin_write_EMAC_OPMODE(0);
+	/* Turn off the EMAC RX DMA */
+	bfin_write_DMA1_CONFIG(0);
+	bfin_write_DMA2_CONFIG(0);
+}
+
+ADI_ETHER_BUFFER *SetupRxBuffer(int no)
+{
+	ADI_ETHER_FRAME_BUFFER *frmbuf;
+	ADI_ETHER_BUFFER *buf;
+	int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2;	/* ensure a multi. of 4 */
+	int total_size = nobytes_buffer + RECV_BUFSIZE;
+
+	buf = (void *) (RXBUF_BASE_ADDR + no * total_size);
+	frmbuf = (void *) (RXBUF_BASE_ADDR + no * total_size + nobytes_buffer);
+
+	memset(buf, 0x00, nobytes_buffer);
+	buf->FrmData = frmbuf;
+	memset(frmbuf, 0xfe, RECV_BUFSIZE);
+
+	/* set up first desc to point to receive frame buffer */
+	buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]);
+	buf->Dma[0].START_ADDR = (u32) buf->FrmData;
+	buf->Dma[0].CONFIG.b_DMA_EN = 1;	/* enabled */
+	buf->Dma[0].CONFIG.b_WNR = 1;	/* Write to memory */
+	buf->Dma[0].CONFIG.b_WDSIZE = 2;	/* wordsize is 32 bits */
+	buf->Dma[0].CONFIG.b_NDSIZE = 5;	/* 5 half words is desc size. */
+	buf->Dma[0].CONFIG.b_FLOW = 7;	/* large desc flow */
+
+	/* set up second desc to point to status word */
+	buf->Dma[1].NEXT_DESC_PTR = buf->Dma;
+	buf->Dma[1].START_ADDR = (u32) & buf->IPHdrChksum;
+	buf->Dma[1].CONFIG.b_DMA_EN = 1;	/* enabled */
+	buf->Dma[1].CONFIG.b_WNR = 1;	/* Write to memory */
+	buf->Dma[1].CONFIG.b_WDSIZE = 2;	/* wordsize is 32 bits */
+	buf->Dma[1].CONFIG.b_DI_EN = 1;	/* enable interrupt */
+	buf->Dma[1].CONFIG.b_NDSIZE = 5;	/* must be 0 when FLOW is 0 */
+	buf->Dma[1].CONFIG.b_FLOW = 7;	/* stop */
+
+	return buf;
+}
+
+ADI_ETHER_BUFFER *SetupTxBuffer(int no)
+{
+	ADI_ETHER_FRAME_BUFFER *frmbuf;
+	ADI_ETHER_BUFFER *buf;
+	int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2;	/* ensure a multi. of 4 */
+	int total_size = nobytes_buffer + RECV_BUFSIZE;
+
+	buf = (void *) (TXBUF_BASE_ADDR + no * total_size);
+	frmbuf = (void *) (TXBUF_BASE_ADDR + no * total_size + nobytes_buffer);
+
+	memset(buf, 0x00, nobytes_buffer);
+	buf->FrmData = frmbuf;
+	memset(frmbuf, 0x00, RECV_BUFSIZE);
+
+	/* set up first desc to point to receive frame buffer */
+	buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]);
+	buf->Dma[0].START_ADDR = (u32) buf->FrmData;
+	buf->Dma[0].CONFIG.b_DMA_EN = 1;	/* enabled */
+	buf->Dma[0].CONFIG.b_WNR = 0;	/* Read to memory */
+	buf->Dma[0].CONFIG.b_WDSIZE = 2;	/* wordsize is 32 bits */
+	buf->Dma[0].CONFIG.b_NDSIZE = 5;	/* 5 half words is desc size. */
+	buf->Dma[0].CONFIG.b_FLOW = 7;	/* large desc flow */
+
+	/* set up second desc to point to status word */
+	buf->Dma[1].NEXT_DESC_PTR = &(buf->Dma[0]);
+	buf->Dma[1].START_ADDR = (u32) & buf->StatusWord;
+	buf->Dma[1].CONFIG.b_DMA_EN = 1;	/* enabled */
+	buf->Dma[1].CONFIG.b_WNR = 1;	/* Write to memory */
+	buf->Dma[1].CONFIG.b_WDSIZE = 2;	/* wordsize is 32 bits */
+	buf->Dma[1].CONFIG.b_DI_EN = 1;	/* enable interrupt */
+	buf->Dma[1].CONFIG.b_NDSIZE = 0;	/* must be 0 when FLOW is 0 */
+	buf->Dma[1].CONFIG.b_FLOW = 0;	/* stop */
+
+	return buf;
+}
+
+#if defined(CONFIG_POST) && defined(CONFIG_SYS_POST_ETHER)
+int ether_post_test(int flags)
+{
+	uchar buf[64];
+	int i, value = 0;
+	int length;
+	uint addr;
+
+	printf("\n--------");
+	bfin_EMAC_init(NULL, NULL);
+	/* construct the package */
+	addr = bfin_read_EMAC_ADDRLO();
+	buf[0] = buf[6] = addr;
+	buf[1] = buf[7] = addr >> 8;
+	buf[2] = buf[8] = addr >> 16;
+	buf[3] = buf[9] = addr >> 24;
+	addr = bfin_read_EMAC_ADDRHI();
+	buf[4] = buf[10] = addr;
+	buf[5] = buf[11] = addr >> 8;
+	buf[12] = 0x08;		/* Type: ARP */
+	buf[13] = 0x06;
+	buf[14] = 0x00;		/* Hardware type: Ethernet */
+	buf[15] = 0x01;
+	buf[16] = 0x08;		/* Protocal type: IP */
+	buf[17] = 0x00;
+	buf[18] = 0x06;		/* Hardware size    */
+	buf[19] = 0x04;		/* Protocol size    */
+	buf[20] = 0x00;		/* Opcode: request  */
+	buf[21] = 0x01;
+
+	for (i = 0; i < 42; i++)
+		buf[i + 22] = i;
+	printf("--------Send 64 bytes......\n");
+	bfin_EMAC_send(NULL, buf, 64);
+	for (i = 0; i < 100; i++) {
+		udelay(10000);
+		if ((rxbuf[rxIdx]->StatusWord & RX_COMP) != 0) {
+			value = 1;
+			break;
+		}
+	}
+	if (value == 0) {
+		printf("--------EMAC can't receive any data\n");
+		eth_halt();
+		return -1;
+	}
+	length = rxbuf[rxIdx]->StatusWord & 0x000007FF - 4;
+	for (i = 0; i < length; i++) {
+		if (rxbuf[rxIdx]->FrmData->Dest[i] != buf[i]) {
+			printf("--------EMAC receive error data!\n");
+			eth_halt();
+			return -1;
+		}
+	}
+	printf("--------receive %d bytes, matched\n", length);
+	bfin_EMAC_halt(NULL);
+	return 0;
+}
+#endif
diff --git a/marvell/uboot/drivers/net/bfin_mac.h b/marvell/uboot/drivers/net/bfin_mac.h
new file mode 100644
index 0000000..54ffb38
--- /dev/null
+++ b/marvell/uboot/drivers/net/bfin_mac.h
@@ -0,0 +1,65 @@
+/*
+ * bfin_mac.h - some defines/structures for the Blackfin on-chip MAC.
+ *
+ * Copyright (c) 2005-2008 Analog Device, Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __BFIN_MAC_H__
+#define __BFIN_MAC_H__
+
+#define RECV_BUFSIZE		(0x614)
+
+typedef struct ADI_DMA_CONFIG_REG {
+	u16 b_DMA_EN:1;		/* 0	Enabled				*/
+	u16 b_WNR:1;		/* 1	Direction			*/
+	u16 b_WDSIZE:2;		/* 2:3	Transfer word size		*/
+	u16 b_DMA2D:1;		/* 4	DMA mode			*/
+	u16 b_RESTART:1;	/* 5	Retain FIFO			*/
+	u16 b_DI_SEL:1;		/* 6	Data interrupt timing select	*/
+	u16 b_DI_EN:1;		/* 7	Data interrupt enabled		*/
+	u16 b_NDSIZE:4;		/* 8:11	Flex descriptor size		*/
+	u16 b_FLOW:3;		/* 12:14Flow				*/
+} ADI_DMA_CONFIG_REG;
+
+typedef struct adi_ether_frame_buffer {
+	u16 NoBytes;		/* the no. of following bytes	*/
+	u8 Dest[6];		/* destination MAC address	*/
+	u8 Srce[6];		/* source MAC address		*/
+	u16 LTfield;		/* length/type field		*/
+	u8 Data[0];		/* payload bytes		*/
+} ADI_ETHER_FRAME_BUFFER;
+/* 16 bytes/struct	*/
+
+typedef struct dma_descriptor {
+	struct dma_descriptor *NEXT_DESC_PTR;
+	u32 START_ADDR;
+	union {
+		u16 CONFIG_DATA;
+		ADI_DMA_CONFIG_REG CONFIG;
+	};
+} DMA_DESCRIPTOR;
+/* 10 bytes/struct in 12 bytes */
+
+typedef struct adi_ether_buffer {
+	DMA_DESCRIPTOR Dma[2];		/* first for the frame, second for the status */
+	ADI_ETHER_FRAME_BUFFER *FrmData;/* pointer to data */
+	struct adi_ether_buffer *pNext;	/* next buffer */
+	struct adi_ether_buffer *pPrev;	/* prev buffer */
+	u16 IPHdrChksum;		/* the IP header checksum */
+	u16 IPPayloadChksum;		/* the IP header and payload checksum */
+	volatile u32 StatusWord;	/* the frame status word */
+} ADI_ETHER_BUFFER;
+/* 40 bytes/struct in 44 bytes */
+
+static ADI_ETHER_BUFFER *SetupRxBuffer(int no);
+static ADI_ETHER_BUFFER *SetupTxBuffer(int no);
+
+static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd);
+static void bfin_EMAC_halt(struct eth_device *dev);
+static int bfin_EMAC_send(struct eth_device *dev, void *packet, int length);
+static int bfin_EMAC_recv(struct eth_device *dev);
+static int bfin_EMAC_setup_addr(struct eth_device *dev);
+
+#endif
diff --git a/marvell/uboot/drivers/net/calxedaxgmac.c b/marvell/uboot/drivers/net/calxedaxgmac.c
new file mode 100644
index 0000000..ff94865
--- /dev/null
+++ b/marvell/uboot/drivers/net/calxedaxgmac.c
@@ -0,0 +1,544 @@
+/*
+ * Copyright 2010-2011 Calxeda, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <linux/compiler.h>
+#include <linux/err.h>
+#include <asm/io.h>
+
+#define TX_NUM_DESC			1
+#define RX_NUM_DESC			32
+
+#define MAC_TIMEOUT			(5*CONFIG_SYS_HZ)
+
+#define ETH_BUF_SZ			2048
+#define TX_BUF_SZ			(ETH_BUF_SZ * TX_NUM_DESC)
+#define RX_BUF_SZ			(ETH_BUF_SZ * RX_NUM_DESC)
+
+#define RXSTART				0x00000002
+#define TXSTART				0x00002000
+
+#define RXENABLE			0x00000004
+#define TXENABLE			0x00000008
+
+#define XGMAC_CONTROL_SPD		0x40000000
+#define XGMAC_CONTROL_SPD_MASK		0x60000000
+#define XGMAC_CONTROL_SARC		0x10000000
+#define XGMAC_CONTROL_SARK_MASK		0x18000000
+#define XGMAC_CONTROL_CAR		0x04000000
+#define XGMAC_CONTROL_CAR_MASK		0x06000000
+#define XGMAC_CONTROL_CAR_SHIFT		25
+#define XGMAC_CONTROL_DP		0x01000000
+#define XGMAC_CONTROL_WD		0x00800000
+#define XGMAC_CONTROL_JD		0x00400000
+#define XGMAC_CONTROL_JE		0x00100000
+#define XGMAC_CONTROL_LM		0x00001000
+#define XGMAC_CONTROL_IPC		0x00000400
+#define XGMAC_CONTROL_ACS		0x00000080
+#define XGMAC_CONTROL_DDIC		0x00000010
+#define XGMAC_CONTROL_TE		0x00000008
+#define XGMAC_CONTROL_RE		0x00000004
+
+#define XGMAC_DMA_BUSMODE_RESET		0x00000001
+#define XGMAC_DMA_BUSMODE_DSL		0x00000004
+#define XGMAC_DMA_BUSMODE_DSL_MASK	0x0000007c
+#define XGMAC_DMA_BUSMODE_DSL_SHIFT	2
+#define XGMAC_DMA_BUSMODE_ATDS		0x00000080
+#define XGMAC_DMA_BUSMODE_PBL_MASK	0x00003f00
+#define XGMAC_DMA_BUSMODE_PBL_SHIFT	8
+#define XGMAC_DMA_BUSMODE_FB		0x00010000
+#define XGMAC_DMA_BUSMODE_USP		0x00800000
+#define XGMAC_DMA_BUSMODE_8PBL		0x01000000
+#define XGMAC_DMA_BUSMODE_AAL		0x02000000
+
+#define XGMAC_DMA_AXIMODE_ENLPI		0x80000000
+#define XGMAC_DMA_AXIMODE_MGK		0x40000000
+#define XGMAC_DMA_AXIMODE_WROSR		0x00100000
+#define XGMAC_DMA_AXIMODE_WROSR_MASK	0x00F00000
+#define XGMAC_DMA_AXIMODE_WROSR_SHIFT	20
+#define XGMAC_DMA_AXIMODE_RDOSR		0x00010000
+#define XGMAC_DMA_AXIMODE_RDOSR_MASK	0x000F0000
+#define XGMAC_DMA_AXIMODE_RDOSR_SHIFT	16
+#define XGMAC_DMA_AXIMODE_AAL		0x00001000
+#define XGMAC_DMA_AXIMODE_BLEN256	0x00000080
+#define XGMAC_DMA_AXIMODE_BLEN128	0x00000040
+#define XGMAC_DMA_AXIMODE_BLEN64	0x00000020
+#define XGMAC_DMA_AXIMODE_BLEN32	0x00000010
+#define XGMAC_DMA_AXIMODE_BLEN16	0x00000008
+#define XGMAC_DMA_AXIMODE_BLEN8		0x00000004
+#define XGMAC_DMA_AXIMODE_BLEN4		0x00000002
+#define XGMAC_DMA_AXIMODE_UNDEF		0x00000001
+
+#define XGMAC_CORE_OMR_RTC_SHIFT	3
+#define XGMAC_CORE_OMR_RTC_MASK		0x00000018
+#define XGMAC_CORE_OMR_RTC		0x00000010
+#define XGMAC_CORE_OMR_RSF		0x00000020
+#define XGMAC_CORE_OMR_DT		0x00000040
+#define XGMAC_CORE_OMR_FEF		0x00000080
+#define XGMAC_CORE_OMR_EFC		0x00000100
+#define XGMAC_CORE_OMR_RFA_SHIFT	9
+#define XGMAC_CORE_OMR_RFA_MASK		0x00000E00
+#define XGMAC_CORE_OMR_RFD_SHIFT	12
+#define XGMAC_CORE_OMR_RFD_MASK		0x00007000
+#define XGMAC_CORE_OMR_TTC_SHIFT	16
+#define XGMAC_CORE_OMR_TTC_MASK		0x00030000
+#define XGMAC_CORE_OMR_TTC		0x00020000
+#define XGMAC_CORE_OMR_FTF		0x00100000
+#define XGMAC_CORE_OMR_TSF		0x00200000
+
+#define FIFO_MINUS_1K			0x0
+#define FIFO_MINUS_2K			0x1
+#define FIFO_MINUS_3K			0x2
+#define FIFO_MINUS_4K			0x3
+#define FIFO_MINUS_6K			0x4
+#define FIFO_MINUS_8K			0x5
+#define FIFO_MINUS_12K			0x6
+#define FIFO_MINUS_16K			0x7
+
+#define XGMAC_CORE_FLOW_PT_SHIFT	16
+#define XGMAC_CORE_FLOW_PT_MASK		0xFFFF0000
+#define XGMAC_CORE_FLOW_PT		0x00010000
+#define XGMAC_CORE_FLOW_DZQP		0x00000080
+#define XGMAC_CORE_FLOW_PLT_SHIFT	4
+#define XGMAC_CORE_FLOW_PLT_MASK	0x00000030
+#define XGMAC_CORE_FLOW_PLT		0x00000010
+#define XGMAC_CORE_FLOW_UP		0x00000008
+#define XGMAC_CORE_FLOW_RFE		0x00000004
+#define XGMAC_CORE_FLOW_TFE		0x00000002
+#define XGMAC_CORE_FLOW_FCB		0x00000001
+
+/* XGMAC Descriptor Defines */
+#define MAX_DESC_BUF_SZ			(0x2000 - 8)
+
+#define RXDESC_EXT_STATUS		0x00000001
+#define RXDESC_CRC_ERR			0x00000002
+#define RXDESC_RX_ERR			0x00000008
+#define RXDESC_RX_WDOG			0x00000010
+#define RXDESC_FRAME_TYPE		0x00000020
+#define RXDESC_GIANT_FRAME		0x00000080
+#define RXDESC_LAST_SEG			0x00000100
+#define RXDESC_FIRST_SEG		0x00000200
+#define RXDESC_VLAN_FRAME		0x00000400
+#define RXDESC_OVERFLOW_ERR		0x00000800
+#define RXDESC_LENGTH_ERR		0x00001000
+#define RXDESC_SA_FILTER_FAIL		0x00002000
+#define RXDESC_DESCRIPTOR_ERR		0x00004000
+#define RXDESC_ERROR_SUMMARY		0x00008000
+#define RXDESC_FRAME_LEN_OFFSET		16
+#define RXDESC_FRAME_LEN_MASK		0x3fff0000
+#define RXDESC_DA_FILTER_FAIL		0x40000000
+
+#define RXDESC1_END_RING		0x00008000
+
+#define RXDESC_IP_PAYLOAD_MASK		0x00000003
+#define RXDESC_IP_PAYLOAD_UDP		0x00000001
+#define RXDESC_IP_PAYLOAD_TCP		0x00000002
+#define RXDESC_IP_PAYLOAD_ICMP		0x00000003
+#define RXDESC_IP_HEADER_ERR		0x00000008
+#define RXDESC_IP_PAYLOAD_ERR		0x00000010
+#define RXDESC_IPV4_PACKET		0x00000040
+#define RXDESC_IPV6_PACKET		0x00000080
+#define TXDESC_UNDERFLOW_ERR		0x00000001
+#define TXDESC_JABBER_TIMEOUT		0x00000002
+#define TXDESC_LOCAL_FAULT		0x00000004
+#define TXDESC_REMOTE_FAULT		0x00000008
+#define TXDESC_VLAN_FRAME		0x00000010
+#define TXDESC_FRAME_FLUSHED		0x00000020
+#define TXDESC_IP_HEADER_ERR		0x00000040
+#define TXDESC_PAYLOAD_CSUM_ERR		0x00000080
+#define TXDESC_ERROR_SUMMARY		0x00008000
+#define TXDESC_SA_CTRL_INSERT		0x00040000
+#define TXDESC_SA_CTRL_REPLACE		0x00080000
+#define TXDESC_2ND_ADDR_CHAINED		0x00100000
+#define TXDESC_END_RING			0x00200000
+#define TXDESC_CSUM_IP			0x00400000
+#define TXDESC_CSUM_IP_PAYLD		0x00800000
+#define TXDESC_CSUM_ALL			0x00C00000
+#define TXDESC_CRC_EN_REPLACE		0x01000000
+#define TXDESC_CRC_EN_APPEND		0x02000000
+#define TXDESC_DISABLE_PAD		0x04000000
+#define TXDESC_FIRST_SEG		0x10000000
+#define TXDESC_LAST_SEG			0x20000000
+#define TXDESC_INTERRUPT		0x40000000
+
+#define DESC_OWN			0x80000000
+#define DESC_BUFFER1_SZ_MASK		0x00001fff
+#define DESC_BUFFER2_SZ_MASK		0x1fff0000
+#define DESC_BUFFER2_SZ_OFFSET		16
+
+struct xgmac_regs {
+	u32 config;
+	u32 framefilter;
+	u32 resv_1[4];
+	u32 flow_control;
+	u32 vlantag;
+	u32 version;
+	u32 vlaninclude;
+	u32 resv_2[2];
+	u32 pacestretch;
+	u32 vlanhash;
+	u32 resv_3;
+	u32 intreg;
+	struct {
+		u32 hi;         /* 0x40 */
+		u32 lo;         /* 0x44 */
+	} macaddr[16];
+	u32 resv_4[0xd0];
+	u32 core_opmode;	/* 0x400 */
+	u32 resv_5[0x2bf];
+	u32 busmode;		/* 0xf00 */
+	u32 txpoll;
+	u32 rxpoll;
+	u32 rxdesclist;
+	u32 txdesclist;
+	u32 dma_status;
+	u32 dma_opmode;
+	u32 intenable;
+	u32 resv_6[2];
+	u32 axi_mode;		/* 0xf28 */
+};
+
+struct xgmac_dma_desc {
+	__le32 flags;
+	__le32 buf_size;
+	__le32 buf1_addr;		/* Buffer 1 Address Pointer */
+	__le32 buf2_addr;		/* Buffer 2 Address Pointer */
+	__le32 ext_status;
+	__le32 res[3];
+};
+
+/* XGMAC Descriptor Access Helpers */
+static inline void desc_set_buf_len(struct xgmac_dma_desc *p, u32 buf_sz)
+{
+	if (buf_sz > MAX_DESC_BUF_SZ)
+		p->buf_size = cpu_to_le32(MAX_DESC_BUF_SZ |
+			(buf_sz - MAX_DESC_BUF_SZ) << DESC_BUFFER2_SZ_OFFSET);
+	else
+		p->buf_size = cpu_to_le32(buf_sz);
+}
+
+static inline int desc_get_buf_len(struct xgmac_dma_desc *p)
+{
+	u32 len = le32_to_cpu(p->buf_size);
+	return (len & DESC_BUFFER1_SZ_MASK) +
+		((len & DESC_BUFFER2_SZ_MASK) >> DESC_BUFFER2_SZ_OFFSET);
+}
+
+static inline void desc_init_rx_desc(struct xgmac_dma_desc *p, int ring_size,
+				     int buf_sz)
+{
+	struct xgmac_dma_desc *end = p + ring_size - 1;
+
+	memset(p, 0, sizeof(*p) * ring_size);
+
+	for (; p <= end; p++)
+		desc_set_buf_len(p, buf_sz);
+
+	end->buf_size |= cpu_to_le32(RXDESC1_END_RING);
+}
+
+static inline void desc_init_tx_desc(struct xgmac_dma_desc *p, u32 ring_size)
+{
+	memset(p, 0, sizeof(*p) * ring_size);
+	p[ring_size - 1].flags = cpu_to_le32(TXDESC_END_RING);
+}
+
+static inline int desc_get_owner(struct xgmac_dma_desc *p)
+{
+	return le32_to_cpu(p->flags) & DESC_OWN;
+}
+
+static inline void desc_set_rx_owner(struct xgmac_dma_desc *p)
+{
+	/* Clear all fields and set the owner */
+	p->flags = cpu_to_le32(DESC_OWN);
+}
+
+static inline void desc_set_tx_owner(struct xgmac_dma_desc *p, u32 flags)
+{
+	u32 tmpflags = le32_to_cpu(p->flags);
+	tmpflags &= TXDESC_END_RING;
+	tmpflags |= flags | DESC_OWN;
+	p->flags = cpu_to_le32(tmpflags);
+}
+
+static inline void *desc_get_buf_addr(struct xgmac_dma_desc *p)
+{
+	return (void *)le32_to_cpu(p->buf1_addr);
+}
+
+static inline void desc_set_buf_addr(struct xgmac_dma_desc *p,
+				     void *paddr, int len)
+{
+	p->buf1_addr = cpu_to_le32(paddr);
+	if (len > MAX_DESC_BUF_SZ)
+		p->buf2_addr = cpu_to_le32(paddr + MAX_DESC_BUF_SZ);
+}
+
+static inline void desc_set_buf_addr_and_size(struct xgmac_dma_desc *p,
+					      void *paddr, int len)
+{
+	desc_set_buf_len(p, len);
+	desc_set_buf_addr(p, paddr, len);
+}
+
+static inline int desc_get_rx_frame_len(struct xgmac_dma_desc *p)
+{
+	u32 data = le32_to_cpu(p->flags);
+	u32 len = (data & RXDESC_FRAME_LEN_MASK) >> RXDESC_FRAME_LEN_OFFSET;
+	if (data & RXDESC_FRAME_TYPE)
+		len -= 4;
+
+	return len;
+}
+
+struct calxeda_eth_dev {
+	struct xgmac_dma_desc rx_chain[RX_NUM_DESC];
+	struct xgmac_dma_desc tx_chain[TX_NUM_DESC];
+	char rxbuffer[RX_BUF_SZ];
+
+	u32 tx_currdesc;
+	u32 rx_currdesc;
+
+	struct eth_device *dev;
+} __aligned(32);
+
+/*
+ * Initialize a descriptor ring.  Calxeda XGMAC is configured to use
+ * advanced descriptors.
+ */
+
+static void init_rx_desc(struct calxeda_eth_dev *priv)
+{
+	struct xgmac_dma_desc *rxdesc = priv->rx_chain;
+	struct xgmac_regs *regs = (struct xgmac_regs *)priv->dev->iobase;
+	void *rxbuffer = priv->rxbuffer;
+	int i;
+
+	desc_init_rx_desc(rxdesc, RX_NUM_DESC, ETH_BUF_SZ);
+	writel((ulong)rxdesc, &regs->rxdesclist);
+
+	for (i = 0; i < RX_NUM_DESC; i++) {
+		desc_set_buf_addr(rxdesc + i, rxbuffer + (i * ETH_BUF_SZ),
+				  ETH_BUF_SZ);
+		desc_set_rx_owner(rxdesc + i);
+	}
+}
+
+static void init_tx_desc(struct calxeda_eth_dev *priv)
+{
+	struct xgmac_regs *regs = (struct xgmac_regs *)priv->dev->iobase;
+
+	desc_init_tx_desc(priv->tx_chain, TX_NUM_DESC);
+	writel((ulong)priv->tx_chain, &regs->txdesclist);
+}
+
+static int xgmac_reset(struct eth_device *dev)
+{
+	struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase;
+	int timeout = MAC_TIMEOUT;
+	u32 value;
+
+	value = readl(&regs->config) & XGMAC_CONTROL_SPD_MASK;
+
+	writel(XGMAC_DMA_BUSMODE_RESET, &regs->busmode);
+	while ((timeout-- >= 0) &&
+		(readl(&regs->busmode) & XGMAC_DMA_BUSMODE_RESET))
+		udelay(1);
+
+	writel(value, &regs->config);
+
+	return timeout;
+}
+
+static void xgmac_hwmacaddr(struct eth_device *dev)
+{
+	struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase;
+	u32 macaddr[2];
+
+	memcpy(macaddr, dev->enetaddr, 6);
+	writel(macaddr[1], &regs->macaddr[0].hi);
+	writel(macaddr[0], &regs->macaddr[0].lo);
+}
+
+static int xgmac_init(struct eth_device *dev, bd_t * bis)
+{
+	struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase;
+	struct calxeda_eth_dev *priv = dev->priv;
+	int value;
+
+	if (xgmac_reset(dev) < 0)
+		return -1;
+
+	/* set the hardware MAC address */
+	xgmac_hwmacaddr(dev);
+
+	/* set the AXI bus modes */
+	value = XGMAC_DMA_BUSMODE_ATDS |
+		(16 << XGMAC_DMA_BUSMODE_PBL_SHIFT) |
+		XGMAC_DMA_BUSMODE_FB | XGMAC_DMA_BUSMODE_AAL;
+	writel(value, &regs->busmode);
+
+	value = XGMAC_DMA_AXIMODE_AAL | XGMAC_DMA_AXIMODE_BLEN16 |
+		XGMAC_DMA_AXIMODE_BLEN8 | XGMAC_DMA_AXIMODE_BLEN4;
+	writel(value, &regs->axi_mode);
+
+	/* set flow control parameters and store and forward mode */
+	value = (FIFO_MINUS_12K << XGMAC_CORE_OMR_RFD_SHIFT) |
+		(FIFO_MINUS_4K << XGMAC_CORE_OMR_RFA_SHIFT) |
+		XGMAC_CORE_OMR_EFC | XGMAC_CORE_OMR_TSF;
+	writel(value, &regs->core_opmode);
+
+	/* enable pause frames */
+	value = (1024 << XGMAC_CORE_FLOW_PT_SHIFT) |
+		(1 << XGMAC_CORE_FLOW_PLT_SHIFT) |
+		XGMAC_CORE_FLOW_UP | XGMAC_CORE_FLOW_RFE | XGMAC_CORE_FLOW_TFE;
+	writel(value, &regs->flow_control);
+
+	/* Initialize the descriptor chains */
+	init_rx_desc(priv);
+	init_tx_desc(priv);
+
+	/* must set to 0, or when started up will cause issues */
+	priv->tx_currdesc = 0;
+	priv->rx_currdesc = 0;
+
+	/* set default core values */
+	value = readl(&regs->config);
+	value &= XGMAC_CONTROL_SPD_MASK;
+	value |= XGMAC_CONTROL_DDIC | XGMAC_CONTROL_ACS |
+		XGMAC_CONTROL_IPC | XGMAC_CONTROL_CAR;
+
+	/* Everything is ready enable both mac and DMA */
+	value |= RXENABLE | TXENABLE;
+	writel(value, &regs->config);
+
+	value = readl(&regs->dma_opmode);
+	value |= RXSTART | TXSTART;
+	writel(value, &regs->dma_opmode);
+
+	return 0;
+}
+
+static int xgmac_tx(struct eth_device *dev, void *packet, int length)
+{
+	struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase;
+	struct calxeda_eth_dev *priv = dev->priv;
+	u32 currdesc = priv->tx_currdesc;
+	struct xgmac_dma_desc *txdesc = &priv->tx_chain[currdesc];
+	int timeout;
+
+	desc_set_buf_addr_and_size(txdesc, packet, length);
+	desc_set_tx_owner(txdesc, TXDESC_FIRST_SEG |
+		TXDESC_LAST_SEG | TXDESC_CRC_EN_APPEND);
+
+	/* write poll demand */
+	writel(1, &regs->txpoll);
+
+	timeout = 1000000;
+	while (desc_get_owner(txdesc)) {
+		if (timeout-- < 0) {
+			printf("xgmac: TX timeout\n");
+			return -ETIMEDOUT;
+		}
+		udelay(1);
+	}
+
+	priv->tx_currdesc = (currdesc + 1) & (TX_NUM_DESC - 1);
+	return 0;
+}
+
+static int xgmac_rx(struct eth_device *dev)
+{
+	struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase;
+	struct calxeda_eth_dev *priv = dev->priv;
+	u32 currdesc = priv->rx_currdesc;
+	struct xgmac_dma_desc *rxdesc = &priv->rx_chain[currdesc];
+	int length = 0;
+
+	/* check if the host has the desc */
+	if (desc_get_owner(rxdesc))
+		return -1; /* something bad happened */
+
+	length = desc_get_rx_frame_len(rxdesc);
+
+	NetReceive(desc_get_buf_addr(rxdesc), length);
+
+	/* set descriptor back to owned by XGMAC */
+	desc_set_rx_owner(rxdesc);
+	writel(1, &regs->rxpoll);
+
+	priv->rx_currdesc = (currdesc + 1) & (RX_NUM_DESC - 1);
+
+	return length;
+}
+
+static void xgmac_halt(struct eth_device *dev)
+{
+	struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase;
+	struct calxeda_eth_dev *priv = dev->priv;
+	int value;
+
+	/* Disable TX/RX */
+	value = readl(&regs->config);
+	value &= ~(RXENABLE | TXENABLE);
+	writel(value, &regs->config);
+
+	/* Disable DMA */
+	value = readl(&regs->dma_opmode);
+	value &= ~(RXSTART | TXSTART);
+	writel(value, &regs->dma_opmode);
+
+	/* must set to 0, or when started up will cause issues */
+	priv->tx_currdesc = 0;
+	priv->rx_currdesc = 0;
+}
+
+int calxedaxgmac_initialize(u32 id, ulong base_addr)
+{
+	struct eth_device *dev;
+	struct calxeda_eth_dev *priv;
+	struct xgmac_regs *regs;
+	u32 macaddr[2];
+
+	regs = (struct xgmac_regs *)base_addr;
+
+	/* check hardware version */
+	if (readl(&regs->version) != 0x1012)
+		return -1;
+
+	dev = malloc(sizeof(*dev));
+	if (!dev)
+		return 0;
+	memset(dev, 0, sizeof(*dev));
+
+	/* Structure must be aligned, because it contains the descriptors */
+	priv = memalign(32, sizeof(*priv));
+	if (!priv) {
+		free(dev);
+		return 0;
+	}
+
+	dev->iobase = (int)base_addr;
+	dev->priv = priv;
+	priv->dev = dev;
+	sprintf(dev->name, "xgmac%d", id);
+
+	/* The MAC address is already configured, so read it from registers. */
+	macaddr[1] = readl(&regs->macaddr[0].hi);
+	macaddr[0] = readl(&regs->macaddr[0].lo);
+	memcpy(dev->enetaddr, macaddr, 6);
+
+	dev->init = xgmac_init;
+	dev->send = xgmac_tx;
+	dev->recv = xgmac_rx;
+	dev->halt = xgmac_halt;
+
+	eth_register(dev);
+
+	return 1;
+}
diff --git a/marvell/uboot/drivers/net/cpsw.c b/marvell/uboot/drivers/net/cpsw.c
new file mode 100644
index 0000000..50167aa
--- /dev/null
+++ b/marvell/uboot/drivers/net/cpsw.c
@@ -0,0 +1,1024 @@
+/*
+ * CPSW Ethernet Switch Driver
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <miiphy.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <cpsw.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <phy.h>
+#include <asm/arch/cpu.h>
+
+#define BITMASK(bits)		(BIT(bits) - 1)
+#define PHY_REG_MASK		0x1f
+#define PHY_ID_MASK		0x1f
+#define NUM_DESCS		(PKTBUFSRX * 2)
+#define PKT_MIN			60
+#define PKT_MAX			(1500 + 14 + 4 + 4)
+#define CLEAR_BIT		1
+#define GIGABITEN		BIT(7)
+#define FULLDUPLEXEN		BIT(0)
+#define MIIEN			BIT(15)
+
+/* DMA Registers */
+#define CPDMA_TXCONTROL		0x004
+#define CPDMA_RXCONTROL		0x014
+#define CPDMA_SOFTRESET		0x01c
+#define CPDMA_RXFREE		0x0e0
+#define CPDMA_TXHDP_VER1	0x100
+#define CPDMA_TXHDP_VER2	0x200
+#define CPDMA_RXHDP_VER1	0x120
+#define CPDMA_RXHDP_VER2	0x220
+#define CPDMA_TXCP_VER1		0x140
+#define CPDMA_TXCP_VER2		0x240
+#define CPDMA_RXCP_VER1		0x160
+#define CPDMA_RXCP_VER2		0x260
+
+/* Descriptor mode bits */
+#define CPDMA_DESC_SOP		BIT(31)
+#define CPDMA_DESC_EOP		BIT(30)
+#define CPDMA_DESC_OWNER	BIT(29)
+#define CPDMA_DESC_EOQ		BIT(28)
+
+/*
+ * This timeout definition is a worst-case ultra defensive measure against
+ * unexpected controller lock ups.  Ideally, we should never ever hit this
+ * scenario in practice.
+ */
+#define MDIO_TIMEOUT            100 /* msecs */
+#define CPDMA_TIMEOUT		100 /* msecs */
+
+struct cpsw_mdio_regs {
+	u32	version;
+	u32	control;
+#define CONTROL_IDLE		BIT(31)
+#define CONTROL_ENABLE		BIT(30)
+
+	u32	alive;
+	u32	link;
+	u32	linkintraw;
+	u32	linkintmasked;
+	u32	__reserved_0[2];
+	u32	userintraw;
+	u32	userintmasked;
+	u32	userintmaskset;
+	u32	userintmaskclr;
+	u32	__reserved_1[20];
+
+	struct {
+		u32		access;
+		u32		physel;
+#define USERACCESS_GO		BIT(31)
+#define USERACCESS_WRITE	BIT(30)
+#define USERACCESS_ACK		BIT(29)
+#define USERACCESS_READ		(0)
+#define USERACCESS_DATA		(0xffff)
+	} user[0];
+};
+
+struct cpsw_regs {
+	u32	id_ver;
+	u32	control;
+	u32	soft_reset;
+	u32	stat_port_en;
+	u32	ptype;
+};
+
+struct cpsw_slave_regs {
+	u32	max_blks;
+	u32	blk_cnt;
+	u32	flow_thresh;
+	u32	port_vlan;
+	u32	tx_pri_map;
+#ifdef CONFIG_AM33XX
+	u32	gap_thresh;
+#elif defined(CONFIG_TI814X)
+	u32	ts_ctl;
+	u32	ts_seq_ltype;
+	u32	ts_vlan;
+#endif
+	u32	sa_lo;
+	u32	sa_hi;
+};
+
+struct cpsw_host_regs {
+	u32	max_blks;
+	u32	blk_cnt;
+	u32	flow_thresh;
+	u32	port_vlan;
+	u32	tx_pri_map;
+	u32	cpdma_tx_pri_map;
+	u32	cpdma_rx_chan_map;
+};
+
+struct cpsw_sliver_regs {
+	u32	id_ver;
+	u32	mac_control;
+	u32	mac_status;
+	u32	soft_reset;
+	u32	rx_maxlen;
+	u32	__reserved_0;
+	u32	rx_pause;
+	u32	tx_pause;
+	u32	__reserved_1;
+	u32	rx_pri_map;
+};
+
+#define ALE_ENTRY_BITS		68
+#define ALE_ENTRY_WORDS		DIV_ROUND_UP(ALE_ENTRY_BITS, 32)
+
+/* ALE Registers */
+#define ALE_CONTROL		0x08
+#define ALE_UNKNOWNVLAN		0x18
+#define ALE_TABLE_CONTROL	0x20
+#define ALE_TABLE		0x34
+#define ALE_PORTCTL		0x40
+
+#define ALE_TABLE_WRITE		BIT(31)
+
+#define ALE_TYPE_FREE			0
+#define ALE_TYPE_ADDR			1
+#define ALE_TYPE_VLAN			2
+#define ALE_TYPE_VLAN_ADDR		3
+
+#define ALE_UCAST_PERSISTANT		0
+#define ALE_UCAST_UNTOUCHED		1
+#define ALE_UCAST_OUI			2
+#define ALE_UCAST_TOUCHED		3
+
+#define ALE_MCAST_FWD			0
+#define ALE_MCAST_BLOCK_LEARN_FWD	1
+#define ALE_MCAST_FWD_LEARN		2
+#define ALE_MCAST_FWD_2			3
+
+enum cpsw_ale_port_state {
+	ALE_PORT_STATE_DISABLE	= 0x00,
+	ALE_PORT_STATE_BLOCK	= 0x01,
+	ALE_PORT_STATE_LEARN	= 0x02,
+	ALE_PORT_STATE_FORWARD	= 0x03,
+};
+
+/* ALE unicast entry flags - passed into cpsw_ale_add_ucast() */
+#define ALE_SECURE	1
+#define ALE_BLOCKED	2
+
+struct cpsw_slave {
+	struct cpsw_slave_regs		*regs;
+	struct cpsw_sliver_regs		*sliver;
+	int				slave_num;
+	u32				mac_control;
+	struct cpsw_slave_data		*data;
+};
+
+struct cpdma_desc {
+	/* hardware fields */
+	u32			hw_next;
+	u32			hw_buffer;
+	u32			hw_len;
+	u32			hw_mode;
+	/* software fields */
+	u32			sw_buffer;
+	u32			sw_len;
+};
+
+struct cpdma_chan {
+	struct cpdma_desc	*head, *tail;
+	void			*hdp, *cp, *rxfree;
+};
+
+#define desc_write(desc, fld, val)	__raw_writel((u32)(val), &(desc)->fld)
+#define desc_read(desc, fld)		__raw_readl(&(desc)->fld)
+#define desc_read_ptr(desc, fld)	((void *)__raw_readl(&(desc)->fld))
+
+#define chan_write(chan, fld, val)	__raw_writel((u32)(val), (chan)->fld)
+#define chan_read(chan, fld)		__raw_readl((chan)->fld)
+#define chan_read_ptr(chan, fld)	((void *)__raw_readl((chan)->fld))
+
+#define for_each_slave(slave, priv) \
+	for (slave = (priv)->slaves; slave != (priv)->slaves + \
+				(priv)->data.slaves; slave++)
+
+struct cpsw_priv {
+	struct eth_device		*dev;
+	struct cpsw_platform_data	data;
+	int				host_port;
+
+	struct cpsw_regs		*regs;
+	void				*dma_regs;
+	struct cpsw_host_regs		*host_port_regs;
+	void				*ale_regs;
+
+	struct cpdma_desc		*descs;
+	struct cpdma_desc		*desc_free;
+	struct cpdma_chan		rx_chan, tx_chan;
+
+	struct cpsw_slave		*slaves;
+	struct phy_device		*phydev;
+	struct mii_dev			*bus;
+
+	u32				mdio_link;
+	u32				phy_mask;
+};
+
+static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
+{
+	int idx;
+
+	idx    = start / 32;
+	start -= idx * 32;
+	idx    = 2 - idx; /* flip */
+	return (ale_entry[idx] >> start) & BITMASK(bits);
+}
+
+static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
+				      u32 value)
+{
+	int idx;
+
+	value &= BITMASK(bits);
+	idx    = start / 32;
+	start -= idx * 32;
+	idx    = 2 - idx; /* flip */
+	ale_entry[idx] &= ~(BITMASK(bits) << start);
+	ale_entry[idx] |=  (value << start);
+}
+
+#define DEFINE_ALE_FIELD(name, start, bits)				\
+static inline int cpsw_ale_get_##name(u32 *ale_entry)			\
+{									\
+	return cpsw_ale_get_field(ale_entry, start, bits);		\
+}									\
+static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value)	\
+{									\
+	cpsw_ale_set_field(ale_entry, start, bits, value);		\
+}
+
+DEFINE_ALE_FIELD(entry_type,		60,	2)
+DEFINE_ALE_FIELD(mcast_state,		62,	2)
+DEFINE_ALE_FIELD(port_mask,		66,	3)
+DEFINE_ALE_FIELD(ucast_type,		62,	2)
+DEFINE_ALE_FIELD(port_num,		66,	2)
+DEFINE_ALE_FIELD(blocked,		65,	1)
+DEFINE_ALE_FIELD(secure,		64,	1)
+DEFINE_ALE_FIELD(mcast,			40,	1)
+
+/* The MAC address field in the ALE entry cannot be macroized as above */
+static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr)
+{
+	int i;
+
+	for (i = 0; i < 6; i++)
+		addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8);
+}
+
+static inline void cpsw_ale_set_addr(u32 *ale_entry, u8 *addr)
+{
+	int i;
+
+	for (i = 0; i < 6; i++)
+		cpsw_ale_set_field(ale_entry, 40 - 8*i, 8, addr[i]);
+}
+
+static int cpsw_ale_read(struct cpsw_priv *priv, int idx, u32 *ale_entry)
+{
+	int i;
+
+	__raw_writel(idx, priv->ale_regs + ALE_TABLE_CONTROL);
+
+	for (i = 0; i < ALE_ENTRY_WORDS; i++)
+		ale_entry[i] = __raw_readl(priv->ale_regs + ALE_TABLE + 4 * i);
+
+	return idx;
+}
+
+static int cpsw_ale_write(struct cpsw_priv *priv, int idx, u32 *ale_entry)
+{
+	int i;
+
+	for (i = 0; i < ALE_ENTRY_WORDS; i++)
+		__raw_writel(ale_entry[i], priv->ale_regs + ALE_TABLE + 4 * i);
+
+	__raw_writel(idx | ALE_TABLE_WRITE, priv->ale_regs + ALE_TABLE_CONTROL);
+
+	return idx;
+}
+
+static int cpsw_ale_match_addr(struct cpsw_priv *priv, u8* addr)
+{
+	u32 ale_entry[ALE_ENTRY_WORDS];
+	int type, idx;
+
+	for (idx = 0; idx < priv->data.ale_entries; idx++) {
+		u8 entry_addr[6];
+
+		cpsw_ale_read(priv, idx, ale_entry);
+		type = cpsw_ale_get_entry_type(ale_entry);
+		if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
+			continue;
+		cpsw_ale_get_addr(ale_entry, entry_addr);
+		if (memcmp(entry_addr, addr, 6) == 0)
+			return idx;
+	}
+	return -ENOENT;
+}
+
+static int cpsw_ale_match_free(struct cpsw_priv *priv)
+{
+	u32 ale_entry[ALE_ENTRY_WORDS];
+	int type, idx;
+
+	for (idx = 0; idx < priv->data.ale_entries; idx++) {
+		cpsw_ale_read(priv, idx, ale_entry);
+		type = cpsw_ale_get_entry_type(ale_entry);
+		if (type == ALE_TYPE_FREE)
+			return idx;
+	}
+	return -ENOENT;
+}
+
+static int cpsw_ale_find_ageable(struct cpsw_priv *priv)
+{
+	u32 ale_entry[ALE_ENTRY_WORDS];
+	int type, idx;
+
+	for (idx = 0; idx < priv->data.ale_entries; idx++) {
+		cpsw_ale_read(priv, idx, ale_entry);
+		type = cpsw_ale_get_entry_type(ale_entry);
+		if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
+			continue;
+		if (cpsw_ale_get_mcast(ale_entry))
+			continue;
+		type = cpsw_ale_get_ucast_type(ale_entry);
+		if (type != ALE_UCAST_PERSISTANT &&
+		    type != ALE_UCAST_OUI)
+			return idx;
+	}
+	return -ENOENT;
+}
+
+static int cpsw_ale_add_ucast(struct cpsw_priv *priv, u8 *addr,
+			      int port, int flags)
+{
+	u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
+	int idx;
+
+	cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
+	cpsw_ale_set_addr(ale_entry, addr);
+	cpsw_ale_set_ucast_type(ale_entry, ALE_UCAST_PERSISTANT);
+	cpsw_ale_set_secure(ale_entry, (flags & ALE_SECURE) ? 1 : 0);
+	cpsw_ale_set_blocked(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0);
+	cpsw_ale_set_port_num(ale_entry, port);
+
+	idx = cpsw_ale_match_addr(priv, addr);
+	if (idx < 0)
+		idx = cpsw_ale_match_free(priv);
+	if (idx < 0)
+		idx = cpsw_ale_find_ageable(priv);
+	if (idx < 0)
+		return -ENOMEM;
+
+	cpsw_ale_write(priv, idx, ale_entry);
+	return 0;
+}
+
+static int cpsw_ale_add_mcast(struct cpsw_priv *priv, u8 *addr, int port_mask)
+{
+	u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
+	int idx, mask;
+
+	idx = cpsw_ale_match_addr(priv, addr);
+	if (idx >= 0)
+		cpsw_ale_read(priv, idx, ale_entry);
+
+	cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
+	cpsw_ale_set_addr(ale_entry, addr);
+	cpsw_ale_set_mcast_state(ale_entry, ALE_MCAST_FWD_2);
+
+	mask = cpsw_ale_get_port_mask(ale_entry);
+	port_mask |= mask;
+	cpsw_ale_set_port_mask(ale_entry, port_mask);
+
+	if (idx < 0)
+		idx = cpsw_ale_match_free(priv);
+	if (idx < 0)
+		idx = cpsw_ale_find_ageable(priv);
+	if (idx < 0)
+		return -ENOMEM;
+
+	cpsw_ale_write(priv, idx, ale_entry);
+	return 0;
+}
+
+static inline void cpsw_ale_control(struct cpsw_priv *priv, int bit, int val)
+{
+	u32 tmp, mask = BIT(bit);
+
+	tmp  = __raw_readl(priv->ale_regs + ALE_CONTROL);
+	tmp &= ~mask;
+	tmp |= val ? mask : 0;
+	__raw_writel(tmp, priv->ale_regs + ALE_CONTROL);
+}
+
+#define cpsw_ale_enable(priv, val)	cpsw_ale_control(priv, 31, val)
+#define cpsw_ale_clear(priv, val)	cpsw_ale_control(priv, 30, val)
+#define cpsw_ale_vlan_aware(priv, val)	cpsw_ale_control(priv,  2, val)
+
+static inline void cpsw_ale_port_state(struct cpsw_priv *priv, int port,
+				       int val)
+{
+	int offset = ALE_PORTCTL + 4 * port;
+	u32 tmp, mask = 0x3;
+
+	tmp  = __raw_readl(priv->ale_regs + offset);
+	tmp &= ~mask;
+	tmp |= val & mask;
+	__raw_writel(tmp, priv->ale_regs + offset);
+}
+
+static struct cpsw_mdio_regs *mdio_regs;
+
+/* wait until hardware is ready for another user access */
+static inline u32 wait_for_user_access(void)
+{
+	u32 reg = 0;
+	int timeout = MDIO_TIMEOUT;
+
+	while (timeout-- &&
+	((reg = __raw_readl(&mdio_regs->user[0].access)) & USERACCESS_GO))
+		udelay(10);
+
+	if (timeout == -1) {
+		printf("wait_for_user_access Timeout\n");
+		return -ETIMEDOUT;
+	}
+	return reg;
+}
+
+/* wait until hardware state machine is idle */
+static inline void wait_for_idle(void)
+{
+	int timeout = MDIO_TIMEOUT;
+
+	while (timeout-- &&
+		((__raw_readl(&mdio_regs->control) & CONTROL_IDLE) == 0))
+		udelay(10);
+
+	if (timeout == -1)
+		printf("wait_for_idle Timeout\n");
+}
+
+static int cpsw_mdio_read(struct mii_dev *bus, int phy_id,
+				int dev_addr, int phy_reg)
+{
+	int data;
+	u32 reg;
+
+	if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
+		return -EINVAL;
+
+	wait_for_user_access();
+	reg = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) |
+	       (phy_id << 16));
+	__raw_writel(reg, &mdio_regs->user[0].access);
+	reg = wait_for_user_access();
+
+	data = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -1;
+	return data;
+}
+
+static int cpsw_mdio_write(struct mii_dev *bus, int phy_id, int dev_addr,
+				int phy_reg, u16 data)
+{
+	u32 reg;
+
+	if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
+		return -EINVAL;
+
+	wait_for_user_access();
+	reg = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) |
+		   (phy_id << 16) | (data & USERACCESS_DATA));
+	__raw_writel(reg, &mdio_regs->user[0].access);
+	wait_for_user_access();
+
+	return 0;
+}
+
+static void cpsw_mdio_init(char *name, u32 mdio_base, u32 div)
+{
+	struct mii_dev *bus = mdio_alloc();
+
+	mdio_regs = (struct cpsw_mdio_regs *)mdio_base;
+
+	/* set enable and clock divider */
+	__raw_writel(div | CONTROL_ENABLE, &mdio_regs->control);
+
+	/*
+	 * wait for scan logic to settle:
+	 * the scan time consists of (a) a large fixed component, and (b) a
+	 * small component that varies with the mii bus frequency.  These
+	 * were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x
+	 * silicon.  Since the effect of (b) was found to be largely
+	 * negligible, we keep things simple here.
+	 */
+	udelay(1000);
+
+	bus->read = cpsw_mdio_read;
+	bus->write = cpsw_mdio_write;
+	sprintf(bus->name, name);
+
+	mdio_register(bus);
+}
+
+/* Set a self-clearing bit in a register, and wait for it to clear */
+static inline void setbit_and_wait_for_clear32(void *addr)
+{
+	__raw_writel(CLEAR_BIT, addr);
+	while (__raw_readl(addr) & CLEAR_BIT)
+		;
+}
+
+#define mac_hi(mac)	(((mac)[0] << 0) | ((mac)[1] << 8) |	\
+			 ((mac)[2] << 16) | ((mac)[3] << 24))
+#define mac_lo(mac)	(((mac)[4] << 0) | ((mac)[5] << 8))
+
+static void cpsw_set_slave_mac(struct cpsw_slave *slave,
+			       struct cpsw_priv *priv)
+{
+	__raw_writel(mac_hi(priv->dev->enetaddr), &slave->regs->sa_hi);
+	__raw_writel(mac_lo(priv->dev->enetaddr), &slave->regs->sa_lo);
+}
+
+static void cpsw_slave_update_link(struct cpsw_slave *slave,
+				   struct cpsw_priv *priv, int *link)
+{
+	struct phy_device *phy;
+	u32 mac_control = 0;
+
+	phy = priv->phydev;
+
+	if (!phy)
+		return;
+
+	phy_startup(phy);
+	*link = phy->link;
+
+	if (*link) { /* link up */
+		mac_control = priv->data.mac_control;
+		if (phy->speed == 1000)
+			mac_control |= GIGABITEN;
+		if (phy->duplex == DUPLEX_FULL)
+			mac_control |= FULLDUPLEXEN;
+		if (phy->speed == 100)
+			mac_control |= MIIEN;
+	}
+
+	if (mac_control == slave->mac_control)
+		return;
+
+	if (mac_control) {
+		printf("link up on port %d, speed %d, %s duplex\n",
+				slave->slave_num, phy->speed,
+				(phy->duplex == DUPLEX_FULL) ? "full" : "half");
+	} else {
+		printf("link down on port %d\n", slave->slave_num);
+	}
+
+	__raw_writel(mac_control, &slave->sliver->mac_control);
+	slave->mac_control = mac_control;
+}
+
+static int cpsw_update_link(struct cpsw_priv *priv)
+{
+	int link = 0;
+	struct cpsw_slave *slave;
+
+	for_each_slave(slave, priv)
+		cpsw_slave_update_link(slave, priv, &link);
+	priv->mdio_link = readl(&mdio_regs->link);
+	return link;
+}
+
+static int cpsw_check_link(struct cpsw_priv *priv)
+{
+	u32 link = 0;
+
+	link = __raw_readl(&mdio_regs->link) & priv->phy_mask;
+	if ((link) && (link == priv->mdio_link))
+		return 1;
+
+	return cpsw_update_link(priv);
+}
+
+static inline u32  cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
+{
+	if (priv->host_port == 0)
+		return slave_num + 1;
+	else
+		return slave_num;
+}
+
+static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv)
+{
+	u32     slave_port;
+
+	setbit_and_wait_for_clear32(&slave->sliver->soft_reset);
+
+	/* setup priority mapping */
+	__raw_writel(0x76543210, &slave->sliver->rx_pri_map);
+	__raw_writel(0x33221100, &slave->regs->tx_pri_map);
+
+	/* setup max packet size, and mac address */
+	__raw_writel(PKT_MAX, &slave->sliver->rx_maxlen);
+	cpsw_set_slave_mac(slave, priv);
+
+	slave->mac_control = 0;	/* no link yet */
+
+	/* enable forwarding */
+	slave_port = cpsw_get_slave_port(priv, slave->slave_num);
+	cpsw_ale_port_state(priv, slave_port, ALE_PORT_STATE_FORWARD);
+
+	cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << slave_port);
+
+	priv->phy_mask |= 1 << slave->data->phy_id;
+}
+
+static struct cpdma_desc *cpdma_desc_alloc(struct cpsw_priv *priv)
+{
+	struct cpdma_desc *desc = priv->desc_free;
+
+	if (desc)
+		priv->desc_free = desc_read_ptr(desc, hw_next);
+	return desc;
+}
+
+static void cpdma_desc_free(struct cpsw_priv *priv, struct cpdma_desc *desc)
+{
+	if (desc) {
+		desc_write(desc, hw_next, priv->desc_free);
+		priv->desc_free = desc;
+	}
+}
+
+static int cpdma_submit(struct cpsw_priv *priv, struct cpdma_chan *chan,
+			void *buffer, int len)
+{
+	struct cpdma_desc *desc, *prev;
+	u32 mode;
+
+	desc = cpdma_desc_alloc(priv);
+	if (!desc)
+		return -ENOMEM;
+
+	if (len < PKT_MIN)
+		len = PKT_MIN;
+
+	mode = CPDMA_DESC_OWNER | CPDMA_DESC_SOP | CPDMA_DESC_EOP;
+
+	desc_write(desc, hw_next,   0);
+	desc_write(desc, hw_buffer, buffer);
+	desc_write(desc, hw_len,    len);
+	desc_write(desc, hw_mode,   mode | len);
+	desc_write(desc, sw_buffer, buffer);
+	desc_write(desc, sw_len,    len);
+
+	if (!chan->head) {
+		/* simple case - first packet enqueued */
+		chan->head = desc;
+		chan->tail = desc;
+		chan_write(chan, hdp, desc);
+		goto done;
+	}
+
+	/* not the first packet - enqueue at the tail */
+	prev = chan->tail;
+	desc_write(prev, hw_next, desc);
+	chan->tail = desc;
+
+	/* next check if EOQ has been triggered already */
+	if (desc_read(prev, hw_mode) & CPDMA_DESC_EOQ)
+		chan_write(chan, hdp, desc);
+
+done:
+	if (chan->rxfree)
+		chan_write(chan, rxfree, 1);
+	return 0;
+}
+
+static int cpdma_process(struct cpsw_priv *priv, struct cpdma_chan *chan,
+			 void **buffer, int *len)
+{
+	struct cpdma_desc *desc = chan->head;
+	u32 status;
+
+	if (!desc)
+		return -ENOENT;
+
+	status = desc_read(desc, hw_mode);
+
+	if (len)
+		*len = status & 0x7ff;
+
+	if (buffer)
+		*buffer = desc_read_ptr(desc, sw_buffer);
+
+	if (status & CPDMA_DESC_OWNER) {
+		if (chan_read(chan, hdp) == 0) {
+			if (desc_read(desc, hw_mode) & CPDMA_DESC_OWNER)
+				chan_write(chan, hdp, desc);
+		}
+
+		return -EBUSY;
+	}
+
+	chan->head = desc_read_ptr(desc, hw_next);
+	chan_write(chan, cp, desc);
+
+	cpdma_desc_free(priv, desc);
+	return 0;
+}
+
+static int cpsw_init(struct eth_device *dev, bd_t *bis)
+{
+	struct cpsw_priv	*priv = dev->priv;
+	struct cpsw_slave	*slave;
+	int i, ret;
+
+	/* soft reset the controller and initialize priv */
+	setbit_and_wait_for_clear32(&priv->regs->soft_reset);
+
+	/* initialize and reset the address lookup engine */
+	cpsw_ale_enable(priv, 1);
+	cpsw_ale_clear(priv, 1);
+	cpsw_ale_vlan_aware(priv, 0); /* vlan unaware mode */
+
+	/* setup host port priority mapping */
+	__raw_writel(0x76543210, &priv->host_port_regs->cpdma_tx_pri_map);
+	__raw_writel(0, &priv->host_port_regs->cpdma_rx_chan_map);
+
+	/* disable priority elevation and enable statistics on all ports */
+	__raw_writel(0, &priv->regs->ptype);
+
+	/* enable statistics collection only on the host port */
+	__raw_writel(BIT(priv->host_port), &priv->regs->stat_port_en);
+	__raw_writel(0x7, &priv->regs->stat_port_en);
+
+	cpsw_ale_port_state(priv, priv->host_port, ALE_PORT_STATE_FORWARD);
+
+	cpsw_ale_add_ucast(priv, priv->dev->enetaddr, priv->host_port,
+			   ALE_SECURE);
+	cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << priv->host_port);
+
+	for_each_slave(slave, priv)
+		cpsw_slave_init(slave, priv);
+
+	cpsw_update_link(priv);
+
+	/* init descriptor pool */
+	for (i = 0; i < NUM_DESCS; i++) {
+		desc_write(&priv->descs[i], hw_next,
+			   (i == (NUM_DESCS - 1)) ? 0 : &priv->descs[i+1]);
+	}
+	priv->desc_free = &priv->descs[0];
+
+	/* initialize channels */
+	if (priv->data.version == CPSW_CTRL_VERSION_2) {
+		memset(&priv->rx_chan, 0, sizeof(struct cpdma_chan));
+		priv->rx_chan.hdp       = priv->dma_regs + CPDMA_RXHDP_VER2;
+		priv->rx_chan.cp        = priv->dma_regs + CPDMA_RXCP_VER2;
+		priv->rx_chan.rxfree    = priv->dma_regs + CPDMA_RXFREE;
+
+		memset(&priv->tx_chan, 0, sizeof(struct cpdma_chan));
+		priv->tx_chan.hdp       = priv->dma_regs + CPDMA_TXHDP_VER2;
+		priv->tx_chan.cp        = priv->dma_regs + CPDMA_TXCP_VER2;
+	} else {
+		memset(&priv->rx_chan, 0, sizeof(struct cpdma_chan));
+		priv->rx_chan.hdp       = priv->dma_regs + CPDMA_RXHDP_VER1;
+		priv->rx_chan.cp        = priv->dma_regs + CPDMA_RXCP_VER1;
+		priv->rx_chan.rxfree    = priv->dma_regs + CPDMA_RXFREE;
+
+		memset(&priv->tx_chan, 0, sizeof(struct cpdma_chan));
+		priv->tx_chan.hdp       = priv->dma_regs + CPDMA_TXHDP_VER1;
+		priv->tx_chan.cp        = priv->dma_regs + CPDMA_TXCP_VER1;
+	}
+
+	/* clear dma state */
+	setbit_and_wait_for_clear32(priv->dma_regs + CPDMA_SOFTRESET);
+
+	if (priv->data.version == CPSW_CTRL_VERSION_2) {
+		for (i = 0; i < priv->data.channels; i++) {
+			__raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER2 + 4
+					* i);
+			__raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4
+					* i);
+			__raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER2 + 4
+					* i);
+			__raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER2 + 4
+					* i);
+			__raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER2 + 4
+					* i);
+		}
+	} else {
+		for (i = 0; i < priv->data.channels; i++) {
+			__raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER1 + 4
+					* i);
+			__raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4
+					* i);
+			__raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER1 + 4
+					* i);
+			__raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER1 + 4
+					* i);
+			__raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER1 + 4
+					* i);
+
+		}
+	}
+
+	__raw_writel(1, priv->dma_regs + CPDMA_TXCONTROL);
+	__raw_writel(1, priv->dma_regs + CPDMA_RXCONTROL);
+
+	/* submit rx descs */
+	for (i = 0; i < PKTBUFSRX; i++) {
+		ret = cpdma_submit(priv, &priv->rx_chan, NetRxPackets[i],
+				   PKTSIZE);
+		if (ret < 0) {
+			printf("error %d submitting rx desc\n", ret);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static void cpsw_halt(struct eth_device *dev)
+{
+	struct cpsw_priv	*priv = dev->priv;
+
+	writel(0, priv->dma_regs + CPDMA_TXCONTROL);
+	writel(0, priv->dma_regs + CPDMA_RXCONTROL);
+
+	/* soft reset the controller and initialize priv */
+	setbit_and_wait_for_clear32(&priv->regs->soft_reset);
+
+	/* clear dma state */
+	setbit_and_wait_for_clear32(priv->dma_regs + CPDMA_SOFTRESET);
+
+	priv->data.control(0);
+}
+
+static int cpsw_send(struct eth_device *dev, void *packet, int length)
+{
+	struct cpsw_priv	*priv = dev->priv;
+	void *buffer;
+	int len;
+	int timeout = CPDMA_TIMEOUT;
+
+	if (!cpsw_check_link(priv))
+		return -EIO;
+
+	flush_dcache_range((unsigned long)packet,
+			   (unsigned long)packet + length);
+
+	/* first reap completed packets */
+	while (timeout-- &&
+		(cpdma_process(priv, &priv->tx_chan, &buffer, &len) >= 0))
+		;
+
+	if (timeout == -1) {
+		printf("cpdma_process timeout\n");
+		return -ETIMEDOUT;
+	}
+
+	return cpdma_submit(priv, &priv->tx_chan, packet, length);
+}
+
+static int cpsw_recv(struct eth_device *dev)
+{
+	struct cpsw_priv	*priv = dev->priv;
+	void *buffer;
+	int len;
+
+	cpsw_check_link(priv);
+
+	while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) >= 0) {
+		invalidate_dcache_range((unsigned long)buffer,
+					(unsigned long)buffer + PKTSIZE_ALIGN);
+		NetReceive(buffer, len);
+		cpdma_submit(priv, &priv->rx_chan, buffer, PKTSIZE);
+	}
+
+	return 0;
+}
+
+static void cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
+			    struct cpsw_priv *priv)
+{
+	void			*regs = priv->regs;
+	struct cpsw_slave_data	*data = priv->data.slave_data + slave_num;
+	slave->slave_num = slave_num;
+	slave->data	= data;
+	slave->regs	= regs + data->slave_reg_ofs;
+	slave->sliver	= regs + data->sliver_reg_ofs;
+}
+
+static int cpsw_phy_init(struct eth_device *dev, struct cpsw_slave *slave)
+{
+	struct cpsw_priv *priv = (struct cpsw_priv *)dev->priv;
+	struct phy_device *phydev;
+	u32 supported = (SUPPORTED_10baseT_Half |
+			SUPPORTED_10baseT_Full |
+			SUPPORTED_100baseT_Half |
+			SUPPORTED_100baseT_Full |
+			SUPPORTED_1000baseT_Full);
+
+	phydev = phy_connect(priv->bus,
+			CONFIG_PHY_ADDR,
+			dev,
+			slave->data->phy_if);
+
+	if (!phydev)
+		return -1;
+
+	phydev->supported &= supported;
+	phydev->advertising = phydev->supported;
+
+	priv->phydev = phydev;
+	phy_config(phydev);
+
+	return 1;
+}
+
+int cpsw_register(struct cpsw_platform_data *data)
+{
+	struct cpsw_priv	*priv;
+	struct cpsw_slave	*slave;
+	void			*regs = (void *)data->cpsw_base;
+	struct eth_device	*dev;
+
+	dev = calloc(sizeof(*dev), 1);
+	if (!dev)
+		return -ENOMEM;
+
+	priv = calloc(sizeof(*priv), 1);
+	if (!priv) {
+		free(dev);
+		return -ENOMEM;
+	}
+
+	priv->data = *data;
+	priv->dev = dev;
+
+	priv->slaves = malloc(sizeof(struct cpsw_slave) * data->slaves);
+	if (!priv->slaves) {
+		free(dev);
+		free(priv);
+		return -ENOMEM;
+	}
+
+	priv->host_port		= data->host_port_num;
+	priv->regs		= regs;
+	priv->host_port_regs	= regs + data->host_port_reg_ofs;
+	priv->dma_regs		= regs + data->cpdma_reg_ofs;
+	priv->ale_regs		= regs + data->ale_reg_ofs;
+	priv->descs		= (void *)regs + data->bd_ram_ofs;
+
+	int idx = 0;
+
+	for_each_slave(slave, priv) {
+		cpsw_slave_setup(slave, idx, priv);
+		idx = idx + 1;
+	}
+
+	strcpy(dev->name, "cpsw");
+	dev->iobase	= 0;
+	dev->init	= cpsw_init;
+	dev->halt	= cpsw_halt;
+	dev->send	= cpsw_send;
+	dev->recv	= cpsw_recv;
+	dev->priv	= priv;
+
+	eth_register(dev);
+
+	cpsw_mdio_init(dev->name, data->mdio_base, data->mdio_div);
+	priv->bus = miiphy_get_dev_by_name(dev->name);
+	for_each_slave(slave, priv)
+		cpsw_phy_init(dev, slave);
+
+	return 1;
+}
diff --git a/marvell/uboot/drivers/net/cs8900.c b/marvell/uboot/drivers/net/cs8900.c
new file mode 100644
index 0000000..84963c1
--- /dev/null
+++ b/marvell/uboot/drivers/net/cs8900.c
@@ -0,0 +1,320 @@
+/*
+ * Cirrus Logic CS8900A Ethernet
+ *
+ * (C) 2009 Ben Warren , biggerbadderben@gmail.com
+ *     Converted to use CONFIG_NET_MULTI API
+ *
+ * (C) 2003 Wolfgang Denk, wd@denx.de
+ *     Extension to synchronize ethaddr environment variable
+ *     against value in EEPROM
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Copyright (C) 1999 Ben Williamson <benw@pobox.com>
+ *
+ * This program is loaded into SRAM in bootstrap mode, where it waits
+ * for commands on UART1 to read and write memory, jump to code etc.
+ * A design goal for this program is to be entirely independent of the
+ * target board.  Anything with a CL-PS7111 or EP7211 should be able to run
+ * this code in bootstrap mode.  All the board specifics can be handled on
+ * the host.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/io.h>
+#include <net.h>
+#include <malloc.h>
+#include "cs8900.h"
+
+#undef DEBUG
+
+/* packet page register access functions */
+
+#ifdef CONFIG_CS8900_BUS32
+
+#define REG_WRITE(v, a) writel((v),(a))
+#define REG_READ(a) readl((a))
+
+/* we don't need 16 bit initialisation on 32 bit bus */
+#define get_reg_init_bus(r,d) get_reg((r),(d))
+
+#else
+
+#define REG_WRITE(v, a) writew((v),(a))
+#define REG_READ(a) readw((a))
+
+static u16 get_reg_init_bus(struct eth_device *dev, int regno)
+{
+	/* force 16 bit busmode */
+	struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv);
+	uint8_t volatile * const iob = (uint8_t volatile * const)dev->iobase;
+
+	readb(iob);
+	readb(iob + 1);
+	readb(iob);
+	readb(iob + 1);
+	readb(iob);
+
+	REG_WRITE(regno, &priv->regs->pptr);
+	return REG_READ(&priv->regs->pdata);
+}
+#endif
+
+static u16 get_reg(struct eth_device *dev, int regno)
+{
+	struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv);
+	REG_WRITE(regno, &priv->regs->pptr);
+	return REG_READ(&priv->regs->pdata);
+}
+
+
+static void put_reg(struct eth_device *dev, int regno, u16 val)
+{
+	struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv);
+	REG_WRITE(regno, &priv->regs->pptr);
+	REG_WRITE(val, &priv->regs->pdata);
+}
+
+static void cs8900_reset(struct eth_device *dev)
+{
+	int tmo;
+	u16 us;
+
+	/* reset NIC */
+	put_reg(dev, PP_SelfCTL, get_reg(dev, PP_SelfCTL) | PP_SelfCTL_Reset);
+
+	/* wait for 200ms */
+	udelay(200000);
+	/* Wait until the chip is reset */
+
+	tmo = get_timer(0) + 1 * CONFIG_SYS_HZ;
+	while ((((us = get_reg_init_bus(dev, PP_SelfSTAT)) &
+		PP_SelfSTAT_InitD) == 0) && tmo < get_timer(0))
+		/*NOP*/;
+}
+
+static void cs8900_reginit(struct eth_device *dev)
+{
+	/* receive only error free packets addressed to this card */
+	put_reg(dev, PP_RxCTL,
+		PP_RxCTL_IA | PP_RxCTL_Broadcast | PP_RxCTL_RxOK);
+	/* do not generate any interrupts on receive operations */
+	put_reg(dev, PP_RxCFG, 0);
+	/* do not generate any interrupts on transmit operations */
+	put_reg(dev, PP_TxCFG, 0);
+	/* do not generate any interrupts on buffer operations */
+	put_reg(dev, PP_BufCFG, 0);
+	/* enable transmitter/receiver mode */
+	put_reg(dev, PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx);
+}
+
+void cs8900_get_enetaddr(struct eth_device *dev)
+{
+	int i;
+
+	/* verify chip id */
+	if (get_reg_init_bus(dev, PP_ChipID) != 0x630e)
+		return;
+	cs8900_reset(dev);
+	if ((get_reg(dev, PP_SelfSTAT) &
+		(PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) ==
+		(PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) {
+
+		/* Load the MAC from EEPROM */
+		for (i = 0; i < 3; i++) {
+			u32 Addr;
+
+			Addr = get_reg(dev, PP_IA + i * 2);
+			dev->enetaddr[i * 2] = Addr & 0xFF;
+			dev->enetaddr[i * 2 + 1] = Addr >> 8;
+		}
+	}
+}
+
+void cs8900_halt(struct eth_device *dev)
+{
+	/* disable transmitter/receiver mode */
+	put_reg(dev, PP_LineCTL, 0);
+
+	/* "shutdown" to show ChipID or kernel wouldn't find he cs8900 ... */
+	get_reg_init_bus(dev, PP_ChipID);
+}
+
+static int cs8900_init(struct eth_device *dev, bd_t * bd)
+{
+	uchar *enetaddr = dev->enetaddr;
+	u16 id;
+
+	/* verify chip id */
+	id = get_reg_init_bus(dev, PP_ChipID);
+	if (id != 0x630e) {
+		printf ("CS8900 Ethernet chip not found: "
+			"ID=0x%04x instead 0x%04x\n", id, 0x630e);
+		return 1;
+	}
+
+	cs8900_reset (dev);
+	/* set the ethernet address */
+	put_reg(dev, PP_IA + 0, enetaddr[0] | (enetaddr[1] << 8));
+	put_reg(dev, PP_IA + 2, enetaddr[2] | (enetaddr[3] << 8));
+	put_reg(dev, PP_IA + 4, enetaddr[4] | (enetaddr[5] << 8));
+
+	cs8900_reginit(dev);
+	return 0;
+}
+
+/* Get a data block via Ethernet */
+static int cs8900_recv(struct eth_device *dev)
+{
+	int i;
+	u16 rxlen;
+	u16 *addr;
+	u16 status;
+
+	struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv);
+
+	status = get_reg(dev, PP_RER);
+
+	if ((status & PP_RER_RxOK) == 0)
+		return 0;
+
+	status = REG_READ(&priv->regs->rtdata);
+	rxlen = REG_READ(&priv->regs->rtdata);
+
+	if (rxlen > PKTSIZE_ALIGN + PKTALIGN)
+		debug("packet too big!\n");
+	for (addr = (u16 *) NetRxPackets[0], i = rxlen >> 1; i > 0;
+		 i--)
+		*addr++ = REG_READ(&priv->regs->rtdata);
+	if (rxlen & 1)
+		*addr++ = REG_READ(&priv->regs->rtdata);
+
+	/* Pass the packet up to the protocol layers. */
+	NetReceive (NetRxPackets[0], rxlen);
+	return rxlen;
+}
+
+/* Send a data block via Ethernet. */
+static int cs8900_send(struct eth_device *dev, void *packet, int length)
+{
+	volatile u16 *addr;
+	int tmo;
+	u16 s;
+	struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv);
+
+retry:
+	/* initiate a transmit sequence */
+	REG_WRITE(PP_TxCmd_TxStart_Full, &priv->regs->txcmd);
+	REG_WRITE(length, &priv->regs->txlen);
+
+	/* Test to see if the chip has allocated memory for the packet */
+	if ((get_reg(dev, PP_BusSTAT) & PP_BusSTAT_TxRDY) == 0) {
+		/* Oops... this should not happen! */
+		debug("cs: unable to send packet; retrying...\n");
+		for (tmo = get_timer(0) + 5 * CONFIG_SYS_HZ;
+			get_timer(0) < tmo;)
+			/*NOP*/;
+		cs8900_reset(dev);
+		cs8900_reginit(dev);
+		goto retry;
+	}
+
+	/* Write the contents of the packet */
+	/* assume even number of bytes */
+	for (addr = packet; length > 0; length -= 2)
+		REG_WRITE(*addr++, &priv->regs->rtdata);
+
+	/* wait for transfer to succeed */
+	tmo = get_timer(0) + 5 * CONFIG_SYS_HZ;
+	while ((s = get_reg(dev, PP_TER) & ~0x1F) == 0) {
+		if (get_timer(0) >= tmo)
+			break;
+	}
+
+	/* nothing */ ;
+	if((s & (PP_TER_CRS | PP_TER_TxOK)) != PP_TER_TxOK) {
+		debug("\ntransmission error %#x\n", s);
+	}
+
+	return 0;
+}
+
+static void cs8900_e2prom_ready(struct eth_device *dev)
+{
+	while (get_reg(dev, PP_SelfSTAT) & SI_BUSY)
+		;
+}
+
+/***********************************************************/
+/* read a 16-bit word out of the EEPROM                    */
+/***********************************************************/
+
+int cs8900_e2prom_read(struct eth_device *dev,
+			u8 addr, u16 *value)
+{
+	cs8900_e2prom_ready(dev);
+	put_reg(dev, PP_EECMD, EEPROM_READ_CMD | addr);
+	cs8900_e2prom_ready(dev);
+	*value = get_reg(dev, PP_EEData);
+
+	return 0;
+}
+
+
+/***********************************************************/
+/* write a 16-bit word into the EEPROM                     */
+/***********************************************************/
+
+int cs8900_e2prom_write(struct eth_device *dev, u8 addr, u16 value)
+{
+	cs8900_e2prom_ready(dev);
+	put_reg(dev, PP_EECMD, EEPROM_WRITE_EN);
+	cs8900_e2prom_ready(dev);
+	put_reg(dev, PP_EEData, value);
+	put_reg(dev, PP_EECMD, EEPROM_WRITE_CMD | addr);
+	cs8900_e2prom_ready(dev);
+	put_reg(dev, PP_EECMD, EEPROM_WRITE_DIS);
+	cs8900_e2prom_ready(dev);
+
+	return 0;
+}
+
+int cs8900_initialize(u8 dev_num, int base_addr)
+{
+	struct eth_device *dev;
+	struct cs8900_priv *priv;
+
+	dev = malloc(sizeof(*dev));
+	if (!dev) {
+		return 0;
+	}
+	memset(dev, 0, sizeof(*dev));
+
+	priv = malloc(sizeof(*priv));
+	if (!priv) {
+		free(dev);
+		return 0;
+	}
+	memset(priv, 0, sizeof(*priv));
+	priv->regs = (struct cs8900_regs *)base_addr;
+
+	dev->iobase = base_addr;
+	dev->priv = priv;
+	dev->init = cs8900_init;
+	dev->halt = cs8900_halt;
+	dev->send = cs8900_send;
+	dev->recv = cs8900_recv;
+
+	/* Load MAC address from EEPROM */
+	cs8900_get_enetaddr(dev);
+
+	sprintf(dev->name, "%s-%hu", CS8900_DRIVERNAME, dev_num);
+
+	eth_register(dev);
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/cs8900.h b/marvell/uboot/drivers/net/cs8900.h
new file mode 100644
index 0000000..79877dd
--- /dev/null
+++ b/marvell/uboot/drivers/net/cs8900.h
@@ -0,0 +1,249 @@
+#ifndef CS8900_H
+#define CS8900_H
+/*
+ * Cirrus Logic CS8900A Ethernet
+ *
+ * (C) 2009 Ben Warren , biggerbadderben@gmail.com
+ *     Converted to use CONFIG_NET_MULTI API
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Copyright (C) 1999 Ben Williamson <benw@pobox.com>
+ *
+ * This program is loaded into SRAM in bootstrap mode, where it waits
+ * for commands on UART1 to read and write memory, jump to code etc.
+ * A design goal for this program is to be entirely independent of the
+ * target board.  Anything with a CL-PS7111 or EP7211 should be able to run
+ * this code in bootstrap mode.  All the board specifics can be handled on
+ * the host.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/types.h>
+#include <config.h>
+
+#define CS8900_DRIVERNAME "CS8900"
+/* although the registers are 16 bit, they are 32-bit aligned on the
+   EDB7111. so we have to read them as 32-bit registers and ignore the
+   upper 16-bits. i'm not sure if this holds for the EDB7211. */
+
+#ifdef CONFIG_CS8900_BUS16
+  /* 16 bit aligned registers, 16 bit wide */
+  #define CS8900_REG u16
+#elif defined(CONFIG_CS8900_BUS32)
+  /* 32 bit aligned registers, 16 bit wide (we ignore upper 16 bits) */
+  #define CS8900_REG u32
+#else
+  #error unknown bussize ...
+#endif
+
+struct cs8900_regs {
+	CS8900_REG rtdata;
+	CS8900_REG pad0;
+	CS8900_REG txcmd;
+	CS8900_REG txlen;
+	CS8900_REG isq;
+	CS8900_REG pptr;
+	CS8900_REG pdata;
+};
+
+struct cs8900_priv {
+	struct cs8900_regs *regs;
+};
+
+#define ISQ_RxEvent     0x04
+#define ISQ_TxEvent     0x08
+#define ISQ_BufEvent    0x0C
+#define ISQ_RxMissEvent 0x10
+#define ISQ_TxColEvent  0x12
+#define ISQ_EventMask   0x3F
+
+/* packet page register offsets */
+
+/* bus interface registers */
+#define PP_ChipID    0x0000  /* Chip identifier - must be 0x630E */
+#define PP_ChipRev   0x0002  /* Chip revision, model codes */
+
+#define PP_IntReg    0x0022  /* Interrupt configuration */
+#define PP_IntReg_IRQ0         0x0000  /* Use INTR0 pin */
+#define PP_IntReg_IRQ1         0x0001  /* Use INTR1 pin */
+#define PP_IntReg_IRQ2         0x0002  /* Use INTR2 pin */
+#define PP_IntReg_IRQ3         0x0003  /* Use INTR3 pin */
+
+/* status and control registers */
+
+#define PP_RxCFG     0x0102  /* Receiver configuration */
+#define PP_RxCFG_Skip1         0x0040  /* Skip (i.e. discard) current frame */
+#define PP_RxCFG_Stream        0x0080  /* Enable streaming mode */
+#define PP_RxCFG_RxOK          0x0100  /* RxOK interrupt enable */
+#define PP_RxCFG_RxDMAonly     0x0200  /* Use RxDMA for all frames */
+#define PP_RxCFG_AutoRxDMA     0x0400  /* Select RxDMA automatically */
+#define PP_RxCFG_BufferCRC     0x0800  /* Include CRC characters in frame */
+#define PP_RxCFG_CRC           0x1000  /* Enable interrupt on CRC error */
+#define PP_RxCFG_RUNT          0x2000  /* Enable interrupt on RUNT frames */
+#define PP_RxCFG_EXTRA         0x4000  /* Enable interrupt on frames with extra data */
+
+#define PP_RxCTL     0x0104  /* Receiver control */
+#define PP_RxCTL_IAHash        0x0040  /* Accept frames that match hash */
+#define PP_RxCTL_Promiscuous   0x0080  /* Accept any frame */
+#define PP_RxCTL_RxOK          0x0100  /* Accept well formed frames */
+#define PP_RxCTL_Multicast     0x0200  /* Accept multicast frames */
+#define PP_RxCTL_IA            0x0400  /* Accept frame that matches IA */
+#define PP_RxCTL_Broadcast     0x0800  /* Accept broadcast frames */
+#define PP_RxCTL_CRC           0x1000  /* Accept frames with bad CRC */
+#define PP_RxCTL_RUNT          0x2000  /* Accept runt frames */
+#define PP_RxCTL_EXTRA         0x4000  /* Accept frames that are too long */
+
+#define PP_TxCFG     0x0106  /* Transmit configuration */
+#define PP_TxCFG_CRS           0x0040  /* Enable interrupt on loss of carrier */
+#define PP_TxCFG_SQE           0x0080  /* Enable interrupt on Signal Quality Error */
+#define PP_TxCFG_TxOK          0x0100  /* Enable interrupt on successful xmits */
+#define PP_TxCFG_Late          0x0200  /* Enable interrupt on "out of window" */
+#define PP_TxCFG_Jabber        0x0400  /* Enable interrupt on jabber detect */
+#define PP_TxCFG_Collision     0x0800  /* Enable interrupt if collision */
+#define PP_TxCFG_16Collisions  0x8000  /* Enable interrupt if > 16 collisions */
+
+#define PP_TxCmd     0x0108  /* Transmit command status */
+#define PP_TxCmd_TxStart_5     0x0000  /* Start after 5 bytes in buffer */
+#define PP_TxCmd_TxStart_381   0x0040  /* Start after 381 bytes in buffer */
+#define PP_TxCmd_TxStart_1021  0x0080  /* Start after 1021 bytes in buffer */
+#define PP_TxCmd_TxStart_Full  0x00C0  /* Start after all bytes loaded */
+#define PP_TxCmd_Force         0x0100  /* Discard any pending packets */
+#define PP_TxCmd_OneCollision  0x0200  /* Abort after a single collision */
+#define PP_TxCmd_NoCRC         0x1000  /* Do not add CRC */
+#define PP_TxCmd_NoPad         0x2000  /* Do not pad short packets */
+
+#define PP_BufCFG    0x010A  /* Buffer configuration */
+#define PP_BufCFG_SWI          0x0040  /* Force interrupt via software */
+#define PP_BufCFG_RxDMA        0x0080  /* Enable interrupt on Rx DMA */
+#define PP_BufCFG_TxRDY        0x0100  /* Enable interrupt when ready for Tx */
+#define PP_BufCFG_TxUE         0x0200  /* Enable interrupt in Tx underrun */
+#define PP_BufCFG_RxMiss       0x0400  /* Enable interrupt on missed Rx packets */
+#define PP_BufCFG_Rx128        0x0800  /* Enable Rx interrupt after 128 bytes */
+#define PP_BufCFG_TxCol        0x1000  /* Enable int on Tx collision ctr overflow */
+#define PP_BufCFG_Miss         0x2000  /* Enable int on Rx miss ctr overflow */
+#define PP_BufCFG_RxDest       0x8000  /* Enable int on Rx dest addr match */
+
+#define PP_LineCTL   0x0112  /* Line control */
+#define PP_LineCTL_Rx          0x0040  /* Enable receiver */
+#define PP_LineCTL_Tx          0x0080  /* Enable transmitter */
+#define PP_LineCTL_AUIonly     0x0100  /* AUI interface only */
+#define PP_LineCTL_AutoAUI10BT 0x0200  /* Autodetect AUI or 10BaseT interface */
+#define PP_LineCTL_ModBackoffE 0x0800  /* Enable modified backoff algorithm */
+#define PP_LineCTL_PolarityDis 0x1000  /* Disable Rx polarity autodetect */
+#define PP_LineCTL_2partDefDis 0x2000  /* Disable two-part defferal */
+#define PP_LineCTL_LoRxSquelch 0x4000  /* Reduce receiver squelch threshold */
+
+#define PP_SelfCTL   0x0114  /* Chip self control */
+#define PP_SelfCTL_Reset       0x0040  /* Self-clearing reset */
+#define PP_SelfCTL_SWSuspend   0x0100  /* Initiate suspend mode */
+#define PP_SelfCTL_HWSleepE    0x0200  /* Enable SLEEP input */
+#define PP_SelfCTL_HWStandbyE  0x0400  /* Enable standby mode */
+#define PP_SelfCTL_HC0E        0x1000  /* use HCB0 for LINK LED */
+#define PP_SelfCTL_HC1E        0x2000  /* use HCB1 for BSTATUS LED */
+#define PP_SelfCTL_HCB0        0x4000  /* control LINK LED if HC0E set */
+#define PP_SelfCTL_HCB1        0x8000  /* control BSTATUS LED if HC1E set */
+
+#define PP_BusCTL    0x0116  /* Bus control */
+#define PP_BusCTL_ResetRxDMA   0x0040  /* Reset RxDMA pointer */
+#define PP_BusCTL_DMAextend    0x0100  /* Extend DMA cycle */
+#define PP_BusCTL_UseSA        0x0200  /* Assert MEMCS16 on address decode */
+#define PP_BusCTL_MemoryE      0x0400  /* Enable memory mode */
+#define PP_BusCTL_DMAburst     0x0800  /* Limit DMA access burst */
+#define PP_BusCTL_IOCHRDYE     0x1000  /* Set IOCHRDY high impedence */
+#define PP_BusCTL_RxDMAsize    0x2000  /* Set DMA buffer size 64KB */
+#define PP_BusCTL_EnableIRQ    0x8000  /* Generate interrupt on interrupt event */
+
+#define PP_TestCTL   0x0118  /* Test control */
+#define PP_TestCTL_DisableLT   0x0080  /* Disable link status */
+#define PP_TestCTL_ENDECloop   0x0200  /* Internal loopback */
+#define PP_TestCTL_AUIloop     0x0400  /* AUI loopback */
+#define PP_TestCTL_DisBackoff  0x0800  /* Disable backoff algorithm */
+#define PP_TestCTL_FDX         0x4000  /* Enable full duplex mode */
+
+#define PP_ISQ       0x0120  /* Interrupt Status Queue */
+
+#define PP_RER       0x0124  /* Receive event */
+#define PP_RER_IAHash          0x0040  /* Frame hash match */
+#define PP_RER_Dribble         0x0080  /* Frame had 1-7 extra bits after last byte */
+#define PP_RER_RxOK            0x0100  /* Frame received with no errors */
+#define PP_RER_Hashed          0x0200  /* Frame address hashed OK */
+#define PP_RER_IA              0x0400  /* Frame address matched IA */
+#define PP_RER_Broadcast       0x0800  /* Broadcast frame */
+#define PP_RER_CRC             0x1000  /* Frame had CRC error */
+#define PP_RER_RUNT            0x2000  /* Runt frame */
+#define PP_RER_EXTRA           0x4000  /* Frame was too long */
+
+#define PP_TER       0x0128 /* Transmit event */
+#define PP_TER_CRS             0x0040  /* Carrier lost */
+#define PP_TER_SQE             0x0080  /* Signal Quality Error */
+#define PP_TER_TxOK            0x0100  /* Packet sent without error */
+#define PP_TER_Late            0x0200  /* Out of window */
+#define PP_TER_Jabber          0x0400  /* Stuck transmit? */
+#define PP_TER_NumCollisions   0x7800  /* Number of collisions */
+#define PP_TER_16Collisions    0x8000  /* > 16 collisions */
+
+#define PP_BER       0x012C /* Buffer event */
+#define PP_BER_SWint           0x0040 /* Software interrupt */
+#define PP_BER_RxDMAFrame      0x0080 /* Received framed DMAed */
+#define PP_BER_Rdy4Tx          0x0100 /* Ready for transmission */
+#define PP_BER_TxUnderrun      0x0200 /* Transmit underrun */
+#define PP_BER_RxMiss          0x0400 /* Received frame missed */
+#define PP_BER_Rx128           0x0800 /* 128 bytes received */
+#define PP_BER_RxDest          0x8000 /* Received framed passed address filter */
+
+#define PP_RxMiss    0x0130  /*  Receiver miss counter */
+
+#define PP_TxCol     0x0132  /*  Transmit collision counter */
+
+#define PP_LineSTAT  0x0134  /* Line status */
+#define PP_LineSTAT_LinkOK     0x0080  /* Line is connected and working */
+#define PP_LineSTAT_AUI        0x0100  /* Connected via AUI */
+#define PP_LineSTAT_10BT       0x0200  /* Connected via twisted pair */
+#define PP_LineSTAT_Polarity   0x1000  /* Line polarity OK (10BT only) */
+#define PP_LineSTAT_CRS        0x4000  /* Frame being received */
+
+#define PP_SelfSTAT  0x0136  /* Chip self status */
+#define PP_SelfSTAT_33VActive  0x0040  /* supply voltage is 3.3V */
+#define PP_SelfSTAT_InitD      0x0080  /* Chip initialization complete */
+#define PP_SelfSTAT_SIBSY      0x0100  /* EEPROM is busy */
+#define PP_SelfSTAT_EEPROM     0x0200  /* EEPROM present */
+#define PP_SelfSTAT_EEPROM_OK  0x0400  /* EEPROM checks out */
+#define PP_SelfSTAT_ELPresent  0x0800  /* External address latch logic available */
+#define PP_SelfSTAT_EEsize     0x1000  /* Size of EEPROM */
+
+#define PP_BusSTAT   0x0138  /* Bus status */
+#define PP_BusSTAT_TxBid       0x0080  /* Tx error */
+#define PP_BusSTAT_TxRDY       0x0100  /* Ready for Tx data */
+
+#define PP_TDR       0x013C  /* AUI Time Domain Reflectometer */
+
+/* initiate transmit registers */
+
+#define PP_TxCommand 0x0144  /* Tx Command */
+#define PP_TxLength  0x0146  /* Tx Length */
+
+
+/* address filter registers */
+
+#define PP_LAF       0x0150  /* Logical address filter (6 bytes) */
+#define PP_IA        0x0158  /* Individual address (MAC) */
+
+/* EEPROM Kram */
+#define SI_BUSY 0x0100
+#define PP_EECMD 0x0040		/*  NVR Interface Command register */
+#define PP_EEData 0x0042	/*  NVR Interface Data Register */
+#define EEPROM_WRITE_EN		0x00F0
+#define EEPROM_WRITE_DIS	0x0000
+#define EEPROM_WRITE_CMD	0x0100
+#define EEPROM_READ_CMD		0x0200
+#define EEPROM_ERASE_CMD	0x0300
+
+/* Exported functions */
+int cs8900_e2prom_read(struct eth_device *dev, uchar, ushort *);
+int cs8900_e2prom_write(struct eth_device *dev, uchar, ushort);
+
+#endif  /* CS8900_H */
diff --git a/marvell/uboot/drivers/net/davinci_emac.c b/marvell/uboot/drivers/net/davinci_emac.c
new file mode 100644
index 0000000..439f8ae
--- /dev/null
+++ b/marvell/uboot/drivers/net/davinci_emac.c
@@ -0,0 +1,894 @@
+/*
+ * Ethernet driver for TI TMS320DM644x (DaVinci) chips.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Parts shamelessly stolen from TI's dm644x_emac.c. Original copyright
+ * follows:
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * dm644x_emac.c
+ *
+ * TI DaVinci (DM644X) EMAC peripheral driver source for DV-EVM
+ *
+ * Copyright (C) 2005 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Modifications:
+ * ver. 1.0: Sep 2005, Anant Gole - Created EMAC version for uBoot.
+ * ver  1.1: Nov 2005, Anant Gole - Extended the RX logic for multiple descriptors
+ */
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <miiphy.h>
+#include <malloc.h>
+#include <linux/compiler.h>
+#include <asm/arch/emac_defs.h>
+#include <asm/io.h>
+#include "davinci_emac.h"
+
+unsigned int	emac_dbg = 0;
+#define debug_emac(fmt,args...)	if (emac_dbg) printf(fmt,##args)
+
+#ifdef EMAC_HW_RAM_ADDR
+static inline unsigned long BD_TO_HW(unsigned long x)
+{
+	if (x == 0)
+		return 0;
+
+	return x - EMAC_WRAPPER_RAM_ADDR + EMAC_HW_RAM_ADDR;
+}
+
+static inline unsigned long HW_TO_BD(unsigned long x)
+{
+	if (x == 0)
+		return 0;
+
+	return x - EMAC_HW_RAM_ADDR + EMAC_WRAPPER_RAM_ADDR;
+}
+#else
+#define BD_TO_HW(x)	(x)
+#define HW_TO_BD(x)	(x)
+#endif
+
+#ifdef DAVINCI_EMAC_GIG_ENABLE
+#define emac_gigabit_enable(phy_addr)	davinci_eth_gigabit_enable(phy_addr)
+#else
+#define emac_gigabit_enable(phy_addr)	/* no gigabit to enable */
+#endif
+
+#if !defined(CONFIG_SYS_EMAC_TI_CLKDIV)
+#define CONFIG_SYS_EMAC_TI_CLKDIV	((EMAC_MDIO_BUS_FREQ / \
+		EMAC_MDIO_CLOCK_FREQ) - 1)
+#endif
+
+static void davinci_eth_mdio_enable(void);
+
+static int gen_init_phy(int phy_addr);
+static int gen_is_phy_connected(int phy_addr);
+static int gen_get_link_speed(int phy_addr);
+static int gen_auto_negotiate(int phy_addr);
+
+void eth_mdio_enable(void)
+{
+	davinci_eth_mdio_enable();
+}
+
+/* EMAC Addresses */
+static volatile emac_regs	*adap_emac = (emac_regs *)EMAC_BASE_ADDR;
+static volatile ewrap_regs	*adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR;
+static volatile mdio_regs	*adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR;
+
+/* EMAC descriptors */
+static volatile emac_desc	*emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE);
+static volatile emac_desc	*emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE);
+static volatile emac_desc	*emac_rx_active_head = 0;
+static volatile emac_desc	*emac_rx_active_tail = 0;
+static int			emac_rx_queue_active = 0;
+
+/* Receive packet buffers */
+static unsigned char emac_rx_buffers[EMAC_MAX_RX_BUFFERS * EMAC_RXBUF_SIZE]
+				__aligned(ARCH_DMA_MINALIGN);
+
+#ifndef CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT
+#define CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT	3
+#endif
+
+/* PHY address for a discovered PHY (0xff - not found) */
+static u_int8_t	active_phy_addr[CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT];
+
+/* number of PHY found active */
+static u_int8_t	num_phy;
+
+phy_t				phy[CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT];
+
+static inline void davinci_flush_rx_descs(void)
+{
+	/* flush the whole RX descs area */
+	flush_dcache_range(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE,
+			EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE);
+}
+
+static inline void davinci_invalidate_rx_descs(void)
+{
+	/* invalidate the whole RX descs area */
+	invalidate_dcache_range(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE,
+			EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE);
+}
+
+static inline void davinci_flush_desc(emac_desc *desc)
+{
+	flush_dcache_range((unsigned long)desc,
+			(unsigned long)desc + sizeof(*desc));
+}
+
+static int davinci_eth_set_mac_addr(struct eth_device *dev)
+{
+	unsigned long		mac_hi;
+	unsigned long		mac_lo;
+
+	/*
+	 * Set MAC Addresses & Init multicast Hash to 0 (disable any multicast
+	 * receive)
+	 *  Using channel 0 only - other channels are disabled
+	 *  */
+	writel(0, &adap_emac->MACINDEX);
+	mac_hi = (dev->enetaddr[3] << 24) |
+		 (dev->enetaddr[2] << 16) |
+		 (dev->enetaddr[1] << 8)  |
+		 (dev->enetaddr[0]);
+	mac_lo = (dev->enetaddr[5] << 8) |
+		 (dev->enetaddr[4]);
+
+	writel(mac_hi, &adap_emac->MACADDRHI);
+#if defined(DAVINCI_EMAC_VERSION2)
+	writel(mac_lo | EMAC_MAC_ADDR_IS_VALID | EMAC_MAC_ADDR_MATCH,
+	       &adap_emac->MACADDRLO);
+#else
+	writel(mac_lo, &adap_emac->MACADDRLO);
+#endif
+
+	writel(0, &adap_emac->MACHASH1);
+	writel(0, &adap_emac->MACHASH2);
+
+	/* Set source MAC address - REQUIRED */
+	writel(mac_hi, &adap_emac->MACSRCADDRHI);
+	writel(mac_lo, &adap_emac->MACSRCADDRLO);
+
+
+	return 0;
+}
+
+static void davinci_eth_mdio_enable(void)
+{
+	u_int32_t	clkdiv;
+
+	clkdiv = CONFIG_SYS_EMAC_TI_CLKDIV;
+
+	writel((clkdiv & 0xff) |
+	       MDIO_CONTROL_ENABLE |
+	       MDIO_CONTROL_FAULT |
+	       MDIO_CONTROL_FAULT_ENABLE,
+	       &adap_mdio->CONTROL);
+
+	while (readl(&adap_mdio->CONTROL) & MDIO_CONTROL_IDLE)
+		;
+}
+
+/*
+ * Tries to find an active connected PHY. Returns 1 if address if found.
+ * If no active PHY (or more than one PHY) found returns 0.
+ * Sets active_phy_addr variable.
+ */
+static int davinci_eth_phy_detect(void)
+{
+	u_int32_t	phy_act_state;
+	int		i;
+	int		j;
+	unsigned int	count = 0;
+
+	for (i = 0; i < CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT; i++)
+		active_phy_addr[i] = 0xff;
+
+	udelay(1000);
+	phy_act_state = readl(&adap_mdio->ALIVE);
+
+	if (phy_act_state == 0)
+		return 0;		/* No active PHYs */
+
+	debug_emac("davinci_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state);
+
+	for (i = 0, j = 0; i < 32; i++)
+		if (phy_act_state & (1 << i)) {
+			count++;
+			if (count <= CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT) {
+				active_phy_addr[j++] = i;
+			} else {
+				printf("%s: to many PHYs detected.\n",
+					__func__);
+				count = 0;
+				break;
+			}
+		}
+
+	num_phy = count;
+
+	return count;
+}
+
+
+/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
+int davinci_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
+{
+	int	tmp;
+
+	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
+		;
+
+	writel(MDIO_USERACCESS0_GO |
+	       MDIO_USERACCESS0_WRITE_READ |
+	       ((reg_num & 0x1f) << 21) |
+	       ((phy_addr & 0x1f) << 16),
+	       &adap_mdio->USERACCESS0);
+
+	/* Wait for command to complete */
+	while ((tmp = readl(&adap_mdio->USERACCESS0)) & MDIO_USERACCESS0_GO)
+		;
+
+	if (tmp & MDIO_USERACCESS0_ACK) {
+		*data = tmp & 0xffff;
+		return(1);
+	}
+
+	*data = -1;
+	return(0);
+}
+
+/* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */
+int davinci_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
+{
+
+	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
+		;
+
+	writel(MDIO_USERACCESS0_GO |
+	       MDIO_USERACCESS0_WRITE_WRITE |
+	       ((reg_num & 0x1f) << 21) |
+	       ((phy_addr & 0x1f) << 16) |
+	       (data & 0xffff),
+	       &adap_mdio->USERACCESS0);
+
+	/* Wait for command to complete */
+	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
+		;
+
+	return(1);
+}
+
+/* PHY functions for a generic PHY */
+static int gen_init_phy(int phy_addr)
+{
+	int	ret = 1;
+
+	if (gen_get_link_speed(phy_addr)) {
+		/* Try another time */
+		ret = gen_get_link_speed(phy_addr);
+	}
+
+	return(ret);
+}
+
+static int gen_is_phy_connected(int phy_addr)
+{
+	u_int16_t	dummy;
+
+	return davinci_eth_phy_read(phy_addr, MII_PHYSID1, &dummy);
+}
+
+static int get_active_phy(void)
+{
+	int i;
+
+	for (i = 0; i < num_phy; i++)
+		if (phy[i].get_link_speed(active_phy_addr[i]))
+			return i;
+
+	return -1;	/* Return error if no link */
+}
+
+static int gen_get_link_speed(int phy_addr)
+{
+	u_int16_t	tmp;
+
+	if (davinci_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) &&
+			(tmp & 0x04)) {
+#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
+		defined(CONFIG_MACH_DAVINCI_DA850_EVM)
+		davinci_eth_phy_read(phy_addr, MII_LPA, &tmp);
+
+		/* Speed doesn't matter, there is no setting for it in EMAC. */
+		if (tmp & (LPA_100FULL | LPA_10FULL)) {
+			/* set EMAC for Full Duplex  */
+			writel(EMAC_MACCONTROL_MIIEN_ENABLE |
+					EMAC_MACCONTROL_FULLDUPLEX_ENABLE,
+					&adap_emac->MACCONTROL);
+		} else {
+			/*set EMAC for Half Duplex  */
+			writel(EMAC_MACCONTROL_MIIEN_ENABLE,
+					&adap_emac->MACCONTROL);
+		}
+
+		if (tmp & (LPA_100FULL | LPA_100HALF))
+			writel(readl(&adap_emac->MACCONTROL) |
+					EMAC_MACCONTROL_RMIISPEED_100,
+					 &adap_emac->MACCONTROL);
+		else
+			writel(readl(&adap_emac->MACCONTROL) &
+					~EMAC_MACCONTROL_RMIISPEED_100,
+					 &adap_emac->MACCONTROL);
+#endif
+		return(1);
+	}
+
+	return(0);
+}
+
+static int gen_auto_negotiate(int phy_addr)
+{
+	u_int16_t	tmp;
+	u_int16_t	val;
+	unsigned long	cntr = 0;
+
+	if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp))
+		return 0;
+
+	val = tmp | BMCR_FULLDPLX | BMCR_ANENABLE |
+						BMCR_SPEED100;
+	davinci_eth_phy_write(phy_addr, MII_BMCR, val);
+
+	if (!davinci_eth_phy_read(phy_addr, MII_ADVERTISE, &val))
+		return 0;
+
+	val |= (ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10FULL |
+							ADVERTISE_10HALF);
+	davinci_eth_phy_write(phy_addr, MII_ADVERTISE, val);
+
+	if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp))
+		return(0);
+
+	/* Restart Auto_negotiation  */
+	tmp |= BMCR_ANRESTART;
+	davinci_eth_phy_write(phy_addr, MII_BMCR, tmp);
+
+	/*check AutoNegotiate complete */
+	do {
+		udelay(40000);
+		if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp))
+			return 0;
+
+		if (tmp & BMSR_ANEGCOMPLETE)
+			break;
+
+		cntr++;
+	} while (cntr < 200);
+
+	if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp))
+		return(0);
+
+	if (!(tmp & BMSR_ANEGCOMPLETE))
+		return(0);
+
+	return(gen_get_link_speed(phy_addr));
+}
+/* End of generic PHY functions */
+
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+static int davinci_mii_phy_read(const char *devname, unsigned char addr, unsigned char reg, unsigned short *value)
+{
+	return(davinci_eth_phy_read(addr, reg, value) ? 0 : 1);
+}
+
+static int davinci_mii_phy_write(const char *devname, unsigned char addr, unsigned char reg, unsigned short value)
+{
+	return(davinci_eth_phy_write(addr, reg, value) ? 0 : 1);
+}
+#endif
+
+static void  __attribute__((unused)) davinci_eth_gigabit_enable(int phy_addr)
+{
+	u_int16_t data;
+
+	if (davinci_eth_phy_read(phy_addr, 0, &data)) {
+		if (data & (1 << 6)) { /* speed selection MSB */
+			/*
+			 * Check if link detected is giga-bit
+			 * If Gigabit mode detected, enable gigbit in MAC
+			 */
+			writel(readl(&adap_emac->MACCONTROL) |
+				EMAC_MACCONTROL_GIGFORCE |
+				EMAC_MACCONTROL_GIGABIT_ENABLE,
+				&adap_emac->MACCONTROL);
+		}
+	}
+}
+
+/* Eth device open */
+static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
+{
+	dv_reg_p		addr;
+	u_int32_t		clkdiv, cnt;
+	volatile emac_desc	*rx_desc;
+	int			index;
+
+	debug_emac("+ emac_open\n");
+
+	/* Reset EMAC module and disable interrupts in wrapper */
+	writel(1, &adap_emac->SOFTRESET);
+	while (readl(&adap_emac->SOFTRESET) != 0)
+		;
+#if defined(DAVINCI_EMAC_VERSION2)
+	writel(1, &adap_ewrap->softrst);
+	while (readl(&adap_ewrap->softrst) != 0)
+		;
+#else
+	writel(0, &adap_ewrap->EWCTL);
+	for (cnt = 0; cnt < 5; cnt++) {
+		clkdiv = readl(&adap_ewrap->EWCTL);
+	}
+#endif
+
+#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
+	defined(CONFIG_MACH_DAVINCI_DA850_EVM)
+	adap_ewrap->c0rxen = adap_ewrap->c1rxen = adap_ewrap->c2rxen = 0;
+	adap_ewrap->c0txen = adap_ewrap->c1txen = adap_ewrap->c2txen = 0;
+	adap_ewrap->c0miscen = adap_ewrap->c1miscen = adap_ewrap->c2miscen = 0;
+#endif
+	rx_desc = emac_rx_desc;
+
+	writel(1, &adap_emac->TXCONTROL);
+	writel(1, &adap_emac->RXCONTROL);
+
+	davinci_eth_set_mac_addr(dev);
+
+	/* Set DMA 8 TX / 8 RX Head pointers to 0 */
+	addr = &adap_emac->TX0HDP;
+	for(cnt = 0; cnt < 16; cnt++)
+		writel(0, addr++);
+
+	addr = &adap_emac->RX0HDP;
+	for(cnt = 0; cnt < 16; cnt++)
+		writel(0, addr++);
+
+	/* Clear Statistics (do this before setting MacControl register) */
+	addr = &adap_emac->RXGOODFRAMES;
+	for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
+		writel(0, addr++);
+
+	/* No multicast addressing */
+	writel(0, &adap_emac->MACHASH1);
+	writel(0, &adap_emac->MACHASH2);
+
+	/* Create RX queue and set receive process in place */
+	emac_rx_active_head = emac_rx_desc;
+	for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
+		rx_desc->next = BD_TO_HW((u_int32_t)(rx_desc + 1));
+		rx_desc->buffer = &emac_rx_buffers[cnt * EMAC_RXBUF_SIZE];
+		rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
+		rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
+		rx_desc++;
+	}
+
+	/* Finalize the rx desc list */
+	rx_desc--;
+	rx_desc->next = 0;
+	emac_rx_active_tail = rx_desc;
+	emac_rx_queue_active = 1;
+
+	davinci_flush_rx_descs();
+
+	/* Enable TX/RX */
+	writel(EMAC_MAX_ETHERNET_PKT_SIZE, &adap_emac->RXMAXLEN);
+	writel(0, &adap_emac->RXBUFFEROFFSET);
+
+	/*
+	 * No fancy configs - Use this for promiscous debug
+	 *   - EMAC_RXMBPENABLE_RXCAFEN_ENABLE
+	 */
+	writel(EMAC_RXMBPENABLE_RXBROADEN, &adap_emac->RXMBPENABLE);
+
+	/* Enable ch 0 only */
+	writel(1, &adap_emac->RXUNICASTSET);
+
+	/* Enable MII interface and Full duplex mode */
+#if defined(CONFIG_SOC_DA8XX) || \
+	(defined(CONFIG_OMAP34XX) && defined(CONFIG_DRIVER_TI_EMAC_USE_RMII))
+	writel((EMAC_MACCONTROL_MIIEN_ENABLE |
+		EMAC_MACCONTROL_FULLDUPLEX_ENABLE |
+		EMAC_MACCONTROL_RMIISPEED_100),
+	       &adap_emac->MACCONTROL);
+#else
+	writel((EMAC_MACCONTROL_MIIEN_ENABLE |
+		EMAC_MACCONTROL_FULLDUPLEX_ENABLE),
+	       &adap_emac->MACCONTROL);
+#endif
+
+	/* Init MDIO & get link state */
+	clkdiv = CONFIG_SYS_EMAC_TI_CLKDIV;
+	writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT,
+	       &adap_mdio->CONTROL);
+
+	/* We need to wait for MDIO to start */
+	udelay(1000);
+
+	index = get_active_phy();
+	if (index == -1)
+		return(0);
+
+	emac_gigabit_enable(active_phy_addr[index]);
+
+	/* Start receive process */
+	writel(BD_TO_HW((u_int32_t)emac_rx_desc), &adap_emac->RX0HDP);
+
+	debug_emac("- emac_open\n");
+
+	return(1);
+}
+
+/* EMAC Channel Teardown */
+static void davinci_eth_ch_teardown(int ch)
+{
+	dv_reg		dly = 0xff;
+	dv_reg		cnt;
+
+	debug_emac("+ emac_ch_teardown\n");
+
+	if (ch == EMAC_CH_TX) {
+		/* Init TX channel teardown */
+		writel(0, &adap_emac->TXTEARDOWN);
+		do {
+			/*
+			 * Wait here for Tx teardown completion interrupt to
+			 * occur. Note: A task delay can be called here to pend
+			 * rather than occupying CPU cycles - anyway it has
+			 * been found that teardown takes very few cpu cycles
+			 * and does not affect functionality
+			 */
+			dly--;
+			udelay(1);
+			if (dly == 0)
+				break;
+			cnt = readl(&adap_emac->TX0CP);
+		} while (cnt != 0xfffffffc);
+		writel(cnt, &adap_emac->TX0CP);
+		writel(0, &adap_emac->TX0HDP);
+	} else {
+		/* Init RX channel teardown */
+		writel(0, &adap_emac->RXTEARDOWN);
+		do {
+			/*
+			 * Wait here for Rx teardown completion interrupt to
+			 * occur. Note: A task delay can be called here to pend
+			 * rather than occupying CPU cycles - anyway it has
+			 * been found that teardown takes very few cpu cycles
+			 * and does not affect functionality
+			 */
+			dly--;
+			udelay(1);
+			if (dly == 0)
+				break;
+			cnt = readl(&adap_emac->RX0CP);
+		} while (cnt != 0xfffffffc);
+		writel(cnt, &adap_emac->RX0CP);
+		writel(0, &adap_emac->RX0HDP);
+	}
+
+	debug_emac("- emac_ch_teardown\n");
+}
+
+/* Eth device close */
+static void davinci_eth_close(struct eth_device *dev)
+{
+	debug_emac("+ emac_close\n");
+
+	davinci_eth_ch_teardown(EMAC_CH_TX);	/* TX Channel teardown */
+	davinci_eth_ch_teardown(EMAC_CH_RX);	/* RX Channel teardown */
+
+	/* Reset EMAC module and disable interrupts in wrapper */
+	writel(1, &adap_emac->SOFTRESET);
+#if defined(DAVINCI_EMAC_VERSION2)
+	writel(1, &adap_ewrap->softrst);
+#else
+	writel(0, &adap_ewrap->EWCTL);
+#endif
+
+#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
+	defined(CONFIG_MACH_DAVINCI_DA850_EVM)
+	adap_ewrap->c0rxen = adap_ewrap->c1rxen = adap_ewrap->c2rxen = 0;
+	adap_ewrap->c0txen = adap_ewrap->c1txen = adap_ewrap->c2txen = 0;
+	adap_ewrap->c0miscen = adap_ewrap->c1miscen = adap_ewrap->c2miscen = 0;
+#endif
+	debug_emac("- emac_close\n");
+}
+
+static int tx_send_loop = 0;
+
+/*
+ * This function sends a single packet on the network and returns
+ * positive number (number of bytes transmitted) or negative for error
+ */
+static int davinci_eth_send_packet (struct eth_device *dev,
+					void *packet, int length)
+{
+	int ret_status = -1;
+	int index;
+	tx_send_loop = 0;
+
+	index = get_active_phy();
+	if (index == -1) {
+		printf(" WARN: emac_send_packet: No link\n");
+		return (ret_status);
+	}
+
+	emac_gigabit_enable(active_phy_addr[index]);
+
+	/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
+	if (length < EMAC_MIN_ETHERNET_PKT_SIZE) {
+		length = EMAC_MIN_ETHERNET_PKT_SIZE;
+	}
+
+	/* Populate the TX descriptor */
+	emac_tx_desc->next = 0;
+	emac_tx_desc->buffer = (u_int8_t *) packet;
+	emac_tx_desc->buff_off_len = (length & 0xffff);
+	emac_tx_desc->pkt_flag_len = ((length & 0xffff) |
+				      EMAC_CPPI_SOP_BIT |
+				      EMAC_CPPI_OWNERSHIP_BIT |
+				      EMAC_CPPI_EOP_BIT);
+
+	flush_dcache_range((unsigned long)packet,
+			(unsigned long)packet + length);
+	davinci_flush_desc(emac_tx_desc);
+
+	/* Send the packet */
+	writel(BD_TO_HW((unsigned long)emac_tx_desc), &adap_emac->TX0HDP);
+
+	/* Wait for packet to complete or link down */
+	while (1) {
+		if (!phy[index].get_link_speed(active_phy_addr[index])) {
+			davinci_eth_ch_teardown (EMAC_CH_TX);
+			return (ret_status);
+		}
+
+		emac_gigabit_enable(active_phy_addr[index]);
+
+		if (readl(&adap_emac->TXINTSTATRAW) & 0x01) {
+			ret_status = length;
+			break;
+		}
+		tx_send_loop++;
+	}
+
+	return (ret_status);
+}
+
+/*
+ * This function handles receipt of a packet from the network
+ */
+static int davinci_eth_rcv_packet (struct eth_device *dev)
+{
+	volatile emac_desc *rx_curr_desc;
+	volatile emac_desc *curr_desc;
+	volatile emac_desc *tail_desc;
+	int status, ret = -1;
+
+	davinci_invalidate_rx_descs();
+
+	rx_curr_desc = emac_rx_active_head;
+	status = rx_curr_desc->pkt_flag_len;
+	if ((rx_curr_desc) && ((status & EMAC_CPPI_OWNERSHIP_BIT) == 0)) {
+		if (status & EMAC_CPPI_RX_ERROR_FRAME) {
+			/* Error in packet - discard it and requeue desc */
+			printf ("WARN: emac_rcv_pkt: Error in packet\n");
+		} else {
+			unsigned long tmp = (unsigned long)rx_curr_desc->buffer;
+
+			invalidate_dcache_range(tmp, tmp + EMAC_RXBUF_SIZE);
+			NetReceive (rx_curr_desc->buffer,
+				    (rx_curr_desc->buff_off_len & 0xffff));
+			ret = rx_curr_desc->buff_off_len & 0xffff;
+		}
+
+		/* Ack received packet descriptor */
+		writel(BD_TO_HW((ulong)rx_curr_desc), &adap_emac->RX0CP);
+		curr_desc = rx_curr_desc;
+		emac_rx_active_head =
+			(volatile emac_desc *) (HW_TO_BD(rx_curr_desc->next));
+
+		if (status & EMAC_CPPI_EOQ_BIT) {
+			if (emac_rx_active_head) {
+				writel(BD_TO_HW((ulong)emac_rx_active_head),
+				       &adap_emac->RX0HDP);
+			} else {
+				emac_rx_queue_active = 0;
+				printf ("INFO:emac_rcv_packet: RX Queue not active\n");
+			}
+		}
+
+		/* Recycle RX descriptor */
+		rx_curr_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
+		rx_curr_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
+		rx_curr_desc->next = 0;
+		davinci_flush_desc(rx_curr_desc);
+
+		if (emac_rx_active_head == 0) {
+			printf ("INFO: emac_rcv_pkt: active queue head = 0\n");
+			emac_rx_active_head = curr_desc;
+			emac_rx_active_tail = curr_desc;
+			if (emac_rx_queue_active != 0) {
+				writel(BD_TO_HW((ulong)emac_rx_active_head),
+				       &adap_emac->RX0HDP);
+				printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
+				emac_rx_queue_active = 1;
+			}
+		} else {
+			tail_desc = emac_rx_active_tail;
+			emac_rx_active_tail = curr_desc;
+			tail_desc->next = BD_TO_HW((ulong) curr_desc);
+			status = tail_desc->pkt_flag_len;
+			if (status & EMAC_CPPI_EOQ_BIT) {
+				davinci_flush_desc(tail_desc);
+				writel(BD_TO_HW((ulong)curr_desc),
+				       &adap_emac->RX0HDP);
+				status &= ~EMAC_CPPI_EOQ_BIT;
+				tail_desc->pkt_flag_len = status;
+			}
+			davinci_flush_desc(tail_desc);
+		}
+		return (ret);
+	}
+	return (0);
+}
+
+/*
+ * This function initializes the emac hardware. It does NOT initialize
+ * EMAC modules power or pin multiplexors, that is done by board_init()
+ * much earlier in bootup process. Returns 1 on success, 0 otherwise.
+ */
+int davinci_emac_initialize(void)
+{
+	u_int32_t	phy_id;
+	u_int16_t	tmp;
+	int		i;
+	int		ret;
+	struct eth_device *dev;
+
+	dev = malloc(sizeof *dev);
+
+	if (dev == NULL)
+		return -1;
+
+	memset(dev, 0, sizeof *dev);
+	sprintf(dev->name, "DaVinci-EMAC");
+
+	dev->iobase = 0;
+	dev->init = davinci_eth_open;
+	dev->halt = davinci_eth_close;
+	dev->send = davinci_eth_send_packet;
+	dev->recv = davinci_eth_rcv_packet;
+	dev->write_hwaddr = davinci_eth_set_mac_addr;
+
+	eth_register(dev);
+
+	davinci_eth_mdio_enable();
+
+	/* let the EMAC detect the PHYs */
+	udelay(5000);
+
+	for (i = 0; i < 256; i++) {
+		if (readl(&adap_mdio->ALIVE))
+			break;
+		udelay(1000);
+	}
+
+	if (i >= 256) {
+		printf("No ETH PHY detected!!!\n");
+		return(0);
+	}
+
+	/* Find if PHY(s) is/are connected */
+	ret = davinci_eth_phy_detect();
+	if (!ret)
+		return(0);
+	else
+		debug_emac(" %d ETH PHY detected\n", ret);
+
+	/* Get PHY ID and initialize phy_ops for a detected PHY */
+	for (i = 0; i < num_phy; i++) {
+		if (!davinci_eth_phy_read(active_phy_addr[i], MII_PHYSID1,
+							&tmp)) {
+			active_phy_addr[i] = 0xff;
+			continue;
+		}
+
+		phy_id = (tmp << 16) & 0xffff0000;
+
+		if (!davinci_eth_phy_read(active_phy_addr[i], MII_PHYSID2,
+							&tmp)) {
+			active_phy_addr[i] = 0xff;
+			continue;
+		}
+
+		phy_id |= tmp & 0x0000ffff;
+
+		switch (phy_id) {
+#ifdef PHY_KSZ8873
+		case PHY_KSZ8873:
+			sprintf(phy[i].name, "KSZ8873 @ 0x%02x",
+						active_phy_addr[i]);
+			phy[i].init = ksz8873_init_phy;
+			phy[i].is_phy_connected = ksz8873_is_phy_connected;
+			phy[i].get_link_speed = ksz8873_get_link_speed;
+			phy[i].auto_negotiate = ksz8873_auto_negotiate;
+			break;
+#endif
+#ifdef PHY_LXT972
+		case PHY_LXT972:
+			sprintf(phy[i].name, "LXT972 @ 0x%02x",
+						active_phy_addr[i]);
+			phy[i].init = lxt972_init_phy;
+			phy[i].is_phy_connected = lxt972_is_phy_connected;
+			phy[i].get_link_speed = lxt972_get_link_speed;
+			phy[i].auto_negotiate = lxt972_auto_negotiate;
+			break;
+#endif
+#ifdef PHY_DP83848
+		case PHY_DP83848:
+			sprintf(phy[i].name, "DP83848 @ 0x%02x",
+						active_phy_addr[i]);
+			phy[i].init = dp83848_init_phy;
+			phy[i].is_phy_connected = dp83848_is_phy_connected;
+			phy[i].get_link_speed = dp83848_get_link_speed;
+			phy[i].auto_negotiate = dp83848_auto_negotiate;
+			break;
+#endif
+#ifdef PHY_ET1011C
+		case PHY_ET1011C:
+			sprintf(phy[i].name, "ET1011C @ 0x%02x",
+						active_phy_addr[i]);
+			phy[i].init = gen_init_phy;
+			phy[i].is_phy_connected = gen_is_phy_connected;
+			phy[i].get_link_speed = et1011c_get_link_speed;
+			phy[i].auto_negotiate = gen_auto_negotiate;
+			break;
+#endif
+		default:
+			sprintf(phy[i].name, "GENERIC @ 0x%02x",
+						active_phy_addr[i]);
+			phy[i].init = gen_init_phy;
+			phy[i].is_phy_connected = gen_is_phy_connected;
+			phy[i].get_link_speed = gen_get_link_speed;
+			phy[i].auto_negotiate = gen_auto_negotiate;
+		}
+
+		debug("Ethernet PHY: %s\n", phy[i].name);
+
+		miiphy_register(phy[i].name, davinci_mii_phy_read,
+						davinci_mii_phy_write);
+	}
+
+#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
+		defined(CONFIG_MACH_DAVINCI_DA850_EVM) && \
+			!defined(CONFIG_DRIVER_TI_EMAC_RMII_NO_NEGOTIATE)
+	for (i = 0; i < num_phy; i++) {
+		if (phy[i].is_phy_connected(i))
+			phy[i].auto_negotiate(i);
+	}
+#endif
+	return(1);
+}
diff --git a/marvell/uboot/drivers/net/davinci_emac.h b/marvell/uboot/drivers/net/davinci_emac.h
new file mode 100644
index 0000000..13cd68f
--- /dev/null
+++ b/marvell/uboot/drivers/net/davinci_emac.h
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2011 Ilya Yanok, Emcraft Systems
+ *
+ * Based on: mach-davinci/emac_defs.h
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _DAVINCI_EMAC_H_
+#define _DAVINCI_EMAC_H_
+/* Ethernet Min/Max packet size */
+#define EMAC_MIN_ETHERNET_PKT_SIZE	60
+#define EMAC_MAX_ETHERNET_PKT_SIZE	1518
+/* Buffer size (should be aligned on 32 byte and cache line) */
+#define EMAC_RXBUF_SIZE	ALIGN(ALIGN(EMAC_MAX_ETHERNET_PKT_SIZE, 32),\
+				ARCH_DMA_MINALIGN)
+
+/* Number of RX packet buffers
+ * NOTE: Only 1 buffer supported as of now
+ */
+#define EMAC_MAX_RX_BUFFERS		10
+
+
+/***********************************************
+ ******** Internally used macros ***************
+ ***********************************************/
+
+#define EMAC_CH_TX			1
+#define EMAC_CH_RX			0
+
+/* Each descriptor occupies 4 words, lets start RX desc's at 0 and
+ * reserve space for 64 descriptors max
+ */
+#define EMAC_RX_DESC_BASE		0x0
+#define EMAC_TX_DESC_BASE		0x1000
+
+/* EMAC Teardown value */
+#define EMAC_TEARDOWN_VALUE		0xfffffffc
+
+/* MII Status Register */
+#define MII_STATUS_REG			1
+
+/* Number of statistics registers */
+#define EMAC_NUM_STATS			36
+
+
+/* EMAC Descriptor */
+typedef volatile struct _emac_desc
+{
+	u_int32_t	next;		/* Pointer to next descriptor
+					   in chain */
+	u_int8_t	*buffer;	/* Pointer to data buffer */
+	u_int32_t	buff_off_len;	/* Buffer Offset(MSW) and Length(LSW) */
+	u_int32_t	pkt_flag_len;	/* Packet Flags(MSW) and Length(LSW) */
+} emac_desc;
+
+/* CPPI bit positions */
+#define EMAC_CPPI_SOP_BIT		(0x80000000)
+#define EMAC_CPPI_EOP_BIT		(0x40000000)
+#define EMAC_CPPI_OWNERSHIP_BIT		(0x20000000)
+#define EMAC_CPPI_EOQ_BIT		(0x10000000)
+#define EMAC_CPPI_TEARDOWN_COMPLETE_BIT	(0x08000000)
+#define EMAC_CPPI_PASS_CRC_BIT		(0x04000000)
+
+#define EMAC_CPPI_RX_ERROR_FRAME	(0x03fc0000)
+
+#define EMAC_MACCONTROL_MIIEN_ENABLE		(0x20)
+#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE	(0x1)
+#define EMAC_MACCONTROL_GIGABIT_ENABLE		(1 << 7)
+#define EMAC_MACCONTROL_GIGFORCE		(1 << 17)
+#define EMAC_MACCONTROL_RMIISPEED_100		(1 << 15)
+
+#define EMAC_MAC_ADDR_MATCH		(1 << 19)
+#define EMAC_MAC_ADDR_IS_VALID		(1 << 20)
+
+#define EMAC_RXMBPENABLE_RXCAFEN_ENABLE	(0x200000)
+#define EMAC_RXMBPENABLE_RXBROADEN	(0x2000)
+
+
+#define MDIO_CONTROL_IDLE		(0x80000000)
+#define MDIO_CONTROL_ENABLE		(0x40000000)
+#define MDIO_CONTROL_FAULT_ENABLE	(0x40000)
+#define MDIO_CONTROL_FAULT		(0x80000)
+#define MDIO_USERACCESS0_GO		(0x80000000)
+#define MDIO_USERACCESS0_WRITE_READ	(0x0)
+#define MDIO_USERACCESS0_WRITE_WRITE	(0x40000000)
+#define MDIO_USERACCESS0_ACK		(0x20000000)
+
+/* Ethernet MAC Registers Structure */
+typedef struct  {
+	dv_reg		TXIDVER;
+	dv_reg		TXCONTROL;
+	dv_reg		TXTEARDOWN;
+	u_int8_t	RSVD0[4];
+	dv_reg		RXIDVER;
+	dv_reg		RXCONTROL;
+	dv_reg		RXTEARDOWN;
+	u_int8_t	RSVD1[100];
+	dv_reg		TXINTSTATRAW;
+	dv_reg		TXINTSTATMASKED;
+	dv_reg		TXINTMASKSET;
+	dv_reg		TXINTMASKCLEAR;
+	dv_reg		MACINVECTOR;
+	u_int8_t	RSVD2[12];
+	dv_reg		RXINTSTATRAW;
+	dv_reg		RXINTSTATMASKED;
+	dv_reg		RXINTMASKSET;
+	dv_reg		RXINTMASKCLEAR;
+	dv_reg		MACINTSTATRAW;
+	dv_reg		MACINTSTATMASKED;
+	dv_reg		MACINTMASKSET;
+	dv_reg		MACINTMASKCLEAR;
+	u_int8_t	RSVD3[64];
+	dv_reg		RXMBPENABLE;
+	dv_reg		RXUNICASTSET;
+	dv_reg		RXUNICASTCLEAR;
+	dv_reg		RXMAXLEN;
+	dv_reg		RXBUFFEROFFSET;
+	dv_reg		RXFILTERLOWTHRESH;
+	u_int8_t	RSVD4[8];
+	dv_reg		RX0FLOWTHRESH;
+	dv_reg		RX1FLOWTHRESH;
+	dv_reg		RX2FLOWTHRESH;
+	dv_reg		RX3FLOWTHRESH;
+	dv_reg		RX4FLOWTHRESH;
+	dv_reg		RX5FLOWTHRESH;
+	dv_reg		RX6FLOWTHRESH;
+	dv_reg		RX7FLOWTHRESH;
+	dv_reg		RX0FREEBUFFER;
+	dv_reg		RX1FREEBUFFER;
+	dv_reg		RX2FREEBUFFER;
+	dv_reg		RX3FREEBUFFER;
+	dv_reg		RX4FREEBUFFER;
+	dv_reg		RX5FREEBUFFER;
+	dv_reg		RX6FREEBUFFER;
+	dv_reg		RX7FREEBUFFER;
+	dv_reg		MACCONTROL;
+	dv_reg		MACSTATUS;
+	dv_reg		EMCONTROL;
+	dv_reg		FIFOCONTROL;
+	dv_reg		MACCONFIG;
+	dv_reg		SOFTRESET;
+	u_int8_t	RSVD5[88];
+	dv_reg		MACSRCADDRLO;
+	dv_reg		MACSRCADDRHI;
+	dv_reg		MACHASH1;
+	dv_reg		MACHASH2;
+	dv_reg		BOFFTEST;
+	dv_reg		TPACETEST;
+	dv_reg		RXPAUSE;
+	dv_reg		TXPAUSE;
+	u_int8_t	RSVD6[16];
+	dv_reg		RXGOODFRAMES;
+	dv_reg		RXBCASTFRAMES;
+	dv_reg		RXMCASTFRAMES;
+	dv_reg		RXPAUSEFRAMES;
+	dv_reg		RXCRCERRORS;
+	dv_reg		RXALIGNCODEERRORS;
+	dv_reg		RXOVERSIZED;
+	dv_reg		RXJABBER;
+	dv_reg		RXUNDERSIZED;
+	dv_reg		RXFRAGMENTS;
+	dv_reg		RXFILTERED;
+	dv_reg		RXQOSFILTERED;
+	dv_reg		RXOCTETS;
+	dv_reg		TXGOODFRAMES;
+	dv_reg		TXBCASTFRAMES;
+	dv_reg		TXMCASTFRAMES;
+	dv_reg		TXPAUSEFRAMES;
+	dv_reg		TXDEFERRED;
+	dv_reg		TXCOLLISION;
+	dv_reg		TXSINGLECOLL;
+	dv_reg		TXMULTICOLL;
+	dv_reg		TXEXCESSIVECOLL;
+	dv_reg		TXLATECOLL;
+	dv_reg		TXUNDERRUN;
+	dv_reg		TXCARRIERSENSE;
+	dv_reg		TXOCTETS;
+	dv_reg		FRAME64;
+	dv_reg		FRAME65T127;
+	dv_reg		FRAME128T255;
+	dv_reg		FRAME256T511;
+	dv_reg		FRAME512T1023;
+	dv_reg		FRAME1024TUP;
+	dv_reg		NETOCTETS;
+	dv_reg		RXSOFOVERRUNS;
+	dv_reg		RXMOFOVERRUNS;
+	dv_reg		RXDMAOVERRUNS;
+	u_int8_t	RSVD7[624];
+	dv_reg		MACADDRLO;
+	dv_reg		MACADDRHI;
+	dv_reg		MACINDEX;
+	u_int8_t	RSVD8[244];
+	dv_reg		TX0HDP;
+	dv_reg		TX1HDP;
+	dv_reg		TX2HDP;
+	dv_reg		TX3HDP;
+	dv_reg		TX4HDP;
+	dv_reg		TX5HDP;
+	dv_reg		TX6HDP;
+	dv_reg		TX7HDP;
+	dv_reg		RX0HDP;
+	dv_reg		RX1HDP;
+	dv_reg		RX2HDP;
+	dv_reg		RX3HDP;
+	dv_reg		RX4HDP;
+	dv_reg		RX5HDP;
+	dv_reg		RX6HDP;
+	dv_reg		RX7HDP;
+	dv_reg		TX0CP;
+	dv_reg		TX1CP;
+	dv_reg		TX2CP;
+	dv_reg		TX3CP;
+	dv_reg		TX4CP;
+	dv_reg		TX5CP;
+	dv_reg		TX6CP;
+	dv_reg		TX7CP;
+	dv_reg		RX0CP;
+	dv_reg		RX1CP;
+	dv_reg		RX2CP;
+	dv_reg		RX3CP;
+	dv_reg		RX4CP;
+	dv_reg		RX5CP;
+	dv_reg		RX6CP;
+	dv_reg		RX7CP;
+} emac_regs;
+
+/* EMAC Wrapper Registers Structure */
+typedef struct  {
+#ifdef DAVINCI_EMAC_VERSION2
+	dv_reg		idver;
+	dv_reg		softrst;
+	dv_reg		emctrl;
+	dv_reg		c0rxthreshen;
+	dv_reg		c0rxen;
+	dv_reg		c0txen;
+	dv_reg		c0miscen;
+	dv_reg		c1rxthreshen;
+	dv_reg		c1rxen;
+	dv_reg		c1txen;
+	dv_reg		c1miscen;
+	dv_reg		c2rxthreshen;
+	dv_reg		c2rxen;
+	dv_reg		c2txen;
+	dv_reg		c2miscen;
+	dv_reg		c0rxthreshstat;
+	dv_reg		c0rxstat;
+	dv_reg		c0txstat;
+	dv_reg		c0miscstat;
+	dv_reg		c1rxthreshstat;
+	dv_reg		c1rxstat;
+	dv_reg		c1txstat;
+	dv_reg		c1miscstat;
+	dv_reg		c2rxthreshstat;
+	dv_reg		c2rxstat;
+	dv_reg		c2txstat;
+	dv_reg		c2miscstat;
+	dv_reg		c0rximax;
+	dv_reg		c0tximax;
+	dv_reg		c1rximax;
+	dv_reg		c1tximax;
+	dv_reg		c2rximax;
+	dv_reg		c2tximax;
+#else
+	u_int8_t	RSVD0[4100];
+	dv_reg		EWCTL;
+	dv_reg		EWINTTCNT;
+#endif
+} ewrap_regs;
+
+/* EMAC MDIO Registers Structure */
+typedef struct  {
+	dv_reg		VERSION;
+	dv_reg		CONTROL;
+	dv_reg		ALIVE;
+	dv_reg		LINK;
+	dv_reg		LINKINTRAW;
+	dv_reg		LINKINTMASKED;
+	u_int8_t	RSVD0[8];
+	dv_reg		USERINTRAW;
+	dv_reg		USERINTMASKED;
+	dv_reg		USERINTMASKSET;
+	dv_reg		USERINTMASKCLEAR;
+	u_int8_t	RSVD1[80];
+	dv_reg		USERACCESS0;
+	dv_reg		USERPHYSEL0;
+	dv_reg		USERACCESS1;
+	dv_reg		USERPHYSEL1;
+} mdio_regs;
+
+int davinci_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data);
+int davinci_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data);
+
+typedef struct {
+	char	name[64];
+	int	(*init)(int phy_addr);
+	int	(*is_phy_connected)(int phy_addr);
+	int	(*get_link_speed)(int phy_addr);
+	int	(*auto_negotiate)(int phy_addr);
+} phy_t;
+
+#endif /* _DAVINCI_EMAC_H_ */
diff --git a/marvell/uboot/drivers/net/dc2114x.c b/marvell/uboot/drivers/net/dc2114x.c
new file mode 100644
index 0000000..799839c
--- /dev/null
+++ b/marvell/uboot/drivers/net/dc2114x.c
@@ -0,0 +1,760 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <pci.h>
+
+#undef DEBUG_SROM
+#undef DEBUG_SROM2
+
+#undef UPDATE_SROM
+
+/* PCI Registers.
+ */
+#define PCI_CFDA_PSM		0x43
+
+#define CFRV_RN		0x000000f0	/* Revision Number */
+
+#define WAKEUP		0x00		/* Power Saving Wakeup */
+#define SLEEP		0x80		/* Power Saving Sleep Mode */
+
+#define DC2114x_BRK	0x0020		/* CFRV break between DC21142 & DC21143 */
+
+/* Ethernet chip registers.
+ */
+#define DE4X5_BMR	0x000		/* Bus Mode Register */
+#define DE4X5_TPD	0x008		/* Transmit Poll Demand Reg */
+#define DE4X5_RRBA	0x018		/* RX Ring Base Address Reg */
+#define DE4X5_TRBA	0x020		/* TX Ring Base Address Reg */
+#define DE4X5_STS	0x028		/* Status Register */
+#define DE4X5_OMR	0x030		/* Operation Mode Register */
+#define DE4X5_SICR	0x068		/* SIA Connectivity Register */
+#define DE4X5_APROM	0x048		/* Ethernet Address PROM */
+
+/* Register bits.
+ */
+#define BMR_SWR		0x00000001	/* Software Reset */
+#define STS_TS		0x00700000	/* Transmit Process State */
+#define STS_RS		0x000e0000	/* Receive Process State */
+#define OMR_ST		0x00002000	/* Start/Stop Transmission Command */
+#define OMR_SR		0x00000002	/* Start/Stop Receive */
+#define OMR_PS		0x00040000	/* Port Select */
+#define OMR_SDP		0x02000000	/* SD Polarity - MUST BE ASSERTED */
+#define OMR_PM		0x00000080	/* Pass All Multicast */
+
+/* Descriptor bits.
+ */
+#define R_OWN		0x80000000	/* Own Bit */
+#define RD_RER		0x02000000	/* Receive End Of Ring */
+#define RD_LS		0x00000100	/* Last Descriptor */
+#define RD_ES		0x00008000	/* Error Summary */
+#define TD_TER		0x02000000	/* Transmit End Of Ring */
+#define T_OWN		0x80000000	/* Own Bit */
+#define TD_LS		0x40000000	/* Last Segment */
+#define TD_FS		0x20000000	/* First Segment */
+#define TD_ES		0x00008000	/* Error Summary */
+#define TD_SET		0x08000000	/* Setup Packet */
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define SROM_WRITE_CMD	5
+#define SROM_READ_CMD	6
+#define SROM_ERASE_CMD	7
+
+#define SROM_HWADD	    0x0014	/* Hardware Address offset in SROM */
+#define SROM_RD		0x00004000	/* Read from Boot ROM */
+#define EE_DATA_WRITE	      0x04	/* EEPROM chip data in. */
+#define EE_WRITE_0	    0x4801
+#define EE_WRITE_1	    0x4805
+#define EE_DATA_READ	      0x08	/* EEPROM chip data out. */
+#define SROM_SR		0x00000800	/* Select Serial ROM when set */
+
+#define DT_IN		0x00000004	/* Serial Data In */
+#define DT_CLK		0x00000002	/* Serial ROM Clock */
+#define DT_CS		0x00000001	/* Serial ROM Chip Select */
+
+#define POLL_DEMAND	1
+
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+#define RESET_DM9102(dev) {\
+    unsigned long i;\
+    i=INL(dev, 0x0);\
+    udelay(1000);\
+    OUTL(dev, i | BMR_SWR, DE4X5_BMR);\
+    udelay(1000);\
+}
+#else
+#define RESET_DE4X5(dev) {\
+    int i;\
+    i=INL(dev, DE4X5_BMR);\
+    udelay(1000);\
+    OUTL(dev, i | BMR_SWR, DE4X5_BMR);\
+    udelay(1000);\
+    OUTL(dev, i, DE4X5_BMR);\
+    udelay(1000);\
+    for (i=0;i<5;i++) {INL(dev, DE4X5_BMR); udelay(10000);}\
+    udelay(1000);\
+}
+#endif
+
+#define START_DE4X5(dev) {\
+    s32 omr; \
+    omr = INL(dev, DE4X5_OMR);\
+    omr |= OMR_ST | OMR_SR;\
+    OUTL(dev, omr, DE4X5_OMR);		/* Enable the TX and/or RX */\
+}
+
+#define STOP_DE4X5(dev) {\
+    s32 omr; \
+    omr = INL(dev, DE4X5_OMR);\
+    omr &= ~(OMR_ST|OMR_SR);\
+    OUTL(dev, omr, DE4X5_OMR);		/* Disable the TX and/or RX */ \
+}
+
+#define NUM_RX_DESC PKTBUFSRX
+#ifndef CONFIG_TULIP_FIX_DAVICOM
+	#define NUM_TX_DESC 1			/* Number of TX descriptors   */
+#else
+	#define NUM_TX_DESC 4
+#endif
+#define RX_BUFF_SZ  PKTSIZE_ALIGN
+
+#define TOUT_LOOP   1000000
+
+#define SETUP_FRAME_LEN 192
+#define ETH_ALEN	6
+
+struct de4x5_desc {
+	volatile s32 status;
+	u32 des1;
+	u32 buf;
+	u32 next;
+};
+
+static struct de4x5_desc rx_ring[NUM_RX_DESC] __attribute__ ((aligned(32))); /* RX descriptor ring         */
+static struct de4x5_desc tx_ring[NUM_TX_DESC] __attribute__ ((aligned(32))); /* TX descriptor ring         */
+static int rx_new;                             /* RX descriptor ring pointer */
+static int tx_new;                             /* TX descriptor ring pointer */
+
+static char rxRingSize;
+static char txRingSize;
+
+#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM)
+static void  sendto_srom(struct eth_device* dev, u_int command, u_long addr);
+static int   getfrom_srom(struct eth_device* dev, u_long addr);
+static int   do_eeprom_cmd(struct eth_device *dev, u_long ioaddr,int cmd,int cmd_len);
+static int   do_read_eeprom(struct eth_device *dev,u_long ioaddr,int location,int addr_len);
+#endif	/* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */
+#ifdef UPDATE_SROM
+static int   write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value);
+static void  update_srom(struct eth_device *dev, bd_t *bis);
+#endif
+#ifndef CONFIG_TULIP_FIX_DAVICOM
+static int   read_srom(struct eth_device *dev, u_long ioaddr, int index);
+static void  read_hw_addr(struct eth_device* dev, bd_t * bis);
+#endif	/* CONFIG_TULIP_FIX_DAVICOM */
+static void  send_setup_frame(struct eth_device* dev, bd_t * bis);
+
+static int   dc21x4x_init(struct eth_device* dev, bd_t* bis);
+static int   dc21x4x_send(struct eth_device *dev, void *packet, int length);
+static int   dc21x4x_recv(struct eth_device* dev);
+static void  dc21x4x_halt(struct eth_device* dev);
+#ifdef CONFIG_TULIP_SELECT_MEDIA
+extern void  dc21x4x_select_media(struct eth_device* dev);
+#endif
+
+#if defined(CONFIG_E500)
+#define phys_to_bus(a) (a)
+#else
+#define phys_to_bus(a)	pci_phys_to_mem((pci_dev_t)dev->priv, a)
+#endif
+
+static int INL(struct eth_device* dev, u_long addr)
+{
+	return le32_to_cpu(*(volatile u_long *)(addr + dev->iobase));
+}
+
+static void OUTL(struct eth_device* dev, int command, u_long addr)
+{
+	*(volatile u_long *)(addr + dev->iobase) = cpu_to_le32(command);
+}
+
+static struct pci_device_id supported[] = {
+	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST },
+	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142 },
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+	{ PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DAVICOM_DM9102A },
+#endif
+	{ }
+};
+
+int dc21x4x_initialize(bd_t *bis)
+{
+	int			idx=0;
+	int			card_number = 0;
+	unsigned int		cfrv;
+	unsigned char		timer;
+	pci_dev_t		devbusfn;
+	unsigned int		iobase;
+	unsigned short		status;
+	struct eth_device*	dev;
+
+	while(1) {
+		devbusfn =  pci_find_devices(supported, idx++);
+		if (devbusfn == -1) {
+			break;
+		}
+
+		/* Get the chip configuration revision register. */
+		pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv);
+
+#ifndef CONFIG_TULIP_FIX_DAVICOM
+		if ((cfrv & CFRV_RN) < DC2114x_BRK ) {
+			printf("Error: The chip is not DC21143.\n");
+			continue;
+		}
+#endif
+
+		pci_read_config_word(devbusfn, PCI_COMMAND, &status);
+		status |=
+#ifdef CONFIG_TULIP_USE_IO
+		  PCI_COMMAND_IO |
+#else
+		  PCI_COMMAND_MEMORY |
+#endif
+		  PCI_COMMAND_MASTER;
+		pci_write_config_word(devbusfn, PCI_COMMAND, status);
+
+		pci_read_config_word(devbusfn, PCI_COMMAND, &status);
+#ifdef CONFIG_TULIP_USE_IO
+		if (!(status & PCI_COMMAND_IO)) {
+			printf("Error: Can not enable I/O access.\n");
+			continue;
+		}
+#else
+		if (!(status & PCI_COMMAND_MEMORY)) {
+			printf("Error: Can not enable MEMORY access.\n");
+			continue;
+		}
+#endif
+
+		if (!(status & PCI_COMMAND_MASTER)) {
+			printf("Error: Can not enable Bus Mastering.\n");
+			continue;
+		}
+
+		/* Check the latency timer for values >= 0x60. */
+		pci_read_config_byte(devbusfn, PCI_LATENCY_TIMER, &timer);
+
+		if (timer < 0x60) {
+			pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x60);
+		}
+
+#ifdef CONFIG_TULIP_USE_IO
+		/* read BAR for memory space access */
+		pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase);
+		iobase &= PCI_BASE_ADDRESS_IO_MASK;
+#else
+		/* read BAR for memory space access */
+		pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &iobase);
+		iobase &= PCI_BASE_ADDRESS_MEM_MASK;
+#endif
+		debug ("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase);
+
+		dev = (struct eth_device*) malloc(sizeof *dev);
+
+		if (!dev) {
+			printf("Can not allocalte memory of dc21x4x\n");
+			break;
+		}
+		memset(dev, 0, sizeof(*dev));
+
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+		sprintf(dev->name, "Davicom#%d", card_number);
+#else
+		sprintf(dev->name, "dc21x4x#%d", card_number);
+#endif
+
+#ifdef CONFIG_TULIP_USE_IO
+		dev->iobase = pci_io_to_phys(devbusfn, iobase);
+#else
+		dev->iobase = pci_mem_to_phys(devbusfn, iobase);
+#endif
+		dev->priv   = (void*) devbusfn;
+		dev->init   = dc21x4x_init;
+		dev->halt   = dc21x4x_halt;
+		dev->send   = dc21x4x_send;
+		dev->recv   = dc21x4x_recv;
+
+		/* Ensure we're not sleeping. */
+		pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);
+
+		udelay(10 * 1000);
+
+#ifndef CONFIG_TULIP_FIX_DAVICOM
+		read_hw_addr(dev, bis);
+#endif
+		eth_register(dev);
+
+		card_number++;
+	}
+
+	return card_number;
+}
+
+static int dc21x4x_init(struct eth_device* dev, bd_t* bis)
+{
+	int		i;
+	int		devbusfn = (int) dev->priv;
+
+	/* Ensure we're not sleeping. */
+	pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP);
+
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+	RESET_DM9102(dev);
+#else
+	RESET_DE4X5(dev);
+#endif
+
+	if ((INL(dev, DE4X5_STS) & (STS_TS | STS_RS)) != 0) {
+		printf("Error: Cannot reset ethernet controller.\n");
+		return -1;
+	}
+
+#ifdef CONFIG_TULIP_SELECT_MEDIA
+	dc21x4x_select_media(dev);
+#else
+	OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR);
+#endif
+
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		rx_ring[i].status = cpu_to_le32(R_OWN);
+		rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);
+		rx_ring[i].buf = cpu_to_le32(phys_to_bus((u32) NetRxPackets[i]));
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+		rx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &rx_ring[(i+1) % NUM_RX_DESC]));
+#else
+		rx_ring[i].next = 0;
+#endif
+	}
+
+	for (i=0; i < NUM_TX_DESC; i++) {
+		tx_ring[i].status = 0;
+		tx_ring[i].des1 = 0;
+		tx_ring[i].buf = 0;
+
+#ifdef CONFIG_TULIP_FIX_DAVICOM
+	tx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &tx_ring[(i+1) % NUM_TX_DESC]));
+#else
+		tx_ring[i].next = 0;
+#endif
+	}
+
+	rxRingSize = NUM_RX_DESC;
+	txRingSize = NUM_TX_DESC;
+
+	/* Write the end of list marker to the descriptor lists. */
+	rx_ring[rxRingSize - 1].des1 |= cpu_to_le32(RD_RER);
+	tx_ring[txRingSize - 1].des1 |= cpu_to_le32(TD_TER);
+
+	/* Tell the adapter where the TX/RX rings are located. */
+	OUTL(dev, phys_to_bus((u32) &rx_ring), DE4X5_RRBA);
+	OUTL(dev, phys_to_bus((u32) &tx_ring), DE4X5_TRBA);
+
+	START_DE4X5(dev);
+
+	tx_new = 0;
+	rx_new = 0;
+
+	send_setup_frame(dev, bis);
+
+	return 0;
+}
+
+static int dc21x4x_send(struct eth_device *dev, void *packet, int length)
+{
+	int		status = -1;
+	int		i;
+
+	if (length <= 0) {
+		printf("%s: bad packet size: %d\n", dev->name, length);
+		goto Done;
+	}
+
+	for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+		if (i >= TOUT_LOOP) {
+			printf("%s: tx error buffer not ready\n", dev->name);
+			goto Done;
+		}
+	}
+
+	tx_ring[tx_new].buf    = cpu_to_le32(phys_to_bus((u32) packet));
+	tx_ring[tx_new].des1   = cpu_to_le32(TD_TER | TD_LS | TD_FS | length);
+	tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+
+	OUTL(dev, POLL_DEMAND, DE4X5_TPD);
+
+	for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+		if (i >= TOUT_LOOP) {
+			printf(".%s: tx buffer not ready\n", dev->name);
+			goto Done;
+		}
+	}
+
+	if (le32_to_cpu(tx_ring[tx_new].status) & TD_ES) {
+#if 0 /* test-only */
+		printf("TX error status = 0x%08X\n",
+			le32_to_cpu(tx_ring[tx_new].status));
+#endif
+		tx_ring[tx_new].status = 0x0;
+		goto Done;
+	}
+
+	status = length;
+
+ Done:
+    tx_new = (tx_new+1) % NUM_TX_DESC;
+	return status;
+}
+
+static int dc21x4x_recv(struct eth_device* dev)
+{
+	s32		status;
+	int		length    = 0;
+
+	for ( ; ; ) {
+		status = (s32)le32_to_cpu(rx_ring[rx_new].status);
+
+		if (status & R_OWN) {
+			break;
+		}
+
+		if (status & RD_LS) {
+			/* Valid frame status.
+			 */
+			if (status & RD_ES) {
+
+				/* There was an error.
+				 */
+				printf("RX error status = 0x%08X\n", status);
+			} else {
+				/* A valid frame received.
+				 */
+				length = (le32_to_cpu(rx_ring[rx_new].status) >> 16);
+
+				/* Pass the packet up to the protocol
+				 * layers.
+				 */
+				NetReceive(NetRxPackets[rx_new], length - 4);
+			}
+
+			/* Change buffer ownership for this frame, back
+			 * to the adapter.
+			 */
+			rx_ring[rx_new].status = cpu_to_le32(R_OWN);
+		}
+
+		/* Update entry information.
+		 */
+		rx_new = (rx_new + 1) % rxRingSize;
+	}
+
+	return length;
+}
+
+static void dc21x4x_halt(struct eth_device* dev)
+{
+	int		devbusfn = (int) dev->priv;
+
+	STOP_DE4X5(dev);
+	OUTL(dev, 0, DE4X5_SICR);
+
+	pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP);
+}
+
+static void send_setup_frame(struct eth_device* dev, bd_t *bis)
+{
+	int		i;
+	char	setup_frame[SETUP_FRAME_LEN];
+	char	*pa = &setup_frame[0];
+
+	memset(pa, 0xff, SETUP_FRAME_LEN);
+
+	for (i = 0; i < ETH_ALEN; i++) {
+		*(pa + (i & 1)) = dev->enetaddr[i];
+		if (i & 0x01) {
+			pa += 4;
+		}
+	}
+
+	for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+		if (i >= TOUT_LOOP) {
+			printf("%s: tx error buffer not ready\n", dev->name);
+			goto Done;
+		}
+	}
+
+	tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32) &setup_frame[0]));
+	tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN);
+	tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+
+	OUTL(dev, POLL_DEMAND, DE4X5_TPD);
+
+	for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+		if (i >= TOUT_LOOP) {
+			printf("%s: tx buffer not ready\n", dev->name);
+			goto Done;
+		}
+	}
+
+	if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) {
+		printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[tx_new].status));
+	}
+	tx_new = (tx_new+1) % NUM_TX_DESC;
+
+Done:
+	return;
+}
+
+#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM)
+/* SROM Read and write routines.
+ */
+static void
+sendto_srom(struct eth_device* dev, u_int command, u_long addr)
+{
+	OUTL(dev, command, addr);
+	udelay(1);
+}
+
+static int
+getfrom_srom(struct eth_device* dev, u_long addr)
+{
+	s32 tmp;
+
+	tmp = INL(dev, addr);
+	udelay(1);
+
+	return tmp;
+}
+
+/* Note: this routine returns extra data bits for size detection. */
+static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, int addr_len)
+{
+	int i;
+	unsigned retval = 0;
+	int read_cmd = location | (SROM_READ_CMD << addr_len);
+
+	sendto_srom(dev, SROM_RD | SROM_SR, ioaddr);
+	sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+
+#ifdef DEBUG_SROM
+	printf(" EEPROM read at %d ", location);
+#endif
+
+	/* Shift the read command bits out. */
+	for (i = 4 + addr_len; i >= 0; i--) {
+		short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+		sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval, ioaddr);
+		udelay(10);
+		sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK, ioaddr);
+		udelay(10);
+#ifdef DEBUG_SROM2
+		printf("%X", getfrom_srom(dev, ioaddr) & 15);
+#endif
+		retval = (retval << 1) | ((getfrom_srom(dev, ioaddr) & EE_DATA_READ) ? 1 : 0);
+	}
+
+	sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+
+#ifdef DEBUG_SROM2
+	printf(" :%X:", getfrom_srom(dev, ioaddr) & 15);
+#endif
+
+	for (i = 16; i > 0; i--) {
+		sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr);
+		udelay(10);
+#ifdef DEBUG_SROM2
+		printf("%X", getfrom_srom(dev, ioaddr) & 15);
+#endif
+		retval = (retval << 1) | ((getfrom_srom(dev, ioaddr) & EE_DATA_READ) ? 1 : 0);
+		sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+		udelay(10);
+	}
+
+	/* Terminate the EEPROM access. */
+	sendto_srom(dev, SROM_RD | SROM_SR, ioaddr);
+
+#ifdef DEBUG_SROM2
+	printf(" EEPROM value at %d is %5.5x.\n", location, retval);
+#endif
+
+	return retval;
+}
+#endif	/* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */
+
+/* This executes a generic EEPROM command, typically a write or write
+ * enable. It returns the data output from the EEPROM, and thus may
+ * also be used for reads.
+ */
+#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM)
+static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, int cmd_len)
+{
+	unsigned retval = 0;
+
+#ifdef DEBUG_SROM
+	printf(" EEPROM op 0x%x: ", cmd);
+#endif
+
+	sendto_srom(dev,SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr);
+
+	/* Shift the command bits out. */
+	do {
+		short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
+		sendto_srom(dev,dataval, ioaddr);
+		udelay(10);
+
+#ifdef DEBUG_SROM2
+		printf("%X", getfrom_srom(dev,ioaddr) & 15);
+#endif
+
+		sendto_srom(dev,dataval | DT_CLK, ioaddr);
+		udelay(10);
+		retval = (retval << 1) | ((getfrom_srom(dev,ioaddr) & EE_DATA_READ) ? 1 : 0);
+	} while (--cmd_len >= 0);
+	sendto_srom(dev,SROM_RD | SROM_SR | DT_CS, ioaddr);
+
+	/* Terminate the EEPROM access. */
+	sendto_srom(dev,SROM_RD | SROM_SR, ioaddr);
+
+#ifdef DEBUG_SROM
+	printf(" EEPROM result is 0x%5.5x.\n", retval);
+#endif
+
+	return retval;
+}
+#endif	/* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */
+
+#ifndef CONFIG_TULIP_FIX_DAVICOM
+static int read_srom(struct eth_device *dev, u_long ioaddr, int index)
+{
+	int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
+
+	return do_eeprom_cmd(dev, ioaddr,
+			     (((SROM_READ_CMD << ee_addr_size) | index) << 16)
+			     | 0xffff, 3 + ee_addr_size + 16);
+}
+#endif	/* CONFIG_TULIP_FIX_DAVICOM */
+
+#ifdef UPDATE_SROM
+static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value)
+{
+	int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
+	int i;
+	unsigned short newval;
+
+	udelay(10*1000); /* test-only */
+
+#ifdef DEBUG_SROM
+	printf("ee_addr_size=%d.\n", ee_addr_size);
+	printf("Writing new entry 0x%4.4x to offset %d.\n", new_value, index);
+#endif
+
+	/* Enable programming modes. */
+	do_eeprom_cmd(dev, ioaddr, (0x4f << (ee_addr_size-4)), 3+ee_addr_size);
+
+	/* Do the actual write. */
+	do_eeprom_cmd(dev, ioaddr,
+		      (((SROM_WRITE_CMD<<ee_addr_size)|index) << 16) | new_value,
+		      3 + ee_addr_size + 16);
+
+	/* Poll for write finished. */
+	sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr);
+	for (i = 0; i < 10000; i++)			/* Typical 2000 ticks */
+		if (getfrom_srom(dev, ioaddr) & EE_DATA_READ)
+			break;
+
+#ifdef DEBUG_SROM
+	printf(" Write finished after %d ticks.\n", i);
+#endif
+
+	/* Disable programming. */
+	do_eeprom_cmd(dev, ioaddr, (0x40 << (ee_addr_size-4)), 3 + ee_addr_size);
+
+	/* And read the result. */
+	newval = do_eeprom_cmd(dev, ioaddr,
+			       (((SROM_READ_CMD<<ee_addr_size)|index) << 16)
+			       | 0xffff, 3 + ee_addr_size + 16);
+#ifdef DEBUG_SROM
+	printf("  New value at offset %d is %4.4x.\n", index, newval);
+#endif
+	return 1;
+}
+#endif
+
+#ifndef CONFIG_TULIP_FIX_DAVICOM
+static void read_hw_addr(struct eth_device *dev, bd_t *bis)
+{
+	u_short tmp, *p = (u_short *)(&dev->enetaddr[0]);
+	int i, j = 0;
+
+	for (i = 0; i < (ETH_ALEN >> 1); i++) {
+		tmp = read_srom(dev, DE4X5_APROM, ((SROM_HWADD >> 1) + i));
+		*p = le16_to_cpu(tmp);
+		j += *p++;
+	}
+
+	if ((j == 0) || (j == 0x2fffd)) {
+		memset (dev->enetaddr, 0, ETH_ALEN);
+		debug ("Warning: can't read HW address from SROM.\n");
+		goto Done;
+	}
+
+	return;
+
+Done:
+#ifdef UPDATE_SROM
+	update_srom(dev, bis);
+#endif
+	return;
+}
+#endif	/* CONFIG_TULIP_FIX_DAVICOM */
+
+#ifdef UPDATE_SROM
+static void update_srom(struct eth_device *dev, bd_t *bis)
+{
+	int i;
+	static unsigned short eeprom[0x40] = {
+		0x140b, 0x6610, 0x0000, 0x0000,	/* 00 */
+		0x0000, 0x0000, 0x0000, 0x0000,	/* 04 */
+		0x00a3, 0x0103, 0x0000, 0x0000,	/* 08 */
+		0x0000, 0x1f00, 0x0000, 0x0000,	/* 0c */
+		0x0108, 0x038d, 0x0000, 0x0000,	/* 10 */
+		0xe078, 0x0001, 0x0040, 0x0018,	/* 14 */
+		0x0000, 0x0000, 0x0000, 0x0000,	/* 18 */
+		0x0000, 0x0000, 0x0000, 0x0000,	/* 1c */
+		0x0000, 0x0000, 0x0000, 0x0000,	/* 20 */
+		0x0000, 0x0000, 0x0000, 0x0000,	/* 24 */
+		0x0000, 0x0000, 0x0000, 0x0000,	/* 28 */
+		0x0000, 0x0000, 0x0000, 0x0000,	/* 2c */
+		0x0000, 0x0000, 0x0000, 0x0000,	/* 30 */
+		0x0000, 0x0000, 0x0000, 0x0000,	/* 34 */
+		0x0000, 0x0000, 0x0000, 0x0000,	/* 38 */
+		0x0000, 0x0000, 0x0000, 0x4e07,	/* 3c */
+	};
+	uchar enetaddr[6];
+
+	/* Ethernet Addr... */
+	if (!eth_getenv_enetaddr("ethaddr", enetaddr))
+		return;
+	eeprom[0x0a] = (enetaddr[1] << 8) | enetaddr[0];
+	eeprom[0x0b] = (enetaddr[3] << 8) | enetaddr[2];
+	eeprom[0x0c] = (enetaddr[5] << 8) | enetaddr[4];
+
+	for (i=0; i<0x40; i++) {
+		write_srom(dev, DE4X5_APROM, i, eeprom[i]);
+	}
+}
+#endif	/* UPDATE_SROM */
diff --git a/marvell/uboot/drivers/net/designware.c b/marvell/uboot/drivers/net/designware.c
new file mode 100644
index 0000000..22155b4
--- /dev/null
+++ b/marvell/uboot/drivers/net/designware.c
@@ -0,0 +1,560 @@
+/*
+ * (C) Copyright 2010
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Designware ethernet IP driver for u-boot
+ */
+
+#include <common.h>
+#include <miiphy.h>
+#include <malloc.h>
+#include <linux/compiler.h>
+#include <linux/err.h>
+#include <asm/io.h>
+#include "designware.h"
+
+static int configure_phy(struct eth_device *dev);
+
+static void tx_descs_init(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_dma_regs *dma_p = priv->dma_regs_p;
+	struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0];
+	char *txbuffs = &priv->txbuffs[0];
+	struct dmamacdescr *desc_p;
+	u32 idx;
+
+	for (idx = 0; idx < CONFIG_TX_DESCR_NUM; idx++) {
+		desc_p = &desc_table_p[idx];
+		desc_p->dmamac_addr = &txbuffs[idx * CONFIG_ETH_BUFSIZE];
+		desc_p->dmamac_next = &desc_table_p[idx + 1];
+
+#if defined(CONFIG_DW_ALTDESCRIPTOR)
+		desc_p->txrx_status &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
+				DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \
+				DESC_TXSTS_TXCHECKINSCTRL | \
+				DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);
+
+		desc_p->txrx_status |= DESC_TXSTS_TXCHAIN;
+		desc_p->dmamac_cntl = 0;
+		desc_p->txrx_status &= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
+#else
+		desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN;
+		desc_p->txrx_status = 0;
+#endif
+	}
+
+	/* Correcting the last pointer of the chain */
+	desc_p->dmamac_next = &desc_table_p[0];
+
+	writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
+}
+
+static void rx_descs_init(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_dma_regs *dma_p = priv->dma_regs_p;
+	struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0];
+	char *rxbuffs = &priv->rxbuffs[0];
+	struct dmamacdescr *desc_p;
+	u32 idx;
+
+	for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
+		desc_p = &desc_table_p[idx];
+		desc_p->dmamac_addr = &rxbuffs[idx * CONFIG_ETH_BUFSIZE];
+		desc_p->dmamac_next = &desc_table_p[idx + 1];
+
+		desc_p->dmamac_cntl =
+			(MAC_MAX_FRAME_SZ & DESC_RXCTRL_SIZE1MASK) | \
+				      DESC_RXCTRL_RXCHAIN;
+
+		desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
+	}
+
+	/* Correcting the last pointer of the chain */
+	desc_p->dmamac_next = &desc_table_p[0];
+
+	writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr);
+}
+
+static void descs_init(struct eth_device *dev)
+{
+	tx_descs_init(dev);
+	rx_descs_init(dev);
+}
+
+static int mac_reset(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_mac_regs *mac_p = priv->mac_regs_p;
+	struct eth_dma_regs *dma_p = priv->dma_regs_p;
+
+	ulong start;
+	int timeout = CONFIG_MACRESET_TIMEOUT;
+
+	writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode);
+
+	if (priv->interface != PHY_INTERFACE_MODE_RGMII)
+		writel(MII_PORTSELECT, &mac_p->conf);
+
+	start = get_timer(0);
+	while (get_timer(start) < timeout) {
+		if (!(readl(&dma_p->busmode) & DMAMAC_SRST))
+			return 0;
+
+		/* Try again after 10usec */
+		udelay(10);
+	};
+
+	return -1;
+}
+
+static int dw_write_hwaddr(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_mac_regs *mac_p = priv->mac_regs_p;
+	u32 macid_lo, macid_hi;
+	u8 *mac_id = &dev->enetaddr[0];
+
+	macid_lo = mac_id[0] + (mac_id[1] << 8) + \
+		   (mac_id[2] << 16) + (mac_id[3] << 24);
+	macid_hi = mac_id[4] + (mac_id[5] << 8);
+
+	writel(macid_hi, &mac_p->macaddr0hi);
+	writel(macid_lo, &mac_p->macaddr0lo);
+
+	return 0;
+}
+
+static int dw_eth_init(struct eth_device *dev, bd_t *bis)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_mac_regs *mac_p = priv->mac_regs_p;
+	struct eth_dma_regs *dma_p = priv->dma_regs_p;
+	u32 conf;
+
+	if (priv->phy_configured != 1)
+		configure_phy(dev);
+
+	/* Print link status only once */
+	if (!priv->link_printed) {
+		printf("ENET Speed is %d Mbps - %s duplex connection\n",
+		       priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL");
+		priv->link_printed = 1;
+	}
+
+	/* Reset ethernet hardware */
+	if (mac_reset(dev) < 0)
+		return -1;
+
+	/* Resore the HW MAC address as it has been lost during MAC reset */
+	dw_write_hwaddr(dev);
+
+	writel(FIXEDBURST | PRIORXTX_41 | BURST_16,
+			&dma_p->busmode);
+
+	writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD |
+		TXSECONDFRAME, &dma_p->opmode);
+
+	conf = FRAMEBURSTENABLE | DISABLERXOWN;
+
+	if (priv->speed != 1000)
+		conf |= MII_PORTSELECT;
+
+	if ((priv->interface != PHY_INTERFACE_MODE_MII) &&
+		(priv->interface != PHY_INTERFACE_MODE_GMII)) {
+
+		if (priv->speed == 100)
+			conf |= FES_100;
+	}
+
+	if (priv->duplex == FULL)
+		conf |= FULLDPLXMODE;
+
+	writel(conf, &mac_p->conf);
+
+	descs_init(dev);
+
+	/*
+	 * Start/Enable xfer at dma as well as mac level
+	 */
+	writel(readl(&dma_p->opmode) | RXSTART, &dma_p->opmode);
+	writel(readl(&dma_p->opmode) | TXSTART, &dma_p->opmode);
+
+	writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf);
+
+	return 0;
+}
+
+static int dw_eth_send(struct eth_device *dev, void *packet, int length)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_dma_regs *dma_p = priv->dma_regs_p;
+	u32 desc_num = priv->tx_currdescnum;
+	struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
+
+	/* Check if the descriptor is owned by CPU */
+	if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) {
+		printf("CPU not owner of tx frame\n");
+		return -1;
+	}
+
+	memcpy((void *)desc_p->dmamac_addr, packet, length);
+
+#if defined(CONFIG_DW_ALTDESCRIPTOR)
+	desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
+	desc_p->dmamac_cntl |= (length << DESC_TXCTRL_SIZE1SHFT) & \
+			       DESC_TXCTRL_SIZE1MASK;
+
+	desc_p->txrx_status &= ~(DESC_TXSTS_MSK);
+	desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA;
+#else
+	desc_p->dmamac_cntl |= ((length << DESC_TXCTRL_SIZE1SHFT) & \
+			       DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | \
+			       DESC_TXCTRL_TXFIRST;
+
+	desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
+#endif
+
+	/* Test the wrap-around condition. */
+	if (++desc_num >= CONFIG_TX_DESCR_NUM)
+		desc_num = 0;
+
+	priv->tx_currdescnum = desc_num;
+
+	/* Start the transmission */
+	writel(POLL_DATA, &dma_p->txpolldemand);
+
+	return 0;
+}
+
+static int dw_eth_recv(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	u32 desc_num = priv->rx_currdescnum;
+	struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
+
+	u32 status = desc_p->txrx_status;
+	int length = 0;
+
+	/* Check  if the owner is the CPU */
+	if (!(status & DESC_RXSTS_OWNBYDMA)) {
+
+		length = (status & DESC_RXSTS_FRMLENMSK) >> \
+			 DESC_RXSTS_FRMLENSHFT;
+
+		NetReceive(desc_p->dmamac_addr, length);
+
+		/*
+		 * Make the current descriptor valid again and go to
+		 * the next one
+		 */
+		desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
+
+		/* Test the wrap-around condition. */
+		if (++desc_num >= CONFIG_RX_DESCR_NUM)
+			desc_num = 0;
+	}
+
+	priv->rx_currdescnum = desc_num;
+
+	return length;
+}
+
+static void dw_eth_halt(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+
+	mac_reset(dev);
+	priv->tx_currdescnum = priv->rx_currdescnum = 0;
+}
+
+static int eth_mdio_read(struct eth_device *dev, u8 addr, u8 reg, u16 *val)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_mac_regs *mac_p = priv->mac_regs_p;
+	ulong start;
+	u32 miiaddr;
+	int timeout = CONFIG_MDIO_TIMEOUT;
+
+	miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | \
+		  ((reg << MIIREGSHIFT) & MII_REGMSK);
+
+	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
+
+	start = get_timer(0);
+	while (get_timer(start) < timeout) {
+		if (!(readl(&mac_p->miiaddr) & MII_BUSY)) {
+			*val = readl(&mac_p->miidata);
+			return 0;
+		}
+
+		/* Try again after 10usec */
+		udelay(10);
+	};
+
+	return -1;
+}
+
+static int eth_mdio_write(struct eth_device *dev, u8 addr, u8 reg, u16 val)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	struct eth_mac_regs *mac_p = priv->mac_regs_p;
+	ulong start;
+	u32 miiaddr;
+	int ret = -1, timeout = CONFIG_MDIO_TIMEOUT;
+	u16 value;
+
+	writel(val, &mac_p->miidata);
+	miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | \
+		  ((reg << MIIREGSHIFT) & MII_REGMSK) | MII_WRITE;
+
+	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
+
+	start = get_timer(0);
+	while (get_timer(start) < timeout) {
+		if (!(readl(&mac_p->miiaddr) & MII_BUSY)) {
+			ret = 0;
+			break;
+		}
+
+		/* Try again after 10usec */
+		udelay(10);
+	};
+
+	/* Needed as a fix for ST-Phy */
+	eth_mdio_read(dev, addr, reg, &value);
+
+	return ret;
+}
+
+#if defined(CONFIG_DW_SEARCH_PHY)
+static int find_phy(struct eth_device *dev)
+{
+	int phy_addr = 0;
+	u16 ctrl, oldctrl;
+
+	do {
+		eth_mdio_read(dev, phy_addr, MII_BMCR, &ctrl);
+		oldctrl = ctrl & BMCR_ANENABLE;
+
+		ctrl ^= BMCR_ANENABLE;
+		eth_mdio_write(dev, phy_addr, MII_BMCR, ctrl);
+		eth_mdio_read(dev, phy_addr, MII_BMCR, &ctrl);
+		ctrl &= BMCR_ANENABLE;
+
+		if (ctrl == oldctrl) {
+			phy_addr++;
+		} else {
+			ctrl ^= BMCR_ANENABLE;
+			eth_mdio_write(dev, phy_addr, MII_BMCR, ctrl);
+
+			return phy_addr;
+		}
+	} while (phy_addr < 32);
+
+	return -1;
+}
+#endif
+
+static int dw_reset_phy(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	u16 ctrl;
+	ulong start;
+	int timeout = CONFIG_PHYRESET_TIMEOUT;
+	u32 phy_addr = priv->address;
+
+	eth_mdio_write(dev, phy_addr, MII_BMCR, BMCR_RESET);
+
+	start = get_timer(0);
+	while (get_timer(start) < timeout) {
+		eth_mdio_read(dev, phy_addr, MII_BMCR, &ctrl);
+		if (!(ctrl & BMCR_RESET))
+			break;
+
+		/* Try again after 10usec */
+		udelay(10);
+	};
+
+	if (get_timer(start) >= CONFIG_PHYRESET_TIMEOUT)
+		return -1;
+
+#ifdef CONFIG_PHY_RESET_DELAY
+	udelay(CONFIG_PHY_RESET_DELAY);
+#endif
+	return 0;
+}
+
+/*
+ * Add weak default function for board specific PHY configuration
+ */
+int __weak designware_board_phy_init(struct eth_device *dev, int phy_addr,
+		int (*mii_write)(struct eth_device *, u8, u8, u16),
+		int dw_reset_phy(struct eth_device *))
+{
+	return 0;
+}
+
+static int configure_phy(struct eth_device *dev)
+{
+	struct dw_eth_dev *priv = dev->priv;
+	int phy_addr;
+	u16 bmcr;
+#if defined(CONFIG_DW_AUTONEG)
+	u16 bmsr;
+	u32 timeout;
+	ulong start;
+#endif
+
+#if defined(CONFIG_DW_SEARCH_PHY)
+	phy_addr = find_phy(dev);
+	if (phy_addr >= 0)
+		priv->address = phy_addr;
+	else
+		return -1;
+#else
+	phy_addr = priv->address;
+#endif
+
+	/*
+	 * Some boards need board specific PHY initialization. This is
+	 * after the main driver init code but before the auto negotiation
+	 * is run.
+	 */
+	if (designware_board_phy_init(dev, phy_addr,
+				      eth_mdio_write, dw_reset_phy) < 0)
+		return -1;
+
+	if (dw_reset_phy(dev) < 0)
+		return -1;
+
+#if defined(CONFIG_DW_AUTONEG)
+	/* Set Auto-Neg Advertisement capabilities to 10/100 half/full */
+	eth_mdio_write(dev, phy_addr, MII_ADVERTISE, 0x1E1);
+
+	bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
+#else
+	bmcr = BMCR_SPEED100 | BMCR_FULLDPLX;
+
+#if defined(CONFIG_DW_SPEED10M)
+	bmcr &= ~BMCR_SPEED100;
+#endif
+#if defined(CONFIG_DW_DUPLEXHALF)
+	bmcr &= ~BMCR_FULLDPLX;
+#endif
+#endif
+	if (eth_mdio_write(dev, phy_addr, MII_BMCR, bmcr) < 0)
+		return -1;
+
+	/* Read the phy status register and populate priv structure */
+#if defined(CONFIG_DW_AUTONEG)
+	timeout = CONFIG_AUTONEG_TIMEOUT;
+	start = get_timer(0);
+	puts("Waiting for PHY auto negotiation to complete");
+	while (get_timer(start) < timeout) {
+		eth_mdio_read(dev, phy_addr, MII_BMSR, &bmsr);
+		if (bmsr & BMSR_ANEGCOMPLETE) {
+			priv->phy_configured = 1;
+			break;
+		}
+
+		/* Print dot all 1s to show progress */
+		if ((get_timer(start) % 1000) == 0)
+			putc('.');
+
+		/* Try again after 1msec */
+		udelay(1000);
+	};
+
+	if (!(bmsr & BMSR_ANEGCOMPLETE))
+		puts(" TIMEOUT!\n");
+	else
+		puts(" done\n");
+#else
+	priv->phy_configured = 1;
+#endif
+
+	priv->speed = miiphy_speed(dev->name, phy_addr);
+	priv->duplex = miiphy_duplex(dev->name, phy_addr);
+
+	return 0;
+}
+
+#if defined(CONFIG_MII)
+static int dw_mii_read(const char *devname, u8 addr, u8 reg, u16 *val)
+{
+	struct eth_device *dev;
+
+	dev = eth_get_dev_by_name(devname);
+	if (dev)
+		eth_mdio_read(dev, addr, reg, val);
+
+	return 0;
+}
+
+static int dw_mii_write(const char *devname, u8 addr, u8 reg, u16 val)
+{
+	struct eth_device *dev;
+
+	dev = eth_get_dev_by_name(devname);
+	if (dev)
+		eth_mdio_write(dev, addr, reg, val);
+
+	return 0;
+}
+#endif
+
+int designware_initialize(u32 id, ulong base_addr, u32 phy_addr, u32 interface)
+{
+	struct eth_device *dev;
+	struct dw_eth_dev *priv;
+
+	dev = (struct eth_device *) malloc(sizeof(struct eth_device));
+	if (!dev)
+		return -ENOMEM;
+
+	/*
+	 * Since the priv structure contains the descriptors which need a strict
+	 * buswidth alignment, memalign is used to allocate memory
+	 */
+	priv = (struct dw_eth_dev *) memalign(16, sizeof(struct dw_eth_dev));
+	if (!priv) {
+		free(dev);
+		return -ENOMEM;
+	}
+
+	memset(dev, 0, sizeof(struct eth_device));
+	memset(priv, 0, sizeof(struct dw_eth_dev));
+
+	sprintf(dev->name, "mii%d", id);
+	dev->iobase = (int)base_addr;
+	dev->priv = priv;
+
+	eth_getenv_enetaddr_by_index("eth", id, &dev->enetaddr[0]);
+
+	priv->dev = dev;
+	priv->mac_regs_p = (struct eth_mac_regs *)base_addr;
+	priv->dma_regs_p = (struct eth_dma_regs *)(base_addr +
+			DW_DMA_BASE_OFFSET);
+	priv->address = phy_addr;
+	priv->phy_configured = 0;
+	priv->interface = interface;
+
+	dev->init = dw_eth_init;
+	dev->send = dw_eth_send;
+	dev->recv = dw_eth_recv;
+	dev->halt = dw_eth_halt;
+	dev->write_hwaddr = dw_write_hwaddr;
+
+	eth_register(dev);
+
+#if defined(CONFIG_MII)
+	miiphy_register(dev->name, dw_mii_read, dw_mii_write);
+#endif
+	return 1;
+}
diff --git a/marvell/uboot/drivers/net/designware.h b/marvell/uboot/drivers/net/designware.h
new file mode 100644
index 0000000..5440c92
--- /dev/null
+++ b/marvell/uboot/drivers/net/designware.h
@@ -0,0 +1,250 @@
+/*
+ * (C) Copyright 2010
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _DW_ETH_H
+#define _DW_ETH_H
+
+#define CONFIG_TX_DESCR_NUM	16
+#define CONFIG_RX_DESCR_NUM	16
+#define CONFIG_ETH_BUFSIZE	2048
+#define TX_TOTAL_BUFSIZE	(CONFIG_ETH_BUFSIZE * CONFIG_TX_DESCR_NUM)
+#define RX_TOTAL_BUFSIZE	(CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM)
+
+#define CONFIG_MACRESET_TIMEOUT	(3 * CONFIG_SYS_HZ)
+#define CONFIG_MDIO_TIMEOUT	(3 * CONFIG_SYS_HZ)
+#define CONFIG_PHYRESET_TIMEOUT	(3 * CONFIG_SYS_HZ)
+#define CONFIG_AUTONEG_TIMEOUT	(5 * CONFIG_SYS_HZ)
+
+struct eth_mac_regs {
+	u32 conf;		/* 0x00 */
+	u32 framefilt;		/* 0x04 */
+	u32 hashtablehigh;	/* 0x08 */
+	u32 hashtablelow;	/* 0x0c */
+	u32 miiaddr;		/* 0x10 */
+	u32 miidata;		/* 0x14 */
+	u32 flowcontrol;	/* 0x18 */
+	u32 vlantag;		/* 0x1c */
+	u32 version;		/* 0x20 */
+	u8 reserved_1[20];
+	u32 intreg;		/* 0x38 */
+	u32 intmask;		/* 0x3c */
+	u32 macaddr0hi;		/* 0x40 */
+	u32 macaddr0lo;		/* 0x44 */
+};
+
+/* MAC configuration register definitions */
+#define FRAMEBURSTENABLE	(1 << 21)
+#define MII_PORTSELECT		(1 << 15)
+#define FES_100			(1 << 14)
+#define DISABLERXOWN		(1 << 13)
+#define FULLDPLXMODE		(1 << 11)
+#define RXENABLE		(1 << 2)
+#define TXENABLE		(1 << 3)
+
+/* MII address register definitions */
+#define MII_BUSY		(1 << 0)
+#define MII_WRITE		(1 << 1)
+#define MII_CLKRANGE_60_100M	(0)
+#define MII_CLKRANGE_100_150M	(0x4)
+#define MII_CLKRANGE_20_35M	(0x8)
+#define MII_CLKRANGE_35_60M	(0xC)
+#define MII_CLKRANGE_150_250M	(0x10)
+#define MII_CLKRANGE_250_300M	(0x14)
+
+#define MIIADDRSHIFT		(11)
+#define MIIREGSHIFT		(6)
+#define MII_REGMSK		(0x1F << 6)
+#define MII_ADDRMSK		(0x1F << 11)
+
+
+struct eth_dma_regs {
+	u32 busmode;		/* 0x00 */
+	u32 txpolldemand;	/* 0x04 */
+	u32 rxpolldemand;	/* 0x08 */
+	u32 rxdesclistaddr;	/* 0x0c */
+	u32 txdesclistaddr;	/* 0x10 */
+	u32 status;		/* 0x14 */
+	u32 opmode;		/* 0x18 */
+	u32 intenable;		/* 0x1c */
+	u8 reserved[40];
+	u32 currhosttxdesc;	/* 0x48 */
+	u32 currhostrxdesc;	/* 0x4c */
+	u32 currhosttxbuffaddr;	/* 0x50 */
+	u32 currhostrxbuffaddr;	/* 0x54 */
+};
+
+#define DW_DMA_BASE_OFFSET	(0x1000)
+
+/* Bus mode register definitions */
+#define FIXEDBURST		(1 << 16)
+#define PRIORXTX_41		(3 << 14)
+#define PRIORXTX_31		(2 << 14)
+#define PRIORXTX_21		(1 << 14)
+#define PRIORXTX_11		(0 << 14)
+#define BURST_1			(1 << 8)
+#define BURST_2			(2 << 8)
+#define BURST_4			(4 << 8)
+#define BURST_8			(8 << 8)
+#define BURST_16		(16 << 8)
+#define BURST_32		(32 << 8)
+#define RXHIGHPRIO		(1 << 1)
+#define DMAMAC_SRST		(1 << 0)
+
+/* Poll demand definitions */
+#define POLL_DATA		(0xFFFFFFFF)
+
+/* Operation mode definitions */
+#define STOREFORWARD		(1 << 21)
+#define FLUSHTXFIFO		(1 << 20)
+#define TXSTART			(1 << 13)
+#define TXSECONDFRAME		(1 << 2)
+#define RXSTART			(1 << 1)
+
+/* Descriptior related definitions */
+#define MAC_MAX_FRAME_SZ	(1600)
+
+struct dmamacdescr {
+	u32 txrx_status;
+	u32 dmamac_cntl;
+	void *dmamac_addr;
+	struct dmamacdescr *dmamac_next;
+} __aligned(16);
+
+/*
+ * txrx_status definitions
+ */
+
+/* tx status bits definitions */
+#if defined(CONFIG_DW_ALTDESCRIPTOR)
+
+#define DESC_TXSTS_OWNBYDMA		(1 << 31)
+#define DESC_TXSTS_TXINT		(1 << 30)
+#define DESC_TXSTS_TXLAST		(1 << 29)
+#define DESC_TXSTS_TXFIRST		(1 << 28)
+#define DESC_TXSTS_TXCRCDIS		(1 << 27)
+
+#define DESC_TXSTS_TXPADDIS		(1 << 26)
+#define DESC_TXSTS_TXCHECKINSCTRL	(3 << 22)
+#define DESC_TXSTS_TXRINGEND		(1 << 21)
+#define DESC_TXSTS_TXCHAIN		(1 << 20)
+#define DESC_TXSTS_MSK			(0x1FFFF << 0)
+
+#else
+
+#define DESC_TXSTS_OWNBYDMA		(1 << 31)
+#define DESC_TXSTS_MSK			(0x1FFFF << 0)
+
+#endif
+
+/* rx status bits definitions */
+#define DESC_RXSTS_OWNBYDMA		(1 << 31)
+#define DESC_RXSTS_DAFILTERFAIL		(1 << 30)
+#define DESC_RXSTS_FRMLENMSK		(0x3FFF << 16)
+#define DESC_RXSTS_FRMLENSHFT		(16)
+
+#define DESC_RXSTS_ERROR		(1 << 15)
+#define DESC_RXSTS_RXTRUNCATED		(1 << 14)
+#define DESC_RXSTS_SAFILTERFAIL		(1 << 13)
+#define DESC_RXSTS_RXIPC_GIANTFRAME	(1 << 12)
+#define DESC_RXSTS_RXDAMAGED		(1 << 11)
+#define DESC_RXSTS_RXVLANTAG		(1 << 10)
+#define DESC_RXSTS_RXFIRST		(1 << 9)
+#define DESC_RXSTS_RXLAST		(1 << 8)
+#define DESC_RXSTS_RXIPC_GIANT		(1 << 7)
+#define DESC_RXSTS_RXCOLLISION		(1 << 6)
+#define DESC_RXSTS_RXFRAMEETHER		(1 << 5)
+#define DESC_RXSTS_RXWATCHDOG		(1 << 4)
+#define DESC_RXSTS_RXMIIERROR		(1 << 3)
+#define DESC_RXSTS_RXDRIBBLING		(1 << 2)
+#define DESC_RXSTS_RXCRC		(1 << 1)
+
+/*
+ * dmamac_cntl definitions
+ */
+
+/* tx control bits definitions */
+#if defined(CONFIG_DW_ALTDESCRIPTOR)
+
+#define DESC_TXCTRL_SIZE1MASK		(0x1FFF << 0)
+#define DESC_TXCTRL_SIZE1SHFT		(0)
+#define DESC_TXCTRL_SIZE2MASK		(0x1FFF << 16)
+#define DESC_TXCTRL_SIZE2SHFT		(16)
+
+#else
+
+#define DESC_TXCTRL_TXINT		(1 << 31)
+#define DESC_TXCTRL_TXLAST		(1 << 30)
+#define DESC_TXCTRL_TXFIRST		(1 << 29)
+#define DESC_TXCTRL_TXCHECKINSCTRL	(3 << 27)
+#define DESC_TXCTRL_TXCRCDIS		(1 << 26)
+#define DESC_TXCTRL_TXRINGEND		(1 << 25)
+#define DESC_TXCTRL_TXCHAIN		(1 << 24)
+
+#define DESC_TXCTRL_SIZE1MASK		(0x7FF << 0)
+#define DESC_TXCTRL_SIZE1SHFT		(0)
+#define DESC_TXCTRL_SIZE2MASK		(0x7FF << 11)
+#define DESC_TXCTRL_SIZE2SHFT		(11)
+
+#endif
+
+/* rx control bits definitions */
+#if defined(CONFIG_DW_ALTDESCRIPTOR)
+
+#define DESC_RXCTRL_RXINTDIS		(1 << 31)
+#define DESC_RXCTRL_RXRINGEND		(1 << 15)
+#define DESC_RXCTRL_RXCHAIN		(1 << 14)
+
+#define DESC_RXCTRL_SIZE1MASK		(0x1FFF << 0)
+#define DESC_RXCTRL_SIZE1SHFT		(0)
+#define DESC_RXCTRL_SIZE2MASK		(0x1FFF << 16)
+#define DESC_RXCTRL_SIZE2SHFT		(16)
+
+#else
+
+#define DESC_RXCTRL_RXINTDIS		(1 << 31)
+#define DESC_RXCTRL_RXRINGEND		(1 << 25)
+#define DESC_RXCTRL_RXCHAIN		(1 << 24)
+
+#define DESC_RXCTRL_SIZE1MASK		(0x7FF << 0)
+#define DESC_RXCTRL_SIZE1SHFT		(0)
+#define DESC_RXCTRL_SIZE2MASK		(0x7FF << 11)
+#define DESC_RXCTRL_SIZE2SHFT		(11)
+
+#endif
+
+struct dw_eth_dev {
+	u32 address;
+	u32 interface;
+	u32 speed;
+	u32 duplex;
+	u32 tx_currdescnum;
+	u32 rx_currdescnum;
+	u32 phy_configured;
+	u32 link_printed;
+
+	struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM];
+	struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM];
+
+	char txbuffs[TX_TOTAL_BUFSIZE];
+	char rxbuffs[RX_TOTAL_BUFSIZE];
+
+	struct eth_mac_regs *mac_regs_p;
+	struct eth_dma_regs *dma_regs_p;
+
+	struct eth_device *dev;
+};
+
+/* Speed specific definitions */
+#define SPEED_10M		1
+#define SPEED_100M		2
+#define SPEED_1000M		3
+
+/* Duplex mode specific definitions */
+#define HALF_DUPLEX		1
+#define FULL_DUPLEX		2
+
+#endif
diff --git a/marvell/uboot/drivers/net/dm9000x.c b/marvell/uboot/drivers/net/dm9000x.c
new file mode 100644
index 0000000..b68d808
--- /dev/null
+++ b/marvell/uboot/drivers/net/dm9000x.c
@@ -0,0 +1,643 @@
+/*
+  dm9000.c: Version 1.2 12/15/2003
+
+	A Davicom DM9000 ISA NIC fast Ethernet driver for Linux.
+	Copyright (C) 1997  Sten Wang
+
+ * SPDX-License-Identifier:	GPL-2.0+
+
+  (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
+
+V0.11	06/20/2001	REG_0A bit3=1, default enable BP with DA match
+	06/22/2001	Support DM9801 progrmming
+			E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000
+			E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200
+		R17 = (R17 & 0xfff0) | NF + 3
+			E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200
+		R17 = (R17 & 0xfff0) | NF
+
+v1.00			modify by simon 2001.9.5
+			change for kernel 2.4.x
+
+v1.1   11/09/2001	fix force mode bug
+
+v1.2   03/18/2003       Weilun Huang <weilun_huang@davicom.com.tw>:
+			Fixed phy reset.
+			Added tx/rx 32 bit mode.
+			Cleaned up for kernel merge.
+
+--------------------------------------
+
+       12/15/2003       Initial port to u-boot by
+       			Sascha Hauer <saschahauer@web.de>
+
+       06/03/2008	Remy Bohmer <linux@bohmer.net>
+			- Fixed the driver to work with DM9000A.
+			  (check on ISR receive status bit before reading the
+			  FIFO as described in DM9000 programming guide and
+			  application notes)
+			- Added autodetect of databus width.
+			- Made debug code compile again.
+			- Adapt eth_send such that it matches the DM9000*
+			  application notes. Needed to make it work properly
+			  for DM9000A.
+			- Adapted reset procedure to match DM9000 application
+			  notes (i.e. double reset)
+			- some minor code cleanups
+			These changes are tested with DM9000{A,EP,E} together
+			with a 200MHz Atmel AT91SAM9261 core
+
+TODO: external MII is not functional, only internal at the moment.
+*/
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <asm/io.h>
+#include <dm9000.h>
+
+#include "dm9000x.h"
+
+/* Board/System/Debug information/definition ---------------- */
+
+/* #define CONFIG_DM9000_DEBUG */
+
+#ifdef CONFIG_DM9000_DEBUG
+#define DM9000_DBG(fmt,args...) printf(fmt, ##args)
+#define DM9000_DMP_PACKET(func,packet,length)  \
+	do { \
+		int i; 							\
+		printf("%s: length: %d\n", func, length);		\
+		for (i = 0; i < length; i++) {				\
+			if (i % 8 == 0)					\
+				printf("\n%s: %02x: ", func, i);	\
+			printf("%02x ", ((unsigned char *) packet)[i]);	\
+		} printf("\n");						\
+	} while(0)
+#else
+#define DM9000_DBG(fmt,args...)
+#define DM9000_DMP_PACKET(func,packet,length)
+#endif
+
+/* Structure/enum declaration ------------------------------- */
+typedef struct board_info {
+	u32 runt_length_counter;	/* counter: RX length < 64byte */
+	u32 long_length_counter;	/* counter: RX length > 1514byte */
+	u32 reset_counter;	/* counter: RESET */
+	u32 reset_tx_timeout;	/* RESET caused by TX Timeout */
+	u32 reset_rx_status;	/* RESET caused by RX Statsus wrong */
+	u16 tx_pkt_cnt;
+	u16 queue_start_addr;
+	u16 dbug_cnt;
+	u8 phy_addr;
+	u8 device_wait_reset;	/* device state */
+	unsigned char srom[128];
+	void (*outblk)(volatile void *data_ptr, int count);
+	void (*inblk)(void *data_ptr, int count);
+	void (*rx_status)(u16 *RxStatus, u16 *RxLen);
+	struct eth_device netdev;
+} board_info_t;
+static board_info_t dm9000_info;
+
+
+/* function declaration ------------------------------------- */
+static int dm9000_probe(void);
+static u16 dm9000_phy_read(int);
+static void dm9000_phy_write(int, u16);
+static u8 DM9000_ior(int);
+static void DM9000_iow(int reg, u8 value);
+
+/* DM9000 network board routine ---------------------------- */
+#ifndef CONFIG_DM9000_BYTE_SWAPPED
+#define DM9000_outb(d,r) writeb(d, (volatile u8 *)(r))
+#define DM9000_outw(d,r) writew(d, (volatile u16 *)(r))
+#define DM9000_outl(d,r) writel(d, (volatile u32 *)(r))
+#define DM9000_inb(r) readb((volatile u8 *)(r))
+#define DM9000_inw(r) readw((volatile u16 *)(r))
+#define DM9000_inl(r) readl((volatile u32 *)(r))
+#else
+#define DM9000_outb(d, r) __raw_writeb(d, r)
+#define DM9000_outw(d, r) __raw_writew(d, r)
+#define DM9000_outl(d, r) __raw_writel(d, r)
+#define DM9000_inb(r) __raw_readb(r)
+#define DM9000_inw(r) __raw_readw(r)
+#define DM9000_inl(r) __raw_readl(r)
+#endif
+
+#ifdef CONFIG_DM9000_DEBUG
+static void
+dump_regs(void)
+{
+	DM9000_DBG("\n");
+	DM9000_DBG("NCR   (0x00): %02x\n", DM9000_ior(0));
+	DM9000_DBG("NSR   (0x01): %02x\n", DM9000_ior(1));
+	DM9000_DBG("TCR   (0x02): %02x\n", DM9000_ior(2));
+	DM9000_DBG("TSRI  (0x03): %02x\n", DM9000_ior(3));
+	DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4));
+	DM9000_DBG("RCR   (0x05): %02x\n", DM9000_ior(5));
+	DM9000_DBG("RSR   (0x06): %02x\n", DM9000_ior(6));
+	DM9000_DBG("ISR   (0xFE): %02x\n", DM9000_ior(DM9000_ISR));
+	DM9000_DBG("\n");
+}
+#endif
+
+static void dm9000_outblk_8bit(volatile void *data_ptr, int count)
+{
+	int i;
+	for (i = 0; i < count; i++)
+		DM9000_outb((((u8 *) data_ptr)[i] & 0xff), DM9000_DATA);
+}
+
+static void dm9000_outblk_16bit(volatile void *data_ptr, int count)
+{
+	int i;
+	u32 tmplen = (count + 1) / 2;
+
+	for (i = 0; i < tmplen; i++)
+		DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA);
+}
+static void dm9000_outblk_32bit(volatile void *data_ptr, int count)
+{
+	int i;
+	u32 tmplen = (count + 3) / 4;
+
+	for (i = 0; i < tmplen; i++)
+		DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA);
+}
+
+static void dm9000_inblk_8bit(void *data_ptr, int count)
+{
+	int i;
+	for (i = 0; i < count; i++)
+		((u8 *) data_ptr)[i] = DM9000_inb(DM9000_DATA);
+}
+
+static void dm9000_inblk_16bit(void *data_ptr, int count)
+{
+	int i;
+	u32 tmplen = (count + 1) / 2;
+
+	for (i = 0; i < tmplen; i++)
+		((u16 *) data_ptr)[i] = DM9000_inw(DM9000_DATA);
+}
+static void dm9000_inblk_32bit(void *data_ptr, int count)
+{
+	int i;
+	u32 tmplen = (count + 3) / 4;
+
+	for (i = 0; i < tmplen; i++)
+		((u32 *) data_ptr)[i] = DM9000_inl(DM9000_DATA);
+}
+
+static void dm9000_rx_status_32bit(u16 *RxStatus, u16 *RxLen)
+{
+	u32 tmpdata;
+
+	DM9000_outb(DM9000_MRCMD, DM9000_IO);
+
+	tmpdata = DM9000_inl(DM9000_DATA);
+	*RxStatus = __le16_to_cpu(tmpdata);
+	*RxLen = __le16_to_cpu(tmpdata >> 16);
+}
+
+static void dm9000_rx_status_16bit(u16 *RxStatus, u16 *RxLen)
+{
+	DM9000_outb(DM9000_MRCMD, DM9000_IO);
+
+	*RxStatus = __le16_to_cpu(DM9000_inw(DM9000_DATA));
+	*RxLen = __le16_to_cpu(DM9000_inw(DM9000_DATA));
+}
+
+static void dm9000_rx_status_8bit(u16 *RxStatus, u16 *RxLen)
+{
+	DM9000_outb(DM9000_MRCMD, DM9000_IO);
+
+	*RxStatus =
+	    __le16_to_cpu(DM9000_inb(DM9000_DATA) +
+			  (DM9000_inb(DM9000_DATA) << 8));
+	*RxLen =
+	    __le16_to_cpu(DM9000_inb(DM9000_DATA) +
+			  (DM9000_inb(DM9000_DATA) << 8));
+}
+
+/*
+  Search DM9000 board, allocate space and register it
+*/
+int
+dm9000_probe(void)
+{
+	u32 id_val;
+	id_val = DM9000_ior(DM9000_VIDL);
+	id_val |= DM9000_ior(DM9000_VIDH) << 8;
+	id_val |= DM9000_ior(DM9000_PIDL) << 16;
+	id_val |= DM9000_ior(DM9000_PIDH) << 24;
+	if (id_val == DM9000_ID) {
+		printf("dm9000 i/o: 0x%x, id: 0x%x \n", CONFIG_DM9000_BASE,
+		       id_val);
+		return 0;
+	} else {
+		printf("dm9000 not found at 0x%08x id: 0x%08x\n",
+		       CONFIG_DM9000_BASE, id_val);
+		return -1;
+	}
+}
+
+/* General Purpose dm9000 reset routine */
+static void
+dm9000_reset(void)
+{
+	DM9000_DBG("resetting DM9000\n");
+
+	/* Reset DM9000,
+	   see DM9000 Application Notes V1.22 Jun 11, 2004 page 29 */
+
+	/* DEBUG: Make all GPIO0 outputs, all others inputs */
+	DM9000_iow(DM9000_GPCR, GPCR_GPIO0_OUT);
+	/* Step 1: Power internal PHY by writing 0 to GPIO0 pin */
+	DM9000_iow(DM9000_GPR, 0);
+	/* Step 2: Software reset */
+	DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST));
+
+	do {
+		DM9000_DBG("resetting the DM9000, 1st reset\n");
+		udelay(25); /* Wait at least 20 us */
+	} while (DM9000_ior(DM9000_NCR) & 1);
+
+	DM9000_iow(DM9000_NCR, 0);
+	DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); /* Issue a second reset */
+
+	do {
+		DM9000_DBG("resetting the DM9000, 2nd reset\n");
+		udelay(25); /* Wait at least 20 us */
+	} while (DM9000_ior(DM9000_NCR) & 1);
+
+	/* Check whether the ethernet controller is present */
+	if ((DM9000_ior(DM9000_PIDL) != 0x0) ||
+	    (DM9000_ior(DM9000_PIDH) != 0x90))
+		printf("ERROR: resetting DM9000 -> not responding\n");
+}
+
+/* Initialize dm9000 board
+*/
+static int dm9000_init(struct eth_device *dev, bd_t *bd)
+{
+	int i, oft, lnk;
+	u8 io_mode;
+	struct board_info *db = &dm9000_info;
+
+	DM9000_DBG("%s\n", __func__);
+
+	/* RESET device */
+	dm9000_reset();
+
+	if (dm9000_probe() < 0)
+		return -1;
+
+	/* Auto-detect 8/16/32 bit mode, ISR Bit 6+7 indicate bus width */
+	io_mode = DM9000_ior(DM9000_ISR) >> 6;
+
+	switch (io_mode) {
+	case 0x0:  /* 16-bit mode */
+		printf("DM9000: running in 16 bit mode\n");
+		db->outblk    = dm9000_outblk_16bit;
+		db->inblk     = dm9000_inblk_16bit;
+		db->rx_status = dm9000_rx_status_16bit;
+		break;
+	case 0x01:  /* 32-bit mode */
+		printf("DM9000: running in 32 bit mode\n");
+		db->outblk    = dm9000_outblk_32bit;
+		db->inblk     = dm9000_inblk_32bit;
+		db->rx_status = dm9000_rx_status_32bit;
+		break;
+	case 0x02: /* 8 bit mode */
+		printf("DM9000: running in 8 bit mode\n");
+		db->outblk    = dm9000_outblk_8bit;
+		db->inblk     = dm9000_inblk_8bit;
+		db->rx_status = dm9000_rx_status_8bit;
+		break;
+	default:
+		/* Assume 8 bit mode, will probably not work anyway */
+		printf("DM9000: Undefined IO-mode:0x%x\n", io_mode);
+		db->outblk    = dm9000_outblk_8bit;
+		db->inblk     = dm9000_inblk_8bit;
+		db->rx_status = dm9000_rx_status_8bit;
+		break;
+	}
+
+	/* Program operating register, only internal phy supported */
+	DM9000_iow(DM9000_NCR, 0x0);
+	/* TX Polling clear */
+	DM9000_iow(DM9000_TCR, 0);
+	/* Less 3Kb, 200us */
+	DM9000_iow(DM9000_BPTR, BPTR_BPHW(3) | BPTR_JPT_600US);
+	/* Flow Control : High/Low Water */
+	DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));
+	/* SH FIXME: This looks strange! Flow Control */
+	DM9000_iow(DM9000_FCR, 0x0);
+	/* Special Mode */
+	DM9000_iow(DM9000_SMCR, 0);
+	/* clear TX status */
+	DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);
+	/* Clear interrupt status */
+	DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS);
+
+	printf("MAC: %pM\n", dev->enetaddr);
+	if (!is_valid_ether_addr(dev->enetaddr)) {
+#ifdef CONFIG_RANDOM_MACADDR
+		printf("Bad MAC address (uninitialized EEPROM?), randomizing\n");
+		eth_random_enetaddr(dev->enetaddr);
+		printf("MAC: %pM\n", dev->enetaddr);
+#else
+		printf("WARNING: Bad MAC address (uninitialized EEPROM?)\n");
+#endif
+	}
+
+	/* fill device MAC address registers */
+	for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
+		DM9000_iow(oft, dev->enetaddr[i]);
+	for (i = 0, oft = 0x16; i < 8; i++, oft++)
+		DM9000_iow(oft, 0xff);
+
+	/* read back mac, just to be sure */
+	for (i = 0, oft = 0x10; i < 6; i++, oft++)
+		DM9000_DBG("%02x:", DM9000_ior(oft));
+	DM9000_DBG("\n");
+
+	/* Activate DM9000 */
+	/* RX enable */
+	DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
+	/* Enable TX/RX interrupt mask */
+	DM9000_iow(DM9000_IMR, IMR_PAR);
+
+	i = 0;
+	while (!(dm9000_phy_read(1) & 0x20)) {	/* autonegation complete bit */
+		udelay(1000);
+		i++;
+		if (i == 10000) {
+			printf("could not establish link\n");
+			return 0;
+		}
+	}
+
+	/* see what we've got */
+	lnk = dm9000_phy_read(17) >> 12;
+	printf("operating at ");
+	switch (lnk) {
+	case 1:
+		printf("10M half duplex ");
+		break;
+	case 2:
+		printf("10M full duplex ");
+		break;
+	case 4:
+		printf("100M half duplex ");
+		break;
+	case 8:
+		printf("100M full duplex ");
+		break;
+	default:
+		printf("unknown: %d ", lnk);
+		break;
+	}
+	printf("mode\n");
+	return 0;
+}
+
+/*
+  Hardware start transmission.
+  Send a packet to media from the upper layer.
+*/
+static int dm9000_send(struct eth_device *netdev, void *packet, int length)
+{
+	int tmo;
+	struct board_info *db = &dm9000_info;
+
+	DM9000_DMP_PACKET(__func__ , packet, length);
+
+	DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */
+
+	/* Move data to DM9000 TX RAM */
+	DM9000_outb(DM9000_MWCMD, DM9000_IO); /* Prepare for TX-data */
+
+	/* push the data to the TX-fifo */
+	(db->outblk)(packet, length);
+
+	/* Set TX length to DM9000 */
+	DM9000_iow(DM9000_TXPLL, length & 0xff);
+	DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff);
+
+	/* Issue TX polling command */
+	DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */
+
+	/* wait for end of transmission */
+	tmo = get_timer(0) + 5 * CONFIG_SYS_HZ;
+	while ( !(DM9000_ior(DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) ||
+		!(DM9000_ior(DM9000_ISR) & IMR_PTM) ) {
+		if (get_timer(0) >= tmo) {
+			printf("transmission timeout\n");
+			break;
+		}
+	}
+	DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */
+
+	DM9000_DBG("transmit done\n\n");
+	return 0;
+}
+
+/*
+  Stop the interface.
+  The interface is stopped when it is brought.
+*/
+static void dm9000_halt(struct eth_device *netdev)
+{
+	DM9000_DBG("%s\n", __func__);
+
+	/* RESET devie */
+	dm9000_phy_write(0, 0x8000);	/* PHY RESET */
+	DM9000_iow(DM9000_GPR, 0x01);	/* Power-Down PHY */
+	DM9000_iow(DM9000_IMR, 0x80);	/* Disable all interrupt */
+	DM9000_iow(DM9000_RCR, 0x00);	/* Disable RX */
+}
+
+/*
+  Received a packet and pass to upper layer
+*/
+static int dm9000_rx(struct eth_device *netdev)
+{
+	u8 rxbyte, *rdptr = (u8 *) NetRxPackets[0];
+	u16 RxStatus, RxLen = 0;
+	struct board_info *db = &dm9000_info;
+
+	/* Check packet ready or not, we must check
+	   the ISR status first for DM9000A */
+	if (!(DM9000_ior(DM9000_ISR) & 0x01)) /* Rx-ISR bit must be set. */
+		return 0;
+
+	DM9000_iow(DM9000_ISR, 0x01); /* clear PR status latched in bit 0 */
+
+	/* There is _at least_ 1 package in the fifo, read them all */
+	for (;;) {
+		DM9000_ior(DM9000_MRCMDX);	/* Dummy read */
+
+		/* Get most updated data,
+		   only look at bits 0:1, See application notes DM9000 */
+		rxbyte = DM9000_inb(DM9000_DATA) & 0x03;
+
+		/* Status check: this byte must be 0 or 1 */
+		if (rxbyte > DM9000_PKT_RDY) {
+			DM9000_iow(DM9000_RCR, 0x00);	/* Stop Device */
+			DM9000_iow(DM9000_ISR, 0x80);	/* Stop INT request */
+			printf("DM9000 error: status check fail: 0x%x\n",
+				rxbyte);
+			return 0;
+		}
+
+		if (rxbyte != DM9000_PKT_RDY)
+			return 0; /* No packet received, ignore */
+
+		DM9000_DBG("receiving packet\n");
+
+		/* A packet ready now  & Get status/length */
+		(db->rx_status)(&RxStatus, &RxLen);
+
+		DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen);
+
+		/* Move data from DM9000 */
+		/* Read received packet from RX SRAM */
+		(db->inblk)(rdptr, RxLen);
+
+		if ((RxStatus & 0xbf00) || (RxLen < 0x40)
+			|| (RxLen > DM9000_PKT_MAX)) {
+			if (RxStatus & 0x100) {
+				printf("rx fifo error\n");
+			}
+			if (RxStatus & 0x200) {
+				printf("rx crc error\n");
+			}
+			if (RxStatus & 0x8000) {
+				printf("rx length error\n");
+			}
+			if (RxLen > DM9000_PKT_MAX) {
+				printf("rx length too big\n");
+				dm9000_reset();
+			}
+		} else {
+			DM9000_DMP_PACKET(__func__ , rdptr, RxLen);
+
+			DM9000_DBG("passing packet to upper layer\n");
+			NetReceive(NetRxPackets[0], RxLen);
+		}
+	}
+	return 0;
+}
+
+/*
+  Read a word data from SROM
+*/
+#if !defined(CONFIG_DM9000_NO_SROM)
+void dm9000_read_srom_word(int offset, u8 *to)
+{
+	DM9000_iow(DM9000_EPAR, offset);
+	DM9000_iow(DM9000_EPCR, 0x4);
+	udelay(8000);
+	DM9000_iow(DM9000_EPCR, 0x0);
+	to[0] = DM9000_ior(DM9000_EPDRL);
+	to[1] = DM9000_ior(DM9000_EPDRH);
+}
+
+void dm9000_write_srom_word(int offset, u16 val)
+{
+	DM9000_iow(DM9000_EPAR, offset);
+	DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff));
+	DM9000_iow(DM9000_EPDRL, (val & 0xff));
+	DM9000_iow(DM9000_EPCR, 0x12);
+	udelay(8000);
+	DM9000_iow(DM9000_EPCR, 0);
+}
+#endif
+
+static void dm9000_get_enetaddr(struct eth_device *dev)
+{
+#if !defined(CONFIG_DM9000_NO_SROM)
+	int i;
+	for (i = 0; i < 3; i++)
+		dm9000_read_srom_word(i, dev->enetaddr + (2 * i));
+#endif
+}
+
+/*
+   Read a byte from I/O port
+*/
+static u8
+DM9000_ior(int reg)
+{
+	DM9000_outb(reg, DM9000_IO);
+	return DM9000_inb(DM9000_DATA);
+}
+
+/*
+   Write a byte to I/O port
+*/
+static void
+DM9000_iow(int reg, u8 value)
+{
+	DM9000_outb(reg, DM9000_IO);
+	DM9000_outb(value, DM9000_DATA);
+}
+
+/*
+   Read a word from phyxcer
+*/
+static u16
+dm9000_phy_read(int reg)
+{
+	u16 val;
+
+	/* Fill the phyxcer register into REG_0C */
+	DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
+	DM9000_iow(DM9000_EPCR, 0xc);	/* Issue phyxcer read command */
+	udelay(100);			/* Wait read complete */
+	DM9000_iow(DM9000_EPCR, 0x0);	/* Clear phyxcer read command */
+	val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);
+
+	/* The read data keeps on REG_0D & REG_0E */
+	DM9000_DBG("dm9000_phy_read(0x%x): 0x%x\n", reg, val);
+	return val;
+}
+
+/*
+   Write a word to phyxcer
+*/
+static void
+dm9000_phy_write(int reg, u16 value)
+{
+
+	/* Fill the phyxcer register into REG_0C */
+	DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
+
+	/* Fill the written data into REG_0D & REG_0E */
+	DM9000_iow(DM9000_EPDRL, (value & 0xff));
+	DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));
+	DM9000_iow(DM9000_EPCR, 0xa);	/* Issue phyxcer write command */
+	udelay(500);			/* Wait write complete */
+	DM9000_iow(DM9000_EPCR, 0x0);	/* Clear phyxcer write command */
+	DM9000_DBG("dm9000_phy_write(reg:0x%x, value:0x%x)\n", reg, value);
+}
+
+int dm9000_initialize(bd_t *bis)
+{
+	struct eth_device *dev = &(dm9000_info.netdev);
+
+	/* Load MAC address from EEPROM */
+	dm9000_get_enetaddr(dev);
+
+	dev->init = dm9000_init;
+	dev->halt = dm9000_halt;
+	dev->send = dm9000_send;
+	dev->recv = dm9000_rx;
+	sprintf(dev->name, "dm9000");
+
+	eth_register(dev);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/dm9000x.h b/marvell/uboot/drivers/net/dm9000x.h
new file mode 100644
index 0000000..0d123e2
--- /dev/null
+++ b/marvell/uboot/drivers/net/dm9000x.h
@@ -0,0 +1,140 @@
+/*
+ * dm9000 Ethernet
+ */
+
+#ifdef CONFIG_DRIVER_DM9000
+
+#define DM9000_ID		0x90000A46
+#define DM9000_PKT_MAX		1536	/* Received packet max size */
+#define DM9000_PKT_RDY		0x01	/* Packet ready to receive */
+
+/* although the registers are 16 bit, they are 32-bit aligned.
+ */
+
+#define DM9000_NCR             0x00
+#define DM9000_NSR             0x01
+#define DM9000_TCR             0x02
+#define DM9000_TSR1            0x03
+#define DM9000_TSR2            0x04
+#define DM9000_RCR             0x05
+#define DM9000_RSR             0x06
+#define DM9000_ROCR            0x07
+#define DM9000_BPTR            0x08
+#define DM9000_FCTR            0x09
+#define DM9000_FCR             0x0A
+#define DM9000_EPCR            0x0B
+#define DM9000_EPAR            0x0C
+#define DM9000_EPDRL           0x0D
+#define DM9000_EPDRH           0x0E
+#define DM9000_WCR             0x0F
+
+#define DM9000_PAR             0x10
+#define DM9000_MAR             0x16
+
+#define DM9000_GPCR			0x1e
+#define DM9000_GPR             0x1f
+#define DM9000_TRPAL           0x22
+#define DM9000_TRPAH           0x23
+#define DM9000_RWPAL           0x24
+#define DM9000_RWPAH           0x25
+
+#define DM9000_VIDL            0x28
+#define DM9000_VIDH            0x29
+#define DM9000_PIDL            0x2A
+#define DM9000_PIDH            0x2B
+
+#define DM9000_CHIPR           0x2C
+#define DM9000_SMCR            0x2F
+
+#define DM9000_PHY		0x40	/* PHY address 0x01 */
+
+#define DM9000_MRCMDX          0xF0
+#define DM9000_MRCMD           0xF2
+#define DM9000_MRRL            0xF4
+#define DM9000_MRRH            0xF5
+#define DM9000_MWCMDX			0xF6
+#define DM9000_MWCMD           0xF8
+#define DM9000_MWRL            0xFA
+#define DM9000_MWRH            0xFB
+#define DM9000_TXPLL           0xFC
+#define DM9000_TXPLH           0xFD
+#define DM9000_ISR             0xFE
+#define DM9000_IMR             0xFF
+
+#define NCR_EXT_PHY		(1<<7)
+#define NCR_WAKEEN		(1<<6)
+#define NCR_FCOL		(1<<4)
+#define NCR_FDX			(1<<3)
+#define NCR_LBK			(3<<1)
+#define NCR_LBK_INT_MAC		(1<<1)
+#define NCR_LBK_INT_PHY		(2<<1)
+#define NCR_RST			(1<<0)
+
+#define NSR_SPEED		(1<<7)
+#define NSR_LINKST		(1<<6)
+#define NSR_WAKEST		(1<<5)
+#define NSR_TX2END		(1<<3)
+#define NSR_TX1END		(1<<2)
+#define NSR_RXOV		(1<<1)
+
+#define TCR_TJDIS		(1<<6)
+#define TCR_EXCECM		(1<<5)
+#define TCR_PAD_DIS2	(1<<4)
+#define TCR_CRC_DIS2	(1<<3)
+#define TCR_PAD_DIS1	(1<<2)
+#define TCR_CRC_DIS1	(1<<1)
+#define TCR_TXREQ		(1<<0)
+
+#define TSR_TJTO		(1<<7)
+#define TSR_LC			(1<<6)
+#define TSR_NC			(1<<5)
+#define TSR_LCOL		(1<<4)
+#define TSR_COL			(1<<3)
+#define TSR_EC			(1<<2)
+
+#define RCR_WTDIS		(1<<6)
+#define RCR_DIS_LONG	(1<<5)
+#define RCR_DIS_CRC		(1<<4)
+#define RCR_ALL			(1<<3)
+#define RCR_RUNT		(1<<2)
+#define RCR_PRMSC		(1<<1)
+#define RCR_RXEN		(1<<0)
+
+#define RSR_RF			(1<<7)
+#define RSR_MF			(1<<6)
+#define RSR_LCS			(1<<5)
+#define RSR_RWTO		(1<<4)
+#define RSR_PLE			(1<<3)
+#define RSR_AE			(1<<2)
+#define RSR_CE			(1<<1)
+#define RSR_FOE			(1<<0)
+
+#define EPCR_EPOS_PHY		(1<<3)
+#define EPCR_EPOS_EE		(0<<3)
+#define EPCR_ERPRR		(1<<2)
+#define EPCR_ERPRW		(1<<1)
+#define EPCR_ERRE		(1<<0)
+
+#define FCTR_HWOT(ot)	(( ot & 0xf ) << 4 )
+#define FCTR_LWOT(ot)	( ot & 0xf )
+
+#define BPTR_BPHW(x)	((x) << 4)
+#define BPTR_JPT_200US		(0x07)
+#define BPTR_JPT_600US		(0x0f)
+
+#define IMR_PAR			(1<<7)
+#define IMR_ROOM		(1<<3)
+#define IMR_ROM			(1<<2)
+#define IMR_PTM			(1<<1)
+#define IMR_PRM			(1<<0)
+
+#define ISR_ROOS		(1<<3)
+#define ISR_ROS			(1<<2)
+#define ISR_PTS			(1<<1)
+#define ISR_PRS			(1<<0)
+
+#define GPCR_GPIO0_OUT		(1<<0)
+
+#define GPR_PHY_PWROFF		(1<<0)
+
+#endif
diff --git a/marvell/uboot/drivers/net/dnet.c b/marvell/uboot/drivers/net/dnet.c
new file mode 100644
index 0000000..944a0c0
--- /dev/null
+++ b/marvell/uboot/drivers/net/dnet.c
@@ -0,0 +1,392 @@
+/*
+ * Dave Ethernet Controller driver
+ *
+ * Copyright (C) 2008 Dave S.r.l. <www.dave.eu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+
+#ifndef CONFIG_DNET_AUTONEG_TIMEOUT
+#define CONFIG_DNET_AUTONEG_TIMEOUT	5000000	/* default value */
+#endif
+
+#include <net.h>
+#include <malloc.h>
+#include <linux/mii.h>
+
+#include <miiphy.h>
+#include <asm/io.h>
+#include <asm/unaligned.h>
+
+#include "dnet.h"
+
+struct dnet_device {
+	struct dnet_registers	*regs;
+	const struct device	*dev;
+	struct eth_device	netdev;
+	unsigned short		phy_addr;
+};
+
+/* get struct dnet_device from given struct netdev */
+#define to_dnet(_nd) container_of(_nd, struct dnet_device, netdev)
+
+/* function for reading internal MAC register */
+u16 dnet_readw_mac(struct dnet_device *dnet, u16 reg)
+{
+	u16 data_read;
+
+	/* issue a read */
+	writel(reg, &dnet->regs->MACREG_ADDR);
+
+	/* since a read/write op to the MAC is very slow,
+	 * we must wait before reading the data */
+	udelay(1);
+
+	/* read data read from the MAC register */
+	data_read = readl(&dnet->regs->MACREG_DATA);
+
+	/* all done */
+	return data_read;
+}
+
+/* function for writing internal MAC register */
+void dnet_writew_mac(struct dnet_device *dnet, u16 reg, u16 val)
+{
+	/* load data to write */
+	writel(val, &dnet->regs->MACREG_DATA);
+
+	/* issue a write */
+	writel(reg | DNET_INTERNAL_WRITE, &dnet->regs->MACREG_ADDR);
+
+	/* since a read/write op to the MAC is very slow,
+	 * we must wait before exiting */
+	udelay(1);
+}
+
+static void dnet_mdio_write(struct dnet_device *dnet, u8 reg, u16 value)
+{
+	u16 tmp;
+
+	debug(DRIVERNAME "dnet_mdio_write %02x:%02x <- %04x\n",
+			dnet->phy_addr, reg, value);
+
+	while (!(dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG) &
+				DNET_INTERNAL_GMII_MNG_CMD_FIN))
+		;
+
+	/* prepare for a write operation */
+	tmp = (1 << 13);
+
+	/* only 5 bits allowed for register offset */
+	reg &= 0x1f;
+
+	/* prepare reg_value for a write */
+	tmp |= (dnet->phy_addr << 8);
+	tmp |= reg;
+
+	/* write data to write first */
+	dnet_writew_mac(dnet, DNET_INTERNAL_GMII_MNG_DAT_REG, value);
+
+	/* write control word */
+	dnet_writew_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG, tmp);
+
+	while (!(dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG) &
+				DNET_INTERNAL_GMII_MNG_CMD_FIN))
+		;
+}
+
+static u16 dnet_mdio_read(struct dnet_device *dnet, u8 reg)
+{
+	u16 value;
+
+	while (!(dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG) &
+				DNET_INTERNAL_GMII_MNG_CMD_FIN))
+		;
+
+	/* only 5 bits allowed for register offset*/
+	reg &= 0x1f;
+
+	/* prepare reg_value for a read */
+	value = (dnet->phy_addr << 8);
+	value |= reg;
+
+	/* write control word */
+	dnet_writew_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG, value);
+
+	/* wait for end of transfer */
+	while (!(dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG) &
+				DNET_INTERNAL_GMII_MNG_CMD_FIN))
+		;
+
+	value = dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_DAT_REG);
+
+	debug(DRIVERNAME "dnet_mdio_read %02x:%02x <- %04x\n",
+		dnet->phy_addr, reg, value);
+
+	return value;
+}
+
+static int dnet_send(struct eth_device *netdev, void *packet, int length)
+{
+	struct dnet_device *dnet = to_dnet(netdev);
+	int i, wrsz;
+	unsigned int *bufp;
+	unsigned int tx_cmd;
+
+	debug(DRIVERNAME "[%s] Sending %u bytes\n", __func__, length);
+
+	bufp = (unsigned int *) (((u32)packet) & 0xFFFFFFFC);
+	wrsz = (u32)length + 3;
+	wrsz += ((u32)packet) & 0x3;
+	wrsz >>= 2;
+	tx_cmd = ((((unsigned int)(packet)) & 0x03) << 16) | (u32)length;
+
+	/* check if there is enough room for the current frame */
+	if (wrsz < (DNET_FIFO_SIZE - readl(&dnet->regs->TX_FIFO_WCNT))) {
+		for (i = 0; i < wrsz; i++)
+			writel(*bufp++, &dnet->regs->TX_DATA_FIFO);
+		/*
+		 * inform MAC that a packet's written and ready
+		 * to be shipped out
+		 */
+		writel(tx_cmd, &dnet->regs->TX_LEN_FIFO);
+	} else {
+		printf(DRIVERNAME "No free space (actual %d, required %d "
+				"(words))\n", DNET_FIFO_SIZE -
+				readl(&dnet->regs->TX_FIFO_WCNT), wrsz);
+	}
+
+	/* No one cares anyway */
+	return 0;
+}
+
+
+static int dnet_recv(struct eth_device *netdev)
+{
+	struct dnet_device *dnet = to_dnet(netdev);
+	unsigned int *data_ptr;
+	int pkt_len, poll, i;
+	u32 cmd_word;
+
+	debug("Waiting for pkt (polling)\n");
+	poll = 50;
+	while ((readl(&dnet->regs->RX_FIFO_WCNT) >> 16) == 0) {
+		udelay(10);  /* wait 10 usec */
+		if (--poll == 0)
+			return 0;	/* no pkt available */
+	}
+
+	cmd_word = readl(&dnet->regs->RX_LEN_FIFO);
+	pkt_len = cmd_word & 0xFFFF;
+
+	debug("Got pkt with size %d bytes\n", pkt_len);
+
+	if (cmd_word & 0xDF180000)
+		printf("%s packet receive error %x\n", __func__, cmd_word);
+
+	data_ptr = (unsigned int *) NetRxPackets[0];
+
+	for (i = 0; i < (pkt_len + 3) >> 2; i++)
+		*data_ptr++ = readl(&dnet->regs->RX_DATA_FIFO);
+
+	NetReceive(NetRxPackets[0], pkt_len + 5); /* ok + 5 ?? */
+
+	return 0;
+}
+
+static void dnet_set_hwaddr(struct eth_device *netdev)
+{
+	struct dnet_device *dnet = to_dnet(netdev);
+	u16 tmp;
+
+	tmp = get_unaligned_be16(netdev->enetaddr);
+	dnet_writew_mac(dnet, DNET_INTERNAL_MAC_ADDR_0_REG, tmp);
+	tmp = get_unaligned_be16(&netdev->enetaddr[2]);
+	dnet_writew_mac(dnet, DNET_INTERNAL_MAC_ADDR_1_REG, tmp);
+	tmp = get_unaligned_be16(&netdev->enetaddr[4]);
+	dnet_writew_mac(dnet, DNET_INTERNAL_MAC_ADDR_2_REG, tmp);
+}
+
+static void dnet_phy_reset(struct dnet_device *dnet)
+{
+	struct eth_device *netdev = &dnet->netdev;
+	int i;
+	u16 status, adv;
+
+	adv = ADVERTISE_CSMA | ADVERTISE_ALL;
+	dnet_mdio_write(dnet, MII_ADVERTISE, adv);
+	printf("%s: Starting autonegotiation...\n", netdev->name);
+	dnet_mdio_write(dnet, MII_BMCR, (BMCR_ANENABLE
+					 | BMCR_ANRESTART));
+
+	for (i = 0; i < CONFIG_DNET_AUTONEG_TIMEOUT / 100; i++) {
+		status = dnet_mdio_read(dnet, MII_BMSR);
+		if (status & BMSR_ANEGCOMPLETE)
+			break;
+		udelay(100);
+	}
+
+	if (status & BMSR_ANEGCOMPLETE)
+		printf("%s: Autonegotiation complete\n", netdev->name);
+	else
+		printf("%s: Autonegotiation timed out (status=0x%04x)\n",
+		       netdev->name, status);
+}
+
+static int dnet_phy_init(struct dnet_device *dnet)
+{
+	struct eth_device *netdev = &dnet->netdev;
+	u16 phy_id, status, adv, lpa;
+	int media, speed, duplex;
+	int i;
+	u32 ctl_reg;
+
+	/* Find a PHY */
+	for (i = 0; i < 32; i++) {
+		dnet->phy_addr = i;
+		phy_id = dnet_mdio_read(dnet, MII_PHYSID1);
+		if (phy_id != 0xffff) {
+			/* ok we found it */
+			printf("Found PHY at address %d PHYID (%04x:%04x)\n",
+					i, phy_id,
+					dnet_mdio_read(dnet, MII_PHYSID2));
+			break;
+		}
+	}
+
+	/* Check if the PHY is up to snuff... */
+	phy_id = dnet_mdio_read(dnet, MII_PHYSID1);
+	if (phy_id == 0xffff) {
+		printf("%s: No PHY present\n", netdev->name);
+		return -1;
+	}
+
+	status = dnet_mdio_read(dnet, MII_BMSR);
+	if (!(status & BMSR_LSTATUS)) {
+		/* Try to re-negotiate if we don't have link already. */
+		dnet_phy_reset(dnet);
+
+		for (i = 0; i < CONFIG_DNET_AUTONEG_TIMEOUT / 100; i++) {
+			status = dnet_mdio_read(dnet, MII_BMSR);
+			if (status & BMSR_LSTATUS)
+				break;
+			udelay(100);
+		}
+	}
+
+	if (!(status & BMSR_LSTATUS)) {
+		printf("%s: link down (status: 0x%04x)\n",
+		       netdev->name, status);
+		return -1;
+	} else {
+		adv = dnet_mdio_read(dnet, MII_ADVERTISE);
+		lpa = dnet_mdio_read(dnet, MII_LPA);
+		media = mii_nway_result(lpa & adv);
+		speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
+			 ? 1 : 0);
+		duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+		/* 1000BaseT ethernet is not supported */
+		printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
+		       netdev->name,
+		       speed ? "100" : "10",
+		       duplex ? "full" : "half",
+		       lpa);
+
+		ctl_reg = dnet_readw_mac(dnet, DNET_INTERNAL_RXTX_CONTROL_REG);
+
+		if (duplex)
+			ctl_reg &= ~(DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP);
+		else
+			ctl_reg |= DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP;
+
+		dnet_writew_mac(dnet, DNET_INTERNAL_RXTX_CONTROL_REG, ctl_reg);
+
+		return 0;
+	}
+}
+
+static int dnet_init(struct eth_device *netdev, bd_t *bd)
+{
+	struct dnet_device *dnet = to_dnet(netdev);
+	u32 config;
+
+	/*
+	 * dnet_halt should have been called at some point before now,
+	 * so we'll assume the controller is idle.
+	 */
+
+	/* set hardware address */
+	dnet_set_hwaddr(netdev);
+
+	if (dnet_phy_init(dnet) < 0)
+		return -1;
+
+	/* flush rx/tx fifos */
+	writel(DNET_SYS_CTL_RXFIFOFLUSH | DNET_SYS_CTL_TXFIFOFLUSH,
+			&dnet->regs->SYS_CTL);
+	udelay(1000);
+	writel(0, &dnet->regs->SYS_CTL);
+
+	config = dnet_readw_mac(dnet, DNET_INTERNAL_RXTX_CONTROL_REG);
+
+	config |= DNET_INTERNAL_RXTX_CONTROL_RXPAUSE |
+			DNET_INTERNAL_RXTX_CONTROL_RXBROADCAST |
+			DNET_INTERNAL_RXTX_CONTROL_DROPCONTROL |
+			DNET_INTERNAL_RXTX_CONTROL_DISCFXFCS;
+
+	dnet_writew_mac(dnet, DNET_INTERNAL_RXTX_CONTROL_REG, config);
+
+	/* Enable TX and RX */
+	dnet_writew_mac(dnet, DNET_INTERNAL_MODE_REG,
+			DNET_INTERNAL_MODE_RXEN | DNET_INTERNAL_MODE_TXEN);
+
+	return 0;
+}
+
+static void dnet_halt(struct eth_device *netdev)
+{
+	struct dnet_device *dnet = to_dnet(netdev);
+
+	/* Disable TX and RX */
+	dnet_writew_mac(dnet, DNET_INTERNAL_MODE_REG, 0);
+}
+
+int dnet_eth_initialize(int id, void *regs, unsigned int phy_addr)
+{
+	struct dnet_device *dnet;
+	struct eth_device *netdev;
+	unsigned int dev_capa;
+
+	dnet = malloc(sizeof(struct dnet_device));
+	if (!dnet) {
+		printf("Error: Failed to allocate memory for DNET%d\n", id);
+		return -1;
+	}
+	memset(dnet, 0, sizeof(struct dnet_device));
+
+	netdev = &dnet->netdev;
+
+	dnet->regs = (struct dnet_registers *)regs;
+	dnet->phy_addr = phy_addr;
+
+	sprintf(netdev->name, "dnet%d", id);
+	netdev->init = dnet_init;
+	netdev->halt = dnet_halt;
+	netdev->send = dnet_send;
+	netdev->recv = dnet_recv;
+
+	dev_capa = readl(&dnet->regs->VERCAPS) & 0xFFFF;
+	debug("%s: has %smdio, %sirq, %sgigabit, %sdma \n", netdev->name,
+		(dev_capa & DNET_HAS_MDIO) ? "" : "no ",
+		(dev_capa & DNET_HAS_IRQ) ? "" : "no ",
+		(dev_capa & DNET_HAS_GIGABIT) ? "" : "no ",
+		(dev_capa & DNET_HAS_DMA) ? "" : "no ");
+
+	eth_register(netdev);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/dnet.h b/marvell/uboot/drivers/net/dnet.h
new file mode 100644
index 0000000..fdb4fd2
--- /dev/null
+++ b/marvell/uboot/drivers/net/dnet.h
@@ -0,0 +1,166 @@
+/*
+ * Dave Ethernet Controller driver
+ *
+ * Copyright (C) 2008 Dave S.r.l. <www.dave.eu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DRIVERS_DNET_H__
+#define __DRIVERS_DNET_H__
+
+#define DRIVERNAME "dnet"
+
+struct dnet_registers {
+	/* ALL DNET FIFO REGISTERS */
+	u32 RX_LEN_FIFO;
+	u32 RX_DATA_FIFO;
+	u32 TX_LEN_FIFO;
+	u32 TX_DATA_FIFO;
+	u32 pad1[0x3c];
+	/* ALL DNET CONTROL/STATUS REGISTERS */
+	u32 VERCAPS;
+	u32 INTR_SRC;
+	u32 INTR_ENB;
+	u32 RX_STATUS;
+	u32 TX_STATUS;
+	u32 RX_FRAMES_CNT;
+	u32 TX_FRAMES_CNT;
+	u32 RX_FIFO_TH;
+	u32 TX_FIFO_TH;
+	u32 SYS_CTL;
+	u32 PAUSE_TMR;
+	u32 RX_FIFO_WCNT;
+	u32 TX_FIFO_WCNT;
+	u32 pad2[0x33];
+	/* ALL DNET MAC REGISTERS */
+	u32 MACREG_DATA;	/* Mac-Reg Data */
+	u32 MACREG_ADDR;	/* Mac-Reg Addr */
+	u32 pad3[0x3e];
+	/* ALL DNET RX STATISTICS COUNTERS  */
+	u32 RX_PKT_IGNR_CNT;
+	u32 RX_LEN_CHK_ERR_CNT;
+	u32 RX_LNG_FRM_CNT;
+	u32 RX_SHRT_FRM_CNT;
+	u32 RX_IPG_VIOL_CNT;
+	u32 RX_CRC_ERR_CNT;
+	u32 RX_OK_PKT_CNT;
+	u32 RX_CTL_FRM_CNT;
+	u32 RX_PAUSE_FRM_CNT;
+	u32 RX_MULTICAST_CNT;
+	u32 RX_BROADCAST_CNT;
+	u32 RX_VLAN_TAG_CNT;
+	u32 RX_PRE_SHRINK_CNT;
+	u32 RX_DRIB_NIB_CNT;
+	u32 RX_UNSUP_OPCD_CNT;
+	u32 RX_BYTE_CNT;
+	u32 pad4[0x30];
+	/* DNET TX STATISTICS COUNTERS */
+	u32 TX_UNICAST_CNT;
+	u32 TX_PAUSE_FRM_CNT;
+	u32 TX_MULTICAST_CNT;
+	u32 TX_BRDCAST_CNT;
+	u32 TX_VLAN_TAG_CNT;
+	u32 TX_BAD_FCS_CNT;
+	u32 TX_JUMBO_CNT;
+	u32 TX_BYTE_CNT;
+};
+
+/* SOME INTERNAL MAC-CORE REGISTER */
+#define DNET_INTERNAL_MODE_REG			0x0
+#define DNET_INTERNAL_RXTX_CONTROL_REG		0x2
+#define DNET_INTERNAL_MAX_PKT_SIZE_REG		0x4
+#define DNET_INTERNAL_IGP_REG			0x8
+#define DNET_INTERNAL_MAC_ADDR_0_REG		0xa
+#define DNET_INTERNAL_MAC_ADDR_1_REG		0xc
+#define DNET_INTERNAL_MAC_ADDR_2_REG		0xe
+#define DNET_INTERNAL_TX_RX_STS_REG		0x12
+#define DNET_INTERNAL_GMII_MNG_CTL_REG		0x14
+#define DNET_INTERNAL_GMII_MNG_DAT_REG		0x16
+
+#define DNET_INTERNAL_GMII_MNG_CMD_FIN		(1 << 14)
+
+#define DNET_INTERNAL_WRITE			(1 << 31)
+
+/* MAC-CORE REGISTER FIELDS */
+
+/* MAC-CORE MODE REGISTER FIELDS */
+#define DNET_INTERNAL_MODE_GBITEN			(1 << 0)
+#define DNET_INTERNAL_MODE_FCEN				(1 << 1)
+#define DNET_INTERNAL_MODE_RXEN				(1 << 2)
+#define DNET_INTERNAL_MODE_TXEN				(1 << 3)
+
+/* MAC-CORE RXTX CONTROL REGISTER FIELDS */
+#define DNET_INTERNAL_RXTX_CONTROL_RXSHORTFRAME		(1 << 8)
+#define DNET_INTERNAL_RXTX_CONTROL_RXBROADCAST		(1 << 7)
+#define DNET_INTERNAL_RXTX_CONTROL_RXMULTICAST		(1 << 4)
+#define DNET_INTERNAL_RXTX_CONTROL_RXPAUSE		(1 << 3)
+#define DNET_INTERNAL_RXTX_CONTROL_DISTXFCS		(1 << 2)
+#define DNET_INTERNAL_RXTX_CONTROL_DISCFXFCS		(1 << 1)
+#define DNET_INTERNAL_RXTX_CONTROL_ENPROMISC		(1 << 0)
+#define DNET_INTERNAL_RXTX_CONTROL_DROPCONTROL		(1 << 6)
+#define DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP	(1 << 5)
+
+/* SYSTEM CONTROL REGISTER FIELDS */
+#define DNET_SYS_CTL_IGNORENEXTPKT			(1 << 0)
+#define DNET_SYS_CTL_SENDPAUSE				(1 << 2)
+#define DNET_SYS_CTL_RXFIFOFLUSH			(1 << 3)
+#define DNET_SYS_CTL_TXFIFOFLUSH			(1 << 4)
+
+/* TX STATUS REGISTER FIELDS */
+#define DNET_TX_STATUS_FIFO_ALMOST_EMPTY		(1 << 2)
+#define DNET_TX_STATUS_FIFO_ALMOST_FULL			(1 << 1)
+
+/* INTERRUPT SOURCE REGISTER FIELDS */
+#define DNET_INTR_SRC_TX_PKTSENT			(1 << 0)
+#define DNET_INTR_SRC_TX_FIFOAF				(1 << 1)
+#define DNET_INTR_SRC_TX_FIFOAE				(1 << 2)
+#define DNET_INTR_SRC_TX_DISCFRM			(1 << 3)
+#define DNET_INTR_SRC_TX_FIFOFULL			(1 << 4)
+#define DNET_INTR_SRC_RX_CMDFIFOAF			(1 << 8)
+#define DNET_INTR_SRC_RX_CMDFIFOFF			(1 << 9)
+#define DNET_INTR_SRC_RX_DATAFIFOFF			(1 << 10)
+#define DNET_INTR_SRC_TX_SUMMARY			(1 << 16)
+#define DNET_INTR_SRC_RX_SUMMARY			(1 << 17)
+#define DNET_INTR_SRC_PHY				(1 << 19)
+
+/* INTERRUPT ENABLE REGISTER FIELDS */
+#define DNET_INTR_ENB_TX_PKTSENT			(1 << 0)
+#define DNET_INTR_ENB_TX_FIFOAF				(1 << 1)
+#define DNET_INTR_ENB_TX_FIFOAE				(1 << 2)
+#define DNET_INTR_ENB_TX_DISCFRM			(1 << 3)
+#define DNET_INTR_ENB_TX_FIFOFULL			(1 << 4)
+#define DNET_INTR_ENB_RX_PKTRDY				(1 << 8)
+#define DNET_INTR_ENB_RX_FIFOAF				(1 << 9)
+#define DNET_INTR_ENB_RX_FIFOERR			(1 << 10)
+#define DNET_INTR_ENB_RX_ERROR				(1 << 11)
+#define DNET_INTR_ENB_RX_FIFOFULL			(1 << 12)
+#define DNET_INTR_ENB_RX_FIFOAE				(1 << 13)
+#define DNET_INTR_ENB_TX_SUMMARY			(1 << 16)
+#define DNET_INTR_ENB_RX_SUMMARY			(1 << 17)
+#define DNET_INTR_ENB_GLOBAL_ENABLE			(1 << 18)
+
+/*
+ * Capabilities. Used by the driver to know the capabilities that
+ * the ethernet controller inside the FPGA have.
+ */
+
+#define DNET_HAS_MDIO		(1 << 0)
+#define DNET_HAS_IRQ		(1 << 1)
+#define DNET_HAS_GIGABIT	(1 << 2)
+#define DNET_HAS_DMA		(1 << 3)
+
+#define DNET_HAS_MII		(1 << 4) /* or GMII */
+#define DNET_HAS_RMII		(1 << 5) /* or RGMII */
+
+#define DNET_CAPS_MASK		0xFFFF
+
+#define DNET_FIFO_SIZE		2048 /* 2K x 32 bit */
+#define DNET_FIFO_TX_DATA_AF_TH	(DNET_FIFO_SIZE - 384) /* 384 = 1536 / 4 */
+#define DNET_FIFO_TX_DATA_AE_TH	(384)
+
+#define DNET_FIFO_RX_CMD_AF_TH	(1 << 16) /* just one frame inside the FIFO */
+
+#endif
diff --git a/marvell/uboot/drivers/net/e1000.c b/marvell/uboot/drivers/net/e1000.c
new file mode 100644
index 0000000..9a66e68
--- /dev/null
+++ b/marvell/uboot/drivers/net/e1000.c
@@ -0,0 +1,5308 @@
+/**************************************************************************
+Intel Pro 1000 for ppcboot/das-u-boot
+Drivers are port from Intel's Linux driver e1000-4.3.15
+and from Etherboot pro 1000 driver by mrakes at vivato dot net
+tested on both gig copper and gig fiber boards
+***************************************************************************/
+/*******************************************************************************
+
+
+  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+
+ * SPDX-License-Identifier:	GPL-2.0+
+
+  Contact Information:
+  Linux NICS <linux.nics@intel.com>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+/*
+ *  Copyright (C) Archway Digital Solutions.
+ *
+ *  written by Chrsitopher Li <cli at arcyway dot com> or <chrisl at gnuchina dot org>
+ *  2/9/2002
+ *
+ *  Copyright (C) Linux Networx.
+ *  Massive upgrade to work with the new intel gigabit NICs.
+ *  <ebiederman at lnxi dot com>
+ *
+ *  Copyright 2011 Freescale Semiconductor, Inc.
+ */
+
+#include "e1000.h"
+
+#define TOUT_LOOP   100000
+
+#define virt_to_bus(devno, v)	pci_virt_to_mem(devno, (void *) (v))
+#define bus_to_phys(devno, a)	pci_mem_to_phys(devno, a)
+
+#define E1000_DEFAULT_PCI_PBA	0x00000030
+#define E1000_DEFAULT_PCIE_PBA	0x000a0026
+
+/* NIC specific static variables go here */
+
+static char tx_pool[128 + 16];
+static char rx_pool[128 + 16];
+static char packet[2096];
+
+static struct e1000_tx_desc *tx_base;
+static struct e1000_rx_desc *rx_base;
+
+static int tx_tail;
+static int rx_tail, rx_last;
+
+static struct pci_device_id e1000_supported[] = {
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82542},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_FIBER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_COPPER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_COPPER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_FIBER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_COPPER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_LOM},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_COPPER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545GM_COPPER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_COPPER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_COPPER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541ER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541GI_LF},
+	/* E1000 PCIe card */
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_COPPER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_FIBER      },
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES     },
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571PT_QUAD_COPPER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_FIBER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER_LOWPROFILE},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_DUAL},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_QUAD},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_COPPER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_FIBER},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_SERDES},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E_IAMT},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573L},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82574L},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_QUAD_COPPER_KSP3},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_DPT},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_DPT},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_SPT},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_SPT},
+	{}
+};
+
+/* Function forward declarations */
+static int e1000_setup_link(struct eth_device *nic);
+static int e1000_setup_fiber_link(struct eth_device *nic);
+static int e1000_setup_copper_link(struct eth_device *nic);
+static int e1000_phy_setup_autoneg(struct e1000_hw *hw);
+static void e1000_config_collision_dist(struct e1000_hw *hw);
+static int e1000_config_mac_to_phy(struct e1000_hw *hw);
+static int e1000_config_fc_after_link_up(struct e1000_hw *hw);
+static int e1000_check_for_link(struct eth_device *nic);
+static int e1000_wait_autoneg(struct e1000_hw *hw);
+static int e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed,
+				       uint16_t * duplex);
+static int e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,
+			      uint16_t * phy_data);
+static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,
+			       uint16_t phy_data);
+static int32_t e1000_phy_hw_reset(struct e1000_hw *hw);
+static int e1000_phy_reset(struct e1000_hw *hw);
+static int e1000_detect_gig_phy(struct e1000_hw *hw);
+static void e1000_set_media_type(struct e1000_hw *hw);
+
+static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
+static int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
+
+#ifndef CONFIG_E1000_NO_NVM
+static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset,
+		uint16_t words,
+		uint16_t *data);
+/******************************************************************************
+ * Raises the EEPROM's clock input.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * eecd - EECD's current value
+ *****************************************************************************/
+void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t * eecd)
+{
+	/* Raise the clock input to the EEPROM (by setting the SK bit), and then
+	 * wait 50 microseconds.
+	 */
+	*eecd = *eecd | E1000_EECD_SK;
+	E1000_WRITE_REG(hw, EECD, *eecd);
+	E1000_WRITE_FLUSH(hw);
+	udelay(50);
+}
+
+/******************************************************************************
+ * Lowers the EEPROM's clock input.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * eecd - EECD's current value
+ *****************************************************************************/
+void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t * eecd)
+{
+	/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
+	 * wait 50 microseconds.
+	 */
+	*eecd = *eecd & ~E1000_EECD_SK;
+	E1000_WRITE_REG(hw, EECD, *eecd);
+	E1000_WRITE_FLUSH(hw);
+	udelay(50);
+}
+
+/******************************************************************************
+ * Shift data bits out to the EEPROM.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * data - data to send to the EEPROM
+ * count - number of bits to shift out
+ *****************************************************************************/
+static void
+e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count)
+{
+	uint32_t eecd;
+	uint32_t mask;
+
+	/* We need to shift "count" bits out to the EEPROM. So, value in the
+	 * "data" parameter will be shifted out to the EEPROM one bit at a time.
+	 * In order to do this, "data" must be broken down into bits.
+	 */
+	mask = 0x01 << (count - 1);
+	eecd = E1000_READ_REG(hw, EECD);
+	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
+	do {
+		/* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
+		 * and then raising and then lowering the clock (the SK bit controls
+		 * the clock input to the EEPROM).  A "0" is shifted out to the EEPROM
+		 * by setting "DI" to "0" and then raising and then lowering the clock.
+		 */
+		eecd &= ~E1000_EECD_DI;
+
+		if (data & mask)
+			eecd |= E1000_EECD_DI;
+
+		E1000_WRITE_REG(hw, EECD, eecd);
+		E1000_WRITE_FLUSH(hw);
+
+		udelay(50);
+
+		e1000_raise_ee_clk(hw, &eecd);
+		e1000_lower_ee_clk(hw, &eecd);
+
+		mask = mask >> 1;
+
+	} while (mask);
+
+	/* We leave the "DI" bit set to "0" when we leave this routine. */
+	eecd &= ~E1000_EECD_DI;
+	E1000_WRITE_REG(hw, EECD, eecd);
+}
+
+/******************************************************************************
+ * Shift data bits in from the EEPROM
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static uint16_t
+e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count)
+{
+	uint32_t eecd;
+	uint32_t i;
+	uint16_t data;
+
+	/* In order to read a register from the EEPROM, we need to shift 'count'
+	 * bits in from the EEPROM. Bits are "shifted in" by raising the clock
+	 * input to the EEPROM (setting the SK bit), and then reading the
+	 * value of the "DO" bit.  During this "shifting in" process the
+	 * "DI" bit should always be clear.
+	 */
+
+	eecd = E1000_READ_REG(hw, EECD);
+
+	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
+	data = 0;
+
+	for (i = 0; i < count; i++) {
+		data = data << 1;
+		e1000_raise_ee_clk(hw, &eecd);
+
+		eecd = E1000_READ_REG(hw, EECD);
+
+		eecd &= ~(E1000_EECD_DI);
+		if (eecd & E1000_EECD_DO)
+			data |= 1;
+
+		e1000_lower_ee_clk(hw, &eecd);
+	}
+
+	return data;
+}
+
+/******************************************************************************
+ * Returns EEPROM to a "standby" state
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+void e1000_standby_eeprom(struct e1000_hw *hw)
+{
+	struct e1000_eeprom_info *eeprom = &hw->eeprom;
+	uint32_t eecd;
+
+	eecd = E1000_READ_REG(hw, EECD);
+
+	if (eeprom->type == e1000_eeprom_microwire) {
+		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
+		E1000_WRITE_REG(hw, EECD, eecd);
+		E1000_WRITE_FLUSH(hw);
+		udelay(eeprom->delay_usec);
+
+		/* Clock high */
+		eecd |= E1000_EECD_SK;
+		E1000_WRITE_REG(hw, EECD, eecd);
+		E1000_WRITE_FLUSH(hw);
+		udelay(eeprom->delay_usec);
+
+		/* Select EEPROM */
+		eecd |= E1000_EECD_CS;
+		E1000_WRITE_REG(hw, EECD, eecd);
+		E1000_WRITE_FLUSH(hw);
+		udelay(eeprom->delay_usec);
+
+		/* Clock low */
+		eecd &= ~E1000_EECD_SK;
+		E1000_WRITE_REG(hw, EECD, eecd);
+		E1000_WRITE_FLUSH(hw);
+		udelay(eeprom->delay_usec);
+	} else if (eeprom->type == e1000_eeprom_spi) {
+		/* Toggle CS to flush commands */
+		eecd |= E1000_EECD_CS;
+		E1000_WRITE_REG(hw, EECD, eecd);
+		E1000_WRITE_FLUSH(hw);
+		udelay(eeprom->delay_usec);
+		eecd &= ~E1000_EECD_CS;
+		E1000_WRITE_REG(hw, EECD, eecd);
+		E1000_WRITE_FLUSH(hw);
+		udelay(eeprom->delay_usec);
+	}
+}
+
+/***************************************************************************
+* Description:     Determines if the onboard NVM is FLASH or EEPROM.
+*
+* hw - Struct containing variables accessed by shared code
+****************************************************************************/
+static bool e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw)
+{
+	uint32_t eecd = 0;
+
+	DEBUGFUNC();
+
+	if (hw->mac_type == e1000_ich8lan)
+		return false;
+
+	if (hw->mac_type == e1000_82573 || hw->mac_type == e1000_82574) {
+		eecd = E1000_READ_REG(hw, EECD);
+
+		/* Isolate bits 15 & 16 */
+		eecd = ((eecd >> 15) & 0x03);
+
+		/* If both bits are set, device is Flash type */
+		if (eecd == 0x03)
+			return false;
+	}
+	return true;
+}
+
+/******************************************************************************
+ * Prepares EEPROM for access
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
+ * function should be called before issuing a command to the EEPROM.
+ *****************************************************************************/
+int32_t e1000_acquire_eeprom(struct e1000_hw *hw)
+{
+	struct e1000_eeprom_info *eeprom = &hw->eeprom;
+	uint32_t eecd, i = 0;
+
+	DEBUGFUNC();
+
+	if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM))
+		return -E1000_ERR_SWFW_SYNC;
+	eecd = E1000_READ_REG(hw, EECD);
+
+	if (hw->mac_type != e1000_82573 || hw->mac_type != e1000_82574) {
+		/* Request EEPROM Access */
+		if (hw->mac_type > e1000_82544) {
+			eecd |= E1000_EECD_REQ;
+			E1000_WRITE_REG(hw, EECD, eecd);
+			eecd = E1000_READ_REG(hw, EECD);
+			while ((!(eecd & E1000_EECD_GNT)) &&
+				(i < E1000_EEPROM_GRANT_ATTEMPTS)) {
+				i++;
+				udelay(5);
+				eecd = E1000_READ_REG(hw, EECD);
+			}
+			if (!(eecd & E1000_EECD_GNT)) {
+				eecd &= ~E1000_EECD_REQ;
+				E1000_WRITE_REG(hw, EECD, eecd);
+				DEBUGOUT("Could not acquire EEPROM grant\n");
+				return -E1000_ERR_EEPROM;
+			}
+		}
+	}
+
+	/* Setup EEPROM for Read/Write */
+
+	if (eeprom->type == e1000_eeprom_microwire) {
+		/* Clear SK and DI */
+		eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
+		E1000_WRITE_REG(hw, EECD, eecd);
+
+		/* Set CS */
+		eecd |= E1000_EECD_CS;
+		E1000_WRITE_REG(hw, EECD, eecd);
+	} else if (eeprom->type == e1000_eeprom_spi) {
+		/* Clear SK and CS */
+		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
+		E1000_WRITE_REG(hw, EECD, eecd);
+		udelay(1);
+	}
+
+	return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Sets up eeprom variables in the hw struct.  Must be called after mac_type
+ * is configured.  Additionally, if this is ICH8, the flash controller GbE
+ * registers must be mapped, or this will crash.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static int32_t e1000_init_eeprom_params(struct e1000_hw *hw)
+{
+	struct e1000_eeprom_info *eeprom = &hw->eeprom;
+	uint32_t eecd = E1000_READ_REG(hw, EECD);
+	int32_t ret_val = E1000_SUCCESS;
+	uint16_t eeprom_size;
+
+	DEBUGFUNC();
+
+	switch (hw->mac_type) {
+	case e1000_82542_rev2_0:
+	case e1000_82542_rev2_1:
+	case e1000_82543:
+	case e1000_82544:
+		eeprom->type = e1000_eeprom_microwire;
+		eeprom->word_size = 64;
+		eeprom->opcode_bits = 3;
+		eeprom->address_bits = 6;
+		eeprom->delay_usec = 50;
+		eeprom->use_eerd = false;
+		eeprom->use_eewr = false;
+	break;
+	case e1000_82540:
+	case e1000_82545:
+	case e1000_82545_rev_3:
+	case e1000_82546:
+	case e1000_82546_rev_3:
+		eeprom->type = e1000_eeprom_microwire;
+		eeprom->opcode_bits = 3;
+		eeprom->delay_usec = 50;
+		if (eecd & E1000_EECD_SIZE) {
+			eeprom->word_size = 256;
+			eeprom->address_bits = 8;
+		} else {
+			eeprom->word_size = 64;
+			eeprom->address_bits = 6;
+		}
+		eeprom->use_eerd = false;
+		eeprom->use_eewr = false;
+		break;
+	case e1000_82541:
+	case e1000_82541_rev_2:
+	case e1000_82547:
+	case e1000_82547_rev_2:
+		if (eecd & E1000_EECD_TYPE) {
+			eeprom->type = e1000_eeprom_spi;
+			eeprom->opcode_bits = 8;
+			eeprom->delay_usec = 1;
+			if (eecd & E1000_EECD_ADDR_BITS) {
+				eeprom->page_size = 32;
+				eeprom->address_bits = 16;
+			} else {
+				eeprom->page_size = 8;
+				eeprom->address_bits = 8;
+			}
+		} else {
+			eeprom->type = e1000_eeprom_microwire;
+			eeprom->opcode_bits = 3;
+			eeprom->delay_usec = 50;
+			if (eecd & E1000_EECD_ADDR_BITS) {
+				eeprom->word_size = 256;
+				eeprom->address_bits = 8;
+			} else {
+				eeprom->word_size = 64;
+				eeprom->address_bits = 6;
+			}
+		}
+		eeprom->use_eerd = false;
+		eeprom->use_eewr = false;
+		break;
+	case e1000_82571:
+	case e1000_82572:
+		eeprom->type = e1000_eeprom_spi;
+		eeprom->opcode_bits = 8;
+		eeprom->delay_usec = 1;
+		if (eecd & E1000_EECD_ADDR_BITS) {
+			eeprom->page_size = 32;
+			eeprom->address_bits = 16;
+		} else {
+			eeprom->page_size = 8;
+			eeprom->address_bits = 8;
+		}
+		eeprom->use_eerd = false;
+		eeprom->use_eewr = false;
+		break;
+	case e1000_82573:
+	case e1000_82574:
+		eeprom->type = e1000_eeprom_spi;
+		eeprom->opcode_bits = 8;
+		eeprom->delay_usec = 1;
+		if (eecd & E1000_EECD_ADDR_BITS) {
+			eeprom->page_size = 32;
+			eeprom->address_bits = 16;
+		} else {
+			eeprom->page_size = 8;
+			eeprom->address_bits = 8;
+		}
+		eeprom->use_eerd = true;
+		eeprom->use_eewr = true;
+		if (e1000_is_onboard_nvm_eeprom(hw) == false) {
+			eeprom->type = e1000_eeprom_flash;
+			eeprom->word_size = 2048;
+
+		/* Ensure that the Autonomous FLASH update bit is cleared due to
+		 * Flash update issue on parts which use a FLASH for NVM. */
+			eecd &= ~E1000_EECD_AUPDEN;
+			E1000_WRITE_REG(hw, EECD, eecd);
+		}
+		break;
+	case e1000_80003es2lan:
+		eeprom->type = e1000_eeprom_spi;
+		eeprom->opcode_bits = 8;
+		eeprom->delay_usec = 1;
+		if (eecd & E1000_EECD_ADDR_BITS) {
+			eeprom->page_size = 32;
+			eeprom->address_bits = 16;
+		} else {
+			eeprom->page_size = 8;
+			eeprom->address_bits = 8;
+		}
+		eeprom->use_eerd = true;
+		eeprom->use_eewr = false;
+		break;
+
+	/* ich8lan does not support currently. if needed, please
+	 * add corresponding code and functions.
+	 */
+#if 0
+	case e1000_ich8lan:
+		{
+		int32_t  i = 0;
+
+		eeprom->type = e1000_eeprom_ich8;
+		eeprom->use_eerd = false;
+		eeprom->use_eewr = false;
+		eeprom->word_size = E1000_SHADOW_RAM_WORDS;
+		uint32_t flash_size = E1000_READ_ICH_FLASH_REG(hw,
+				ICH_FLASH_GFPREG);
+		/* Zero the shadow RAM structure. But don't load it from NVM
+		 * so as to save time for driver init */
+		if (hw->eeprom_shadow_ram != NULL) {
+			for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
+				hw->eeprom_shadow_ram[i].modified = false;
+				hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
+			}
+		}
+
+		hw->flash_base_addr = (flash_size & ICH_GFPREG_BASE_MASK) *
+				ICH_FLASH_SECTOR_SIZE;
+
+		hw->flash_bank_size = ((flash_size >> 16)
+				& ICH_GFPREG_BASE_MASK) + 1;
+		hw->flash_bank_size -= (flash_size & ICH_GFPREG_BASE_MASK);
+
+		hw->flash_bank_size *= ICH_FLASH_SECTOR_SIZE;
+
+		hw->flash_bank_size /= 2 * sizeof(uint16_t);
+		break;
+		}
+#endif
+	default:
+		break;
+	}
+
+	if (eeprom->type == e1000_eeprom_spi) {
+		/* eeprom_size will be an enum [0..8] that maps
+		 * to eeprom sizes 128B to
+		 * 32KB (incremented by powers of 2).
+		 */
+		if (hw->mac_type <= e1000_82547_rev_2) {
+			/* Set to default value for initial eeprom read. */
+			eeprom->word_size = 64;
+			ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1,
+					&eeprom_size);
+			if (ret_val)
+				return ret_val;
+			eeprom_size = (eeprom_size & EEPROM_SIZE_MASK)
+				>> EEPROM_SIZE_SHIFT;
+			/* 256B eeprom size was not supported in earlier
+			 * hardware, so we bump eeprom_size up one to
+			 * ensure that "1" (which maps to 256B) is never
+			 * the result used in the shifting logic below. */
+			if (eeprom_size)
+				eeprom_size++;
+		} else {
+			eeprom_size = (uint16_t)((eecd &
+				E1000_EECD_SIZE_EX_MASK) >>
+				E1000_EECD_SIZE_EX_SHIFT);
+		}
+
+		eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT);
+	}
+	return ret_val;
+}
+
+/******************************************************************************
+ * Polls the status bit (bit 1) of the EERD to determine when the read is done.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static int32_t
+e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
+{
+	uint32_t attempts = 100000;
+	uint32_t i, reg = 0;
+	int32_t done = E1000_ERR_EEPROM;
+
+	for (i = 0; i < attempts; i++) {
+		if (eerd == E1000_EEPROM_POLL_READ)
+			reg = E1000_READ_REG(hw, EERD);
+		else
+			reg = E1000_READ_REG(hw, EEWR);
+
+		if (reg & E1000_EEPROM_RW_REG_DONE) {
+			done = E1000_SUCCESS;
+			break;
+		}
+		udelay(5);
+	}
+
+	return done;
+}
+
+/******************************************************************************
+ * Reads a 16 bit word from the EEPROM using the EERD register.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * offset - offset of  word in the EEPROM to read
+ * data - word read from the EEPROM
+ * words - number of words to read
+ *****************************************************************************/
+static int32_t
+e1000_read_eeprom_eerd(struct e1000_hw *hw,
+			uint16_t offset,
+			uint16_t words,
+			uint16_t *data)
+{
+	uint32_t i, eerd = 0;
+	int32_t error = 0;
+
+	for (i = 0; i < words; i++) {
+		eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) +
+			E1000_EEPROM_RW_REG_START;
+
+		E1000_WRITE_REG(hw, EERD, eerd);
+		error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ);
+
+		if (error)
+			break;
+		data[i] = (E1000_READ_REG(hw, EERD) >>
+				E1000_EEPROM_RW_REG_DATA);
+
+	}
+
+	return error;
+}
+
+void e1000_release_eeprom(struct e1000_hw *hw)
+{
+	uint32_t eecd;
+
+	DEBUGFUNC();
+
+	eecd = E1000_READ_REG(hw, EECD);
+
+	if (hw->eeprom.type == e1000_eeprom_spi) {
+		eecd |= E1000_EECD_CS;  /* Pull CS high */
+		eecd &= ~E1000_EECD_SK; /* Lower SCK */
+
+		E1000_WRITE_REG(hw, EECD, eecd);
+
+		udelay(hw->eeprom.delay_usec);
+	} else if (hw->eeprom.type == e1000_eeprom_microwire) {
+		/* cleanup eeprom */
+
+		/* CS on Microwire is active-high */
+		eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
+
+		E1000_WRITE_REG(hw, EECD, eecd);
+
+		/* Rising edge of clock */
+		eecd |= E1000_EECD_SK;
+		E1000_WRITE_REG(hw, EECD, eecd);
+		E1000_WRITE_FLUSH(hw);
+		udelay(hw->eeprom.delay_usec);
+
+		/* Falling edge of clock */
+		eecd &= ~E1000_EECD_SK;
+		E1000_WRITE_REG(hw, EECD, eecd);
+		E1000_WRITE_FLUSH(hw);
+		udelay(hw->eeprom.delay_usec);
+	}
+
+	/* Stop requesting EEPROM access */
+	if (hw->mac_type > e1000_82544) {
+		eecd &= ~E1000_EECD_REQ;
+		E1000_WRITE_REG(hw, EECD, eecd);
+	}
+}
+/******************************************************************************
+ * Reads a 16 bit word from the EEPROM.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static int32_t
+e1000_spi_eeprom_ready(struct e1000_hw *hw)
+{
+	uint16_t retry_count = 0;
+	uint8_t spi_stat_reg;
+
+	DEBUGFUNC();
+
+	/* Read "Status Register" repeatedly until the LSB is cleared.  The
+	 * EEPROM will signal that the command has been completed by clearing
+	 * bit 0 of the internal status register.  If it's not cleared within
+	 * 5 milliseconds, then error out.
+	 */
+	retry_count = 0;
+	do {
+		e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
+			hw->eeprom.opcode_bits);
+		spi_stat_reg = (uint8_t)e1000_shift_in_ee_bits(hw, 8);
+		if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
+			break;
+
+		udelay(5);
+		retry_count += 5;
+
+		e1000_standby_eeprom(hw);
+	} while (retry_count < EEPROM_MAX_RETRY_SPI);
+
+	/* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
+	 * only 0-5mSec on 5V devices)
+	 */
+	if (retry_count >= EEPROM_MAX_RETRY_SPI) {
+		DEBUGOUT("SPI EEPROM Status error\n");
+		return -E1000_ERR_EEPROM;
+	}
+
+	return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Reads a 16 bit word from the EEPROM.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * offset - offset of  word in the EEPROM to read
+ * data - word read from the EEPROM
+ *****************************************************************************/
+static int32_t
+e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset,
+		uint16_t words, uint16_t *data)
+{
+	struct e1000_eeprom_info *eeprom = &hw->eeprom;
+	uint32_t i = 0;
+
+	DEBUGFUNC();
+
+	/* If eeprom is not yet detected, do so now */
+	if (eeprom->word_size == 0)
+		e1000_init_eeprom_params(hw);
+
+	/* A check for invalid values:  offset too large, too many words,
+	 * and not enough words.
+	 */
+	if ((offset >= eeprom->word_size) ||
+		(words > eeprom->word_size - offset) ||
+		(words == 0)) {
+		DEBUGOUT("\"words\" parameter out of bounds."
+			"Words = %d, size = %d\n", offset, eeprom->word_size);
+		return -E1000_ERR_EEPROM;
+	}
+
+	/* EEPROM's that don't use EERD to read require us to bit-bang the SPI
+	 * directly. In this case, we need to acquire the EEPROM so that
+	 * FW or other port software does not interrupt.
+	 */
+	if (e1000_is_onboard_nvm_eeprom(hw) == true &&
+		hw->eeprom.use_eerd == false) {
+
+		/* Prepare the EEPROM for bit-bang reading */
+		if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+			return -E1000_ERR_EEPROM;
+	}
+
+	/* Eerd register EEPROM access requires no eeprom aquire/release */
+	if (eeprom->use_eerd == true)
+		return e1000_read_eeprom_eerd(hw, offset, words, data);
+
+	/* ich8lan does not support currently. if needed, please
+	 * add corresponding code and functions.
+	 */
+#if 0
+	/* ICH EEPROM access is done via the ICH flash controller */
+	if (eeprom->type == e1000_eeprom_ich8)
+		return e1000_read_eeprom_ich8(hw, offset, words, data);
+#endif
+	/* Set up the SPI or Microwire EEPROM for bit-bang reading.  We have
+	 * acquired the EEPROM at this point, so any returns should relase it */
+	if (eeprom->type == e1000_eeprom_spi) {
+		uint16_t word_in;
+		uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
+
+		if (e1000_spi_eeprom_ready(hw)) {
+			e1000_release_eeprom(hw);
+			return -E1000_ERR_EEPROM;
+		}
+
+		e1000_standby_eeprom(hw);
+
+		/* Some SPI eeproms use the 8th address bit embedded in
+		 * the opcode */
+		if ((eeprom->address_bits == 8) && (offset >= 128))
+			read_opcode |= EEPROM_A8_OPCODE_SPI;
+
+		/* Send the READ command (opcode + addr)  */
+		e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
+		e1000_shift_out_ee_bits(hw, (uint16_t)(offset*2),
+				eeprom->address_bits);
+
+		/* Read the data.  The address of the eeprom internally
+		 * increments with each byte (spi) being read, saving on the
+		 * overhead of eeprom setup and tear-down.  The address
+		 * counter will roll over if reading beyond the size of
+		 * the eeprom, thus allowing the entire memory to be read
+		 * starting from any offset. */
+		for (i = 0; i < words; i++) {
+			word_in = e1000_shift_in_ee_bits(hw, 16);
+			data[i] = (word_in >> 8) | (word_in << 8);
+		}
+	} else if (eeprom->type == e1000_eeprom_microwire) {
+		for (i = 0; i < words; i++) {
+			/* Send the READ command (opcode + addr)  */
+			e1000_shift_out_ee_bits(hw,
+				EEPROM_READ_OPCODE_MICROWIRE,
+				eeprom->opcode_bits);
+			e1000_shift_out_ee_bits(hw, (uint16_t)(offset + i),
+				eeprom->address_bits);
+
+			/* Read the data.  For microwire, each word requires
+			 * the overhead of eeprom setup and tear-down. */
+			data[i] = e1000_shift_in_ee_bits(hw, 16);
+			e1000_standby_eeprom(hw);
+		}
+	}
+
+	/* End this read operation */
+	e1000_release_eeprom(hw);
+
+	return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Verifies that the EEPROM has a valid checksum
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Reads the first 64 16 bit words of the EEPROM and sums the values read.
+ * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
+ * valid.
+ *****************************************************************************/
+static int e1000_validate_eeprom_checksum(struct e1000_hw *hw)
+{
+	uint16_t i, checksum, checksum_reg, *buf;
+
+	DEBUGFUNC();
+
+	/* Allocate a temporary buffer */
+	buf = malloc(sizeof(buf[0]) * (EEPROM_CHECKSUM_REG + 1));
+	if (!buf) {
+		E1000_ERR(hw->nic, "Unable to allocate EEPROM buffer!\n");
+		return -E1000_ERR_EEPROM;
+	}
+
+	/* Read the EEPROM */
+	if (e1000_read_eeprom(hw, 0, EEPROM_CHECKSUM_REG + 1, buf) < 0) {
+		E1000_ERR(hw->nic, "Unable to read EEPROM!\n");
+		return -E1000_ERR_EEPROM;
+	}
+
+	/* Compute the checksum */
+	checksum = 0;
+	for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
+		checksum += buf[i];
+	checksum = ((uint16_t)EEPROM_SUM) - checksum;
+	checksum_reg = buf[i];
+
+	/* Verify it! */
+	if (checksum == checksum_reg)
+		return 0;
+
+	/* Hrm, verification failed, print an error */
+	E1000_ERR(hw->nic, "EEPROM checksum is incorrect!\n");
+	E1000_ERR(hw->nic, "  ...register was 0x%04hx, calculated 0x%04hx\n",
+			checksum_reg, checksum);
+
+	return -E1000_ERR_EEPROM;
+}
+#endif /* CONFIG_E1000_NO_NVM */
+
+/*****************************************************************************
+ * Set PHY to class A mode
+ * Assumes the following operations will follow to enable the new class mode.
+ *  1. Do a PHY soft reset
+ *  2. Restart auto-negotiation or force link.
+ *
+ * hw - Struct containing variables accessed by shared code
+ ****************************************************************************/
+static int32_t
+e1000_set_phy_mode(struct e1000_hw *hw)
+{
+#ifndef CONFIG_E1000_NO_NVM
+	int32_t ret_val;
+	uint16_t eeprom_data;
+
+	DEBUGFUNC();
+
+	if ((hw->mac_type == e1000_82545_rev_3) &&
+		(hw->media_type == e1000_media_type_copper)) {
+		ret_val = e1000_read_eeprom(hw, EEPROM_PHY_CLASS_WORD,
+				1, &eeprom_data);
+		if (ret_val)
+			return ret_val;
+
+		if ((eeprom_data != EEPROM_RESERVED_WORD) &&
+			(eeprom_data & EEPROM_PHY_CLASS_A)) {
+			ret_val = e1000_write_phy_reg(hw,
+					M88E1000_PHY_PAGE_SELECT, 0x000B);
+			if (ret_val)
+				return ret_val;
+			ret_val = e1000_write_phy_reg(hw,
+					M88E1000_PHY_GEN_CONTROL, 0x8104);
+			if (ret_val)
+				return ret_val;
+
+			hw->phy_reset_disable = false;
+		}
+	}
+#endif
+	return E1000_SUCCESS;
+}
+
+#ifndef CONFIG_E1000_NO_NVM
+/***************************************************************************
+ *
+ * Obtaining software semaphore bit (SMBI) before resetting PHY.
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * returns: - E1000_ERR_RESET if fail to obtain semaphore.
+ *            E1000_SUCCESS at any other case.
+ *
+ ***************************************************************************/
+static int32_t
+e1000_get_software_semaphore(struct e1000_hw *hw)
+{
+	 int32_t timeout = hw->eeprom.word_size + 1;
+	 uint32_t swsm;
+
+	DEBUGFUNC();
+
+	if (hw->mac_type != e1000_80003es2lan)
+		return E1000_SUCCESS;
+
+	while (timeout) {
+		swsm = E1000_READ_REG(hw, SWSM);
+		/* If SMBI bit cleared, it is now set and we hold
+		 * the semaphore */
+		if (!(swsm & E1000_SWSM_SMBI))
+			break;
+		mdelay(1);
+		timeout--;
+	}
+
+	if (!timeout) {
+		DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
+		return -E1000_ERR_RESET;
+	}
+
+	return E1000_SUCCESS;
+}
+#endif
+
+/***************************************************************************
+ * This function clears HW semaphore bits.
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * returns: - None.
+ *
+ ***************************************************************************/
+static void
+e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
+{
+#ifndef CONFIG_E1000_NO_NVM
+	 uint32_t swsm;
+
+	DEBUGFUNC();
+
+	if (!hw->eeprom_semaphore_present)
+		return;
+
+	swsm = E1000_READ_REG(hw, SWSM);
+	if (hw->mac_type == e1000_80003es2lan) {
+		/* Release both semaphores. */
+		swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
+	} else
+		swsm &= ~(E1000_SWSM_SWESMBI);
+	E1000_WRITE_REG(hw, SWSM, swsm);
+#endif
+}
+
+/***************************************************************************
+ *
+ * Using the combination of SMBI and SWESMBI semaphore bits when resetting
+ * adapter or Eeprom access.
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * returns: - E1000_ERR_EEPROM if fail to access EEPROM.
+ *            E1000_SUCCESS at any other case.
+ *
+ ***************************************************************************/
+static int32_t
+e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
+{
+#ifndef CONFIG_E1000_NO_NVM
+	int32_t timeout;
+	uint32_t swsm;
+
+	DEBUGFUNC();
+
+	if (!hw->eeprom_semaphore_present)
+		return E1000_SUCCESS;
+
+	if (hw->mac_type == e1000_80003es2lan) {
+		/* Get the SW semaphore. */
+		if (e1000_get_software_semaphore(hw) != E1000_SUCCESS)
+			return -E1000_ERR_EEPROM;
+	}
+
+	/* Get the FW semaphore. */
+	timeout = hw->eeprom.word_size + 1;
+	while (timeout) {
+		swsm = E1000_READ_REG(hw, SWSM);
+		swsm |= E1000_SWSM_SWESMBI;
+		E1000_WRITE_REG(hw, SWSM, swsm);
+		/* if we managed to set the bit we got the semaphore. */
+		swsm = E1000_READ_REG(hw, SWSM);
+		if (swsm & E1000_SWSM_SWESMBI)
+			break;
+
+		udelay(50);
+		timeout--;
+	}
+
+	if (!timeout) {
+		/* Release semaphores */
+		e1000_put_hw_eeprom_semaphore(hw);
+		DEBUGOUT("Driver can't access the Eeprom - "
+				"SWESMBI bit is set.\n");
+		return -E1000_ERR_EEPROM;
+	}
+#endif
+	return E1000_SUCCESS;
+}
+
+static int32_t
+e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask)
+{
+	uint32_t swfw_sync = 0;
+	uint32_t swmask = mask;
+	uint32_t fwmask = mask << 16;
+	int32_t timeout = 200;
+
+	DEBUGFUNC();
+	while (timeout) {
+		if (e1000_get_hw_eeprom_semaphore(hw))
+			return -E1000_ERR_SWFW_SYNC;
+
+		swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
+		if (!(swfw_sync & (fwmask | swmask)))
+			break;
+
+		/* firmware currently using resource (fwmask) */
+		/* or other software thread currently using resource (swmask) */
+		e1000_put_hw_eeprom_semaphore(hw);
+		mdelay(5);
+		timeout--;
+	}
+
+	if (!timeout) {
+		DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
+		return -E1000_ERR_SWFW_SYNC;
+	}
+
+	swfw_sync |= swmask;
+	E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync);
+
+	e1000_put_hw_eeprom_semaphore(hw);
+	return E1000_SUCCESS;
+}
+
+static bool e1000_is_second_port(struct e1000_hw *hw)
+{
+	switch (hw->mac_type) {
+	case e1000_80003es2lan:
+	case e1000_82546:
+	case e1000_82571:
+		if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
+			return true;
+		/* Fallthrough */
+	default:
+		return false;
+	}
+}
+
+#ifndef CONFIG_E1000_NO_NVM
+/******************************************************************************
+ * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
+ * second function of dual function devices
+ *
+ * nic - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static int
+e1000_read_mac_addr(struct eth_device *nic)
+{
+	struct e1000_hw *hw = nic->priv;
+	uint16_t offset;
+	uint16_t eeprom_data;
+	int i;
+
+	DEBUGFUNC();
+
+	for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
+		offset = i >> 1;
+		if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
+			DEBUGOUT("EEPROM Read Error\n");
+			return -E1000_ERR_EEPROM;
+		}
+		nic->enetaddr[i] = eeprom_data & 0xff;
+		nic->enetaddr[i + 1] = (eeprom_data >> 8) & 0xff;
+	}
+
+	/* Invert the last bit if this is the second device */
+	if (e1000_is_second_port(hw))
+		nic->enetaddr[5] ^= 1;
+
+#ifdef CONFIG_E1000_FALLBACK_MAC
+	if (!is_valid_ether_addr(nic->enetaddr)) {
+		unsigned char fb_mac[NODE_ADDRESS_SIZE] = CONFIG_E1000_FALLBACK_MAC;
+
+		memcpy (nic->enetaddr, fb_mac, NODE_ADDRESS_SIZE);
+	}
+#endif
+	return 0;
+}
+#endif
+
+/******************************************************************************
+ * Initializes receive address filters.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Places the MAC address in receive address register 0 and clears the rest
+ * of the receive addresss registers. Clears the multicast table. Assumes
+ * the receiver is in reset when the routine is called.
+ *****************************************************************************/
+static void
+e1000_init_rx_addrs(struct eth_device *nic)
+{
+	struct e1000_hw *hw = nic->priv;
+	uint32_t i;
+	uint32_t addr_low;
+	uint32_t addr_high;
+
+	DEBUGFUNC();
+
+	/* Setup the receive address. */
+	DEBUGOUT("Programming MAC Address into RAR[0]\n");
+	addr_low = (nic->enetaddr[0] |
+		    (nic->enetaddr[1] << 8) |
+		    (nic->enetaddr[2] << 16) | (nic->enetaddr[3] << 24));
+
+	addr_high = (nic->enetaddr[4] | (nic->enetaddr[5] << 8) | E1000_RAH_AV);
+
+	E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low);
+	E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high);
+
+	/* Zero out the other 15 receive addresses. */
+	DEBUGOUT("Clearing RAR[1-15]\n");
+	for (i = 1; i < E1000_RAR_ENTRIES; i++) {
+		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
+		E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
+	}
+}
+
+/******************************************************************************
+ * Clears the VLAN filer table
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_clear_vfta(struct e1000_hw *hw)
+{
+	uint32_t offset;
+
+	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++)
+		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
+}
+
+/******************************************************************************
+ * Set the mac type member in the hw struct.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+int32_t
+e1000_set_mac_type(struct e1000_hw *hw)
+{
+	DEBUGFUNC();
+
+	switch (hw->device_id) {
+	case E1000_DEV_ID_82542:
+		switch (hw->revision_id) {
+		case E1000_82542_2_0_REV_ID:
+			hw->mac_type = e1000_82542_rev2_0;
+			break;
+		case E1000_82542_2_1_REV_ID:
+			hw->mac_type = e1000_82542_rev2_1;
+			break;
+		default:
+			/* Invalid 82542 revision ID */
+			return -E1000_ERR_MAC_TYPE;
+		}
+		break;
+	case E1000_DEV_ID_82543GC_FIBER:
+	case E1000_DEV_ID_82543GC_COPPER:
+		hw->mac_type = e1000_82543;
+		break;
+	case E1000_DEV_ID_82544EI_COPPER:
+	case E1000_DEV_ID_82544EI_FIBER:
+	case E1000_DEV_ID_82544GC_COPPER:
+	case E1000_DEV_ID_82544GC_LOM:
+		hw->mac_type = e1000_82544;
+		break;
+	case E1000_DEV_ID_82540EM:
+	case E1000_DEV_ID_82540EM_LOM:
+	case E1000_DEV_ID_82540EP:
+	case E1000_DEV_ID_82540EP_LOM:
+	case E1000_DEV_ID_82540EP_LP:
+		hw->mac_type = e1000_82540;
+		break;
+	case E1000_DEV_ID_82545EM_COPPER:
+	case E1000_DEV_ID_82545EM_FIBER:
+		hw->mac_type = e1000_82545;
+		break;
+	case E1000_DEV_ID_82545GM_COPPER:
+	case E1000_DEV_ID_82545GM_FIBER:
+	case E1000_DEV_ID_82545GM_SERDES:
+		hw->mac_type = e1000_82545_rev_3;
+		break;
+	case E1000_DEV_ID_82546EB_COPPER:
+	case E1000_DEV_ID_82546EB_FIBER:
+	case E1000_DEV_ID_82546EB_QUAD_COPPER:
+		hw->mac_type = e1000_82546;
+		break;
+	case E1000_DEV_ID_82546GB_COPPER:
+	case E1000_DEV_ID_82546GB_FIBER:
+	case E1000_DEV_ID_82546GB_SERDES:
+	case E1000_DEV_ID_82546GB_PCIE:
+	case E1000_DEV_ID_82546GB_QUAD_COPPER:
+	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
+		hw->mac_type = e1000_82546_rev_3;
+		break;
+	case E1000_DEV_ID_82541EI:
+	case E1000_DEV_ID_82541EI_MOBILE:
+	case E1000_DEV_ID_82541ER_LOM:
+		hw->mac_type = e1000_82541;
+		break;
+	case E1000_DEV_ID_82541ER:
+	case E1000_DEV_ID_82541GI:
+	case E1000_DEV_ID_82541GI_LF:
+	case E1000_DEV_ID_82541GI_MOBILE:
+		hw->mac_type = e1000_82541_rev_2;
+		break;
+	case E1000_DEV_ID_82547EI:
+	case E1000_DEV_ID_82547EI_MOBILE:
+		hw->mac_type = e1000_82547;
+		break;
+	case E1000_DEV_ID_82547GI:
+		hw->mac_type = e1000_82547_rev_2;
+		break;
+	case E1000_DEV_ID_82571EB_COPPER:
+	case E1000_DEV_ID_82571EB_FIBER:
+	case E1000_DEV_ID_82571EB_SERDES:
+	case E1000_DEV_ID_82571EB_SERDES_DUAL:
+	case E1000_DEV_ID_82571EB_SERDES_QUAD:
+	case E1000_DEV_ID_82571EB_QUAD_COPPER:
+	case E1000_DEV_ID_82571PT_QUAD_COPPER:
+	case E1000_DEV_ID_82571EB_QUAD_FIBER:
+	case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
+		hw->mac_type = e1000_82571;
+		break;
+	case E1000_DEV_ID_82572EI_COPPER:
+	case E1000_DEV_ID_82572EI_FIBER:
+	case E1000_DEV_ID_82572EI_SERDES:
+	case E1000_DEV_ID_82572EI:
+		hw->mac_type = e1000_82572;
+		break;
+	case E1000_DEV_ID_82573E:
+	case E1000_DEV_ID_82573E_IAMT:
+	case E1000_DEV_ID_82573L:
+		hw->mac_type = e1000_82573;
+		break;
+	case E1000_DEV_ID_82574L:
+		hw->mac_type = e1000_82574;
+		break;
+	case E1000_DEV_ID_80003ES2LAN_COPPER_SPT:
+	case E1000_DEV_ID_80003ES2LAN_SERDES_SPT:
+	case E1000_DEV_ID_80003ES2LAN_COPPER_DPT:
+	case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
+		hw->mac_type = e1000_80003es2lan;
+		break;
+	case E1000_DEV_ID_ICH8_IGP_M_AMT:
+	case E1000_DEV_ID_ICH8_IGP_AMT:
+	case E1000_DEV_ID_ICH8_IGP_C:
+	case E1000_DEV_ID_ICH8_IFE:
+	case E1000_DEV_ID_ICH8_IFE_GT:
+	case E1000_DEV_ID_ICH8_IFE_G:
+	case E1000_DEV_ID_ICH8_IGP_M:
+		hw->mac_type = e1000_ich8lan;
+		break;
+	default:
+		/* Should never have loaded on this device */
+		return -E1000_ERR_MAC_TYPE;
+	}
+	return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Reset the transmit and receive units; mask and clear all interrupts.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+void
+e1000_reset_hw(struct e1000_hw *hw)
+{
+	uint32_t ctrl;
+	uint32_t ctrl_ext;
+	uint32_t manc;
+	uint32_t pba = 0;
+
+	DEBUGFUNC();
+
+	/* get the correct pba value for both PCI and PCIe*/
+	if (hw->mac_type <  e1000_82571)
+		pba = E1000_DEFAULT_PCI_PBA;
+	else
+		pba = E1000_DEFAULT_PCIE_PBA;
+
+	/* For 82542 (rev 2.0), disable MWI before issuing a device reset */
+	if (hw->mac_type == e1000_82542_rev2_0) {
+		DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
+		pci_write_config_word(hw->pdev, PCI_COMMAND,
+				hw->pci_cmd_word & ~PCI_COMMAND_INVALIDATE);
+	}
+
+	/* Clear interrupt mask to stop board from generating interrupts */
+	DEBUGOUT("Masking off all interrupts\n");
+	E1000_WRITE_REG(hw, IMC, 0xffffffff);
+
+	/* Disable the Transmit and Receive units.  Then delay to allow
+	 * any pending transactions to complete before we hit the MAC with
+	 * the global reset.
+	 */
+	E1000_WRITE_REG(hw, RCTL, 0);
+	E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
+	E1000_WRITE_FLUSH(hw);
+
+	/* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
+	hw->tbi_compatibility_on = false;
+
+	/* Delay to allow any outstanding PCI transactions to complete before
+	 * resetting the device
+	 */
+	mdelay(10);
+
+	/* Issue a global reset to the MAC.  This will reset the chip's
+	 * transmit, receive, DMA, and link units.  It will not effect
+	 * the current PCI configuration.  The global reset bit is self-
+	 * clearing, and should clear within a microsecond.
+	 */
+	DEBUGOUT("Issuing a global reset to MAC\n");
+	ctrl = E1000_READ_REG(hw, CTRL);
+
+	E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
+
+	/* Force a reload from the EEPROM if necessary */
+	if (hw->mac_type < e1000_82540) {
+		/* Wait for reset to complete */
+		udelay(10);
+		ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+		ctrl_ext |= E1000_CTRL_EXT_EE_RST;
+		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+		E1000_WRITE_FLUSH(hw);
+		/* Wait for EEPROM reload */
+		mdelay(2);
+	} else {
+		/* Wait for EEPROM reload (it happens automatically) */
+		mdelay(4);
+		/* Dissable HW ARPs on ASF enabled adapters */
+		manc = E1000_READ_REG(hw, MANC);
+		manc &= ~(E1000_MANC_ARP_EN);
+		E1000_WRITE_REG(hw, MANC, manc);
+	}
+
+	/* Clear interrupt mask to stop board from generating interrupts */
+	DEBUGOUT("Masking off all interrupts\n");
+	E1000_WRITE_REG(hw, IMC, 0xffffffff);
+
+	/* Clear any pending interrupt events. */
+	E1000_READ_REG(hw, ICR);
+
+	/* If MWI was previously enabled, reenable it. */
+	if (hw->mac_type == e1000_82542_rev2_0) {
+		pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word);
+	}
+	E1000_WRITE_REG(hw, PBA, pba);
+}
+
+/******************************************************************************
+ *
+ * Initialize a number of hardware-dependent bits
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * This function contains hardware limitation workarounds for PCI-E adapters
+ *
+ *****************************************************************************/
+static void
+e1000_initialize_hardware_bits(struct e1000_hw *hw)
+{
+	if ((hw->mac_type >= e1000_82571) &&
+			(!hw->initialize_hw_bits_disable)) {
+		/* Settings common to all PCI-express silicon */
+		uint32_t reg_ctrl, reg_ctrl_ext;
+		uint32_t reg_tarc0, reg_tarc1;
+		uint32_t reg_tctl;
+		uint32_t reg_txdctl, reg_txdctl1;
+
+		/* link autonegotiation/sync workarounds */
+		reg_tarc0 = E1000_READ_REG(hw, TARC0);
+		reg_tarc0 &= ~((1 << 30)|(1 << 29)|(1 << 28)|(1 << 27));
+
+		/* Enable not-done TX descriptor counting */
+		reg_txdctl = E1000_READ_REG(hw, TXDCTL);
+		reg_txdctl |= E1000_TXDCTL_COUNT_DESC;
+		E1000_WRITE_REG(hw, TXDCTL, reg_txdctl);
+
+		reg_txdctl1 = E1000_READ_REG(hw, TXDCTL1);
+		reg_txdctl1 |= E1000_TXDCTL_COUNT_DESC;
+		E1000_WRITE_REG(hw, TXDCTL1, reg_txdctl1);
+
+		switch (hw->mac_type) {
+		case e1000_82571:
+		case e1000_82572:
+			/* Clear PHY TX compatible mode bits */
+			reg_tarc1 = E1000_READ_REG(hw, TARC1);
+			reg_tarc1 &= ~((1 << 30)|(1 << 29));
+
+			/* link autonegotiation/sync workarounds */
+			reg_tarc0 |= ((1 << 26)|(1 << 25)|(1 << 24)|(1 << 23));
+
+			/* TX ring control fixes */
+			reg_tarc1 |= ((1 << 26)|(1 << 25)|(1 << 24));
+
+			/* Multiple read bit is reversed polarity */
+			reg_tctl = E1000_READ_REG(hw, TCTL);
+			if (reg_tctl & E1000_TCTL_MULR)
+				reg_tarc1 &= ~(1 << 28);
+			else
+				reg_tarc1 |= (1 << 28);
+
+			E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+			break;
+		case e1000_82573:
+		case e1000_82574:
+			reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+			reg_ctrl_ext &= ~(1 << 23);
+			reg_ctrl_ext |= (1 << 22);
+
+			/* TX byte count fix */
+			reg_ctrl = E1000_READ_REG(hw, CTRL);
+			reg_ctrl &= ~(1 << 29);
+
+			E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext);
+			E1000_WRITE_REG(hw, CTRL, reg_ctrl);
+			break;
+		case e1000_80003es2lan:
+	/* improve small packet performace for fiber/serdes */
+			if ((hw->media_type == e1000_media_type_fiber)
+			|| (hw->media_type ==
+				e1000_media_type_internal_serdes)) {
+				reg_tarc0 &= ~(1 << 20);
+			}
+
+		/* Multiple read bit is reversed polarity */
+			reg_tctl = E1000_READ_REG(hw, TCTL);
+			reg_tarc1 = E1000_READ_REG(hw, TARC1);
+			if (reg_tctl & E1000_TCTL_MULR)
+				reg_tarc1 &= ~(1 << 28);
+			else
+				reg_tarc1 |= (1 << 28);
+
+			E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+			break;
+		case e1000_ich8lan:
+			/* Reduce concurrent DMA requests to 3 from 4 */
+			if ((hw->revision_id < 3) ||
+			((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
+				(hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))
+				reg_tarc0 |= ((1 << 29)|(1 << 28));
+
+			reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+			reg_ctrl_ext |= (1 << 22);
+			E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext);
+
+			/* workaround TX hang with TSO=on */
+			reg_tarc0 |= ((1 << 27)|(1 << 26)|(1 << 24)|(1 << 23));
+
+			/* Multiple read bit is reversed polarity */
+			reg_tctl = E1000_READ_REG(hw, TCTL);
+			reg_tarc1 = E1000_READ_REG(hw, TARC1);
+			if (reg_tctl & E1000_TCTL_MULR)
+				reg_tarc1 &= ~(1 << 28);
+			else
+				reg_tarc1 |= (1 << 28);
+
+			/* workaround TX hang with TSO=on */
+			reg_tarc1 |= ((1 << 30)|(1 << 26)|(1 << 24));
+
+			E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+			break;
+		default:
+			break;
+		}
+
+		E1000_WRITE_REG(hw, TARC0, reg_tarc0);
+	}
+}
+
+/******************************************************************************
+ * Performs basic configuration of the adapter.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Assumes that the controller has previously been reset and is in a
+ * post-reset uninitialized state. Initializes the receive address registers,
+ * multicast table, and VLAN filter table. Calls routines to setup link
+ * configuration and flow control settings. Clears all on-chip counters. Leaves
+ * the transmit and receive units disabled and uninitialized.
+ *****************************************************************************/
+static int
+e1000_init_hw(struct eth_device *nic)
+{
+	struct e1000_hw *hw = nic->priv;
+	uint32_t ctrl;
+	uint32_t i;
+	int32_t ret_val;
+	uint16_t pcix_cmd_word;
+	uint16_t pcix_stat_hi_word;
+	uint16_t cmd_mmrbc;
+	uint16_t stat_mmrbc;
+	uint32_t mta_size;
+	uint32_t reg_data;
+	uint32_t ctrl_ext;
+	DEBUGFUNC();
+	/* force full DMA clock frequency for 10/100 on ICH8 A0-B0 */
+	if ((hw->mac_type == e1000_ich8lan) &&
+		((hw->revision_id < 3) ||
+		((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
+		(hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))) {
+			reg_data = E1000_READ_REG(hw, STATUS);
+			reg_data &= ~0x80000000;
+			E1000_WRITE_REG(hw, STATUS, reg_data);
+	}
+	/* Do not need initialize Identification LED */
+
+	/* Set the media type and TBI compatibility */
+	e1000_set_media_type(hw);
+
+	/* Must be called after e1000_set_media_type
+	 * because media_type is used */
+	e1000_initialize_hardware_bits(hw);
+
+	/* Disabling VLAN filtering. */
+	DEBUGOUT("Initializing the IEEE VLAN\n");
+	/* VET hardcoded to standard value and VFTA removed in ICH8 LAN */
+	if (hw->mac_type != e1000_ich8lan) {
+		if (hw->mac_type < e1000_82545_rev_3)
+			E1000_WRITE_REG(hw, VET, 0);
+		e1000_clear_vfta(hw);
+	}
+
+	/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
+	if (hw->mac_type == e1000_82542_rev2_0) {
+		DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
+		pci_write_config_word(hw->pdev, PCI_COMMAND,
+				      hw->
+				      pci_cmd_word & ~PCI_COMMAND_INVALIDATE);
+		E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
+		E1000_WRITE_FLUSH(hw);
+		mdelay(5);
+	}
+
+	/* Setup the receive address. This involves initializing all of the Receive
+	 * Address Registers (RARs 0 - 15).
+	 */
+	e1000_init_rx_addrs(nic);
+
+	/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
+	if (hw->mac_type == e1000_82542_rev2_0) {
+		E1000_WRITE_REG(hw, RCTL, 0);
+		E1000_WRITE_FLUSH(hw);
+		mdelay(1);
+		pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word);
+	}
+
+	/* Zero out the Multicast HASH table */
+	DEBUGOUT("Zeroing the MTA\n");
+	mta_size = E1000_MC_TBL_SIZE;
+	if (hw->mac_type == e1000_ich8lan)
+		mta_size = E1000_MC_TBL_SIZE_ICH8LAN;
+	for (i = 0; i < mta_size; i++) {
+		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
+		/* use write flush to prevent Memory Write Block (MWB) from
+		 * occuring when accessing our register space */
+		E1000_WRITE_FLUSH(hw);
+	}
+#if 0
+	/* Set the PCI priority bit correctly in the CTRL register.  This
+	 * determines if the adapter gives priority to receives, or if it
+	 * gives equal priority to transmits and receives.  Valid only on
+	 * 82542 and 82543 silicon.
+	 */
+	if (hw->dma_fairness && hw->mac_type <= e1000_82543) {
+		ctrl = E1000_READ_REG(hw, CTRL);
+		E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
+	}
+#endif
+	switch (hw->mac_type) {
+	case e1000_82545_rev_3:
+	case e1000_82546_rev_3:
+		break;
+	default:
+	/* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
+	if (hw->bus_type == e1000_bus_type_pcix) {
+		pci_read_config_word(hw->pdev, PCIX_COMMAND_REGISTER,
+				     &pcix_cmd_word);
+		pci_read_config_word(hw->pdev, PCIX_STATUS_REGISTER_HI,
+				     &pcix_stat_hi_word);
+		cmd_mmrbc =
+		    (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
+		    PCIX_COMMAND_MMRBC_SHIFT;
+		stat_mmrbc =
+		    (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
+		    PCIX_STATUS_HI_MMRBC_SHIFT;
+		if (stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
+			stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
+		if (cmd_mmrbc > stat_mmrbc) {
+			pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
+			pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
+			pci_write_config_word(hw->pdev, PCIX_COMMAND_REGISTER,
+					      pcix_cmd_word);
+		}
+	}
+		break;
+	}
+
+	/* More time needed for PHY to initialize */
+	if (hw->mac_type == e1000_ich8lan)
+		mdelay(15);
+
+	/* Call a subroutine to configure the link and setup flow control. */
+	ret_val = e1000_setup_link(nic);
+
+	/* Set the transmit descriptor write-back policy */
+	if (hw->mac_type > e1000_82544) {
+		ctrl = E1000_READ_REG(hw, TXDCTL);
+		ctrl =
+		    (ctrl & ~E1000_TXDCTL_WTHRESH) |
+		    E1000_TXDCTL_FULL_TX_DESC_WB;
+		E1000_WRITE_REG(hw, TXDCTL, ctrl);
+	}
+
+	/* Set the receive descriptor write back policy */
+
+	if (hw->mac_type >= e1000_82571) {
+		ctrl = E1000_READ_REG(hw, RXDCTL);
+		ctrl =
+		    (ctrl & ~E1000_RXDCTL_WTHRESH) |
+		    E1000_RXDCTL_FULL_RX_DESC_WB;
+		E1000_WRITE_REG(hw, RXDCTL, ctrl);
+	}
+
+	switch (hw->mac_type) {
+	default:
+		break;
+	case e1000_80003es2lan:
+		/* Enable retransmit on late collisions */
+		reg_data = E1000_READ_REG(hw, TCTL);
+		reg_data |= E1000_TCTL_RTLC;
+		E1000_WRITE_REG(hw, TCTL, reg_data);
+
+		/* Configure Gigabit Carry Extend Padding */
+		reg_data = E1000_READ_REG(hw, TCTL_EXT);
+		reg_data &= ~E1000_TCTL_EXT_GCEX_MASK;
+		reg_data |= DEFAULT_80003ES2LAN_TCTL_EXT_GCEX;
+		E1000_WRITE_REG(hw, TCTL_EXT, reg_data);
+
+		/* Configure Transmit Inter-Packet Gap */
+		reg_data = E1000_READ_REG(hw, TIPG);
+		reg_data &= ~E1000_TIPG_IPGT_MASK;
+		reg_data |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000;
+		E1000_WRITE_REG(hw, TIPG, reg_data);
+
+		reg_data = E1000_READ_REG_ARRAY(hw, FFLT, 0x0001);
+		reg_data &= ~0x00100000;
+		E1000_WRITE_REG_ARRAY(hw, FFLT, 0x0001, reg_data);
+		/* Fall through */
+	case e1000_82571:
+	case e1000_82572:
+	case e1000_ich8lan:
+		ctrl = E1000_READ_REG(hw, TXDCTL1);
+		ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH)
+			| E1000_TXDCTL_FULL_TX_DESC_WB;
+		E1000_WRITE_REG(hw, TXDCTL1, ctrl);
+		break;
+	case e1000_82573:
+	case e1000_82574:
+		reg_data = E1000_READ_REG(hw, GCR);
+		reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
+		E1000_WRITE_REG(hw, GCR, reg_data);
+	}
+
+#if 0
+	/* Clear all of the statistics registers (clear on read).  It is
+	 * important that we do this after we have tried to establish link
+	 * because the symbol error count will increment wildly if there
+	 * is no link.
+	 */
+	e1000_clear_hw_cntrs(hw);
+
+	/* ICH8 No-snoop bits are opposite polarity.
+	 * Set to snoop by default after reset. */
+	if (hw->mac_type == e1000_ich8lan)
+		e1000_set_pci_ex_no_snoop(hw, PCI_EX_82566_SNOOP_ALL);
+#endif
+
+	if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER ||
+		hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) {
+		ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+		/* Relaxed ordering must be disabled to avoid a parity
+		 * error crash in a PCI slot. */
+		ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
+		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+	}
+
+	return ret_val;
+}
+
+/******************************************************************************
+ * Configures flow control and link settings.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Determines which flow control settings to use. Calls the apropriate media-
+ * specific link configuration function. Configures the flow control settings.
+ * Assuming the adapter has a valid link partner, a valid link should be
+ * established. Assumes the hardware has previously been reset and the
+ * transmitter and receiver are not enabled.
+ *****************************************************************************/
+static int
+e1000_setup_link(struct eth_device *nic)
+{
+	struct e1000_hw *hw = nic->priv;
+	int32_t ret_val;
+#ifndef CONFIG_E1000_NO_NVM
+	uint32_t ctrl_ext;
+	uint16_t eeprom_data;
+#endif
+
+	DEBUGFUNC();
+
+	/* In the case of the phy reset being blocked, we already have a link.
+	 * We do not have to set it up again. */
+	if (e1000_check_phy_reset_block(hw))
+		return E1000_SUCCESS;
+
+#ifndef CONFIG_E1000_NO_NVM
+	/* Read and store word 0x0F of the EEPROM. This word contains bits
+	 * that determine the hardware's default PAUSE (flow control) mode,
+	 * a bit that determines whether the HW defaults to enabling or
+	 * disabling auto-negotiation, and the direction of the
+	 * SW defined pins. If there is no SW over-ride of the flow
+	 * control setting, then the variable hw->fc will
+	 * be initialized based on a value in the EEPROM.
+	 */
+	if (e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1,
+				&eeprom_data) < 0) {
+		DEBUGOUT("EEPROM Read Error\n");
+		return -E1000_ERR_EEPROM;
+	}
+#endif
+	if (hw->fc == e1000_fc_default) {
+		switch (hw->mac_type) {
+		case e1000_ich8lan:
+		case e1000_82573:
+		case e1000_82574:
+			hw->fc = e1000_fc_full;
+			break;
+		default:
+#ifndef CONFIG_E1000_NO_NVM
+			ret_val = e1000_read_eeprom(hw,
+				EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
+			if (ret_val) {
+				DEBUGOUT("EEPROM Read Error\n");
+				return -E1000_ERR_EEPROM;
+			}
+			if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
+				hw->fc = e1000_fc_none;
+			else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
+				    EEPROM_WORD0F_ASM_DIR)
+				hw->fc = e1000_fc_tx_pause;
+			else
+#endif
+				hw->fc = e1000_fc_full;
+			break;
+		}
+	}
+
+	/* We want to save off the original Flow Control configuration just
+	 * in case we get disconnected and then reconnected into a different
+	 * hub or switch with different Flow Control capabilities.
+	 */
+	if (hw->mac_type == e1000_82542_rev2_0)
+		hw->fc &= (~e1000_fc_tx_pause);
+
+	if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
+		hw->fc &= (~e1000_fc_rx_pause);
+
+	hw->original_fc = hw->fc;
+
+	DEBUGOUT("After fix-ups FlowControl is now = %x\n", hw->fc);
+
+#ifndef CONFIG_E1000_NO_NVM
+	/* Take the 4 bits from EEPROM word 0x0F that determine the initial
+	 * polarity value for the SW controlled pins, and setup the
+	 * Extended Device Control reg with that info.
+	 * This is needed because one of the SW controlled pins is used for
+	 * signal detection.  So this should be done before e1000_setup_pcs_link()
+	 * or e1000_phy_setup() is called.
+	 */
+	if (hw->mac_type == e1000_82543) {
+		ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
+			    SWDPIO__EXT_SHIFT);
+		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+	}
+#endif
+
+	/* Call the necessary subroutine to configure the link. */
+	ret_val = (hw->media_type == e1000_media_type_fiber) ?
+	    e1000_setup_fiber_link(nic) : e1000_setup_copper_link(nic);
+	if (ret_val < 0) {
+		return ret_val;
+	}
+
+	/* Initialize the flow control address, type, and PAUSE timer
+	 * registers to their default values.  This is done even if flow
+	 * control is disabled, because it does not hurt anything to
+	 * initialize these registers.
+	 */
+	DEBUGOUT("Initializing the Flow Control address, type"
+			"and timer regs\n");
+
+	/* FCAL/H and FCT are hardcoded to standard values in e1000_ich8lan. */
+	if (hw->mac_type != e1000_ich8lan) {
+		E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE);
+		E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH);
+		E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW);
+	}
+
+	E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time);
+
+	/* Set the flow control receive threshold registers.  Normally,
+	 * these registers will be set to a default threshold that may be
+	 * adjusted later by the driver's runtime code.  However, if the
+	 * ability to transmit pause frames in not enabled, then these
+	 * registers will be set to 0.
+	 */
+	if (!(hw->fc & e1000_fc_tx_pause)) {
+		E1000_WRITE_REG(hw, FCRTL, 0);
+		E1000_WRITE_REG(hw, FCRTH, 0);
+	} else {
+		/* We need to set up the Receive Threshold high and low water marks
+		 * as well as (optionally) enabling the transmission of XON frames.
+		 */
+		if (hw->fc_send_xon) {
+			E1000_WRITE_REG(hw, FCRTL,
+					(hw->fc_low_water | E1000_FCRTL_XONE));
+			E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
+		} else {
+			E1000_WRITE_REG(hw, FCRTL, hw->fc_low_water);
+			E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
+		}
+	}
+	return ret_val;
+}
+
+/******************************************************************************
+ * Sets up link for a fiber based adapter
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Manipulates Physical Coding Sublayer functions in order to configure
+ * link. Assumes the hardware has been previously reset and the transmitter
+ * and receiver are not enabled.
+ *****************************************************************************/
+static int
+e1000_setup_fiber_link(struct eth_device *nic)
+{
+	struct e1000_hw *hw = nic->priv;
+	uint32_t ctrl;
+	uint32_t status;
+	uint32_t txcw = 0;
+	uint32_t i;
+	uint32_t signal;
+	int32_t ret_val;
+
+	DEBUGFUNC();
+	/* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
+	 * set when the optics detect a signal. On older adapters, it will be
+	 * cleared when there is a signal
+	 */
+	ctrl = E1000_READ_REG(hw, CTRL);
+	if ((hw->mac_type > e1000_82544) && !(ctrl & E1000_CTRL_ILOS))
+		signal = E1000_CTRL_SWDPIN1;
+	else
+		signal = 0;
+
+	printf("signal for %s is %x (ctrl %08x)!!!!\n", nic->name, signal,
+	       ctrl);
+	/* Take the link out of reset */
+	ctrl &= ~(E1000_CTRL_LRST);
+
+	e1000_config_collision_dist(hw);
+
+	/* Check for a software override of the flow control settings, and setup
+	 * the device accordingly.  If auto-negotiation is enabled, then software
+	 * will have to set the "PAUSE" bits to the correct value in the Tranmsit
+	 * Config Word Register (TXCW) and re-start auto-negotiation.  However, if
+	 * auto-negotiation is disabled, then software will have to manually
+	 * configure the two flow control enable bits in the CTRL register.
+	 *
+	 * The possible values of the "fc" parameter are:
+	 *	0:  Flow control is completely disabled
+	 *	1:  Rx flow control is enabled (we can receive pause frames, but
+	 *	    not send pause frames).
+	 *	2:  Tx flow control is enabled (we can send pause frames but we do
+	 *	    not support receiving pause frames).
+	 *	3:  Both Rx and TX flow control (symmetric) are enabled.
+	 */
+	switch (hw->fc) {
+	case e1000_fc_none:
+		/* Flow control is completely disabled by a software over-ride. */
+		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
+		break;
+	case e1000_fc_rx_pause:
+		/* RX Flow control is enabled and TX Flow control is disabled by a
+		 * software over-ride. Since there really isn't a way to advertise
+		 * that we are capable of RX Pause ONLY, we will advertise that we
+		 * support both symmetric and asymmetric RX PAUSE. Later, we will
+		 *  disable the adapter's ability to send PAUSE frames.
+		 */
+		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
+		break;
+	case e1000_fc_tx_pause:
+		/* TX Flow control is enabled, and RX Flow control is disabled, by a
+		 * software over-ride.
+		 */
+		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
+		break;
+	case e1000_fc_full:
+		/* Flow control (both RX and TX) is enabled by a software over-ride. */
+		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
+		break;
+	default:
+		DEBUGOUT("Flow control param set incorrectly\n");
+		return -E1000_ERR_CONFIG;
+		break;
+	}
+
+	/* Since auto-negotiation is enabled, take the link out of reset (the link
+	 * will be in reset, because we previously reset the chip). This will
+	 * restart auto-negotiation.  If auto-neogtiation is successful then the
+	 * link-up status bit will be set and the flow control enable bits (RFCE
+	 * and TFCE) will be set according to their negotiated value.
+	 */
+	DEBUGOUT("Auto-negotiation enabled (%#x)\n", txcw);
+
+	E1000_WRITE_REG(hw, TXCW, txcw);
+	E1000_WRITE_REG(hw, CTRL, ctrl);
+	E1000_WRITE_FLUSH(hw);
+
+	hw->txcw = txcw;
+	mdelay(1);
+
+	/* If we have a signal (the cable is plugged in) then poll for a "Link-Up"
+	 * indication in the Device Status Register.  Time-out if a link isn't
+	 * seen in 500 milliseconds seconds (Auto-negotiation should complete in
+	 * less than 500 milliseconds even if the other end is doing it in SW).
+	 */
+	if ((E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
+		DEBUGOUT("Looking for Link\n");
+		for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
+			mdelay(10);
+			status = E1000_READ_REG(hw, STATUS);
+			if (status & E1000_STATUS_LU)
+				break;
+		}
+		if (i == (LINK_UP_TIMEOUT / 10)) {
+			/* AutoNeg failed to achieve a link, so we'll call
+			 * e1000_check_for_link. This routine will force the link up if we
+			 * detect a signal. This will allow us to communicate with
+			 * non-autonegotiating link partners.
+			 */
+			DEBUGOUT("Never got a valid link from auto-neg!!!\n");
+			hw->autoneg_failed = 1;
+			ret_val = e1000_check_for_link(nic);
+			if (ret_val < 0) {
+				DEBUGOUT("Error while checking for link\n");
+				return ret_val;
+			}
+			hw->autoneg_failed = 0;
+		} else {
+			hw->autoneg_failed = 0;
+			DEBUGOUT("Valid Link Found\n");
+		}
+	} else {
+		DEBUGOUT("No Signal Detected\n");
+		return -E1000_ERR_NOLINK;
+	}
+	return 0;
+}
+
+/******************************************************************************
+* Make sure we have a valid PHY and change PHY mode before link setup.
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int32_t
+e1000_copper_link_preconfig(struct e1000_hw *hw)
+{
+	uint32_t ctrl;
+	int32_t ret_val;
+	uint16_t phy_data;
+
+	DEBUGFUNC();
+
+	ctrl = E1000_READ_REG(hw, CTRL);
+	/* With 82543, we need to force speed and duplex on the MAC equal to what
+	 * the PHY speed and duplex configuration is. In addition, we need to
+	 * perform a hardware reset on the PHY to take it out of reset.
+	 */
+	if (hw->mac_type > e1000_82543) {
+		ctrl |= E1000_CTRL_SLU;
+		ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
+		E1000_WRITE_REG(hw, CTRL, ctrl);
+	} else {
+		ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX
+				| E1000_CTRL_SLU);
+		E1000_WRITE_REG(hw, CTRL, ctrl);
+		ret_val = e1000_phy_hw_reset(hw);
+		if (ret_val)
+			return ret_val;
+	}
+
+	/* Make sure we have a valid PHY */
+	ret_val = e1000_detect_gig_phy(hw);
+	if (ret_val) {
+		DEBUGOUT("Error, did not detect valid phy.\n");
+		return ret_val;
+	}
+	DEBUGOUT("Phy ID = %x \n", hw->phy_id);
+
+	/* Set PHY to class A mode (if necessary) */
+	ret_val = e1000_set_phy_mode(hw);
+	if (ret_val)
+		return ret_val;
+	if ((hw->mac_type == e1000_82545_rev_3) ||
+		(hw->mac_type == e1000_82546_rev_3)) {
+		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+				&phy_data);
+		phy_data |= 0x00000008;
+		ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+				phy_data);
+	}
+
+	if (hw->mac_type <= e1000_82543 ||
+		hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
+		hw->mac_type == e1000_82541_rev_2
+		|| hw->mac_type == e1000_82547_rev_2)
+			hw->phy_reset_disable = false;
+
+	return E1000_SUCCESS;
+}
+
+/*****************************************************************************
+ *
+ * This function sets the lplu state according to the active flag.  When
+ * activating lplu this function also disables smart speed and vise versa.
+ * lplu will not be activated unless the device autonegotiation advertisment
+ * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
+ * hw: Struct containing variables accessed by shared code
+ * active - true to enable lplu false to disable lplu.
+ *
+ * returns: - E1000_ERR_PHY if fail to read/write the PHY
+ *            E1000_SUCCESS at any other case.
+ *
+ ****************************************************************************/
+
+static int32_t
+e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active)
+{
+	uint32_t phy_ctrl = 0;
+	int32_t ret_val;
+	uint16_t phy_data;
+	DEBUGFUNC();
+
+	if (hw->phy_type != e1000_phy_igp && hw->phy_type != e1000_phy_igp_2
+	    && hw->phy_type != e1000_phy_igp_3)
+		return E1000_SUCCESS;
+
+	/* During driver activity LPLU should not be used or it will attain link
+	 * from the lowest speeds starting from 10Mbps. The capability is used
+	 * for Dx transitions and states */
+	if (hw->mac_type == e1000_82541_rev_2
+			|| hw->mac_type == e1000_82547_rev_2) {
+		ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
+				&phy_data);
+		if (ret_val)
+			return ret_val;
+	} else if (hw->mac_type == e1000_ich8lan) {
+		/* MAC writes into PHY register based on the state transition
+		 * and start auto-negotiation. SW driver can overwrite the
+		 * settings in CSR PHY power control E1000_PHY_CTRL register. */
+		phy_ctrl = E1000_READ_REG(hw, PHY_CTRL);
+	} else {
+		ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
+				&phy_data);
+		if (ret_val)
+			return ret_val;
+	}
+
+	if (!active) {
+		if (hw->mac_type == e1000_82541_rev_2 ||
+			hw->mac_type == e1000_82547_rev_2) {
+			phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
+			ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
+					phy_data);
+			if (ret_val)
+				return ret_val;
+		} else {
+			if (hw->mac_type == e1000_ich8lan) {
+				phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU;
+				E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
+			} else {
+				phy_data &= ~IGP02E1000_PM_D3_LPLU;
+				ret_val = e1000_write_phy_reg(hw,
+					IGP02E1000_PHY_POWER_MGMT, phy_data);
+				if (ret_val)
+					return ret_val;
+			}
+		}
+
+	/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used during
+	 * Dx states where the power conservation is most important.  During
+	 * driver activity we should enable SmartSpeed, so performance is
+	 * maintained. */
+		if (hw->smart_speed == e1000_smart_speed_on) {
+			ret_val = e1000_read_phy_reg(hw,
+					IGP01E1000_PHY_PORT_CONFIG, &phy_data);
+			if (ret_val)
+				return ret_val;
+
+			phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
+			ret_val = e1000_write_phy_reg(hw,
+					IGP01E1000_PHY_PORT_CONFIG, phy_data);
+			if (ret_val)
+				return ret_val;
+		} else if (hw->smart_speed == e1000_smart_speed_off) {
+			ret_val = e1000_read_phy_reg(hw,
+					IGP01E1000_PHY_PORT_CONFIG, &phy_data);
+			if (ret_val)
+				return ret_val;
+
+			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+			ret_val = e1000_write_phy_reg(hw,
+					IGP01E1000_PHY_PORT_CONFIG, phy_data);
+			if (ret_val)
+				return ret_val;
+		}
+
+	} else if ((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT)
+		|| (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL) ||
+		(hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) {
+
+		if (hw->mac_type == e1000_82541_rev_2 ||
+		    hw->mac_type == e1000_82547_rev_2) {
+			phy_data |= IGP01E1000_GMII_FLEX_SPD;
+			ret_val = e1000_write_phy_reg(hw,
+					IGP01E1000_GMII_FIFO, phy_data);
+			if (ret_val)
+				return ret_val;
+		} else {
+			if (hw->mac_type == e1000_ich8lan) {
+				phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU;
+				E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
+			} else {
+				phy_data |= IGP02E1000_PM_D3_LPLU;
+				ret_val = e1000_write_phy_reg(hw,
+					IGP02E1000_PHY_POWER_MGMT, phy_data);
+				if (ret_val)
+					return ret_val;
+			}
+		}
+
+		/* When LPLU is enabled we should disable SmartSpeed */
+		ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+				&phy_data);
+		if (ret_val)
+			return ret_val;
+
+		phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+		ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+				phy_data);
+		if (ret_val)
+			return ret_val;
+	}
+	return E1000_SUCCESS;
+}
+
+/*****************************************************************************
+ *
+ * This function sets the lplu d0 state according to the active flag.  When
+ * activating lplu this function also disables smart speed and vise versa.
+ * lplu will not be activated unless the device autonegotiation advertisment
+ * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
+ * hw: Struct containing variables accessed by shared code
+ * active - true to enable lplu false to disable lplu.
+ *
+ * returns: - E1000_ERR_PHY if fail to read/write the PHY
+ *            E1000_SUCCESS at any other case.
+ *
+ ****************************************************************************/
+
+static int32_t
+e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
+{
+	uint32_t phy_ctrl = 0;
+	int32_t ret_val;
+	uint16_t phy_data;
+	DEBUGFUNC();
+
+	if (hw->mac_type <= e1000_82547_rev_2)
+		return E1000_SUCCESS;
+
+	if (hw->mac_type == e1000_ich8lan) {
+		phy_ctrl = E1000_READ_REG(hw, PHY_CTRL);
+	} else {
+		ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
+				&phy_data);
+		if (ret_val)
+			return ret_val;
+	}
+
+	if (!active) {
+		if (hw->mac_type == e1000_ich8lan) {
+			phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU;
+			E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
+		} else {
+			phy_data &= ~IGP02E1000_PM_D0_LPLU;
+			ret_val = e1000_write_phy_reg(hw,
+					IGP02E1000_PHY_POWER_MGMT, phy_data);
+			if (ret_val)
+				return ret_val;
+		}
+
+	/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used during
+	 * Dx states where the power conservation is most important.  During
+	 * driver activity we should enable SmartSpeed, so performance is
+	 * maintained. */
+		if (hw->smart_speed == e1000_smart_speed_on) {
+			ret_val = e1000_read_phy_reg(hw,
+					IGP01E1000_PHY_PORT_CONFIG, &phy_data);
+			if (ret_val)
+				return ret_val;
+
+			phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
+			ret_val = e1000_write_phy_reg(hw,
+					IGP01E1000_PHY_PORT_CONFIG, phy_data);
+			if (ret_val)
+				return ret_val;
+		} else if (hw->smart_speed == e1000_smart_speed_off) {
+			ret_val = e1000_read_phy_reg(hw,
+					IGP01E1000_PHY_PORT_CONFIG, &phy_data);
+			if (ret_val)
+				return ret_val;
+
+			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+			ret_val = e1000_write_phy_reg(hw,
+					IGP01E1000_PHY_PORT_CONFIG, phy_data);
+			if (ret_val)
+				return ret_val;
+		}
+
+
+	} else {
+
+		if (hw->mac_type == e1000_ich8lan) {
+			phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU;
+			E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
+		} else {
+			phy_data |= IGP02E1000_PM_D0_LPLU;
+			ret_val = e1000_write_phy_reg(hw,
+					IGP02E1000_PHY_POWER_MGMT, phy_data);
+			if (ret_val)
+				return ret_val;
+		}
+
+		/* When LPLU is enabled we should disable SmartSpeed */
+		ret_val = e1000_read_phy_reg(hw,
+				IGP01E1000_PHY_PORT_CONFIG, &phy_data);
+		if (ret_val)
+			return ret_val;
+
+		phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+		ret_val = e1000_write_phy_reg(hw,
+				IGP01E1000_PHY_PORT_CONFIG, phy_data);
+		if (ret_val)
+			return ret_val;
+
+	}
+	return E1000_SUCCESS;
+}
+
+/********************************************************************
+* Copper link setup for e1000_phy_igp series.
+*
+* hw - Struct containing variables accessed by shared code
+*********************************************************************/
+static int32_t
+e1000_copper_link_igp_setup(struct e1000_hw *hw)
+{
+	uint32_t led_ctrl;
+	int32_t ret_val;
+	uint16_t phy_data;
+
+	DEBUGFUNC();
+
+	if (hw->phy_reset_disable)
+		return E1000_SUCCESS;
+
+	ret_val = e1000_phy_reset(hw);
+	if (ret_val) {
+		DEBUGOUT("Error Resetting the PHY\n");
+		return ret_val;
+	}
+
+	/* Wait 15ms for MAC to configure PHY from eeprom settings */
+	mdelay(15);
+	if (hw->mac_type != e1000_ich8lan) {
+		/* Configure activity LED after PHY reset */
+		led_ctrl = E1000_READ_REG(hw, LEDCTL);
+		led_ctrl &= IGP_ACTIVITY_LED_MASK;
+		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
+		E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
+	}
+
+	/* The NVM settings will configure LPLU in D3 for IGP2 and IGP3 PHYs */
+	if (hw->phy_type == e1000_phy_igp) {
+		/* disable lplu d3 during driver init */
+		ret_val = e1000_set_d3_lplu_state(hw, false);
+		if (ret_val) {
+			DEBUGOUT("Error Disabling LPLU D3\n");
+			return ret_val;
+		}
+	}
+
+	/* disable lplu d0 during driver init */
+	ret_val = e1000_set_d0_lplu_state(hw, false);
+	if (ret_val) {
+		DEBUGOUT("Error Disabling LPLU D0\n");
+		return ret_val;
+	}
+	/* Configure mdi-mdix settings */
+	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
+	if (ret_val)
+		return ret_val;
+
+	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+		hw->dsp_config_state = e1000_dsp_config_disabled;
+		/* Force MDI for earlier revs of the IGP PHY */
+		phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX
+				| IGP01E1000_PSCR_FORCE_MDI_MDIX);
+		hw->mdix = 1;
+
+	} else {
+		hw->dsp_config_state = e1000_dsp_config_enabled;
+		phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
+
+		switch (hw->mdix) {
+		case 1:
+			phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
+			break;
+		case 2:
+			phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
+			break;
+		case 0:
+		default:
+			phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
+			break;
+		}
+	}
+	ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
+	if (ret_val)
+		return ret_val;
+
+	/* set auto-master slave resolution settings */
+	if (hw->autoneg) {
+		e1000_ms_type phy_ms_setting = hw->master_slave;
+
+		if (hw->ffe_config_state == e1000_ffe_config_active)
+			hw->ffe_config_state = e1000_ffe_config_enabled;
+
+		if (hw->dsp_config_state == e1000_dsp_config_activated)
+			hw->dsp_config_state = e1000_dsp_config_enabled;
+
+		/* when autonegotiation advertisment is only 1000Mbps then we
+		  * should disable SmartSpeed and enable Auto MasterSlave
+		  * resolution as hardware default. */
+		if (hw->autoneg_advertised == ADVERTISE_1000_FULL) {
+			/* Disable SmartSpeed */
+			ret_val = e1000_read_phy_reg(hw,
+					IGP01E1000_PHY_PORT_CONFIG, &phy_data);
+			if (ret_val)
+				return ret_val;
+			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+			ret_val = e1000_write_phy_reg(hw,
+					IGP01E1000_PHY_PORT_CONFIG, phy_data);
+			if (ret_val)
+				return ret_val;
+			/* Set auto Master/Slave resolution process */
+			ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL,
+					&phy_data);
+			if (ret_val)
+				return ret_val;
+			phy_data &= ~CR_1000T_MS_ENABLE;
+			ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
+					phy_data);
+			if (ret_val)
+				return ret_val;
+		}
+
+		ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
+		if (ret_val)
+			return ret_val;
+
+		/* load defaults for future use */
+		hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
+				((phy_data & CR_1000T_MS_VALUE) ?
+				e1000_ms_force_master :
+				e1000_ms_force_slave) :
+				e1000_ms_auto;
+
+		switch (phy_ms_setting) {
+		case e1000_ms_force_master:
+			phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
+			break;
+		case e1000_ms_force_slave:
+			phy_data |= CR_1000T_MS_ENABLE;
+			phy_data &= ~(CR_1000T_MS_VALUE);
+			break;
+		case e1000_ms_auto:
+			phy_data &= ~CR_1000T_MS_ENABLE;
+		default:
+			break;
+		}
+		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
+		if (ret_val)
+			return ret_val;
+	}
+
+	return E1000_SUCCESS;
+}
+
+/*****************************************************************************
+ * This function checks the mode of the firmware.
+ *
+ * returns  - true when the mode is IAMT or false.
+ ****************************************************************************/
+bool
+e1000_check_mng_mode(struct e1000_hw *hw)
+{
+	uint32_t fwsm;
+	DEBUGFUNC();
+
+	fwsm = E1000_READ_REG(hw, FWSM);
+
+	if (hw->mac_type == e1000_ich8lan) {
+		if ((fwsm & E1000_FWSM_MODE_MASK) ==
+		    (E1000_MNG_ICH_IAMT_MODE << E1000_FWSM_MODE_SHIFT))
+			return true;
+	} else if ((fwsm & E1000_FWSM_MODE_MASK) ==
+		       (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT))
+			return true;
+
+	return false;
+}
+
+static int32_t
+e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data)
+{
+	uint16_t swfw = E1000_SWFW_PHY0_SM;
+	uint32_t reg_val;
+	DEBUGFUNC();
+
+	if (e1000_is_second_port(hw))
+		swfw = E1000_SWFW_PHY1_SM;
+
+	if (e1000_swfw_sync_acquire(hw, swfw))
+		return -E1000_ERR_SWFW_SYNC;
+
+	reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT)
+			& E1000_KUMCTRLSTA_OFFSET) | data;
+	E1000_WRITE_REG(hw, KUMCTRLSTA, reg_val);
+	udelay(2);
+
+	return E1000_SUCCESS;
+}
+
+static int32_t
+e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *data)
+{
+	uint16_t swfw = E1000_SWFW_PHY0_SM;
+	uint32_t reg_val;
+	DEBUGFUNC();
+
+	if (e1000_is_second_port(hw))
+		swfw = E1000_SWFW_PHY1_SM;
+
+	if (e1000_swfw_sync_acquire(hw, swfw))
+		return -E1000_ERR_SWFW_SYNC;
+
+	/* Write register address */
+	reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) &
+			E1000_KUMCTRLSTA_OFFSET) | E1000_KUMCTRLSTA_REN;
+	E1000_WRITE_REG(hw, KUMCTRLSTA, reg_val);
+	udelay(2);
+
+	/* Read the data returned */
+	reg_val = E1000_READ_REG(hw, KUMCTRLSTA);
+	*data = (uint16_t)reg_val;
+
+	return E1000_SUCCESS;
+}
+
+/********************************************************************
+* Copper link setup for e1000_phy_gg82563 series.
+*
+* hw - Struct containing variables accessed by shared code
+*********************************************************************/
+static int32_t
+e1000_copper_link_ggp_setup(struct e1000_hw *hw)
+{
+	int32_t ret_val;
+	uint16_t phy_data;
+	uint32_t reg_data;
+
+	DEBUGFUNC();
+
+	if (!hw->phy_reset_disable) {
+		/* Enable CRS on TX for half-duplex operation. */
+		ret_val = e1000_read_phy_reg(hw,
+				GG82563_PHY_MAC_SPEC_CTRL, &phy_data);
+		if (ret_val)
+			return ret_val;
+
+		phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
+		/* Use 25MHz for both link down and 1000BASE-T for Tx clock */
+		phy_data |= GG82563_MSCR_TX_CLK_1000MBPS_25MHZ;
+
+		ret_val = e1000_write_phy_reg(hw,
+				GG82563_PHY_MAC_SPEC_CTRL, phy_data);
+		if (ret_val)
+			return ret_val;
+
+		/* Options:
+		 *   MDI/MDI-X = 0 (default)
+		 *   0 - Auto for all speeds
+		 *   1 - MDI mode
+		 *   2 - MDI-X mode
+		 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
+		 */
+		ret_val = e1000_read_phy_reg(hw,
+				GG82563_PHY_SPEC_CTRL, &phy_data);
+		if (ret_val)
+			return ret_val;
+
+		phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK;
+
+		switch (hw->mdix) {
+		case 1:
+			phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDI;
+			break;
+		case 2:
+			phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDIX;
+			break;
+		case 0:
+		default:
+			phy_data |= GG82563_PSCR_CROSSOVER_MODE_AUTO;
+			break;
+		}
+
+		/* Options:
+		 *   disable_polarity_correction = 0 (default)
+		 *       Automatic Correction for Reversed Cable Polarity
+		 *   0 - Disabled
+		 *   1 - Enabled
+		 */
+		phy_data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE;
+		ret_val = e1000_write_phy_reg(hw,
+				GG82563_PHY_SPEC_CTRL, phy_data);
+
+		if (ret_val)
+			return ret_val;
+
+		/* SW Reset the PHY so all changes take effect */
+		ret_val = e1000_phy_reset(hw);
+		if (ret_val) {
+			DEBUGOUT("Error Resetting the PHY\n");
+			return ret_val;
+		}
+	} /* phy_reset_disable */
+
+	if (hw->mac_type == e1000_80003es2lan) {
+		/* Bypass RX and TX FIFO's */
+		ret_val = e1000_write_kmrn_reg(hw,
+				E1000_KUMCTRLSTA_OFFSET_FIFO_CTRL,
+				E1000_KUMCTRLSTA_FIFO_CTRL_RX_BYPASS
+				| E1000_KUMCTRLSTA_FIFO_CTRL_TX_BYPASS);
+		if (ret_val)
+			return ret_val;
+
+		ret_val = e1000_read_phy_reg(hw,
+				GG82563_PHY_SPEC_CTRL_2, &phy_data);
+		if (ret_val)
+			return ret_val;
+
+		phy_data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG;
+		ret_val = e1000_write_phy_reg(hw,
+				GG82563_PHY_SPEC_CTRL_2, phy_data);
+
+		if (ret_val)
+			return ret_val;
+
+		reg_data = E1000_READ_REG(hw, CTRL_EXT);
+		reg_data &= ~(E1000_CTRL_EXT_LINK_MODE_MASK);
+		E1000_WRITE_REG(hw, CTRL_EXT, reg_data);
+
+		ret_val = e1000_read_phy_reg(hw,
+				GG82563_PHY_PWR_MGMT_CTRL, &phy_data);
+		if (ret_val)
+			return ret_val;
+
+	/* Do not init these registers when the HW is in IAMT mode, since the
+	 * firmware will have already initialized them.  We only initialize
+	 * them if the HW is not in IAMT mode.
+	 */
+		if (e1000_check_mng_mode(hw) == false) {
+			/* Enable Electrical Idle on the PHY */
+			phy_data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE;
+			ret_val = e1000_write_phy_reg(hw,
+					GG82563_PHY_PWR_MGMT_CTRL, phy_data);
+			if (ret_val)
+				return ret_val;
+
+			ret_val = e1000_read_phy_reg(hw,
+					GG82563_PHY_KMRN_MODE_CTRL, &phy_data);
+			if (ret_val)
+				return ret_val;
+
+			phy_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
+			ret_val = e1000_write_phy_reg(hw,
+					GG82563_PHY_KMRN_MODE_CTRL, phy_data);
+
+			if (ret_val)
+				return ret_val;
+		}
+
+		/* Workaround: Disable padding in Kumeran interface in the MAC
+		 * and in the PHY to avoid CRC errors.
+		 */
+		ret_val = e1000_read_phy_reg(hw,
+				GG82563_PHY_INBAND_CTRL, &phy_data);
+		if (ret_val)
+			return ret_val;
+		phy_data |= GG82563_ICR_DIS_PADDING;
+		ret_val = e1000_write_phy_reg(hw,
+				GG82563_PHY_INBAND_CTRL, phy_data);
+		if (ret_val)
+			return ret_val;
+	}
+	return E1000_SUCCESS;
+}
+
+/********************************************************************
+* Copper link setup for e1000_phy_m88 series.
+*
+* hw - Struct containing variables accessed by shared code
+*********************************************************************/
+static int32_t
+e1000_copper_link_mgp_setup(struct e1000_hw *hw)
+{
+	int32_t ret_val;
+	uint16_t phy_data;
+
+	DEBUGFUNC();
+
+	if (hw->phy_reset_disable)
+		return E1000_SUCCESS;
+
+	/* Enable CRS on TX. This must be set for half-duplex operation. */
+	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
+	if (ret_val)
+		return ret_val;
+
+	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+
+	/* Options:
+	 *   MDI/MDI-X = 0 (default)
+	 *   0 - Auto for all speeds
+	 *   1 - MDI mode
+	 *   2 - MDI-X mode
+	 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
+	 */
+	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+
+	switch (hw->mdix) {
+	case 1:
+		phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
+		break;
+	case 2:
+		phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
+		break;
+	case 3:
+		phy_data |= M88E1000_PSCR_AUTO_X_1000T;
+		break;
+	case 0:
+	default:
+		phy_data |= M88E1000_PSCR_AUTO_X_MODE;
+		break;
+	}
+
+	/* Options:
+	 *   disable_polarity_correction = 0 (default)
+	 *       Automatic Correction for Reversed Cable Polarity
+	 *   0 - Disabled
+	 *   1 - Enabled
+	 */
+	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
+	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
+	if (ret_val)
+		return ret_val;
+
+	if (hw->phy_revision < M88E1011_I_REV_4) {
+		/* Force TX_CLK in the Extended PHY Specific Control Register
+		 * to 25MHz clock.
+		 */
+		ret_val = e1000_read_phy_reg(hw,
+				M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
+		if (ret_val)
+			return ret_val;
+
+		phy_data |= M88E1000_EPSCR_TX_CLK_25;
+
+		if ((hw->phy_revision == E1000_REVISION_2) &&
+			(hw->phy_id == M88E1111_I_PHY_ID)) {
+			/* Vidalia Phy, set the downshift counter to 5x */
+			phy_data &= ~(M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK);
+			phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
+			ret_val = e1000_write_phy_reg(hw,
+					M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
+			if (ret_val)
+				return ret_val;
+		} else {
+			/* Configure Master and Slave downshift values */
+			phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK
+					| M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
+			phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X
+					| M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
+			ret_val = e1000_write_phy_reg(hw,
+					M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
+			if (ret_val)
+				return ret_val;
+		}
+	}
+
+	/* SW Reset the PHY so all changes take effect */
+	ret_val = e1000_phy_reset(hw);
+	if (ret_val) {
+		DEBUGOUT("Error Resetting the PHY\n");
+		return ret_val;
+	}
+
+	return E1000_SUCCESS;
+}
+
+/********************************************************************
+* Setup auto-negotiation and flow control advertisements,
+* and then perform auto-negotiation.
+*
+* hw - Struct containing variables accessed by shared code
+*********************************************************************/
+static int32_t
+e1000_copper_link_autoneg(struct e1000_hw *hw)
+{
+	int32_t ret_val;
+	uint16_t phy_data;
+
+	DEBUGFUNC();
+
+	/* Perform some bounds checking on the hw->autoneg_advertised
+	 * parameter.  If this variable is zero, then set it to the default.
+	 */
+	hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
+
+	/* If autoneg_advertised is zero, we assume it was not defaulted
+	 * by the calling code so we set to advertise full capability.
+	 */
+	if (hw->autoneg_advertised == 0)
+		hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+
+	/* IFE phy only supports 10/100 */
+	if (hw->phy_type == e1000_phy_ife)
+		hw->autoneg_advertised &= AUTONEG_ADVERTISE_10_100_ALL;
+
+	DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
+	ret_val = e1000_phy_setup_autoneg(hw);
+	if (ret_val) {
+		DEBUGOUT("Error Setting up Auto-Negotiation\n");
+		return ret_val;
+	}
+	DEBUGOUT("Restarting Auto-Neg\n");
+
+	/* Restart auto-negotiation by setting the Auto Neg Enable bit and
+	 * the Auto Neg Restart bit in the PHY control register.
+	 */
+	ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
+	if (ret_val)
+		return ret_val;
+
+	phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
+	ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
+	if (ret_val)
+		return ret_val;
+
+	/* Does the user want to wait for Auto-Neg to complete here, or
+	 * check at a later time (for example, callback routine).
+	 */
+	/* If we do not wait for autonegtation to complete I
+	 * do not see a valid link status.
+	 * wait_autoneg_complete = 1 .
+	 */
+	if (hw->wait_autoneg_complete) {
+		ret_val = e1000_wait_autoneg(hw);
+		if (ret_val) {
+			DEBUGOUT("Error while waiting for autoneg"
+					"to complete\n");
+			return ret_val;
+		}
+	}
+
+	hw->get_link_status = true;
+
+	return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Config the MAC and the PHY after link is up.
+*   1) Set up the MAC to the current PHY speed/duplex
+*      if we are on 82543.  If we
+*      are on newer silicon, we only need to configure
+*      collision distance in the Transmit Control Register.
+*   2) Set up flow control on the MAC to that established with
+*      the link partner.
+*   3) Config DSP to improve Gigabit link quality for some PHY revisions.
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int32_t
+e1000_copper_link_postconfig(struct e1000_hw *hw)
+{
+	int32_t ret_val;
+	DEBUGFUNC();
+
+	if (hw->mac_type >= e1000_82544) {
+		e1000_config_collision_dist(hw);
+	} else {
+		ret_val = e1000_config_mac_to_phy(hw);
+		if (ret_val) {
+			DEBUGOUT("Error configuring MAC to PHY settings\n");
+			return ret_val;
+		}
+	}
+	ret_val = e1000_config_fc_after_link_up(hw);
+	if (ret_val) {
+		DEBUGOUT("Error Configuring Flow Control\n");
+		return ret_val;
+	}
+	return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Detects which PHY is present and setup the speed and duplex
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int
+e1000_setup_copper_link(struct eth_device *nic)
+{
+	struct e1000_hw *hw = nic->priv;
+	int32_t ret_val;
+	uint16_t i;
+	uint16_t phy_data;
+	uint16_t reg_data;
+
+	DEBUGFUNC();
+
+	switch (hw->mac_type) {
+	case e1000_80003es2lan:
+	case e1000_ich8lan:
+		/* Set the mac to wait the maximum time between each
+		 * iteration and increase the max iterations when
+		 * polling the phy; this fixes erroneous timeouts at 10Mbps. */
+		ret_val = e1000_write_kmrn_reg(hw,
+				GG82563_REG(0x34, 4), 0xFFFF);
+		if (ret_val)
+			return ret_val;
+		ret_val = e1000_read_kmrn_reg(hw,
+				GG82563_REG(0x34, 9), &reg_data);
+		if (ret_val)
+			return ret_val;
+		reg_data |= 0x3F;
+		ret_val = e1000_write_kmrn_reg(hw,
+				GG82563_REG(0x34, 9), reg_data);
+		if (ret_val)
+			return ret_val;
+	default:
+		break;
+	}
+
+	/* Check if it is a valid PHY and set PHY mode if necessary. */
+	ret_val = e1000_copper_link_preconfig(hw);
+	if (ret_val)
+		return ret_val;
+	switch (hw->mac_type) {
+	case e1000_80003es2lan:
+		/* Kumeran registers are written-only */
+		reg_data =
+		E1000_KUMCTRLSTA_INB_CTRL_LINK_STATUS_TX_TIMEOUT_DEFAULT;
+		reg_data |= E1000_KUMCTRLSTA_INB_CTRL_DIS_PADDING;
+		ret_val = e1000_write_kmrn_reg(hw,
+				E1000_KUMCTRLSTA_OFFSET_INB_CTRL, reg_data);
+		if (ret_val)
+			return ret_val;
+		break;
+	default:
+		break;
+	}
+
+	if (hw->phy_type == e1000_phy_igp ||
+		hw->phy_type == e1000_phy_igp_3 ||
+		hw->phy_type == e1000_phy_igp_2) {
+		ret_val = e1000_copper_link_igp_setup(hw);
+		if (ret_val)
+			return ret_val;
+	} else if (hw->phy_type == e1000_phy_m88) {
+		ret_val = e1000_copper_link_mgp_setup(hw);
+		if (ret_val)
+			return ret_val;
+	} else if (hw->phy_type == e1000_phy_gg82563) {
+		ret_val = e1000_copper_link_ggp_setup(hw);
+		if (ret_val)
+			return ret_val;
+	}
+
+	/* always auto */
+	/* Setup autoneg and flow control advertisement
+	  * and perform autonegotiation */
+	ret_val = e1000_copper_link_autoneg(hw);
+	if (ret_val)
+		return ret_val;
+
+	/* Check link status. Wait up to 100 microseconds for link to become
+	 * valid.
+	 */
+	for (i = 0; i < 10; i++) {
+		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
+		if (ret_val)
+			return ret_val;
+		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
+		if (ret_val)
+			return ret_val;
+
+		if (phy_data & MII_SR_LINK_STATUS) {
+			/* Config the MAC and PHY after link is up */
+			ret_val = e1000_copper_link_postconfig(hw);
+			if (ret_val)
+				return ret_val;
+
+			DEBUGOUT("Valid link established!!!\n");
+			return E1000_SUCCESS;
+		}
+		udelay(10);
+	}
+
+	DEBUGOUT("Unable to establish link!!!\n");
+	return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Configures PHY autoneg and flow control advertisement settings
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+int32_t
+e1000_phy_setup_autoneg(struct e1000_hw *hw)
+{
+	int32_t ret_val;
+	uint16_t mii_autoneg_adv_reg;
+	uint16_t mii_1000t_ctrl_reg;
+
+	DEBUGFUNC();
+
+	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
+	ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
+	if (ret_val)
+		return ret_val;
+
+	if (hw->phy_type != e1000_phy_ife) {
+		/* Read the MII 1000Base-T Control Register (Address 9). */
+		ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL,
+				&mii_1000t_ctrl_reg);
+		if (ret_val)
+			return ret_val;
+	} else
+		mii_1000t_ctrl_reg = 0;
+
+	/* Need to parse both autoneg_advertised and fc and set up
+	 * the appropriate PHY registers.  First we will parse for
+	 * autoneg_advertised software override.  Since we can advertise
+	 * a plethora of combinations, we need to check each bit
+	 * individually.
+	 */
+
+	/* First we clear all the 10/100 mb speed bits in the Auto-Neg
+	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
+	 * the  1000Base-T Control Register (Address 9).
+	 */
+	mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
+	mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
+
+	DEBUGOUT("autoneg_advertised %x\n", hw->autoneg_advertised);
+
+	/* Do we want to advertise 10 Mb Half Duplex? */
+	if (hw->autoneg_advertised & ADVERTISE_10_HALF) {
+		DEBUGOUT("Advertise 10mb Half duplex\n");
+		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
+	}
+
+	/* Do we want to advertise 10 Mb Full Duplex? */
+	if (hw->autoneg_advertised & ADVERTISE_10_FULL) {
+		DEBUGOUT("Advertise 10mb Full duplex\n");
+		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
+	}
+
+	/* Do we want to advertise 100 Mb Half Duplex? */
+	if (hw->autoneg_advertised & ADVERTISE_100_HALF) {
+		DEBUGOUT("Advertise 100mb Half duplex\n");
+		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
+	}
+
+	/* Do we want to advertise 100 Mb Full Duplex? */
+	if (hw->autoneg_advertised & ADVERTISE_100_FULL) {
+		DEBUGOUT("Advertise 100mb Full duplex\n");
+		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
+	}
+
+	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
+	if (hw->autoneg_advertised & ADVERTISE_1000_HALF) {
+		DEBUGOUT
+		    ("Advertise 1000mb Half duplex requested, request denied!\n");
+	}
+
+	/* Do we want to advertise 1000 Mb Full Duplex? */
+	if (hw->autoneg_advertised & ADVERTISE_1000_FULL) {
+		DEBUGOUT("Advertise 1000mb Full duplex\n");
+		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
+	}
+
+	/* Check for a software override of the flow control settings, and
+	 * setup the PHY advertisement registers accordingly.  If
+	 * auto-negotiation is enabled, then software will have to set the
+	 * "PAUSE" bits to the correct value in the Auto-Negotiation
+	 * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation.
+	 *
+	 * The possible values of the "fc" parameter are:
+	 *	0:  Flow control is completely disabled
+	 *	1:  Rx flow control is enabled (we can receive pause frames
+	 *	    but not send pause frames).
+	 *	2:  Tx flow control is enabled (we can send pause frames
+	 *	    but we do not support receiving pause frames).
+	 *	3:  Both Rx and TX flow control (symmetric) are enabled.
+	 *  other:  No software override.  The flow control configuration
+	 *	    in the EEPROM is used.
+	 */
+	switch (hw->fc) {
+	case e1000_fc_none:	/* 0 */
+		/* Flow control (RX & TX) is completely disabled by a
+		 * software over-ride.
+		 */
+		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+		break;
+	case e1000_fc_rx_pause:	/* 1 */
+		/* RX Flow control is enabled, and TX Flow control is
+		 * disabled, by a software over-ride.
+		 */
+		/* Since there really isn't a way to advertise that we are
+		 * capable of RX Pause ONLY, we will advertise that we
+		 * support both symmetric and asymmetric RX PAUSE.  Later
+		 * (in e1000_config_fc_after_link_up) we will disable the
+		 *hw's ability to send PAUSE frames.
+		 */
+		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+		break;
+	case e1000_fc_tx_pause:	/* 2 */
+		/* TX Flow control is enabled, and RX Flow control is
+		 * disabled, by a software over-ride.
+		 */
+		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
+		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
+		break;
+	case e1000_fc_full:	/* 3 */
+		/* Flow control (both RX and TX) is enabled by a software
+		 * over-ride.
+		 */
+		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+		break;
+	default:
+		DEBUGOUT("Flow control param set incorrectly\n");
+		return -E1000_ERR_CONFIG;
+	}
+
+	ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
+	if (ret_val)
+		return ret_val;
+
+	DEBUGOUT("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
+
+	if (hw->phy_type != e1000_phy_ife) {
+		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
+				mii_1000t_ctrl_reg);
+		if (ret_val)
+			return ret_val;
+	}
+
+	return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Sets the collision distance in the Transmit Control register
+*
+* hw - Struct containing variables accessed by shared code
+*
+* Link should have been established previously. Reads the speed and duplex
+* information from the Device Status register.
+******************************************************************************/
+static void
+e1000_config_collision_dist(struct e1000_hw *hw)
+{
+	uint32_t tctl, coll_dist;
+
+	DEBUGFUNC();
+
+	if (hw->mac_type < e1000_82543)
+		coll_dist = E1000_COLLISION_DISTANCE_82542;
+	else
+		coll_dist = E1000_COLLISION_DISTANCE;
+
+	tctl = E1000_READ_REG(hw, TCTL);
+
+	tctl &= ~E1000_TCTL_COLD;
+	tctl |= coll_dist << E1000_COLD_SHIFT;
+
+	E1000_WRITE_REG(hw, TCTL, tctl);
+	E1000_WRITE_FLUSH(hw);
+}
+
+/******************************************************************************
+* Sets MAC speed and duplex settings to reflect the those in the PHY
+*
+* hw - Struct containing variables accessed by shared code
+* mii_reg - data to write to the MII control register
+*
+* The contents of the PHY register containing the needed information need to
+* be passed in.
+******************************************************************************/
+static int
+e1000_config_mac_to_phy(struct e1000_hw *hw)
+{
+	uint32_t ctrl;
+	uint16_t phy_data;
+
+	DEBUGFUNC();
+
+	/* Read the Device Control Register and set the bits to Force Speed
+	 * and Duplex.
+	 */
+	ctrl = E1000_READ_REG(hw, CTRL);
+	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
+	ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
+
+	/* Set up duplex in the Device Control and Transmit Control
+	 * registers depending on negotiated values.
+	 */
+	if (e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
+		DEBUGOUT("PHY Read Error\n");
+		return -E1000_ERR_PHY;
+	}
+	if (phy_data & M88E1000_PSSR_DPLX)
+		ctrl |= E1000_CTRL_FD;
+	else
+		ctrl &= ~E1000_CTRL_FD;
+
+	e1000_config_collision_dist(hw);
+
+	/* Set up speed in the Device Control register depending on
+	 * negotiated values.
+	 */
+	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
+		ctrl |= E1000_CTRL_SPD_1000;
+	else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
+		ctrl |= E1000_CTRL_SPD_100;
+	/* Write the configured values back to the Device Control Reg. */
+	E1000_WRITE_REG(hw, CTRL, ctrl);
+	return 0;
+}
+
+/******************************************************************************
+ * Forces the MAC's flow control settings.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Sets the TFCE and RFCE bits in the device control register to reflect
+ * the adapter settings. TFCE and RFCE need to be explicitly set by
+ * software when a Copper PHY is used because autonegotiation is managed
+ * by the PHY rather than the MAC. Software must also configure these
+ * bits when link is forced on a fiber connection.
+ *****************************************************************************/
+static int
+e1000_force_mac_fc(struct e1000_hw *hw)
+{
+	uint32_t ctrl;
+
+	DEBUGFUNC();
+
+	/* Get the current configuration of the Device Control Register */
+	ctrl = E1000_READ_REG(hw, CTRL);
+
+	/* Because we didn't get link via the internal auto-negotiation
+	 * mechanism (we either forced link or we got link via PHY
+	 * auto-neg), we have to manually enable/disable transmit an
+	 * receive flow control.
+	 *
+	 * The "Case" statement below enables/disable flow control
+	 * according to the "hw->fc" parameter.
+	 *
+	 * The possible values of the "fc" parameter are:
+	 *	0:  Flow control is completely disabled
+	 *	1:  Rx flow control is enabled (we can receive pause
+	 *	    frames but not send pause frames).
+	 *	2:  Tx flow control is enabled (we can send pause frames
+	 *	    frames but we do not receive pause frames).
+	 *	3:  Both Rx and TX flow control (symmetric) is enabled.
+	 *  other:  No other values should be possible at this point.
+	 */
+
+	switch (hw->fc) {
+	case e1000_fc_none:
+		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
+		break;
+	case e1000_fc_rx_pause:
+		ctrl &= (~E1000_CTRL_TFCE);
+		ctrl |= E1000_CTRL_RFCE;
+		break;
+	case e1000_fc_tx_pause:
+		ctrl &= (~E1000_CTRL_RFCE);
+		ctrl |= E1000_CTRL_TFCE;
+		break;
+	case e1000_fc_full:
+		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
+		break;
+	default:
+		DEBUGOUT("Flow control param set incorrectly\n");
+		return -E1000_ERR_CONFIG;
+	}
+
+	/* Disable TX Flow Control for 82542 (rev 2.0) */
+	if (hw->mac_type == e1000_82542_rev2_0)
+		ctrl &= (~E1000_CTRL_TFCE);
+
+	E1000_WRITE_REG(hw, CTRL, ctrl);
+	return 0;
+}
+
+/******************************************************************************
+ * Configures flow control settings after link is established
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Should be called immediately after a valid link has been established.
+ * Forces MAC flow control settings if link was forced. When in MII/GMII mode
+ * and autonegotiation is enabled, the MAC flow control settings will be set
+ * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
+ * and RFCE bits will be automaticaly set to the negotiated flow control mode.
+ *****************************************************************************/
+static int32_t
+e1000_config_fc_after_link_up(struct e1000_hw *hw)
+{
+	int32_t ret_val;
+	uint16_t mii_status_reg;
+	uint16_t mii_nway_adv_reg;
+	uint16_t mii_nway_lp_ability_reg;
+	uint16_t speed;
+	uint16_t duplex;
+
+	DEBUGFUNC();
+
+	/* Check for the case where we have fiber media and auto-neg failed
+	 * so we had to force link.  In this case, we need to force the
+	 * configuration of the MAC to match the "fc" parameter.
+	 */
+	if (((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed))
+		|| ((hw->media_type == e1000_media_type_internal_serdes)
+		&& (hw->autoneg_failed))
+		|| ((hw->media_type == e1000_media_type_copper)
+		&& (!hw->autoneg))) {
+		ret_val = e1000_force_mac_fc(hw);
+		if (ret_val < 0) {
+			DEBUGOUT("Error forcing flow control settings\n");
+			return ret_val;
+		}
+	}
+
+	/* Check for the case where we have copper media and auto-neg is
+	 * enabled.  In this case, we need to check and see if Auto-Neg
+	 * has completed, and if so, how the PHY and link partner has
+	 * flow control configured.
+	 */
+	if (hw->media_type == e1000_media_type_copper) {
+		/* Read the MII Status Register and check to see if AutoNeg
+		 * has completed.  We read this twice because this reg has
+		 * some "sticky" (latched) bits.
+		 */
+		if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+			DEBUGOUT("PHY Read Error \n");
+			return -E1000_ERR_PHY;
+		}
+		if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
+			DEBUGOUT("PHY Read Error \n");
+			return -E1000_ERR_PHY;
+		}
+
+		if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
+			/* The AutoNeg process has completed, so we now need to
+			 * read both the Auto Negotiation Advertisement Register
+			 * (Address 4) and the Auto_Negotiation Base Page Ability
+			 * Register (Address 5) to determine how flow control was
+			 * negotiated.
+			 */
+			if (e1000_read_phy_reg
+			    (hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg) < 0) {
+				DEBUGOUT("PHY Read Error\n");
+				return -E1000_ERR_PHY;
+			}
+			if (e1000_read_phy_reg
+			    (hw, PHY_LP_ABILITY,
+			     &mii_nway_lp_ability_reg) < 0) {
+				DEBUGOUT("PHY Read Error\n");
+				return -E1000_ERR_PHY;
+			}
+
+			/* Two bits in the Auto Negotiation Advertisement Register
+			 * (Address 4) and two bits in the Auto Negotiation Base
+			 * Page Ability Register (Address 5) determine flow control
+			 * for both the PHY and the link partner.  The following
+			 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
+			 * 1999, describes these PAUSE resolution bits and how flow
+			 * control is determined based upon these settings.
+			 * NOTE:  DC = Don't Care
+			 *
+			 *   LOCAL DEVICE  |   LINK PARTNER
+			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
+			 *-------|---------|-------|---------|--------------------
+			 *   0	 |    0    |  DC   |   DC    | e1000_fc_none
+			 *   0	 |    1    |   0   |   DC    | e1000_fc_none
+			 *   0	 |    1    |   1   |	0    | e1000_fc_none
+			 *   0	 |    1    |   1   |	1    | e1000_fc_tx_pause
+			 *   1	 |    0    |   0   |   DC    | e1000_fc_none
+			 *   1	 |   DC    |   1   |   DC    | e1000_fc_full
+			 *   1	 |    1    |   0   |	0    | e1000_fc_none
+			 *   1	 |    1    |   0   |	1    | e1000_fc_rx_pause
+			 *
+			 */
+			/* Are both PAUSE bits set to 1?  If so, this implies
+			 * Symmetric Flow Control is enabled at both ends.  The
+			 * ASM_DIR bits are irrelevant per the spec.
+			 *
+			 * For Symmetric Flow Control:
+			 *
+			 *   LOCAL DEVICE  |   LINK PARTNER
+			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+			 *-------|---------|-------|---------|--------------------
+			 *   1	 |   DC    |   1   |   DC    | e1000_fc_full
+			 *
+			 */
+			if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+			    (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
+				/* Now we need to check if the user selected RX ONLY
+				 * of pause frames.  In this case, we had to advertise
+				 * FULL flow control because we could not advertise RX
+				 * ONLY. Hence, we must now check to see if we need to
+				 * turn OFF  the TRANSMISSION of PAUSE frames.
+				 */
+				if (hw->original_fc == e1000_fc_full) {
+					hw->fc = e1000_fc_full;
+					DEBUGOUT("Flow Control = FULL.\r\n");
+				} else {
+					hw->fc = e1000_fc_rx_pause;
+					DEBUGOUT
+					    ("Flow Control = RX PAUSE frames only.\r\n");
+				}
+			}
+			/* For receiving PAUSE frames ONLY.
+			 *
+			 *   LOCAL DEVICE  |   LINK PARTNER
+			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+			 *-------|---------|-------|---------|--------------------
+			 *   0	 |    1    |   1   |	1    | e1000_fc_tx_pause
+			 *
+			 */
+			else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
+				 (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
+				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
+			{
+				hw->fc = e1000_fc_tx_pause;
+				DEBUGOUT
+				    ("Flow Control = TX PAUSE frames only.\r\n");
+			}
+			/* For transmitting PAUSE frames ONLY.
+			 *
+			 *   LOCAL DEVICE  |   LINK PARTNER
+			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+			 *-------|---------|-------|---------|--------------------
+			 *   1	 |    1    |   0   |	1    | e1000_fc_rx_pause
+			 *
+			 */
+			else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
+				 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
+				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
+			{
+				hw->fc = e1000_fc_rx_pause;
+				DEBUGOUT
+				    ("Flow Control = RX PAUSE frames only.\r\n");
+			}
+			/* Per the IEEE spec, at this point flow control should be
+			 * disabled.  However, we want to consider that we could
+			 * be connected to a legacy switch that doesn't advertise
+			 * desired flow control, but can be forced on the link
+			 * partner.  So if we advertised no flow control, that is
+			 * what we will resolve to.  If we advertised some kind of
+			 * receive capability (Rx Pause Only or Full Flow Control)
+			 * and the link partner advertised none, we will configure
+			 * ourselves to enable Rx Flow Control only.  We can do
+			 * this safely for two reasons:  If the link partner really
+			 * didn't want flow control enabled, and we enable Rx, no
+			 * harm done since we won't be receiving any PAUSE frames
+			 * anyway.  If the intent on the link partner was to have
+			 * flow control enabled, then by us enabling RX only, we
+			 * can at least receive pause frames and process them.
+			 * This is a good idea because in most cases, since we are
+			 * predominantly a server NIC, more times than not we will
+			 * be asked to delay transmission of packets than asking
+			 * our link partner to pause transmission of frames.
+			 */
+			else if (hw->original_fc == e1000_fc_none ||
+				 hw->original_fc == e1000_fc_tx_pause) {
+				hw->fc = e1000_fc_none;
+				DEBUGOUT("Flow Control = NONE.\r\n");
+			} else {
+				hw->fc = e1000_fc_rx_pause;
+				DEBUGOUT
+				    ("Flow Control = RX PAUSE frames only.\r\n");
+			}
+
+			/* Now we need to do one last check...	If we auto-
+			 * negotiated to HALF DUPLEX, flow control should not be
+			 * enabled per IEEE 802.3 spec.
+			 */
+			e1000_get_speed_and_duplex(hw, &speed, &duplex);
+
+			if (duplex == HALF_DUPLEX)
+				hw->fc = e1000_fc_none;
+
+			/* Now we call a subroutine to actually force the MAC
+			 * controller to use the correct flow control settings.
+			 */
+			ret_val = e1000_force_mac_fc(hw);
+			if (ret_val < 0) {
+				DEBUGOUT
+				    ("Error forcing flow control settings\n");
+				return ret_val;
+			}
+		} else {
+			DEBUGOUT
+			    ("Copper PHY and Auto Neg has not completed.\r\n");
+		}
+	}
+	return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Checks to see if the link status of the hardware has changed.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Called by any function that needs to check the link status of the adapter.
+ *****************************************************************************/
+static int
+e1000_check_for_link(struct eth_device *nic)
+{
+	struct e1000_hw *hw = nic->priv;
+	uint32_t rxcw;
+	uint32_t ctrl;
+	uint32_t status;
+	uint32_t rctl;
+	uint32_t signal;
+	int32_t ret_val;
+	uint16_t phy_data;
+	uint16_t lp_capability;
+
+	DEBUGFUNC();
+
+	/* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
+	 * set when the optics detect a signal. On older adapters, it will be
+	 * cleared when there is a signal
+	 */
+	ctrl = E1000_READ_REG(hw, CTRL);
+	if ((hw->mac_type > e1000_82544) && !(ctrl & E1000_CTRL_ILOS))
+		signal = E1000_CTRL_SWDPIN1;
+	else
+		signal = 0;
+
+	status = E1000_READ_REG(hw, STATUS);
+	rxcw = E1000_READ_REG(hw, RXCW);
+	DEBUGOUT("ctrl: %#08x status %#08x rxcw %#08x\n", ctrl, status, rxcw);
+
+	/* If we have a copper PHY then we only want to go out to the PHY
+	 * registers to see if Auto-Neg has completed and/or if our link
+	 * status has changed.	The get_link_status flag will be set if we
+	 * receive a Link Status Change interrupt or we have Rx Sequence
+	 * Errors.
+	 */
+	if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {
+		/* First we want to see if the MII Status Register reports
+		 * link.  If so, then we want to get the current speed/duplex
+		 * of the PHY.
+		 * Read the register twice since the link bit is sticky.
+		 */
+		if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+			DEBUGOUT("PHY Read Error\n");
+			return -E1000_ERR_PHY;
+		}
+		if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+			DEBUGOUT("PHY Read Error\n");
+			return -E1000_ERR_PHY;
+		}
+
+		if (phy_data & MII_SR_LINK_STATUS) {
+			hw->get_link_status = false;
+		} else {
+			/* No link detected */
+			return -E1000_ERR_NOLINK;
+		}
+
+		/* We have a M88E1000 PHY and Auto-Neg is enabled.  If we
+		 * have Si on board that is 82544 or newer, Auto
+		 * Speed Detection takes care of MAC speed/duplex
+		 * configuration.  So we only need to configure Collision
+		 * Distance in the MAC.  Otherwise, we need to force
+		 * speed/duplex on the MAC to the current PHY speed/duplex
+		 * settings.
+		 */
+		if (hw->mac_type >= e1000_82544)
+			e1000_config_collision_dist(hw);
+		else {
+			ret_val = e1000_config_mac_to_phy(hw);
+			if (ret_val < 0) {
+				DEBUGOUT
+				    ("Error configuring MAC to PHY settings\n");
+				return ret_val;
+			}
+		}
+
+		/* Configure Flow Control now that Auto-Neg has completed. First, we
+		 * need to restore the desired flow control settings because we may
+		 * have had to re-autoneg with a different link partner.
+		 */
+		ret_val = e1000_config_fc_after_link_up(hw);
+		if (ret_val < 0) {
+			DEBUGOUT("Error configuring flow control\n");
+			return ret_val;
+		}
+
+		/* At this point we know that we are on copper and we have
+		 * auto-negotiated link.  These are conditions for checking the link
+		 * parter capability register.	We use the link partner capability to
+		 * determine if TBI Compatibility needs to be turned on or off.  If
+		 * the link partner advertises any speed in addition to Gigabit, then
+		 * we assume that they are GMII-based, and TBI compatibility is not
+		 * needed. If no other speeds are advertised, we assume the link
+		 * partner is TBI-based, and we turn on TBI Compatibility.
+		 */
+		if (hw->tbi_compatibility_en) {
+			if (e1000_read_phy_reg
+			    (hw, PHY_LP_ABILITY, &lp_capability) < 0) {
+				DEBUGOUT("PHY Read Error\n");
+				return -E1000_ERR_PHY;
+			}
+			if (lp_capability & (NWAY_LPAR_10T_HD_CAPS |
+					     NWAY_LPAR_10T_FD_CAPS |
+					     NWAY_LPAR_100TX_HD_CAPS |
+					     NWAY_LPAR_100TX_FD_CAPS |
+					     NWAY_LPAR_100T4_CAPS)) {
+				/* If our link partner advertises anything in addition to
+				 * gigabit, we do not need to enable TBI compatibility.
+				 */
+				if (hw->tbi_compatibility_on) {
+					/* If we previously were in the mode, turn it off. */
+					rctl = E1000_READ_REG(hw, RCTL);
+					rctl &= ~E1000_RCTL_SBP;
+					E1000_WRITE_REG(hw, RCTL, rctl);
+					hw->tbi_compatibility_on = false;
+				}
+			} else {
+				/* If TBI compatibility is was previously off, turn it on. For
+				 * compatibility with a TBI link partner, we will store bad
+				 * packets. Some frames have an additional byte on the end and
+				 * will look like CRC errors to to the hardware.
+				 */
+				if (!hw->tbi_compatibility_on) {
+					hw->tbi_compatibility_on = true;
+					rctl = E1000_READ_REG(hw, RCTL);
+					rctl |= E1000_RCTL_SBP;
+					E1000_WRITE_REG(hw, RCTL, rctl);
+				}
+			}
+		}
+	}
+	/* If we don't have link (auto-negotiation failed or link partner cannot
+	 * auto-negotiate), the cable is plugged in (we have signal), and our
+	 * link partner is not trying to auto-negotiate with us (we are receiving
+	 * idles or data), we need to force link up. We also need to give
+	 * auto-negotiation time to complete, in case the cable was just plugged
+	 * in. The autoneg_failed flag does this.
+	 */
+	else if ((hw->media_type == e1000_media_type_fiber) &&
+		 (!(status & E1000_STATUS_LU)) &&
+		 ((ctrl & E1000_CTRL_SWDPIN1) == signal) &&
+		 (!(rxcw & E1000_RXCW_C))) {
+		if (hw->autoneg_failed == 0) {
+			hw->autoneg_failed = 1;
+			return 0;
+		}
+		DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\r\n");
+
+		/* Disable auto-negotiation in the TXCW register */
+		E1000_WRITE_REG(hw, TXCW, (hw->txcw & ~E1000_TXCW_ANE));
+
+		/* Force link-up and also force full-duplex. */
+		ctrl = E1000_READ_REG(hw, CTRL);
+		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
+		E1000_WRITE_REG(hw, CTRL, ctrl);
+
+		/* Configure Flow Control after forcing link up. */
+		ret_val = e1000_config_fc_after_link_up(hw);
+		if (ret_val < 0) {
+			DEBUGOUT("Error configuring flow control\n");
+			return ret_val;
+		}
+	}
+	/* If we are forcing link and we are receiving /C/ ordered sets, re-enable
+	 * auto-negotiation in the TXCW register and disable forced link in the
+	 * Device Control register in an attempt to auto-negotiate with our link
+	 * partner.
+	 */
+	else if ((hw->media_type == e1000_media_type_fiber) &&
+		 (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
+		DEBUGOUT
+		    ("RXing /C/, enable AutoNeg and stop forcing link.\r\n");
+		E1000_WRITE_REG(hw, TXCW, hw->txcw);
+		E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
+	}
+	return 0;
+}
+
+/******************************************************************************
+* Configure the MAC-to-PHY interface for 10/100Mbps
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int32_t
+e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, uint16_t duplex)
+{
+	int32_t ret_val = E1000_SUCCESS;
+	uint32_t tipg;
+	uint16_t reg_data;
+
+	DEBUGFUNC();
+
+	reg_data = E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT;
+	ret_val = e1000_write_kmrn_reg(hw,
+			E1000_KUMCTRLSTA_OFFSET_HD_CTRL, reg_data);
+	if (ret_val)
+		return ret_val;
+
+	/* Configure Transmit Inter-Packet Gap */
+	tipg = E1000_READ_REG(hw, TIPG);
+	tipg &= ~E1000_TIPG_IPGT_MASK;
+	tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_10_100;
+	E1000_WRITE_REG(hw, TIPG, tipg);
+
+	ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);
+
+	if (ret_val)
+		return ret_val;
+
+	if (duplex == HALF_DUPLEX)
+		reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER;
+	else
+		reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
+
+	ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
+
+	return ret_val;
+}
+
+static int32_t
+e1000_configure_kmrn_for_1000(struct e1000_hw *hw)
+{
+	int32_t ret_val = E1000_SUCCESS;
+	uint16_t reg_data;
+	uint32_t tipg;
+
+	DEBUGFUNC();
+
+	reg_data = E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT;
+	ret_val = e1000_write_kmrn_reg(hw,
+			E1000_KUMCTRLSTA_OFFSET_HD_CTRL, reg_data);
+	if (ret_val)
+		return ret_val;
+
+	/* Configure Transmit Inter-Packet Gap */
+	tipg = E1000_READ_REG(hw, TIPG);
+	tipg &= ~E1000_TIPG_IPGT_MASK;
+	tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000;
+	E1000_WRITE_REG(hw, TIPG, tipg);
+
+	ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);
+
+	if (ret_val)
+		return ret_val;
+
+	reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
+	ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
+
+	return ret_val;
+}
+
+/******************************************************************************
+ * Detects the current speed and duplex settings of the hardware.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * speed - Speed of the connection
+ * duplex - Duplex setting of the connection
+ *****************************************************************************/
+static int
+e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t *speed,
+		uint16_t *duplex)
+{
+	uint32_t status;
+	int32_t ret_val;
+	uint16_t phy_data;
+
+	DEBUGFUNC();
+
+	if (hw->mac_type >= e1000_82543) {
+		status = E1000_READ_REG(hw, STATUS);
+		if (status & E1000_STATUS_SPEED_1000) {
+			*speed = SPEED_1000;
+			DEBUGOUT("1000 Mbs, ");
+		} else if (status & E1000_STATUS_SPEED_100) {
+			*speed = SPEED_100;
+			DEBUGOUT("100 Mbs, ");
+		} else {
+			*speed = SPEED_10;
+			DEBUGOUT("10 Mbs, ");
+		}
+
+		if (status & E1000_STATUS_FD) {
+			*duplex = FULL_DUPLEX;
+			DEBUGOUT("Full Duplex\r\n");
+		} else {
+			*duplex = HALF_DUPLEX;
+			DEBUGOUT(" Half Duplex\r\n");
+		}
+	} else {
+		DEBUGOUT("1000 Mbs, Full Duplex\r\n");
+		*speed = SPEED_1000;
+		*duplex = FULL_DUPLEX;
+	}
+
+	/* IGP01 PHY may advertise full duplex operation after speed downgrade
+	 * even if it is operating at half duplex.  Here we set the duplex
+	 * settings to match the duplex in the link partner's capabilities.
+	 */
+	if (hw->phy_type == e1000_phy_igp && hw->speed_downgraded) {
+		ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data);
+		if (ret_val)
+			return ret_val;
+
+		if (!(phy_data & NWAY_ER_LP_NWAY_CAPS))
+			*duplex = HALF_DUPLEX;
+		else {
+			ret_val = e1000_read_phy_reg(hw,
+					PHY_LP_ABILITY, &phy_data);
+			if (ret_val)
+				return ret_val;
+			if ((*speed == SPEED_100 &&
+				!(phy_data & NWAY_LPAR_100TX_FD_CAPS))
+				|| (*speed == SPEED_10
+				&& !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
+				*duplex = HALF_DUPLEX;
+		}
+	}
+
+	if ((hw->mac_type == e1000_80003es2lan) &&
+		(hw->media_type == e1000_media_type_copper)) {
+		if (*speed == SPEED_1000)
+			ret_val = e1000_configure_kmrn_for_1000(hw);
+		else
+			ret_val = e1000_configure_kmrn_for_10_100(hw, *duplex);
+		if (ret_val)
+			return ret_val;
+	}
+	return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Blocks until autoneg completes or times out (~4.5 seconds)
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int
+e1000_wait_autoneg(struct e1000_hw *hw)
+{
+	uint16_t i;
+	uint16_t phy_data;
+
+	DEBUGFUNC();
+	DEBUGOUT("Waiting for Auto-Neg to complete.\n");
+
+	/* We will wait for autoneg to complete or 4.5 seconds to expire. */
+	for (i = PHY_AUTO_NEG_TIME; i > 0; i--) {
+		/* Read the MII Status Register and wait for Auto-Neg
+		 * Complete bit to be set.
+		 */
+		if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+			DEBUGOUT("PHY Read Error\n");
+			return -E1000_ERR_PHY;
+		}
+		if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+			DEBUGOUT("PHY Read Error\n");
+			return -E1000_ERR_PHY;
+		}
+		if (phy_data & MII_SR_AUTONEG_COMPLETE) {
+			DEBUGOUT("Auto-Neg complete.\n");
+			return 0;
+		}
+		mdelay(100);
+	}
+	DEBUGOUT("Auto-Neg timedout.\n");
+	return -E1000_ERR_TIMEOUT;
+}
+
+/******************************************************************************
+* Raises the Management Data Clock
+*
+* hw - Struct containing variables accessed by shared code
+* ctrl - Device control register's current value
+******************************************************************************/
+static void
+e1000_raise_mdi_clk(struct e1000_hw *hw, uint32_t * ctrl)
+{
+	/* Raise the clock input to the Management Data Clock (by setting the MDC
+	 * bit), and then delay 2 microseconds.
+	 */
+	E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
+	E1000_WRITE_FLUSH(hw);
+	udelay(2);
+}
+
+/******************************************************************************
+* Lowers the Management Data Clock
+*
+* hw - Struct containing variables accessed by shared code
+* ctrl - Device control register's current value
+******************************************************************************/
+static void
+e1000_lower_mdi_clk(struct e1000_hw *hw, uint32_t * ctrl)
+{
+	/* Lower the clock input to the Management Data Clock (by clearing the MDC
+	 * bit), and then delay 2 microseconds.
+	 */
+	E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
+	E1000_WRITE_FLUSH(hw);
+	udelay(2);
+}
+
+/******************************************************************************
+* Shifts data bits out to the PHY
+*
+* hw - Struct containing variables accessed by shared code
+* data - Data to send out to the PHY
+* count - Number of bits to shift out
+*
+* Bits are shifted out in MSB to LSB order.
+******************************************************************************/
+static void
+e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, uint16_t count)
+{
+	uint32_t ctrl;
+	uint32_t mask;
+
+	/* We need to shift "count" number of bits out to the PHY. So, the value
+	 * in the "data" parameter will be shifted out to the PHY one bit at a
+	 * time. In order to do this, "data" must be broken down into bits.
+	 */
+	mask = 0x01;
+	mask <<= (count - 1);
+
+	ctrl = E1000_READ_REG(hw, CTRL);
+
+	/* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
+	ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
+
+	while (mask) {
+		/* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
+		 * then raising and lowering the Management Data Clock. A "0" is
+		 * shifted out to the PHY by setting the MDIO bit to "0" and then
+		 * raising and lowering the clock.
+		 */
+		if (data & mask)
+			ctrl |= E1000_CTRL_MDIO;
+		else
+			ctrl &= ~E1000_CTRL_MDIO;
+
+		E1000_WRITE_REG(hw, CTRL, ctrl);
+		E1000_WRITE_FLUSH(hw);
+
+		udelay(2);
+
+		e1000_raise_mdi_clk(hw, &ctrl);
+		e1000_lower_mdi_clk(hw, &ctrl);
+
+		mask = mask >> 1;
+	}
+}
+
+/******************************************************************************
+* Shifts data bits in from the PHY
+*
+* hw - Struct containing variables accessed by shared code
+*
+* Bits are shifted in in MSB to LSB order.
+******************************************************************************/
+static uint16_t
+e1000_shift_in_mdi_bits(struct e1000_hw *hw)
+{
+	uint32_t ctrl;
+	uint16_t data = 0;
+	uint8_t i;
+
+	/* In order to read a register from the PHY, we need to shift in a total
+	 * of 18 bits from the PHY. The first two bit (turnaround) times are used
+	 * to avoid contention on the MDIO pin when a read operation is performed.
+	 * These two bits are ignored by us and thrown away. Bits are "shifted in"
+	 * by raising the input to the Management Data Clock (setting the MDC bit),
+	 * and then reading the value of the MDIO bit.
+	 */
+	ctrl = E1000_READ_REG(hw, CTRL);
+
+	/* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
+	ctrl &= ~E1000_CTRL_MDIO_DIR;
+	ctrl &= ~E1000_CTRL_MDIO;
+
+	E1000_WRITE_REG(hw, CTRL, ctrl);
+	E1000_WRITE_FLUSH(hw);
+
+	/* Raise and Lower the clock before reading in the data. This accounts for
+	 * the turnaround bits. The first clock occurred when we clocked out the
+	 * last bit of the Register Address.
+	 */
+	e1000_raise_mdi_clk(hw, &ctrl);
+	e1000_lower_mdi_clk(hw, &ctrl);
+
+	for (data = 0, i = 0; i < 16; i++) {
+		data = data << 1;
+		e1000_raise_mdi_clk(hw, &ctrl);
+		ctrl = E1000_READ_REG(hw, CTRL);
+		/* Check to see if we shifted in a "1". */
+		if (ctrl & E1000_CTRL_MDIO)
+			data |= 1;
+		e1000_lower_mdi_clk(hw, &ctrl);
+	}
+
+	e1000_raise_mdi_clk(hw, &ctrl);
+	e1000_lower_mdi_clk(hw, &ctrl);
+
+	return data;
+}
+
+/*****************************************************************************
+* Reads the value from a PHY register
+*
+* hw - Struct containing variables accessed by shared code
+* reg_addr - address of the PHY register to read
+******************************************************************************/
+static int
+e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t * phy_data)
+{
+	uint32_t i;
+	uint32_t mdic = 0;
+	const uint32_t phy_addr = 1;
+
+	if (reg_addr > MAX_PHY_REG_ADDRESS) {
+		DEBUGOUT("PHY Address %d is out of range\n", reg_addr);
+		return -E1000_ERR_PARAM;
+	}
+
+	if (hw->mac_type > e1000_82543) {
+		/* Set up Op-code, Phy Address, and register address in the MDI
+		 * Control register.  The MAC will take care of interfacing with the
+		 * PHY to retrieve the desired data.
+		 */
+		mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
+			(phy_addr << E1000_MDIC_PHY_SHIFT) |
+			(E1000_MDIC_OP_READ));
+
+		E1000_WRITE_REG(hw, MDIC, mdic);
+
+		/* Poll the ready bit to see if the MDI read completed */
+		for (i = 0; i < 64; i++) {
+			udelay(10);
+			mdic = E1000_READ_REG(hw, MDIC);
+			if (mdic & E1000_MDIC_READY)
+				break;
+		}
+		if (!(mdic & E1000_MDIC_READY)) {
+			DEBUGOUT("MDI Read did not complete\n");
+			return -E1000_ERR_PHY;
+		}
+		if (mdic & E1000_MDIC_ERROR) {
+			DEBUGOUT("MDI Error\n");
+			return -E1000_ERR_PHY;
+		}
+		*phy_data = (uint16_t) mdic;
+	} else {
+		/* We must first send a preamble through the MDIO pin to signal the
+		 * beginning of an MII instruction.  This is done by sending 32
+		 * consecutive "1" bits.
+		 */
+		e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
+
+		/* Now combine the next few fields that are required for a read
+		 * operation.  We use this method instead of calling the
+		 * e1000_shift_out_mdi_bits routine five different times. The format of
+		 * a MII read instruction consists of a shift out of 14 bits and is
+		 * defined as follows:
+		 *    <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
+		 * followed by a shift in of 18 bits.  This first two bits shifted in
+		 * are TurnAround bits used to avoid contention on the MDIO pin when a
+		 * READ operation is performed.  These two bits are thrown away
+		 * followed by a shift in of 16 bits which contains the desired data.
+		 */
+		mdic = ((reg_addr) | (phy_addr << 5) |
+			(PHY_OP_READ << 10) | (PHY_SOF << 12));
+
+		e1000_shift_out_mdi_bits(hw, mdic, 14);
+
+		/* Now that we've shifted out the read command to the MII, we need to
+		 * "shift in" the 16-bit value (18 total bits) of the requested PHY
+		 * register address.
+		 */
+		*phy_data = e1000_shift_in_mdi_bits(hw);
+	}
+	return 0;
+}
+
+/******************************************************************************
+* Writes a value to a PHY register
+*
+* hw - Struct containing variables accessed by shared code
+* reg_addr - address of the PHY register to write
+* data - data to write to the PHY
+******************************************************************************/
+static int
+e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t phy_data)
+{
+	uint32_t i;
+	uint32_t mdic = 0;
+	const uint32_t phy_addr = 1;
+
+	if (reg_addr > MAX_PHY_REG_ADDRESS) {
+		DEBUGOUT("PHY Address %d is out of range\n", reg_addr);
+		return -E1000_ERR_PARAM;
+	}
+
+	if (hw->mac_type > e1000_82543) {
+		/* Set up Op-code, Phy Address, register address, and data intended
+		 * for the PHY register in the MDI Control register.  The MAC will take
+		 * care of interfacing with the PHY to send the desired data.
+		 */
+		mdic = (((uint32_t) phy_data) |
+			(reg_addr << E1000_MDIC_REG_SHIFT) |
+			(phy_addr << E1000_MDIC_PHY_SHIFT) |
+			(E1000_MDIC_OP_WRITE));
+
+		E1000_WRITE_REG(hw, MDIC, mdic);
+
+		/* Poll the ready bit to see if the MDI read completed */
+		for (i = 0; i < 64; i++) {
+			udelay(10);
+			mdic = E1000_READ_REG(hw, MDIC);
+			if (mdic & E1000_MDIC_READY)
+				break;
+		}
+		if (!(mdic & E1000_MDIC_READY)) {
+			DEBUGOUT("MDI Write did not complete\n");
+			return -E1000_ERR_PHY;
+		}
+	} else {
+		/* We'll need to use the SW defined pins to shift the write command
+		 * out to the PHY. We first send a preamble to the PHY to signal the
+		 * beginning of the MII instruction.  This is done by sending 32
+		 * consecutive "1" bits.
+		 */
+		e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
+
+		/* Now combine the remaining required fields that will indicate a
+		 * write operation. We use this method instead of calling the
+		 * e1000_shift_out_mdi_bits routine for each field in the command. The
+		 * format of a MII write instruction is as follows:
+		 * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
+		 */
+		mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
+			(PHY_OP_WRITE << 12) | (PHY_SOF << 14));
+		mdic <<= 16;
+		mdic |= (uint32_t) phy_data;
+
+		e1000_shift_out_mdi_bits(hw, mdic, 32);
+	}
+	return 0;
+}
+
+/******************************************************************************
+ * Checks if PHY reset is blocked due to SOL/IDER session, for example.
+ * Returning E1000_BLK_PHY_RESET isn't necessarily an error.  But it's up to
+ * the caller to figure out how to deal with it.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * returns: - E1000_BLK_PHY_RESET
+ *            E1000_SUCCESS
+ *
+ *****************************************************************************/
+int32_t
+e1000_check_phy_reset_block(struct e1000_hw *hw)
+{
+	uint32_t manc = 0;
+	uint32_t fwsm = 0;
+
+	if (hw->mac_type == e1000_ich8lan) {
+		fwsm = E1000_READ_REG(hw, FWSM);
+		return (fwsm & E1000_FWSM_RSPCIPHY) ? E1000_SUCCESS
+						: E1000_BLK_PHY_RESET;
+	}
+
+	if (hw->mac_type > e1000_82547_rev_2)
+		manc = E1000_READ_REG(hw, MANC);
+	return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
+		E1000_BLK_PHY_RESET : E1000_SUCCESS;
+}
+
+/***************************************************************************
+ * Checks if the PHY configuration is done
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * returns: - E1000_ERR_RESET if fail to reset MAC
+ *            E1000_SUCCESS at any other case.
+ *
+ ***************************************************************************/
+static int32_t
+e1000_get_phy_cfg_done(struct e1000_hw *hw)
+{
+	int32_t timeout = PHY_CFG_TIMEOUT;
+	uint32_t cfg_mask = E1000_EEPROM_CFG_DONE;
+
+	DEBUGFUNC();
+
+	switch (hw->mac_type) {
+	default:
+		mdelay(10);
+		break;
+
+	case e1000_80003es2lan:
+		/* Separate *_CFG_DONE_* bit for each port */
+		if (e1000_is_second_port(hw))
+			cfg_mask = E1000_EEPROM_CFG_DONE_PORT_1;
+		/* Fall Through */
+
+	case e1000_82571:
+	case e1000_82572:
+		while (timeout) {
+			if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask)
+				break;
+			else
+				mdelay(1);
+			timeout--;
+		}
+		if (!timeout) {
+			DEBUGOUT("MNG configuration cycle has not "
+					"completed.\n");
+			return -E1000_ERR_RESET;
+		}
+		break;
+	}
+
+	return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Returns the PHY to the power-on reset state
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+int32_t
+e1000_phy_hw_reset(struct e1000_hw *hw)
+{
+	uint16_t swfw = E1000_SWFW_PHY0_SM;
+	uint32_t ctrl, ctrl_ext;
+	uint32_t led_ctrl;
+	int32_t ret_val;
+
+	DEBUGFUNC();
+
+	/* In the case of the phy reset being blocked, it's not an error, we
+	 * simply return success without performing the reset. */
+	ret_val = e1000_check_phy_reset_block(hw);
+	if (ret_val)
+		return E1000_SUCCESS;
+
+	DEBUGOUT("Resetting Phy...\n");
+
+	if (hw->mac_type > e1000_82543) {
+		if (e1000_is_second_port(hw))
+			swfw = E1000_SWFW_PHY1_SM;
+
+		if (e1000_swfw_sync_acquire(hw, swfw)) {
+			DEBUGOUT("Unable to acquire swfw sync\n");
+			return -E1000_ERR_SWFW_SYNC;
+		}
+
+		/* Read the device control register and assert the E1000_CTRL_PHY_RST
+		 * bit. Then, take it out of reset.
+		 */
+		ctrl = E1000_READ_REG(hw, CTRL);
+		E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
+		E1000_WRITE_FLUSH(hw);
+
+		if (hw->mac_type < e1000_82571)
+			udelay(10);
+		else
+			udelay(100);
+
+		E1000_WRITE_REG(hw, CTRL, ctrl);
+		E1000_WRITE_FLUSH(hw);
+
+		if (hw->mac_type >= e1000_82571)
+			mdelay(10);
+
+	} else {
+		/* Read the Extended Device Control Register, assert the PHY_RESET_DIR
+		 * bit to put the PHY into reset. Then, take it out of reset.
+		 */
+		ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+		ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
+		ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
+		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+		E1000_WRITE_FLUSH(hw);
+		mdelay(10);
+		ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
+		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+		E1000_WRITE_FLUSH(hw);
+	}
+	udelay(150);
+
+	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+		/* Configure activity LED after PHY reset */
+		led_ctrl = E1000_READ_REG(hw, LEDCTL);
+		led_ctrl &= IGP_ACTIVITY_LED_MASK;
+		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
+		E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
+	}
+
+	/* Wait for FW to finish PHY configuration. */
+	ret_val = e1000_get_phy_cfg_done(hw);
+	if (ret_val != E1000_SUCCESS)
+		return ret_val;
+
+	return ret_val;
+}
+
+/******************************************************************************
+ * IGP phy init script - initializes the GbE PHY
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_phy_init_script(struct e1000_hw *hw)
+{
+	uint32_t ret_val;
+	uint16_t phy_saved_data;
+	DEBUGFUNC();
+
+	if (hw->phy_init_script) {
+		mdelay(20);
+
+		/* Save off the current value of register 0x2F5B to be
+		 * restored at the end of this routine. */
+		ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
+
+		/* Disabled the PHY transmitter */
+		e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
+
+		mdelay(20);
+
+		e1000_write_phy_reg(hw, 0x0000, 0x0140);
+
+		mdelay(5);
+
+		switch (hw->mac_type) {
+		case e1000_82541:
+		case e1000_82547:
+			e1000_write_phy_reg(hw, 0x1F95, 0x0001);
+
+			e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
+
+			e1000_write_phy_reg(hw, 0x1F79, 0x0018);
+
+			e1000_write_phy_reg(hw, 0x1F30, 0x1600);
+
+			e1000_write_phy_reg(hw, 0x1F31, 0x0014);
+
+			e1000_write_phy_reg(hw, 0x1F32, 0x161C);
+
+			e1000_write_phy_reg(hw, 0x1F94, 0x0003);
+
+			e1000_write_phy_reg(hw, 0x1F96, 0x003F);
+
+			e1000_write_phy_reg(hw, 0x2010, 0x0008);
+			break;
+
+		case e1000_82541_rev_2:
+		case e1000_82547_rev_2:
+			e1000_write_phy_reg(hw, 0x1F73, 0x0099);
+			break;
+		default:
+			break;
+		}
+
+		e1000_write_phy_reg(hw, 0x0000, 0x3300);
+
+		mdelay(20);
+
+		/* Now enable the transmitter */
+		if (!ret_val)
+			e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
+
+		if (hw->mac_type == e1000_82547) {
+			uint16_t fused, fine, coarse;
+
+			/* Move to analog registers page */
+			e1000_read_phy_reg(hw,
+				IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused);
+
+			if (!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
+				e1000_read_phy_reg(hw,
+					IGP01E1000_ANALOG_FUSE_STATUS, &fused);
+
+				fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
+				coarse = fused
+					& IGP01E1000_ANALOG_FUSE_COARSE_MASK;
+
+				if (coarse >
+					IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
+					coarse -=
+					IGP01E1000_ANALOG_FUSE_COARSE_10;
+					fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
+				} else if (coarse
+					== IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
+					fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
+
+				fused = (fused
+					& IGP01E1000_ANALOG_FUSE_POLY_MASK) |
+					(fine
+					& IGP01E1000_ANALOG_FUSE_FINE_MASK) |
+					(coarse
+					& IGP01E1000_ANALOG_FUSE_COARSE_MASK);
+
+				e1000_write_phy_reg(hw,
+					IGP01E1000_ANALOG_FUSE_CONTROL, fused);
+				e1000_write_phy_reg(hw,
+					IGP01E1000_ANALOG_FUSE_BYPASS,
+				IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
+			}
+		}
+	}
+}
+
+/******************************************************************************
+* Resets the PHY
+*
+* hw - Struct containing variables accessed by shared code
+*
+* Sets bit 15 of the MII Control register
+******************************************************************************/
+int32_t
+e1000_phy_reset(struct e1000_hw *hw)
+{
+	int32_t ret_val;
+	uint16_t phy_data;
+
+	DEBUGFUNC();
+
+	/* In the case of the phy reset being blocked, it's not an error, we
+	 * simply return success without performing the reset. */
+	ret_val = e1000_check_phy_reset_block(hw);
+	if (ret_val)
+		return E1000_SUCCESS;
+
+	switch (hw->phy_type) {
+	case e1000_phy_igp:
+	case e1000_phy_igp_2:
+	case e1000_phy_igp_3:
+	case e1000_phy_ife:
+		ret_val = e1000_phy_hw_reset(hw);
+		if (ret_val)
+			return ret_val;
+		break;
+	default:
+		ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
+		if (ret_val)
+			return ret_val;
+
+		phy_data |= MII_CR_RESET;
+		ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
+		if (ret_val)
+			return ret_val;
+
+		udelay(1);
+		break;
+	}
+
+	if (hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2)
+		e1000_phy_init_script(hw);
+
+	return E1000_SUCCESS;
+}
+
+static int e1000_set_phy_type (struct e1000_hw *hw)
+{
+	DEBUGFUNC ();
+
+	if (hw->mac_type == e1000_undefined)
+		return -E1000_ERR_PHY_TYPE;
+
+	switch (hw->phy_id) {
+	case M88E1000_E_PHY_ID:
+	case M88E1000_I_PHY_ID:
+	case M88E1011_I_PHY_ID:
+	case M88E1111_I_PHY_ID:
+		hw->phy_type = e1000_phy_m88;
+		break;
+	case IGP01E1000_I_PHY_ID:
+		if (hw->mac_type == e1000_82541 ||
+			hw->mac_type == e1000_82541_rev_2 ||
+			hw->mac_type == e1000_82547 ||
+			hw->mac_type == e1000_82547_rev_2) {
+			hw->phy_type = e1000_phy_igp;
+			hw->phy_type = e1000_phy_igp;
+			break;
+		}
+	case IGP03E1000_E_PHY_ID:
+		hw->phy_type = e1000_phy_igp_3;
+		break;
+	case IFE_E_PHY_ID:
+	case IFE_PLUS_E_PHY_ID:
+	case IFE_C_E_PHY_ID:
+		hw->phy_type = e1000_phy_ife;
+		break;
+	case GG82563_E_PHY_ID:
+		if (hw->mac_type == e1000_80003es2lan) {
+			hw->phy_type = e1000_phy_gg82563;
+			break;
+		}
+	case BME1000_E_PHY_ID:
+		hw->phy_type = e1000_phy_bm;
+		break;
+		/* Fall Through */
+	default:
+		/* Should never have loaded on this device */
+		hw->phy_type = e1000_phy_undefined;
+		return -E1000_ERR_PHY_TYPE;
+	}
+
+	return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Probes the expected PHY address for known PHY IDs
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int32_t
+e1000_detect_gig_phy(struct e1000_hw *hw)
+{
+	int32_t phy_init_status, ret_val;
+	uint16_t phy_id_high, phy_id_low;
+	bool match = false;
+
+	DEBUGFUNC();
+
+	/* The 82571 firmware may still be configuring the PHY.  In this
+	 * case, we cannot access the PHY until the configuration is done.  So
+	 * we explicitly set the PHY values. */
+	if (hw->mac_type == e1000_82571 ||
+		hw->mac_type == e1000_82572) {
+		hw->phy_id = IGP01E1000_I_PHY_ID;
+		hw->phy_type = e1000_phy_igp_2;
+		return E1000_SUCCESS;
+	}
+
+	/* ESB-2 PHY reads require e1000_phy_gg82563 to be set because of a
+	 * work- around that forces PHY page 0 to be set or the reads fail.
+	 * The rest of the code in this routine uses e1000_read_phy_reg to
+	 * read the PHY ID.  So for ESB-2 we need to have this set so our
+	 * reads won't fail.  If the attached PHY is not a e1000_phy_gg82563,
+	 * the routines below will figure this out as well. */
+	if (hw->mac_type == e1000_80003es2lan)
+		hw->phy_type = e1000_phy_gg82563;
+
+	/* Read the PHY ID Registers to identify which PHY is onboard. */
+	ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high);
+	if (ret_val)
+		return ret_val;
+
+	hw->phy_id = (uint32_t) (phy_id_high << 16);
+	udelay(20);
+	ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low);
+	if (ret_val)
+		return ret_val;
+
+	hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK);
+	hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK;
+
+	switch (hw->mac_type) {
+	case e1000_82543:
+		if (hw->phy_id == M88E1000_E_PHY_ID)
+			match = true;
+		break;
+	case e1000_82544:
+		if (hw->phy_id == M88E1000_I_PHY_ID)
+			match = true;
+		break;
+	case e1000_82540:
+	case e1000_82545:
+	case e1000_82545_rev_3:
+	case e1000_82546:
+	case e1000_82546_rev_3:
+		if (hw->phy_id == M88E1011_I_PHY_ID)
+			match = true;
+		break;
+	case e1000_82541:
+	case e1000_82541_rev_2:
+	case e1000_82547:
+	case e1000_82547_rev_2:
+		if(hw->phy_id == IGP01E1000_I_PHY_ID)
+			match = true;
+
+		break;
+	case e1000_82573:
+		if (hw->phy_id == M88E1111_I_PHY_ID)
+			match = true;
+		break;
+	case e1000_82574:
+		if (hw->phy_id == BME1000_E_PHY_ID)
+			match = true;
+		break;
+	case e1000_80003es2lan:
+		if (hw->phy_id == GG82563_E_PHY_ID)
+			match = true;
+		break;
+	case e1000_ich8lan:
+		if (hw->phy_id == IGP03E1000_E_PHY_ID)
+			match = true;
+		if (hw->phy_id == IFE_E_PHY_ID)
+			match = true;
+		if (hw->phy_id == IFE_PLUS_E_PHY_ID)
+			match = true;
+		if (hw->phy_id == IFE_C_E_PHY_ID)
+			match = true;
+		break;
+	default:
+		DEBUGOUT("Invalid MAC type %d\n", hw->mac_type);
+		return -E1000_ERR_CONFIG;
+	}
+
+	phy_init_status = e1000_set_phy_type(hw);
+
+	if ((match) && (phy_init_status == E1000_SUCCESS)) {
+		DEBUGOUT("PHY ID 0x%X detected\n", hw->phy_id);
+		return 0;
+	}
+	DEBUGOUT("Invalid PHY ID 0x%X\n", hw->phy_id);
+	return -E1000_ERR_PHY;
+}
+
+/*****************************************************************************
+ * Set media type and TBI compatibility.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * **************************************************************************/
+void
+e1000_set_media_type(struct e1000_hw *hw)
+{
+	uint32_t status;
+
+	DEBUGFUNC();
+
+	if (hw->mac_type != e1000_82543) {
+		/* tbi_compatibility is only valid on 82543 */
+		hw->tbi_compatibility_en = false;
+	}
+
+	switch (hw->device_id) {
+	case E1000_DEV_ID_82545GM_SERDES:
+	case E1000_DEV_ID_82546GB_SERDES:
+	case E1000_DEV_ID_82571EB_SERDES:
+	case E1000_DEV_ID_82571EB_SERDES_DUAL:
+	case E1000_DEV_ID_82571EB_SERDES_QUAD:
+	case E1000_DEV_ID_82572EI_SERDES:
+	case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
+		hw->media_type = e1000_media_type_internal_serdes;
+		break;
+	default:
+		switch (hw->mac_type) {
+		case e1000_82542_rev2_0:
+		case e1000_82542_rev2_1:
+			hw->media_type = e1000_media_type_fiber;
+			break;
+		case e1000_ich8lan:
+		case e1000_82573:
+		case e1000_82574:
+			/* The STATUS_TBIMODE bit is reserved or reused
+			 * for the this device.
+			 */
+			hw->media_type = e1000_media_type_copper;
+			break;
+		default:
+			status = E1000_READ_REG(hw, STATUS);
+			if (status & E1000_STATUS_TBIMODE) {
+				hw->media_type = e1000_media_type_fiber;
+				/* tbi_compatibility not valid on fiber */
+				hw->tbi_compatibility_en = false;
+			} else {
+				hw->media_type = e1000_media_type_copper;
+			}
+			break;
+		}
+	}
+}
+
+/**
+ * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
+ *
+ * e1000_sw_init initializes the Adapter private data structure.
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ **/
+
+static int
+e1000_sw_init(struct eth_device *nic)
+{
+	struct e1000_hw *hw = (typeof(hw)) nic->priv;
+	int result;
+
+	/* PCI config space info */
+	pci_read_config_word(hw->pdev, PCI_VENDOR_ID, &hw->vendor_id);
+	pci_read_config_word(hw->pdev, PCI_DEVICE_ID, &hw->device_id);
+	pci_read_config_word(hw->pdev, PCI_SUBSYSTEM_VENDOR_ID,
+			     &hw->subsystem_vendor_id);
+	pci_read_config_word(hw->pdev, PCI_SUBSYSTEM_ID, &hw->subsystem_id);
+
+	pci_read_config_byte(hw->pdev, PCI_REVISION_ID, &hw->revision_id);
+	pci_read_config_word(hw->pdev, PCI_COMMAND, &hw->pci_cmd_word);
+
+	/* identify the MAC */
+	result = e1000_set_mac_type(hw);
+	if (result) {
+		E1000_ERR(hw->nic, "Unknown MAC Type\n");
+		return result;
+	}
+
+	switch (hw->mac_type) {
+	default:
+		break;
+	case e1000_82541:
+	case e1000_82547:
+	case e1000_82541_rev_2:
+	case e1000_82547_rev_2:
+		hw->phy_init_script = 1;
+		break;
+	}
+
+	/* flow control settings */
+	hw->fc_high_water = E1000_FC_HIGH_THRESH;
+	hw->fc_low_water = E1000_FC_LOW_THRESH;
+	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
+	hw->fc_send_xon = 1;
+
+	/* Media type - copper or fiber */
+	e1000_set_media_type(hw);
+
+	if (hw->mac_type >= e1000_82543) {
+		uint32_t status = E1000_READ_REG(hw, STATUS);
+
+		if (status & E1000_STATUS_TBIMODE) {
+			DEBUGOUT("fiber interface\n");
+			hw->media_type = e1000_media_type_fiber;
+		} else {
+			DEBUGOUT("copper interface\n");
+			hw->media_type = e1000_media_type_copper;
+		}
+	} else {
+		hw->media_type = e1000_media_type_fiber;
+	}
+
+	hw->tbi_compatibility_en = true;
+	hw->wait_autoneg_complete = true;
+	if (hw->mac_type < e1000_82543)
+		hw->report_tx_early = 0;
+	else
+		hw->report_tx_early = 1;
+
+	return E1000_SUCCESS;
+}
+
+void
+fill_rx(struct e1000_hw *hw)
+{
+	struct e1000_rx_desc *rd;
+
+	rx_last = rx_tail;
+	rd = rx_base + rx_tail;
+	rx_tail = (rx_tail + 1) % 8;
+	memset(rd, 0, 16);
+	rd->buffer_addr = cpu_to_le64((u32) & packet);
+	E1000_WRITE_REG(hw, RDT, rx_tail);
+}
+
+/**
+ * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx unit of the MAC after a reset.
+ **/
+
+static void
+e1000_configure_tx(struct e1000_hw *hw)
+{
+	unsigned long ptr;
+	unsigned long tctl;
+	unsigned long tipg, tarc;
+	uint32_t ipgr1, ipgr2;
+
+	ptr = (u32) tx_pool;
+	if (ptr & 0xf)
+		ptr = (ptr + 0x10) & (~0xf);
+
+	tx_base = (typeof(tx_base)) ptr;
+
+	E1000_WRITE_REG(hw, TDBAL, (u32) tx_base);
+	E1000_WRITE_REG(hw, TDBAH, 0);
+
+	E1000_WRITE_REG(hw, TDLEN, 128);
+
+	/* Setup the HW Tx Head and Tail descriptor pointers */
+	E1000_WRITE_REG(hw, TDH, 0);
+	E1000_WRITE_REG(hw, TDT, 0);
+	tx_tail = 0;
+
+	/* Set the default values for the Tx Inter Packet Gap timer */
+	if (hw->mac_type <= e1000_82547_rev_2 &&
+	    (hw->media_type == e1000_media_type_fiber ||
+	     hw->media_type == e1000_media_type_internal_serdes))
+		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
+	else
+		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
+
+	/* Set the default values for the Tx Inter Packet Gap timer */
+	switch (hw->mac_type) {
+	case e1000_82542_rev2_0:
+	case e1000_82542_rev2_1:
+		tipg = DEFAULT_82542_TIPG_IPGT;
+		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
+		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
+		break;
+	case e1000_80003es2lan:
+		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
+		ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2;
+		break;
+	default:
+		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
+		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
+		break;
+	}
+	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
+	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
+	E1000_WRITE_REG(hw, TIPG, tipg);
+	/* Program the Transmit Control Register */
+	tctl = E1000_READ_REG(hw, TCTL);
+	tctl &= ~E1000_TCTL_CT;
+	tctl |= E1000_TCTL_EN | E1000_TCTL_PSP |
+	    (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
+
+	if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
+		tarc = E1000_READ_REG(hw, TARC0);
+		/* set the speed mode bit, we'll clear it if we're not at
+		 * gigabit link later */
+		/* git bit can be set to 1*/
+	} else if (hw->mac_type == e1000_80003es2lan) {
+		tarc = E1000_READ_REG(hw, TARC0);
+		tarc |= 1;
+		E1000_WRITE_REG(hw, TARC0, tarc);
+		tarc = E1000_READ_REG(hw, TARC1);
+		tarc |= 1;
+		E1000_WRITE_REG(hw, TARC1, tarc);
+	}
+
+
+	e1000_config_collision_dist(hw);
+	/* Setup Transmit Descriptor Settings for eop descriptor */
+	hw->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
+
+	/* Need to set up RS bit */
+	if (hw->mac_type < e1000_82543)
+		hw->txd_cmd |= E1000_TXD_CMD_RPS;
+	else
+		hw->txd_cmd |= E1000_TXD_CMD_RS;
+	E1000_WRITE_REG(hw, TCTL, tctl);
+}
+
+/**
+ * e1000_setup_rctl - configure the receive control register
+ * @adapter: Board private structure
+ **/
+static void
+e1000_setup_rctl(struct e1000_hw *hw)
+{
+	uint32_t rctl;
+
+	rctl = E1000_READ_REG(hw, RCTL);
+
+	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
+
+	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO
+		| E1000_RCTL_RDMTS_HALF;	/* |
+			(hw.mc_filter_type << E1000_RCTL_MO_SHIFT); */
+
+	if (hw->tbi_compatibility_on == 1)
+		rctl |= E1000_RCTL_SBP;
+	else
+		rctl &= ~E1000_RCTL_SBP;
+
+	rctl &= ~(E1000_RCTL_SZ_4096);
+		rctl |= E1000_RCTL_SZ_2048;
+		rctl &= ~(E1000_RCTL_BSEX | E1000_RCTL_LPE);
+	E1000_WRITE_REG(hw, RCTL, rctl);
+}
+
+/**
+ * e1000_configure_rx - Configure 8254x Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Rx unit of the MAC after a reset.
+ **/
+static void
+e1000_configure_rx(struct e1000_hw *hw)
+{
+	unsigned long ptr;
+	unsigned long rctl, ctrl_ext;
+	rx_tail = 0;
+	/* make sure receives are disabled while setting up the descriptors */
+	rctl = E1000_READ_REG(hw, RCTL);
+	E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
+	if (hw->mac_type >= e1000_82540) {
+		/* Set the interrupt throttling rate.  Value is calculated
+		 * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) */
+#define MAX_INTS_PER_SEC	8000
+#define DEFAULT_ITR		1000000000/(MAX_INTS_PER_SEC * 256)
+		E1000_WRITE_REG(hw, ITR, DEFAULT_ITR);
+	}
+
+	if (hw->mac_type >= e1000_82571) {
+		ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+		/* Reset delay timers after every interrupt */
+		ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR;
+		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+		E1000_WRITE_FLUSH(hw);
+	}
+	/* Setup the Base and Length of the Rx Descriptor Ring */
+	ptr = (u32) rx_pool;
+	if (ptr & 0xf)
+		ptr = (ptr + 0x10) & (~0xf);
+	rx_base = (typeof(rx_base)) ptr;
+	E1000_WRITE_REG(hw, RDBAL, (u32) rx_base);
+	E1000_WRITE_REG(hw, RDBAH, 0);
+
+	E1000_WRITE_REG(hw, RDLEN, 128);
+
+	/* Setup the HW Rx Head and Tail Descriptor Pointers */
+	E1000_WRITE_REG(hw, RDH, 0);
+	E1000_WRITE_REG(hw, RDT, 0);
+	/* Enable Receives */
+
+	E1000_WRITE_REG(hw, RCTL, rctl);
+	fill_rx(hw);
+}
+
+/**************************************************************************
+POLL - Wait for a frame
+***************************************************************************/
+static int
+e1000_poll(struct eth_device *nic)
+{
+	struct e1000_hw *hw = nic->priv;
+	struct e1000_rx_desc *rd;
+	/* return true if there's an ethernet packet ready to read */
+	rd = rx_base + rx_last;
+	if (!(le32_to_cpu(rd->status)) & E1000_RXD_STAT_DD)
+		return 0;
+	/*DEBUGOUT("recv: packet len=%d \n", rd->length); */
+	NetReceive((uchar *)packet, le32_to_cpu(rd->length));
+	fill_rx(hw);
+	return 1;
+}
+
+/**************************************************************************
+TRANSMIT - Transmit a frame
+***************************************************************************/
+static int e1000_transmit(struct eth_device *nic, void *packet, int length)
+{
+	void *nv_packet = (void *)packet;
+	struct e1000_hw *hw = nic->priv;
+	struct e1000_tx_desc *txp;
+	int i = 0;
+
+	txp = tx_base + tx_tail;
+	tx_tail = (tx_tail + 1) % 8;
+
+	txp->buffer_addr = cpu_to_le64(virt_to_bus(hw->pdev, nv_packet));
+	txp->lower.data = cpu_to_le32(hw->txd_cmd | length);
+	txp->upper.data = 0;
+	E1000_WRITE_REG(hw, TDT, tx_tail);
+
+	E1000_WRITE_FLUSH(hw);
+	while (!(le32_to_cpu(txp->upper.data) & E1000_TXD_STAT_DD)) {
+		if (i++ > TOUT_LOOP) {
+			DEBUGOUT("e1000: tx timeout\n");
+			return 0;
+		}
+		udelay(10);	/* give the nic a chance to write to the register */
+	}
+	return 1;
+}
+
+/*reset function*/
+static inline int
+e1000_reset(struct eth_device *nic)
+{
+	struct e1000_hw *hw = nic->priv;
+
+	e1000_reset_hw(hw);
+	if (hw->mac_type >= e1000_82544) {
+		E1000_WRITE_REG(hw, WUC, 0);
+	}
+	return e1000_init_hw(nic);
+}
+
+/**************************************************************************
+DISABLE - Turn off ethernet interface
+***************************************************************************/
+static void
+e1000_disable(struct eth_device *nic)
+{
+	struct e1000_hw *hw = nic->priv;
+
+	/* Turn off the ethernet interface */
+	E1000_WRITE_REG(hw, RCTL, 0);
+	E1000_WRITE_REG(hw, TCTL, 0);
+
+	/* Clear the transmit ring */
+	E1000_WRITE_REG(hw, TDH, 0);
+	E1000_WRITE_REG(hw, TDT, 0);
+
+	/* Clear the receive ring */
+	E1000_WRITE_REG(hw, RDH, 0);
+	E1000_WRITE_REG(hw, RDT, 0);
+
+	/* put the card in its initial state */
+#if 0
+	E1000_WRITE_REG(hw, CTRL, E1000_CTRL_RST);
+#endif
+	mdelay(10);
+
+}
+
+/**************************************************************************
+INIT - set up ethernet interface(s)
+***************************************************************************/
+static int
+e1000_init(struct eth_device *nic, bd_t * bis)
+{
+	struct e1000_hw *hw = nic->priv;
+	int ret_val = 0;
+
+	ret_val = e1000_reset(nic);
+	if (ret_val < 0) {
+		if ((ret_val == -E1000_ERR_NOLINK) ||
+		    (ret_val == -E1000_ERR_TIMEOUT)) {
+			E1000_ERR(hw->nic, "Valid Link not detected\n");
+		} else {
+			E1000_ERR(hw->nic, "Hardware Initialization Failed\n");
+		}
+		return 0;
+	}
+	e1000_configure_tx(hw);
+	e1000_setup_rctl(hw);
+	e1000_configure_rx(hw);
+	return 1;
+}
+
+/******************************************************************************
+ * Gets the current PCI bus type of hardware
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+void e1000_get_bus_type(struct e1000_hw *hw)
+{
+	uint32_t status;
+
+	switch (hw->mac_type) {
+	case e1000_82542_rev2_0:
+	case e1000_82542_rev2_1:
+		hw->bus_type = e1000_bus_type_pci;
+		break;
+	case e1000_82571:
+	case e1000_82572:
+	case e1000_82573:
+	case e1000_82574:
+	case e1000_80003es2lan:
+		hw->bus_type = e1000_bus_type_pci_express;
+		break;
+	case e1000_ich8lan:
+		hw->bus_type = e1000_bus_type_pci_express;
+		break;
+	default:
+		status = E1000_READ_REG(hw, STATUS);
+		hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
+				e1000_bus_type_pcix : e1000_bus_type_pci;
+		break;
+	}
+}
+
+/* A list of all registered e1000 devices */
+static LIST_HEAD(e1000_hw_list);
+
+/**************************************************************************
+PROBE - Look for an adapter, this routine's visible to the outside
+You should omit the last argument struct pci_device * for a non-PCI NIC
+***************************************************************************/
+int
+e1000_initialize(bd_t * bis)
+{
+	unsigned int i;
+	pci_dev_t devno;
+
+	DEBUGFUNC();
+
+	/* Find and probe all the matching PCI devices */
+	for (i = 0; (devno = pci_find_devices(e1000_supported, i)) >= 0; i++) {
+		u32 val;
+
+		/*
+		 * These will never get freed due to errors, this allows us to
+		 * perform SPI EEPROM programming from U-boot, for example.
+		 */
+		struct eth_device *nic = malloc(sizeof(*nic));
+		struct e1000_hw *hw = malloc(sizeof(*hw));
+		if (!nic || !hw) {
+			printf("e1000#%u: Out of Memory!\n", i);
+			free(nic);
+			free(hw);
+			continue;
+		}
+
+		/* Make sure all of the fields are initially zeroed */
+		memset(nic, 0, sizeof(*nic));
+		memset(hw, 0, sizeof(*hw));
+
+		/* Assign the passed-in values */
+		hw->cardnum = i;
+		hw->pdev = devno;
+		hw->nic = nic;
+		nic->priv = hw;
+
+		/* Generate a card name */
+		sprintf(nic->name, "e1000#%u", hw->cardnum);
+
+		/* Print a debug message with the IO base address */
+		pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &val);
+		E1000_DBG(nic, "iobase 0x%08x\n", val & 0xfffffff0);
+
+		/* Try to enable I/O accesses and bus-mastering */
+		val = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+		pci_write_config_dword(devno, PCI_COMMAND, val);
+
+		/* Make sure it worked */
+		pci_read_config_dword(devno, PCI_COMMAND, &val);
+		if (!(val & PCI_COMMAND_MEMORY)) {
+			E1000_ERR(nic, "Can't enable I/O memory\n");
+			continue;
+		}
+		if (!(val & PCI_COMMAND_MASTER)) {
+			E1000_ERR(nic, "Can't enable bus-mastering\n");
+			continue;
+		}
+
+		/* Are these variables needed? */
+		hw->fc = e1000_fc_default;
+		hw->original_fc = e1000_fc_default;
+		hw->autoneg_failed = 0;
+		hw->autoneg = 1;
+		hw->get_link_status = true;
+		hw->hw_addr = pci_map_bar(devno,	PCI_BASE_ADDRESS_0,
+							PCI_REGION_MEM);
+		hw->mac_type = e1000_undefined;
+
+		/* MAC and Phy settings */
+		if (e1000_sw_init(nic) < 0) {
+			E1000_ERR(nic, "Software init failed\n");
+			continue;
+		}
+		if (e1000_check_phy_reset_block(hw))
+			E1000_ERR(nic, "PHY Reset is blocked!\n");
+
+		/* Basic init was OK, reset the hardware and allow SPI access */
+		e1000_reset_hw(hw);
+		list_add_tail(&hw->list_node, &e1000_hw_list);
+
+#ifndef CONFIG_E1000_NO_NVM
+		/* Validate the EEPROM and get chipset information */
+#if !defined(CONFIG_MVBC_1G)
+		if (e1000_init_eeprom_params(hw)) {
+			E1000_ERR(nic, "EEPROM is invalid!\n");
+			continue;
+		}
+		if (e1000_validate_eeprom_checksum(hw))
+			continue;
+#endif
+		e1000_read_mac_addr(nic);
+#endif
+		e1000_get_bus_type(hw);
+
+#ifndef CONFIG_E1000_NO_NVM
+		printf("e1000: %02x:%02x:%02x:%02x:%02x:%02x\n       ",
+		       nic->enetaddr[0], nic->enetaddr[1], nic->enetaddr[2],
+		       nic->enetaddr[3], nic->enetaddr[4], nic->enetaddr[5]);
+#else
+		memset(nic->enetaddr, 0, 6);
+		printf("e1000: no NVM\n");
+#endif
+
+		/* Set up the function pointers and register the device */
+		nic->init = e1000_init;
+		nic->recv = e1000_poll;
+		nic->send = e1000_transmit;
+		nic->halt = e1000_disable;
+		eth_register(nic);
+	}
+
+	return i;
+}
+
+struct e1000_hw *e1000_find_card(unsigned int cardnum)
+{
+	struct e1000_hw *hw;
+
+	list_for_each_entry(hw, &e1000_hw_list, list_node)
+		if (hw->cardnum == cardnum)
+			return hw;
+
+	return NULL;
+}
+
+#ifdef CONFIG_CMD_E1000
+static int do_e1000(cmd_tbl_t *cmdtp, int flag,
+		int argc, char * const argv[])
+{
+	struct e1000_hw *hw;
+
+	if (argc < 3) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	/* Make sure we can find the requested e1000 card */
+	hw = e1000_find_card(simple_strtoul(argv[1], NULL, 10));
+	if (!hw) {
+		printf("e1000: ERROR: No such device: e1000#%s\n", argv[1]);
+		return 1;
+	}
+
+	if (!strcmp(argv[2], "print-mac-address")) {
+		unsigned char *mac = hw->nic->enetaddr;
+		printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
+			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+		return 0;
+	}
+
+#ifdef CONFIG_E1000_SPI
+	/* Handle the "SPI" subcommand */
+	if (!strcmp(argv[2], "spi"))
+		return do_e1000_spi(cmdtp, hw, argc - 3, argv + 3);
+#endif
+
+	cmd_usage(cmdtp);
+	return 1;
+}
+
+U_BOOT_CMD(
+	e1000, 7, 0, do_e1000,
+	"Intel e1000 controller management",
+	/*  */"<card#> print-mac-address\n"
+#ifdef CONFIG_E1000_SPI
+	"e1000 <card#> spi show [<offset> [<length>]]\n"
+	"e1000 <card#> spi dump <addr> <offset> <length>\n"
+	"e1000 <card#> spi program <addr> <offset> <length>\n"
+	"e1000 <card#> spi checksum [update]\n"
+#endif
+	"       - Manage the Intel E1000 PCI device"
+);
+#endif /* not CONFIG_CMD_E1000 */
diff --git a/marvell/uboot/drivers/net/e1000.h b/marvell/uboot/drivers/net/e1000.h
new file mode 100644
index 0000000..ff87af2
--- /dev/null
+++ b/marvell/uboot/drivers/net/e1000.h
@@ -0,0 +1,2601 @@
+/*******************************************************************************
+
+
+  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright 2011 Freescale Semiconductor, Inc.
+
+ * SPDX-License-Identifier:	GPL-2.0+
+
+  Contact Information:
+  Linux NICS <linux.nics@intel.com>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+/* e1000_hw.h
+ * Structures, enums, and macros for the MAC
+ */
+
+#ifndef _E1000_HW_H_
+#define _E1000_HW_H_
+
+#include <common.h>
+#include <linux/list.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#ifdef CONFIG_E1000_SPI
+#include <spi.h>
+#endif
+
+#define E1000_ERR(NIC, fmt, args...) \
+	printf("e1000: %s: ERROR: " fmt, (NIC)->name ,##args)
+
+#ifdef E1000_DEBUG
+#define E1000_DBG(NIC, fmt, args...) \
+	printf("e1000: %s: DEBUG: " fmt, (NIC)->name ,##args)
+#define DEBUGOUT(fmt, args...)	printf(fmt ,##args)
+#define DEBUGFUNC()		printf("%s\n", __func__);
+#else
+#define E1000_DBG(HW, args...)	do { } while (0)
+#define DEBUGFUNC()		do { } while (0)
+#define DEBUGOUT(fmt, args...)	do { } while (0)
+#endif
+
+/* I/O wrapper functions */
+#define E1000_WRITE_REG(a, reg, value) \
+	writel((value), ((a)->hw_addr + E1000_##reg))
+#define E1000_READ_REG(a, reg) \
+	readl((a)->hw_addr + E1000_##reg)
+#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) \
+	writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2)))
+#define E1000_READ_REG_ARRAY(a, reg, offset) \
+	readl((a)->hw_addr + E1000_##reg + ((offset) << 2))
+#define E1000_WRITE_FLUSH(a) \
+	do { E1000_READ_REG(a, STATUS); } while (0)
+
+/* Forward declarations of structures used by the shared code */
+struct e1000_hw;
+struct e1000_hw_stats;
+
+/* Internal E1000 helper functions */
+struct e1000_hw *e1000_find_card(unsigned int cardnum);
+
+#ifndef CONFIG_E1000_NO_NVM
+int32_t e1000_acquire_eeprom(struct e1000_hw *hw);
+void e1000_standby_eeprom(struct e1000_hw *hw);
+void e1000_release_eeprom(struct e1000_hw *hw);
+void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
+void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
+#endif
+
+#ifdef CONFIG_E1000_SPI
+int do_e1000_spi(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
+		int argc, char * const argv[]);
+#endif
+
+/* Enumerated types specific to the e1000 hardware */
+/* Media Access Controlers */
+typedef enum {
+	e1000_undefined = 0,
+	e1000_82542_rev2_0,
+	e1000_82542_rev2_1,
+	e1000_82543,
+	e1000_82544,
+	e1000_82540,
+	e1000_82545,
+	e1000_82545_rev_3,
+	e1000_82546,
+	e1000_82546_rev_3,
+	e1000_82541,
+	e1000_82541_rev_2,
+	e1000_82547,
+	e1000_82547_rev_2,
+	e1000_82571,
+	e1000_82572,
+	e1000_82573,
+	e1000_82574,
+	e1000_80003es2lan,
+	e1000_ich8lan,
+	e1000_num_macs
+} e1000_mac_type;
+
+/* Media Types */
+typedef enum {
+	e1000_media_type_copper = 0,
+	e1000_media_type_fiber = 1,
+	e1000_media_type_internal_serdes = 2,
+	e1000_num_media_types
+} e1000_media_type;
+
+typedef enum {
+	e1000_eeprom_uninitialized = 0,
+	e1000_eeprom_spi,
+	e1000_eeprom_microwire,
+	e1000_eeprom_flash,
+	e1000_eeprom_ich8,
+	e1000_eeprom_none, /* No NVM support */
+	e1000_num_eeprom_types
+} e1000_eeprom_type;
+
+typedef enum {
+	e1000_10_half = 0,
+	e1000_10_full = 1,
+	e1000_100_half = 2,
+	e1000_100_full = 3
+} e1000_speed_duplex_type;
+
+/* Flow Control Settings */
+typedef enum {
+	e1000_fc_none = 0,
+	e1000_fc_rx_pause = 1,
+	e1000_fc_tx_pause = 2,
+	e1000_fc_full = 3,
+	e1000_fc_default = 0xFF
+} e1000_fc_type;
+
+/* PCI bus types */
+typedef enum {
+	e1000_bus_type_unknown = 0,
+	e1000_bus_type_pci,
+	e1000_bus_type_pcix,
+	e1000_bus_type_pci_express,
+	e1000_bus_type_reserved
+} e1000_bus_type;
+
+/* PCI bus speeds */
+typedef enum {
+	e1000_bus_speed_unknown = 0,
+	e1000_bus_speed_33,
+	e1000_bus_speed_66,
+	e1000_bus_speed_100,
+	e1000_bus_speed_133,
+	e1000_bus_speed_reserved
+} e1000_bus_speed;
+
+/* PCI bus widths */
+typedef enum {
+	e1000_bus_width_unknown = 0,
+	e1000_bus_width_32,
+	e1000_bus_width_64
+} e1000_bus_width;
+
+/* PHY status info structure and supporting enums */
+typedef enum {
+	e1000_cable_length_50 = 0,
+	e1000_cable_length_50_80,
+	e1000_cable_length_80_110,
+	e1000_cable_length_110_140,
+	e1000_cable_length_140,
+	e1000_cable_length_undefined = 0xFF
+} e1000_cable_length;
+
+typedef enum {
+	e1000_10bt_ext_dist_enable_normal = 0,
+	e1000_10bt_ext_dist_enable_lower,
+	e1000_10bt_ext_dist_enable_undefined = 0xFF
+} e1000_10bt_ext_dist_enable;
+
+typedef enum {
+	e1000_rev_polarity_normal = 0,
+	e1000_rev_polarity_reversed,
+	e1000_rev_polarity_undefined = 0xFF
+} e1000_rev_polarity;
+
+typedef enum {
+	e1000_polarity_reversal_enabled = 0,
+	e1000_polarity_reversal_disabled,
+	e1000_polarity_reversal_undefined = 0xFF
+} e1000_polarity_reversal;
+
+typedef enum {
+	e1000_auto_x_mode_manual_mdi = 0,
+	e1000_auto_x_mode_manual_mdix,
+	e1000_auto_x_mode_auto1,
+	e1000_auto_x_mode_auto2,
+	e1000_auto_x_mode_undefined = 0xFF
+} e1000_auto_x_mode;
+
+typedef enum {
+	e1000_1000t_rx_status_not_ok = 0,
+	e1000_1000t_rx_status_ok,
+	e1000_1000t_rx_status_undefined = 0xFF
+} e1000_1000t_rx_status;
+
+typedef enum {
+	e1000_phy_m88 = 0,
+	e1000_phy_igp,
+	e1000_phy_igp_2,
+	e1000_phy_gg82563,
+	e1000_phy_igp_3,
+	e1000_phy_ife,
+	e1000_phy_bm,
+	e1000_phy_undefined = 0xFF
+} e1000_phy_type;
+
+struct e1000_phy_info {
+	e1000_cable_length cable_length;
+	e1000_10bt_ext_dist_enable extended_10bt_distance;
+	e1000_rev_polarity cable_polarity;
+	e1000_polarity_reversal polarity_correction;
+	e1000_auto_x_mode mdix_mode;
+	e1000_1000t_rx_status local_rx;
+	e1000_1000t_rx_status remote_rx;
+};
+
+struct e1000_phy_stats {
+	uint32_t idle_errors;
+	uint32_t receive_errors;
+};
+
+/* Error Codes */
+#define E1000_SUCCESS				0
+#define E1000_ERR_EEPROM			1
+#define E1000_ERR_PHY				2
+#define E1000_ERR_CONFIG			3
+#define E1000_ERR_PARAM				4
+#define E1000_ERR_MAC_TYPE			5
+#define E1000_ERR_PHY_TYPE			6
+#define E1000_ERR_NOLINK			7
+#define E1000_ERR_TIMEOUT			8
+#define E1000_ERR_RESET				9
+#define E1000_ERR_MASTER_REQUESTS_PENDING	10
+#define E1000_ERR_HOST_INTERFACE_COMMAND	11
+#define E1000_BLK_PHY_RESET			12
+#define E1000_ERR_SWFW_SYNC 			13
+
+/* PCI Device IDs */
+#define E1000_DEV_ID_82542	    0x1000
+#define E1000_DEV_ID_82543GC_FIBER  0x1001
+#define E1000_DEV_ID_82543GC_COPPER 0x1004
+#define E1000_DEV_ID_82544EI_COPPER 0x1008
+#define E1000_DEV_ID_82544EI_FIBER  0x1009
+#define E1000_DEV_ID_82544GC_COPPER 0x100C
+#define E1000_DEV_ID_82544GC_LOM    0x100D
+#define E1000_DEV_ID_82540EM	    0x100E
+#define E1000_DEV_ID_82540EM_LOM         0x1015
+#define E1000_DEV_ID_82540EP_LOM         0x1016
+#define E1000_DEV_ID_82540EP             0x1017
+#define E1000_DEV_ID_82540EP_LP          0x101E
+#define E1000_DEV_ID_82545EM_COPPER      0x100F
+#define E1000_DEV_ID_82545EM_FIBER       0x1011
+#define E1000_DEV_ID_82545GM_COPPER      0x1026
+#define E1000_DEV_ID_82545GM_FIBER       0x1027
+#define E1000_DEV_ID_82545GM_SERDES      0x1028
+#define E1000_DEV_ID_82546EB_COPPER      0x1010
+#define E1000_DEV_ID_82546EB_FIBER       0x1012
+#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
+#define E1000_DEV_ID_82541EI             0x1013
+#define E1000_DEV_ID_82541EI_MOBILE      0x1018
+#define E1000_DEV_ID_82541ER_LOM         0x1014
+#define E1000_DEV_ID_82541ER             0x1078
+#define E1000_DEV_ID_82547GI             0x1075
+#define E1000_DEV_ID_82541GI             0x1076
+#define E1000_DEV_ID_82541GI_MOBILE      0x1077
+#define E1000_DEV_ID_82541GI_LF          0x107C
+#define E1000_DEV_ID_82546GB_COPPER      0x1079
+#define E1000_DEV_ID_82546GB_FIBER       0x107A
+#define E1000_DEV_ID_82546GB_SERDES      0x107B
+#define E1000_DEV_ID_82546GB_PCIE        0x108A
+#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
+#define E1000_DEV_ID_82547EI             0x1019
+#define E1000_DEV_ID_82547EI_MOBILE      0x101A
+#define E1000_DEV_ID_82571EB_COPPER      0x105E
+#define E1000_DEV_ID_82571EB_FIBER       0x105F
+#define E1000_DEV_ID_82571EB_SERDES      0x1060
+#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
+#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
+#define E1000_DEV_ID_82571EB_QUAD_FIBER  0x10A5
+#define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE  0x10BC
+#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
+#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
+#define E1000_DEV_ID_82572EI_COPPER      0x107D
+#define E1000_DEV_ID_82572EI_FIBER       0x107E
+#define E1000_DEV_ID_82572EI_SERDES      0x107F
+#define E1000_DEV_ID_82572EI             0x10B9
+#define E1000_DEV_ID_82573E              0x108B
+#define E1000_DEV_ID_82573E_IAMT         0x108C
+#define E1000_DEV_ID_82573L              0x109A
+#define E1000_DEV_ID_82574L              0x10D3
+#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5
+#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT     0x1096
+#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT     0x1098
+#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT     0x10BA
+#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT     0x10BB
+
+#define E1000_DEV_ID_ICH8_IGP_M_AMT      0x1049
+#define E1000_DEV_ID_ICH8_IGP_AMT        0x104A
+#define E1000_DEV_ID_ICH8_IGP_C          0x104B
+#define E1000_DEV_ID_ICH8_IFE            0x104C
+#define E1000_DEV_ID_ICH8_IFE_GT         0x10C4
+#define E1000_DEV_ID_ICH8_IFE_G          0x10C5
+#define E1000_DEV_ID_ICH8_IGP_M          0x104D
+
+#define IGP03E1000_E_PHY_ID  0x02A80390
+#define IFE_E_PHY_ID         0x02A80330 /* 10/100 PHY */
+#define IFE_PLUS_E_PHY_ID    0x02A80320
+#define IFE_C_E_PHY_ID       0x02A80310
+
+#define IFE_PHY_EXTENDED_STATUS_CONTROL   0x10  /* 100BaseTx Extended Status,
+						   Control and Address */
+#define IFE_PHY_SPECIAL_CONTROL           0x11  /* 100BaseTx PHY special
+						   control register */
+#define IFE_PHY_RCV_FALSE_CARRIER         0x13  /* 100BaseTx Receive false
+						   Carrier Counter */
+#define IFE_PHY_RCV_DISCONNECT            0x14  /* 100BaseTx Receive Disconnet
+						   Counter */
+#define IFE_PHY_RCV_ERROT_FRAME           0x15  /* 100BaseTx Receive Error
+						   Frame Counter */
+#define IFE_PHY_RCV_SYMBOL_ERR            0x16  /* Receive Symbol Error
+						   Counter */
+#define IFE_PHY_PREM_EOF_ERR              0x17  /* 100BaseTx Receive
+						   Premature End Of Frame
+						   Error Counter */
+#define IFE_PHY_RCV_EOF_ERR               0x18  /* 10BaseT Receive End Of
+						   Frame Error Counter */
+#define IFE_PHY_TX_JABBER_DETECT          0x19  /* 10BaseT Transmit Jabber
+						   Detect Counter */
+#define IFE_PHY_EQUALIZER                 0x1A  /* PHY Equalizer Control and
+						   Status */
+#define IFE_PHY_SPECIAL_CONTROL_LED       0x1B  /* PHY special control and
+						   LED configuration */
+#define IFE_PHY_MDIX_CONTROL              0x1C  /* MDI/MDI-X Control register */
+#define IFE_PHY_HWI_CONTROL               0x1D  /* Hardware Integrity Control
+						   (HWI) */
+
+#define IFE_PESC_REDUCED_POWER_DOWN_DISABLE  0x2000  /* Defaut 1 = Disable auto
+							reduced power down */
+#define IFE_PESC_100BTX_POWER_DOWN           0x0400  /* Indicates the power
+							state of 100BASE-TX */
+#define IFE_PESC_10BTX_POWER_DOWN            0x0200  /* Indicates the power
+							state of 10BASE-T */
+#define IFE_PESC_POLARITY_REVERSED           0x0100  /* Indicates 10BASE-T
+							polarity */
+#define IFE_PESC_PHY_ADDR_MASK               0x007C  /* Bit 6:2 for sampled PHY
+							address */
+#define IFE_PESC_SPEED                       0x0002  /* Auto-negotiation speed
+						result 1=100Mbs, 0=10Mbs */
+#define IFE_PESC_DUPLEX                      0x0001  /* Auto-negotiation
+						duplex result 1=Full, 0=Half */
+#define IFE_PESC_POLARITY_REVERSED_SHIFT     8
+
+#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN   0x0100  /* 1 = Dyanmic Power Down
+							disabled */
+#define IFE_PSC_FORCE_POLARITY               0x0020  /* 1=Reversed Polarity,
+							0=Normal */
+#define IFE_PSC_AUTO_POLARITY_DISABLE        0x0010  /* 1=Auto Polarity
+							Disabled, 0=Enabled */
+#define IFE_PSC_JABBER_FUNC_DISABLE          0x0001  /* 1=Jabber Disabled,
+						0=Normal Jabber Operation */
+#define IFE_PSC_FORCE_POLARITY_SHIFT         5
+#define IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT  4
+
+#define IFE_PMC_AUTO_MDIX                    0x0080  /* 1=enable MDI/MDI-X
+						feature, default 0=disabled */
+#define IFE_PMC_FORCE_MDIX                   0x0040  /* 1=force MDIX-X,
+							0=force MDI */
+#define IFE_PMC_MDIX_STATUS                  0x0020  /* 1=MDI-X, 0=MDI */
+#define IFE_PMC_AUTO_MDIX_COMPLETE           0x0010  /* Resolution algorithm
+							is completed */
+#define IFE_PMC_MDIX_MODE_SHIFT              6
+#define IFE_PHC_MDIX_RESET_ALL_MASK          0x0000  /* Disable auto MDI-X */
+
+#define IFE_PHC_HWI_ENABLE                   0x8000  /* Enable the HWI
+							feature */
+#define IFE_PHC_ABILITY_CHECK                0x4000  /* 1= Test Passed,
+							0=failed */
+#define IFE_PHC_TEST_EXEC                    0x2000  /* PHY launch test pulses
+							on the wire */
+#define IFE_PHC_HIGHZ                        0x0200  /* 1 = Open Circuit */
+#define IFE_PHC_LOWZ                         0x0400  /* 1 = Short Circuit */
+#define IFE_PHC_LOW_HIGH_Z_MASK              0x0600  /* Mask for indication
+						type of problem on the line */
+#define IFE_PHC_DISTANCE_MASK                0x01FF  /* Mask for distance to
+				the cable problem, in 80cm granularity */
+#define IFE_PHC_RESET_ALL_MASK               0x0000  /* Disable HWI */
+#define IFE_PSCL_PROBE_MODE                  0x0020  /* LED Probe mode */
+#define IFE_PSCL_PROBE_LEDS_OFF              0x0006  /* Force LEDs 0 and 2
+							off */
+#define IFE_PSCL_PROBE_LEDS_ON               0x0007  /* Force LEDs 0 and 2 on */
+
+
+#define NUM_DEV_IDS 16
+
+#define NODE_ADDRESS_SIZE 6
+#define ETH_LENGTH_OF_ADDRESS 6
+
+/* MAC decode size is 128K - This is the size of BAR0 */
+#define MAC_DECODE_SIZE (128 * 1024)
+
+#define E1000_82542_2_0_REV_ID 2
+#define E1000_82542_2_1_REV_ID 3
+#define E1000_REVISION_0       0
+#define E1000_REVISION_1       1
+#define E1000_REVISION_2       2
+#define E1000_REVISION_3       3
+
+#define SPEED_10    10
+#define SPEED_100   100
+#define SPEED_1000  1000
+#define HALF_DUPLEX 1
+#define FULL_DUPLEX 2
+
+/* The sizes (in bytes) of a ethernet packet */
+#define ENET_HEADER_SIZE	     14
+#define MAXIMUM_ETHERNET_FRAME_SIZE  1518	/* With FCS */
+#define MINIMUM_ETHERNET_FRAME_SIZE  64	/* With FCS */
+#define ETHERNET_FCS_SIZE	     4
+#define MAXIMUM_ETHERNET_PACKET_SIZE \
+    (MAXIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
+#define MINIMUM_ETHERNET_PACKET_SIZE \
+    (MINIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
+#define CRC_LENGTH		     ETHERNET_FCS_SIZE
+#define MAX_JUMBO_FRAME_SIZE	     0x3F00
+
+/* 802.1q VLAN Packet Sizes */
+#define VLAN_TAG_SIZE			  4	/* 802.3ac tag (not DMAed) */
+
+/* Ethertype field values */
+#define ETHERNET_IEEE_VLAN_TYPE 0x8100	/* 802.3ac packet */
+#define ETHERNET_IP_TYPE	0x0800	/* IP packets */
+#define ETHERNET_ARP_TYPE	0x0806	/* Address Resolution Protocol (ARP) */
+
+/* Packet Header defines */
+#define IP_PROTOCOL_TCP    6
+#define IP_PROTOCOL_UDP    0x11
+
+/* This defines the bits that are set in the Interrupt Mask
+ * Set/Read Register.  Each bit is documented below:
+ *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
+ *   o RXSEQ  = Receive Sequence Error
+ */
+#define POLL_IMS_ENABLE_MASK ( \
+    E1000_IMS_RXDMT0 |	       \
+    E1000_IMS_RXSEQ)
+
+/* This defines the bits that are set in the Interrupt Mask
+ * Set/Read Register.  Each bit is documented below:
+ *   o RXT0   = Receiver Timer Interrupt (ring 0)
+ *   o TXDW   = Transmit Descriptor Written Back
+ *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
+ *   o RXSEQ  = Receive Sequence Error
+ *   o LSC    = Link Status Change
+ */
+#define IMS_ENABLE_MASK ( \
+    E1000_IMS_RXT0   |	  \
+    E1000_IMS_TXDW   |	  \
+    E1000_IMS_RXDMT0 |	  \
+    E1000_IMS_RXSEQ  |	  \
+    E1000_IMS_LSC)
+
+/* The number of high/low register pairs in the RAR. The RAR (Receive Address
+ * Registers) holds the directed and multicast addresses that we monitor. We
+ * reserve one of these spots for our directed address, allowing us room for
+ * E1000_RAR_ENTRIES - 1 multicast addresses.
+ */
+#define E1000_RAR_ENTRIES 16
+
+#define MIN_NUMBER_OF_DESCRIPTORS 8
+#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
+
+/* Receive Descriptor */
+struct e1000_rx_desc {
+	uint64_t buffer_addr;	/* Address of the descriptor's data buffer */
+	uint16_t length;	/* Length of data DMAed into data buffer */
+	uint16_t csum;		/* Packet checksum */
+	uint8_t status;		/* Descriptor status */
+	uint8_t errors;		/* Descriptor Errors */
+	uint16_t special;
+};
+
+/* Receive Decriptor bit definitions */
+#define E1000_RXD_STAT_DD	0x01	/* Descriptor Done */
+#define E1000_RXD_STAT_EOP	0x02	/* End of Packet */
+#define E1000_RXD_STAT_IXSM	0x04	/* Ignore checksum */
+#define E1000_RXD_STAT_VP	0x08	/* IEEE VLAN Packet */
+#define E1000_RXD_STAT_TCPCS	0x20	/* TCP xsum calculated */
+#define E1000_RXD_STAT_IPCS	0x40	/* IP xsum calculated */
+#define E1000_RXD_STAT_PIF	0x80	/* passed in-exact filter */
+#define E1000_RXD_ERR_CE	0x01	/* CRC Error */
+#define E1000_RXD_ERR_SE	0x02	/* Symbol Error */
+#define E1000_RXD_ERR_SEQ	0x04	/* Sequence Error */
+#define E1000_RXD_ERR_CXE	0x10	/* Carrier Extension Error */
+#define E1000_RXD_ERR_TCPE	0x20	/* TCP/UDP Checksum Error */
+#define E1000_RXD_ERR_IPE	0x40	/* IP Checksum Error */
+#define E1000_RXD_ERR_RXE	0x80	/* Rx Data Error */
+#define E1000_RXD_SPC_VLAN_MASK 0x0FFF	/* VLAN ID is in lower 12 bits */
+#define E1000_RXD_SPC_PRI_MASK	0xE000	/* Priority is in upper 3 bits */
+#define E1000_RXD_SPC_PRI_SHIFT 0x000D	/* Priority is in upper 3 of 16 */
+#define E1000_RXD_SPC_CFI_MASK	0x1000	/* CFI is bit 12 */
+#define E1000_RXD_SPC_CFI_SHIFT 0x000C	/* CFI is bit 12 */
+
+/* mask to determine if packets should be dropped due to frame errors */
+#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
+    E1000_RXD_ERR_CE  |		       \
+    E1000_RXD_ERR_SE  |		       \
+    E1000_RXD_ERR_SEQ |		       \
+    E1000_RXD_ERR_CXE |		       \
+    E1000_RXD_ERR_RXE)
+
+/* Transmit Descriptor */
+struct e1000_tx_desc {
+	uint64_t buffer_addr;	/* Address of the descriptor's data buffer */
+	union {
+		uint32_t data;
+		struct {
+			uint16_t length;	/* Data buffer length */
+			uint8_t cso;	/* Checksum offset */
+			uint8_t cmd;	/* Descriptor control */
+		} flags;
+	} lower;
+	union {
+		uint32_t data;
+		struct {
+			uint8_t status;	/* Descriptor status */
+			uint8_t css;	/* Checksum start */
+			uint16_t special;
+		} fields;
+	} upper;
+};
+
+/* Transmit Descriptor bit definitions */
+#define E1000_TXD_DTYP_D     0x00100000	/* Data Descriptor */
+#define E1000_TXD_DTYP_C     0x00000000	/* Context Descriptor */
+#define E1000_TXD_POPTS_IXSM 0x01	/* Insert IP checksum */
+#define E1000_TXD_POPTS_TXSM 0x02	/* Insert TCP/UDP checksum */
+#define E1000_TXD_CMD_EOP    0x01000000	/* End of Packet */
+#define E1000_TXD_CMD_IFCS   0x02000000	/* Insert FCS (Ethernet CRC) */
+#define E1000_TXD_CMD_IC     0x04000000	/* Insert Checksum */
+#define E1000_TXD_CMD_RS     0x08000000	/* Report Status */
+#define E1000_TXD_CMD_RPS    0x10000000	/* Report Packet Sent */
+#define E1000_TXD_CMD_DEXT   0x20000000	/* Descriptor extension (0 = legacy) */
+#define E1000_TXD_CMD_VLE    0x40000000	/* Add VLAN tag */
+#define E1000_TXD_CMD_IDE    0x80000000	/* Enable Tidv register */
+#define E1000_TXD_STAT_DD    0x00000001	/* Descriptor Done */
+#define E1000_TXD_STAT_EC    0x00000002	/* Excess Collisions */
+#define E1000_TXD_STAT_LC    0x00000004	/* Late Collisions */
+#define E1000_TXD_STAT_TU    0x00000008	/* Transmit underrun */
+#define E1000_TXD_CMD_TCP    0x01000000	/* TCP packet */
+#define E1000_TXD_CMD_IP     0x02000000	/* IP packet */
+#define E1000_TXD_CMD_TSE    0x04000000	/* TCP Seg enable */
+#define E1000_TXD_STAT_TC    0x00000004	/* Tx Underrun */
+
+/* Offload Context Descriptor */
+struct e1000_context_desc {
+	union {
+		uint32_t ip_config;
+		struct {
+			uint8_t ipcss;	/* IP checksum start */
+			uint8_t ipcso;	/* IP checksum offset */
+			uint16_t ipcse;	/* IP checksum end */
+		} ip_fields;
+	} lower_setup;
+	union {
+		uint32_t tcp_config;
+		struct {
+			uint8_t tucss;	/* TCP checksum start */
+			uint8_t tucso;	/* TCP checksum offset */
+			uint16_t tucse;	/* TCP checksum end */
+		} tcp_fields;
+	} upper_setup;
+	uint32_t cmd_and_length;	/* */
+	union {
+		uint32_t data;
+		struct {
+			uint8_t status;	/* Descriptor status */
+			uint8_t hdr_len;	/* Header length */
+			uint16_t mss;	/* Maximum segment size */
+		} fields;
+	} tcp_seg_setup;
+};
+
+/* Offload data descriptor */
+struct e1000_data_desc {
+	uint64_t buffer_addr;	/* Address of the descriptor's buffer address */
+	union {
+		uint32_t data;
+		struct {
+			uint16_t length;	/* Data buffer length */
+			uint8_t typ_len_ext;	/* */
+			uint8_t cmd;	/* */
+		} flags;
+	} lower;
+	union {
+		uint32_t data;
+		struct {
+			uint8_t status;	/* Descriptor status */
+			uint8_t popts;	/* Packet Options */
+			uint16_t special;	/* */
+		} fields;
+	} upper;
+};
+
+/* Filters */
+#define E1000_NUM_UNICAST	   16	/* Unicast filter entries */
+#define E1000_MC_TBL_SIZE	   128	/* Multicast Filter Table (4096 bits) */
+#define E1000_VLAN_FILTER_TBL_SIZE 128	/* VLAN Filter Table (4096 bits) */
+
+/* Receive Address Register */
+struct e1000_rar {
+	volatile uint32_t low;	/* receive address low */
+	volatile uint32_t high;	/* receive address high */
+};
+
+/* The number of entries in the Multicast Table Array (MTA). */
+#define E1000_NUM_MTA_REGISTERS 128
+
+/* IPv4 Address Table Entry */
+struct e1000_ipv4_at_entry {
+	volatile uint32_t ipv4_addr;	/* IP Address (RW) */
+	volatile uint32_t reserved;
+};
+
+/* Four wakeup IP addresses are supported */
+#define E1000_WAKEUP_IP_ADDRESS_COUNT_MAX 4
+#define E1000_IP4AT_SIZE		  E1000_WAKEUP_IP_ADDRESS_COUNT_MAX
+#define E1000_IP6AT_SIZE		  1
+
+/* IPv6 Address Table Entry */
+struct e1000_ipv6_at_entry {
+	volatile uint8_t ipv6_addr[16];
+};
+
+/* Flexible Filter Length Table Entry */
+struct e1000_fflt_entry {
+	volatile uint32_t length;	/* Flexible Filter Length (RW) */
+	volatile uint32_t reserved;
+};
+
+/* Flexible Filter Mask Table Entry */
+struct e1000_ffmt_entry {
+	volatile uint32_t mask;	/* Flexible Filter Mask (RW) */
+	volatile uint32_t reserved;
+};
+
+/* Flexible Filter Value Table Entry */
+struct e1000_ffvt_entry {
+	volatile uint32_t value;	/* Flexible Filter Value (RW) */
+	volatile uint32_t reserved;
+};
+
+/* Four Flexible Filters are supported */
+#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
+
+/* Each Flexible Filter is at most 128 (0x80) bytes in length */
+#define E1000_FLEXIBLE_FILTER_SIZE_MAX	128
+
+#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX
+#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
+#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
+
+/* Register Set. (82543, 82544)
+ *
+ * Registers are defined to be 32 bits and  should be accessed as 32 bit values.
+ * These registers are physically located on the NIC, but are mapped into the
+ * host memory address space.
+ *
+ * RW - register is both readable and writable
+ * RO - register is read only
+ * WO - register is write only
+ * R/clr - register is read only and is cleared when read
+ * A - register array
+ */
+#define E1000_CTRL     0x00000	/* Device Control - RW */
+#define E1000_STATUS   0x00008	/* Device Status - RO */
+#define E1000_EECD     0x00010	/* EEPROM/Flash Control - RW */
+#define E1000_EERD     0x00014	/* EEPROM Read - RW */
+#define E1000_CTRL_EXT 0x00018	/* Extended Device Control - RW */
+#define E1000_MDIC     0x00020	/* MDI Control - RW */
+#define E1000_FCAL     0x00028	/* Flow Control Address Low - RW */
+#define E1000_FCAH     0x0002C	/* Flow Control Address High -RW */
+#define E1000_FCT      0x00030	/* Flow Control Type - RW */
+#define E1000_VET      0x00038	/* VLAN Ether Type - RW */
+#define E1000_ICR      0x000C0	/* Interrupt Cause Read - R/clr */
+#define E1000_ITR      0x000C4	/* Interrupt Throttling Rate - RW */
+#define E1000_ICS      0x000C8	/* Interrupt Cause Set - WO */
+#define E1000_IMS      0x000D0	/* Interrupt Mask Set - RW */
+#define E1000_IMC      0x000D8	/* Interrupt Mask Clear - WO */
+#define E1000_RCTL     0x00100	/* RX Control - RW */
+#define E1000_FCTTV    0x00170	/* Flow Control Transmit Timer Value - RW */
+#define E1000_TXCW     0x00178	/* TX Configuration Word - RW */
+#define E1000_RXCW     0x00180	/* RX Configuration Word - RO */
+#define E1000_TCTL     0x00400	/* TX Control - RW */
+#define E1000_TCTL_EXT 0x00404  /* Extended TX Control - RW */
+#define E1000_TIPG     0x00410	/* TX Inter-packet gap -RW */
+#define E1000_TBT      0x00448	/* TX Burst Timer - RW */
+#define E1000_AIT      0x00458	/* Adaptive Interframe Spacing Throttle - RW */
+#define E1000_LEDCTL   0x00E00	/* LED Control - RW */
+#define E1000_EXTCNF_CTRL  0x00F00  /* Extended Configuration Control */
+#define E1000_EXTCNF_SIZE  0x00F08  /* Extended Configuration Size */
+#define E1000_PHY_CTRL     0x00F10  /* PHY Control Register in CSR */
+#define FEXTNVM_SW_CONFIG  0x0001
+#define E1000_PBA      0x01000	/* Packet Buffer Allocation - RW */
+#define E1000_PBS      0x01008  /* Packet Buffer Size */
+#define E1000_EEMNGCTL 0x01010  /* MNG EEprom Control */
+#define E1000_FLASH_UPDATES 1000
+#define E1000_EEARBC   0x01024  /* EEPROM Auto Read Bus Control */
+#define E1000_FLASHT   0x01028  /* FLASH Timer Register */
+#define E1000_EEWR     0x0102C  /* EEPROM Write Register - RW */
+#define E1000_FLSWCTL  0x01030  /* FLASH control register */
+#define E1000_FLSWDATA 0x01034  /* FLASH data register */
+#define E1000_FLSWCNT  0x01038  /* FLASH Access Counter */
+#define E1000_FLOP     0x0103C  /* FLASH Opcode Register */
+#define E1000_ERT      0x02008  /* Early Rx Threshold - RW */
+#define E1000_FCRTL    0x02160	/* Flow Control Receive Threshold Low - RW */
+#define E1000_FCRTH    0x02168	/* Flow Control Receive Threshold High - RW */
+#define E1000_RDBAL    0x02800	/* RX Descriptor Base Address Low - RW */
+#define E1000_RDBAH    0x02804	/* RX Descriptor Base Address High - RW */
+#define E1000_RDLEN    0x02808	/* RX Descriptor Length - RW */
+#define E1000_RDH      0x02810	/* RX Descriptor Head - RW */
+#define E1000_RDT      0x02818	/* RX Descriptor Tail - RW */
+#define E1000_RDTR     0x02820	/* RX Delay Timer - RW */
+#define E1000_RXDCTL   0x02828	/* RX Descriptor Control - RW */
+#define E1000_RADV     0x0282C	/* RX Interrupt Absolute Delay Timer - RW */
+#define E1000_RSRPD    0x02C00	/* RX Small Packet Detect - RW */
+#define E1000_TXDMAC   0x03000	/* TX DMA Control - RW */
+#define E1000_TDFH     0x03410  /* TX Data FIFO Head - RW */
+#define E1000_TDFT     0x03418  /* TX Data FIFO Tail - RW */
+#define E1000_TDFHS    0x03420  /* TX Data FIFO Head Saved - RW */
+#define E1000_TDFTS    0x03428  /* TX Data FIFO Tail Saved - RW */
+#define E1000_TDFPC    0x03430  /* TX Data FIFO Packet Count - RW */
+#define E1000_TDBAL    0x03800	/* TX Descriptor Base Address Low - RW */
+#define E1000_TDBAH    0x03804	/* TX Descriptor Base Address High - RW */
+#define E1000_TDLEN    0x03808	/* TX Descriptor Length - RW */
+#define E1000_TDH      0x03810	/* TX Descriptor Head - RW */
+#define E1000_TDT      0x03818	/* TX Descripotr Tail - RW */
+#define E1000_TIDV     0x03820	/* TX Interrupt Delay Value - RW */
+#define E1000_TXDCTL   0x03828	/* TX Descriptor Control - RW */
+#define E1000_TADV     0x0382C	/* TX Interrupt Absolute Delay Val - RW */
+#define E1000_TSPMT    0x03830	/* TCP Segmentation PAD & Min Threshold - RW */
+#define E1000_TARC0    0x03840  /* TX Arbitration Count (0) */
+#define E1000_TDBAL1   0x03900  /* TX Desc Base Address Low (1) - RW */
+#define E1000_TDBAH1   0x03904  /* TX Desc Base Address High (1) - RW */
+#define E1000_TDLEN1   0x03908  /* TX Desc Length (1) - RW */
+#define E1000_TDH1     0x03910  /* TX Desc Head (1) - RW */
+#define E1000_TDT1     0x03918  /* TX Desc Tail (1) - RW */
+#define E1000_TXDCTL1  0x03928  /* TX Descriptor Control (1) - RW */
+#define E1000_TARC1    0x03940  /* TX Arbitration Count (1) */
+#define E1000_CRCERRS  0x04000	/* CRC Error Count - R/clr */
+#define E1000_ALGNERRC 0x04004	/* Alignment Error Count - R/clr */
+#define E1000_SYMERRS  0x04008	/* Symbol Error Count - R/clr */
+#define E1000_RXERRC   0x0400C	/* Receive Error Count - R/clr */
+#define E1000_MPC      0x04010	/* Missed Packet Count - R/clr */
+#define E1000_SCC      0x04014	/* Single Collision Count - R/clr */
+#define E1000_ECOL     0x04018	/* Excessive Collision Count - R/clr */
+#define E1000_MCC      0x0401C	/* Multiple Collision Count - R/clr */
+#define E1000_LATECOL  0x04020	/* Late Collision Count - R/clr */
+#define E1000_COLC     0x04028	/* Collision Count - R/clr */
+#define E1000_DC       0x04030	/* Defer Count - R/clr */
+#define E1000_TNCRS    0x04034	/* TX-No CRS - R/clr */
+#define E1000_SEC      0x04038	/* Sequence Error Count - R/clr */
+#define E1000_CEXTERR  0x0403C	/* Carrier Extension Error Count - R/clr */
+#define E1000_RLEC     0x04040	/* Receive Length Error Count - R/clr */
+#define E1000_XONRXC   0x04048	/* XON RX Count - R/clr */
+#define E1000_XONTXC   0x0404C	/* XON TX Count - R/clr */
+#define E1000_XOFFRXC  0x04050	/* XOFF RX Count - R/clr */
+#define E1000_XOFFTXC  0x04054	/* XOFF TX Count - R/clr */
+#define E1000_FCRUC    0x04058	/* Flow Control RX Unsupported Count- R/clr */
+#define E1000_PRC64    0x0405C	/* Packets RX (64 bytes) - R/clr */
+#define E1000_PRC127   0x04060	/* Packets RX (65-127 bytes) - R/clr */
+#define E1000_PRC255   0x04064	/* Packets RX (128-255 bytes) - R/clr */
+#define E1000_PRC511   0x04068	/* Packets RX (255-511 bytes) - R/clr */
+#define E1000_PRC1023  0x0406C	/* Packets RX (512-1023 bytes) - R/clr */
+#define E1000_PRC1522  0x04070	/* Packets RX (1024-1522 bytes) - R/clr */
+#define E1000_GPRC     0x04074	/* Good Packets RX Count - R/clr */
+#define E1000_BPRC     0x04078	/* Broadcast Packets RX Count - R/clr */
+#define E1000_MPRC     0x0407C	/* Multicast Packets RX Count - R/clr */
+#define E1000_GPTC     0x04080	/* Good Packets TX Count - R/clr */
+#define E1000_GORCL    0x04088	/* Good Octets RX Count Low - R/clr */
+#define E1000_GORCH    0x0408C	/* Good Octets RX Count High - R/clr */
+#define E1000_GOTCL    0x04090	/* Good Octets TX Count Low - R/clr */
+#define E1000_GOTCH    0x04094	/* Good Octets TX Count High - R/clr */
+#define E1000_RNBC     0x040A0	/* RX No Buffers Count - R/clr */
+#define E1000_RUC      0x040A4	/* RX Undersize Count - R/clr */
+#define E1000_RFC      0x040A8	/* RX Fragment Count - R/clr */
+#define E1000_ROC      0x040AC	/* RX Oversize Count - R/clr */
+#define E1000_RJC      0x040B0	/* RX Jabber Count - R/clr */
+#define E1000_MGTPRC   0x040B4	/* Management Packets RX Count - R/clr */
+#define E1000_MGTPDC   0x040B8	/* Management Packets Dropped Count - R/clr */
+#define E1000_MGTPTC   0x040BC	/* Management Packets TX Count - R/clr */
+#define E1000_TORL     0x040C0	/* Total Octets RX Low - R/clr */
+#define E1000_TORH     0x040C4	/* Total Octets RX High - R/clr */
+#define E1000_TOTL     0x040C8	/* Total Octets TX Low - R/clr */
+#define E1000_TOTH     0x040CC	/* Total Octets TX High - R/clr */
+#define E1000_TPR      0x040D0	/* Total Packets RX - R/clr */
+#define E1000_TPT      0x040D4	/* Total Packets TX - R/clr */
+#define E1000_PTC64    0x040D8	/* Packets TX (64 bytes) - R/clr */
+#define E1000_PTC127   0x040DC	/* Packets TX (65-127 bytes) - R/clr */
+#define E1000_PTC255   0x040E0	/* Packets TX (128-255 bytes) - R/clr */
+#define E1000_PTC511   0x040E4	/* Packets TX (256-511 bytes) - R/clr */
+#define E1000_PTC1023  0x040E8	/* Packets TX (512-1023 bytes) - R/clr */
+#define E1000_PTC1522  0x040EC	/* Packets TX (1024-1522 Bytes) - R/clr */
+#define E1000_MPTC     0x040F0	/* Multicast Packets TX Count - R/clr */
+#define E1000_BPTC     0x040F4	/* Broadcast Packets TX Count - R/clr */
+#define E1000_TSCTC    0x040F8	/* TCP Segmentation Context TX - R/clr */
+#define E1000_TSCTFC   0x040FC	/* TCP Segmentation Context TX Fail - R/clr */
+#define E1000_RXCSUM   0x05000	/* RX Checksum Control - RW */
+#define E1000_MTA      0x05200	/* Multicast Table Array - RW Array */
+#define E1000_RA       0x05400	/* Receive Address - RW Array */
+#define E1000_VFTA     0x05600	/* VLAN Filter Table Array - RW Array */
+#define E1000_WUC      0x05800	/* Wakeup Control - RW */
+#define E1000_WUFC     0x05808	/* Wakeup Filter Control - RW */
+#define E1000_WUS      0x05810	/* Wakeup Status - RO */
+#define E1000_MANC     0x05820	/* Management Control - RW */
+#define E1000_IPAV     0x05838	/* IP Address Valid - RW */
+#define E1000_IP4AT    0x05840	/* IPv4 Address Table - RW Array */
+#define E1000_IP6AT    0x05880	/* IPv6 Address Table - RW Array */
+#define E1000_WUPL     0x05900	/* Wakeup Packet Length - RW */
+#define E1000_WUPM     0x05A00	/* Wakeup Packet Memory - RO A */
+#define E1000_FFLT     0x05F00	/* Flexible Filter Length Table - RW Array */
+#define E1000_FFMT     0x09000	/* Flexible Filter Mask Table - RW Array */
+#define E1000_FFVT     0x09800	/* Flexible Filter Value Table - RW Array */
+
+/* Register Set (82542)
+ *
+ * Some of the 82542 registers are located at different offsets than they are
+ * in more current versions of the 8254x. Despite the difference in location,
+ * the registers function in the same manner.
+ */
+#define E1000_82542_CTRL     E1000_CTRL
+#define E1000_82542_STATUS   E1000_STATUS
+#define E1000_82542_EECD     E1000_EECD
+#define E1000_82542_EERD     E1000_EERD
+#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
+#define E1000_82542_MDIC     E1000_MDIC
+#define E1000_82542_FCAL     E1000_FCAL
+#define E1000_82542_FCAH     E1000_FCAH
+#define E1000_82542_FCT      E1000_FCT
+#define E1000_82542_VET      E1000_VET
+#define E1000_82542_RA	     0x00040
+#define E1000_82542_ICR      E1000_ICR
+#define E1000_82542_ITR      E1000_ITR
+#define E1000_82542_ICS      E1000_ICS
+#define E1000_82542_IMS      E1000_IMS
+#define E1000_82542_IMC      E1000_IMC
+#define E1000_82542_RCTL     E1000_RCTL
+#define E1000_82542_RDTR     0x00108
+#define E1000_82542_RDBAL    0x00110
+#define E1000_82542_RDBAH    0x00114
+#define E1000_82542_RDLEN    0x00118
+#define E1000_82542_RDH      0x00120
+#define E1000_82542_RDT      0x00128
+#define E1000_82542_FCRTH    0x00160
+#define E1000_82542_FCRTL    0x00168
+#define E1000_82542_FCTTV    E1000_FCTTV
+#define E1000_82542_TXCW     E1000_TXCW
+#define E1000_82542_RXCW     E1000_RXCW
+#define E1000_82542_MTA      0x00200
+#define E1000_82542_TCTL     E1000_TCTL
+#define E1000_82542_TIPG     E1000_TIPG
+#define E1000_82542_TDBAL    0x00420
+#define E1000_82542_TDBAH    0x00424
+#define E1000_82542_TDLEN    0x00428
+#define E1000_82542_TDH      0x00430
+#define E1000_82542_TDT      0x00438
+#define E1000_82542_TIDV     0x00440
+#define E1000_82542_TBT      E1000_TBT
+#define E1000_82542_AIT      E1000_AIT
+#define E1000_82542_VFTA     0x00600
+#define E1000_82542_LEDCTL   E1000_LEDCTL
+#define E1000_82542_PBA      E1000_PBA
+#define E1000_82542_RXDCTL   E1000_RXDCTL
+#define E1000_82542_RADV     E1000_RADV
+#define E1000_82542_RSRPD    E1000_RSRPD
+#define E1000_82542_TXDMAC   E1000_TXDMAC
+#define E1000_82542_TXDCTL   E1000_TXDCTL
+#define E1000_82542_TADV     E1000_TADV
+#define E1000_82542_TSPMT    E1000_TSPMT
+#define E1000_82542_CRCERRS  E1000_CRCERRS
+#define E1000_82542_ALGNERRC E1000_ALGNERRC
+#define E1000_82542_SYMERRS  E1000_SYMERRS
+#define E1000_82542_RXERRC   E1000_RXERRC
+#define E1000_82542_MPC      E1000_MPC
+#define E1000_82542_SCC      E1000_SCC
+#define E1000_82542_ECOL     E1000_ECOL
+#define E1000_82542_MCC      E1000_MCC
+#define E1000_82542_LATECOL  E1000_LATECOL
+#define E1000_82542_COLC     E1000_COLC
+#define E1000_82542_DC	     E1000_DC
+#define E1000_82542_TNCRS    E1000_TNCRS
+#define E1000_82542_SEC      E1000_SEC
+#define E1000_82542_CEXTERR  E1000_CEXTERR
+#define E1000_82542_RLEC     E1000_RLEC
+#define E1000_82542_XONRXC   E1000_XONRXC
+#define E1000_82542_XONTXC   E1000_XONTXC
+#define E1000_82542_XOFFRXC  E1000_XOFFRXC
+#define E1000_82542_XOFFTXC  E1000_XOFFTXC
+#define E1000_82542_FCRUC    E1000_FCRUC
+#define E1000_82542_PRC64    E1000_PRC64
+#define E1000_82542_PRC127   E1000_PRC127
+#define E1000_82542_PRC255   E1000_PRC255
+#define E1000_82542_PRC511   E1000_PRC511
+#define E1000_82542_PRC1023  E1000_PRC1023
+#define E1000_82542_PRC1522  E1000_PRC1522
+#define E1000_82542_GPRC     E1000_GPRC
+#define E1000_82542_BPRC     E1000_BPRC
+#define E1000_82542_MPRC     E1000_MPRC
+#define E1000_82542_GPTC     E1000_GPTC
+#define E1000_82542_GORCL    E1000_GORCL
+#define E1000_82542_GORCH    E1000_GORCH
+#define E1000_82542_GOTCL    E1000_GOTCL
+#define E1000_82542_GOTCH    E1000_GOTCH
+#define E1000_82542_RNBC     E1000_RNBC
+#define E1000_82542_RUC      E1000_RUC
+#define E1000_82542_RFC      E1000_RFC
+#define E1000_82542_ROC      E1000_ROC
+#define E1000_82542_RJC      E1000_RJC
+#define E1000_82542_MGTPRC   E1000_MGTPRC
+#define E1000_82542_MGTPDC   E1000_MGTPDC
+#define E1000_82542_MGTPTC   E1000_MGTPTC
+#define E1000_82542_TORL     E1000_TORL
+#define E1000_82542_TORH     E1000_TORH
+#define E1000_82542_TOTL     E1000_TOTL
+#define E1000_82542_TOTH     E1000_TOTH
+#define E1000_82542_TPR      E1000_TPR
+#define E1000_82542_TPT      E1000_TPT
+#define E1000_82542_PTC64    E1000_PTC64
+#define E1000_82542_PTC127   E1000_PTC127
+#define E1000_82542_PTC255   E1000_PTC255
+#define E1000_82542_PTC511   E1000_PTC511
+#define E1000_82542_PTC1023  E1000_PTC1023
+#define E1000_82542_PTC1522  E1000_PTC1522
+#define E1000_82542_MPTC     E1000_MPTC
+#define E1000_82542_BPTC     E1000_BPTC
+#define E1000_82542_TSCTC    E1000_TSCTC
+#define E1000_82542_TSCTFC   E1000_TSCTFC
+#define E1000_82542_RXCSUM   E1000_RXCSUM
+#define E1000_82542_WUC      E1000_WUC
+#define E1000_82542_WUFC     E1000_WUFC
+#define E1000_82542_WUS      E1000_WUS
+#define E1000_82542_MANC     E1000_MANC
+#define E1000_82542_IPAV     E1000_IPAV
+#define E1000_82542_IP4AT    E1000_IP4AT
+#define E1000_82542_IP6AT    E1000_IP6AT
+#define E1000_82542_WUPL     E1000_WUPL
+#define E1000_82542_WUPM     E1000_WUPM
+#define E1000_82542_FFLT     E1000_FFLT
+#define E1000_82542_FFMT     E1000_FFMT
+#define E1000_82542_FFVT     E1000_FFVT
+
+/* Statistics counters collected by the MAC */
+struct e1000_hw_stats {
+	uint64_t crcerrs;
+	uint64_t algnerrc;
+	uint64_t symerrs;
+	uint64_t rxerrc;
+	uint64_t mpc;
+	uint64_t scc;
+	uint64_t ecol;
+	uint64_t mcc;
+	uint64_t latecol;
+	uint64_t colc;
+	uint64_t dc;
+	uint64_t tncrs;
+	uint64_t sec;
+	uint64_t cexterr;
+	uint64_t rlec;
+	uint64_t xonrxc;
+	uint64_t xontxc;
+	uint64_t xoffrxc;
+	uint64_t xofftxc;
+	uint64_t fcruc;
+	uint64_t prc64;
+	uint64_t prc127;
+	uint64_t prc255;
+	uint64_t prc511;
+	uint64_t prc1023;
+	uint64_t prc1522;
+	uint64_t gprc;
+	uint64_t bprc;
+	uint64_t mprc;
+	uint64_t gptc;
+	uint64_t gorcl;
+	uint64_t gorch;
+	uint64_t gotcl;
+	uint64_t gotch;
+	uint64_t rnbc;
+	uint64_t ruc;
+	uint64_t rfc;
+	uint64_t roc;
+	uint64_t rjc;
+	uint64_t mgprc;
+	uint64_t mgpdc;
+	uint64_t mgptc;
+	uint64_t torl;
+	uint64_t torh;
+	uint64_t totl;
+	uint64_t toth;
+	uint64_t tpr;
+	uint64_t tpt;
+	uint64_t ptc64;
+	uint64_t ptc127;
+	uint64_t ptc255;
+	uint64_t ptc511;
+	uint64_t ptc1023;
+	uint64_t ptc1522;
+	uint64_t mptc;
+	uint64_t bptc;
+	uint64_t tsctc;
+	uint64_t tsctfc;
+};
+
+#ifndef CONFIG_E1000_NO_NVM
+struct e1000_eeprom_info {
+e1000_eeprom_type type;
+	uint16_t word_size;
+	uint16_t opcode_bits;
+	uint16_t address_bits;
+	uint16_t delay_usec;
+	uint16_t page_size;
+	bool use_eerd;
+	bool use_eewr;
+};
+#endif
+
+typedef enum {
+    e1000_smart_speed_default = 0,
+    e1000_smart_speed_on,
+    e1000_smart_speed_off
+} e1000_smart_speed;
+
+typedef enum {
+    e1000_dsp_config_disabled = 0,
+    e1000_dsp_config_enabled,
+    e1000_dsp_config_activated,
+    e1000_dsp_config_undefined = 0xFF
+} e1000_dsp_config;
+
+typedef enum {
+    e1000_ms_hw_default = 0,
+    e1000_ms_force_master,
+    e1000_ms_force_slave,
+    e1000_ms_auto
+} e1000_ms_type;
+
+typedef enum {
+    e1000_ffe_config_enabled = 0,
+    e1000_ffe_config_active,
+    e1000_ffe_config_blocked
+} e1000_ffe_config;
+
+
+/* Structure containing variables used by the shared code (e1000_hw.c) */
+struct e1000_hw {
+	struct list_head list_node;
+	struct eth_device *nic;
+#ifdef CONFIG_E1000_SPI
+	struct spi_slave spi;
+#endif
+	unsigned int cardnum;
+
+	pci_dev_t pdev;
+	uint8_t *hw_addr;
+	e1000_mac_type mac_type;
+	e1000_phy_type phy_type;
+	uint32_t phy_init_script;
+	uint32_t txd_cmd;
+	e1000_media_type media_type;
+	e1000_fc_type fc;
+	e1000_bus_type bus_type;
+#if 0
+	e1000_bus_speed bus_speed;
+	e1000_bus_width bus_width;
+	uint32_t io_base;
+#endif
+	uint32_t		asf_firmware_present;
+#ifndef CONFIG_E1000_NO_NVM
+	uint32_t		eeprom_semaphore_present;
+#endif
+	uint32_t		swfw_sync_present;
+	uint32_t		swfwhw_semaphore_present;
+#ifndef CONFIG_E1000_NO_NVM
+	struct e1000_eeprom_info eeprom;
+#endif
+	e1000_ms_type		master_slave;
+	e1000_ms_type		original_master_slave;
+	e1000_ffe_config	ffe_config_state;
+	uint32_t phy_id;
+	uint32_t phy_revision;
+	uint32_t phy_addr;
+	uint32_t original_fc;
+	uint32_t txcw;
+	uint32_t autoneg_failed;
+#if 0
+	uint32_t max_frame_size;
+	uint32_t min_frame_size;
+	uint32_t mc_filter_type;
+	uint32_t num_mc_addrs;
+	uint32_t collision_delta;
+	uint32_t tx_packet_delta;
+	uint32_t ledctl_default;
+	uint32_t ledctl_mode1;
+	uint32_t ledctl_mode2;
+#endif
+	uint16_t autoneg_advertised;
+	uint16_t pci_cmd_word;
+	uint16_t fc_high_water;
+	uint16_t fc_low_water;
+	uint16_t fc_pause_time;
+#if 0
+	uint16_t current_ifs_val;
+	uint16_t ifs_min_val;
+	uint16_t ifs_max_val;
+	uint16_t ifs_step_size;
+	uint16_t ifs_ratio;
+#endif
+	uint16_t device_id;
+	uint16_t vendor_id;
+	uint16_t subsystem_id;
+	uint16_t subsystem_vendor_id;
+	uint8_t revision_id;
+	uint8_t autoneg;
+	uint8_t mdix;
+	uint8_t forced_speed_duplex;
+	uint8_t wait_autoneg_complete;
+	uint8_t dma_fairness;
+#if 0
+	uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
+#endif
+	bool disable_polarity_correction;
+	bool		speed_downgraded;
+	bool get_link_status;
+	bool tbi_compatibility_en;
+	bool tbi_compatibility_on;
+	bool		fc_strict_ieee;
+	bool fc_send_xon;
+	bool report_tx_early;
+	bool phy_reset_disable;
+	bool		initialize_hw_bits_disable;
+#if 0
+	bool adaptive_ifs;
+	bool ifs_params_forced;
+	bool in_ifs_mode;
+#endif
+	e1000_smart_speed	smart_speed;
+	e1000_dsp_config	dsp_config_state;
+};
+
+#define E1000_EEPROM_SWDPIN0   0x0001	/* SWDPIN 0 EEPROM Value */
+#define E1000_EEPROM_LED_LOGIC 0x0020	/* Led Logic Word */
+#define E1000_EEPROM_RW_REG_DATA   16   /* Offset to data in EEPROM
+					   read/write registers */
+#define E1000_EEPROM_RW_REG_DONE   2    /* Offset to READ/WRITE done bit */
+#define E1000_EEPROM_RW_REG_START  1    /* First bit for telling part to start
+					   operation */
+#define E1000_EEPROM_RW_ADDR_SHIFT 2    /* Shift to the address bits */
+#define E1000_EEPROM_POLL_WRITE    1    /* Flag for polling for write
+					   complete */
+#define E1000_EEPROM_POLL_READ     0    /* Flag for polling for read complete */
+#define EEPROM_RESERVED_WORD          0xFFFF
+
+/* Register Bit Masks */
+/* Device Control */
+#define E1000_CTRL_FD	    0x00000001	/* Full duplex.0=half; 1=full */
+#define E1000_CTRL_BEM	    0x00000002	/* Endian Mode.0=little,1=big */
+#define E1000_CTRL_PRIOR    0x00000004	/* Priority on PCI. 0=rx,1=fair */
+#define E1000_CTRL_LRST     0x00000008	/* Link reset. 0=normal,1=reset */
+#define E1000_CTRL_TME	    0x00000010	/* Test mode. 0=normal,1=test */
+#define E1000_CTRL_SLE	    0x00000020	/* Serial Link on 0=dis,1=en */
+#define E1000_CTRL_ASDE     0x00000020	/* Auto-speed detect enable */
+#define E1000_CTRL_SLU	    0x00000040	/* Set link up (Force Link) */
+#define E1000_CTRL_ILOS     0x00000080	/* Invert Loss-Of Signal */
+#define E1000_CTRL_SPD_SEL  0x00000300	/* Speed Select Mask */
+#define E1000_CTRL_SPD_10   0x00000000	/* Force 10Mb */
+#define E1000_CTRL_SPD_100  0x00000100	/* Force 100Mb */
+#define E1000_CTRL_SPD_1000 0x00000200	/* Force 1Gb */
+#define E1000_CTRL_BEM32    0x00000400	/* Big Endian 32 mode */
+#define E1000_CTRL_FRCSPD   0x00000800	/* Force Speed */
+#define E1000_CTRL_FRCDPX   0x00001000	/* Force Duplex */
+#define E1000_CTRL_SWDPIN0  0x00040000	/* SWDPIN 0 value */
+#define E1000_CTRL_SWDPIN1  0x00080000	/* SWDPIN 1 value */
+#define E1000_CTRL_SWDPIN2  0x00100000	/* SWDPIN 2 value */
+#define E1000_CTRL_SWDPIN3  0x00200000	/* SWDPIN 3 value */
+#define E1000_CTRL_SWDPIO0  0x00400000	/* SWDPIN 0 Input or output */
+#define E1000_CTRL_SWDPIO1  0x00800000	/* SWDPIN 1 input or output */
+#define E1000_CTRL_SWDPIO2  0x01000000	/* SWDPIN 2 input or output */
+#define E1000_CTRL_SWDPIO3  0x02000000	/* SWDPIN 3 input or output */
+#define E1000_CTRL_RST	    0x04000000	/* Global reset */
+#define E1000_CTRL_RFCE     0x08000000	/* Receive Flow Control enable */
+#define E1000_CTRL_TFCE     0x10000000	/* Transmit flow control enable */
+#define E1000_CTRL_RTE	    0x20000000	/* Routing tag enable */
+#define E1000_CTRL_VME	    0x40000000	/* IEEE VLAN mode enable */
+#define E1000_CTRL_PHY_RST  0x80000000	/* PHY Reset */
+
+/* Device Status */
+#define E1000_STATUS_FD		0x00000001	/* Full duplex.0=half,1=full */
+#define E1000_STATUS_LU		0x00000002	/* Link up.0=no,1=link */
+#define E1000_STATUS_FUNC_MASK	0x0000000C	/* PCI Function Mask */
+#define E1000_STATUS_FUNC_0	0x00000000	/* Function 0 */
+#define E1000_STATUS_FUNC_1	0x00000004	/* Function 1 */
+#define E1000_STATUS_TXOFF	0x00000010	/* transmission paused */
+#define E1000_STATUS_TBIMODE	0x00000020	/* TBI mode */
+#define E1000_STATUS_SPEED_MASK 0x000000C0
+#define E1000_STATUS_SPEED_10	0x00000000	/* Speed 10Mb/s */
+#define E1000_STATUS_SPEED_100	0x00000040	/* Speed 100Mb/s */
+#define E1000_STATUS_SPEED_1000 0x00000080	/* Speed 1000Mb/s */
+#define E1000_STATUS_ASDV	0x00000300	/* Auto speed detect value */
+#define E1000_STATUS_MTXCKOK	0x00000400	/* MTX clock running OK */
+#define E1000_STATUS_PCI66	0x00000800	/* In 66Mhz slot */
+#define E1000_STATUS_BUS64	0x00001000	/* In 64 bit slot */
+#define E1000_STATUS_PCIX_MODE	0x00002000	/* PCI-X mode */
+#define E1000_STATUS_PCIX_SPEED 0x0000C000	/* PCI-X bus speed */
+
+/* Constants used to intrepret the masked PCI-X bus speed. */
+#define E1000_STATUS_PCIX_SPEED_66  0x00000000	/* PCI-X bus speed  50-66 MHz */
+#define E1000_STATUS_PCIX_SPEED_100 0x00004000	/* PCI-X bus speed  66-100 MHz */
+#define E1000_STATUS_PCIX_SPEED_133 0x00008000	/* PCI-X bus speed 100-133 MHz */
+
+/* EEPROM/Flash Control */
+#define E1000_EECD_SK	     0x00000001	/* EEPROM Clock */
+#define E1000_EECD_CS	     0x00000002	/* EEPROM Chip Select */
+#define E1000_EECD_DI	     0x00000004	/* EEPROM Data In */
+#define E1000_EECD_DO	     0x00000008	/* EEPROM Data Out */
+#define E1000_EECD_FWE_MASK  0x00000030
+#define E1000_EECD_FWE_DIS   0x00000010	/* Disable FLASH writes */
+#define E1000_EECD_FWE_EN    0x00000020	/* Enable FLASH writes */
+#define E1000_EECD_FWE_SHIFT 4
+#define E1000_EECD_SIZE      0x00000200	/* EEPROM Size (0=64 word 1=256 word) */
+#define E1000_EECD_REQ	     0x00000040	/* EEPROM Access Request */
+#define E1000_EECD_GNT	     0x00000080	/* EEPROM Access Grant */
+#define E1000_EECD_PRES      0x00000100	/* EEPROM Present */
+#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
+					 * (0-small, 1-large) */
+
+#define E1000_EECD_TYPE      0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
+#ifndef E1000_EEPROM_GRANT_ATTEMPTS
+#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
+#endif
+#define E1000_EECD_AUTO_RD          0x00000200  /* EEPROM Auto Read done */
+#define E1000_EECD_SIZE_EX_MASK     0x00007800  /* EEprom Size */
+#define E1000_EECD_SIZE_EX_SHIFT    11
+#define E1000_EECD_NVADDS    0x00018000 /* NVM Address Size */
+#define E1000_EECD_SELSHAD   0x00020000 /* Select Shadow RAM */
+#define E1000_EECD_INITSRAM  0x00040000 /* Initialize Shadow RAM */
+#define E1000_EECD_FLUPD     0x00080000 /* Update FLASH */
+#define E1000_EECD_AUPDEN    0x00100000 /* Enable Autonomous FLASH update */
+#define E1000_EECD_SHADV     0x00200000 /* Shadow RAM Data Valid */
+#define E1000_EECD_SEC1VAL   0x00400000 /* Sector One Valid */
+#define E1000_EECD_SECVAL_SHIFT      22
+#define E1000_STM_OPCODE     0xDB00
+#define E1000_HICR_FW_RESET  0xC0
+
+#define E1000_SHADOW_RAM_WORDS     2048
+#define E1000_ICH_NVM_SIG_WORD     0x13
+#define E1000_ICH_NVM_SIG_MASK     0xC0
+
+/* EEPROM Read */
+#define E1000_EERD_START      0x00000001	/* Start Read */
+#define E1000_EERD_DONE       0x00000010	/* Read Done */
+#define E1000_EERD_ADDR_SHIFT 8
+#define E1000_EERD_ADDR_MASK  0x0000FF00	/* Read Address */
+#define E1000_EERD_DATA_SHIFT 16
+#define E1000_EERD_DATA_MASK  0xFFFF0000	/* Read Data */
+
+/* EEPROM Commands - Microwire */
+#define EEPROM_READ_OPCODE_MICROWIRE  0x6  /* EEPROM read opcode */
+#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5  /* EEPROM write opcode */
+#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7  /* EEPROM erase opcode */
+#define EEPROM_EWEN_OPCODE_MICROWIRE  0x13 /* EEPROM erase/write enable */
+#define EEPROM_EWDS_OPCODE_MICROWIRE  0x10 /* EEPROM erast/write disable */
+
+/* EEPROM Commands - SPI */
+#define EEPROM_MAX_RETRY_SPI        5000 /* Max wait of 5ms, for RDY signal */
+#define EEPROM_READ_OPCODE_SPI      0x03  /* EEPROM read opcode */
+#define EEPROM_WRITE_OPCODE_SPI     0x02  /* EEPROM write opcode */
+#define EEPROM_A8_OPCODE_SPI        0x08  /* opcode bit-3 = address bit-8 */
+#define EEPROM_WREN_OPCODE_SPI      0x06  /* EEPROM set Write Enable latch */
+#define EEPROM_WRDI_OPCODE_SPI      0x04  /* EEPROM reset Write Enable latch */
+#define EEPROM_RDSR_OPCODE_SPI      0x05  /* EEPROM read Status register */
+#define EEPROM_WRSR_OPCODE_SPI      0x01  /* EEPROM write Status register */
+#define EEPROM_ERASE4K_OPCODE_SPI   0x20  /* EEPROM ERASE 4KB */
+#define EEPROM_ERASE64K_OPCODE_SPI  0xD8  /* EEPROM ERASE 64KB */
+#define EEPROM_ERASE256_OPCODE_SPI  0xDB  /* EEPROM ERASE 256B */
+
+/* EEPROM Size definitions */
+#define EEPROM_WORD_SIZE_SHIFT  6
+#define EEPROM_SIZE_SHIFT       10
+#define EEPROM_SIZE_MASK        0x1C00
+
+/* EEPROM Word Offsets */
+#define EEPROM_COMPAT                 0x0003
+#define EEPROM_ID_LED_SETTINGS        0x0004
+#define EEPROM_VERSION                0x0005
+#define EEPROM_SERDES_AMPLITUDE       0x0006 /* For SERDES output amplitude
+						adjustment. */
+#define EEPROM_PHY_CLASS_WORD         0x0007
+#define EEPROM_INIT_CONTROL1_REG      0x000A
+#define EEPROM_INIT_CONTROL2_REG      0x000F
+#define EEPROM_SWDEF_PINS_CTRL_PORT_1 0x0010
+#define EEPROM_INIT_CONTROL3_PORT_B   0x0014
+#define EEPROM_INIT_3GIO_3            0x001A
+#define EEPROM_SWDEF_PINS_CTRL_PORT_0 0x0020
+#define EEPROM_INIT_CONTROL3_PORT_A   0x0024
+#define EEPROM_CFG                    0x0012
+#define EEPROM_FLASH_VERSION          0x0032
+#define EEPROM_CHECKSUM_REG           0x003F
+
+#define E1000_EEPROM_CFG_DONE         0x00040000   /* MNG config cycle done */
+#define E1000_EEPROM_CFG_DONE_PORT_1  0x00080000   /* ...for second port */
+
+/* Extended Device Control */
+#define E1000_CTRL_EXT_GPI0_EN	 0x00000001	/* Maps SDP4 to GPI0 */
+#define E1000_CTRL_EXT_GPI1_EN	 0x00000002	/* Maps SDP5 to GPI1 */
+#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN
+#define E1000_CTRL_EXT_GPI2_EN	 0x00000004	/* Maps SDP6 to GPI2 */
+#define E1000_CTRL_EXT_GPI3_EN	 0x00000008	/* Maps SDP7 to GPI3 */
+#define E1000_CTRL_EXT_SDP4_DATA 0x00000010	/* Value of SW Defineable
+						   Pin 4 */
+#define E1000_CTRL_EXT_SDP5_DATA 0x00000020	/* Value of SW Defineable
+						   Pin 5 */
+#define E1000_CTRL_EXT_PHY_INT	 E1000_CTRL_EXT_SDP5_DATA
+#define E1000_CTRL_EXT_SDP6_DATA 0x00000040	/* Value of SW Defineable Pin 6 */
+#define E1000_CTRL_EXT_SWDPIN6	 0x00000040	/* SWDPIN 6 value */
+#define E1000_CTRL_EXT_SDP7_DATA 0x00000080	/* Value of SW Defineable Pin 7 */
+#define E1000_CTRL_EXT_SWDPIN7	 0x00000080	/* SWDPIN 7 value */
+#define E1000_CTRL_EXT_SDP4_DIR  0x00000100	/* Direction of SDP4 0=in 1=out */
+#define E1000_CTRL_EXT_SDP5_DIR  0x00000200	/* Direction of SDP5 0=in 1=out */
+#define E1000_CTRL_EXT_SDP6_DIR  0x00000400	/* Direction of SDP6 0=in 1=out */
+#define E1000_CTRL_EXT_SWDPIO6	 0x00000400	/* SWDPIN 6 Input or output */
+#define E1000_CTRL_EXT_SDP7_DIR  0x00000800	/* Direction of SDP7 0=in 1=out */
+#define E1000_CTRL_EXT_SWDPIO7	 0x00000800	/* SWDPIN 7 Input or output */
+#define E1000_CTRL_EXT_ASDCHK	 0x00001000	/* Initiate an ASD sequence */
+#define E1000_CTRL_EXT_EE_RST	 0x00002000	/* Reinitialize from EEPROM */
+#define E1000_CTRL_EXT_IPS	 0x00004000	/* Invert Power State */
+#define E1000_CTRL_EXT_SPD_BYPS  0x00008000	/* Speed Select Bypass */
+#define E1000_CTRL_EXT_RO_DIS    0x00020000 /* Relaxed Ordering disable */
+#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
+#define E1000_CTRL_EXT_LINK_MODE_TBI  0x00C00000
+#define E1000_CTRL_EXT_WR_WMARK_MASK  0x03000000
+#define E1000_CTRL_EXT_WR_WMARK_256   0x00000000
+#define E1000_CTRL_EXT_WR_WMARK_320   0x01000000
+#define E1000_CTRL_EXT_WR_WMARK_384   0x02000000
+#define E1000_CTRL_EXT_WR_WMARK_448   0x03000000
+
+/* MDI Control */
+#define E1000_MDIC_DATA_MASK 0x0000FFFF
+#define E1000_MDIC_REG_MASK  0x001F0000
+#define E1000_MDIC_REG_SHIFT 16
+#define E1000_MDIC_PHY_MASK  0x03E00000
+#define E1000_MDIC_PHY_SHIFT 21
+#define E1000_MDIC_OP_WRITE  0x04000000
+#define E1000_MDIC_OP_READ   0x08000000
+#define E1000_MDIC_READY     0x10000000
+#define E1000_MDIC_INT_EN    0x20000000
+#define E1000_MDIC_ERROR     0x40000000
+
+#define E1000_PHY_CTRL_SPD_EN                  0x00000001
+#define E1000_PHY_CTRL_D0A_LPLU                0x00000002
+#define E1000_PHY_CTRL_NOND0A_LPLU             0x00000004
+#define E1000_PHY_CTRL_NOND0A_GBE_DISABLE      0x00000008
+#define E1000_PHY_CTRL_GBE_DISABLE             0x00000040
+#define E1000_PHY_CTRL_B2B_EN                  0x00000080
+/* LED Control */
+#define E1000_LEDCTL_LED0_MODE_MASK  0x0000000F
+#define E1000_LEDCTL_LED0_MODE_SHIFT 0
+#define E1000_LEDCTL_LED0_IVRT	     0x00000040
+#define E1000_LEDCTL_LED0_BLINK      0x00000080
+#define E1000_LEDCTL_LED1_MODE_MASK  0x00000F00
+#define E1000_LEDCTL_LED1_MODE_SHIFT 8
+#define E1000_LEDCTL_LED1_IVRT	     0x00004000
+#define E1000_LEDCTL_LED1_BLINK      0x00008000
+#define E1000_LEDCTL_LED2_MODE_MASK  0x000F0000
+#define E1000_LEDCTL_LED2_MODE_SHIFT 16
+#define E1000_LEDCTL_LED2_IVRT	     0x00400000
+#define E1000_LEDCTL_LED2_BLINK      0x00800000
+#define E1000_LEDCTL_LED3_MODE_MASK  0x0F000000
+#define E1000_LEDCTL_LED3_MODE_SHIFT 24
+#define E1000_LEDCTL_LED3_IVRT	     0x40000000
+#define E1000_LEDCTL_LED3_BLINK      0x80000000
+
+#define E1000_LEDCTL_MODE_LINK_10_1000	0x0
+#define E1000_LEDCTL_MODE_LINK_100_1000 0x1
+#define E1000_LEDCTL_MODE_LINK_UP	0x2
+#define E1000_LEDCTL_MODE_ACTIVITY	0x3
+#define E1000_LEDCTL_MODE_LINK_ACTIVITY 0x4
+#define E1000_LEDCTL_MODE_LINK_10	0x5
+#define E1000_LEDCTL_MODE_LINK_100	0x6
+#define E1000_LEDCTL_MODE_LINK_1000	0x7
+#define E1000_LEDCTL_MODE_PCIX_MODE	0x8
+#define E1000_LEDCTL_MODE_FULL_DUPLEX	0x9
+#define E1000_LEDCTL_MODE_COLLISION	0xA
+#define E1000_LEDCTL_MODE_BUS_SPEED	0xB
+#define E1000_LEDCTL_MODE_BUS_SIZE	0xC
+#define E1000_LEDCTL_MODE_PAUSED	0xD
+#define E1000_LEDCTL_MODE_LED_ON	0xE
+#define E1000_LEDCTL_MODE_LED_OFF	0xF
+
+/* Receive Address */
+#define E1000_RAH_AV  0x80000000	/* Receive descriptor valid */
+
+/* Interrupt Cause Read */
+#define E1000_ICR_TXDW	  0x00000001	/* Transmit desc written back */
+#define E1000_ICR_TXQE	  0x00000002	/* Transmit Queue empty */
+#define E1000_ICR_LSC	  0x00000004	/* Link Status Change */
+#define E1000_ICR_RXSEQ   0x00000008	/* rx sequence error */
+#define E1000_ICR_RXDMT0  0x00000010	/* rx desc min. threshold (0) */
+#define E1000_ICR_RXO	  0x00000040	/* rx overrun */
+#define E1000_ICR_RXT0	  0x00000080	/* rx timer intr (ring 0) */
+#define E1000_ICR_MDAC	  0x00000200	/* MDIO access complete */
+#define E1000_ICR_RXCFG   0x00000400	/* RX /c/ ordered set */
+#define E1000_ICR_GPI_EN0 0x00000800	/* GP Int 0 */
+#define E1000_ICR_GPI_EN1 0x00001000	/* GP Int 1 */
+#define E1000_ICR_GPI_EN2 0x00002000	/* GP Int 2 */
+#define E1000_ICR_GPI_EN3 0x00004000	/* GP Int 3 */
+#define E1000_ICR_TXD_LOW 0x00008000
+#define E1000_ICR_SRPD	  0x00010000
+
+/* Interrupt Cause Set */
+#define E1000_ICS_TXDW	  E1000_ICR_TXDW	/* Transmit desc written back */
+#define E1000_ICS_TXQE	  E1000_ICR_TXQE	/* Transmit Queue empty */
+#define E1000_ICS_LSC	  E1000_ICR_LSC	/* Link Status Change */
+#define E1000_ICS_RXSEQ   E1000_ICR_RXSEQ	/* rx sequence error */
+#define E1000_ICS_RXDMT0  E1000_ICR_RXDMT0	/* rx desc min. threshold */
+#define E1000_ICS_RXO	  E1000_ICR_RXO	/* rx overrun */
+#define E1000_ICS_RXT0	  E1000_ICR_RXT0	/* rx timer intr */
+#define E1000_ICS_MDAC	  E1000_ICR_MDAC	/* MDIO access complete */
+#define E1000_ICS_RXCFG   E1000_ICR_RXCFG	/* RX /c/ ordered set */
+#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0	/* GP Int 0 */
+#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1	/* GP Int 1 */
+#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2	/* GP Int 2 */
+#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3	/* GP Int 3 */
+#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
+#define E1000_ICS_SRPD	  E1000_ICR_SRPD
+
+/* Interrupt Mask Set */
+#define E1000_IMS_TXDW	  E1000_ICR_TXDW	/* Transmit desc written back */
+#define E1000_IMS_TXQE	  E1000_ICR_TXQE	/* Transmit Queue empty */
+#define E1000_IMS_LSC	  E1000_ICR_LSC	/* Link Status Change */
+#define E1000_IMS_RXSEQ   E1000_ICR_RXSEQ	/* rx sequence error */
+#define E1000_IMS_RXDMT0  E1000_ICR_RXDMT0	/* rx desc min. threshold */
+#define E1000_IMS_RXO	  E1000_ICR_RXO	/* rx overrun */
+#define E1000_IMS_RXT0	  E1000_ICR_RXT0	/* rx timer intr */
+#define E1000_IMS_MDAC	  E1000_ICR_MDAC	/* MDIO access complete */
+#define E1000_IMS_RXCFG   E1000_ICR_RXCFG	/* RX /c/ ordered set */
+#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0	/* GP Int 0 */
+#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1	/* GP Int 1 */
+#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2	/* GP Int 2 */
+#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3	/* GP Int 3 */
+#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
+#define E1000_IMS_SRPD	  E1000_ICR_SRPD
+
+/* Interrupt Mask Clear */
+#define E1000_IMC_TXDW	  E1000_ICR_TXDW	/* Transmit desc written back */
+#define E1000_IMC_TXQE	  E1000_ICR_TXQE	/* Transmit Queue empty */
+#define E1000_IMC_LSC	  E1000_ICR_LSC	/* Link Status Change */
+#define E1000_IMC_RXSEQ   E1000_ICR_RXSEQ	/* rx sequence error */
+#define E1000_IMC_RXDMT0  E1000_ICR_RXDMT0	/* rx desc min. threshold */
+#define E1000_IMC_RXO	  E1000_ICR_RXO	/* rx overrun */
+#define E1000_IMC_RXT0	  E1000_ICR_RXT0	/* rx timer intr */
+#define E1000_IMC_MDAC	  E1000_ICR_MDAC	/* MDIO access complete */
+#define E1000_IMC_RXCFG   E1000_ICR_RXCFG	/* RX /c/ ordered set */
+#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0	/* GP Int 0 */
+#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1	/* GP Int 1 */
+#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2	/* GP Int 2 */
+#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3	/* GP Int 3 */
+#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
+#define E1000_IMC_SRPD	  E1000_ICR_SRPD
+
+/* Receive Control */
+#define E1000_RCTL_RST		0x00000001	/* Software reset */
+#define E1000_RCTL_EN		0x00000002	/* enable */
+#define E1000_RCTL_SBP		0x00000004	/* store bad packet */
+#define E1000_RCTL_UPE		0x00000008	/* unicast promiscuous enable */
+#define E1000_RCTL_MPE		0x00000010	/* multicast promiscuous enab */
+#define E1000_RCTL_LPE		0x00000020	/* long packet enable */
+#define E1000_RCTL_LBM_NO	0x00000000	/* no loopback mode */
+#define E1000_RCTL_LBM_MAC	0x00000040	/* MAC loopback mode */
+#define E1000_RCTL_LBM_SLP	0x00000080	/* serial link loopback mode */
+#define E1000_RCTL_LBM_TCVR	0x000000C0	/* tcvr loopback mode */
+#define E1000_RCTL_RDMTS_HALF	0x00000000	/* rx desc min threshold size */
+#define E1000_RCTL_RDMTS_QUAT	0x00000100	/* rx desc min threshold size */
+#define E1000_RCTL_RDMTS_EIGTH	0x00000200	/* rx desc min threshold size */
+#define E1000_RCTL_MO_SHIFT	12	/* multicast offset shift */
+#define E1000_RCTL_MO_0		0x00000000	/* multicast offset 11:0 */
+#define E1000_RCTL_MO_1		0x00001000	/* multicast offset 12:1 */
+#define E1000_RCTL_MO_2		0x00002000	/* multicast offset 13:2 */
+#define E1000_RCTL_MO_3		0x00003000	/* multicast offset 15:4 */
+#define E1000_RCTL_MDR		0x00004000	/* multicast desc ring 0 */
+#define E1000_RCTL_BAM		0x00008000	/* broadcast enable */
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
+#define E1000_RCTL_SZ_2048	0x00000000	/* rx buffer size 2048 */
+#define E1000_RCTL_SZ_1024	0x00010000	/* rx buffer size 1024 */
+#define E1000_RCTL_SZ_512	0x00020000	/* rx buffer size 512 */
+#define E1000_RCTL_SZ_256	0x00030000	/* rx buffer size 256 */
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
+#define E1000_RCTL_SZ_16384	0x00010000	/* rx buffer size 16384 */
+#define E1000_RCTL_SZ_8192	0x00020000	/* rx buffer size 8192 */
+#define E1000_RCTL_SZ_4096	0x00030000	/* rx buffer size 4096 */
+#define E1000_RCTL_VFE		0x00040000	/* vlan filter enable */
+#define E1000_RCTL_CFIEN	0x00080000	/* canonical form enable */
+#define E1000_RCTL_CFI		0x00100000	/* canonical form indicator */
+#define E1000_RCTL_DPF		0x00400000	/* discard pause frames */
+#define E1000_RCTL_PMCF		0x00800000	/* pass MAC control frames */
+#define E1000_RCTL_BSEX		0x02000000	/* Buffer size extension */
+
+/* SW_W_SYNC definitions */
+#define E1000_SWFW_EEP_SM     0x0001
+#define E1000_SWFW_PHY0_SM    0x0002
+#define E1000_SWFW_PHY1_SM    0x0004
+#define E1000_SWFW_MAC_CSR_SM 0x0008
+
+/* Receive Descriptor */
+#define E1000_RDT_DELAY 0x0000ffff	/* Delay timer (1=1024us) */
+#define E1000_RDT_FPDB	0x80000000	/* Flush descriptor block */
+#define E1000_RDLEN_LEN 0x0007ff80	/* descriptor length */
+#define E1000_RDH_RDH	0x0000ffff	/* receive descriptor head */
+#define E1000_RDT_RDT	0x0000ffff	/* receive descriptor tail */
+
+/* Flow Control */
+#define E1000_FCRTH_RTH  0x0000FFF8	/* Mask Bits[15:3] for RTH */
+#define E1000_FCRTH_XFCE 0x80000000	/* External Flow Control Enable */
+#define E1000_FCRTL_RTL  0x0000FFF8	/* Mask Bits[15:3] for RTL */
+#define E1000_FCRTL_XONE 0x80000000	/* Enable XON frame transmission */
+
+/* Receive Descriptor Control */
+#define E1000_RXDCTL_PTHRESH 0x0000003F	/* RXDCTL Prefetch Threshold */
+#define E1000_RXDCTL_HTHRESH 0x00003F00	/* RXDCTL Host Threshold */
+#define E1000_RXDCTL_WTHRESH 0x003F0000	/* RXDCTL Writeback Threshold */
+#define E1000_RXDCTL_GRAN    0x01000000	/* RXDCTL Granularity */
+#define E1000_RXDCTL_FULL_RX_DESC_WB 0x01010000	/* GRAN=1, WTHRESH=1 */
+
+/* Transmit Descriptor Control */
+#define E1000_TXDCTL_PTHRESH 0x0000003F	/* TXDCTL Prefetch Threshold */
+#define E1000_TXDCTL_HTHRESH 0x00003F00	/* TXDCTL Host Threshold */
+#define E1000_TXDCTL_WTHRESH 0x003F0000	/* TXDCTL Writeback Threshold */
+#define E1000_TXDCTL_GRAN    0x01000000	/* TXDCTL Granularity */
+#define E1000_TXDCTL_LWTHRESH 0xFE000000	/* TXDCTL Low Threshold */
+#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000	/* GRAN=1, WTHRESH=1 */
+#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Enable the counting of desc.
+					      still to be processed. */
+
+/* Transmit Configuration Word */
+#define E1000_TXCW_FD	      0x00000020	/* TXCW full duplex */
+#define E1000_TXCW_HD	      0x00000040	/* TXCW half duplex */
+#define E1000_TXCW_PAUSE      0x00000080	/* TXCW sym pause request */
+#define E1000_TXCW_ASM_DIR    0x00000100	/* TXCW astm pause direction */
+#define E1000_TXCW_PAUSE_MASK 0x00000180	/* TXCW pause request mask */
+#define E1000_TXCW_RF	      0x00003000	/* TXCW remote fault */
+#define E1000_TXCW_NP	      0x00008000	/* TXCW next page */
+#define E1000_TXCW_CW	      0x0000ffff	/* TxConfigWord mask */
+#define E1000_TXCW_TXC	      0x40000000	/* Transmit Config control */
+#define E1000_TXCW_ANE	      0x80000000	/* Auto-neg enable */
+
+/* Receive Configuration Word */
+#define E1000_RXCW_CW	 0x0000ffff	/* RxConfigWord mask */
+#define E1000_RXCW_NC	 0x04000000	/* Receive config no carrier */
+#define E1000_RXCW_IV	 0x08000000	/* Receive config invalid */
+#define E1000_RXCW_CC	 0x10000000	/* Receive config change */
+#define E1000_RXCW_C	 0x20000000	/* Receive config */
+#define E1000_RXCW_SYNCH 0x40000000	/* Receive config synch */
+#define E1000_RXCW_ANC	 0x80000000	/* Auto-neg complete */
+
+/* Transmit Control */
+#define E1000_TCTL_RST	  0x00000001	/* software reset */
+#define E1000_TCTL_EN	  0x00000002	/* enable tx */
+#define E1000_TCTL_BCE	  0x00000004	/* busy check enable */
+#define E1000_TCTL_PSP	  0x00000008	/* pad short packets */
+#define E1000_TCTL_CT	  0x00000ff0	/* collision threshold */
+#define E1000_TCTL_COLD   0x003ff000	/* collision distance */
+#define E1000_TCTL_SWXOFF 0x00400000	/* SW Xoff transmission */
+#define E1000_TCTL_PBE	  0x00800000	/* Packet Burst Enable */
+#define E1000_TCTL_RTLC   0x01000000	/* Re-transmit on late collision */
+#define E1000_TCTL_NRTU   0x02000000	/* No Re-transmit on underrun */
+#define E1000_TCTL_MULR   0x10000000    /* Multiple request support */
+
+/* Receive Checksum Control */
+#define E1000_RXCSUM_PCSS_MASK 0x000000FF	/* Packet Checksum Start */
+#define E1000_RXCSUM_IPOFL     0x00000100	/* IPv4 checksum offload */
+#define E1000_RXCSUM_TUOFL     0x00000200	/* TCP / UDP checksum offload */
+#define E1000_RXCSUM_IPV6OFL   0x00000400	/* IPv6 checksum offload */
+
+/* Definitions for power management and wakeup registers */
+/* Wake Up Control */
+#define E1000_WUC_APME	     0x00000001	/* APM Enable */
+#define E1000_WUC_PME_EN     0x00000002	/* PME Enable */
+#define E1000_WUC_PME_STATUS 0x00000004	/* PME Status */
+#define E1000_WUC_APMPME     0x00000008	/* Assert PME on APM Wakeup */
+
+/* Wake Up Filter Control */
+#define E1000_WUFC_LNKC 0x00000001	/* Link Status Change Wakeup Enable */
+#define E1000_WUFC_MAG	0x00000002	/* Magic Packet Wakeup Enable */
+#define E1000_WUFC_EX	0x00000004	/* Directed Exact Wakeup Enable */
+#define E1000_WUFC_MC	0x00000008	/* Directed Multicast Wakeup Enable */
+#define E1000_WUFC_BC	0x00000010	/* Broadcast Wakeup Enable */
+#define E1000_WUFC_ARP	0x00000020	/* ARP Request Packet Wakeup Enable */
+#define E1000_WUFC_IPV4 0x00000040	/* Directed IPv4 Packet Wakeup Enable */
+#define E1000_WUFC_IPV6 0x00000080	/* Directed IPv6 Packet Wakeup Enable */
+#define E1000_WUFC_FLX0 0x00010000	/* Flexible Filter 0 Enable */
+#define E1000_WUFC_FLX1 0x00020000	/* Flexible Filter 1 Enable */
+#define E1000_WUFC_FLX2 0x00040000	/* Flexible Filter 2 Enable */
+#define E1000_WUFC_FLX3 0x00080000	/* Flexible Filter 3 Enable */
+#define E1000_WUFC_ALL_FILTERS 0x000F00FF	/* Mask for all wakeup filters */
+#define E1000_WUFC_FLX_OFFSET 16	/* Offset to the Flexible Filters bits */
+#define E1000_WUFC_FLX_FILTERS 0x000F0000	/* Mask for the 4 flexible filters */
+
+/* Wake Up Status */
+#define E1000_WUS_LNKC 0x00000001	/* Link Status Changed */
+#define E1000_WUS_MAG  0x00000002	/* Magic Packet Received */
+#define E1000_WUS_EX   0x00000004	/* Directed Exact Received */
+#define E1000_WUS_MC   0x00000008	/* Directed Multicast Received */
+#define E1000_WUS_BC   0x00000010	/* Broadcast Received */
+#define E1000_WUS_ARP  0x00000020	/* ARP Request Packet Received */
+#define E1000_WUS_IPV4 0x00000040	/* Directed IPv4 Packet Wakeup Received */
+#define E1000_WUS_IPV6 0x00000080	/* Directed IPv6 Packet Wakeup Received */
+#define E1000_WUS_FLX0 0x00010000	/* Flexible Filter 0 Match */
+#define E1000_WUS_FLX1 0x00020000	/* Flexible Filter 1 Match */
+#define E1000_WUS_FLX2 0x00040000	/* Flexible Filter 2 Match */
+#define E1000_WUS_FLX3 0x00080000	/* Flexible Filter 3 Match */
+#define E1000_WUS_FLX_FILTERS 0x000F0000	/* Mask for the 4 flexible filters */
+
+/* Management Control */
+#define E1000_MANC_SMBUS_EN	 0x00000001	/* SMBus Enabled - RO */
+#define E1000_MANC_ASF_EN	 0x00000002	/* ASF Enabled - RO */
+#define E1000_MANC_R_ON_FORCE	 0x00000004	/* Reset on Force TCO - RO */
+#define E1000_MANC_RMCP_EN	 0x00000100	/* Enable RCMP 026Fh Filtering */
+#define E1000_MANC_0298_EN	 0x00000200	/* Enable RCMP 0298h Filtering */
+#define E1000_MANC_IPV4_EN	 0x00000400	/* Enable IPv4 */
+#define E1000_MANC_IPV6_EN	 0x00000800	/* Enable IPv6 */
+#define E1000_MANC_SNAP_EN	 0x00001000	/* Accept LLC/SNAP */
+#define E1000_MANC_ARP_EN	 0x00002000	/* Enable ARP Request Filtering */
+#define E1000_MANC_NEIGHBOR_EN	 0x00004000	/* Enable Neighbor Discovery
+						 * Filtering */
+#define E1000_MANC_TCO_RESET	 0x00010000	/* TCO Reset Occurred */
+#define E1000_MANC_RCV_TCO_EN	 0x00020000	/* Receive TCO Packets Enabled */
+#define E1000_MANC_REPORT_STATUS 0x00040000	/* Status Reporting Enabled */
+#define E1000_MANC_SMB_REQ	 0x01000000	/* SMBus Request */
+#define E1000_MANC_SMB_GNT	 0x02000000	/* SMBus Grant */
+#define E1000_MANC_SMB_CLK_IN	 0x04000000	/* SMBus Clock In */
+#define E1000_MANC_SMB_DATA_IN	 0x08000000	/* SMBus Data In */
+#define E1000_MANC_SMB_DATA_OUT  0x10000000	/* SMBus Data Out */
+#define E1000_MANC_SMB_CLK_OUT	 0x20000000	/* SMBus Clock Out */
+
+#define E1000_MANC_SMB_DATA_OUT_SHIFT  28	/* SMBus Data Out Shift */
+#define E1000_MANC_SMB_CLK_OUT_SHIFT   29	/* SMBus Clock Out Shift */
+
+/* Wake Up Packet Length */
+#define E1000_WUPL_LENGTH_MASK 0x0FFF	/* Only the lower 12 bits are valid */
+
+#define E1000_MDALIGN	       4096
+
+/* EEPROM Commands */
+#define EEPROM_READ_OPCODE  0x6	/* EERPOM read opcode */
+#define EEPROM_WRITE_OPCODE 0x5	/* EERPOM write opcode */
+#define EEPROM_ERASE_OPCODE 0x7	/* EERPOM erase opcode */
+#define EEPROM_EWEN_OPCODE  0x13	/* EERPOM erase/write enable */
+#define EEPROM_EWDS_OPCODE  0x10	/* EERPOM erast/write disable */
+
+/* Word definitions for ID LED Settings */
+#define ID_LED_RESERVED_0000 0x0000
+#define ID_LED_RESERVED_FFFF 0xFFFF
+#define ID_LED_DEFAULT	     ((ID_LED_OFF1_ON2 << 12) | \
+			      (ID_LED_OFF1_OFF2 << 8) | \
+			      (ID_LED_DEF1_DEF2 << 4) | \
+			      (ID_LED_DEF1_DEF2))
+#define ID_LED_DEF1_DEF2     0x1
+#define ID_LED_DEF1_ON2      0x2
+#define ID_LED_DEF1_OFF2     0x3
+#define ID_LED_ON1_DEF2      0x4
+#define ID_LED_ON1_ON2	     0x5
+#define ID_LED_ON1_OFF2      0x6
+#define ID_LED_OFF1_DEF2     0x7
+#define ID_LED_OFF1_ON2      0x8
+#define ID_LED_OFF1_OFF2     0x9
+
+/* Mask bits for fields in Word 0x03 of the EEPROM */
+#define EEPROM_COMPAT_SERVER 0x0400
+#define EEPROM_COMPAT_CLIENT 0x0200
+
+/* Mask bits for fields in Word 0x0a of the EEPROM */
+#define EEPROM_WORD0A_ILOS   0x0010
+#define EEPROM_WORD0A_SWDPIO 0x01E0
+#define EEPROM_WORD0A_LRST   0x0200
+#define EEPROM_WORD0A_FD     0x0400
+#define EEPROM_WORD0A_66MHZ  0x0800
+
+/* Mask bits for fields in Word 0x0f of the EEPROM */
+#define EEPROM_WORD0F_PAUSE_MASK 0x3000
+#define EEPROM_WORD0F_PAUSE	 0x1000
+#define EEPROM_WORD0F_ASM_DIR	 0x2000
+#define EEPROM_WORD0F_ANE	 0x0800
+#define EEPROM_WORD0F_SWPDIO_EXT 0x00F0
+
+/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
+#define EEPROM_SUM 0xBABA
+
+/* EEPROM Map defines (WORD OFFSETS)*/
+#define EEPROM_NODE_ADDRESS_BYTE_0 0
+#define EEPROM_PBA_BYTE_1	   8
+
+/* EEPROM Map Sizes (Byte Counts) */
+#define PBA_SIZE 4
+
+/* Collision related configuration parameters */
+#define E1000_COLLISION_THRESHOLD	0xF
+#define E1000_CT_SHIFT			4
+#define E1000_COLLISION_DISTANCE        63
+#define E1000_COLLISION_DISTANCE_82542  64
+#define E1000_FDX_COLLISION_DISTANCE	E1000_COLLISION_DISTANCE
+#define E1000_HDX_COLLISION_DISTANCE	E1000_COLLISION_DISTANCE
+#define E1000_GB_HDX_COLLISION_DISTANCE 512
+#define E1000_COLD_SHIFT		12
+
+/* The number of Transmit and Receive Descriptors must be a multiple of 8 */
+#define REQ_TX_DESCRIPTOR_MULTIPLE  8
+#define REQ_RX_DESCRIPTOR_MULTIPLE  8
+
+/* Default values for the transmit IPG register */
+#define DEFAULT_82542_TIPG_IPGT        10
+#define DEFAULT_82543_TIPG_IPGT_FIBER  9
+#define DEFAULT_82543_TIPG_IPGT_COPPER 8
+
+#define E1000_TIPG_IPGT_MASK  0x000003FF
+#define E1000_TIPG_IPGR1_MASK 0x000FFC00
+#define E1000_TIPG_IPGR2_MASK 0x3FF00000
+
+#define DEFAULT_82542_TIPG_IPGR1 2
+#define DEFAULT_82543_TIPG_IPGR1 8
+#define E1000_TIPG_IPGR1_SHIFT	10
+
+#define DEFAULT_82542_TIPG_IPGR2 10
+#define DEFAULT_82543_TIPG_IPGR2 6
+#define DEFAULT_80003ES2LAN_TIPG_IPGR2 7
+#define E1000_TIPG_IPGR2_SHIFT	20
+
+#define E1000_TXDMAC_DPP 0x00000001
+
+/* Adaptive IFS defines */
+#define TX_THRESHOLD_START     8
+#define TX_THRESHOLD_INCREMENT 10
+#define TX_THRESHOLD_DECREMENT 1
+#define TX_THRESHOLD_STOP      190
+#define TX_THRESHOLD_DISABLE   0
+#define TX_THRESHOLD_TIMER_MS  10000
+#define MIN_NUM_XMITS	       1000
+#define IFS_MAX		       80
+#define IFS_STEP	       10
+#define IFS_MIN		       40
+#define IFS_RATIO	       4
+
+/* PBA constants */
+#define E1000_PBA_16K 0x0010	/* 16KB, default TX allocation */
+#define E1000_PBA_24K 0x0018
+#define E1000_PBA_38K 0x0026
+#define E1000_PBA_40K 0x0028
+#define E1000_PBA_48K 0x0030	/* 48KB, default RX allocation */
+
+/* Flow Control Constants */
+#define FLOW_CONTROL_ADDRESS_LOW  0x00C28001
+#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
+#define FLOW_CONTROL_TYPE	  0x8808
+
+/* The historical defaults for the flow control values are given below. */
+#define FC_DEFAULT_HI_THRESH	    (0x8000)	/* 32KB */
+#define FC_DEFAULT_LO_THRESH	    (0x4000)	/* 16KB */
+#define FC_DEFAULT_TX_TIMER	    (0x100)	/* ~130 us */
+
+/* Flow Control High-Watermark: 43464 bytes */
+#define E1000_FC_HIGH_THRESH 0xA9C8
+/* Flow Control Low-Watermark: 43456 bytes */
+#define E1000_FC_LOW_THRESH 0xA9C0
+/* Flow Control Pause Time: 858 usec */
+#define E1000_FC_PAUSE_TIME 0x0680
+
+/* PCIX Config space */
+#define PCIX_COMMAND_REGISTER	 0xE6
+#define PCIX_STATUS_REGISTER_LO  0xE8
+#define PCIX_STATUS_REGISTER_HI  0xEA
+
+#define PCIX_COMMAND_MMRBC_MASK      0x000C
+#define PCIX_COMMAND_MMRBC_SHIFT     0x2
+#define PCIX_STATUS_HI_MMRBC_MASK    0x0060
+#define PCIX_STATUS_HI_MMRBC_SHIFT   0x5
+#define PCIX_STATUS_HI_MMRBC_4K      0x3
+#define PCIX_STATUS_HI_MMRBC_2K      0x2
+
+/* The number of bits that we need to shift right to move the "pause"
+ * bits from the EEPROM (bits 13:12) to the "pause" (bits 8:7) field
+ * in the TXCW register
+ */
+#define PAUSE_SHIFT 5
+
+/* The number of bits that we need to shift left to move the "SWDPIO"
+ * bits from the EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field
+ * in the CTRL register
+ */
+#define SWDPIO_SHIFT 17
+
+/* The number of bits that we need to shift left to move the "SWDPIO_EXT"
+ * bits from the EEPROM word F (bits 7:4) to the bits 11:8 of The
+ * Extended CTRL register.
+ * in the CTRL register
+ */
+#define SWDPIO__EXT_SHIFT 4
+
+/* The number of bits that we need to shift left to move the "ILOS"
+ * bit from the EEPROM (bit 4) to the "ILOS" (bit 7) field
+ * in the CTRL register
+ */
+#define ILOS_SHIFT  3
+
+#define RECEIVE_BUFFER_ALIGN_SIZE  (256)
+
+/* The number of milliseconds we wait for auto-negotiation to complete */
+#define LINK_UP_TIMEOUT		    500
+
+#define E1000_TX_BUFFER_SIZE ((uint32_t)1514)
+
+/* The carrier extension symbol, as received by the NIC. */
+#define CARRIER_EXTENSION   0x0F
+
+/* TBI_ACCEPT macro definition:
+ *
+ * This macro requires:
+ *	adapter = a pointer to struct e1000_hw
+ *	status = the 8 bit status field of the RX descriptor with EOP set
+ *	error = the 8 bit error field of the RX descriptor with EOP set
+ *	length = the sum of all the length fields of the RX descriptors that
+ *		 make up the current frame
+ *	last_byte = the last byte of the frame DMAed by the hardware
+ *	max_frame_length = the maximum frame length we want to accept.
+ *	min_frame_length = the minimum frame length we want to accept.
+ *
+ * This macro is a conditional that should be used in the interrupt
+ * handler's Rx processing routine when RxErrors have been detected.
+ *
+ * Typical use:
+ *  ...
+ *  if (TBI_ACCEPT) {
+ *	accept_frame = true;
+ *	e1000_tbi_adjust_stats(adapter, MacAddress);
+ *	frame_length--;
+ *  } else {
+ *	accept_frame = false;
+ *  }
+ *  ...
+ */
+
+#define TBI_ACCEPT(adapter, status, errors, length, last_byte) \
+    ((adapter)->tbi_compatibility_on && \
+     (((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
+     ((last_byte) == CARRIER_EXTENSION) && \
+     (((status) & E1000_RXD_STAT_VP) ? \
+	  (((length) > ((adapter)->min_frame_size - VLAN_TAG_SIZE)) && \
+	   ((length) <= ((adapter)->max_frame_size + 1))) : \
+	  (((length) > (adapter)->min_frame_size) && \
+	   ((length) <= ((adapter)->max_frame_size + VLAN_TAG_SIZE + 1)))))
+
+/* Structures, enums, and macros for the PHY */
+
+/* Bit definitions for the Management Data IO (MDIO) and Management Data
+ * Clock (MDC) pins in the Device Control Register.
+ */
+#define E1000_CTRL_PHY_RESET_DIR	E1000_CTRL_SWDPIO0
+#define E1000_CTRL_PHY_RESET		E1000_CTRL_SWDPIN0
+#define E1000_CTRL_MDIO_DIR		E1000_CTRL_SWDPIO2
+#define E1000_CTRL_MDIO			E1000_CTRL_SWDPIN2
+#define E1000_CTRL_MDC_DIR		E1000_CTRL_SWDPIO3
+#define E1000_CTRL_MDC			E1000_CTRL_SWDPIN3
+#define E1000_CTRL_PHY_RESET_DIR4	E1000_CTRL_EXT_SDP4_DIR
+#define E1000_CTRL_PHY_RESET4		E1000_CTRL_EXT_SDP4_DATA
+
+/* PHY 1000 MII Register/Bit Definitions */
+/* PHY Registers defined by IEEE */
+#define PHY_CTRL			0x00	/* Control Register */
+#define PHY_STATUS			0x01	/* Status Regiser */
+#define PHY_ID1				0x02	/* Phy Id Reg (word 1) */
+#define PHY_ID2				0x03	/* Phy Id Reg (word 2) */
+#define PHY_AUTONEG_ADV		0x04	/* Autoneg Advertisement */
+#define PHY_LP_ABILITY			0x05	/* Link Partner Ability (Base Page) */
+#define PHY_AUTONEG_EXP		0x06	/* Autoneg Expansion Reg */
+#define PHY_NEXT_PAGE_TX		0x07	/* Next Page TX */
+#define PHY_LP_NEXT_PAGE		0x08	/* Link Partner Next Page */
+#define PHY_1000T_CTRL			0x09	/* 1000Base-T Control Reg */
+#define PHY_1000T_STATUS		0x0A	/* 1000Base-T Status Reg */
+#define PHY_EXT_STATUS			0x0F	/* Extended Status Reg */
+
+/* M88E1000 Specific Registers */
+#define M88E1000_PHY_SPEC_CTRL		0x10	/* PHY Specific Control Register */
+#define M88E1000_PHY_SPEC_STATUS	0x11	/* PHY Specific Status Register */
+#define M88E1000_INT_ENABLE		0x12	/* Interrupt Enable Register */
+#define M88E1000_INT_STATUS		0x13	/* Interrupt Status Register */
+#define M88E1000_EXT_PHY_SPEC_CTRL	0x14	/* Extended PHY Specific Control */
+#define M88E1000_RX_ERR_CNTR		0x15	/* Receive Error Counter */
+
+#define M88E1000_PHY_PAGE_SELECT   0x1D  /* Reg 29 for page number setting */
+#define M88E1000_PHY_GEN_CONTROL   0x1E  /* Its meaning depends on reg 29 */
+
+#define MAX_PHY_REG_ADDRESS		0x1F	/* 5 bit address bus (0-0x1F) */
+
+/* M88EC018 Rev 2 specific DownShift settings */
+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK  0x0E00
+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_1X    0x0000
+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_2X    0x0200
+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_3X    0x0400
+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_4X    0x0600
+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X    0x0800
+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_6X    0x0A00
+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_7X    0x0C00
+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_8X    0x0E00
+
+/* IGP01E1000 specifics */
+#define IGP01E1000_IEEE_REGS_PAGE	0x0000
+#define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300
+#define IGP01E1000_IEEE_FORCE_GIGA	0x0140
+
+/* IGP01E1000 Specific Registers */
+#define IGP01E1000_PHY_PORT_CONFIG	0x10 /* PHY Specific Port Config Register */
+#define IGP01E1000_PHY_PORT_STATUS	0x11 /* PHY Specific Status Register */
+#define IGP01E1000_PHY_PORT_CTRL	0x12 /* PHY Specific Control Register */
+#define IGP01E1000_PHY_LINK_HEALTH	0x13 /* PHY Link Health Register */
+#define IGP01E1000_GMII_FIFO		0x14 /* GMII FIFO Register */
+#define IGP01E1000_PHY_CHANNEL_QUALITY	0x15 /* PHY Channel Quality Register */
+#define IGP02E1000_PHY_POWER_MGMT	0x19
+#define IGP01E1000_PHY_PAGE_SELECT	0x1F /* PHY Page Select Core Register */
+
+/* IGP01E1000 AGC Registers - stores the cable length values*/
+#define IGP01E1000_PHY_AGC_A        0x1172
+#define IGP01E1000_PHY_AGC_B        0x1272
+#define IGP01E1000_PHY_AGC_C        0x1472
+#define IGP01E1000_PHY_AGC_D        0x1872
+
+/* IGP01E1000 Specific Port Config Register - R/W */
+#define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT  0x0010
+#define IGP01E1000_PSCFR_PRE_EN                0x0020
+#define IGP01E1000_PSCFR_SMART_SPEED           0x0080
+#define IGP01E1000_PSCFR_DISABLE_TPLOOPBACK    0x0100
+#define IGP01E1000_PSCFR_DISABLE_JABBER        0x0400
+#define IGP01E1000_PSCFR_DISABLE_TRANSMIT      0x2000
+/* IGP02E1000 AGC Registers for cable length values */
+#define IGP02E1000_PHY_AGC_A        0x11B1
+#define IGP02E1000_PHY_AGC_B        0x12B1
+#define IGP02E1000_PHY_AGC_C        0x14B1
+#define IGP02E1000_PHY_AGC_D        0x18B1
+
+#define IGP02E1000_PM_SPD                         0x0001  /* Smart Power Down */
+#define IGP02E1000_PM_D3_LPLU                     0x0004  /* Enable LPLU in
+							     non-D0a modes */
+#define IGP02E1000_PM_D0_LPLU                     0x0002  /* Enable LPLU in
+							     D0a mode */
+
+/* IGP01E1000 DSP Reset Register */
+#define IGP01E1000_PHY_DSP_RESET   0x1F33
+#define IGP01E1000_PHY_DSP_SET     0x1F71
+#define IGP01E1000_PHY_DSP_FFE     0x1F35
+
+#define IGP01E1000_PHY_CHANNEL_NUM    4
+#define IGP02E1000_PHY_CHANNEL_NUM    4
+
+#define IGP01E1000_PHY_AGC_PARAM_A    0x1171
+#define IGP01E1000_PHY_AGC_PARAM_B    0x1271
+#define IGP01E1000_PHY_AGC_PARAM_C    0x1471
+#define IGP01E1000_PHY_AGC_PARAM_D    0x1871
+
+#define IGP01E1000_PHY_EDAC_MU_INDEX        0xC000
+#define IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS 0x8000
+
+#define IGP01E1000_PHY_ANALOG_TX_STATE      0x2890
+#define IGP01E1000_PHY_ANALOG_CLASS_A       0x2000
+#define IGP01E1000_PHY_FORCE_ANALOG_ENABLE  0x0004
+#define IGP01E1000_PHY_DSP_FFE_CM_CP        0x0069
+
+#define IGP01E1000_PHY_DSP_FFE_DEFAULT      0x002A
+/* IGP01E1000 PCS Initialization register - stores the polarity status when
+ * speed = 1000 Mbps. */
+#define IGP01E1000_PHY_PCS_INIT_REG  0x00B4
+#define IGP01E1000_PHY_PCS_CTRL_REG  0x00B5
+
+#define IGP01E1000_ANALOG_REGS_PAGE  0x20C0
+
+/* IGP01E1000 GMII FIFO Register */
+#define IGP01E1000_GMII_FLEX_SPD               0x10 /* Enable flexible speed
+							* on Link-Up */
+#define IGP01E1000_GMII_SPD                    0x20 /* Enable SPD */
+
+/* IGP01E1000 Analog Register */
+#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS       0x20D1
+#define IGP01E1000_ANALOG_FUSE_STATUS             0x20D0
+#define IGP01E1000_ANALOG_FUSE_CONTROL            0x20DC
+#define IGP01E1000_ANALOG_FUSE_BYPASS             0x20DE
+
+#define IGP01E1000_ANALOG_FUSE_POLY_MASK            0xF000
+#define IGP01E1000_ANALOG_FUSE_FINE_MASK            0x0F80
+#define IGP01E1000_ANALOG_FUSE_COARSE_MASK          0x0070
+#define IGP01E1000_ANALOG_SPARE_FUSE_ENABLED        0x0100
+#define IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL    0x0002
+
+#define IGP01E1000_ANALOG_FUSE_COARSE_THRESH        0x0040
+#define IGP01E1000_ANALOG_FUSE_COARSE_10            0x0010
+#define IGP01E1000_ANALOG_FUSE_FINE_1               0x0080
+#define IGP01E1000_ANALOG_FUSE_FINE_10              0x0500
+
+/* IGP01E1000 Specific Port Control Register - R/W */
+#define IGP01E1000_PSCR_TP_LOOPBACK            0x0010
+#define IGP01E1000_PSCR_CORRECT_NC_SCMBLR      0x0200
+#define IGP01E1000_PSCR_TEN_CRS_SELECT         0x0400
+#define IGP01E1000_PSCR_FLIP_CHIP              0x0800
+#define IGP01E1000_PSCR_AUTO_MDIX              0x1000
+#define IGP01E1000_PSCR_FORCE_MDI_MDIX         0x2000 /* 0-MDI, 1-MDIX */
+/* GG82563 PHY Specific Status Register (Page 0, Register 16 */
+#define GG82563_PSCR_DISABLE_JABBER             0x0001 /* 1=Disable Jabber */
+#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE  0x0002 /* 1=Polarity Reversal
+							  Disabled */
+#define GG82563_PSCR_POWER_DOWN                 0x0004 /* 1=Power Down */
+#define GG82563_PSCR_COPPER_TRANSMITER_DISABLE  0x0008 /* 1=Transmitter
+							  Disabled */
+#define GG82563_PSCR_CROSSOVER_MODE_MASK        0x0060
+#define GG82563_PSCR_CROSSOVER_MODE_MDI         0x0000 /* 00=Manual MDI
+							  configuration */
+#define GG82563_PSCR_CROSSOVER_MODE_MDIX        0x0020 /* 01=Manual MDIX
+							  configuration */
+#define GG82563_PSCR_CROSSOVER_MODE_AUTO        0x0060 /* 11=Automatic
+							  crossover */
+#define GG82563_PSCR_ENALBE_EXTENDED_DISTANCE   0x0080 /* 1=Enable Extended
+							  Distance */
+#define GG82563_PSCR_ENERGY_DETECT_MASK         0x0300
+#define GG82563_PSCR_ENERGY_DETECT_OFF          0x0000 /* 00,01=Off */
+#define GG82563_PSCR_ENERGY_DETECT_RX           0x0200 /* 10=Sense on Rx only
+							  (Energy Detect) */
+#define GG82563_PSCR_ENERGY_DETECT_RX_TM        0x0300 /* 11=Sense and Tx NLP */
+#define GG82563_PSCR_FORCE_LINK_GOOD            0x0400 /* 1=Force Link Good */
+#define GG82563_PSCR_DOWNSHIFT_ENABLE           0x0800 /* 1=Enable Downshift */
+#define GG82563_PSCR_DOWNSHIFT_COUNTER_MASK     0x7000
+#define GG82563_PSCR_DOWNSHIFT_COUNTER_SHIFT    12
+
+/* PHY Specific Status Register (Page 0, Register 17) */
+#define GG82563_PSSR_JABBER                0x0001 /* 1=Jabber */
+#define GG82563_PSSR_POLARITY              0x0002 /* 1=Polarity Reversed */
+#define GG82563_PSSR_LINK                  0x0008 /* 1=Link is Up */
+#define GG82563_PSSR_ENERGY_DETECT         0x0010 /* 1=Sleep, 0=Active */
+#define GG82563_PSSR_DOWNSHIFT             0x0020 /* 1=Downshift */
+#define GG82563_PSSR_CROSSOVER_STATUS      0x0040 /* 1=MDIX, 0=MDI */
+#define GG82563_PSSR_RX_PAUSE_ENABLED      0x0100 /* 1=Receive Pause Enabled */
+#define GG82563_PSSR_TX_PAUSE_ENABLED      0x0200 /* 1=Transmit Pause Enabled */
+#define GG82563_PSSR_LINK_UP               0x0400 /* 1=Link Up */
+#define GG82563_PSSR_SPEED_DUPLEX_RESOLVED 0x0800 /* 1=Resolved */
+#define GG82563_PSSR_PAGE_RECEIVED         0x1000 /* 1=Page Received */
+#define GG82563_PSSR_DUPLEX                0x2000 /* 1-Full-Duplex */
+#define GG82563_PSSR_SPEED_MASK            0xC000
+#define GG82563_PSSR_SPEED_10MBPS          0x0000 /* 00=10Mbps */
+#define GG82563_PSSR_SPEED_100MBPS         0x4000 /* 01=100Mbps */
+#define GG82563_PSSR_SPEED_1000MBPS        0x8000 /* 10=1000Mbps */
+
+/* PHY Specific Status Register 2 (Page 0, Register 19) */
+#define GG82563_PSSR2_JABBER                0x0001 /* 1=Jabber */
+#define GG82563_PSSR2_POLARITY_CHANGED      0x0002 /* 1=Polarity Changed */
+#define GG82563_PSSR2_ENERGY_DETECT_CHANGED 0x0010 /* 1=Energy Detect Changed */
+#define GG82563_PSSR2_DOWNSHIFT_INTERRUPT   0x0020 /* 1=Downshift Detected */
+#define GG82563_PSSR2_MDI_CROSSOVER_CHANGE  0x0040 /* 1=Crossover Changed */
+#define GG82563_PSSR2_FALSE_CARRIER         0x0100 /* 1=false Carrier */
+#define GG82563_PSSR2_SYMBOL_ERROR          0x0200 /* 1=Symbol Error */
+#define GG82563_PSSR2_LINK_STATUS_CHANGED   0x0400 /* 1=Link Status Changed */
+#define GG82563_PSSR2_AUTO_NEG_COMPLETED    0x0800 /* 1=Auto-Neg Completed */
+#define GG82563_PSSR2_PAGE_RECEIVED         0x1000 /* 1=Page Received */
+#define GG82563_PSSR2_DUPLEX_CHANGED        0x2000 /* 1=Duplex Changed */
+#define GG82563_PSSR2_SPEED_CHANGED         0x4000 /* 1=Speed Changed */
+#define GG82563_PSSR2_AUTO_NEG_ERROR        0x8000 /* 1=Auto-Neg Error */
+
+/* PHY Specific Control Register 2 (Page 0, Register 26) */
+#define GG82563_PSCR2_10BT_POLARITY_FORCE           0x0002 /* 1=Force Negative
+							      Polarity */
+#define GG82563_PSCR2_1000MB_TEST_SELECT_MASK       0x000C
+#define GG82563_PSCR2_1000MB_TEST_SELECT_NORMAL     0x0000 /* 00,01=Normal
+							      Operation */
+#define GG82563_PSCR2_1000MB_TEST_SELECT_112NS      0x0008 /* 10=Select 112ns
+							      Sequence */
+#define GG82563_PSCR2_1000MB_TEST_SELECT_16NS       0x000C /* 11=Select 16ns
+							      Sequence */
+#define GG82563_PSCR2_REVERSE_AUTO_NEG              0x2000 /* 1=Reverse
+							Auto-Negotiation */
+#define GG82563_PSCR2_1000BT_DISABLE                0x4000 /* 1=Disable
+							      1000BASE-T */
+#define GG82563_PSCR2_TRANSMITER_TYPE_MASK          0x8000
+#define GG82563_PSCR2_TRANSMITTER_TYPE_CLASS_B      0x0000 /* 0=Class B */
+#define GG82563_PSCR2_TRANSMITTER_TYPE_CLASS_A      0x8000 /* 1=Class A */
+
+/* MAC Specific Control Register (Page 2, Register 21) */
+/* Tx clock speed for Link Down and 1000BASE-T for the following speeds */
+#define GG82563_MSCR_TX_CLK_MASK                    0x0007
+#define GG82563_MSCR_TX_CLK_10MBPS_2_5MHZ           0x0004
+#define GG82563_MSCR_TX_CLK_100MBPS_25MHZ           0x0005
+#define GG82563_MSCR_TX_CLK_1000MBPS_2_5MHZ         0x0006
+#define GG82563_MSCR_TX_CLK_1000MBPS_25MHZ          0x0007
+
+#define GG82563_MSCR_ASSERT_CRS_ON_TX               0x0010 /* 1=Assert */
+
+/* DSP Distance Register (Page 5, Register 26) */
+#define GG82563_DSPD_CABLE_LENGTH               0x0007 /* 0 = <50M;
+							  1 = 50-80M;
+							  2 = 80-110M;
+							  3 = 110-140M;
+							  4 = >140M */
+
+/* Kumeran Mode Control Register (Page 193, Register 16) */
+#define GG82563_KMCR_PHY_LEDS_EN                    0x0020 /* 1=PHY LEDs,
+							0=Kumeran Inband LEDs */
+#define GG82563_KMCR_FORCE_LINK_UP                  0x0040 /* 1=Force Link Up */
+#define GG82563_KMCR_SUPPRESS_SGMII_EPD_EXT         0x0080
+#define GG82563_KMCR_MDIO_BUS_SPEED_SELECT_MASK     0x0400
+#define GG82563_KMCR_MDIO_BUS_SPEED_SELECT          0x0400 /* 1=6.25MHz,
+							      0=0.8MHz */
+#define GG82563_KMCR_PASS_FALSE_CARRIER             0x0800
+
+/* Power Management Control Register (Page 193, Register 20) */
+#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE    0x0001 /* 1=Enalbe SERDES
+						Electrical Idle */
+#define GG82563_PMCR_DISABLE_PORT              0x0002 /* 1=Disable Port */
+#define GG82563_PMCR_DISABLE_SERDES            0x0004 /* 1=Disable SERDES */
+#define GG82563_PMCR_REVERSE_AUTO_NEG          0x0008 /* 1=Enable Reverse
+						Auto-Negotiation */
+#define GG82563_PMCR_DISABLE_1000_NON_D0       0x0010 /* 1=Disable 1000Mbps
+							 Auto-Neg in non D0 */
+#define GG82563_PMCR_DISABLE_1000              0x0020 /* 1=Disable 1000Mbps
+							 Auto-Neg Always */
+#define GG82563_PMCR_REVERSE_AUTO_NEG_D0A      0x0040 /* 1=Enable D0a
+						Reverse Auto-Negotiation */
+#define GG82563_PMCR_FORCE_POWER_STATE         0x0080 /* 1=Force Power State */
+#define GG82563_PMCR_PROGRAMMED_POWER_STATE_MASK    0x0300
+#define GG82563_PMCR_PROGRAMMED_POWER_STATE_DR      0x0000 /* 00=Dr */
+#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D0U     0x0100 /* 01=D0u */
+#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D0A     0x0200 /* 10=D0a */
+#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D3      0x0300 /* 11=D3 */
+
+/* In-Band Control Register (Page 194, Register 18) */
+#define GG82563_ICR_DIS_PADDING		0x0010 /* Disable Padding Use */
+
+
+/* Bits...
+ * 15-5: page
+ * 4-0: register offset
+ */
+#define GG82563_PAGE_SHIFT        5
+#define GG82563_REG(page, reg)    \
+	(((page) << GG82563_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS))
+#define GG82563_MIN_ALT_REG       30
+
+/* GG82563 Specific Registers */
+#define GG82563_PHY_SPEC_CTRL           \
+	GG82563_REG(0, 16) /* PHY Specific Control */
+#define GG82563_PHY_SPEC_STATUS         \
+	GG82563_REG(0, 17) /* PHY Specific Status */
+#define GG82563_PHY_INT_ENABLE          \
+	GG82563_REG(0, 18) /* Interrupt Enable */
+#define GG82563_PHY_SPEC_STATUS_2       \
+	GG82563_REG(0, 19) /* PHY Specific Status 2 */
+#define GG82563_PHY_RX_ERR_CNTR         \
+	GG82563_REG(0, 21) /* Receive Error Counter */
+#define GG82563_PHY_PAGE_SELECT         \
+	GG82563_REG(0, 22) /* Page Select */
+#define GG82563_PHY_SPEC_CTRL_2         \
+	GG82563_REG(0, 26) /* PHY Specific Control 2 */
+#define GG82563_PHY_PAGE_SELECT_ALT     \
+	GG82563_REG(0, 29) /* Alternate Page Select */
+#define GG82563_PHY_TEST_CLK_CTRL       \
+	GG82563_REG(0, 30) /* Test Clock Control (use reg. 29 to select) */
+
+#define GG82563_PHY_MAC_SPEC_CTRL       \
+	GG82563_REG(2, 21) /* MAC Specific Control Register */
+#define GG82563_PHY_MAC_SPEC_CTRL_2     \
+	GG82563_REG(2, 26) /* MAC Specific Control 2 */
+
+#define GG82563_PHY_DSP_DISTANCE    \
+	GG82563_REG(5, 26) /* DSP Distance */
+
+/* Page 193 - Port Control Registers */
+#define GG82563_PHY_KMRN_MODE_CTRL   \
+	GG82563_REG(193, 16) /* Kumeran Mode Control */
+#define GG82563_PHY_PORT_RESET          \
+	GG82563_REG(193, 17) /* Port Reset */
+#define GG82563_PHY_REVISION_ID         \
+	GG82563_REG(193, 18) /* Revision ID */
+#define GG82563_PHY_DEVICE_ID           \
+	GG82563_REG(193, 19) /* Device ID */
+#define GG82563_PHY_PWR_MGMT_CTRL       \
+	GG82563_REG(193, 20) /* Power Management Control */
+#define GG82563_PHY_RATE_ADAPT_CTRL     \
+	GG82563_REG(193, 25) /* Rate Adaptation Control */
+
+/* Page 194 - KMRN Registers */
+#define GG82563_PHY_KMRN_FIFO_CTRL_STAT \
+	GG82563_REG(194, 16) /* FIFO's Control/Status */
+#define GG82563_PHY_KMRN_CTRL           \
+	GG82563_REG(194, 17) /* Control */
+#define GG82563_PHY_INBAND_CTRL         \
+	GG82563_REG(194, 18) /* Inband Control */
+#define GG82563_PHY_KMRN_DIAGNOSTIC     \
+	GG82563_REG(194, 19) /* Diagnostic */
+#define GG82563_PHY_ACK_TIMEOUTS        \
+	GG82563_REG(194, 20) /* Acknowledge Timeouts */
+#define GG82563_PHY_ADV_ABILITY         \
+	GG82563_REG(194, 21) /* Advertised Ability */
+#define GG82563_PHY_LINK_PARTNER_ADV_ABILITY \
+	GG82563_REG(194, 23) /* Link Partner Advertised Ability */
+#define GG82563_PHY_ADV_NEXT_PAGE       \
+	GG82563_REG(194, 24) /* Advertised Next Page */
+#define GG82563_PHY_LINK_PARTNER_ADV_NEXT_PAGE \
+	GG82563_REG(194, 25) /* Link Partner Advertised Next page */
+#define GG82563_PHY_KMRN_MISC           \
+	GG82563_REG(194, 26) /* Misc. */
+
+/* PHY Control Register */
+#define MII_CR_SPEED_SELECT_MSB		0x0040	/* bits 6,13: 10=1000, 01=100, 00=10 */
+#define MII_CR_COLL_TEST_ENABLE		0x0080	/* Collision test enable */
+#define MII_CR_FULL_DUPLEX		0x0100	/* FDX =1, half duplex =0 */
+#define MII_CR_RESTART_AUTO_NEG		0x0200	/* Restart auto negotiation */
+#define MII_CR_ISOLATE			0x0400	/* Isolate PHY from MII */
+#define MII_CR_POWER_DOWN		0x0800	/* Power down */
+#define MII_CR_AUTO_NEG_EN		0x1000	/* Auto Neg Enable */
+#define MII_CR_SPEED_SELECT_LSB		0x2000	/* bits 6,13: 10=1000, 01=100, 00=10 */
+#define MII_CR_LOOPBACK			0x4000	/* 0 = normal, 1 = loopback */
+#define MII_CR_RESET			0x8000	/* 0 = normal, 1 = PHY reset */
+
+/* PHY Status Register */
+#define MII_SR_EXTENDED_CAPS		0x0001	/* Extended register capabilities */
+#define MII_SR_JABBER_DETECT		0x0002	/* Jabber Detected */
+#define MII_SR_LINK_STATUS		0x0004	/* Link Status 1 = link */
+#define MII_SR_AUTONEG_CAPS		0x0008	/* Auto Neg Capable */
+#define MII_SR_REMOTE_FAULT		0x0010	/* Remote Fault Detect */
+#define MII_SR_AUTONEG_COMPLETE		0x0020	/* Auto Neg Complete */
+#define MII_SR_PREAMBLE_SUPPRESS	0x0040	/* Preamble may be suppressed */
+#define MII_SR_EXTENDED_STATUS		0x0100	/* Ext. status info in Reg 0x0F */
+#define MII_SR_100T2_HD_CAPS		0x0200	/* 100T2 Half Duplex Capable */
+#define MII_SR_100T2_FD_CAPS		0x0400	/* 100T2 Full Duplex Capable */
+#define MII_SR_10T_HD_CAPS		0x0800	/* 10T	 Half Duplex Capable */
+#define MII_SR_10T_FD_CAPS		0x1000	/* 10T	 Full Duplex Capable */
+#define MII_SR_100X_HD_CAPS		0x2000	/* 100X  Half Duplex Capable */
+#define MII_SR_100X_FD_CAPS		0x4000	/* 100X  Full Duplex Capable */
+#define MII_SR_100T4_CAPS		0x8000	/* 100T4 Capable */
+
+/* Autoneg Advertisement Register */
+#define NWAY_AR_SELECTOR_FIELD		0x0001	/* indicates IEEE 802.3 CSMA/CD */
+#define NWAY_AR_10T_HD_CAPS		0x0020	/* 10T	 Half Duplex Capable */
+#define NWAY_AR_10T_FD_CAPS		0x0040	/* 10T	 Full Duplex Capable */
+#define NWAY_AR_100TX_HD_CAPS		0x0080	/* 100TX Half Duplex Capable */
+#define NWAY_AR_100TX_FD_CAPS		0x0100	/* 100TX Full Duplex Capable */
+#define NWAY_AR_100T4_CAPS		0x0200	/* 100T4 Capable */
+#define NWAY_AR_PAUSE			0x0400	/* Pause operation desired */
+#define NWAY_AR_ASM_DIR		0x0800	/* Asymmetric Pause Direction bit */
+#define NWAY_AR_REMOTE_FAULT		0x2000	/* Remote Fault detected */
+#define NWAY_AR_NEXT_PAGE		0x8000	/* Next Page ability supported */
+
+/* Link Partner Ability Register (Base Page) */
+#define NWAY_LPAR_SELECTOR_FIELD	0x0000	/* LP protocol selector field */
+#define NWAY_LPAR_10T_HD_CAPS		0x0020	/* LP is 10T   Half Duplex Capable */
+#define NWAY_LPAR_10T_FD_CAPS		0x0040	/* LP is 10T   Full Duplex Capable */
+#define NWAY_LPAR_100TX_HD_CAPS	0x0080	/* LP is 100TX Half Duplex Capable */
+#define NWAY_LPAR_100TX_FD_CAPS	0x0100	/* LP is 100TX Full Duplex Capable */
+#define NWAY_LPAR_100T4_CAPS		0x0200	/* LP is 100T4 Capable */
+#define NWAY_LPAR_PAUSE			0x0400	/* LP Pause operation desired */
+#define NWAY_LPAR_ASM_DIR		0x0800	/* LP Asymmetric Pause Direction bit */
+#define NWAY_LPAR_REMOTE_FAULT		0x2000	/* LP has detected Remote Fault */
+#define NWAY_LPAR_ACKNOWLEDGE		0x4000	/* LP has rx'd link code word */
+#define NWAY_LPAR_NEXT_PAGE		0x8000	/* Next Page ability supported */
+
+/* Autoneg Expansion Register */
+#define NWAY_ER_LP_NWAY_CAPS		0x0001	/* LP has Auto Neg Capability */
+#define NWAY_ER_PAGE_RXD		0x0002	/* LP is 10T   Half Duplex Capable */
+#define NWAY_ER_NEXT_PAGE_CAPS		0x0004	/* LP is 10T   Full Duplex Capable */
+#define NWAY_ER_LP_NEXT_PAGE_CAPS	0x0008	/* LP is 100TX Half Duplex Capable */
+#define NWAY_ER_PAR_DETECT_FAULT	0x0100	/* LP is 100TX Full Duplex Capable */
+
+/* Next Page TX Register */
+#define NPTX_MSG_CODE_FIELD		0x0001	/* NP msg code or unformatted data */
+#define NPTX_TOGGLE			0x0800	/* Toggles between exchanges
+						 * of different NP
+						 */
+#define NPTX_ACKNOWLDGE2		0x1000	/* 1 = will comply with msg
+						 * 0 = cannot comply with msg
+						 */
+#define NPTX_MSG_PAGE			0x2000	/* formatted(1)/unformatted(0) pg */
+#define NPTX_NEXT_PAGE			0x8000	/* 1 = addition NP will follow
+						 * 0 = sending last NP
+						 */
+
+/* Link Partner Next Page Register */
+#define LP_RNPR_MSG_CODE_FIELD		0x0001	/* NP msg code or unformatted data */
+#define LP_RNPR_TOGGLE			0x0800	/* Toggles between exchanges
+						 * of different NP
+						 */
+#define LP_RNPR_ACKNOWLDGE2		0x1000	/* 1 = will comply with msg
+						 * 0 = cannot comply with msg
+						 */
+#define LP_RNPR_MSG_PAGE		0x2000	/* formatted(1)/unformatted(0) pg */
+#define LP_RNPR_ACKNOWLDGE		0x4000	/* 1 = ACK / 0 = NO ACK */
+#define LP_RNPR_NEXT_PAGE		0x8000	/* 1 = addition NP will follow
+						 * 0 = sending last NP
+						 */
+
+/* 1000BASE-T Control Register */
+#define CR_1000T_ASYM_PAUSE		0x0080	/* Advertise asymmetric pause bit */
+#define CR_1000T_HD_CAPS		0x0100	/* Advertise 1000T HD capability */
+#define CR_1000T_FD_CAPS		0x0200	/* Advertise 1000T FD capability  */
+#define CR_1000T_REPEATER_DTE		0x0400	/* 1=Repeater/switch device port */
+						/* 0=DTE device */
+#define CR_1000T_MS_VALUE		0x0800	/* 1=Configure PHY as Master */
+						/* 0=Configure PHY as Slave */
+#define CR_1000T_MS_ENABLE		0x1000	/* 1=Master/Slave manual config value */
+						/* 0=Automatic Master/Slave config */
+#define CR_1000T_TEST_MODE_NORMAL	0x0000	/* Normal Operation */
+#define CR_1000T_TEST_MODE_1		0x2000	/* Transmit Waveform test */
+#define CR_1000T_TEST_MODE_2		0x4000	/* Master Transmit Jitter test */
+#define CR_1000T_TEST_MODE_3		0x6000	/* Slave Transmit Jitter test */
+#define CR_1000T_TEST_MODE_4		0x8000	/* Transmitter Distortion test */
+
+/* 1000BASE-T Status Register */
+#define SR_1000T_IDLE_ERROR_CNT	0x00FF	/* Num idle errors since last read */
+#define SR_1000T_ASYM_PAUSE_DIR	0x0100	/* LP asymmetric pause direction bit */
+#define SR_1000T_LP_HD_CAPS		0x0400	/* LP is 1000T HD capable */
+#define SR_1000T_LP_FD_CAPS		0x0800	/* LP is 1000T FD capable */
+#define SR_1000T_REMOTE_RX_STATUS	0x1000	/* Remote receiver OK */
+#define SR_1000T_LOCAL_RX_STATUS	0x2000	/* Local receiver OK */
+#define SR_1000T_MS_CONFIG_RES		0x4000	/* 1=Local TX is Master, 0=Slave */
+#define SR_1000T_MS_CONFIG_FAULT	0x8000	/* Master/Slave config fault */
+#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12
+#define SR_1000T_LOCAL_RX_STATUS_SHIFT	13
+
+/* Extended Status Register */
+#define IEEE_ESR_1000T_HD_CAPS		0x1000	/* 1000T HD capable */
+#define IEEE_ESR_1000T_FD_CAPS		0x2000	/* 1000T FD capable */
+#define IEEE_ESR_1000X_HD_CAPS		0x4000	/* 1000X HD capable */
+#define IEEE_ESR_1000X_FD_CAPS		0x8000	/* 1000X FD capable */
+
+#define PHY_TX_POLARITY_MASK		0x0100	/* register 10h bit 8 (polarity bit) */
+#define PHY_TX_NORMAL_POLARITY		0	/* register 10h bit 8 (normal polarity) */
+
+#define AUTO_POLARITY_DISABLE		0x0010	/* register 11h bit 4 */
+						/* (0=enable, 1=disable) */
+
+/* M88E1000 PHY Specific Control Register */
+#define M88E1000_PSCR_JABBER_DISABLE	0x0001	/* 1=Jabber Function disabled */
+#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002	/* 1=Polarity Reversal enabled */
+#define M88E1000_PSCR_SQE_TEST		0x0004	/* 1=SQE Test enabled */
+#define M88E1000_PSCR_CLK125_DISABLE	0x0010	/* 1=CLK125 low,
+						 * 0=CLK125 toggling
+						 */
+#define M88E1000_PSCR_MDI_MANUAL_MODE	0x0000	/* MDI Crossover Mode bits 6:5 */
+						/* Manual MDI configuration */
+#define M88E1000_PSCR_MDIX_MANUAL_MODE	0x0020	/* Manual MDIX configuration */
+#define M88E1000_PSCR_AUTO_X_1000T	0x0040	/* 1000BASE-T: Auto crossover,
+						 *  100BASE-TX/10BASE-T:
+						 *  MDI Mode
+						 */
+#define M88E1000_PSCR_AUTO_X_MODE	0x0060	/* Auto crossover enabled
+						 * all speeds.
+						 */
+#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE 0x0080
+						/* 1=Enable Extended 10BASE-T distance
+						 * (Lower 10BASE-T RX Threshold)
+						 * 0=Normal 10BASE-T RX Threshold */
+#define M88E1000_PSCR_MII_5BIT_ENABLE	0x0100
+						/* 1=5-Bit interface in 100BASE-TX
+						 * 0=MII interface in 100BASE-TX */
+#define M88E1000_PSCR_SCRAMBLER_DISABLE 0x0200	/* 1=Scrambler disable */
+#define M88E1000_PSCR_FORCE_LINK_GOOD	0x0400	/* 1=Force link good */
+#define M88E1000_PSCR_ASSERT_CRS_ON_TX	0x0800	/* 1=Assert CRS on Transmit */
+
+#define M88E1000_PSCR_POLARITY_REVERSAL_SHIFT	 1
+#define M88E1000_PSCR_AUTO_X_MODE_SHIFT		 5
+#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
+
+/* M88E1000 PHY Specific Status Register */
+#define M88E1000_PSSR_JABBER		0x0001	/* 1=Jabber */
+#define M88E1000_PSSR_REV_POLARITY	0x0002	/* 1=Polarity reversed */
+#define M88E1000_PSSR_MDIX		0x0040	/* 1=MDIX; 0=MDI */
+#define M88E1000_PSSR_CABLE_LENGTH	0x0380	/* 0=<50M;1=50-80M;2=80-110M;
+						 * 3=110-140M;4=>140M */
+#define M88E1000_PSSR_LINK		0x0400	/* 1=Link up, 0=Link down */
+#define M88E1000_PSSR_SPD_DPLX_RESOLVED 0x0800	/* 1=Speed & Duplex resolved */
+#define M88E1000_PSSR_PAGE_RCVD		0x1000	/* 1=Page received */
+#define M88E1000_PSSR_DPLX		0x2000	/* 1=Duplex 0=Half Duplex */
+#define M88E1000_PSSR_SPEED		0xC000	/* Speed, bits 14:15 */
+#define M88E1000_PSSR_10MBS		0x0000	/* 00=10Mbs */
+#define M88E1000_PSSR_100MBS		0x4000	/* 01=100Mbs */
+#define M88E1000_PSSR_1000MBS		0x8000	/* 10=1000Mbs */
+
+#define M88E1000_PSSR_REV_POLARITY_SHIFT 1
+#define M88E1000_PSSR_MDIX_SHIFT	 6
+#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
+
+/* M88E1000 Extended PHY Specific Control Register */
+#define M88E1000_EPSCR_FIBER_LOOPBACK	0x4000	/* 1=Fiber loopback */
+#define M88E1000_EPSCR_DOWN_NO_IDLE	0x8000	/* 1=Lost lock detect enabled.
+						 * Will assert lost lock and bring
+						 * link down if idle not seen
+						 * within 1ms in 1000BASE-T
+						 */
+/* Number of times we will attempt to autonegotiate before downshifting if we
+ * are the master */
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X   0x0000
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X   0x0400
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X   0x0800
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X   0x0C00
+/* Number of times we will attempt to autonegotiate before downshifting if we
+ * are the slave */
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK  0x0300
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_DIS   0x0000
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X    0x0100
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_2X    0x0200
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_3X    0x0300
+#define M88E1000_EPSCR_TX_CLK_2_5	0x0060	/* 2.5 MHz TX_CLK */
+#define M88E1000_EPSCR_TX_CLK_25	0x0070	/* 25  MHz TX_CLK */
+#define M88E1000_EPSCR_TX_CLK_0	0x0000	/* NO  TX_CLK */
+
+/* Bit definitions for valid PHY IDs. */
+#define M88E1000_E_PHY_ID		0x01410C50
+#define M88E1000_I_PHY_ID		0x01410C30
+#define M88E1011_I_PHY_ID		0x01410C20
+#define M88E1000_12_PHY_ID		M88E1000_E_PHY_ID
+#define M88E1000_14_PHY_ID		M88E1000_E_PHY_ID
+#define IGP01E1000_I_PHY_ID		0x02A80380
+#define M88E1011_I_REV_4   0x04
+#define M88E1111_I_PHY_ID  0x01410CC0
+#define L1LXT971A_PHY_ID   0x001378E0
+#define GG82563_E_PHY_ID   0x01410CA0
+
+#define BME1000_E_PHY_ID     0x01410CB0
+
+/* Miscellaneous PHY bit definitions. */
+#define PHY_PREAMBLE			0xFFFFFFFF
+#define PHY_SOF				0x01
+#define PHY_OP_READ			0x02
+#define PHY_OP_WRITE			0x01
+#define PHY_TURNAROUND			0x02
+#define PHY_PREAMBLE_SIZE		32
+#define MII_CR_SPEED_1000		0x0040
+#define MII_CR_SPEED_100		0x2000
+#define MII_CR_SPEED_10		0x0000
+#define E1000_PHY_ADDRESS		0x01
+#define PHY_AUTO_NEG_TIME		45	/* 4.5 Seconds */
+#define PHY_FORCE_TIME			20	/* 2.0 Seconds */
+#define PHY_REVISION_MASK		0xFFFFFFF0
+#define DEVICE_SPEED_MASK		0x00000300	/* Device Ctrl Reg Speed Mask */
+#define REG4_SPEED_MASK		0x01E0
+#define REG9_SPEED_MASK		0x0300
+#define ADVERTISE_10_HALF		0x0001
+#define ADVERTISE_10_FULL		0x0002
+#define ADVERTISE_100_HALF		0x0004
+#define ADVERTISE_100_FULL		0x0008
+#define ADVERTISE_1000_HALF		0x0010
+#define ADVERTISE_1000_FULL		0x0020
+
+#define ICH_FLASH_GFPREG   0x0000
+#define ICH_FLASH_HSFSTS   0x0004
+#define ICH_FLASH_HSFCTL   0x0006
+#define ICH_FLASH_FADDR    0x0008
+#define ICH_FLASH_FDATA0   0x0010
+#define ICH_FLASH_FRACC    0x0050
+#define ICH_FLASH_FREG0    0x0054
+#define ICH_FLASH_FREG1    0x0058
+#define ICH_FLASH_FREG2    0x005C
+#define ICH_FLASH_FREG3    0x0060
+#define ICH_FLASH_FPR0     0x0074
+#define ICH_FLASH_FPR1     0x0078
+#define ICH_FLASH_SSFSTS   0x0090
+#define ICH_FLASH_SSFCTL   0x0092
+#define ICH_FLASH_PREOP    0x0094
+#define ICH_FLASH_OPTYPE   0x0096
+#define ICH_FLASH_OPMENU   0x0098
+
+#define ICH_FLASH_REG_MAPSIZE      0x00A0
+#define ICH_FLASH_SECTOR_SIZE      4096
+#define ICH_GFPREG_BASE_MASK       0x1FFF
+#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
+
+#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
+
+/* SPI EEPROM Status Register */
+#define EEPROM_STATUS_RDY_SPI  0x01
+#define EEPROM_STATUS_WEN_SPI  0x02
+#define EEPROM_STATUS_BP0_SPI  0x04
+#define EEPROM_STATUS_BP1_SPI  0x08
+#define EEPROM_STATUS_WPEN_SPI 0x80
+
+/* SW Semaphore Register */
+#define E1000_SWSM_SMBI		0x00000001 /* Driver Semaphore bit */
+#define E1000_SWSM_SWESMBI	0x00000002 /* FW Semaphore bit */
+#define E1000_SWSM_WMNG		0x00000004 /* Wake MNG Clock */
+#define E1000_SWSM_DRV_LOAD	0x00000008 /* Driver Loaded Bit */
+
+/* FW Semaphore Register */
+#define E1000_FWSM_MODE_MASK    0x0000000E /* FW mode */
+#define E1000_FWSM_MODE_SHIFT            1
+#define E1000_FWSM_FW_VALID     0x00008000 /* FW established a valid mode */
+
+#define E1000_FWSM_RSPCIPHY        0x00000040 /* Reset PHY on PCI reset */
+#define E1000_FWSM_DISSW           0x10000000 /* FW disable SW Write Access */
+#define E1000_FWSM_SKUSEL_MASK     0x60000000 /* LAN SKU select */
+#define E1000_FWSM_SKUEL_SHIFT     29
+#define E1000_FWSM_SKUSEL_EMB      0x0 /* Embedded SKU */
+#define E1000_FWSM_SKUSEL_CONS     0x1 /* Consumer SKU */
+#define E1000_FWSM_SKUSEL_PERF_100 0x2 /* Perf & Corp 10/100 SKU */
+#define E1000_FWSM_SKUSEL_PERF_GBE 0x3 /* Perf & Copr GbE SKU */
+
+#define E1000_GCR       0x05B00 /* PCI-Ex Control */
+#define E1000_GSCL_1    0x05B10 /* PCI-Ex Statistic Control #1 */
+#define E1000_GSCL_2    0x05B14 /* PCI-Ex Statistic Control #2 */
+#define E1000_GSCL_3    0x05B18 /* PCI-Ex Statistic Control #3 */
+#define E1000_GSCL_4    0x05B1C /* PCI-Ex Statistic Control #4 */
+#define E1000_FACTPS    0x05B30 /* Function Active and Power State to MNG */
+#define E1000_SWSM      0x05B50 /* SW Semaphore */
+#define E1000_FWSM      0x05B54 /* FW Semaphore */
+#define E1000_FFLT_DBG  0x05F04 /* Debug Register */
+#define E1000_HICR      0x08F00 /* Host Inteface Control */
+
+#define IGP_ACTIVITY_LED_MASK   0xFFFFF0FF
+#define IGP_ACTIVITY_LED_ENABLE 0x0300
+#define IGP_LED3_MODE           0x07000000
+
+/* Mask bit for PHY class in Word 7 of the EEPROM */
+#define EEPROM_PHY_CLASS_A   0x8000
+#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F  /* Everything but 1000-Half */
+#define AUTONEG_ADVERTISE_10_100_ALL    0x000F /* All 10/100 speeds*/
+#define AUTONEG_ADVERTISE_10_ALL        0x0003 /* 10Mbps Full & Half speeds*/
+
+#define E1000_KUMCTRLSTA_MASK           0x0000FFFF
+#define E1000_KUMCTRLSTA_OFFSET         0x001F0000
+#define E1000_KUMCTRLSTA_OFFSET_SHIFT   16
+#define E1000_KUMCTRLSTA_REN            0x00200000
+
+#define E1000_KUMCTRLSTA_OFFSET_FIFO_CTRL      0x00000000
+#define E1000_KUMCTRLSTA_OFFSET_CTRL           0x00000001
+#define E1000_KUMCTRLSTA_OFFSET_INB_CTRL       0x00000002
+#define E1000_KUMCTRLSTA_OFFSET_DIAG           0x00000003
+#define E1000_KUMCTRLSTA_OFFSET_TIMEOUTS       0x00000004
+#define E1000_KUMCTRLSTA_OFFSET_INB_PARAM      0x00000009
+#define E1000_KUMCTRLSTA_OFFSET_HD_CTRL        0x00000010
+#define E1000_KUMCTRLSTA_OFFSET_M2P_SERDES     0x0000001E
+#define E1000_KUMCTRLSTA_OFFSET_M2P_MODES      0x0000001F
+
+/* FIFO Control */
+#define E1000_KUMCTRLSTA_FIFO_CTRL_RX_BYPASS   0x00000008
+#define E1000_KUMCTRLSTA_FIFO_CTRL_TX_BYPASS   0x00000800
+
+/* In-Band Control */
+#define E1000_KUMCTRLSTA_INB_CTRL_LINK_STATUS_TX_TIMEOUT_DEFAULT    0x00000500
+#define E1000_KUMCTRLSTA_INB_CTRL_DIS_PADDING  0x00000010
+
+/* Half-Duplex Control */
+#define E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT 0x00000004
+#define E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT  0x00000000
+
+#define E1000_KUMCTRLSTA_OFFSET_K0S_CTRL       0x0000001E
+
+#define E1000_KUMCTRLSTA_DIAG_FELPBK           0x2000
+#define E1000_KUMCTRLSTA_DIAG_NELPBK           0x1000
+
+#define E1000_KUMCTRLSTA_K0S_100_EN            0x2000
+#define E1000_KUMCTRLSTA_K0S_GBE_EN            0x1000
+#define E1000_KUMCTRLSTA_K0S_ENTRY_LATENCY_MASK   0x0003
+
+#define E1000_MNG_ICH_IAMT_MODE         0x2
+#define E1000_MNG_IAMT_MODE             0x3
+#define E1000_MANC_BLK_PHY_RST_ON_IDE   0x00040000 /* Block phy resets */
+#define E1000_KUMCTRLSTA 0x00034 /* MAC-PHY interface - RW */
+/* Number of milliseconds we wait for PHY configuration done after MAC reset */
+#define PHY_CFG_TIMEOUT             100
+#define DEFAULT_80003ES2LAN_TIPG_IPGT_10_100 0x00000009
+#define DEFAULT_80003ES2LAN_TIPG_IPGT_1000   0x00000008
+#define AUTO_ALL_MODES	0
+
+#ifndef E1000_MASTER_SLAVE
+/* Switch to override PHY master/slave setting */
+#define E1000_MASTER_SLAVE	e1000_ms_hw_default
+#endif
+/* Extended Transmit Control */
+#define E1000_TCTL_EXT_BST_MASK  0x000003FF /* Backoff Slot Time */
+#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */
+
+#define DEFAULT_80003ES2LAN_TCTL_EXT_GCEX   0x00010000
+
+#define PCI_EX_82566_SNOOP_ALL PCI_EX_NO_SNOOP_ALL
+
+#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
+#define E1000_MC_TBL_SIZE_ICH8LAN  32
+
+#define E1000_CTRL_EXT_INT_TIMER_CLR  0x20000000 /* Clear Interrupt timers
+							after IMS clear */
+#endif	/* _E1000_HW_H_ */
diff --git a/marvell/uboot/drivers/net/e1000_spi.c b/marvell/uboot/drivers/net/e1000_spi.c
new file mode 100644
index 0000000..93043a1
--- /dev/null
+++ b/marvell/uboot/drivers/net/e1000_spi.c
@@ -0,0 +1,577 @@
+#include "e1000.h"
+#include <linux/compiler.h>
+
+/*-----------------------------------------------------------------------
+ * SPI transfer
+ *
+ * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks
+ * "bitlen" bits in the SPI MISO port.  That's just the way SPI works.
+ *
+ * The source of the outgoing bits is the "dout" parameter and the
+ * destination of the input bits is the "din" parameter.  Note that "dout"
+ * and "din" can point to the same memory location, in which case the
+ * input data overwrites the output data (since both are buffered by
+ * temporary variables, this is OK).
+ *
+ * This may be interrupted with Ctrl-C if "intr" is true, otherwise it will
+ * never return an error.
+ */
+static int e1000_spi_xfer(struct e1000_hw *hw, unsigned int bitlen,
+		const void *dout_mem, void *din_mem, bool intr)
+{
+	const uint8_t *dout = dout_mem;
+	uint8_t *din = din_mem;
+
+	uint8_t mask = 0;
+	uint32_t eecd;
+	unsigned long i;
+
+	/* Pre-read the control register */
+	eecd = E1000_READ_REG(hw, EECD);
+
+	/* Iterate over each bit */
+	for (i = 0, mask = 0x80; i < bitlen; i++, mask = (mask >> 1)?:0x80) {
+		/* Check for interrupt */
+		if (intr && ctrlc())
+			return -1;
+
+		/* Determine the output bit */
+		if (dout && dout[i >> 3] & mask)
+			eecd |=  E1000_EECD_DI;
+		else
+			eecd &= ~E1000_EECD_DI;
+
+		/* Write the output bit and wait 50us */
+		E1000_WRITE_REG(hw, EECD, eecd);
+		E1000_WRITE_FLUSH(hw);
+		udelay(50);
+
+		/* Poke the clock (waits 50us) */
+		e1000_raise_ee_clk(hw, &eecd);
+
+		/* Now read the input bit */
+		eecd = E1000_READ_REG(hw, EECD);
+		if (din) {
+			if (eecd & E1000_EECD_DO)
+				din[i >> 3] |=  mask;
+			else
+				din[i >> 3] &= ~mask;
+		}
+
+		/* Poke the clock again (waits 50us) */
+		e1000_lower_ee_clk(hw, &eecd);
+	}
+
+	/* Now clear any remaining bits of the input */
+	if (din && (i & 7))
+		din[i >> 3] &= ~((mask << 1) - 1);
+
+	return 0;
+}
+
+#ifdef CONFIG_E1000_SPI_GENERIC
+static inline struct e1000_hw *e1000_hw_from_spi(struct spi_slave *spi)
+{
+	return container_of(spi, struct e1000_hw, spi);
+}
+
+/* Not sure why all of these are necessary */
+void spi_init_r(void) { /* Nothing to do */ }
+void spi_init_f(void) { /* Nothing to do */ }
+void spi_init(void)   { /* Nothing to do */ }
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+		unsigned int max_hz, unsigned int mode)
+{
+	/* Find the right PCI device */
+	struct e1000_hw *hw = e1000_find_card(bus);
+	if (!hw) {
+		printf("ERROR: No such e1000 device: e1000#%u\n", bus);
+		return NULL;
+	}
+
+	/* Make sure it has an SPI chip */
+	if (hw->eeprom.type != e1000_eeprom_spi) {
+		E1000_ERR(hw->nic, "No attached SPI EEPROM found!\n");
+		return NULL;
+	}
+
+	/* Argument sanity checks */
+	if (cs != 0) {
+		E1000_ERR(hw->nic, "No such SPI chip: %u\n", cs);
+		return NULL;
+	}
+	if (mode != SPI_MODE_0) {
+		E1000_ERR(hw->nic, "Only SPI MODE-0 is supported!\n");
+		return NULL;
+	}
+
+	/* TODO: Use max_hz somehow */
+	E1000_DBG(hw->nic, "EEPROM SPI access requested\n");
+	return &hw->spi;
+}
+
+void spi_free_slave(struct spi_slave *spi)
+{
+	__maybe_unused struct e1000_hw *hw = e1000_hw_from_spi(spi);
+	E1000_DBG(hw->nic, "EEPROM SPI access released\n");
+}
+
+int spi_claim_bus(struct spi_slave *spi)
+{
+	struct e1000_hw *hw = e1000_hw_from_spi(spi);
+
+	if (e1000_acquire_eeprom(hw)) {
+		E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+void spi_release_bus(struct spi_slave *spi)
+{
+	struct e1000_hw *hw = e1000_hw_from_spi(spi);
+	e1000_release_eeprom(hw);
+}
+
+/* Skinny wrapper around e1000_spi_xfer */
+int spi_xfer(struct spi_slave *spi, unsigned int bitlen,
+		const void *dout_mem, void *din_mem, unsigned long flags)
+{
+	struct e1000_hw *hw = e1000_hw_from_spi(spi);
+	int ret;
+
+	if (flags & SPI_XFER_BEGIN)
+		e1000_standby_eeprom(hw);
+
+	ret = e1000_spi_xfer(hw, bitlen, dout_mem, din_mem, true);
+
+	if (flags & SPI_XFER_END)
+		e1000_standby_eeprom(hw);
+
+	return ret;
+}
+
+#endif /* not CONFIG_E1000_SPI_GENERIC */
+
+#ifdef CONFIG_CMD_E1000
+
+/* The EEPROM opcodes */
+#define SPI_EEPROM_ENABLE_WR	0x06
+#define SPI_EEPROM_DISABLE_WR	0x04
+#define SPI_EEPROM_WRITE_STATUS	0x01
+#define SPI_EEPROM_READ_STATUS	0x05
+#define SPI_EEPROM_WRITE_PAGE	0x02
+#define SPI_EEPROM_READ_PAGE	0x03
+
+/* The EEPROM status bits */
+#define SPI_EEPROM_STATUS_BUSY	0x01
+#define SPI_EEPROM_STATUS_WREN	0x02
+
+static int e1000_spi_eeprom_enable_wr(struct e1000_hw *hw, bool intr)
+{
+	u8 op[] = { SPI_EEPROM_ENABLE_WR };
+	e1000_standby_eeprom(hw);
+	return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr);
+}
+
+/*
+ * These have been tested to perform correctly, but they are not used by any
+ * of the EEPROM commands at this time.
+ */
+#if 0
+static int e1000_spi_eeprom_disable_wr(struct e1000_hw *hw, bool intr)
+{
+	u8 op[] = { SPI_EEPROM_DISABLE_WR };
+	e1000_standby_eeprom(hw);
+	return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr);
+}
+
+static int e1000_spi_eeprom_write_status(struct e1000_hw *hw,
+		u8 status, bool intr)
+{
+	u8 op[] = { SPI_EEPROM_WRITE_STATUS, status };
+	e1000_standby_eeprom(hw);
+	return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr);
+}
+#endif
+
+static int e1000_spi_eeprom_read_status(struct e1000_hw *hw, bool intr)
+{
+	u8 op[] = { SPI_EEPROM_READ_STATUS, 0 };
+	e1000_standby_eeprom(hw);
+	if (e1000_spi_xfer(hw, 8*sizeof(op), op, op, intr))
+		return -1;
+	return op[1];
+}
+
+static int e1000_spi_eeprom_write_page(struct e1000_hw *hw,
+		const void *data, u16 off, u16 len, bool intr)
+{
+	u8 op[] = {
+		SPI_EEPROM_WRITE_PAGE,
+		(off >> (hw->eeprom.address_bits - 8)) & 0xff, off & 0xff
+	};
+
+	e1000_standby_eeprom(hw);
+
+	if (e1000_spi_xfer(hw, 8 + hw->eeprom.address_bits, op, NULL, intr))
+		return -1;
+	if (e1000_spi_xfer(hw, len << 3, data, NULL, intr))
+		return -1;
+
+	return 0;
+}
+
+static int e1000_spi_eeprom_read_page(struct e1000_hw *hw,
+		void *data, u16 off, u16 len, bool intr)
+{
+	u8 op[] = {
+		SPI_EEPROM_READ_PAGE,
+		(off >> (hw->eeprom.address_bits - 8)) & 0xff, off & 0xff
+	};
+
+	e1000_standby_eeprom(hw);
+
+	if (e1000_spi_xfer(hw, 8 + hw->eeprom.address_bits, op, NULL, intr))
+		return -1;
+	if (e1000_spi_xfer(hw, len << 3, NULL, data, intr))
+		return -1;
+
+	return 0;
+}
+
+static int e1000_spi_eeprom_poll_ready(struct e1000_hw *hw, bool intr)
+{
+	int status;
+	while ((status = e1000_spi_eeprom_read_status(hw, intr)) >= 0) {
+		if (!(status & SPI_EEPROM_STATUS_BUSY))
+			return 0;
+	}
+	return -1;
+}
+
+static int e1000_spi_eeprom_dump(struct e1000_hw *hw,
+		void *data, u16 off, unsigned int len, bool intr)
+{
+	/* Interruptibly wait for the EEPROM to be ready */
+	if (e1000_spi_eeprom_poll_ready(hw, intr))
+		return -1;
+
+	/* Dump each page in sequence */
+	while (len) {
+		/* Calculate the data bytes on this page */
+		u16 pg_off = off & (hw->eeprom.page_size - 1);
+		u16 pg_len = hw->eeprom.page_size - pg_off;
+		if (pg_len > len)
+			pg_len = len;
+
+		/* Now dump the page */
+		if (e1000_spi_eeprom_read_page(hw, data, off, pg_len, intr))
+			return -1;
+
+		/* Otherwise go on to the next page */
+		len  -= pg_len;
+		off  += pg_len;
+		data += pg_len;
+	}
+
+	/* We're done! */
+	return 0;
+}
+
+static int e1000_spi_eeprom_program(struct e1000_hw *hw,
+		const void *data, u16 off, u16 len, bool intr)
+{
+	/* Program each page in sequence */
+	while (len) {
+		/* Calculate the data bytes on this page */
+		u16 pg_off = off & (hw->eeprom.page_size - 1);
+		u16 pg_len = hw->eeprom.page_size - pg_off;
+		if (pg_len > len)
+			pg_len = len;
+
+		/* Interruptibly wait for the EEPROM to be ready */
+		if (e1000_spi_eeprom_poll_ready(hw, intr))
+			return -1;
+
+		/* Enable write access */
+		if (e1000_spi_eeprom_enable_wr(hw, intr))
+			return -1;
+
+		/* Now program the page */
+		if (e1000_spi_eeprom_write_page(hw, data, off, pg_len, intr))
+			return -1;
+
+		/* Otherwise go on to the next page */
+		len  -= pg_len;
+		off  += pg_len;
+		data += pg_len;
+	}
+
+	/* Wait for the last write to complete */
+	if (e1000_spi_eeprom_poll_ready(hw, intr))
+		return -1;
+
+	/* We're done! */
+	return 0;
+}
+
+static int do_e1000_spi_show(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
+		int argc, char * const argv[])
+{
+	unsigned int length = 0;
+	u16 i, offset = 0;
+	u8 *buffer;
+	int err;
+
+	if (argc > 2) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	/* Parse the offset and length */
+	if (argc >= 1)
+		offset = simple_strtoul(argv[0], NULL, 0);
+	if (argc == 2)
+		length = simple_strtoul(argv[1], NULL, 0);
+	else if (offset < (hw->eeprom.word_size << 1))
+		length = (hw->eeprom.word_size << 1) - offset;
+
+	/* Extra sanity checks */
+	if (!length) {
+		E1000_ERR(hw->nic, "Requested zero-sized dump!\n");
+		return 1;
+	}
+	if ((0x10000 < length) || (0x10000 - length < offset)) {
+		E1000_ERR(hw->nic, "Can't dump past 0xFFFF!\n");
+		return 1;
+	}
+
+	/* Allocate a buffer to hold stuff */
+	buffer = malloc(length);
+	if (!buffer) {
+		E1000_ERR(hw->nic, "Out of Memory!\n");
+		return 1;
+	}
+
+	/* Acquire the EEPROM and perform the dump */
+	if (e1000_acquire_eeprom(hw)) {
+		E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
+		free(buffer);
+		return 1;
+	}
+	err = e1000_spi_eeprom_dump(hw, buffer, offset, length, true);
+	e1000_release_eeprom(hw);
+	if (err) {
+		E1000_ERR(hw->nic, "Interrupted!\n");
+		free(buffer);
+		return 1;
+	}
+
+	/* Now hexdump the result */
+	printf("%s: ===== Intel e1000 EEPROM (0x%04hX - 0x%04hX) =====",
+			hw->nic->name, offset, offset + length - 1);
+	for (i = 0; i < length; i++) {
+		if ((i & 0xF) == 0)
+			printf("\n%s: %04hX: ", hw->nic->name, offset + i);
+		else if ((i & 0xF) == 0x8)
+			printf(" ");
+		printf(" %02hx", buffer[i]);
+	}
+	printf("\n");
+
+	/* Success! */
+	free(buffer);
+	return 0;
+}
+
+static int do_e1000_spi_dump(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
+		int argc, char * const argv[])
+{
+	unsigned int length;
+	u16 offset;
+	void *dest;
+
+	if (argc != 3) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	/* Parse the arguments */
+	dest = (void *)simple_strtoul(argv[0], NULL, 16);
+	offset = simple_strtoul(argv[1], NULL, 0);
+	length = simple_strtoul(argv[2], NULL, 0);
+
+	/* Extra sanity checks */
+	if (!length) {
+		E1000_ERR(hw->nic, "Requested zero-sized dump!\n");
+		return 1;
+	}
+	if ((0x10000 < length) || (0x10000 - length < offset)) {
+		E1000_ERR(hw->nic, "Can't dump past 0xFFFF!\n");
+		return 1;
+	}
+
+	/* Acquire the EEPROM */
+	if (e1000_acquire_eeprom(hw)) {
+		E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
+		return 1;
+	}
+
+	/* Perform the programming operation */
+	if (e1000_spi_eeprom_dump(hw, dest, offset, length, true) < 0) {
+		E1000_ERR(hw->nic, "Interrupted!\n");
+		e1000_release_eeprom(hw);
+		return 1;
+	}
+
+	e1000_release_eeprom(hw);
+	printf("%s: ===== EEPROM DUMP COMPLETE =====\n", hw->nic->name);
+	return 0;
+}
+
+static int do_e1000_spi_program(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
+		int argc, char * const argv[])
+{
+	unsigned int length;
+	const void *source;
+	u16 offset;
+
+	if (argc != 3) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	/* Parse the arguments */
+	source = (const void *)simple_strtoul(argv[0], NULL, 16);
+	offset = simple_strtoul(argv[1], NULL, 0);
+	length = simple_strtoul(argv[2], NULL, 0);
+
+	/* Acquire the EEPROM */
+	if (e1000_acquire_eeprom(hw)) {
+		E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
+		return 1;
+	}
+
+	/* Perform the programming operation */
+	if (e1000_spi_eeprom_program(hw, source, offset, length, true) < 0) {
+		E1000_ERR(hw->nic, "Interrupted!\n");
+		e1000_release_eeprom(hw);
+		return 1;
+	}
+
+	e1000_release_eeprom(hw);
+	printf("%s: ===== EEPROM PROGRAMMED =====\n", hw->nic->name);
+	return 0;
+}
+
+static int do_e1000_spi_checksum(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
+		int argc, char * const argv[])
+{
+	uint16_t i, length, checksum = 0, checksum_reg;
+	uint16_t *buffer;
+	bool upd;
+
+	if (argc == 0)
+		upd = 0;
+	else if ((argc == 1) && !strcmp(argv[0], "update"))
+		upd = 1;
+	else {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	/* Allocate a temporary buffer */
+	length = sizeof(uint16_t) * (EEPROM_CHECKSUM_REG + 1);
+	buffer = malloc(length);
+	if (!buffer) {
+		E1000_ERR(hw->nic, "Unable to allocate EEPROM buffer!\n");
+		return 1;
+	}
+
+	/* Acquire the EEPROM */
+	if (e1000_acquire_eeprom(hw)) {
+		E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
+		return 1;
+	}
+
+	/* Read the EEPROM */
+	if (e1000_spi_eeprom_dump(hw, buffer, 0, length, true) < 0) {
+		E1000_ERR(hw->nic, "Interrupted!\n");
+		e1000_release_eeprom(hw);
+		return 1;
+	}
+
+	/* Compute the checksum and read the expected value */
+	for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
+		checksum += le16_to_cpu(buffer[i]);
+	checksum = ((uint16_t)EEPROM_SUM) - checksum;
+	checksum_reg = le16_to_cpu(buffer[i]);
+
+	/* Verify it! */
+	if (checksum_reg == checksum) {
+		printf("%s: INFO: EEPROM checksum is correct! (0x%04hx)\n",
+				hw->nic->name, checksum);
+		e1000_release_eeprom(hw);
+		return 0;
+	}
+
+	/* Hrm, verification failed, print an error */
+	E1000_ERR(hw->nic, "EEPROM checksum is incorrect!\n");
+	E1000_ERR(hw->nic, "  ...register was 0x%04hx, calculated 0x%04hx\n",
+			checksum_reg, checksum);
+
+	/* If they didn't ask us to update it, just return an error */
+	if (!upd) {
+		e1000_release_eeprom(hw);
+		return 1;
+	}
+
+	/* Ok, correct it! */
+	printf("%s: Reprogramming the EEPROM checksum...\n", hw->nic->name);
+	buffer[i] = cpu_to_le16(checksum);
+	if (e1000_spi_eeprom_program(hw, &buffer[i], i * sizeof(uint16_t),
+			sizeof(uint16_t), true)) {
+		E1000_ERR(hw->nic, "Interrupted!\n");
+		e1000_release_eeprom(hw);
+		return 1;
+	}
+
+	e1000_release_eeprom(hw);
+	return 0;
+}
+
+int do_e1000_spi(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
+		int argc, char * const argv[])
+{
+	if (argc < 1) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	/* Make sure it has an SPI chip */
+	if (hw->eeprom.type != e1000_eeprom_spi) {
+		E1000_ERR(hw->nic, "No attached SPI EEPROM found!\n");
+		return 1;
+	}
+
+	/* Check the eeprom sub-sub-command arguments */
+	if (!strcmp(argv[0], "show"))
+		return do_e1000_spi_show(cmdtp, hw, argc - 1, argv + 1);
+
+	if (!strcmp(argv[0], "dump"))
+		return do_e1000_spi_dump(cmdtp, hw, argc - 1, argv + 1);
+
+	if (!strcmp(argv[0], "program"))
+		return do_e1000_spi_program(cmdtp, hw, argc - 1, argv + 1);
+
+	if (!strcmp(argv[0], "checksum"))
+		return do_e1000_spi_checksum(cmdtp, hw, argc - 1, argv + 1);
+
+	cmd_usage(cmdtp);
+	return 1;
+}
+
+#endif /* not CONFIG_CMD_E1000 */
diff --git a/marvell/uboot/drivers/net/eepro100.c b/marvell/uboot/drivers/net/eepro100.c
new file mode 100644
index 0000000..1e4ea0c
--- /dev/null
+++ b/marvell/uboot/drivers/net/eepro100.c
@@ -0,0 +1,931 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <pci.h>
+#include <miiphy.h>
+
+#undef DEBUG
+
+	/* Ethernet chip registers.
+	 */
+#define SCBStatus		0	/* Rx/Command Unit Status *Word* */
+#define SCBIntAckByte		1	/* Rx/Command Unit STAT/ACK byte */
+#define SCBCmd			2	/* Rx/Command Unit Command *Word* */
+#define SCBIntrCtlByte		3	/* Rx/Command Unit Intr.Control Byte */
+#define SCBPointer		4	/* General purpose pointer. */
+#define SCBPort			8	/* Misc. commands and operands. */
+#define SCBflash		12	/* Flash memory control. */
+#define SCBeeprom		14	/* EEPROM memory control. */
+#define SCBCtrlMDI		16	/* MDI interface control. */
+#define SCBEarlyRx		20	/* Early receive byte count. */
+#define SCBGenControl		28	/* 82559 General Control Register */
+#define SCBGenStatus		29	/* 82559 General Status register */
+
+	/* 82559 SCB status word defnitions
+	 */
+#define SCB_STATUS_CX		0x8000	/* CU finished command (transmit) */
+#define SCB_STATUS_FR		0x4000	/* frame received */
+#define SCB_STATUS_CNA		0x2000	/* CU left active state */
+#define SCB_STATUS_RNR		0x1000	/* receiver left ready state */
+#define SCB_STATUS_MDI		0x0800	/* MDI read/write cycle done */
+#define SCB_STATUS_SWI		0x0400	/* software generated interrupt */
+#define SCB_STATUS_FCP		0x0100	/* flow control pause interrupt */
+
+#define SCB_INTACK_MASK		0xFD00	/* all the above */
+
+#define SCB_INTACK_TX		(SCB_STATUS_CX | SCB_STATUS_CNA)
+#define SCB_INTACK_RX		(SCB_STATUS_FR | SCB_STATUS_RNR)
+
+	/* System control block commands
+	 */
+/* CU Commands */
+#define CU_NOP			0x0000
+#define CU_START		0x0010
+#define CU_RESUME		0x0020
+#define CU_STATSADDR		0x0040	/* Load Dump Statistics ctrs addr */
+#define CU_SHOWSTATS		0x0050	/* Dump statistics counters. */
+#define CU_ADDR_LOAD		0x0060	/* Base address to add to CU commands */
+#define CU_DUMPSTATS		0x0070	/* Dump then reset stats counters. */
+
+/* RUC Commands */
+#define RUC_NOP			0x0000
+#define RUC_START		0x0001
+#define RUC_RESUME		0x0002
+#define RUC_ABORT		0x0004
+#define RUC_ADDR_LOAD		0x0006	/* (seems not to clear on acceptance) */
+#define RUC_RESUMENR		0x0007
+
+#define CU_CMD_MASK		0x00f0
+#define RU_CMD_MASK		0x0007
+
+#define SCB_M			0x0100	/* 0 = enable interrupt, 1 = disable */
+#define SCB_SWI			0x0200	/* 1 - cause device to interrupt */
+
+#define CU_STATUS_MASK		0x00C0
+#define RU_STATUS_MASK		0x003C
+
+#define RU_STATUS_IDLE		(0<<2)
+#define RU_STATUS_SUS		(1<<2)
+#define RU_STATUS_NORES		(2<<2)
+#define RU_STATUS_READY		(4<<2)
+#define RU_STATUS_NO_RBDS_SUS	((1<<2)|(8<<2))
+#define RU_STATUS_NO_RBDS_NORES ((2<<2)|(8<<2))
+#define RU_STATUS_NO_RBDS_READY ((4<<2)|(8<<2))
+
+	/* 82559 Port interface commands.
+	 */
+#define I82559_RESET		0x00000000	/* Software reset */
+#define I82559_SELFTEST		0x00000001	/* 82559 Selftest command */
+#define I82559_SELECTIVE_RESET	0x00000002
+#define I82559_DUMP		0x00000003
+#define I82559_DUMP_WAKEUP	0x00000007
+
+	/* 82559 Eeprom interface.
+	 */
+#define EE_SHIFT_CLK		0x01	/* EEPROM shift clock. */
+#define EE_CS			0x02	/* EEPROM chip select. */
+#define EE_DATA_WRITE		0x04	/* EEPROM chip data in. */
+#define EE_WRITE_0		0x01
+#define EE_WRITE_1		0x05
+#define EE_DATA_READ		0x08	/* EEPROM chip data out. */
+#define EE_ENB			(0x4800 | EE_CS)
+#define EE_CMD_BITS		3
+#define EE_DATA_BITS		16
+
+	/* The EEPROM commands include the alway-set leading bit.
+	 */
+#define EE_EWENB_CMD		(4 << addr_len)
+#define EE_WRITE_CMD		(5 << addr_len)
+#define EE_READ_CMD		(6 << addr_len)
+#define EE_ERASE_CMD		(7 << addr_len)
+
+	/* Receive frame descriptors.
+	 */
+struct RxFD {
+	volatile u16 status;
+	volatile u16 control;
+	volatile u32 link;		/* struct RxFD * */
+	volatile u32 rx_buf_addr;	/* void * */
+	volatile u32 count;
+
+	volatile u8 data[PKTSIZE_ALIGN];
+};
+
+#define RFD_STATUS_C		0x8000	/* completion of received frame */
+#define RFD_STATUS_OK		0x2000	/* frame received with no errors */
+
+#define RFD_CONTROL_EL		0x8000	/* 1=last RFD in RFA */
+#define RFD_CONTROL_S		0x4000	/* 1=suspend RU after receiving frame */
+#define RFD_CONTROL_H		0x0010	/* 1=RFD is a header RFD */
+#define RFD_CONTROL_SF		0x0008	/* 0=simplified, 1=flexible mode */
+
+#define RFD_COUNT_MASK		0x3fff
+#define RFD_COUNT_F		0x4000
+#define RFD_COUNT_EOF		0x8000
+
+#define RFD_RX_CRC		0x0800	/* crc error */
+#define RFD_RX_ALIGNMENT	0x0400	/* alignment error */
+#define RFD_RX_RESOURCE		0x0200	/* out of space, no resources */
+#define RFD_RX_DMA_OVER		0x0100	/* DMA overrun */
+#define RFD_RX_SHORT		0x0080	/* short frame error */
+#define RFD_RX_LENGTH		0x0020
+#define RFD_RX_ERROR		0x0010	/* receive error */
+#define RFD_RX_NO_ADR_MATCH	0x0004	/* no address match */
+#define RFD_RX_IA_MATCH		0x0002	/* individual address does not match */
+#define RFD_RX_TCO		0x0001	/* TCO indication */
+
+	/* Transmit frame descriptors
+	 */
+struct TxFD {				/* Transmit frame descriptor set. */
+	volatile u16 status;
+	volatile u16 command;
+	volatile u32 link;		/* void * */
+	volatile u32 tx_desc_addr;	/* Always points to the tx_buf_addr element. */
+	volatile s32 count;
+
+	volatile u32 tx_buf_addr0;	/* void *, frame to be transmitted.  */
+	volatile s32 tx_buf_size0;	/* Length of Tx frame. */
+	volatile u32 tx_buf_addr1;	/* void *, frame to be transmitted.  */
+	volatile s32 tx_buf_size1;	/* Length of Tx frame. */
+};
+
+#define TxCB_CMD_TRANSMIT	0x0004	/* transmit command */
+#define TxCB_CMD_SF		0x0008	/* 0=simplified, 1=flexible mode */
+#define TxCB_CMD_NC		0x0010	/* 0=CRC insert by controller */
+#define TxCB_CMD_I		0x2000	/* generate interrupt on completion */
+#define TxCB_CMD_S		0x4000	/* suspend on completion */
+#define TxCB_CMD_EL		0x8000	/* last command block in CBL */
+
+#define TxCB_COUNT_MASK		0x3fff
+#define TxCB_COUNT_EOF		0x8000
+
+	/* The Speedo3 Rx and Tx frame/buffer descriptors.
+	 */
+struct descriptor {			/* A generic descriptor. */
+	volatile u16 status;
+	volatile u16 command;
+	volatile u32 link;		/* struct descriptor *	*/
+
+	unsigned char params[0];
+};
+
+#define CONFIG_SYS_CMD_EL		0x8000
+#define CONFIG_SYS_CMD_SUSPEND		0x4000
+#define CONFIG_SYS_CMD_INT		0x2000
+#define CONFIG_SYS_CMD_IAS		0x0001	/* individual address setup */
+#define CONFIG_SYS_CMD_CONFIGURE	0x0002	/* configure */
+
+#define CONFIG_SYS_STATUS_C		0x8000
+#define CONFIG_SYS_STATUS_OK		0x2000
+
+	/* Misc.
+	 */
+#define NUM_RX_DESC		PKTBUFSRX
+#define NUM_TX_DESC		1	/* Number of TX descriptors   */
+
+#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 */
+static int tx_next;			/* TX descriptor ring pointer */
+static int tx_threshold;
+
+/*
+ * The parameters for a CmdConfigure operation.
+ * There are so many options that it would be difficult to document
+ * each bit. We mostly use the default or recommended settings.
+ */
+static const char i82557_config_cmd[] = {
+	22, 0x08, 0, 0, 0, 0, 0x32, 0x03, 1,	/* 1=Use MII  0=Use AUI */
+	0, 0x2E, 0, 0x60, 0,
+	0xf2, 0x48, 0, 0x40, 0xf2, 0x80,	/* 0x40=Force full-duplex */
+	0x3f, 0x05,
+};
+static const char i82558_config_cmd[] = {
+	22, 0x08, 0, 1, 0, 0, 0x22, 0x03, 1,	/* 1=Use MII  0=Use AUI */
+	0, 0x2E, 0, 0x60, 0x08, 0x88,
+	0x68, 0, 0x40, 0xf2, 0x84,		/* Disable FC */
+	0x31, 0x05,
+};
+
+static void init_rx_ring (struct eth_device *dev);
+static void purge_tx_ring (struct eth_device *dev);
+
+static void read_hw_addr (struct eth_device *dev, bd_t * bis);
+
+static int eepro100_init (struct eth_device *dev, bd_t * bis);
+static int eepro100_send(struct eth_device *dev, void *packet, int length);
+static int eepro100_recv (struct eth_device *dev);
+static void eepro100_halt (struct eth_device *dev);
+
+#if defined(CONFIG_E500) || defined(CONFIG_DB64360) || defined(CONFIG_DB64460)
+#define bus_to_phys(a) (a)
+#define phys_to_bus(a) (a)
+#else
+#define bus_to_phys(a)	pci_mem_to_phys((pci_dev_t)dev->priv, a)
+#define phys_to_bus(a)	pci_phys_to_mem((pci_dev_t)dev->priv, a)
+#endif
+
+static inline int INW (struct eth_device *dev, u_long addr)
+{
+	return le16_to_cpu (*(volatile u16 *) (addr + dev->iobase));
+}
+
+static inline void OUTW (struct eth_device *dev, int command, u_long addr)
+{
+	*(volatile u16 *) ((addr + dev->iobase)) = cpu_to_le16 (command);
+}
+
+static inline void OUTL (struct eth_device *dev, int command, u_long addr)
+{
+	*(volatile u32 *) ((addr + dev->iobase)) = cpu_to_le32 (command);
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+static inline int INL (struct eth_device *dev, u_long addr)
+{
+	return le32_to_cpu (*(volatile u32 *) (addr + dev->iobase));
+}
+
+static int get_phyreg (struct eth_device *dev, unsigned char addr,
+		unsigned char reg, unsigned short *value)
+{
+	int cmd;
+	int timeout = 50;
+
+	/* read requested data */
+	cmd = (2 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16);
+	OUTL (dev, cmd, SCBCtrlMDI);
+
+	do {
+		udelay(1000);
+		cmd = INL (dev, SCBCtrlMDI);
+	} while (!(cmd & (1 << 28)) && (--timeout));
+
+	if (timeout == 0)
+		return -1;
+
+	*value = (unsigned short) (cmd & 0xffff);
+
+	return 0;
+}
+
+static int set_phyreg (struct eth_device *dev, unsigned char addr,
+		unsigned char reg, unsigned short value)
+{
+	int cmd;
+	int timeout = 50;
+
+	/* write requested data */
+	cmd = (1 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16);
+	OUTL (dev, cmd | value, SCBCtrlMDI);
+
+	while (!(INL (dev, SCBCtrlMDI) & (1 << 28)) && (--timeout))
+		udelay(1000);
+
+	if (timeout == 0)
+		return -1;
+
+	return 0;
+}
+
+/* Check if given phyaddr is valid, i.e. there is a PHY connected.
+ * Do this by checking model value field from ID2 register.
+ */
+static struct eth_device* verify_phyaddr (const char *devname,
+						unsigned char addr)
+{
+	struct eth_device *dev;
+	unsigned short value;
+	unsigned char model;
+
+	dev = eth_get_dev_by_name(devname);
+	if (dev == NULL) {
+		printf("%s: no such device\n", devname);
+		return NULL;
+	}
+
+	/* read id2 register */
+	if (get_phyreg(dev, addr, MII_PHYSID2, &value) != 0) {
+		printf("%s: mii read timeout!\n", devname);
+		return NULL;
+	}
+
+	/* get model */
+	model = (unsigned char)((value >> 4) & 0x003f);
+
+	if (model == 0) {
+		printf("%s: no PHY at address %d\n", devname, addr);
+		return NULL;
+	}
+
+	return dev;
+}
+
+static int eepro100_miiphy_read(const char *devname, unsigned char addr,
+		unsigned char reg, unsigned short *value)
+{
+	struct eth_device *dev;
+
+	dev = verify_phyaddr(devname, addr);
+	if (dev == NULL)
+		return -1;
+
+	if (get_phyreg(dev, addr, reg, value) != 0) {
+		printf("%s: mii read timeout!\n", devname);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int eepro100_miiphy_write(const char *devname, unsigned char addr,
+		unsigned char reg, unsigned short value)
+{
+	struct eth_device *dev;
+
+	dev = verify_phyaddr(devname, addr);
+	if (dev == NULL)
+		return -1;
+
+	if (set_phyreg(dev, addr, reg, value) != 0) {
+		printf("%s: mii write timeout!\n", devname);
+		return -1;
+	}
+
+	return 0;
+}
+
+#endif
+
+/* Wait for the chip get the command.
+*/
+static int wait_for_eepro100 (struct eth_device *dev)
+{
+	int i;
+
+	for (i = 0; INW (dev, SCBCmd) & (CU_CMD_MASK | RU_CMD_MASK); i++) {
+		if (i >= TOUT_LOOP) {
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+static struct pci_device_id supported[] = {
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559},
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER},
+	{}
+};
+
+int eepro100_initialize (bd_t * bis)
+{
+	pci_dev_t devno;
+	int card_number = 0;
+	struct eth_device *dev;
+	u32 iobase, status;
+	int idx = 0;
+
+	while (1) {
+		/* Find PCI device
+		 */
+		if ((devno = pci_find_devices (supported, idx++)) < 0) {
+			break;
+		}
+
+		pci_read_config_dword (devno, PCI_BASE_ADDRESS_0, &iobase);
+		iobase &= ~0xf;
+
+#ifdef DEBUG
+		printf ("eepro100: Intel i82559 PCI EtherExpressPro @0x%x\n",
+				iobase);
+#endif
+
+		pci_write_config_dword (devno,
+					PCI_COMMAND,
+					PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+		/* Check if I/O accesses and Bus Mastering are enabled.
+		 */
+		pci_read_config_dword (devno, PCI_COMMAND, &status);
+		if (!(status & PCI_COMMAND_MEMORY)) {
+			printf ("Error: Can not enable MEM access.\n");
+			continue;
+		}
+
+		if (!(status & PCI_COMMAND_MASTER)) {
+			printf ("Error: Can not enable Bus Mastering.\n");
+			continue;
+		}
+
+		dev = (struct eth_device *) malloc (sizeof *dev);
+		if (!dev) {
+			printf("eepro100: Can not allocate memory\n");
+			break;
+		}
+		memset(dev, 0, sizeof(*dev));
+
+		sprintf (dev->name, "i82559#%d", card_number);
+		dev->priv = (void *) devno; /* this have to come before bus_to_phys() */
+		dev->iobase = bus_to_phys (iobase);
+		dev->init = eepro100_init;
+		dev->halt = eepro100_halt;
+		dev->send = eepro100_send;
+		dev->recv = eepro100_recv;
+
+		eth_register (dev);
+
+#if defined (CONFIG_MII) || defined(CONFIG_CMD_MII)
+		/* register mii command access routines */
+		miiphy_register(dev->name,
+				eepro100_miiphy_read, eepro100_miiphy_write);
+#endif
+
+		card_number++;
+
+		/* Set the latency timer for value.
+		 */
+		pci_write_config_byte (devno, PCI_LATENCY_TIMER, 0x20);
+
+		udelay (10 * 1000);
+
+		read_hw_addr (dev, bis);
+	}
+
+	return card_number;
+}
+
+
+static int eepro100_init (struct eth_device *dev, bd_t * bis)
+{
+	int i, status = -1;
+	int tx_cur;
+	struct descriptor *ias_cmd, *cfg_cmd;
+
+	/* Reset the ethernet controller
+	 */
+	OUTL (dev, I82559_SELECTIVE_RESET, SCBPort);
+	udelay (20);
+
+	OUTL (dev, I82559_RESET, SCBPort);
+	udelay (20);
+
+	if (!wait_for_eepro100 (dev)) {
+		printf ("Error: Can not reset ethernet controller.\n");
+		goto Done;
+	}
+	OUTL (dev, 0, SCBPointer);
+	OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd);
+
+	if (!wait_for_eepro100 (dev)) {
+		printf ("Error: Can not reset ethernet controller.\n");
+		goto Done;
+	}
+	OUTL (dev, 0, SCBPointer);
+	OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd);
+
+	/* Initialize Rx and Tx rings.
+	 */
+	init_rx_ring (dev);
+	purge_tx_ring (dev);
+
+	/* Tell the adapter where the RX ring is located.
+	 */
+	if (!wait_for_eepro100 (dev)) {
+		printf ("Error: Can not reset ethernet controller.\n");
+		goto Done;
+	}
+
+	OUTL (dev, phys_to_bus ((u32) & rx_ring[rx_next]), SCBPointer);
+	OUTW (dev, SCB_M | RUC_START, SCBCmd);
+
+	/* Send the Configure frame */
+	tx_cur = tx_next;
+	tx_next = ((tx_next + 1) % NUM_TX_DESC);
+
+	cfg_cmd = (struct descriptor *) &tx_ring[tx_cur];
+	cfg_cmd->command = cpu_to_le16 ((CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_CONFIGURE));
+	cfg_cmd->status = 0;
+	cfg_cmd->link = cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next]));
+
+	memcpy (cfg_cmd->params, i82558_config_cmd,
+			sizeof (i82558_config_cmd));
+
+	if (!wait_for_eepro100 (dev)) {
+		printf ("Error---CONFIG_SYS_CMD_CONFIGURE: Can not reset ethernet controller.\n");
+		goto Done;
+	}
+
+	OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer);
+	OUTW (dev, SCB_M | CU_START, SCBCmd);
+
+	for (i = 0;
+	     !(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C);
+	     i++) {
+		if (i >= TOUT_LOOP) {
+			printf ("%s: Tx error buffer not ready\n", dev->name);
+			goto Done;
+		}
+	}
+
+	if (!(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) {
+		printf ("TX error status = 0x%08X\n",
+			le16_to_cpu (tx_ring[tx_cur].status));
+		goto Done;
+	}
+
+	/* Send the Individual Address Setup frame
+	 */
+	tx_cur = tx_next;
+	tx_next = ((tx_next + 1) % NUM_TX_DESC);
+
+	ias_cmd = (struct descriptor *) &tx_ring[tx_cur];
+	ias_cmd->command = cpu_to_le16 ((CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_IAS));
+	ias_cmd->status = 0;
+	ias_cmd->link = cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next]));
+
+	memcpy (ias_cmd->params, dev->enetaddr, 6);
+
+	/* Tell the adapter where the TX ring is located.
+	 */
+	if (!wait_for_eepro100 (dev)) {
+		printf ("Error: Can not reset ethernet controller.\n");
+		goto Done;
+	}
+
+	OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer);
+	OUTW (dev, SCB_M | CU_START, SCBCmd);
+
+	for (i = 0; !(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C);
+		 i++) {
+		if (i >= TOUT_LOOP) {
+			printf ("%s: Tx error buffer not ready\n",
+				dev->name);
+			goto Done;
+		}
+	}
+
+	if (!(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) {
+		printf ("TX error status = 0x%08X\n",
+			le16_to_cpu (tx_ring[tx_cur].status));
+		goto Done;
+	}
+
+	status = 0;
+
+  Done:
+	return status;
+}
+
+static int eepro100_send(struct eth_device *dev, void *packet, int length)
+{
+	int i, status = -1;
+	int tx_cur;
+
+	if (length <= 0) {
+		printf ("%s: bad packet size: %d\n", dev->name, length);
+		goto Done;
+	}
+
+	tx_cur = tx_next;
+	tx_next = (tx_next + 1) % NUM_TX_DESC;
+
+	tx_ring[tx_cur].command = cpu_to_le16 ( TxCB_CMD_TRANSMIT |
+						TxCB_CMD_SF	|
+						TxCB_CMD_S	|
+						TxCB_CMD_EL );
+	tx_ring[tx_cur].status = 0;
+	tx_ring[tx_cur].count = cpu_to_le32 (tx_threshold);
+	tx_ring[tx_cur].link =
+		cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next]));
+	tx_ring[tx_cur].tx_desc_addr =
+		cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_cur].tx_buf_addr0));
+	tx_ring[tx_cur].tx_buf_addr0 =
+		cpu_to_le32 (phys_to_bus ((u_long) packet));
+	tx_ring[tx_cur].tx_buf_size0 = cpu_to_le32 (length);
+
+	if (!wait_for_eepro100 (dev)) {
+		printf ("%s: Tx error ethernet controller not ready.\n",
+				dev->name);
+		goto Done;
+	}
+
+	/* Send the packet.
+	 */
+	OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer);
+	OUTW (dev, SCB_M | CU_START, SCBCmd);
+
+	for (i = 0; !(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C);
+		 i++) {
+		if (i >= TOUT_LOOP) {
+			printf ("%s: Tx error buffer not ready\n", dev->name);
+			goto Done;
+		}
+	}
+
+	if (!(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) {
+		printf ("TX error status = 0x%08X\n",
+			le16_to_cpu (tx_ring[tx_cur].status));
+		goto Done;
+	}
+
+	status = length;
+
+  Done:
+	return status;
+}
+
+static int eepro100_recv (struct eth_device *dev)
+{
+	u16 status, stat;
+	int rx_prev, length = 0;
+
+	stat = INW (dev, SCBStatus);
+	OUTW (dev, stat & SCB_STATUS_RNR, SCBStatus);
+
+	for (;;) {
+		status = le16_to_cpu (rx_ring[rx_next].status);
+
+		if (!(status & RFD_STATUS_C)) {
+			break;
+		}
+
+		/* Valid frame status.
+		 */
+		if ((status & RFD_STATUS_OK)) {
+			/* A valid frame received.
+			 */
+			length = le32_to_cpu (rx_ring[rx_next].count) & 0x3fff;
+
+			/* Pass the packet up to the protocol
+			 * layers.
+			 */
+			NetReceive((u8 *)rx_ring[rx_next].data, length);
+		} else {
+			/* There was an error.
+			 */
+			printf ("RX error status = 0x%08X\n", status);
+		}
+
+		rx_ring[rx_next].control = cpu_to_le16 (RFD_CONTROL_S);
+		rx_ring[rx_next].status = 0;
+		rx_ring[rx_next].count = cpu_to_le32 (PKTSIZE_ALIGN << 16);
+
+		rx_prev = (rx_next + NUM_RX_DESC - 1) % NUM_RX_DESC;
+		rx_ring[rx_prev].control = 0;
+
+		/* Update entry information.
+		 */
+		rx_next = (rx_next + 1) % NUM_RX_DESC;
+	}
+
+	if (stat & SCB_STATUS_RNR) {
+
+		printf ("%s: Receiver is not ready, restart it !\n", dev->name);
+
+		/* Reinitialize Rx ring.
+		 */
+		init_rx_ring (dev);
+
+		if (!wait_for_eepro100 (dev)) {
+			printf ("Error: Can not restart ethernet controller.\n");
+			goto Done;
+		}
+
+		OUTL (dev, phys_to_bus ((u32) & rx_ring[rx_next]), SCBPointer);
+		OUTW (dev, SCB_M | RUC_START, SCBCmd);
+	}
+
+  Done:
+	return length;
+}
+
+static void eepro100_halt (struct eth_device *dev)
+{
+	/* Reset the ethernet controller
+	 */
+	OUTL (dev, I82559_SELECTIVE_RESET, SCBPort);
+	udelay (20);
+
+	OUTL (dev, I82559_RESET, SCBPort);
+	udelay (20);
+
+	if (!wait_for_eepro100 (dev)) {
+		printf ("Error: Can not reset ethernet controller.\n");
+		goto Done;
+	}
+	OUTL (dev, 0, SCBPointer);
+	OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd);
+
+	if (!wait_for_eepro100 (dev)) {
+		printf ("Error: Can not reset ethernet controller.\n");
+		goto Done;
+	}
+	OUTL (dev, 0, SCBPointer);
+	OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd);
+
+  Done:
+	return;
+}
+
+	/* SROM Read.
+	 */
+static int read_eeprom (struct eth_device *dev, int location, int addr_len)
+{
+	unsigned short retval = 0;
+	int read_cmd = location | EE_READ_CMD;
+	int i;
+
+	OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom);
+	OUTW (dev, EE_ENB, SCBeeprom);
+
+	/* Shift the read command bits out. */
+	for (i = 12; i >= 0; i--) {
+		short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+
+		OUTW (dev, EE_ENB | dataval, SCBeeprom);
+		udelay (1);
+		OUTW (dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
+		udelay (1);
+	}
+	OUTW (dev, EE_ENB, SCBeeprom);
+
+	for (i = 15; i >= 0; i--) {
+		OUTW (dev, EE_ENB | EE_SHIFT_CLK, SCBeeprom);
+		udelay (1);
+		retval = (retval << 1) |
+				((INW (dev, SCBeeprom) & EE_DATA_READ) ? 1 : 0);
+		OUTW (dev, EE_ENB, SCBeeprom);
+		udelay (1);
+	}
+
+	/* Terminate the EEPROM access. */
+	OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom);
+	return retval;
+}
+
+#ifdef CONFIG_EEPRO100_SROM_WRITE
+int eepro100_write_eeprom (struct eth_device* dev, int location, int addr_len, unsigned short data)
+{
+    unsigned short dataval;
+    int enable_cmd = 0x3f | EE_EWENB_CMD;
+    int write_cmd  = location | EE_WRITE_CMD;
+    int i;
+    unsigned long datalong, tmplong;
+
+    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);
+    udelay(1);
+    OUTW(dev, EE_ENB, SCBeeprom);
+
+    /* Shift the enable command bits out. */
+    for (i = (addr_len+EE_CMD_BITS-1); i >= 0; i--)
+    {
+	dataval = (enable_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+	OUTW(dev, EE_ENB | dataval, SCBeeprom);
+	udelay(1);
+	OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
+	udelay(1);
+    }
+
+    OUTW(dev, EE_ENB, SCBeeprom);
+    udelay(1);
+    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);
+    udelay(1);
+    OUTW(dev, EE_ENB, SCBeeprom);
+
+
+    /* Shift the write command bits out. */
+    for (i = (addr_len+EE_CMD_BITS-1); i >= 0; i--)
+    {
+	dataval = (write_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+	OUTW(dev, EE_ENB | dataval, SCBeeprom);
+	udelay(1);
+	OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
+	udelay(1);
+    }
+
+    /* Write the data */
+    datalong= (unsigned long) ((((data) & 0x00ff) << 8) | ( (data) >> 8));
+
+    for (i = 0; i< EE_DATA_BITS; i++)
+    {
+    /* Extract and move data bit to bit DI */
+    dataval = ((datalong & 0x8000)>>13) ? EE_DATA_WRITE : 0;
+
+    OUTW(dev, EE_ENB | dataval, SCBeeprom);
+    udelay(1);
+    OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom);
+    udelay(1);
+    OUTW(dev, EE_ENB | dataval, SCBeeprom);
+    udelay(1);
+
+    datalong = datalong << 1;	/* Adjust significant data bit*/
+    }
+
+    /* Finish up command  (toggle CS) */
+    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);
+    udelay(1);			/* delay for more than 250 ns */
+    OUTW(dev, EE_ENB, SCBeeprom);
+
+    /* Wait for programming ready (D0 = 1) */
+    tmplong = 10;
+    do
+    {
+	dataval = INW(dev, SCBeeprom);
+	if (dataval & EE_DATA_READ)
+	    break;
+	udelay(10000);
+    }
+    while (-- tmplong);
+
+    if (tmplong == 0)
+    {
+	printf ("Write i82559 eeprom timed out (100 ms waiting for data ready.\n");
+	return -1;
+    }
+
+    /* Terminate the EEPROM access. */
+    OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom);
+
+    return 0;
+}
+#endif
+
+static void init_rx_ring (struct eth_device *dev)
+{
+	int i;
+
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		rx_ring[i].status = 0;
+		rx_ring[i].control =
+				(i == NUM_RX_DESC - 1) ? cpu_to_le16 (RFD_CONTROL_S) : 0;
+		rx_ring[i].link =
+				cpu_to_le32 (phys_to_bus
+							 ((u32) & rx_ring[(i + 1) % NUM_RX_DESC]));
+		rx_ring[i].rx_buf_addr = 0xffffffff;
+		rx_ring[i].count = cpu_to_le32 (PKTSIZE_ALIGN << 16);
+	}
+
+	rx_next = 0;
+}
+
+static void purge_tx_ring (struct eth_device *dev)
+{
+	int i;
+
+	tx_next = 0;
+	tx_threshold = 0x01208000;
+
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		tx_ring[i].status = 0;
+		tx_ring[i].command = 0;
+		tx_ring[i].link = 0;
+		tx_ring[i].tx_desc_addr = 0;
+		tx_ring[i].count = 0;
+
+		tx_ring[i].tx_buf_addr0 = 0;
+		tx_ring[i].tx_buf_size0 = 0;
+		tx_ring[i].tx_buf_addr1 = 0;
+		tx_ring[i].tx_buf_size1 = 0;
+	}
+}
+
+static void read_hw_addr (struct eth_device *dev, bd_t * bis)
+{
+	u16 sum = 0;
+	int i, j;
+	int addr_len = read_eeprom (dev, 0, 6) == 0xffff ? 8 : 6;
+
+	for (j = 0, i = 0; i < 0x40; i++) {
+		u16 value = read_eeprom (dev, i, addr_len);
+
+		sum += value;
+		if (i < 3) {
+			dev->enetaddr[j++] = value;
+			dev->enetaddr[j++] = value >> 8;
+		}
+	}
+
+	if (sum != 0xBABA) {
+		memset (dev->enetaddr, 0, ETH_ALEN);
+#ifdef DEBUG
+		printf ("%s: Invalid EEPROM checksum %#4.4x, "
+			"check settings before activating this device!\n",
+			dev->name, sum);
+#endif
+	}
+}
diff --git a/marvell/uboot/drivers/net/enc28j60.c b/marvell/uboot/drivers/net/enc28j60.c
new file mode 100644
index 0000000..ec33764
--- /dev/null
+++ b/marvell/uboot/drivers/net/enc28j60.c
@@ -0,0 +1,963 @@
+/*
+ * (C) Copyright 2010
+ * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de
+ * Martin Krause, Martin.Krause@tqs.de
+ * reworked original enc28j60.c
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <net.h>
+#include <spi.h>
+#include <malloc.h>
+#include <netdev.h>
+#include <miiphy.h>
+#include "enc28j60.h"
+
+/*
+ * IMPORTANT: spi_claim_bus() and spi_release_bus()
+ * are called at begin and end of each of the following functions:
+ * enc_miiphy_read(), enc_miiphy_write(), enc_write_hwaddr(),
+ * enc_init(), enc_recv(), enc_send(), enc_halt()
+ * ALL other functions assume that the bus has already been claimed!
+ * Since NetReceive() might call enc_send() in return, the bus must be
+ * released, NetReceive() called and claimed again.
+ */
+
+/*
+ * Controller memory layout.
+ * We only allow 1 frame for transmission and reserve the rest
+ * for reception to handle as many broadcast packets as possible.
+ * Also use the memory from 0x0000 for receiver buffer. See errata pt. 5
+ * 0x0000 - 0x19ff 6656 bytes receive buffer
+ * 0x1a00 - 0x1fff 1536 bytes transmit buffer =
+ * control(1)+frame(1518)+status(7)+reserve(10).
+ */
+#define ENC_RX_BUF_START	0x0000
+#define ENC_RX_BUF_END		0x19ff
+#define ENC_TX_BUF_START	0x1a00
+#define ENC_TX_BUF_END		0x1fff
+#define ENC_MAX_FRM_LEN		1518
+#define RX_RESET_COUNTER	1000
+
+/*
+ * For non data transfer functions, like phy read/write, set hwaddr, init
+ * we do not need a full, time consuming init including link ready wait.
+ * This enum helps to bring the chip through the minimum necessary inits.
+ */
+enum enc_initstate {none=0, setupdone, linkready};
+typedef struct enc_device {
+	struct eth_device	*dev;	/* back pointer */
+	struct spi_slave	*slave;
+	int			rx_reset_counter;
+	u16			next_pointer;
+	u8			bank;	/* current bank in enc28j60 */
+	enum enc_initstate	initstate;
+} enc_dev_t;
+
+/*
+ * enc_bset:		set bits in a common register
+ * enc_bclr:		clear bits in a common register
+ *
+ * making the reg parameter u8 will give a compile time warning if the
+ * functions are called with a register not accessible in all Banks
+ */
+static void enc_bset(enc_dev_t *enc, const u8 reg, const u8 data)
+{
+	u8 dout[2];
+
+	dout[0] = CMD_BFS(reg);
+	dout[1] = data;
+	spi_xfer(enc->slave, 2 * 8, dout, NULL,
+		SPI_XFER_BEGIN | SPI_XFER_END);
+}
+
+static void enc_bclr(enc_dev_t *enc, const u8 reg, const u8 data)
+{
+	u8 dout[2];
+
+	dout[0] = CMD_BFC(reg);
+	dout[1] = data;
+	spi_xfer(enc->slave, 2 * 8, dout, NULL,
+		SPI_XFER_BEGIN | SPI_XFER_END);
+}
+
+/*
+ * high byte of the register contains bank number:
+ * 0: no bank switch necessary
+ * 1: switch to bank 0
+ * 2: switch to bank 1
+ * 3: switch to bank 2
+ * 4: switch to bank 3
+ */
+static void enc_set_bank(enc_dev_t *enc, const u16 reg)
+{
+	u8 newbank = reg >> 8;
+
+	if (newbank == 0 || newbank == enc->bank)
+		return;
+	switch (newbank) {
+	case 1:
+		enc_bclr(enc, CTL_REG_ECON1,
+			ENC_ECON1_BSEL0 | ENC_ECON1_BSEL1);
+		break;
+	case 2:
+		enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_BSEL0);
+		enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_BSEL1);
+		break;
+	case 3:
+		enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_BSEL0);
+		enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_BSEL1);
+		break;
+	case 4:
+		enc_bset(enc, CTL_REG_ECON1,
+			ENC_ECON1_BSEL0 | ENC_ECON1_BSEL1);
+		break;
+	}
+	enc->bank = newbank;
+}
+
+/*
+ * local functions to access SPI
+ *
+ * reg: register inside ENC28J60
+ * data: 8/16 bits to write
+ * c: number of retries
+ *
+ * enc_r8:		read 8 bits
+ * enc_r16:		read 16 bits
+ * enc_w8:		write 8 bits
+ * enc_w16:		write 16 bits
+ * enc_w8_retry:	write 8 bits, verify and retry
+ * enc_rbuf:		read from ENC28J60 into buffer
+ * enc_wbuf:		write from buffer into ENC28J60
+ */
+
+/*
+ * MAC and MII registers need a 3 byte SPI transfer to read,
+ * all other registers need a 2 byte SPI transfer.
+ */
+static int enc_reg2nbytes(const u16 reg)
+{
+	/* check if MAC or MII register */
+	return ((reg >= CTL_REG_MACON1 && reg <= CTL_REG_MIRDH) ||
+		(reg >= CTL_REG_MAADR1 && reg <= CTL_REG_MAADR4) ||
+		(reg == CTL_REG_MISTAT)) ? 3 : 2;
+}
+
+/*
+ * Read a byte register
+ */
+static u8 enc_r8(enc_dev_t *enc, const u16 reg)
+{
+	u8 dout[3];
+	u8 din[3];
+	int nbytes = enc_reg2nbytes(reg);
+
+	enc_set_bank(enc, reg);
+	dout[0] = CMD_RCR(reg);
+	spi_xfer(enc->slave, nbytes * 8, dout, din,
+		SPI_XFER_BEGIN | SPI_XFER_END);
+	return din[nbytes-1];
+}
+
+/*
+ * Read a L/H register pair and return a word.
+ * Must be called with the L register's address.
+ */
+static u16 enc_r16(enc_dev_t *enc, const u16 reg)
+{
+	u8 dout[3];
+	u8 din[3];
+	u16 result;
+	int nbytes = enc_reg2nbytes(reg);
+
+	enc_set_bank(enc, reg);
+	dout[0] = CMD_RCR(reg);
+	spi_xfer(enc->slave, nbytes * 8, dout, din,
+		SPI_XFER_BEGIN | SPI_XFER_END);
+	result = din[nbytes-1];
+	dout[0]++; /* next register */
+	spi_xfer(enc->slave, nbytes * 8, dout, din,
+		SPI_XFER_BEGIN | SPI_XFER_END);
+	result |= din[nbytes-1] << 8;
+	return result;
+}
+
+/*
+ * Write a byte register
+ */
+static void enc_w8(enc_dev_t *enc, const u16 reg, const u8 data)
+{
+	u8 dout[2];
+
+	enc_set_bank(enc, reg);
+	dout[0] = CMD_WCR(reg);
+	dout[1] = data;
+	spi_xfer(enc->slave, 2 * 8, dout, NULL,
+		SPI_XFER_BEGIN | SPI_XFER_END);
+}
+
+/*
+ * Write a L/H register pair.
+ * Must be called with the L register's address.
+ */
+static void enc_w16(enc_dev_t *enc, const u16 reg, const u16 data)
+{
+	u8 dout[2];
+
+	enc_set_bank(enc, reg);
+	dout[0] = CMD_WCR(reg);
+	dout[1] = data;
+	spi_xfer(enc->slave, 2 * 8, dout, NULL,
+		SPI_XFER_BEGIN | SPI_XFER_END);
+	dout[0]++; /* next register */
+	dout[1] = data >> 8;
+	spi_xfer(enc->slave, 2 * 8, dout, NULL,
+		SPI_XFER_BEGIN | SPI_XFER_END);
+}
+
+/*
+ * Write a byte register, verify and retry
+ */
+static void enc_w8_retry(enc_dev_t *enc, const u16 reg, const u8 data, const int c)
+{
+	u8 dout[2];
+	u8 readback;
+	int i;
+
+	enc_set_bank(enc, reg);
+	for (i = 0; i < c; i++) {
+		dout[0] = CMD_WCR(reg);
+		dout[1] = data;
+		spi_xfer(enc->slave, 2 * 8, dout, NULL,
+			SPI_XFER_BEGIN | SPI_XFER_END);
+		readback = enc_r8(enc, reg);
+		if (readback == data)
+			break;
+		/* wait 1ms */
+		udelay(1000);
+	}
+	if (i == c) {
+		printf("%s: write reg 0x%03x failed\n", enc->dev->name, reg);
+	}
+}
+
+/*
+ * Read ENC RAM into buffer
+ */
+static void enc_rbuf(enc_dev_t *enc, const u16 length, u8 *buf)
+{
+	u8 dout[1];
+
+	dout[0] = CMD_RBM;
+	spi_xfer(enc->slave, 8, dout, NULL, SPI_XFER_BEGIN);
+	spi_xfer(enc->slave, length * 8, NULL, buf, SPI_XFER_END);
+#ifdef DEBUG
+	puts("Rx:\n");
+	print_buffer(0, buf, 1, length, 0);
+#endif
+}
+
+/*
+ * Write buffer into ENC RAM
+ */
+static void enc_wbuf(enc_dev_t *enc, const u16 length, const u8 *buf, const u8 control)
+{
+	u8 dout[2];
+	dout[0] = CMD_WBM;
+	dout[1] = control;
+	spi_xfer(enc->slave, 2 * 8, dout, NULL, SPI_XFER_BEGIN);
+	spi_xfer(enc->slave, length * 8, buf, NULL, SPI_XFER_END);
+#ifdef DEBUG
+	puts("Tx:\n");
+	print_buffer(0, buf, 1, length, 0);
+#endif
+}
+
+/*
+ * Try to claim the SPI bus.
+ * Print error message on failure.
+ */
+static int enc_claim_bus(enc_dev_t *enc)
+{
+	int rc = spi_claim_bus(enc->slave);
+	if (rc)
+		printf("%s: failed to claim SPI bus\n", enc->dev->name);
+	return rc;
+}
+
+/*
+ * Release previously claimed SPI bus.
+ * This function is mainly for symmetry to enc_claim_bus().
+ * Let the toolchain decide to inline it...
+ */
+static void enc_release_bus(enc_dev_t *enc)
+{
+	spi_release_bus(enc->slave);
+}
+
+/*
+ * Read PHY register
+ */
+static u16 enc_phy_read(enc_dev_t *enc, const u8 addr)
+{
+	uint64_t etime;
+	u8 status;
+
+	enc_w8(enc, CTL_REG_MIREGADR, addr);
+	enc_w8(enc, CTL_REG_MICMD, ENC_MICMD_MIIRD);
+	/* 1 second timeout - only happens on hardware problem */
+	etime = get_ticks() + get_tbclk();
+	/* poll MISTAT.BUSY bit until operation is complete */
+	do
+	{
+		status = enc_r8(enc, CTL_REG_MISTAT);
+	} while (get_ticks() <= etime && (status & ENC_MISTAT_BUSY));
+	if (status & ENC_MISTAT_BUSY) {
+		printf("%s: timeout reading phy\n", enc->dev->name);
+		return 0;
+	}
+	enc_w8(enc, CTL_REG_MICMD, 0);
+	return enc_r16(enc, CTL_REG_MIRDL);
+}
+
+/*
+ * Write PHY register
+ */
+static void enc_phy_write(enc_dev_t *enc, const u8 addr, const u16 data)
+{
+	uint64_t etime;
+	u8 status;
+
+	enc_w8(enc, CTL_REG_MIREGADR, addr);
+	enc_w16(enc, CTL_REG_MIWRL, data);
+	/* 1 second timeout - only happens on hardware problem */
+	etime = get_ticks() + get_tbclk();
+	/* poll MISTAT.BUSY bit until operation is complete */
+	do
+	{
+		status = enc_r8(enc, CTL_REG_MISTAT);
+	} while (get_ticks() <= etime && (status & ENC_MISTAT_BUSY));
+	if (status & ENC_MISTAT_BUSY) {
+		printf("%s: timeout writing phy\n", enc->dev->name);
+		return;
+	}
+}
+
+/*
+ * Verify link status, wait if necessary
+ *
+ * Note: with a 10 MBit/s only PHY there is no autonegotiation possible,
+ * half/full duplex is a pure setup matter. For the time being, this driver
+ * will setup in half duplex mode only.
+ */
+static int enc_phy_link_wait(enc_dev_t *enc)
+{
+	u16 status;
+	int duplex;
+	uint64_t etime;
+
+#ifdef CONFIG_ENC_SILENTLINK
+	/* check if we have a link, then just return */
+	status = enc_phy_read(enc, PHY_REG_PHSTAT1);
+	if (status & ENC_PHSTAT1_LLSTAT)
+		return 0;
+#endif
+
+	/* wait for link with 1 second timeout */
+	etime = get_ticks() + get_tbclk();
+	while (get_ticks() <= etime) {
+		status = enc_phy_read(enc, PHY_REG_PHSTAT1);
+		if (status & ENC_PHSTAT1_LLSTAT) {
+			/* now we have a link */
+			status = enc_phy_read(enc, PHY_REG_PHSTAT2);
+			duplex = (status & ENC_PHSTAT2_DPXSTAT) ? 1 : 0;
+			printf("%s: link up, 10Mbps %s-duplex\n",
+				enc->dev->name, duplex ? "full" : "half");
+			return 0;
+		}
+		udelay(1000);
+	}
+
+	/* timeout occured */
+	printf("%s: link down\n", enc->dev->name);
+	return 1;
+}
+
+/*
+ * This function resets the receiver only.
+ */
+static void enc_reset_rx(enc_dev_t *enc)
+{
+	u8 econ1;
+
+	econ1 = enc_r8(enc, CTL_REG_ECON1);
+	if ((econ1 & ENC_ECON1_RXRST) == 0) {
+		enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_RXRST);
+		enc->rx_reset_counter = RX_RESET_COUNTER;
+	}
+}
+
+/*
+ * Reset receiver and reenable it.
+ */
+static void enc_reset_rx_call(enc_dev_t *enc)
+{
+	enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_RXRST);
+	enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_RXEN);
+}
+
+/*
+ * Copy a packet from the receive ring and forward it to
+ * the protocol stack.
+ */
+static void enc_receive(enc_dev_t *enc)
+{
+	u8 *packet = (u8 *)NetRxPackets[0];
+	u16 pkt_len;
+	u16 copy_len;
+	u16 status;
+	u8 pkt_cnt = 0;
+	u16 rxbuf_rdpt;
+	u8 hbuf[6];
+
+	enc_w16(enc, CTL_REG_ERDPTL, enc->next_pointer);
+	do {
+		enc_rbuf(enc, 6, hbuf);
+		enc->next_pointer = hbuf[0] | (hbuf[1] << 8);
+		pkt_len = hbuf[2] | (hbuf[3] << 8);
+		status = hbuf[4] | (hbuf[5] << 8);
+		debug("next_pointer=$%04x pkt_len=%u status=$%04x\n",
+			enc->next_pointer, pkt_len, status);
+		if (pkt_len <= ENC_MAX_FRM_LEN)
+			copy_len = pkt_len;
+		else
+			copy_len = 0;
+		if ((status & (1L << 7)) == 0) /* check Received Ok bit */
+			copy_len = 0;
+		/* check if next pointer is resonable */
+		if (enc->next_pointer >= ENC_TX_BUF_START)
+			copy_len = 0;
+		if (copy_len > 0) {
+			enc_rbuf(enc, copy_len, packet);
+		}
+		/* advance read pointer to next pointer */
+		enc_w16(enc, CTL_REG_ERDPTL, enc->next_pointer);
+		/* decrease packet counter */
+		enc_bset(enc, CTL_REG_ECON2, ENC_ECON2_PKTDEC);
+		/*
+		 * Only odd values should be written to ERXRDPTL,
+		 * see errata B4 pt.13
+		 */
+		rxbuf_rdpt = enc->next_pointer - 1;
+		if ((rxbuf_rdpt < enc_r16(enc, CTL_REG_ERXSTL)) ||
+			(rxbuf_rdpt > enc_r16(enc, CTL_REG_ERXNDL))) {
+			enc_w16(enc, CTL_REG_ERXRDPTL,
+				enc_r16(enc, CTL_REG_ERXNDL));
+		} else {
+			enc_w16(enc, CTL_REG_ERXRDPTL, rxbuf_rdpt);
+		}
+		/* read pktcnt */
+		pkt_cnt = enc_r8(enc, CTL_REG_EPKTCNT);
+		if (copy_len == 0) {
+			(void)enc_r8(enc, CTL_REG_EIR);
+			enc_reset_rx(enc);
+			printf("%s: receive copy_len=0\n", enc->dev->name);
+			continue;
+		}
+		/*
+		 * Because NetReceive() might call enc_send(), we need to
+		 * release the SPI bus, call NetReceive(), reclaim the bus
+		 */
+		enc_release_bus(enc);
+		NetReceive(packet, pkt_len);
+		if (enc_claim_bus(enc))
+			return;
+		(void)enc_r8(enc, CTL_REG_EIR);
+	} while (pkt_cnt);
+	/* Use EPKTCNT not EIR.PKTIF flag, see errata pt. 6 */
+}
+
+/*
+ * Poll for completely received packets.
+ */
+static void enc_poll(enc_dev_t *enc)
+{
+	u8 eir_reg;
+	u8 pkt_cnt;
+
+#ifdef CONFIG_USE_IRQ
+	/* clear global interrupt enable bit in enc28j60 */
+	enc_bclr(enc, CTL_REG_EIE, ENC_EIE_INTIE);
+#endif
+	(void)enc_r8(enc, CTL_REG_ESTAT);
+	eir_reg = enc_r8(enc, CTL_REG_EIR);
+	if (eir_reg & ENC_EIR_TXIF) {
+		/* clear TXIF bit in EIR */
+		enc_bclr(enc, CTL_REG_EIR, ENC_EIR_TXIF);
+	}
+	/* We have to use pktcnt and not pktif bit, see errata pt. 6 */
+	pkt_cnt = enc_r8(enc, CTL_REG_EPKTCNT);
+	if (pkt_cnt > 0) {
+		if ((eir_reg & ENC_EIR_PKTIF) == 0) {
+			debug("enc_poll: pkt cnt > 0, but pktif not set\n");
+		}
+		enc_receive(enc);
+		/*
+		 * clear PKTIF bit in EIR, this should not need to be done
+		 * but it seems like we get problems if we do not
+		 */
+		enc_bclr(enc, CTL_REG_EIR, ENC_EIR_PKTIF);
+	}
+	if (eir_reg & ENC_EIR_RXERIF) {
+		printf("%s: rx error\n", enc->dev->name);
+		enc_bclr(enc, CTL_REG_EIR, ENC_EIR_RXERIF);
+	}
+	if (eir_reg & ENC_EIR_TXERIF) {
+		printf("%s: tx error\n", enc->dev->name);
+		enc_bclr(enc, CTL_REG_EIR, ENC_EIR_TXERIF);
+	}
+#ifdef CONFIG_USE_IRQ
+	/* set global interrupt enable bit in enc28j60 */
+	enc_bset(enc, CTL_REG_EIE, ENC_EIE_INTIE);
+#endif
+}
+
+/*
+ * Completely Reset the ENC
+ */
+static void enc_reset(enc_dev_t *enc)
+{
+	u8 dout[1];
+
+	dout[0] = CMD_SRC;
+	spi_xfer(enc->slave, 8, dout, NULL,
+		SPI_XFER_BEGIN | SPI_XFER_END);
+	/* sleep 1 ms. See errata pt. 2 */
+	udelay(1000);
+}
+
+/*
+ * Initialisation data for most of the ENC registers
+ */
+static const u16 enc_initdata[] = {
+	/*
+	 * Setup the buffer space. The reset values are valid for the
+	 * other pointers.
+	 *
+	 * We shall not write to ERXST, see errata pt. 5. Instead we
+	 * have to make sure that ENC_RX_BUS_START is 0.
+	 */
+	CTL_REG_ERXSTL, ENC_RX_BUF_START,
+	CTL_REG_ERXSTH, ENC_RX_BUF_START >> 8,
+	CTL_REG_ERXNDL, ENC_RX_BUF_END,
+	CTL_REG_ERXNDH, ENC_RX_BUF_END >> 8,
+	CTL_REG_ERDPTL, ENC_RX_BUF_START,
+	CTL_REG_ERDPTH, ENC_RX_BUF_START >> 8,
+	/*
+	 * Set the filter to receive only good-CRC, unicast and broadcast
+	 * frames.
+	 * Note: some DHCP servers return their answers as broadcasts!
+	 * So its unwise to remove broadcast from this. This driver
+	 * might incur receiver overruns with packet loss on a broadcast
+	 * flooded network.
+	 */
+	CTL_REG_ERXFCON, ENC_RFR_BCEN | ENC_RFR_UCEN | ENC_RFR_CRCEN,
+
+	/* enable MAC to receive frames */
+	CTL_REG_MACON1,
+		ENC_MACON1_MARXEN | ENC_MACON1_TXPAUS | ENC_MACON1_RXPAUS,
+
+	/* configure pad, tx-crc and duplex */
+	CTL_REG_MACON3,
+		ENC_MACON3_PADCFG0 | ENC_MACON3_TXCRCEN |
+		ENC_MACON3_FRMLNEN,
+
+	/* Allow infinite deferals if the medium is continously busy */
+	CTL_REG_MACON4, ENC_MACON4_DEFER,
+
+	/* Late collisions occur beyond 63 bytes */
+	CTL_REG_MACLCON2, 63,
+
+	/*
+	 * Set (low byte) Non-Back-to_Back Inter-Packet Gap.
+	 * Recommended 0x12
+	 */
+	CTL_REG_MAIPGL, 0x12,
+
+	/*
+	 * Set (high byte) Non-Back-to_Back Inter-Packet Gap.
+	 * Recommended 0x0c for half-duplex. Nothing for full-duplex
+	 */
+	CTL_REG_MAIPGH, 0x0C,
+
+	/* set maximum frame length */
+	CTL_REG_MAMXFLL, ENC_MAX_FRM_LEN,
+	CTL_REG_MAMXFLH, ENC_MAX_FRM_LEN >> 8,
+
+	/*
+	 * Set MAC back-to-back inter-packet gap.
+	 * Recommended 0x12 for half duplex
+	 * and 0x15 for full duplex.
+	 */
+	CTL_REG_MABBIPG, 0x12,
+
+	/* end of table */
+	0xffff
+};
+
+/*
+ * Wait for the XTAL oscillator to become ready
+ */
+static int enc_clock_wait(enc_dev_t *enc)
+{
+	uint64_t etime;
+
+	/* one second timeout */
+	etime = get_ticks() + get_tbclk();
+
+	/*
+	 * Wait for CLKRDY to become set (i.e., check that we can
+	 * communicate with the ENC)
+	 */
+	do
+	{
+		if (enc_r8(enc, CTL_REG_ESTAT) & ENC_ESTAT_CLKRDY)
+			return 0;
+	} while (get_ticks() <= etime);
+
+	printf("%s: timeout waiting for CLKRDY\n", enc->dev->name);
+	return -1;
+}
+
+/*
+ * Write the MAC address into the ENC
+ */
+static int enc_write_macaddr(enc_dev_t *enc)
+{
+	unsigned char *p = enc->dev->enetaddr;
+
+	enc_w8_retry(enc, CTL_REG_MAADR5, *p++, 5);
+	enc_w8_retry(enc, CTL_REG_MAADR4, *p++, 5);
+	enc_w8_retry(enc, CTL_REG_MAADR3, *p++, 5);
+	enc_w8_retry(enc, CTL_REG_MAADR2, *p++, 5);
+	enc_w8_retry(enc, CTL_REG_MAADR1, *p++, 5);
+	enc_w8_retry(enc, CTL_REG_MAADR0, *p, 5);
+	return 0;
+}
+
+/*
+ * Setup most of the ENC registers
+ */
+static int enc_setup(enc_dev_t *enc)
+{
+	u16 phid1 = 0;
+	u16 phid2 = 0;
+	const u16 *tp;
+
+	/* reset enc struct values */
+	enc->next_pointer = ENC_RX_BUF_START;
+	enc->rx_reset_counter = RX_RESET_COUNTER;
+	enc->bank = 0xff;	/* invalidate current bank in enc28j60 */
+
+	/* verify PHY identification */
+	phid1 = enc_phy_read(enc, PHY_REG_PHID1);
+	phid2 = enc_phy_read(enc, PHY_REG_PHID2) & ENC_PHID2_MASK;
+	if (phid1 != ENC_PHID1_VALUE || phid2 != ENC_PHID2_VALUE) {
+		printf("%s: failed to identify PHY. Found %04x:%04x\n",
+			enc->dev->name, phid1, phid2);
+		return -1;
+	}
+
+	/* now program registers */
+	for (tp = enc_initdata; *tp != 0xffff; tp += 2)
+		enc_w8_retry(enc, tp[0], tp[1], 10);
+
+	/*
+	 * Prevent automatic loopback of data beeing transmitted by setting
+	 * ENC_PHCON2_HDLDIS
+	 */
+	enc_phy_write(enc, PHY_REG_PHCON2, (1<<8));
+
+	/*
+	 * LEDs configuration
+	 * LEDA: LACFG = 0100 -> display link status
+	 * LEDB: LBCFG = 0111 -> display TX & RX activity
+	 * STRCH = 1 -> LED pulses
+	 */
+	enc_phy_write(enc, PHY_REG_PHLCON, 0x0472);
+
+	/* Reset PDPXMD-bit => half duplex */
+	enc_phy_write(enc, PHY_REG_PHCON1, 0);
+
+#ifdef CONFIG_USE_IRQ
+	/* enable interrupts */
+	enc_bset(enc, CTL_REG_EIE, ENC_EIE_PKTIE);
+	enc_bset(enc, CTL_REG_EIE, ENC_EIE_TXIE);
+	enc_bset(enc, CTL_REG_EIE, ENC_EIE_RXERIE);
+	enc_bset(enc, CTL_REG_EIE, ENC_EIE_TXERIE);
+	enc_bset(enc, CTL_REG_EIE, ENC_EIE_INTIE);
+#endif
+
+	return 0;
+}
+
+/*
+ * Check if ENC has been initialized.
+ * If not, try to initialize it.
+ * Remember initialized state in struct.
+ */
+static int enc_initcheck(enc_dev_t *enc, const enum enc_initstate requiredstate)
+{
+	if (enc->initstate >= requiredstate)
+		return 0;
+
+	if (enc->initstate < setupdone) {
+		/* Initialize the ENC only */
+		enc_reset(enc);
+		/* if any of functions fails, skip the rest and return an error */
+		if (enc_clock_wait(enc) || enc_setup(enc) || enc_write_macaddr(enc)) {
+			return -1;
+		}
+		enc->initstate = setupdone;
+	}
+	/* if that's all we need, return here */
+	if (enc->initstate >= requiredstate)
+		return 0;
+
+	/* now wait for link ready condition */
+	if (enc_phy_link_wait(enc)) {
+		return -1;
+	}
+	enc->initstate = linkready;
+	return 0;
+}
+
+#if defined(CONFIG_CMD_MII)
+/*
+ * Read a PHY register.
+ *
+ * This function is registered with miiphy_register().
+ */
+int enc_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	enc_dev_t *enc;
+
+	if (!dev || phy_adr != 0)
+		return -1;
+
+	enc = dev->priv;
+	if (enc_claim_bus(enc))
+		return -1;
+	if (enc_initcheck(enc, setupdone)) {
+		enc_release_bus(enc);
+		return -1;
+	}
+	*value = enc_phy_read(enc, reg);
+	enc_release_bus(enc);
+	return 0;
+}
+
+/*
+ * Write a PHY register.
+ *
+ * This function is registered with miiphy_register().
+ */
+int enc_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	enc_dev_t *enc;
+
+	if (!dev || phy_adr != 0)
+		return -1;
+
+	enc = dev->priv;
+	if (enc_claim_bus(enc))
+		return -1;
+	if (enc_initcheck(enc, setupdone)) {
+		enc_release_bus(enc);
+		return -1;
+	}
+	enc_phy_write(enc, reg, value);
+	enc_release_bus(enc);
+	return 0;
+}
+#endif
+
+/*
+ * Write hardware (MAC) address.
+ *
+ * This function entered into eth_device structure.
+ */
+static int enc_write_hwaddr(struct eth_device *dev)
+{
+	enc_dev_t *enc = dev->priv;
+
+	if (enc_claim_bus(enc))
+		return -1;
+	if (enc_initcheck(enc, setupdone)) {
+		enc_release_bus(enc);
+		return -1;
+	}
+	enc_release_bus(enc);
+	return 0;
+}
+
+/*
+ * Initialize ENC28J60 for use.
+ *
+ * This function entered into eth_device structure.
+ */
+static int enc_init(struct eth_device *dev, bd_t *bis)
+{
+	enc_dev_t *enc = dev->priv;
+
+	if (enc_claim_bus(enc))
+		return -1;
+	if (enc_initcheck(enc, linkready)) {
+		enc_release_bus(enc);
+		return -1;
+	}
+	/* enable receive */
+	enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_RXEN);
+	enc_release_bus(enc);
+	return 0;
+}
+
+/*
+ * Check for received packets.
+ *
+ * This function entered into eth_device structure.
+ */
+static int enc_recv(struct eth_device *dev)
+{
+	enc_dev_t *enc = dev->priv;
+
+	if (enc_claim_bus(enc))
+		return -1;
+	if (enc_initcheck(enc, linkready)) {
+		enc_release_bus(enc);
+		return -1;
+	}
+	/* Check for dead receiver */
+	if (enc->rx_reset_counter > 0)
+		enc->rx_reset_counter--;
+	else
+		enc_reset_rx_call(enc);
+	enc_poll(enc);
+	enc_release_bus(enc);
+	return 0;
+}
+
+/*
+ * Send a packet.
+ *
+ * This function entered into eth_device structure.
+ *
+ * Should we wait here until we have a Link? Or shall we leave that to
+ * protocol retries?
+ */
+static int enc_send(
+	struct eth_device *dev,
+	void *packet,
+	int length)
+{
+	enc_dev_t *enc = dev->priv;
+
+	if (enc_claim_bus(enc))
+		return -1;
+	if (enc_initcheck(enc, linkready)) {
+		enc_release_bus(enc);
+		return -1;
+	}
+	/* setup transmit pointers */
+	enc_w16(enc, CTL_REG_EWRPTL, ENC_TX_BUF_START);
+	enc_w16(enc, CTL_REG_ETXNDL, length + ENC_TX_BUF_START);
+	enc_w16(enc, CTL_REG_ETXSTL, ENC_TX_BUF_START);
+	/* write packet to ENC */
+	enc_wbuf(enc, length, (u8 *) packet, 0x00);
+	/*
+	 * Check that the internal transmit logic has not been altered
+	 * by excessive collisions. Reset transmitter if so.
+	 * See Errata B4 12 and 14.
+	 */
+	if (enc_r8(enc, CTL_REG_EIR) & ENC_EIR_TXERIF) {
+		enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_TXRST);
+		enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_TXRST);
+	}
+	enc_bclr(enc, CTL_REG_EIR, (ENC_EIR_TXERIF | ENC_EIR_TXIF));
+	/* start transmitting */
+	enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_TXRTS);
+	enc_release_bus(enc);
+	return 0;
+}
+
+/*
+ * Finish use of ENC.
+ *
+ * This function entered into eth_device structure.
+ */
+static void enc_halt(struct eth_device *dev)
+{
+	enc_dev_t *enc = dev->priv;
+
+	if (enc_claim_bus(enc))
+		return;
+	/* Just disable receiver */
+	enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_RXEN);
+	enc_release_bus(enc);
+}
+
+/*
+ * This is the only exported function.
+ *
+ * It may be called several times with different bus:cs combinations.
+ */
+int enc28j60_initialize(unsigned int bus, unsigned int cs,
+	unsigned int max_hz, unsigned int mode)
+{
+	struct eth_device *dev;
+	enc_dev_t *enc;
+
+	/* try to allocate, check and clear eth_device object */
+	dev = malloc(sizeof(*dev));
+	if (!dev) {
+		return -1;
+	}
+	memset(dev, 0, sizeof(*dev));
+
+	/* try to allocate, check and clear enc_dev_t object */
+	enc = malloc(sizeof(*enc));
+	if (!enc) {
+		free(dev);
+		return -1;
+	}
+	memset(enc, 0, sizeof(*enc));
+
+	/* try to setup the SPI slave */
+	enc->slave = spi_setup_slave(bus, cs, max_hz, mode);
+	if (!enc->slave) {
+		printf("enc28j60: invalid SPI device %i:%i\n", bus, cs);
+		free(enc);
+		free(dev);
+		return -1;
+	}
+
+	enc->dev = dev;
+	/* now fill the eth_device object */
+	dev->priv = enc;
+	dev->init = enc_init;
+	dev->halt = enc_halt;
+	dev->send = enc_send;
+	dev->recv = enc_recv;
+	dev->write_hwaddr = enc_write_hwaddr;
+	sprintf(dev->name, "enc%i.%i", bus, cs);
+	eth_register(dev);
+#if defined(CONFIG_CMD_MII)
+	miiphy_register(dev->name, enc_miiphy_read, enc_miiphy_write);
+#endif
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/enc28j60.h b/marvell/uboot/drivers/net/enc28j60.h
new file mode 100644
index 0000000..289e412
--- /dev/null
+++ b/marvell/uboot/drivers/net/enc28j60.h
@@ -0,0 +1,238 @@
+/*
+ * (X) extracted from enc28j60.c
+ * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _enc28j60_h
+#define _enc28j60_h
+
+/*
+ * SPI Commands
+ *
+ * Bits 7-5: Command
+ * Bits 4-0: Register
+ */
+#define CMD_RCR(x)	(0x00+((x)&0x1f))	/* Read Control Register */
+#define CMD_RBM		0x3a			/* Read Buffer Memory */
+#define CMD_WCR(x)	(0x40+((x)&0x1f))	/* Write Control Register */
+#define CMD_WBM		0x7a			/* Write Buffer Memory */
+#define CMD_BFS(x)	(0x80+((x)&0x1f))	/* Bit Field Set */
+#define CMD_BFC(x)	(0xa0+((x)&0x1f))	/* Bit Field Clear */
+#define CMD_SRC		0xff			/* System Reset Command */
+
+/* NEW: encode (bank number+1) in upper byte */
+
+/* Common Control Registers accessible in all Banks */
+#define CTL_REG_EIE		0x01B
+#define CTL_REG_EIR		0x01C
+#define CTL_REG_ESTAT		0x01D
+#define CTL_REG_ECON2		0x01E
+#define CTL_REG_ECON1		0x01F
+
+/* Control Registers accessible in Bank 0 */
+#define CTL_REG_ERDPTL		0x100
+#define CTL_REG_ERDPTH		0x101
+#define CTL_REG_EWRPTL		0x102
+#define CTL_REG_EWRPTH		0x103
+#define CTL_REG_ETXSTL		0x104
+#define CTL_REG_ETXSTH		0x105
+#define CTL_REG_ETXNDL		0x106
+#define CTL_REG_ETXNDH		0x107
+#define CTL_REG_ERXSTL		0x108
+#define CTL_REG_ERXSTH		0x109
+#define CTL_REG_ERXNDL		0x10A
+#define CTL_REG_ERXNDH		0x10B
+#define CTL_REG_ERXRDPTL	0x10C
+#define CTL_REG_ERXRDPTH	0x10D
+#define CTL_REG_ERXWRPTL	0x10E
+#define CTL_REG_ERXWRPTH	0x10F
+#define CTL_REG_EDMASTL		0x110
+#define CTL_REG_EDMASTH		0x111
+#define CTL_REG_EDMANDL		0x112
+#define CTL_REG_EDMANDH		0x113
+#define CTL_REG_EDMADSTL	0x114
+#define CTL_REG_EDMADSTH	0x115
+#define CTL_REG_EDMACSL		0x116
+#define CTL_REG_EDMACSH		0x117
+
+/* Control Registers accessible in Bank 1 */
+#define CTL_REG_EHT0		0x200
+#define CTL_REG_EHT1		0x201
+#define CTL_REG_EHT2		0x202
+#define CTL_REG_EHT3		0x203
+#define CTL_REG_EHT4		0x204
+#define CTL_REG_EHT5		0x205
+#define CTL_REG_EHT6		0x206
+#define CTL_REG_EHT7		0x207
+#define CTL_REG_EPMM0		0x208
+#define CTL_REG_EPMM1		0x209
+#define CTL_REG_EPMM2		0x20A
+#define CTL_REG_EPMM3		0x20B
+#define CTL_REG_EPMM4		0x20C
+#define CTL_REG_EPMM5		0x20D
+#define CTL_REG_EPMM6		0x20E
+#define CTL_REG_EPMM7		0x20F
+#define CTL_REG_EPMCSL		0x210
+#define CTL_REG_EPMCSH		0x211
+#define CTL_REG_EPMOL		0x214
+#define CTL_REG_EPMOH		0x215
+#define CTL_REG_EWOLIE		0x216
+#define CTL_REG_EWOLIR		0x217
+#define CTL_REG_ERXFCON		0x218
+#define CTL_REG_EPKTCNT		0x219
+
+/* Control Registers accessible in Bank 2 */
+#define CTL_REG_MACON1		0x300
+#define CTL_REG_MACON2		0x301
+#define CTL_REG_MACON3		0x302
+#define CTL_REG_MACON4		0x303
+#define CTL_REG_MABBIPG		0x304
+#define CTL_REG_MAIPGL		0x306
+#define CTL_REG_MAIPGH		0x307
+#define CTL_REG_MACLCON1	0x308
+#define CTL_REG_MACLCON2	0x309
+#define CTL_REG_MAMXFLL		0x30A
+#define CTL_REG_MAMXFLH		0x30B
+#define CTL_REG_MAPHSUP		0x30D
+#define CTL_REG_MICON		0x311
+#define CTL_REG_MICMD		0x312
+#define CTL_REG_MIREGADR	0x314
+#define CTL_REG_MIWRL		0x316
+#define CTL_REG_MIWRH		0x317
+#define CTL_REG_MIRDL		0x318
+#define CTL_REG_MIRDH		0x319
+
+/* Control Registers accessible in Bank 3 */
+#define CTL_REG_MAADR1		0x400
+#define CTL_REG_MAADR0		0x401
+#define CTL_REG_MAADR3		0x402
+#define CTL_REG_MAADR2		0x403
+#define CTL_REG_MAADR5		0x404
+#define CTL_REG_MAADR4		0x405
+#define CTL_REG_EBSTSD		0x406
+#define CTL_REG_EBSTCON		0x407
+#define CTL_REG_EBSTCSL		0x408
+#define CTL_REG_EBSTCSH		0x409
+#define CTL_REG_MISTAT		0x40A
+#define CTL_REG_EREVID		0x412
+#define CTL_REG_ECOCON		0x415
+#define CTL_REG_EFLOCON		0x417
+#define CTL_REG_EPAUSL		0x418
+#define CTL_REG_EPAUSH		0x419
+
+/* PHY Register */
+#define PHY_REG_PHCON1		0x00
+#define PHY_REG_PHSTAT1		0x01
+#define PHY_REG_PHID1		0x02
+#define PHY_REG_PHID2		0x03
+#define PHY_REG_PHCON2		0x10
+#define PHY_REG_PHSTAT2		0x11
+#define PHY_REG_PHLCON		0x14
+
+/* Receive Filter Register (ERXFCON) bits */
+#define ENC_RFR_UCEN		0x80
+#define ENC_RFR_ANDOR		0x40
+#define ENC_RFR_CRCEN		0x20
+#define ENC_RFR_PMEN		0x10
+#define ENC_RFR_MPEN		0x08
+#define ENC_RFR_HTEN		0x04
+#define ENC_RFR_MCEN		0x02
+#define ENC_RFR_BCEN		0x01
+
+/* ECON1 Register Bits */
+#define ENC_ECON1_TXRST		0x80
+#define ENC_ECON1_RXRST		0x40
+#define ENC_ECON1_DMAST		0x20
+#define ENC_ECON1_CSUMEN	0x10
+#define ENC_ECON1_TXRTS		0x08
+#define ENC_ECON1_RXEN		0x04
+#define ENC_ECON1_BSEL1		0x02
+#define ENC_ECON1_BSEL0		0x01
+
+/* ECON2 Register Bits */
+#define ENC_ECON2_AUTOINC	0x80
+#define ENC_ECON2_PKTDEC	0x40
+#define ENC_ECON2_PWRSV		0x20
+#define ENC_ECON2_VRPS		0x08
+
+/* EIR Register Bits */
+#define ENC_EIR_PKTIF		0x40
+#define ENC_EIR_DMAIF		0x20
+#define ENC_EIR_LINKIF		0x10
+#define ENC_EIR_TXIF		0x08
+#define ENC_EIR_WOLIF		0x04
+#define ENC_EIR_TXERIF		0x02
+#define ENC_EIR_RXERIF		0x01
+
+/* ESTAT Register Bits */
+#define ENC_ESTAT_INT		0x80
+#define ENC_ESTAT_LATECOL	0x10
+#define ENC_ESTAT_RXBUSY	0x04
+#define ENC_ESTAT_TXABRT	0x02
+#define ENC_ESTAT_CLKRDY	0x01
+
+/* EIE Register Bits */
+#define ENC_EIE_INTIE		0x80
+#define ENC_EIE_PKTIE		0x40
+#define ENC_EIE_DMAIE		0x20
+#define ENC_EIE_LINKIE		0x10
+#define ENC_EIE_TXIE		0x08
+#define ENC_EIE_WOLIE		0x04
+#define ENC_EIE_TXERIE		0x02
+#define ENC_EIE_RXERIE		0x01
+
+/* MACON1 Register Bits */
+#define ENC_MACON1_LOOPBK	0x10
+#define ENC_MACON1_TXPAUS	0x08
+#define ENC_MACON1_RXPAUS	0x04
+#define ENC_MACON1_PASSALL	0x02
+#define ENC_MACON1_MARXEN	0x01
+
+/* MACON2 Register Bits */
+#define ENC_MACON2_MARST	0x80
+#define ENC_MACON2_RNDRST	0x40
+#define ENC_MACON2_MARXRST	0x08
+#define ENC_MACON2_RFUNRST	0x04
+#define ENC_MACON2_MATXRST	0x02
+#define ENC_MACON2_TFUNRST	0x01
+
+/* MACON3 Register Bits */
+#define ENC_MACON3_PADCFG2	0x80
+#define ENC_MACON3_PADCFG1	0x40
+#define ENC_MACON3_PADCFG0	0x20
+#define ENC_MACON3_TXCRCEN	0x10
+#define ENC_MACON3_PHDRLEN	0x08
+#define ENC_MACON3_HFRMEN	0x04
+#define ENC_MACON3_FRMLNEN	0x02
+#define ENC_MACON3_FULDPX	0x01
+
+/* MACON4 Register Bits */
+#define ENC_MACON4_DEFER	0x40
+
+/* MICMD Register Bits */
+#define ENC_MICMD_MIISCAN	0x02
+#define ENC_MICMD_MIIRD		0x01
+
+/* MISTAT Register Bits */
+#define ENC_MISTAT_NVALID	0x04
+#define ENC_MISTAT_SCAN		0x02
+#define ENC_MISTAT_BUSY		0x01
+
+/* PHID1 and PHID2 values */
+#define ENC_PHID1_VALUE		0x0083
+#define ENC_PHID2_VALUE		0x1400
+#define ENC_PHID2_MASK		0xFC00
+
+/* PHCON1 values */
+#define	ENC_PHCON1_PDPXMD	0x0100
+
+/* PHSTAT1 values */
+#define	ENC_PHSTAT1_LLSTAT	0x0004
+
+/* PHSTAT2 values */
+#define	ENC_PHSTAT2_LSTAT	0x0400
+#define	ENC_PHSTAT2_DPXSTAT	0x0200
+
+#endif
diff --git a/marvell/uboot/drivers/net/ep93xx_eth.c b/marvell/uboot/drivers/net/ep93xx_eth.c
new file mode 100644
index 0000000..1c09f10
--- /dev/null
+++ b/marvell/uboot/drivers/net/ep93xx_eth.c
@@ -0,0 +1,639 @@
+/*
+ * Cirrus Logic EP93xx ethernet MAC / MII driver.
+ *
+ * Copyright (C) 2010, 2009
+ * Matthias Kaehlcke <matthias@kaehlcke.net>
+ *
+ * Copyright (C) 2004, 2005
+ * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com>
+ *
+ * Based on the original eth.[ch] Cirrus Logic EP93xx Rev D. Ethernet Driver,
+ * which is
+ *
+ * (C) Copyright 2002 2003
+ * Adam Bezanson, Network Audio Technologies, Inc.
+ * <bezanson@netaudiotech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <command.h>
+#include <common.h>
+#include <asm/arch/ep93xx.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <linux/types.h>
+#include "ep93xx_eth.h"
+
+#define GET_PRIV(eth_dev)	((struct ep93xx_priv *)(eth_dev)->priv)
+#define GET_REGS(eth_dev)	(GET_PRIV(eth_dev)->regs)
+
+/* ep93xx_miiphy ops forward declarations */
+static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr,
+			unsigned char const reg, unsigned short * const value);
+static int ep93xx_miiphy_write(const char * const dev, unsigned char const addr,
+			unsigned char const reg, unsigned short const value);
+
+#if defined(EP93XX_MAC_DEBUG)
+/**
+ * Dump ep93xx_mac values to the terminal.
+ */
+static void dump_dev(struct eth_device *dev)
+{
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	int i;
+
+	printf("\ndump_dev()\n");
+	printf("  rx_dq.base	     %p\n", priv->rx_dq.base);
+	printf("  rx_dq.current	     %p\n", priv->rx_dq.current);
+	printf("  rx_dq.end	     %p\n", priv->rx_dq.end);
+	printf("  rx_sq.base	     %p\n", priv->rx_sq.base);
+	printf("  rx_sq.current	     %p\n", priv->rx_sq.current);
+	printf("  rx_sq.end	     %p\n", priv->rx_sq.end);
+
+	for (i = 0; i < NUMRXDESC; i++)
+		printf("  rx_buffer[%2.d]      %p\n", i, NetRxPackets[i]);
+
+	printf("  tx_dq.base	     %p\n", priv->tx_dq.base);
+	printf("  tx_dq.current	     %p\n", priv->tx_dq.current);
+	printf("  tx_dq.end	     %p\n", priv->tx_dq.end);
+	printf("  tx_sq.base	     %p\n", priv->tx_sq.base);
+	printf("  tx_sq.current	     %p\n", priv->tx_sq.current);
+	printf("  tx_sq.end	     %p\n", priv->tx_sq.end);
+}
+
+/**
+ * Dump all RX status queue entries to the terminal.
+ */
+static void dump_rx_status_queue(struct eth_device *dev)
+{
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	int i;
+
+	printf("\ndump_rx_status_queue()\n");
+	printf("  descriptor address	 word1		 word2\n");
+	for (i = 0; i < NUMRXDESC; i++) {
+		printf("  [ %p ]	     %08X	 %08X\n",
+			priv->rx_sq.base + i,
+			(priv->rx_sq.base + i)->word1,
+			(priv->rx_sq.base + i)->word2);
+	}
+}
+
+/**
+ * Dump all RX descriptor queue entries to the terminal.
+ */
+static void dump_rx_descriptor_queue(struct eth_device *dev)
+{
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	int i;
+
+	printf("\ndump_rx_descriptor_queue()\n");
+	printf("  descriptor address	 word1		 word2\n");
+	for (i = 0; i < NUMRXDESC; i++) {
+		printf("  [ %p ]	     %08X	 %08X\n",
+			priv->rx_dq.base + i,
+			(priv->rx_dq.base + i)->word1,
+			(priv->rx_dq.base + i)->word2);
+	}
+}
+
+/**
+ * Dump all TX descriptor queue entries to the terminal.
+ */
+static void dump_tx_descriptor_queue(struct eth_device *dev)
+{
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	int i;
+
+	printf("\ndump_tx_descriptor_queue()\n");
+	printf("  descriptor address	 word1		 word2\n");
+	for (i = 0; i < NUMTXDESC; i++) {
+		printf("  [ %p ]	     %08X	 %08X\n",
+			priv->tx_dq.base + i,
+			(priv->tx_dq.base + i)->word1,
+			(priv->tx_dq.base + i)->word2);
+	}
+}
+
+/**
+ * Dump all TX status queue entries to the terminal.
+ */
+static void dump_tx_status_queue(struct eth_device *dev)
+{
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	int i;
+
+	printf("\ndump_tx_status_queue()\n");
+	printf("  descriptor address	 word1\n");
+	for (i = 0; i < NUMTXDESC; i++) {
+		printf("  [ %p ]	     %08X\n",
+			priv->rx_sq.base + i,
+			(priv->rx_sq.base + i)->word1);
+	}
+}
+#else
+#define dump_dev(x)
+#define dump_rx_descriptor_queue(x)
+#define dump_rx_status_queue(x)
+#define dump_tx_descriptor_queue(x)
+#define dump_tx_status_queue(x)
+#endif	/* defined(EP93XX_MAC_DEBUG) */
+
+/**
+ * Reset the EP93xx MAC by twiddling the soft reset bit and spinning until
+ * it's cleared.
+ */
+static void ep93xx_mac_reset(struct eth_device *dev)
+{
+	struct mac_regs *mac = GET_REGS(dev);
+	uint32_t value;
+
+	debug("+ep93xx_mac_reset");
+
+	value = readl(&mac->selfctl);
+	value |= SELFCTL_RESET;
+	writel(value, &mac->selfctl);
+
+	while (readl(&mac->selfctl) & SELFCTL_RESET)
+		; /* noop */
+
+	debug("-ep93xx_mac_reset");
+}
+
+/* Eth device open */
+static int ep93xx_eth_open(struct eth_device *dev, bd_t *bd)
+{
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	struct mac_regs *mac = GET_REGS(dev);
+	uchar *mac_addr = dev->enetaddr;
+	int i;
+
+	debug("+ep93xx_eth_open");
+
+	/* Reset the MAC */
+	ep93xx_mac_reset(dev);
+
+	/* Reset the descriptor queues' current and end address values */
+	priv->tx_dq.current = priv->tx_dq.base;
+	priv->tx_dq.end = (priv->tx_dq.base + NUMTXDESC);
+
+	priv->tx_sq.current = priv->tx_sq.base;
+	priv->tx_sq.end = (priv->tx_sq.base + NUMTXDESC);
+
+	priv->rx_dq.current = priv->rx_dq.base;
+	priv->rx_dq.end = (priv->rx_dq.base + NUMRXDESC);
+
+	priv->rx_sq.current = priv->rx_sq.base;
+	priv->rx_sq.end = (priv->rx_sq.base + NUMRXDESC);
+
+	/*
+	 * Set the transmit descriptor and status queues' base address,
+	 * current address, and length registers.  Set the maximum frame
+	 * length and threshold. Enable the transmit descriptor processor.
+	 */
+	writel((uint32_t)priv->tx_dq.base, &mac->txdq.badd);
+	writel((uint32_t)priv->tx_dq.base, &mac->txdq.curadd);
+	writel(sizeof(struct tx_descriptor) * NUMTXDESC, &mac->txdq.blen);
+
+	writel((uint32_t)priv->tx_sq.base, &mac->txstsq.badd);
+	writel((uint32_t)priv->tx_sq.base, &mac->txstsq.curadd);
+	writel(sizeof(struct tx_status) * NUMTXDESC, &mac->txstsq.blen);
+
+	writel(0x00040000, &mac->txdthrshld);
+	writel(0x00040000, &mac->txststhrshld);
+
+	writel((TXSTARTMAX << 0) | (PKTSIZE_ALIGN << 16), &mac->maxfrmlen);
+	writel(BMCTL_TXEN, &mac->bmctl);
+
+	/*
+	 * Set the receive descriptor and status queues' base address,
+	 * current address, and length registers.  Enable the receive
+	 * descriptor processor.
+	 */
+	writel((uint32_t)priv->rx_dq.base, &mac->rxdq.badd);
+	writel((uint32_t)priv->rx_dq.base, &mac->rxdq.curadd);
+	writel(sizeof(struct rx_descriptor) * NUMRXDESC, &mac->rxdq.blen);
+
+	writel((uint32_t)priv->rx_sq.base, &mac->rxstsq.badd);
+	writel((uint32_t)priv->rx_sq.base, &mac->rxstsq.curadd);
+	writel(sizeof(struct rx_status) * NUMRXDESC, &mac->rxstsq.blen);
+
+	writel(0x00040000, &mac->rxdthrshld);
+
+	writel(BMCTL_RXEN, &mac->bmctl);
+
+	writel(0x00040000, &mac->rxststhrshld);
+
+	/* Wait until the receive descriptor processor is active */
+	while (!(readl(&mac->bmsts) & BMSTS_RXACT))
+		; /* noop */
+
+	/*
+	 * Initialize the RX descriptor queue. Clear the TX descriptor queue.
+	 * Clear the RX and TX status queues. Enqueue the RX descriptor and
+	 * status entries to the MAC.
+	 */
+	for (i = 0; i < NUMRXDESC; i++) {
+		/* set buffer address */
+		(priv->rx_dq.base + i)->word1 = (uint32_t)NetRxPackets[i];
+
+		/* set buffer length, clear buffer index and NSOF */
+		(priv->rx_dq.base + i)->word2 = PKTSIZE_ALIGN;
+	}
+
+	memset(priv->tx_dq.base, 0,
+		(sizeof(struct tx_descriptor) * NUMTXDESC));
+	memset(priv->rx_sq.base, 0,
+		(sizeof(struct rx_status) * NUMRXDESC));
+	memset(priv->tx_sq.base, 0,
+		(sizeof(struct tx_status) * NUMTXDESC));
+
+	writel(NUMRXDESC, &mac->rxdqenq);
+	writel(NUMRXDESC, &mac->rxstsqenq);
+
+	/* Set the primary MAC address */
+	writel(AFP_IAPRIMARY, &mac->afp);
+	writel(mac_addr[0] | (mac_addr[1] << 8) |
+		(mac_addr[2] << 16) | (mac_addr[3] << 24),
+		&mac->indad);
+	writel(mac_addr[4] | (mac_addr[5] << 8), &mac->indad_upper);
+
+	/* Turn on RX and TX */
+	writel(RXCTL_IA0 | RXCTL_BA | RXCTL_SRXON |
+		RXCTL_RCRCA | RXCTL_MA, &mac->rxctl);
+	writel(TXCTL_STXON, &mac->txctl);
+
+	/* Dump data structures if we're debugging */
+	dump_dev(dev);
+	dump_rx_descriptor_queue(dev);
+	dump_rx_status_queue(dev);
+	dump_tx_descriptor_queue(dev);
+	dump_tx_status_queue(dev);
+
+	debug("-ep93xx_eth_open");
+
+	return 1;
+}
+
+/**
+ * Halt EP93xx MAC transmit and receive by clearing the TxCTL and RxCTL
+ * registers.
+ */
+static void ep93xx_eth_close(struct eth_device *dev)
+{
+	struct mac_regs *mac = GET_REGS(dev);
+
+	debug("+ep93xx_eth_close");
+
+	writel(0x00000000, &mac->rxctl);
+	writel(0x00000000, &mac->txctl);
+
+	debug("-ep93xx_eth_close");
+}
+
+/**
+ * Copy a frame of data from the MAC into the protocol layer for further
+ * processing.
+ */
+static int ep93xx_eth_rcv_packet(struct eth_device *dev)
+{
+	struct mac_regs *mac = GET_REGS(dev);
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	int len = -1;
+
+	debug("+ep93xx_eth_rcv_packet");
+
+	if (RX_STATUS_RFP(priv->rx_sq.current)) {
+		if (RX_STATUS_RWE(priv->rx_sq.current)) {
+			/*
+			 * We have a good frame. Extract the frame's length
+			 * from the current rx_status_queue entry, and copy
+			 * the frame's data into NetRxPackets[] of the
+			 * protocol stack. We track the total number of
+			 * bytes in the frame (nbytes_frame) which will be
+			 * used when we pass the data off to the protocol
+			 * layer via NetReceive().
+			 */
+			len = RX_STATUS_FRAME_LEN(priv->rx_sq.current);
+
+			NetReceive((uchar *)priv->rx_dq.current->word1,	len);
+
+			debug("reporting %d bytes...\n", len);
+		} else {
+			/* Do we have an erroneous packet? */
+			error("packet rx error, status %08X %08X",
+				priv->rx_sq.current->word1,
+				priv->rx_sq.current->word2);
+			dump_rx_descriptor_queue(dev);
+			dump_rx_status_queue(dev);
+		}
+
+		/*
+		 * Clear the associated status queue entry, and
+		 * increment our current pointers to the next RX
+		 * descriptor and status queue entries (making sure
+		 * we wrap properly).
+		 */
+		memset((void *)priv->rx_sq.current, 0,
+			sizeof(struct rx_status));
+
+		priv->rx_sq.current++;
+		if (priv->rx_sq.current >= priv->rx_sq.end)
+			priv->rx_sq.current = priv->rx_sq.base;
+
+		priv->rx_dq.current++;
+		if (priv->rx_dq.current >= priv->rx_dq.end)
+			priv->rx_dq.current = priv->rx_dq.base;
+
+		/*
+		 * Finally, return the RX descriptor and status entries
+		 * back to the MAC engine, and loop again, checking for
+		 * more descriptors to process.
+		 */
+		writel(1, &mac->rxdqenq);
+		writel(1, &mac->rxstsqenq);
+	} else {
+		len = 0;
+	}
+
+	debug("-ep93xx_eth_rcv_packet %d", len);
+	return len;
+}
+
+/**
+ * Send a block of data via ethernet.
+ */
+static int ep93xx_eth_send_packet(struct eth_device *dev,
+				void * const packet, int const length)
+{
+	struct mac_regs *mac = GET_REGS(dev);
+	struct ep93xx_priv *priv = GET_PRIV(dev);
+	int ret = -1;
+
+	debug("+ep93xx_eth_send_packet");
+
+	/* Parameter check */
+	BUG_ON(packet == NULL);
+
+	/*
+	 * Initialize the TX descriptor queue with the new packet's info.
+	 * Clear the associated status queue entry. Enqueue the packet
+	 * to the MAC for transmission.
+	 */
+
+	/* set buffer address */
+	priv->tx_dq.current->word1 = (uint32_t)packet;
+
+	/* set buffer length and EOF bit */
+	priv->tx_dq.current->word2 = length | TX_DESC_EOF;
+
+	/* clear tx status */
+	priv->tx_sq.current->word1 = 0;
+
+	/* enqueue the TX descriptor */
+	writel(1, &mac->txdqenq);
+
+	/* wait for the frame to become processed */
+	while (!TX_STATUS_TXFP(priv->tx_sq.current))
+		; /* noop */
+
+	if (!TX_STATUS_TXWE(priv->tx_sq.current)) {
+		error("packet tx error, status %08X",
+			priv->tx_sq.current->word1);
+		dump_tx_descriptor_queue(dev);
+		dump_tx_status_queue(dev);
+
+		/* TODO: Add better error handling? */
+		goto eth_send_out;
+	}
+
+	ret = 0;
+	/* Fall through */
+
+eth_send_out:
+	debug("-ep93xx_eth_send_packet %d", ret);
+	return ret;
+}
+
+#if defined(CONFIG_MII)
+int ep93xx_miiphy_initialize(bd_t * const bd)
+{
+	miiphy_register("ep93xx_eth0", ep93xx_miiphy_read, ep93xx_miiphy_write);
+	return 0;
+}
+#endif
+
+/**
+ * Initialize the EP93xx MAC.  The MAC hardware is reset.  Buffers are
+ * allocated, if necessary, for the TX and RX descriptor and status queues,
+ * as well as for received packets.  The EP93XX MAC hardware is initialized.
+ * Transmit and receive operations are enabled.
+ */
+int ep93xx_eth_initialize(u8 dev_num, int base_addr)
+{
+	int ret = -1;
+	struct eth_device *dev;
+	struct ep93xx_priv *priv;
+
+	debug("+ep93xx_eth_initialize");
+
+	priv = malloc(sizeof(*priv));
+	if (!priv) {
+		error("malloc() failed");
+		goto eth_init_failed_0;
+	}
+	memset(priv, 0, sizeof(*priv));
+
+	priv->regs = (struct mac_regs *)base_addr;
+
+	priv->tx_dq.base = calloc(NUMTXDESC,
+				sizeof(struct tx_descriptor));
+	if (priv->tx_dq.base == NULL) {
+		error("calloc() failed");
+		goto eth_init_failed_1;
+	}
+
+	priv->tx_sq.base = calloc(NUMTXDESC,
+				sizeof(struct tx_status));
+	if (priv->tx_sq.base == NULL) {
+		error("calloc() failed");
+		goto eth_init_failed_2;
+	}
+
+	priv->rx_dq.base = calloc(NUMRXDESC,
+				sizeof(struct rx_descriptor));
+	if (priv->rx_dq.base == NULL) {
+		error("calloc() failed");
+		goto eth_init_failed_3;
+	}
+
+	priv->rx_sq.base = calloc(NUMRXDESC,
+				sizeof(struct rx_status));
+	if (priv->rx_sq.base == NULL) {
+		error("calloc() failed");
+		goto eth_init_failed_4;
+	}
+
+	dev = malloc(sizeof *dev);
+	if (dev == NULL) {
+		error("malloc() failed");
+		goto eth_init_failed_5;
+	}
+	memset(dev, 0, sizeof *dev);
+
+	dev->iobase = base_addr;
+	dev->priv = priv;
+	dev->init = ep93xx_eth_open;
+	dev->halt = ep93xx_eth_close;
+	dev->send = ep93xx_eth_send_packet;
+	dev->recv = ep93xx_eth_rcv_packet;
+
+	sprintf(dev->name, "ep93xx_eth-%hu", dev_num);
+
+	eth_register(dev);
+
+	/* Done! */
+	ret = 1;
+	goto eth_init_done;
+
+eth_init_failed_5:
+	free(priv->rx_sq.base);
+	/* Fall through */
+
+eth_init_failed_4:
+	free(priv->rx_dq.base);
+	/* Fall through */
+
+eth_init_failed_3:
+	free(priv->tx_sq.base);
+	/* Fall through */
+
+eth_init_failed_2:
+	free(priv->tx_dq.base);
+	/* Fall through */
+
+eth_init_failed_1:
+	free(priv);
+	/* Fall through */
+
+eth_init_failed_0:
+	/* Fall through */
+
+eth_init_done:
+	debug("-ep93xx_eth_initialize %d", ret);
+	return ret;
+}
+
+#if defined(CONFIG_MII)
+
+/**
+ * Maximum MII address we support
+ */
+#define MII_ADDRESS_MAX			31
+
+/**
+ * Maximum MII register address we support
+ */
+#define MII_REGISTER_MAX		31
+
+/**
+ * Read a 16-bit value from an MII register.
+ */
+static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr,
+			unsigned char const reg, unsigned short * const value)
+{
+	struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
+	int ret = -1;
+	uint32_t self_ctl;
+
+	debug("+ep93xx_miiphy_read");
+
+	/* Parameter checks */
+	BUG_ON(dev == NULL);
+	BUG_ON(addr > MII_ADDRESS_MAX);
+	BUG_ON(reg > MII_REGISTER_MAX);
+	BUG_ON(value == NULL);
+
+	/*
+	 * Save the current SelfCTL register value.  Set MAC to suppress
+	 * preamble bits.  Wait for any previous MII command to complete
+	 * before issuing the new command.
+	 */
+	self_ctl = readl(&mac->selfctl);
+#if defined(CONFIG_MII_SUPPRESS_PREAMBLE)
+	writel(self_ctl & ~(1 << 8), &mac->selfctl);
+#endif	/* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */
+
+	while (readl(&mac->miists) & MIISTS_BUSY)
+		; /* noop */
+
+	/*
+	 * Issue the MII 'read' command.  Wait for the command to complete.
+	 * Read the MII data value.
+	 */
+	writel(MIICMD_OPCODE_READ | ((uint32_t)addr << 5) | (uint32_t)reg,
+		&mac->miicmd);
+	while (readl(&mac->miists) & MIISTS_BUSY)
+		; /* noop */
+
+	*value = (unsigned short)readl(&mac->miidata);
+
+	/* Restore the saved SelfCTL value and return. */
+	writel(self_ctl, &mac->selfctl);
+
+	ret = 0;
+	/* Fall through */
+
+	debug("-ep93xx_miiphy_read");
+	return ret;
+}
+
+/**
+ * Write a 16-bit value to an MII register.
+ */
+static int ep93xx_miiphy_write(const char * const dev, unsigned char const addr,
+			unsigned char const reg, unsigned short const value)
+{
+	struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
+	int ret = -1;
+	uint32_t self_ctl;
+
+	debug("+ep93xx_miiphy_write");
+
+	/* Parameter checks */
+	BUG_ON(dev == NULL);
+	BUG_ON(addr > MII_ADDRESS_MAX);
+	BUG_ON(reg > MII_REGISTER_MAX);
+
+	/*
+	 * Save the current SelfCTL register value.  Set MAC to suppress
+	 * preamble bits.  Wait for any previous MII command to complete
+	 * before issuing the new command.
+	 */
+	self_ctl = readl(&mac->selfctl);
+#if defined(CONFIG_MII_SUPPRESS_PREAMBLE)
+	writel(self_ctl & ~(1 << 8), &mac->selfctl);
+#endif	/* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */
+
+	while (readl(&mac->miists) & MIISTS_BUSY)
+		; /* noop */
+
+	/* Issue the MII 'write' command.  Wait for the command to complete. */
+	writel((uint32_t)value, &mac->miidata);
+	writel(MIICMD_OPCODE_WRITE | ((uint32_t)addr << 5) | (uint32_t)reg,
+		&mac->miicmd);
+	while (readl(&mac->miists) & MIISTS_BUSY)
+		; /* noop */
+
+	/* Restore the saved SelfCTL value and return. */
+	writel(self_ctl, &mac->selfctl);
+
+	ret = 0;
+	/* Fall through */
+
+	debug("-ep93xx_miiphy_write");
+	return ret;
+}
+#endif	/* defined(CONFIG_MII) */
diff --git a/marvell/uboot/drivers/net/ep93xx_eth.h b/marvell/uboot/drivers/net/ep93xx_eth.h
new file mode 100644
index 0000000..e6c949f
--- /dev/null
+++ b/marvell/uboot/drivers/net/ep93xx_eth.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
+ *
+ * Copyright (C) 2004, 2005
+ * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _EP93XX_ETH_H
+#define _EP93XX_ETH_H
+
+#include <net.h>
+
+/**
+ * #define this to dump device status and queue info during initialization and
+ * following errors.
+ */
+#undef EP93XX_MAC_DEBUG
+
+/**
+ * Number of descriptor and status entries in our RX queues.
+ * It must be power of 2 !
+ */
+#define NUMRXDESC		PKTBUFSRX
+
+/**
+ * Number of descriptor and status entries in our TX queues.
+ */
+#define NUMTXDESC		1
+
+/**
+ * 944 = (1024 - 64) - 16, Fifo size - Minframesize - 16 (Chip FACT)
+ */
+#define TXSTARTMAX		944
+
+/**
+ * Receive descriptor queue entry
+ */
+struct rx_descriptor {
+	uint32_t word1;
+	uint32_t word2;
+};
+
+/**
+ * Receive status queue entry
+ */
+struct rx_status {
+	uint32_t word1;
+	uint32_t word2;
+};
+
+#define RX_STATUS_RWE(rx_status) ((rx_status->word1 >> 30) & 0x01)
+#define RX_STATUS_RFP(rx_status) ((rx_status->word1 >> 31) & 0x01)
+#define RX_STATUS_FRAME_LEN(rx_status) (rx_status->word2 & 0xFFFF)
+
+/**
+ * Transmit descriptor queue entry
+ */
+struct tx_descriptor {
+	uint32_t word1;
+	uint32_t word2;
+};
+
+#define TX_DESC_EOF (1 << 31)
+
+/**
+ * Transmit status queue entry
+ */
+struct tx_status {
+	uint32_t word1;
+};
+
+#define TX_STATUS_TXWE(tx_status) (((tx_status)->word1 >> 30) & 0x01)
+#define TX_STATUS_TXFP(tx_status) (((tx_status)->word1 >> 31) & 0x01)
+
+/**
+ * Transmit descriptor queue
+ */
+struct tx_descriptor_queue {
+	struct tx_descriptor *base;
+	struct tx_descriptor *current;
+	struct tx_descriptor *end;
+};
+
+/**
+ * Transmit status queue
+ */
+struct tx_status_queue {
+	struct tx_status *base;
+	volatile struct tx_status *current;
+	struct tx_status *end;
+};
+
+/**
+ * Receive descriptor queue
+ */
+struct rx_descriptor_queue {
+	struct rx_descriptor *base;
+	struct rx_descriptor *current;
+	struct rx_descriptor *end;
+};
+
+/**
+ * Receive status queue
+ */
+struct rx_status_queue {
+	struct rx_status *base;
+	volatile struct rx_status *current;
+	struct rx_status *end;
+};
+
+/**
+ * EP93xx MAC private data structure
+ */
+struct ep93xx_priv {
+	struct rx_descriptor_queue	rx_dq;
+	struct rx_status_queue		rx_sq;
+	void				*rx_buffer[NUMRXDESC];
+
+	struct tx_descriptor_queue	tx_dq;
+	struct tx_status_queue		tx_sq;
+
+	struct mac_regs			*regs;
+};
+
+#endif
diff --git a/marvell/uboot/drivers/net/ethoc.c b/marvell/uboot/drivers/net/ethoc.c
new file mode 100644
index 0000000..af06d4f
--- /dev/null
+++ b/marvell/uboot/drivers/net/ethoc.c
@@ -0,0 +1,511 @@
+/*
+ * Opencore 10/100 ethernet mac driver
+ *
+ * Copyright (C) 2007-2008 Avionic Design Development GmbH
+ * Copyright (C) 2008-2009 Avionic Design GmbH
+ *   Thierry Reding <thierry.reding@avionic-design.de>
+ * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <net.h>
+#include <miiphy.h>
+#include <asm/io.h>
+#include <asm/cache.h>
+
+/* register offsets */
+#define	MODER		0x00
+#define	INT_SOURCE	0x04
+#define	INT_MASK	0x08
+#define	IPGT		0x0c
+#define	IPGR1		0x10
+#define	IPGR2		0x14
+#define	PACKETLEN	0x18
+#define	COLLCONF	0x1c
+#define	TX_BD_NUM	0x20
+#define	CTRLMODER	0x24
+#define	MIIMODER	0x28
+#define	MIICOMMAND	0x2c
+#define	MIIADDRESS	0x30
+#define	MIITX_DATA	0x34
+#define	MIIRX_DATA	0x38
+#define	MIISTATUS	0x3c
+#define	MAC_ADDR0	0x40
+#define	MAC_ADDR1	0x44
+#define	ETH_HASH0	0x48
+#define	ETH_HASH1	0x4c
+#define	ETH_TXCTRL	0x50
+
+/* mode register */
+#define	MODER_RXEN	(1 <<  0)	/* receive enable */
+#define	MODER_TXEN	(1 <<  1)	/* transmit enable */
+#define	MODER_NOPRE	(1 <<  2)	/* no preamble */
+#define	MODER_BRO	(1 <<  3)	/* broadcast address */
+#define	MODER_IAM	(1 <<  4)	/* individual address mode */
+#define	MODER_PRO	(1 <<  5)	/* promiscuous mode */
+#define	MODER_IFG	(1 <<  6)	/* interframe gap for incoming frames */
+#define	MODER_LOOP	(1 <<  7)	/* loopback */
+#define	MODER_NBO	(1 <<  8)	/* no back-off */
+#define	MODER_EDE	(1 <<  9)	/* excess defer enable */
+#define	MODER_FULLD	(1 << 10)	/* full duplex */
+#define	MODER_RESET	(1 << 11)	/* FIXME: reset (undocumented) */
+#define	MODER_DCRC	(1 << 12)	/* delayed CRC enable */
+#define	MODER_CRC	(1 << 13)	/* CRC enable */
+#define	MODER_HUGE	(1 << 14)	/* huge packets enable */
+#define	MODER_PAD	(1 << 15)	/* padding enabled */
+#define	MODER_RSM	(1 << 16)	/* receive small packets */
+
+/* interrupt source and mask registers */
+#define	INT_MASK_TXF	(1 << 0)	/* transmit frame */
+#define	INT_MASK_TXE	(1 << 1)	/* transmit error */
+#define	INT_MASK_RXF	(1 << 2)	/* receive frame */
+#define	INT_MASK_RXE	(1 << 3)	/* receive error */
+#define	INT_MASK_BUSY	(1 << 4)
+#define	INT_MASK_TXC	(1 << 5)	/* transmit control frame */
+#define	INT_MASK_RXC	(1 << 6)	/* receive control frame */
+
+#define	INT_MASK_TX	(INT_MASK_TXF | INT_MASK_TXE)
+#define	INT_MASK_RX	(INT_MASK_RXF | INT_MASK_RXE)
+
+#define	INT_MASK_ALL ( \
+		INT_MASK_TXF | INT_MASK_TXE | \
+		INT_MASK_RXF | INT_MASK_RXE | \
+		INT_MASK_TXC | INT_MASK_RXC | \
+		INT_MASK_BUSY \
+	)
+
+/* packet length register */
+#define	PACKETLEN_MIN(min)		(((min) & 0xffff) << 16)
+#define	PACKETLEN_MAX(max)		(((max) & 0xffff) <<  0)
+#define	PACKETLEN_MIN_MAX(min, max)	(PACKETLEN_MIN(min) | \
+					PACKETLEN_MAX(max))
+
+/* transmit buffer number register */
+#define	TX_BD_NUM_VAL(x)	(((x) <= 0x80) ? (x) : 0x80)
+
+/* control module mode register */
+#define	CTRLMODER_PASSALL	(1 << 0)	/* pass all receive frames */
+#define	CTRLMODER_RXFLOW	(1 << 1)	/* receive control flow */
+#define	CTRLMODER_TXFLOW	(1 << 2)	/* transmit control flow */
+
+/* MII mode register */
+#define	MIIMODER_CLKDIV(x)	((x) & 0xfe)	/* needs to be an even number */
+#define	MIIMODER_NOPRE		(1 << 8)	/* no preamble */
+
+/* MII command register */
+#define	MIICOMMAND_SCAN		(1 << 0)	/* scan status */
+#define	MIICOMMAND_READ		(1 << 1)	/* read status */
+#define	MIICOMMAND_WRITE	(1 << 2)	/* write control data */
+
+/* MII address register */
+#define	MIIADDRESS_FIAD(x)		(((x) & 0x1f) << 0)
+#define	MIIADDRESS_RGAD(x)		(((x) & 0x1f) << 8)
+#define	MIIADDRESS_ADDR(phy, reg)	(MIIADDRESS_FIAD(phy) | \
+					MIIADDRESS_RGAD(reg))
+
+/* MII transmit data register */
+#define	MIITX_DATA_VAL(x)	((x) & 0xffff)
+
+/* MII receive data register */
+#define	MIIRX_DATA_VAL(x)	((x) & 0xffff)
+
+/* MII status register */
+#define	MIISTATUS_LINKFAIL	(1 << 0)
+#define	MIISTATUS_BUSY		(1 << 1)
+#define	MIISTATUS_INVALID	(1 << 2)
+
+/* TX buffer descriptor */
+#define	TX_BD_CS		(1 <<  0)	/* carrier sense lost */
+#define	TX_BD_DF		(1 <<  1)	/* defer indication */
+#define	TX_BD_LC		(1 <<  2)	/* late collision */
+#define	TX_BD_RL		(1 <<  3)	/* retransmission limit */
+#define	TX_BD_RETRY_MASK	(0x00f0)
+#define	TX_BD_RETRY(x)		(((x) & 0x00f0) >>  4)
+#define	TX_BD_UR		(1 <<  8)	/* transmitter underrun */
+#define	TX_BD_CRC		(1 << 11)	/* TX CRC enable */
+#define	TX_BD_PAD		(1 << 12)	/* pad enable */
+#define	TX_BD_WRAP		(1 << 13)
+#define	TX_BD_IRQ		(1 << 14)	/* interrupt request enable */
+#define	TX_BD_READY		(1 << 15)	/* TX buffer ready */
+#define	TX_BD_LEN(x)		(((x) & 0xffff) << 16)
+#define	TX_BD_LEN_MASK		(0xffff << 16)
+
+#define	TX_BD_STATS		(TX_BD_CS | TX_BD_DF | TX_BD_LC | \
+				TX_BD_RL | TX_BD_RETRY_MASK | TX_BD_UR)
+
+/* RX buffer descriptor */
+#define	RX_BD_LC	(1 <<  0)	/* late collision */
+#define	RX_BD_CRC	(1 <<  1)	/* RX CRC error */
+#define	RX_BD_SF	(1 <<  2)	/* short frame */
+#define	RX_BD_TL	(1 <<  3)	/* too long */
+#define	RX_BD_DN	(1 <<  4)	/* dribble nibble */
+#define	RX_BD_IS	(1 <<  5)	/* invalid symbol */
+#define	RX_BD_OR	(1 <<  6)	/* receiver overrun */
+#define	RX_BD_MISS	(1 <<  7)
+#define	RX_BD_CF	(1 <<  8)	/* control frame */
+#define	RX_BD_WRAP	(1 << 13)
+#define	RX_BD_IRQ	(1 << 14)	/* interrupt request enable */
+#define	RX_BD_EMPTY	(1 << 15)
+#define	RX_BD_LEN(x)	(((x) & 0xffff) << 16)
+
+#define	RX_BD_STATS	(RX_BD_LC | RX_BD_CRC | RX_BD_SF | RX_BD_TL | \
+			RX_BD_DN | RX_BD_IS | RX_BD_OR | RX_BD_MISS)
+
+#define	ETHOC_BUFSIZ		1536
+#define	ETHOC_ZLEN		64
+#define	ETHOC_BD_BASE		0x400
+#define	ETHOC_TIMEOUT		(HZ / 2)
+#define	ETHOC_MII_TIMEOUT	(1 + (HZ / 5))
+
+/**
+ * struct ethoc - driver-private device structure
+ * @num_tx:	number of send buffers
+ * @cur_tx:	last send buffer written
+ * @dty_tx:	last buffer actually sent
+ * @num_rx:	number of receive buffers
+ * @cur_rx:	current receive buffer
+ */
+struct ethoc {
+	u32 num_tx;
+	u32 cur_tx;
+	u32 dty_tx;
+	u32 num_rx;
+	u32 cur_rx;
+};
+
+/**
+ * struct ethoc_bd - buffer descriptor
+ * @stat:	buffer statistics
+ * @addr:	physical memory address
+ */
+struct ethoc_bd {
+	u32 stat;
+	u32 addr;
+};
+
+static inline u32 ethoc_read(struct eth_device *dev, loff_t offset)
+{
+	return readl(dev->iobase + offset);
+}
+
+static inline void ethoc_write(struct eth_device *dev, loff_t offset, u32 data)
+{
+	writel(data, dev->iobase + offset);
+}
+
+static inline void ethoc_read_bd(struct eth_device *dev, int index,
+				 struct ethoc_bd *bd)
+{
+	loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
+	bd->stat = ethoc_read(dev, offset + 0);
+	bd->addr = ethoc_read(dev, offset + 4);
+}
+
+static inline void ethoc_write_bd(struct eth_device *dev, int index,
+				  const struct ethoc_bd *bd)
+{
+	loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
+	ethoc_write(dev, offset + 0, bd->stat);
+	ethoc_write(dev, offset + 4, bd->addr);
+}
+
+static int ethoc_set_mac_address(struct eth_device *dev)
+{
+	u8 *mac = dev->enetaddr;
+
+	ethoc_write(dev, MAC_ADDR0, (mac[2] << 24) | (mac[3] << 16) |
+		    (mac[4] << 8) | (mac[5] << 0));
+	ethoc_write(dev, MAC_ADDR1, (mac[0] << 8) | (mac[1] << 0));
+	return 0;
+}
+
+static inline void ethoc_ack_irq(struct eth_device *dev, u32 mask)
+{
+	ethoc_write(dev, INT_SOURCE, mask);
+}
+
+static inline void ethoc_enable_rx_and_tx(struct eth_device *dev)
+{
+	u32 mode = ethoc_read(dev, MODER);
+	mode |= MODER_RXEN | MODER_TXEN;
+	ethoc_write(dev, MODER, mode);
+}
+
+static inline void ethoc_disable_rx_and_tx(struct eth_device *dev)
+{
+	u32 mode = ethoc_read(dev, MODER);
+	mode &= ~(MODER_RXEN | MODER_TXEN);
+	ethoc_write(dev, MODER, mode);
+}
+
+static int ethoc_init_ring(struct eth_device *dev)
+{
+	struct ethoc *priv = (struct ethoc *)dev->priv;
+	struct ethoc_bd bd;
+	int i;
+
+	priv->cur_tx = 0;
+	priv->dty_tx = 0;
+	priv->cur_rx = 0;
+
+	/* setup transmission buffers */
+	bd.stat = TX_BD_IRQ | TX_BD_CRC;
+
+	for (i = 0; i < priv->num_tx; i++) {
+		if (i == priv->num_tx - 1)
+			bd.stat |= TX_BD_WRAP;
+
+		ethoc_write_bd(dev, i, &bd);
+	}
+
+	bd.stat = RX_BD_EMPTY | RX_BD_IRQ;
+
+	for (i = 0; i < priv->num_rx; i++) {
+		bd.addr = (u32)NetRxPackets[i];
+		if (i == priv->num_rx - 1)
+			bd.stat |= RX_BD_WRAP;
+
+		flush_dcache_range(bd.addr, bd.addr + PKTSIZE_ALIGN);
+		ethoc_write_bd(dev, priv->num_tx + i, &bd);
+	}
+
+	return 0;
+}
+
+static int ethoc_reset(struct eth_device *dev)
+{
+	u32 mode;
+
+	/* TODO: reset controller? */
+
+	ethoc_disable_rx_and_tx(dev);
+
+	/* TODO: setup registers */
+
+	/* enable FCS generation and automatic padding */
+	mode = ethoc_read(dev, MODER);
+	mode |= MODER_CRC | MODER_PAD;
+	ethoc_write(dev, MODER, mode);
+
+	/* set full-duplex mode */
+	mode = ethoc_read(dev, MODER);
+	mode |= MODER_FULLD;
+	ethoc_write(dev, MODER, mode);
+	ethoc_write(dev, IPGT, 0x15);
+
+	ethoc_ack_irq(dev, INT_MASK_ALL);
+	ethoc_enable_rx_and_tx(dev);
+	return 0;
+}
+
+static int ethoc_init(struct eth_device *dev, bd_t * bd)
+{
+	struct ethoc *priv = (struct ethoc *)dev->priv;
+	printf("ethoc\n");
+
+	priv->num_tx = 1;
+	priv->num_rx = PKTBUFSRX;
+	ethoc_write(dev, TX_BD_NUM, priv->num_tx);
+	ethoc_init_ring(dev);
+	ethoc_reset(dev);
+
+	return 0;
+}
+
+static int ethoc_update_rx_stats(struct ethoc_bd *bd)
+{
+	int ret = 0;
+
+	if (bd->stat & RX_BD_TL) {
+		debug("ETHOC: " "RX: frame too long\n");
+		ret++;
+	}
+
+	if (bd->stat & RX_BD_SF) {
+		debug("ETHOC: " "RX: frame too short\n");
+		ret++;
+	}
+
+	if (bd->stat & RX_BD_DN)
+		debug("ETHOC: " "RX: dribble nibble\n");
+
+	if (bd->stat & RX_BD_CRC) {
+		debug("ETHOC: " "RX: wrong CRC\n");
+		ret++;
+	}
+
+	if (bd->stat & RX_BD_OR) {
+		debug("ETHOC: " "RX: overrun\n");
+		ret++;
+	}
+
+	if (bd->stat & RX_BD_LC) {
+		debug("ETHOC: " "RX: late collision\n");
+		ret++;
+	}
+
+	return ret;
+}
+
+static int ethoc_rx(struct eth_device *dev, int limit)
+{
+	struct ethoc *priv = (struct ethoc *)dev->priv;
+	int count;
+
+	for (count = 0; count < limit; ++count) {
+		u32 entry;
+		struct ethoc_bd bd;
+
+		entry = priv->num_tx + (priv->cur_rx % priv->num_rx);
+		ethoc_read_bd(dev, entry, &bd);
+		if (bd.stat & RX_BD_EMPTY)
+			break;
+
+		debug("%s(): RX buffer %d, %x received\n",
+		      __func__, priv->cur_rx, bd.stat);
+		if (ethoc_update_rx_stats(&bd) == 0) {
+			int size = bd.stat >> 16;
+			size -= 4;	/* strip the CRC */
+			NetReceive((void *)bd.addr, size);
+		}
+
+		/* clear the buffer descriptor so it can be reused */
+		flush_dcache_range(bd.addr, bd.addr + PKTSIZE_ALIGN);
+		bd.stat &= ~RX_BD_STATS;
+		bd.stat |= RX_BD_EMPTY;
+		ethoc_write_bd(dev, entry, &bd);
+		priv->cur_rx++;
+	}
+
+	return count;
+}
+
+static int ethoc_update_tx_stats(struct ethoc_bd *bd)
+{
+	if (bd->stat & TX_BD_LC)
+		debug("ETHOC: " "TX: late collision\n");
+
+	if (bd->stat & TX_BD_RL)
+		debug("ETHOC: " "TX: retransmit limit\n");
+
+	if (bd->stat & TX_BD_UR)
+		debug("ETHOC: " "TX: underrun\n");
+
+	if (bd->stat & TX_BD_CS)
+		debug("ETHOC: " "TX: carrier sense lost\n");
+
+	return 0;
+}
+
+static void ethoc_tx(struct eth_device *dev)
+{
+	struct ethoc *priv = (struct ethoc *)dev->priv;
+	u32 entry = priv->dty_tx % priv->num_tx;
+	struct ethoc_bd bd;
+
+	ethoc_read_bd(dev, entry, &bd);
+	if ((bd.stat & TX_BD_READY) == 0)
+		(void)ethoc_update_tx_stats(&bd);
+}
+
+static int ethoc_send(struct eth_device *dev, void *packet, int length)
+{
+	struct ethoc *priv = (struct ethoc *)dev->priv;
+	struct ethoc_bd bd;
+	u32 entry;
+	u32 pending;
+	int tmo;
+
+	entry = priv->cur_tx % priv->num_tx;
+	ethoc_read_bd(dev, entry, &bd);
+	if (unlikely(length < ETHOC_ZLEN))
+		bd.stat |= TX_BD_PAD;
+	else
+		bd.stat &= ~TX_BD_PAD;
+	bd.addr = (u32)packet;
+
+	flush_dcache_range(bd.addr, bd.addr + length);
+	bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK);
+	bd.stat |= TX_BD_LEN(length);
+	ethoc_write_bd(dev, entry, &bd);
+
+	/* start transmit */
+	bd.stat |= TX_BD_READY;
+	ethoc_write_bd(dev, entry, &bd);
+
+	/* wait for transfer to succeed */
+	tmo = get_timer(0) + 5 * CONFIG_SYS_HZ;
+	while (1) {
+		pending = ethoc_read(dev, INT_SOURCE);
+		ethoc_ack_irq(dev, pending & ~INT_MASK_RX);
+		if (pending & INT_MASK_BUSY)
+			debug("%s(): packet dropped\n", __func__);
+
+		if (pending & INT_MASK_TX) {
+			ethoc_tx(dev);
+			break;
+		}
+		if (get_timer(0) >= tmo) {
+			debug("%s(): timed out\n", __func__);
+			return -1;
+		}
+	}
+
+	debug("%s(): packet sent\n", __func__);
+	return 0;
+}
+
+static void ethoc_halt(struct eth_device *dev)
+{
+	ethoc_disable_rx_and_tx(dev);
+}
+
+static int ethoc_recv(struct eth_device *dev)
+{
+	u32 pending;
+
+	pending = ethoc_read(dev, INT_SOURCE);
+	ethoc_ack_irq(dev, pending);
+	if (pending & INT_MASK_BUSY)
+		debug("%s(): packet dropped\n", __func__);
+	if (pending & INT_MASK_RX) {
+		debug("%s(): rx irq\n", __func__);
+		ethoc_rx(dev, PKTBUFSRX);
+	}
+
+	return 0;
+}
+
+int ethoc_initialize(u8 dev_num, int base_addr)
+{
+	struct ethoc *priv;
+	struct eth_device *dev;
+
+	priv = malloc(sizeof(*priv));
+	if (!priv)
+		return 0;
+	dev = malloc(sizeof(*dev));
+	if (!dev) {
+		free(priv);
+		return 0;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->priv = priv;
+	dev->iobase = base_addr;
+	dev->init = ethoc_init;
+	dev->halt = ethoc_halt;
+	dev->send = ethoc_send;
+	dev->recv = ethoc_recv;
+	dev->write_hwaddr = ethoc_set_mac_address;
+	sprintf(dev->name, "%s-%hu", "ETHOC", dev_num);
+
+	eth_register(dev);
+	return 1;
+}
diff --git a/marvell/uboot/drivers/net/fec_mxc.c b/marvell/uboot/drivers/net/fec_mxc.c
new file mode 100644
index 0000000..3b2b995
--- /dev/null
+++ b/marvell/uboot/drivers/net/fec_mxc.c
@@ -0,0 +1,1098 @@
+/*
+ * (C) Copyright 2009 Ilya Yanok, Emcraft Systems Ltd <yanok@emcraft.com>
+ * (C) Copyright 2008,2009 Eric Jarrige <eric.jarrige@armadeus.org>
+ * (C) Copyright 2008 Armadeus Systems nc
+ * (C) Copyright 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ * (C) Copyright 2007 Pengutronix, Juergen Beisert <j.beisert@pengutronix.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <miiphy.h>
+#include "fec_mxc.h"
+
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <linux/compiler.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Timeout the transfer after 5 mS. This is usually a bit more, since
+ * the code in the tightloops this timeout is used in adds some overhead.
+ */
+#define FEC_XFER_TIMEOUT	5000
+
+#ifndef CONFIG_MII
+#error "CONFIG_MII has to be defined!"
+#endif
+
+#ifndef CONFIG_FEC_XCV_TYPE
+#define CONFIG_FEC_XCV_TYPE MII100
+#endif
+
+/*
+ * The i.MX28 operates with packets in big endian. We need to swap them before
+ * sending and after receiving.
+ */
+#ifdef CONFIG_MX28
+#define CONFIG_FEC_MXC_SWAP_PACKET
+#endif
+
+#define RXDESC_PER_CACHELINE (ARCH_DMA_MINALIGN/sizeof(struct fec_bd))
+
+/* Check various alignment issues at compile time */
+#if ((ARCH_DMA_MINALIGN < 16) || (ARCH_DMA_MINALIGN % 16 != 0))
+#error "ARCH_DMA_MINALIGN must be multiple of 16!"
+#endif
+
+#if ((PKTALIGN < ARCH_DMA_MINALIGN) || \
+	(PKTALIGN % ARCH_DMA_MINALIGN != 0))
+#error "PKTALIGN must be multiple of ARCH_DMA_MINALIGN!"
+#endif
+
+#undef DEBUG
+
+struct nbuf {
+	uint8_t data[1500];	/**< actual data */
+	int length;		/**< actual length */
+	int used;		/**< buffer in use or not */
+	uint8_t head[16];	/**< MAC header(6 + 6 + 2) + 2(aligned) */
+};
+
+#ifdef CONFIG_FEC_MXC_SWAP_PACKET
+static void swap_packet(uint32_t *packet, int length)
+{
+	int i;
+
+	for (i = 0; i < DIV_ROUND_UP(length, 4); i++)
+		packet[i] = __swab32(packet[i]);
+}
+#endif
+
+/*
+ * MII-interface related functions
+ */
+static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr,
+		uint8_t regAddr)
+{
+	uint32_t reg;		/* convenient holder for the PHY register */
+	uint32_t phy;		/* convenient holder for the PHY */
+	uint32_t start;
+	int val;
+
+	/*
+	 * reading from any PHY's register is done by properly
+	 * programming the FEC's MII data register.
+	 */
+	writel(FEC_IEVENT_MII, &eth->ievent);
+	reg = regAddr << FEC_MII_DATA_RA_SHIFT;
+	phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
+
+	writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA |
+			phy | reg, &eth->mii_data);
+
+	/*
+	 * wait for the related interrupt
+	 */
+	start = get_timer(0);
+	while (!(readl(&eth->ievent) & FEC_IEVENT_MII)) {
+		if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
+			printf("Read MDIO failed...\n");
+			return -1;
+		}
+	}
+
+	/*
+	 * clear mii interrupt bit
+	 */
+	writel(FEC_IEVENT_MII, &eth->ievent);
+
+	/*
+	 * it's now safe to read the PHY's register
+	 */
+	val = (unsigned short)readl(&eth->mii_data);
+	debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyAddr,
+			regAddr, val);
+	return val;
+}
+
+static void fec_mii_setspeed(struct ethernet_regs *eth)
+{
+	/*
+	 * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
+	 * and do not drop the Preamble.
+	 */
+	writel((((imx_get_fecclk() / 1000000) + 2) / 5) << 1,
+			&eth->mii_speed);
+	debug("%s: mii_speed %08x\n", __func__, readl(&eth->mii_speed));
+}
+
+static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr,
+		uint8_t regAddr, uint16_t data)
+{
+	uint32_t reg;		/* convenient holder for the PHY register */
+	uint32_t phy;		/* convenient holder for the PHY */
+	uint32_t start;
+
+	reg = regAddr << FEC_MII_DATA_RA_SHIFT;
+	phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
+
+	writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR |
+		FEC_MII_DATA_TA | phy | reg | data, &eth->mii_data);
+
+	/*
+	 * wait for the MII interrupt
+	 */
+	start = get_timer(0);
+	while (!(readl(&eth->ievent) & FEC_IEVENT_MII)) {
+		if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
+			printf("Write MDIO failed...\n");
+			return -1;
+		}
+	}
+
+	/*
+	 * clear MII interrupt bit
+	 */
+	writel(FEC_IEVENT_MII, &eth->ievent);
+	debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyAddr,
+			regAddr, data);
+
+	return 0;
+}
+
+int fec_phy_read(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr)
+{
+	return fec_mdio_read(bus->priv, phyAddr, regAddr);
+}
+
+int fec_phy_write(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr,
+		u16 data)
+{
+	return fec_mdio_write(bus->priv, phyAddr, regAddr, data);
+}
+
+#ifndef CONFIG_PHYLIB
+static int miiphy_restart_aneg(struct eth_device *dev)
+{
+	int ret = 0;
+#if !defined(CONFIG_FEC_MXC_NO_ANEG)
+	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+	struct ethernet_regs *eth = fec->bus->priv;
+
+	/*
+	 * Wake up from sleep if necessary
+	 * Reset PHY, then delay 300ns
+	 */
+#ifdef CONFIG_MX27
+	fec_mdio_write(eth, fec->phy_id, MII_DCOUNTER, 0x00FF);
+#endif
+	fec_mdio_write(eth, fec->phy_id, MII_BMCR, BMCR_RESET);
+	udelay(1000);
+
+	/*
+	 * Set the auto-negotiation advertisement register bits
+	 */
+	fec_mdio_write(eth, fec->phy_id, MII_ADVERTISE,
+			LPA_100FULL | LPA_100HALF | LPA_10FULL |
+			LPA_10HALF | PHY_ANLPAR_PSB_802_3);
+	fec_mdio_write(eth, fec->phy_id, MII_BMCR,
+			BMCR_ANENABLE | BMCR_ANRESTART);
+
+	if (fec->mii_postcall)
+		ret = fec->mii_postcall(fec->phy_id);
+
+#endif
+	return ret;
+}
+
+static int miiphy_wait_aneg(struct eth_device *dev)
+{
+	uint32_t start;
+	int status;
+	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+	struct ethernet_regs *eth = fec->bus->priv;
+
+	/*
+	 * Wait for AN completion
+	 */
+	start = get_timer(0);
+	do {
+		if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
+			printf("%s: Autonegotiation timeout\n", dev->name);
+			return -1;
+		}
+
+		status = fec_mdio_read(eth, fec->phy_id, MII_BMSR);
+		if (status < 0) {
+			printf("%s: Autonegotiation failed. status: %d\n",
+					dev->name, status);
+			return -1;
+		}
+	} while (!(status & BMSR_LSTATUS));
+
+	return 0;
+}
+#endif
+
+static int fec_rx_task_enable(struct fec_priv *fec)
+{
+	writel(FEC_R_DES_ACTIVE_RDAR, &fec->eth->r_des_active);
+	return 0;
+}
+
+static int fec_rx_task_disable(struct fec_priv *fec)
+{
+	return 0;
+}
+
+static int fec_tx_task_enable(struct fec_priv *fec)
+{
+	writel(FEC_X_DES_ACTIVE_TDAR, &fec->eth->x_des_active);
+	return 0;
+}
+
+static int fec_tx_task_disable(struct fec_priv *fec)
+{
+	return 0;
+}
+
+/**
+ * Initialize receive task's buffer descriptors
+ * @param[in] fec all we know about the device yet
+ * @param[in] count receive buffer count to be allocated
+ * @param[in] dsize desired size of each receive buffer
+ * @return 0 on success
+ *
+ * Init all RX descriptors to default values.
+ */
+static void fec_rbd_init(struct fec_priv *fec, int count, int dsize)
+{
+	uint32_t size;
+	uint8_t *data;
+	int i;
+
+	/*
+	 * Reload the RX descriptors with default values and wipe
+	 * the RX buffers.
+	 */
+	size = roundup(dsize, ARCH_DMA_MINALIGN);
+	for (i = 0; i < count; i++) {
+		data = (uint8_t *)fec->rbd_base[i].data_pointer;
+		memset(data, 0, dsize);
+		flush_dcache_range((uint32_t)data, (uint32_t)data + size);
+
+		fec->rbd_base[i].status = FEC_RBD_EMPTY;
+		fec->rbd_base[i].data_length = 0;
+	}
+
+	/* Mark the last RBD to close the ring. */
+	fec->rbd_base[i - 1].status = FEC_RBD_WRAP | FEC_RBD_EMPTY;
+	fec->rbd_index = 0;
+
+	flush_dcache_range((unsigned)fec->rbd_base,
+			   (unsigned)fec->rbd_base + size);
+}
+
+/**
+ * Initialize transmit task's buffer descriptors
+ * @param[in] fec all we know about the device yet
+ *
+ * Transmit buffers are created externally. We only have to init the BDs here.\n
+ * Note: There is a race condition in the hardware. When only one BD is in
+ * use it must be marked with the WRAP bit to use it for every transmitt.
+ * This bit in combination with the READY bit results into double transmit
+ * of each data buffer. It seems the state machine checks READY earlier then
+ * resetting it after the first transfer.
+ * Using two BDs solves this issue.
+ */
+static void fec_tbd_init(struct fec_priv *fec)
+{
+	unsigned addr = (unsigned)fec->tbd_base;
+	unsigned size = roundup(2 * sizeof(struct fec_bd),
+				ARCH_DMA_MINALIGN);
+
+	memset(fec->tbd_base, 0, size);
+	fec->tbd_base[0].status = 0;
+	fec->tbd_base[1].status = FEC_TBD_WRAP;
+	fec->tbd_index = 0;
+	flush_dcache_range(addr, addr + size);
+}
+
+/**
+ * Mark the given read buffer descriptor as free
+ * @param[in] last 1 if this is the last buffer descriptor in the chain, else 0
+ * @param[in] pRbd buffer descriptor to mark free again
+ */
+static void fec_rbd_clean(int last, struct fec_bd *pRbd)
+{
+	unsigned short flags = FEC_RBD_EMPTY;
+	if (last)
+		flags |= FEC_RBD_WRAP;
+	writew(flags, &pRbd->status);
+	writew(0, &pRbd->data_length);
+}
+
+static int fec_get_hwaddr(struct eth_device *dev, int dev_id,
+						unsigned char *mac)
+{
+	imx_get_mac_from_fuse(dev_id, mac);
+	return !is_valid_ether_addr(mac);
+}
+
+static int fec_set_hwaddr(struct eth_device *dev)
+{
+	uchar *mac = dev->enetaddr;
+	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+
+	writel(0, &fec->eth->iaddr1);
+	writel(0, &fec->eth->iaddr2);
+	writel(0, &fec->eth->gaddr1);
+	writel(0, &fec->eth->gaddr2);
+
+	/*
+	 * Set physical address
+	 */
+	writel((mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3],
+			&fec->eth->paddr1);
+	writel((mac[4] << 24) + (mac[5] << 16) + 0x8808, &fec->eth->paddr2);
+
+	return 0;
+}
+
+/*
+ * Do initial configuration of the FEC registers
+ */
+static void fec_reg_setup(struct fec_priv *fec)
+{
+	uint32_t rcntrl;
+
+	/*
+	 * Set interrupt mask register
+	 */
+	writel(0x00000000, &fec->eth->imask);
+
+	/*
+	 * Clear FEC-Lite interrupt event register(IEVENT)
+	 */
+	writel(0xffffffff, &fec->eth->ievent);
+
+
+	/*
+	 * Set FEC-Lite receive control register(R_CNTRL):
+	 */
+
+	/* Start with frame length = 1518, common for all modes. */
+	rcntrl = PKTSIZE << FEC_RCNTRL_MAX_FL_SHIFT;
+	if (fec->xcv_type != SEVENWIRE)		/* xMII modes */
+		rcntrl |= FEC_RCNTRL_FCE | FEC_RCNTRL_MII_MODE;
+	if (fec->xcv_type == RGMII)
+		rcntrl |= FEC_RCNTRL_RGMII;
+	else if (fec->xcv_type == RMII)
+		rcntrl |= FEC_RCNTRL_RMII;
+
+	writel(rcntrl, &fec->eth->r_cntrl);
+}
+
+/**
+ * Start the FEC engine
+ * @param[in] dev Our device to handle
+ */
+static int fec_open(struct eth_device *edev)
+{
+	struct fec_priv *fec = (struct fec_priv *)edev->priv;
+	int speed;
+	uint32_t addr, size;
+	int i;
+
+	debug("fec_open: fec_open(dev)\n");
+	/* full-duplex, heartbeat disabled */
+	writel(1 << 2, &fec->eth->x_cntrl);
+	fec->rbd_index = 0;
+
+	/* Invalidate all descriptors */
+	for (i = 0; i < FEC_RBD_NUM - 1; i++)
+		fec_rbd_clean(0, &fec->rbd_base[i]);
+	fec_rbd_clean(1, &fec->rbd_base[i]);
+
+	/* Flush the descriptors into RAM */
+	size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd),
+			ARCH_DMA_MINALIGN);
+	addr = (uint32_t)fec->rbd_base;
+	flush_dcache_range(addr, addr + size);
+
+#ifdef FEC_QUIRK_ENET_MAC
+	/* Enable ENET HW endian SWAP */
+	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_DBSWAP,
+		&fec->eth->ecntrl);
+	/* Enable ENET store and forward mode */
+	writel(readl(&fec->eth->x_wmrk) | FEC_X_WMRK_STRFWD,
+		&fec->eth->x_wmrk);
+#endif
+	/*
+	 * Enable FEC-Lite controller
+	 */
+	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_ETHER_EN,
+		&fec->eth->ecntrl);
+#if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL)
+	udelay(100);
+	/*
+	 * setup the MII gasket for RMII mode
+	 */
+
+	/* disable the gasket */
+	writew(0, &fec->eth->miigsk_enr);
+
+	/* wait for the gasket to be disabled */
+	while (readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY)
+		udelay(2);
+
+	/* configure gasket for RMII, 50 MHz, no loopback, and no echo */
+	writew(MIIGSK_CFGR_IF_MODE_RMII, &fec->eth->miigsk_cfgr);
+
+	/* re-enable the gasket */
+	writew(MIIGSK_ENR_EN, &fec->eth->miigsk_enr);
+
+	/* wait until MII gasket is ready */
+	int max_loops = 10;
+	while ((readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) == 0) {
+		if (--max_loops <= 0) {
+			printf("WAIT for MII Gasket ready timed out\n");
+			break;
+		}
+	}
+#endif
+
+#ifdef CONFIG_PHYLIB
+	{
+		/* Start up the PHY */
+		int ret = phy_startup(fec->phydev);
+
+		if (ret) {
+			printf("Could not initialize PHY %s\n",
+			       fec->phydev->dev->name);
+			return ret;
+		}
+		speed = fec->phydev->speed;
+	}
+#else
+	miiphy_wait_aneg(edev);
+	speed = miiphy_speed(edev->name, fec->phy_id);
+	miiphy_duplex(edev->name, fec->phy_id);
+#endif
+
+#ifdef FEC_QUIRK_ENET_MAC
+	{
+		u32 ecr = readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_SPEED;
+		u32 rcr = readl(&fec->eth->r_cntrl) & ~FEC_RCNTRL_RMII_10T;
+		if (speed == _1000BASET)
+			ecr |= FEC_ECNTRL_SPEED;
+		else if (speed != _100BASET)
+			rcr |= FEC_RCNTRL_RMII_10T;
+		writel(ecr, &fec->eth->ecntrl);
+		writel(rcr, &fec->eth->r_cntrl);
+	}
+#endif
+	debug("%s:Speed=%i\n", __func__, speed);
+
+	/*
+	 * Enable SmartDMA receive task
+	 */
+	fec_rx_task_enable(fec);
+
+	udelay(100000);
+	return 0;
+}
+
+static int fec_init(struct eth_device *dev, bd_t* bd)
+{
+	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+	uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop;
+	int i;
+
+	/* Initialize MAC address */
+	fec_set_hwaddr(dev);
+
+	/*
+	 * Setup transmit descriptors, there are two in total.
+	 */
+	fec_tbd_init(fec);
+
+	/* Setup receive descriptors. */
+	fec_rbd_init(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE);
+
+	fec_reg_setup(fec);
+
+	if (fec->xcv_type != SEVENWIRE)
+		fec_mii_setspeed(fec->bus->priv);
+
+	/*
+	 * Set Opcode/Pause Duration Register
+	 */
+	writel(0x00010020, &fec->eth->op_pause);	/* FIXME 0xffff0020; */
+	writel(0x2, &fec->eth->x_wmrk);
+	/*
+	 * Set multicast address filter
+	 */
+	writel(0x00000000, &fec->eth->gaddr1);
+	writel(0x00000000, &fec->eth->gaddr2);
+
+
+	/* clear MIB RAM */
+	for (i = mib_ptr; i <= mib_ptr + 0xfc; i += 4)
+		writel(0, i);
+
+	/* FIFO receive start register */
+	writel(0x520, &fec->eth->r_fstart);
+
+	/* size and address of each buffer */
+	writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr);
+	writel((uint32_t)fec->tbd_base, &fec->eth->etdsr);
+	writel((uint32_t)fec->rbd_base, &fec->eth->erdsr);
+
+#ifndef CONFIG_PHYLIB
+	if (fec->xcv_type != SEVENWIRE)
+		miiphy_restart_aneg(dev);
+#endif
+	fec_open(dev);
+	return 0;
+}
+
+/**
+ * Halt the FEC engine
+ * @param[in] dev Our device to handle
+ */
+static void fec_halt(struct eth_device *dev)
+{
+	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+	int counter = 0xffff;
+
+	/*
+	 * issue graceful stop command to the FEC transmitter if necessary
+	 */
+	writel(FEC_TCNTRL_GTS | readl(&fec->eth->x_cntrl),
+			&fec->eth->x_cntrl);
+
+	debug("eth_halt: wait for stop regs\n");
+	/*
+	 * wait for graceful stop to register
+	 */
+	while ((counter--) && (!(readl(&fec->eth->ievent) & FEC_IEVENT_GRA)))
+		udelay(1);
+
+	/*
+	 * Disable SmartDMA tasks
+	 */
+	fec_tx_task_disable(fec);
+	fec_rx_task_disable(fec);
+
+	/*
+	 * Disable the Ethernet Controller
+	 * Note: this will also reset the BD index counter!
+	 */
+	writel(readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_ETHER_EN,
+			&fec->eth->ecntrl);
+	fec->rbd_index = 0;
+	fec->tbd_index = 0;
+	debug("eth_halt: done\n");
+}
+
+/**
+ * Transmit one frame
+ * @param[in] dev Our ethernet device to handle
+ * @param[in] packet Pointer to the data to be transmitted
+ * @param[in] length Data count in bytes
+ * @return 0 on success
+ */
+static int fec_send(struct eth_device *dev, void *packet, int length)
+{
+	unsigned int status;
+	uint32_t size, end;
+	uint32_t addr;
+	int timeout = FEC_XFER_TIMEOUT;
+	int ret = 0;
+
+	/*
+	 * This routine transmits one frame.  This routine only accepts
+	 * 6-byte Ethernet addresses.
+	 */
+	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+
+	/*
+	 * Check for valid length of data.
+	 */
+	if ((length > 1500) || (length <= 0)) {
+		printf("Payload (%d) too large\n", length);
+		return -1;
+	}
+
+	/*
+	 * Setup the transmit buffer. We are always using the first buffer for
+	 * transmission, the second will be empty and only used to stop the DMA
+	 * engine. We also flush the packet to RAM here to avoid cache trouble.
+	 */
+#ifdef CONFIG_FEC_MXC_SWAP_PACKET
+	swap_packet((uint32_t *)packet, length);
+#endif
+
+	addr = (uint32_t)packet;
+	end = roundup(addr + length, ARCH_DMA_MINALIGN);
+	addr &= ~(ARCH_DMA_MINALIGN - 1);
+	flush_dcache_range(addr, end);
+
+	writew(length, &fec->tbd_base[fec->tbd_index].data_length);
+	writel(addr, &fec->tbd_base[fec->tbd_index].data_pointer);
+
+	/*
+	 * update BD's status now
+	 * This block:
+	 * - is always the last in a chain (means no chain)
+	 * - should transmitt the CRC
+	 * - might be the last BD in the list, so the address counter should
+	 *   wrap (-> keep the WRAP flag)
+	 */
+	status = readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_WRAP;
+	status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
+	writew(status, &fec->tbd_base[fec->tbd_index].status);
+
+	/*
+	 * Flush data cache. This code flushes both TX descriptors to RAM.
+	 * After this code, the descriptors will be safely in RAM and we
+	 * can start DMA.
+	 */
+	size = roundup(2 * sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
+	addr = (uint32_t)fec->tbd_base;
+	flush_dcache_range(addr, addr + size);
+
+	/*
+	 * Below we read the DMA descriptor's last four bytes back from the
+	 * DRAM. This is important in order to make sure that all WRITE
+	 * operations on the bus that were triggered by previous cache FLUSH
+	 * have completed.
+	 *
+	 * Otherwise, on MX28, it is possible to observe a corruption of the
+	 * DMA descriptors. Please refer to schematic "Figure 1-2" in MX28RM
+	 * for the bus structure of MX28. The scenario is as follows:
+	 *
+	 * 1) ARM core triggers a series of WRITEs on the AHB_ARB2 bus going
+	 *    to DRAM due to flush_dcache_range()
+	 * 2) ARM core writes the FEC registers via AHB_ARB2
+	 * 3) FEC DMA starts reading/writing from/to DRAM via AHB_ARB3
+	 *
+	 * Note that 2) does sometimes finish before 1) due to reordering of
+	 * WRITE accesses on the AHB bus, therefore triggering 3) before the
+	 * DMA descriptor is fully written into DRAM. This results in occasional
+	 * corruption of the DMA descriptor.
+	 */
+	readl(addr + size - 4);
+
+	/*
+	 * Enable SmartDMA transmit task
+	 */
+	fec_tx_task_enable(fec);
+
+	/*
+	 * Wait until frame is sent. On each turn of the wait cycle, we must
+	 * invalidate data cache to see what's really in RAM. Also, we need
+	 * barrier here.
+	 */
+	while (--timeout) {
+		if (!(readl(&fec->eth->x_des_active) & FEC_X_DES_ACTIVE_TDAR))
+			break;
+	}
+
+	if (!timeout)
+		ret = -EINVAL;
+
+	invalidate_dcache_range(addr, addr + size);
+	if (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY)
+		ret = -EINVAL;
+
+	debug("fec_send: status 0x%x index %d ret %i\n",
+			readw(&fec->tbd_base[fec->tbd_index].status),
+			fec->tbd_index, ret);
+	/* for next transmission use the other buffer */
+	if (fec->tbd_index)
+		fec->tbd_index = 0;
+	else
+		fec->tbd_index = 1;
+
+	return ret;
+}
+
+/**
+ * Pull one frame from the card
+ * @param[in] dev Our ethernet device to handle
+ * @return Length of packet read
+ */
+static int fec_recv(struct eth_device *dev)
+{
+	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+	struct fec_bd *rbd = &fec->rbd_base[fec->rbd_index];
+	unsigned long ievent;
+	int frame_length, len = 0;
+	struct nbuf *frame;
+	uint16_t bd_status;
+	uint32_t addr, size, end;
+	int i;
+	ALLOC_CACHE_ALIGN_BUFFER(uchar, buff, FEC_MAX_PKT_SIZE);
+
+	/*
+	 * Check if any critical events have happened
+	 */
+	ievent = readl(&fec->eth->ievent);
+	writel(ievent, &fec->eth->ievent);
+	debug("fec_recv: ievent 0x%lx\n", ievent);
+	if (ievent & FEC_IEVENT_BABR) {
+		fec_halt(dev);
+		fec_init(dev, fec->bd);
+		printf("some error: 0x%08lx\n", ievent);
+		return 0;
+	}
+	if (ievent & FEC_IEVENT_HBERR) {
+		/* Heartbeat error */
+		writel(0x00000001 | readl(&fec->eth->x_cntrl),
+				&fec->eth->x_cntrl);
+	}
+	if (ievent & FEC_IEVENT_GRA) {
+		/* Graceful stop complete */
+		if (readl(&fec->eth->x_cntrl) & 0x00000001) {
+			fec_halt(dev);
+			writel(~0x00000001 & readl(&fec->eth->x_cntrl),
+					&fec->eth->x_cntrl);
+			fec_init(dev, fec->bd);
+		}
+	}
+
+	/*
+	 * Read the buffer status. Before the status can be read, the data cache
+	 * must be invalidated, because the data in RAM might have been changed
+	 * by DMA. The descriptors are properly aligned to cachelines so there's
+	 * no need to worry they'd overlap.
+	 *
+	 * WARNING: By invalidating the descriptor here, we also invalidate
+	 * the descriptors surrounding this one. Therefore we can NOT change the
+	 * contents of this descriptor nor the surrounding ones. The problem is
+	 * that in order to mark the descriptor as processed, we need to change
+	 * the descriptor. The solution is to mark the whole cache line when all
+	 * descriptors in the cache line are processed.
+	 */
+	addr = (uint32_t)rbd;
+	addr &= ~(ARCH_DMA_MINALIGN - 1);
+	size = roundup(sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
+	invalidate_dcache_range(addr, addr + size);
+
+	bd_status = readw(&rbd->status);
+	debug("fec_recv: status 0x%x\n", bd_status);
+
+	if (!(bd_status & FEC_RBD_EMPTY)) {
+		if ((bd_status & FEC_RBD_LAST) && !(bd_status & FEC_RBD_ERR) &&
+			((readw(&rbd->data_length) - 4) > 14)) {
+			/*
+			 * Get buffer address and size
+			 */
+			frame = (struct nbuf *)readl(&rbd->data_pointer);
+			frame_length = readw(&rbd->data_length) - 4;
+			/*
+			 * Invalidate data cache over the buffer
+			 */
+			addr = (uint32_t)frame;
+			end = roundup(addr + frame_length, ARCH_DMA_MINALIGN);
+			addr &= ~(ARCH_DMA_MINALIGN - 1);
+			invalidate_dcache_range(addr, end);
+
+			/*
+			 *  Fill the buffer and pass it to upper layers
+			 */
+#ifdef CONFIG_FEC_MXC_SWAP_PACKET
+			swap_packet((uint32_t *)frame->data, frame_length);
+#endif
+			memcpy(buff, frame->data, frame_length);
+			NetReceive(buff, frame_length);
+			len = frame_length;
+		} else {
+			if (bd_status & FEC_RBD_ERR)
+				printf("error frame: 0x%08lx 0x%08x\n",
+						(ulong)rbd->data_pointer,
+						bd_status);
+		}
+
+		/*
+		 * Free the current buffer, restart the engine and move forward
+		 * to the next buffer. Here we check if the whole cacheline of
+		 * descriptors was already processed and if so, we mark it free
+		 * as whole.
+		 */
+		size = RXDESC_PER_CACHELINE - 1;
+		if ((fec->rbd_index & size) == size) {
+			i = fec->rbd_index - size;
+			addr = (uint32_t)&fec->rbd_base[i];
+			for (; i <= fec->rbd_index ; i++) {
+				fec_rbd_clean(i == (FEC_RBD_NUM - 1),
+					      &fec->rbd_base[i]);
+			}
+			flush_dcache_range(addr,
+				addr + ARCH_DMA_MINALIGN);
+		}
+
+		fec_rx_task_enable(fec);
+		fec->rbd_index = (fec->rbd_index + 1) % FEC_RBD_NUM;
+	}
+	debug("fec_recv: stop\n");
+
+	return len;
+}
+
+static void fec_set_dev_name(char *dest, int dev_id)
+{
+	sprintf(dest, (dev_id == -1) ? "FEC" : "FEC%i", dev_id);
+}
+
+static int fec_alloc_descs(struct fec_priv *fec)
+{
+	unsigned int size;
+	int i;
+	uint8_t *data;
+
+	/* Allocate TX descriptors. */
+	size = roundup(2 * sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
+	fec->tbd_base = memalign(ARCH_DMA_MINALIGN, size);
+	if (!fec->tbd_base)
+		goto err_tx;
+
+	/* Allocate RX descriptors. */
+	size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
+	fec->rbd_base = memalign(ARCH_DMA_MINALIGN, size);
+	if (!fec->rbd_base)
+		goto err_rx;
+
+	memset(fec->rbd_base, 0, size);
+
+	/* Allocate RX buffers. */
+
+	/* Maximum RX buffer size. */
+	size = roundup(FEC_MAX_PKT_SIZE, ARCH_DMA_MINALIGN);
+	for (i = 0; i < FEC_RBD_NUM; i++) {
+		data = memalign(ARCH_DMA_MINALIGN, size);
+		if (!data) {
+			printf("%s: error allocating rxbuf %d\n", __func__, i);
+			goto err_ring;
+		}
+
+		memset(data, 0, size);
+
+		fec->rbd_base[i].data_pointer = (uint32_t)data;
+		fec->rbd_base[i].status = FEC_RBD_EMPTY;
+		fec->rbd_base[i].data_length = 0;
+		/* Flush the buffer to memory. */
+		flush_dcache_range((uint32_t)data, (uint32_t)data + size);
+	}
+
+	/* Mark the last RBD to close the ring. */
+	fec->rbd_base[i - 1].status = FEC_RBD_WRAP | FEC_RBD_EMPTY;
+
+	fec->rbd_index = 0;
+	fec->tbd_index = 0;
+
+	return 0;
+
+err_ring:
+	for (; i >= 0; i--)
+		free((void *)fec->rbd_base[i].data_pointer);
+	free(fec->rbd_base);
+err_rx:
+	free(fec->tbd_base);
+err_tx:
+	return -ENOMEM;
+}
+
+static void fec_free_descs(struct fec_priv *fec)
+{
+	int i;
+
+	for (i = 0; i < FEC_RBD_NUM; i++)
+		free((void *)fec->rbd_base[i].data_pointer);
+	free(fec->rbd_base);
+	free(fec->tbd_base);
+}
+
+#ifdef CONFIG_PHYLIB
+int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
+		struct mii_dev *bus, struct phy_device *phydev)
+#else
+static int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
+		struct mii_dev *bus, int phy_id)
+#endif
+{
+	struct eth_device *edev;
+	struct fec_priv *fec;
+	unsigned char ethaddr[6];
+	uint32_t start;
+	int ret = 0;
+
+	/* create and fill edev struct */
+	edev = (struct eth_device *)malloc(sizeof(struct eth_device));
+	if (!edev) {
+		puts("fec_mxc: not enough malloc memory for eth_device\n");
+		ret = -ENOMEM;
+		goto err1;
+	}
+
+	fec = (struct fec_priv *)malloc(sizeof(struct fec_priv));
+	if (!fec) {
+		puts("fec_mxc: not enough malloc memory for fec_priv\n");
+		ret = -ENOMEM;
+		goto err2;
+	}
+
+	memset(edev, 0, sizeof(*edev));
+	memset(fec, 0, sizeof(*fec));
+
+	ret = fec_alloc_descs(fec);
+	if (ret)
+		goto err3;
+
+	edev->priv = fec;
+	edev->init = fec_init;
+	edev->send = fec_send;
+	edev->recv = fec_recv;
+	edev->halt = fec_halt;
+	edev->write_hwaddr = fec_set_hwaddr;
+
+	fec->eth = (struct ethernet_regs *)base_addr;
+	fec->bd = bd;
+
+	fec->xcv_type = CONFIG_FEC_XCV_TYPE;
+
+	/* Reset chip. */
+	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_RESET, &fec->eth->ecntrl);
+	start = get_timer(0);
+	while (readl(&fec->eth->ecntrl) & FEC_ECNTRL_RESET) {
+		if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
+			printf("FEC MXC: Timeout reseting chip\n");
+			goto err4;
+		}
+		udelay(10);
+	}
+
+	fec_reg_setup(fec);
+	fec_set_dev_name(edev->name, dev_id);
+	fec->dev_id = (dev_id == -1) ? 0 : dev_id;
+	fec->bus = bus;
+	fec_mii_setspeed(bus->priv);
+#ifdef CONFIG_PHYLIB
+	fec->phydev = phydev;
+	phy_connect_dev(phydev, edev);
+	/* Configure phy */
+	phy_config(phydev);
+#else
+	fec->phy_id = phy_id;
+#endif
+	eth_register(edev);
+
+	if (fec_get_hwaddr(edev, dev_id, ethaddr) == 0) {
+		debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr);
+		memcpy(edev->enetaddr, ethaddr, 6);
+		if (!getenv("ethaddr"))
+			eth_setenv_enetaddr("ethaddr", ethaddr);
+	}
+	return ret;
+err4:
+	fec_free_descs(fec);
+err3:
+	free(fec);
+err2:
+	free(edev);
+err1:
+	return ret;
+}
+
+struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id)
+{
+	struct ethernet_regs *eth = (struct ethernet_regs *)base_addr;
+	struct mii_dev *bus;
+	int ret;
+
+	bus = mdio_alloc();
+	if (!bus) {
+		printf("mdio_alloc failed\n");
+		return NULL;
+	}
+	bus->read = fec_phy_read;
+	bus->write = fec_phy_write;
+	bus->priv = eth;
+	fec_set_dev_name(bus->name, dev_id);
+
+	ret = mdio_register(bus);
+	if (ret) {
+		printf("mdio_register failed\n");
+		free(bus);
+		return NULL;
+	}
+	fec_mii_setspeed(eth);
+	return bus;
+}
+
+int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr)
+{
+	uint32_t base_mii;
+	struct mii_dev *bus = NULL;
+#ifdef CONFIG_PHYLIB
+	struct phy_device *phydev = NULL;
+#endif
+	int ret;
+
+#ifdef CONFIG_MX28
+	/*
+	 * The i.MX28 has two ethernet interfaces, but they are not equal.
+	 * Only the first one can access the MDIO bus.
+	 */
+	base_mii = MXS_ENET0_BASE;
+#else
+	base_mii = addr;
+#endif
+	debug("eth_init: fec_probe(bd, %i, %i) @ %08x\n", dev_id, phy_id, addr);
+	bus = fec_get_miibus(base_mii, dev_id);
+	if (!bus)
+		return -ENOMEM;
+#ifdef CONFIG_PHYLIB
+	phydev = phy_find_by_mask(bus, 1 << phy_id, PHY_INTERFACE_MODE_RGMII);
+	if (!phydev) {
+		free(bus);
+		return -ENOMEM;
+	}
+	ret = fec_probe(bd, dev_id, addr, bus, phydev);
+#else
+	ret = fec_probe(bd, dev_id, addr, bus, phy_id);
+#endif
+	if (ret) {
+#ifdef CONFIG_PHYLIB
+		free(phydev);
+#endif
+		free(bus);
+	}
+	return ret;
+}
+
+#ifdef CONFIG_FEC_MXC_PHYADDR
+int fecmxc_initialize(bd_t *bd)
+{
+	return fecmxc_initialize_multi(bd, -1, CONFIG_FEC_MXC_PHYADDR,
+			IMX_FEC_BASE);
+}
+#endif
+
+#ifndef CONFIG_PHYLIB
+int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int))
+{
+	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+	fec->mii_postcall = cb;
+	return 0;
+}
+#endif
diff --git a/marvell/uboot/drivers/net/fec_mxc.h b/marvell/uboot/drivers/net/fec_mxc.h
new file mode 100644
index 0000000..0717cc6
--- /dev/null
+++ b/marvell/uboot/drivers/net/fec_mxc.h
@@ -0,0 +1,323 @@
+/*
+ * (C) Copyright 2009 Ilya Yanok, Emcraft Systems Ltd <yanok@emcraft.com>
+ * (C) Copyright 2008 Armadeus Systems, nc
+ * (C) Copyright 2008 Eric Jarrige <eric.jarrige@armadeus.org>
+ * (C) Copyright 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ * (C) Copyright 2007 Pengutronix, Juergen Beisert <j.beisert@pengutronix.de>
+ *
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This file is based on mpc4200fec.h
+ * (C) Copyright Motorola, Inc., 2000
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+
+#ifndef __FEC_MXC_H
+#define __FEC_MXC_H
+
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
+
+/**
+ * Layout description of the FEC
+ */
+struct ethernet_regs {
+
+/* [10:2]addr = 00 */
+
+/*  Control and status Registers (offset 000-1FF) */
+
+	uint32_t res0[1];		/* MBAR_ETH + 0x000 */
+	uint32_t ievent;		/* MBAR_ETH + 0x004 */
+	uint32_t imask;			/* MBAR_ETH + 0x008 */
+
+	uint32_t res1[1];		/* MBAR_ETH + 0x00C */
+	uint32_t r_des_active;		/* MBAR_ETH + 0x010 */
+	uint32_t x_des_active;		/* MBAR_ETH + 0x014 */
+	uint32_t res2[3];		/* MBAR_ETH + 0x018-20 */
+	uint32_t ecntrl;		/* MBAR_ETH + 0x024 */
+
+	uint32_t res3[6];		/* MBAR_ETH + 0x028-03C */
+	uint32_t mii_data;		/* MBAR_ETH + 0x040 */
+	uint32_t mii_speed;		/* MBAR_ETH + 0x044 */
+	uint32_t res4[7];		/* MBAR_ETH + 0x048-60 */
+	uint32_t mib_control;		/* MBAR_ETH + 0x064 */
+
+	uint32_t res5[7];		/* MBAR_ETH + 0x068-80 */
+	uint32_t r_cntrl;		/* MBAR_ETH + 0x084 */
+	uint32_t res6[15];		/* MBAR_ETH + 0x088-C0 */
+	uint32_t x_cntrl;		/* MBAR_ETH + 0x0C4 */
+	uint32_t res7[7];		/* MBAR_ETH + 0x0C8-E0 */
+	uint32_t paddr1;		/* MBAR_ETH + 0x0E4 */
+	uint32_t paddr2;		/* MBAR_ETH + 0x0E8 */
+	uint32_t op_pause;		/* MBAR_ETH + 0x0EC */
+
+	uint32_t res8[10];		/* MBAR_ETH + 0x0F0-114 */
+	uint32_t iaddr1;		/* MBAR_ETH + 0x118 */
+	uint32_t iaddr2;		/* MBAR_ETH + 0x11C */
+	uint32_t gaddr1;		/* MBAR_ETH + 0x120 */
+	uint32_t gaddr2;		/* MBAR_ETH + 0x124 */
+	uint32_t res9[7];		/* MBAR_ETH + 0x128-140 */
+
+	uint32_t x_wmrk;		/* MBAR_ETH + 0x144 */
+	uint32_t res10[1];		/* MBAR_ETH + 0x148 */
+	uint32_t r_bound;		/* MBAR_ETH + 0x14C */
+	uint32_t r_fstart;		/* MBAR_ETH + 0x150 */
+	uint32_t res11[11];		/* MBAR_ETH + 0x154-17C */
+	uint32_t erdsr;			/* MBAR_ETH + 0x180 */
+	uint32_t etdsr;			/* MBAR_ETH + 0x184 */
+	uint32_t emrbr;			/* MBAR_ETH + 0x188 */
+	uint32_t res12[29];		/* MBAR_ETH + 0x18C-1FC */
+
+/*  MIB COUNTERS (Offset 200-2FF) */
+
+	uint32_t rmon_t_drop;		/* MBAR_ETH + 0x200 */
+	uint32_t rmon_t_packets;	/* MBAR_ETH + 0x204 */
+	uint32_t rmon_t_bc_pkt;		/* MBAR_ETH + 0x208 */
+	uint32_t rmon_t_mc_pkt;		/* MBAR_ETH + 0x20C */
+	uint32_t rmon_t_crc_align;	/* MBAR_ETH + 0x210 */
+	uint32_t rmon_t_undersize;	/* MBAR_ETH + 0x214 */
+	uint32_t rmon_t_oversize;	/* MBAR_ETH + 0x218 */
+	uint32_t rmon_t_frag;		/* MBAR_ETH + 0x21C */
+	uint32_t rmon_t_jab;		/* MBAR_ETH + 0x220 */
+	uint32_t rmon_t_col;		/* MBAR_ETH + 0x224 */
+	uint32_t rmon_t_p64;		/* MBAR_ETH + 0x228 */
+	uint32_t rmon_t_p65to127;	/* MBAR_ETH + 0x22C */
+	uint32_t rmon_t_p128to255;	/* MBAR_ETH + 0x230 */
+	uint32_t rmon_t_p256to511;	/* MBAR_ETH + 0x234 */
+	uint32_t rmon_t_p512to1023;	/* MBAR_ETH + 0x238 */
+	uint32_t rmon_t_p1024to2047;	/* MBAR_ETH + 0x23C */
+	uint32_t rmon_t_p_gte2048;	/* MBAR_ETH + 0x240 */
+	uint32_t rmon_t_octets;		/* MBAR_ETH + 0x244 */
+	uint32_t ieee_t_drop;		/* MBAR_ETH + 0x248 */
+	uint32_t ieee_t_frame_ok;	/* MBAR_ETH + 0x24C */
+	uint32_t ieee_t_1col;		/* MBAR_ETH + 0x250 */
+	uint32_t ieee_t_mcol;		/* MBAR_ETH + 0x254 */
+	uint32_t ieee_t_def;		/* MBAR_ETH + 0x258 */
+	uint32_t ieee_t_lcol;		/* MBAR_ETH + 0x25C */
+	uint32_t ieee_t_excol;		/* MBAR_ETH + 0x260 */
+	uint32_t ieee_t_macerr;		/* MBAR_ETH + 0x264 */
+	uint32_t ieee_t_cserr;		/* MBAR_ETH + 0x268 */
+	uint32_t ieee_t_sqe;		/* MBAR_ETH + 0x26C */
+	uint32_t t_fdxfc;		/* MBAR_ETH + 0x270 */
+	uint32_t ieee_t_octets_ok;	/* MBAR_ETH + 0x274 */
+
+	uint32_t res13[2];		/* MBAR_ETH + 0x278-27C */
+	uint32_t rmon_r_drop;		/* MBAR_ETH + 0x280 */
+	uint32_t rmon_r_packets;	/* MBAR_ETH + 0x284 */
+	uint32_t rmon_r_bc_pkt;		/* MBAR_ETH + 0x288 */
+	uint32_t rmon_r_mc_pkt;		/* MBAR_ETH + 0x28C */
+	uint32_t rmon_r_crc_align;	/* MBAR_ETH + 0x290 */
+	uint32_t rmon_r_undersize;	/* MBAR_ETH + 0x294 */
+	uint32_t rmon_r_oversize;	/* MBAR_ETH + 0x298 */
+	uint32_t rmon_r_frag;		/* MBAR_ETH + 0x29C */
+	uint32_t rmon_r_jab;		/* MBAR_ETH + 0x2A0 */
+
+	uint32_t rmon_r_resvd_0;	/* MBAR_ETH + 0x2A4 */
+
+	uint32_t rmon_r_p64;		/* MBAR_ETH + 0x2A8 */
+	uint32_t rmon_r_p65to127;	/* MBAR_ETH + 0x2AC */
+	uint32_t rmon_r_p128to255;	/* MBAR_ETH + 0x2B0 */
+	uint32_t rmon_r_p256to511;	/* MBAR_ETH + 0x2B4 */
+	uint32_t rmon_r_p512to1023;	/* MBAR_ETH + 0x2B8 */
+	uint32_t rmon_r_p1024to2047;	/* MBAR_ETH + 0x2BC */
+	uint32_t rmon_r_p_gte2048;	/* MBAR_ETH + 0x2C0 */
+	uint32_t rmon_r_octets;		/* MBAR_ETH + 0x2C4 */
+	uint32_t ieee_r_drop;		/* MBAR_ETH + 0x2C8 */
+	uint32_t ieee_r_frame_ok;	/* MBAR_ETH + 0x2CC */
+	uint32_t ieee_r_crc;		/* MBAR_ETH + 0x2D0 */
+	uint32_t ieee_r_align;		/* MBAR_ETH + 0x2D4 */
+	uint32_t r_macerr;		/* MBAR_ETH + 0x2D8 */
+	uint32_t r_fdxfc;		/* MBAR_ETH + 0x2DC */
+	uint32_t ieee_r_octets_ok;	/* MBAR_ETH + 0x2E0 */
+
+	uint32_t res14[7];		/* MBAR_ETH + 0x2E4-2FC */
+
+#if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL)
+	uint16_t miigsk_cfgr;		/* MBAR_ETH + 0x300 */
+	uint16_t res15[3];		/* MBAR_ETH + 0x302-306 */
+	uint16_t miigsk_enr;		/* MBAR_ETH + 0x308 */
+	uint16_t res16[3];		/* MBAR_ETH + 0x30a-30e */
+	uint32_t res17[60];		/* MBAR_ETH + 0x300-3FF */
+#else
+	uint32_t res15[64];		/* MBAR_ETH + 0x300-3FF */
+#endif
+};
+
+#define FEC_IEVENT_HBERR		0x80000000
+#define FEC_IEVENT_BABR			0x40000000
+#define FEC_IEVENT_BABT			0x20000000
+#define FEC_IEVENT_GRA			0x10000000
+#define FEC_IEVENT_TXF			0x08000000
+#define FEC_IEVENT_TXB			0x04000000
+#define FEC_IEVENT_RXF			0x02000000
+#define FEC_IEVENT_RXB			0x01000000
+#define FEC_IEVENT_MII			0x00800000
+#define FEC_IEVENT_EBERR		0x00400000
+#define FEC_IEVENT_LC			0x00200000
+#define FEC_IEVENT_RL			0x00100000
+#define FEC_IEVENT_UN			0x00080000
+
+#define FEC_IMASK_HBERR			0x80000000
+#define FEC_IMASK_BABR			0x40000000
+#define FEC_IMASKT_BABT			0x20000000
+#define FEC_IMASK_GRA			0x10000000
+#define FEC_IMASKT_TXF			0x08000000
+#define FEC_IMASK_TXB			0x04000000
+#define FEC_IMASKT_RXF			0x02000000
+#define FEC_IMASK_RXB			0x01000000
+#define FEC_IMASK_MII			0x00800000
+#define FEC_IMASK_EBERR			0x00400000
+#define FEC_IMASK_LC			0x00200000
+#define FEC_IMASKT_RL			0x00100000
+#define FEC_IMASK_UN			0x00080000
+
+
+#define FEC_RCNTRL_MAX_FL_SHIFT		16
+#define FEC_RCNTRL_LOOP			0x00000001
+#define FEC_RCNTRL_DRT			0x00000002
+#define FEC_RCNTRL_MII_MODE		0x00000004
+#define FEC_RCNTRL_PROM			0x00000008
+#define FEC_RCNTRL_BC_REJ		0x00000010
+#define FEC_RCNTRL_FCE			0x00000020
+#define FEC_RCNTRL_RGMII		0x00000040
+#define FEC_RCNTRL_RMII			0x00000100
+#define FEC_RCNTRL_RMII_10T		0x00000200
+
+#define FEC_TCNTRL_GTS			0x00000001
+#define FEC_TCNTRL_HBC			0x00000002
+#define FEC_TCNTRL_FDEN			0x00000004
+#define FEC_TCNTRL_TFC_PAUSE		0x00000008
+#define FEC_TCNTRL_RFC_PAUSE		0x00000010
+
+#define FEC_ECNTRL_RESET		0x00000001	/* reset the FEC */
+#define FEC_ECNTRL_ETHER_EN		0x00000002	/* enable the FEC */
+#define FEC_ECNTRL_SPEED		0x00000020
+#define FEC_ECNTRL_DBSWAP		0x00000100
+
+#define FEC_X_WMRK_STRFWD		0x00000100
+
+#define FEC_X_DES_ACTIVE_TDAR		0x01000000
+#define FEC_R_DES_ACTIVE_RDAR		0x01000000
+
+#if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL)
+/* defines for MIIGSK */
+/* RMII frequency control: 0=50MHz, 1=5MHz */
+#define MIIGSK_CFGR_FRCONT		(1 << 6)
+/* loopback mode */
+#define MIIGSK_CFGR_LBMODE		(1 << 4)
+/* echo mode */
+#define MIIGSK_CFGR_EMODE		(1 << 3)
+/* MII gasket mode field */
+#define MIIGSK_CFGR_IF_MODE_MASK	(3 << 0)
+/* MMI/7-Wire mode */
+#define MIIGSK_CFGR_IF_MODE_MII		(0 << 0)
+/* RMII mode */
+#define MIIGSK_CFGR_IF_MODE_RMII	(1 << 0)
+/* reflects MIIGSK Enable bit (RO) */
+#define MIIGSK_ENR_READY		(1 << 2)
+/* enable MIGSK (set by default) */
+#define MIIGSK_ENR_EN			(1 << 1)
+#endif
+
+/**
+ * @brief Receive & Transmit Buffer Descriptor definitions
+ *
+ * Note: The first BD must be aligned (see DB_ALIGNMENT)
+ */
+struct fec_bd {
+	uint16_t data_length;		/* payload's length in bytes */
+	uint16_t status;		/* BD's staus (see datasheet) */
+	uint32_t data_pointer;		/* payload's buffer address */
+};
+
+/**
+ * Supported phy types on this platform
+ */
+enum xceiver_type {
+	SEVENWIRE,	/* 7-wire       */
+	MII10,		/* MII 10Mbps   */
+	MII100,		/* MII 100Mbps  */
+	RMII,		/* RMII */
+	RGMII,		/* RGMII */
+};
+
+/**
+ * @brief i.MX27-FEC private structure
+ */
+struct fec_priv {
+	struct ethernet_regs *eth;	/* pointer to register'S base */
+	enum xceiver_type xcv_type;	/* transceiver type */
+	struct fec_bd *rbd_base;	/* RBD ring */
+	int rbd_index;			/* next receive BD to read */
+	struct fec_bd *tbd_base;	/* TBD ring */
+	int tbd_index;			/* next transmit BD to write */
+	bd_t *bd;
+	uint8_t *tdb_ptr;
+	int dev_id;
+	struct mii_dev *bus;
+#ifdef CONFIG_PHYLIB
+	struct phy_device *phydev;
+#else
+	int phy_id;
+	int (*mii_postcall)(int);
+#endif
+};
+
+/**
+ * @brief Numbers of buffer descriptors for receiving
+ *
+ * The number defines the stocked memory buffers for the receiving task.
+ * Larger values makes no sense in this limited environment.
+ */
+#define FEC_RBD_NUM		64
+
+/**
+ * @brief Define the ethernet packet size limit in memory
+ *
+ * Note: Do not shrink this number. This will force the FEC to spread larger
+ * frames in more than one BD. This is nothing to worry about, but the current
+ * driver can't handle it.
+ */
+#define FEC_MAX_PKT_SIZE	1536
+
+/* Receive BD status bits */
+#define FEC_RBD_EMPTY	0x8000	/* Receive BD status: Buffer is empty */
+#define FEC_RBD_WRAP	0x2000	/* Receive BD status: Last BD in ring */
+/* Receive BD status: Buffer is last in frame (useless here!) */
+#define FEC_RBD_LAST	0x0800
+#define FEC_RBD_MISS	0x0100	/* Receive BD status: Miss bit for prom mode */
+/* Receive BD status: The received frame is broadcast frame */
+#define FEC_RBD_BC	0x0080
+/* Receive BD status: The received frame is multicast frame */
+#define FEC_RBD_MC	0x0040
+#define FEC_RBD_LG	0x0020	/* Receive BD status: Frame length violation */
+#define FEC_RBD_NO	0x0010	/* Receive BD status: Nonoctet align frame */
+#define FEC_RBD_CR	0x0004	/* Receive BD status: CRC error */
+#define FEC_RBD_OV	0x0002	/* Receive BD status: Receive FIFO overrun */
+#define FEC_RBD_TR	0x0001	/* Receive BD status: Frame is truncated */
+#define FEC_RBD_ERR	(FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \
+			FEC_RBD_OV | FEC_RBD_TR)
+
+/* Transmit BD status bits */
+#define FEC_TBD_READY	0x8000	/* Tansmit BD status: Buffer is ready */
+#define FEC_TBD_WRAP	0x2000	/* Tansmit BD status: Mark as last BD in ring */
+#define FEC_TBD_LAST	0x0800	/* Tansmit BD status: Buffer is last in frame */
+#define FEC_TBD_TC	0x0400	/* Tansmit BD status: Transmit the CRC */
+#define FEC_TBD_ABC	0x0200	/* Tansmit BD status: Append bad CRC */
+
+/* MII-related definitios */
+#define FEC_MII_DATA_ST		0x40000000	/* Start of frame delimiter */
+#define FEC_MII_DATA_OP_RD	0x20000000	/* Perform a read operation */
+#define FEC_MII_DATA_OP_WR	0x10000000	/* Perform a write operation */
+#define FEC_MII_DATA_PA_MSK	0x0f800000	/* PHY Address field mask */
+#define FEC_MII_DATA_RA_MSK	0x007c0000	/* PHY Register field mask */
+#define FEC_MII_DATA_TA		0x00020000	/* Turnaround */
+#define FEC_MII_DATA_DATAMSK	0x0000ffff	/* PHY data field */
+
+#define FEC_MII_DATA_RA_SHIFT	18	/* MII Register address bits */
+#define FEC_MII_DATA_PA_SHIFT	23	/* MII PHY address bits */
+
+#endif	/* __FEC_MXC_H */
diff --git a/marvell/uboot/drivers/net/fm/Makefile b/marvell/uboot/drivers/net/fm/Makefile
new file mode 100644
index 0000000..ee5d768
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/Makefile
@@ -0,0 +1,36 @@
+#
+# Copyright 2009-2011 Freescale Semiconductor, Inc.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += dtsec.o
+obj-y += eth.o
+obj-y += fm.o
+obj-y += init.o
+obj-y += tgec.o
+obj-y += tgec_phy.o
+
+# Soc have FMAN v3 with mEMAC
+obj-$(CONFIG_SYS_FMAN_V3) += memac_phy.o
+obj-$(CONFIG_SYS_FMAN_V3) += memac.o
+
+# SoC specific SERDES support
+obj-$(CONFIG_P1017)	+= p1023.o
+obj-$(CONFIG_P1023)	+= p1023.o
+# The P204x, P304x, and P5020 are the same
+obj-$(CONFIG_PPC_P2041) += p5020.o
+obj-$(CONFIG_PPC_P3041) += p5020.o
+obj-$(CONFIG_PPC_P4080) += p4080.o
+obj-$(CONFIG_PPC_P5020) += p5020.o
+obj-$(CONFIG_PPC_P5040) += p5040.o
+obj-$(CONFIG_PPC_T1040) += t1040.o
+obj-$(CONFIG_PPC_T1042)	+= t1040.o
+obj-$(CONFIG_PPC_T1020)	+= t1040.o
+obj-$(CONFIG_PPC_T1022)	+= t1040.o
+obj-$(CONFIG_PPC_T2080) += t2080.o
+obj-$(CONFIG_PPC_T2081) += t2080.o
+obj-$(CONFIG_PPC_T4240) += t4240.o
+obj-$(CONFIG_PPC_T4160) += t4240.o
+obj-$(CONFIG_PPC_B4420) += b4860.o
+obj-$(CONFIG_PPC_B4860) += b4860.o
diff --git a/marvell/uboot/drivers/net/fm/b4860.c b/marvell/uboot/drivers/net/fm/b4860.c
new file mode 100644
index 0000000..373cc4f
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/b4860.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *	Roy Zang <tie-fei.zang@freescale.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <phy.h>
+#include <fm_eth.h>
+#include <asm/io.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_serdes.h>
+
+u32 port_to_devdisr[] = {
+	[FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1,
+	[FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2,
+	[FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3,
+	[FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4,
+	[FM1_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC1_5,
+	[FM1_DTSEC6] = FSL_CORENET_DEVDISR2_DTSEC1_6,
+	[FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1_1,
+	[FM1_10GEC2] = FSL_CORENET_DEVDISR2_10GEC1_2,
+};
+
+static int is_device_disabled(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+	u32 devdisr2 = in_be32(&gur->devdisr2);
+
+	return port_to_devdisr[port] & devdisr2;
+}
+
+void fman_disable_port(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+	setbits_be32(&gur->devdisr2, port_to_devdisr[port]);
+}
+
+void fman_enable_port(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+	clrbits_be32(&gur->devdisr2, port_to_devdisr[port]);
+}
+
+phy_interface_t fman_port_enet_if(enum fm_port port)
+{
+	if (is_device_disabled(port))
+		return PHY_INTERFACE_MODE_NONE;
+
+	/*B4860 has two 10Gig Mac*/
+	if ((port == FM1_10GEC1 || port == FM1_10GEC2)	&&
+	    ((is_serdes_configured(XAUI_FM1_MAC9))	||
+	    (is_serdes_configured(XAUI_FM1_MAC10))))
+		return PHY_INTERFACE_MODE_XGMII;
+
+	/* Fix me need to handle RGMII here first */
+
+	switch (port) {
+	case FM1_DTSEC1:
+	case FM1_DTSEC2:
+	case FM1_DTSEC3:
+	case FM1_DTSEC4:
+	case FM1_DTSEC5:
+	case FM1_DTSEC6:
+		if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1))
+			return PHY_INTERFACE_MODE_SGMII;
+		break;
+	default:
+		return PHY_INTERFACE_MODE_NONE;
+	}
+
+	return PHY_INTERFACE_MODE_NONE;
+}
diff --git a/marvell/uboot/drivers/net/fm/dtsec.c b/marvell/uboot/drivers/net/fm/dtsec.c
new file mode 100644
index 0000000..78bbd43
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/dtsec.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2009-2011 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/fsl_enet.h>
+#include <asm/fsl_dtsec.h>
+#include <fsl_mdio.h>
+#include <phy.h>
+
+#include "fm.h"
+
+#define RCTRL_INIT	(RCTRL_GRS | RCTRL_UPROM)
+#define TCTRL_INIT	TCTRL_GTS
+#define MACCFG1_INIT	MACCFG1_SOFT_RST
+
+#define MACCFG2_INIT	(MACCFG2_PRE_LEN(0x7) | MACCFG2_LEN_CHECK | \
+			 MACCFG2_PAD_CRC | MACCFG2_FULL_DUPLEX | \
+			 MACCFG2_IF_MODE_NIBBLE)
+
+/* MAXFRM - maximum frame length register */
+#define MAXFRM_MASK		0x00003fff
+
+static void dtsec_init_mac(struct fsl_enet_mac *mac)
+{
+	struct dtsec *regs = mac->base;
+
+	/* soft reset */
+	out_be32(&regs->maccfg1, MACCFG1_SOFT_RST);
+	udelay(1000);
+
+	/* clear soft reset, Rx/Tx MAC disable */
+	out_be32(&regs->maccfg1, 0);
+
+	/* graceful stop rx */
+	out_be32(&regs->rctrl, RCTRL_INIT);
+	udelay(1000);
+
+	/* graceful stop tx */
+	out_be32(&regs->tctrl, TCTRL_INIT);
+	udelay(1000);
+
+	/* disable all interrupts */
+	out_be32(&regs->imask, IMASK_MASK_ALL);
+
+	/* clear all events */
+	out_be32(&regs->ievent, IEVENT_CLEAR_ALL);
+
+	/* set the max Rx length */
+	out_be32(&regs->maxfrm, mac->max_rx_len & MAXFRM_MASK);
+
+	/* set the ecntrl to reset value */
+	out_be32(&regs->ecntrl, ECNTRL_DEFAULT);
+
+	/*
+	 * Rx length check, no strip CRC for Rx, pad and append CRC for Tx,
+	 * full duplex
+	 */
+	out_be32(&regs->maccfg2, MACCFG2_INIT);
+}
+
+static void dtsec_enable_mac(struct fsl_enet_mac *mac)
+{
+	struct dtsec *regs = mac->base;
+
+	/* enable Rx/Tx MAC */
+	setbits_be32(&regs->maccfg1, MACCFG1_RXTX_EN);
+
+	/* clear the graceful Rx stop */
+	clrbits_be32(&regs->rctrl, RCTRL_GRS);
+
+	/* clear the graceful Tx stop */
+	clrbits_be32(&regs->tctrl, TCTRL_GTS);
+}
+
+static void dtsec_disable_mac(struct fsl_enet_mac *mac)
+{
+	struct dtsec *regs = mac->base;
+
+	/* graceful Rx stop */
+	setbits_be32(&regs->rctrl, RCTRL_GRS);
+
+	/* graceful Tx stop */
+	setbits_be32(&regs->tctrl, TCTRL_GTS);
+
+	/* disable Rx/Tx MAC */
+	clrbits_be32(&regs->maccfg1, MACCFG1_RXTX_EN);
+}
+
+static void dtsec_set_mac_addr(struct fsl_enet_mac *mac, u8 *mac_addr)
+{
+	struct dtsec *regs = mac->base;
+	u32 mac_addr1, mac_addr2;
+
+	/*
+	 * if a station address of 0x12345678ABCD, perform a write to
+	 * MACSTNADDR1 of 0xCDAB7856, MACSTNADDR2 of 0x34120000
+	 */
+	mac_addr1 = (mac_addr[5] << 24) | (mac_addr[4] << 16) | \
+			(mac_addr[3] << 8)  | (mac_addr[2]);
+	out_be32(&regs->macstnaddr1, mac_addr1);
+
+	mac_addr2 = ((mac_addr[1] << 24) | (mac_addr[0] << 16)) & 0xffff0000;
+	out_be32(&regs->macstnaddr2, mac_addr2);
+}
+
+static void dtsec_set_interface_mode(struct fsl_enet_mac *mac,
+		phy_interface_t type, int speed)
+{
+	struct dtsec *regs = mac->base;
+	u32 ecntrl, maccfg2;
+
+	/* clear all bits relative with interface mode */
+	ecntrl = in_be32(&regs->ecntrl);
+	ecntrl &= ~(ECNTRL_TBIM | ECNTRL_GMIIM | ECNTRL_RPM |
+				  ECNTRL_R100M | ECNTRL_SGMIIM);
+
+	maccfg2 = in_be32(&regs->maccfg2);
+	maccfg2 &= ~MACCFG2_IF_MODE_MASK;
+
+	if (speed == SPEED_1000)
+		maccfg2 |= MACCFG2_IF_MODE_BYTE;
+	else
+		maccfg2 |= MACCFG2_IF_MODE_NIBBLE;
+
+	/* set interface mode */
+	switch (type) {
+	case PHY_INTERFACE_MODE_GMII:
+		ecntrl |= ECNTRL_GMIIM;
+		break;
+	case PHY_INTERFACE_MODE_RGMII:
+		ecntrl |= (ECNTRL_GMIIM | ECNTRL_RPM);
+		if (speed == SPEED_100)
+			ecntrl |= ECNTRL_R100M;
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		if (speed == SPEED_100)
+			ecntrl |= ECNTRL_R100M;
+		break;
+	case PHY_INTERFACE_MODE_SGMII:
+		ecntrl |= (ECNTRL_SGMIIM | ECNTRL_TBIM);
+		if (speed == SPEED_100)
+			ecntrl |= ECNTRL_R100M;
+		break;
+	default:
+		break;
+	}
+
+	out_be32(&regs->ecntrl, ecntrl);
+	out_be32(&regs->maccfg2, maccfg2);
+}
+
+void init_dtsec(struct fsl_enet_mac *mac, void *base,
+		void *phyregs, int max_rx_len)
+{
+	mac->base = base;
+	mac->phyregs = phyregs;
+	mac->max_rx_len = max_rx_len;
+	mac->init_mac = dtsec_init_mac;
+	mac->enable_mac = dtsec_enable_mac;
+	mac->disable_mac = dtsec_disable_mac;
+	mac->set_mac_addr = dtsec_set_mac_addr;
+	mac->set_if_mode = dtsec_set_interface_mode;
+}
diff --git a/marvell/uboot/drivers/net/fm/eth.c b/marvell/uboot/drivers/net/fm/eth.c
new file mode 100644
index 0000000..218a5ed
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/eth.c
@@ -0,0 +1,712 @@
+/*
+ * Copyright 2009-2012 Freescale Semiconductor, Inc.
+ *	Dave Liu <daveliu@freescale.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <net.h>
+#include <hwconfig.h>
+#include <fm_eth.h>
+#include <fsl_mdio.h>
+#include <miiphy.h>
+#include <phy.h>
+#include <asm/fsl_dtsec.h>
+#include <asm/fsl_tgec.h>
+#include <asm/fsl_memac.h>
+
+#include "fm.h"
+
+static struct eth_device *devlist[NUM_FM_PORTS];
+static int num_controllers;
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) && !defined(BITBANGMII)
+
+#define TBIANA_SETTINGS (TBIANA_ASYMMETRIC_PAUSE | TBIANA_SYMMETRIC_PAUSE | \
+			 TBIANA_FULL_DUPLEX)
+
+#define TBIANA_SGMII_ACK 0x4001
+
+#define TBICR_SETTINGS (TBICR_ANEG_ENABLE | TBICR_RESTART_ANEG | \
+			TBICR_FULL_DUPLEX | TBICR_SPEED1_SET)
+
+/* Configure the TBI for SGMII operation */
+static void dtsec_configure_serdes(struct fm_eth *priv)
+{
+#ifdef CONFIG_SYS_FMAN_V3
+	u32 value;
+	struct mii_dev bus;
+	bus.priv = priv->mac->phyregs;
+
+	/* SGMII IF mode + AN enable */
+	value = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII;
+	memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x14, value);
+
+	/* Dev ability according to SGMII specification */
+	value = PHY_SGMII_DEV_ABILITY_SGMII;
+	memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x4, value);
+
+	/* Adjust link timer for SGMII  -
+	1.6 ms in units of 8 ns = 2 * 10^5 = 0x30d40 */
+	memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x13, 0x3);
+	memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x12, 0xd40);
+
+	/* Restart AN */
+	value = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
+	memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0, value);
+#else
+	struct dtsec *regs = priv->mac->base;
+	struct tsec_mii_mng *phyregs = priv->mac->phyregs;
+
+	/*
+	 * Access TBI PHY registers at given TSEC register offset as
+	 * opposed to the register offset used for external PHY accesses
+	 */
+	tsec_local_mdio_write(phyregs, in_be32(&regs->tbipa), 0, TBI_TBICON,
+			TBICON_CLK_SELECT);
+	tsec_local_mdio_write(phyregs, in_be32(&regs->tbipa), 0, TBI_ANA,
+			TBIANA_SGMII_ACK);
+	tsec_local_mdio_write(phyregs, in_be32(&regs->tbipa), 0,
+			TBI_CR, TBICR_SETTINGS);
+#endif
+}
+
+static void dtsec_init_phy(struct eth_device *dev)
+{
+	struct fm_eth *fm_eth = dev->priv;
+#ifndef CONFIG_SYS_FMAN_V3
+	struct dtsec *regs = (struct dtsec *)CONFIG_SYS_FSL_FM1_DTSEC1_ADDR;
+
+	/* Assign a Physical address to the TBI */
+	out_be32(&regs->tbipa, CONFIG_SYS_TBIPA_VALUE);
+#endif
+
+	if (fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII)
+		dtsec_configure_serdes(fm_eth);
+}
+
+static int tgec_is_fibre(struct eth_device *dev)
+{
+	struct fm_eth *fm = dev->priv;
+	char phyopt[20];
+
+	sprintf(phyopt, "fsl_fm%d_xaui_phy", fm->fm_index + 1);
+
+	return hwconfig_arg_cmp(phyopt, "xfi");
+}
+#endif
+
+static u16 muram_readw(u16 *addr)
+{
+	u32 base = (u32)addr & ~0x3;
+	u32 val32 = *(u32 *)base;
+	int byte_pos;
+	u16 ret;
+
+	byte_pos = (u32)addr & 0x3;
+	if (byte_pos)
+		ret = (u16)(val32 & 0x0000ffff);
+	else
+		ret = (u16)((val32 & 0xffff0000) >> 16);
+
+	return ret;
+}
+
+static void muram_writew(u16 *addr, u16 val)
+{
+	u32 base = (u32)addr & ~0x3;
+	u32 org32 = *(u32 *)base;
+	u32 val32;
+	int byte_pos;
+
+	byte_pos = (u32)addr & 0x3;
+	if (byte_pos)
+		val32 = (org32 & 0xffff0000) | val;
+	else
+		val32 = (org32 & 0x0000ffff) | ((u32)val << 16);
+
+	*(u32 *)base = val32;
+}
+
+static void bmi_rx_port_disable(struct fm_bmi_rx_port *rx_port)
+{
+	int timeout = 1000000;
+
+	clrbits_be32(&rx_port->fmbm_rcfg, FMBM_RCFG_EN);
+
+	/* wait until the rx port is not busy */
+	while ((in_be32(&rx_port->fmbm_rst) & FMBM_RST_BSY) && timeout--)
+		;
+}
+
+static void bmi_rx_port_init(struct fm_bmi_rx_port *rx_port)
+{
+	/* set BMI to independent mode, Rx port disable */
+	out_be32(&rx_port->fmbm_rcfg, FMBM_RCFG_IM);
+	/* clear FOF in IM case */
+	out_be32(&rx_port->fmbm_rim, 0);
+	/* Rx frame next engine -RISC */
+	out_be32(&rx_port->fmbm_rfne, NIA_ENG_RISC | NIA_RISC_AC_IM_RX);
+	/* Rx command attribute - no order, MR[3] = 1 */
+	clrbits_be32(&rx_port->fmbm_rfca, FMBM_RFCA_ORDER | FMBM_RFCA_MR_MASK);
+	setbits_be32(&rx_port->fmbm_rfca, FMBM_RFCA_MR(4));
+	/* enable Rx statistic counters */
+	out_be32(&rx_port->fmbm_rstc, FMBM_RSTC_EN);
+	/* disable Rx performance counters */
+	out_be32(&rx_port->fmbm_rpc, 0);
+}
+
+static void bmi_tx_port_disable(struct fm_bmi_tx_port *tx_port)
+{
+	int timeout = 1000000;
+
+	clrbits_be32(&tx_port->fmbm_tcfg, FMBM_TCFG_EN);
+
+	/* wait until the tx port is not busy */
+	while ((in_be32(&tx_port->fmbm_tst) & FMBM_TST_BSY) && timeout--)
+		;
+}
+
+static void bmi_tx_port_init(struct fm_bmi_tx_port *tx_port)
+{
+	/* set BMI to independent mode, Tx port disable */
+	out_be32(&tx_port->fmbm_tcfg, FMBM_TCFG_IM);
+	/* Tx frame next engine -RISC */
+	out_be32(&tx_port->fmbm_tfne, NIA_ENG_RISC | NIA_RISC_AC_IM_TX);
+	out_be32(&tx_port->fmbm_tfene, NIA_ENG_RISC | NIA_RISC_AC_IM_TX);
+	/* Tx command attribute - no order, MR[3] = 1 */
+	clrbits_be32(&tx_port->fmbm_tfca, FMBM_TFCA_ORDER | FMBM_TFCA_MR_MASK);
+	setbits_be32(&tx_port->fmbm_tfca, FMBM_TFCA_MR(4));
+	/* enable Tx statistic counters */
+	out_be32(&tx_port->fmbm_tstc, FMBM_TSTC_EN);
+	/* disable Tx performance counters */
+	out_be32(&tx_port->fmbm_tpc, 0);
+}
+
+static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth)
+{
+	struct fm_port_global_pram *pram;
+	u32 pram_page_offset;
+	void *rx_bd_ring_base;
+	void *rx_buf_pool;
+	struct fm_port_bd *rxbd;
+	struct fm_port_qd *rxqd;
+	struct fm_bmi_rx_port *bmi_rx_port = fm_eth->rx_port;
+	int i;
+
+	/* alloc global parameter ram at MURAM */
+	pram = (struct fm_port_global_pram *)fm_muram_alloc(fm_eth->fm_index,
+		FM_PRAM_SIZE, FM_PRAM_ALIGN);
+	fm_eth->rx_pram = pram;
+
+	/* parameter page offset to MURAM */
+	pram_page_offset = (u32)pram - fm_muram_base(fm_eth->fm_index);
+
+	/* enable global mode- snooping data buffers and BDs */
+	pram->mode = PRAM_MODE_GLOBAL;
+
+	/* init the Rx queue descriptor pionter */
+	pram->rxqd_ptr = pram_page_offset + 0x20;
+
+	/* set the max receive buffer length, power of 2 */
+	muram_writew(&pram->mrblr, MAX_RXBUF_LOG2);
+
+	/* alloc Rx buffer descriptors from main memory */
+	rx_bd_ring_base = malloc(sizeof(struct fm_port_bd)
+			* RX_BD_RING_SIZE);
+	if (!rx_bd_ring_base)
+		return 0;
+	memset(rx_bd_ring_base, 0, sizeof(struct fm_port_bd)
+			* RX_BD_RING_SIZE);
+
+	/* alloc Rx buffer from main memory */
+	rx_buf_pool = malloc(MAX_RXBUF_LEN * RX_BD_RING_SIZE);
+	if (!rx_buf_pool)
+		return 0;
+	memset(rx_buf_pool, 0, MAX_RXBUF_LEN * RX_BD_RING_SIZE);
+
+	/* save them to fm_eth */
+	fm_eth->rx_bd_ring = rx_bd_ring_base;
+	fm_eth->cur_rxbd = rx_bd_ring_base;
+	fm_eth->rx_buf = rx_buf_pool;
+
+	/* init Rx BDs ring */
+	rxbd = (struct fm_port_bd *)rx_bd_ring_base;
+	for (i = 0; i < RX_BD_RING_SIZE; i++) {
+		rxbd->status = RxBD_EMPTY;
+		rxbd->len = 0;
+		rxbd->buf_ptr_hi = 0;
+		rxbd->buf_ptr_lo = (u32)rx_buf_pool + i * MAX_RXBUF_LEN;
+		rxbd++;
+	}
+
+	/* set the Rx queue descriptor */
+	rxqd = &pram->rxqd;
+	muram_writew(&rxqd->gen, 0);
+	muram_writew(&rxqd->bd_ring_base_hi, 0);
+	rxqd->bd_ring_base_lo = (u32)rx_bd_ring_base;
+	muram_writew(&rxqd->bd_ring_size, sizeof(struct fm_port_bd)
+			* RX_BD_RING_SIZE);
+	muram_writew(&rxqd->offset_in, 0);
+	muram_writew(&rxqd->offset_out, 0);
+
+	/* set IM parameter ram pointer to Rx Frame Queue ID */
+	out_be32(&bmi_rx_port->fmbm_rfqid, pram_page_offset);
+
+	return 1;
+}
+
+static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth)
+{
+	struct fm_port_global_pram *pram;
+	u32 pram_page_offset;
+	void *tx_bd_ring_base;
+	struct fm_port_bd *txbd;
+	struct fm_port_qd *txqd;
+	struct fm_bmi_tx_port *bmi_tx_port = fm_eth->tx_port;
+	int i;
+
+	/* alloc global parameter ram at MURAM */
+	pram = (struct fm_port_global_pram *)fm_muram_alloc(fm_eth->fm_index,
+		FM_PRAM_SIZE, FM_PRAM_ALIGN);
+	fm_eth->tx_pram = pram;
+
+	/* parameter page offset to MURAM */
+	pram_page_offset = (u32)pram - fm_muram_base(fm_eth->fm_index);
+
+	/* enable global mode- snooping data buffers and BDs */
+	pram->mode = PRAM_MODE_GLOBAL;
+
+	/* init the Tx queue descriptor pionter */
+	pram->txqd_ptr = pram_page_offset + 0x40;
+
+	/* alloc Tx buffer descriptors from main memory */
+	tx_bd_ring_base = malloc(sizeof(struct fm_port_bd)
+			* TX_BD_RING_SIZE);
+	if (!tx_bd_ring_base)
+		return 0;
+	memset(tx_bd_ring_base, 0, sizeof(struct fm_port_bd)
+			* TX_BD_RING_SIZE);
+	/* save it to fm_eth */
+	fm_eth->tx_bd_ring = tx_bd_ring_base;
+	fm_eth->cur_txbd = tx_bd_ring_base;
+
+	/* init Tx BDs ring */
+	txbd = (struct fm_port_bd *)tx_bd_ring_base;
+	for (i = 0; i < TX_BD_RING_SIZE; i++) {
+		txbd->status = TxBD_LAST;
+		txbd->len = 0;
+		txbd->buf_ptr_hi = 0;
+		txbd->buf_ptr_lo = 0;
+	}
+
+	/* set the Tx queue decriptor */
+	txqd = &pram->txqd;
+	muram_writew(&txqd->bd_ring_base_hi, 0);
+	txqd->bd_ring_base_lo = (u32)tx_bd_ring_base;
+	muram_writew(&txqd->bd_ring_size, sizeof(struct fm_port_bd)
+			* TX_BD_RING_SIZE);
+	muram_writew(&txqd->offset_in, 0);
+	muram_writew(&txqd->offset_out, 0);
+
+	/* set IM parameter ram pointer to Tx Confirmation Frame Queue ID */
+	out_be32(&bmi_tx_port->fmbm_tcfqid, pram_page_offset);
+
+	return 1;
+}
+
+static int fm_eth_init(struct fm_eth *fm_eth)
+{
+
+	if (!fm_eth_rx_port_parameter_init(fm_eth))
+		return 0;
+
+	if (!fm_eth_tx_port_parameter_init(fm_eth))
+		return 0;
+
+	return 1;
+}
+
+static int fm_eth_startup(struct fm_eth *fm_eth)
+{
+	struct fsl_enet_mac *mac;
+	mac = fm_eth->mac;
+
+	/* Rx/TxBDs, Rx/TxQDs, Rx buff and parameter ram init */
+	if (!fm_eth_init(fm_eth))
+		return 0;
+	/* setup the MAC controller */
+	mac->init_mac(mac);
+
+	/* For some reason we need to set SPEED_100 */
+	if (((fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII) ||
+	     (fm_eth->enet_if == PHY_INTERFACE_MODE_QSGMII)) &&
+	      mac->set_if_mode)
+		mac->set_if_mode(mac, fm_eth->enet_if, SPEED_100);
+
+	/* init bmi rx port, IM mode and disable */
+	bmi_rx_port_init(fm_eth->rx_port);
+	/* init bmi tx port, IM mode and disable */
+	bmi_tx_port_init(fm_eth->tx_port);
+
+	return 1;
+}
+
+static void fmc_tx_port_graceful_stop_enable(struct fm_eth *fm_eth)
+{
+	struct fm_port_global_pram *pram;
+
+	pram = fm_eth->tx_pram;
+	/* graceful stop transmission of frames */
+	pram->mode |= PRAM_MODE_GRACEFUL_STOP;
+	sync();
+}
+
+static void fmc_tx_port_graceful_stop_disable(struct fm_eth *fm_eth)
+{
+	struct fm_port_global_pram *pram;
+
+	pram = fm_eth->tx_pram;
+	/* re-enable transmission of frames */
+	pram->mode &= ~PRAM_MODE_GRACEFUL_STOP;
+	sync();
+}
+
+static int fm_eth_open(struct eth_device *dev, bd_t *bd)
+{
+	struct fm_eth *fm_eth;
+	struct fsl_enet_mac *mac;
+#ifdef CONFIG_PHYLIB
+	int ret;
+#endif
+
+	fm_eth = (struct fm_eth *)dev->priv;
+	mac = fm_eth->mac;
+
+	/* setup the MAC address */
+	if (dev->enetaddr[0] & 0x01) {
+		printf("%s: MacAddress is multcast address\n",	__func__);
+		return 1;
+	}
+	mac->set_mac_addr(mac, dev->enetaddr);
+
+	/* enable bmi Rx port */
+	setbits_be32(&fm_eth->rx_port->fmbm_rcfg, FMBM_RCFG_EN);
+	/* enable MAC rx/tx port */
+	mac->enable_mac(mac);
+	/* enable bmi Tx port */
+	setbits_be32(&fm_eth->tx_port->fmbm_tcfg, FMBM_TCFG_EN);
+	/* re-enable transmission of frame */
+	fmc_tx_port_graceful_stop_disable(fm_eth);
+
+#ifdef CONFIG_PHYLIB
+	ret = phy_startup(fm_eth->phydev);
+	if (ret) {
+		printf("%s: Could not initialize\n", fm_eth->phydev->dev->name);
+		return ret;
+	}
+#else
+	fm_eth->phydev->speed = SPEED_1000;
+	fm_eth->phydev->link = 1;
+	fm_eth->phydev->duplex = DUPLEX_FULL;
+#endif
+
+	/* set the MAC-PHY mode */
+	mac->set_if_mode(mac, fm_eth->enet_if, fm_eth->phydev->speed);
+
+	if (!fm_eth->phydev->link)
+		printf("%s: No link.\n", fm_eth->phydev->dev->name);
+
+	return fm_eth->phydev->link ? 0 : -1;
+}
+
+static void fm_eth_halt(struct eth_device *dev)
+{
+	struct fm_eth *fm_eth;
+	struct fsl_enet_mac *mac;
+
+	fm_eth = (struct fm_eth *)dev->priv;
+	mac = fm_eth->mac;
+
+	/* graceful stop the transmission of frames */
+	fmc_tx_port_graceful_stop_enable(fm_eth);
+	/* disable bmi Tx port */
+	bmi_tx_port_disable(fm_eth->tx_port);
+	/* disable MAC rx/tx port */
+	mac->disable_mac(mac);
+	/* disable bmi Rx port */
+	bmi_rx_port_disable(fm_eth->rx_port);
+
+	phy_shutdown(fm_eth->phydev);
+}
+
+static int fm_eth_send(struct eth_device *dev, void *buf, int len)
+{
+	struct fm_eth *fm_eth;
+	struct fm_port_global_pram *pram;
+	struct fm_port_bd *txbd, *txbd_base;
+	u16 offset_in;
+	int i;
+
+	fm_eth = (struct fm_eth *)dev->priv;
+	pram = fm_eth->tx_pram;
+	txbd = fm_eth->cur_txbd;
+
+	/* find one empty TxBD */
+	for (i = 0; txbd->status & TxBD_READY; i++) {
+		udelay(100);
+		if (i > 0x1000) {
+			printf("%s: Tx buffer not ready\n", dev->name);
+			return 0;
+		}
+	}
+	/* setup TxBD */
+	txbd->buf_ptr_hi = 0;
+	txbd->buf_ptr_lo = (u32)buf;
+	txbd->len = len;
+	sync();
+	txbd->status = TxBD_READY | TxBD_LAST;
+	sync();
+
+	/* update TxQD, let RISC to send the packet */
+	offset_in = muram_readw(&pram->txqd.offset_in);
+	offset_in += sizeof(struct fm_port_bd);
+	if (offset_in >= muram_readw(&pram->txqd.bd_ring_size))
+		offset_in = 0;
+	muram_writew(&pram->txqd.offset_in, offset_in);
+	sync();
+
+	/* wait for buffer to be transmitted */
+	for (i = 0; txbd->status & TxBD_READY; i++) {
+		udelay(100);
+		if (i > 0x10000) {
+			printf("%s: Tx error\n", dev->name);
+			return 0;
+		}
+	}
+
+	/* advance the TxBD */
+	txbd++;
+	txbd_base = (struct fm_port_bd *)fm_eth->tx_bd_ring;
+	if (txbd >= (txbd_base + TX_BD_RING_SIZE))
+		txbd = txbd_base;
+	/* update current txbd */
+	fm_eth->cur_txbd = (void *)txbd;
+
+	return 1;
+}
+
+static int fm_eth_recv(struct eth_device *dev)
+{
+	struct fm_eth *fm_eth;
+	struct fm_port_global_pram *pram;
+	struct fm_port_bd *rxbd, *rxbd_base;
+	u16 status, len;
+	u8 *data;
+	u16 offset_out;
+
+	fm_eth = (struct fm_eth *)dev->priv;
+	pram = fm_eth->rx_pram;
+	rxbd = fm_eth->cur_rxbd;
+	status = rxbd->status;
+
+	while (!(status & RxBD_EMPTY)) {
+		if (!(status & RxBD_ERROR)) {
+			data = (u8 *)rxbd->buf_ptr_lo;
+			len = rxbd->len;
+			NetReceive(data, len);
+		} else {
+			printf("%s: Rx error\n", dev->name);
+			return 0;
+		}
+
+		/* clear the RxBDs */
+		rxbd->status = RxBD_EMPTY;
+		rxbd->len = 0;
+		sync();
+
+		/* advance RxBD */
+		rxbd++;
+		rxbd_base = (struct fm_port_bd *)fm_eth->rx_bd_ring;
+		if (rxbd >= (rxbd_base + RX_BD_RING_SIZE))
+			rxbd = rxbd_base;
+		/* read next status */
+		status = rxbd->status;
+
+		/* update RxQD */
+		offset_out = muram_readw(&pram->rxqd.offset_out);
+		offset_out += sizeof(struct fm_port_bd);
+		if (offset_out >= muram_readw(&pram->rxqd.bd_ring_size))
+			offset_out = 0;
+		muram_writew(&pram->rxqd.offset_out, offset_out);
+		sync();
+	}
+	fm_eth->cur_rxbd = (void *)rxbd;
+
+	return 1;
+}
+
+static int fm_eth_init_mac(struct fm_eth *fm_eth, struct ccsr_fman *reg)
+{
+	struct fsl_enet_mac *mac;
+	int num;
+	void *base, *phyregs = NULL;
+
+	num = fm_eth->num;
+
+#ifdef CONFIG_SYS_FMAN_V3
+	if (fm_eth->type == FM_ETH_10G_E) {
+		/* 10GEC1/10GEC2 use mEMAC9/mEMAC10
+		 * 10GEC3/10GEC4 use mEMAC1/mEMAC2
+		 * so it needs to change the num.
+		 */
+		if (fm_eth->num >= 2)
+			num -= 2;
+		else
+			num += 8;
+	}
+	base = &reg->memac[num].fm_memac;
+	phyregs = &reg->memac[num].fm_memac_mdio;
+#else
+	/* Get the mac registers base address */
+	if (fm_eth->type == FM_ETH_1G_E) {
+		base = &reg->mac_1g[num].fm_dtesc;
+		phyregs = &reg->mac_1g[num].fm_mdio.miimcfg;
+	} else {
+		base = &reg->mac_10g[num].fm_10gec;
+		phyregs = &reg->mac_10g[num].fm_10gec_mdio;
+	}
+#endif
+
+	/* alloc mac controller */
+	mac = malloc(sizeof(struct fsl_enet_mac));
+	if (!mac)
+		return 0;
+	memset(mac, 0, sizeof(struct fsl_enet_mac));
+
+	/* save the mac to fm_eth struct */
+	fm_eth->mac = mac;
+
+#ifdef CONFIG_SYS_FMAN_V3
+	init_memac(mac, base, phyregs, MAX_RXBUF_LEN);
+#else
+	if (fm_eth->type == FM_ETH_1G_E)
+		init_dtsec(mac, base, phyregs, MAX_RXBUF_LEN);
+	else
+		init_tgec(mac, base, phyregs, MAX_RXBUF_LEN);
+#endif
+
+	return 1;
+}
+
+static int init_phy(struct eth_device *dev)
+{
+	struct fm_eth *fm_eth = dev->priv;
+	struct phy_device *phydev = NULL;
+	u32 supported;
+
+#ifdef CONFIG_PHYLIB
+	if (fm_eth->type == FM_ETH_1G_E)
+		dtsec_init_phy(dev);
+
+	if (fm_eth->bus) {
+		phydev = phy_connect(fm_eth->bus, fm_eth->phyaddr, dev,
+					fm_eth->enet_if);
+	}
+
+	if (!phydev) {
+		printf("Failed to connect\n");
+		return -1;
+	}
+
+	if (fm_eth->type == FM_ETH_1G_E) {
+		supported = (SUPPORTED_10baseT_Half |
+				SUPPORTED_10baseT_Full |
+				SUPPORTED_100baseT_Half |
+				SUPPORTED_100baseT_Full |
+				SUPPORTED_1000baseT_Full);
+	} else {
+		supported = SUPPORTED_10000baseT_Full;
+
+		if (tgec_is_fibre(dev))
+			phydev->port = PORT_FIBRE;
+	}
+
+	phydev->supported &= supported;
+	phydev->advertising = phydev->supported;
+
+	fm_eth->phydev = phydev;
+
+	phy_config(phydev);
+#endif
+
+	return 0;
+}
+
+int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info)
+{
+	struct eth_device *dev;
+	struct fm_eth *fm_eth;
+	int i, num = info->num;
+
+	/* alloc eth device */
+	dev = (struct eth_device *)malloc(sizeof(struct eth_device));
+	if (!dev)
+		return 0;
+	memset(dev, 0, sizeof(struct eth_device));
+
+	/* alloc the FMan ethernet private struct */
+	fm_eth = (struct fm_eth *)malloc(sizeof(struct fm_eth));
+	if (!fm_eth)
+		return 0;
+	memset(fm_eth, 0, sizeof(struct fm_eth));
+
+	/* save off some things we need from the info struct */
+	fm_eth->fm_index = info->index - 1; /* keep as 0 based for muram */
+	fm_eth->num = num;
+	fm_eth->type = info->type;
+
+	fm_eth->rx_port = (void *)&reg->port[info->rx_port_id - 1].fm_bmi;
+	fm_eth->tx_port = (void *)&reg->port[info->tx_port_id - 1].fm_bmi;
+
+	/* set the ethernet max receive length */
+	fm_eth->max_rx_len = MAX_RXBUF_LEN;
+
+	/* init global mac structure */
+	if (!fm_eth_init_mac(fm_eth, reg))
+		return 0;
+
+	/* keep same as the manual, we call FMAN1, FMAN2, DTSEC1, DTSEC2, etc */
+	if (fm_eth->type == FM_ETH_1G_E)
+		sprintf(dev->name, "FM%d@DTSEC%d", info->index, num + 1);
+	else
+		sprintf(dev->name, "FM%d@TGEC%d", info->index, num + 1);
+
+	devlist[num_controllers++] = dev;
+	dev->iobase = 0;
+	dev->priv = (void *)fm_eth;
+	dev->init = fm_eth_open;
+	dev->halt = fm_eth_halt;
+	dev->send = fm_eth_send;
+	dev->recv = fm_eth_recv;
+	fm_eth->dev = dev;
+	fm_eth->bus = info->bus;
+	fm_eth->phyaddr = info->phy_addr;
+	fm_eth->enet_if = info->enet_if;
+
+	/* startup the FM im */
+	if (!fm_eth_startup(fm_eth))
+		return 0;
+
+	if (init_phy(dev))
+		return 0;
+
+	/* clear the ethernet address */
+	for (i = 0; i < 6; i++)
+		dev->enetaddr[i] = 0;
+	eth_register(dev);
+
+	return 1;
+}
diff --git a/marvell/uboot/drivers/net/fm/fm.c b/marvell/uboot/drivers/net/fm/fm.c
new file mode 100644
index 0000000..bca20b3
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/fm.c
@@ -0,0 +1,420 @@
+/*
+ * Copyright 2009-2011 Freescale Semiconductor, Inc.
+ *	Dave Liu <daveliu@freescale.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+#include "fm.h"
+#include "../../qe/qe.h"		/* For struct qe_firmware */
+
+#ifdef CONFIG_SYS_QE_FMAN_FW_IN_NAND
+#include <nand.h>
+#elif defined(CONFIG_SYS_QE_FW_IN_SPIFLASH)
+#include <spi_flash.h>
+#elif defined(CONFIG_SYS_QE_FMAN_FW_IN_MMC)
+#include <mmc.h>
+#endif
+
+struct fm_muram muram[CONFIG_SYS_NUM_FMAN];
+
+u32 fm_muram_base(int fm_idx)
+{
+	return muram[fm_idx].base;
+}
+
+u32 fm_muram_alloc(int fm_idx, u32 size, u32 align)
+{
+	u32 ret;
+	u32 align_mask, off;
+	u32 save;
+
+	align_mask = align - 1;
+	save = muram[fm_idx].alloc;
+
+	off = save & align_mask;
+	if (off != 0)
+		muram[fm_idx].alloc += (align - off);
+	off = size & align_mask;
+	if (off != 0)
+		size += (align - off);
+	if ((muram[fm_idx].alloc + size) >= muram[fm_idx].top) {
+		muram[fm_idx].alloc = save;
+		printf("%s: run out of ram.\n", __func__);
+	}
+
+	ret = muram[fm_idx].alloc;
+	muram[fm_idx].alloc += size;
+	memset((void *)ret, 0, size);
+
+	return ret;
+}
+
+static void fm_init_muram(int fm_idx, void *reg)
+{
+	u32 base = (u32)reg;
+
+	muram[fm_idx].base = base;
+	muram[fm_idx].size = CONFIG_SYS_FM_MURAM_SIZE;
+	muram[fm_idx].alloc = base + FM_MURAM_RES_SIZE;
+	muram[fm_idx].top = base + CONFIG_SYS_FM_MURAM_SIZE;
+}
+
+/*
+ * fm_upload_ucode - Fman microcode upload worker function
+ *
+ * This function does the actual uploading of an Fman microcode
+ * to an Fman.
+ */
+static void fm_upload_ucode(int fm_idx, struct fm_imem *imem,
+			    u32 *ucode, unsigned int size)
+{
+	unsigned int i;
+	unsigned int timeout = 1000000;
+
+	/* enable address auto increase */
+	out_be32(&imem->iadd, IRAM_IADD_AIE);
+	/* write microcode to IRAM */
+	for (i = 0; i < size / 4; i++)
+		out_be32(&imem->idata, ucode[i]);
+
+	/* verify if the writing is over */
+	out_be32(&imem->iadd, 0);
+	while ((in_be32(&imem->idata) != ucode[0]) && --timeout)
+		;
+	if (!timeout)
+		printf("Fman%u: microcode upload timeout\n", fm_idx + 1);
+
+	/* enable microcode from IRAM */
+	out_be32(&imem->iready, IRAM_READY);
+}
+
+/*
+ * Upload an Fman firmware
+ *
+ * This function is similar to qe_upload_firmware(), exception that it uploads
+ * a microcode to the Fman instead of the QE.
+ *
+ * Because the process for uploading a microcode to the Fman is similar for
+ * that of the QE, the QE firmware binary format is used for Fman microcode.
+ * It should be possible to unify these two functions, but for now we keep them
+ * separate.
+ */
+static int fman_upload_firmware(int fm_idx,
+				struct fm_imem *fm_imem,
+				const struct qe_firmware *firmware)
+{
+	unsigned int i;
+	u32 crc;
+	size_t calc_size = sizeof(struct qe_firmware);
+	size_t length;
+	const struct qe_header *hdr;
+
+	if (!firmware) {
+		printf("Fman%u: Invalid address for firmware\n", fm_idx + 1);
+		return -EINVAL;
+	}
+
+	hdr = &firmware->header;
+	length = be32_to_cpu(hdr->length);
+
+	/* Check the magic */
+	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
+		(hdr->magic[2] != 'F')) {
+		printf("Fman%u: Data at %p is not a firmware\n", fm_idx + 1,
+		       firmware);
+		return -EPERM;
+	}
+
+	/* Check the version */
+	if (hdr->version != 1) {
+		printf("Fman%u: Unsupported firmware version %u\n", fm_idx + 1,
+		       hdr->version);
+		return -EPERM;
+	}
+
+	/* Validate some of the fields */
+	if ((firmware->count != 1)) {
+		printf("Fman%u: Invalid data in firmware header\n", fm_idx + 1);
+		return -EINVAL;
+	}
+
+	/* Validate the length and check if there's a CRC */
+	calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
+
+	for (i = 0; i < firmware->count; i++)
+		/*
+		 * For situations where the second RISC uses the same microcode
+		 * as the first, the 'code_offset' and 'count' fields will be
+		 * zero, so it's okay to add those.
+		 */
+		calc_size += sizeof(u32) *
+			be32_to_cpu(firmware->microcode[i].count);
+
+	/* Validate the length */
+	if (length != calc_size + sizeof(u32)) {
+		printf("Fman%u: Invalid length in firmware header\n",
+		       fm_idx + 1);
+		return -EPERM;
+	}
+
+	/*
+	 * Validate the CRC.  We would normally call crc32_no_comp(), but that
+	 * function isn't available unless you turn on JFFS support.
+	 */
+	crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size));
+	if (crc != (crc32(-1, (const void *)firmware, calc_size) ^ -1)) {
+		printf("Fman%u: Firmware CRC is invalid\n", fm_idx + 1);
+		return -EIO;
+	}
+
+	/* Loop through each microcode. */
+	for (i = 0; i < firmware->count; i++) {
+		const struct qe_microcode *ucode = &firmware->microcode[i];
+
+		/* Upload a microcode if it's present */
+		if (ucode->code_offset) {
+			u32 ucode_size;
+			u32 *code;
+			printf("Fman%u: Uploading microcode version %u.%u.%u\n",
+			       fm_idx + 1, ucode->major, ucode->minor,
+			       ucode->revision);
+			code = (void *)firmware + ucode->code_offset;
+			ucode_size = sizeof(u32) * ucode->count;
+			fm_upload_ucode(fm_idx, fm_imem, code, ucode_size);
+		}
+	}
+
+	return 0;
+}
+
+static u32 fm_assign_risc(int port_id)
+{
+	u32 risc_sel, val;
+	risc_sel = (port_id & 0x1) ? FMFPPRC_RISC2 : FMFPPRC_RISC1;
+	val = (port_id << FMFPPRC_PORTID_SHIFT) & FMFPPRC_PORTID_MASK;
+	val |= ((risc_sel << FMFPPRC_ORA_SHIFT) | risc_sel);
+
+	return val;
+}
+
+static void fm_init_fpm(struct fm_fpm *fpm)
+{
+	int i, port_id;
+	u32 val;
+
+	setbits_be32(&fpm->fmfpee, FMFPEE_EHM | FMFPEE_UEC |
+				   FMFPEE_CER | FMFPEE_DER);
+
+	/* IM mode, each even port ID to RISC#1, each odd port ID to RISC#2 */
+
+	/* offline/parser port */
+	for (i = 0; i < MAX_NUM_OH_PORT; i++) {
+		port_id = OH_PORT_ID_BASE + i;
+		val = fm_assign_risc(port_id);
+		out_be32(&fpm->fpmprc, val);
+	}
+	/* Rx 1G port */
+	for (i = 0; i < MAX_NUM_RX_PORT_1G; i++) {
+		port_id = RX_PORT_1G_BASE + i;
+		val = fm_assign_risc(port_id);
+		out_be32(&fpm->fpmprc, val);
+	}
+	/* Tx 1G port */
+	for (i = 0; i < MAX_NUM_TX_PORT_1G; i++) {
+		port_id = TX_PORT_1G_BASE + i;
+		val = fm_assign_risc(port_id);
+		out_be32(&fpm->fpmprc, val);
+	}
+	/* Rx 10G port */
+	port_id = RX_PORT_10G_BASE;
+	val = fm_assign_risc(port_id);
+	out_be32(&fpm->fpmprc, val);
+	/* Tx 10G port */
+	port_id = TX_PORT_10G_BASE;
+	val = fm_assign_risc(port_id);
+	out_be32(&fpm->fpmprc, val);
+
+	/* disable the dispatch limit in IM case */
+	out_be32(&fpm->fpmflc, FMFP_FLC_DISP_LIM_NONE);
+	/* clear events */
+	out_be32(&fpm->fmfpee, FMFPEE_CLEAR_EVENT);
+
+	/* clear risc events */
+	for (i = 0; i < 4; i++)
+		out_be32(&fpm->fpmcev[i], 0xffffffff);
+
+	/* clear error */
+	out_be32(&fpm->fpmrcr, FMFP_RCR_MDEC | FMFP_RCR_IDEC);
+}
+
+static int fm_init_bmi(int fm_idx, struct fm_bmi_common *bmi)
+{
+	int blk, i, port_id;
+	u32 val, offset, base;
+
+	/* alloc free buffer pool in MURAM */
+	base = fm_muram_alloc(fm_idx, FM_FREE_POOL_SIZE, FM_FREE_POOL_ALIGN);
+	if (!base) {
+		printf("%s: no muram for free buffer pool\n", __func__);
+		return -ENOMEM;
+	}
+	offset = base - fm_muram_base(fm_idx);
+
+	/* Need 128KB total free buffer pool size */
+	val = offset / 256;
+	blk = FM_FREE_POOL_SIZE / 256;
+	/* in IM, we must not begin from offset 0 in MURAM */
+	val |= ((blk - 1) << FMBM_CFG1_FBPS_SHIFT);
+	out_be32(&bmi->fmbm_cfg1, val);
+
+	/* disable all BMI interrupt */
+	out_be32(&bmi->fmbm_ier, FMBM_IER_DISABLE_ALL);
+
+	/* clear all events */
+	out_be32(&bmi->fmbm_ievr, FMBM_IEVR_CLEAR_ALL);
+
+	/*
+	 * set port parameters - FMBM_PP_x
+	 * max tasks 10G Rx/Tx=12, 1G Rx/Tx 4, others is 1
+	 * max dma 10G Rx/Tx=3, others is 1
+	 * set port FIFO size - FMBM_PFS_x
+	 * 4KB for all Rx and Tx ports
+	 */
+	/* offline/parser port */
+	for (i = 0; i < MAX_NUM_OH_PORT; i++) {
+		port_id = OH_PORT_ID_BASE + i - 1;
+		/* max tasks=1, max dma=1, no extra */
+		out_be32(&bmi->fmbm_pp[port_id], 0);
+		/* port FIFO size - 256 bytes, no extra */
+		out_be32(&bmi->fmbm_pfs[port_id], 0);
+	}
+	/* Rx 1G port */
+	for (i = 0; i < MAX_NUM_RX_PORT_1G; i++) {
+		port_id = RX_PORT_1G_BASE + i - 1;
+		/* max tasks=4, max dma=1, no extra */
+		out_be32(&bmi->fmbm_pp[port_id], FMBM_PP_MXT(4));
+		/* FIFO size - 4KB, no extra */
+		out_be32(&bmi->fmbm_pfs[port_id], FMBM_PFS_IFSZ(0xf));
+	}
+	/* Tx 1G port FIFO size - 4KB, no extra */
+	for (i = 0; i < MAX_NUM_TX_PORT_1G; i++) {
+		port_id = TX_PORT_1G_BASE + i - 1;
+		/* max tasks=4, max dma=1, no extra */
+		out_be32(&bmi->fmbm_pp[port_id], FMBM_PP_MXT(4));
+		/* FIFO size - 4KB, no extra */
+		out_be32(&bmi->fmbm_pfs[port_id], FMBM_PFS_IFSZ(0xf));
+	}
+	/* Rx 10G port */
+	port_id = RX_PORT_10G_BASE - 1;
+	/* max tasks=12, max dma=3, no extra */
+	out_be32(&bmi->fmbm_pp[port_id], FMBM_PP_MXT(12) | FMBM_PP_MXD(3));
+	/* FIFO size - 4KB, no extra */
+	out_be32(&bmi->fmbm_pfs[port_id], FMBM_PFS_IFSZ(0xf));
+
+	/* Tx 10G port */
+	port_id = TX_PORT_10G_BASE - 1;
+	/* max tasks=12, max dma=3, no extra */
+	out_be32(&bmi->fmbm_pp[port_id], FMBM_PP_MXT(12) | FMBM_PP_MXD(3));
+	/* FIFO size - 4KB, no extra */
+	out_be32(&bmi->fmbm_pfs[port_id], FMBM_PFS_IFSZ(0xf));
+
+	/* initialize internal buffers data base (linked list) */
+	out_be32(&bmi->fmbm_init, FMBM_INIT_START);
+
+	return 0;
+}
+
+static void fm_init_qmi(struct fm_qmi_common *qmi)
+{
+	/* disable enqueue and dequeue of QMI */
+	clrbits_be32(&qmi->fmqm_gc, FMQM_GC_ENQ_EN | FMQM_GC_DEQ_EN);
+
+	/* disable all error interrupts */
+	out_be32(&qmi->fmqm_eien, FMQM_EIEN_DISABLE_ALL);
+	/* clear all error events */
+	out_be32(&qmi->fmqm_eie, FMQM_EIE_CLEAR_ALL);
+
+	/* disable all interrupts */
+	out_be32(&qmi->fmqm_ien, FMQM_IEN_DISABLE_ALL);
+	/* clear all interrupts */
+	out_be32(&qmi->fmqm_ie, FMQM_IE_CLEAR_ALL);
+}
+
+/* Init common part of FM, index is fm num# like fm as above */
+int fm_init_common(int index, struct ccsr_fman *reg)
+{
+	int rc;
+#if defined(CONFIG_SYS_QE_FMAN_FW_IN_NOR)
+	void *addr = (void *)CONFIG_SYS_QE_FMAN_FW_ADDR;
+#elif defined(CONFIG_SYS_QE_FMAN_FW_IN_NAND)
+	size_t fw_length = CONFIG_SYS_QE_FMAN_FW_LENGTH;
+	void *addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH);
+
+	rc = nand_read(&nand_info[0], (loff_t)CONFIG_SYS_QE_FMAN_FW_ADDR,
+		       &fw_length, (u_char *)addr);
+	if (rc == -EUCLEAN) {
+		printf("NAND read of FMAN firmware at offset 0x%x failed %d\n",
+			CONFIG_SYS_QE_FMAN_FW_ADDR, rc);
+	}
+#elif defined(CONFIG_SYS_QE_FW_IN_SPIFLASH)
+	struct spi_flash *ucode_flash;
+	void *addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH);
+	int ret = 0;
+
+	ucode_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
+			CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
+	if (!ucode_flash)
+		printf("SF: probe for ucode failed\n");
+	else {
+		ret = spi_flash_read(ucode_flash, CONFIG_SYS_QE_FMAN_FW_ADDR,
+				CONFIG_SYS_QE_FMAN_FW_LENGTH, addr);
+		if (ret)
+			printf("SF: read for ucode failed\n");
+		spi_flash_free(ucode_flash);
+	}
+#elif defined(CONFIG_SYS_QE_FMAN_FW_IN_MMC)
+	int dev = CONFIG_SYS_MMC_ENV_DEV;
+	void *addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH);
+	u32 cnt = CONFIG_SYS_QE_FMAN_FW_LENGTH / 512;
+	u32 blk = CONFIG_SYS_QE_FMAN_FW_ADDR / 512;
+	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
+
+	if (!mmc)
+		printf("\nMMC cannot find device for ucode\n");
+	else {
+		printf("\nMMC read: dev # %u, block # %u, count %u ...\n",
+				dev, blk, cnt);
+		mmc_init(mmc);
+		(void)mmc->block_dev.block_read(dev, blk, cnt, addr);
+		/* flush cache after read */
+		flush_cache((ulong)addr, cnt * 512);
+	}
+#elif defined(CONFIG_SYS_QE_FMAN_FW_IN_REMOTE)
+	void *addr = (void *)CONFIG_SYS_QE_FMAN_FW_ADDR;
+#else
+	void *addr = NULL;
+#endif
+
+	/* Upload the Fman microcode if it's present */
+	rc = fman_upload_firmware(index, &reg->fm_imem, addr);
+	if (rc)
+		return rc;
+	setenv_addr("fman_ucode", addr);
+
+	fm_init_muram(index, &reg->muram);
+	fm_init_qmi(&reg->fm_qmi_common);
+	fm_init_fpm(&reg->fm_fpm);
+
+	/* clear DMA status */
+	setbits_be32(&reg->fm_dma.fmdmsr, FMDMSR_CLEAR_ALL);
+
+	/* set DMA mode */
+	setbits_be32(&reg->fm_dma.fmdmmr, FMDMMR_SBER);
+
+	return fm_init_bmi(index, &reg->fm_bmi_common);
+}
diff --git a/marvell/uboot/drivers/net/fm/fm.h b/marvell/uboot/drivers/net/fm/fm.h
new file mode 100644
index 0000000..43de114
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/fm.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2009-2011 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __FM_H__
+#define __FM_H__
+
+#include <common.h>
+#include <fm_eth.h>
+#include <asm/fsl_enet.h>
+#include <asm/fsl_fman.h>
+
+/* Port ID */
+#define OH_PORT_ID_BASE		0x01
+#define MAX_NUM_OH_PORT		7
+#define RX_PORT_1G_BASE		0x08
+#define MAX_NUM_RX_PORT_1G	CONFIG_SYS_NUM_FM1_DTSEC
+#define RX_PORT_10G_BASE	0x10
+#define RX_PORT_10G_BASE2	0x08
+#define TX_PORT_1G_BASE		0x28
+#define MAX_NUM_TX_PORT_1G	CONFIG_SYS_NUM_FM1_DTSEC
+#define TX_PORT_10G_BASE	0x30
+#define TX_PORT_10G_BASE2	0x28
+#define MIIM_TIMEOUT    0xFFFF
+
+struct fm_muram {
+	u32 base;
+	u32 top;
+	u32 size;
+	u32 alloc;
+};
+#define FM_MURAM_RES_SIZE	0x01000
+
+/* Rx/Tx buffer descriptor */
+struct fm_port_bd {
+	u16 status;
+	u16 len;
+	u32 res0;
+	u16 res1;
+	u16 buf_ptr_hi;
+	u32 buf_ptr_lo;
+};
+
+/* Common BD flags */
+#define BD_LAST			0x0800
+
+/* Rx BD status flags */
+#define RxBD_EMPTY		0x8000
+#define RxBD_LAST		BD_LAST
+#define RxBD_FIRST		0x0400
+#define RxBD_PHYS_ERR		0x0008
+#define RxBD_SIZE_ERR		0x0004
+#define RxBD_ERROR		(RxBD_PHYS_ERR | RxBD_SIZE_ERR)
+
+/* Tx BD status flags */
+#define TxBD_READY		0x8000
+#define TxBD_LAST		BD_LAST
+
+/* Rx/Tx queue descriptor */
+struct fm_port_qd {
+	u16 gen;
+	u16 bd_ring_base_hi;
+	u32 bd_ring_base_lo;
+	u16 bd_ring_size;
+	u16 offset_in;
+	u16 offset_out;
+	u16 res0;
+	u32 res1[0x4];
+};
+
+/* IM global parameter RAM */
+struct fm_port_global_pram {
+	u32 mode;	/* independent mode register */
+	u32 rxqd_ptr;	/* Rx queue descriptor pointer */
+	u32 txqd_ptr;	/* Tx queue descriptor pointer */
+	u16 mrblr;	/* max Rx buffer length */
+	u16 rxqd_bsy_cnt;	/* RxQD busy counter, should be cleared */
+	u32 res0[0x4];
+	struct fm_port_qd rxqd;	/* Rx queue descriptor */
+	struct fm_port_qd txqd;	/* Tx queue descriptor */
+	u32 res1[0x28];
+};
+
+#define FM_PRAM_SIZE		sizeof(struct fm_port_global_pram)
+#define FM_PRAM_ALIGN		256
+#define PRAM_MODE_GLOBAL	0x20000000
+#define PRAM_MODE_GRACEFUL_STOP	0x00800000
+
+#if defined(CONFIG_P1017) || defined(CONFIG_P1023)
+#define FM_FREE_POOL_SIZE	0x2000 /* 8K bytes */
+#else
+#define FM_FREE_POOL_SIZE	0x20000 /* 128K bytes */
+#endif
+#define FM_FREE_POOL_ALIGN	256
+
+u32 fm_muram_alloc(int fm_idx, u32 size, u32 align);
+u32 fm_muram_base(int fm_idx);
+int fm_init_common(int index, struct ccsr_fman *reg);
+int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info);
+phy_interface_t fman_port_enet_if(enum fm_port port);
+void fman_disable_port(enum fm_port port);
+void fman_enable_port(enum fm_port port);
+
+struct fsl_enet_mac {
+	void *base; /* MAC controller registers base address */
+	void *phyregs;
+	int max_rx_len;
+	void (*init_mac)(struct fsl_enet_mac *mac);
+	void (*enable_mac)(struct fsl_enet_mac *mac);
+	void (*disable_mac)(struct fsl_enet_mac *mac);
+	void (*set_mac_addr)(struct fsl_enet_mac *mac, u8 *mac_addr);
+	void (*set_if_mode)(struct fsl_enet_mac *mac, phy_interface_t type,
+				int speed);
+};
+
+/* Fman ethernet private struct */
+struct fm_eth {
+	int fm_index;			/* Fman index */
+	u32 num;			/* 0..n-1 for give type */
+	struct fm_bmi_tx_port *tx_port;
+	struct fm_bmi_rx_port *rx_port;
+	enum fm_eth_type type;		/* 1G or 10G ethernet */
+	phy_interface_t enet_if;
+	struct fsl_enet_mac *mac;	/* MAC controller */
+	struct mii_dev *bus;
+	struct phy_device *phydev;
+	int phyaddr;
+	struct eth_device *dev;
+	int max_rx_len;
+	struct fm_port_global_pram *rx_pram; /* Rx parameter table */
+	struct fm_port_global_pram *tx_pram; /* Tx parameter table */
+	void *rx_bd_ring;		/* Rx BD ring base */
+	void *cur_rxbd;			/* current Rx BD */
+	void *rx_buf;			/* Rx buffer base */
+	void *tx_bd_ring;		/* Tx BD ring base */
+	void *cur_txbd;			/* current Tx BD */
+};
+
+#define RX_BD_RING_SIZE		8
+#define TX_BD_RING_SIZE		8
+#define MAX_RXBUF_LOG2		11
+#define MAX_RXBUF_LEN		(1 << MAX_RXBUF_LOG2)
+
+#define PORT_IS_ENABLED(port)	fm_info[fm_port_to_index(port)].enabled
+
+#endif /* __FM_H__ */
diff --git a/marvell/uboot/drivers/net/fm/init.c b/marvell/uboot/drivers/net/fm/init.c
new file mode 100644
index 0000000..74c72d3
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/init.c
@@ -0,0 +1,389 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <asm/fsl_serdes.h>
+
+#include "fm.h"
+
+struct fm_eth_info fm_info[] = {
+#if (CONFIG_SYS_NUM_FM1_DTSEC >= 1)
+	FM_DTSEC_INFO_INITIALIZER(1, 1),
+#endif
+#if (CONFIG_SYS_NUM_FM1_DTSEC >= 2)
+	FM_DTSEC_INFO_INITIALIZER(1, 2),
+#endif
+#if (CONFIG_SYS_NUM_FM1_DTSEC >= 3)
+	FM_DTSEC_INFO_INITIALIZER(1, 3),
+#endif
+#if (CONFIG_SYS_NUM_FM1_DTSEC >= 4)
+	FM_DTSEC_INFO_INITIALIZER(1, 4),
+#endif
+#if (CONFIG_SYS_NUM_FM1_DTSEC >= 5)
+	FM_DTSEC_INFO_INITIALIZER(1, 5),
+#endif
+#if (CONFIG_SYS_NUM_FM1_DTSEC >= 6)
+	FM_DTSEC_INFO_INITIALIZER(1, 6),
+#endif
+#if (CONFIG_SYS_NUM_FM1_DTSEC >= 7)
+	FM_DTSEC_INFO_INITIALIZER(1, 9),
+#endif
+#if (CONFIG_SYS_NUM_FM1_DTSEC >= 8)
+	FM_DTSEC_INFO_INITIALIZER(1, 10),
+#endif
+#if (CONFIG_SYS_NUM_FM2_DTSEC >= 1)
+	FM_DTSEC_INFO_INITIALIZER(2, 1),
+#endif
+#if (CONFIG_SYS_NUM_FM2_DTSEC >= 2)
+	FM_DTSEC_INFO_INITIALIZER(2, 2),
+#endif
+#if (CONFIG_SYS_NUM_FM2_DTSEC >= 3)
+	FM_DTSEC_INFO_INITIALIZER(2, 3),
+#endif
+#if (CONFIG_SYS_NUM_FM2_DTSEC >= 4)
+	FM_DTSEC_INFO_INITIALIZER(2, 4),
+#endif
+#if (CONFIG_SYS_NUM_FM2_DTSEC >= 5)
+	FM_DTSEC_INFO_INITIALIZER(2, 5),
+#endif
+#if (CONFIG_SYS_NUM_FM2_DTSEC >= 6)
+	FM_DTSEC_INFO_INITIALIZER(2, 6),
+#endif
+#if (CONFIG_SYS_NUM_FM2_DTSEC >= 7)
+	FM_DTSEC_INFO_INITIALIZER(2, 9),
+#endif
+#if (CONFIG_SYS_NUM_FM2_DTSEC >= 8)
+	FM_DTSEC_INFO_INITIALIZER(2, 10),
+#endif
+#if (CONFIG_SYS_NUM_FM1_10GEC >= 1)
+	FM_TGEC_INFO_INITIALIZER(1, 1),
+#endif
+#if (CONFIG_SYS_NUM_FM1_10GEC >= 2)
+	FM_TGEC_INFO_INITIALIZER(1, 2),
+#endif
+#if (CONFIG_SYS_NUM_FM1_10GEC >= 3)
+	FM_TGEC_INFO_INITIALIZER2(1, 3),
+#endif
+#if (CONFIG_SYS_NUM_FM1_10GEC >= 4)
+	FM_TGEC_INFO_INITIALIZER2(1, 4),
+#endif
+#if (CONFIG_SYS_NUM_FM2_10GEC >= 1)
+	FM_TGEC_INFO_INITIALIZER(2, 1),
+#endif
+#if (CONFIG_SYS_NUM_FM2_10GEC >= 2)
+	FM_TGEC_INFO_INITIALIZER(2, 2),
+#endif
+};
+
+int fm_standard_init(bd_t *bis)
+{
+	int i;
+	struct ccsr_fman *reg;
+
+	reg = (void *)CONFIG_SYS_FSL_FM1_ADDR;
+	if (fm_init_common(0, reg))
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(fm_info); i++) {
+		if ((fm_info[i].enabled) && (fm_info[i].index == 1))
+			fm_eth_initialize(reg, &fm_info[i]);
+	}
+
+#if (CONFIG_SYS_NUM_FMAN == 2)
+	reg = (void *)CONFIG_SYS_FSL_FM2_ADDR;
+	if (fm_init_common(1, reg))
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(fm_info); i++) {
+		if ((fm_info[i].enabled) && (fm_info[i].index == 2))
+			fm_eth_initialize(reg, &fm_info[i]);
+	}
+#endif
+
+	return 1;
+}
+
+/* simple linear search to map from port to array index */
+static int fm_port_to_index(enum fm_port port)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(fm_info); i++) {
+		if (fm_info[i].port == port)
+			return i;
+	}
+
+	return -1;
+}
+
+/*
+ * Determine if an interface is actually active based on HW config
+ * we expect fman_port_enet_if() to report PHY_INTERFACE_MODE_NONE if
+ * the interface is not active based on HW cfg of the SoC
+ */
+void fman_enet_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(fm_info); i++) {
+		phy_interface_t enet_if;
+
+		enet_if = fman_port_enet_if(fm_info[i].port);
+		if (enet_if != PHY_INTERFACE_MODE_NONE) {
+			fm_info[i].enabled = 1;
+			fm_info[i].enet_if = enet_if;
+		} else {
+			fm_info[i].enabled = 0;
+		}
+	}
+
+	return ;
+}
+
+void fm_disable_port(enum fm_port port)
+{
+	int i = fm_port_to_index(port);
+
+	fm_info[i].enabled = 0;
+	fman_disable_port(port);
+}
+
+void fm_enable_port(enum fm_port port)
+{
+	int i = fm_port_to_index(port);
+
+	fm_info[i].enabled = 1;
+	fman_enable_port(port);
+}
+
+void fm_info_set_mdio(enum fm_port port, struct mii_dev *bus)
+{
+	int i = fm_port_to_index(port);
+
+	if (i == -1)
+		return;
+
+	fm_info[i].bus = bus;
+}
+
+void fm_info_set_phy_address(enum fm_port port, int address)
+{
+	int i = fm_port_to_index(port);
+
+	if (i == -1)
+		return;
+
+	fm_info[i].phy_addr = address;
+}
+
+/*
+ * Returns the PHY address for a given Fman port
+ *
+ * The port must be set via a prior call to fm_info_set_phy_address().
+ * A negative error code is returned if the port is invalid.
+ */
+int fm_info_get_phy_address(enum fm_port port)
+{
+	int i = fm_port_to_index(port);
+
+	if (i == -1)
+		return -1;
+
+	return fm_info[i].phy_addr;
+}
+
+/*
+ * Returns the type of the data interface between the given MAC and its PHY.
+ * This is typically determined by the RCW.
+ */
+phy_interface_t fm_info_get_enet_if(enum fm_port port)
+{
+	int i = fm_port_to_index(port);
+
+	if (i == -1)
+		return PHY_INTERFACE_MODE_NONE;
+
+	if (fm_info[i].enabled)
+		return fm_info[i].enet_if;
+
+	return PHY_INTERFACE_MODE_NONE;
+}
+
+static void
+__def_board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa,
+				enum fm_port port, int offset)
+{
+	return ;
+}
+
+void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa,
+				enum fm_port port, int offset)
+	 __attribute__((weak, alias("__def_board_ft_fman_fixup_port")));
+
+static void ft_fixup_port(void *blob, struct fm_eth_info *info, char *prop)
+{
+	int off;
+	uint32_t ph;
+	phys_addr_t paddr = CONFIG_SYS_CCSRBAR_PHYS + info->compat_offset;
+	u64 dtsec1_addr = (u64)CONFIG_SYS_CCSRBAR_PHYS +
+				CONFIG_SYS_FSL_FM1_DTSEC1_OFFSET;
+
+	off = fdt_node_offset_by_compat_reg(blob, prop, paddr);
+
+	if (info->enabled) {
+		fdt_fixup_phy_connection(blob, off, info->enet_if);
+		board_ft_fman_fixup_port(blob, prop, paddr, info->port, off);
+		return ;
+	}
+
+#ifdef CONFIG_SYS_FMAN_V3
+	/*
+	 * Physically FM1_DTSEC9 and FM1_10GEC1 use the same dual-role MAC, when
+	 * FM1_10GEC1 is enabled and  FM1_DTSEC9 is disabled, ensure that the
+	 * dual-role MAC is not disabled, ditto for other dual-role MACs.
+	 */
+	if (((info->port == FM1_DTSEC9) && (PORT_IS_ENABLED(FM1_10GEC1)))  ||
+	    ((info->port == FM1_DTSEC10) && (PORT_IS_ENABLED(FM1_10GEC2))) ||
+	    ((info->port == FM1_DTSEC1) && (PORT_IS_ENABLED(FM1_10GEC3)))  ||
+	    ((info->port == FM1_DTSEC2) && (PORT_IS_ENABLED(FM1_10GEC4)))  ||
+	    ((info->port == FM1_10GEC1) && (PORT_IS_ENABLED(FM1_DTSEC9)))  ||
+	    ((info->port == FM1_10GEC2) && (PORT_IS_ENABLED(FM1_DTSEC10))) ||
+	    ((info->port == FM1_10GEC3) && (PORT_IS_ENABLED(FM1_DTSEC1)))  ||
+	    ((info->port == FM1_10GEC4) && (PORT_IS_ENABLED(FM1_DTSEC2)))
+#if (CONFIG_SYS_NUM_FMAN == 2)
+										||
+	    ((info->port == FM2_DTSEC9) && (PORT_IS_ENABLED(FM2_10GEC1)))	||
+	    ((info->port == FM2_DTSEC10) && (PORT_IS_ENABLED(FM2_10GEC2)))	||
+	    ((info->port == FM2_10GEC1) && (PORT_IS_ENABLED(FM2_DTSEC9)))	||
+	    ((info->port == FM2_10GEC2) && (PORT_IS_ENABLED(FM2_DTSEC10)))
+#endif
+	)
+		return;
+#endif
+	/* board code might have caused offset to change */
+	off = fdt_node_offset_by_compat_reg(blob, prop, paddr);
+
+	/* Don't disable FM1-DTSEC1 MAC as its used for MDIO */
+	if (paddr != dtsec1_addr)
+		fdt_status_disabled(blob, off); /* disable the MAC node */
+
+	/* disable the fsl,dpa-ethernet node that points to the MAC */
+	ph = fdt_get_phandle(blob, off);
+	do_fixup_by_prop(blob, "fsl,fman-mac", &ph, sizeof(ph),
+		"status", "disabled", strlen("disabled") + 1, 1);
+}
+
+#ifdef CONFIG_SYS_FMAN_V3
+static int ft_fixup_xgec(void *blob, struct fm_eth_info *info)
+{
+	int off, i, ci;
+#define FM1_10GEC3_RX_PORT_ADDR	(CONFIG_SYS_CCSRBAR_PHYS + 0x488000)
+#define FM1_10GEC3_TX_PORT_ADDR	(CONFIG_SYS_CCSRBAR_PHYS + 0x4a8000)
+#define FM1_10GEC3_MAC_ADDR	(CONFIG_SYS_CCSRBAR_PHYS + 0x4e0000)
+
+	if ((info->port == FM1_10GEC3) || (info->port == FM1_10GEC4)) {
+		ci = (info->port == FM1_10GEC3) ? 2 : 3;
+		i = (info->port == FM1_10GEC3) ? 0 : 1;
+
+		off = fdt_node_offset_by_compat_reg(blob, "fsl,fman-port-1g-rx",
+						    FM1_10GEC3_RX_PORT_ADDR +
+						    i * 0x1000);
+		if (off > 0) {
+			fdt_setprop(blob, off, "cell-index", &ci, sizeof(int));
+			fdt_setprop(blob, off, "compatible",
+				    "fsl,fman-port-10g-rx", 20);
+		} else {
+			goto err;
+		}
+
+		off = fdt_node_offset_by_compat_reg(blob, "fsl,fman-port-1g-tx",
+						    FM1_10GEC3_TX_PORT_ADDR +
+						    i * 0x1000);
+		if (off > 0) {
+			fdt_setprop(blob, off, "cell-index", &ci, sizeof(int));
+			fdt_setprop(blob, off, "compatible",
+				    "fsl,fman-port-10g-tx", 20);
+		} else {
+			goto err;
+		}
+
+		off = fdt_node_offset_by_compat_reg(blob, "fsl,fman-memac",
+						    FM1_10GEC3_MAC_ADDR +
+						    i * 0x2000);
+		if (off > 0)
+			fdt_setprop(blob, off, "cell-index", &ci, sizeof(int));
+		else
+			goto err;
+	}
+	return 0;
+err:
+	printf("WARNING: Fail to find the node\n");
+	return -1;
+}
+#endif
+
+void fdt_fixup_fman_ethernet(void *blob)
+{
+	int i;
+
+#ifdef CONFIG_SYS_FMAN_V3
+	for (i = 0; i < ARRAY_SIZE(fm_info); i++) {
+		ft_fixup_port(blob, &fm_info[i], "fsl,fman-memac");
+		ft_fixup_xgec(blob, &fm_info[i]);
+	}
+#else
+	for (i = 0; i < ARRAY_SIZE(fm_info); i++) {
+		if (fm_info[i].type == FM_ETH_1G_E)
+			ft_fixup_port(blob, &fm_info[i], "fsl,fman-1g-mac");
+		else
+			ft_fixup_port(blob, &fm_info[i], "fsl,fman-10g-mac");
+	}
+#endif
+}
+
+/*QSGMII Riser Card can work in SGMII mode, but the PHY address is different.
+ *This function scans which Riser Card being used(QSGMII or SGMII Riser Card),
+ *then set the correct PHY address
+ */
+void set_sgmii_phy(struct mii_dev *bus, enum fm_port base_port,
+		unsigned int port_num, int phy_base_addr)
+{
+	unsigned int regnum = 0;
+	int qsgmii;
+	int i;
+	int phy_real_addr;
+
+	qsgmii = is_qsgmii_riser_card(bus, phy_base_addr, port_num, regnum);
+
+	if (!qsgmii)
+		return;
+
+	for (i = base_port; i < base_port + port_num; i++) {
+		if (fm_info_get_enet_if(i) == PHY_INTERFACE_MODE_SGMII) {
+			phy_real_addr = phy_base_addr + i - base_port;
+			fm_info_set_phy_address(i, phy_real_addr);
+		}
+	}
+}
+
+/*to check whether qsgmii riser card is used*/
+int is_qsgmii_riser_card(struct mii_dev *bus, int phy_base_addr,
+		unsigned int port_num, unsigned regnum)
+{
+	int i;
+	int val;
+
+	if (!bus)
+		return 0;
+
+	for (i = phy_base_addr; i < phy_base_addr + port_num; i++) {
+		val = bus->read(bus, i, MDIO_DEVAD_NONE, regnum);
+		if (val != MIIM_TIMEOUT)
+			return 1;
+	}
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/fm/memac.c b/marvell/uboot/drivers/net/fm/memac.c
new file mode 100644
index 0000000..592a67f
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/memac.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *	Roy Zang <tie-fei.zang@freescale.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/* MAXFRM - maximum frame length */
+#define MAXFRM_MASK	0x0000ffff
+
+#include <common.h>
+#include <phy.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/fsl_enet.h>
+#include <asm/fsl_memac.h>
+
+#include "fm.h"
+
+static void memac_init_mac(struct fsl_enet_mac *mac)
+{
+	struct memac *regs = mac->base;
+
+	/* mask all interrupt */
+	out_be32(&regs->imask, IMASK_MASK_ALL);
+
+	/* clear all events */
+	out_be32(&regs->ievent, IEVENT_CLEAR_ALL);
+
+	/* set the max receive length */
+	out_be32(&regs->maxfrm, mac->max_rx_len & MAXFRM_MASK);
+
+	/* multicast frame reception for the hash entry disable */
+	out_be32(&regs->hashtable_ctrl, 0);
+}
+
+static void memac_enable_mac(struct fsl_enet_mac *mac)
+{
+	struct memac *regs = mac->base;
+
+	setbits_be32(&regs->command_config, MEMAC_CMD_CFG_RXTX_EN);
+}
+
+static void memac_disable_mac(struct fsl_enet_mac *mac)
+{
+	struct memac *regs = mac->base;
+
+	clrbits_be32(&regs->command_config, MEMAC_CMD_CFG_RXTX_EN);
+}
+
+static void memac_set_mac_addr(struct fsl_enet_mac *mac, u8 *mac_addr)
+{
+	struct memac *regs = mac->base;
+	u32 mac_addr0, mac_addr1;
+
+	/*
+	 * if a station address of 0x12345678ABCD, perform a write to
+	 * MAC_ADDR0 of 0x78563412, MAC_ADDR1 of 0x0000CDAB
+	 */
+	mac_addr0 = (mac_addr[3] << 24) | (mac_addr[2] << 16) | \
+			(mac_addr[1] << 8)  | (mac_addr[0]);
+	out_be32(&regs->mac_addr_0, mac_addr0);
+
+	mac_addr1 = ((mac_addr[5] << 8) | mac_addr[4]) & 0x0000ffff;
+	out_be32(&regs->mac_addr_1, mac_addr1);
+}
+
+static void memac_set_interface_mode(struct fsl_enet_mac *mac,
+					phy_interface_t type, int speed)
+{
+	/* Roy need more work here */
+
+	struct memac *regs = mac->base;
+	u32 if_mode, if_status;
+
+	/* clear all bits relative with interface mode */
+	if_mode = in_be32(&regs->if_mode);
+	if_status = in_be32(&regs->if_status);
+
+	/* set interface mode */
+	switch (type) {
+	case PHY_INTERFACE_MODE_GMII:
+		if_mode &= ~IF_MODE_MASK;
+		if_mode |= IF_MODE_GMII;
+		break;
+	case PHY_INTERFACE_MODE_RGMII:
+		if_mode |= (IF_MODE_GMII | IF_MODE_RG);
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		if_mode |= (IF_MODE_GMII | IF_MODE_RM);
+		break;
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_QSGMII:
+		if_mode &= ~IF_MODE_MASK;
+		if_mode |= (IF_MODE_GMII);
+		break;
+	default:
+		break;
+	}
+	/* Enable automatic speed selection */
+	if_mode |= IF_MODE_EN_AUTO;
+
+	if (type == PHY_INTERFACE_MODE_RGMII) {
+		if_mode &= ~IF_MODE_EN_AUTO;
+		if_mode &= ~IF_MODE_SETSP_MASK;
+		switch (speed) {
+		case SPEED_1000:
+			if_mode |= IF_MODE_SETSP_1000M;
+			break;
+		case SPEED_100:
+			if_mode |= IF_MODE_SETSP_100M;
+			break;
+		case SPEED_10:
+			if_mode |= IF_MODE_SETSP_10M;
+		default:
+			break;
+		}
+	}
+
+	debug(" %s, if_mode = %x\n", __func__,  if_mode);
+	debug(" %s, if_status = %x\n", __func__,  if_status);
+	out_be32(&regs->if_mode, if_mode);
+	return;
+}
+
+void init_memac(struct fsl_enet_mac *mac, void *base,
+		void *phyregs, int max_rx_len)
+{
+	mac->base = base;
+	mac->phyregs = phyregs;
+	mac->max_rx_len = max_rx_len;
+	mac->init_mac = memac_init_mac;
+	mac->enable_mac = memac_enable_mac;
+	mac->disable_mac = memac_disable_mac;
+	mac->set_mac_addr = memac_set_mac_addr;
+	mac->set_if_mode = memac_set_interface_mode;
+}
diff --git a/marvell/uboot/drivers/net/fm/memac_phy.c b/marvell/uboot/drivers/net/fm/memac_phy.c
new file mode 100644
index 0000000..140e59b
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/memac_phy.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *	Andy Fleming <afleming@freescale.com>
+ *	Roy Zang <tie-fei.zang@freescale.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ * Some part is taken from tsec.c
+ */
+#include <common.h>
+#include <miiphy.h>
+#include <phy.h>
+#include <asm/io.h>
+#include <asm/fsl_memac.h>
+#include <fm_eth.h>
+
+/*
+ * Write value to the PHY for this device to the register at regnum, waiting
+ * until the write is done before it returns.  All PHY configuration has to be
+ * done through the TSEC1 MIIM regs
+ */
+int memac_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr,
+			int regnum, u16 value)
+{
+	u32 mdio_ctl;
+	struct memac_mdio_controller *regs = bus->priv;
+	u32 c45 = 1; /* Default to 10G interface */
+
+	if (dev_addr == MDIO_DEVAD_NONE) {
+		c45 = 0; /* clause 22 */
+		dev_addr = regnum & 0x1f;
+		clrbits_be32(&regs->mdio_stat, MDIO_STAT_ENC);
+	} else {
+		setbits_be32(&regs->mdio_stat, MDIO_STAT_ENC);
+		setbits_be32(&regs->mdio_stat, MDIO_STAT_HOLD_15_CLK);
+	}
+
+	/* Wait till the bus is free */
+	while ((in_be32(&regs->mdio_stat)) & MDIO_STAT_BSY)
+		;
+
+	/* Set the port and dev addr */
+	mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr);
+	out_be32(&regs->mdio_ctl, mdio_ctl);
+
+	/* Set the register address */
+	if (c45)
+		out_be32(&regs->mdio_addr, regnum & 0xffff);
+
+	/* Wait till the bus is free */
+	while ((in_be32(&regs->mdio_stat)) & MDIO_STAT_BSY)
+		;
+
+	/* Write the value to the register */
+	out_be32(&regs->mdio_data, MDIO_DATA(value));
+
+	/* Wait till the MDIO write is complete */
+	while ((in_be32(&regs->mdio_data)) & MDIO_DATA_BSY)
+		;
+
+	return 0;
+}
+
+/*
+ * Reads from register regnum in the PHY for device dev, returning the value.
+ * Clears miimcom first.  All PHY configuration has to be done through the
+ * TSEC1 MIIM regs
+ */
+int memac_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr,
+			int regnum)
+{
+	u32 mdio_ctl;
+	struct memac_mdio_controller *regs = bus->priv;
+	u32 c45 = 1;
+
+	if (dev_addr == MDIO_DEVAD_NONE) {
+		c45 = 0; /* clause 22 */
+		dev_addr = regnum & 0x1f;
+		clrbits_be32(&regs->mdio_stat, MDIO_STAT_ENC);
+	} else {
+		setbits_be32(&regs->mdio_stat, MDIO_STAT_ENC);
+		setbits_be32(&regs->mdio_stat, MDIO_STAT_HOLD_15_CLK);
+	}
+
+	/* Wait till the bus is free */
+	while ((in_be32(&regs->mdio_stat)) & MDIO_STAT_BSY)
+		;
+
+	/* Set the Port and Device Addrs */
+	mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr);
+	out_be32(&regs->mdio_ctl, mdio_ctl);
+
+	/* Set the register address */
+	if (c45)
+		out_be32(&regs->mdio_addr, regnum & 0xffff);
+
+	/* Wait till the bus is free */
+	while ((in_be32(&regs->mdio_stat)) & MDIO_STAT_BSY)
+		;
+
+	/* Initiate the read */
+	mdio_ctl |= MDIO_CTL_READ;
+	out_be32(&regs->mdio_ctl, mdio_ctl);
+
+	/* Wait till the MDIO write is complete */
+	while ((in_be32(&regs->mdio_data)) & MDIO_DATA_BSY)
+		;
+
+	/* Return all Fs if nothing was there */
+	if (in_be32(&regs->mdio_stat) & MDIO_STAT_RD_ER)
+		return 0xffff;
+
+	return in_be32(&regs->mdio_data) & 0xffff;
+}
+
+int memac_mdio_reset(struct mii_dev *bus)
+{
+	return 0;
+}
+
+int fm_memac_mdio_init(bd_t *bis, struct memac_mdio_info *info)
+{
+	struct mii_dev *bus = mdio_alloc();
+
+	if (!bus) {
+		printf("Failed to allocate FM TGEC MDIO bus\n");
+		return -1;
+	}
+
+	bus->read = memac_mdio_read;
+	bus->write = memac_mdio_write;
+	bus->reset = memac_mdio_reset;
+	sprintf(bus->name, info->name);
+
+	bus->priv = info->regs;
+
+	return mdio_register(bus);
+}
diff --git a/marvell/uboot/drivers/net/fm/p1023.c b/marvell/uboot/drivers/net/fm/p1023.c
new file mode 100644
index 0000000..b25d10a
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/p1023.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <phy.h>
+#include <fm_eth.h>
+#include <asm/io.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_serdes.h>
+
+static u32 port_to_devdisr[] = {
+	[FM1_DTSEC1] = MPC85xx_DEVDISR_TSEC1,
+	[FM1_DTSEC2] = MPC85xx_DEVDISR_TSEC2,
+};
+
+static int is_device_disabled(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+	u32 devdisr = in_be32(&gur->devdisr);
+
+	return port_to_devdisr[port] & devdisr;
+}
+
+void fman_disable_port(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+	/* don't allow disabling of DTSEC1 as its needed for MDIO */
+	if (port == FM1_DTSEC1)
+		return;
+
+	setbits_be32(&gur->devdisr, port_to_devdisr[port]);
+}
+
+void fman_enable_port(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+	clrbits_be32(&gur->devdisr, port_to_devdisr[port]);
+}
+
+phy_interface_t fman_port_enet_if(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+	u32 pordevsr = in_be32(&gur->pordevsr);
+
+	if (is_device_disabled(port))
+		return PHY_INTERFACE_MODE_NONE;
+
+	/* DTSEC1 can be SGMII, RGMII or RMII */
+	if (port == FM1_DTSEC1) {
+		if (is_serdes_configured(SGMII_FM1_DTSEC1))
+			return PHY_INTERFACE_MODE_SGMII;
+		if (pordevsr & MPC85xx_PORDEVSR_SGMII1_DIS) {
+			if (pordevsr & MPC85xx_PORDEVSR_TSEC1_PRTC)
+				return PHY_INTERFACE_MODE_RGMII;
+			else
+				return PHY_INTERFACE_MODE_RMII;
+		}
+	}
+
+	/* DTSEC2 only supports SGMII or RGMII */
+	if (port == FM1_DTSEC2) {
+		if (is_serdes_configured(SGMII_FM1_DTSEC2))
+			return PHY_INTERFACE_MODE_SGMII;
+		if (pordevsr & MPC85xx_PORDEVSR_SGMII2_DIS)
+			return PHY_INTERFACE_MODE_RGMII;
+	}
+
+	return PHY_INTERFACE_MODE_NONE;
+}
diff --git a/marvell/uboot/drivers/net/fm/p4080.c b/marvell/uboot/drivers/net/fm/p4080.c
new file mode 100644
index 0000000..de71911
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/p4080.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <phy.h>
+#include <fm_eth.h>
+#include <asm/io.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_serdes.h>
+
+static u32 port_to_devdisr[] = {
+	[FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1,
+	[FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2,
+	[FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3,
+	[FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4,
+	[FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1,
+	[FM2_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC2_1,
+	[FM2_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC2_2,
+	[FM2_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC2_3,
+	[FM2_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC2_4,
+	[FM2_10GEC1] = FSL_CORENET_DEVDISR2_10GEC2,
+};
+
+static int is_device_disabled(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+	u32 devdisr2 = in_be32(&gur->devdisr2);
+
+	return port_to_devdisr[port] & devdisr2;
+}
+
+void fman_disable_port(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+	/* don't allow disabling of DTSEC1 as its needed for MDIO */
+	if (port == FM1_DTSEC1)
+		return;
+
+	setbits_be32(&gur->devdisr2, port_to_devdisr[port]);
+}
+
+void fman_enable_port(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+	clrbits_be32(&gur->devdisr2, port_to_devdisr[port]);
+}
+
+phy_interface_t fman_port_enet_if(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+	u32 rcwsr11 = in_be32(&gur->rcwsr[11]);
+
+	if (is_device_disabled(port))
+		return PHY_INTERFACE_MODE_NONE;
+
+	if ((port == FM1_10GEC1) && (is_serdes_configured(XAUI_FM1)))
+		return PHY_INTERFACE_MODE_XGMII;
+
+	if ((port == FM2_10GEC1) && (is_serdes_configured(XAUI_FM2)))
+		return PHY_INTERFACE_MODE_XGMII;
+
+	/* handle RGMII first */
+	if ((port == FM1_DTSEC1) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) ==
+		FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1))
+		return PHY_INTERFACE_MODE_RGMII;
+
+	if ((port == FM1_DTSEC2) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) ==
+		FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2))
+		return PHY_INTERFACE_MODE_RGMII;
+
+	if ((port == FM2_DTSEC1) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) ==
+		FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1))
+		return PHY_INTERFACE_MODE_RGMII;
+
+	switch (port) {
+	case FM1_DTSEC1:
+	case FM1_DTSEC2:
+	case FM1_DTSEC3:
+	case FM1_DTSEC4:
+		if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1))
+			return PHY_INTERFACE_MODE_SGMII;
+		break;
+	case FM2_DTSEC1:
+	case FM2_DTSEC2:
+	case FM2_DTSEC3:
+	case FM2_DTSEC4:
+		if (is_serdes_configured(SGMII_FM2_DTSEC1 + port - FM2_DTSEC1))
+			return PHY_INTERFACE_MODE_SGMII;
+		break;
+	default:
+		return PHY_INTERFACE_MODE_NONE;
+	}
+
+	return PHY_INTERFACE_MODE_NONE;
+}
diff --git a/marvell/uboot/drivers/net/fm/p5020.c b/marvell/uboot/drivers/net/fm/p5020.c
new file mode 100644
index 0000000..5c158cd
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/p5020.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <phy.h>
+#include <fm_eth.h>
+#include <asm/io.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_serdes.h>
+
+static u32 port_to_devdisr[] = {
+	[FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1,
+	[FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2,
+	[FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3,
+	[FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4,
+	[FM1_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC1_5,
+	[FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1,
+};
+
+static int is_device_disabled(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+	u32 devdisr2 = in_be32(&gur->devdisr2);
+
+	return port_to_devdisr[port] & devdisr2;
+}
+
+void fman_disable_port(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+	/* don't allow disabling of DTSEC1 as its needed for MDIO */
+	if (port == FM1_DTSEC1)
+		return;
+
+	setbits_be32(&gur->devdisr2, port_to_devdisr[port]);
+}
+
+void fman_enable_port(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+	clrbits_be32(&gur->devdisr2, port_to_devdisr[port]);
+}
+
+phy_interface_t fman_port_enet_if(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+	u32 rcwsr11 = in_be32(&gur->rcwsr[11]);
+
+	if (is_device_disabled(port))
+		return PHY_INTERFACE_MODE_NONE;
+
+	if ((port == FM1_10GEC1) && (is_serdes_configured(XAUI_FM1)))
+		return PHY_INTERFACE_MODE_XGMII;
+
+	/* handle RGMII first */
+	if ((port == FM1_DTSEC4) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) ==
+		FSL_CORENET_RCWSR11_EC1_FM1_DTSEC4_RGMII))
+		return PHY_INTERFACE_MODE_RGMII;
+
+	if ((port == FM1_DTSEC4) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) ==
+		FSL_CORENET_RCWSR11_EC1_FM1_DTSEC4_MII))
+		return PHY_INTERFACE_MODE_MII;
+
+	if ((port == FM1_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) ==
+		FSL_CORENET_RCWSR11_EC2_FM1_DTSEC5_RGMII))
+		return PHY_INTERFACE_MODE_RGMII;
+
+	if ((port == FM1_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) ==
+		FSL_CORENET_RCWSR11_EC2_FM1_DTSEC5_MII))
+		return PHY_INTERFACE_MODE_MII;
+
+	switch (port) {
+	case FM1_DTSEC1:
+	case FM1_DTSEC2:
+	case FM1_DTSEC3:
+	case FM1_DTSEC4:
+	case FM1_DTSEC5:
+		if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1))
+			return PHY_INTERFACE_MODE_SGMII;
+		break;
+	default:
+		return PHY_INTERFACE_MODE_NONE;
+	}
+
+	return PHY_INTERFACE_MODE_NONE;
+}
diff --git a/marvell/uboot/drivers/net/fm/p5040.c b/marvell/uboot/drivers/net/fm/p5040.c
new file mode 100644
index 0000000..403d7d7
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/p5040.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <phy.h>
+#include <fm_eth.h>
+#include <asm/io.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_serdes.h>
+
+u32 port_to_devdisr[] = {
+	[FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1,
+	[FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2,
+	[FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3,
+	[FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4,
+	[FM1_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC1_5,
+	[FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1,
+	[FM2_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC2_1,
+	[FM2_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC2_2,
+	[FM2_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC2_3,
+	[FM2_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC2_4,
+	[FM2_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC2_5,
+	[FM2_10GEC1] = FSL_CORENET_DEVDISR2_10GEC2,
+};
+
+static int is_device_disabled(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+	u32 devdisr2 = in_be32(&gur->devdisr2);
+
+	return port_to_devdisr[port] & devdisr2;
+}
+
+void fman_disable_port(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+	/* don't allow disabling of DTSEC1 as its needed for MDIO */
+	if (port == FM1_DTSEC1)
+		return;
+
+	setbits_be32(&gur->devdisr2, port_to_devdisr[port]);
+}
+
+void fman_enable_port(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+	clrbits_be32(&gur->devdisr2, port_to_devdisr[port]);
+}
+
+phy_interface_t fman_port_enet_if(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+	u32 rcwsr11 = in_be32(&gur->rcwsr[11]);
+
+	if (is_device_disabled(port))
+		return PHY_INTERFACE_MODE_NONE;
+
+	if ((port == FM1_10GEC1) && (is_serdes_configured(XAUI_FM1)))
+		return PHY_INTERFACE_MODE_XGMII;
+
+	if ((port == FM2_10GEC1) && (is_serdes_configured(XAUI_FM2)))
+		return PHY_INTERFACE_MODE_XGMII;
+
+	/* handle RGMII first */
+	if ((port == FM1_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) ==
+		FSL_CORENET_RCWSR11_EC1_FM1_DTSEC5_RGMII))
+		return PHY_INTERFACE_MODE_RGMII;
+
+	if ((port == FM1_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) ==
+		FSL_CORENET_RCWSR11_EC1_FM1_DTSEC5_MII))
+		return PHY_INTERFACE_MODE_MII;
+
+	if ((port == FM2_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) ==
+		FSL_CORENET_RCWSR11_EC2_FM2_DTSEC5_RGMII))
+		return PHY_INTERFACE_MODE_RGMII;
+
+	if ((port == FM2_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) ==
+		FSL_CORENET_RCWSR11_EC2_FM2_DTSEC5_MII))
+		return PHY_INTERFACE_MODE_MII;
+
+	switch (port) {
+	case FM1_DTSEC1:
+	case FM1_DTSEC2:
+	case FM1_DTSEC3:
+	case FM1_DTSEC4:
+	case FM1_DTSEC5:
+		if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1))
+			return PHY_INTERFACE_MODE_SGMII;
+		break;
+	case FM2_DTSEC1:
+	case FM2_DTSEC2:
+	case FM2_DTSEC3:
+	case FM2_DTSEC4:
+	case FM2_DTSEC5:
+		if (is_serdes_configured(SGMII_FM2_DTSEC1 + port - FM2_DTSEC1))
+			return PHY_INTERFACE_MODE_SGMII;
+		break;
+	default:
+		return PHY_INTERFACE_MODE_NONE;
+	}
+
+	return PHY_INTERFACE_MODE_NONE;
+}
diff --git a/marvell/uboot/drivers/net/fm/t1040.c b/marvell/uboot/drivers/net/fm/t1040.c
new file mode 100644
index 0000000..83cf081
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/t1040.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <phy.h>
+#include <fm_eth.h>
+#include <asm/io.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_serdes.h>
+
+phy_interface_t fman_port_enet_if(enum fm_port port)
+{
+	return PHY_INTERFACE_MODE_NONE;
+}
diff --git a/marvell/uboot/drivers/net/fm/t2080.c b/marvell/uboot/drivers/net/fm/t2080.c
new file mode 100644
index 0000000..b5c1e9f
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/t2080.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * Shengzhou Liu <Shengzhou.Liu@freescale.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <phy.h>
+#include <fm_eth.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_serdes.h>
+
+u32 port_to_devdisr[] = {
+	[FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1,
+	[FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2,
+	[FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3,
+	[FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4,
+	[FM1_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC1_5,
+	[FM1_DTSEC6] = FSL_CORENET_DEVDISR2_DTSEC1_6,
+	[FM1_DTSEC9] = FSL_CORENET_DEVDISR2_DTSEC1_9,
+	[FM1_DTSEC10] = FSL_CORENET_DEVDISR2_DTSEC1_10,
+	[FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1_1,
+	[FM1_10GEC2] = FSL_CORENET_DEVDISR2_10GEC1_2,
+	[FM1_10GEC3] = FSL_CORENET_DEVDISR2_10GEC1_3,
+	[FM1_10GEC4] = FSL_CORENET_DEVDISR2_10GEC1_4,
+};
+
+static int is_device_disabled(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+	u32 devdisr2 = in_be32(&gur->devdisr2);
+
+	return port_to_devdisr[port] & devdisr2;
+}
+
+void fman_disable_port(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+	setbits_be32(&gur->devdisr2, port_to_devdisr[port]);
+}
+
+phy_interface_t fman_port_enet_if(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+	u32 rcwsr13 = in_be32(&gur->rcwsr[13]);
+
+	if (is_device_disabled(port))
+		return PHY_INTERFACE_MODE_NONE;
+
+	if ((port == FM1_10GEC1 || port == FM1_10GEC2 ||
+	     port == FM1_10GEC3 || port == FM1_10GEC4) &&
+	    ((is_serdes_configured(XAUI_FM1_MAC9))	||
+	     (is_serdes_configured(XFI_FM1_MAC1))	||
+	     (is_serdes_configured(XFI_FM1_MAC2))	||
+	     (is_serdes_configured(XFI_FM1_MAC9))	||
+	     (is_serdes_configured(XFI_FM1_MAC10))))
+		return PHY_INTERFACE_MODE_XGMII;
+
+	if ((port == FM1_DTSEC3) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC1) ==
+		FSL_CORENET_RCWSR13_EC1_DTSEC3_RGMII))
+		return PHY_INTERFACE_MODE_RGMII;
+
+	if ((port == FM1_DTSEC4) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) ==
+		FSL_CORENET_RCWSR13_EC2_DTSEC4_RGMII))
+		return PHY_INTERFACE_MODE_RGMII;
+
+	if ((port == FM1_DTSEC10) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) ==
+		FSL_CORENET_RCWSR13_EC2_DTSEC10_RGMII))
+		return PHY_INTERFACE_MODE_RGMII;
+
+	switch (port) {
+	case FM1_DTSEC1:
+	case FM1_DTSEC2:
+	case FM1_DTSEC3:
+	case FM1_DTSEC4:
+	case FM1_DTSEC5:
+	case FM1_DTSEC6:
+	case FM1_DTSEC9:
+	case FM1_DTSEC10:
+		if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1))
+			return PHY_INTERFACE_MODE_SGMII;
+		break;
+	default:
+		return PHY_INTERFACE_MODE_NONE;
+	}
+
+	return PHY_INTERFACE_MODE_NONE;
+}
diff --git a/marvell/uboot/drivers/net/fm/t4240.c b/marvell/uboot/drivers/net/fm/t4240.c
new file mode 100644
index 0000000..1eacb22
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/t4240.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *	Roy Zang <tie-fei.zang@freescale.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <phy.h>
+#include <fm_eth.h>
+#include <asm/io.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_serdes.h>
+
+u32 port_to_devdisr[] = {
+	[FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1,
+	[FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2,
+	[FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3,
+	[FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4,
+	[FM1_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC1_5,
+	[FM1_DTSEC6] = FSL_CORENET_DEVDISR2_DTSEC1_6,
+	[FM1_DTSEC9] = FSL_CORENET_DEVDISR2_DTSEC1_9,
+	[FM1_DTSEC10] = FSL_CORENET_DEVDISR2_DTSEC1_10,
+	[FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1_1,
+	[FM1_10GEC2] = FSL_CORENET_DEVDISR2_10GEC1_2,
+	[FM2_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC2_1,
+	[FM2_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC2_2,
+	[FM2_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC2_3,
+	[FM2_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC2_4,
+	[FM2_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC2_5,
+	[FM2_DTSEC6] = FSL_CORENET_DEVDISR2_DTSEC2_6,
+	[FM2_DTSEC9] = FSL_CORENET_DEVDISR2_DTSEC2_9,
+	[FM2_DTSEC10] = FSL_CORENET_DEVDISR2_DTSEC2_10,
+	[FM2_10GEC1] = FSL_CORENET_DEVDISR2_10GEC2_1,
+	[FM2_10GEC2] = FSL_CORENET_DEVDISR2_10GEC2_2,
+};
+
+static int is_device_disabled(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+	u32 devdisr2 = in_be32(&gur->devdisr2);
+
+	return port_to_devdisr[port] & devdisr2;
+}
+
+void fman_disable_port(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+	setbits_be32(&gur->devdisr2, port_to_devdisr[port]);
+}
+
+void fman_enable_port(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+	clrbits_be32(&gur->devdisr2, port_to_devdisr[port]);
+}
+
+phy_interface_t fman_port_enet_if(enum fm_port port)
+{
+	ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+	u32 rcwsr13 = in_be32(&gur->rcwsr[13]);
+
+	if (is_device_disabled(port))
+		return PHY_INTERFACE_MODE_NONE;
+
+	if ((port == FM1_10GEC1 || port == FM1_10GEC2) &&
+	    ((is_serdes_configured(XAUI_FM1_MAC9))	||
+	     (is_serdes_configured(XAUI_FM1_MAC10))	||
+	     (is_serdes_configured(XFI_FM1_MAC9))	||
+	     (is_serdes_configured(XFI_FM1_MAC10))))
+		return PHY_INTERFACE_MODE_XGMII;
+
+	if ((port == FM2_10GEC1 || port == FM2_10GEC2) &&
+	    ((is_serdes_configured(XAUI_FM2_MAC9))	||
+	     (is_serdes_configured(XAUI_FM2_MAC10))	||
+	     (is_serdes_configured(XFI_FM2_MAC9))	||
+	     (is_serdes_configured(XFI_FM2_MAC10))))
+		return PHY_INTERFACE_MODE_XGMII;
+
+#define FSL_CORENET_RCWSR13_EC1			0x60000000 /* bits 417..418 */
+#define FSL_CORENET_RCWSR13_EC1_FM2_DTSEC5_RGMII	0x00000000
+#define FSL_CORENET_RCWSR13_EC1_FM2_GPIO		0x40000000
+#define FSL_CORENET_RCWSR13_EC2			0x18000000 /* bits 419..420 */
+#define FSL_CORENET_RCWSR13_EC2_FM1_DTSEC5_RGMII	0x00000000
+#define FSL_CORENET_RCWSR13_EC2_FM2_DTSEC6_RGMII	0x08000000
+#define FSL_CORENET_RCWSR13_EC2_FM1_GPIO		0x10000000
+	/* handle RGMII first */
+	if ((port == FM2_DTSEC5) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC1) ==
+		FSL_CORENET_RCWSR13_EC1_FM2_DTSEC5_RGMII))
+		return PHY_INTERFACE_MODE_RGMII;
+
+	if ((port == FM1_DTSEC5) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) ==
+		FSL_CORENET_RCWSR13_EC2_FM1_DTSEC5_RGMII))
+		return PHY_INTERFACE_MODE_RGMII;
+
+	if ((port == FM2_DTSEC6) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) ==
+		FSL_CORENET_RCWSR13_EC2_FM2_DTSEC6_RGMII))
+		return PHY_INTERFACE_MODE_RGMII;
+	switch (port) {
+	case FM1_DTSEC1:
+	case FM1_DTSEC2:
+	case FM1_DTSEC3:
+	case FM1_DTSEC4:
+	case FM1_DTSEC5:
+	case FM1_DTSEC6:
+	case FM1_DTSEC9:
+	case FM1_DTSEC10:
+		if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1))
+			return PHY_INTERFACE_MODE_SGMII;
+		break;
+	case FM2_DTSEC1:
+	case FM2_DTSEC2:
+	case FM2_DTSEC3:
+	case FM2_DTSEC4:
+	case FM2_DTSEC5:
+	case FM2_DTSEC6:
+	case FM2_DTSEC9:
+	case FM2_DTSEC10:
+		if (is_serdes_configured(SGMII_FM2_DTSEC1 + port - FM2_DTSEC1))
+			return PHY_INTERFACE_MODE_SGMII;
+		break;
+	default:
+		break;
+	}
+
+	/* handle QSGMII */
+	switch (port) {
+	case FM1_DTSEC1:
+	case FM1_DTSEC2:
+	case FM1_DTSEC3:
+	case FM1_DTSEC4:
+		/* check lane G on SerDes1 */
+		if (is_serdes_configured(QSGMII_FM1_A))
+			return PHY_INTERFACE_MODE_QSGMII;
+		break;
+	case FM1_DTSEC5:
+	case FM1_DTSEC6:
+	case FM1_DTSEC9:
+	case FM1_DTSEC10:
+		/* check lane C on SerDes1 */
+		if (is_serdes_configured(QSGMII_FM1_B))
+			return PHY_INTERFACE_MODE_QSGMII;
+		break;
+	case FM2_DTSEC1:
+	case FM2_DTSEC2:
+	case FM2_DTSEC3:
+	case FM2_DTSEC4:
+		/* check lane G on SerDes2 */
+		if (is_serdes_configured(QSGMII_FM2_A))
+			return PHY_INTERFACE_MODE_QSGMII;
+		break;
+	case FM2_DTSEC5:
+	case FM2_DTSEC6:
+	case FM2_DTSEC9:
+	case FM2_DTSEC10:
+		/* check lane C on SerDes2 */
+		if (is_serdes_configured(QSGMII_FM2_B))
+			return PHY_INTERFACE_MODE_QSGMII;
+		break;
+	default:
+		break;
+	}
+
+	return PHY_INTERFACE_MODE_NONE;
+}
diff --git a/marvell/uboot/drivers/net/fm/tgec.c b/marvell/uboot/drivers/net/fm/tgec.c
new file mode 100644
index 0000000..f450f80
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/tgec.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2009-2011 Freescale Semiconductor, Inc.
+ *	Dave Liu <daveliu@freescale.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/* MAXFRM - maximum frame length */
+#define MAXFRM_MASK	0x0000ffff
+
+#include <common.h>
+#include <phy.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/fsl_enet.h>
+#include <asm/fsl_tgec.h>
+
+#include "fm.h"
+
+#define TGEC_CMD_CFG_INIT	(TGEC_CMD_CFG_NO_LEN_CHK | \
+				 TGEC_CMD_CFG_RX_ER_DISC | \
+				 TGEC_CMD_CFG_STAT_CLR | \
+				 TGEC_CMD_CFG_PAUSE_IGNORE | \
+				 TGEC_CMD_CFG_CRC_FWD)
+#define TGEC_CMD_CFG_FINAL	(TGEC_CMD_CFG_NO_LEN_CHK | \
+				 TGEC_CMD_CFG_RX_ER_DISC | \
+				 TGEC_CMD_CFG_PAUSE_IGNORE | \
+				 TGEC_CMD_CFG_CRC_FWD)
+
+static void tgec_init_mac(struct fsl_enet_mac *mac)
+{
+	struct tgec *regs = mac->base;
+
+	/* mask all interrupt */
+	out_be32(&regs->imask, IMASK_MASK_ALL);
+
+	/* clear all events */
+	out_be32(&regs->ievent, IEVENT_CLEAR_ALL);
+
+	/* set the max receive length */
+	out_be32(&regs->maxfrm, mac->max_rx_len & MAXFRM_MASK);
+
+	/*
+	 * 1588 disable, insert second mac disable payload length check
+	 * disable, normal operation, any rx error frame is discarded, clear
+	 * counters, pause frame ignore, no promiscuous, LAN mode Rx CRC no
+	 * strip, Tx CRC append, Rx disable and Tx disable
+	 */
+	out_be32(&regs->command_config, TGEC_CMD_CFG_INIT);
+	udelay(1000);
+	out_be32(&regs->command_config, TGEC_CMD_CFG_FINAL);
+
+	/* multicast frame reception for the hash entry disable */
+	out_be32(&regs->hashtable_ctrl, 0);
+}
+
+static void tgec_enable_mac(struct fsl_enet_mac *mac)
+{
+	struct tgec *regs = mac->base;
+
+	setbits_be32(&regs->command_config, TGEC_CMD_CFG_RXTX_EN);
+}
+
+static void tgec_disable_mac(struct fsl_enet_mac *mac)
+{
+	struct tgec *regs = mac->base;
+
+	clrbits_be32(&regs->command_config, TGEC_CMD_CFG_RXTX_EN);
+}
+
+static void tgec_set_mac_addr(struct fsl_enet_mac *mac, u8 *mac_addr)
+{
+	struct tgec *regs = mac->base;
+	u32 mac_addr0, mac_addr1;
+
+	/*
+	 * if a station address of 0x12345678ABCD, perform a write to
+	 * MAC_ADDR0 of 0x78563412, MAC_ADDR1 of 0x0000CDAB
+	 */
+	mac_addr0 = (mac_addr[3] << 24) | (mac_addr[2] << 16) | \
+			(mac_addr[1] << 8)  | (mac_addr[0]);
+	out_be32(&regs->mac_addr_0, mac_addr0);
+
+	mac_addr1 = ((mac_addr[5] << 8) | mac_addr[4]) & 0x0000ffff;
+	out_be32(&regs->mac_addr_1, mac_addr1);
+}
+
+static void tgec_set_interface_mode(struct fsl_enet_mac *mac,
+					phy_interface_t type, int speed)
+{
+	/* nothing right now */
+	return;
+}
+
+void init_tgec(struct fsl_enet_mac *mac, void *base,
+		void *phyregs, int max_rx_len)
+{
+	mac->base = base;
+	mac->phyregs = phyregs;
+	mac->max_rx_len = max_rx_len;
+	mac->init_mac = tgec_init_mac;
+	mac->enable_mac = tgec_enable_mac;
+	mac->disable_mac = tgec_disable_mac;
+	mac->set_mac_addr = tgec_set_mac_addr;
+	mac->set_if_mode = tgec_set_interface_mode;
+}
diff --git a/marvell/uboot/drivers/net/fm/tgec_phy.c b/marvell/uboot/drivers/net/fm/tgec_phy.c
new file mode 100644
index 0000000..faec317
--- /dev/null
+++ b/marvell/uboot/drivers/net/fm/tgec_phy.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2009-2011 Freescale Semiconductor, Inc.
+ *	Andy Fleming <afleming@freescale.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ * Some part is taken from tsec.c
+ */
+#include <common.h>
+#include <miiphy.h>
+#include <phy.h>
+#include <asm/io.h>
+#include <asm/fsl_tgec.h>
+#include <fm_eth.h>
+
+/*
+ * Write value to the PHY for this device to the register at regnum, waiting
+ * until the write is done before it returns.  All PHY configuration has to be
+ * done through the TSEC1 MIIM regs
+ */
+static int tgec_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr,
+			   int regnum, u16 value)
+{
+	u32 mdio_ctl;
+	u32 stat_val;
+	struct tgec_mdio_controller *regs = bus->priv;
+
+	if (dev_addr == MDIO_DEVAD_NONE)
+		return 0;
+
+	/* Wait till the bus is free */
+	stat_val = MDIO_STAT_CLKDIV(100);
+	out_be32(&regs->mdio_stat, stat_val);
+	while ((in_be32(&regs->mdio_stat)) & MDIO_STAT_BSY)
+		;
+
+	/* Set the port and dev addr */
+	mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr);
+	out_be32(&regs->mdio_ctl, mdio_ctl);
+
+	/* Set the register address */
+	out_be32(&regs->mdio_addr, regnum & 0xffff);
+
+	/* Wait till the bus is free */
+	while ((in_be32(&regs->mdio_stat)) & MDIO_STAT_BSY)
+		;
+
+	/* Write the value to the register */
+	out_be32(&regs->mdio_data, MDIO_DATA(value));
+
+	/* Wait till the MDIO write is complete */
+	while ((in_be32(&regs->mdio_data)) & MDIO_DATA_BSY)
+		;
+
+	return 0;
+}
+
+/*
+ * Reads from register regnum in the PHY for device dev, returning the value.
+ * Clears miimcom first.  All PHY configuration has to be done through the
+ * TSEC1 MIIM regs
+ */
+static int tgec_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr,
+			  int regnum)
+{
+	u32 mdio_ctl;
+	u32 stat_val;
+	struct tgec_mdio_controller *regs = bus->priv;
+
+	if (dev_addr == MDIO_DEVAD_NONE)
+		return 0xffff;
+
+	stat_val = MDIO_STAT_CLKDIV(100);
+	out_be32(&regs->mdio_stat, stat_val);
+	/* Wait till the bus is free */
+	while ((in_be32(&regs->mdio_stat)) & MDIO_STAT_BSY)
+		;
+
+	/* Set the Port and Device Addrs */
+	mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr);
+	out_be32(&regs->mdio_ctl, mdio_ctl);
+
+	/* Set the register address */
+	out_be32(&regs->mdio_addr, regnum & 0xffff);
+
+	/* Wait till the bus is free */
+	while ((in_be32(&regs->mdio_stat)) & MDIO_STAT_BSY)
+		;
+
+	/* Initiate the read */
+	mdio_ctl |= MDIO_CTL_READ;
+	out_be32(&regs->mdio_ctl, mdio_ctl);
+
+	/* Wait till the MDIO write is complete */
+	while ((in_be32(&regs->mdio_data)) & MDIO_DATA_BSY)
+		;
+
+	/* Return all Fs if nothing was there */
+	if (in_be32(&regs->mdio_stat) & MDIO_STAT_RD_ER)
+		return 0xffff;
+
+	return in_be32(&regs->mdio_data) & 0xffff;
+}
+
+static int tgec_mdio_reset(struct mii_dev *bus)
+{
+	return 0;
+}
+
+int fm_tgec_mdio_init(bd_t *bis, struct tgec_mdio_info *info)
+{
+	struct mii_dev *bus = mdio_alloc();
+
+	if (!bus) {
+		printf("Failed to allocate FM TGEC MDIO bus\n");
+		return -1;
+	}
+
+	bus->read = tgec_mdio_read;
+	bus->write = tgec_mdio_write;
+	bus->reset = tgec_mdio_reset;
+	sprintf(bus->name, info->name);
+
+	bus->priv = info->regs;
+
+	return mdio_register(bus);
+}
diff --git a/marvell/uboot/drivers/net/fsl_mcdmafec.c b/marvell/uboot/drivers/net/fsl_mcdmafec.c
new file mode 100644
index 0000000..6391f9b
--- /dev/null
+++ b/marvell/uboot/drivers/net/fsl_mcdmafec.c
@@ -0,0 +1,571 @@
+/*
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2007 Freescale Semiconductor, Inc.
+ * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <command.h>
+#include <config.h>
+#include <net.h>
+#include <miiphy.h>
+
+#undef	ET_DEBUG
+#undef	MII_DEBUG
+
+/* Ethernet Transmit and Receive Buffers */
+#define DBUF_LENGTH		1520
+#define PKT_MAXBUF_SIZE		1518
+#define PKT_MINBUF_SIZE		64
+#define PKT_MAXBLR_SIZE		1536
+#define LAST_PKTBUFSRX		PKTBUFSRX - 1
+#define BD_ENET_RX_W_E		(BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY)
+#define BD_ENET_TX_RDY_LST	(BD_ENET_TX_READY | BD_ENET_TX_LAST)
+#define FIFO_ERRSTAT		(FIFO_STAT_RXW | FIFO_STAT_UF | FIFO_STAT_OF)
+
+/* RxBD bits definitions */
+#define BD_ENET_RX_ERR	(BD_ENET_RX_LG | BD_ENET_RX_NO | BD_ENET_RX_CR | \
+			 BD_ENET_RX_OV | BD_ENET_RX_TR)
+
+#include <asm/immap.h>
+#include <asm/fsl_mcdmafec.h>
+
+#include "MCD_dma.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct fec_info_dma fec_info[] = {
+#ifdef CONFIG_SYS_FEC0_IOBASE
+	{
+	 0,			/* index */
+	 CONFIG_SYS_FEC0_IOBASE,	/* io base */
+	 CONFIG_SYS_FEC0_PINMUX,	/* gpio pin muxing */
+	 CONFIG_SYS_FEC0_MIIBASE,	/* mii base */
+	 -1,			/* phy_addr */
+	 0,			/* duplex and speed */
+	 0,			/* phy name */
+	 0,			/* phyname init */
+	 0,			/* RX BD */
+	 0,			/* TX BD */
+	 0,			/* rx Index */
+	 0,			/* tx Index */
+	 0,			/* tx buffer */
+	 0,			/* initialized flag */
+	 (struct fec_info_dma *)-1,	/* next */
+	 FEC0_RX_TASK,		/* rxTask */
+	 FEC0_TX_TASK,		/* txTask */
+	 FEC0_RX_PRIORITY,	/* rxPri */
+	 FEC0_TX_PRIORITY,	/* txPri */
+	 FEC0_RX_INIT,		/* rxInit */
+	 FEC0_TX_INIT,		/* txInit */
+	 0,			/* usedTbdIndex */
+	 0,			/* cleanTbdNum */
+	 },
+#endif
+#ifdef CONFIG_SYS_FEC1_IOBASE
+	{
+	 1,			/* index */
+	 CONFIG_SYS_FEC1_IOBASE,	/* io base */
+	 CONFIG_SYS_FEC1_PINMUX,	/* gpio pin muxing */
+	 CONFIG_SYS_FEC1_MIIBASE,	/* mii base */
+	 -1,			/* phy_addr */
+	 0,			/* duplex and speed */
+	 0,			/* phy name */
+	 0,			/* phy name init */
+#ifdef CONFIG_SYS_DMA_USE_INTSRAM
+	 (cbd_t *)DBUF_LENGTH,	/* RX BD */
+#else
+	 0,			/* RX BD */
+#endif
+	 0,			/* TX BD */
+	 0,			/* rx Index */
+	 0,			/* tx Index */
+	 0,			/* tx buffer */
+	 0,			/* initialized flag */
+	 (struct fec_info_dma *)-1,	/* next */
+	 FEC1_RX_TASK,		/* rxTask */
+	 FEC1_TX_TASK,		/* txTask */
+	 FEC1_RX_PRIORITY,	/* rxPri */
+	 FEC1_TX_PRIORITY,	/* txPri */
+	 FEC1_RX_INIT,		/* rxInit */
+	 FEC1_TX_INIT,		/* txInit */
+	 0,			/* usedTbdIndex */
+	 0,			/* cleanTbdNum */
+	 }
+#endif
+};
+
+static int fec_send(struct eth_device *dev, void *packet, int length);
+static int fec_recv(struct eth_device *dev);
+static int fec_init(struct eth_device *dev, bd_t * bd);
+static void fec_halt(struct eth_device *dev);
+
+#ifdef ET_DEBUG
+static void dbg_fec_regs(struct eth_device *dev)
+{
+	struct fec_info_dma *info = dev->priv;
+	volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
+
+	printf("=====\n");
+	printf("ievent       %x - %x\n", (int)&fecp->eir, fecp->eir);
+	printf("imask        %x - %x\n", (int)&fecp->eimr, fecp->eimr);
+	printf("ecntrl       %x - %x\n", (int)&fecp->ecr, fecp->ecr);
+	printf("mii_mframe   %x - %x\n", (int)&fecp->mmfr, fecp->mmfr);
+	printf("mii_speed    %x - %x\n", (int)&fecp->mscr, fecp->mscr);
+	printf("mii_ctrlstat %x - %x\n", (int)&fecp->mibc, fecp->mibc);
+	printf("r_cntrl      %x - %x\n", (int)&fecp->rcr, fecp->rcr);
+	printf("r hash       %x - %x\n", (int)&fecp->rhr, fecp->rhr);
+	printf("x_cntrl      %x - %x\n", (int)&fecp->tcr, fecp->tcr);
+	printf("padr_l       %x - %x\n", (int)&fecp->palr, fecp->palr);
+	printf("padr_u       %x - %x\n", (int)&fecp->paur, fecp->paur);
+	printf("op_pause     %x - %x\n", (int)&fecp->opd, fecp->opd);
+	printf("iadr_u       %x - %x\n", (int)&fecp->iaur, fecp->iaur);
+	printf("iadr_l       %x - %x\n", (int)&fecp->ialr, fecp->ialr);
+	printf("gadr_u       %x - %x\n", (int)&fecp->gaur, fecp->gaur);
+	printf("gadr_l       %x - %x\n", (int)&fecp->galr, fecp->galr);
+	printf("x_wmrk       %x - %x\n", (int)&fecp->tfwr, fecp->tfwr);
+	printf("r_fdata      %x - %x\n", (int)&fecp->rfdr, fecp->rfdr);
+	printf("r_fstat      %x - %x\n", (int)&fecp->rfsr, fecp->rfsr);
+	printf("r_fctrl      %x - %x\n", (int)&fecp->rfcr, fecp->rfcr);
+	printf("r_flrfp      %x - %x\n", (int)&fecp->rlrfp, fecp->rlrfp);
+	printf("r_flwfp      %x - %x\n", (int)&fecp->rlwfp, fecp->rlwfp);
+	printf("r_frfar      %x - %x\n", (int)&fecp->rfar, fecp->rfar);
+	printf("r_frfrp      %x - %x\n", (int)&fecp->rfrp, fecp->rfrp);
+	printf("r_frfwp      %x - %x\n", (int)&fecp->rfwp, fecp->rfwp);
+	printf("t_fdata      %x - %x\n", (int)&fecp->tfdr, fecp->tfdr);
+	printf("t_fstat      %x - %x\n", (int)&fecp->tfsr, fecp->tfsr);
+	printf("t_fctrl      %x - %x\n", (int)&fecp->tfcr, fecp->tfcr);
+	printf("t_flrfp      %x - %x\n", (int)&fecp->tlrfp, fecp->tlrfp);
+	printf("t_flwfp      %x - %x\n", (int)&fecp->tlwfp, fecp->tlwfp);
+	printf("t_ftfar      %x - %x\n", (int)&fecp->tfar, fecp->tfar);
+	printf("t_ftfrp      %x - %x\n", (int)&fecp->tfrp, fecp->tfrp);
+	printf("t_ftfwp      %x - %x\n", (int)&fecp->tfwp, fecp->tfwp);
+	printf("frst         %x - %x\n", (int)&fecp->frst, fecp->frst);
+	printf("ctcwr        %x - %x\n", (int)&fecp->ctcwr, fecp->ctcwr);
+}
+#endif
+
+static void set_fec_duplex_speed(volatile fecdma_t * fecp, bd_t * bd,
+				 int dup_spd)
+{
+	if ((dup_spd >> 16) == FULL) {
+		/* Set maximum frame length */
+		fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | FEC_RCR_MII_MODE |
+		    FEC_RCR_PROM | 0x100;
+		fecp->tcr = FEC_TCR_FDEN;
+	} else {
+		/* Half duplex mode */
+		fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) |
+		    FEC_RCR_MII_MODE | FEC_RCR_DRT;
+		fecp->tcr &= ~FEC_TCR_FDEN;
+	}
+
+	if ((dup_spd & 0xFFFF) == _100BASET) {
+#ifdef MII_DEBUG
+		printf("100Mbps\n");
+#endif
+		bd->bi_ethspeed = 100;
+	} else {
+#ifdef MII_DEBUG
+		printf("10Mbps\n");
+#endif
+		bd->bi_ethspeed = 10;
+	}
+}
+
+static int fec_send(struct eth_device *dev, void *packet, int length)
+{
+	struct fec_info_dma *info = dev->priv;
+	cbd_t *pTbd, *pUsedTbd;
+	u16 phyStatus;
+
+	miiphy_read(dev->name, info->phy_addr, MII_BMSR, &phyStatus);
+
+	/* process all the consumed TBDs */
+	while (info->cleanTbdNum < CONFIG_SYS_TX_ETH_BUFFER) {
+		pUsedTbd = &info->txbd[info->usedTbdIdx];
+		if (pUsedTbd->cbd_sc & BD_ENET_TX_READY) {
+#ifdef ET_DEBUG
+			printf("Cannot clean TBD %d, in use\n",
+			       info->cleanTbdNum);
+#endif
+			return 0;
+		}
+
+		/* clean this buffer descriptor */
+		if (info->usedTbdIdx == (CONFIG_SYS_TX_ETH_BUFFER - 1))
+			pUsedTbd->cbd_sc = BD_ENET_TX_WRAP;
+		else
+			pUsedTbd->cbd_sc = 0;
+
+		/* update some indeces for a correct handling of the TBD ring */
+		info->cleanTbdNum++;
+		info->usedTbdIdx = (info->usedTbdIdx + 1) % CONFIG_SYS_TX_ETH_BUFFER;
+	}
+
+	/* Check for valid length of data. */
+	if ((length > 1500) || (length <= 0)) {
+		return -1;
+	}
+
+	/* Check the number of vacant TxBDs. */
+	if (info->cleanTbdNum < 1) {
+		printf("No available TxBDs ...\n");
+		return -1;
+	}
+
+	/* Get the first TxBD to send the mac header */
+	pTbd = &info->txbd[info->txIdx];
+	pTbd->cbd_datlen = length;
+	pTbd->cbd_bufaddr = (u32) packet;
+	pTbd->cbd_sc |= BD_ENET_TX_LAST | BD_ENET_TX_TC | BD_ENET_TX_READY;
+	info->txIdx = (info->txIdx + 1) % CONFIG_SYS_TX_ETH_BUFFER;
+
+	/* Enable DMA transmit task */
+	MCD_continDma(info->txTask);
+
+	info->cleanTbdNum -= 1;
+
+	/* wait until frame is sent . */
+	while (pTbd->cbd_sc & BD_ENET_TX_READY) {
+		udelay(10);
+	}
+
+	return (int)(info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_STATS);
+}
+
+static int fec_recv(struct eth_device *dev)
+{
+	struct fec_info_dma *info = dev->priv;
+	volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
+
+	cbd_t *pRbd = &info->rxbd[info->rxIdx];
+	u32 ievent;
+	int frame_length, len = 0;
+
+	/* Check if any critical events have happened */
+	ievent = fecp->eir;
+	if (ievent != 0) {
+		fecp->eir = ievent;
+
+		if (ievent & (FEC_EIR_BABT | FEC_EIR_TXERR | FEC_EIR_RXERR)) {
+			printf("fec_recv: error\n");
+			fec_halt(dev);
+			fec_init(dev, NULL);
+			return 0;
+		}
+
+		if (ievent & FEC_EIR_HBERR) {
+			/* Heartbeat error */
+			fecp->tcr |= FEC_TCR_GTS;
+		}
+
+		if (ievent & FEC_EIR_GRA) {
+			/* Graceful stop complete */
+			if (fecp->tcr & FEC_TCR_GTS) {
+				printf("fec_recv: tcr_gts\n");
+				fec_halt(dev);
+				fecp->tcr &= ~FEC_TCR_GTS;
+				fec_init(dev, NULL);
+			}
+		}
+	}
+
+	if (!(pRbd->cbd_sc & BD_ENET_RX_EMPTY)) {
+		if ((pRbd->cbd_sc & BD_ENET_RX_LAST)
+		    && !(pRbd->cbd_sc & BD_ENET_RX_ERR)
+		    && ((pRbd->cbd_datlen - 4) > 14)) {
+
+			/* Get buffer address and size */
+			frame_length = pRbd->cbd_datlen - 4;
+
+			/* Fill the buffer and pass it to upper layers */
+			NetReceive((uchar *)pRbd->cbd_bufaddr, frame_length);
+			len = frame_length;
+		}
+
+		/* Reset buffer descriptor as empty */
+		if ((info->rxIdx) == (PKTBUFSRX - 1))
+			pRbd->cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
+		else
+			pRbd->cbd_sc = BD_ENET_RX_EMPTY;
+
+		pRbd->cbd_datlen = PKTSIZE_ALIGN;
+
+		/* Now, we have an empty RxBD, restart the DMA receive task */
+		MCD_continDma(info->rxTask);
+
+		/* Increment BD count */
+		info->rxIdx = (info->rxIdx + 1) % PKTBUFSRX;
+	}
+
+	return len;
+}
+
+static void fec_set_hwaddr(volatile fecdma_t * fecp, u8 * mac)
+{
+	u8 currByte;		/* byte for which to compute the CRC */
+	int byte;		/* loop - counter */
+	int bit;		/* loop - counter */
+	u32 crc = 0xffffffff;	/* initial value */
+
+	for (byte = 0; byte < 6; byte++) {
+		currByte = mac[byte];
+		for (bit = 0; bit < 8; bit++) {
+			if ((currByte & 0x01) ^ (crc & 0x01)) {
+				crc >>= 1;
+				crc = crc ^ 0xedb88320;
+			} else {
+				crc >>= 1;
+			}
+			currByte >>= 1;
+		}
+	}
+
+	crc = crc >> 26;
+
+	/* Set individual hash table register */
+	if (crc >= 32) {
+		fecp->ialr = (1 << (crc - 32));
+		fecp->iaur = 0;
+	} else {
+		fecp->ialr = 0;
+		fecp->iaur = (1 << crc);
+	}
+
+	/* Set physical address */
+	fecp->palr = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3];
+	fecp->paur = (mac[4] << 24) + (mac[5] << 16) + 0x8808;
+
+	/* Clear multicast address hash table */
+	fecp->gaur = 0;
+	fecp->galr = 0;
+}
+
+static int fec_init(struct eth_device *dev, bd_t * bd)
+{
+	struct fec_info_dma *info = dev->priv;
+	volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
+	int i;
+	uchar enetaddr[6];
+
+#ifdef ET_DEBUG
+	printf("fec_init: iobase 0x%08x ...\n", info->iobase);
+#endif
+
+	fecpin_setclear(dev, 1);
+
+	fec_halt(dev);
+
+#if defined(CONFIG_CMD_MII) || defined (CONFIG_MII) || \
+	defined (CONFIG_SYS_DISCOVER_PHY)
+
+	mii_init();
+
+	set_fec_duplex_speed(fecp, bd, info->dup_spd);
+#else
+#ifndef CONFIG_SYS_DISCOVER_PHY
+	set_fec_duplex_speed(fecp, bd, (FECDUPLEX << 16) | FECSPEED);
+#endif				/* ifndef CONFIG_SYS_DISCOVER_PHY */
+#endif				/* CONFIG_CMD_MII || CONFIG_MII */
+
+	/* We use strictly polling mode only */
+	fecp->eimr = 0;
+
+	/* Clear any pending interrupt */
+	fecp->eir = 0xffffffff;
+
+	/* Set station address   */
+	if ((u32) fecp == CONFIG_SYS_FEC0_IOBASE)
+		eth_getenv_enetaddr("ethaddr", enetaddr);
+	else
+		eth_getenv_enetaddr("eth1addr", enetaddr);
+	fec_set_hwaddr(fecp, enetaddr);
+
+	/* Set Opcode/Pause Duration Register */
+	fecp->opd = 0x00010020;
+
+	/* Setup Buffers and Buffer Desriptors */
+	info->rxIdx = 0;
+	info->txIdx = 0;
+
+	/* Setup Receiver Buffer Descriptors (13.14.24.18)
+	 * Settings:     Empty, Wrap */
+	for (i = 0; i < PKTBUFSRX; i++) {
+		info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
+		info->rxbd[i].cbd_datlen = PKTSIZE_ALIGN;
+		info->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+	}
+	info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
+
+	/* Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
+	 * Settings:    Last, Tx CRC */
+	for (i = 0; i < CONFIG_SYS_TX_ETH_BUFFER; i++) {
+		info->txbd[i].cbd_sc = 0;
+		info->txbd[i].cbd_datlen = 0;
+		info->txbd[i].cbd_bufaddr = (uint) (&info->txbuf[0]);
+	}
+	info->txbd[CONFIG_SYS_TX_ETH_BUFFER - 1].cbd_sc |= BD_ENET_TX_WRAP;
+
+	info->usedTbdIdx = 0;
+	info->cleanTbdNum = CONFIG_SYS_TX_ETH_BUFFER;
+
+	/* Set Rx FIFO alarm and granularity value */
+	fecp->rfcr = 0x0c000000;
+	fecp->rfar = 0x0000030c;
+
+	/* Set Tx FIFO granularity value */
+	fecp->tfcr = FIFO_CTRL_FRAME | FIFO_CTRL_GR(6) | 0x00040000;
+	fecp->tfar = 0x00000080;
+
+	fecp->tfwr = 0x2;
+	fecp->ctcwr = 0x03000000;
+
+	/* Enable DMA receive task */
+	MCD_startDma(info->rxTask,	/* Dma channel */
+		     (s8 *) info->rxbd,	/*Source Address */
+		     0,		/* Source increment */
+		     (s8 *) (&fecp->rfdr),	/* dest */
+		     4,		/* dest increment */
+		     0,		/* DMA size */
+		     4,		/* xfer size */
+		     info->rxInit,	/* initiator */
+		     info->rxPri,	/* priority */
+		     (MCD_FECRX_DMA | MCD_TT_FLAGS_DEF),	/* Flags */
+		     (MCD_NO_CSUM | MCD_NO_BYTE_SWAP)	/* Function description */
+	    );
+
+	/* Enable DMA tx task with no ready buffer descriptors */
+	MCD_startDma(info->txTask,	/* Dma channel */
+		     (s8 *) info->txbd,	/*Source Address */
+		     0,		/* Source increment */
+		     (s8 *) (&fecp->tfdr),	/* dest */
+		     4,		/* dest incr */
+		     0,		/* DMA size */
+		     4,		/* xfer size */
+		     info->txInit,	/* initiator */
+		     info->txPri,	/* priority */
+		     (MCD_FECTX_DMA | MCD_TT_FLAGS_DEF),	/* Flags */
+		     (MCD_NO_CSUM | MCD_NO_BYTE_SWAP)	/* Function description */
+	    );
+
+	/* Now enable the transmit and receive processing */
+	fecp->ecr |= FEC_ECR_ETHER_EN;
+
+	return 1;
+}
+
+static void fec_halt(struct eth_device *dev)
+{
+	struct fec_info_dma *info = dev->priv;
+	volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
+	int counter = 0xffff;
+
+	/* issue graceful stop command to the FEC transmitter if necessary */
+	fecp->tcr |= FEC_TCR_GTS;
+
+	/* wait for graceful stop to register */
+	while ((counter--) && (!(fecp->eir & FEC_EIR_GRA))) ;
+
+	/* Disable DMA tasks */
+	MCD_killDma(info->txTask);
+	MCD_killDma(info->rxTask);;
+
+	/* Disable the Ethernet Controller */
+	fecp->ecr &= ~FEC_ECR_ETHER_EN;
+
+	/* Clear FIFO status registers */
+	fecp->rfsr &= FIFO_ERRSTAT;
+	fecp->tfsr &= FIFO_ERRSTAT;
+
+	fecp->frst = 0x01000000;
+
+	/* Issue a reset command to the FEC chip */
+	fecp->ecr |= FEC_ECR_RESET;
+
+	/* wait at least 20 clock cycles */
+	udelay(10000);
+
+#ifdef ET_DEBUG
+	printf("Ethernet task stopped\n");
+#endif
+}
+
+int mcdmafec_initialize(bd_t * bis)
+{
+	struct eth_device *dev;
+	int i;
+#ifdef CONFIG_SYS_DMA_USE_INTSRAM
+	u32 tmp = CONFIG_SYS_INTSRAM + 0x2000;
+#endif
+
+	for (i = 0; i < ARRAY_SIZE(fec_info); i++) {
+
+		dev =
+		    (struct eth_device *)memalign(CONFIG_SYS_CACHELINE_SIZE,
+						  sizeof *dev);
+		if (dev == NULL)
+			hang();
+
+		memset(dev, 0, sizeof(*dev));
+
+		sprintf(dev->name, "FEC%d", fec_info[i].index);
+
+		dev->priv = &fec_info[i];
+		dev->init = fec_init;
+		dev->halt = fec_halt;
+		dev->send = fec_send;
+		dev->recv = fec_recv;
+
+		/* setup Receive and Transmit buffer descriptor */
+#ifdef CONFIG_SYS_DMA_USE_INTSRAM
+		fec_info[i].rxbd = (cbd_t *)((u32)fec_info[i].rxbd + tmp);
+		tmp = (u32)fec_info[i].rxbd;
+		fec_info[i].txbd =
+		    (cbd_t *)((u32)fec_info[i].txbd + tmp +
+		    (PKTBUFSRX * sizeof(cbd_t)));
+		tmp = (u32)fec_info[i].txbd;
+		fec_info[i].txbuf =
+		    (char *)((u32)fec_info[i].txbuf + tmp +
+		    (CONFIG_SYS_TX_ETH_BUFFER * sizeof(cbd_t)));
+		tmp = (u32)fec_info[i].txbuf;
+#else
+		fec_info[i].rxbd =
+		    (cbd_t *) memalign(CONFIG_SYS_CACHELINE_SIZE,
+				       (PKTBUFSRX * sizeof(cbd_t)));
+		fec_info[i].txbd =
+		    (cbd_t *) memalign(CONFIG_SYS_CACHELINE_SIZE,
+				       (CONFIG_SYS_TX_ETH_BUFFER * sizeof(cbd_t)));
+		fec_info[i].txbuf =
+		    (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, DBUF_LENGTH);
+#endif
+
+#ifdef ET_DEBUG
+		printf("rxbd %x txbd %x\n",
+		       (int)fec_info[i].rxbd, (int)fec_info[i].txbd);
+#endif
+
+		fec_info[i].phy_name = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, 32);
+
+		eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+		miiphy_register(dev->name,
+				mcffec_miiphy_read, mcffec_miiphy_write);
+#endif
+
+		if (i > 0)
+			fec_info[i - 1].next = &fec_info[i];
+	}
+	fec_info[i - 1].next = &fec_info[0];
+
+	/* default speed */
+	bis->bi_ethspeed = 10;
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/fsl_mdio.c b/marvell/uboot/drivers/net/fsl_mdio.c
new file mode 100644
index 0000000..1d88e65
--- /dev/null
+++ b/marvell/uboot/drivers/net/fsl_mdio.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2009-2010, 2013 Freescale Semiconductor, Inc.
+ *	Jun-jie Zhang <b18070@freescale.com>
+ *	Mingkai Hu <Mingkai.hu@freescale.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+#include <miiphy.h>
+#include <phy.h>
+#include <fsl_mdio.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/fsl_enet.h>
+
+void tsec_local_mdio_write(struct tsec_mii_mng __iomem *phyregs, int port_addr,
+		int dev_addr, int regnum, int value)
+{
+	int timeout = 1000000;
+
+	out_be32(&phyregs->miimadd, (port_addr << 8) | (regnum & 0x1f));
+	out_be32(&phyregs->miimcon, value);
+	asm("sync");
+
+	while ((in_be32(&phyregs->miimind) & MIIMIND_BUSY) && timeout--)
+		;
+}
+
+int tsec_local_mdio_read(struct tsec_mii_mng __iomem *phyregs, int port_addr,
+		int dev_addr, int regnum)
+{
+	int value;
+	int timeout = 1000000;
+
+	/* Put the address of the phy, and the register
+	 * number into MIIMADD */
+	out_be32(&phyregs->miimadd, (port_addr << 8) | (regnum & 0x1f));
+
+	/* Clear the command register, and wait */
+	out_be32(&phyregs->miimcom, 0);
+	asm("sync");
+
+	/* Initiate a read command, and wait */
+	out_be32(&phyregs->miimcom, MIIMCOM_READ_CYCLE);
+	asm("sync");
+
+	/* Wait for the the indication that the read is done */
+	while ((in_be32(&phyregs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
+			&& timeout--)
+		;
+
+	/* Grab the value read from the PHY */
+	value = in_be32(&phyregs->miimstat);
+
+	return value;
+}
+
+static int fsl_pq_mdio_reset(struct mii_dev *bus)
+{
+	struct tsec_mii_mng __iomem *regs =
+		(struct tsec_mii_mng __iomem *)bus->priv;
+
+	/* Reset MII (due to new addresses) */
+	out_be32(&regs->miimcfg, MIIMCFG_RESET_MGMT);
+
+	out_be32(&regs->miimcfg, MIIMCFG_INIT_VALUE);
+
+	while (in_be32(&regs->miimind) & MIIMIND_BUSY)
+		;
+
+	return 0;
+}
+
+int tsec_phy_read(struct mii_dev *bus, int addr, int dev_addr, int regnum)
+{
+	struct tsec_mii_mng __iomem *phyregs =
+		(struct tsec_mii_mng __iomem *)bus->priv;
+
+	return tsec_local_mdio_read(phyregs, addr, dev_addr, regnum);
+}
+
+int tsec_phy_write(struct mii_dev *bus, int addr, int dev_addr, int regnum,
+			u16 value)
+{
+	struct tsec_mii_mng __iomem *phyregs =
+		(struct tsec_mii_mng __iomem *)bus->priv;
+
+	tsec_local_mdio_write(phyregs, addr, dev_addr, regnum, value);
+
+	return 0;
+}
+
+int fsl_pq_mdio_init(bd_t *bis, struct fsl_pq_mdio_info *info)
+{
+	struct mii_dev *bus = mdio_alloc();
+
+	if (!bus) {
+		printf("Failed to allocate FSL MDIO bus\n");
+		return -1;
+	}
+
+	bus->read = tsec_phy_read;
+	bus->write = tsec_phy_write;
+	bus->reset = fsl_pq_mdio_reset;
+	sprintf(bus->name, info->name);
+
+	bus->priv = (void *)info->regs;
+
+	return mdio_register(bus);
+}
diff --git a/marvell/uboot/drivers/net/ftgmac100.c b/marvell/uboot/drivers/net/ftgmac100.c
new file mode 100644
index 0000000..8519314
--- /dev/null
+++ b/marvell/uboot/drivers/net/ftgmac100.c
@@ -0,0 +1,583 @@
+/*
+ * Faraday FTGMAC100 Ethernet
+ *
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratbert@faraday-tech.com>
+ *
+ * (C) Copyright 2010 Andes Technology
+ * Macpaul Lin <macpaul@andestech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <asm/dma-mapping.h>
+#include <linux/mii.h>
+
+#include "ftgmac100.h"
+
+#define ETH_ZLEN	60
+#define CFG_XBUF_SIZE	1536
+
+/* RBSR - hw default init value is also 0x640 */
+#define RBSR_DEFAULT_VALUE	0x640
+
+/* PKTBUFSTX/PKTBUFSRX must both be power of 2 */
+#define PKTBUFSTX	4	/* must be power of 2 */
+
+struct ftgmac100_data {
+	ulong txdes_dma;
+	struct ftgmac100_txdes *txdes;
+	ulong rxdes_dma;
+	struct ftgmac100_rxdes *rxdes;
+	int tx_index;
+	int rx_index;
+	int phy_addr;
+};
+
+/*
+ * struct mii_bus functions
+ */
+static int ftgmac100_mdiobus_read(struct eth_device *dev, int phy_addr,
+	int regnum)
+{
+	struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+	int phycr;
+	int i;
+
+	phycr = readl(&ftgmac100->phycr);
+
+	/* preserve MDC cycle threshold */
+	phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK;
+
+	phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr)
+	      |  FTGMAC100_PHYCR_REGAD(regnum)
+	      |  FTGMAC100_PHYCR_MIIRD;
+
+	writel(phycr, &ftgmac100->phycr);
+
+	for (i = 0; i < 10; i++) {
+		phycr = readl(&ftgmac100->phycr);
+
+		if ((phycr & FTGMAC100_PHYCR_MIIRD) == 0) {
+			int data;
+
+			data = readl(&ftgmac100->phydata);
+			return FTGMAC100_PHYDATA_MIIRDATA(data);
+		}
+
+		mdelay(10);
+	}
+
+	debug("mdio read timed out\n");
+	return -1;
+}
+
+static int ftgmac100_mdiobus_write(struct eth_device *dev, int phy_addr,
+	int regnum, u16 value)
+{
+	struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+	int phycr;
+	int data;
+	int i;
+
+	phycr = readl(&ftgmac100->phycr);
+
+	/* preserve MDC cycle threshold */
+	phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK;
+
+	phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr)
+	      |  FTGMAC100_PHYCR_REGAD(regnum)
+	      |  FTGMAC100_PHYCR_MIIWR;
+
+	data = FTGMAC100_PHYDATA_MIIWDATA(value);
+
+	writel(data, &ftgmac100->phydata);
+	writel(phycr, &ftgmac100->phycr);
+
+	for (i = 0; i < 10; i++) {
+		phycr = readl(&ftgmac100->phycr);
+
+		if ((phycr & FTGMAC100_PHYCR_MIIWR) == 0) {
+			debug("(phycr & FTGMAC100_PHYCR_MIIWR) == 0: " \
+				"phy_addr: %x\n", phy_addr);
+			return 0;
+		}
+
+		mdelay(1);
+	}
+
+	debug("mdio write timed out\n");
+	return -1;
+}
+
+int ftgmac100_phy_read(struct eth_device *dev, int addr, int reg, u16 *value)
+{
+	*value = ftgmac100_mdiobus_read(dev , addr, reg);
+
+	if (*value == -1)
+		return -1;
+
+	return 0;
+}
+
+int  ftgmac100_phy_write(struct eth_device *dev, int addr, int reg, u16 value)
+{
+	if (ftgmac100_mdiobus_write(dev, addr, reg, value) == -1)
+		return -1;
+
+	return 0;
+}
+
+static int ftgmac100_phy_reset(struct eth_device *dev)
+{
+	struct ftgmac100_data *priv = dev->priv;
+	int i;
+	u16 status, adv;
+
+	adv = ADVERTISE_CSMA | ADVERTISE_ALL;
+
+	ftgmac100_phy_write(dev, priv->phy_addr, MII_ADVERTISE, adv);
+
+	printf("%s: Starting autonegotiation...\n", dev->name);
+
+	ftgmac100_phy_write(dev, priv->phy_addr,
+		MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART));
+
+	for (i = 0; i < 100000 / 100; i++) {
+		ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &status);
+
+		if (status & BMSR_ANEGCOMPLETE)
+			break;
+		mdelay(1);
+	}
+
+	if (status & BMSR_ANEGCOMPLETE) {
+		printf("%s: Autonegotiation complete\n", dev->name);
+	} else {
+		printf("%s: Autonegotiation timed out (status=0x%04x)\n",
+		       dev->name, status);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int ftgmac100_phy_init(struct eth_device *dev)
+{
+	struct ftgmac100_data *priv = dev->priv;
+
+	int phy_addr;
+	u16 phy_id, status, adv, lpa, stat_ge;
+	int media, speed, duplex;
+	int i;
+
+	/* Check if the PHY is up to snuff... */
+	for (phy_addr = 0; phy_addr < CONFIG_PHY_MAX_ADDR; phy_addr++) {
+
+		ftgmac100_phy_read(dev, phy_addr, MII_PHYSID1, &phy_id);
+
+		/*
+		 * When it is unable to found PHY,
+		 * the interface usually return 0xffff or 0x0000
+		 */
+		if (phy_id != 0xffff && phy_id != 0x0) {
+			printf("%s: found PHY at 0x%02x\n",
+				dev->name, phy_addr);
+			priv->phy_addr = phy_addr;
+			break;
+		}
+	}
+
+	if (phy_id == 0xffff || phy_id == 0x0) {
+		printf("%s: no PHY present\n", dev->name);
+		return 0;
+	}
+
+	ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &status);
+
+	if (!(status & BMSR_LSTATUS)) {
+		/* Try to re-negotiate if we don't have link already. */
+		ftgmac100_phy_reset(dev);
+
+		for (i = 0; i < 100000 / 100; i++) {
+			ftgmac100_phy_read(dev, priv->phy_addr,
+				MII_BMSR, &status);
+			if (status & BMSR_LSTATUS)
+				break;
+			udelay(100);
+		}
+	}
+
+	if (!(status & BMSR_LSTATUS)) {
+		printf("%s: link down\n", dev->name);
+		return 0;
+	}
+
+#ifdef CONFIG_FTGMAC100_EGIGA
+	/* 1000 Base-T Status Register */
+	ftgmac100_phy_read(dev, priv->phy_addr,
+		MII_STAT1000, &stat_ge);
+
+	speed = (stat_ge & (LPA_1000FULL | LPA_1000HALF)
+		 ? 1 : 0);
+
+	duplex = ((stat_ge & LPA_1000FULL)
+		 ? 1 : 0);
+
+	if (speed) { /* Speed is 1000 */
+		printf("%s: link up, 1000bps %s-duplex\n",
+			dev->name, duplex ? "full" : "half");
+		return 0;
+	}
+#endif
+
+	ftgmac100_phy_read(dev, priv->phy_addr, MII_ADVERTISE, &adv);
+	ftgmac100_phy_read(dev, priv->phy_addr, MII_LPA, &lpa);
+
+	media = mii_nway_result(lpa & adv);
+	speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 1 : 0);
+	duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+
+	printf("%s: link up, %sMbps %s-duplex\n",
+	       dev->name, speed ? "100" : "10", duplex ? "full" : "half");
+
+	return 1;
+}
+
+static int ftgmac100_update_link_speed(struct eth_device *dev)
+{
+	struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+	struct ftgmac100_data *priv = dev->priv;
+
+	unsigned short stat_fe;
+	unsigned short stat_ge;
+	unsigned int maccr;
+
+#ifdef CONFIG_FTGMAC100_EGIGA
+	/* 1000 Base-T Status Register */
+	ftgmac100_phy_read(dev, priv->phy_addr, MII_STAT1000, &stat_ge);
+#endif
+
+	ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &stat_fe);
+
+	if (!(stat_fe & BMSR_LSTATUS))	/* link status up? */
+		return 0;
+
+	/* read MAC control register and clear related bits */
+	maccr = readl(&ftgmac100->maccr) &
+		~(FTGMAC100_MACCR_GIGA_MODE |
+		  FTGMAC100_MACCR_FAST_MODE |
+		  FTGMAC100_MACCR_FULLDUP);
+
+#ifdef CONFIG_FTGMAC100_EGIGA
+	if (stat_ge & LPA_1000FULL) {
+		/* set gmac for 1000BaseTX and Full Duplex */
+		maccr |= FTGMAC100_MACCR_GIGA_MODE | FTGMAC100_MACCR_FULLDUP;
+	}
+
+	if (stat_ge & LPA_1000HALF) {
+		/* set gmac for 1000BaseTX and Half Duplex */
+		maccr |= FTGMAC100_MACCR_GIGA_MODE;
+	}
+#endif
+
+	if (stat_fe & BMSR_100FULL) {
+		/* set MII for 100BaseTX and Full Duplex */
+		maccr |= FTGMAC100_MACCR_FAST_MODE | FTGMAC100_MACCR_FULLDUP;
+	}
+
+	if (stat_fe & BMSR_10FULL) {
+		/* set MII for 10BaseT and Full Duplex */
+		maccr |= FTGMAC100_MACCR_FULLDUP;
+	}
+
+	if (stat_fe & BMSR_100HALF) {
+		/* set MII for 100BaseTX and Half Duplex */
+		maccr |= FTGMAC100_MACCR_FAST_MODE;
+	}
+
+	if (stat_fe & BMSR_10HALF) {
+		/* set MII for 10BaseT and Half Duplex */
+		/* we have already clear these bits, do nothing */
+		;
+	}
+
+	/* update MII config into maccr */
+	writel(maccr, &ftgmac100->maccr);
+
+	return 1;
+}
+
+/*
+ * Reset MAC
+ */
+static void ftgmac100_reset(struct eth_device *dev)
+{
+	struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+
+	debug("%s()\n", __func__);
+
+	writel(FTGMAC100_MACCR_SW_RST, &ftgmac100->maccr);
+
+	while (readl(&ftgmac100->maccr) & FTGMAC100_MACCR_SW_RST)
+		;
+}
+
+/*
+ * Set MAC address
+ */
+static void ftgmac100_set_mac(struct eth_device *dev,
+	const unsigned char *mac)
+{
+	struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+	unsigned int maddr = mac[0] << 8 | mac[1];
+	unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
+
+	debug("%s(%x %x)\n", __func__, maddr, laddr);
+
+	writel(maddr, &ftgmac100->mac_madr);
+	writel(laddr, &ftgmac100->mac_ladr);
+}
+
+static void ftgmac100_set_mac_from_env(struct eth_device *dev)
+{
+	eth_getenv_enetaddr("ethaddr", dev->enetaddr);
+
+	ftgmac100_set_mac(dev, dev->enetaddr);
+}
+
+/*
+ * disable transmitter, receiver
+ */
+static void ftgmac100_halt(struct eth_device *dev)
+{
+	struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+
+	debug("%s()\n", __func__);
+
+	writel(0, &ftgmac100->maccr);
+}
+
+static int ftgmac100_init(struct eth_device *dev, bd_t *bd)
+{
+	struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+	struct ftgmac100_data *priv = dev->priv;
+	struct ftgmac100_txdes *txdes;
+	struct ftgmac100_rxdes *rxdes;
+	unsigned int maccr;
+	void *buf;
+	int i;
+
+	debug("%s()\n", __func__);
+
+	if (!priv->txdes) {
+		txdes = dma_alloc_coherent(
+			sizeof(*txdes) * PKTBUFSTX, &priv->txdes_dma);
+		if (!txdes)
+			panic("ftgmac100: out of memory\n");
+		memset(txdes, 0, sizeof(*txdes) * PKTBUFSTX);
+		priv->txdes = txdes;
+	}
+	txdes = priv->txdes;
+
+	if (!priv->rxdes) {
+		rxdes = dma_alloc_coherent(
+			sizeof(*rxdes) * PKTBUFSRX, &priv->rxdes_dma);
+		if (!rxdes)
+			panic("ftgmac100: out of memory\n");
+		memset(rxdes, 0, sizeof(*rxdes) * PKTBUFSRX);
+		priv->rxdes = rxdes;
+	}
+	rxdes = priv->rxdes;
+
+	/* set the ethernet address */
+	ftgmac100_set_mac_from_env(dev);
+
+	/* disable all interrupts */
+	writel(0, &ftgmac100->ier);
+
+	/* initialize descriptors */
+	priv->tx_index = 0;
+	priv->rx_index = 0;
+
+	txdes[PKTBUFSTX - 1].txdes0	= FTGMAC100_TXDES0_EDOTR;
+	rxdes[PKTBUFSRX - 1].rxdes0	= FTGMAC100_RXDES0_EDORR;
+
+	for (i = 0; i < PKTBUFSTX; i++) {
+		/* TXBUF_BADR */
+		if (!txdes[i].txdes2) {
+			buf = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE);
+			if (!buf)
+				panic("ftgmac100: out of memory\n");
+			txdes[i].txdes3 = virt_to_phys(buf);
+			txdes[i].txdes2 = (uint)buf;
+		}
+		txdes[i].txdes1 = 0;
+	}
+
+	for (i = 0; i < PKTBUFSRX; i++) {
+		/* RXBUF_BADR */
+		if (!rxdes[i].rxdes2) {
+			buf = NetRxPackets[i];
+			rxdes[i].rxdes3 = virt_to_phys(buf);
+			rxdes[i].rxdes2 = (uint)buf;
+		}
+		rxdes[i].rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
+	}
+
+	/* transmit ring */
+	writel(priv->txdes_dma, &ftgmac100->txr_badr);
+
+	/* receive ring */
+	writel(priv->rxdes_dma, &ftgmac100->rxr_badr);
+
+	/* poll receive descriptor automatically */
+	writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc);
+
+	/* config receive buffer size register */
+	writel(FTGMAC100_RBSR_SIZE(RBSR_DEFAULT_VALUE), &ftgmac100->rbsr);
+
+	/* enable transmitter, receiver */
+	maccr = FTGMAC100_MACCR_TXMAC_EN |
+		FTGMAC100_MACCR_RXMAC_EN |
+		FTGMAC100_MACCR_TXDMA_EN |
+		FTGMAC100_MACCR_RXDMA_EN |
+		FTGMAC100_MACCR_CRC_APD |
+		FTGMAC100_MACCR_FULLDUP |
+		FTGMAC100_MACCR_RX_RUNT |
+		FTGMAC100_MACCR_RX_BROADPKT;
+
+	writel(maccr, &ftgmac100->maccr);
+
+	if (!ftgmac100_phy_init(dev)) {
+		if (!ftgmac100_update_link_speed(dev))
+			return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Get a data block via Ethernet
+ */
+static int ftgmac100_recv(struct eth_device *dev)
+{
+	struct ftgmac100_data *priv = dev->priv;
+	struct ftgmac100_rxdes *curr_des;
+	unsigned short rxlen;
+
+	curr_des = &priv->rxdes[priv->rx_index];
+
+	if (!(curr_des->rxdes0 & FTGMAC100_RXDES0_RXPKT_RDY))
+		return -1;
+
+	if (curr_des->rxdes0 & (FTGMAC100_RXDES0_RX_ERR |
+				FTGMAC100_RXDES0_CRC_ERR |
+				FTGMAC100_RXDES0_FTL |
+				FTGMAC100_RXDES0_RUNT |
+				FTGMAC100_RXDES0_RX_ODD_NB)) {
+		return -1;
+	}
+
+	rxlen = FTGMAC100_RXDES0_VDBC(curr_des->rxdes0);
+
+	debug("%s(): RX buffer %d, %x received\n",
+	       __func__, priv->rx_index, rxlen);
+
+	/* invalidate d-cache */
+	dma_map_single((void *)curr_des->rxdes2, rxlen, DMA_FROM_DEVICE);
+
+	/* pass the packet up to the protocol layers. */
+	NetReceive((void *)curr_des->rxdes2, rxlen);
+
+	/* release buffer to DMA */
+	curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
+
+	priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX;
+
+	return 0;
+}
+
+/*
+ * Send a data block via Ethernet
+ */
+static int ftgmac100_send(struct eth_device *dev, void *packet, int length)
+{
+	struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase;
+	struct ftgmac100_data *priv = dev->priv;
+	struct ftgmac100_txdes *curr_des = &priv->txdes[priv->tx_index];
+
+	if (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) {
+		debug("%s(): no TX descriptor available\n", __func__);
+		return -1;
+	}
+
+	debug("%s(%x, %x)\n", __func__, (int)packet, length);
+
+	length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
+
+	memcpy((void *)curr_des->txdes2, (void *)packet, length);
+	dma_map_single((void *)curr_des->txdes2, length, DMA_TO_DEVICE);
+
+	/* only one descriptor on TXBUF */
+	curr_des->txdes0 &= FTGMAC100_TXDES0_EDOTR;
+	curr_des->txdes0 |= FTGMAC100_TXDES0_FTS |
+			    FTGMAC100_TXDES0_LTS |
+			    FTGMAC100_TXDES0_TXBUF_SIZE(length) |
+			    FTGMAC100_TXDES0_TXDMA_OWN ;
+
+	/* start transmit */
+	writel(1, &ftgmac100->txpd);
+
+	debug("%s(): packet sent\n", __func__);
+
+	priv->tx_index = (priv->tx_index + 1) % PKTBUFSTX;
+
+	return 0;
+}
+
+int ftgmac100_initialize(bd_t *bd)
+{
+	struct eth_device *dev;
+	struct ftgmac100_data *priv;
+
+	dev = malloc(sizeof *dev);
+	if (!dev) {
+		printf("%s(): failed to allocate dev\n", __func__);
+		goto out;
+	}
+
+	/* Transmit and receive descriptors should align to 16 bytes */
+	priv = memalign(16, sizeof(struct ftgmac100_data));
+	if (!priv) {
+		printf("%s(): failed to allocate priv\n", __func__);
+		goto free_dev;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	memset(priv, 0, sizeof(*priv));
+
+	sprintf(dev->name, "FTGMAC100");
+	dev->iobase	= CONFIG_FTGMAC100_BASE;
+	dev->init	= ftgmac100_init;
+	dev->halt	= ftgmac100_halt;
+	dev->send	= ftgmac100_send;
+	dev->recv	= ftgmac100_recv;
+	dev->priv	= priv;
+
+	eth_register(dev);
+
+	ftgmac100_reset(dev);
+
+	return 1;
+
+free_dev:
+	free(dev);
+out:
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/ftgmac100.h b/marvell/uboot/drivers/net/ftgmac100.h
new file mode 100644
index 0000000..71121ba
--- /dev/null
+++ b/marvell/uboot/drivers/net/ftgmac100.h
@@ -0,0 +1,243 @@
+/*
+ * Faraday FTGMAC100 Ethernet
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Po-Yu Chuang <ratbert@faraday-tech.com>
+ *
+ * (C) Copyright 2010 Andes Technology
+ * Macpaul Lin <macpaul@andestech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __FTGMAC100_H
+#define __FTGMAC100_H
+
+/* The registers offset table of ftgmac100 */
+struct ftgmac100 {
+	unsigned int	isr;		/* 0x00 */
+	unsigned int	ier;		/* 0x04 */
+	unsigned int	mac_madr;	/* 0x08 */
+	unsigned int	mac_ladr;	/* 0x0c */
+	unsigned int	maht0;		/* 0x10 */
+	unsigned int	maht1;		/* 0x14 */
+	unsigned int	txpd;		/* 0x18 */
+	unsigned int	rxpd;		/* 0x1c */
+	unsigned int	txr_badr;	/* 0x20 */
+	unsigned int	rxr_badr;	/* 0x24 */
+	unsigned int	hptxpd;		/* 0x28 */
+	unsigned int	hptxpd_badr;	/* 0x2c */
+	unsigned int	itc;		/* 0x30 */
+	unsigned int	aptc;		/* 0x34 */
+	unsigned int	dblac;		/* 0x38 */
+	unsigned int	dmafifos;	/* 0x3c */
+	unsigned int	revr;		/* 0x40 */
+	unsigned int	fear;		/* 0x44 */
+	unsigned int	tpafcr;		/* 0x48 */
+	unsigned int	rbsr;		/* 0x4c */
+	unsigned int	maccr;		/* 0x50 */
+	unsigned int	macsr;		/* 0x54 */
+	unsigned int	tm;		/* 0x58 */
+	unsigned int	resv1;		/* 0x5c */ /* not defined in spec */
+	unsigned int	phycr;		/* 0x60 */
+	unsigned int	phydata;	/* 0x64 */
+	unsigned int	fcr;		/* 0x68 */
+	unsigned int	bpr;		/* 0x6c */
+	unsigned int	wolcr;		/* 0x70 */
+	unsigned int	wolsr;		/* 0x74 */
+	unsigned int	wfcrc;		/* 0x78 */
+	unsigned int	resv2;		/* 0x7c */ /* not defined in spec */
+	unsigned int	wfbm1;		/* 0x80 */
+	unsigned int	wfbm2;		/* 0x84 */
+	unsigned int	wfbm3;		/* 0x88 */
+	unsigned int	wfbm4;		/* 0x8c */
+	unsigned int	nptxr_ptr;	/* 0x90 */
+	unsigned int	hptxr_ptr;	/* 0x94 */
+	unsigned int	rxr_ptr;	/* 0x98 */
+	unsigned int	resv3;		/* 0x9c */ /* not defined in spec */
+	unsigned int	tx;		/* 0xa0 */
+	unsigned int	tx_mcol_scol;	/* 0xa4 */
+	unsigned int	tx_ecol_fail;	/* 0xa8 */
+	unsigned int	tx_lcol_und;	/* 0xac */
+	unsigned int	rx;		/* 0xb0 */
+	unsigned int	rx_bc;		/* 0xb4 */
+	unsigned int	rx_mc;		/* 0xb8 */
+	unsigned int	rx_pf_aep;	/* 0xbc */
+	unsigned int	rx_runt;	/* 0xc0 */
+	unsigned int	rx_crcer_ftl;	/* 0xc4 */
+	unsigned int	rx_col_lost;	/* 0xc8 */
+};
+
+/*
+ * Interrupt status register & interrupt enable register
+ */
+#define FTGMAC100_INT_RPKT_BUF		(1 << 0)
+#define FTGMAC100_INT_RPKT_FIFO		(1 << 1)
+#define FTGMAC100_INT_NO_RXBUF		(1 << 2)
+#define FTGMAC100_INT_RPKT_LOST		(1 << 3)
+#define FTGMAC100_INT_XPKT_ETH		(1 << 4)
+#define FTGMAC100_INT_XPKT_FIFO		(1 << 5)
+#define FTGMAC100_INT_NO_NPTXBUF	(1 << 6)
+#define FTGMAC100_INT_XPKT_LOST		(1 << 7)
+#define FTGMAC100_INT_AHB_ERR		(1 << 8)
+#define FTGMAC100_INT_PHYSTS_CHG	(1 << 9)
+#define FTGMAC100_INT_NO_HPTXBUF	(1 << 10)
+
+/*
+ * Interrupt timer control register
+ */
+#define FTGMAC100_ITC_RXINT_CNT(x)	(((x) & 0xf) << 0)
+#define FTGMAC100_ITC_RXINT_THR(x)	(((x) & 0x7) << 4)
+#define FTGMAC100_ITC_RXINT_TIME_SEL	(1 << 7)
+#define FTGMAC100_ITC_TXINT_CNT(x)	(((x) & 0xf) << 8)
+#define FTGMAC100_ITC_TXINT_THR(x)	(((x) & 0x7) << 12)
+#define FTGMAC100_ITC_TXINT_TIME_SEL	(1 << 15)
+
+/*
+ * Automatic polling timer control register
+ */
+#define FTGMAC100_APTC_RXPOLL_CNT(x)	(((x) & 0xf) << 0)
+#define FTGMAC100_APTC_RXPOLL_TIME_SEL	(1 << 4)
+#define FTGMAC100_APTC_TXPOLL_CNT(x)	(((x) & 0xf) << 8)
+#define FTGMAC100_APTC_TXPOLL_TIME_SEL	(1 << 12)
+
+/*
+ * DMA burst length and arbitration control register
+ */
+#define FTGMAC100_DBLAC_RXFIFO_LTHR(x)	(((x) & 0x7) << 0)
+#define FTGMAC100_DBLAC_RXFIFO_HTHR(x)	(((x) & 0x7) << 3)
+#define FTGMAC100_DBLAC_RX_THR_EN	(1 << 6)
+#define FTGMAC100_DBLAC_RXBURST_SIZE(x)	(((x) & 0x3) << 8)
+#define FTGMAC100_DBLAC_TXBURST_SIZE(x)	(((x) & 0x3) << 10)
+#define FTGMAC100_DBLAC_RXDES_SIZE(x)	(((x) & 0xf) << 12)
+#define FTGMAC100_DBLAC_TXDES_SIZE(x)	(((x) & 0xf) << 16)
+#define FTGMAC100_DBLAC_IFG_CNT(x)	(((x) & 0x7) << 20)
+#define FTGMAC100_DBLAC_IFG_INC		(1 << 23)
+
+/*
+ * DMA FIFO status register
+ */
+#define FTGMAC100_DMAFIFOS_RXDMA1_SM(dmafifos)	((dmafifos) & 0xf)
+#define FTGMAC100_DMAFIFOS_RXDMA2_SM(dmafifos)	(((dmafifos) >> 4) & 0xf)
+#define FTGMAC100_DMAFIFOS_RXDMA3_SM(dmafifos)	(((dmafifos) >> 8) & 0x7)
+#define FTGMAC100_DMAFIFOS_TXDMA1_SM(dmafifos)	(((dmafifos) >> 12) & 0xf)
+#define FTGMAC100_DMAFIFOS_TXDMA2_SM(dmafifos)	(((dmafifos) >> 16) & 0x3)
+#define FTGMAC100_DMAFIFOS_TXDMA3_SM(dmafifos)	(((dmafifos) >> 18) & 0xf)
+#define FTGMAC100_DMAFIFOS_RXFIFO_EMPTY		(1 << 26)
+#define FTGMAC100_DMAFIFOS_TXFIFO_EMPTY		(1 << 27)
+#define FTGMAC100_DMAFIFOS_RXDMA_GRANT		(1 << 28)
+#define FTGMAC100_DMAFIFOS_TXDMA_GRANT		(1 << 29)
+#define FTGMAC100_DMAFIFOS_RXDMA_REQ		(1 << 30)
+#define FTGMAC100_DMAFIFOS_TXDMA_REQ		(1 << 31)
+
+/*
+ * Receive buffer size register
+ */
+#define FTGMAC100_RBSR_SIZE(x)		((x) & 0x3fff)
+
+/*
+ * MAC control register
+ */
+#define FTGMAC100_MACCR_TXDMA_EN	(1 << 0)
+#define FTGMAC100_MACCR_RXDMA_EN	(1 << 1)
+#define FTGMAC100_MACCR_TXMAC_EN	(1 << 2)
+#define FTGMAC100_MACCR_RXMAC_EN	(1 << 3)
+#define FTGMAC100_MACCR_RM_VLAN		(1 << 4)
+#define FTGMAC100_MACCR_HPTXR_EN	(1 << 5)
+#define FTGMAC100_MACCR_LOOP_EN		(1 << 6)
+#define FTGMAC100_MACCR_ENRX_IN_HALFTX	(1 << 7)
+#define FTGMAC100_MACCR_FULLDUP		(1 << 8)
+#define FTGMAC100_MACCR_GIGA_MODE	(1 << 9)
+#define FTGMAC100_MACCR_CRC_APD		(1 << 10)
+#define FTGMAC100_MACCR_RX_RUNT		(1 << 12)
+#define FTGMAC100_MACCR_JUMBO_LF	(1 << 13)
+#define FTGMAC100_MACCR_RX_ALL		(1 << 14)
+#define FTGMAC100_MACCR_HT_MULTI_EN	(1 << 15)
+#define FTGMAC100_MACCR_RX_MULTIPKT	(1 << 16)
+#define FTGMAC100_MACCR_RX_BROADPKT	(1 << 17)
+#define FTGMAC100_MACCR_DISCARD_CRCERR	(1 << 18)
+#define FTGMAC100_MACCR_FAST_MODE	(1 << 19)
+#define FTGMAC100_MACCR_SW_RST		(1 << 31)
+
+/*
+ * PHY control register
+ */
+#define FTGMAC100_PHYCR_MDC_CYCTHR_MASK	0x3f
+#define FTGMAC100_PHYCR_MDC_CYCTHR(x)	((x) & 0x3f)
+#define FTGMAC100_PHYCR_PHYAD(x)	(((x) & 0x1f) << 16)
+#define FTGMAC100_PHYCR_REGAD(x)	(((x) & 0x1f) << 21)
+#define FTGMAC100_PHYCR_MIIRD		(1 << 26)
+#define FTGMAC100_PHYCR_MIIWR		(1 << 27)
+
+/*
+ * PHY data register
+ */
+#define FTGMAC100_PHYDATA_MIIWDATA(x)		((x) & 0xffff)
+#define FTGMAC100_PHYDATA_MIIRDATA(phydata)	(((phydata) >> 16) & 0xffff)
+
+/*
+ * Transmit descriptor, aligned to 16 bytes
+ */
+struct ftgmac100_txdes {
+	unsigned int	txdes0;
+	unsigned int	txdes1;
+	unsigned int	txdes2;	/* not used by HW */
+	unsigned int	txdes3;	/* TXBUF_BADR */
+} __attribute__ ((aligned(16)));
+
+#define FTGMAC100_TXDES0_TXBUF_SIZE(x)	((x) & 0x3fff)
+#define FTGMAC100_TXDES0_EDOTR		(1 << 15)
+#define FTGMAC100_TXDES0_CRC_ERR	(1 << 19)
+#define FTGMAC100_TXDES0_LTS		(1 << 28)
+#define FTGMAC100_TXDES0_FTS		(1 << 29)
+#define FTGMAC100_TXDES0_TXDMA_OWN	(1 << 31)
+
+#define FTGMAC100_TXDES1_VLANTAG_CI(x)	((x) & 0xffff)
+#define FTGMAC100_TXDES1_INS_VLANTAG	(1 << 16)
+#define FTGMAC100_TXDES1_TCP_CHKSUM	(1 << 17)
+#define FTGMAC100_TXDES1_UDP_CHKSUM	(1 << 18)
+#define FTGMAC100_TXDES1_IP_CHKSUM	(1 << 19)
+#define FTGMAC100_TXDES1_LLC		(1 << 22)
+#define FTGMAC100_TXDES1_TX2FIC		(1 << 30)
+#define FTGMAC100_TXDES1_TXIC		(1 << 31)
+
+/*
+ * Receive descriptor, aligned to 16 bytes
+ */
+struct ftgmac100_rxdes {
+	unsigned int	rxdes0;
+	unsigned int	rxdes1;
+	unsigned int	rxdes2;	/* not used by HW */
+	unsigned int	rxdes3;	/* RXBUF_BADR */
+} __attribute__ ((aligned(16)));
+
+#define FTGMAC100_RXDES0_VDBC(x)	((x) & 0x3fff)
+#define FTGMAC100_RXDES0_EDORR		(1 << 15)
+#define FTGMAC100_RXDES0_MULTICAST	(1 << 16)
+#define FTGMAC100_RXDES0_BROADCAST	(1 << 17)
+#define FTGMAC100_RXDES0_RX_ERR		(1 << 18)
+#define FTGMAC100_RXDES0_CRC_ERR	(1 << 19)
+#define FTGMAC100_RXDES0_FTL		(1 << 20)
+#define FTGMAC100_RXDES0_RUNT		(1 << 21)
+#define FTGMAC100_RXDES0_RX_ODD_NB	(1 << 22)
+#define FTGMAC100_RXDES0_FIFO_FULL	(1 << 23)
+#define FTGMAC100_RXDES0_PAUSE_OPCODE	(1 << 24)
+#define FTGMAC100_RXDES0_PAUSE_FRAME	(1 << 25)
+#define FTGMAC100_RXDES0_LRS		(1 << 28)
+#define FTGMAC100_RXDES0_FRS		(1 << 29)
+#define FTGMAC100_RXDES0_RXPKT_RDY	(1 << 31)
+
+#define FTGMAC100_RXDES1_VLANTAG_CI	0xffff
+#define FTGMAC100_RXDES1_PROT_MASK	(0x3 << 20)
+#define FTGMAC100_RXDES1_PROT_NONIP	(0x0 << 20)
+#define FTGMAC100_RXDES1_PROT_IP	(0x1 << 20)
+#define FTGMAC100_RXDES1_PROT_TCPIP	(0x2 << 20)
+#define FTGMAC100_RXDES1_PROT_UDPIP	(0x3 << 20)
+#define FTGMAC100_RXDES1_LLC		(1 << 22)
+#define FTGMAC100_RXDES1_DF		(1 << 23)
+#define FTGMAC100_RXDES1_VLANTAG_AVAIL	(1 << 24)
+#define FTGMAC100_RXDES1_TCP_CHKSUM_ERR	(1 << 25)
+#define FTGMAC100_RXDES1_UDP_CHKSUM_ERR	(1 << 26)
+#define FTGMAC100_RXDES1_IP_CHKSUM_ERR	(1 << 27)
+
+#endif /* __FTGMAC100_H */
diff --git a/marvell/uboot/drivers/net/ftmac100.c b/marvell/uboot/drivers/net/ftmac100.c
new file mode 100644
index 0000000..3e148db
--- /dev/null
+++ b/marvell/uboot/drivers/net/ftmac100.c
@@ -0,0 +1,265 @@
+/*
+ * Faraday FTMAC100 Ethernet
+ *
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratbert@faraday-tech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+
+#include "ftmac100.h"
+
+#define ETH_ZLEN	60
+
+struct ftmac100_data {
+	struct ftmac100_txdes txdes[1];
+	struct ftmac100_rxdes rxdes[PKTBUFSRX];
+	int rx_index;
+};
+
+/*
+ * Reset MAC
+ */
+static void ftmac100_reset (struct eth_device *dev)
+{
+	struct ftmac100 *ftmac100 = (struct ftmac100 *)dev->iobase;
+
+	debug ("%s()\n", __func__);
+
+	writel (FTMAC100_MACCR_SW_RST, &ftmac100->maccr);
+
+	while (readl (&ftmac100->maccr) & FTMAC100_MACCR_SW_RST)
+		;
+}
+
+/*
+ * Set MAC address
+ */
+static void ftmac100_set_mac (struct eth_device *dev, const unsigned char *mac)
+{
+	struct ftmac100 *ftmac100 = (struct ftmac100 *)dev->iobase;
+	unsigned int maddr = mac[0] << 8 | mac[1];
+	unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
+
+	debug ("%s(%x %x)\n", __func__, maddr, laddr);
+
+	writel (maddr, &ftmac100->mac_madr);
+	writel (laddr, &ftmac100->mac_ladr);
+}
+
+static void ftmac100_set_mac_from_env (struct eth_device *dev)
+{
+	eth_getenv_enetaddr ("ethaddr", dev->enetaddr);
+
+	ftmac100_set_mac (dev, dev->enetaddr);
+}
+
+/*
+ * disable transmitter, receiver
+ */
+static void ftmac100_halt (struct eth_device *dev)
+{
+	struct ftmac100 *ftmac100 = (struct ftmac100 *)dev->iobase;
+
+	debug ("%s()\n", __func__);
+
+	writel (0, &ftmac100->maccr);
+}
+
+static int ftmac100_init (struct eth_device *dev, bd_t *bd)
+{
+	struct ftmac100 *ftmac100 = (struct ftmac100 *)dev->iobase;
+	struct ftmac100_data *priv = dev->priv;
+	struct ftmac100_txdes *txdes = priv->txdes;
+	struct ftmac100_rxdes *rxdes = priv->rxdes;
+	unsigned int maccr;
+	int i;
+
+	debug ("%s()\n", __func__);
+
+	ftmac100_reset (dev);
+
+	/* set the ethernet address */
+
+	ftmac100_set_mac_from_env (dev);
+
+	/* disable all interrupts */
+
+	writel (0, &ftmac100->imr);
+
+	/* initialize descriptors */
+
+	priv->rx_index = 0;
+
+	txdes[0].txdes1			= FTMAC100_TXDES1_EDOTR;
+	rxdes[PKTBUFSRX - 1].rxdes1	= FTMAC100_RXDES1_EDORR;
+
+	for (i = 0; i < PKTBUFSRX; i++) {
+		/* RXBUF_BADR */
+		rxdes[i].rxdes2 = (unsigned int)NetRxPackets[i];
+		rxdes[i].rxdes1 |= FTMAC100_RXDES1_RXBUF_SIZE (PKTSIZE_ALIGN);
+		rxdes[i].rxdes0 = FTMAC100_RXDES0_RXDMA_OWN;
+	}
+
+	/* transmit ring */
+
+	writel ((unsigned int)txdes, &ftmac100->txr_badr);
+
+	/* receive ring */
+
+	writel ((unsigned int)rxdes, &ftmac100->rxr_badr);
+
+	/* poll receive descriptor automatically */
+
+	writel (FTMAC100_APTC_RXPOLL_CNT (1), &ftmac100->aptc);
+
+	/* enable transmitter, receiver */
+
+	maccr = FTMAC100_MACCR_XMT_EN |
+		FTMAC100_MACCR_RCV_EN |
+		FTMAC100_MACCR_XDMA_EN |
+		FTMAC100_MACCR_RDMA_EN |
+		FTMAC100_MACCR_CRC_APD |
+		FTMAC100_MACCR_ENRX_IN_HALFTX |
+		FTMAC100_MACCR_RX_RUNT |
+		FTMAC100_MACCR_RX_BROADPKT;
+
+	writel (maccr, &ftmac100->maccr);
+
+	return 0;
+}
+
+/*
+ * Get a data block via Ethernet
+ */
+static int ftmac100_recv (struct eth_device *dev)
+{
+	struct ftmac100_data *priv = dev->priv;
+	struct ftmac100_rxdes *curr_des;
+	unsigned short rxlen;
+
+	curr_des = &priv->rxdes[priv->rx_index];
+
+	if (curr_des->rxdes0 & FTMAC100_RXDES0_RXDMA_OWN)
+		return -1;
+
+	if (curr_des->rxdes0 & (FTMAC100_RXDES0_RX_ERR |
+				FTMAC100_RXDES0_CRC_ERR |
+				FTMAC100_RXDES0_FTL |
+				FTMAC100_RXDES0_RUNT |
+				FTMAC100_RXDES0_RX_ODD_NB)) {
+		return -1;
+	}
+
+	rxlen = FTMAC100_RXDES0_RFL (curr_des->rxdes0);
+
+	debug ("%s(): RX buffer %d, %x received\n",
+	       __func__, priv->rx_index, rxlen);
+
+	/* pass the packet up to the protocol layers. */
+
+	NetReceive ((void *)curr_des->rxdes2, rxlen);
+
+	/* release buffer to DMA */
+
+	curr_des->rxdes0 |= FTMAC100_RXDES0_RXDMA_OWN;
+
+	priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX;
+
+	return 0;
+}
+
+/*
+ * Send a data block via Ethernet
+ */
+static int ftmac100_send(struct eth_device *dev, void *packet, int length)
+{
+	struct ftmac100 *ftmac100 = (struct ftmac100 *)dev->iobase;
+	struct ftmac100_data *priv = dev->priv;
+	struct ftmac100_txdes *curr_des = priv->txdes;
+	ulong start;
+
+	if (curr_des->txdes0 & FTMAC100_TXDES0_TXDMA_OWN) {
+		debug ("%s(): no TX descriptor available\n", __func__);
+		return -1;
+	}
+
+	debug ("%s(%x, %x)\n", __func__, (int)packet, length);
+
+	length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
+
+	/* initiate a transmit sequence */
+
+	curr_des->txdes2 = (unsigned int)packet;	/* TXBUF_BADR */
+
+	curr_des->txdes1 &= FTMAC100_TXDES1_EDOTR;
+	curr_des->txdes1 |= FTMAC100_TXDES1_FTS |
+			    FTMAC100_TXDES1_LTS |
+			    FTMAC100_TXDES1_TXBUF_SIZE (length);
+
+	curr_des->txdes0 = FTMAC100_TXDES0_TXDMA_OWN;
+
+	/* start transmit */
+
+	writel (1, &ftmac100->txpd);
+
+	/* wait for transfer to succeed */
+
+	start = get_timer(0);
+	while (curr_des->txdes0 & FTMAC100_TXDES0_TXDMA_OWN) {
+		if (get_timer(start) >= 5) {
+			debug ("%s(): timed out\n", __func__);
+			return -1;
+		}
+	}
+
+	debug ("%s(): packet sent\n", __func__);
+
+	return 0;
+}
+
+int ftmac100_initialize (bd_t *bd)
+{
+	struct eth_device *dev;
+	struct ftmac100_data *priv;
+
+	dev = malloc (sizeof *dev);
+	if (!dev) {
+		printf ("%s(): failed to allocate dev\n", __func__);
+		goto out;
+	}
+
+	/* Transmit and receive descriptors should align to 16 bytes */
+
+	priv = memalign (16, sizeof (struct ftmac100_data));
+	if (!priv) {
+		printf ("%s(): failed to allocate priv\n", __func__);
+		goto free_dev;
+	}
+
+	memset (dev, 0, sizeof (*dev));
+	memset (priv, 0, sizeof (*priv));
+
+	sprintf (dev->name, "FTMAC100");
+	dev->iobase	= CONFIG_FTMAC100_BASE;
+	dev->init	= ftmac100_init;
+	dev->halt	= ftmac100_halt;
+	dev->send	= ftmac100_send;
+	dev->recv	= ftmac100_recv;
+	dev->priv	= priv;
+
+	eth_register (dev);
+
+	return 1;
+
+free_dev:
+	free (dev);
+out:
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/ftmac100.h b/marvell/uboot/drivers/net/ftmac100.h
new file mode 100644
index 0000000..b674d02
--- /dev/null
+++ b/marvell/uboot/drivers/net/ftmac100.h
@@ -0,0 +1,142 @@
+/*
+ * Faraday FTMAC100 Ethernet
+ *
+ * (C) Copyright 2009 Faraday Technology
+ * Po-Yu Chuang <ratbert@faraday-tech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __FTMAC100_H
+#define __FTMAC100_H
+
+struct ftmac100 {
+	unsigned int	isr;		/* 0x00 */
+	unsigned int	imr;		/* 0x04 */
+	unsigned int	mac_madr;	/* 0x08 */
+	unsigned int	mac_ladr;	/* 0x0c */
+	unsigned int	maht0;		/* 0x10 */
+	unsigned int	maht1;		/* 0x14 */
+	unsigned int	txpd;		/* 0x18 */
+	unsigned int	rxpd;		/* 0x1c */
+	unsigned int	txr_badr;	/* 0x20 */
+	unsigned int	rxr_badr;	/* 0x24 */
+	unsigned int	itc;		/* 0x28 */
+	unsigned int	aptc;		/* 0x2c */
+	unsigned int	dblac;		/* 0x30 */
+	unsigned int	pad1[3];	/* 0x34 - 0x3c */
+	unsigned int	pad2[16];	/* 0x40 - 0x7c */
+	unsigned int	pad3[2];	/* 0x80 - 0x84 */
+	unsigned int	maccr;		/* 0x88 */
+	unsigned int	macsr;		/* 0x8c */
+	unsigned int	phycr;		/* 0x90 */
+	unsigned int	phywdata;	/* 0x94 */
+	unsigned int	fcr;		/* 0x98 */
+	unsigned int	bpr;		/* 0x9c */
+	unsigned int	pad4[8];	/* 0xa0 - 0xbc */
+	unsigned int	pad5;		/* 0xc0 */
+	unsigned int	ts;		/* 0xc4 */
+	unsigned int	dmafifos;	/* 0xc8 */
+	unsigned int	tm;		/* 0xcc */
+	unsigned int	pad6;		/* 0xd0 */
+	unsigned int	tx_mcol_scol;	/* 0xd4 */
+	unsigned int	rpf_aep;	/* 0xd8 */
+	unsigned int	xm_pg;		/* 0xdc */
+	unsigned int	runt_tlcc;	/* 0xe0 */
+	unsigned int	crcer_ftl;	/* 0xe4 */
+	unsigned int	rlc_rcc;	/* 0xe8 */
+	unsigned int	broc;		/* 0xec */
+	unsigned int	mulca;		/* 0xf0 */
+	unsigned int	rp;		/* 0xf4 */
+	unsigned int	xp;		/* 0xf8 */
+};
+
+/*
+ * Interrupt status register & interrupt mask register
+ */
+#define FTMAC100_INT_RPKT_FINISH	(1 << 0)
+#define FTMAC100_INT_NORXBUF		(1 << 1)
+#define FTMAC100_INT_XPKT_FINISH	(1 << 2)
+#define FTMAC100_INT_NOTXBUF		(1 << 3)
+#define FTMAC100_INT_XPKT_OK		(1 << 4)
+#define FTMAC100_INT_XPKT_LOST		(1 << 5)
+#define FTMAC100_INT_RPKT_SAV		(1 << 6)
+#define FTMAC100_INT_RPKT_LOST		(1 << 7)
+#define FTMAC100_INT_AHB_ERR		(1 << 8)
+#define FTMAC100_INT_PHYSTS_CHG		(1 << 9)
+
+/*
+ * Automatic polling timer control register
+ */
+#define FTMAC100_APTC_RXPOLL_CNT(x)	(((x) & 0xf) << 0)
+#define FTMAC100_APTC_RXPOLL_TIME_SEL	(1 << 4)
+#define FTMAC100_APTC_TXPOLL_CNT(x)	(((x) & 0xf) << 8)
+#define FTMAC100_APTC_TXPOLL_TIME_SEL	(1 << 12)
+
+/*
+ * MAC control register
+ */
+#define FTMAC100_MACCR_XDMA_EN		(1 << 0)
+#define FTMAC100_MACCR_RDMA_EN		(1 << 1)
+#define FTMAC100_MACCR_SW_RST		(1 << 2)
+#define FTMAC100_MACCR_LOOP_EN		(1 << 3)
+#define FTMAC100_MACCR_CRC_DIS		(1 << 4)
+#define FTMAC100_MACCR_XMT_EN		(1 << 5)
+#define FTMAC100_MACCR_ENRX_IN_HALFTX	(1 << 6)
+#define FTMAC100_MACCR_RCV_EN		(1 << 8)
+#define FTMAC100_MACCR_HT_MULTI_EN	(1 << 9)
+#define FTMAC100_MACCR_RX_RUNT		(1 << 10)
+#define FTMAC100_MACCR_RX_FTL		(1 << 11)
+#define FTMAC100_MACCR_RCV_ALL		(1 << 12)
+#define FTMAC100_MACCR_CRC_APD		(1 << 14)
+#define FTMAC100_MACCR_FULLDUP		(1 << 15)
+#define FTMAC100_MACCR_RX_MULTIPKT	(1 << 16)
+#define FTMAC100_MACCR_RX_BROADPKT	(1 << 17)
+
+/*
+ * Transmit descriptor, aligned to 16 bytes
+ */
+struct ftmac100_txdes {
+	unsigned int	txdes0;
+	unsigned int	txdes1;
+	unsigned int	txdes2;	/* TXBUF_BADR */
+	unsigned int	txdes3;	/* not used by HW */
+} __attribute__ ((aligned(16)));
+
+#define FTMAC100_TXDES0_TXPKT_LATECOL	(1 << 0)
+#define FTMAC100_TXDES0_TXPKT_EXSCOL	(1 << 1)
+#define FTMAC100_TXDES0_TXDMA_OWN	(1 << 31)
+
+#define FTMAC100_TXDES1_TXBUF_SIZE(x)	((x) & 0x7ff)
+#define FTMAC100_TXDES1_LTS		(1 << 27)
+#define FTMAC100_TXDES1_FTS		(1 << 28)
+#define FTMAC100_TXDES1_TX2FIC		(1 << 29)
+#define FTMAC100_TXDES1_TXIC		(1 << 30)
+#define FTMAC100_TXDES1_EDOTR		(1 << 31)
+
+/*
+ * Receive descriptor, aligned to 16 bytes
+ */
+struct ftmac100_rxdes {
+	unsigned int	rxdes0;
+	unsigned int	rxdes1;
+	unsigned int	rxdes2;	/* RXBUF_BADR */
+	unsigned int	rxdes3;	/* not used by HW */
+} __attribute__ ((aligned(16)));
+
+#define FTMAC100_RXDES0_RFL(des)	((des) & 0x7ff)
+#define FTMAC100_RXDES0_MULTICAST	(1 << 16)
+#define FTMAC100_RXDES0_BROADCAST	(1 << 17)
+#define FTMAC100_RXDES0_RX_ERR		(1 << 18)
+#define FTMAC100_RXDES0_CRC_ERR		(1 << 19)
+#define FTMAC100_RXDES0_FTL		(1 << 20)
+#define FTMAC100_RXDES0_RUNT		(1 << 21)
+#define FTMAC100_RXDES0_RX_ODD_NB	(1 << 22)
+#define FTMAC100_RXDES0_LRS		(1 << 28)
+#define FTMAC100_RXDES0_FRS		(1 << 29)
+#define FTMAC100_RXDES0_RXDMA_OWN	(1 << 31)
+
+#define FTMAC100_RXDES1_RXBUF_SIZE(x)	((x) & 0x7ff)
+#define FTMAC100_RXDES1_EDORR		(1 << 31)
+
+#endif	/* __FTMAC100_H */
diff --git a/marvell/uboot/drivers/net/ftmac110.c b/marvell/uboot/drivers/net/ftmac110.c
new file mode 100644
index 0000000..8eee272
--- /dev/null
+++ b/marvell/uboot/drivers/net/ftmac110.c
@@ -0,0 +1,480 @@
+/*
+ * Faraday 10/100Mbps Ethernet Controller
+ *
+ * (C) Copyright 2013 Faraday Technology
+ * Dante Su <dantesu@faraday-tech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/dma-mapping.h>
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+#include <miiphy.h>
+#endif
+
+#include "ftmac110.h"
+
+#define CFG_RXDES_NUM   8
+#define CFG_TXDES_NUM   2
+#define CFG_XBUF_SIZE   1536
+
+#define CFG_MDIORD_TIMEOUT  (CONFIG_SYS_HZ >> 1) /* 500 ms */
+#define CFG_MDIOWR_TIMEOUT  (CONFIG_SYS_HZ >> 1) /* 500 ms */
+#define CFG_LINKUP_TIMEOUT  (CONFIG_SYS_HZ << 2) /* 4 sec */
+
+/*
+ * FTMAC110 DMA design issue
+ *
+ * Its DMA engine has a weird restriction that its Rx DMA engine
+ * accepts only 16-bits aligned address, 32-bits aligned is not
+ * acceptable. However this restriction does not apply to Tx DMA.
+ *
+ * Conclusion:
+ * (1) Tx DMA Buffer Address:
+ *     1 bytes aligned: Invalid
+ *     2 bytes aligned: O.K
+ *     4 bytes aligned: O.K (-> u-boot ZeroCopy is possible)
+ * (2) Rx DMA Buffer Address:
+ *     1 bytes aligned: Invalid
+ *     2 bytes aligned: O.K
+ *     4 bytes aligned: Invalid
+ */
+
+struct ftmac110_chip {
+	void __iomem *regs;
+	uint32_t imr;
+	uint32_t maccr;
+	uint32_t lnkup;
+	uint32_t phy_addr;
+
+	struct ftmac110_desc *rxd;
+	ulong                rxd_dma;
+	uint32_t             rxd_idx;
+
+	struct ftmac110_desc *txd;
+	ulong                txd_dma;
+	uint32_t             txd_idx;
+};
+
+static int ftmac110_reset(struct eth_device *dev);
+
+static uint16_t mdio_read(struct eth_device *dev,
+	uint8_t phyaddr, uint8_t phyreg)
+{
+	struct ftmac110_chip *chip = dev->priv;
+	struct ftmac110_regs *regs = chip->regs;
+	uint32_t tmp, ts;
+	uint16_t ret = 0xffff;
+
+	tmp = PHYCR_READ
+		| (phyaddr << PHYCR_ADDR_SHIFT)
+		| (phyreg  << PHYCR_REG_SHIFT);
+
+	writel(tmp, &regs->phycr);
+
+	for (ts = get_timer(0); get_timer(ts) < CFG_MDIORD_TIMEOUT; ) {
+		tmp = readl(&regs->phycr);
+		if (tmp & PHYCR_READ)
+			continue;
+		break;
+	}
+
+	if (tmp & PHYCR_READ)
+		printf("ftmac110: mdio read timeout\n");
+	else
+		ret = (uint16_t)(tmp & 0xffff);
+
+	return ret;
+}
+
+static void mdio_write(struct eth_device *dev,
+	uint8_t phyaddr, uint8_t phyreg, uint16_t phydata)
+{
+	struct ftmac110_chip *chip = dev->priv;
+	struct ftmac110_regs *regs = chip->regs;
+	uint32_t tmp, ts;
+
+	tmp = PHYCR_WRITE
+		| (phyaddr << PHYCR_ADDR_SHIFT)
+		| (phyreg  << PHYCR_REG_SHIFT);
+
+	writel(phydata, &regs->phydr);
+	writel(tmp, &regs->phycr);
+
+	for (ts = get_timer(0); get_timer(ts) < CFG_MDIOWR_TIMEOUT; ) {
+		if (readl(&regs->phycr) & PHYCR_WRITE)
+			continue;
+		break;
+	}
+
+	if (readl(&regs->phycr) & PHYCR_WRITE)
+		printf("ftmac110: mdio write timeout\n");
+}
+
+static uint32_t ftmac110_phyqry(struct eth_device *dev)
+{
+	ulong ts;
+	uint32_t maccr;
+	uint16_t pa, tmp, bmsr, bmcr;
+	struct ftmac110_chip *chip = dev->priv;
+
+	/* Default = 100Mbps Full */
+	maccr = MACCR_100M | MACCR_FD;
+
+	/* 1. find the phy device  */
+	for (pa = 0; pa < 32; ++pa) {
+		tmp = mdio_read(dev, pa, MII_PHYSID1);
+		if (tmp == 0xFFFF || tmp == 0x0000)
+			continue;
+		chip->phy_addr = pa;
+		break;
+	}
+	if (pa >= 32) {
+		puts("ftmac110: phy device not found!\n");
+		goto exit;
+	}
+
+	/* 2. wait until link-up & auto-negotiation complete */
+	chip->lnkup = 0;
+	bmcr = mdio_read(dev, chip->phy_addr, MII_BMCR);
+	ts = get_timer(0);
+	do {
+		bmsr = mdio_read(dev, chip->phy_addr, MII_BMSR);
+		chip->lnkup = (bmsr & BMSR_LSTATUS) ? 1 : 0;
+		if (!chip->lnkup)
+			continue;
+		if (!(bmcr & BMCR_ANENABLE) || (bmsr & BMSR_ANEGCOMPLETE))
+			break;
+	} while (get_timer(ts) < CFG_LINKUP_TIMEOUT);
+	if (!chip->lnkup) {
+		puts("ftmac110: link down\n");
+		goto exit;
+	}
+	if (!(bmcr & BMCR_ANENABLE))
+		puts("ftmac110: auto negotiation disabled\n");
+	else if (!(bmsr & BMSR_ANEGCOMPLETE))
+		puts("ftmac110: auto negotiation timeout\n");
+
+	/* 3. derive MACCR */
+	if ((bmcr & BMCR_ANENABLE) && (bmsr & BMSR_ANEGCOMPLETE)) {
+		tmp  = mdio_read(dev, chip->phy_addr, MII_ADVERTISE);
+		tmp &= mdio_read(dev, chip->phy_addr, MII_LPA);
+		if (tmp & LPA_100FULL)      /* 100Mbps full-duplex */
+			maccr = MACCR_100M | MACCR_FD;
+		else if (tmp & LPA_100HALF) /* 100Mbps half-duplex */
+			maccr = MACCR_100M;
+		else if (tmp & LPA_10FULL)  /* 10Mbps full-duplex */
+			maccr = MACCR_FD;
+		else if (tmp & LPA_10HALF)  /* 10Mbps half-duplex */
+			maccr = 0;
+	} else {
+		if (bmcr & BMCR_SPEED100)
+			maccr = MACCR_100M;
+		else
+			maccr = 0;
+		if (bmcr & BMCR_FULLDPLX)
+			maccr |= MACCR_FD;
+	}
+
+exit:
+	printf("ftmac110: %d Mbps, %s\n",
+	       (maccr & MACCR_100M) ? 100 : 10,
+	       (maccr & MACCR_FD) ? "Full" : "half");
+	return maccr;
+}
+
+static int ftmac110_reset(struct eth_device *dev)
+{
+	uint8_t *a;
+	uint32_t i, maccr;
+	struct ftmac110_chip *chip = dev->priv;
+	struct ftmac110_regs *regs = chip->regs;
+
+	/* 1. MAC reset */
+	writel(MACCR_RESET, &regs->maccr);
+	for (i = get_timer(0); get_timer(i) < 1000; ) {
+		if (readl(&regs->maccr) & MACCR_RESET)
+			continue;
+		break;
+	}
+	if (readl(&regs->maccr) & MACCR_RESET) {
+		printf("ftmac110: reset failed\n");
+		return -ENXIO;
+	}
+
+	/* 1-1. Init tx ring */
+	for (i = 0; i < CFG_TXDES_NUM; ++i) {
+		/* owned by SW */
+		chip->txd[i].ctrl &= cpu_to_le64(FTMAC110_TXD_CLRMASK);
+	}
+	chip->txd_idx = 0;
+
+	/* 1-2. Init rx ring */
+	for (i = 0; i < CFG_RXDES_NUM; ++i) {
+		/* owned by HW */
+		chip->rxd[i].ctrl &= cpu_to_le64(FTMAC110_RXD_CLRMASK);
+		chip->rxd[i].ctrl |= cpu_to_le64(FTMAC110_RXD_OWNER);
+	}
+	chip->rxd_idx = 0;
+
+	/* 2. PHY status query */
+	maccr = ftmac110_phyqry(dev);
+
+	/* 3. Fix up the MACCR value */
+	chip->maccr = maccr | MACCR_CRCAPD | MACCR_RXALL | MACCR_RXRUNT
+		| MACCR_RXEN | MACCR_TXEN | MACCR_RXDMAEN | MACCR_TXDMAEN;
+
+	/* 4. MAC address setup */
+	a = dev->enetaddr;
+	writel(a[1] | (a[0] << 8), &regs->mac[0]);
+	writel(a[5] | (a[4] << 8) | (a[3] << 16)
+		| (a[2] << 24), &regs->mac[1]);
+
+	/* 5. MAC registers setup */
+	writel(chip->rxd_dma, &regs->rxba);
+	writel(chip->txd_dma, &regs->txba);
+	/* interrupt at each tx/rx */
+	writel(ITC_DEFAULT, &regs->itc);
+	/* no tx pool, rx poll = 1 normal cycle */
+	writel(APTC_DEFAULT, &regs->aptc);
+	/* rx threshold = [6/8 fifo, 2/8 fifo] */
+	writel(DBLAC_DEFAULT, &regs->dblac);
+	/* disable & clear all interrupt status */
+	chip->imr = 0;
+	writel(ISR_ALL, &regs->isr);
+	writel(chip->imr, &regs->imr);
+	/* enable mac */
+	writel(chip->maccr, &regs->maccr);
+
+	return 0;
+}
+
+static int ftmac110_probe(struct eth_device *dev, bd_t *bis)
+{
+	debug("ftmac110: probe\n");
+
+	if (ftmac110_reset(dev))
+		return -1;
+
+	return 0;
+}
+
+static void ftmac110_halt(struct eth_device *dev)
+{
+	struct ftmac110_chip *chip = dev->priv;
+	struct ftmac110_regs *regs = chip->regs;
+
+	writel(0, &regs->imr);
+	writel(0, &regs->maccr);
+
+	debug("ftmac110: halt\n");
+}
+
+static int ftmac110_send(struct eth_device *dev, void *pkt, int len)
+{
+	struct ftmac110_chip *chip = dev->priv;
+	struct ftmac110_regs *regs = chip->regs;
+	struct ftmac110_desc *txd;
+	uint64_t ctrl;
+
+	if (!chip->lnkup)
+		return 0;
+
+	if (len <= 0 || len > CFG_XBUF_SIZE) {
+		printf("ftmac110: bad tx pkt len(%d)\n", len);
+		return 0;
+	}
+
+	len = max(60, len);
+
+	txd = &chip->txd[chip->txd_idx];
+	ctrl = le64_to_cpu(txd->ctrl);
+	if (ctrl & FTMAC110_TXD_OWNER) {
+		/* kick-off Tx DMA */
+		writel(0xffffffff, &regs->txpd);
+		printf("ftmac110: out of txd\n");
+		return 0;
+	}
+
+	memcpy(txd->vbuf, (void *)pkt, len);
+	dma_map_single(txd->vbuf, len, DMA_TO_DEVICE);
+
+	/* clear control bits */
+	ctrl &= FTMAC110_TXD_CLRMASK;
+	/* set len, fts and lts */
+	ctrl |= FTMAC110_TXD_LEN(len) | FTMAC110_TXD_FTS | FTMAC110_TXD_LTS;
+	/* set owner bit */
+	ctrl |= FTMAC110_TXD_OWNER;
+	/* write back to descriptor */
+	txd->ctrl = cpu_to_le64(ctrl);
+
+	/* kick-off Tx DMA */
+	writel(0xffffffff, &regs->txpd);
+
+	chip->txd_idx = (chip->txd_idx + 1) % CFG_TXDES_NUM;
+
+	return len;
+}
+
+static int ftmac110_recv(struct eth_device *dev)
+{
+	struct ftmac110_chip *chip = dev->priv;
+	struct ftmac110_desc *rxd;
+	uint32_t len, rlen = 0;
+	uint64_t ctrl;
+	uint8_t *buf;
+
+	if (!chip->lnkup)
+		return 0;
+
+	do {
+		rxd = &chip->rxd[chip->rxd_idx];
+		ctrl = le64_to_cpu(rxd->ctrl);
+		if (ctrl & FTMAC110_RXD_OWNER)
+			break;
+
+		len = (uint32_t)FTMAC110_RXD_LEN(ctrl);
+		buf = rxd->vbuf;
+
+		if (ctrl & FTMAC110_RXD_ERRMASK) {
+			printf("ftmac110: rx error\n");
+		} else {
+			dma_map_single(buf, len, DMA_FROM_DEVICE);
+			NetReceive(buf, len);
+			rlen += len;
+		}
+
+		/* owned by hardware */
+		ctrl &= FTMAC110_RXD_CLRMASK;
+		ctrl |= FTMAC110_RXD_OWNER;
+		rxd->ctrl |= cpu_to_le64(ctrl);
+
+		chip->rxd_idx = (chip->rxd_idx + 1) % CFG_RXDES_NUM;
+	} while (0);
+
+	return rlen;
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+
+static int ftmac110_mdio_read(
+	const char *devname, uint8_t addr, uint8_t reg, uint16_t *value)
+{
+	int ret = 0;
+	struct eth_device *dev;
+
+	dev = eth_get_dev_by_name(devname);
+	if (dev == NULL) {
+		printf("%s: no such device\n", devname);
+		ret = -1;
+	} else {
+		*value = mdio_read(dev, addr, reg);
+	}
+
+	return ret;
+}
+
+static int ftmac110_mdio_write(
+	const char *devname, uint8_t addr, uint8_t reg, uint16_t value)
+{
+	int ret = 0;
+	struct eth_device *dev;
+
+	dev = eth_get_dev_by_name(devname);
+	if (dev == NULL) {
+		printf("%s: no such device\n", devname);
+		ret = -1;
+	} else {
+		mdio_write(dev, addr, reg, value);
+	}
+
+	return ret;
+}
+
+#endif    /* #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) */
+
+int ftmac110_initialize(bd_t *bis)
+{
+	int i, card_nr = 0;
+	struct eth_device *dev;
+	struct ftmac110_chip *chip;
+
+	dev = malloc(sizeof(*dev) + sizeof(*chip));
+	if (dev == NULL) {
+		panic("ftmac110: out of memory 1\n");
+		return -1;
+	}
+	chip = (struct ftmac110_chip *)(dev + 1);
+	memset(dev, 0, sizeof(*dev) + sizeof(*chip));
+
+	sprintf(dev->name, "FTMAC110#%d", card_nr);
+
+	dev->iobase = CONFIG_FTMAC110_BASE;
+	chip->regs = (void __iomem *)dev->iobase;
+	dev->priv = chip;
+	dev->init = ftmac110_probe;
+	dev->halt = ftmac110_halt;
+	dev->send = ftmac110_send;
+	dev->recv = ftmac110_recv;
+
+	if (!eth_getenv_enetaddr_by_index("eth", card_nr, dev->enetaddr))
+		eth_random_enetaddr(dev->enetaddr);
+
+	/* allocate tx descriptors (it must be 16 bytes aligned) */
+	chip->txd = dma_alloc_coherent(
+		sizeof(struct ftmac110_desc) * CFG_TXDES_NUM, &chip->txd_dma);
+	if (!chip->txd)
+		panic("ftmac110: out of memory 3\n");
+	memset(chip->txd, 0,
+	       sizeof(struct ftmac110_desc) * CFG_TXDES_NUM);
+	for (i = 0; i < CFG_TXDES_NUM; ++i) {
+		void *va = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE);
+
+		if (!va)
+			panic("ftmac110: out of memory 4\n");
+		chip->txd[i].vbuf = va;
+		chip->txd[i].pbuf = cpu_to_le32(virt_to_phys(va));
+		chip->txd[i].ctrl = 0;	/* owned by SW */
+	}
+	chip->txd[i - 1].ctrl |= cpu_to_le64(FTMAC110_TXD_END);
+	chip->txd_idx = 0;
+
+	/* allocate rx descriptors (it must be 16 bytes aligned) */
+	chip->rxd = dma_alloc_coherent(
+		sizeof(struct ftmac110_desc) * CFG_RXDES_NUM, &chip->rxd_dma);
+	if (!chip->rxd)
+		panic("ftmac110: out of memory 4\n");
+	memset((void *)chip->rxd, 0,
+	       sizeof(struct ftmac110_desc) * CFG_RXDES_NUM);
+	for (i = 0; i < CFG_RXDES_NUM; ++i) {
+		void *va = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE + 2);
+
+		if (!va)
+			panic("ftmac110: out of memory 5\n");
+		/* it needs to be exactly 2 bytes aligned */
+		va = ((uint8_t *)va + 2);
+		chip->rxd[i].vbuf = va;
+		chip->rxd[i].pbuf = cpu_to_le32(virt_to_phys(va));
+		chip->rxd[i].ctrl = cpu_to_le64(FTMAC110_RXD_OWNER
+			| FTMAC110_RXD_BUFSZ(CFG_XBUF_SIZE));
+	}
+	chip->rxd[i - 1].ctrl |= cpu_to_le64(FTMAC110_RXD_END);
+	chip->rxd_idx = 0;
+
+	eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	miiphy_register(dev->name, ftmac110_mdio_read, ftmac110_mdio_write);
+#endif
+
+	card_nr++;
+
+	return card_nr;
+}
diff --git a/marvell/uboot/drivers/net/ftmac110.h b/marvell/uboot/drivers/net/ftmac110.h
new file mode 100644
index 0000000..2772ae7
--- /dev/null
+++ b/marvell/uboot/drivers/net/ftmac110.h
@@ -0,0 +1,176 @@
+/*
+ * Faraday 10/100Mbps Ethernet Controller
+ *
+ * (C) Copyright 2013 Faraday Technology
+ * Dante Su <dantesu@faraday-tech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _FTMAC110_H
+#define _FTMAC110_H
+
+struct ftmac110_regs {
+	uint32_t isr;    /* 0x00: Interrups Status Register */
+	uint32_t imr;    /* 0x04: Interrupt Mask Register */
+	uint32_t mac[2]; /* 0x08: MAC Address */
+	uint32_t mht[2]; /* 0x10: Multicast Hash Table Register */
+	uint32_t txpd;   /* 0x18: Tx Poll Demand Register */
+	uint32_t rxpd;   /* 0x1c: Rx Poll Demand Register */
+	uint32_t txba;   /* 0x20: Tx Ring Base Address Register */
+	uint32_t rxba;   /* 0x24: Rx Ring Base Address Register */
+	uint32_t itc;    /* 0x28: Interrupt Timer Control Register */
+	uint32_t aptc;   /* 0x2C: Automatic Polling Timer Control Register */
+	uint32_t dblac;  /* 0x30: DMA Burst Length&Arbitration Control */
+	uint32_t revr;   /* 0x34: Revision Register */
+	uint32_t fear;   /* 0x38: Feature Register */
+	uint32_t rsvd[19];
+	uint32_t maccr;  /* 0x88: MAC Control Register */
+	uint32_t macsr;  /* 0x8C: MAC Status Register */
+	uint32_t phycr;  /* 0x90: PHY Control Register */
+	uint32_t phydr;  /* 0x94: PHY Data Register */
+	uint32_t fcr;    /* 0x98: Flow Control Register */
+	uint32_t bpr;    /* 0x9C: Back Pressure Register */
+};
+
+/*
+ * Interrupt status/mask register(ISR/IMR) bits
+ */
+#define ISR_ALL          0x3ff
+#define ISR_PHYSTCHG     (1 << 9) /* phy status change */
+#define ISR_AHBERR       (1 << 8) /* bus error */
+#define ISR_RXLOST       (1 << 7) /* rx lost */
+#define ISR_RXFIFO       (1 << 6) /* rx to fifo */
+#define ISR_TXLOST       (1 << 5) /* tx lost */
+#define ISR_TXOK         (1 << 4) /* tx to ethernet */
+#define ISR_NOTXBUF      (1 << 3) /* out of tx buffer */
+#define ISR_TXFIFO       (1 << 2) /* tx to fifo */
+#define ISR_NORXBUF      (1 << 1) /* out of rx buffer */
+#define ISR_RXOK         (1 << 0) /* rx to buffer */
+
+/*
+ * MACCR control bits
+ */
+#define MACCR_100M       (1 << 18) /* 100Mbps mode */
+#define MACCR_RXBCST     (1 << 17) /* rx broadcast packet */
+#define MACCR_RXMCST     (1 << 16) /* rx multicast packet */
+#define MACCR_FD         (1 << 15) /* full duplex */
+#define MACCR_CRCAPD     (1 << 14) /* tx crc append */
+#define MACCR_RXALL      (1 << 12) /* rx all packets */
+#define MACCR_RXFTL      (1 << 11) /* rx packet even it's > 1518 byte */
+#define MACCR_RXRUNT     (1 << 10) /* rx packet even it's < 64 byte */
+#define MACCR_RXMCSTHT   (1 << 9)  /* rx multicast hash table */
+#define MACCR_RXEN       (1 << 8)  /* rx enable */
+#define MACCR_RXINHDTX   (1 << 6)  /* rx in half duplex tx */
+#define MACCR_TXEN       (1 << 5)  /* tx enable */
+#define MACCR_CRCDIS     (1 << 4)  /* tx packet even it's crc error */
+#define MACCR_LOOPBACK   (1 << 3)  /* loop-back */
+#define MACCR_RESET      (1 << 2)  /* reset */
+#define MACCR_RXDMAEN    (1 << 1)  /* rx dma enable */
+#define MACCR_TXDMAEN    (1 << 0)  /* tx dma enable */
+
+/*
+ * PHYCR control bits
+ */
+#define PHYCR_READ       (1 << 26)
+#define PHYCR_WRITE      (1 << 27)
+#define PHYCR_REG_SHIFT  21
+#define PHYCR_ADDR_SHIFT 16
+
+/*
+ * ITC control bits
+ */
+
+/* Tx Cycle Length */
+#define ITC_TX_CYCLONG   (1 << 15) /* 100Mbps=81.92us; 10Mbps=819.2us */
+#define ITC_TX_CYCNORM   (0 << 15) /* 100Mbps=5.12us;  10Mbps=51.2us */
+/* Tx Threshold: Aggregate n interrupts as 1 interrupt */
+#define ITC_TX_THR(n)    (((n) & 0x7) << 12)
+/* Tx Interrupt Timeout = n * Tx Cycle */
+#define ITC_TX_ITMO(n)   (((n) & 0xf) << 8)
+/* Rx Cycle Length */
+#define ITC_RX_CYCLONG   (1 << 7)  /* 100Mbps=81.92us; 10Mbps=819.2us */
+#define ITC_RX_CYCNORM   (0 << 7)  /* 100Mbps=5.12us;  10Mbps=51.2us */
+/* Rx Threshold: Aggregate n interrupts as 1 interrupt */
+#define ITC_RX_THR(n)    (((n) & 0x7) << 4)
+/* Rx Interrupt Timeout = n * Rx Cycle */
+#define ITC_RX_ITMO(n)   (((n) & 0xf) << 0)
+
+#define ITC_DEFAULT \
+	(ITC_TX_THR(1) | ITC_TX_ITMO(0) | ITC_RX_THR(1) | ITC_RX_ITMO(0))
+
+/*
+ * APTC contrl bits
+ */
+
+/* Tx Cycle Length */
+#define APTC_TX_CYCLONG  (1 << 12) /* 100Mbps=81.92us; 10Mbps=819.2us */
+#define APTC_TX_CYCNORM  (0 << 12) /* 100Mbps=5.12us;  10Mbps=51.2us */
+/* Tx Poll Timeout = n * Tx Cycle, 0=No auto polling */
+#define APTC_TX_PTMO(n)  (((n) & 0xf) << 8)
+/* Rx Cycle Length */
+#define APTC_RX_CYCLONG  (1 << 4)  /* 100Mbps=81.92us; 10Mbps=819.2us */
+#define APTC_RX_CYCNORM  (0 << 4)  /* 100Mbps=5.12us;  10Mbps=51.2us */
+/* Rx Poll Timeout = n * Rx Cycle, 0=No auto polling */
+#define APTC_RX_PTMO(n)  (((n) & 0xf) << 0)
+
+#define APTC_DEFAULT     (APTC_TX_PTMO(0) | APTC_RX_PTMO(1))
+
+/*
+ * DBLAC contrl bits
+ */
+#define DBLAC_BURST_MAX_ANY  (0 << 14) /* un-limited */
+#define DBLAC_BURST_MAX_32X4 (2 << 14) /* max = 32 x 4 bytes */
+#define DBLAC_BURST_MAX_64X4 (3 << 14) /* max = 64 x 4 bytes */
+#define DBLAC_RXTHR_EN       (1 << 9)  /* enable rx threshold arbitration */
+#define DBLAC_RXTHR_HIGH(n)  (((n) & 0x7) << 6) /* upper bound = n/8 fifo */
+#define DBLAC_RXTHR_LOW(n)   (((n) & 0x7) << 3) /* lower bound = n/8 fifo */
+#define DBLAC_BURST_CAP16    (1 << 2)  /* support burst 16 */
+#define DBLAC_BURST_CAP8     (1 << 1)  /* support burst 8 */
+#define DBLAC_BURST_CAP4     (1 << 0)  /* support burst 4 */
+
+#define DBLAC_DEFAULT \
+	(DBLAC_RXTHR_EN | DBLAC_RXTHR_HIGH(6) | DBLAC_RXTHR_LOW(2))
+
+/*
+ * descriptor structure
+ */
+struct ftmac110_desc {
+	uint64_t ctrl;
+	uint32_t pbuf;
+	void    *vbuf;
+};
+
+#define FTMAC110_RXD_END        ((uint64_t)1 << 63)
+#define FTMAC110_RXD_BUFSZ(x)   (((uint64_t)(x) & 0x7ff) << 32)
+
+#define FTMAC110_RXD_OWNER      ((uint64_t)1 << 31) /* owner: 1=HW, 0=SW */
+#define FTMAC110_RXD_FRS        ((uint64_t)1 << 29) /* first pkt desc */
+#define FTMAC110_RXD_LRS        ((uint64_t)1 << 28) /* last pkt desc */
+#define FTMAC110_RXD_ODDNB      ((uint64_t)1 << 22) /* odd nibble */
+#define FTMAC110_RXD_RUNT       ((uint64_t)1 << 21) /* runt pkt */
+#define FTMAC110_RXD_FTL        ((uint64_t)1 << 20) /* frame too long */
+#define FTMAC110_RXD_CRC        ((uint64_t)1 << 19) /* pkt crc error */
+#define FTMAC110_RXD_ERR        ((uint64_t)1 << 18) /* bus error */
+#define FTMAC110_RXD_ERRMASK    ((uint64_t)0x1f << 18)
+#define FTMAC110_RXD_BCST       ((uint64_t)1 << 17) /* Bcst pkt */
+#define FTMAC110_RXD_MCST       ((uint64_t)1 << 16) /* Mcst pkt */
+#define FTMAC110_RXD_LEN(x)     ((uint64_t)((x) & 0x7ff))
+
+#define FTMAC110_RXD_CLRMASK	\
+	(FTMAC110_RXD_END | FTMAC110_RXD_BUFSZ(0x7ff))
+
+#define FTMAC110_TXD_END    ((uint64_t)1 << 63) /* end of ring */
+#define FTMAC110_TXD_TXIC   ((uint64_t)1 << 62) /* tx done interrupt */
+#define FTMAC110_TXD_TX2FIC ((uint64_t)1 << 61) /* tx fifo interrupt */
+#define FTMAC110_TXD_FTS    ((uint64_t)1 << 60) /* first pkt desc */
+#define FTMAC110_TXD_LTS    ((uint64_t)1 << 59) /* last pkt desc */
+#define FTMAC110_TXD_LEN(x) ((uint64_t)((x) & 0x7ff) << 32)
+
+#define FTMAC110_TXD_OWNER  ((uint64_t)1 << 31)	/* owner: 1=HW, 0=SW */
+#define FTMAC110_TXD_COL    ((uint64_t)3)		/* collision */
+
+#define FTMAC110_TXD_CLRMASK    \
+	(FTMAC110_TXD_END)
+
+#endif  /* FTMAC110_H */
diff --git a/marvell/uboot/drivers/net/greth.c b/marvell/uboot/drivers/net/greth.c
new file mode 100644
index 0000000..c817af4
--- /dev/null
+++ b/marvell/uboot/drivers/net/greth.c
@@ -0,0 +1,670 @@
+/* Gaisler.com GRETH 10/100/1000 Ethernet MAC driver
+ *
+ * Driver use polling mode (no Interrupt)
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/* #define DEBUG */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <netdev.h>
+#include <malloc.h>
+#include <asm/processor.h>
+#include <ambapp.h>
+#include <asm/leon.h>
+
+#include "greth.h"
+
+/* Default to 3s timeout on autonegotiation */
+#ifndef GRETH_PHY_TIMEOUT_MS
+#define GRETH_PHY_TIMEOUT_MS 3000
+#endif
+
+/* Default to PHY adrress 0 not not specified */
+#ifdef CONFIG_SYS_GRLIB_GRETH_PHYADDR
+#define GRETH_PHY_ADR_DEFAULT CONFIG_SYS_GRLIB_GRETH_PHYADDR
+#else
+#define GRETH_PHY_ADR_DEFAULT 0
+#endif
+
+/* ByPass Cache when reading regs */
+#define GRETH_REGLOAD(addr)		SPARC_NOCACHE_READ(addr)
+/* Write-through cache ==> no bypassing needed on writes */
+#define GRETH_REGSAVE(addr,data) (*(volatile unsigned int *)(addr) = (data))
+#define GRETH_REGORIN(addr,data) GRETH_REGSAVE(addr,GRETH_REGLOAD(addr)|data)
+#define GRETH_REGANDIN(addr,data) GRETH_REGSAVE(addr,GRETH_REGLOAD(addr)&data)
+
+#define GRETH_RXBD_CNT 4
+#define GRETH_TXBD_CNT 1
+
+#define GRETH_RXBUF_SIZE 1540
+#define GRETH_BUF_ALIGN 4
+#define GRETH_RXBUF_EFF_SIZE \
+	( (GRETH_RXBUF_SIZE&~(GRETH_BUF_ALIGN-1))+GRETH_BUF_ALIGN )
+
+typedef struct {
+	greth_regs *regs;
+	int irq;
+	struct eth_device *dev;
+
+	/* Hardware info */
+	unsigned char phyaddr;
+	int gbit_mac;
+
+	/* Current operating Mode */
+	int gb;			/* GigaBit */
+	int fd;			/* Full Duplex */
+	int sp;			/* 10/100Mbps speed (1=100,0=10) */
+	int auto_neg;		/* Auto negotiate done */
+
+	unsigned char hwaddr[6];	/* MAC Address */
+
+	/* Descriptors */
+	greth_bd *rxbd_base, *rxbd_max;
+	greth_bd *txbd_base, *txbd_max;
+
+	greth_bd *rxbd_curr;
+
+	/* rx buffers in rx descriptors */
+	void *rxbuf_base;	/* (GRETH_RXBUF_SIZE+ALIGNBYTES) * GRETH_RXBD_CNT */
+
+	/* unused for gbit_mac, temp buffer for sending packets with unligned
+	 * start.
+	 * Pointer to packet allocated with malloc.
+	 */
+	void *txbuf;
+
+	struct {
+		/* rx status */
+		unsigned int rx_packets,
+		    rx_crc_errors, rx_frame_errors, rx_length_errors, rx_errors;
+
+		/* tx stats */
+		unsigned int tx_packets,
+		    tx_latecol_errors,
+		    tx_underrun_errors, tx_limit_errors, tx_errors;
+	} stats;
+} greth_priv;
+
+/* Read MII register 'addr' from core 'regs' */
+static int read_mii(int phyaddr, int regaddr, volatile greth_regs * regs)
+{
+	while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
+	}
+
+	GRETH_REGSAVE(&regs->mdio, ((phyaddr & 0x1F) << 11) | ((regaddr & 0x1F) << 6) | 2);
+
+	while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
+	}
+
+	if (!(GRETH_REGLOAD(&regs->mdio) & GRETH_MII_NVALID)) {
+		return (GRETH_REGLOAD(&regs->mdio) >> 16) & 0xFFFF;
+	} else {
+		return -1;
+	}
+}
+
+static void write_mii(int phyaddr, int regaddr, int data, volatile greth_regs * regs)
+{
+	while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
+	}
+
+	GRETH_REGSAVE(&regs->mdio,
+		      ((data & 0xFFFF) << 16) | ((phyaddr & 0x1F) << 11) |
+		      ((regaddr & 0x1F) << 6) | 1);
+
+	while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
+	}
+
+}
+
+/* init/start hardware and allocate descriptor buffers for rx side
+ *
+ */
+int greth_init(struct eth_device *dev, bd_t * bis)
+{
+	int i;
+
+	greth_priv *greth = dev->priv;
+	greth_regs *regs = greth->regs;
+
+	debug("greth_init\n");
+
+	/* Reset core */
+	GRETH_REGSAVE(&regs->control, (GRETH_RESET | (greth->gb << 8) |
+		(greth->sp << 7) | (greth->fd << 4)));
+
+	/* Wait for Reset to complete */
+	while ( GRETH_REGLOAD(&regs->control) & GRETH_RESET) ;
+
+	GRETH_REGSAVE(&regs->control,
+		((greth->gb << 8) | (greth->sp << 7) | (greth->fd << 4)));
+
+	if (!greth->rxbd_base) {
+
+		/* allocate descriptors */
+		greth->rxbd_base = (greth_bd *)
+		    memalign(0x1000, GRETH_RXBD_CNT * sizeof(greth_bd));
+		greth->txbd_base = (greth_bd *)
+		    memalign(0x1000, GRETH_TXBD_CNT * sizeof(greth_bd));
+
+		/* allocate buffers to all descriptors  */
+		greth->rxbuf_base =
+		    malloc(GRETH_RXBUF_EFF_SIZE * GRETH_RXBD_CNT);
+	}
+
+	/* initate rx decriptors */
+	for (i = 0; i < GRETH_RXBD_CNT; i++) {
+		greth->rxbd_base[i].addr = (unsigned int)
+		    greth->rxbuf_base + (GRETH_RXBUF_EFF_SIZE * i);
+		/* enable desciptor & set wrap bit if last descriptor */
+		if (i >= (GRETH_RXBD_CNT - 1)) {
+			greth->rxbd_base[i].stat = GRETH_BD_EN | GRETH_BD_WR;
+		} else {
+			greth->rxbd_base[i].stat = GRETH_BD_EN;
+		}
+	}
+
+	/* initiate indexes */
+	greth->rxbd_curr = greth->rxbd_base;
+	greth->rxbd_max = greth->rxbd_base + (GRETH_RXBD_CNT - 1);
+	greth->txbd_max = greth->txbd_base + (GRETH_TXBD_CNT - 1);
+	/*
+	 * greth->txbd_base->addr = 0;
+	 * greth->txbd_base->stat = GRETH_BD_WR;
+	 */
+
+	/* initate tx decriptors */
+	for (i = 0; i < GRETH_TXBD_CNT; i++) {
+		greth->txbd_base[i].addr = 0;
+		/* enable desciptor & set wrap bit if last descriptor */
+		if (i >= (GRETH_TXBD_CNT - 1)) {
+			greth->txbd_base[i].stat = GRETH_BD_WR;
+		} else {
+			greth->txbd_base[i].stat = 0;
+		}
+	}
+
+	/**** SET HARDWARE REGS ****/
+
+	/* Set pointer to tx/rx descriptor areas */
+	GRETH_REGSAVE(&regs->rx_desc_p, (unsigned int)&greth->rxbd_base[0]);
+	GRETH_REGSAVE(&regs->tx_desc_p, (unsigned int)&greth->txbd_base[0]);
+
+	/* Enable Transmitter, GRETH will now scan descriptors for packets
+	 * to transmitt */
+	debug("greth_init: enabling receiver\n");
+	GRETH_REGORIN(&regs->control, GRETH_RXEN);
+
+	return 0;
+}
+
+/* Initiate PHY to a relevant speed
+ * return:
+ *  - 0 = success
+ *  - 1 = timeout/fail
+ */
+int greth_init_phy(greth_priv * dev, bd_t * bis)
+{
+	greth_regs *regs = dev->regs;
+	int tmp, tmp1, tmp2, i;
+	unsigned int start, timeout;
+	int phyaddr = GRETH_PHY_ADR_DEFAULT;
+
+#ifndef CONFIG_SYS_GRLIB_GRETH_PHYADDR
+	/* If BSP doesn't provide a hardcoded PHY address the driver will
+	 * try to autodetect PHY address by stopping the search on the first
+	 * PHY address which has REG0 implemented.
+	 */
+	for (i=0; i<32; i++) {
+		tmp = read_mii(i, 0, regs);
+		if ( (tmp != 0) && (tmp != 0xffff) ) {
+			phyaddr = i;
+			break;
+		}
+	}
+#endif
+
+	/* Save PHY Address */
+	dev->phyaddr = phyaddr;
+
+	debug("GRETH PHY ADDRESS: %d\n", phyaddr);
+
+	/* X msecs to ticks */
+	timeout = usec2ticks(GRETH_PHY_TIMEOUT_MS * 1000);
+
+	/* Get system timer0 current value
+	 * Total timeout is 5s
+	 */
+	start = get_timer(0);
+
+	/* get phy control register default values */
+
+	while ((tmp = read_mii(phyaddr, 0, regs)) & 0x8000) {
+		if (get_timer(start) > timeout) {
+			debug("greth_init_phy: PHY read 1 failed\n");
+			return 1;	/* Fail */
+		}
+	}
+
+	/* reset PHY and wait for completion */
+	write_mii(phyaddr, 0, 0x8000 | tmp, regs);
+
+	while (((tmp = read_mii(phyaddr, 0, regs))) & 0x8000) {
+		if (get_timer(start) > timeout) {
+			debug("greth_init_phy: PHY read 2 failed\n");
+			return 1;	/* Fail */
+		}
+	}
+
+	/* Check if PHY is autoneg capable and then determine operating
+	 * mode, otherwise force it to 10 Mbit halfduplex
+	 */
+	dev->gb = 0;
+	dev->fd = 0;
+	dev->sp = 0;
+	dev->auto_neg = 0;
+	if (!((tmp >> 12) & 1)) {
+		write_mii(phyaddr, 0, 0, regs);
+	} else {
+		/* wait for auto negotiation to complete and then check operating mode */
+		dev->auto_neg = 1;
+		i = 0;
+		while (!(((tmp = read_mii(phyaddr, 1, regs)) >> 5) & 1)) {
+			if (get_timer(start) > timeout) {
+				printf("Auto negotiation timed out. "
+				       "Selecting default config\n");
+				tmp = read_mii(phyaddr, 0, regs);
+				dev->gb = ((tmp >> 6) & 1)
+				    && !((tmp >> 13) & 1);
+				dev->sp = !((tmp >> 6) & 1)
+				    && ((tmp >> 13) & 1);
+				dev->fd = (tmp >> 8) & 1;
+				goto auto_neg_done;
+			}
+		}
+		if ((tmp >> 8) & 1) {
+			tmp1 = read_mii(phyaddr, 9, regs);
+			tmp2 = read_mii(phyaddr, 10, regs);
+			if ((tmp1 & GRETH_MII_EXTADV_1000FD) &&
+			    (tmp2 & GRETH_MII_EXTPRT_1000FD)) {
+				dev->gb = 1;
+				dev->fd = 1;
+			}
+			if ((tmp1 & GRETH_MII_EXTADV_1000HD) &&
+			    (tmp2 & GRETH_MII_EXTPRT_1000HD)) {
+				dev->gb = 1;
+				dev->fd = 0;
+			}
+		}
+		if ((dev->gb == 0) || ((dev->gb == 1) && (dev->gbit_mac == 0))) {
+			tmp1 = read_mii(phyaddr, 4, regs);
+			tmp2 = read_mii(phyaddr, 5, regs);
+			if ((tmp1 & GRETH_MII_100TXFD) &&
+			    (tmp2 & GRETH_MII_100TXFD)) {
+				dev->sp = 1;
+				dev->fd = 1;
+			}
+			if ((tmp1 & GRETH_MII_100TXHD) &&
+			    (tmp2 & GRETH_MII_100TXHD)) {
+				dev->sp = 1;
+				dev->fd = 0;
+			}
+			if ((tmp1 & GRETH_MII_10FD) && (tmp2 & GRETH_MII_10FD)) {
+				dev->fd = 1;
+			}
+			if ((dev->gb == 1) && (dev->gbit_mac == 0)) {
+				dev->gb = 0;
+				dev->fd = 0;
+				write_mii(phyaddr, 0, dev->sp << 13, regs);
+			}
+		}
+
+	}
+      auto_neg_done:
+	debug("%s GRETH Ethermac at [0x%x] irq %d. Running \
+		%d Mbps %s duplex\n", dev->gbit_mac ? "10/100/1000" : "10/100", (unsigned int)(regs), (unsigned int)(dev->irq), dev->gb ? 1000 : (dev->sp ? 100 : 10), dev->fd ? "full" : "half");
+	/* Read out PHY info if extended registers are available */
+	if (tmp & 1) {
+		tmp1 = read_mii(phyaddr, 2, regs);
+		tmp2 = read_mii(phyaddr, 3, regs);
+		tmp1 = (tmp1 << 6) | ((tmp2 >> 10) & 0x3F);
+		tmp = tmp2 & 0xF;
+
+		tmp2 = (tmp2 >> 4) & 0x3F;
+		debug("PHY: Vendor %x   Device %x    Revision %d\n", tmp1,
+		       tmp2, tmp);
+	} else {
+		printf("PHY info not available\n");
+	}
+
+	/* set speed and duplex bits in control register */
+	GRETH_REGORIN(&regs->control,
+		      (dev->gb << 8) | (dev->sp << 7) | (dev->fd << 4));
+
+	return 0;
+}
+
+void greth_halt(struct eth_device *dev)
+{
+	greth_priv *greth;
+	greth_regs *regs;
+	int i;
+
+	debug("greth_halt\n");
+
+	if (!dev || !dev->priv)
+		return;
+
+	greth = dev->priv;
+	regs = greth->regs;
+
+	if (!regs)
+		return;
+
+	/* disable receiver/transmitter by clearing the enable bits */
+	GRETH_REGANDIN(&regs->control, ~(GRETH_RXEN | GRETH_TXEN));
+
+	/* reset rx/tx descriptors */
+	if (greth->rxbd_base) {
+		for (i = 0; i < GRETH_RXBD_CNT; i++) {
+			greth->rxbd_base[i].stat =
+			    (i >= (GRETH_RXBD_CNT - 1)) ? GRETH_BD_WR : 0;
+		}
+	}
+
+	if (greth->txbd_base) {
+		for (i = 0; i < GRETH_TXBD_CNT; i++) {
+			greth->txbd_base[i].stat =
+			    (i >= (GRETH_TXBD_CNT - 1)) ? GRETH_BD_WR : 0;
+		}
+	}
+}
+
+int greth_send(struct eth_device *dev, void *eth_data, int data_length)
+{
+	greth_priv *greth = dev->priv;
+	greth_regs *regs = greth->regs;
+	greth_bd *txbd;
+	void *txbuf;
+	unsigned int status;
+
+	debug("greth_send\n");
+
+	/* send data, wait for data to be sent, then return */
+	if (((unsigned int)eth_data & (GRETH_BUF_ALIGN - 1))
+	    && !greth->gbit_mac) {
+		/* data not aligned as needed by GRETH 10/100, solve this by allocating 4 byte aligned buffer
+		 * and copy data to before giving it to GRETH.
+		 */
+		if (!greth->txbuf) {
+			greth->txbuf = malloc(GRETH_RXBUF_SIZE);
+		}
+
+		txbuf = greth->txbuf;
+
+		/* copy data info buffer */
+		memcpy((char *)txbuf, (char *)eth_data, data_length);
+
+		/* keep buffer to next time */
+	} else {
+		txbuf = (void *)eth_data;
+	}
+	/* get descriptor to use, only 1 supported... hehe easy */
+	txbd = greth->txbd_base;
+
+	/* setup descriptor to wrap around to it self */
+	txbd->addr = (unsigned int)txbuf;
+	txbd->stat = GRETH_BD_EN | GRETH_BD_WR | data_length;
+
+	/* Remind Core which descriptor to use when sending */
+	GRETH_REGSAVE(&regs->tx_desc_p, (unsigned int)txbd);
+
+	/* initate send by enabling transmitter */
+	GRETH_REGORIN(&regs->control, GRETH_TXEN);
+
+	/* Wait for data to be sent */
+	while ((status = GRETH_REGLOAD(&txbd->stat)) & GRETH_BD_EN) {
+		;
+	}
+
+	/* was the packet transmitted succesfully? */
+	if (status & GRETH_TXBD_ERR_AL) {
+		greth->stats.tx_limit_errors++;
+	}
+
+	if (status & GRETH_TXBD_ERR_UE) {
+		greth->stats.tx_underrun_errors++;
+	}
+
+	if (status & GRETH_TXBD_ERR_LC) {
+		greth->stats.tx_latecol_errors++;
+	}
+
+	if (status &
+	    (GRETH_TXBD_ERR_LC | GRETH_TXBD_ERR_UE | GRETH_TXBD_ERR_AL)) {
+		/* any error */
+		greth->stats.tx_errors++;
+		return -1;
+	}
+
+	/* bump tx packet counter */
+	greth->stats.tx_packets++;
+
+	/* return succefully */
+	return 0;
+}
+
+int greth_recv(struct eth_device *dev)
+{
+	greth_priv *greth = dev->priv;
+	greth_regs *regs = greth->regs;
+	greth_bd *rxbd;
+	unsigned int status, len = 0, bad;
+	char *d;
+	int enable = 0;
+	int i;
+
+	/* Receive One packet only, but clear as many error packets as there are
+	 * available.
+	 */
+	{
+		/* current receive descriptor */
+		rxbd = greth->rxbd_curr;
+
+		/* get status of next received packet */
+		status = GRETH_REGLOAD(&rxbd->stat);
+
+		bad = 0;
+
+		/* stop if no more packets received */
+		if (status & GRETH_BD_EN) {
+			goto done;
+		}
+
+		debug("greth_recv: packet 0x%x, 0x%x, len: %d\n",
+		       (unsigned int)rxbd, status, status & GRETH_BD_LEN);
+
+		/* Check status for errors.
+		 */
+		if (status & GRETH_RXBD_ERR_FT) {
+			greth->stats.rx_length_errors++;
+			bad = 1;
+		}
+		if (status & (GRETH_RXBD_ERR_AE | GRETH_RXBD_ERR_OE)) {
+			greth->stats.rx_frame_errors++;
+			bad = 1;
+		}
+		if (status & GRETH_RXBD_ERR_CRC) {
+			greth->stats.rx_crc_errors++;
+			bad = 1;
+		}
+		if (bad) {
+			greth->stats.rx_errors++;
+			printf
+			    ("greth_recv: Bad packet (%d, %d, %d, 0x%08x, %d)\n",
+			     greth->stats.rx_length_errors,
+			     greth->stats.rx_frame_errors,
+			     greth->stats.rx_crc_errors, status,
+			     greth->stats.rx_packets);
+			/* print all rx descriptors */
+			for (i = 0; i < GRETH_RXBD_CNT; i++) {
+				printf("[%d]: Stat=0x%lx, Addr=0x%lx\n", i,
+				       GRETH_REGLOAD(&greth->rxbd_base[i].stat),
+				       GRETH_REGLOAD(&greth->rxbd_base[i].addr));
+			}
+		} else {
+			/* Process the incoming packet. */
+			len = status & GRETH_BD_LEN;
+			d = (char *)rxbd->addr;
+
+			debug
+			    ("greth_recv: new packet, length: %d. data: %x %x %x %x %x %x %x %x\n",
+			     len, d[0], d[1], d[2], d[3], d[4], d[5], d[6],
+			     d[7]);
+
+			/* flush all data cache to make sure we're not reading old packet data */
+			sparc_dcache_flush_all();
+
+			/* pass packet on to network subsystem */
+			NetReceive((void *)d, len);
+
+			/* bump stats counters */
+			greth->stats.rx_packets++;
+
+			/* bad is now 0 ==> will stop loop */
+		}
+
+		/* reenable descriptor to receive more packet with this descriptor, wrap around if needed */
+		rxbd->stat =
+		    GRETH_BD_EN |
+		    (((unsigned int)greth->rxbd_curr >=
+		      (unsigned int)greth->rxbd_max) ? GRETH_BD_WR : 0);
+		enable = 1;
+
+		/* increase index */
+		greth->rxbd_curr =
+		    ((unsigned int)greth->rxbd_curr >=
+		     (unsigned int)greth->rxbd_max) ? greth->
+		    rxbd_base : (greth->rxbd_curr + 1);
+
+	}
+
+	if (enable) {
+		GRETH_REGORIN(&regs->control, GRETH_RXEN);
+	}
+      done:
+	/* return positive length of packet or 0 if non received */
+	return len;
+}
+
+void greth_set_hwaddr(greth_priv * greth, unsigned char *mac)
+{
+	/* save new MAC address */
+	greth->dev->enetaddr[0] = greth->hwaddr[0] = mac[0];
+	greth->dev->enetaddr[1] = greth->hwaddr[1] = mac[1];
+	greth->dev->enetaddr[2] = greth->hwaddr[2] = mac[2];
+	greth->dev->enetaddr[3] = greth->hwaddr[3] = mac[3];
+	greth->dev->enetaddr[4] = greth->hwaddr[4] = mac[4];
+	greth->dev->enetaddr[5] = greth->hwaddr[5] = mac[5];
+	greth->regs->esa_msb = (mac[0] << 8) | mac[1];
+	greth->regs->esa_lsb =
+	    (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5];
+
+	debug("GRETH: New MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+	       mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+}
+
+int greth_initialize(bd_t * bis)
+{
+	greth_priv *greth;
+	ambapp_apbdev apbdev;
+	struct eth_device *dev;
+	int i;
+	char *addr_str, *end;
+	unsigned char addr[6];
+
+	debug("Scanning for GRETH\n");
+
+	/* Find Device & IRQ via AMBA Plug&Play information */
+	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_ETHMAC, &apbdev) != 1) {
+		return -1;	/* GRETH not found */
+	}
+
+	greth = (greth_priv *) malloc(sizeof(greth_priv));
+	dev = (struct eth_device *)malloc(sizeof(struct eth_device));
+	memset(dev, 0, sizeof(struct eth_device));
+	memset(greth, 0, sizeof(greth_priv));
+
+	greth->regs = (greth_regs *) apbdev.address;
+	greth->irq = apbdev.irq;
+	debug("Found GRETH at %p, irq %d\n", greth->regs, greth->irq);
+	dev->priv = (void *)greth;
+	dev->iobase = (unsigned int)greth->regs;
+	dev->init = greth_init;
+	dev->halt = greth_halt;
+	dev->send = greth_send;
+	dev->recv = greth_recv;
+	greth->dev = dev;
+
+	/* Reset Core */
+	GRETH_REGSAVE(&greth->regs->control, GRETH_RESET);
+
+	/* Wait for core to finish reset cycle */
+	while (GRETH_REGLOAD(&greth->regs->control) & GRETH_RESET) ;
+
+	/* Get the phy address which assumed to have been set
+	   correctly with the reset value in hardware */
+	greth->phyaddr = (GRETH_REGLOAD(&greth->regs->mdio) >> 11) & 0x1F;
+
+	/* Check if mac is gigabit capable */
+	greth->gbit_mac = (GRETH_REGLOAD(&greth->regs->control) >> 27) & 1;
+
+	/* Make descriptor string */
+	if (greth->gbit_mac) {
+		sprintf(dev->name, "GRETH_10/100/GB");
+	} else {
+		sprintf(dev->name, "GRETH_10/100");
+	}
+
+	/* initiate PHY, select speed/duplex depending on connected PHY */
+	if (greth_init_phy(greth, bis)) {
+		/* Failed to init PHY (timedout) */
+		debug("GRETH[%p]: Failed to init PHY\n", greth->regs);
+		return -1;
+	}
+
+	/* Register Device to EtherNet subsystem  */
+	eth_register(dev);
+
+	/* Get MAC address */
+	if ((addr_str = getenv("ethaddr")) != NULL) {
+		for (i = 0; i < 6; i++) {
+			addr[i] =
+			    addr_str ? simple_strtoul(addr_str, &end, 16) : 0;
+			if (addr_str) {
+				addr_str = (*end) ? end + 1 : end;
+			}
+		}
+	} else {
+		/* HW Address not found in environment, Set default HW address */
+		addr[0] = GRETH_HWADDR_0;	/* MSB */
+		addr[1] = GRETH_HWADDR_1;
+		addr[2] = GRETH_HWADDR_2;
+		addr[3] = GRETH_HWADDR_3;
+		addr[4] = GRETH_HWADDR_4;
+		addr[5] = GRETH_HWADDR_5;	/* LSB */
+	}
+
+	/* set and remember MAC address */
+	greth_set_hwaddr(greth, addr);
+
+	debug("GRETH[%p]: Initialized successfully\n", greth->regs);
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/greth.h b/marvell/uboot/drivers/net/greth.h
new file mode 100644
index 0000000..5299b28
--- /dev/null
+++ b/marvell/uboot/drivers/net/greth.h
@@ -0,0 +1,81 @@
+/* Gaisler.com GRETH 10/100/1000 Ethernet MAC driver
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#define GRETH_FD 0x10
+#define GRETH_RESET 0x40
+#define GRETH_MII_BUSY 0x8
+#define GRETH_MII_NVALID 0x10
+
+/* MII registers */
+#define GRETH_MII_EXTADV_1000FD 0x00000200
+#define GRETH_MII_EXTADV_1000HD 0x00000100
+#define GRETH_MII_EXTPRT_1000FD 0x00000800
+#define GRETH_MII_EXTPRT_1000HD 0x00000400
+
+#define GRETH_MII_100T4 0x00000200
+#define GRETH_MII_100TXFD 0x00000100
+#define GRETH_MII_100TXHD 0x00000080
+#define GRETH_MII_10FD 0x00000040
+#define GRETH_MII_10HD 0x00000020
+
+#define GRETH_BD_EN 0x800
+#define GRETH_BD_WR 0x1000
+#define GRETH_BD_IE 0x2000
+#define GRETH_BD_LEN 0x7FF
+
+#define GRETH_TXEN 0x1
+#define GRETH_INT_TX 0x8
+#define GRETH_TXI 0x4
+#define GRETH_TXBD_STATUS 0x0001C000
+#define GRETH_TXBD_MORE 0x20000
+#define GRETH_TXBD_IPCS 0x40000
+#define GRETH_TXBD_TCPCS 0x80000
+#define GRETH_TXBD_UDPCS 0x100000
+#define GRETH_TXBD_ERR_LC 0x10000
+#define GRETH_TXBD_ERR_UE 0x4000
+#define GRETH_TXBD_ERR_AL 0x8000
+#define GRETH_TXBD_NUM 128
+#define GRETH_TXBD_NUM_MASK (GRETH_TXBD_NUM-1)
+#define GRETH_TX_BUF_SIZE 2048
+
+#define GRETH_INT_RX         0x4
+#define GRETH_RXEN           0x2
+#define GRETH_RXI            0x8
+#define GRETH_RXBD_STATUS    0xFFFFC000
+#define GRETH_RXBD_ERR_AE    0x4000
+#define GRETH_RXBD_ERR_FT    0x8000
+#define GRETH_RXBD_ERR_CRC   0x10000
+#define GRETH_RXBD_ERR_OE    0x20000
+#define GRETH_RXBD_ERR_LE    0x40000
+#define GRETH_RXBD_IP_DEC    0x80000
+#define GRETH_RXBD_IP_CSERR  0x100000
+#define GRETH_RXBD_UDP_DEC   0x200000
+#define GRETH_RXBD_UDP_CSERR 0x400000
+#define GRETH_RXBD_TCP_DEC   0x800000
+#define GRETH_RXBD_TCP_CSERR 0x1000000
+
+#define GRETH_RXBD_NUM 128
+#define GRETH_RXBD_NUM_MASK (GRETH_RXBD_NUM-1)
+#define GRETH_RX_BUF_SIZE 2048
+
+/* Ethernet configuration registers */
+typedef struct _greth_regs {
+	volatile unsigned int control;
+	volatile unsigned int status;
+	volatile unsigned int esa_msb;
+	volatile unsigned int esa_lsb;
+	volatile unsigned int mdio;
+	volatile unsigned int tx_desc_p;
+	volatile unsigned int rx_desc_p;
+} greth_regs;
+
+/* Ethernet buffer descriptor */
+typedef struct _greth_bd {
+	volatile unsigned int stat;
+	unsigned int addr;	/* Buffer address not changed by HW */
+} greth_bd;
diff --git a/marvell/uboot/drivers/net/inca-ip_sw.c b/marvell/uboot/drivers/net/inca-ip_sw.c
new file mode 100644
index 0000000..cdfbfa6
--- /dev/null
+++ b/marvell/uboot/drivers/net/inca-ip_sw.c
@@ -0,0 +1,793 @@
+/*
+ * INCA-IP internal switch ethernet driver.
+ *
+ * (C) Copyright 2003-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+
+#include <common.h>
+
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/inca-ip.h>
+#include <asm/addrspace.h>
+
+
+#define NUM_RX_DESC	PKTBUFSRX
+#define NUM_TX_DESC	3
+#define TOUT_LOOP	1000000
+
+
+#define DELAY	udelay(10000)
+  /* Sometimes the store word instruction hangs while writing to one
+   * of the Switch registers. Moving the instruction into a separate
+   * function somehow makes the problem go away.
+   */
+static void SWORD(volatile u32 * reg, u32 value)
+{
+	*reg = value;
+}
+
+#define DMA_WRITE_REG(reg, value) *((volatile u32 *)reg) = (u32)value;
+#define DMA_READ_REG(reg, value)    value = (u32)*((volatile u32*)reg)
+#define SW_WRITE_REG(reg, value)   \
+	SWORD(reg, value);\
+	DELAY;\
+	SWORD(reg, value);
+
+#define SW_READ_REG(reg, value)	   \
+	value = (u32)*((volatile u32*)reg);\
+	DELAY;\
+	value = (u32)*((volatile u32*)reg);
+
+#define INCA_DMA_TX_POLLING_TIME	0x07
+#define INCA_DMA_RX_POLLING_TIME	0x07
+
+#define INCA_DMA_TX_HOLD		0x80000000
+#define INCA_DMA_TX_EOP			0x40000000
+#define INCA_DMA_TX_SOP			0x20000000
+#define INCA_DMA_TX_ICPT		0x10000000
+#define INCA_DMA_TX_IEOP		0x08000000
+
+#define INCA_DMA_RX_C			0x80000000
+#define INCA_DMA_RX_SOP			0x40000000
+#define INCA_DMA_RX_EOP			0x20000000
+
+#define INCA_SWITCH_PHY_SPEED_10H	0x1
+#define INCA_SWITCH_PHY_SPEED_10F	0x5
+#define INCA_SWITCH_PHY_SPEED_100H	0x2
+#define INCA_SWITCH_PHY_SPEED_100F	0x6
+
+/************************ Auto MDIX settings ************************/
+#define INCA_IP_AUTO_MDIX_LAN_PORTS_DIR		INCA_IP_Ports_P1_DIR
+#define INCA_IP_AUTO_MDIX_LAN_PORTS_ALTSEL	INCA_IP_Ports_P1_ALTSEL
+#define INCA_IP_AUTO_MDIX_LAN_PORTS_OUT		INCA_IP_Ports_P1_OUT
+#define INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX	16
+
+#define WAIT_SIGNAL_RETRIES			100
+#define WAIT_LINK_RETRIES			100
+#define LINK_RETRY_DELAY			2000  /* ms */
+/********************************************************************/
+
+typedef struct
+{
+	union {
+		struct {
+			volatile u32 HOLD		:1;
+			volatile u32 ICpt		:1;
+			volatile u32 IEop		:1;
+			volatile u32 offset		:3;
+			volatile u32 reserved0		:4;
+			volatile u32 NFB		:22;
+		}field;
+
+		volatile u32 word;
+	}params;
+
+	volatile u32 nextRxDescPtr;
+
+	volatile u32 RxDataPtr;
+
+	union {
+		struct {
+			volatile u32 C			:1;
+			volatile u32 Sop		:1;
+			volatile u32 Eop		:1;
+			volatile u32 reserved3		:12;
+			volatile u32 NBT		:17;
+		}field;
+
+		volatile u32 word;
+	}status;
+
+} inca_rx_descriptor_t;
+
+
+typedef struct
+{
+	union {
+		struct {
+			volatile u32 HOLD		:1;
+			volatile u32 Eop		:1;
+			volatile u32 Sop		:1;
+			volatile u32 ICpt		:1;
+			volatile u32 IEop		:1;
+			volatile u32 reserved0		:5;
+			volatile u32 NBA		:22;
+		}field;
+
+		volatile u32 word;
+	}params;
+
+	volatile u32 nextTxDescPtr;
+
+	volatile u32 TxDataPtr;
+
+	volatile u32 C			:1;
+	volatile u32 reserved3		:31;
+
+} inca_tx_descriptor_t;
+
+
+static inca_rx_descriptor_t rx_ring[NUM_RX_DESC] __attribute__ ((aligned(16)));
+static inca_tx_descriptor_t tx_ring[NUM_TX_DESC] __attribute__ ((aligned(16)));
+
+static int tx_new, rx_new, tx_hold, rx_hold;
+static int tx_old_hold = -1;
+static int initialized	= 0;
+
+
+static int inca_switch_init(struct eth_device *dev, bd_t * bis);
+static int inca_switch_send(struct eth_device *dev, void *packet, int length);
+static int inca_switch_recv(struct eth_device *dev);
+static void inca_switch_halt(struct eth_device *dev);
+static void inca_init_switch_chip(void);
+static void inca_dma_init(void);
+static int inca_amdix(void);
+
+
+int inca_switch_initialize(bd_t * bis)
+{
+	struct eth_device *dev;
+
+#if 0
+	printf("Entered inca_switch_initialize()\n");
+#endif
+
+	if (!(dev = (struct eth_device *) malloc (sizeof *dev))) {
+		printf("Failed to allocate memory\n");
+		return 0;
+	}
+	memset(dev, 0, sizeof(*dev));
+
+	inca_dma_init();
+
+	inca_init_switch_chip();
+
+#if defined(CONFIG_INCA_IP_SWITCH_AMDIX)
+	inca_amdix();
+#endif
+
+	sprintf(dev->name, "INCA-IP Switch");
+	dev->init = inca_switch_init;
+	dev->halt = inca_switch_halt;
+	dev->send = inca_switch_send;
+	dev->recv = inca_switch_recv;
+
+	eth_register(dev);
+
+#if 0
+	printf("Leaving inca_switch_initialize()\n");
+#endif
+
+	return 0;
+}
+
+
+static int inca_switch_init(struct eth_device *dev, bd_t * bis)
+{
+	int i;
+	u32 v, regValue;
+	u16 wTmp;
+
+#if 0
+	printf("Entering inca_switch_init()\n");
+#endif
+
+	/* Set MAC address.
+	 */
+	wTmp = (u16)dev->enetaddr[0];
+	regValue = (wTmp << 8) | dev->enetaddr[1];
+
+	SW_WRITE_REG(INCA_IP_Switch_PMAC_SA1, regValue);
+
+	wTmp = (u16)dev->enetaddr[2];
+	regValue = (wTmp << 8) | dev->enetaddr[3];
+	regValue = regValue << 16;
+	wTmp = (u16)dev->enetaddr[4];
+	regValue |= (wTmp<<8) | dev->enetaddr[5];
+
+	SW_WRITE_REG(INCA_IP_Switch_PMAC_SA2, regValue);
+
+	/* Initialize the descriptor rings.
+	 */
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		inca_rx_descriptor_t * rx_desc = (inca_rx_descriptor_t *)CKSEG1ADDR(&rx_ring[i]);
+		memset(rx_desc, 0, sizeof(rx_ring[i]));
+
+		/* Set maximum size of receive buffer.
+		 */
+		rx_desc->params.field.NFB = PKTSIZE_ALIGN;
+
+		/* Set the offset of the receive buffer. Zero means
+		 * that the offset mechanism is not used.
+		 */
+		rx_desc->params.field.offset = 0;
+
+		/* Check if it is the last descriptor.
+		 */
+		if (i == (NUM_RX_DESC - 1)) {
+			/* Let the last descriptor point to the first
+			 * one.
+			 */
+			rx_desc->nextRxDescPtr = (u32)CKSEG1ADDR(rx_ring);
+		} else {
+			/* Set the address of the next descriptor.
+			 */
+			rx_desc->nextRxDescPtr = (u32)CKSEG1ADDR(&rx_ring[i+1]);
+		}
+
+		rx_desc->RxDataPtr = (u32)CKSEG1ADDR(NetRxPackets[i]);
+	}
+
+#if 0
+	printf("rx_ring = 0x%08X 0x%08X\n", (u32)rx_ring, (u32)&rx_ring[0]);
+	printf("tx_ring = 0x%08X 0x%08X\n", (u32)tx_ring, (u32)&tx_ring[0]);
+#endif
+
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		inca_tx_descriptor_t * tx_desc = (inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[i]);
+
+		memset(tx_desc, 0, sizeof(tx_ring[i]));
+
+		tx_desc->params.word	   = 0;
+		tx_desc->params.field.HOLD = 1;
+		tx_desc->C		   = 1;
+
+			/* Check if it is the last descriptor.
+			 */
+		if (i == (NUM_TX_DESC - 1)) {
+				/* Let the last descriptor point to the
+				 * first one.
+				 */
+			tx_desc->nextTxDescPtr = (u32)CKSEG1ADDR(tx_ring);
+		} else {
+				/* Set the address of the next descriptor.
+				 */
+			tx_desc->nextTxDescPtr = (u32)CKSEG1ADDR(&tx_ring[i+1]);
+		}
+	}
+
+	/* Initialize RxDMA.
+	 */
+	DMA_READ_REG(INCA_IP_DMA_DMA_RXISR, v);
+	debug("RX status = 0x%08X\n", v);
+
+	/* Writing to the FRDA of CHANNEL.
+	 */
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXFRDA0, (u32)rx_ring);
+
+	/* Writing to the COMMAND REG.
+	 */
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_INIT);
+
+	/* Initialize TxDMA.
+	 */
+	DMA_READ_REG(INCA_IP_DMA_DMA_TXISR, v);
+	debug("TX status = 0x%08X\n", v);
+
+	/* Writing to the FRDA of CHANNEL.
+	 */
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXFRDA0, (u32)tx_ring);
+
+	tx_new = rx_new = 0;
+
+	tx_hold = NUM_TX_DESC - 1;
+	rx_hold = NUM_RX_DESC - 1;
+
+#if 0
+	rx_ring[rx_hold].params.field.HOLD = 1;
+#endif
+	/* enable spanning tree forwarding, enable the CPU port */
+	/* ST_PT:
+	 *	CPS (CPU port status)	0x3 (forwarding)
+	 *	LPS (LAN port status)	0x3 (forwarding)
+	 *	PPS (PC port status)	0x3 (forwarding)
+	 */
+	SW_WRITE_REG(INCA_IP_Switch_ST_PT,0x3f);
+
+#if 0
+	printf("Leaving inca_switch_init()\n");
+#endif
+
+	return 0;
+}
+
+
+static int inca_switch_send(struct eth_device *dev, void *packet, int length)
+{
+	int		       i;
+	int		       res	= -1;
+	u32		       command;
+	u32		       regValue;
+	inca_tx_descriptor_t * tx_desc	= (inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_new]);
+
+#if 0
+	printf("Entered inca_switch_send()\n");
+#endif
+
+	if (length <= 0) {
+		printf ("%s: bad packet size: %d\n", dev->name, length);
+		goto Done;
+	}
+
+	for(i = 0; tx_desc->C == 0; i++) {
+		if (i >= TOUT_LOOP) {
+			printf("%s: tx error buffer not ready\n", dev->name);
+			goto Done;
+		}
+	}
+
+	if (tx_old_hold >= 0) {
+		((inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_old_hold]))->params.field.HOLD = 1;
+	}
+	tx_old_hold = tx_hold;
+
+	tx_desc->params.word =
+			(INCA_DMA_TX_SOP | INCA_DMA_TX_EOP | INCA_DMA_TX_HOLD);
+
+	tx_desc->C = 0;
+	tx_desc->TxDataPtr = (u32)packet;
+	tx_desc->params.field.NBA = length;
+
+	((inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_hold]))->params.field.HOLD = 0;
+
+	tx_hold = tx_new;
+	tx_new	= (tx_new + 1) % NUM_TX_DESC;
+
+
+	if (! initialized) {
+		command = INCA_IP_DMA_DMA_TXCCR0_INIT;
+		initialized = 1;
+	} else {
+		command = INCA_IP_DMA_DMA_TXCCR0_HR;
+	}
+
+	DMA_READ_REG(INCA_IP_DMA_DMA_TXCCR0, regValue);
+	regValue |= command;
+#if 0
+	printf("regValue = 0x%x\n", regValue);
+#endif
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, regValue);
+
+#if 1
+	for(i = 0; ((inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_hold]))->C == 0; i++) {
+		if (i >= TOUT_LOOP) {
+			printf("%s: tx buffer not ready\n", dev->name);
+			goto Done;
+		}
+	}
+#endif
+	res = length;
+Done:
+#if 0
+	printf("Leaving inca_switch_send()\n");
+#endif
+	return res;
+}
+
+
+static int inca_switch_recv(struct eth_device *dev)
+{
+	int		       length  = 0;
+	inca_rx_descriptor_t * rx_desc;
+
+#if 0
+	printf("Entered inca_switch_recv()\n");
+#endif
+
+	for (;;) {
+		rx_desc = (inca_rx_descriptor_t *)CKSEG1ADDR(&rx_ring[rx_new]);
+
+		if (rx_desc->status.field.C == 0) {
+			break;
+		}
+
+#if 0
+		rx_ring[rx_new].params.field.HOLD = 1;
+#endif
+
+		if (! rx_desc->status.field.Eop) {
+			printf("Partly received packet!!!\n");
+			break;
+		}
+
+		length = rx_desc->status.field.NBT;
+		rx_desc->status.word &=
+			 ~(INCA_DMA_RX_EOP | INCA_DMA_RX_SOP | INCA_DMA_RX_C);
+#if 0
+{
+  int i;
+  for (i=0;i<length - 4;i++) {
+    if (i % 16 == 0) printf("\n%04x: ", i);
+    printf("%02X ", NetRxPackets[rx_new][i]);
+  }
+  printf("\n");
+}
+#endif
+
+		if (length) {
+#if 0
+			printf("Received %d bytes\n", length);
+#endif
+			NetReceive((void*)CKSEG1ADDR(NetRxPackets[rx_new]), length - 4);
+		} else {
+#if 1
+			printf("Zero length!!!\n");
+#endif
+		}
+
+
+		((inca_rx_descriptor_t *)CKSEG1ADDR(&rx_ring[rx_hold]))->params.field.HOLD = 0;
+
+		rx_hold = rx_new;
+
+		rx_new = (rx_new + 1) % NUM_RX_DESC;
+	}
+
+#if 0
+	printf("Leaving inca_switch_recv()\n");
+#endif
+
+	return length;
+}
+
+
+static void inca_switch_halt(struct eth_device *dev)
+{
+#if 0
+	printf("Entered inca_switch_halt()\n");
+#endif
+
+#if 1
+	initialized = 0;
+#endif
+#if 1
+	/* Disable forwarding to the CPU port.
+	 */
+	SW_WRITE_REG(INCA_IP_Switch_ST_PT,0xf);
+
+	/* Close RxDMA channel.
+	 */
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
+
+	/* Close TxDMA channel.
+	 */
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, INCA_IP_DMA_DMA_TXCCR0_OFF);
+
+
+#endif
+#if 0
+	printf("Leaving inca_switch_halt()\n");
+#endif
+}
+
+
+static void inca_init_switch_chip(void)
+{
+	u32 regValue;
+
+	/* To workaround a problem with collision counter
+	 * (see Errata sheet).
+	 */
+	SW_WRITE_REG(INCA_IP_Switch_PC_TX_CTL, 0x00000001);
+	SW_WRITE_REG(INCA_IP_Switch_LAN_TX_CTL, 0x00000001);
+
+#if 1
+	/* init MDIO configuration:
+	 *	MDS (Poll speed):	0x01 (4ms)
+	 *	PHY_LAN_ADDR:		0x06
+	 *	PHY_PC_ADDR:		0x05
+	 *	UEP (Use External PHY): 0x00 (Internal PHY is used)
+	 *	PS (Port Select):	0x00 (PT/UMM for LAN)
+	 *	PT (PHY Test):		0x00 (no test mode)
+	 *	UMM (Use MDIO Mode):	0x00 (state machine is disabled)
+	 */
+	SW_WRITE_REG(INCA_IP_Switch_MDIO_CFG, 0x4c50);
+
+	/* init PHY:
+	 *	SL (Auto Neg. Speed for LAN)
+	 *	SP (Auto Neg. Speed for PC)
+	 *	LL (Link Status for LAN)
+	 *	LP (Link Status for PC)
+	 *	DL (Duplex Status for LAN)
+	 *	DP (Duplex Status for PC)
+	 *	PL (Auto Neg. Pause Status for LAN)
+	 *	PP (Auto Neg. Pause Status for PC)
+	 */
+	SW_WRITE_REG (INCA_IP_Switch_EPHY, 0xff);
+
+	/* MDIO_ACC:
+	 *	RA (Request/Ack)  0x01 (Request)
+	 *	RW (Read/Write)	  0x01 (Write)
+	 *	PHY_ADDR	  0x05 (PC)
+	 *	REG_ADDR	  0x00 (PHY_BCR: basic control register)
+	 *	PHY_DATA	  0x8000
+	 *		      Reset		      - software reset
+	 *		      LB (loop back)	      - normal
+	 *		      SS (speed select)	      - 10 Mbit/s
+	 *		      ANE (auto neg. enable)  - enable
+	 *		      PD (power down)	      - normal
+	 *		      ISO (isolate)	      - normal
+	 *		      RAN (restart auto neg.) - normal
+	 *		      DM (duplex mode)	      - half duplex
+	 *		      CT (collision test)     - enable
+	 */
+	SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, 0xc0a09000);
+
+	/* MDIO_ACC:
+	 *	RA (Request/Ack)  0x01 (Request)
+	 *	RW (Read/Write)	  0x01 (Write)
+	 *	PHY_ADDR	  0x06 (LAN)
+	 *	REG_ADDR	  0x00 (PHY_BCR: basic control register)
+	 *	PHY_DATA	  0x8000
+	 *		      Reset		      - software reset
+	 *		      LB (loop back)	      - normal
+	 *		      SS (speed select)	      - 10 Mbit/s
+	 *		      ANE (auto neg. enable)  - enable
+	 *		      PD (power down)	      - normal
+	 *		      ISO (isolate)	      - normal
+	 *		      RAN (restart auto neg.) - normal
+	 *		      DM (duplex mode)	      - half duplex
+	 *		      CT (collision test)     - enable
+	 */
+	SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC, 0xc0c09000);
+
+#endif
+
+	/* Make sure the CPU port is disabled for now. We
+	 * don't want packets to get stacked for us until
+	 * we enable DMA and are prepared to receive them.
+	 */
+	SW_WRITE_REG(INCA_IP_Switch_ST_PT,0xf);
+
+	SW_READ_REG(INCA_IP_Switch_ARL_CTL, regValue);
+
+	/* CRC GEN is enabled.
+	 */
+	regValue |= 0x00000200;
+	SW_WRITE_REG(INCA_IP_Switch_ARL_CTL, regValue);
+
+	/* ADD TAG is disabled.
+	 */
+	SW_READ_REG(INCA_IP_Switch_PMAC_HD_CTL, regValue);
+	regValue &= ~0x00000002;
+	SW_WRITE_REG(INCA_IP_Switch_PMAC_HD_CTL, regValue);
+}
+
+
+static void inca_dma_init(void)
+{
+	/* Switch off all DMA channels.
+	 */
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXCCR1, INCA_IP_DMA_DMA_RXCCR1_OFF);
+
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, INCA_IP_DMA_DMA_RXCCR0_OFF);
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR1, INCA_IP_DMA_DMA_TXCCR1_OFF);
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR2, INCA_IP_DMA_DMA_TXCCR2_OFF);
+
+	/* Setup TX channel polling time.
+	 */
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXPOLL, INCA_DMA_TX_POLLING_TIME);
+
+	/* Setup RX channel polling time.
+	 */
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXPOLL, INCA_DMA_RX_POLLING_TIME);
+
+	/* ERRATA: write reset value into the DMA RX IMR register.
+	 */
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXIMR, 0xFFFFFFFF);
+
+	/* Just in case: disable all transmit interrupts also.
+	 */
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXIMR, 0xFFFFFFFF);
+
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_TXISR, 0xFFFFFFFF);
+	DMA_WRITE_REG(INCA_IP_DMA_DMA_RXISR, 0xFFFFFFFF);
+}
+
+#if defined(CONFIG_INCA_IP_SWITCH_AMDIX)
+static int inca_amdix(void)
+{
+	u32 phyReg1 = 0;
+	u32 phyReg4 = 0;
+	u32 phyReg5 = 0;
+	u32 phyReg6 = 0;
+	u32 phyReg31 = 0;
+	u32 regEphy = 0;
+	int mdi_flag;
+	int retries;
+
+	/* Setup GPIO pins.
+	 */
+	*INCA_IP_AUTO_MDIX_LAN_PORTS_DIR    |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
+	*INCA_IP_AUTO_MDIX_LAN_PORTS_ALTSEL |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
+
+#if 0
+	/* Wait for signal.
+	 */
+	retries = WAIT_SIGNAL_RETRIES;
+	while (--retries) {
+		SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+				(0x1 << 31) |	/* RA		*/
+				(0x0 << 30) |	/* Read		*/
+				(0x6 << 21) |	/* LAN		*/
+				(17  << 16));	/* PHY_MCSR	*/
+		do {
+			SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
+		} while (phyReg1 & (1 << 31));
+
+		if (phyReg1 & (1 << 1)) {
+			/* Signal detected */
+			break;
+		}
+	}
+
+	if (!retries)
+		goto Fail;
+#endif
+
+	/* Set MDI mode.
+	 */
+	*INCA_IP_AUTO_MDIX_LAN_PORTS_OUT &= ~(1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
+	mdi_flag = 1;
+
+	/* Wait for link.
+	 */
+	retries = WAIT_LINK_RETRIES;
+	while (--retries) {
+		udelay(LINK_RETRY_DELAY * 1000);
+		SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+				(0x1 << 31) |	/* RA		*/
+				(0x0 << 30) |	/* Read		*/
+				(0x6 << 21) |	/* LAN		*/
+				(1   << 16));	/* PHY_BSR	*/
+		do {
+			SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
+		} while (phyReg1 & (1 << 31));
+
+		if (phyReg1 & (1 << 2)) {
+			/* Link is up */
+			break;
+		} else if (mdi_flag) {
+			/* Set MDIX mode */
+			*INCA_IP_AUTO_MDIX_LAN_PORTS_OUT |= (1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
+			mdi_flag = 0;
+		} else {
+			/* Set MDI mode */
+			*INCA_IP_AUTO_MDIX_LAN_PORTS_OUT &= ~(1 << INCA_IP_AUTO_MDIX_LAN_GPIO_PIN_RXTX);
+			mdi_flag = 1;
+		}
+	}
+
+	if (!retries) {
+		goto Fail;
+	} else {
+		SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+				(0x1 << 31) |	/* RA		*/
+				(0x0 << 30) |	/* Read		*/
+				(0x6 << 21) |	/* LAN		*/
+				(1   << 16));	/* PHY_BSR	*/
+		do {
+			SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg1);
+		} while (phyReg1 & (1 << 31));
+
+		/* Auto-negotiation / Parallel detection complete
+		 */
+		if (phyReg1 & (1 << 5)) {
+			SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+				(0x1 << 31) |	/* RA		*/
+				(0x0 << 30) |	/* Read		*/
+				(0x6 << 21) |	/* LAN		*/
+				(31  << 16));	/* PHY_SCSR	*/
+			do {
+				SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg31);
+			} while (phyReg31 & (1 << 31));
+
+			switch ((phyReg31 >> 2) & 0x7) {
+			case INCA_SWITCH_PHY_SPEED_10H:
+				/* 10Base-T Half-duplex */
+				regEphy = 0;
+				break;
+			case INCA_SWITCH_PHY_SPEED_10F:
+				/* 10Base-T Full-duplex */
+				regEphy = INCA_IP_Switch_EPHY_DL;
+				break;
+			case INCA_SWITCH_PHY_SPEED_100H:
+				/* 100Base-TX Half-duplex */
+				regEphy = INCA_IP_Switch_EPHY_SL;
+				break;
+			case INCA_SWITCH_PHY_SPEED_100F:
+				/* 100Base-TX Full-duplex */
+				regEphy = INCA_IP_Switch_EPHY_SL | INCA_IP_Switch_EPHY_DL;
+				break;
+			}
+
+			/* In case of Auto-negotiation,
+			 * update the negotiated PAUSE support status
+			 */
+			if (phyReg1 & (1 << 3)) {
+				SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+					(0x1 << 31) |	/* RA		*/
+					(0x0 << 30) |	/* Read		*/
+					(0x6 << 21) |	/* LAN		*/
+					(6   << 16));	/* MII_EXPANSION	*/
+				do {
+					SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg6);
+				} while (phyReg6 & (1 << 31));
+
+				/* We are Autoneg-able.
+				 * Is Link partner also able to autoneg?
+				 */
+				if (phyReg6 & (1 << 0)) {
+					SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+						(0x1 << 31) |	/* RA		*/
+						(0x0 << 30) |	/* Read		*/
+						(0x6 << 21) |	/* LAN		*/
+						(4   << 16));	/* MII_ADVERTISE	*/
+					do {
+						SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg4);
+					} while (phyReg4 & (1 << 31));
+
+					/* We advertise PAUSE capab.
+					 * Does link partner also advertise it?
+					 */
+					if (phyReg4 & (1 << 10)) {
+						SW_WRITE_REG(INCA_IP_Switch_MDIO_ACC,
+							(0x1 << 31) |	/* RA		*/
+							(0x0 << 30) |	/* Read		*/
+							(0x6 << 21) |	/* LAN		*/
+							(5   << 16));	/* MII_LPA	*/
+						do {
+							SW_READ_REG(INCA_IP_Switch_MDIO_ACC, phyReg5);
+						} while (phyReg5 & (1 << 31));
+
+						/* Link partner is PAUSE capab.
+						 */
+						if (phyReg5 & (1 << 10)) {
+							regEphy |= INCA_IP_Switch_EPHY_PL;
+						}
+					}
+				}
+
+			}
+
+			/* Link is up */
+			regEphy |= INCA_IP_Switch_EPHY_LL;
+
+			SW_WRITE_REG(INCA_IP_Switch_EPHY, regEphy);
+		}
+	}
+
+	return 0;
+
+Fail:
+	printf("No Link on LAN port\n");
+	return -1;
+}
+#endif /* CONFIG_INCA_IP_SWITCH_AMDIX */
diff --git a/marvell/uboot/drivers/net/ks8695eth.c b/marvell/uboot/drivers/net/ks8695eth.c
new file mode 100644
index 0000000..b4822e9
--- /dev/null
+++ b/marvell/uboot/drivers/net/ks8695eth.c
@@ -0,0 +1,229 @@
+/*
+ * ks8695eth.c -- KS8695 ethernet driver
+ *
+ * (C) Copyright 2004-2005, Greg Ungerer <greg.ungerer@opengear.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/****************************************************************************/
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <asm/arch/platform.h>
+
+/****************************************************************************/
+
+/*
+ * Hardware register access to the KS8695 LAN ethernet port
+ * (well, it is the 4 port switch really).
+ */
+#define	ks8695_read(a)    *((volatile unsigned long *) (KS8695_IO_BASE + (a)))
+#define	ks8695_write(a,v) *((volatile unsigned long *) (KS8695_IO_BASE + (a))) = (v)
+
+/****************************************************************************/
+
+/*
+ * Define the descriptor in-memory data structures.
+ */
+struct ks8695_txdesc {
+	uint32_t	owner;
+	uint32_t	ctrl;
+	uint32_t	addr;
+	uint32_t	next;
+};
+
+struct ks8695_rxdesc {
+	uint32_t	status;
+	uint32_t	ctrl;
+	uint32_t	addr;
+	uint32_t	next;
+};
+
+/****************************************************************************/
+
+/*
+ * Allocate local data structures to use for receiving and sending
+ * packets. Just to keep it all nice and simple.
+ */
+
+#define	TXDESCS		4
+#define	RXDESCS		4
+#define	BUFSIZE		2048
+
+volatile struct ks8695_txdesc ks8695_tx[TXDESCS] __attribute__((aligned(256)));
+volatile struct ks8695_rxdesc ks8695_rx[RXDESCS] __attribute__((aligned(256)));
+volatile uint8_t ks8695_bufs[BUFSIZE*(TXDESCS+RXDESCS)] __attribute__((aligned(2048)));;
+
+/****************************************************************************/
+
+/*
+ *	Ideally we want to use the MAC address stored in flash.
+ *	But we do some sanity checks in case they are not present
+ *	first.
+ */
+unsigned char eth_mac[] = {
+	0x00, 0x13, 0xc6, 0x00, 0x00, 0x00
+};
+
+void ks8695_getmac(void)
+{
+	unsigned char *fp;
+	int i;
+
+	/* Check if flash MAC is valid */
+	fp = (unsigned char *) 0x0201c000;
+	for (i = 0; (i < 6); i++) {
+		if ((fp[i] != 0) && (fp[i] != 0xff))
+			break;
+	}
+
+	/* If we found a valid looking MAC address then use it */
+	if (i < 6)
+		memcpy(&eth_mac[0], fp, 6);
+}
+
+/****************************************************************************/
+
+static int ks8695_eth_init(struct eth_device *dev, bd_t *bd)
+{
+	int i;
+
+	debug ("%s(%d): eth_reset()\n", __FILE__, __LINE__);
+
+	/* Reset the ethernet engines first */
+	ks8695_write(KS8695_LAN_DMA_TX, 0x80000000);
+	ks8695_write(KS8695_LAN_DMA_RX, 0x80000000);
+
+	ks8695_getmac();
+
+	/* Set MAC address */
+	ks8695_write(KS8695_LAN_MAC_LOW, (eth_mac[5] | (eth_mac[4] << 8) |
+		(eth_mac[3] << 16) | (eth_mac[2] << 24)));
+	ks8695_write(KS8695_LAN_MAC_HIGH, (eth_mac[1] | (eth_mac[0] << 8)));
+
+	/* Turn the 4 port switch on */
+	i = ks8695_read(KS8695_SWITCH_CTRL0);
+	ks8695_write(KS8695_SWITCH_CTRL0, (i | 0x1));
+	/* ks8695_write(KS8695_WAN_CONTROL, 0x3f000066); */
+
+	/* Initialize descriptor rings */
+	for (i = 0; (i < TXDESCS); i++) {
+		ks8695_tx[i].owner = 0;
+		ks8695_tx[i].ctrl = 0;
+		ks8695_tx[i].addr = (uint32_t) &ks8695_bufs[i*BUFSIZE];
+		ks8695_tx[i].next = (uint32_t) &ks8695_tx[i+1];
+	}
+	ks8695_tx[TXDESCS-1].ctrl = 0x02000000;
+	ks8695_tx[TXDESCS-1].next = (uint32_t) &ks8695_tx[0];
+
+	for (i = 0; (i < RXDESCS); i++) {
+		ks8695_rx[i].status = 0x80000000;
+		ks8695_rx[i].ctrl = BUFSIZE - 4;
+		ks8695_rx[i].addr = (uint32_t) &ks8695_bufs[(i+TXDESCS)*BUFSIZE];
+		ks8695_rx[i].next = (uint32_t) &ks8695_rx[i+1];
+	}
+	ks8695_rx[RXDESCS-1].ctrl |= 0x00080000;
+	ks8695_rx[RXDESCS-1].next = (uint32_t) &ks8695_rx[0];
+
+	/* The KS8695 is pretty slow reseting the ethernets... */
+	udelay(2000000);
+
+	/* Enable the ethernet engine */
+	ks8695_write(KS8695_LAN_TX_LIST, (uint32_t) &ks8695_tx[0]);
+	ks8695_write(KS8695_LAN_RX_LIST, (uint32_t) &ks8695_rx[0]);
+	ks8695_write(KS8695_LAN_DMA_TX, 0x3);
+	ks8695_write(KS8695_LAN_DMA_RX, 0x71);
+	ks8695_write(KS8695_LAN_DMA_RX_START, 0x1);
+
+	printf("KS8695 ETHERNET: %pM\n", eth_mac);
+	return 0;
+}
+
+/****************************************************************************/
+
+static void ks8695_eth_halt(struct eth_device *dev)
+{
+	debug ("%s(%d): eth_halt()\n", __FILE__, __LINE__);
+
+	/* Reset the ethernet engines */
+	ks8695_write(KS8695_LAN_DMA_TX, 0x80000000);
+	ks8695_write(KS8695_LAN_DMA_RX, 0x80000000);
+}
+
+/****************************************************************************/
+
+static int ks8695_eth_recv(struct eth_device *dev)
+{
+	volatile struct ks8695_rxdesc *dp;
+	int i, len = 0;
+
+	debug ("%s(%d): eth_rx()\n", __FILE__, __LINE__);
+
+	for (i = 0; (i < RXDESCS); i++) {
+		dp= &ks8695_rx[i];
+		if ((dp->status & 0x80000000) == 0) {
+			len = (dp->status & 0x7ff) - 4;
+			NetReceive((void *) dp->addr, len);
+			dp->status = 0x80000000;
+			ks8695_write(KS8695_LAN_DMA_RX_START, 0x1);
+			break;
+		}
+	}
+
+	return len;
+}
+
+/****************************************************************************/
+
+static int ks8695_eth_send(struct eth_device *dev, void *packet, int len)
+{
+	volatile struct ks8695_txdesc *dp;
+	static int next = 0;
+
+	debug ("%s(%d): eth_send(packet=%p,len=%d)\n", __FILE__, __LINE__,
+		packet, len);
+
+	dp = &ks8695_tx[next];
+	memcpy((void *) dp->addr, (void *) packet, len);
+
+	if (len < 64) {
+		memset((void *) (dp->addr + len), 0, 64-len);
+		len = 64;
+	}
+
+	dp->ctrl = len | 0xe0000000;
+	dp->owner = 0x80000000;
+
+	ks8695_write(KS8695_LAN_DMA_TX, 0x3);
+	ks8695_write(KS8695_LAN_DMA_TX_START, 0x1);
+
+	if (++next >= TXDESCS)
+		next = 0;
+
+	return 0;
+}
+
+/****************************************************************************/
+
+int ks8695_eth_initialize(void)
+{
+	struct eth_device *dev;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL)
+		return -1;
+	memset(dev, 0, sizeof(*dev));
+
+	dev->iobase = KS8695_IO_BASE + KS8695_LAN_DMA_TX;
+	dev->init = ks8695_eth_init;
+	dev->halt = ks8695_eth_halt;
+	dev->send = ks8695_eth_send;
+	dev->recv = ks8695_eth_recv;
+	strcpy(dev->name, "ks8695eth");
+
+	eth_register(dev);
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/ks8851_mll.c b/marvell/uboot/drivers/net/ks8851_mll.c
new file mode 100644
index 0000000..05e5b14
--- /dev/null
+++ b/marvell/uboot/drivers/net/ks8851_mll.c
@@ -0,0 +1,633 @@
+/*
+ * Micrel KS8851_MLL 16bit Network driver
+ * Copyright (c) 2011 Roberto Cerati <roberto.cerati@bticino.it>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/io.h>
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <net.h>
+#include <miiphy.h>
+
+#include "ks8851_mll.h"
+
+#define DRIVERNAME			"ks8851_mll"
+
+#define MAX_RECV_FRAMES			32
+#define MAX_BUF_SIZE			2048
+#define TX_BUF_SIZE			2000
+#define RX_BUF_SIZE			2000
+
+static const struct chip_id chip_ids[] =  {
+	{CIDER_ID, "KSZ8851"},
+	{0, NULL},
+};
+
+/*
+ * union ks_tx_hdr - tx header data
+ * @txb: The header as bytes
+ * @txw: The header as 16bit, little-endian words
+ *
+ * A dual representation of the tx header data to allow
+ * access to individual bytes, and to allow 16bit accesses
+ * with 16bit alignment.
+ */
+union ks_tx_hdr {
+	u8      txb[4];
+	__le16  txw[2];
+};
+
+/*
+ * struct ks_net - KS8851 driver private data
+ * @net_device	: The network device we're bound to
+ * @txh		: temporaly buffer to save status/length.
+ * @frame_head_info	: frame header information for multi-pkt rx.
+ * @statelock	: Lock on this structure for tx list.
+ * @msg_enable	: The message flags controlling driver output (see ethtool).
+ * @frame_cnt	: number of frames received.
+ * @bus_width	: i/o bus width.
+ * @irq		: irq number assigned to this device.
+ * @rc_rxqcr	: Cached copy of KS_RXQCR.
+ * @rc_txcr	: Cached copy of KS_TXCR.
+ * @rc_ier	: Cached copy of KS_IER.
+ * @sharedbus	: Multipex(addr and data bus) mode indicator.
+ * @cmd_reg_cache	: command register cached.
+ * @cmd_reg_cache_int	: command register cached. Used in the irq handler.
+ * @promiscuous	: promiscuous mode indicator.
+ * @all_mcast	: mutlicast indicator.
+ * @mcast_lst_size	: size of multicast list.
+ * @mcast_lst		: multicast list.
+ * @mcast_bits		: multicast enabed.
+ * @mac_addr		: MAC address assigned to this device.
+ * @fid			: frame id.
+ * @extra_byte		: number of extra byte prepended rx pkt.
+ * @enabled		: indicator this device works.
+ */
+
+/* Receive multiplex framer header info */
+struct type_frame_head {
+	u16	sts;         /* Frame status */
+	u16	len;         /* Byte count */
+} fr_h_i[MAX_RECV_FRAMES];
+
+struct ks_net {
+	struct net_device	*netdev;
+	union ks_tx_hdr		txh;
+	struct type_frame_head	*frame_head_info;
+	u32			msg_enable;
+	u32			frame_cnt;
+	int			bus_width;
+	int			irq;
+	u16			rc_rxqcr;
+	u16			rc_txcr;
+	u16			rc_ier;
+	u16			sharedbus;
+	u16			cmd_reg_cache;
+	u16			cmd_reg_cache_int;
+	u16			promiscuous;
+	u16			all_mcast;
+	u16			mcast_lst_size;
+	u8			mcast_lst[MAX_MCAST_LST][MAC_ADDR_LEN];
+	u8			mcast_bits[HW_MCAST_SIZE];
+	u8			mac_addr[6];
+	u8                      fid;
+	u8			extra_byte;
+	u8			enabled;
+} ks_str, *ks;
+
+#define BE3             0x8000      /* Byte Enable 3 */
+#define BE2             0x4000      /* Byte Enable 2 */
+#define BE1             0x2000      /* Byte Enable 1 */
+#define BE0             0x1000      /* Byte Enable 0 */
+
+static u8 ks_rdreg8(struct eth_device *dev, u16 offset)
+{
+	u8 shift_bit = offset & 0x03;
+	u8 shift_data = (offset & 1) << 3;
+
+	writew(offset | (BE0 << shift_bit), dev->iobase + 2);
+
+	return (u8)(readw(dev->iobase) >> shift_data);
+}
+
+static u16 ks_rdreg16(struct eth_device *dev, u16 offset)
+{
+	writew(offset | ((BE1 | BE0) << (offset & 0x02)), dev->iobase + 2);
+
+	return readw(dev->iobase);
+}
+
+static void ks_wrreg8(struct eth_device *dev, u16 offset, u8 val)
+{
+	u8 shift_bit = (offset & 0x03);
+	u16 value_write = (u16)(val << ((offset & 1) << 3));
+
+	writew(offset | (BE0 << shift_bit), dev->iobase + 2);
+	writew(value_write, dev->iobase);
+}
+
+static void ks_wrreg16(struct eth_device *dev, u16 offset, u16 val)
+{
+	writew(offset | ((BE1 | BE0) << (offset & 0x02)), dev->iobase + 2);
+	writew(val, dev->iobase);
+}
+
+/*
+ * ks_inblk - read a block of data from QMU. This is called after sudo DMA mode
+ * enabled.
+ * @ks: The chip state
+ * @wptr: buffer address to save data
+ * @len: length in byte to read
+ */
+static inline void ks_inblk(struct eth_device *dev, u16 *wptr, u32 len)
+{
+	len >>= 1;
+
+	while (len--)
+		*wptr++ = readw(dev->iobase);
+}
+
+/*
+ * ks_outblk - write data to QMU. This is called after sudo DMA mode enabled.
+ * @ks: The chip information
+ * @wptr: buffer address
+ * @len: length in byte to write
+ */
+static inline void ks_outblk(struct eth_device *dev, u16 *wptr, u32 len)
+{
+	len >>= 1;
+
+	while (len--)
+		writew(*wptr++, dev->iobase);
+}
+
+static void ks_enable_int(struct eth_device *dev)
+{
+	ks_wrreg16(dev, KS_IER, ks->rc_ier);
+}
+
+static void ks_set_powermode(struct eth_device *dev, unsigned pwrmode)
+{
+	unsigned pmecr;
+
+	ks_rdreg16(dev, KS_GRR);
+	pmecr = ks_rdreg16(dev, KS_PMECR);
+	pmecr &= ~PMECR_PM_MASK;
+	pmecr |= pwrmode;
+
+	ks_wrreg16(dev, KS_PMECR, pmecr);
+}
+
+/*
+ * ks_read_config - read chip configuration of bus width.
+ * @ks: The chip information
+ */
+static void ks_read_config(struct eth_device *dev)
+{
+	u16 reg_data = 0;
+
+	/* Regardless of bus width, 8 bit read should always work. */
+	reg_data = ks_rdreg8(dev, KS_CCR) & 0x00FF;
+	reg_data |= ks_rdreg8(dev, KS_CCR + 1) << 8;
+
+	/* addr/data bus are multiplexed */
+	ks->sharedbus = (reg_data & CCR_SHARED) == CCR_SHARED;
+
+	/*
+	 * There are garbage data when reading data from QMU,
+	 * depending on bus-width.
+	 */
+	if (reg_data & CCR_8BIT) {
+		ks->bus_width = ENUM_BUS_8BIT;
+		ks->extra_byte = 1;
+	} else if (reg_data & CCR_16BIT) {
+		ks->bus_width = ENUM_BUS_16BIT;
+		ks->extra_byte = 2;
+	} else {
+		ks->bus_width = ENUM_BUS_32BIT;
+		ks->extra_byte = 4;
+	}
+}
+
+/*
+ * ks_soft_reset - issue one of the soft reset to the device
+ * @ks: The device state.
+ * @op: The bit(s) to set in the GRR
+ *
+ * Issue the relevant soft-reset command to the device's GRR register
+ * specified by @op.
+ *
+ * Note, the delays are in there as a caution to ensure that the reset
+ * has time to take effect and then complete. Since the datasheet does
+ * not currently specify the exact sequence, we have chosen something
+ * that seems to work with our device.
+ */
+static void ks_soft_reset(struct eth_device *dev, unsigned op)
+{
+	/* Disable interrupt first */
+	ks_wrreg16(dev, KS_IER, 0x0000);
+	ks_wrreg16(dev, KS_GRR, op);
+	mdelay(10);	/* wait a short time to effect reset */
+	ks_wrreg16(dev, KS_GRR, 0);
+	mdelay(1);	/* wait for condition to clear */
+}
+
+void ks_enable_qmu(struct eth_device *dev)
+{
+	u16 w;
+
+	w = ks_rdreg16(dev, KS_TXCR);
+
+	/* Enables QMU Transmit (TXCR). */
+	ks_wrreg16(dev, KS_TXCR, w | TXCR_TXE);
+
+	/* Enable RX Frame Count Threshold and Auto-Dequeue RXQ Frame */
+	w = ks_rdreg16(dev, KS_RXQCR);
+	ks_wrreg16(dev, KS_RXQCR, w | RXQCR_RXFCTE);
+
+	/* Enables QMU Receive (RXCR1). */
+	w = ks_rdreg16(dev, KS_RXCR1);
+	ks_wrreg16(dev, KS_RXCR1, w | RXCR1_RXE);
+}
+
+static void ks_disable_qmu(struct eth_device *dev)
+{
+	u16 w;
+
+	w = ks_rdreg16(dev, KS_TXCR);
+
+	/* Disables QMU Transmit (TXCR). */
+	w &= ~TXCR_TXE;
+	ks_wrreg16(dev, KS_TXCR, w);
+
+	/* Disables QMU Receive (RXCR1). */
+	w = ks_rdreg16(dev, KS_RXCR1);
+	w &= ~RXCR1_RXE;
+	ks_wrreg16(dev, KS_RXCR1, w);
+}
+
+static inline void ks_read_qmu(struct eth_device *dev, u16 *buf, u32 len)
+{
+	u32 r = ks->extra_byte & 0x1;
+	u32 w = ks->extra_byte - r;
+
+	/* 1. set sudo DMA mode */
+	ks_wrreg16(dev, KS_RXFDPR, RXFDPR_RXFPAI);
+	ks_wrreg8(dev, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff);
+
+	/*
+	 * 2. read prepend data
+	 *
+	 * read 4 + extra bytes and discard them.
+	 * extra bytes for dummy, 2 for status, 2 for len
+	 */
+
+	if (r)
+		ks_rdreg8(dev, 0);
+
+	ks_inblk(dev, buf, w + 2 + 2);
+
+	/* 3. read pkt data */
+	ks_inblk(dev, buf, ALIGN(len, 4));
+
+	/* 4. reset sudo DMA Mode */
+	ks_wrreg8(dev, KS_RXQCR, (ks->rc_rxqcr & ~RXQCR_SDA) & 0xff);
+}
+
+static void ks_rcv(struct eth_device *dev, uchar **pv_data)
+{
+	struct type_frame_head *frame_hdr = ks->frame_head_info;
+	int i;
+
+	ks->frame_cnt = ks_rdreg16(dev, KS_RXFCTR) >> 8;
+
+	/* read all header information */
+	for (i = 0; i < ks->frame_cnt; i++) {
+		/* Checking Received packet status */
+		frame_hdr->sts = ks_rdreg16(dev, KS_RXFHSR);
+		/* Get packet len from hardware */
+		frame_hdr->len = ks_rdreg16(dev, KS_RXFHBCR);
+		frame_hdr++;
+	}
+
+	frame_hdr = ks->frame_head_info;
+	while (ks->frame_cnt--) {
+		if ((frame_hdr->sts & RXFSHR_RXFV) &&
+		    (frame_hdr->len < RX_BUF_SIZE) &&
+		    frame_hdr->len) {
+			/* read data block including CRC 4 bytes */
+			ks_read_qmu(dev, (u16 *)(*pv_data), frame_hdr->len);
+
+			/* NetRxPackets buffer size is ok (*pv_data pointer) */
+			NetReceive(*pv_data, frame_hdr->len);
+			pv_data++;
+		} else {
+			ks_wrreg16(dev, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF));
+			printf(DRIVERNAME ": bad packet\n");
+		}
+		frame_hdr++;
+	}
+}
+
+/*
+ * ks_read_selftest - read the selftest memory info.
+ * @ks: The device state
+ *
+ * Read and check the TX/RX memory selftest information.
+ */
+static int ks_read_selftest(struct eth_device *dev)
+{
+	u16 both_done = MBIR_TXMBF | MBIR_RXMBF;
+	u16 mbir;
+	int ret = 0;
+
+	mbir = ks_rdreg16(dev, KS_MBIR);
+
+	if ((mbir & both_done) != both_done) {
+		printf(DRIVERNAME ": Memory selftest not finished\n");
+		return 0;
+	}
+
+	if (mbir & MBIR_TXMBFA) {
+		printf(DRIVERNAME ": TX memory selftest fails\n");
+		ret |= 1;
+	}
+
+	if (mbir & MBIR_RXMBFA) {
+		printf(DRIVERNAME ": RX memory selftest fails\n");
+		ret |= 2;
+	}
+
+	debug(DRIVERNAME ": the selftest passes\n");
+
+	return ret;
+}
+
+static void ks_setup(struct eth_device *dev)
+{
+	u16 w;
+
+	/* Setup Transmit Frame Data Pointer Auto-Increment (TXFDPR) */
+	ks_wrreg16(dev, KS_TXFDPR, TXFDPR_TXFPAI);
+
+	/* Setup Receive Frame Data Pointer Auto-Increment */
+	ks_wrreg16(dev, KS_RXFDPR, RXFDPR_RXFPAI);
+
+	/* Setup Receive Frame Threshold - 1 frame (RXFCTFC) */
+	ks_wrreg16(dev, KS_RXFCTR, 1 & RXFCTR_THRESHOLD_MASK);
+
+	/* Setup RxQ Command Control (RXQCR) */
+	ks->rc_rxqcr = RXQCR_CMD_CNTL;
+	ks_wrreg16(dev, KS_RXQCR, ks->rc_rxqcr);
+
+	/*
+	 * set the force mode to half duplex, default is full duplex
+	 * because if the auto-negotiation fails, most switch uses
+	 * half-duplex.
+	 */
+	w = ks_rdreg16(dev, KS_P1MBCR);
+	w &= ~P1MBCR_FORCE_FDX;
+	ks_wrreg16(dev, KS_P1MBCR, w);
+
+	w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP;
+	ks_wrreg16(dev, KS_TXCR, w);
+
+	w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME | RXCR1_RXIPFCC;
+
+	/* Normal mode */
+	w |= RXCR1_RXPAFMA;
+
+	ks_wrreg16(dev, KS_RXCR1, w);
+}
+
+static void ks_setup_int(struct eth_device *dev)
+{
+	ks->rc_ier = 0x00;
+
+	/* Clear the interrupts status of the hardware. */
+	ks_wrreg16(dev, KS_ISR, 0xffff);
+
+	/* Enables the interrupts of the hardware. */
+	ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI);
+}
+
+static int ks8851_mll_detect_chip(struct eth_device *dev)
+{
+	unsigned short val, i;
+
+	ks_read_config(dev);
+
+	val = ks_rdreg16(dev, KS_CIDER);
+
+	if (val == 0xffff) {
+		/* Special case -- no chip present */
+		printf(DRIVERNAME ":  is chip mounted ?\n");
+		return -1;
+	} else if ((val & 0xfff0) != CIDER_ID) {
+		printf(DRIVERNAME ": Invalid chip id 0x%04x\n", val);
+		return -1;
+	}
+
+	debug("Read back KS8851 id 0x%x\n", val);
+
+	/* only one entry in the table */
+	val &= 0xfff0;
+	for (i = 0; chip_ids[i].id != 0; i++) {
+		if (chip_ids[i].id == val)
+			break;
+	}
+	if (!chip_ids[i].id) {
+		printf(DRIVERNAME ": Unknown chip ID %04x\n", val);
+		return -1;
+	}
+
+	dev->priv = (void *)&chip_ids[i];
+
+	return 0;
+}
+
+static void ks8851_mll_reset(struct eth_device *dev)
+{
+	/* wake up powermode to normal mode */
+	ks_set_powermode(dev, PMECR_PM_NORMAL);
+	mdelay(1);	/* wait for normal mode to take effect */
+
+	/* Disable interrupt and reset */
+	ks_soft_reset(dev, GRR_GSR);
+
+	/* turn off the IRQs and ack any outstanding */
+	ks_wrreg16(dev, KS_IER, 0x0000);
+	ks_wrreg16(dev, KS_ISR, 0xffff);
+
+	/* shutdown RX/TX QMU */
+	ks_disable_qmu(dev);
+}
+
+static void ks8851_mll_phy_configure(struct eth_device *dev)
+{
+	u16 data;
+
+	ks_setup(dev);
+	ks_setup_int(dev);
+
+	/* Probing the phy */
+	data = ks_rdreg16(dev, KS_OBCR);
+	ks_wrreg16(dev, KS_OBCR, data | OBCR_ODS_16MA);
+
+	debug(DRIVERNAME ": phy initialized\n");
+}
+
+static void ks8851_mll_enable(struct eth_device *dev)
+{
+	ks_wrreg16(dev, KS_ISR, 0xffff);
+	ks_enable_int(dev);
+	ks_enable_qmu(dev);
+}
+
+static int ks8851_mll_init(struct eth_device *dev, bd_t *bd)
+{
+	struct chip_id *id = dev->priv;
+
+	debug(DRIVERNAME ": detected %s controller\n", id->name);
+
+	if (ks_read_selftest(dev)) {
+		printf(DRIVERNAME ": Selftest failed\n");
+		return -1;
+	}
+
+	ks8851_mll_reset(dev);
+
+	/* Configure the PHY, initialize the link state */
+	ks8851_mll_phy_configure(dev);
+
+	/* static allocation of private informations */
+	ks->frame_head_info = fr_h_i;
+
+	/* Turn on Tx + Rx */
+	ks8851_mll_enable(dev);
+
+	return 0;
+}
+
+static void ks_write_qmu(struct eth_device *dev, u8 *pdata, u16 len)
+{
+	/* start header at txb[0] to align txw entries */
+	ks->txh.txw[0] = 0;
+	ks->txh.txw[1] = cpu_to_le16(len);
+
+	/* 1. set sudo-DMA mode */
+	ks_wrreg16(dev, KS_TXFDPR, TXFDPR_TXFPAI);
+	ks_wrreg8(dev, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff);
+	/* 2. write status/lenth info */
+	ks_outblk(dev, ks->txh.txw, 4);
+	/* 3. write pkt data */
+	ks_outblk(dev, (u16 *)pdata, ALIGN(len, 4));
+	/* 4. reset sudo-DMA mode */
+	ks_wrreg8(dev, KS_RXQCR, (ks->rc_rxqcr & ~RXQCR_SDA) & 0xff);
+	/* 5. Enqueue Tx(move the pkt from TX buffer into TXQ) */
+	ks_wrreg16(dev, KS_TXQCR, TXQCR_METFE);
+	/* 6. wait until TXQCR_METFE is auto-cleared */
+	do { } while (ks_rdreg16(dev, KS_TXQCR) & TXQCR_METFE);
+}
+
+static int ks8851_mll_send(struct eth_device *dev, void *packet, int length)
+{
+	u8 *data = (u8 *)packet;
+	u16 tmplen = (u16)length;
+	u16 retv;
+
+	/*
+	 * Extra space are required:
+	 * 4 byte for alignment, 4 for status/length, 4 for CRC
+	 */
+	retv = ks_rdreg16(dev, KS_TXMIR) & 0x1fff;
+	if (retv >= tmplen + 12) {
+		ks_write_qmu(dev, data, tmplen);
+		return 0;
+	} else {
+		printf(DRIVERNAME ": failed to send packet: No buffer\n");
+		return -1;
+	}
+}
+
+static void ks8851_mll_halt(struct eth_device *dev)
+{
+	ks8851_mll_reset(dev);
+}
+
+/*
+ * Maximum receive ring size; that is, the number of packets
+ * we can buffer before overflow happens. Basically, this just
+ * needs to be enough to prevent a packet being discarded while
+ * we are processing the previous one.
+ */
+static int ks8851_mll_recv(struct eth_device *dev)
+{
+	u16 status;
+
+	status = ks_rdreg16(dev, KS_ISR);
+
+	ks_wrreg16(dev, KS_ISR, status);
+
+	if ((status & IRQ_RXI))
+		ks_rcv(dev, (uchar **)NetRxPackets);
+
+	if ((status & IRQ_LDI)) {
+		u16 pmecr = ks_rdreg16(dev, KS_PMECR);
+		pmecr &= ~PMECR_WKEVT_MASK;
+		ks_wrreg16(dev, KS_PMECR, pmecr | PMECR_WKEVT_LINK);
+	}
+
+	return 0;
+}
+
+static int ks8851_mll_write_hwaddr(struct eth_device *dev)
+{
+	u16 addrl, addrm, addrh;
+
+	addrh = (dev->enetaddr[0] << 8) | dev->enetaddr[1];
+	addrm = (dev->enetaddr[2] << 8) | dev->enetaddr[3];
+	addrl = (dev->enetaddr[4] << 8) | dev->enetaddr[5];
+
+	ks_wrreg16(dev, KS_MARH, addrh);
+	ks_wrreg16(dev, KS_MARM, addrm);
+	ks_wrreg16(dev, KS_MARL, addrl);
+
+	return 0;
+}
+
+int ks8851_mll_initialize(u8 dev_num, int base_addr)
+{
+	struct eth_device *dev;
+
+	dev = malloc(sizeof(*dev));
+	if (!dev) {
+		printf("Error: Failed to allocate memory\n");
+		return -1;
+	}
+	memset(dev, 0, sizeof(*dev));
+
+	dev->iobase = base_addr;
+
+	ks = &ks_str;
+
+	/* Try to detect chip. Will fail if not present. */
+	if (ks8851_mll_detect_chip(dev)) {
+		free(dev);
+		return -1;
+	}
+
+	dev->init = ks8851_mll_init;
+	dev->halt = ks8851_mll_halt;
+	dev->send = ks8851_mll_send;
+	dev->recv = ks8851_mll_recv;
+	dev->write_hwaddr = ks8851_mll_write_hwaddr;
+	sprintf(dev->name, "%s-%hu", DRIVERNAME, dev_num);
+
+	eth_register(dev);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/ks8851_mll.h b/marvell/uboot/drivers/net/ks8851_mll.h
new file mode 100644
index 0000000..7f90ae4
--- /dev/null
+++ b/marvell/uboot/drivers/net/ks8851_mll.h
@@ -0,0 +1,357 @@
+/*
+ * drivers/net/ks8851_mll.c
+ *
+ * Supports:
+ * KS8851 16bit MLL chip from Micrel Inc.
+ *
+ * Copyright (c) 2009 Micrel Inc.
+ *
+ * modified by
+ * (c) 2011 Bticino s.p.a, Roberto Cerati <roberto.cerati@bticino.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _KS8851_MLL_H_
+#define _KS8851_MLL_H_
+
+#include <linux/types.h>
+
+#define KS_CCR				0x08
+#define CCR_EEPROM			(1 << 9)
+#define CCR_SPI				(1 << 8)
+#define CCR_8BIT			(1 << 7)
+#define CCR_16BIT			(1 << 6)
+#define CCR_32BIT			(1 << 5)
+#define CCR_SHARED			(1 << 4)
+#define CCR_32PIN			(1 << 0)
+
+/* MAC address registers */
+#define KS_MARL				0x10
+#define KS_MARM				0x12
+#define KS_MARH				0x14
+
+#define KS_OBCR				0x20
+#define OBCR_ODS_16MA			(1 << 6)
+
+#define KS_EEPCR			0x22
+#define EEPCR_EESA			(1 << 4)
+#define EEPCR_EESB			(1 << 3)
+#define EEPCR_EEDO			(1 << 2)
+#define EEPCR_EESCK			(1 << 1)
+#define EEPCR_EECS			(1 << 0)
+
+#define KS_MBIR				0x24
+#define MBIR_TXMBF			(1 << 12)
+#define MBIR_TXMBFA			(1 << 11)
+#define MBIR_RXMBF			(1 << 4)
+#define MBIR_RXMBFA			(1 << 3)
+
+#define KS_GRR				0x26
+#define GRR_QMU				(1 << 1)
+#define GRR_GSR				(1 << 0)
+
+#define KS_WFCR				0x2A
+#define WFCR_MPRXE			(1 << 7)
+#define WFCR_WF3E			(1 << 3)
+#define WFCR_WF2E			(1 << 2)
+#define WFCR_WF1E			(1 << 1)
+#define WFCR_WF0E			(1 << 0)
+
+#define KS_WF0CRC0			0x30
+#define KS_WF0CRC1			0x32
+#define KS_WF0BM0			0x34
+#define KS_WF0BM1			0x36
+#define KS_WF0BM2			0x38
+#define KS_WF0BM3			0x3A
+
+#define KS_WF1CRC0			0x40
+#define KS_WF1CRC1			0x42
+#define KS_WF1BM0			0x44
+#define KS_WF1BM1			0x46
+#define KS_WF1BM2			0x48
+#define KS_WF1BM3			0x4A
+
+#define KS_WF2CRC0			0x50
+#define KS_WF2CRC1			0x52
+#define KS_WF2BM0			0x54
+#define KS_WF2BM1			0x56
+#define KS_WF2BM2			0x58
+#define KS_WF2BM3			0x5A
+
+#define KS_WF3CRC0			0x60
+#define KS_WF3CRC1			0x62
+#define KS_WF3BM0			0x64
+#define KS_WF3BM1			0x66
+#define KS_WF3BM2			0x68
+#define KS_WF3BM3			0x6A
+
+#define KS_TXCR				0x70
+#define TXCR_TCGICMP			(1 << 8)
+#define TXCR_TCGUDP			(1 << 7)
+#define TXCR_TCGTCP			(1 << 6)
+#define TXCR_TCGIP			(1 << 5)
+#define TXCR_FTXQ			(1 << 4)
+#define TXCR_TXFCE			(1 << 3)
+#define TXCR_TXPE			(1 << 2)
+#define TXCR_TXCRC			(1 << 1)
+#define TXCR_TXE			(1 << 0)
+
+#define KS_TXSR				0x72
+#define TXSR_TXLC			(1 << 13)
+#define TXSR_TXMC			(1 << 12)
+#define TXSR_TXFID_MASK			(0x3f << 0)
+#define TXSR_TXFID_SHIFT		(0)
+#define TXSR_TXFID_GET(_v)		(((_v) >> 0) & 0x3f)
+
+
+#define KS_RXCR1			0x74
+#define RXCR1_FRXQ			(1 << 15)
+#define RXCR1_RXUDPFCC			(1 << 14)
+#define RXCR1_RXTCPFCC			(1 << 13)
+#define RXCR1_RXIPFCC			(1 << 12)
+#define RXCR1_RXPAFMA			(1 << 11)
+#define RXCR1_RXFCE			(1 << 10)
+#define RXCR1_RXEFE			(1 << 9)
+#define RXCR1_RXMAFMA			(1 << 8)
+#define RXCR1_RXBE			(1 << 7)
+#define RXCR1_RXME			(1 << 6)
+#define RXCR1_RXUE			(1 << 5)
+#define RXCR1_RXAE			(1 << 4)
+#define RXCR1_RXINVF			(1 << 1)
+#define RXCR1_RXE			(1 << 0)
+#define RXCR1_FILTER_MASK		(RXCR1_RXINVF | RXCR1_RXAE | \
+					 RXCR1_RXMAFMA | RXCR1_RXPAFMA)
+
+#define KS_RXCR2			0x76
+#define RXCR2_SRDBL_MASK		(0x7 << 5)
+#define RXCR2_SRDBL_SHIFT		(5)
+#define RXCR2_SRDBL_4B			(0x0 << 5)
+#define RXCR2_SRDBL_8B			(0x1 << 5)
+#define RXCR2_SRDBL_16B			(0x2 << 5)
+#define RXCR2_SRDBL_32B			(0x3 << 5)
+/* #define RXCR2_SRDBL_FRAME		(0x4 << 5) */
+#define RXCR2_IUFFP			(1 << 4)
+#define RXCR2_RXIUFCEZ			(1 << 3)
+#define RXCR2_UDPLFE			(1 << 2)
+#define RXCR2_RXICMPFCC			(1 << 1)
+#define RXCR2_RXSAF			(1 << 0)
+
+#define KS_TXMIR			0x78
+
+#define KS_RXFHSR			0x7C
+#define RXFSHR_RXFV			(1 << 15)
+#define RXFSHR_RXICMPFCS		(1 << 13)
+#define RXFSHR_RXIPFCS			(1 << 12)
+#define RXFSHR_RXTCPFCS			(1 << 11)
+#define RXFSHR_RXUDPFCS			(1 << 10)
+#define RXFSHR_RXBF			(1 << 7)
+#define RXFSHR_RXMF			(1 << 6)
+#define RXFSHR_RXUF			(1 << 5)
+#define RXFSHR_RXMR			(1 << 4)
+#define RXFSHR_RXFT			(1 << 3)
+#define RXFSHR_RXFTL			(1 << 2)
+#define RXFSHR_RXRF			(1 << 1)
+#define RXFSHR_RXCE			(1 << 0)
+#define RXFSHR_ERR			(RXFSHR_RXCE | RXFSHR_RXRF |\
+					RXFSHR_RXFTL | RXFSHR_RXMR |\
+					RXFSHR_RXICMPFCS | RXFSHR_RXIPFCS |\
+					RXFSHR_RXTCPFCS)
+#define KS_RXFHBCR			0x7E
+#define RXFHBCR_CNT_MASK		0x0FFF
+
+#define KS_TXQCR			0x80
+#define TXQCR_AETFE			(1 << 2)
+#define TXQCR_TXQMAM			(1 << 1)
+#define TXQCR_METFE			(1 << 0)
+
+#define KS_RXQCR			0x82
+#define RXQCR_RXDTTS			(1 << 12)
+#define RXQCR_RXDBCTS			(1 << 11)
+#define RXQCR_RXFCTS			(1 << 10)
+#define RXQCR_RXIPHTOE			(1 << 9)
+#define RXQCR_RXDTTE			(1 << 7)
+#define RXQCR_RXDBCTE			(1 << 6)
+#define RXQCR_RXFCTE			(1 << 5)
+#define RXQCR_ADRFE			(1 << 4)
+#define RXQCR_SDA			(1 << 3)
+#define RXQCR_RRXEF			(1 << 0)
+#define RXQCR_CMD_CNTL			(RXQCR_RXFCTE|RXQCR_ADRFE)
+
+#define KS_TXFDPR			0x84
+#define TXFDPR_TXFPAI			(1 << 14)
+#define TXFDPR_TXFP_MASK		(0x7ff << 0)
+#define TXFDPR_TXFP_SHIFT		(0)
+
+#define KS_RXFDPR			0x86
+#define RXFDPR_RXFPAI			(1 << 14)
+
+#define KS_RXDTTR			0x8C
+#define KS_RXDBCTR			0x8E
+
+#define KS_IER				0x90
+#define KS_ISR				0x92
+#define IRQ_LCI				(1 << 15)
+#define IRQ_TXI				(1 << 14)
+#define IRQ_RXI				(1 << 13)
+#define IRQ_RXOI			(1 << 11)
+#define IRQ_TXPSI			(1 << 9)
+#define IRQ_RXPSI			(1 << 8)
+#define IRQ_TXSAI			(1 << 6)
+#define IRQ_RXWFDI			(1 << 5)
+#define IRQ_RXMPDI			(1 << 4)
+#define IRQ_LDI				(1 << 3)
+#define IRQ_EDI				(1 << 2)
+#define IRQ_SPIBEI			(1 << 1)
+#define IRQ_DEDI			(1 << 0)
+
+#define KS_RXFCTR			0x9C
+#define RXFCTR_THRESHOLD_MASK		0x00FF
+
+#define KS_RXFC				0x9D
+#define RXFCTR_RXFC_MASK		(0xff << 8)
+#define RXFCTR_RXFC_SHIFT		(8)
+#define RXFCTR_RXFC_GET(_v)		(((_v) >> 8) & 0xff)
+#define RXFCTR_RXFCT_MASK		(0xff << 0)
+#define RXFCTR_RXFCT_SHIFT		(0)
+
+#define KS_TXNTFSR			0x9E
+
+#define KS_MAHTR0			0xA0
+#define KS_MAHTR1			0xA2
+#define KS_MAHTR2			0xA4
+#define KS_MAHTR3			0xA6
+
+#define KS_FCLWR			0xB0
+#define KS_FCHWR			0xB2
+#define KS_FCOWR			0xB4
+
+#define KS_CIDER			0xC0
+#define CIDER_ID			0x8870
+#define CIDER_REV_MASK			(0x7 << 1)
+#define CIDER_REV_SHIFT			(1)
+#define CIDER_REV_GET(_v)		(((_v) >> 1) & 0x7)
+
+#define KS_CGCR				0xC6
+#define KS_IACR				0xC8
+#define IACR_RDEN			(1 << 12)
+#define IACR_TSEL_MASK			(0x3 << 10)
+#define IACR_TSEL_SHIFT			(10)
+#define IACR_TSEL_MIB			(0x3 << 10)
+#define IACR_ADDR_MASK			(0x1f << 0)
+#define IACR_ADDR_SHIFT			(0)
+
+#define KS_IADLR			0xD0
+#define KS_IAHDR			0xD2
+
+#define KS_PMECR			0xD4
+#define PMECR_PME_DELAY			(1 << 14)
+#define PMECR_PME_POL			(1 << 12)
+#define PMECR_WOL_WAKEUP		(1 << 11)
+#define PMECR_WOL_MAGICPKT		(1 << 10)
+#define PMECR_WOL_LINKUP		(1 << 9)
+#define PMECR_WOL_ENERGY		(1 << 8)
+#define PMECR_AUTO_WAKE_EN		(1 << 7)
+#define PMECR_WAKEUP_NORMAL		(1 << 6)
+#define PMECR_WKEVT_MASK		(0xf << 2)
+#define PMECR_WKEVT_SHIFT		(2)
+#define PMECR_WKEVT_GET(_v)		(((_v) >> 2) & 0xf)
+#define PMECR_WKEVT_ENERGY		(0x1 << 2)
+#define PMECR_WKEVT_LINK		(0x2 << 2)
+#define PMECR_WKEVT_MAGICPKT		(0x4 << 2)
+#define PMECR_WKEVT_FRAME		(0x8 << 2)
+#define PMECR_PM_MASK			(0x3 << 0)
+#define PMECR_PM_SHIFT			(0)
+#define PMECR_PM_NORMAL			(0x0 << 0)
+#define PMECR_PM_ENERGY			(0x1 << 0)
+#define PMECR_PM_SOFTDOWN		(0x2 << 0)
+#define PMECR_PM_POWERSAVE		(0x3 << 0)
+
+/* Standard MII PHY data */
+#define KS_P1MBCR			0xE4
+#define P1MBCR_FORCE_FDX		(1 << 8)
+
+#define KS_P1MBSR			0xE6
+#define P1MBSR_AN_COMPLETE		(1 << 5)
+#define P1MBSR_AN_CAPABLE		(1 << 3)
+#define P1MBSR_LINK_UP			(1 << 2)
+
+#define KS_PHY1ILR			0xE8
+#define KS_PHY1IHR			0xEA
+#define KS_P1ANAR			0xEC
+#define KS_P1ANLPR			0xEE
+
+#define KS_P1SCLMD			0xF4
+#define P1SCLMD_LEDOFF			(1 << 15)
+#define P1SCLMD_TXIDS			(1 << 14)
+#define P1SCLMD_RESTARTAN		(1 << 13)
+#define P1SCLMD_DISAUTOMDIX		(1 << 10)
+#define P1SCLMD_FORCEMDIX		(1 << 9)
+#define P1SCLMD_AUTONEGEN		(1 << 7)
+#define P1SCLMD_FORCE100		(1 << 6)
+#define P1SCLMD_FORCEFDX		(1 << 5)
+#define P1SCLMD_ADV_FLOW		(1 << 4)
+#define P1SCLMD_ADV_100BT_FDX		(1 << 3)
+#define P1SCLMD_ADV_100BT_HDX		(1 << 2)
+#define P1SCLMD_ADV_10BT_FDX		(1 << 1)
+#define P1SCLMD_ADV_10BT_HDX		(1 << 0)
+
+#define KS_P1CR				0xF6
+#define P1CR_HP_MDIX			(1 << 15)
+#define P1CR_REV_POL			(1 << 13)
+#define P1CR_OP_100M			(1 << 10)
+#define P1CR_OP_FDX			(1 << 9)
+#define P1CR_OP_MDI			(1 << 7)
+#define P1CR_AN_DONE			(1 << 6)
+#define P1CR_LINK_GOOD			(1 << 5)
+#define P1CR_PNTR_FLOW			(1 << 4)
+#define P1CR_PNTR_100BT_FDX		(1 << 3)
+#define P1CR_PNTR_100BT_HDX		(1 << 2)
+#define P1CR_PNTR_10BT_FDX		(1 << 1)
+#define P1CR_PNTR_10BT_HDX		(1 << 0)
+
+/* TX Frame control */
+#define TXFR_TXIC			(1 << 15)
+#define TXFR_TXFID_MASK			(0x3f << 0)
+#define TXFR_TXFID_SHIFT		(0)
+
+#define KS_P1SR				0xF8
+#define P1SR_HP_MDIX			(1 << 15)
+#define P1SR_REV_POL			(1 << 13)
+#define P1SR_OP_100M			(1 << 10)
+#define P1SR_OP_FDX			(1 << 9)
+#define P1SR_OP_MDI			(1 << 7)
+#define P1SR_AN_DONE			(1 << 6)
+#define P1SR_LINK_GOOD			(1 << 5)
+#define P1SR_PNTR_FLOW			(1 << 4)
+#define P1SR_PNTR_100BT_FDX		(1 << 3)
+#define P1SR_PNTR_100BT_HDX		(1 << 2)
+#define P1SR_PNTR_10BT_FDX		(1 << 1)
+#define P1SR_PNTR_10BT_HDX		(1 << 0)
+
+#define ENUM_BUS_NONE			0
+#define ENUM_BUS_8BIT			1
+#define ENUM_BUS_16BIT			2
+#define ENUM_BUS_32BIT			3
+
+#define MAX_MCAST_LST			32
+#define HW_MCAST_SIZE			8
+#define MAC_ADDR_LEN			6
+
+/* Chip ID values */
+struct chip_id {
+	u16 id;
+	char *name;
+};
+
+#endif
diff --git a/marvell/uboot/drivers/net/lan91c96.c b/marvell/uboot/drivers/net/lan91c96.c
new file mode 100644
index 0000000..229658a
--- /dev/null
+++ b/marvell/uboot/drivers/net/lan91c96.c
@@ -0,0 +1,804 @@
+/*------------------------------------------------------------------------
+ * lan91c96.c
+ * This is a driver for SMSC's LAN91C96 single-chip Ethernet device, based
+ * on the SMC91111 driver from U-boot.
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Rolf Offermanns <rof@sysgo.de>
+ *
+ * Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
+ *       Developed by Simple Network Magic Corporation (SNMC)
+ * Copyright (C) 1996 by Erik Stahlman (ES)
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Information contained in this file was obtained from the LAN91C96
+ * manual from SMC.  To get a copy, if you really want one, you can find
+ * information under www.smsc.com.
+ *
+ * "Features" of the SMC chip:
+ *   6144 byte packet memory. ( for the 91C96 )
+ *   EEPROM for configuration
+ *   AUI/TP selection  ( mine has 10Base2/10BaseT select )
+ *
+ * Arguments:
+ *	io	= for the base address
+ *	irq	= for the IRQ
+ *
+ * author:
+ *	Erik Stahlman				( erik@vt.edu )
+ *	Daris A Nevil				( dnevil@snmc.com )
+ *
+ *
+ * Hardware multicast code from Peter Cammaert ( pc@denkart.be )
+ *
+ * Sources:
+ *    o   SMSC LAN91C96 databook (www.smsc.com)
+ *    o   smc91111.c (u-boot driver)
+ *    o   smc9194.c (linux kernel driver)
+ *    o   lan91c96.c (Intel Diagnostic Manager driver)
+ *
+ * History:
+ *	04/30/03  Mathijs Haarman	Modified smc91111.c (u-boot version)
+ *					for lan91c96
+ *---------------------------------------------------------------------------
+ */
+
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include "lan91c96.h"
+#include <net.h>
+#include <linux/compiler.h>
+
+/*------------------------------------------------------------------------
+ *
+ * Configuration options, for the experienced user to change.
+ *
+ -------------------------------------------------------------------------*/
+
+/* Use power-down feature of the chip */
+#define POWER_DOWN	0
+
+/*
+ * Wait time for memory to be free.  This probably shouldn't be
+ * tuned that much, as waiting for this means nothing else happens
+ * in the system
+*/
+#define MEMORY_WAIT_TIME 16
+
+#define SMC_DEBUG 0
+
+#if (SMC_DEBUG > 2 )
+#define PRINTK3(args...) printf(args)
+#else
+#define PRINTK3(args...)
+#endif
+
+#if SMC_DEBUG > 1
+#define PRINTK2(args...) printf(args)
+#else
+#define PRINTK2(args...)
+#endif
+
+#ifdef SMC_DEBUG
+#define PRINTK(args...) printf(args)
+#else
+#define PRINTK(args...)
+#endif
+
+
+/*------------------------------------------------------------------------
+ *
+ * The internal workings of the driver.  If you are changing anything
+ * here with the SMC stuff, you should have the datasheet and know
+ * what you are doing.
+ *
+ *------------------------------------------------------------------------
+ */
+#define DRIVER_NAME "LAN91C96"
+#define SMC_ALLOC_MAX_TRY 5
+#define SMC_TX_TIMEOUT 30
+
+#define ETH_ZLEN 60
+
+#ifdef  CONFIG_LAN91C96_USE_32_BIT
+#define USE_32_BIT  1
+#else
+#undef USE_32_BIT
+#endif
+
+/* See if a MAC address is defined in the current environment. If so use it. If not
+ . print a warning and set the environment and other globals with the default.
+ . If an EEPROM is present it really should be consulted.
+*/
+static int smc_get_ethaddr(bd_t *bd, struct eth_device *dev);
+static int get_rom_mac(struct eth_device *dev, unsigned char *v_rom_mac);
+
+/* ------------------------------------------------------------
+ * Internal routines
+ * ------------------------------------------------------------
+ */
+
+static unsigned char smc_mac_addr[] = { 0xc0, 0x00, 0x00, 0x1b, 0x62, 0x9c };
+
+/*
+ * This function must be called before smc_open() if you want to override
+ * the default mac address.
+ */
+
+static void smc_set_mac_addr(const unsigned char *addr)
+{
+	int i;
+
+	for (i = 0; i < sizeof (smc_mac_addr); i++) {
+		smc_mac_addr[i] = addr[i];
+	}
+}
+
+/***********************************************
+ * Show available memory                       *
+ ***********************************************/
+void dump_memory_info(struct eth_device *dev)
+{
+	__maybe_unused word mem_info;
+	word old_bank;
+
+	old_bank = SMC_inw(dev, LAN91C96_BANK_SELECT) & 0xF;
+
+	SMC_SELECT_BANK(dev, 0);
+	mem_info = SMC_inw(dev, LAN91C96_MIR);
+	PRINTK2 ("Memory: %4d available\n", (mem_info >> 8) * 2048);
+
+	SMC_SELECT_BANK(dev, old_bank);
+}
+
+/*
+ * A rather simple routine to print out a packet for debugging purposes.
+ */
+#if SMC_DEBUG > 2
+static void print_packet (byte *, int);
+#endif
+
+static int poll4int (struct eth_device *dev, byte mask, int timeout)
+{
+	int tmo = get_timer (0) + timeout * CONFIG_SYS_HZ;
+	int is_timeout = 0;
+	word old_bank = SMC_inw(dev, LAN91C96_BANK_SELECT);
+
+	PRINTK2 ("Polling...\n");
+	SMC_SELECT_BANK(dev, 2);
+	while ((SMC_inw(dev, LAN91C96_INT_STATS) & mask) == 0) {
+		if (get_timer (0) >= tmo) {
+			is_timeout = 1;
+			break;
+		}
+	}
+
+	/* restore old bank selection */
+	SMC_SELECT_BANK(dev, old_bank);
+
+	if (is_timeout)
+		return 1;
+	else
+		return 0;
+}
+
+/*
+ * Function: smc_reset
+ * Purpose:
+ *	This sets the SMC91111 chip to its normal state, hopefully from whatever
+ *	mess that any other DOS driver has put it in.
+ *
+ * Maybe I should reset more registers to defaults in here?  SOFTRST  should
+ * do that for me.
+ *
+ * Method:
+ *	1.  send a SOFT RESET
+ *	2.  wait for it to finish
+ *	3.  enable autorelease mode
+ *	4.  reset the memory management unit
+ *	5.  clear all interrupts
+ *
+*/
+static void smc_reset(struct eth_device *dev)
+{
+	PRINTK2("%s:smc_reset\n", dev->name);
+
+	/* This resets the registers mostly to defaults, but doesn't
+	   affect EEPROM.  That seems unnecessary */
+	SMC_SELECT_BANK(dev, 0);
+	SMC_outw(dev, LAN91C96_RCR_SOFT_RST, LAN91C96_RCR);
+
+	udelay (10);
+
+	/* Disable transmit and receive functionality */
+	SMC_outw(dev, 0, LAN91C96_RCR);
+	SMC_outw(dev, 0, LAN91C96_TCR);
+
+	/* set the control register */
+	SMC_SELECT_BANK(dev, 1);
+	SMC_outw(dev, SMC_inw(dev, LAN91C96_CONTROL) | LAN91C96_CTR_BIT_8,
+			  LAN91C96_CONTROL);
+
+	/* Disable all interrupts */
+	SMC_outb(dev, 0, LAN91C96_INT_MASK);
+}
+
+/*
+ * Function: smc_enable
+ * Purpose: let the chip talk to the outside work
+ * Method:
+ *	1.  Initialize the Memory Configuration Register
+ *	2.  Enable the transmitter
+ *	3.  Enable the receiver
+*/
+static void smc_enable(struct eth_device *dev)
+{
+	PRINTK2("%s:smc_enable\n", dev->name);
+	SMC_SELECT_BANK(dev, 0);
+
+	/* Initialize the Memory Configuration Register. See page
+	   49 of the LAN91C96 data sheet for details. */
+	SMC_outw(dev, LAN91C96_MCR_TRANSMIT_PAGES, LAN91C96_MCR);
+
+	/* Initialize the Transmit Control Register */
+	SMC_outw(dev, LAN91C96_TCR_TXENA, LAN91C96_TCR);
+	/* Initialize the Receive Control Register
+	 * FIXME:
+	 * The promiscuous bit set because I could not receive ARP reply
+	 * packets from the server when I send a ARP request. It only works
+	 * when I set the promiscuous bit
+	 */
+	SMC_outw(dev, LAN91C96_RCR_RXEN | LAN91C96_RCR_PRMS, LAN91C96_RCR);
+}
+
+/*
+ * Function: smc_shutdown
+ * Purpose:  closes down the SMC91xxx chip.
+ * Method:
+ *	1. zero the interrupt mask
+ *	2. clear the enable receive flag
+ *	3. clear the enable xmit flags
+ *
+ * TODO:
+ *   (1) maybe utilize power down mode.
+ *	Why not yet?  Because while the chip will go into power down mode,
+ *	the manual says that it will wake up in response to any I/O requests
+ *	in the register space.   Empirical results do not show this working.
+ */
+static void smc_shutdown(struct eth_device *dev)
+{
+	PRINTK2("%s:smc_shutdown\n", dev->name);
+
+	/* no more interrupts for me */
+	SMC_SELECT_BANK(dev, 2);
+	SMC_outb(dev, 0, LAN91C96_INT_MASK);
+
+	/* and tell the card to stay away from that nasty outside world */
+	SMC_SELECT_BANK(dev, 0);
+	SMC_outb(dev, 0, LAN91C96_RCR);
+	SMC_outb(dev, 0, LAN91C96_TCR);
+}
+
+
+/*
+ * Function:  smc_hardware_send_packet(struct net_device * )
+ * Purpose:
+ *	This sends the actual packet to the SMC9xxx chip.
+ *
+ * Algorithm:
+ *	First, see if a saved_skb is available.
+ *		( this should NOT be called if there is no 'saved_skb'
+ *	Now, find the packet number that the chip allocated
+ *	Point the data pointers at it in memory
+ *	Set the length word in the chip's memory
+ *	Dump the packet to chip memory
+ *	Check if a last byte is needed ( odd length packet )
+ *		if so, set the control flag right
+ *	Tell the card to send it
+ *	Enable the transmit interrupt, so I know if it failed
+ *	Free the kernel data if I actually sent it.
+ */
+static int smc_send_packet(struct eth_device *dev, void *packet,
+		int packet_length)
+{
+	byte packet_no;
+	byte *buf;
+	int length;
+	int numPages;
+	int try = 0;
+	int time_out;
+	byte status;
+
+
+	PRINTK3("%s:smc_hardware_send_packet\n", dev->name);
+
+	length = ETH_ZLEN < packet_length ? packet_length : ETH_ZLEN;
+
+	/* allocate memory
+	 ** The MMU wants the number of pages to be the number of 256 bytes
+	 ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
+	 **
+	 ** The 91C111 ignores the size bits, but the code is left intact
+	 ** for backwards and future compatibility.
+	 **
+	 ** Pkt size for allocating is data length +6 (for additional status
+	 ** words, length and ctl!)
+	 **
+	 ** If odd size then last byte is included in this header.
+	 */
+	numPages = ((length & 0xfffe) + 6);
+	numPages >>= 8;				/* Divide by 256 */
+
+	if (numPages > 7) {
+		printf("%s: Far too big packet error. \n", dev->name);
+		return 0;
+	}
+
+	/* now, try to allocate the memory */
+
+	SMC_SELECT_BANK(dev, 2);
+	SMC_outw(dev, LAN91C96_MMUCR_ALLOC_TX | numPages, LAN91C96_MMU);
+
+  again:
+	try++;
+	time_out = MEMORY_WAIT_TIME;
+	do {
+		status = SMC_inb(dev, LAN91C96_INT_STATS);
+		if (status & LAN91C96_IST_ALLOC_INT) {
+
+			SMC_outb(dev, LAN91C96_IST_ALLOC_INT,
+					LAN91C96_INT_STATS);
+			break;
+		}
+	} while (--time_out);
+
+	if (!time_out) {
+		PRINTK2 ("%s: memory allocation, try %d failed ...\n",
+				 dev->name, try);
+		if (try < SMC_ALLOC_MAX_TRY)
+			goto again;
+		else
+			return 0;
+	}
+
+	PRINTK2 ("%s: memory allocation, try %d succeeded ...\n",
+			 dev->name, try);
+
+	/* I can send the packet now.. */
+	buf = (byte *) packet;
+
+	/* If I get here, I _know_ there is a packet slot waiting for me */
+	packet_no = SMC_inb(dev, LAN91C96_ARR);
+	if (packet_no & LAN91C96_ARR_FAILED) {
+		/* or isn't there?  BAD CHIP! */
+		printf("%s: Memory allocation failed. \n", dev->name);
+		return 0;
+	}
+
+	/* we have a packet address, so tell the card to use it */
+	SMC_outb(dev, packet_no, LAN91C96_PNR);
+
+	/* point to the beginning of the packet */
+	SMC_outw(dev, LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER);
+
+	PRINTK3("%s: Trying to xmit packet of length %x\n",
+			 dev->name, length);
+
+#if SMC_DEBUG > 2
+	printf ("Transmitting Packet\n");
+	print_packet (buf, length);
+#endif
+
+	/* send the packet length ( +6 for status, length and ctl byte )
+	   and the status word ( set to zeros ) */
+#ifdef USE_32_BIT
+	SMC_outl(dev, (length + 6) << 16, LAN91C96_DATA_HIGH);
+#else
+	SMC_outw(dev, 0, LAN91C96_DATA_HIGH);
+	/* send the packet length ( +6 for status words, length, and ctl */
+	SMC_outw(dev, (length + 6), LAN91C96_DATA_HIGH);
+#endif /* USE_32_BIT */
+
+	/* send the actual data
+	 * I _think_ it's faster to send the longs first, and then
+	 * mop up by sending the last word.  It depends heavily
+	 * on alignment, at least on the 486.  Maybe it would be
+	 * a good idea to check which is optimal?  But that could take
+	 * almost as much time as is saved?
+	 */
+#ifdef USE_32_BIT
+	SMC_outsl(dev, LAN91C96_DATA_HIGH, buf, length >> 2);
+	if (length & 0x2)
+		SMC_outw(dev, *((word *) (buf + (length & 0xFFFFFFFC))),
+				  LAN91C96_DATA_HIGH);
+#else
+	SMC_outsw(dev, LAN91C96_DATA_HIGH, buf, (length) >> 1);
+#endif /* USE_32_BIT */
+
+	/* Send the last byte, if there is one.   */
+	if ((length & 1) == 0) {
+		SMC_outw(dev, 0, LAN91C96_DATA_HIGH);
+	} else {
+		SMC_outw(dev, buf[length - 1] | 0x2000, LAN91C96_DATA_HIGH);
+	}
+
+	/* and let the chipset deal with it */
+	SMC_outw(dev, LAN91C96_MMUCR_ENQUEUE, LAN91C96_MMU);
+
+	/* poll for TX INT */
+	if (poll4int (dev, LAN91C96_MSK_TX_INT, SMC_TX_TIMEOUT)) {
+		/* sending failed */
+		PRINTK2("%s: TX timeout, sending failed...\n", dev->name);
+
+		/* release packet */
+		SMC_outw(dev, LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
+
+		/* wait for MMU getting ready (low) */
+		while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
+			udelay (10);
+
+		PRINTK2("MMU ready\n");
+
+
+		return 0;
+	} else {
+		/* ack. int */
+		SMC_outw(dev, LAN91C96_IST_TX_INT, LAN91C96_INT_STATS);
+
+		PRINTK2("%s: Sent packet of length %d \n", dev->name, length);
+
+		/* release packet */
+		SMC_outw(dev, LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
+
+		/* wait for MMU getting ready (low) */
+		while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
+			udelay (10);
+
+		PRINTK2 ("MMU ready\n");
+	}
+
+	return length;
+}
+
+
+/*
+ * Open and Initialize the board
+ *
+ * Set up everything, reset the card, etc ..
+ *
+ */
+static int smc_open(bd_t *bd, struct eth_device *dev)
+{
+	int i, err;			/* used to set hw ethernet address */
+
+	PRINTK2("%s:smc_open\n", dev->name);
+
+	/* reset the hardware */
+
+	smc_reset(dev);
+	smc_enable(dev);
+
+	SMC_SELECT_BANK(dev, 1);
+	/* set smc_mac_addr, and sync it with u-boot globals */
+	err = smc_get_ethaddr(bd, dev);
+	if (err < 0)
+		return -1;
+#ifdef USE_32_BIT
+	for (i = 0; i < 6; i += 2) {
+		word address;
+
+		address = smc_mac_addr[i + 1] << 8;
+		address |= smc_mac_addr[i];
+		SMC_outw(dev, address, LAN91C96_IA0 + i);
+	}
+#else
+	for (i = 0; i < 6; i++)
+		SMC_outb(dev, smc_mac_addr[i], LAN91C96_IA0 + i);
+#endif
+	return 0;
+}
+
+/*-------------------------------------------------------------
+ *
+ * smc_rcv -  receive a packet from the card
+ *
+ * There is ( at least ) a packet waiting to be read from
+ * chip-memory.
+ *
+ * o Read the status
+ * o If an error, record it
+ * o otherwise, read in the packet
+ *-------------------------------------------------------------
+ */
+static int smc_rcv(struct eth_device *dev)
+{
+	int packet_number;
+	word status;
+	word packet_length;
+	int is_error = 0;
+
+#ifdef USE_32_BIT
+	dword stat_len;
+#endif
+
+
+	SMC_SELECT_BANK(dev, 2);
+	packet_number = SMC_inw(dev, LAN91C96_FIFO);
+
+	if (packet_number & LAN91C96_FIFO_RXEMPTY) {
+		return 0;
+	}
+
+	PRINTK3("%s:smc_rcv\n", dev->name);
+	/*  start reading from the start of the packet */
+	SMC_outw(dev, LAN91C96_PTR_READ | LAN91C96_PTR_RCV |
+			  LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER);
+
+	/* First two words are status and packet_length */
+#ifdef USE_32_BIT
+	stat_len = SMC_inl(dev, LAN91C96_DATA_HIGH);
+	status = stat_len & 0xffff;
+	packet_length = stat_len >> 16;
+#else
+	status = SMC_inw(dev, LAN91C96_DATA_HIGH);
+	packet_length = SMC_inw(dev, LAN91C96_DATA_HIGH);
+#endif
+
+	packet_length &= 0x07ff;	/* mask off top bits */
+
+	PRINTK2 ("RCV: STATUS %4x LENGTH %4x\n", status, packet_length);
+
+	if (!(status & FRAME_FILTER)) {
+		/* Adjust for having already read the first two words */
+		packet_length -= 4;		/*4; */
+
+
+		/* set odd length for bug in LAN91C111, */
+		/* which never sets RS_ODDFRAME */
+		/* TODO ? */
+
+
+#ifdef USE_32_BIT
+		PRINTK3 (" Reading %d dwords (and %d bytes) \n",
+			 packet_length >> 2, packet_length & 3);
+		/* QUESTION:  Like in the TX routine, do I want
+		   to send the DWORDs or the bytes first, or some
+		   mixture.  A mixture might improve already slow PIO
+		   performance  */
+		SMC_insl(dev, LAN91C96_DATA_HIGH, NetRxPackets[0],
+				packet_length >> 2);
+		/* read the left over bytes */
+		if (packet_length & 3) {
+			int i;
+
+			byte *tail = (byte *) (NetRxPackets[0] + (packet_length & ~3));
+			dword leftover = SMC_inl(dev, LAN91C96_DATA_HIGH);
+
+			for (i = 0; i < (packet_length & 3); i++)
+				*tail++ = (byte) (leftover >> (8 * i)) & 0xff;
+		}
+#else
+		PRINTK3 (" Reading %d words and %d byte(s) \n",
+				 (packet_length >> 1), packet_length & 1);
+		SMC_insw(dev, LAN91C96_DATA_HIGH, NetRxPackets[0],
+				packet_length >> 1);
+
+#endif /* USE_32_BIT */
+
+#if	SMC_DEBUG > 2
+		printf ("Receiving Packet\n");
+		print_packet((byte *)NetRxPackets[0], packet_length);
+#endif
+	} else {
+		/* error ... */
+		/* TODO ? */
+		is_error = 1;
+	}
+
+	while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
+		udelay (1);		/* Wait until not busy */
+
+	/*  error or good, tell the card to get rid of this packet */
+	SMC_outw(dev, LAN91C96_MMUCR_RELEASE_RX, LAN91C96_MMU);
+
+	while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
+		udelay (1);		/* Wait until not busy */
+
+	if (!is_error) {
+		/* Pass the packet up to the protocol layers. */
+		NetReceive (NetRxPackets[0], packet_length);
+		return packet_length;
+	} else {
+		return 0;
+	}
+
+}
+
+/*----------------------------------------------------
+ * smc_close
+ *
+ * this makes the board clean up everything that it can
+ * and not talk to the outside world.   Caused by
+ * an 'ifconfig ethX down'
+ *
+ -----------------------------------------------------*/
+static int smc_close(struct eth_device *dev)
+{
+	PRINTK2("%s:smc_close\n", dev->name);
+
+	/* clear everything */
+	smc_shutdown(dev);
+
+	return 0;
+}
+
+#if SMC_DEBUG > 2
+static void print_packet(byte *buf, int length)
+{
+#if 0
+	int i;
+	int remainder;
+	int lines;
+
+	printf ("Packet of length %d \n", length);
+
+	lines = length / 16;
+	remainder = length % 16;
+
+	for (i = 0; i < lines; i++) {
+		int cur;
+
+		for (cur = 0; cur < 8; cur++) {
+			byte a, b;
+
+			a = *(buf++);
+			b = *(buf++);
+			printf ("%02x%02x ", a, b);
+		}
+		printf ("\n");
+	}
+	for (i = 0; i < remainder / 2; i++) {
+		byte a, b;
+
+		a = *(buf++);
+		b = *(buf++);
+		printf ("%02x%02x ", a, b);
+	}
+	printf ("\n");
+#endif /* 0 */
+}
+#endif /* SMC_DEBUG > 2 */
+
+static int  lan91c96_init(struct eth_device *dev, bd_t *bd)
+{
+	return smc_open(bd, dev);
+}
+
+static void lan91c96_halt(struct eth_device *dev)
+{
+	smc_close(dev);
+}
+
+static int lan91c96_recv(struct eth_device *dev)
+{
+	return smc_rcv(dev);
+}
+
+static int lan91c96_send(struct eth_device *dev, void *packet,
+		int length)
+{
+	return smc_send_packet(dev, packet, length);
+}
+
+/* smc_get_ethaddr
+ *
+ * This checks both the environment and the ROM for an ethernet address. If
+ * found, the environment takes precedence.
+ */
+
+static int smc_get_ethaddr(bd_t *bd, struct eth_device *dev)
+{
+	uchar v_mac[6];
+
+	if (!eth_getenv_enetaddr("ethaddr", v_mac)) {
+		/* get ROM mac value if any */
+		if (!get_rom_mac(dev, v_mac)) {
+			printf("\n*** ERROR: ethaddr is NOT set !!\n");
+			return -1;
+		}
+		eth_setenv_enetaddr("ethaddr", v_mac);
+	}
+
+	smc_set_mac_addr(v_mac); /* use old function to update smc default */
+	PRINTK("Using MAC Address %pM\n", v_mac);
+	return 0;
+}
+
+/*
+ * get_rom_mac()
+ * Note, this has omly been tested for the OMAP730 P2.
+ */
+
+static int get_rom_mac(struct eth_device *dev, unsigned char *v_rom_mac)
+{
+#ifdef HARDCODE_MAC	/* used for testing or to supress run time warnings */
+	char hw_mac_addr[] = { 0x02, 0x80, 0xad, 0x20, 0x31, 0xb8 };
+
+	memcpy (v_rom_mac, hw_mac_addr, 6);
+	return (1);
+#else
+	int i;
+	SMC_SELECT_BANK(dev, 1);
+	for (i=0; i<6; i++)
+	{
+		v_rom_mac[i] = SMC_inb(dev, LAN91C96_IA0 + i);
+	}
+	return (1);
+#endif
+}
+
+/* Structure to detect the device IDs */
+struct id_type {
+	u8 id;
+	char *name;
+};
+static struct id_type supported_chips[] = {
+	{0, ""}, /* Dummy entry to prevent id check failure */
+	{9, "LAN91C110"},
+	{8, "LAN91C100FD"},
+	{7, "LAN91C100"},
+	{5, "LAN91C95"},
+	{4, "LAN91C94/96"},
+	{3, "LAN91C90/92"},
+};
+/* lan91c96_detect_chip
+ * See:
+ * http://www.embeddedsys.com/subpages/resources/images/documents/LAN91C96_datasheet.pdf
+ * page 71 - that is the closest we get to detect this device
+ */
+static int lan91c96_detect_chip(struct eth_device *dev)
+{
+	u8 chip_id;
+	int r;
+	SMC_SELECT_BANK(dev, 3);
+	chip_id = (SMC_inw(dev, 0xA) & LAN91C96_REV_CHIPID) >> 4;
+	SMC_SELECT_BANK(dev, 0);
+	for (r = 0; r < ARRAY_SIZE(supported_chips); r++)
+		if (chip_id == supported_chips[r].id)
+			return r;
+	return 0;
+}
+
+int lan91c96_initialize(u8 dev_num, int base_addr)
+{
+	struct eth_device *dev;
+	int r = 0;
+
+	dev = malloc(sizeof(*dev));
+	if (!dev) {
+		return 0;
+	}
+	memset(dev, 0, sizeof(*dev));
+
+	dev->iobase = base_addr;
+
+	/* Try to detect chip. Will fail if not present. */
+	r = lan91c96_detect_chip(dev);
+	if (!r) {
+		free(dev);
+		return 0;
+	}
+	get_rom_mac(dev, dev->enetaddr);
+
+	dev->init = lan91c96_init;
+	dev->halt = lan91c96_halt;
+	dev->send = lan91c96_send;
+	dev->recv = lan91c96_recv;
+	sprintf(dev->name, "%s-%hu", supported_chips[r].name, dev_num);
+
+	eth_register(dev);
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/lan91c96.h b/marvell/uboot/drivers/net/lan91c96.h
new file mode 100644
index 0000000..2f0d640
--- /dev/null
+++ b/marvell/uboot/drivers/net/lan91c96.h
@@ -0,0 +1,623 @@
+/*------------------------------------------------------------------------
+ * lan91c96.h
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Rolf Offermanns <rof@sysgo.de>
+ * Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
+ *       Developed by Simple Network Magic Corporation (SNMC)
+ * Copyright (C) 1996 by Erik Stahlman (ES)
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * This file contains register information and access macros for
+ * the LAN91C96 single chip ethernet controller.  It is a modified
+ * version of the smc9111.h file.
+ *
+ * Information contained in this file was obtained from the LAN91C96
+ * manual from SMC. To get a copy, if you really want one, you can find
+ * information under www.smsc.com.
+ *
+ * Authors
+ *	Erik Stahlman				( erik@vt.edu )
+ *	Daris A Nevil				( dnevil@snmc.com )
+ *
+ * History
+ * 04/30/03	Mathijs Haarman		Modified smc91111.h (u-boot version)
+ *		                        for lan91c96
+ *-------------------------------------------------------------------------
+ */
+#ifndef _LAN91C96_H_
+#define _LAN91C96_H_
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <config.h>
+
+/* I want some simple types */
+
+typedef unsigned char			byte;
+typedef unsigned short			word;
+typedef unsigned long int		dword;
+
+/*
+ * DEBUGGING LEVELS
+ *
+ * 0 for normal operation
+ * 1 for slightly more details
+ * >2 for various levels of increasingly useless information
+ *    2 for interrupt tracking, status flags
+ *    3 for packet info
+ *    4 for complete packet dumps
+ */
+/*#define SMC_DEBUG 0 */
+
+/* Because of bank switching, the LAN91xxx uses only 16 I/O ports */
+
+#define	SMC_IO_EXTENT	16
+
+#ifdef CONFIG_CPU_PXA25X
+
+#ifdef	CONFIG_LUBBOCK
+#define	SMC_IO_SHIFT	2
+#undef	USE_32_BIT
+
+#else
+#define	SMC_IO_SHIFT	0
+#endif
+
+#define	SMCREG(edev, r)	((edev)->iobase+((r)<<SMC_IO_SHIFT))
+
+#define	SMC_inl(edev, r)	(*((volatile dword *)SMCREG(edev, r)))
+#define	SMC_inw(edev, r)	(*((volatile word *)SMCREG(edev, r)))
+#define SMC_inb(edev, p) ({ \
+	unsigned int __p = p; \
+	unsigned int __v = SMC_inw(edev, __p & ~1); \
+	if (__p & 1) __v >>= 8; \
+	else __v &= 0xff; \
+	__v; })
+
+#define	SMC_outl(edev, d, r)	(*((volatile dword *)SMCREG(edev, r)) = d)
+#define	SMC_outw(edev, d, r)	(*((volatile word *)SMCREG(edev, r)) = d)
+#define	SMC_outb(edev, d, r)	({	word __d = (byte)(d);  \
+				word __w = SMC_inw(edev, (r)&~1);  \
+				__w &= ((r)&1) ? 0x00FF : 0xFF00;  \
+				__w |= ((r)&1) ? __d<<8 : __d;  \
+				SMC_outw(edev, __w, (r)&~1);  \
+			})
+
+#define SMC_outsl(edev, r, b, l)	({	int __i; \
+					dword *__b2; \
+					__b2 = (dword *) b; \
+					for (__i = 0; __i < l; __i++) { \
+						SMC_outl(edev, *(__b2 + __i),\
+							r); \
+					} \
+				})
+
+#define SMC_outsw(edev, r, b, l)	({	int __i; \
+					word *__b2; \
+					__b2 = (word *) b; \
+					for (__i = 0; __i < l; __i++) { \
+						SMC_outw(edev, *(__b2 + __i),\
+							r); \
+					} \
+				})
+
+#define SMC_insl(edev, r, b, l)		({	int __i ;  \
+					dword *__b2;  \
+					__b2 = (dword *) b;  \
+					for (__i = 0; __i < l; __i++) {  \
+						*(__b2 + __i) = SMC_inl(edev,\
+							r);  \
+						SMC_inl(edev, 0);  \
+					};  \
+				})
+
+#define SMC_insw(edev, r, b, l)		({	int __i ;  \
+					word *__b2;  \
+					__b2 = (word *) b;  \
+					for (__i = 0; __i < l; __i++) {  \
+						*(__b2 + __i) = SMC_inw(edev,\
+							r);  \
+						SMC_inw(edev, 0);  \
+					};  \
+				})
+
+#define SMC_insb(edev, r, b, l)		({	int __i ;  \
+					byte *__b2;  \
+					__b2 = (byte *) b;  \
+					for (__i = 0; __i < l; __i++) {  \
+						*(__b2 + __i) = SMC_inb(edev,\
+							r);  \
+						SMC_inb(edev, 0);  \
+					};  \
+				})
+
+#else /* if not CONFIG_CPU_PXA25X */
+
+/*
+ * We have only 16 Bit PCMCIA access on Socket 0
+ */
+
+#define	SMC_inw(edev, r)	(*((volatile word *)((edev)->iobase+(r))))
+#define  SMC_inb(edev, r)	(((r)&1) ? SMC_inw(edev, (r)&~1)>>8 :\
+					SMC_inw(edev, r)&0xFF)
+
+#define	SMC_outw(edev, d, r)	(*((volatile word *)((edev)->iobase+(r))) = d)
+#define	SMC_outb(edev, d, r)	({	word __d = (byte)(d);  \
+				word __w = SMC_inw(edev, (r)&~1);  \
+				__w &= ((r)&1) ? 0x00FF : 0xFF00;  \
+				__w |= ((r)&1) ? __d<<8 : __d;  \
+				SMC_outw(edev, __w, (r)&~1);  \
+			})
+#define SMC_outsw(edev, r, b, l)	({	int __i; \
+					word *__b2; \
+					__b2 = (word *) b; \
+					for (__i = 0; __i < l; __i++) { \
+						SMC_outw(edev, *(__b2 + __i),\
+							r); \
+					} \
+				})
+
+#define SMC_insw(edev, r, b, l)	({	int __i ;  \
+					word *__b2;  \
+					__b2 = (word *) b;  \
+					for (__i = 0; __i < l; __i++) {  \
+						*(__b2 + __i) = SMC_inw(edev,\
+							r);  \
+						SMC_inw(edev, 0);  \
+					};  \
+				})
+
+#endif
+
+/*
+ ****************************************************************************
+ *	Bank Select Field
+ ****************************************************************************
+ */
+#define LAN91C96_BANK_SELECT  14       /* Bank Select Register */
+#define LAN91C96_BANKSELECT (0x3UC << 0)
+#define BANK0               0x00
+#define BANK1               0x01
+#define BANK2               0x02
+#define BANK3               0x03
+#define BANK4               0x04
+
+/*
+ ****************************************************************************
+ *	EEPROM Addresses.
+ ****************************************************************************
+ */
+#define EEPROM_MAC_OFFSET_1    0x6020
+#define EEPROM_MAC_OFFSET_2    0x6021
+#define EEPROM_MAC_OFFSET_3    0x6022
+
+/*
+ ****************************************************************************
+ *	Bank 0 Register Map in I/O Space
+ ****************************************************************************
+ */
+#define LAN91C96_TCR          0        /* Transmit Control Register */
+#define LAN91C96_EPH_STATUS   2        /* EPH Status Register */
+#define LAN91C96_RCR          4        /* Receive Control Register */
+#define LAN91C96_COUNTER      6        /* Counter Register */
+#define LAN91C96_MIR          8        /* Memory Information Register */
+#define LAN91C96_MCR          10       /* Memory Configuration Register */
+
+/*
+ ****************************************************************************
+ *	Transmit Control Register - Bank 0 - Offset 0
+ ****************************************************************************
+ */
+#define LAN91C96_TCR_TXENA        (0x1U << 0)
+#define LAN91C96_TCR_LOOP         (0x1U << 1)
+#define LAN91C96_TCR_FORCOL       (0x1U << 2)
+#define LAN91C96_TCR_TXP_EN       (0x1U << 3)
+#define LAN91C96_TCR_PAD_EN       (0x1U << 7)
+#define LAN91C96_TCR_NOCRC        (0x1U << 8)
+#define LAN91C96_TCR_MON_CSN      (0x1U << 10)
+#define LAN91C96_TCR_FDUPLX       (0x1U << 11)
+#define LAN91C96_TCR_STP_SQET     (0x1U << 12)
+#define LAN91C96_TCR_EPH_LOOP     (0x1U << 13)
+#define LAN91C96_TCR_ETEN_TYPE    (0x1U << 14)
+#define LAN91C96_TCR_FDSE         (0x1U << 15)
+
+/*
+ ****************************************************************************
+ *	EPH Status Register - Bank 0 - Offset 2
+ ****************************************************************************
+ */
+#define LAN91C96_EPHSR_TX_SUC     (0x1U << 0)
+#define LAN91C96_EPHSR_SNGL_COL   (0x1U << 1)
+#define LAN91C96_EPHSR_MUL_COL    (0x1U << 2)
+#define LAN91C96_EPHSR_LTX_MULT   (0x1U << 3)
+#define LAN91C96_EPHSR_16COL      (0x1U << 4)
+#define LAN91C96_EPHSR_SQET       (0x1U << 5)
+#define LAN91C96_EPHSR_LTX_BRD    (0x1U << 6)
+#define LAN91C96_EPHSR_TX_DEFR    (0x1U << 7)
+#define LAN91C96_EPHSR_WAKEUP     (0x1U << 8)
+#define LAN91C96_EPHSR_LATCOL     (0x1U << 9)
+#define LAN91C96_EPHSR_LOST_CARR  (0x1U << 10)
+#define LAN91C96_EPHSR_EXC_DEF    (0x1U << 11)
+#define LAN91C96_EPHSR_CTR_ROL    (0x1U << 12)
+
+#define LAN91C96_EPHSR_LINK_OK    (0x1U << 14)
+#define LAN91C96_EPHSR_TX_UNRN    (0x1U << 15)
+
+#define LAN91C96_EPHSR_ERRORS     (LAN91C96_EPHSR_SNGL_COL  |    \
+				   LAN91C96_EPHSR_MUL_COL   |    \
+				   LAN91C96_EPHSR_16COL     |    \
+				   LAN91C96_EPHSR_SQET      |    \
+				   LAN91C96_EPHSR_TX_DEFR   |    \
+				   LAN91C96_EPHSR_LATCOL    |    \
+				   LAN91C96_EPHSR_LOST_CARR |    \
+				   LAN91C96_EPHSR_EXC_DEF   |    \
+				   LAN91C96_EPHSR_LINK_OK   |    \
+				   LAN91C96_EPHSR_TX_UNRN)
+
+/*
+ ****************************************************************************
+ *	Receive Control Register - Bank 0 - Offset 4
+ ****************************************************************************
+ */
+#define LAN91C96_RCR_RX_ABORT     (0x1U << 0)
+#define LAN91C96_RCR_PRMS         (0x1U << 1)
+#define LAN91C96_RCR_ALMUL        (0x1U << 2)
+#define LAN91C96_RCR_RXEN         (0x1U << 8)
+#define LAN91C96_RCR_STRIP_CRC    (0x1U << 9)
+#define LAN91C96_RCR_FILT_CAR     (0x1U << 14)
+#define LAN91C96_RCR_SOFT_RST     (0x1U << 15)
+
+/*
+ ****************************************************************************
+ *	Counter Register - Bank 0 - Offset 6
+ ****************************************************************************
+ */
+#define LAN91C96_ECR_SNGL_COL     (0xFU << 0)
+#define LAN91C96_ECR_MULT_COL     (0xFU << 5)
+#define LAN91C96_ECR_DEF_TX       (0xFU << 8)
+#define LAN91C96_ECR_EXC_DEF_TX   (0xFU << 12)
+
+/*
+ ****************************************************************************
+ *	Memory Information Register - Bank 0 - OFfset 8
+ ****************************************************************************
+ */
+#define LAN91C96_MIR_SIZE        (0x18 << 0)    /* 6144 bytes */
+
+/*
+ ****************************************************************************
+ *	Memory Configuration Register - Bank 0 - Offset 10
+ ****************************************************************************
+ */
+#define LAN91C96_MCR_MEM_RES      (0xFFU << 0)
+#define LAN91C96_MCR_MEM_MULT     (0x3U << 9)
+#define LAN91C96_MCR_HIGH_ID      (0x3U << 12)
+
+#define LAN91C96_MCR_TRANSMIT_PAGES 0x6
+
+/*
+ ****************************************************************************
+ *	Bank 1 Register Map in I/O Space
+ ****************************************************************************
+ */
+#define LAN91C96_CONFIG       0        /* Configuration Register */
+#define LAN91C96_BASE         2        /* Base Address Register */
+#define LAN91C96_IA0          4        /* Individual Address Register - 0 */
+#define LAN91C96_IA1          5        /* Individual Address Register - 1 */
+#define LAN91C96_IA2          6        /* Individual Address Register - 2 */
+#define LAN91C96_IA3          7        /* Individual Address Register - 3 */
+#define LAN91C96_IA4          8        /* Individual Address Register - 4 */
+#define LAN91C96_IA5          9        /* Individual Address Register - 5 */
+#define LAN91C96_GEN_PURPOSE  10       /* General Address Registers */
+#define LAN91C96_CONTROL      12       /* Control Register */
+
+/*
+ ****************************************************************************
+ *	Configuration Register - Bank 1 - Offset 0
+ ****************************************************************************
+ */
+#define LAN91C96_CR_INT_SEL0      (0x1U << 1)
+#define LAN91C96_CR_INT_SEL1      (0x1U << 2)
+#define LAN91C96_CR_RES           (0x3U << 3)
+#define LAN91C96_CR_DIS_LINK      (0x1U << 6)
+#define LAN91C96_CR_16BIT         (0x1U << 7)
+#define LAN91C96_CR_AUI_SELECT    (0x1U << 8)
+#define LAN91C96_CR_SET_SQLCH     (0x1U << 9)
+#define LAN91C96_CR_FULL_STEP     (0x1U << 10)
+#define LAN91C96_CR_NO_WAIT       (0x1U << 12)
+
+/*
+ ****************************************************************************
+ *	Base Address Register - Bank 1 - Offset 2
+ ****************************************************************************
+ */
+#define LAN91C96_BAR_RA_BITS      (0x27U << 0)
+#define LAN91C96_BAR_ROM_SIZE     (0x1U << 6)
+#define LAN91C96_BAR_A_BITS       (0xFFU << 8)
+
+/*
+ ****************************************************************************
+ *	Control Register - Bank 1 - Offset 12
+ ****************************************************************************
+ */
+#define LAN91C96_CTR_STORE        (0x1U << 0)
+#define LAN91C96_CTR_RELOAD       (0x1U << 1)
+#define LAN91C96_CTR_EEPROM       (0x1U << 2)
+#define LAN91C96_CTR_TE_ENABLE    (0x1U << 5)
+#define LAN91C96_CTR_CR_ENABLE    (0x1U << 6)
+#define LAN91C96_CTR_LE_ENABLE    (0x1U << 7)
+#define LAN91C96_CTR_BIT_8        (0x1U << 8)
+#define LAN91C96_CTR_AUTO_RELEASE (0x1U << 11)
+#define LAN91C96_CTR_WAKEUP_EN    (0x1U << 12)
+#define LAN91C96_CTR_PWRDN        (0x1U << 13)
+#define LAN91C96_CTR_RCV_BAD      (0x1U << 14)
+
+/*
+ ****************************************************************************
+ *	Bank 2 Register Map in I/O Space
+ ****************************************************************************
+ */
+#define LAN91C96_MMU            0      /* MMU Command Register */
+#define LAN91C96_AUTO_TX_START  1      /* Auto Tx Start Register */
+#define LAN91C96_PNR            2      /* Packet Number Register */
+#define LAN91C96_ARR            3      /* Allocation Result Register */
+#define LAN91C96_FIFO           4      /* FIFO Ports Register */
+#define LAN91C96_POINTER        6      /* Pointer Register */
+#define LAN91C96_DATA_HIGH      8      /* Data High Register */
+#define LAN91C96_DATA_LOW       10     /* Data Low Register */
+#define LAN91C96_INT_STATS      12     /* Interrupt Status Register - RO */
+#define LAN91C96_INT_ACK        12     /* Interrupt Acknowledge Register -WO */
+#define LAN91C96_INT_MASK       13     /* Interrupt Mask Register */
+
+/*
+ ****************************************************************************
+ *	MMU Command Register - Bank 2 - Offset 0
+ ****************************************************************************
+ */
+#define LAN91C96_MMUCR_NO_BUSY    (0x1U << 0)
+#define LAN91C96_MMUCR_N1         (0x1U << 1)
+#define LAN91C96_MMUCR_N2         (0x1U << 2)
+#define LAN91C96_MMUCR_COMMAND    (0xFU << 4)
+#define LAN91C96_MMUCR_ALLOC_TX   (0x2U << 4)    /* WXYZ = 0010 */
+#define LAN91C96_MMUCR_RESET_MMU  (0x4U << 4)    /* WXYZ = 0100 */
+#define LAN91C96_MMUCR_REMOVE_RX  (0x6U << 4)    /* WXYZ = 0110 */
+#define LAN91C96_MMUCR_REMOVE_TX  (0x7U << 4)    /* WXYZ = 0111 */
+#define LAN91C96_MMUCR_RELEASE_RX (0x8U << 4)    /* WXYZ = 1000 */
+#define LAN91C96_MMUCR_RELEASE_TX (0xAU << 4)    /* WXYZ = 1010 */
+#define LAN91C96_MMUCR_ENQUEUE    (0xCU << 4)    /* WXYZ = 1100 */
+#define LAN91C96_MMUCR_RESET_TX   (0xEU << 4)    /* WXYZ = 1110 */
+
+/*
+ ****************************************************************************
+ *	Auto Tx Start Register - Bank 2 - Offset 1
+ ****************************************************************************
+ */
+#define LAN91C96_AUTOTX           (0xFFU << 0)
+
+/*
+ ****************************************************************************
+ *	Packet Number Register - Bank 2 - Offset 2
+ ****************************************************************************
+ */
+#define LAN91C96_PNR_TX           (0x1FU << 0)
+
+/*
+ ****************************************************************************
+ *	Allocation Result Register - Bank 2 - Offset 3
+ ****************************************************************************
+ */
+#define LAN91C96_ARR_ALLOC_PN     (0x7FU << 0)
+#define LAN91C96_ARR_FAILED       (0x1U << 7)
+
+/*
+ ****************************************************************************
+ *	FIFO Ports Register - Bank 2 - Offset 4
+ ****************************************************************************
+ */
+#define LAN91C96_FIFO_TX_DONE_PN  (0x1FU << 0)
+#define LAN91C96_FIFO_TEMPTY      (0x1U << 7)
+#define LAN91C96_FIFO_RX_DONE_PN  (0x1FU << 8)
+#define LAN91C96_FIFO_RXEMPTY     (0x1U << 15)
+
+/*
+ ****************************************************************************
+ *	Pointer Register - Bank 2 - Offset 6
+ ****************************************************************************
+ */
+#define LAN91C96_PTR_LOW          (0xFFU << 0)
+#define LAN91C96_PTR_HIGH         (0x7U << 8)
+#define LAN91C96_PTR_AUTO_TX      (0x1U << 11)
+#define LAN91C96_PTR_ETEN         (0x1U << 12)
+#define LAN91C96_PTR_READ         (0x1U << 13)
+#define LAN91C96_PTR_AUTO_INCR    (0x1U << 14)
+#define LAN91C96_PTR_RCV          (0x1U << 15)
+
+#define LAN91C96_PTR_RX_FRAME     (LAN91C96_PTR_RCV       |    \
+				   LAN91C96_PTR_AUTO_INCR |    \
+				   LAN91C96_PTR_READ)
+
+/*
+ ****************************************************************************
+ *	Data Register - Bank 2 - Offset 8
+ ****************************************************************************
+ */
+#define LAN91C96_CONTROL_CRC      (0x1U << 4)    /* CRC bit */
+#define LAN91C96_CONTROL_ODD      (0x1U << 5)    /* ODD bit */
+
+/*
+ ****************************************************************************
+ *	Interrupt Status Register - Bank 2 - Offset 12
+ ****************************************************************************
+ */
+#define LAN91C96_IST_RCV_INT      (0x1U << 0)
+#define LAN91C96_IST_TX_INT       (0x1U << 1)
+#define LAN91C96_IST_TX_EMPTY_INT (0x1U << 2)
+#define LAN91C96_IST_ALLOC_INT    (0x1U << 3)
+#define LAN91C96_IST_RX_OVRN_INT  (0x1U << 4)
+#define LAN91C96_IST_EPH_INT      (0x1U << 5)
+#define LAN91C96_IST_ERCV_INT     (0x1U << 6)
+#define LAN91C96_IST_RX_IDLE_INT  (0x1U << 7)
+
+/*
+ ****************************************************************************
+ *	Interrupt Acknowledge Register - Bank 2 - Offset 12
+ ****************************************************************************
+ */
+#define LAN91C96_ACK_TX_INT       (0x1U << 1)
+#define LAN91C96_ACK_TX_EMPTY_INT (0x1U << 2)
+#define LAN91C96_ACK_RX_OVRN_INT  (0x1U << 4)
+#define LAN91C96_ACK_ERCV_INT     (0x1U << 6)
+
+/*
+ ****************************************************************************
+ *	Interrupt Mask Register - Bank 2 - Offset 13
+ ****************************************************************************
+ */
+#define LAN91C96_MSK_RCV_INT      (0x1U << 0)
+#define LAN91C96_MSK_TX_INT       (0x1U << 1)
+#define LAN91C96_MSK_TX_EMPTY_INT (0x1U << 2)
+#define LAN91C96_MSK_ALLOC_INT    (0x1U << 3)
+#define LAN91C96_MSK_RX_OVRN_INT  (0x1U << 4)
+#define LAN91C96_MSK_EPH_INT      (0x1U << 5)
+#define LAN91C96_MSK_ERCV_INT     (0x1U << 6)
+#define LAN91C96_MSK_TX_IDLE_INT  (0x1U << 7)
+
+/*
+ ****************************************************************************
+ *	Bank 3 Register Map in I/O Space
+ **************************************************************************
+ */
+#define LAN91C96_MGMT_MDO         (0x1U << 0)
+#define LAN91C96_MGMT_MDI         (0x1U << 1)
+#define LAN91C96_MGMT_MCLK        (0x1U << 2)
+#define LAN91C96_MGMT_MDOE        (0x1U << 3)
+#define LAN91C96_MGMT_LOW_ID      (0x3U << 4)
+#define LAN91C96_MGMT_IOS0        (0x1U << 8)
+#define LAN91C96_MGMT_IOS1        (0x1U << 9)
+#define LAN91C96_MGMT_IOS2        (0x1U << 10)
+#define LAN91C96_MGMT_nXNDEC      (0x1U << 11)
+#define LAN91C96_MGMT_HIGH_ID     (0x3U << 12)
+
+/*
+ ****************************************************************************
+ *	Revision Register - Bank 3 - Offset 10
+ ****************************************************************************
+ */
+#define LAN91C96_REV_REVID        (0xFU << 0)
+#define LAN91C96_REV_CHIPID       (0xFU << 4)
+
+/*
+ ****************************************************************************
+ *	Early RCV Register - Bank 3 - Offset 12
+ ****************************************************************************
+ */
+#define LAN91C96_ERCV_THRESHOLD   (0x1FU << 0)
+#define LAN91C96_ERCV_RCV_DISCRD  (0x1U << 7)
+
+/*
+ ****************************************************************************
+ *	PCMCIA Configuration Registers
+ ****************************************************************************
+ */
+#define LAN91C96_ECOR    0x8000        /* Ethernet Configuration Register */
+#define LAN91C96_ECSR    0x8002        /* Ethernet Configuration and Status */
+
+/*
+ ****************************************************************************
+ *	PCMCIA Ethernet Configuration Option Register (ECOR)
+ ****************************************************************************
+ */
+#define LAN91C96_ECOR_ENABLE       (0x1U << 0)
+#define LAN91C96_ECOR_WR_ATTRIB    (0x1U << 2)
+#define LAN91C96_ECOR_LEVEL_REQ    (0x1U << 6)
+#define LAN91C96_ECOR_SRESET       (0x1U << 7)
+
+/*
+ ****************************************************************************
+ *	PCMCIA Ethernet Configuration and Status Register (ECSR)
+ ****************************************************************************
+ */
+#define LAN91C96_ECSR_INTR        (0x1U << 1)
+#define LAN91C96_ECSR_PWRDWN      (0x1U << 2)
+#define LAN91C96_ECSR_IOIS8       (0x1U << 5)
+
+/*
+ ****************************************************************************
+ *	Receive Frame Status Word - See page 38 of the LAN91C96 specification.
+ ****************************************************************************
+ */
+#define LAN91C96_TOO_SHORT        (0x1U << 10)
+#define LAN91C96_TOO_LONG         (0x1U << 11)
+#define LAN91C96_ODD_FRM          (0x1U << 12)
+#define LAN91C96_BAD_CRC          (0x1U << 13)
+#define LAN91C96_BROD_CAST        (0x1U << 14)
+#define LAN91C96_ALGN_ERR         (0x1U << 15)
+
+#define FRAME_FILTER              (LAN91C96_TOO_SHORT | LAN91C96_TOO_LONG  | LAN91C96_BAD_CRC   | LAN91C96_ALGN_ERR)
+
+/*
+ ****************************************************************************
+ *	Default MAC Address
+ ****************************************************************************
+ */
+#define MAC_DEF_HI  0x0800
+#define MAC_DEF_MED 0x3333
+#define MAC_DEF_LO  0x0100
+
+/*
+ ****************************************************************************
+ *	Default I/O Signature - 0x33
+ ****************************************************************************
+ */
+#define LAN91C96_LOW_SIGNATURE        (0x33U << 0)
+#define LAN91C96_HIGH_SIGNATURE       (0x33U << 8)
+#define LAN91C96_SIGNATURE (LAN91C96_HIGH_SIGNATURE | LAN91C96_LOW_SIGNATURE)
+
+#define LAN91C96_MAX_PAGES     6        /* Maximum number of 256 pages. */
+#define ETHERNET_MAX_LENGTH 1514
+
+
+/*-------------------------------------------------------------------------
+ *  I define some macros to make it easier to do somewhat common
+ * or slightly complicated, repeated tasks.
+ *-------------------------------------------------------------------------
+ */
+
+/* select a register bank, 0 to 3  */
+
+#define SMC_SELECT_BANK(edev, x)  { SMC_outw(edev, x, LAN91C96_BANK_SELECT); }
+
+/* this enables an interrupt in the interrupt mask register */
+#define SMC_ENABLE_INT(edev, x) {\
+		unsigned char mask;\
+		SMC_SELECT_BANK(edev, 2);\
+		mask = SMC_inb(edev, LAN91C96_INT_MASK);\
+		mask |= (x);\
+		SMC_outb(edev, mask, LAN91C96_INT_MASK); \
+}
+
+/* this disables an interrupt from the interrupt mask register */
+
+#define SMC_DISABLE_INT(edev, x) {\
+		unsigned char mask;\
+		SMC_SELECT_BANK(edev, 2);\
+		mask = SMC_inb(edev, LAN91C96_INT_MASK);\
+		mask &= ~(x);\
+		SMC_outb(edev, mask, LAN91C96_INT_MASK); \
+}
+
+/*----------------------------------------------------------------------
+ * Define the interrupts that I want to receive from the card
+ *
+ * I want:
+ *  LAN91C96_IST_EPH_INT, for nasty errors
+ *  LAN91C96_IST_RCV_INT, for happy received packets
+ *  LAN91C96_IST_RX_OVRN_INT, because I have to kick the receiver
+ *-------------------------------------------------------------------------
+ */
+#define SMC_INTERRUPT_MASK   (LAN91C96_IST_EPH_INT | LAN91C96_IST_RX_OVRN_INT | LAN91C96_IST_RCV_INT)
+
+#endif  /* _LAN91C96_H_ */
diff --git a/marvell/uboot/drivers/net/macb.c b/marvell/uboot/drivers/net/macb.c
new file mode 100644
index 0000000..781a272
--- /dev/null
+++ b/marvell/uboot/drivers/net/macb.c
@@ -0,0 +1,702 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <common.h>
+
+/*
+ * The u-boot networking stack is a little weird.  It seems like the
+ * networking core allocates receive buffers up front without any
+ * regard to the hardware that's supposed to actually receive those
+ * packets.
+ *
+ * The MACB receives packets into 128-byte receive buffers, so the
+ * buffers allocated by the core isn't very practical to use.  We'll
+ * allocate our own, but we need one such buffer in case a packet
+ * wraps around the DMA ring so that we have to copy it.
+ *
+ * Therefore, define CONFIG_SYS_RX_ETH_BUFFER to 1 in the board-specific
+ * configuration header.  This way, the core allocates one RX buffer
+ * and one TX buffer, each of which can hold a ethernet packet of
+ * maximum size.
+ *
+ * For some reason, the networking core unconditionally specifies a
+ * 32-byte packet "alignment" (which really should be called
+ * "padding").  MACB shouldn't need that, but we'll refrain from any
+ * core modifications here...
+ */
+
+#include <net.h>
+#include <netdev.h>
+#include <malloc.h>
+#include <miiphy.h>
+
+#include <linux/mii.h>
+#include <asm/io.h>
+#include <asm/dma-mapping.h>
+#include <asm/arch/clk.h>
+#include <asm-generic/errno.h>
+
+#include "macb.h"
+
+#define CONFIG_SYS_MACB_RX_BUFFER_SIZE		4096
+#define CONFIG_SYS_MACB_RX_RING_SIZE		(CONFIG_SYS_MACB_RX_BUFFER_SIZE / 128)
+#define CONFIG_SYS_MACB_TX_RING_SIZE		16
+#define CONFIG_SYS_MACB_TX_TIMEOUT		1000
+#define CONFIG_SYS_MACB_AUTONEG_TIMEOUT	5000000
+
+struct macb_dma_desc {
+	u32	addr;
+	u32	ctrl;
+};
+
+#define RXADDR_USED		0x00000001
+#define RXADDR_WRAP		0x00000002
+
+#define RXBUF_FRMLEN_MASK	0x00000fff
+#define RXBUF_FRAME_START	0x00004000
+#define RXBUF_FRAME_END		0x00008000
+#define RXBUF_TYPEID_MATCH	0x00400000
+#define RXBUF_ADDR4_MATCH	0x00800000
+#define RXBUF_ADDR3_MATCH	0x01000000
+#define RXBUF_ADDR2_MATCH	0x02000000
+#define RXBUF_ADDR1_MATCH	0x04000000
+#define RXBUF_BROADCAST		0x80000000
+
+#define TXBUF_FRMLEN_MASK	0x000007ff
+#define TXBUF_FRAME_END		0x00008000
+#define TXBUF_NOCRC		0x00010000
+#define TXBUF_EXHAUSTED		0x08000000
+#define TXBUF_UNDERRUN		0x10000000
+#define TXBUF_MAXRETRY		0x20000000
+#define TXBUF_WRAP		0x40000000
+#define TXBUF_USED		0x80000000
+
+struct macb_device {
+	void			*regs;
+
+	unsigned int		rx_tail;
+	unsigned int		tx_head;
+	unsigned int		tx_tail;
+
+	void			*rx_buffer;
+	void			*tx_buffer;
+	struct macb_dma_desc	*rx_ring;
+	struct macb_dma_desc	*tx_ring;
+
+	unsigned long		rx_buffer_dma;
+	unsigned long		rx_ring_dma;
+	unsigned long		tx_ring_dma;
+
+	const struct device	*dev;
+	struct eth_device	netdev;
+	unsigned short		phy_addr;
+	struct mii_dev		*bus;
+};
+#define to_macb(_nd) container_of(_nd, struct macb_device, netdev)
+
+static int macb_is_gem(struct macb_device *macb)
+{
+	return MACB_BFEXT(IDNUM, macb_readl(macb, MID)) == 0x2;
+}
+
+static void macb_mdio_write(struct macb_device *macb, u8 reg, u16 value)
+{
+	unsigned long netctl;
+	unsigned long netstat;
+	unsigned long frame;
+
+	netctl = macb_readl(macb, NCR);
+	netctl |= MACB_BIT(MPE);
+	macb_writel(macb, NCR, netctl);
+
+	frame = (MACB_BF(SOF, 1)
+		 | MACB_BF(RW, 1)
+		 | MACB_BF(PHYA, macb->phy_addr)
+		 | MACB_BF(REGA, reg)
+		 | MACB_BF(CODE, 2)
+		 | MACB_BF(DATA, value));
+	macb_writel(macb, MAN, frame);
+
+	do {
+		netstat = macb_readl(macb, NSR);
+	} while (!(netstat & MACB_BIT(IDLE)));
+
+	netctl = macb_readl(macb, NCR);
+	netctl &= ~MACB_BIT(MPE);
+	macb_writel(macb, NCR, netctl);
+}
+
+static u16 macb_mdio_read(struct macb_device *macb, u8 reg)
+{
+	unsigned long netctl;
+	unsigned long netstat;
+	unsigned long frame;
+
+	netctl = macb_readl(macb, NCR);
+	netctl |= MACB_BIT(MPE);
+	macb_writel(macb, NCR, netctl);
+
+	frame = (MACB_BF(SOF, 1)
+		 | MACB_BF(RW, 2)
+		 | MACB_BF(PHYA, macb->phy_addr)
+		 | MACB_BF(REGA, reg)
+		 | MACB_BF(CODE, 2));
+	macb_writel(macb, MAN, frame);
+
+	do {
+		netstat = macb_readl(macb, NSR);
+	} while (!(netstat & MACB_BIT(IDLE)));
+
+	frame = macb_readl(macb, MAN);
+
+	netctl = macb_readl(macb, NCR);
+	netctl &= ~MACB_BIT(MPE);
+	macb_writel(macb, NCR, netctl);
+
+	return MACB_BFEXT(DATA, frame);
+}
+
+void __weak arch_get_mdio_control(const char *name)
+{
+	return;
+}
+
+#if defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
+
+int macb_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct macb_device *macb = to_macb(dev);
+
+	if ( macb->phy_addr != phy_adr )
+		return -1;
+
+	arch_get_mdio_control(devname);
+	*value = macb_mdio_read(macb, reg);
+
+	return 0;
+}
+
+int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct macb_device *macb = to_macb(dev);
+
+	if ( macb->phy_addr != phy_adr )
+		return -1;
+
+	arch_get_mdio_control(devname);
+	macb_mdio_write(macb, reg, value);
+
+	return 0;
+}
+#endif
+
+
+#if defined(CONFIG_CMD_NET)
+
+static int macb_send(struct eth_device *netdev, void *packet, int length)
+{
+	struct macb_device *macb = to_macb(netdev);
+	unsigned long paddr, ctrl;
+	unsigned int tx_head = macb->tx_head;
+	int i;
+
+	paddr = dma_map_single(packet, length, DMA_TO_DEVICE);
+
+	ctrl = length & TXBUF_FRMLEN_MASK;
+	ctrl |= TXBUF_FRAME_END;
+	if (tx_head == (CONFIG_SYS_MACB_TX_RING_SIZE - 1)) {
+		ctrl |= TXBUF_WRAP;
+		macb->tx_head = 0;
+	} else
+		macb->tx_head++;
+
+	macb->tx_ring[tx_head].ctrl = ctrl;
+	macb->tx_ring[tx_head].addr = paddr;
+	barrier();
+	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
+
+	/*
+	 * I guess this is necessary because the networking core may
+	 * re-use the transmit buffer as soon as we return...
+	 */
+	for (i = 0; i <= CONFIG_SYS_MACB_TX_TIMEOUT; i++) {
+		barrier();
+		ctrl = macb->tx_ring[tx_head].ctrl;
+		if (ctrl & TXBUF_USED)
+			break;
+		udelay(1);
+	}
+
+	dma_unmap_single(packet, length, paddr);
+
+	if (i <= CONFIG_SYS_MACB_TX_TIMEOUT) {
+		if (ctrl & TXBUF_UNDERRUN)
+			printf("%s: TX underrun\n", netdev->name);
+		if (ctrl & TXBUF_EXHAUSTED)
+			printf("%s: TX buffers exhausted in mid frame\n",
+			       netdev->name);
+	} else {
+		printf("%s: TX timeout\n", netdev->name);
+	}
+
+	/* No one cares anyway */
+	return 0;
+}
+
+static void reclaim_rx_buffers(struct macb_device *macb,
+			       unsigned int new_tail)
+{
+	unsigned int i;
+
+	i = macb->rx_tail;
+	while (i > new_tail) {
+		macb->rx_ring[i].addr &= ~RXADDR_USED;
+		i++;
+		if (i > CONFIG_SYS_MACB_RX_RING_SIZE)
+			i = 0;
+	}
+
+	while (i < new_tail) {
+		macb->rx_ring[i].addr &= ~RXADDR_USED;
+		i++;
+	}
+
+	barrier();
+	macb->rx_tail = new_tail;
+}
+
+static int macb_recv(struct eth_device *netdev)
+{
+	struct macb_device *macb = to_macb(netdev);
+	unsigned int rx_tail = macb->rx_tail;
+	void *buffer;
+	int length;
+	int wrapped = 0;
+	u32 status;
+
+	for (;;) {
+		if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED))
+			return -1;
+
+		status = macb->rx_ring[rx_tail].ctrl;
+		if (status & RXBUF_FRAME_START) {
+			if (rx_tail != macb->rx_tail)
+				reclaim_rx_buffers(macb, rx_tail);
+			wrapped = 0;
+		}
+
+		if (status & RXBUF_FRAME_END) {
+			buffer = macb->rx_buffer + 128 * macb->rx_tail;
+			length = status & RXBUF_FRMLEN_MASK;
+			if (wrapped) {
+				unsigned int headlen, taillen;
+
+				headlen = 128 * (CONFIG_SYS_MACB_RX_RING_SIZE
+						 - macb->rx_tail);
+				taillen = length - headlen;
+				memcpy((void *)NetRxPackets[0],
+				       buffer, headlen);
+				memcpy((void *)NetRxPackets[0] + headlen,
+				       macb->rx_buffer, taillen);
+				buffer = (void *)NetRxPackets[0];
+			}
+
+			NetReceive(buffer, length);
+			if (++rx_tail >= CONFIG_SYS_MACB_RX_RING_SIZE)
+				rx_tail = 0;
+			reclaim_rx_buffers(macb, rx_tail);
+		} else {
+			if (++rx_tail >= CONFIG_SYS_MACB_RX_RING_SIZE) {
+				wrapped = 1;
+				rx_tail = 0;
+			}
+		}
+		barrier();
+	}
+
+	return 0;
+}
+
+static void macb_phy_reset(struct macb_device *macb)
+{
+	struct eth_device *netdev = &macb->netdev;
+	int i;
+	u16 status, adv;
+
+	adv = ADVERTISE_CSMA | ADVERTISE_ALL;
+	macb_mdio_write(macb, MII_ADVERTISE, adv);
+	printf("%s: Starting autonegotiation...\n", netdev->name);
+	macb_mdio_write(macb, MII_BMCR, (BMCR_ANENABLE
+					 | BMCR_ANRESTART));
+
+	for (i = 0; i < CONFIG_SYS_MACB_AUTONEG_TIMEOUT / 100; i++) {
+		status = macb_mdio_read(macb, MII_BMSR);
+		if (status & BMSR_ANEGCOMPLETE)
+			break;
+		udelay(100);
+	}
+
+	if (status & BMSR_ANEGCOMPLETE)
+		printf("%s: Autonegotiation complete\n", netdev->name);
+	else
+		printf("%s: Autonegotiation timed out (status=0x%04x)\n",
+		       netdev->name, status);
+}
+
+#ifdef CONFIG_MACB_SEARCH_PHY
+static int macb_phy_find(struct macb_device *macb)
+{
+	int i;
+	u16 phy_id;
+
+	/* Search for PHY... */
+	for (i = 0; i < 32; i++) {
+		macb->phy_addr = i;
+		phy_id = macb_mdio_read(macb, MII_PHYSID1);
+		if (phy_id != 0xffff) {
+			printf("%s: PHY present at %d\n", macb->netdev.name, i);
+			return 1;
+		}
+	}
+
+	/* PHY isn't up to snuff */
+	printf("%s: PHY not found\n", macb->netdev.name);
+
+	return 0;
+}
+#endif /* CONFIG_MACB_SEARCH_PHY */
+
+
+static int macb_phy_init(struct macb_device *macb)
+{
+	struct eth_device *netdev = &macb->netdev;
+#ifdef CONFIG_PHYLIB
+	struct phy_device *phydev;
+#endif
+	u32 ncfgr;
+	u16 phy_id, status, adv, lpa;
+	int media, speed, duplex;
+	int i;
+
+	arch_get_mdio_control(netdev->name);
+#ifdef CONFIG_MACB_SEARCH_PHY
+	/* Auto-detect phy_addr */
+	if (!macb_phy_find(macb)) {
+		return 0;
+	}
+#endif /* CONFIG_MACB_SEARCH_PHY */
+
+	/* Check if the PHY is up to snuff... */
+	phy_id = macb_mdio_read(macb, MII_PHYSID1);
+	if (phy_id == 0xffff) {
+		printf("%s: No PHY present\n", netdev->name);
+		return 0;
+	}
+
+#ifdef CONFIG_PHYLIB
+	/* need to consider other phy interface mode */
+	phydev = phy_connect(macb->bus, macb->phy_addr, netdev,
+			     PHY_INTERFACE_MODE_RGMII);
+	if (!phydev) {
+		printf("phy_connect failed\n");
+		return -ENODEV;
+	}
+
+	phy_config(phydev);
+#endif
+
+	status = macb_mdio_read(macb, MII_BMSR);
+	if (!(status & BMSR_LSTATUS)) {
+		/* Try to re-negotiate if we don't have link already. */
+		macb_phy_reset(macb);
+
+		for (i = 0; i < CONFIG_SYS_MACB_AUTONEG_TIMEOUT / 100; i++) {
+			status = macb_mdio_read(macb, MII_BMSR);
+			if (status & BMSR_LSTATUS)
+				break;
+			udelay(100);
+		}
+	}
+
+	if (!(status & BMSR_LSTATUS)) {
+		printf("%s: link down (status: 0x%04x)\n",
+		       netdev->name, status);
+		return 0;
+	}
+
+	/* First check for GMAC */
+	if (macb_is_gem(macb)) {
+		lpa = macb_mdio_read(macb, MII_STAT1000);
+		if (lpa & (1 << 11)) {
+			speed = 1000;
+			duplex = 1;
+		} else {
+		       if (lpa & (1 << 10)) {
+				speed = 1000;
+				duplex = 1;
+			} else {
+				speed = 0;
+			}
+		}
+
+		if (speed == 1000) {
+			printf("%s: link up, %dMbps %s-duplex (lpa: 0x%04x)\n",
+			       netdev->name,
+			       speed,
+			       duplex ? "full" : "half",
+			       lpa);
+
+			ncfgr = macb_readl(macb, NCFGR);
+			ncfgr &= ~(GEM_BIT(GBE) | MACB_BIT(SPD) | MACB_BIT(FD));
+			if (speed)
+				ncfgr |= GEM_BIT(GBE);
+			if (duplex)
+				ncfgr |= MACB_BIT(FD);
+			macb_writel(macb, NCFGR, ncfgr);
+
+			return 1;
+		}
+	}
+
+	/* fall back for EMAC checking */
+	adv = macb_mdio_read(macb, MII_ADVERTISE);
+	lpa = macb_mdio_read(macb, MII_LPA);
+	media = mii_nway_result(lpa & adv);
+	speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
+		 ? 1 : 0);
+	duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+	printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
+	       netdev->name,
+	       speed ? "100" : "10",
+	       duplex ? "full" : "half",
+	       lpa);
+
+	ncfgr = macb_readl(macb, NCFGR);
+	ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
+	if (speed)
+		ncfgr |= MACB_BIT(SPD);
+	if (duplex)
+		ncfgr |= MACB_BIT(FD);
+	macb_writel(macb, NCFGR, ncfgr);
+
+	return 1;
+}
+
+static int macb_init(struct eth_device *netdev, bd_t *bd)
+{
+	struct macb_device *macb = to_macb(netdev);
+	unsigned long paddr;
+	int i;
+
+	/*
+	 * macb_halt should have been called at some point before now,
+	 * so we'll assume the controller is idle.
+	 */
+
+	/* initialize DMA descriptors */
+	paddr = macb->rx_buffer_dma;
+	for (i = 0; i < CONFIG_SYS_MACB_RX_RING_SIZE; i++) {
+		if (i == (CONFIG_SYS_MACB_RX_RING_SIZE - 1))
+			paddr |= RXADDR_WRAP;
+		macb->rx_ring[i].addr = paddr;
+		macb->rx_ring[i].ctrl = 0;
+		paddr += 128;
+	}
+	for (i = 0; i < CONFIG_SYS_MACB_TX_RING_SIZE; i++) {
+		macb->tx_ring[i].addr = 0;
+		if (i == (CONFIG_SYS_MACB_TX_RING_SIZE - 1))
+			macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP;
+		else
+			macb->tx_ring[i].ctrl = TXBUF_USED;
+	}
+	macb->rx_tail = macb->tx_head = macb->tx_tail = 0;
+
+	macb_writel(macb, RBQP, macb->rx_ring_dma);
+	macb_writel(macb, TBQP, macb->tx_ring_dma);
+
+	if (macb_is_gem(macb)) {
+#ifdef CONFIG_RGMII
+		gem_writel(macb, UR, GEM_BIT(RGMII));
+#else
+		gem_writel(macb, UR, 0);
+#endif
+	} else {
+	/* choose RMII or MII mode. This depends on the board */
+#ifdef CONFIG_RMII
+#ifdef CONFIG_AT91FAMILY
+	macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN));
+#else
+	macb_writel(macb, USRIO, 0);
+#endif
+#else
+#ifdef CONFIG_AT91FAMILY
+	macb_writel(macb, USRIO, MACB_BIT(CLKEN));
+#else
+	macb_writel(macb, USRIO, MACB_BIT(MII));
+#endif
+#endif /* CONFIG_RMII */
+	}
+
+	if (!macb_phy_init(macb))
+		return -1;
+
+	/* Enable TX and RX */
+	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE));
+
+	return 0;
+}
+
+static void macb_halt(struct eth_device *netdev)
+{
+	struct macb_device *macb = to_macb(netdev);
+	u32 ncr, tsr;
+
+	/* Halt the controller and wait for any ongoing transmission to end. */
+	ncr = macb_readl(macb, NCR);
+	ncr |= MACB_BIT(THALT);
+	macb_writel(macb, NCR, ncr);
+
+	do {
+		tsr = macb_readl(macb, TSR);
+	} while (tsr & MACB_BIT(TGO));
+
+	/* Disable TX and RX, and clear statistics */
+	macb_writel(macb, NCR, MACB_BIT(CLRSTAT));
+}
+
+static int macb_write_hwaddr(struct eth_device *dev)
+{
+	struct macb_device *macb = to_macb(dev);
+	u32 hwaddr_bottom;
+	u16 hwaddr_top;
+
+	/* set hardware address */
+	hwaddr_bottom = dev->enetaddr[0] | dev->enetaddr[1] << 8 |
+			dev->enetaddr[2] << 16 | dev->enetaddr[3] << 24;
+	macb_writel(macb, SA1B, hwaddr_bottom);
+	hwaddr_top = dev->enetaddr[4] | dev->enetaddr[5] << 8;
+	macb_writel(macb, SA1T, hwaddr_top);
+	return 0;
+}
+
+static u32 macb_mdc_clk_div(int id, struct macb_device *macb)
+{
+	u32 config;
+	unsigned long macb_hz = get_macb_pclk_rate(id);
+
+	if (macb_hz < 20000000)
+		config = MACB_BF(CLK, MACB_CLK_DIV8);
+	else if (macb_hz < 40000000)
+		config = MACB_BF(CLK, MACB_CLK_DIV16);
+	else if (macb_hz < 80000000)
+		config = MACB_BF(CLK, MACB_CLK_DIV32);
+	else
+		config = MACB_BF(CLK, MACB_CLK_DIV64);
+
+	return config;
+}
+
+static u32 gem_mdc_clk_div(int id, struct macb_device *macb)
+{
+	u32 config;
+	unsigned long macb_hz = get_macb_pclk_rate(id);
+
+	if (macb_hz < 20000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV8);
+	else if (macb_hz < 40000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV16);
+	else if (macb_hz < 80000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV32);
+	else if (macb_hz < 120000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV48);
+	else if (macb_hz < 160000000)
+		config = GEM_BF(CLK, GEM_CLK_DIV64);
+	else
+		config = GEM_BF(CLK, GEM_CLK_DIV96);
+
+	return config;
+}
+
+/*
+ * Get the DMA bus width field of the network configuration register that we
+ * should program. We find the width from decoding the design configuration
+ * register to find the maximum supported data bus width.
+ */
+static u32 macb_dbw(struct macb_device *macb)
+{
+	switch (GEM_BFEXT(DBWDEF, gem_readl(macb, DCFG1))) {
+	case 4:
+		return GEM_BF(DBW, GEM_DBW128);
+	case 2:
+		return GEM_BF(DBW, GEM_DBW64);
+	case 1:
+	default:
+		return GEM_BF(DBW, GEM_DBW32);
+	}
+}
+
+int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
+{
+	struct macb_device *macb;
+	struct eth_device *netdev;
+	u32 ncfgr;
+
+	macb = malloc(sizeof(struct macb_device));
+	if (!macb) {
+		printf("Error: Failed to allocate memory for MACB%d\n", id);
+		return -1;
+	}
+	memset(macb, 0, sizeof(struct macb_device));
+
+	netdev = &macb->netdev;
+
+	macb->rx_buffer = dma_alloc_coherent(CONFIG_SYS_MACB_RX_BUFFER_SIZE,
+					     &macb->rx_buffer_dma);
+	macb->rx_ring = dma_alloc_coherent(CONFIG_SYS_MACB_RX_RING_SIZE
+					   * sizeof(struct macb_dma_desc),
+					   &macb->rx_ring_dma);
+	macb->tx_ring = dma_alloc_coherent(CONFIG_SYS_MACB_TX_RING_SIZE
+					   * sizeof(struct macb_dma_desc),
+					   &macb->tx_ring_dma);
+
+	macb->regs = regs;
+	macb->phy_addr = phy_addr;
+
+	if (macb_is_gem(macb))
+		sprintf(netdev->name, "gmac%d", id);
+	else
+		sprintf(netdev->name, "macb%d", id);
+
+	netdev->init = macb_init;
+	netdev->halt = macb_halt;
+	netdev->send = macb_send;
+	netdev->recv = macb_recv;
+	netdev->write_hwaddr = macb_write_hwaddr;
+
+	/*
+	 * Do some basic initialization so that we at least can talk
+	 * to the PHY
+	 */
+	if (macb_is_gem(macb)) {
+		ncfgr = gem_mdc_clk_div(id, macb);
+		ncfgr |= macb_dbw(macb);
+	} else {
+		ncfgr = macb_mdc_clk_div(id, macb);
+	}
+
+	macb_writel(macb, NCFGR, ncfgr);
+
+	eth_register(netdev);
+
+#if defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
+	miiphy_register(netdev->name, macb_miiphy_read, macb_miiphy_write);
+	macb->bus = miiphy_get_dev_by_name(netdev->name);
+#endif
+	return 0;
+}
+
+#endif
diff --git a/marvell/uboot/drivers/net/macb.h b/marvell/uboot/drivers/net/macb.h
new file mode 100644
index 0000000..06f7c66
--- /dev/null
+++ b/marvell/uboot/drivers/net/macb.h
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef __DRIVERS_MACB_H__
+#define __DRIVERS_MACB_H__
+
+/* MACB register offsets */
+#define MACB_NCR				0x0000
+#define MACB_NCFGR				0x0004
+#define MACB_NSR				0x0008
+#define GEM_UR					0x000c
+#define MACB_TSR				0x0014
+#define MACB_RBQP				0x0018
+#define MACB_TBQP				0x001c
+#define MACB_RSR				0x0020
+#define MACB_ISR				0x0024
+#define MACB_IER				0x0028
+#define MACB_IDR				0x002c
+#define MACB_IMR				0x0030
+#define MACB_MAN				0x0034
+#define MACB_PTR				0x0038
+#define MACB_PFR				0x003c
+#define MACB_FTO				0x0040
+#define MACB_SCF				0x0044
+#define MACB_MCF				0x0048
+#define MACB_FRO				0x004c
+#define MACB_FCSE				0x0050
+#define MACB_ALE				0x0054
+#define MACB_DTF				0x0058
+#define MACB_LCOL				0x005c
+#define MACB_EXCOL				0x0060
+#define MACB_TUND				0x0064
+#define MACB_CSE				0x0068
+#define MACB_RRE				0x006c
+#define MACB_ROVR				0x0070
+#define MACB_RSE				0x0074
+#define MACB_ELE				0x0078
+#define MACB_RJA				0x007c
+#define MACB_USF				0x0080
+#define MACB_STE				0x0084
+#define MACB_RLE				0x0088
+#define MACB_TPF				0x008c
+#define MACB_HRB				0x0090
+#define MACB_HRT				0x0094
+#define MACB_SA1B				0x0098
+#define MACB_SA1T				0x009c
+#define MACB_SA2B				0x00a0
+#define MACB_SA2T				0x00a4
+#define MACB_SA3B				0x00a8
+#define MACB_SA3T				0x00ac
+#define MACB_SA4B				0x00b0
+#define MACB_SA4T				0x00b4
+#define MACB_TID				0x00b8
+#define MACB_TPQ				0x00bc
+#define MACB_USRIO				0x00c0
+#define MACB_WOL				0x00c4
+#define MACB_MID				0x00fc
+
+/* GEM specific register offsets */
+#define GEM_DCFG1				0x0280
+
+/* Bitfields in NCR */
+#define MACB_LB_OFFSET				0
+#define MACB_LB_SIZE				1
+#define MACB_LLB_OFFSET				1
+#define MACB_LLB_SIZE				1
+#define MACB_RE_OFFSET				2
+#define MACB_RE_SIZE				1
+#define MACB_TE_OFFSET				3
+#define MACB_TE_SIZE				1
+#define MACB_MPE_OFFSET				4
+#define MACB_MPE_SIZE				1
+#define MACB_CLRSTAT_OFFSET			5
+#define MACB_CLRSTAT_SIZE			1
+#define MACB_INCSTAT_OFFSET			6
+#define MACB_INCSTAT_SIZE			1
+#define MACB_WESTAT_OFFSET			7
+#define MACB_WESTAT_SIZE			1
+#define MACB_BP_OFFSET				8
+#define MACB_BP_SIZE				1
+#define MACB_TSTART_OFFSET			9
+#define MACB_TSTART_SIZE			1
+#define MACB_THALT_OFFSET			10
+#define MACB_THALT_SIZE				1
+#define MACB_NCR_TPF_OFFSET			11
+#define MACB_NCR_TPF_SIZE			1
+#define MACB_TZQ_OFFSET				12
+#define MACB_TZQ_SIZE				1
+
+/* Bitfields in NCFGR */
+#define MACB_SPD_OFFSET				0
+#define MACB_SPD_SIZE				1
+#define MACB_FD_OFFSET				1
+#define MACB_FD_SIZE				1
+#define MACB_BIT_RATE_OFFSET			2
+#define MACB_BIT_RATE_SIZE			1
+#define MACB_JFRAME_OFFSET			3
+#define MACB_JFRAME_SIZE			1
+#define MACB_CAF_OFFSET				4
+#define MACB_CAF_SIZE				1
+#define MACB_NBC_OFFSET				5
+#define MACB_NBC_SIZE				1
+#define MACB_NCFGR_MTI_OFFSET			6
+#define MACB_NCFGR_MTI_SIZE			1
+#define MACB_UNI_OFFSET				7
+#define MACB_UNI_SIZE				1
+#define MACB_BIG_OFFSET				8
+#define MACB_BIG_SIZE				1
+#define MACB_EAE_OFFSET				9
+#define MACB_EAE_SIZE				1
+#define MACB_CLK_OFFSET				10
+#define MACB_CLK_SIZE				2
+#define MACB_RTY_OFFSET				12
+#define MACB_RTY_SIZE				1
+#define MACB_PAE_OFFSET				13
+#define MACB_PAE_SIZE				1
+#define MACB_RBOF_OFFSET			14
+#define MACB_RBOF_SIZE				2
+#define MACB_RLCE_OFFSET			16
+#define MACB_RLCE_SIZE				1
+#define MACB_DRFCS_OFFSET			17
+#define MACB_DRFCS_SIZE				1
+#define MACB_EFRHD_OFFSET			18
+#define MACB_EFRHD_SIZE				1
+#define MACB_IRXFCS_OFFSET			19
+#define MACB_IRXFCS_SIZE			1
+
+#define GEM_GBE_OFFSET				10
+#define GEM_GBE_SIZE				1
+#define GEM_CLK_OFFSET				18
+#define GEM_CLK_SIZE				3
+#define GEM_DBW_OFFSET				21
+#define GEM_DBW_SIZE				2
+
+/* Bitfields in NSR */
+#define MACB_NSR_LINK_OFFSET			0
+#define MACB_NSR_LINK_SIZE			1
+#define MACB_MDIO_OFFSET			1
+#define MACB_MDIO_SIZE				1
+#define MACB_IDLE_OFFSET			2
+#define MACB_IDLE_SIZE				1
+
+/* Bitfields in UR */
+#define GEM_RGMII_OFFSET			0
+#define GEM_RGMII_SIZE				1
+
+/* Bitfields in TSR */
+#define MACB_UBR_OFFSET				0
+#define MACB_UBR_SIZE				1
+#define MACB_COL_OFFSET				1
+#define MACB_COL_SIZE				1
+#define MACB_TSR_RLE_OFFSET			2
+#define MACB_TSR_RLE_SIZE			1
+#define MACB_TGO_OFFSET				3
+#define MACB_TGO_SIZE				1
+#define MACB_BEX_OFFSET				4
+#define MACB_BEX_SIZE				1
+#define MACB_COMP_OFFSET			5
+#define MACB_COMP_SIZE				1
+#define MACB_UND_OFFSET				6
+#define MACB_UND_SIZE				1
+
+/* Bitfields in RSR */
+#define MACB_BNA_OFFSET				0
+#define MACB_BNA_SIZE				1
+#define MACB_REC_OFFSET				1
+#define MACB_REC_SIZE				1
+#define MACB_OVR_OFFSET				2
+#define MACB_OVR_SIZE				1
+
+/* Bitfields in ISR/IER/IDR/IMR */
+#define MACB_MFD_OFFSET				0
+#define MACB_MFD_SIZE				1
+#define MACB_RCOMP_OFFSET			1
+#define MACB_RCOMP_SIZE				1
+#define MACB_RXUBR_OFFSET			2
+#define MACB_RXUBR_SIZE				1
+#define MACB_TXUBR_OFFSET			3
+#define MACB_TXUBR_SIZE				1
+#define MACB_ISR_TUND_OFFSET			4
+#define MACB_ISR_TUND_SIZE			1
+#define MACB_ISR_RLE_OFFSET			5
+#define MACB_ISR_RLE_SIZE			1
+#define MACB_TXERR_OFFSET			6
+#define MACB_TXERR_SIZE				1
+#define MACB_TCOMP_OFFSET			7
+#define MACB_TCOMP_SIZE				1
+#define MACB_ISR_LINK_OFFSET			9
+#define MACB_ISR_LINK_SIZE			1
+#define MACB_ISR_ROVR_OFFSET			10
+#define MACB_ISR_ROVR_SIZE			1
+#define MACB_HRESP_OFFSET			11
+#define MACB_HRESP_SIZE				1
+#define MACB_PFR_OFFSET				12
+#define MACB_PFR_SIZE				1
+#define MACB_PTZ_OFFSET				13
+#define MACB_PTZ_SIZE				1
+
+/* Bitfields in MAN */
+#define MACB_DATA_OFFSET			0
+#define MACB_DATA_SIZE				16
+#define MACB_CODE_OFFSET			16
+#define MACB_CODE_SIZE				2
+#define MACB_REGA_OFFSET			18
+#define MACB_REGA_SIZE				5
+#define MACB_PHYA_OFFSET			23
+#define MACB_PHYA_SIZE				5
+#define MACB_RW_OFFSET				28
+#define MACB_RW_SIZE				2
+#define MACB_SOF_OFFSET				30
+#define MACB_SOF_SIZE				2
+
+/* Bitfields in USRIO */
+#define MACB_MII_OFFSET				0
+#define MACB_MII_SIZE				1
+#define MACB_EAM_OFFSET				1
+#define MACB_EAM_SIZE				1
+#define MACB_TX_PAUSE_OFFSET			2
+#define MACB_TX_PAUSE_SIZE			1
+#define MACB_TX_PAUSE_ZERO_OFFSET		3
+#define MACB_TX_PAUSE_ZERO_SIZE			1
+
+/* Bitfields in USRIO (AT91) */
+#define MACB_RMII_OFFSET			0
+#define MACB_RMII_SIZE				1
+#define MACB_CLKEN_OFFSET			1
+#define MACB_CLKEN_SIZE				1
+
+/* Bitfields in WOL */
+#define MACB_IP_OFFSET				0
+#define MACB_IP_SIZE				16
+#define MACB_MAG_OFFSET				16
+#define MACB_MAG_SIZE				1
+#define MACB_ARP_OFFSET				17
+#define MACB_ARP_SIZE				1
+#define MACB_SA1_OFFSET				18
+#define MACB_SA1_SIZE				1
+#define MACB_WOL_MTI_OFFSET			19
+#define MACB_WOL_MTI_SIZE			1
+
+/* Bitfields in MID */
+#define MACB_IDNUM_OFFSET			16
+#define MACB_IDNUM_SIZE				16
+
+/* Bitfields in DCFG1 */
+#define GEM_DBWDEF_OFFSET			25
+#define GEM_DBWDEF_SIZE				3
+
+/* constants for data bus width */
+#define GEM_DBW32				0
+#define GEM_DBW64				1
+#define GEM_DBW128				2
+
+/* Constants for CLK */
+#define MACB_CLK_DIV8				0
+#define MACB_CLK_DIV16				1
+#define MACB_CLK_DIV32				2
+#define MACB_CLK_DIV64				3
+
+/* GEM specific constants for CLK */
+#define GEM_CLK_DIV8				0
+#define GEM_CLK_DIV16				1
+#define GEM_CLK_DIV32				2
+#define GEM_CLK_DIV48				3
+#define GEM_CLK_DIV64				4
+#define GEM_CLK_DIV96				5
+
+/* Constants for MAN register */
+#define MACB_MAN_SOF				1
+#define MACB_MAN_WRITE				1
+#define MACB_MAN_READ				2
+#define MACB_MAN_CODE				2
+
+/* Bit manipulation macros */
+#define MACB_BIT(name)					\
+	(1 << MACB_##name##_OFFSET)
+#define MACB_BF(name, value)				\
+	(((value) & ((1 << MACB_##name##_SIZE) - 1))	\
+	 << MACB_##name##_OFFSET)
+#define MACB_BFEXT(name, value)\
+	(((value) >> MACB_##name##_OFFSET)		\
+	 & ((1 << MACB_##name##_SIZE) - 1))
+#define MACB_BFINS(name, value, old)			\
+	(((old) & ~(((1 << MACB_##name##_SIZE) - 1)	\
+		    << MACB_##name##_OFFSET))		\
+	 | MACB_BF(name, value))
+
+#define GEM_BIT(name)					\
+	(1 << GEM_##name##_OFFSET)
+#define GEM_BF(name, value)				\
+	(((value) & ((1 << GEM_##name##_SIZE) - 1))	\
+	 << GEM_##name##_OFFSET)
+#define GEM_BFEXT(name, value)\
+	(((value) >> GEM_##name##_OFFSET)		\
+	 & ((1 << GEM_##name##_SIZE) - 1))
+#define GEM_BFINS(name, value, old)			\
+	(((old) & ~(((1 << GEM_##name##_SIZE) - 1)	\
+		    << GEM_##name##_OFFSET))		\
+	 | GEM_BF(name, value))
+
+/* Register access macros */
+#define macb_readl(port, reg)				\
+	readl((port)->regs + MACB_##reg)
+#define macb_writel(port, reg, value)			\
+	writel((value), (port)->regs + MACB_##reg)
+#define gem_readl(port, reg)				\
+	readl((port)->regs + GEM_##reg)
+#define gem_writel(port, reg, value)			\
+	writel((value), (port)->regs + GEM_##reg)
+
+#endif /* __DRIVERS_MACB_H__ */
diff --git a/marvell/uboot/drivers/net/mcffec.c b/marvell/uboot/drivers/net/mcffec.c
new file mode 100644
index 0000000..7c4b210
--- /dev/null
+++ b/marvell/uboot/drivers/net/mcffec.c
@@ -0,0 +1,609 @@
+/*
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2007 Freescale Semiconductor, Inc.
+ * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+
+#include <command.h>
+#include <net.h>
+#include <netdev.h>
+#include <miiphy.h>
+
+#include <asm/fec.h>
+#include <asm/immap.h>
+
+#undef	ET_DEBUG
+#undef	MII_DEBUG
+
+/* Ethernet Transmit and Receive Buffers */
+#define DBUF_LENGTH		1520
+#define TX_BUF_CNT		2
+#define PKT_MAXBUF_SIZE		1518
+#define PKT_MINBUF_SIZE		64
+#define PKT_MAXBLR_SIZE		1520
+#define LAST_PKTBUFSRX		PKTBUFSRX - 1
+#define BD_ENET_RX_W_E		(BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY)
+#define BD_ENET_TX_RDY_LST	(BD_ENET_TX_READY | BD_ENET_TX_LAST)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct fec_info_s fec_info[] = {
+#ifdef CONFIG_SYS_FEC0_IOBASE
+	{
+	 0,			/* index */
+	 CONFIG_SYS_FEC0_IOBASE,	/* io base */
+	 CONFIG_SYS_FEC0_PINMUX,	/* gpio pin muxing */
+	 CONFIG_SYS_FEC0_MIIBASE,	/* mii base */
+	 -1,			/* phy_addr */
+	 0,			/* duplex and speed */
+	 0,			/* phy name */
+	 0,			/* phyname init */
+	 0,			/* RX BD */
+	 0,			/* TX BD */
+	 0,			/* rx Index */
+	 0,			/* tx Index */
+	 0,			/* tx buffer */
+	 0,			/* initialized flag */
+	 (struct fec_info_s *)-1,
+	 },
+#endif
+#ifdef CONFIG_SYS_FEC1_IOBASE
+	{
+	 1,			/* index */
+	 CONFIG_SYS_FEC1_IOBASE,	/* io base */
+	 CONFIG_SYS_FEC1_PINMUX,	/* gpio pin muxing */
+	 CONFIG_SYS_FEC1_MIIBASE,	/* mii base */
+	 -1,			/* phy_addr */
+	 0,			/* duplex and speed */
+	 0,			/* phy name */
+	 0,			/* phy name init */
+#ifdef CONFIG_SYS_FEC_BUF_USE_SRAM
+	 (cbd_t *)DBUF_LENGTH,	/* RX BD */
+#else
+	 0,			/* RX BD */
+#endif
+	 0,			/* TX BD */
+	 0,			/* rx Index */
+	 0,			/* tx Index */
+	 0,			/* tx buffer */
+	 0,			/* initialized flag */
+	 (struct fec_info_s *)-1,
+	 }
+#endif
+};
+
+int fec_recv(struct eth_device *dev);
+int fec_init(struct eth_device *dev, bd_t * bd);
+void fec_halt(struct eth_device *dev);
+void fec_reset(struct eth_device *dev);
+
+void setFecDuplexSpeed(volatile fec_t * fecp, bd_t * bd, int dup_spd)
+{
+	if ((dup_spd >> 16) == FULL) {
+		/* Set maximum frame length */
+		fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | FEC_RCR_MII_MODE |
+		    FEC_RCR_PROM | 0x100;
+		fecp->tcr = FEC_TCR_FDEN;
+	} else {
+		/* Half duplex mode */
+		fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) |
+		    FEC_RCR_MII_MODE | FEC_RCR_DRT;
+		fecp->tcr &= ~FEC_TCR_FDEN;
+	}
+
+	if ((dup_spd & 0xFFFF) == _100BASET) {
+#ifdef CONFIG_MCF5445x
+		fecp->rcr &= ~0x200;	/* disabled 10T base */
+#endif
+#ifdef MII_DEBUG
+		printf("100Mbps\n");
+#endif
+		bd->bi_ethspeed = 100;
+	} else {
+#ifdef CONFIG_MCF5445x
+		fecp->rcr |= 0x200;	/* enabled 10T base */
+#endif
+#ifdef MII_DEBUG
+		printf("10Mbps\n");
+#endif
+		bd->bi_ethspeed = 10;
+	}
+}
+
+static int fec_send(struct eth_device *dev, void *packet, int length)
+{
+	struct fec_info_s *info = dev->priv;
+	volatile fec_t *fecp = (fec_t *) (info->iobase);
+	int j, rc;
+	u16 phyStatus;
+
+	miiphy_read(dev->name, info->phy_addr, MII_BMSR, &phyStatus);
+
+	/* section 16.9.23.3
+	 * Wait for ready
+	 */
+	j = 0;
+	while ((info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_READY) &&
+	       (j < MCFFEC_TOUT_LOOP)) {
+		udelay(1);
+		j++;
+	}
+	if (j >= MCFFEC_TOUT_LOOP) {
+		printf("TX not ready\n");
+	}
+
+	info->txbd[info->txIdx].cbd_bufaddr = (uint) packet;
+	info->txbd[info->txIdx].cbd_datlen = length;
+	info->txbd[info->txIdx].cbd_sc |= BD_ENET_TX_RDY_LST;
+
+	/* Activate transmit Buffer Descriptor polling */
+	fecp->tdar = 0x01000000;	/* Descriptor polling active    */
+
+#ifndef CONFIG_SYS_FEC_BUF_USE_SRAM
+	/*
+	 * FEC unable to initial transmit data packet.
+	 * A nop will ensure the descriptor polling active completed.
+	 * CF Internal RAM has shorter cycle access than DRAM. If use
+	 * DRAM as Buffer descriptor and data, a nop is a must.
+	 * Affect only V2 and V3.
+	 */
+	__asm__ ("nop");
+
+#endif
+
+#ifdef CONFIG_SYS_UNIFY_CACHE
+	icache_invalid();
+#endif
+
+	j = 0;
+	while ((info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_READY) &&
+	       (j < MCFFEC_TOUT_LOOP)) {
+		udelay(1);
+		j++;
+	}
+	if (j >= MCFFEC_TOUT_LOOP) {
+		printf("TX timeout\n");
+	}
+
+#ifdef ET_DEBUG
+	printf("%s[%d] %s: cycles: %d    status: %x  retry cnt: %d\n",
+	       __FILE__, __LINE__, __FUNCTION__, j,
+	       info->txbd[info->txIdx].cbd_sc,
+	       (info->txbd[info->txIdx].cbd_sc & 0x003C) >> 2);
+#endif
+
+	/* return only status bits */
+	rc = (info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_STATS);
+	info->txIdx = (info->txIdx + 1) % TX_BUF_CNT;
+
+	return rc;
+}
+
+int fec_recv(struct eth_device *dev)
+{
+	struct fec_info_s *info = dev->priv;
+	volatile fec_t *fecp = (fec_t *) (info->iobase);
+	int length;
+
+	for (;;) {
+#ifndef CONFIG_SYS_FEC_BUF_USE_SRAM
+#endif
+#ifdef CONFIG_SYS_UNIFY_CACHE
+		icache_invalid();
+#endif
+		/* section 16.9.23.2 */
+		if (info->rxbd[info->rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
+			length = -1;
+			break;	/* nothing received - leave for() loop */
+		}
+
+		length = info->rxbd[info->rxIdx].cbd_datlen;
+
+		if (info->rxbd[info->rxIdx].cbd_sc & 0x003f) {
+			printf("%s[%d] err: %x\n",
+			       __FUNCTION__, __LINE__,
+			       info->rxbd[info->rxIdx].cbd_sc);
+#ifdef ET_DEBUG
+			printf("%s[%d] err: %x\n",
+			       __FUNCTION__, __LINE__,
+			       info->rxbd[info->rxIdx].cbd_sc);
+#endif
+		} else {
+
+			length -= 4;
+			/* Pass the packet up to the protocol layers. */
+			NetReceive(NetRxPackets[info->rxIdx], length);
+
+			fecp->eir |= FEC_EIR_RXF;
+		}
+
+		/* Give the buffer back to the FEC. */
+		info->rxbd[info->rxIdx].cbd_datlen = 0;
+
+		/* wrap around buffer index when necessary */
+		if (info->rxIdx == LAST_PKTBUFSRX) {
+			info->rxbd[PKTBUFSRX - 1].cbd_sc = BD_ENET_RX_W_E;
+			info->rxIdx = 0;
+		} else {
+			info->rxbd[info->rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
+			info->rxIdx++;
+		}
+
+		/* Try to fill Buffer Descriptors */
+		fecp->rdar = 0x01000000;	/* Descriptor polling active    */
+	}
+
+	return length;
+}
+
+#ifdef ET_DEBUG
+void dbgFecRegs(struct eth_device *dev)
+{
+	struct fec_info_s *info = dev->priv;
+	volatile fec_t *fecp = (fec_t *) (info->iobase);
+
+	printf("=====\n");
+	printf("ievent       %x - %x\n", (int)&fecp->eir, fecp->eir);
+	printf("imask        %x - %x\n", (int)&fecp->eimr, fecp->eimr);
+	printf("r_des_active %x - %x\n", (int)&fecp->rdar, fecp->rdar);
+	printf("x_des_active %x - %x\n", (int)&fecp->tdar, fecp->tdar);
+	printf("ecntrl       %x - %x\n", (int)&fecp->ecr, fecp->ecr);
+	printf("mii_mframe   %x - %x\n", (int)&fecp->mmfr, fecp->mmfr);
+	printf("mii_speed    %x - %x\n", (int)&fecp->mscr, fecp->mscr);
+	printf("mii_ctrlstat %x - %x\n", (int)&fecp->mibc, fecp->mibc);
+	printf("r_cntrl      %x - %x\n", (int)&fecp->rcr, fecp->rcr);
+	printf("x_cntrl      %x - %x\n", (int)&fecp->tcr, fecp->tcr);
+	printf("padr_l       %x - %x\n", (int)&fecp->palr, fecp->palr);
+	printf("padr_u       %x - %x\n", (int)&fecp->paur, fecp->paur);
+	printf("op_pause     %x - %x\n", (int)&fecp->opd, fecp->opd);
+	printf("iadr_u       %x - %x\n", (int)&fecp->iaur, fecp->iaur);
+	printf("iadr_l       %x - %x\n", (int)&fecp->ialr, fecp->ialr);
+	printf("gadr_u       %x - %x\n", (int)&fecp->gaur, fecp->gaur);
+	printf("gadr_l       %x - %x\n", (int)&fecp->galr, fecp->galr);
+	printf("x_wmrk       %x - %x\n", (int)&fecp->tfwr, fecp->tfwr);
+	printf("r_bound      %x - %x\n", (int)&fecp->frbr, fecp->frbr);
+	printf("r_fstart     %x - %x\n", (int)&fecp->frsr, fecp->frsr);
+	printf("r_drng       %x - %x\n", (int)&fecp->erdsr, fecp->erdsr);
+	printf("x_drng       %x - %x\n", (int)&fecp->etdsr, fecp->etdsr);
+	printf("r_bufsz      %x - %x\n", (int)&fecp->emrbr, fecp->emrbr);
+
+	printf("\n");
+	printf("rmon_t_drop        %x - %x\n", (int)&fecp->rmon_t_drop,
+	       fecp->rmon_t_drop);
+	printf("rmon_t_packets     %x - %x\n", (int)&fecp->rmon_t_packets,
+	       fecp->rmon_t_packets);
+	printf("rmon_t_bc_pkt      %x - %x\n", (int)&fecp->rmon_t_bc_pkt,
+	       fecp->rmon_t_bc_pkt);
+	printf("rmon_t_mc_pkt      %x - %x\n", (int)&fecp->rmon_t_mc_pkt,
+	       fecp->rmon_t_mc_pkt);
+	printf("rmon_t_crc_align   %x - %x\n", (int)&fecp->rmon_t_crc_align,
+	       fecp->rmon_t_crc_align);
+	printf("rmon_t_undersize   %x - %x\n", (int)&fecp->rmon_t_undersize,
+	       fecp->rmon_t_undersize);
+	printf("rmon_t_oversize    %x - %x\n", (int)&fecp->rmon_t_oversize,
+	       fecp->rmon_t_oversize);
+	printf("rmon_t_frag        %x - %x\n", (int)&fecp->rmon_t_frag,
+	       fecp->rmon_t_frag);
+	printf("rmon_t_jab         %x - %x\n", (int)&fecp->rmon_t_jab,
+	       fecp->rmon_t_jab);
+	printf("rmon_t_col         %x - %x\n", (int)&fecp->rmon_t_col,
+	       fecp->rmon_t_col);
+	printf("rmon_t_p64         %x - %x\n", (int)&fecp->rmon_t_p64,
+	       fecp->rmon_t_p64);
+	printf("rmon_t_p65to127    %x - %x\n", (int)&fecp->rmon_t_p65to127,
+	       fecp->rmon_t_p65to127);
+	printf("rmon_t_p128to255   %x - %x\n", (int)&fecp->rmon_t_p128to255,
+	       fecp->rmon_t_p128to255);
+	printf("rmon_t_p256to511   %x - %x\n", (int)&fecp->rmon_t_p256to511,
+	       fecp->rmon_t_p256to511);
+	printf("rmon_t_p512to1023  %x - %x\n", (int)&fecp->rmon_t_p512to1023,
+	       fecp->rmon_t_p512to1023);
+	printf("rmon_t_p1024to2047 %x - %x\n", (int)&fecp->rmon_t_p1024to2047,
+	       fecp->rmon_t_p1024to2047);
+	printf("rmon_t_p_gte2048   %x - %x\n", (int)&fecp->rmon_t_p_gte2048,
+	       fecp->rmon_t_p_gte2048);
+	printf("rmon_t_octets      %x - %x\n", (int)&fecp->rmon_t_octets,
+	       fecp->rmon_t_octets);
+
+	printf("\n");
+	printf("ieee_t_drop      %x - %x\n", (int)&fecp->ieee_t_drop,
+	       fecp->ieee_t_drop);
+	printf("ieee_t_frame_ok  %x - %x\n", (int)&fecp->ieee_t_frame_ok,
+	       fecp->ieee_t_frame_ok);
+	printf("ieee_t_1col      %x - %x\n", (int)&fecp->ieee_t_1col,
+	       fecp->ieee_t_1col);
+	printf("ieee_t_mcol      %x - %x\n", (int)&fecp->ieee_t_mcol,
+	       fecp->ieee_t_mcol);
+	printf("ieee_t_def       %x - %x\n", (int)&fecp->ieee_t_def,
+	       fecp->ieee_t_def);
+	printf("ieee_t_lcol      %x - %x\n", (int)&fecp->ieee_t_lcol,
+	       fecp->ieee_t_lcol);
+	printf("ieee_t_excol     %x - %x\n", (int)&fecp->ieee_t_excol,
+	       fecp->ieee_t_excol);
+	printf("ieee_t_macerr    %x - %x\n", (int)&fecp->ieee_t_macerr,
+	       fecp->ieee_t_macerr);
+	printf("ieee_t_cserr     %x - %x\n", (int)&fecp->ieee_t_cserr,
+	       fecp->ieee_t_cserr);
+	printf("ieee_t_sqe       %x - %x\n", (int)&fecp->ieee_t_sqe,
+	       fecp->ieee_t_sqe);
+	printf("ieee_t_fdxfc     %x - %x\n", (int)&fecp->ieee_t_fdxfc,
+	       fecp->ieee_t_fdxfc);
+	printf("ieee_t_octets_ok %x - %x\n", (int)&fecp->ieee_t_octets_ok,
+	       fecp->ieee_t_octets_ok);
+
+	printf("\n");
+	printf("rmon_r_drop        %x - %x\n", (int)&fecp->rmon_r_drop,
+	       fecp->rmon_r_drop);
+	printf("rmon_r_packets     %x - %x\n", (int)&fecp->rmon_r_packets,
+	       fecp->rmon_r_packets);
+	printf("rmon_r_bc_pkt      %x - %x\n", (int)&fecp->rmon_r_bc_pkt,
+	       fecp->rmon_r_bc_pkt);
+	printf("rmon_r_mc_pkt      %x - %x\n", (int)&fecp->rmon_r_mc_pkt,
+	       fecp->rmon_r_mc_pkt);
+	printf("rmon_r_crc_align   %x - %x\n", (int)&fecp->rmon_r_crc_align,
+	       fecp->rmon_r_crc_align);
+	printf("rmon_r_undersize   %x - %x\n", (int)&fecp->rmon_r_undersize,
+	       fecp->rmon_r_undersize);
+	printf("rmon_r_oversize    %x - %x\n", (int)&fecp->rmon_r_oversize,
+	       fecp->rmon_r_oversize);
+	printf("rmon_r_frag        %x - %x\n", (int)&fecp->rmon_r_frag,
+	       fecp->rmon_r_frag);
+	printf("rmon_r_jab         %x - %x\n", (int)&fecp->rmon_r_jab,
+	       fecp->rmon_r_jab);
+	printf("rmon_r_p64         %x - %x\n", (int)&fecp->rmon_r_p64,
+	       fecp->rmon_r_p64);
+	printf("rmon_r_p65to127    %x - %x\n", (int)&fecp->rmon_r_p65to127,
+	       fecp->rmon_r_p65to127);
+	printf("rmon_r_p128to255   %x - %x\n", (int)&fecp->rmon_r_p128to255,
+	       fecp->rmon_r_p128to255);
+	printf("rmon_r_p256to511   %x - %x\n", (int)&fecp->rmon_r_p256to511,
+	       fecp->rmon_r_p256to511);
+	printf("rmon_r_p512to1023  %x - %x\n", (int)&fecp->rmon_r_p512to1023,
+	       fecp->rmon_r_p512to1023);
+	printf("rmon_r_p1024to2047 %x - %x\n", (int)&fecp->rmon_r_p1024to2047,
+	       fecp->rmon_r_p1024to2047);
+	printf("rmon_r_p_gte2048   %x - %x\n", (int)&fecp->rmon_r_p_gte2048,
+	       fecp->rmon_r_p_gte2048);
+	printf("rmon_r_octets      %x - %x\n", (int)&fecp->rmon_r_octets,
+	       fecp->rmon_r_octets);
+
+	printf("\n");
+	printf("ieee_r_drop      %x - %x\n", (int)&fecp->ieee_r_drop,
+	       fecp->ieee_r_drop);
+	printf("ieee_r_frame_ok  %x - %x\n", (int)&fecp->ieee_r_frame_ok,
+	       fecp->ieee_r_frame_ok);
+	printf("ieee_r_crc       %x - %x\n", (int)&fecp->ieee_r_crc,
+	       fecp->ieee_r_crc);
+	printf("ieee_r_align     %x - %x\n", (int)&fecp->ieee_r_align,
+	       fecp->ieee_r_align);
+	printf("ieee_r_macerr    %x - %x\n", (int)&fecp->ieee_r_macerr,
+	       fecp->ieee_r_macerr);
+	printf("ieee_r_fdxfc     %x - %x\n", (int)&fecp->ieee_r_fdxfc,
+	       fecp->ieee_r_fdxfc);
+	printf("ieee_r_octets_ok %x - %x\n", (int)&fecp->ieee_r_octets_ok,
+	       fecp->ieee_r_octets_ok);
+
+	printf("\n\n\n");
+}
+#endif
+
+int fec_init(struct eth_device *dev, bd_t * bd)
+{
+	struct fec_info_s *info = dev->priv;
+	volatile fec_t *fecp = (fec_t *) (info->iobase);
+	int i;
+	uchar ea[6];
+
+	fecpin_setclear(dev, 1);
+
+	fec_reset(dev);
+
+#if defined(CONFIG_CMD_MII) || defined (CONFIG_MII) || \
+	defined (CONFIG_SYS_DISCOVER_PHY)
+
+	mii_init();
+
+	setFecDuplexSpeed(fecp, bd, info->dup_spd);
+#else
+#ifndef CONFIG_SYS_DISCOVER_PHY
+	setFecDuplexSpeed(fecp, bd, (FECDUPLEX << 16) | FECSPEED);
+#endif				/* ifndef CONFIG_SYS_DISCOVER_PHY */
+#endif				/* CONFIG_CMD_MII || CONFIG_MII */
+
+	/* We use strictly polling mode only */
+	fecp->eimr = 0;
+
+	/* Clear any pending interrupt */
+	fecp->eir = 0xffffffff;
+
+	/* Set station address   */
+	if ((u32) fecp == CONFIG_SYS_FEC0_IOBASE) {
+#ifdef CONFIG_SYS_FEC1_IOBASE
+		volatile fec_t *fecp1 = (fec_t *) (CONFIG_SYS_FEC1_IOBASE);
+		eth_getenv_enetaddr("eth1addr", ea);
+		fecp1->palr =
+		    (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
+		fecp1->paur = (ea[4] << 24) | (ea[5] << 16);
+#endif
+		eth_getenv_enetaddr("ethaddr", ea);
+		fecp->palr =
+		    (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
+		fecp->paur = (ea[4] << 24) | (ea[5] << 16);
+	} else {
+#ifdef CONFIG_SYS_FEC0_IOBASE
+		volatile fec_t *fecp0 = (fec_t *) (CONFIG_SYS_FEC0_IOBASE);
+		eth_getenv_enetaddr("ethaddr", ea);
+		fecp0->palr =
+		    (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
+		fecp0->paur = (ea[4] << 24) | (ea[5] << 16);
+#endif
+#ifdef CONFIG_SYS_FEC1_IOBASE
+		eth_getenv_enetaddr("eth1addr", ea);
+		fecp->palr =
+		    (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
+		fecp->paur = (ea[4] << 24) | (ea[5] << 16);
+#endif
+	}
+
+	/* Clear unicast address hash table */
+	fecp->iaur = 0;
+	fecp->ialr = 0;
+
+	/* Clear multicast address hash table */
+	fecp->gaur = 0;
+	fecp->galr = 0;
+
+	/* Set maximum receive buffer size. */
+	fecp->emrbr = PKT_MAXBLR_SIZE;
+
+	/*
+	 * Setup Buffers and Buffer Desriptors
+	 */
+	info->rxIdx = 0;
+	info->txIdx = 0;
+
+	/*
+	 * Setup Receiver Buffer Descriptors (13.14.24.18)
+	 * Settings:
+	 *     Empty, Wrap
+	 */
+	for (i = 0; i < PKTBUFSRX; i++) {
+		info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
+		info->rxbd[i].cbd_datlen = 0;	/* Reset */
+		info->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+	}
+	info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
+
+	/*
+	 * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
+	 * Settings:
+	 *    Last, Tx CRC
+	 */
+	for (i = 0; i < TX_BUF_CNT; i++) {
+		info->txbd[i].cbd_sc = BD_ENET_TX_LAST | BD_ENET_TX_TC;
+		info->txbd[i].cbd_datlen = 0;	/* Reset */
+		info->txbd[i].cbd_bufaddr = (uint) (&info->txbuf[0]);
+	}
+	info->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
+
+	/* Set receive and transmit descriptor base */
+	fecp->erdsr = (unsigned int)(&info->rxbd[0]);
+	fecp->etdsr = (unsigned int)(&info->txbd[0]);
+
+	/* Now enable the transmit and receive processing */
+	fecp->ecr |= FEC_ECR_ETHER_EN;
+
+	/* And last, try to fill Rx Buffer Descriptors */
+	fecp->rdar = 0x01000000;	/* Descriptor polling active    */
+
+	return 1;
+}
+
+void fec_reset(struct eth_device *dev)
+{
+	struct fec_info_s *info = dev->priv;
+	volatile fec_t *fecp = (fec_t *) (info->iobase);
+	int i;
+
+	fecp->ecr = FEC_ECR_RESET;
+	for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) {
+		udelay(1);
+	}
+	if (i == FEC_RESET_DELAY) {
+		printf("FEC_RESET_DELAY timeout\n");
+	}
+}
+
+void fec_halt(struct eth_device *dev)
+{
+	struct fec_info_s *info = dev->priv;
+
+	fec_reset(dev);
+
+	fecpin_setclear(dev, 0);
+
+	info->rxIdx = info->txIdx = 0;
+	memset(info->rxbd, 0, PKTBUFSRX * sizeof(cbd_t));
+	memset(info->txbd, 0, TX_BUF_CNT * sizeof(cbd_t));
+	memset(info->txbuf, 0, DBUF_LENGTH);
+}
+
+int mcffec_initialize(bd_t * bis)
+{
+	struct eth_device *dev;
+	int i;
+#ifdef CONFIG_SYS_FEC_BUF_USE_SRAM
+	u32 tmp = CONFIG_SYS_INIT_RAM_ADDR + 0x1000;
+#endif
+
+	for (i = 0; i < ARRAY_SIZE(fec_info); i++) {
+
+		dev =
+		    (struct eth_device *)memalign(CONFIG_SYS_CACHELINE_SIZE,
+						  sizeof *dev);
+		if (dev == NULL)
+			hang();
+
+		memset(dev, 0, sizeof(*dev));
+
+		sprintf(dev->name, "FEC%d", fec_info[i].index);
+
+		dev->priv = &fec_info[i];
+		dev->init = fec_init;
+		dev->halt = fec_halt;
+		dev->send = fec_send;
+		dev->recv = fec_recv;
+
+		/* setup Receive and Transmit buffer descriptor */
+#ifdef CONFIG_SYS_FEC_BUF_USE_SRAM
+		fec_info[i].rxbd = (cbd_t *)((u32)fec_info[i].rxbd + tmp);
+		tmp = (u32)fec_info[i].rxbd;
+		fec_info[i].txbd =
+		    (cbd_t *)((u32)fec_info[i].txbd + tmp +
+		    (PKTBUFSRX * sizeof(cbd_t)));
+		tmp = (u32)fec_info[i].txbd;
+		fec_info[i].txbuf =
+		    (char *)((u32)fec_info[i].txbuf + tmp +
+		    (CONFIG_SYS_TX_ETH_BUFFER * sizeof(cbd_t)));
+		tmp = (u32)fec_info[i].txbuf;
+#else
+		fec_info[i].rxbd =
+		    (cbd_t *) memalign(CONFIG_SYS_CACHELINE_SIZE,
+				       (PKTBUFSRX * sizeof(cbd_t)));
+		fec_info[i].txbd =
+		    (cbd_t *) memalign(CONFIG_SYS_CACHELINE_SIZE,
+				       (TX_BUF_CNT * sizeof(cbd_t)));
+		fec_info[i].txbuf =
+		    (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, DBUF_LENGTH);
+#endif
+
+#ifdef ET_DEBUG
+		printf("rxbd %x txbd %x\n",
+		       (int)fec_info[i].rxbd, (int)fec_info[i].txbd);
+#endif
+
+		fec_info[i].phy_name = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, 32);
+
+		eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+		miiphy_register(dev->name,
+				mcffec_miiphy_read, mcffec_miiphy_write);
+#endif
+		if (i > 0)
+			fec_info[i - 1].next = &fec_info[i];
+	}
+	fec_info[i - 1].next = &fec_info[0];
+
+	/* default speed */
+	bis->bi_ethspeed = 10;
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/mcfmii.c b/marvell/uboot/drivers/net/mcfmii.c
new file mode 100644
index 0000000..17a780c
--- /dev/null
+++ b/marvell/uboot/drivers/net/mcfmii.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2004-2008 Freescale Semiconductor, Inc.
+ * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <config.h>
+#include <net.h>
+#include <netdev.h>
+
+#ifdef CONFIG_MCF547x_8x
+#include <asm/fsl_mcdmafec.h>
+#else
+#include <asm/fec.h>
+#endif
+#include <asm/immap.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_CMD_NET)
+#undef MII_DEBUG
+#undef ET_DEBUG
+
+/*extern int fecpin_setclear(struct eth_device *dev, int setclear);*/
+
+#if defined(CONFIG_SYS_DISCOVER_PHY) || defined(CONFIG_CMD_MII)
+#include <miiphy.h>
+
+/* Make MII read/write commands for the FEC. */
+#define mk_mii_read(ADDR, REG)		(0x60020000 | ((ADDR << 23) | \
+					 (REG & 0x1f) << 18))
+#define mk_mii_write(ADDR, REG, VAL)	(0x50020000 | ((ADDR << 23) | \
+					 (REG & 0x1f) << 18) | (VAL & 0xffff))
+
+#ifndef CONFIG_SYS_UNSPEC_PHYID
+#	define CONFIG_SYS_UNSPEC_PHYID		0
+#endif
+#ifndef CONFIG_SYS_UNSPEC_STRID
+#	define CONFIG_SYS_UNSPEC_STRID		0
+#endif
+
+#ifdef CONFIG_MCF547x_8x
+typedef struct fec_info_dma FEC_INFO_T;
+#define FEC_T fecdma_t
+#else
+typedef struct fec_info_s FEC_INFO_T;
+#define FEC_T fec_t
+#endif
+
+typedef struct phy_info_struct {
+	u32 phyid;
+	char *strid;
+} phy_info_t;
+
+phy_info_t phyinfo[] = {
+	{0x0022561B, "AMD79C784VC"},	/* AMD 79C784VC */
+	{0x00406322, "BCM5222"},	/* Broadcom 5222 */
+	{0x02a80150, "Intel82555"},	/* Intel 82555 */
+	{0x0016f870, "LSI80225"},	/* LSI 80225 */
+	{0x0016f880, "LSI80225/B"},	/* LSI 80225/B */
+	{0x78100000, "LXT970"},		/* LXT970 */
+	{0x001378e0, "LXT971"},		/* LXT971 and 972 */
+	{0x00221619, "KS8721BL"},	/* Micrel KS8721BL/SL */
+	{0x00221512, "KSZ8041NL"},	/* Micrel KSZ8041NL */
+	{0x20005CE1, "N83640"},		/* National 83640 */
+	{0x20005C90, "N83848"},		/* National 83848 */
+	{0x20005CA2, "N83849"},		/* National 83849 */
+	{0x01814400, "QS6612"},		/* QS6612 */
+#if defined(CONFIG_SYS_UNSPEC_PHYID) && defined(CONFIG_SYS_UNSPEC_STRID)
+	{CONFIG_SYS_UNSPEC_PHYID, CONFIG_SYS_UNSPEC_STRID},
+#endif
+	{0, 0}
+};
+
+/*
+ * mii_init -- Initialize the MII for MII command without ethernet
+ * This function is a subset of eth_init
+ */
+void mii_reset(FEC_INFO_T *info)
+{
+	volatile FEC_T *fecp = (FEC_T *) (info->miibase);
+	int i;
+
+	fecp->ecr = FEC_ECR_RESET;
+
+	for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) {
+		udelay(1);
+	}
+	if (i == FEC_RESET_DELAY)
+		printf("FEC_RESET_DELAY timeout\n");
+}
+
+/* send command to phy using mii, wait for result */
+uint mii_send(uint mii_cmd)
+{
+	FEC_INFO_T *info;
+	volatile FEC_T *ep;
+	struct eth_device *dev;
+	uint mii_reply;
+	int j = 0;
+
+	/* retrieve from register structure */
+	dev = eth_get_dev();
+	info = dev->priv;
+
+	ep = (FEC_T *) info->miibase;
+
+	ep->mmfr = mii_cmd;	/* command to phy */
+
+	/* wait for mii complete */
+	while (!(ep->eir & FEC_EIR_MII) && (j < MCFFEC_TOUT_LOOP)) {
+		udelay(1);
+		j++;
+	}
+	if (j >= MCFFEC_TOUT_LOOP) {
+		printf("MII not complete\n");
+		return -1;
+	}
+
+	mii_reply = ep->mmfr;	/* result from phy */
+	ep->eir = FEC_EIR_MII;	/* clear MII complete */
+#ifdef ET_DEBUG
+	printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n",
+	       __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply);
+#endif
+
+	return (mii_reply & 0xffff);	/* data read from phy */
+}
+#endif				/* CONFIG_SYS_DISCOVER_PHY || (CONFIG_MII) */
+
+#if defined(CONFIG_SYS_DISCOVER_PHY)
+int mii_discover_phy(struct eth_device *dev)
+{
+#define MAX_PHY_PASSES 11
+	FEC_INFO_T *info = dev->priv;
+	int phyaddr, pass;
+	uint phyno, phytype;
+	int i, found = 0;
+
+	if (info->phyname_init)
+		return info->phy_addr;
+
+	phyaddr = -1;		/* didn't find a PHY yet */
+	for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) {
+		if (pass > 1) {
+			/* PHY may need more time to recover from reset.
+			 * The LXT970 needs 50ms typical, no maximum is
+			 * specified, so wait 10ms before try again.
+			 * With 11 passes this gives it 100ms to wake up.
+			 */
+			udelay(10000);	/* wait 10ms */
+		}
+
+		for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) {
+
+			phytype = mii_send(mk_mii_read(phyno, MII_PHYSID1));
+#ifdef ET_DEBUG
+			printf("PHY type 0x%x pass %d type\n", phytype, pass);
+#endif
+			if (phytype == 0xffff)
+				continue;
+			phyaddr = phyno;
+			phytype <<= 16;
+			phytype |=
+			    mii_send(mk_mii_read(phyno, MII_PHYSID2));
+
+#ifdef ET_DEBUG
+			printf("PHY @ 0x%x pass %d\n", phyno, pass);
+#endif
+
+			for (i = 0; (i < ARRAY_SIZE(phyinfo))
+				&& (phyinfo[i].phyid != 0); i++) {
+				if (phyinfo[i].phyid == phytype) {
+#ifdef ET_DEBUG
+					printf("phyid %x - %s\n",
+					       phyinfo[i].phyid,
+					       phyinfo[i].strid);
+#endif
+					strcpy(info->phy_name, phyinfo[i].strid);
+					info->phyname_init = 1;
+					found = 1;
+					break;
+				}
+			}
+
+			if (!found) {
+#ifdef ET_DEBUG
+				printf("0x%08x\n", phytype);
+#endif
+				strcpy(info->phy_name, "unknown");
+				info->phyname_init = 1;
+				break;
+			}
+		}
+	}
+
+	if (phyaddr < 0)
+		printf("No PHY device found.\n");
+
+	return phyaddr;
+}
+#endif				/* CONFIG_SYS_DISCOVER_PHY */
+
+void mii_init(void) __attribute__((weak,alias("__mii_init")));
+
+void __mii_init(void)
+{
+	FEC_INFO_T *info;
+	volatile FEC_T *fecp;
+	struct eth_device *dev;
+	int miispd = 0, i = 0;
+	u16 status = 0;
+	u16 linkgood = 0;
+
+	/* retrieve from register structure */
+	dev = eth_get_dev();
+	info = dev->priv;
+
+	fecp = (FEC_T *) info->miibase;
+
+	fecpin_setclear(dev, 1);
+
+	mii_reset(info);
+
+	/* We use strictly polling mode only */
+	fecp->eimr = 0;
+
+	/* Clear any pending interrupt */
+	fecp->eir = 0xffffffff;
+
+	/* Set MII speed */
+	miispd = (gd->bus_clk / 1000000) / 5;
+	fecp->mscr = miispd << 1;
+
+	info->phy_addr = mii_discover_phy(dev);
+
+	while (i < MCFFEC_TOUT_LOOP) {
+		status = 0;
+		i++;
+		/* Read PHY control register */
+		miiphy_read(dev->name, info->phy_addr, MII_BMCR, &status);
+
+		/* If phy set to autonegotiate, wait for autonegotiation done,
+		 * if phy is not autonegotiating, just wait for link up.
+		 */
+		if ((status & BMCR_ANENABLE) == BMCR_ANENABLE) {
+			linkgood = (BMSR_ANEGCOMPLETE | BMSR_LSTATUS);
+		} else {
+			linkgood = BMSR_LSTATUS;
+		}
+		/* Read PHY status register */
+		miiphy_read(dev->name, info->phy_addr, MII_BMSR, &status);
+		if ((status & linkgood) == linkgood)
+			break;
+
+		udelay(1);
+	}
+	if (i >= MCFFEC_TOUT_LOOP) {
+		printf("Link UP timeout\n");
+	}
+
+	/* adapt to the duplex and speed settings of the phy */
+	info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16;
+	info->dup_spd |= miiphy_speed(dev->name, info->phy_addr);
+}
+
+/*
+ * Read and write a MII PHY register, routines used by MII Utilities
+ *
+ * FIXME: These routines are expected to return 0 on success, but mii_send
+ *	  does _not_ return an error code. Maybe 0xFFFF means error, i.e.
+ *	  no PHY connected...
+ *	  For now always return 0.
+ * FIXME: These routines only work after calling eth_init() at least once!
+ *	  Otherwise they hang in mii_send() !!! Sorry!
+ */
+
+int mcffec_miiphy_read(const char *devname, unsigned char addr, unsigned char reg,
+		       unsigned short *value)
+{
+	short rdreg;		/* register working value */
+
+#ifdef MII_DEBUG
+	printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr);
+#endif
+	rdreg = mii_send(mk_mii_read(addr, reg));
+
+	*value = rdreg;
+
+#ifdef MII_DEBUG
+	printf("0x%04x\n", *value);
+#endif
+
+	return 0;
+}
+
+int mcffec_miiphy_write(const char *devname, unsigned char addr, unsigned char reg,
+			unsigned short value)
+{
+#ifdef MII_DEBUG
+	printf("miiphy_write(0x%x) @ 0x%x = ", reg, addr);
+#endif
+
+	mii_send(mk_mii_write(addr, reg, value));
+
+#ifdef MII_DEBUG
+	printf("0x%04x\n", value);
+#endif
+
+	return 0;
+}
+
+#endif				/* CONFIG_CMD_NET */
diff --git a/marvell/uboot/drivers/net/mpc512x_fec.c b/marvell/uboot/drivers/net/mpc512x_fec.c
new file mode 100644
index 0000000..427e0b8
--- /dev/null
+++ b/marvell/uboot/drivers/net/mpc512x_fec.c
@@ -0,0 +1,754 @@
+/*
+ * (C) Copyright 2003-2010
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Derived from the MPC8xx FEC driver.
+ * Adapted for MPC512x by Grzegorz Bernacki <gjb@semihalf.com>
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <miiphy.h>
+#include <asm/io.h>
+#include "mpc512x_fec.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define DEBUG 0
+
+#if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
+#error "CONFIG_MII has to be defined!"
+#endif
+
+int fec512x_miiphy_read(const char *devname, u8 phyAddr, u8 regAddr, u16 * retVal);
+int fec512x_miiphy_write(const char *devname, u8 phyAddr, u8 regAddr, u16 data);
+int mpc512x_fec_init_phy(struct eth_device *dev, bd_t * bis);
+
+static uchar rx_buff[FEC_BUFFER_SIZE];
+static int rx_buff_idx = 0;
+
+/********************************************************************/
+#if (DEBUG & 0x2)
+static void mpc512x_fec_phydump (char *devname)
+{
+	u16 phyStatus, i;
+	u8 phyAddr = CONFIG_PHY_ADDR;
+	u8 reg_mask[] = {
+		/* regs to print: 0...8, 21,27,31 */
+		1, 1, 1, 1,  1, 1, 1, 1,     1, 0, 0, 0,  0, 0, 0, 0,
+		0, 0, 0, 0,  0, 1, 0, 0,     0, 0, 0, 1,  0, 0, 0, 1,
+	};
+
+	for (i = 0; i < 32; i++) {
+		if (reg_mask[i]) {
+			miiphy_read (devname, phyAddr, i, &phyStatus);
+			printf ("Mii reg %d: 0x%04x\n", i, phyStatus);
+		}
+	}
+}
+#endif
+
+/********************************************************************/
+static int mpc512x_fec_bd_init (mpc512x_fec_priv *fec)
+{
+	int ix;
+
+	/*
+	 * Receive BDs init
+	 */
+	for (ix = 0; ix < FEC_RBD_NUM; ix++) {
+		fec->bdBase->rbd[ix].dataPointer =
+				(u32)&fec->bdBase->recv_frames[ix];
+		fec->bdBase->rbd[ix].status = FEC_RBD_EMPTY;
+		fec->bdBase->rbd[ix].dataLength = 0;
+	}
+
+	/*
+	 * have the last RBD to close the ring
+	 */
+	fec->bdBase->rbd[ix - 1].status |= FEC_RBD_WRAP;
+	fec->rbdIndex = 0;
+
+	/*
+	 * Trasmit BDs init
+	 */
+	for (ix = 0; ix < FEC_TBD_NUM; ix++) {
+		fec->bdBase->tbd[ix].status = 0;
+	}
+
+	/*
+	 * Have the last TBD to close the ring
+	 */
+	fec->bdBase->tbd[ix - 1].status |= FEC_TBD_WRAP;
+
+	/*
+	 * Initialize some indices
+	 */
+	fec->tbdIndex = 0;
+	fec->usedTbdIndex = 0;
+	fec->cleanTbdNum = FEC_TBD_NUM;
+
+	return 0;
+}
+
+/********************************************************************/
+static void mpc512x_fec_rbd_clean (mpc512x_fec_priv *fec, volatile FEC_RBD * pRbd)
+{
+	/*
+	 * Reset buffer descriptor as empty
+	 */
+	if ((fec->rbdIndex) == (FEC_RBD_NUM - 1))
+		pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY);
+	else
+		pRbd->status = FEC_RBD_EMPTY;
+
+	pRbd->dataLength = 0;
+
+	/*
+	 * Increment BD count
+	 */
+	fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM;
+
+	/*
+	 * Now, we have an empty RxBD, notify FEC
+	 * Set Descriptor polling active
+	 */
+	out_be32(&fec->eth->r_des_active, 0x01000000);
+}
+
+/********************************************************************/
+static void mpc512x_fec_tbd_scrub (mpc512x_fec_priv *fec)
+{
+	volatile FEC_TBD *pUsedTbd;
+
+#if (DEBUG & 0x1)
+	printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n",
+		fec->cleanTbdNum, fec->usedTbdIndex);
+#endif
+
+	/*
+	 * process all the consumed TBDs
+	 */
+	while (fec->cleanTbdNum < FEC_TBD_NUM) {
+		pUsedTbd = &fec->bdBase->tbd[fec->usedTbdIndex];
+		if (pUsedTbd->status & FEC_TBD_READY) {
+#if (DEBUG & 0x20)
+			printf ("Cannot clean TBD %d, in use\n", fec->usedTbdIndex);
+#endif
+			return;
+		}
+
+		/*
+		 * clean this buffer descriptor
+		 */
+		if (fec->usedTbdIndex == (FEC_TBD_NUM - 1))
+			pUsedTbd->status = FEC_TBD_WRAP;
+		else
+			pUsedTbd->status = 0;
+
+		/*
+		 * update some indeces for a correct handling of the TBD ring
+		 */
+		fec->cleanTbdNum++;
+		fec->usedTbdIndex = (fec->usedTbdIndex + 1) % FEC_TBD_NUM;
+	}
+}
+
+/********************************************************************/
+static void mpc512x_fec_set_hwaddr (mpc512x_fec_priv *fec, unsigned char *mac)
+{
+	u8 currByte;			/* byte for which to compute the CRC */
+	int byte;			/* loop - counter */
+	int bit;			/* loop - counter */
+	u32 crc = 0xffffffff;		/* initial value */
+
+	/*
+	 * The algorithm used is the following:
+	 * we loop on each of the six bytes of the provided address,
+	 * and we compute the CRC by left-shifting the previous
+	 * value by one position, so that each bit in the current
+	 * byte of the address may contribute the calculation. If
+	 * the latter and the MSB in the CRC are different, then
+	 * the CRC value so computed is also ex-ored with the
+	 * "polynomium generator". The current byte of the address
+	 * is also shifted right by one bit at each iteration.
+	 * This is because the CRC generatore in hardware is implemented
+	 * as a shift-register with as many ex-ores as the radixes
+	 * in the polynomium. This suggests that we represent the
+	 * polynomiumm itself as a 32-bit constant.
+	 */
+	for (byte = 0; byte < 6; byte++) {
+		currByte = mac[byte];
+		for (bit = 0; bit < 8; bit++) {
+			if ((currByte & 0x01) ^ (crc & 0x01)) {
+				crc >>= 1;
+				crc = crc ^ 0xedb88320;
+			} else {
+				crc >>= 1;
+			}
+			currByte >>= 1;
+		}
+	}
+
+	crc = crc >> 26;
+
+	/*
+	 * Set individual hash table register
+	 */
+	if (crc >= 32) {
+		out_be32(&fec->eth->iaddr1, (1 << (crc - 32)));
+		out_be32(&fec->eth->iaddr2, 0);
+	} else {
+		out_be32(&fec->eth->iaddr1, 0);
+		out_be32(&fec->eth->iaddr2, (1 << crc));
+	}
+
+	/*
+	 * Set physical address
+	 */
+	out_be32(&fec->eth->paddr1, (mac[0] << 24) + (mac[1] << 16) +
+				    (mac[2] <<  8) + mac[3]);
+	out_be32(&fec->eth->paddr2, (mac[4] << 24) + (mac[5] << 16) +
+				     0x8808);
+}
+
+/********************************************************************/
+static int mpc512x_fec_init (struct eth_device *dev, bd_t * bis)
+{
+	mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
+
+#if (DEBUG & 0x1)
+	printf ("mpc512x_fec_init... Begin\n");
+#endif
+
+	mpc512x_fec_set_hwaddr (fec, dev->enetaddr);
+	out_be32(&fec->eth->gaddr1, 0x00000000);
+	out_be32(&fec->eth->gaddr2, 0x00000000);
+
+	mpc512x_fec_init_phy (dev, bis);
+
+	/* Set interrupt mask register */
+	out_be32(&fec->eth->imask, 0x00000000);
+
+	/* Clear FEC-Lite interrupt event register(IEVENT) */
+	out_be32(&fec->eth->ievent, 0xffffffff);
+
+	/* Set transmit fifo watermark register(X_WMRK), default = 64 */
+	out_be32(&fec->eth->x_wmrk, 0x0);
+
+	/* Set Opcode/Pause Duration Register */
+	out_be32(&fec->eth->op_pause, 0x00010020);
+
+	/* Frame length=1522; MII mode */
+	out_be32(&fec->eth->r_cntrl, (FEC_MAX_FRAME_LEN << 16) | 0x24);
+
+	/* Half-duplex, heartbeat disabled */
+	out_be32(&fec->eth->x_cntrl, 0x00000000);
+
+	/* Enable MIB counters */
+	out_be32(&fec->eth->mib_control, 0x0);
+
+	/* Setup recv fifo start and buff size */
+	out_be32(&fec->eth->r_fstart, 0x500);
+	out_be32(&fec->eth->r_buff_size, FEC_BUFFER_SIZE);
+
+	/* Setup BD base addresses */
+	out_be32(&fec->eth->r_des_start, (u32)fec->bdBase->rbd);
+	out_be32(&fec->eth->x_des_start, (u32)fec->bdBase->tbd);
+
+	/* DMA Control */
+	out_be32(&fec->eth->dma_control, 0xc0000000);
+
+	/* Enable FEC */
+	setbits_be32(&fec->eth->ecntrl, 0x00000006);
+
+	/* Initilize addresses and status words of BDs */
+	mpc512x_fec_bd_init (fec);
+
+	 /* Descriptor polling active */
+	out_be32(&fec->eth->r_des_active, 0x01000000);
+
+#if (DEBUG & 0x1)
+	printf("mpc512x_fec_init... Done \n");
+#endif
+	return 1;
+}
+
+/********************************************************************/
+int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis)
+{
+	mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
+	const u8 phyAddr = CONFIG_PHY_ADDR;	/* Only one PHY */
+	int timeout = 1;
+	u16 phyStatus;
+
+#if (DEBUG & 0x1)
+	printf ("mpc512x_fec_init_phy... Begin\n");
+#endif
+
+	/*
+	 * Clear FEC-Lite interrupt event register(IEVENT)
+	 */
+	out_be32(&fec->eth->ievent, 0xffffffff);
+
+	/*
+	 * Set interrupt mask register
+	 */
+	out_be32(&fec->eth->imask, 0x00000000);
+
+	if (fec->xcv_type != SEVENWIRE) {
+		/*
+		 * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
+		 * and do not drop the Preamble.
+		 */
+		out_be32(&fec->eth->mii_speed,
+			 (((gd->arch.ips_clk / 1000000) / 5) + 1) << 1);
+
+		/*
+		 * Reset PHY, then delay 300ns
+		 */
+		miiphy_write (dev->name, phyAddr, 0x0, 0x8000);
+		udelay (1000);
+
+		if (fec->xcv_type == MII10) {
+		/*
+		 * Force 10Base-T, FDX operation
+		 */
+#if (DEBUG & 0x2)
+			printf ("Forcing 10 Mbps ethernet link... ");
+#endif
+			miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
+
+			miiphy_write (dev->name, phyAddr, 0x0, 0x0180);
+
+			timeout = 20;
+			do {    /* wait for link status to go down */
+				udelay (10000);
+				if ((timeout--) == 0) {
+#if (DEBUG & 0x2)
+					printf ("hmmm, should not have waited...");
+#endif
+					break;
+				}
+				miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
+#if (DEBUG & 0x2)
+				printf ("=");
+#endif
+			} while ((phyStatus & 0x0004)); /* !link up */
+
+			timeout = 1000;
+			do {    /* wait for link status to come back up */
+				udelay (10000);
+				if ((timeout--) == 0) {
+					printf ("failed. Link is down.\n");
+					break;
+				}
+				miiphy_read (dev->name, phyAddr, 0x1, &phyStatus);
+#if (DEBUG & 0x2)
+				printf ("+");
+#endif
+			} while (!(phyStatus & 0x0004)); /* !link up */
+
+#if (DEBUG & 0x2)
+			printf ("done.\n");
+#endif
+		} else {	/* MII100 */
+			/*
+			 * Set the auto-negotiation advertisement register bits
+			 */
+			miiphy_write (dev->name, phyAddr, 0x4, 0x01e1);
+
+			/*
+			 * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
+			 */
+			miiphy_write (dev->name, phyAddr, 0x0, 0x1200);
+
+			/*
+			 * Wait for AN completion
+			 */
+			timeout = 2500;
+			do {
+				udelay (1000);
+
+				if ((timeout--) == 0) {
+#if (DEBUG & 0x2)
+					printf ("PHY auto neg 0 failed...\n");
+#endif
+					return -1;
+				}
+
+				if (miiphy_read (dev->name, phyAddr, 0x1, &phyStatus) != 0) {
+#if (DEBUG & 0x2)
+					printf ("PHY auto neg 1 failed 0x%04x...\n", phyStatus);
+#endif
+					return -1;
+				}
+			} while (!(phyStatus & 0x0004));
+
+#if (DEBUG & 0x2)
+			printf ("PHY auto neg complete! \n");
+#endif
+		}
+	}
+
+#if (DEBUG & 0x2)
+	if (fec->xcv_type != SEVENWIRE)
+		mpc512x_fec_phydump (dev->name);
+#endif
+
+#if (DEBUG & 0x1)
+	printf ("mpc512x_fec_init_phy... Done \n");
+#endif
+	return 1;
+}
+
+/********************************************************************/
+static void mpc512x_fec_halt (struct eth_device *dev)
+{
+	mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
+	int counter = 0xffff;
+
+#if (DEBUG & 0x2)
+	if (fec->xcv_type != SEVENWIRE)
+		mpc512x_fec_phydump (dev->name);
+#endif
+
+	/*
+	 * mask FEC chip interrupts
+	 */
+	out_be32(&fec->eth->imask, 0);
+
+	/*
+	 * issue graceful stop command to the FEC transmitter if necessary
+	 */
+	setbits_be32(&fec->eth->x_cntrl, 0x00000001);
+
+	/*
+	 * wait for graceful stop to register
+	 */
+	while ((counter--) && (!(in_be32(&fec->eth->ievent) & 0x10000000)))
+		;
+
+	/*
+	 * Disable the Ethernet Controller
+	 */
+	clrbits_be32(&fec->eth->ecntrl, 0x00000002);
+
+	/*
+	 * Issue a reset command to the FEC chip
+	 */
+	setbits_be32(&fec->eth->ecntrl, 0x1);
+
+	/*
+	 * wait at least 16 clock cycles
+	 */
+	udelay (10);
+#if (DEBUG & 0x3)
+	printf ("Ethernet task stopped\n");
+#endif
+}
+
+/********************************************************************/
+
+static int mpc512x_fec_send(struct eth_device *dev, void *eth_data,
+			    int data_length)
+{
+	/*
+	 * This routine transmits one frame.  This routine only accepts
+	 * 6-byte Ethernet addresses.
+	 */
+	mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
+	volatile FEC_TBD *pTbd;
+
+#if (DEBUG & 0x20)
+	printf("tbd status: 0x%04x\n", fec->tbdBase[fec->tbdIndex].status);
+#endif
+
+	/*
+	 * Clear Tx BD ring at first
+	 */
+	mpc512x_fec_tbd_scrub (fec);
+
+	/*
+	 * Check for valid length of data.
+	 */
+	if ((data_length > 1500) || (data_length <= 0)) {
+		return -1;
+	}
+
+	/*
+	 * Check the number of vacant TxBDs.
+	 */
+	if (fec->cleanTbdNum < 1) {
+#if (DEBUG & 0x20)
+		printf ("No available TxBDs ...\n");
+#endif
+		return -1;
+	}
+
+	/*
+	 * Get the first TxBD to send the mac header
+	 */
+	pTbd = &fec->bdBase->tbd[fec->tbdIndex];
+	pTbd->dataLength = data_length;
+	pTbd->dataPointer = (u32)eth_data;
+	pTbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
+	fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM;
+
+	/* Activate transmit Buffer Descriptor polling */
+	out_be32(&fec->eth->x_des_active, 0x01000000);
+
+#if (DEBUG & 0x8)
+	printf ( "+" );
+#endif
+
+	fec->cleanTbdNum -= 1;
+
+	/*
+	 * wait until frame is sent .
+	 */
+	while (pTbd->status & FEC_TBD_READY) {
+		udelay (10);
+#if (DEBUG & 0x8)
+		printf ("TDB status = %04x\n", pTbd->status);
+#endif
+	}
+
+	return 0;
+}
+
+
+/********************************************************************/
+static int mpc512x_fec_recv (struct eth_device *dev)
+{
+	/*
+	 * This command pulls one frame from the card
+	 */
+	mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
+	volatile FEC_RBD *pRbd = &fec->bdBase->rbd[fec->rbdIndex];
+	unsigned long ievent;
+	int frame_length = 0;
+
+#if (DEBUG & 0x1)
+	printf ("mpc512x_fec_recv %d Start...\n", fec->rbdIndex);
+#endif
+#if (DEBUG & 0x8)
+	printf( "-" );
+#endif
+
+	/*
+	 * Check if any critical events have happened
+	 */
+	ievent = in_be32(&fec->eth->ievent);
+	out_be32(&fec->eth->ievent, ievent);
+	if (ievent & 0x20060000) {
+		/* BABT, Rx/Tx FIFO errors */
+		mpc512x_fec_halt (dev);
+		mpc512x_fec_init (dev, NULL);
+		return 0;
+	}
+	if (ievent & 0x80000000) {
+		/* Heartbeat error */
+		setbits_be32(&fec->eth->x_cntrl, 0x00000001);
+	}
+	if (ievent & 0x10000000) {
+		/* Graceful stop complete */
+		if (in_be32(&fec->eth->x_cntrl) & 0x00000001) {
+			mpc512x_fec_halt (dev);
+			clrbits_be32(&fec->eth->x_cntrl, 0x00000001);;
+			mpc512x_fec_init (dev, NULL);
+		}
+	}
+
+	if (!(pRbd->status & FEC_RBD_EMPTY)) {
+		if (!(pRbd->status & FEC_RBD_ERR) &&
+			((pRbd->dataLength - 4) > 14)) {
+
+			/*
+			 * Get buffer size
+			 */
+			if (pRbd->status & FEC_RBD_LAST)
+				frame_length = pRbd->dataLength - 4;
+			else
+				frame_length = pRbd->dataLength;
+#if (DEBUG & 0x20)
+			{
+				int i;
+				printf ("recv data length 0x%08x data hdr: ",
+					pRbd->dataLength);
+				for (i = 0; i < 14; i++)
+					printf ("%x ", *((u8*)pRbd->dataPointer + i));
+				printf("\n");
+			}
+#endif
+			/*
+			 *  Fill the buffer and pass it to upper layers
+			 */
+			memcpy (&rx_buff[rx_buff_idx], (void*)pRbd->dataPointer,
+				frame_length - rx_buff_idx);
+			rx_buff_idx = frame_length;
+
+			if (pRbd->status & FEC_RBD_LAST) {
+				NetReceive ((uchar*)rx_buff, frame_length);
+				rx_buff_idx = 0;
+			}
+		}
+
+		/*
+		 * Reset buffer descriptor as empty
+		 */
+		mpc512x_fec_rbd_clean (fec, pRbd);
+	}
+
+	/* Try to fill Buffer Descriptors */
+	out_be32(&fec->eth->r_des_active, 0x01000000);
+
+	return frame_length;
+}
+
+/********************************************************************/
+int mpc512x_fec_initialize (bd_t * bis)
+{
+	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
+	mpc512x_fec_priv *fec;
+	struct eth_device *dev;
+	void * bd;
+
+	fec = (mpc512x_fec_priv *) malloc (sizeof(*fec));
+	dev = (struct eth_device *) malloc (sizeof(*dev));
+	memset (dev, 0, sizeof *dev);
+
+	fec->eth = &im->fec;
+
+# ifndef CONFIG_FEC_10MBIT
+	fec->xcv_type = MII100;
+# else
+	fec->xcv_type = MII10;
+# endif
+	dev->priv = (void *)fec;
+	dev->iobase = (int)&im->fec;
+	dev->init = mpc512x_fec_init;
+	dev->halt = mpc512x_fec_halt;
+	dev->send = mpc512x_fec_send;
+	dev->recv = mpc512x_fec_recv;
+
+	sprintf (dev->name, "FEC");
+	eth_register (dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	miiphy_register (dev->name,
+			fec512x_miiphy_read, fec512x_miiphy_write);
+#endif
+
+	/* Clean up space FEC's MIB and FIFO RAM ...*/
+	memset ((void *)&im->fec.mib,  0x00, sizeof(im->fec.mib));
+	memset ((void *)&im->fec.fifo, 0x00, sizeof(im->fec.fifo));
+
+	/*
+	 * Malloc space for BDs  (must be quad word-aligned)
+	 * this pointer is lost, so cannot be freed
+	 */
+	bd = malloc (sizeof(mpc512x_buff_descs) + 0x1f);
+	fec->bdBase = (mpc512x_buff_descs*)((u32)bd & 0xfffffff0);
+	memset ((void *) bd, 0x00, sizeof(mpc512x_buff_descs) + 0x1f);
+
+	/*
+	 * Set interrupt mask register
+	 */
+	out_be32(&fec->eth->imask, 0x00000000);
+
+	/*
+	 * Clear FEC-Lite interrupt event register(IEVENT)
+	 */
+	out_be32(&fec->eth->ievent, 0xffffffff);
+
+	return 1;
+}
+
+/* MII-interface related functions */
+/********************************************************************/
+int fec512x_miiphy_read(const char *devname, u8 phyAddr, u8 regAddr, u16 *retVal)
+{
+	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
+	volatile fec512x_t *eth = &im->fec;
+	u32 reg;		/* convenient holder for the PHY register */
+	u32 phy;		/* convenient holder for the PHY */
+	int timeout = 0xffff;
+
+	/*
+	 * reading from any PHY's register is done by properly
+	 * programming the FEC's MII data register.
+	 */
+	reg = regAddr << FEC_MII_DATA_RA_SHIFT;
+	phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
+
+	out_be32(&eth->mii_data, FEC_MII_DATA_ST |
+				 FEC_MII_DATA_OP_RD |
+				 FEC_MII_DATA_TA |
+				 phy | reg);
+
+	/*
+	 * wait for the related interrupt
+	 */
+	while ((timeout--) && (!(in_be32(&eth->ievent) & 0x00800000)))
+		;
+
+	if (timeout == 0) {
+#if (DEBUG & 0x2)
+		printf ("Read MDIO failed...\n");
+#endif
+		return -1;
+	}
+
+	/*
+	 * clear mii interrupt bit
+	 */
+	out_be32(&eth->ievent, 0x00800000);
+
+	/*
+	 * it's now safe to read the PHY's register
+	 */
+	*retVal = (u16) in_be32(&eth->mii_data);
+
+	return 0;
+}
+
+/********************************************************************/
+int fec512x_miiphy_write(const char *devname, u8 phyAddr, u8 regAddr, u16 data)
+{
+	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
+	volatile fec512x_t *eth = &im->fec;
+	u32 reg;		/* convenient holder for the PHY register */
+	u32 phy;		/* convenient holder for the PHY */
+	int timeout = 0xffff;
+
+	reg = regAddr << FEC_MII_DATA_RA_SHIFT;
+	phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
+
+	out_be32(&eth->mii_data, FEC_MII_DATA_ST |
+				 FEC_MII_DATA_OP_WR |
+				 FEC_MII_DATA_TA |
+				 phy | reg | data);
+
+	/*
+	 * wait for the MII interrupt
+	 */
+	while ((timeout--) && (!(in_be32(&eth->ievent) & 0x00800000)))
+		;
+
+	if (timeout == 0) {
+#if (DEBUG & 0x2)
+		printf ("Write MDIO failed...\n");
+#endif
+		return -1;
+	}
+
+	/*
+	 * clear MII interrupt bit
+	 */
+	out_be32(&eth->ievent, 0x00800000);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/mpc512x_fec.h b/marvell/uboot/drivers/net/mpc512x_fec.h
new file mode 100644
index 0000000..a083cca
--- /dev/null
+++ b/marvell/uboot/drivers/net/mpc512x_fec.h
@@ -0,0 +1,98 @@
+/*
+ * (C) Copyright 2003 - 2009
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Derived from the MPC8xx driver's header file.
+ */
+
+#ifndef __MPC512X_FEC_H
+#define __MPC512X_FEC_H
+
+#include <common.h>
+
+/* Receive & Transmit Buffer Descriptor definitions */
+typedef struct BufferDescriptor {
+	u16 status;
+	u16 dataLength;
+	u32 dataPointer;
+} FEC_RBD;
+
+typedef struct {
+	u16 status;
+	u16 dataLength;
+	u32 dataPointer;
+} FEC_TBD;
+
+/* private structure */
+typedef enum {
+	SEVENWIRE,			/* 7-wire       */
+	MII10,				/* MII 10Mbps   */
+	MII100				/* MII 100Mbps  */
+} xceiver_type;
+
+/* BD Numer definitions */
+#define FEC_TBD_NUM		48	/* The user can adjust this value */
+#define FEC_RBD_NUM		32	/* The user can adjust this value */
+
+/* packet size limit */
+#define FEC_MAX_FRAME_LEN	1522	/* recommended default value */
+
+/* Buffer size must be evenly divisible by 16 */
+#define FEC_BUFFER_SIZE		((FEC_MAX_FRAME_LEN + 0x10) & (~0xf))
+
+typedef struct {
+	u8 frame[FEC_BUFFER_SIZE];
+} mpc512x_frame;
+
+typedef struct {
+	FEC_RBD rbd[FEC_RBD_NUM];			/* RBD ring */
+	FEC_TBD tbd[FEC_TBD_NUM];			/* TBD ring */
+	mpc512x_frame recv_frames[FEC_RBD_NUM];		/* receive buff */
+} mpc512x_buff_descs;
+
+typedef struct {
+	volatile fec512x_t *eth;
+	xceiver_type xcv_type;		/* transceiver type */
+	mpc512x_buff_descs *bdBase;	/* BD rings and recv buffer */
+	u16 rbdIndex;			/* next receive BD to read */
+	u16 tbdIndex;			/* next transmit BD to send */
+	u16 usedTbdIndex;		/* next transmit BD to clean */
+	u16 cleanTbdNum;		/* the number of available transmit BDs */
+} mpc512x_fec_priv;
+
+/* RBD bits definitions */
+#define FEC_RBD_EMPTY		0x8000	/* Buffer is empty */
+#define FEC_RBD_WRAP		0x2000	/* Last BD in ring */
+#define FEC_RBD_LAST		0x0800	/* Buffer is last in frame(useless) */
+#define FEC_RBD_MISS		0x0100	/* Miss bit for prom mode */
+#define FEC_RBD_BC		0x0080	/* The received frame is broadcast frame */
+#define FEC_RBD_MC		0x0040	/* The received frame is multicast frame */
+#define FEC_RBD_LG		0x0020	/* Frame length violation */
+#define FEC_RBD_NO		0x0010	/* Nonoctet align frame */
+#define FEC_RBD_SH		0x0008	/* Short frame */
+#define FEC_RBD_CR		0x0004	/* CRC error */
+#define FEC_RBD_OV		0x0002	/* Receive FIFO overrun */
+#define FEC_RBD_TR		0x0001	/* Frame is truncated */
+#define FEC_RBD_ERR		(FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \
+				FEC_RBD_OV | FEC_RBD_TR)
+
+/* TBD bits definitions */
+#define FEC_TBD_READY		0x8000	/* Buffer is ready */
+#define FEC_TBD_WRAP		0x2000	/* Last BD in ring */
+#define FEC_TBD_LAST		0x0800	/* Buffer is last in frame */
+#define FEC_TBD_TC		0x0400	/* Transmit the CRC */
+#define FEC_TBD_ABC		0x0200	/* Append bad CRC */
+
+/* MII-related definitios */
+#define FEC_MII_DATA_ST		0x40000000	/* Start of frame delimiter */
+#define FEC_MII_DATA_OP_RD	0x20000000	/* Perform a read operation */
+#define FEC_MII_DATA_OP_WR	0x10000000	/* Perform a write operation */
+#define FEC_MII_DATA_PA_MSK	0x0f800000	/* PHY Address field mask */
+#define FEC_MII_DATA_RA_MSK	0x007c0000	/* PHY Register field mask */
+#define FEC_MII_DATA_TA		0x00020000	/* Turnaround */
+#define FEC_MII_DATA_DATAMSK	0x0000ffff	/* PHY data field */
+
+#define FEC_MII_DATA_RA_SHIFT	18	/* MII Register address bits */
+#define FEC_MII_DATA_PA_SHIFT	23	/* MII PHY address bits */
+
+#endif	/* __MPC512X_FEC_H */
diff --git a/marvell/uboot/drivers/net/mpc5xxx_fec.c b/marvell/uboot/drivers/net/mpc5xxx_fec.c
new file mode 100644
index 0000000..1093ba5
--- /dev/null
+++ b/marvell/uboot/drivers/net/mpc5xxx_fec.c
@@ -0,0 +1,1027 @@
+/*
+ * (C) Copyright 2003-2010
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This file is based on mpc4200fec.c,
+ * (C) Copyright Motorola, Inc., 2000
+ */
+
+#include <common.h>
+#include <mpc5xxx.h>
+#include <mpc5xxx_sdma.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <miiphy.h>
+#include "mpc5xxx_fec.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* #define DEBUG	0x28 */
+
+#if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
+#error "CONFIG_MII has to be defined!"
+#endif
+
+#if (DEBUG & 0x60)
+static void tfifo_print(char *devname, mpc5xxx_fec_priv *fec);
+static void rfifo_print(char *devname, mpc5xxx_fec_priv *fec);
+#endif /* DEBUG */
+
+typedef struct {
+    uint8 data[1500];           /* actual data */
+    int length;                 /* actual length */
+    int used;                   /* buffer in use or not */
+    uint8 head[16];             /* MAC header(6 + 6 + 2) + 2(aligned) */
+} NBUF;
+
+int fec5xxx_miiphy_read(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 *retVal);
+int fec5xxx_miiphy_write(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 data);
+
+static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis);
+
+/********************************************************************/
+#if (DEBUG & 0x2)
+static void mpc5xxx_fec_phydump (char *devname)
+{
+	uint16 phyStatus, i;
+	uint8 phyAddr = CONFIG_PHY_ADDR;
+	uint8 reg_mask[] = {
+#if CONFIG_PHY_TYPE == 0x79c874	/* AMD Am79C874 */
+		/* regs to print: 0...7, 16...19, 21, 23, 24 */
+		1, 1, 1, 1,  1, 1, 1, 1,     0, 0, 0, 0,  0, 0, 0, 0,
+		1, 1, 1, 1,  0, 1, 0, 1,     1, 0, 0, 0,  0, 0, 0, 0,
+#else
+		/* regs to print: 0...8, 16...20 */
+		1, 1, 1, 1,  1, 1, 1, 1,     1, 0, 0, 0,  0, 0, 0, 0,
+		1, 1, 1, 1,  1, 0, 0, 0,     0, 0, 0, 0,  0, 0, 0, 0,
+#endif
+	};
+
+	for (i = 0; i < 32; i++) {
+		if (reg_mask[i]) {
+			miiphy_read(devname, phyAddr, i, &phyStatus);
+			printf("Mii reg %d: 0x%04x\n", i, phyStatus);
+		}
+	}
+}
+#endif
+
+/********************************************************************/
+static int mpc5xxx_fec_rbd_init(mpc5xxx_fec_priv *fec)
+{
+	int ix;
+	char *data;
+	static int once = 0;
+
+	for (ix = 0; ix < FEC_RBD_NUM; ix++) {
+		if (!once) {
+			data = (char *)malloc(FEC_MAX_PKT_SIZE);
+			if (data == NULL) {
+				printf ("RBD INIT FAILED\n");
+				return -1;
+			}
+			fec->rbdBase[ix].dataPointer = (uint32)data;
+		}
+		fec->rbdBase[ix].status = FEC_RBD_EMPTY;
+		fec->rbdBase[ix].dataLength = 0;
+	}
+	once ++;
+
+	/*
+	 * have the last RBD to close the ring
+	 */
+	fec->rbdBase[ix - 1].status |= FEC_RBD_WRAP;
+	fec->rbdIndex = 0;
+
+	return 0;
+}
+
+/********************************************************************/
+static void mpc5xxx_fec_tbd_init(mpc5xxx_fec_priv *fec)
+{
+	int ix;
+
+	for (ix = 0; ix < FEC_TBD_NUM; ix++) {
+		fec->tbdBase[ix].status = 0;
+	}
+
+	/*
+	 * Have the last TBD to close the ring
+	 */
+	fec->tbdBase[ix - 1].status |= FEC_TBD_WRAP;
+
+	/*
+	 * Initialize some indices
+	 */
+	fec->tbdIndex = 0;
+	fec->usedTbdIndex = 0;
+	fec->cleanTbdNum = FEC_TBD_NUM;
+}
+
+/********************************************************************/
+static void mpc5xxx_fec_rbd_clean(mpc5xxx_fec_priv *fec, volatile FEC_RBD * pRbd)
+{
+	/*
+	 * Reset buffer descriptor as empty
+	 */
+	if ((fec->rbdIndex) == (FEC_RBD_NUM - 1))
+		pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY);
+	else
+		pRbd->status = FEC_RBD_EMPTY;
+
+	pRbd->dataLength = 0;
+
+	/*
+	 * Now, we have an empty RxBD, restart the SmartDMA receive task
+	 */
+	SDMA_TASK_ENABLE(FEC_RECV_TASK_NO);
+
+	/*
+	 * Increment BD count
+	 */
+	fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM;
+}
+
+/********************************************************************/
+static void mpc5xxx_fec_tbd_scrub(mpc5xxx_fec_priv *fec)
+{
+	volatile FEC_TBD *pUsedTbd;
+
+#if (DEBUG & 0x1)
+	printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n",
+		fec->cleanTbdNum, fec->usedTbdIndex);
+#endif
+
+	/*
+	 * process all the consumed TBDs
+	 */
+	while (fec->cleanTbdNum < FEC_TBD_NUM) {
+		pUsedTbd = &fec->tbdBase[fec->usedTbdIndex];
+		if (pUsedTbd->status & FEC_TBD_READY) {
+#if (DEBUG & 0x20)
+			printf("Cannot clean TBD %d, in use\n", fec->cleanTbdNum);
+#endif
+			return;
+		}
+
+		/*
+		 * clean this buffer descriptor
+		 */
+		if (fec->usedTbdIndex == (FEC_TBD_NUM - 1))
+			pUsedTbd->status = FEC_TBD_WRAP;
+		else
+			pUsedTbd->status = 0;
+
+		/*
+		 * update some indeces for a correct handling of the TBD ring
+		 */
+		fec->cleanTbdNum++;
+		fec->usedTbdIndex = (fec->usedTbdIndex + 1) % FEC_TBD_NUM;
+	}
+}
+
+/********************************************************************/
+static void mpc5xxx_fec_set_hwaddr(mpc5xxx_fec_priv *fec, char *mac)
+{
+	uint8 currByte;			/* byte for which to compute the CRC */
+	int byte;			/* loop - counter */
+	int bit;			/* loop - counter */
+	uint32 crc = 0xffffffff;	/* initial value */
+
+	/*
+	 * The algorithm used is the following:
+	 * we loop on each of the six bytes of the provided address,
+	 * and we compute the CRC by left-shifting the previous
+	 * value by one position, so that each bit in the current
+	 * byte of the address may contribute the calculation. If
+	 * the latter and the MSB in the CRC are different, then
+	 * the CRC value so computed is also ex-ored with the
+	 * "polynomium generator". The current byte of the address
+	 * is also shifted right by one bit at each iteration.
+	 * This is because the CRC generatore in hardware is implemented
+	 * as a shift-register with as many ex-ores as the radixes
+	 * in the polynomium. This suggests that we represent the
+	 * polynomiumm itself as a 32-bit constant.
+	 */
+	for (byte = 0; byte < 6; byte++) {
+		currByte = mac[byte];
+		for (bit = 0; bit < 8; bit++) {
+			if ((currByte & 0x01) ^ (crc & 0x01)) {
+				crc >>= 1;
+				crc = crc ^ 0xedb88320;
+			} else {
+				crc >>= 1;
+			}
+			currByte >>= 1;
+		}
+	}
+
+	crc = crc >> 26;
+
+	/*
+	 * Set individual hash table register
+	 */
+	if (crc >= 32) {
+		fec->eth->iaddr1 = (1 << (crc - 32));
+		fec->eth->iaddr2 = 0;
+	} else {
+		fec->eth->iaddr1 = 0;
+		fec->eth->iaddr2 = (1 << crc);
+	}
+
+	/*
+	 * Set physical address
+	 */
+	fec->eth->paddr1 = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3];
+	fec->eth->paddr2 = (mac[4] << 24) + (mac[5] << 16) + 0x8808;
+}
+
+/********************************************************************/
+static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
+{
+	mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
+	struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA;
+
+#if (DEBUG & 0x1)
+	printf ("mpc5xxx_fec_init... Begin\n");
+#endif
+
+	mpc5xxx_fec_init_phy(dev, bis);
+
+	/*
+	 * Call board-specific PHY fixups (if any)
+	 */
+#ifdef CONFIG_RESET_PHY_R
+	reset_phy();
+#endif
+
+	/*
+	 * Initialize RxBD/TxBD rings
+	 */
+	mpc5xxx_fec_rbd_init(fec);
+	mpc5xxx_fec_tbd_init(fec);
+
+	/*
+	 * Clear FEC-Lite interrupt event register(IEVENT)
+	 */
+	fec->eth->ievent = 0xffffffff;
+
+	/*
+	 * Set interrupt mask register
+	 */
+	fec->eth->imask = 0x00000000;
+
+	/*
+	 * Set FEC-Lite receive control register(R_CNTRL):
+	 */
+	if (fec->xcv_type == SEVENWIRE) {
+		/*
+		 * Frame length=1518; 7-wire mode
+		 */
+		fec->eth->r_cntrl = 0x05ee0020;	/*0x05ee0000;FIXME */
+	} else {
+		/*
+		 * Frame length=1518; MII mode;
+		 */
+		fec->eth->r_cntrl = 0x05ee0024;	/*0x05ee0004;FIXME */
+	}
+
+	fec->eth->x_cntrl = 0x00000000;	/* half-duplex, heartbeat disabled */
+
+	/*
+	 * Set Opcode/Pause Duration Register
+	 */
+	fec->eth->op_pause = 0x00010020;	/*FIXME 0xffff0020; */
+
+	/*
+	 * Set Rx FIFO alarm and granularity value
+	 */
+	fec->eth->rfifo_cntrl = 0x0c000000
+				| (fec->eth->rfifo_cntrl & ~0x0f000000);
+	fec->eth->rfifo_alarm = 0x0000030c;
+#if (DEBUG & 0x22)
+	if (fec->eth->rfifo_status & 0x00700000 ) {
+		printf("mpc5xxx_fec_init() RFIFO error\n");
+	}
+#endif
+
+	/*
+	 * Set Tx FIFO granularity value
+	 */
+	fec->eth->tfifo_cntrl = 0x0c000000
+				| (fec->eth->tfifo_cntrl & ~0x0f000000);
+#if (DEBUG & 0x2)
+	printf("tfifo_status: 0x%08x\n", fec->eth->tfifo_status);
+	printf("tfifo_alarm: 0x%08x\n", fec->eth->tfifo_alarm);
+#endif
+
+	/*
+	 * Set transmit fifo watermark register(X_WMRK), default = 64
+	 */
+	fec->eth->tfifo_alarm = 0x00000080;
+	fec->eth->x_wmrk = 0x2;
+
+	/*
+	 * Set individual address filter for unicast address
+	 * and set physical address registers.
+	 */
+	mpc5xxx_fec_set_hwaddr(fec, (char *)dev->enetaddr);
+
+	/*
+	 * Set multicast address filter
+	 */
+	fec->eth->gaddr1 = 0x00000000;
+	fec->eth->gaddr2 = 0x00000000;
+
+	/*
+	 * Turn ON cheater FSM: ????
+	 */
+	fec->eth->xmit_fsm = 0x03000000;
+
+	/*
+	 * Turn off COMM bus prefetch in the MPC5200 BestComm. It doesn't
+	 * work w/ the current receive task.
+	 */
+	 sdma->PtdCntrl |= 0x00000001;
+
+	/*
+	 * Set priority of different initiators
+	 */
+	sdma->IPR0 = 7;		/* always */
+	sdma->IPR3 = 6;		/* Eth RX */
+	sdma->IPR4 = 5;		/* Eth Tx */
+
+	/*
+	 * Clear SmartDMA task interrupt pending bits
+	 */
+	SDMA_CLEAR_IEVENT(FEC_RECV_TASK_NO);
+
+	/*
+	 * Initialize SmartDMA parameters stored in SRAM
+	 */
+	*(volatile int *)FEC_TBD_BASE = (int)fec->tbdBase;
+	*(volatile int *)FEC_RBD_BASE = (int)fec->rbdBase;
+	*(volatile int *)FEC_TBD_NEXT = (int)fec->tbdBase;
+	*(volatile int *)FEC_RBD_NEXT = (int)fec->rbdBase;
+
+	/*
+	 * Enable FEC-Lite controller
+	 */
+	fec->eth->ecntrl |= 0x00000006;
+
+#if (DEBUG & 0x2)
+	if (fec->xcv_type != SEVENWIRE)
+		mpc5xxx_fec_phydump (dev->name);
+#endif
+
+	/*
+	 * Enable SmartDMA receive task
+	 */
+	SDMA_TASK_ENABLE(FEC_RECV_TASK_NO);
+
+#if (DEBUG & 0x1)
+	printf("mpc5xxx_fec_init... Done \n");
+#endif
+
+	return 1;
+}
+
+/********************************************************************/
+static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis)
+{
+	mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
+	const uint8 phyAddr = CONFIG_PHY_ADDR;	/* Only one PHY */
+	static int initialized = 0;
+
+	if(initialized)
+		return 0;
+	initialized = 1;
+
+#if (DEBUG & 0x1)
+	printf ("mpc5xxx_fec_init_phy... Begin\n");
+#endif
+
+	/*
+	 * Initialize GPIO pins
+	 */
+	if (fec->xcv_type == SEVENWIRE) {
+		/*  10MBit with 7-wire operation */
+#if defined(CONFIG_TOTAL5200)
+		/* 7-wire and USB2 on Ethernet */
+		*(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00030000;
+#else	/* !CONFIG_TOTAL5200 */
+		/* 7-wire only */
+		*(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00020000;
+#endif	/* CONFIG_TOTAL5200 */
+	} else {
+		/* 100MBit with MD operation */
+		*(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00050000;
+	}
+
+	/*
+	 * Clear FEC-Lite interrupt event register(IEVENT)
+	 */
+	fec->eth->ievent = 0xffffffff;
+
+	/*
+	 * Set interrupt mask register
+	 */
+	fec->eth->imask = 0x00000000;
+
+/*
+ * In original Promess-provided code PHY initialization is disabled with the
+ * following comment: "Phy initialization is DISABLED for now.  There was a
+ * problem with running 100 Mbps on PRO board". Thus we temporarily disable
+ * PHY initialization for the Motion-PRO board, until a proper fix is found.
+ */
+
+	if (fec->xcv_type != SEVENWIRE) {
+		/*
+		 * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
+		 * and do not drop the Preamble.
+		 * No MII for 7-wire mode
+		 */
+		fec->eth->mii_speed = (((gd->arch.ipb_clk >> 20) / 5) << 1);
+	}
+
+	if (fec->xcv_type != SEVENWIRE) {
+		/*
+		 * Initialize PHY(LXT971A):
+		 *
+		 *   Generally, on power up, the LXT971A reads its configuration
+		 *   pins to check for forced operation, If not cofigured for
+		 *   forced operation, it uses auto-negotiation/parallel detection
+		 *   to automatically determine line operating conditions.
+		 *   If the PHY device on the other side of the link supports
+		 *   auto-negotiation, the LXT971A auto-negotiates with it
+		 *   using Fast Link Pulse(FLP) Bursts. If the PHY partner does not
+		 *   support auto-negotiation, the LXT971A automatically detects
+		 *   the presence of either link pulses(10Mbps PHY) or Idle
+		 *   symbols(100Mbps) and sets its operating conditions accordingly.
+		 *
+		 *   When auto-negotiation is controlled by software, the following
+		 *   steps are recommended.
+		 *
+		 * Note:
+		 *   The physical address is dependent on hardware configuration.
+		 *
+		 */
+		int timeout = 1;
+		uint16 phyStatus;
+
+		/*
+		 * Reset PHY, then delay 300ns
+		 */
+		miiphy_write(dev->name, phyAddr, 0x0, 0x8000);
+		udelay(1000);
+
+#if defined(CONFIG_UC101) || defined(CONFIG_MUCMC52)
+		/* Set the LED configuration Register for the UC101
+		   and MUCMC52 Board */
+		miiphy_write(dev->name, phyAddr, 0x14, 0x4122);
+#endif
+		if (fec->xcv_type == MII10) {
+			/*
+			 * Force 10Base-T, FDX operation
+			 */
+#if (DEBUG & 0x2)
+			printf("Forcing 10 Mbps ethernet link... ");
+#endif
+			miiphy_read(dev->name, phyAddr, 0x1, &phyStatus);
+			/*
+			miiphy_write(dev->name, fec, phyAddr, 0x0, 0x0100);
+			*/
+			miiphy_write(dev->name, phyAddr, 0x0, 0x0180);
+
+			timeout = 20;
+			do {	/* wait for link status to go down */
+				udelay(10000);
+				if ((timeout--) == 0) {
+#if (DEBUG & 0x2)
+					printf("hmmm, should not have waited...");
+#endif
+					break;
+				}
+				miiphy_read(dev->name, phyAddr, 0x1, &phyStatus);
+#if (DEBUG & 0x2)
+				printf("=");
+#endif
+			} while ((phyStatus & 0x0004));	/* !link up */
+
+			timeout = 1000;
+			do {	/* wait for link status to come back up */
+				udelay(10000);
+				if ((timeout--) == 0) {
+					printf("failed. Link is down.\n");
+					break;
+				}
+				miiphy_read(dev->name, phyAddr, 0x1, &phyStatus);
+#if (DEBUG & 0x2)
+				printf("+");
+#endif
+			} while (!(phyStatus & 0x0004));	/* !link up */
+
+#if (DEBUG & 0x2)
+			printf ("done.\n");
+#endif
+		} else {	/* MII100 */
+			/*
+			 * Set the auto-negotiation advertisement register bits
+			 */
+			miiphy_write(dev->name, phyAddr, 0x4, 0x01e1);
+
+			/*
+			 * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
+			 */
+			miiphy_write(dev->name, phyAddr, 0x0, 0x1200);
+
+			/*
+			 * Wait for AN completion
+			 */
+			timeout = 5000;
+			do {
+				udelay(1000);
+
+				if ((timeout--) == 0) {
+#if (DEBUG & 0x2)
+					printf("PHY auto neg 0 failed...\n");
+#endif
+					return -1;
+				}
+
+				if (miiphy_read(dev->name, phyAddr, 0x1, &phyStatus) != 0) {
+#if (DEBUG & 0x2)
+					printf("PHY auto neg 1 failed 0x%04x...\n", phyStatus);
+#endif
+					return -1;
+				}
+			} while (!(phyStatus & 0x0004));
+
+#if (DEBUG & 0x2)
+			printf("PHY auto neg complete! \n");
+#endif
+		}
+
+	}
+
+#if (DEBUG & 0x2)
+	if (fec->xcv_type != SEVENWIRE)
+		mpc5xxx_fec_phydump (dev->name);
+#endif
+
+
+#if (DEBUG & 0x1)
+	printf("mpc5xxx_fec_init_phy... Done \n");
+#endif
+
+	return 1;
+}
+
+/********************************************************************/
+static void mpc5xxx_fec_halt(struct eth_device *dev)
+{
+	struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA;
+	mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
+	int counter = 0xffff;
+
+#if (DEBUG & 0x2)
+	if (fec->xcv_type != SEVENWIRE)
+		mpc5xxx_fec_phydump (dev->name);
+#endif
+
+	/*
+	 * mask FEC chip interrupts
+	 */
+	fec->eth->imask = 0;
+
+	/*
+	 * issue graceful stop command to the FEC transmitter if necessary
+	 */
+	fec->eth->x_cntrl |= 0x00000001;
+
+	/*
+	 * wait for graceful stop to register
+	 */
+	while ((counter--) && (!(fec->eth->ievent & 0x10000000))) ;
+
+	/*
+	 * Disable SmartDMA tasks
+	 */
+	SDMA_TASK_DISABLE (FEC_XMIT_TASK_NO);
+	SDMA_TASK_DISABLE (FEC_RECV_TASK_NO);
+
+	/*
+	 * Turn on COMM bus prefetch in the MPC5200 BestComm after we're
+	 * done. It doesn't work w/ the current receive task.
+	 */
+	 sdma->PtdCntrl &= ~0x00000001;
+
+	/*
+	 * Disable the Ethernet Controller
+	 */
+	fec->eth->ecntrl &= 0xfffffffd;
+
+	/*
+	 * Clear FIFO status registers
+	 */
+	fec->eth->rfifo_status &= 0x00700000;
+	fec->eth->tfifo_status &= 0x00700000;
+
+	fec->eth->reset_cntrl = 0x01000000;
+
+	/*
+	 * Issue a reset command to the FEC chip
+	 */
+	fec->eth->ecntrl |= 0x1;
+
+	/*
+	 * wait at least 16 clock cycles
+	 */
+	udelay(10);
+
+	/* don't leave the MII speed set to zero */
+	if (fec->xcv_type != SEVENWIRE) {
+		/*
+		 * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
+		 * and do not drop the Preamble.
+		 * No MII for 7-wire mode
+		 */
+		fec->eth->mii_speed = (((gd->arch.ipb_clk >> 20) / 5) << 1);
+	}
+
+#if (DEBUG & 0x3)
+	printf("Ethernet task stopped\n");
+#endif
+}
+
+#if (DEBUG & 0x60)
+/********************************************************************/
+
+static void tfifo_print(char *devname, mpc5xxx_fec_priv *fec)
+{
+	uint16 phyAddr = CONFIG_PHY_ADDR;
+	uint16 phyStatus;
+
+	if ((fec->eth->tfifo_lrf_ptr != fec->eth->tfifo_lwf_ptr)
+		|| (fec->eth->tfifo_rdptr != fec->eth->tfifo_wrptr)) {
+
+		miiphy_read(devname, phyAddr, 0x1, &phyStatus);
+		printf("\nphyStatus: 0x%04x\n", phyStatus);
+		printf("ecntrl:   0x%08x\n", fec->eth->ecntrl);
+		printf("ievent:   0x%08x\n", fec->eth->ievent);
+		printf("x_status: 0x%08x\n", fec->eth->x_status);
+		printf("tfifo: status  0x%08x\n", fec->eth->tfifo_status);
+
+		printf("       control 0x%08x\n", fec->eth->tfifo_cntrl);
+		printf("       lrfp    0x%08x\n", fec->eth->tfifo_lrf_ptr);
+		printf("       lwfp    0x%08x\n", fec->eth->tfifo_lwf_ptr);
+		printf("       alarm   0x%08x\n", fec->eth->tfifo_alarm);
+		printf("       readptr 0x%08x\n", fec->eth->tfifo_rdptr);
+		printf("       writptr 0x%08x\n", fec->eth->tfifo_wrptr);
+	}
+}
+
+static void rfifo_print(char *devname, mpc5xxx_fec_priv *fec)
+{
+	uint16 phyAddr = CONFIG_PHY_ADDR;
+	uint16 phyStatus;
+
+	if ((fec->eth->rfifo_lrf_ptr != fec->eth->rfifo_lwf_ptr)
+		|| (fec->eth->rfifo_rdptr != fec->eth->rfifo_wrptr)) {
+
+		miiphy_read(devname, phyAddr, 0x1, &phyStatus);
+		printf("\nphyStatus: 0x%04x\n", phyStatus);
+		printf("ecntrl:   0x%08x\n", fec->eth->ecntrl);
+		printf("ievent:   0x%08x\n", fec->eth->ievent);
+		printf("x_status: 0x%08x\n", fec->eth->x_status);
+		printf("rfifo: status  0x%08x\n", fec->eth->rfifo_status);
+
+		printf("       control 0x%08x\n", fec->eth->rfifo_cntrl);
+		printf("       lrfp    0x%08x\n", fec->eth->rfifo_lrf_ptr);
+		printf("       lwfp    0x%08x\n", fec->eth->rfifo_lwf_ptr);
+		printf("       alarm   0x%08x\n", fec->eth->rfifo_alarm);
+		printf("       readptr 0x%08x\n", fec->eth->rfifo_rdptr);
+		printf("       writptr 0x%08x\n", fec->eth->rfifo_wrptr);
+	}
+}
+#endif /* DEBUG */
+
+/********************************************************************/
+
+static int mpc5xxx_fec_send(struct eth_device *dev, void *eth_data,
+		int data_length)
+{
+	/*
+	 * This routine transmits one frame.  This routine only accepts
+	 * 6-byte Ethernet addresses.
+	 */
+	mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
+	volatile FEC_TBD *pTbd;
+
+#if (DEBUG & 0x20)
+	printf("tbd status: 0x%04x\n", fec->tbdBase[0].status);
+	tfifo_print(dev->name, fec);
+#endif
+
+	/*
+	 * Clear Tx BD ring at first
+	 */
+	mpc5xxx_fec_tbd_scrub(fec);
+
+	/*
+	 * Check for valid length of data.
+	 */
+	if ((data_length > 1500) || (data_length <= 0)) {
+		return -1;
+	}
+
+	/*
+	 * Check the number of vacant TxBDs.
+	 */
+	if (fec->cleanTbdNum < 1) {
+#if (DEBUG & 0x20)
+		printf("No available TxBDs ...\n");
+#endif
+		return -1;
+	}
+
+	/*
+	 * Get the first TxBD to send the mac header
+	 */
+	pTbd = &fec->tbdBase[fec->tbdIndex];
+	pTbd->dataLength = data_length;
+	pTbd->dataPointer = (uint32)eth_data;
+	pTbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
+	fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM;
+
+#if (DEBUG & 0x100)
+	printf("SDMA_TASK_ENABLE, fec->tbdIndex = %d \n", fec->tbdIndex);
+#endif
+
+	/*
+	 * Kick the MII i/f
+	 */
+	if (fec->xcv_type != SEVENWIRE) {
+		uint16 phyStatus;
+		miiphy_read(dev->name, 0, 0x1, &phyStatus);
+	}
+
+	/*
+	 * Enable SmartDMA transmit task
+	 */
+
+#if (DEBUG & 0x20)
+	tfifo_print(dev->name, fec);
+#endif
+	SDMA_TASK_ENABLE (FEC_XMIT_TASK_NO);
+#if (DEBUG & 0x20)
+	tfifo_print(dev->name, fec);
+#endif
+#if (DEBUG & 0x8)
+	printf( "+" );
+#endif
+
+	fec->cleanTbdNum -= 1;
+
+#if (DEBUG & 0x129) && (DEBUG & 0x80000000)
+	printf ("smartDMA ethernet Tx task enabled\n");
+#endif
+	/*
+	 * wait until frame is sent .
+	 */
+	while (pTbd->status & FEC_TBD_READY) {
+		udelay(10);
+#if (DEBUG & 0x8)
+		printf ("TDB status = %04x\n", pTbd->status);
+#endif
+	}
+
+	return 0;
+}
+
+
+/********************************************************************/
+static int mpc5xxx_fec_recv(struct eth_device *dev)
+{
+	/*
+	 * This command pulls one frame from the card
+	 */
+	mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
+	volatile FEC_RBD *pRbd = &fec->rbdBase[fec->rbdIndex];
+	unsigned long ievent;
+	int frame_length, len = 0;
+	NBUF *frame;
+	uchar buff[FEC_MAX_PKT_SIZE];
+
+#if (DEBUG & 0x1)
+	printf ("mpc5xxx_fec_recv %d Start...\n", fec->rbdIndex);
+#endif
+#if (DEBUG & 0x8)
+	printf( "-" );
+#endif
+
+	/*
+	 * Check if any critical events have happened
+	 */
+	ievent = fec->eth->ievent;
+	fec->eth->ievent = ievent;
+	if (ievent & 0x20060000) {
+		/* BABT, Rx/Tx FIFO errors */
+		mpc5xxx_fec_halt(dev);
+		mpc5xxx_fec_init(dev, NULL);
+		return 0;
+	}
+	if (ievent & 0x80000000) {
+		/* Heartbeat error */
+		fec->eth->x_cntrl |= 0x00000001;
+	}
+	if (ievent & 0x10000000) {
+		/* Graceful stop complete */
+		if (fec->eth->x_cntrl & 0x00000001) {
+			mpc5xxx_fec_halt(dev);
+			fec->eth->x_cntrl &= ~0x00000001;
+			mpc5xxx_fec_init(dev, NULL);
+		}
+	}
+
+	if (!(pRbd->status & FEC_RBD_EMPTY)) {
+		if ((pRbd->status & FEC_RBD_LAST) && !(pRbd->status & FEC_RBD_ERR) &&
+			((pRbd->dataLength - 4) > 14)) {
+
+			/*
+			 * Get buffer address and size
+			 */
+			frame = (NBUF *)pRbd->dataPointer;
+			frame_length = pRbd->dataLength - 4;
+
+#if (DEBUG & 0x20)
+			{
+				int i;
+				printf("recv data hdr:");
+				for (i = 0; i < 14; i++)
+					printf("%x ", *(frame->head + i));
+				printf("\n");
+			}
+#endif
+			/*
+			 *  Fill the buffer and pass it to upper layers
+			 */
+			memcpy(buff, frame->head, 14);
+			memcpy(buff + 14, frame->data, frame_length);
+			NetReceive(buff, frame_length);
+			len = frame_length;
+		}
+		/*
+		 * Reset buffer descriptor as empty
+		 */
+		mpc5xxx_fec_rbd_clean(fec, pRbd);
+	}
+	SDMA_CLEAR_IEVENT (FEC_RECV_TASK_NO);
+	return len;
+}
+
+
+/********************************************************************/
+int mpc5xxx_fec_initialize(bd_t * bis)
+{
+	mpc5xxx_fec_priv *fec;
+	struct eth_device *dev;
+	char *tmp, *end;
+	char env_enetaddr[6];
+	int i;
+
+	fec = (mpc5xxx_fec_priv *)malloc(sizeof(*fec));
+	dev = (struct eth_device *)malloc(sizeof(*dev));
+	memset(dev, 0, sizeof *dev);
+
+	fec->eth = (ethernet_regs *)MPC5XXX_FEC;
+	fec->tbdBase = (FEC_TBD *)FEC_BD_BASE;
+	fec->rbdBase = (FEC_RBD *)(FEC_BD_BASE + FEC_TBD_NUM * sizeof(FEC_TBD));
+#if defined(CONFIG_MPC5xxx_FEC_MII100)
+	fec->xcv_type = MII100;
+#elif defined(CONFIG_MPC5xxx_FEC_MII10)
+	fec->xcv_type = MII10;
+#elif defined(CONFIG_MPC5xxx_FEC_SEVENWIRE)
+	fec->xcv_type = SEVENWIRE;
+#else
+#error fec->xcv_type not initialized.
+#endif
+	if (fec->xcv_type != SEVENWIRE) {
+		/*
+		 * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
+		 * and do not drop the Preamble.
+		 * No MII for 7-wire mode
+		 */
+		fec->eth->mii_speed = (((gd->arch.ipb_clk >> 20) / 5) << 1);
+	}
+
+	dev->priv = (void *)fec;
+	dev->iobase = MPC5XXX_FEC;
+	dev->init = mpc5xxx_fec_init;
+	dev->halt = mpc5xxx_fec_halt;
+	dev->send = mpc5xxx_fec_send;
+	dev->recv = mpc5xxx_fec_recv;
+
+	sprintf(dev->name, "FEC");
+	eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	miiphy_register (dev->name,
+			fec5xxx_miiphy_read, fec5xxx_miiphy_write);
+#endif
+
+	/*
+	 * Try to set the mac address now. The fec mac address is
+	 * a garbage after reset. When not using fec for booting
+	 * the Linux fec driver will try to work with this garbage.
+	 */
+	tmp = getenv("ethaddr");
+	if (tmp) {
+		for (i=0; i<6; i++) {
+			env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
+			if (tmp)
+				tmp = (*end) ? end+1 : end;
+		}
+		mpc5xxx_fec_set_hwaddr(fec, env_enetaddr);
+	}
+
+	return 1;
+}
+
+/* MII-interface related functions */
+/********************************************************************/
+int fec5xxx_miiphy_read(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal)
+{
+	ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC;
+	uint32 reg;		/* convenient holder for the PHY register */
+	uint32 phy;		/* convenient holder for the PHY */
+	int timeout = 0xffff;
+
+	/*
+	 * reading from any PHY's register is done by properly
+	 * programming the FEC's MII data register.
+	 */
+	reg = regAddr << FEC_MII_DATA_RA_SHIFT;
+	phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
+
+	eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA | phy | reg);
+
+	/*
+	 * wait for the related interrupt
+	 */
+	while ((timeout--) && (!(eth->ievent & 0x00800000))) ;
+
+	if (timeout == 0) {
+#if (DEBUG & 0x2)
+		printf ("Read MDIO failed...\n");
+#endif
+		return -1;
+	}
+
+	/*
+	 * clear mii interrupt bit
+	 */
+	eth->ievent = 0x00800000;
+
+	/*
+	 * it's now safe to read the PHY's register
+	 */
+	*retVal = (uint16) eth->mii_data;
+
+	return 0;
+}
+
+/********************************************************************/
+int fec5xxx_miiphy_write(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 data)
+{
+	ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC;
+	uint32 reg;		/* convenient holder for the PHY register */
+	uint32 phy;		/* convenient holder for the PHY */
+	int timeout = 0xffff;
+
+	reg = regAddr << FEC_MII_DATA_RA_SHIFT;
+	phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
+
+	eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR |
+			FEC_MII_DATA_TA | phy | reg | data);
+
+	/*
+	 * wait for the MII interrupt
+	 */
+	while ((timeout--) && (!(eth->ievent & 0x00800000))) ;
+
+	if (timeout == 0) {
+#if (DEBUG & 0x2)
+		printf ("Write MDIO failed...\n");
+#endif
+		return -1;
+	}
+
+	/*
+	 * clear MII interrupt bit
+	 */
+	eth->ievent = 0x00800000;
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/mpc5xxx_fec.h b/marvell/uboot/drivers/net/mpc5xxx_fec.h
new file mode 100644
index 0000000..16c3e8e
--- /dev/null
+++ b/marvell/uboot/drivers/net/mpc5xxx_fec.h
@@ -0,0 +1,282 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This file is based on mpc4200fec.h
+ * (C) Copyright Motorola, Inc., 2000
+ *
+ * odin ethernet header file
+ */
+
+#ifndef __MPC5XXX_FEC_H
+#define __MPC5XXX_FEC_H
+
+typedef unsigned long uint32;
+typedef unsigned short uint16;
+typedef unsigned char uint8;
+
+typedef struct ethernet_register_set {
+
+/* [10:2]addr = 00 */
+
+/*  Control and status Registers (offset 000-1FF) */
+
+	volatile uint32 fec_id;			/* MBAR_ETH + 0x000 */
+	volatile uint32 ievent;			/* MBAR_ETH + 0x004 */
+	volatile uint32 imask;			/* MBAR_ETH + 0x008 */
+
+	volatile uint32 RES0[1];		/* MBAR_ETH + 0x00C */
+	volatile uint32 r_des_active;		/* MBAR_ETH + 0x010 */
+	volatile uint32 x_des_active;		/* MBAR_ETH + 0x014 */
+	volatile uint32 r_des_active_cl;	/* MBAR_ETH + 0x018 */
+	volatile uint32 x_des_active_cl;	/* MBAR_ETH + 0x01C */
+	volatile uint32 ivent_set;		/* MBAR_ETH + 0x020 */
+	volatile uint32 ecntrl;			/* MBAR_ETH + 0x024 */
+
+	volatile uint32 RES1[6];		/* MBAR_ETH + 0x028-03C */
+	volatile uint32 mii_data;		/* MBAR_ETH + 0x040 */
+	volatile uint32 mii_speed;		/* MBAR_ETH + 0x044 */
+	volatile uint32 mii_status;		/* MBAR_ETH + 0x048 */
+
+	volatile uint32 RES2[5];		/* MBAR_ETH + 0x04C-05C */
+	volatile uint32 mib_data;		/* MBAR_ETH + 0x060 */
+	volatile uint32 mib_control;		/* MBAR_ETH + 0x064 */
+
+	volatile uint32 RES3[6];		/* MBAR_ETH + 0x068-7C */
+	volatile uint32 r_activate;		/* MBAR_ETH + 0x080 */
+	volatile uint32 r_cntrl;		/* MBAR_ETH + 0x084 */
+	volatile uint32 r_hash;			/* MBAR_ETH + 0x088 */
+	volatile uint32 r_data;			/* MBAR_ETH + 0x08C */
+	volatile uint32 ar_done;		/* MBAR_ETH + 0x090 */
+	volatile uint32 r_test;			/* MBAR_ETH + 0x094 */
+	volatile uint32 r_mib;			/* MBAR_ETH + 0x098 */
+	volatile uint32 r_da_low;		/* MBAR_ETH + 0x09C */
+	volatile uint32 r_da_high;		/* MBAR_ETH + 0x0A0 */
+
+	volatile uint32 RES4[7];		/* MBAR_ETH + 0x0A4-0BC */
+	volatile uint32 x_activate;		/* MBAR_ETH + 0x0C0 */
+	volatile uint32 x_cntrl;		/* MBAR_ETH + 0x0C4 */
+	volatile uint32 backoff;		/* MBAR_ETH + 0x0C8 */
+	volatile uint32 x_data;			/* MBAR_ETH + 0x0CC */
+	volatile uint32 x_status;		/* MBAR_ETH + 0x0D0 */
+	volatile uint32 x_mib;			/* MBAR_ETH + 0x0D4 */
+	volatile uint32 x_test;			/* MBAR_ETH + 0x0D8 */
+	volatile uint32 fdxfc_da1;		/* MBAR_ETH + 0x0DC */
+	volatile uint32 fdxfc_da2;		/* MBAR_ETH + 0x0E0 */
+	volatile uint32 paddr1;			/* MBAR_ETH + 0x0E4 */
+	volatile uint32 paddr2;			/* MBAR_ETH + 0x0E8 */
+	volatile uint32 op_pause;		/* MBAR_ETH + 0x0EC */
+
+	volatile uint32 RES5[4];		/* MBAR_ETH + 0x0F0-0FC */
+	volatile uint32 instr_reg;		/* MBAR_ETH + 0x100 */
+	volatile uint32 context_reg;		/* MBAR_ETH + 0x104 */
+	volatile uint32 test_cntrl;		/* MBAR_ETH + 0x108 */
+	volatile uint32 acc_reg;		/* MBAR_ETH + 0x10C */
+	volatile uint32 ones;			/* MBAR_ETH + 0x110 */
+	volatile uint32 zeros;			/* MBAR_ETH + 0x114 */
+	volatile uint32 iaddr1;			/* MBAR_ETH + 0x118 */
+	volatile uint32 iaddr2;			/* MBAR_ETH + 0x11C */
+	volatile uint32 gaddr1;			/* MBAR_ETH + 0x120 */
+	volatile uint32 gaddr2;			/* MBAR_ETH + 0x124 */
+	volatile uint32 random;			/* MBAR_ETH + 0x128 */
+	volatile uint32 rand1;			/* MBAR_ETH + 0x12C */
+	volatile uint32 tmp;			/* MBAR_ETH + 0x130 */
+
+	volatile uint32 RES6[3];		/* MBAR_ETH + 0x134-13C */
+	volatile uint32 fifo_id;		/* MBAR_ETH + 0x140 */
+	volatile uint32 x_wmrk;			/* MBAR_ETH + 0x144 */
+	volatile uint32 fcntrl;			/* MBAR_ETH + 0x148 */
+	volatile uint32 r_bound;		/* MBAR_ETH + 0x14C */
+	volatile uint32 r_fstart;		/* MBAR_ETH + 0x150 */
+	volatile uint32 r_count;		/* MBAR_ETH + 0x154 */
+	volatile uint32 r_lag;			/* MBAR_ETH + 0x158 */
+	volatile uint32 r_read;			/* MBAR_ETH + 0x15C */
+	volatile uint32 r_write;		/* MBAR_ETH + 0x160 */
+	volatile uint32 x_count;		/* MBAR_ETH + 0x164 */
+	volatile uint32 x_lag;			/* MBAR_ETH + 0x168 */
+	volatile uint32 x_retry;		/* MBAR_ETH + 0x16C */
+	volatile uint32 x_write;		/* MBAR_ETH + 0x170 */
+	volatile uint32 x_read;			/* MBAR_ETH + 0x174 */
+
+	volatile uint32 RES7[2];		/* MBAR_ETH + 0x178-17C */
+	volatile uint32 fm_cntrl;		/* MBAR_ETH + 0x180 */
+	volatile uint32 rfifo_data;		/* MBAR_ETH + 0x184 */
+	volatile uint32 rfifo_status;		/* MBAR_ETH + 0x188 */
+	volatile uint32 rfifo_cntrl;		/* MBAR_ETH + 0x18C */
+	volatile uint32 rfifo_lrf_ptr;		/* MBAR_ETH + 0x190 */
+	volatile uint32 rfifo_lwf_ptr;		/* MBAR_ETH + 0x194 */
+	volatile uint32 rfifo_alarm;		/* MBAR_ETH + 0x198 */
+	volatile uint32 rfifo_rdptr;		/* MBAR_ETH + 0x19C */
+	volatile uint32 rfifo_wrptr;		/* MBAR_ETH + 0x1A0 */
+	volatile uint32 tfifo_data;		/* MBAR_ETH + 0x1A4 */
+	volatile uint32 tfifo_status;		/* MBAR_ETH + 0x1A8 */
+	volatile uint32 tfifo_cntrl;		/* MBAR_ETH + 0x1AC */
+	volatile uint32 tfifo_lrf_ptr;		/* MBAR_ETH + 0x1B0 */
+	volatile uint32 tfifo_lwf_ptr;		/* MBAR_ETH + 0x1B4 */
+	volatile uint32 tfifo_alarm;		/* MBAR_ETH + 0x1B8 */
+	volatile uint32 tfifo_rdptr;		/* MBAR_ETH + 0x1BC */
+	volatile uint32 tfifo_wrptr;		/* MBAR_ETH + 0x1C0 */
+
+	volatile uint32 reset_cntrl;		/* MBAR_ETH + 0x1C4 */
+	volatile uint32 xmit_fsm;		/* MBAR_ETH + 0x1C8 */
+
+	volatile uint32 RES8[3];		/* MBAR_ETH + 0x1CC-1D4 */
+	volatile uint32 rdes_data0;		/* MBAR_ETH + 0x1D8 */
+	volatile uint32 rdes_data1;		/* MBAR_ETH + 0x1DC */
+	volatile uint32 r_length;		/* MBAR_ETH + 0x1E0 */
+	volatile uint32 x_length;		/* MBAR_ETH + 0x1E4 */
+	volatile uint32 x_addr;			/* MBAR_ETH + 0x1E8 */
+	volatile uint32 cdes_data;		/* MBAR_ETH + 0x1EC */
+	volatile uint32 status;			/* MBAR_ETH + 0x1F0 */
+	volatile uint32 dma_control;		/* MBAR_ETH + 0x1F4 */
+	volatile uint32 des_cmnd;		/* MBAR_ETH + 0x1F8 */
+	volatile uint32 data;			/* MBAR_ETH + 0x1FC */
+
+/*  MIB COUNTERS (Offset 200-2FF) */
+
+	volatile uint32 rmon_t_drop;		/* MBAR_ETH + 0x200 */
+	volatile uint32 rmon_t_packets;		/* MBAR_ETH + 0x204 */
+	volatile uint32 rmon_t_bc_pkt;		/* MBAR_ETH + 0x208 */
+	volatile uint32 rmon_t_mc_pkt;		/* MBAR_ETH + 0x20C */
+	volatile uint32 rmon_t_crc_align;	/* MBAR_ETH + 0x210 */
+	volatile uint32 rmon_t_undersize;	/* MBAR_ETH + 0x214 */
+	volatile uint32 rmon_t_oversize;	/* MBAR_ETH + 0x218 */
+	volatile uint32 rmon_t_frag;		/* MBAR_ETH + 0x21C */
+	volatile uint32 rmon_t_jab;		/* MBAR_ETH + 0x220 */
+	volatile uint32 rmon_t_col;		/* MBAR_ETH + 0x224 */
+	volatile uint32 rmon_t_p64;		/* MBAR_ETH + 0x228 */
+	volatile uint32 rmon_t_p65to127;	/* MBAR_ETH + 0x22C */
+	volatile uint32 rmon_t_p128to255;	/* MBAR_ETH + 0x230 */
+	volatile uint32 rmon_t_p256to511;	/* MBAR_ETH + 0x234 */
+	volatile uint32 rmon_t_p512to1023;	/* MBAR_ETH + 0x238 */
+	volatile uint32 rmon_t_p1024to2047;	/* MBAR_ETH + 0x23C */
+	volatile uint32 rmon_t_p_gte2048;	/* MBAR_ETH + 0x240 */
+	volatile uint32 rmon_t_octets;		/* MBAR_ETH + 0x244 */
+	volatile uint32 ieee_t_drop;		/* MBAR_ETH + 0x248 */
+	volatile uint32 ieee_t_frame_ok;	/* MBAR_ETH + 0x24C */
+	volatile uint32 ieee_t_1col;		/* MBAR_ETH + 0x250 */
+	volatile uint32 ieee_t_mcol;		/* MBAR_ETH + 0x254 */
+	volatile uint32 ieee_t_def;		/* MBAR_ETH + 0x258 */
+	volatile uint32 ieee_t_lcol;		/* MBAR_ETH + 0x25C */
+	volatile uint32 ieee_t_excol;		/* MBAR_ETH + 0x260 */
+	volatile uint32 ieee_t_macerr;		/* MBAR_ETH + 0x264 */
+	volatile uint32 ieee_t_cserr;		/* MBAR_ETH + 0x268 */
+	volatile uint32 ieee_t_sqe;		/* MBAR_ETH + 0x26C */
+	volatile uint32 t_fdxfc;		/* MBAR_ETH + 0x270 */
+	volatile uint32 ieee_t_octets_ok;	/* MBAR_ETH + 0x274 */
+
+	volatile uint32 RES9[2];		/* MBAR_ETH + 0x278-27C */
+	volatile uint32 rmon_r_drop;		/* MBAR_ETH + 0x280 */
+	volatile uint32 rmon_r_packets;		/* MBAR_ETH + 0x284 */
+	volatile uint32 rmon_r_bc_pkt;		/* MBAR_ETH + 0x288 */
+	volatile uint32 rmon_r_mc_pkt;		/* MBAR_ETH + 0x28C */
+	volatile uint32 rmon_r_crc_align;	/* MBAR_ETH + 0x290 */
+	volatile uint32 rmon_r_undersize;	/* MBAR_ETH + 0x294 */
+	volatile uint32 rmon_r_oversize;	/* MBAR_ETH + 0x298 */
+	volatile uint32 rmon_r_frag;		/* MBAR_ETH + 0x29C */
+	volatile uint32 rmon_r_jab;		/* MBAR_ETH + 0x2A0 */
+
+	volatile uint32 rmon_r_resvd_0;		/* MBAR_ETH + 0x2A4 */
+
+	volatile uint32 rmon_r_p64;		/* MBAR_ETH + 0x2A8 */
+	volatile uint32 rmon_r_p65to127;	/* MBAR_ETH + 0x2AC */
+	volatile uint32 rmon_r_p128to255;	/* MBAR_ETH + 0x2B0 */
+	volatile uint32 rmon_r_p256to511;	/* MBAR_ETH + 0x2B4 */
+	volatile uint32 rmon_r_p512to1023;	/* MBAR_ETH + 0x2B8 */
+	volatile uint32 rmon_r_p1024to2047;	/* MBAR_ETH + 0x2BC */
+	volatile uint32 rmon_r_p_gte2048;	/* MBAR_ETH + 0x2C0 */
+	volatile uint32 rmon_r_octets;		/* MBAR_ETH + 0x2C4 */
+	volatile uint32 ieee_r_drop;		/* MBAR_ETH + 0x2C8 */
+	volatile uint32 ieee_r_frame_ok;	/* MBAR_ETH + 0x2CC */
+	volatile uint32 ieee_r_crc;		/* MBAR_ETH + 0x2D0 */
+	volatile uint32 ieee_r_align;		/* MBAR_ETH + 0x2D4 */
+	volatile uint32 r_macerr;		/* MBAR_ETH + 0x2D8 */
+	volatile uint32 r_fdxfc;		/* MBAR_ETH + 0x2DC */
+	volatile uint32 ieee_r_octets_ok;	/* MBAR_ETH + 0x2E0 */
+
+	volatile uint32 RES10[6];		/* MBAR_ETH + 0x2E4-2FC */
+
+	volatile uint32 RES11[64];		/* MBAR_ETH + 0x300-3FF */
+} ethernet_regs;
+
+/* Receive & Transmit Buffer Descriptor definitions */
+typedef struct BufferDescriptor {
+	uint16 status;
+	uint16 dataLength;
+	uint32 dataPointer;
+} FEC_RBD;
+typedef struct {
+	uint16 status;
+	uint16 dataLength;
+	uint32 dataPointer;
+} FEC_TBD;
+
+/* private structure */
+typedef enum {
+	SEVENWIRE,			/* 7-wire       */
+	MII10,				/* MII 10Mbps   */
+	MII100				/* MII 100Mbps  */
+} xceiver_type;
+
+typedef struct {
+	ethernet_regs *eth;
+	xceiver_type xcv_type;		/* transceiver type */
+	FEC_RBD *rbdBase;		/* RBD ring */
+	FEC_TBD *tbdBase;		/* TBD ring */
+	uint16 rbdIndex;		/* next receive BD to read */
+	uint16 tbdIndex;		/* next transmit BD to send */
+	uint16 usedTbdIndex;		/* next transmit BD to clean */
+	uint16 cleanTbdNum;		/* the number of available transmit BDs */
+} mpc5xxx_fec_priv;
+
+/* Ethernet parameter area */
+#define FEC_TBD_BASE		(FEC_PARAM_BASE + 0x00)
+#define FEC_TBD_NEXT		(FEC_PARAM_BASE + 0x04)
+#define FEC_RBD_BASE		(FEC_PARAM_BASE + 0x08)
+#define FEC_RBD_NEXT		(FEC_PARAM_BASE + 0x0c)
+
+/* BD Numer definitions */
+#define FEC_TBD_NUM		48	/* The user can adjust this value */
+#define FEC_RBD_NUM		32	/* The user can adjust this value */
+
+/* packet size limit */
+#define FEC_MAX_PKT_SIZE	1536
+
+/* RBD bits definitions */
+#define FEC_RBD_EMPTY		0x8000	/* Buffer is empty */
+#define FEC_RBD_WRAP		0x2000	/* Last BD in ring */
+#define FEC_RBD_INT		0x1000	/* Interrupt */
+#define FEC_RBD_LAST		0x0800	/* Buffer is last in frame(useless) */
+#define FEC_RBD_MISS		0x0100	/* Miss bit for prom mode */
+#define FEC_RBD_BC		0x0080	/* The received frame is broadcast frame */
+#define FEC_RBD_MC		0x0040	/* The received frame is multicast frame */
+#define FEC_RBD_LG		0x0020	/* Frame length violation */
+#define FEC_RBD_NO		0x0010	/* Nonoctet align frame */
+#define FEC_RBD_SH		0x0008	/* Short frame */
+#define FEC_RBD_CR		0x0004	/* CRC error */
+#define FEC_RBD_OV		0x0002	/* Receive FIFO overrun */
+#define FEC_RBD_TR		0x0001	/* Frame is truncated */
+#define FEC_RBD_ERR		(FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \
+				FEC_RBD_OV | FEC_RBD_TR)
+
+/* TBD bits definitions */
+#define FEC_TBD_READY		0x8000	/* Buffer is ready */
+#define FEC_TBD_WRAP		0x2000	/* Last BD in ring */
+#define FEC_TBD_INT		0x1000	/* Interrupt */
+#define FEC_TBD_LAST		0x0800	/* Buffer is last in frame */
+#define FEC_TBD_TC		0x0400	/* Transmit the CRC */
+#define FEC_TBD_ABC		0x0200	/* Append bad CRC */
+
+/* MII-related definitios */
+#define FEC_MII_DATA_ST		0x40000000	/* Start of frame delimiter */
+#define FEC_MII_DATA_OP_RD	0x20000000	/* Perform a read operation */
+#define FEC_MII_DATA_OP_WR	0x10000000	/* Perform a write operation */
+#define FEC_MII_DATA_PA_MSK	0x0f800000	/* PHY Address field mask */
+#define FEC_MII_DATA_RA_MSK	0x007c0000	/* PHY Register field mask */
+#define FEC_MII_DATA_TA		0x00020000	/* Turnaround */
+#define FEC_MII_DATA_DATAMSK	0x0000ffff	/* PHY data field */
+
+#define FEC_MII_DATA_RA_SHIFT	18	/* MII Register address bits */
+#define FEC_MII_DATA_PA_SHIFT	23	/* MII PHY address bits */
+
+#endif	/* __MPC5XXX_FEC_H */
diff --git a/marvell/uboot/drivers/net/mvgbe.c b/marvell/uboot/drivers/net/mvgbe.c
new file mode 100644
index 0000000..0cd06b6
--- /dev/null
+++ b/marvell/uboot/drivers/net/mvgbe.c
@@ -0,0 +1,788 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * (C) Copyright 2003
+ * Ingo Assmus <ingo.assmus@keymile.com>
+ *
+ * based on - Driver for MV64360X ethernet ports
+ * Copyright (C) 2002 rabeeh@galileo.co.il
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <net.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/types.h>
+#include <asm/system.h>
+#include <asm/byteorder.h>
+#include <asm/arch/cpu.h>
+
+#if defined(CONFIG_KIRKWOOD)
+#include <asm/arch/kirkwood.h>
+#elif defined(CONFIG_ORION5X)
+#include <asm/arch/orion5x.h>
+#elif defined(CONFIG_DOVE)
+#include <asm/arch/dove.h>
+#endif
+
+#include "mvgbe.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MV_PHY_ADR_REQUEST 0xee
+#define MVGBE_SMI_REG (((struct mvgbe_registers *)MVGBE0_BASE)->smi)
+
+#if defined(CONFIG_PHYLIB) || defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+/*
+ * smi_reg_read - miiphy_read callback function.
+ *
+ * Returns 16bit phy register value, or 0xffff on error
+ */
+static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+	struct mvgbe_registers *regs = dmvgbe->regs;
+	u32 smi_reg;
+	u32 timeout;
+
+	/* Phyadr read request */
+	if (phy_adr == MV_PHY_ADR_REQUEST &&
+			reg_ofs == MV_PHY_ADR_REQUEST) {
+		/* */
+		*data = (u16) (MVGBE_REG_RD(regs->phyadr) & PHYADR_MASK);
+		return 0;
+	}
+	/* check parameters */
+	if (phy_adr > PHYADR_MASK) {
+		printf("Err..(%s) Invalid PHY address %d\n",
+			__FUNCTION__, phy_adr);
+		return -EFAULT;
+	}
+	if (reg_ofs > PHYREG_MASK) {
+		printf("Err..(%s) Invalid register offset %d\n",
+			__FUNCTION__, reg_ofs);
+		return -EFAULT;
+	}
+
+	timeout = MVGBE_PHY_SMI_TIMEOUT;
+	/* wait till the SMI is not busy */
+	do {
+		/* read smi register */
+		smi_reg = MVGBE_REG_RD(MVGBE_SMI_REG);
+		if (timeout-- == 0) {
+			printf("Err..(%s) SMI busy timeout\n", __FUNCTION__);
+			return -EFAULT;
+		}
+	} while (smi_reg & MVGBE_PHY_SMI_BUSY_MASK);
+
+	/* fill the phy address and regiser offset and read opcode */
+	smi_reg = (phy_adr << MVGBE_PHY_SMI_DEV_ADDR_OFFS)
+		| (reg_ofs << MVGBE_SMI_REG_ADDR_OFFS)
+		| MVGBE_PHY_SMI_OPCODE_READ;
+
+	/* write the smi register */
+	MVGBE_REG_WR(MVGBE_SMI_REG, smi_reg);
+
+	/*wait till read value is ready */
+	timeout = MVGBE_PHY_SMI_TIMEOUT;
+
+	do {
+		/* read smi register */
+		smi_reg = MVGBE_REG_RD(MVGBE_SMI_REG);
+		if (timeout-- == 0) {
+			printf("Err..(%s) SMI read ready timeout\n",
+				__FUNCTION__);
+			return -EFAULT;
+		}
+	} while (!(smi_reg & MVGBE_PHY_SMI_READ_VALID_MASK));
+
+	/* Wait for the data to update in the SMI register */
+	for (timeout = 0; timeout < MVGBE_PHY_SMI_TIMEOUT; timeout++)
+		;
+
+	*data = (u16) (MVGBE_REG_RD(MVGBE_SMI_REG) & MVGBE_PHY_SMI_DATA_MASK);
+
+	debug("%s:(adr %d, off %d) value= %04x\n", __FUNCTION__, phy_adr,
+		reg_ofs, *data);
+
+	return 0;
+}
+
+/*
+ * smi_reg_write - imiiphy_write callback function.
+ *
+ * Returns 0 if write succeed, -EINVAL on bad parameters
+ * -ETIME on timeout
+ */
+static int smi_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+	struct mvgbe_registers *regs = dmvgbe->regs;
+	u32 smi_reg;
+	u32 timeout;
+
+	/* Phyadr write request*/
+	if (phy_adr == MV_PHY_ADR_REQUEST &&
+			reg_ofs == MV_PHY_ADR_REQUEST) {
+		MVGBE_REG_WR(regs->phyadr, data);
+		return 0;
+	}
+
+	/* check parameters */
+	if (phy_adr > PHYADR_MASK) {
+		printf("Err..(%s) Invalid phy address\n", __FUNCTION__);
+		return -EINVAL;
+	}
+	if (reg_ofs > PHYREG_MASK) {
+		printf("Err..(%s) Invalid register offset\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	/* wait till the SMI is not busy */
+	timeout = MVGBE_PHY_SMI_TIMEOUT;
+	do {
+		/* read smi register */
+		smi_reg = MVGBE_REG_RD(MVGBE_SMI_REG);
+		if (timeout-- == 0) {
+			printf("Err..(%s) SMI busy timeout\n", __FUNCTION__);
+			return -ETIME;
+		}
+	} while (smi_reg & MVGBE_PHY_SMI_BUSY_MASK);
+
+	/* fill the phy addr and reg offset and write opcode and data */
+	smi_reg = (data << MVGBE_PHY_SMI_DATA_OFFS);
+	smi_reg |= (phy_adr << MVGBE_PHY_SMI_DEV_ADDR_OFFS)
+		| (reg_ofs << MVGBE_SMI_REG_ADDR_OFFS);
+	smi_reg &= ~MVGBE_PHY_SMI_OPCODE_READ;
+
+	/* write the smi register */
+	MVGBE_REG_WR(MVGBE_SMI_REG, smi_reg);
+
+	return 0;
+}
+#endif
+
+#if defined(CONFIG_PHYLIB)
+int mvgbe_phy_read(struct mii_dev *bus, int phy_addr, int dev_addr,
+		   int reg_addr)
+{
+	u16 data;
+	int ret;
+	ret = smi_reg_read(bus->name, phy_addr, reg_addr, &data);
+	if (ret)
+		return ret;
+	return data;
+}
+
+int mvgbe_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
+		    int reg_addr, u16 data)
+{
+	return smi_reg_write(bus->name, phy_addr, reg_addr, data);
+}
+#endif
+
+/* Stop and checks all queues */
+static void stop_queue(u32 * qreg)
+{
+	u32 reg_data;
+
+	reg_data = readl(qreg);
+
+	if (reg_data & 0xFF) {
+		/* Issue stop command for active channels only */
+		writel((reg_data << 8), qreg);
+
+		/* Wait for all queue activity to terminate. */
+		do {
+			/*
+			 * Check port cause register that all queues
+			 * are stopped
+			 */
+			reg_data = readl(qreg);
+		}
+		while (reg_data & 0xFF);
+	}
+}
+
+/*
+ * set_access_control - Config address decode parameters for Ethernet unit
+ *
+ * This function configures the address decode parameters for the Gigabit
+ * Ethernet Controller according the given parameters struct.
+ *
+ * @regs	Register struct pointer.
+ * @param	Address decode parameter struct.
+ */
+static void set_access_control(struct mvgbe_registers *regs,
+				struct mvgbe_winparam *param)
+{
+	u32 access_prot_reg;
+
+	/* Set access control register */
+	access_prot_reg = MVGBE_REG_RD(regs->epap);
+	/* clear window permission */
+	access_prot_reg &= (~(3 << (param->win * 2)));
+	access_prot_reg |= (param->access_ctrl << (param->win * 2));
+	MVGBE_REG_WR(regs->epap, access_prot_reg);
+
+	/* Set window Size reg (SR) */
+	MVGBE_REG_WR(regs->barsz[param->win].size,
+			(((param->size / 0x10000) - 1) << 16));
+
+	/* Set window Base address reg (BA) */
+	MVGBE_REG_WR(regs->barsz[param->win].bar,
+			(param->target | param->attrib | param->base_addr));
+	/* High address remap reg (HARR) */
+	if (param->win < 4)
+		MVGBE_REG_WR(regs->ha_remap[param->win], param->high_addr);
+
+	/* Base address enable reg (BARER) */
+	if (param->enable == 1)
+		MVGBE_REG_BITS_RESET(regs->bare, (1 << param->win));
+	else
+		MVGBE_REG_BITS_SET(regs->bare, (1 << param->win));
+}
+
+static void set_dram_access(struct mvgbe_registers *regs)
+{
+	struct mvgbe_winparam win_param;
+	int i;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		/* Set access parameters for DRAM bank i */
+		win_param.win = i;	/* Use Ethernet window i */
+		/* Window target - DDR */
+		win_param.target = MVGBE_TARGET_DRAM;
+		/* Enable full access */
+		win_param.access_ctrl = EWIN_ACCESS_FULL;
+		win_param.high_addr = 0;
+		/* Get bank base and size */
+		win_param.base_addr = gd->bd->bi_dram[i].start;
+		win_param.size = gd->bd->bi_dram[i].size;
+		if (win_param.size == 0)
+			win_param.enable = 0;
+		else
+			win_param.enable = 1;	/* Enable the access */
+
+		/* Enable DRAM bank */
+		switch (i) {
+		case 0:
+			win_param.attrib = EBAR_DRAM_CS0;
+			break;
+		case 1:
+			win_param.attrib = EBAR_DRAM_CS1;
+			break;
+		case 2:
+			win_param.attrib = EBAR_DRAM_CS2;
+			break;
+		case 3:
+			win_param.attrib = EBAR_DRAM_CS3;
+			break;
+		default:
+			/* invalid bank, disable access */
+			win_param.enable = 0;
+			win_param.attrib = 0;
+			break;
+		}
+		/* Set the access control for address window(EPAPR) RD/WR */
+		set_access_control(regs, &win_param);
+	}
+}
+
+/*
+ * port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
+ *
+ * Go through all the DA filter tables (Unicast, Special Multicast & Other
+ * Multicast) and set each entry to 0.
+ */
+static void port_init_mac_tables(struct mvgbe_registers *regs)
+{
+	int table_index;
+
+	/* Clear DA filter unicast table (Ex_dFUT) */
+	for (table_index = 0; table_index < 4; ++table_index)
+		MVGBE_REG_WR(regs->dfut[table_index], 0);
+
+	for (table_index = 0; table_index < 64; ++table_index) {
+		/* Clear DA filter special multicast table (Ex_dFSMT) */
+		MVGBE_REG_WR(regs->dfsmt[table_index], 0);
+		/* Clear DA filter other multicast table (Ex_dFOMT) */
+		MVGBE_REG_WR(regs->dfomt[table_index], 0);
+	}
+}
+
+/*
+ * port_uc_addr - This function Set the port unicast address table
+ *
+ * This function locates the proper entry in the Unicast table for the
+ * specified MAC nibble and sets its properties according to function
+ * parameters.
+ * This function add/removes MAC addresses from the port unicast address
+ * table.
+ *
+ * @uc_nibble	Unicast MAC Address last nibble.
+ * @option      0 = Add, 1 = remove address.
+ *
+ * RETURN: 1 if output succeeded. 0 if option parameter is invalid.
+ */
+static int port_uc_addr(struct mvgbe_registers *regs, u8 uc_nibble,
+			int option)
+{
+	u32 unicast_reg;
+	u32 tbl_offset;
+	u32 reg_offset;
+
+	/* Locate the Unicast table entry */
+	uc_nibble = (0xf & uc_nibble);
+	/* Register offset from unicast table base */
+	tbl_offset = (uc_nibble / 4);
+	/* Entry offset within the above register */
+	reg_offset = uc_nibble % 4;
+
+	switch (option) {
+	case REJECT_MAC_ADDR:
+		/*
+		 * Clear accepts frame bit at specified unicast
+		 * DA table entry
+		 */
+		unicast_reg = MVGBE_REG_RD(regs->dfut[tbl_offset]);
+		unicast_reg &= (0xFF << (8 * reg_offset));
+		MVGBE_REG_WR(regs->dfut[tbl_offset], unicast_reg);
+		break;
+	case ACCEPT_MAC_ADDR:
+		/* Set accepts frame bit at unicast DA filter table entry */
+		unicast_reg = MVGBE_REG_RD(regs->dfut[tbl_offset]);
+		unicast_reg &= (0xFF << (8 * reg_offset));
+		unicast_reg |= ((0x01 | (RXUQ << 1)) << (8 * reg_offset));
+		MVGBE_REG_WR(regs->dfut[tbl_offset], unicast_reg);
+		break;
+	default:
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * port_uc_addr_set - This function Set the port Unicast address.
+ */
+static void port_uc_addr_set(struct mvgbe_registers *regs, u8 * p_addr)
+{
+	u32 mac_h;
+	u32 mac_l;
+
+	mac_l = (p_addr[4] << 8) | (p_addr[5]);
+	mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) |
+		(p_addr[3] << 0);
+
+	MVGBE_REG_WR(regs->macal, mac_l);
+	MVGBE_REG_WR(regs->macah, mac_h);
+
+	/* Accept frames of this address */
+	port_uc_addr(regs, p_addr[5], ACCEPT_MAC_ADDR);
+}
+
+/*
+ * mvgbe_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
+ */
+static void mvgbe_init_rx_desc_ring(struct mvgbe_device *dmvgbe)
+{
+	struct mvgbe_rxdesc *p_rx_desc;
+	int i;
+
+	/* initialize the Rx descriptors ring */
+	p_rx_desc = dmvgbe->p_rxdesc;
+	for (i = 0; i < RINGSZ; i++) {
+		p_rx_desc->cmd_sts =
+			MVGBE_BUFFER_OWNED_BY_DMA | MVGBE_RX_EN_INTERRUPT;
+		p_rx_desc->buf_size = PKTSIZE_ALIGN;
+		p_rx_desc->byte_cnt = 0;
+		p_rx_desc->buf_ptr = dmvgbe->p_rxbuf + i * PKTSIZE_ALIGN;
+		if (i == (RINGSZ - 1))
+			p_rx_desc->nxtdesc_p = dmvgbe->p_rxdesc;
+		else {
+			p_rx_desc->nxtdesc_p = (struct mvgbe_rxdesc *)
+				((u32) p_rx_desc + MV_RXQ_DESC_ALIGNED_SIZE);
+			p_rx_desc = p_rx_desc->nxtdesc_p;
+		}
+	}
+	dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc;
+}
+
+static int mvgbe_init(struct eth_device *dev)
+{
+	struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+	struct mvgbe_registers *regs = dmvgbe->regs;
+#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) &&  \
+	!defined(CONFIG_PHYLIB) &&			 \
+	defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
+	int i;
+#endif
+	/* setup RX rings */
+	mvgbe_init_rx_desc_ring(dmvgbe);
+
+	/* Clear the ethernet port interrupts */
+	MVGBE_REG_WR(regs->ic, 0);
+	MVGBE_REG_WR(regs->ice, 0);
+	/* Unmask RX buffer and TX end interrupt */
+	MVGBE_REG_WR(regs->pim, INT_CAUSE_UNMASK_ALL);
+	/* Unmask phy and link status changes interrupts */
+	MVGBE_REG_WR(regs->peim, INT_CAUSE_UNMASK_ALL_EXT);
+
+	set_dram_access(regs);
+	port_init_mac_tables(regs);
+	port_uc_addr_set(regs, dmvgbe->dev.enetaddr);
+
+	/* Assign port configuration and command. */
+	MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL);
+	MVGBE_REG_WR(regs->pxcx, PORT_CFG_EXTEND_VALUE);
+	MVGBE_REG_WR(regs->psc0, PORT_SERIAL_CONTROL_VALUE);
+
+	/* Assign port SDMA configuration */
+	MVGBE_REG_WR(regs->sdc, PORT_SDMA_CFG_VALUE);
+	MVGBE_REG_WR(regs->tqx[0].qxttbc, QTKNBKT_DEF_VAL);
+	MVGBE_REG_WR(regs->tqx[0].tqxtbc,
+		(QMTBS_DEF_VAL << 16) | QTKNRT_DEF_VAL);
+	/* Turn off the port/RXUQ bandwidth limitation */
+	MVGBE_REG_WR(regs->pmtu, 0);
+
+	/* Set maximum receive buffer to 9700 bytes */
+	MVGBE_REG_WR(regs->psc0, MVGBE_MAX_RX_PACKET_9700BYTE
+			| (MVGBE_REG_RD(regs->psc0) & MRU_MASK));
+
+	/* Enable port initially */
+	MVGBE_REG_BITS_SET(regs->psc0, MVGBE_SERIAL_PORT_EN);
+
+	/*
+	 * Set ethernet MTU for leaky bucket mechanism to 0 - this will
+	 * disable the leaky bucket mechanism .
+	 */
+	MVGBE_REG_WR(regs->pmtu, 0);
+
+	/* Assignment of Rx CRDB of given RXUQ */
+	MVGBE_REG_WR(regs->rxcdp[RXUQ], (u32) dmvgbe->p_rxdesc_curr);
+	/* ensure previous write is done before enabling Rx DMA */
+	isb();
+	/* Enable port Rx. */
+	MVGBE_REG_WR(regs->rqc, (1 << RXUQ));
+
+#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
+	!defined(CONFIG_PHYLIB) && \
+	defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
+	/* Wait up to 5s for the link status */
+	for (i = 0; i < 5; i++) {
+		u16 phyadr;
+
+		miiphy_read(dev->name, MV_PHY_ADR_REQUEST,
+				MV_PHY_ADR_REQUEST, &phyadr);
+		/* Return if we get link up */
+		if (miiphy_link(dev->name, phyadr))
+			return 0;
+		udelay(1000000);
+	}
+
+	printf("No link on %s\n", dev->name);
+	return -1;
+#endif
+	return 0;
+}
+
+static int mvgbe_halt(struct eth_device *dev)
+{
+	struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+	struct mvgbe_registers *regs = dmvgbe->regs;
+
+	/* Disable all gigE address decoder */
+	MVGBE_REG_WR(regs->bare, 0x3f);
+
+	stop_queue(&regs->tqc);
+	stop_queue(&regs->rqc);
+
+	/* Disable port */
+	MVGBE_REG_BITS_RESET(regs->psc0, MVGBE_SERIAL_PORT_EN);
+	/* Set port is not reset */
+	MVGBE_REG_BITS_RESET(regs->psc1, 1 << 4);
+#ifdef CONFIG_SYS_MII_MODE
+	/* Set MMI interface up */
+	MVGBE_REG_BITS_RESET(regs->psc1, 1 << 3);
+#endif
+	/* Disable & mask ethernet port interrupts */
+	MVGBE_REG_WR(regs->ic, 0);
+	MVGBE_REG_WR(regs->ice, 0);
+	MVGBE_REG_WR(regs->pim, 0);
+	MVGBE_REG_WR(regs->peim, 0);
+
+	return 0;
+}
+
+static int mvgbe_write_hwaddr(struct eth_device *dev)
+{
+	struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+	struct mvgbe_registers *regs = dmvgbe->regs;
+
+	/* Programs net device MAC address after initialization */
+	port_uc_addr_set(regs, dmvgbe->dev.enetaddr);
+	return 0;
+}
+
+static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
+{
+	struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+	struct mvgbe_registers *regs = dmvgbe->regs;
+	struct mvgbe_txdesc *p_txdesc = dmvgbe->p_txdesc;
+	void *p = (void *)dataptr;
+	u32 cmd_sts;
+	u32 txuq0_reg_addr;
+
+	/* Copy buffer if it's misaligned */
+	if ((u32) dataptr & 0x07) {
+		if (datasize > PKTSIZE_ALIGN) {
+			printf("Non-aligned data too large (%d)\n",
+					datasize);
+			return -1;
+		}
+
+		memcpy(dmvgbe->p_aligned_txbuf, p, datasize);
+		p = dmvgbe->p_aligned_txbuf;
+	}
+
+	p_txdesc->cmd_sts = MVGBE_ZERO_PADDING | MVGBE_GEN_CRC;
+	p_txdesc->cmd_sts |= MVGBE_TX_FIRST_DESC | MVGBE_TX_LAST_DESC;
+	p_txdesc->cmd_sts |= MVGBE_BUFFER_OWNED_BY_DMA;
+	p_txdesc->cmd_sts |= MVGBE_TX_EN_INTERRUPT;
+	p_txdesc->buf_ptr = (u8 *) p;
+	p_txdesc->byte_cnt = datasize;
+
+	/* Set this tc desc as zeroth TXUQ */
+	txuq0_reg_addr = (u32)&regs->tcqdp[TXUQ];
+	writel((u32) p_txdesc, txuq0_reg_addr);
+
+	/* ensure tx desc writes above are performed before we start Tx DMA */
+	isb();
+
+	/* Apply send command using zeroth TXUQ */
+	MVGBE_REG_WR(regs->tqc, (1 << TXUQ));
+
+	/*
+	 * wait for packet xmit completion
+	 */
+	cmd_sts = readl(&p_txdesc->cmd_sts);
+	while (cmd_sts & MVGBE_BUFFER_OWNED_BY_DMA) {
+		/* return fail if error is detected */
+		if ((cmd_sts & (MVGBE_ERROR_SUMMARY | MVGBE_TX_LAST_FRAME)) ==
+				(MVGBE_ERROR_SUMMARY | MVGBE_TX_LAST_FRAME) &&
+				cmd_sts & (MVGBE_UR_ERROR | MVGBE_RL_ERROR)) {
+			printf("Err..(%s) in xmit packet\n", __FUNCTION__);
+			return -1;
+		}
+		cmd_sts = readl(&p_txdesc->cmd_sts);
+	};
+	return 0;
+}
+
+static int mvgbe_recv(struct eth_device *dev)
+{
+	struct mvgbe_device *dmvgbe = to_mvgbe(dev);
+	struct mvgbe_rxdesc *p_rxdesc_curr = dmvgbe->p_rxdesc_curr;
+	u32 cmd_sts;
+	u32 timeout = 0;
+	u32 rxdesc_curr_addr;
+
+	/* wait untill rx packet available or timeout */
+	do {
+		if (timeout < MVGBE_PHY_SMI_TIMEOUT)
+			timeout++;
+		else {
+			debug("%s time out...\n", __FUNCTION__);
+			return -1;
+		}
+	} while (readl(&p_rxdesc_curr->cmd_sts) & MVGBE_BUFFER_OWNED_BY_DMA);
+
+	if (p_rxdesc_curr->byte_cnt != 0) {
+		debug("%s: Received %d byte Packet @ 0x%x (cmd_sts= %08x)\n",
+			__FUNCTION__, (u32) p_rxdesc_curr->byte_cnt,
+			(u32) p_rxdesc_curr->buf_ptr,
+			(u32) p_rxdesc_curr->cmd_sts);
+	}
+
+	/*
+	 * In case received a packet without first/last bits on
+	 * OR the error summary bit is on,
+	 * the packets needs to be dropeed.
+	 */
+	cmd_sts = readl(&p_rxdesc_curr->cmd_sts);
+
+	if ((cmd_sts &
+		(MVGBE_RX_FIRST_DESC | MVGBE_RX_LAST_DESC))
+		!= (MVGBE_RX_FIRST_DESC | MVGBE_RX_LAST_DESC)) {
+
+		printf("Err..(%s) Dropping packet spread on"
+			" multiple descriptors\n", __FUNCTION__);
+
+	} else if (cmd_sts & MVGBE_ERROR_SUMMARY) {
+
+		printf("Err..(%s) Dropping packet with errors\n",
+			__FUNCTION__);
+
+	} else {
+		/* !!! call higher layer processing */
+		debug("%s: Sending Received packet to"
+			" upper layer (NetReceive)\n", __FUNCTION__);
+
+		/* let the upper layer handle the packet */
+		NetReceive((p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET),
+			(int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET));
+	}
+	/*
+	 * free these descriptors and point next in the ring
+	 */
+	p_rxdesc_curr->cmd_sts =
+		MVGBE_BUFFER_OWNED_BY_DMA | MVGBE_RX_EN_INTERRUPT;
+	p_rxdesc_curr->buf_size = PKTSIZE_ALIGN;
+	p_rxdesc_curr->byte_cnt = 0;
+
+	rxdesc_curr_addr = (u32)&dmvgbe->p_rxdesc_curr;
+	writel((unsigned)p_rxdesc_curr->nxtdesc_p, rxdesc_curr_addr);
+
+	return 0;
+}
+
+#if defined(CONFIG_PHYLIB)
+int mvgbe_phylib_init(struct eth_device *dev, int phyid)
+{
+	struct mii_dev *bus;
+	struct phy_device *phydev;
+	int ret;
+
+	bus = mdio_alloc();
+	if (!bus) {
+		printf("mdio_alloc failed\n");
+		return -ENOMEM;
+	}
+	bus->read = mvgbe_phy_read;
+	bus->write = mvgbe_phy_write;
+	sprintf(bus->name, dev->name);
+
+	ret = mdio_register(bus);
+	if (ret) {
+		printf("mdio_register failed\n");
+		free(bus);
+		return -ENOMEM;
+	}
+
+	/* Set phy address of the port */
+	mvgbe_phy_write(bus, MV_PHY_ADR_REQUEST, 0, MV_PHY_ADR_REQUEST, phyid);
+
+	phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RGMII);
+	if (!phydev) {
+		printf("phy_connect failed\n");
+		return -ENODEV;
+	}
+
+	phy_config(phydev);
+	phy_startup(phydev);
+
+	return 0;
+}
+#endif
+
+int mvgbe_initialize(bd_t *bis)
+{
+	struct mvgbe_device *dmvgbe;
+	struct eth_device *dev;
+	int devnum;
+	u8 used_ports[MAX_MVGBE_DEVS] = CONFIG_MVGBE_PORTS;
+
+	for (devnum = 0; devnum < MAX_MVGBE_DEVS; devnum++) {
+		/*skip if port is configured not to use */
+		if (used_ports[devnum] == 0)
+			continue;
+
+		dmvgbe = malloc(sizeof(struct mvgbe_device));
+
+		if (!dmvgbe)
+			goto error1;
+
+		memset(dmvgbe, 0, sizeof(struct mvgbe_device));
+
+		dmvgbe->p_rxdesc =
+			(struct mvgbe_rxdesc *)memalign(PKTALIGN,
+			MV_RXQ_DESC_ALIGNED_SIZE*RINGSZ + 1);
+
+		if (!dmvgbe->p_rxdesc)
+			goto error2;
+
+		dmvgbe->p_rxbuf = (u8 *) memalign(PKTALIGN,
+			RINGSZ*PKTSIZE_ALIGN + 1);
+
+		if (!dmvgbe->p_rxbuf)
+			goto error3;
+
+		dmvgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
+
+		if (!dmvgbe->p_aligned_txbuf)
+			goto error4;
+
+		dmvgbe->p_txdesc = (struct mvgbe_txdesc *) memalign(
+			PKTALIGN, sizeof(struct mvgbe_txdesc) + 1);
+
+		if (!dmvgbe->p_txdesc) {
+			free(dmvgbe->p_aligned_txbuf);
+error4:
+			free(dmvgbe->p_rxbuf);
+error3:
+			free(dmvgbe->p_rxdesc);
+error2:
+			free(dmvgbe);
+error1:
+			printf("Err.. %s Failed to allocate memory\n",
+				__FUNCTION__);
+			return -1;
+		}
+
+		dev = &dmvgbe->dev;
+
+		/* must be less than sizeof(dev->name) */
+		sprintf(dev->name, "egiga%d", devnum);
+
+		switch (devnum) {
+		case 0:
+			dmvgbe->regs = (void *)MVGBE0_BASE;
+			break;
+#if defined(MVGBE1_BASE)
+		case 1:
+			dmvgbe->regs = (void *)MVGBE1_BASE;
+			break;
+#endif
+		default:	/* this should never happen */
+			printf("Err..(%s) Invalid device number %d\n",
+				__FUNCTION__, devnum);
+			return -1;
+		}
+
+		dev->init = (void *)mvgbe_init;
+		dev->halt = (void *)mvgbe_halt;
+		dev->send = (void *)mvgbe_send;
+		dev->recv = (void *)mvgbe_recv;
+		dev->write_hwaddr = (void *)mvgbe_write_hwaddr;
+
+		eth_register(dev);
+
+#if defined(CONFIG_PHYLIB)
+		mvgbe_phylib_init(dev, PHY_BASE_ADR + devnum);
+#elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+		miiphy_register(dev->name, smi_reg_read, smi_reg_write);
+		/* Set phy address of the port */
+		miiphy_write(dev->name, MV_PHY_ADR_REQUEST,
+				MV_PHY_ADR_REQUEST, PHY_BASE_ADR + devnum);
+#endif
+	}
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/mvgbe.h b/marvell/uboot/drivers/net/mvgbe.h
new file mode 100644
index 0000000..27a3f41
--- /dev/null
+++ b/marvell/uboot/drivers/net/mvgbe.h
@@ -0,0 +1,498 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * based on - Driver for MV64360X ethernet ports
+ * Copyright (C) 2002 rabeeh@galileo.co.il
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __MVGBE_H__
+#define __MVGBE_H__
+
+/* PHY_BASE_ADR is board specific and can be configured */
+#if defined (CONFIG_PHY_BASE_ADR)
+#define PHY_BASE_ADR		CONFIG_PHY_BASE_ADR
+#else
+#define PHY_BASE_ADR		0x08	/* default phy base addr */
+#endif
+
+/* Constants */
+#define INT_CAUSE_UNMASK_ALL		0x0007ffff
+#define INT_CAUSE_UNMASK_ALL_EXT	0x0011ffff
+#define MRU_MASK			0xfff1ffff
+#define PHYADR_MASK			0x0000001f
+#define PHYREG_MASK			0x0000001f
+#define QTKNBKT_DEF_VAL			0x3fffffff
+#define QMTBS_DEF_VAL			0x000003ff
+#define QTKNRT_DEF_VAL			0x0000fcff
+#define RXUQ	0 /* Used Rx queue */
+#define TXUQ	0 /* Used Rx queue */
+
+#define to_mvgbe(_d) container_of(_d, struct mvgbe_device, dev)
+#define MVGBE_REG_WR(adr, val)		writel(val, &adr)
+#define MVGBE_REG_RD(adr)		readl(&adr)
+#define MVGBE_REG_BITS_RESET(adr, val)	writel(readl(&adr) & ~(val), &adr)
+#define MVGBE_REG_BITS_SET(adr, val)	writel(readl(&adr) | val, &adr)
+
+/* Default port configuration value */
+#define PRT_CFG_VAL			( \
+	MVGBE_UCAST_MOD_NRML		| \
+	MVGBE_DFLT_RXQ(RXUQ)		| \
+	MVGBE_DFLT_RX_ARPQ(RXUQ)	| \
+	MVGBE_RX_BC_IF_NOT_IP_OR_ARP	| \
+	MVGBE_RX_BC_IF_IP		| \
+	MVGBE_RX_BC_IF_ARP		| \
+	MVGBE_CPTR_TCP_FRMS_DIS		| \
+	MVGBE_CPTR_UDP_FRMS_DIS		| \
+	MVGBE_DFLT_RX_TCPQ(RXUQ)	| \
+	MVGBE_DFLT_RX_UDPQ(RXUQ)	| \
+	MVGBE_DFLT_RX_BPDUQ(RXUQ))
+
+/* Default port extend configuration value */
+#define PORT_CFG_EXTEND_VALUE		\
+	MVGBE_SPAN_BPDU_PACKETS_AS_NORMAL	| \
+	MVGBE_PARTITION_DIS		| \
+	MVGBE_TX_CRC_GENERATION_EN
+
+#define GT_MVGBE_IPG_INT_RX(value)	((value & 0x3fff) << 8)
+
+/* Default sdma control value */
+#define PORT_SDMA_CFG_VALUE		( \
+	MVGBE_RX_BURST_SIZE_16_64BIT	| \
+	MVGBE_BLM_RX_NO_SWAP		| \
+	MVGBE_BLM_TX_NO_SWAP		| \
+	GT_MVGBE_IPG_INT_RX(RXUQ)	| \
+	MVGBE_TX_BURST_SIZE_16_64BIT)
+
+/* Default port serial control value */
+#ifndef PORT_SERIAL_CONTROL_VALUE
+#define PORT_SERIAL_CONTROL_VALUE		( \
+	MVGBE_FORCE_LINK_PASS			| \
+	MVGBE_DIS_AUTO_NEG_FOR_DUPLX		| \
+	MVGBE_DIS_AUTO_NEG_FOR_FLOW_CTRL	| \
+	MVGBE_ADV_NO_FLOW_CTRL			| \
+	MVGBE_FORCE_FC_MODE_NO_PAUSE_DIS_TX	| \
+	MVGBE_FORCE_BP_MODE_NO_JAM		| \
+	(1 << 9) /* Reserved bit has to be 1 */	| \
+	MVGBE_DO_NOT_FORCE_LINK_FAIL		| \
+	MVGBE_EN_AUTO_NEG_SPEED_GMII		| \
+	MVGBE_DTE_ADV_0				| \
+	MVGBE_MIIPHY_MAC_MODE			| \
+	MVGBE_AUTO_NEG_NO_CHANGE		| \
+	MVGBE_MAX_RX_PACKET_1552BYTE		| \
+	MVGBE_CLR_EXT_LOOPBACK			| \
+	MVGBE_SET_FULL_DUPLEX_MODE		| \
+	MVGBE_DIS_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX)
+#endif
+
+/* Tx WRR confoguration macros */
+#define PORT_MAX_TRAN_UNIT	0x24	/* MTU register (default) 9KByte */
+#define PORT_MAX_TOKEN_BUCKET_SIZE	0x_FFFF	/* PMTBS reg (default) */
+#define PORT_TOKEN_RATE		1023	/* PTTBRC reg (default) */
+/* MAC accepet/reject macros */
+#define ACCEPT_MAC_ADDR		0
+#define REJECT_MAC_ADDR		1
+/* Size of a Tx/Rx descriptor used in chain list data structure */
+#define MV_RXQ_DESC_ALIGNED_SIZE	\
+	(((sizeof(struct mvgbe_rxdesc) / PKTALIGN) + 1) * PKTALIGN)
+/* Buffer offset from buffer pointer */
+#define RX_BUF_OFFSET		0x2
+
+/* Port serial status reg (PSR) */
+#define MVGBE_INTERFACE_GMII_MII	0
+#define MVGBE_INTERFACE_PCM		1
+#define MVGBE_LINK_IS_DOWN		0
+#define MVGBE_LINK_IS_UP		(1 << 1)
+#define MVGBE_PORT_AT_HALF_DUPLEX	0
+#define MVGBE_PORT_AT_FULL_DUPLEX	(1 << 2)
+#define MVGBE_RX_FLOW_CTRL_DISD		0
+#define MVGBE_RX_FLOW_CTRL_ENBALED	(1 << 3)
+#define MVGBE_GMII_SPEED_100_10		0
+#define MVGBE_GMII_SPEED_1000		(1 << 4)
+#define MVGBE_MII_SPEED_10		0
+#define MVGBE_MII_SPEED_100		(1 << 5)
+#define MVGBE_NO_TX			0
+#define MVGBE_TX_IN_PROGRESS		(1 << 7)
+#define MVGBE_BYPASS_NO_ACTIVE		0
+#define MVGBE_BYPASS_ACTIVE		(1 << 8)
+#define MVGBE_PORT_NOT_AT_PARTN_STT	0
+#define MVGBE_PORT_AT_PARTN_STT		(1 << 9)
+#define MVGBE_PORT_TX_FIFO_NOT_EMPTY	0
+#define MVGBE_PORT_TX_FIFO_EMPTY	(1 << 10)
+
+/* These macros describes the Port configuration reg (Px_cR) bits */
+#define MVGBE_UCAST_MOD_NRML		0
+#define MVGBE_UNICAST_PROMISCUOUS_MODE	1
+#define MVGBE_DFLT_RXQ(_x)		(_x << 1)
+#define MVGBE_DFLT_RX_ARPQ(_x)		(_x << 4)
+#define MVGBE_RX_BC_IF_NOT_IP_OR_ARP	0
+#define MVGBE_REJECT_BC_IF_NOT_IP_OR_ARP (1 << 7)
+#define MVGBE_RX_BC_IF_IP		0
+#define MVGBE_REJECT_BC_IF_IP		(1 << 8)
+#define MVGBE_RX_BC_IF_ARP		0
+#define MVGBE_REJECT_BC_IF_ARP		(1 << 9)
+#define MVGBE_TX_AM_NO_UPDATE_ERR_SMRY	(1 << 12)
+#define MVGBE_CPTR_TCP_FRMS_DIS		0
+#define MVGBE_CPTR_TCP_FRMS_EN		(1 << 14)
+#define MVGBE_CPTR_UDP_FRMS_DIS		0
+#define MVGBE_CPTR_UDP_FRMS_EN		(1 << 15)
+#define MVGBE_DFLT_RX_TCPQ(_x)		(_x << 16)
+#define MVGBE_DFLT_RX_UDPQ(_x)		(_x << 19)
+#define MVGBE_DFLT_RX_BPDUQ(_x)		(_x << 22)
+#define MVGBE_DFLT_RX_TCP_CHKSUM_MODE	(1 << 25)
+
+/* These macros describes the Port configuration extend reg (Px_cXR) bits*/
+#define MVGBE_CLASSIFY_EN			1
+#define MVGBE_SPAN_BPDU_PACKETS_AS_NORMAL	0
+#define MVGBE_SPAN_BPDU_PACKETS_TO_RX_Q7	(1 << 1)
+#define MVGBE_PARTITION_DIS			0
+#define MVGBE_PARTITION_EN			(1 << 2)
+#define MVGBE_TX_CRC_GENERATION_EN		0
+#define MVGBE_TX_CRC_GENERATION_DIS		(1 << 3)
+
+/* These macros describes the Port Sdma configuration reg (SDCR) bits */
+#define MVGBE_RIFB				1
+#define MVGBE_RX_BURST_SIZE_1_64BIT		0
+#define MVGBE_RX_BURST_SIZE_2_64BIT		(1 << 1)
+#define MVGBE_RX_BURST_SIZE_4_64BIT		(1 << 2)
+#define MVGBE_RX_BURST_SIZE_8_64BIT		((1 << 2) | (1 << 1))
+#define MVGBE_RX_BURST_SIZE_16_64BIT		(1 << 3)
+#define MVGBE_BLM_RX_NO_SWAP			(1 << 4)
+#define MVGBE_BLM_RX_BYTE_SWAP			0
+#define MVGBE_BLM_TX_NO_SWAP			(1 << 5)
+#define MVGBE_BLM_TX_BYTE_SWAP			0
+#define MVGBE_DESCRIPTORS_BYTE_SWAP		(1 << 6)
+#define MVGBE_DESCRIPTORS_NO_SWAP		0
+#define MVGBE_TX_BURST_SIZE_1_64BIT		0
+#define MVGBE_TX_BURST_SIZE_2_64BIT		(1 << 22)
+#define MVGBE_TX_BURST_SIZE_4_64BIT		(1 << 23)
+#define MVGBE_TX_BURST_SIZE_8_64BIT		((1 << 23) | (1 << 22))
+#define MVGBE_TX_BURST_SIZE_16_64BIT		(1 << 24)
+
+/* These macros describes the Port serial control reg (PSCR) bits */
+#define MVGBE_SERIAL_PORT_DIS			0
+#define MVGBE_SERIAL_PORT_EN			1
+#define MVGBE_FORCE_LINK_PASS			(1 << 1)
+#define MVGBE_DO_NOT_FORCE_LINK_PASS		0
+#define MVGBE_EN_AUTO_NEG_FOR_DUPLX		0
+#define MVGBE_DIS_AUTO_NEG_FOR_DUPLX		(1 << 2)
+#define MVGBE_EN_AUTO_NEG_FOR_FLOW_CTRL		0
+#define MVGBE_DIS_AUTO_NEG_FOR_FLOW_CTRL	(1 << 3)
+#define MVGBE_ADV_NO_FLOW_CTRL			0
+#define MVGBE_ADV_SYMMETRIC_FLOW_CTRL		(1 << 4)
+#define MVGBE_FORCE_FC_MODE_NO_PAUSE_DIS_TX	0
+#define MVGBE_FORCE_FC_MODE_TX_PAUSE_DIS	(1 << 5)
+#define MVGBE_FORCE_BP_MODE_NO_JAM		0
+#define MVGBE_FORCE_BP_MODE_JAM_TX		(1 << 7)
+#define MVGBE_FORCE_BP_MODE_JAM_TX_ON_RX_ERR	(1 << 8)
+#define MVGBE_FORCE_LINK_FAIL			0
+#define MVGBE_DO_NOT_FORCE_LINK_FAIL		(1 << 10)
+#define MVGBE_DIS_AUTO_NEG_SPEED_GMII		(1 << 13)
+#define MVGBE_EN_AUTO_NEG_SPEED_GMII		0
+#define MVGBE_DTE_ADV_0				0
+#define MVGBE_DTE_ADV_1				(1 << 14)
+#define MVGBE_MIIPHY_MAC_MODE			0
+#define MVGBE_MIIPHY_PHY_MODE			(1 << 15)
+#define MVGBE_AUTO_NEG_NO_CHANGE		0
+#define MVGBE_RESTART_AUTO_NEG			(1 << 16)
+#define MVGBE_MAX_RX_PACKET_1518BYTE		0
+#define MVGBE_MAX_RX_PACKET_1522BYTE		(1 << 17)
+#define MVGBE_MAX_RX_PACKET_1552BYTE		(1 << 18)
+#define MVGBE_MAX_RX_PACKET_9022BYTE		((1 << 18) | (1 << 17))
+#define MVGBE_MAX_RX_PACKET_9192BYTE		(1 << 19)
+#define MVGBE_MAX_RX_PACKET_9700BYTE		((1 << 19) | (1 << 17))
+#define MVGBE_SET_EXT_LOOPBACK			(1 << 20)
+#define MVGBE_CLR_EXT_LOOPBACK			0
+#define MVGBE_SET_FULL_DUPLEX_MODE		(1 << 21)
+#define MVGBE_SET_HALF_DUPLEX_MODE		0
+#define MVGBE_EN_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX	(1 << 22)
+#define MVGBE_DIS_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX 0
+#define MVGBE_SET_GMII_SPEED_TO_10_100		0
+#define MVGBE_SET_GMII_SPEED_TO_1000		(1 << 23)
+#define MVGBE_SET_MII_SPEED_TO_10		0
+#define MVGBE_SET_MII_SPEED_TO_100		(1 << 24)
+
+/* SMI register fields */
+#define MVGBE_PHY_SMI_TIMEOUT		10000
+#define MVGBE_PHY_SMI_DATA_OFFS		0	/* Data */
+#define MVGBE_PHY_SMI_DATA_MASK		(0xffff << MVGBE_PHY_SMI_DATA_OFFS)
+#define MVGBE_PHY_SMI_DEV_ADDR_OFFS	16	/* PHY device address */
+#define MVGBE_PHY_SMI_DEV_ADDR_MASK \
+	(PHYADR_MASK << MVGBE_PHY_SMI_DEV_ADDR_OFFS)
+#define MVGBE_SMI_REG_ADDR_OFFS		21	/* PHY device reg addr */
+#define MVGBE_SMI_REG_ADDR_MASK \
+	(PHYADR_MASK << MVGBE_SMI_REG_ADDR_OFFS)
+#define MVGBE_PHY_SMI_OPCODE_OFFS	26	/* Write/Read opcode */
+#define MVGBE_PHY_SMI_OPCODE_MASK	(3 << MVGBE_PHY_SMI_OPCODE_OFFS)
+#define MVGBE_PHY_SMI_OPCODE_WRITE	(0 << MVGBE_PHY_SMI_OPCODE_OFFS)
+#define MVGBE_PHY_SMI_OPCODE_READ	(1 << MVGBE_PHY_SMI_OPCODE_OFFS)
+#define MVGBE_PHY_SMI_READ_VALID_MASK	(1 << 27)	/* Read Valid */
+#define MVGBE_PHY_SMI_BUSY_MASK		(1 << 28)	/* Busy */
+
+/* SDMA command status fields macros */
+/* Tx & Rx descriptors status */
+#define MVGBE_ERROR_SUMMARY		1
+/* Tx & Rx descriptors command */
+#define MVGBE_BUFFER_OWNED_BY_DMA	(1 << 31)
+/* Tx descriptors status */
+#define MVGBE_LC_ERROR			0
+#define MVGBE_UR_ERROR			(1 << 1)
+#define MVGBE_RL_ERROR			(1 << 2)
+#define MVGBE_LLC_SNAP_FORMAT		(1 << 9)
+#define MVGBE_TX_LAST_FRAME		(1 << 20)
+
+/* Rx descriptors status */
+#define MVGBE_CRC_ERROR			0
+#define MVGBE_OVERRUN_ERROR		(1 << 1)
+#define MVGBE_MAX_FRAME_LENGTH_ERROR	(1 << 2)
+#define MVGBE_RESOURCE_ERROR		((1 << 2) | (1 << 1))
+#define MVGBE_VLAN_TAGGED		(1 << 19)
+#define MVGBE_BPDU_FRAME		(1 << 20)
+#define MVGBE_TCP_FRAME_OVER_IP_V_4	0
+#define MVGBE_UDP_FRAME_OVER_IP_V_4	(1 << 21)
+#define MVGBE_OTHER_FRAME_TYPE		(1 << 22)
+#define MVGBE_LAYER_2_IS_MVGBE_V_2	(1 << 23)
+#define MVGBE_FRAME_TYPE_IP_V_4		(1 << 24)
+#define MVGBE_FRAME_HEADER_OK		(1 << 25)
+#define MVGBE_RX_LAST_DESC		(1 << 26)
+#define MVGBE_RX_FIRST_DESC		(1 << 27)
+#define MVGBE_UNKNOWN_DESTINATION_ADDR	(1 << 28)
+#define MVGBE_RX_EN_INTERRUPT		(1 << 29)
+#define MVGBE_LAYER_4_CHECKSUM_OK	(1 << 30)
+
+/* Rx descriptors byte count */
+#define MVGBE_FRAME_FRAGMENTED		(1 << 2)
+
+/* Tx descriptors command */
+#define MVGBE_LAYER_4_CHECKSUM_FIRST_DESC	(1 << 10)
+#define MVGBE_FRAME_SET_TO_VLAN			(1 << 15)
+#define MVGBE_TCP_FRAME				0
+#define MVGBE_UDP_FRAME				(1 << 16)
+#define MVGBE_GEN_TCP_UDP_CHECKSUM		(1 << 17)
+#define MVGBE_GEN_IP_V_4_CHECKSUM		(1 << 18)
+#define MVGBE_ZERO_PADDING			(1 << 19)
+#define MVGBE_TX_LAST_DESC			(1 << 20)
+#define MVGBE_TX_FIRST_DESC			(1 << 21)
+#define MVGBE_GEN_CRC				(1 << 22)
+#define MVGBE_TX_EN_INTERRUPT			(1 << 23)
+#define MVGBE_AUTO_MODE				(1 << 30)
+
+/* Address decode parameters */
+/* Ethernet Base Address Register bits */
+#define EBAR_TARGET_DRAM			0x00000000
+#define EBAR_TARGET_DEVICE			0x00000001
+#define EBAR_TARGET_CBS				0x00000002
+#define EBAR_TARGET_PCI0			0x00000003
+#define EBAR_TARGET_PCI1			0x00000004
+#define EBAR_TARGET_CUNIT			0x00000005
+#define EBAR_TARGET_AUNIT			0x00000006
+#define EBAR_TARGET_GUNIT			0x00000007
+
+/* Window attrib */
+#if defined(CONFIG_DOVE)
+#define EBAR_DRAM_CS0				0x00000000
+#define EBAR_DRAM_CS1				0x00000000
+#define EBAR_DRAM_CS2				0x00000000
+#define EBAR_DRAM_CS3				0x00000000
+#else
+#define EBAR_DRAM_CS0				0x00000E00
+#define EBAR_DRAM_CS1				0x00000D00
+#define EBAR_DRAM_CS2				0x00000B00
+#define EBAR_DRAM_CS3				0x00000700
+#endif
+
+/* DRAM Target interface */
+#define EBAR_DRAM_NO_CACHE_COHERENCY		0x00000000
+#define EBAR_DRAM_CACHE_COHERENCY_WT		0x00001000
+#define EBAR_DRAM_CACHE_COHERENCY_WB		0x00002000
+
+/* Device Bus Target interface */
+#define EBAR_DEVICE_DEVCS0			0x00001E00
+#define EBAR_DEVICE_DEVCS1			0x00001D00
+#define EBAR_DEVICE_DEVCS2			0x00001B00
+#define EBAR_DEVICE_DEVCS3			0x00001700
+#define EBAR_DEVICE_BOOTCS3			0x00000F00
+
+/* PCI Target interface */
+#define EBAR_PCI_BYTE_SWAP			0x00000000
+#define EBAR_PCI_NO_SWAP			0x00000100
+#define EBAR_PCI_BYTE_WORD_SWAP			0x00000200
+#define EBAR_PCI_WORD_SWAP			0x00000300
+#define EBAR_PCI_NO_SNOOP_NOT_ASSERT		0x00000000
+#define EBAR_PCI_NO_SNOOP_ASSERT		0x00000400
+#define EBAR_PCI_IO_SPACE			0x00000000
+#define EBAR_PCI_MEMORY_SPACE			0x00000800
+#define EBAR_PCI_REQ64_FORCE			0x00000000
+#define EBAR_PCI_REQ64_SIZE			0x00001000
+
+/* Window access control */
+#define EWIN_ACCESS_NOT_ALLOWED 0
+#define EWIN_ACCESS_READ_ONLY	1
+#define EWIN_ACCESS_FULL	((1 << 1) | 1)
+
+/* structures represents Controller registers */
+struct mvgbe_barsz {
+	u32 bar;
+	u32 size;
+};
+
+struct mvgbe_rxcdp {
+	struct mvgbe_rxdesc *rxcdp;
+	u32 rxcdp_pad[3];
+};
+
+struct mvgbe_tqx {
+	u32 qxttbc;
+	u32 tqxtbc;
+	u32 tqxac;
+	u32 tqxpad;
+};
+
+struct mvgbe_registers {
+	u32 phyadr;
+	u32 smi;
+	u32 euda;
+	u32 eudid;
+	u8 pad1[0x080 - 0x00c - 4];
+	u32 euic;
+	u32 euim;
+	u8 pad2[0x094 - 0x084 - 4];
+	u32 euea;
+	u32 euiae;
+	u8 pad3[0x0b0 - 0x098 - 4];
+	u32 euc;
+	u8 pad3a[0x200 - 0x0b0 - 4];
+	struct mvgbe_barsz barsz[6];
+	u8 pad4[0x280 - 0x22c - 4];
+	u32 ha_remap[4];
+	u32 bare;
+	u32 epap;
+	u8 pad5[0x400 - 0x294 - 4];
+	u32 pxc;
+	u32 pxcx;
+	u32 mii_ser_params;
+	u8 pad6[0x410 - 0x408 - 4];
+	u32 evlane;
+	u32 macal;
+	u32 macah;
+	u32 sdc;
+	u32 dscp[7];
+	u32 psc0;
+	u32 vpt2p;
+	u32 ps0;
+	u32 tqc;
+	u32 psc1;
+	u32 ps1;
+	u32 mrvl_header;
+	u8 pad7[0x460 - 0x454 - 4];
+	u32 ic;
+	u32 ice;
+	u32 pim;
+	u32 peim;
+	u8 pad8[0x474 - 0x46c - 4];
+	u32 pxtfut;
+	u32 pad9;
+	u32 pxmfs;
+	u32 pad10;
+	u32 pxdfc;
+	u32 pxofc;
+	u8 pad11[0x494 - 0x488 - 4];
+	u32 peuiae;
+	u8 pad12[0x4bc - 0x494 - 4];
+	u32 eth_type_prio;
+	u8 pad13[0x4dc - 0x4bc - 4];
+	u32 tqfpc;
+	u32 pttbrc;
+	u32 tqc1;
+	u32 pmtu;
+	u32 pmtbs;
+	u8 pad14[0x60c - 0x4ec - 4];
+	struct mvgbe_rxcdp rxcdp[7];
+	struct mvgbe_rxdesc *rxcdp7;
+	u32 rqc;
+	struct mvgbe_txdesc *tcsdp;
+	u8 pad15[0x6c0 - 0x684 - 4];
+	struct mvgbe_txdesc *tcqdp[8];
+	u8 pad16[0x700 - 0x6dc - 4];
+	struct mvgbe_tqx tqx[8];
+	u32 pttbc;
+	u8 pad17[0x7a8 - 0x780 - 4];
+	u32 tqxipg0;
+	u32 pad18[3];
+	u32 tqxipg1;
+	u8 pad19[0x7c0 - 0x7b8 - 4];
+	u32 hitkninlopkt;
+	u32 hitkninasyncpkt;
+	u32 lotkninasyncpkt;
+	u32 pad20;
+	u32 ts;
+	u8 pad21[0x3000 - 0x27d0 - 4];
+	u32 pad20_1[32];	/* mib counter registes */
+	u8 pad22[0x3400 - 0x3000 - sizeof(u32) * 32];
+	u32 dfsmt[64];
+	u32 dfomt[64];
+	u32 dfut[4];
+	u8 pad23[0xe20c0 - 0x7360c - 4];
+	u32 pmbus_top_arbiter;
+};
+
+/* structures/enums needed by driver */
+enum mvgbe_adrwin {
+	MVGBE_WIN0,
+	MVGBE_WIN1,
+	MVGBE_WIN2,
+	MVGBE_WIN3,
+	MVGBE_WIN4,
+	MVGBE_WIN5
+};
+
+enum mvgbe_target {
+	MVGBE_TARGET_DRAM,
+	MVGBE_TARGET_DEV,
+	MVGBE_TARGET_CBS,
+	MVGBE_TARGET_PCI0,
+	MVGBE_TARGET_PCI1
+};
+
+struct mvgbe_winparam {
+	enum mvgbe_adrwin win;	/* Window number */
+	enum mvgbe_target target;	/* System targets */
+	u16 attrib;		/* BAR attrib. See above macros */
+	u32 base_addr;		/* Window base address in u32 form */
+	u32 high_addr;		/* Window high address in u32 form */
+	u32 size;		/* Size in MBytes. Must be % 64Kbyte. */
+	int enable;		/* Enable/disable access to the window. */
+	u16 access_ctrl;	/*Access ctrl register. see above macros */
+};
+
+struct mvgbe_rxdesc {
+	u32 cmd_sts;		/* Descriptor command status */
+	u16 buf_size;		/* Buffer size */
+	u16 byte_cnt;		/* Descriptor buffer byte count */
+	u8 *buf_ptr;		/* Descriptor buffer pointer */
+	struct mvgbe_rxdesc *nxtdesc_p;	/* Next descriptor pointer */
+};
+
+struct mvgbe_txdesc {
+	u32 cmd_sts;		/* Descriptor command status */
+	u16 l4i_chk;		/* CPU provided TCP Checksum */
+	u16 byte_cnt;		/* Descriptor buffer byte count */
+	u8 *buf_ptr;		/* Descriptor buffer ptr */
+	struct mvgbe_txdesc *nxtdesc_p;	/* Next descriptor ptr */
+};
+
+/* port device data struct */
+struct mvgbe_device {
+	struct eth_device dev;
+	struct mvgbe_registers *regs;
+	struct mvgbe_txdesc *p_txdesc;
+	struct mvgbe_rxdesc *p_rxdesc;
+	struct mvgbe_rxdesc *p_rxdesc_curr;
+	u8 *p_rxbuf;
+	u8 *p_aligned_txbuf;
+};
+
+#endif /* __MVGBE_H__ */
diff --git a/marvell/uboot/drivers/net/natsemi.c b/marvell/uboot/drivers/net/natsemi.c
new file mode 100644
index 0000000..04743bd
--- /dev/null
+++ b/marvell/uboot/drivers/net/natsemi.c
@@ -0,0 +1,882 @@
+/*
+   natsemi.c: A U-Boot driver for the NatSemi DP8381x series.
+   Author: Mark A. Rakes (mark_rakes@vivato.net)
+
+   Adapted from an Etherboot driver written by:
+
+   Copyright (C) 2001 Entity Cyber, Inc.
+
+   This development of this Etherboot driver was funded by
+
+      Sicom Systems: http://www.sicompos.com/
+
+   Author: Marty Connor (mdc@thinguin.org)
+   Adapted from a Linux driver which was written by Donald Becker
+
+   This software may be used and distributed according to the terms
+   of the GNU Public License (GPL), incorporated herein by reference.
+
+   Original Copyright Notice:
+
+   Written/copyright 1999-2001 by Donald Becker.
+
+   This software may be used and distributed according to the terms of
+   the GNU General Public License (GPL), incorporated herein by reference.
+   Drivers based on or derived from this code fall under the GPL and must
+   retain the authorship, copyright and license notice.  This file is not
+   a complete program and may only be used when the entire operating
+   system is licensed under the GPL.  License for under other terms may be
+   available.  Contact the original author for details.
+
+   The original author may be reached as becker@scyld.com, or at
+   Scyld Computing Corporation
+   410 Severn Ave., Suite 210
+   Annapolis MD 21403
+
+   Support information and updates available at
+   http://www.scyld.com/network/netsemi.html
+
+   References:
+   http://www.scyld.com/expert/100mbps.html
+   http://www.scyld.com/expert/NWay.html
+   Datasheet is available from:
+   http://www.national.com/pf/DP/DP83815.html
+*/
+
+/* Revision History
+ * October 2002 mar	1.0
+ *   Initial U-Boot Release.  Tested with Netgear FA311 board
+ *   and dp83815 chipset on custom board
+*/
+
+/* Includes */
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <pci.h>
+
+/* defines */
+#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
+#define RX_BUF_SIZE	1536
+#define NUM_RX_DESC	4	/* Number of Rx descriptor registers. */
+
+/* Offsets to the device registers.
+   Unlike software-only systems, device drivers interact with complex hardware.
+   It's not useful to define symbolic names for every register bit in the
+   device.  */
+enum register_offsets {
+	ChipCmd	= 0x00,
+	ChipConfig	= 0x04,
+	EECtrl		= 0x08,
+	IntrMask	= 0x14,
+	IntrEnable	= 0x18,
+	TxRingPtr	= 0x20,
+	TxConfig	= 0x24,
+	RxRingPtr	= 0x30,
+	RxConfig	= 0x34,
+	ClkRun		= 0x3C,
+	RxFilterAddr	= 0x48,
+	RxFilterData	= 0x4C,
+	SiliconRev	= 0x58,
+	PCIPM		= 0x44,
+	BasicControl	= 0x80,
+	BasicStatus	= 0x84,
+	/* These are from the spec, around page 78... on a separate table. */
+	PGSEL		= 0xCC,
+	PMDCSR		= 0xE4,
+	TSTDAT		= 0xFC,
+	DSPCFG		= 0xF4,
+	SDCFG		= 0x8C
+};
+
+/* Bit in ChipCmd. */
+enum ChipCmdBits {
+	ChipReset	= 0x100,
+	RxReset		= 0x20,
+	TxReset		= 0x10,
+	RxOff		= 0x08,
+	RxOn		= 0x04,
+	TxOff		= 0x02,
+	TxOn		= 0x01
+};
+
+enum ChipConfigBits {
+	LinkSts	= 0x80000000,
+	HundSpeed	= 0x40000000,
+	FullDuplex	= 0x20000000,
+	TenPolarity	= 0x10000000,
+	AnegDone	= 0x08000000,
+	AnegEnBothBoth	= 0x0000E000,
+	AnegDis100Full	= 0x0000C000,
+	AnegEn100Both	= 0x0000A000,
+	AnegDis100Half	= 0x00008000,
+	AnegEnBothHalf	= 0x00006000,
+	AnegDis10Full	= 0x00004000,
+	AnegEn10Both	= 0x00002000,
+	DuplexMask	= 0x00008000,
+	SpeedMask	= 0x00004000,
+	AnegMask	= 0x00002000,
+	AnegDis10Half	= 0x00000000,
+	ExtPhy		= 0x00001000,
+	PhyRst		= 0x00000400,
+	PhyDis		= 0x00000200,
+	BootRomDisable	= 0x00000004,
+	BEMode		= 0x00000001,
+};
+
+enum TxConfig_bits {
+	TxDrthMask	= 0x3f,
+	TxFlthMask	= 0x3f00,
+	TxMxdmaMask	= 0x700000,
+	TxMxdma_512	= 0x0,
+	TxMxdma_4	= 0x100000,
+	TxMxdma_8	= 0x200000,
+	TxMxdma_16	= 0x300000,
+	TxMxdma_32	= 0x400000,
+	TxMxdma_64	= 0x500000,
+	TxMxdma_128	= 0x600000,
+	TxMxdma_256	= 0x700000,
+	TxCollRetry	= 0x800000,
+	TxAutoPad	= 0x10000000,
+	TxMacLoop	= 0x20000000,
+	TxHeartIgn	= 0x40000000,
+	TxCarrierIgn	= 0x80000000
+};
+
+enum RxConfig_bits {
+	RxDrthMask	= 0x3e,
+	RxMxdmaMask	= 0x700000,
+	RxMxdma_512	= 0x0,
+	RxMxdma_4	= 0x100000,
+	RxMxdma_8	= 0x200000,
+	RxMxdma_16	= 0x300000,
+	RxMxdma_32	= 0x400000,
+	RxMxdma_64	= 0x500000,
+	RxMxdma_128	= 0x600000,
+	RxMxdma_256	= 0x700000,
+	RxAcceptLong	= 0x8000000,
+	RxAcceptTx	= 0x10000000,
+	RxAcceptRunt	= 0x40000000,
+	RxAcceptErr	= 0x80000000
+};
+
+/* Bits in the RxMode register. */
+enum rx_mode_bits {
+	AcceptErr	= 0x20,
+	AcceptRunt	= 0x10,
+	AcceptBroadcast	= 0xC0000000,
+	AcceptMulticast	= 0x00200000,
+	AcceptAllMulticast = 0x20000000,
+	AcceptAllPhys	= 0x10000000,
+	AcceptMyPhys	= 0x08000000
+};
+
+typedef struct _BufferDesc {
+	u32 link;
+	vu_long cmdsts;
+	u32 bufptr;
+	u32 software_use;
+} BufferDesc;
+
+/* Bits in network_desc.status */
+enum desc_status_bits {
+	DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000,
+	DescNoCRC = 0x10000000, DescPktOK = 0x08000000,
+	DescSizeMask = 0xfff,
+
+	DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000,
+	DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000,
+	DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000,
+	DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000,
+
+	DescRxAbort = 0x04000000, DescRxOver = 0x02000000,
+	DescRxDest = 0x01800000, DescRxLong = 0x00400000,
+	DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000,
+	DescRxCRC = 0x00080000, DescRxAlign = 0x00040000,
+	DescRxLoop = 0x00020000, DesRxColl = 0x00010000,
+};
+
+/* Globals */
+#ifdef NATSEMI_DEBUG
+static int natsemi_debug = 0;	/* 1 verbose debugging, 0 normal */
+#endif
+static u32 SavedClkRun;
+static unsigned int cur_rx;
+static unsigned int advertising;
+static unsigned int rx_config;
+static unsigned int tx_config;
+
+/* Note: transmit and receive buffers and descriptors must be
+   longword aligned */
+static BufferDesc txd __attribute__ ((aligned(4)));
+static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4)));
+
+static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4)));
+static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]
+    __attribute__ ((aligned(4)));
+
+/* Function Prototypes */
+#if 0
+static void write_eeprom(struct eth_device *dev, long addr, int location,
+			 short value);
+#endif
+static int read_eeprom(struct eth_device *dev, long addr, int location);
+static int mdio_read(struct eth_device *dev, int phy_id, int location);
+static int natsemi_init(struct eth_device *dev, bd_t * bis);
+static void natsemi_reset(struct eth_device *dev);
+static void natsemi_init_rxfilter(struct eth_device *dev);
+static void natsemi_init_txd(struct eth_device *dev);
+static void natsemi_init_rxd(struct eth_device *dev);
+static void natsemi_set_rx_mode(struct eth_device *dev);
+static void natsemi_check_duplex(struct eth_device *dev);
+static int natsemi_send(struct eth_device *dev, void *packet, int length);
+static int natsemi_poll(struct eth_device *dev);
+static void natsemi_disable(struct eth_device *dev);
+
+static struct pci_device_id supported[] = {
+	{PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815},
+	{}
+};
+
+#define bus_to_phys(a)	pci_mem_to_phys((pci_dev_t)dev->priv, a)
+#define phys_to_bus(a)	pci_phys_to_mem((pci_dev_t)dev->priv, a)
+
+static inline int
+INW(struct eth_device *dev, u_long addr)
+{
+	return le16_to_cpu(*(vu_short *) (addr + dev->iobase));
+}
+
+static int
+INL(struct eth_device *dev, u_long addr)
+{
+	return le32_to_cpu(*(vu_long *) (addr + dev->iobase));
+}
+
+static inline void
+OUTW(struct eth_device *dev, int command, u_long addr)
+{
+	*(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command);
+}
+
+static inline void
+OUTL(struct eth_device *dev, int command, u_long addr)
+{
+	*(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command);
+}
+
+/*
+ * Function: natsemi_initialize
+ *
+ * Description: Retrieves the MAC address of the card, and sets up some
+ * globals required by other routines,  and initializes the NIC, making it
+ * ready to send and receive packets.
+ *
+ * Side effects:
+ *            leaves the natsemi initialized, and ready to receive packets.
+ *
+ * Returns:   struct eth_device *:          pointer to NIC data structure
+ */
+
+int
+natsemi_initialize(bd_t * bis)
+{
+	pci_dev_t devno;
+	int card_number = 0;
+	struct eth_device *dev;
+	u32 iobase, status, chip_config;
+	int i, idx = 0;
+	int prev_eedata;
+	u32 tmp;
+
+	while (1) {
+		/* Find PCI device(s) */
+		if ((devno = pci_find_devices(supported, idx++)) < 0) {
+			break;
+		}
+
+		pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase);
+		iobase &= ~0x3;	/* bit 1: unused and bit 0: I/O Space Indicator */
+
+		pci_write_config_dword(devno, PCI_COMMAND,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+		/* Check if I/O accesses and Bus Mastering are enabled. */
+		pci_read_config_dword(devno, PCI_COMMAND, &status);
+		if (!(status & PCI_COMMAND_MEMORY)) {
+			printf("Error: Can not enable MEM access.\n");
+			continue;
+		} else if (!(status & PCI_COMMAND_MASTER)) {
+			printf("Error: Can not enable Bus Mastering.\n");
+			continue;
+		}
+
+		dev = (struct eth_device *) malloc(sizeof *dev);
+		if (!dev) {
+			printf("natsemi: Can not allocate memory\n");
+			break;
+		}
+		memset(dev, 0, sizeof(*dev));
+
+		sprintf(dev->name, "dp83815#%d", card_number);
+		dev->iobase = bus_to_phys(iobase);
+#ifdef NATSEMI_DEBUG
+		printf("natsemi: NatSemi ns8381[56] @ %#x\n", dev->iobase);
+#endif
+		dev->priv = (void *) devno;
+		dev->init = natsemi_init;
+		dev->halt = natsemi_disable;
+		dev->send = natsemi_send;
+		dev->recv = natsemi_poll;
+
+		eth_register(dev);
+
+		card_number++;
+
+		/* Set the latency timer for value. */
+		pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20);
+
+		udelay(10 * 1000);
+
+		/* natsemi has a non-standard PM control register
+		 * in PCI config space.  Some boards apparently need
+		 * to be brought to D0 in this manner.  */
+		pci_read_config_dword(devno, PCIPM, &tmp);
+		if (tmp & (0x03 | 0x100)) {
+			/* D0 state, disable PME assertion */
+			u32 newtmp = tmp & ~(0x03 | 0x100);
+			pci_write_config_dword(devno, PCIPM, newtmp);
+		}
+
+		printf("natsemi: EEPROM contents:\n");
+		for (i = 0; i <= EEPROM_SIZE; i++) {
+			short eedata = read_eeprom(dev, EECtrl, i);
+			printf(" %04hx", eedata);
+		}
+		printf("\n");
+
+		/* get MAC address */
+		prev_eedata = read_eeprom(dev, EECtrl, 6);
+		for (i = 0; i < 3; i++) {
+			int eedata = read_eeprom(dev, EECtrl, i + 7);
+			dev->enetaddr[i*2] = (eedata << 1) + (prev_eedata >> 15);
+			dev->enetaddr[i*2+1] = eedata >> 7;
+			prev_eedata = eedata;
+		}
+
+		/* Reset the chip to erase any previous misconfiguration. */
+		OUTL(dev, ChipReset, ChipCmd);
+
+		advertising = mdio_read(dev, 1, 4);
+		chip_config = INL(dev, ChipConfig);
+#ifdef NATSEMI_DEBUG
+		printf("%s: Transceiver status %#08X advertising %#08X\n",
+			dev->name, (int) INL(dev, BasicStatus), advertising);
+		printf("%s: Transceiver default autoneg. %s 10%s %s duplex.\n",
+			dev->name, chip_config & AnegMask ? "enabled, advertise" :
+			"disabled, force", chip_config & SpeedMask ? "0" : "",
+			chip_config & DuplexMask ? "full" : "half");
+#endif
+		chip_config |= AnegEnBothBoth;
+#ifdef NATSEMI_DEBUG
+		printf("%s: changed to autoneg. %s 10%s %s duplex.\n",
+			dev->name, chip_config & AnegMask ? "enabled, advertise" :
+			"disabled, force", chip_config & SpeedMask ? "0" : "",
+			chip_config & DuplexMask ? "full" : "half");
+#endif
+		/*write new autoneg bits, reset phy*/
+		OUTL(dev, (chip_config | PhyRst), ChipConfig);
+		/*un-reset phy*/
+		OUTL(dev, chip_config, ChipConfig);
+
+		/* Disable PME:
+		 * The PME bit is initialized from the EEPROM contents.
+		 * PCI cards probably have PME disabled, but motherboard
+		 * implementations may have PME set to enable WakeOnLan.
+		 * With PME set the chip will scan incoming packets but
+		 * nothing will be written to memory. */
+		SavedClkRun = INL(dev, ClkRun);
+		OUTL(dev, SavedClkRun & ~0x100, ClkRun);
+	}
+	return card_number;
+}
+
+/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
+   The EEPROM code is for common 93c06/46 EEPROMs w/ 6bit addresses.  */
+
+/* Delay between EEPROM clock transitions.
+   No extra delay is needed with 33MHz PCI, but future 66MHz
+   access may need a delay. */
+#define eeprom_delay(ee_addr)	INL(dev, ee_addr)
+
+enum EEPROM_Ctrl_Bits {
+	EE_ShiftClk = 0x04,
+	EE_DataIn = 0x01,
+	EE_ChipSelect = 0x08,
+	EE_DataOut = 0x02
+};
+
+#define EE_Write0 (EE_ChipSelect)
+#define EE_Write1 (EE_ChipSelect | EE_DataIn)
+/* The EEPROM commands include the alway-set leading bit. */
+enum EEPROM_Cmds {
+	EE_WrEnCmd = (4 << 6), EE_WriteCmd = (5 << 6),
+	EE_ReadCmd = (6 << 6), EE_EraseCmd = (7 << 6),
+};
+
+#if 0
+static void
+write_eeprom(struct eth_device *dev, long addr, int location, short value)
+{
+	int i;
+	int ee_addr = (typeof(ee_addr))addr;
+	short wren_cmd = EE_WrEnCmd | 0x30; /*wren is 100 + 11XXXX*/
+	short write_cmd = location | EE_WriteCmd;
+
+#ifdef NATSEMI_DEBUG
+	printf("write_eeprom: %08x, %04hx, %04hx\n",
+		dev->iobase + ee_addr, write_cmd, value);
+#endif
+	/* Shift the write enable command bits out. */
+	for (i = 9; i >= 0; i--) {
+		short cmdval = (wren_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
+		OUTL(dev, cmdval, ee_addr);
+		eeprom_delay(ee_addr);
+		OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
+		eeprom_delay(ee_addr);
+	}
+
+	OUTL(dev, 0, ee_addr); /*bring chip select low*/
+	OUTL(dev, EE_ShiftClk, ee_addr);
+	eeprom_delay(ee_addr);
+
+	/* Shift the write command bits out. */
+	for (i = 9; i >= 0; i--) {
+		short cmdval = (write_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
+		OUTL(dev, cmdval, ee_addr);
+		eeprom_delay(ee_addr);
+		OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
+		eeprom_delay(ee_addr);
+	}
+
+	for (i = 0; i < 16; i++) {
+		short cmdval = (value & (1 << i)) ? EE_Write1 : EE_Write0;
+		OUTL(dev, cmdval, ee_addr);
+		eeprom_delay(ee_addr);
+		OUTL(dev, cmdval | EE_ShiftClk, ee_addr);
+		eeprom_delay(ee_addr);
+	}
+
+	OUTL(dev, 0, ee_addr); /*bring chip select low*/
+	OUTL(dev, EE_ShiftClk, ee_addr);
+	for (i = 0; i < 200000; i++) {
+		OUTL(dev, EE_Write0, ee_addr); /*poll for done*/
+		if (INL(dev, ee_addr) & EE_DataOut) {
+		    break; /*finished*/
+		}
+	}
+	eeprom_delay(ee_addr);
+
+	/* Terminate the EEPROM access. */
+	OUTL(dev, EE_Write0, ee_addr);
+	OUTL(dev, 0, ee_addr);
+	return;
+}
+#endif
+
+static int
+read_eeprom(struct eth_device *dev, long addr, int location)
+{
+	int i;
+	int retval = 0;
+	int ee_addr = (typeof(ee_addr))addr;
+	int read_cmd = location | EE_ReadCmd;
+
+	OUTL(dev, EE_Write0, ee_addr);
+
+	/* Shift the read command bits out. */
+	for (i = 10; i >= 0; i--) {
+		short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
+		OUTL(dev, dataval, ee_addr);
+		eeprom_delay(ee_addr);
+		OUTL(dev, dataval | EE_ShiftClk, ee_addr);
+		eeprom_delay(ee_addr);
+	}
+	OUTL(dev, EE_ChipSelect, ee_addr);
+	eeprom_delay(ee_addr);
+
+	for (i = 0; i < 16; i++) {
+		OUTL(dev, EE_ChipSelect | EE_ShiftClk, ee_addr);
+		eeprom_delay(ee_addr);
+		retval |= (INL(dev, ee_addr) & EE_DataOut) ? 1 << i : 0;
+		OUTL(dev, EE_ChipSelect, ee_addr);
+		eeprom_delay(ee_addr);
+	}
+
+	/* Terminate the EEPROM access. */
+	OUTL(dev, EE_Write0, ee_addr);
+	OUTL(dev, 0, ee_addr);
+#ifdef NATSEMI_DEBUG
+	if (natsemi_debug)
+		printf("read_eeprom: %08x, %08x, retval %08x\n",
+			dev->iobase + ee_addr, read_cmd, retval);
+#endif
+	return retval;
+}
+
+/*  MII transceiver control section.
+	The 83815 series has an internal transceiver, and we present the
+	management registers as if they were MII connected. */
+
+static int
+mdio_read(struct eth_device *dev, int phy_id, int location)
+{
+	if (phy_id == 1 && location < 32)
+		return INL(dev, BasicControl+(location<<2))&0xffff;
+	else
+		return 0xffff;
+}
+
+/* Function: natsemi_init
+ *
+ * Description: resets the ethernet controller chip and configures
+ *    registers and data structures required for sending and receiving packets.
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * returns:	int.
+ */
+
+static int
+natsemi_init(struct eth_device *dev, bd_t * bis)
+{
+
+	natsemi_reset(dev);
+
+	/* Disable PME:
+	 * The PME bit is initialized from the EEPROM contents.
+	 * PCI cards probably have PME disabled, but motherboard
+	 * implementations may have PME set to enable WakeOnLan.
+	 * With PME set the chip will scan incoming packets but
+	 * nothing will be written to memory. */
+	OUTL(dev, SavedClkRun & ~0x100, ClkRun);
+
+	natsemi_init_rxfilter(dev);
+	natsemi_init_txd(dev);
+	natsemi_init_rxd(dev);
+
+	/* Configure the PCI bus bursts and FIFO thresholds. */
+	tx_config = TxAutoPad | TxCollRetry | TxMxdma_256 | (0x1002);
+	rx_config = RxMxdma_256 | 0x20;
+
+#ifdef NATSEMI_DEBUG
+	printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config);
+	printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config);
+#endif
+	OUTL(dev, tx_config, TxConfig);
+	OUTL(dev, rx_config, RxConfig);
+
+	natsemi_check_duplex(dev);
+	natsemi_set_rx_mode(dev);
+
+	OUTL(dev, (RxOn | TxOn), ChipCmd);
+	return 1;
+}
+
+/*
+ * Function: natsemi_reset
+ *
+ * Description: soft resets the controller chip
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * Returns:   void.
+ */
+static void
+natsemi_reset(struct eth_device *dev)
+{
+	OUTL(dev, ChipReset, ChipCmd);
+
+	/* On page 78 of the spec, they recommend some settings for "optimum
+	   performance" to be done in sequence.  These settings optimize some
+	   of the 100Mbit autodetection circuitry.  Also, we only want to do
+	   this for rev C of the chip.  */
+	if (INL(dev, SiliconRev) == 0x302) {
+		OUTW(dev, 0x0001, PGSEL);
+		OUTW(dev, 0x189C, PMDCSR);
+		OUTW(dev, 0x0000, TSTDAT);
+		OUTW(dev, 0x5040, DSPCFG);
+		OUTW(dev, 0x008C, SDCFG);
+	}
+	/* Disable interrupts using the mask. */
+	OUTL(dev, 0, IntrMask);
+	OUTL(dev, 0, IntrEnable);
+}
+
+/* Function: natsemi_init_rxfilter
+ *
+ * Description: sets receive filter address to our MAC address
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * returns:   void.
+ */
+
+static void
+natsemi_init_rxfilter(struct eth_device *dev)
+{
+	int i;
+
+	for (i = 0; i < ETH_ALEN; i += 2) {
+		OUTL(dev, i, RxFilterAddr);
+		OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8),
+		     RxFilterData);
+	}
+}
+
+/*
+ * Function: natsemi_init_txd
+ *
+ * Description: initializes the Tx descriptor
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * returns:   void.
+ */
+
+static void
+natsemi_init_txd(struct eth_device *dev)
+{
+	txd.link = (u32) 0;
+	txd.cmdsts = (u32) 0;
+	txd.bufptr = (u32) & txb[0];
+
+	/* load Transmit Descriptor Register */
+	OUTL(dev, (u32) & txd, TxRingPtr);
+#ifdef NATSEMI_DEBUG
+	printf("natsemi_init_txd: TX descriptor reg loaded with: %#08X\n",
+	       INL(dev, TxRingPtr));
+#endif
+}
+
+/* Function: natsemi_init_rxd
+ *
+ * Description: initializes the Rx descriptor ring
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void
+natsemi_init_rxd(struct eth_device *dev)
+{
+	int i;
+
+	cur_rx = 0;
+
+	/* init RX descriptor */
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		rxd[i].link =
+		    cpu_to_le32((i + 1 <
+				 NUM_RX_DESC) ? (u32) & rxd[i +
+							    1] : (u32) &
+				rxd[0]);
+		rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);
+		rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);
+#ifdef NATSEMI_DEBUG
+		printf
+		    ("natsemi_init_rxd: rxd[%d]=%p link=%X cmdsts=%lX bufptr=%X\n",
+			i, &rxd[i], le32_to_cpu(rxd[i].link),
+				rxd[i].cmdsts, rxd[i].bufptr);
+#endif
+	}
+
+	/* load Receive Descriptor Register */
+	OUTL(dev, (u32) & rxd[0], RxRingPtr);
+
+#ifdef NATSEMI_DEBUG
+	printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n",
+	       INL(dev, RxRingPtr));
+#endif
+}
+
+/* Function: natsemi_set_rx_mode
+ *
+ * Description:
+ *    sets the receive mode to accept all broadcast packets and packets
+ *    with our MAC address, and reject all multicast packets.
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void
+natsemi_set_rx_mode(struct eth_device *dev)
+{
+	u32 rx_mode = AcceptBroadcast | AcceptMyPhys;
+
+	OUTL(dev, rx_mode, RxFilterAddr);
+}
+
+static void
+natsemi_check_duplex(struct eth_device *dev)
+{
+	int duplex = INL(dev, ChipConfig) & FullDuplex ? 1 : 0;
+
+#ifdef NATSEMI_DEBUG
+	printf("%s: Setting %s-duplex based on negotiated link"
+	       " capability.\n", dev->name, duplex ? "full" : "half");
+#endif
+	if (duplex) {
+		rx_config |= RxAcceptTx;
+		tx_config |= (TxCarrierIgn | TxHeartIgn);
+	} else {
+		rx_config &= ~RxAcceptTx;
+		tx_config &= ~(TxCarrierIgn | TxHeartIgn);
+	}
+	OUTL(dev, tx_config, TxConfig);
+	OUTL(dev, rx_config, RxConfig);
+}
+
+/* Function: natsemi_send
+ *
+ * Description: transmits a packet and waits for completion or timeout.
+ *
+ * Returns:   void.  */
+static int natsemi_send(struct eth_device *dev, void *packet, int length)
+{
+	u32 i, status = 0;
+	u32 tx_status = 0;
+	u32 *tx_ptr = &tx_status;
+	vu_long *res = (vu_long *)tx_ptr;
+
+	/* Stop the transmitter */
+	OUTL(dev, TxOff, ChipCmd);
+
+#ifdef NATSEMI_DEBUG
+	if (natsemi_debug)
+		printf("natsemi_send: sending %d bytes\n", (int) length);
+#endif
+
+	/* set the transmit buffer descriptor and enable Transmit State Machine */
+	txd.link = cpu_to_le32(0);
+	txd.bufptr = cpu_to_le32(phys_to_bus((u32) packet));
+	txd.cmdsts = cpu_to_le32(DescOwn | length);
+
+	/* load Transmit Descriptor Register */
+	OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);
+#ifdef NATSEMI_DEBUG
+	if (natsemi_debug)
+	    printf("natsemi_send: TX descriptor register loaded with: %#08X\n",
+	     INL(dev, TxRingPtr));
+#endif
+	/* restart the transmitter */
+	OUTL(dev, TxOn, ChipCmd);
+
+	for (i = 0;
+	     (*res = le32_to_cpu(txd.cmdsts)) & DescOwn;
+	     i++) {
+		if (i >= TOUT_LOOP) {
+			printf
+			    ("%s: tx error buffer not ready: txd.cmdsts == %#X\n",
+			     dev->name, tx_status);
+			goto Done;
+		}
+	}
+
+	if (!(tx_status & DescPktOK)) {
+		printf("natsemi_send: Transmit error, Tx status %X.\n",
+		       tx_status);
+		goto Done;
+	}
+
+	status = 1;
+      Done:
+	return status;
+}
+
+/* Function: natsemi_poll
+ *
+ * Description: checks for a received packet and returns it if found.
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * Returns:   1 if    packet was received.
+ *            0 if no packet was received.
+ *
+ * Side effects:
+ *            Returns (copies) the packet to the array dev->packet.
+ *            Returns the length of the packet.
+ */
+
+static int
+natsemi_poll(struct eth_device *dev)
+{
+	int retstat = 0;
+	int length = 0;
+	u32 rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);
+
+	if (!(rx_status & (u32) DescOwn))
+		return retstat;
+#ifdef NATSEMI_DEBUG
+	if (natsemi_debug)
+		printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",
+		       cur_rx, rx_status);
+#endif
+	length = (rx_status & DSIZE) - CRC_SIZE;
+
+	if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {
+		printf
+		    ("natsemi_poll: Corrupted packet received, buffer status = %X\n",
+		     rx_status);
+		retstat = 0;
+	} else {		/* give packet to higher level routine */
+		NetReceive((rxb + cur_rx * RX_BUF_SIZE), length);
+		retstat = 1;
+	}
+
+	/* return the descriptor and buffer to receive ring */
+	rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE);
+	rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]);
+
+	if (++cur_rx == NUM_RX_DESC)
+		cur_rx = 0;
+
+	/* re-enable the potentially idle receive state machine */
+	OUTL(dev, RxOn, ChipCmd);
+
+	return retstat;
+}
+
+/* Function: natsemi_disable
+ *
+ * Description: Turns off interrupts and stops Tx and Rx engines
+ *
+ * Arguments: struct eth_device *dev:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void
+natsemi_disable(struct eth_device *dev)
+{
+	/* Disable interrupts using the mask. */
+	OUTL(dev, 0, IntrMask);
+	OUTL(dev, 0, IntrEnable);
+
+	/* Stop the chip's Tx and Rx processes. */
+	OUTL(dev, RxOff | TxOff, ChipCmd);
+
+	/* Restore PME enable bit */
+	OUTL(dev, SavedClkRun, ClkRun);
+}
diff --git a/marvell/uboot/drivers/net/ne2000.c b/marvell/uboot/drivers/net/ne2000.c
new file mode 100644
index 0000000..e6cd3e9
--- /dev/null
+++ b/marvell/uboot/drivers/net/ne2000.c
@@ -0,0 +1,259 @@
+/*
+Ported to U-Boot by Christian Pellegrin <chri@ascensit.com>
+
+Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
+eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
+are GPL, so this is, of course, GPL.
+
+==========================================================================
+
+dev/if_dp83902a.c
+
+Ethernet device driver for NS DP83902a ethernet controller
+
+==========================================================================
+####ECOSGPLCOPYRIGHTBEGIN####
+-------------------------------------------
+This file is part of eCos, the Embedded Configurable Operating System.
+Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+
+eCos 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 or (at your option) any later version.
+
+eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with eCos; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+As a special exception, if other files instantiate templates or use macros
+or inline functions from this file, or you compile this file and link it
+with other works to produce a work based on this file, this file does not
+by itself cause the resulting work to be covered by the GNU General Public
+License. However the source code for this file must still be made available
+in accordance with section (3) of the GNU General Public License.
+
+This exception does not invalidate any other reasons why a work based on
+this file might be covered by the GNU General Public License.
+
+Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+at http://sources.redhat.com/ecos/ecos-license/
+-------------------------------------------
+####ECOSGPLCOPYRIGHTEND####
+####BSDCOPYRIGHTBEGIN####
+
+-------------------------------------------
+
+Portions of this software may have been derived from OpenBSD or other sources,
+and are covered by the appropriate copyright disclaimers included herein.
+
+-------------------------------------------
+
+####BSDCOPYRIGHTEND####
+==========================================================================
+#####DESCRIPTIONBEGIN####
+
+Author(s):	gthomas
+Contributors:	gthomas, jskov, rsandifo
+Date:		2001-06-13
+Purpose:
+Description:
+
+FIXME:		Will fail if pinged with large packets (1520 bytes)
+Add promisc config
+Add SNMP
+
+####DESCRIPTIONEND####
+
+==========================================================================
+*/
+
+#include <common.h>
+#include <command.h>
+
+/* NE2000 base header file */
+#include "ne2000_base.h"
+
+/* find prom (taken from pc_net_cs.c from Linux) */
+
+#include "8390.h"
+/*
+typedef struct hw_info_t {
+	u_int	offset;
+	u_char	a0, a1, a2;
+	u_int	flags;
+} hw_info_t;
+*/
+#define DELAY_OUTPUT	0x01
+#define HAS_MISC_REG	0x02
+#define USE_BIG_BUF	0x04
+#define HAS_IBM_MISC	0x08
+#define IS_DL10019	0x10
+#define IS_DL10022	0x20
+#define HAS_MII		0x40
+#define USE_SHMEM	0x80	/* autodetected */
+
+#define AM79C9XX_HOME_PHY	0x00006B90	/* HomePNA PHY */
+#define AM79C9XX_ETH_PHY	0x00006B70	/* 10baseT PHY */
+#define MII_PHYID_REV_MASK	0xfffffff0
+#define MII_PHYID_REG1		0x02
+#define MII_PHYID_REG2		0x03
+
+static hw_info_t hw_info[] = {
+	{ /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT },
+	{ /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 },
+	{ /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 },
+	{ /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94,
+			DELAY_OUTPUT | HAS_IBM_MISC },
+	{ /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 },
+	{ /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 },
+	{ /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 },
+	{ /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 },
+	{ /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 },
+	{ /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 },
+	{ /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 },
+	{ /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 },
+	{ /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* IBM FME */ 0x0374, 0x00, 0x04, 0xac,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 },
+	{ /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 },
+	{ /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 },
+	{ /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 },
+	{ /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 },
+	{ /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 },
+	{ /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45,
+			HAS_MISC_REG | HAS_IBM_MISC },
+	{ /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 },
+	{ /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 },
+	{ /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 },
+	{ /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b,
+			DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF },
+	{ /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 },
+	{ /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 },
+	{ /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 },
+	{ /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 },
+	{ /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 },
+	{ /* Qemu */ 0x0, 0x52, 0x54, 0x00, 0 },
+	{ /* RTL8019AS */ 0x0, 0x0, 0x18, 0x5f, 0 }
+};
+
+#define NR_INFO		(sizeof(hw_info)/sizeof(hw_info_t))
+
+#define PCNET_CMD	0x00
+#define PCNET_DATAPORT	0x10	/* NatSemi-defined port window offset. */
+#define PCNET_RESET	0x1f	/* Issue a read to reset, a write to clear. */
+#define PCNET_MISC	0x18	/* For IBM CCAE and Socket EA cards */
+
+static void pcnet_reset_8390(u8* addr)
+{
+	int i, r;
+
+	n2k_outb(E8390_NODMA + E8390_PAGE0+E8390_STOP, E8390_CMD);
+	PRINTK("cmd (at %lx) is %x\n", addr + E8390_CMD, n2k_inb(E8390_CMD));
+	n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD);
+	PRINTK("cmd (at %lx) is %x\n", addr + E8390_CMD, n2k_inb(E8390_CMD));
+	n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
+	PRINTK("cmd (at %lx) is %x\n", addr + E8390_CMD, n2k_inb(E8390_CMD));
+	n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
+
+	n2k_outb(n2k_inb(PCNET_RESET), PCNET_RESET);
+
+	for (i = 0; i < 100; i++) {
+		if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0)
+			break;
+		PRINTK("got %x in reset\n", r);
+		udelay(100);
+	}
+	n2k_outb(ENISR_RESET, EN0_ISR); /* Ack intr. */
+
+	if (i == 100)
+		printf("pcnet_reset_8390() did not complete.\n");
+} /* pcnet_reset_8390 */
+
+int get_prom(u8* mac_addr, u8* base_addr)
+{
+	u8 prom[32];
+	int i, j;
+	struct {
+		u_char value, offset;
+	} program_seq[] = {
+		{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
+		{0x48, EN0_DCFG},		/* Set byte-wide (0x48) access. */
+		{0x00, EN0_RCNTLO},		/* Clear the count regs. */
+		{0x00, EN0_RCNTHI},
+		{0x00, EN0_IMR},		/* Mask completion irq. */
+		{0xFF, EN0_ISR},
+		{E8390_RXOFF, EN0_RXCR},	/* 0x20 Set to monitor */
+		{E8390_TXOFF, EN0_TXCR},	/* 0x02 and loopback mode. */
+		{32, EN0_RCNTLO},
+		{0x00, EN0_RCNTHI},
+		{0x00, EN0_RSARLO},		/* DMA starting at 0x0000. */
+		{0x00, EN0_RSARHI},
+		{E8390_RREAD+E8390_START, E8390_CMD},
+	};
+
+	PRINTK ("trying to get MAC via prom reading\n");
+
+	pcnet_reset_8390 (base_addr);
+
+	mdelay (10);
+
+	for (i = 0; i < ARRAY_SIZE(program_seq); i++)
+		n2k_outb (program_seq[i].value, program_seq[i].offset);
+
+	PRINTK ("PROM:");
+	for (i = 0; i < 32; i++) {
+		prom[i] = n2k_inb (PCNET_DATAPORT);
+		PRINTK (" %02x", prom[i]);
+	}
+	PRINTK ("\n");
+	for (i = 0; i < NR_INFO; i++) {
+		if ((prom[0] == hw_info[i].a0) &&
+			(prom[2] == hw_info[i].a1) &&
+			(prom[4] == hw_info[i].a2)) {
+			PRINTK ("matched board %d\n", i);
+			break;
+		}
+	}
+	if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) {
+		PRINTK ("on exit i is %d/%ld\n", i, NR_INFO);
+		PRINTK ("MAC address is ");
+		for (j = 0; j < 6; j++) {
+			mac_addr[j] = prom[j << 1];
+			PRINTK ("%02x:", mac_addr[i]);
+		}
+		PRINTK ("\n");
+		return (i < NR_INFO) ? i : 0;
+	}
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/ne2000.h b/marvell/uboot/drivers/net/ne2000.h
new file mode 100644
index 0000000..2cde6be
--- /dev/null
+++ b/marvell/uboot/drivers/net/ne2000.h
@@ -0,0 +1,94 @@
+/*
+Ported to U-Boot by Christian Pellegrin <chri@ascensit.com>
+
+Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
+eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
+are GPL, so this is, of course, GPL.
+
+==========================================================================
+
+	dev/dp83902a.h
+
+	National Semiconductor DP83902a ethernet chip
+
+==========================================================================
+####ECOSGPLCOPYRIGHTBEGIN####
+ -------------------------------------------
+ This file is part of eCos, the Embedded Configurable Operating System.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+
+ eCos 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 or (at your option) any later version.
+
+ eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with eCos; if not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+ As a special exception, if other files instantiate templates or use macros
+ or inline functions from this file, or you compile this file and link it
+ with other works to produce a work based on this file, this file does not
+ by itself cause the resulting work to be covered by the GNU General Public
+ License. However the source code for this file must still be made available
+ in accordance with section (3) of the GNU General Public License.
+
+ This exception does not invalidate any other reasons why a work based on
+ this file might be covered by the GNU General Public License.
+
+ Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+ at http://sources.redhat.com/ecos/ecos-license/
+ -------------------------------------------
+####ECOSGPLCOPYRIGHTEND####
+####BSDCOPYRIGHTBEGIN####
+
+ -------------------------------------------
+
+ Portions of this software may have been derived from OpenBSD or other sources,
+ and are covered by the appropriate copyright disclaimers included herein.
+
+ -------------------------------------------
+
+####BSDCOPYRIGHTEND####
+==========================================================================
+#####DESCRIPTIONBEGIN####
+
+ Author(s):	gthomas
+ Contributors:	gthomas, jskov
+ Date:		2001-06-13
+ Purpose:
+ Description:
+
+####DESCRIPTIONEND####
+
+==========================================================================
+*/
+
+/*
+ * NE2000 support header file.
+ *		Created by Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+ */
+
+#ifndef __DRIVERS_NE2000_H__
+#define __DRIVERS_NE2000_H__
+
+/* Enable NE2000 basic init function */
+#define NE2000_BASIC_INIT
+
+#define DP_DATA		0x10
+#define START_PG	0x50	/* First page of TX buffer */
+#define START_PG2	0x48
+#define STOP_PG		0x80	/* Last page +1 of RX ring */
+
+#define RX_START	0x50
+#define RX_END		0x80
+
+#define DP_IN(_b_, _o_, _d_)	(_d_) = *( (vu_char *) ((_b_)+(_o_)))
+#define DP_OUT(_b_, _o_, _d_)	*( (vu_char *) ((_b_)+(_o_))) = (_d_)
+#define DP_IN_DATA(_b_, _d_)	(_d_) = *( (vu_char *) ((_b_)))
+#define DP_OUT_DATA(_b_, _d_)	*( (vu_char *) ((_b_))) = (_d_)
+#endif /* __DRIVERS_NE2000_H__ */
diff --git a/marvell/uboot/drivers/net/ne2000_base.c b/marvell/uboot/drivers/net/ne2000_base.c
new file mode 100644
index 0000000..ef35922
--- /dev/null
+++ b/marvell/uboot/drivers/net/ne2000_base.c
@@ -0,0 +1,800 @@
+/*
+Ported to U-Boot by Christian Pellegrin <chri@ascensit.com>
+
+Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
+eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
+are GPL, so this is, of course, GPL.
+
+==========================================================================
+
+dev/if_dp83902a.c
+
+Ethernet device driver for NS DP83902a ethernet controller
+
+==========================================================================
+####ECOSGPLCOPYRIGHTBEGIN####
+-------------------------------------------
+This file is part of eCos, the Embedded Configurable Operating System.
+Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+
+eCos 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 or (at your option) any later version.
+
+eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with eCos; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+As a special exception, if other files instantiate templates or use macros
+or inline functions from this file, or you compile this file and link it
+with other works to produce a work based on this file, this file does not
+by itself cause the resulting work to be covered by the GNU General Public
+License. However the source code for this file must still be made available
+in accordance with section (3) of the GNU General Public License.
+
+This exception does not invalidate any other reasons why a work based on
+this file might be covered by the GNU General Public License.
+
+Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+at http://sources.redhat.com/ecos/ecos-license/
+-------------------------------------------
+####ECOSGPLCOPYRIGHTEND####
+####BSDCOPYRIGHTBEGIN####
+
+-------------------------------------------
+
+Portions of this software may have been derived from OpenBSD or other sources,
+and are covered by the appropriate copyright disclaimers included herein.
+
+-------------------------------------------
+
+####BSDCOPYRIGHTEND####
+==========================================================================
+#####DESCRIPTIONBEGIN####
+
+Author(s):	gthomas
+Contributors:	gthomas, jskov, rsandifo
+Date:		2001-06-13
+Purpose:
+Description:
+
+FIXME:		Will fail if pinged with large packets (1520 bytes)
+Add promisc config
+Add SNMP
+
+####DESCRIPTIONEND####
+
+==========================================================================
+*/
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <malloc.h>
+#include <linux/compiler.h>
+
+/* forward definition of function used for the uboot interface */
+void uboot_push_packet_len(int len);
+void uboot_push_tx_done(int key, int val);
+
+/* NE2000 base header file */
+#include "ne2000_base.h"
+
+#if defined(CONFIG_DRIVER_AX88796L)
+/* AX88796L support */
+#include "ax88796.h"
+#else
+/* Basic NE2000 chip support */
+#include "ne2000.h"
+#endif
+
+static dp83902a_priv_data_t nic; /* just one instance of the card supported */
+
+/**
+ * This function reads the MAC address from the serial EEPROM,
+ * used if PROM read fails. Does nothing for ax88796 chips (sh boards)
+ */
+static bool
+dp83902a_init(unsigned char *enetaddr)
+{
+	dp83902a_priv_data_t *dp = &nic;
+	u8* base;
+#if defined(NE2000_BASIC_INIT)
+	int i;
+#endif
+
+	DEBUG_FUNCTION();
+
+	base = dp->base;
+	if (!base)
+		return false;	/* No device found */
+
+	DEBUG_LINE();
+
+#if defined(NE2000_BASIC_INIT)
+	/* AX88796L doesn't need */
+	/* Prepare ESA */
+	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1);	/* Select page 1 */
+	/* Use the address from the serial EEPROM */
+	for (i = 0; i < 6; i++)
+		DP_IN(base, DP_P1_PAR0+i, dp->esa[i]);
+	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0);	/* Select page 0 */
+
+	printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+		"eeprom",
+		dp->esa[0],
+		dp->esa[1],
+		dp->esa[2],
+		dp->esa[3],
+		dp->esa[4],
+		dp->esa[5] );
+
+	memcpy(enetaddr, dp->esa, 6); /* Use MAC from serial EEPROM */
+#endif	/* NE2000_BASIC_INIT */
+	return true;
+}
+
+static void
+dp83902a_stop(void)
+{
+	dp83902a_priv_data_t *dp = &nic;
+	u8 *base = dp->base;
+
+	DEBUG_FUNCTION();
+
+	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP);	/* Brutal */
+	DP_OUT(base, DP_ISR, 0xFF);		/* Clear any pending interrupts */
+	DP_OUT(base, DP_IMR, 0x00);		/* Disable all interrupts */
+
+	dp->running = false;
+}
+
+/*
+ * This function is called to "start up" the interface. It may be called
+ * multiple times, even when the hardware is already running. It will be
+ * called whenever something "hardware oriented" changes and should leave
+ * the hardware ready to send/receive packets.
+ */
+static void
+dp83902a_start(u8 * enaddr)
+{
+	dp83902a_priv_data_t *dp = &nic;
+	u8 *base = dp->base;
+	int i;
+
+	debug("The MAC is %pM\n", enaddr);
+
+	DEBUG_FUNCTION();
+
+	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */
+	DP_OUT(base, DP_DCR, DP_DCR_INIT);
+	DP_OUT(base, DP_RBCH, 0);		/* Remote byte count */
+	DP_OUT(base, DP_RBCL, 0);
+	DP_OUT(base, DP_RCR, DP_RCR_MON);	/* Accept no packets */
+	DP_OUT(base, DP_TCR, DP_TCR_LOCAL);	/* Transmitter [virtually] off */
+	DP_OUT(base, DP_TPSR, dp->tx_buf1);	/* Transmitter start page */
+	dp->tx1 = dp->tx2 = 0;
+	dp->tx_next = dp->tx_buf1;
+	dp->tx_started = false;
+	dp->running = true;
+	DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */
+	DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); /* Receive ring boundary */
+	DP_OUT(base, DP_PSTOP, dp->rx_buf_end);	/* Receive ring end page */
+	dp->rx_next = dp->rx_buf_start - 1;
+	dp->running = true;
+	DP_OUT(base, DP_ISR, 0xFF);		/* Clear any pending interrupts */
+	DP_OUT(base, DP_IMR, DP_IMR_All);	/* Enable all interrupts */
+	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP);	/* Select page 1 */
+	DP_OUT(base, DP_P1_CURP, dp->rx_buf_start);	/* Current page - next free page for Rx */
+	dp->running = true;
+	for (i = 0; i < ETHER_ADDR_LEN; i++) {
+		/* FIXME */
+		/*((vu_short*)( base + ((DP_P1_PAR0 + i) * 2) +
+		 * 0x1400)) = enaddr[i];*/
+		DP_OUT(base, DP_P1_PAR0+i, enaddr[i]);
+	}
+	/* Enable and start device */
+	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+	DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */
+	DP_OUT(base, DP_RCR, DP_RCR_AB); /* Accept broadcast, no errors, no multicast */
+	dp->running = true;
+}
+
+/*
+ * This routine is called to start the transmitter. It is split out from the
+ * data handling routine so it may be called either when data becomes first
+ * available or when an Tx interrupt occurs
+ */
+
+static void
+dp83902a_start_xmit(int start_page, int len)
+{
+	dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic;
+	u8 *base = dp->base;
+
+	DEBUG_FUNCTION();
+
+#if DEBUG & 1
+	printf("Tx pkt %d len %d\n", start_page, len);
+	if (dp->tx_started)
+		printf("TX already started?!?\n");
+#endif
+
+	DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE));
+	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+	DP_OUT(base, DP_TBCL, len & 0xFF);
+	DP_OUT(base, DP_TBCH, len >> 8);
+	DP_OUT(base, DP_TPSR, start_page);
+	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
+
+	dp->tx_started = true;
+}
+
+/*
+ * This routine is called to send data to the hardware. It is known a-priori
+ * that there is free buffer space (dp->tx_next).
+ */
+static void
+dp83902a_send(u8 *data, int total_len, u32 key)
+{
+	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
+	u8 *base = dp->base;
+	int len, start_page, pkt_len, i, isr;
+#if DEBUG & 4
+	int dx;
+#endif
+
+	DEBUG_FUNCTION();
+
+	len = pkt_len = total_len;
+	if (pkt_len < IEEE_8023_MIN_FRAME)
+		pkt_len = IEEE_8023_MIN_FRAME;
+
+	start_page = dp->tx_next;
+	if (dp->tx_next == dp->tx_buf1) {
+		dp->tx1 = start_page;
+		dp->tx1_len = pkt_len;
+		dp->tx1_key = key;
+		dp->tx_next = dp->tx_buf2;
+	} else {
+		dp->tx2 = start_page;
+		dp->tx2_len = pkt_len;
+		dp->tx2_key = key;
+		dp->tx_next = dp->tx_buf1;
+	}
+
+#if DEBUG & 5
+	printf("TX prep page %d len %d\n", start_page, pkt_len);
+#endif
+
+	DP_OUT(base, DP_ISR, DP_ISR_RDC);	/* Clear end of DMA */
+	{
+		/*
+		 * Dummy read. The manual sez something slightly different,
+		 * but the code is extended a bit to do what Hitachi's monitor
+		 * does (i.e., also read data).
+		 */
+
+		__maybe_unused u16 tmp;
+		int len = 1;
+
+		DP_OUT(base, DP_RSAL, 0x100 - len);
+		DP_OUT(base, DP_RSAH, (start_page - 1) & 0xff);
+		DP_OUT(base, DP_RBCL, len);
+		DP_OUT(base, DP_RBCH, 0);
+		DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START);
+		DP_IN_DATA(dp->data, tmp);
+	}
+
+#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
+	/*
+	 * Stall for a bit before continuing to work around random data
+	 * corruption problems on some platforms.
+	 */
+	CYGACC_CALL_IF_DELAY_US(1);
+#endif
+
+	/* Send data to device buffer(s) */
+	DP_OUT(base, DP_RSAL, 0);
+	DP_OUT(base, DP_RSAH, start_page);
+	DP_OUT(base, DP_RBCL, pkt_len & 0xFF);
+	DP_OUT(base, DP_RBCH, pkt_len >> 8);
+	DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START);
+
+	/* Put data into buffer */
+#if DEBUG & 4
+	printf(" sg buf %08lx len %08x\n ", (u32)data, len);
+	dx = 0;
+#endif
+	while (len > 0) {
+#if DEBUG & 4
+		printf(" %02x", *data);
+		if (0 == (++dx % 16)) printf("\n ");
+#endif
+
+		DP_OUT_DATA(dp->data, *data++);
+		len--;
+	}
+#if DEBUG & 4
+	printf("\n");
+#endif
+	if (total_len < pkt_len) {
+#if DEBUG & 4
+		printf("  + %d bytes of padding\n", pkt_len - total_len);
+#endif
+		/* Padding to 802.3 length was required */
+		for (i = total_len; i < pkt_len;) {
+			i++;
+			DP_OUT_DATA(dp->data, 0);
+		}
+	}
+
+#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
+	/*
+	 * After last data write, delay for a bit before accessing the
+	 * device again, or we may get random data corruption in the last
+	 * datum (on some platforms).
+	 */
+	CYGACC_CALL_IF_DELAY_US(1);
+#endif
+
+	/* Wait for DMA to complete */
+	do {
+		DP_IN(base, DP_ISR, isr);
+	} while ((isr & DP_ISR_RDC) == 0);
+
+	/* Then disable DMA */
+	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+
+	/* Start transmit if not already going */
+	if (!dp->tx_started) {
+		if (start_page == dp->tx1) {
+			dp->tx_int = 1; /* Expecting interrupt from BUF1 */
+		} else {
+			dp->tx_int = 2; /* Expecting interrupt from BUF2 */
+		}
+		dp83902a_start_xmit(start_page, pkt_len);
+	}
+}
+
+/*
+ * This function is called when a packet has been received. It's job is
+ * to prepare to unload the packet from the hardware. Once the length of
+ * the packet is known, the upper layer of the driver can be told. When
+ * the upper layer is ready to unload the packet, the internal function
+ * 'dp83902a_recv' will be called to actually fetch it from the hardware.
+ */
+static void
+dp83902a_RxEvent(void)
+{
+	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
+	u8 *base = dp->base;
+	__maybe_unused u8 rsr;
+	u8 rcv_hdr[4];
+	int i, len, pkt, cur;
+
+	DEBUG_FUNCTION();
+
+	DP_IN(base, DP_RSR, rsr);
+	while (true) {
+		/* Read incoming packet header */
+		DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START);
+		DP_IN(base, DP_P1_CURP, cur);
+		DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+		DP_IN(base, DP_BNDRY, pkt);
+
+		pkt += 1;
+		if (pkt == dp->rx_buf_end)
+			pkt = dp->rx_buf_start;
+
+		if (pkt == cur) {
+			break;
+		}
+		DP_OUT(base, DP_RBCL, sizeof(rcv_hdr));
+		DP_OUT(base, DP_RBCH, 0);
+		DP_OUT(base, DP_RSAL, 0);
+		DP_OUT(base, DP_RSAH, pkt);
+		if (dp->rx_next == pkt) {
+			if (cur == dp->rx_buf_start)
+				DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1);
+			else
+				DP_OUT(base, DP_BNDRY, cur - 1); /* Update pointer */
+			return;
+		}
+		dp->rx_next = pkt;
+		DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
+		DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
+#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
+		CYGACC_CALL_IF_DELAY_US(10);
+#endif
+
+		/* read header (get data size)*/
+		for (i = 0; i < sizeof(rcv_hdr);) {
+			DP_IN_DATA(dp->data, rcv_hdr[i++]);
+		}
+
+#if DEBUG & 5
+		printf("rx hdr %02x %02x %02x %02x\n",
+			rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]);
+#endif
+		len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr);
+
+		/* data read */
+		uboot_push_packet_len(len);
+
+		if (rcv_hdr[1] == dp->rx_buf_start)
+			DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1);
+		else
+			DP_OUT(base, DP_BNDRY, rcv_hdr[1] - 1); /* Update pointer */
+	}
+}
+
+/*
+ * This function is called as a result of the "eth_drv_recv()" call above.
+ * It's job is to actually fetch data for a packet from the hardware once
+ * memory buffers have been allocated for the packet. Note that the buffers
+ * may come in pieces, using a scatter-gather list. This allows for more
+ * efficient processing in the upper layers of the stack.
+ */
+static void
+dp83902a_recv(u8 *data, int len)
+{
+	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
+	u8 *base = dp->base;
+	int i, mlen;
+	u8 saved_char = 0;
+	bool saved;
+#if DEBUG & 4
+	int dx;
+#endif
+
+	DEBUG_FUNCTION();
+
+#if DEBUG & 5
+	printf("Rx packet %d length %d\n", dp->rx_next, len);
+#endif
+
+	/* Read incoming packet data */
+	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
+	DP_OUT(base, DP_RBCL, len & 0xFF);
+	DP_OUT(base, DP_RBCH, len >> 8);
+	DP_OUT(base, DP_RSAL, 4);		/* Past header */
+	DP_OUT(base, DP_RSAH, dp->rx_next);
+	DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
+	DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
+#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
+	CYGACC_CALL_IF_DELAY_US(10);
+#endif
+
+	saved = false;
+	for (i = 0; i < 1; i++) {
+		if (data) {
+			mlen = len;
+#if DEBUG & 4
+			printf(" sg buf %08lx len %08x \n", (u32) data, mlen);
+			dx = 0;
+#endif
+			while (0 < mlen) {
+				/* Saved byte from previous loop? */
+				if (saved) {
+					*data++ = saved_char;
+					mlen--;
+					saved = false;
+					continue;
+				}
+
+				{
+					u8 tmp;
+					DP_IN_DATA(dp->data, tmp);
+#if DEBUG & 4
+					printf(" %02x", tmp);
+					if (0 == (++dx % 16)) printf("\n ");
+#endif
+					*data++ = tmp;;
+					mlen--;
+				}
+			}
+#if DEBUG & 4
+			printf("\n");
+#endif
+		}
+	}
+}
+
+static void
+dp83902a_TxEvent(void)
+{
+	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
+	u8 *base = dp->base;
+	__maybe_unused u8 tsr;
+	u32 key;
+
+	DEBUG_FUNCTION();
+
+	DP_IN(base, DP_TSR, tsr);
+	if (dp->tx_int == 1) {
+		key = dp->tx1_key;
+		dp->tx1 = 0;
+	} else {
+		key = dp->tx2_key;
+		dp->tx2 = 0;
+	}
+	/* Start next packet if one is ready */
+	dp->tx_started = false;
+	if (dp->tx1) {
+		dp83902a_start_xmit(dp->tx1, dp->tx1_len);
+		dp->tx_int = 1;
+	} else if (dp->tx2) {
+		dp83902a_start_xmit(dp->tx2, dp->tx2_len);
+		dp->tx_int = 2;
+	} else {
+		dp->tx_int = 0;
+	}
+	/* Tell higher level we sent this packet */
+	uboot_push_tx_done(key, 0);
+}
+
+/*
+ * Read the tally counters to clear them. Called in response to a CNT
+ * interrupt.
+ */
+static void
+dp83902a_ClearCounters(void)
+{
+	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
+	u8 *base = dp->base;
+	__maybe_unused u8 cnt1, cnt2, cnt3;
+
+	DP_IN(base, DP_FER, cnt1);
+	DP_IN(base, DP_CER, cnt2);
+	DP_IN(base, DP_MISSED, cnt3);
+	DP_OUT(base, DP_ISR, DP_ISR_CNT);
+}
+
+/*
+ * Deal with an overflow condition. This code follows the procedure set
+ * out in section 7.0 of the datasheet.
+ */
+static void
+dp83902a_Overflow(void)
+{
+	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic;
+	u8 *base = dp->base;
+	u8 isr;
+
+	/* Issue a stop command and wait 1.6ms for it to complete. */
+	DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA);
+	CYGACC_CALL_IF_DELAY_US(1600);
+
+	/* Clear the remote byte counter registers. */
+	DP_OUT(base, DP_RBCL, 0);
+	DP_OUT(base, DP_RBCH, 0);
+
+	/* Enter loopback mode while we clear the buffer. */
+	DP_OUT(base, DP_TCR, DP_TCR_LOCAL);
+	DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA);
+
+	/*
+	 * Read in as many packets as we can and acknowledge any and receive
+	 * interrupts. Since the buffer has overflowed, a receive event of
+	 * some kind will have occured.
+	 */
+	dp83902a_RxEvent();
+	DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE);
+
+	/* Clear the overflow condition and leave loopback mode. */
+	DP_OUT(base, DP_ISR, DP_ISR_OFLW);
+	DP_OUT(base, DP_TCR, DP_TCR_NORMAL);
+
+	/*
+	 * If a transmit command was issued, but no transmit event has occured,
+	 * restart it here.
+	 */
+	DP_IN(base, DP_ISR, isr);
+	if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) {
+		DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
+	}
+}
+
+static void
+dp83902a_poll(void)
+{
+	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
+	u8 *base = dp->base;
+	u8 isr;
+
+	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START);
+	DP_IN(base, DP_ISR, isr);
+	while (0 != isr) {
+		/*
+		 * The CNT interrupt triggers when the MSB of one of the error
+		 * counters is set. We don't much care about these counters, but
+		 * we should read their values to reset them.
+		 */
+		if (isr & DP_ISR_CNT) {
+			dp83902a_ClearCounters();
+		}
+		/*
+		 * Check for overflow. It's a special case, since there's a
+		 * particular procedure that must be followed to get back into
+		 * a running state.a
+		 */
+		if (isr & DP_ISR_OFLW) {
+			dp83902a_Overflow();
+		} else {
+			/*
+			 * Other kinds of interrupts can be acknowledged simply by
+			 * clearing the relevant bits of the ISR. Do that now, then
+			 * handle the interrupts we care about.
+			 */
+			DP_OUT(base, DP_ISR, isr);	/* Clear set bits */
+			if (!dp->running) break;	/* Is this necessary? */
+			/*
+			 * Check for tx_started on TX event since these may happen
+			 * spuriously it seems.
+			 */
+			if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) {
+				dp83902a_TxEvent();
+			}
+			if (isr & (DP_ISR_RxP|DP_ISR_RxE)) {
+				dp83902a_RxEvent();
+			}
+		}
+		DP_IN(base, DP_ISR, isr);
+	}
+}
+
+
+/* U-boot specific routines */
+static u8 *pbuf = NULL;
+
+static int pkey = -1;
+static int initialized = 0;
+
+void uboot_push_packet_len(int len) {
+	PRINTK("pushed len = %d\n", len);
+	if (len >= 2000) {
+		printf("NE2000: packet too big\n");
+		return;
+	}
+	dp83902a_recv(&pbuf[0], len);
+
+	/*Just pass it to the upper layer*/
+	NetReceive(&pbuf[0], len);
+}
+
+void uboot_push_tx_done(int key, int val) {
+	PRINTK("pushed key = %d\n", key);
+	pkey = key;
+}
+
+/**
+ * Setup the driver and init MAC address according to doc/README.enetaddr
+ * Called by ne2k_register() before registering the driver @eth layer
+ *
+ * @param struct ethdevice of this instance of the driver for dev->enetaddr
+ * @return 0 on success, -1 on error (causing caller to print error msg)
+ */
+static int ne2k_setup_driver(struct eth_device *dev)
+{
+	PRINTK("### ne2k_setup_driver\n");
+
+	if (!pbuf) {
+		pbuf = malloc(2000);
+		if (!pbuf) {
+			printf("Cannot allocate rx buffer\n");
+			return -1;
+		}
+	}
+
+#ifdef CONFIG_DRIVER_NE2000_CCR
+	{
+		vu_char *p = (vu_char *) CONFIG_DRIVER_NE2000_CCR;
+
+		PRINTK("CCR before is %x\n", *p);
+		*p = CONFIG_DRIVER_NE2000_VAL;
+		PRINTK("CCR after is %x\n", *p);
+	}
+#endif
+
+	nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE;
+
+	nic.data = nic.base + DP_DATA;
+	nic.tx_buf1 = START_PG;
+	nic.tx_buf2 = START_PG2;
+	nic.rx_buf_start = RX_START;
+	nic.rx_buf_end = RX_END;
+
+	/*
+	 * According to doc/README.enetaddr, drivers shall give priority
+	 * to the MAC address value in the environment, so we do not read
+	 * it from the prom or eeprom if it is specified in the environment.
+	 */
+	if (!eth_getenv_enetaddr("ethaddr", dev->enetaddr)) {
+		/* If the MAC address is not in the environment, get it: */
+		if (!get_prom(dev->enetaddr, nic.base)) /* get MAC from prom */
+			dp83902a_init(dev->enetaddr);   /* fallback: seeprom */
+		/* And write it into the environment otherwise eth_write_hwaddr
+		 * returns -1 due to eth_getenv_enetaddr_by_index() failing,
+		 * and this causes "Warning: failed to set MAC address", and
+		 * cmd_bdinfo has no ethaddr value which it can show: */
+		eth_setenv_enetaddr("ethaddr", dev->enetaddr);
+	}
+	return 0;
+}
+
+static int ne2k_init(struct eth_device *dev, bd_t *bd)
+{
+	dp83902a_start(dev->enetaddr);
+	initialized = 1;
+	return 0;
+}
+
+static void ne2k_halt(struct eth_device *dev)
+{
+	debug("### ne2k_halt\n");
+	if(initialized)
+		dp83902a_stop();
+	initialized = 0;
+}
+
+static int ne2k_recv(struct eth_device *dev)
+{
+	dp83902a_poll();
+	return 1;
+}
+
+static int ne2k_send(struct eth_device *dev, void *packet, int length)
+{
+	int tmo;
+
+	debug("### ne2k_send\n");
+
+	pkey = -1;
+
+	dp83902a_send((u8 *) packet, length, 666);
+	tmo = get_timer (0) + TOUT * CONFIG_SYS_HZ;
+	while(1) {
+		dp83902a_poll();
+		if (pkey != -1) {
+			PRINTK("Packet sucesfully sent\n");
+			return 0;
+		}
+		if (get_timer (0) >= tmo) {
+			printf("transmission error (timoeut)\n");
+			return 0;
+		}
+
+	}
+	return 0;
+}
+
+/**
+ * Setup the driver for use and register it with the eth layer
+ * @return 0 on success, -1 on error (causing caller to print error msg)
+ */
+int ne2k_register(void)
+{
+	struct eth_device *dev;
+
+	dev = calloc(sizeof(*dev), 1);
+	if (dev == NULL)
+		return -1;
+
+	if (ne2k_setup_driver(dev))
+		return -1;
+
+	dev->init = ne2k_init;
+	dev->halt = ne2k_halt;
+	dev->send = ne2k_send;
+	dev->recv = ne2k_recv;
+
+	sprintf(dev->name, "NE2000");
+
+	return eth_register(dev);
+}
diff --git a/marvell/uboot/drivers/net/ne2000_base.h b/marvell/uboot/drivers/net/ne2000_base.h
new file mode 100644
index 0000000..eee0956
--- /dev/null
+++ b/marvell/uboot/drivers/net/ne2000_base.h
@@ -0,0 +1,304 @@
+/*
+Ported to U-Boot by Christian Pellegrin <chri@ascensit.com>
+
+Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
+eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
+are GPL, so this is, of course, GPL.
+
+
+==========================================================================
+
+	dev/dp83902a.h
+
+	National Semiconductor DP83902a ethernet chip
+
+==========================================================================
+####ECOSGPLCOPYRIGHTBEGIN####
+ -------------------------------------------
+ This file is part of eCos, the Embedded Configurable Operating System.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+
+ eCos 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 or (at your option) any later version.
+
+ eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with eCos; if not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+ As a special exception, if other files instantiate templates or use macros
+ or inline functions from this file, or you compile this file and link it
+ with other works to produce a work based on this file, this file does not
+ by itself cause the resulting work to be covered by the GNU General Public
+ License. However the source code for this file must still be made available
+ in accordance with section (3) of the GNU General Public License.
+
+ This exception does not invalidate any other reasons why a work based on
+ this file might be covered by the GNU General Public License.
+
+ Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+ at http://sources.redhat.com/ecos/ecos-license/
+ -------------------------------------------
+####ECOSGPLCOPYRIGHTEND####
+####BSDCOPYRIGHTBEGIN####
+
+ -------------------------------------------
+
+ Portions of this software may have been derived from OpenBSD or other sources,
+ and are covered by the appropriate copyright disclaimers included herein.
+
+ -------------------------------------------
+
+####BSDCOPYRIGHTEND####
+==========================================================================
+#####DESCRIPTIONBEGIN####
+
+ Author(s):	gthomas
+ Contributors:	gthomas, jskov
+ Date:		2001-06-13
+ Purpose:
+ Description:
+
+####DESCRIPTIONEND####
+
+==========================================================================
+
+*/
+
+/*
+ ------------------------------------------------------------------------
+ Macros for accessing DP registers
+ These can be overridden by the platform header
+*/
+
+#ifndef __NE2000_BASE_H__
+#define __NE2000_BASE_H__
+
+/*
+ * Debugging details
+ *
+ * Set to perms of:
+ * 0 disables all debug output
+ * 1 for process debug output
+ * 2 for added data IO output: get_reg, put_reg
+ * 4 for packet allocation/free output
+ * 8 for only startup status, so we can tell we're installed OK
+ */
+#if 0
+#define DEBUG 0xf
+#else
+#define DEBUG 0
+#endif
+
+#if DEBUG & 1
+#define DEBUG_FUNCTION() do { printf("%s\n", __FUNCTION__); } while (0)
+#define DEBUG_LINE() do { printf("%d\n", __LINE__); } while (0)
+#define PRINTK(args...) printf(args)
+#else
+#define DEBUG_FUNCTION() do {} while(0)
+#define DEBUG_LINE() do {} while(0)
+#define PRINTK(args...)
+#endif
+
+/* timeout for tx/rx in s */
+#define TOUT 5
+/* Ether MAC address size */
+#define ETHER_ADDR_LEN 6
+
+
+#define CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA 1
+#define CYGACC_CALL_IF_DELAY_US(X) udelay(X)
+
+/* H/W infomation struct */
+typedef struct hw_info_t {
+	u32 offset;
+	u8 a0, a1, a2;
+	u32 flags;
+} hw_info_t;
+
+typedef struct dp83902a_priv_data {
+	u8* base;
+	u8* data;
+	u8* reset;
+	int tx_next;		/* First free Tx page */
+	int tx_int;		/* Expecting interrupt from this buffer */
+	int rx_next;		/* First free Rx page */
+	int tx1, tx2;		/* Page numbers for Tx buffers */
+	u32 tx1_key, tx2_key;	/* Used to ack when packet sent */
+	int tx1_len, tx2_len;
+	bool tx_started, running, hardwired_esa;
+	u8 esa[6];
+	void* plf_priv;
+
+	/* Buffer allocation */
+	int tx_buf1, tx_buf2;
+	int rx_buf_start, rx_buf_end;
+} dp83902a_priv_data_t;
+
+/* ------------------------------------------------------------------------ */
+/* Register offsets */
+
+#define DP_CR		0x00
+#define DP_CLDA0	0x01
+#define DP_PSTART	0x01	/* write */
+#define DP_CLDA1	0x02
+#define DP_PSTOP	0x02	/* write */
+#define DP_BNDRY	0x03
+#define DP_TSR		0x04
+#define DP_TPSR		0x04	/* write */
+#define DP_NCR		0x05
+#define DP_TBCL		0x05	/* write */
+#define DP_FIFO		0x06
+#define DP_TBCH		0x06	/* write */
+#define DP_ISR		0x07
+#define DP_CRDA0	0x08
+#define DP_RSAL		0x08	/* write */
+#define DP_CRDA1	0x09
+#define DP_RSAH		0x09	/* write */
+#define DP_RBCL		0x0a	/* write */
+#define DP_RBCH		0x0b	/* write */
+#define DP_RSR		0x0c
+#define DP_RCR		0x0c	/* write */
+#define DP_FER		0x0d
+#define DP_TCR		0x0d	/* write */
+#define DP_CER		0x0e
+#define DP_DCR		0x0e	/* write */
+#define DP_MISSED	0x0f
+#define DP_IMR		0x0f	/* write */
+#define DP_DATAPORT	0x10	/* "eprom" data port */
+
+#define DP_P1_CR	0x00
+#define DP_P1_PAR0	0x01
+#define DP_P1_PAR1	0x02
+#define DP_P1_PAR2	0x03
+#define DP_P1_PAR3	0x04
+#define DP_P1_PAR4	0x05
+#define DP_P1_PAR5	0x06
+#define DP_P1_CURP	0x07
+#define DP_P1_MAR0	0x08
+#define DP_P1_MAR1	0x09
+#define DP_P1_MAR2	0x0a
+#define DP_P1_MAR3	0x0b
+#define DP_P1_MAR4	0x0c
+#define DP_P1_MAR5	0x0d
+#define DP_P1_MAR6	0x0e
+#define DP_P1_MAR7	0x0f
+
+#define DP_P2_CR	0x00
+#define DP_P2_PSTART	0x01
+#define DP_P2_CLDA0	0x01	/* write */
+#define DP_P2_PSTOP	0x02
+#define DP_P2_CLDA1	0x02	/* write */
+#define DP_P2_RNPP	0x03
+#define DP_P2_TPSR	0x04
+#define DP_P2_LNPP	0x05
+#define DP_P2_ACH	0x06
+#define DP_P2_ACL	0x07
+#define DP_P2_RCR	0x0c
+#define DP_P2_TCR	0x0d
+#define DP_P2_DCR	0x0e
+#define DP_P2_IMR	0x0f
+
+/* Command register - common to all pages */
+
+#define DP_CR_STOP	0x01	/* Stop: software reset */
+#define DP_CR_START	0x02	/* Start: initialize device */
+#define DP_CR_TXPKT	0x04	/* Transmit packet */
+#define DP_CR_RDMA	0x08	/* Read DMA (recv data from device) */
+#define DP_CR_WDMA	0x10	/* Write DMA (send data to device) */
+#define DP_CR_SEND	0x18	/* Send packet */
+#define DP_CR_NODMA	0x20	/* Remote (or no) DMA */
+#define DP_CR_PAGE0	0x00	/* Page select */
+#define DP_CR_PAGE1	0x40
+#define DP_CR_PAGE2	0x80
+#define DP_CR_PAGEMSK	0x3F	/* Used to mask out page bits */
+
+/* Data configuration register */
+
+#define DP_DCR_WTS	0x01	/* 1=16 bit word transfers */
+#define DP_DCR_BOS	0x02	/* 1=Little Endian */
+#define DP_DCR_LAS	0x04	/* 1=Single 32 bit DMA mode */
+#define DP_DCR_LS	0x08	/* 1=normal mode, 0=loopback */
+#define DP_DCR_ARM	0x10	/* 0=no send command (program I/O) */
+#define DP_DCR_FIFO_1	0x00	/* FIFO threshold */
+#define DP_DCR_FIFO_2	0x20
+#define DP_DCR_FIFO_4	0x40
+#define DP_DCR_FIFO_6	0x60
+
+#define DP_DCR_INIT	(DP_DCR_LS|DP_DCR_FIFO_4)
+
+/* Interrupt status register */
+
+#define DP_ISR_RxP	0x01	/* Packet received */
+#define DP_ISR_TxP	0x02	/* Packet transmitted */
+#define DP_ISR_RxE	0x04	/* Receive error */
+#define DP_ISR_TxE	0x08	/* Transmit error */
+#define DP_ISR_OFLW	0x10	/* Receive overflow */
+#define DP_ISR_CNT	0x20	/* Tally counters need emptying */
+#define DP_ISR_RDC	0x40	/* Remote DMA complete */
+#define DP_ISR_RESET	0x80	/* Device has reset (shutdown, error) */
+
+/* Interrupt mask register */
+
+#define DP_IMR_RxP	0x01	/* Packet received */
+#define DP_IMR_TxP	0x02	/* Packet transmitted */
+#define DP_IMR_RxE	0x04	/* Receive error */
+#define DP_IMR_TxE	0x08	/* Transmit error */
+#define DP_IMR_OFLW	0x10	/* Receive overflow */
+#define DP_IMR_CNT	0x20	/* Tall counters need emptying */
+#define DP_IMR_RDC	0x40	/* Remote DMA complete */
+
+#define DP_IMR_All	0x3F	/* Everything but remote DMA */
+
+/* Receiver control register */
+
+#define DP_RCR_SEP	0x01	/* Save bad(error) packets */
+#define DP_RCR_AR	0x02	/* Accept runt packets */
+#define DP_RCR_AB	0x04	/* Accept broadcast packets */
+#define DP_RCR_AM	0x08	/* Accept multicast packets */
+#define DP_RCR_PROM	0x10	/* Promiscuous mode */
+#define DP_RCR_MON	0x20	/* Monitor mode - 1=accept no packets */
+
+/* Receiver status register */
+
+#define DP_RSR_RxP	0x01	/* Packet received */
+#define DP_RSR_CRC	0x02	/* CRC error */
+#define DP_RSR_FRAME	0x04	/* Framing error */
+#define DP_RSR_FO	0x08	/* FIFO overrun */
+#define DP_RSR_MISS	0x10	/* Missed packet */
+#define DP_RSR_PHY	0x20	/* 0=pad match, 1=mad match */
+#define DP_RSR_DIS	0x40	/* Receiver disabled */
+#define DP_RSR_DFR	0x80	/* Receiver processing deferred */
+
+/* Transmitter control register */
+
+#define DP_TCR_NOCRC	0x01	/* 1=inhibit CRC */
+#define DP_TCR_NORMAL	0x00	/* Normal transmitter operation */
+#define DP_TCR_LOCAL	0x02	/* Internal NIC loopback */
+#define DP_TCR_INLOOP	0x04	/* Full internal loopback */
+#define DP_TCR_OUTLOOP	0x08	/* External loopback */
+#define DP_TCR_ATD	0x10	/* Auto transmit disable */
+#define DP_TCR_OFFSET	0x20	/* Collision offset adjust */
+
+/* Transmit status register */
+
+#define DP_TSR_TxP	0x01	/* Packet transmitted */
+#define DP_TSR_COL	0x04	/* Collision (at least one) */
+#define DP_TSR_ABT	0x08	/* Aborted because of too many collisions */
+#define DP_TSR_CRS	0x10	/* Lost carrier */
+#define DP_TSR_FU	0x20	/* FIFO underrun */
+#define DP_TSR_CDH	0x40	/* Collision Detect Heartbeat */
+#define DP_TSR_OWC	0x80	/* Collision outside normal window */
+
+#define IEEE_8023_MAX_FRAME	1518	/* Largest possible ethernet frame */
+#define IEEE_8023_MIN_FRAME	64	/* Smallest possible ethernet frame */
+
+/* Functions */
+int get_prom(u8* mac_addr, u8* base_addr);
+
+#endif /* __NE2000_BASE_H__ */
diff --git a/marvell/uboot/drivers/net/netconsole.c b/marvell/uboot/drivers/net/netconsole.c
new file mode 100644
index 0000000..65c747e
--- /dev/null
+++ b/marvell/uboot/drivers/net/netconsole.c
@@ -0,0 +1,331 @@
+/*
+ * (C) Copyright 2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <stdio_dev.h>
+#include <net.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_NETCONSOLE_BUFFER_SIZE
+#define CONFIG_NETCONSOLE_BUFFER_SIZE 512
+#endif
+
+static char input_buffer[CONFIG_NETCONSOLE_BUFFER_SIZE];
+static int input_size; /* char count in input buffer */
+static int input_offset; /* offset to valid chars in input buffer */
+static int input_recursion;
+static int output_recursion;
+static int net_timeout;
+static uchar nc_ether[6]; /* server enet address */
+static IPaddr_t nc_ip; /* server ip */
+static short nc_out_port; /* target output port */
+static short nc_in_port; /* source input port */
+static const char *output_packet; /* used by first send udp */
+static int output_packet_len;
+/*
+ * Start with a default last protocol.
+ * We are only interested in NETCONS or not.
+ */
+enum proto_t net_loop_last_protocol = BOOTP;
+
+static void nc_wait_arp_handler(uchar *pkt, unsigned dest,
+				 IPaddr_t sip, unsigned src,
+				 unsigned len)
+{
+	net_set_state(NETLOOP_SUCCESS); /* got arp reply - quit net loop */
+}
+
+static void nc_handler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
+			unsigned len)
+{
+	if (input_size)
+		net_set_state(NETLOOP_SUCCESS); /* got input - quit net loop */
+}
+
+static void nc_timeout(void)
+{
+	net_set_state(NETLOOP_SUCCESS);
+}
+
+static int is_broadcast(IPaddr_t ip)
+{
+	static IPaddr_t netmask;
+	static IPaddr_t our_ip;
+	static int env_changed_id;
+	int env_id = get_env_id();
+
+	/* update only when the environment has changed */
+	if (env_changed_id != env_id) {
+		netmask = getenv_IPaddr("netmask");
+		our_ip = getenv_IPaddr("ipaddr");
+
+		env_changed_id = env_id;
+	}
+
+	return (ip == ~0 ||				/* 255.255.255.255 */
+	    ((netmask & our_ip) == (netmask & ip) &&	/* on the same net */
+	    (netmask | ip) == ~0));		/* broadcast to our net */
+}
+
+static int refresh_settings_from_env(void)
+{
+	const char *p;
+	static int env_changed_id;
+	int env_id = get_env_id();
+
+	/* update only when the environment has changed */
+	if (env_changed_id != env_id) {
+		if (getenv("ncip")) {
+			nc_ip = getenv_IPaddr("ncip");
+			if (!nc_ip)
+				return -1;	/* ncip is 0.0.0.0 */
+			p = strchr(getenv("ncip"), ':');
+			if (p != NULL) {
+				nc_out_port = simple_strtoul(p + 1, NULL, 10);
+				nc_in_port = nc_out_port;
+			}
+		} else
+			nc_ip = ~0; /* ncip is not set, so broadcast */
+
+		p = getenv("ncoutport");
+		if (p != NULL)
+			nc_out_port = simple_strtoul(p, NULL, 10);
+		p = getenv("ncinport");
+		if (p != NULL)
+			nc_in_port = simple_strtoul(p, NULL, 10);
+
+		if (is_broadcast(nc_ip))
+			/* broadcast MAC address */
+			memset(nc_ether, 0xff, sizeof(nc_ether));
+		else
+			/* force arp request */
+			memset(nc_ether, 0, sizeof(nc_ether));
+	}
+	return 0;
+}
+
+/**
+ * Called from NetLoop in net/net.c before each packet
+ */
+void NcStart(void)
+{
+	refresh_settings_from_env();
+	if (!output_packet_len || memcmp(nc_ether, NetEtherNullAddr, 6)) {
+		/* going to check for input packet */
+		net_set_udp_handler(nc_handler);
+		NetSetTimeout(net_timeout, nc_timeout);
+	} else {
+		/* send arp request */
+		uchar *pkt;
+		net_set_arp_handler(nc_wait_arp_handler);
+		pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
+		memcpy(pkt, output_packet, output_packet_len);
+		NetSendUDPPacket(nc_ether, nc_ip, nc_out_port, nc_in_port,
+			output_packet_len);
+	}
+}
+
+int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port,
+	unsigned src_port, unsigned len)
+{
+	int end, chunk;
+
+	if (dest_port != nc_in_port || !len)
+		return 0; /* not for us */
+
+	if (src_ip != nc_ip && !is_broadcast(nc_ip))
+		return 0; /* not from our client */
+
+	debug_cond(DEBUG_DEV_PKT, "input: \"%*.*s\"\n", len, len, pkt);
+
+	if (input_size == sizeof(input_buffer))
+		return 1; /* no space */
+	if (len > sizeof(input_buffer) - input_size)
+		len = sizeof(input_buffer) - input_size;
+
+	end = input_offset + input_size;
+	if (end > sizeof(input_buffer))
+		end -= sizeof(input_buffer);
+
+	chunk = len;
+	if (end + len > sizeof(input_buffer)) {
+		chunk = sizeof(input_buffer) - end;
+		memcpy(input_buffer, pkt + chunk, len - chunk);
+	}
+	memcpy(input_buffer + end, pkt, chunk);
+
+	input_size += len;
+
+	return 1;
+}
+
+static void nc_send_packet(const char *buf, int len)
+{
+	struct eth_device *eth;
+	int inited = 0;
+	uchar *pkt;
+	uchar *ether;
+	IPaddr_t ip;
+
+	debug_cond(DEBUG_DEV_PKT, "output: \"%*.*s\"\n", len, len, buf);
+
+	eth = eth_get_dev();
+	if (eth == NULL)
+		return;
+
+	if (!memcmp(nc_ether, NetEtherNullAddr, 6)) {
+		if (eth->state == ETH_STATE_ACTIVE)
+			return;	/* inside net loop */
+		output_packet = buf;
+		output_packet_len = len;
+		input_recursion = 1;
+		NetLoop(NETCONS); /* wait for arp reply and send packet */
+		input_recursion = 0;
+		output_packet_len = 0;
+		return;
+	}
+
+	if (eth->state != ETH_STATE_ACTIVE) {
+		if (eth_is_on_demand_init()) {
+			if (eth_init(gd->bd) < 0)
+				return;
+			eth_set_last_protocol(NETCONS);
+		} else
+			eth_init_state_only(gd->bd);
+
+		inited = 1;
+	}
+	pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
+	memcpy(pkt, buf, len);
+	ether = nc_ether;
+	ip = nc_ip;
+	NetSendUDPPacket(ether, ip, nc_out_port, nc_in_port, len);
+
+	if (inited) {
+		if (eth_is_on_demand_init())
+			eth_halt();
+		else
+			eth_halt_state_only();
+	}
+}
+
+static int nc_start(void)
+{
+	int retval;
+
+	nc_out_port = 6666; /* default port */
+	nc_in_port = nc_out_port;
+
+	retval = refresh_settings_from_env();
+	if (retval != 0)
+		return retval;
+
+	/*
+	 * Initialize the static IP settings and buffer pointers
+	 * incase we call NetSendUDPPacket before NetLoop
+	 */
+	net_init();
+
+	return 0;
+}
+
+static void nc_putc(char c)
+{
+	if (output_recursion)
+		return;
+	output_recursion = 1;
+
+	nc_send_packet(&c, 1);
+
+	output_recursion = 0;
+}
+
+static void nc_puts(const char *s)
+{
+	int len;
+
+	if (output_recursion)
+		return;
+	output_recursion = 1;
+
+	len = strlen(s);
+	while (len) {
+		int send_len = min(len, sizeof(input_buffer));
+		nc_send_packet(s, send_len);
+		len -= send_len;
+		s += send_len;
+	}
+
+	output_recursion = 0;
+}
+
+static int nc_getc(void)
+{
+	uchar c;
+
+	input_recursion = 1;
+
+	net_timeout = 0;	/* no timeout */
+	while (!input_size)
+		NetLoop(NETCONS);
+
+	input_recursion = 0;
+
+	c = input_buffer[input_offset++];
+
+	if (input_offset >= sizeof(input_buffer))
+		input_offset -= sizeof(input_buffer);
+	input_size--;
+
+	return c;
+}
+
+static int nc_tstc(void)
+{
+	struct eth_device *eth;
+
+	if (input_recursion)
+		return 0;
+
+	if (input_size)
+		return 1;
+
+	eth = eth_get_dev();
+	if (eth && eth->state == ETH_STATE_ACTIVE)
+		return 0;	/* inside net loop */
+
+	input_recursion = 1;
+
+	net_timeout = 1;
+	NetLoop(NETCONS);	/* kind of poll */
+
+	input_recursion = 0;
+
+	return input_size != 0;
+}
+
+int drv_nc_init(void)
+{
+	struct stdio_dev dev;
+	int rc;
+
+	memset(&dev, 0, sizeof(dev));
+
+	strcpy(dev.name, "nc");
+	dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+	dev.start = nc_start;
+	dev.putc = nc_putc;
+	dev.puts = nc_puts;
+	dev.getc = nc_getc;
+	dev.tstc = nc_tstc;
+
+	rc = stdio_register(&dev);
+
+	return (rc == 0) ? 1 : rc;
+}
diff --git a/marvell/uboot/drivers/net/nicext.h b/marvell/uboot/drivers/net/nicext.h
new file mode 100644
index 0000000..ff422e7
--- /dev/null
+++ b/marvell/uboot/drivers/net/nicext.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+ * Copyright(c) 2000-2001 Broadcom Corporation. All rights reserved.
+ *
+ * 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.
+ *
+ * Name:        nicext.h
+ *
+ * Description: Broadcom Network Interface Card Extension (NICE) is an
+ *              extension to Linux NET device kernel mode drivers.
+ *              NICE is designed to provide additional functionalities,
+ *              such as receive packet intercept. To support Broadcom NICE,
+ *              the network device driver can be modified by adding an
+ *              device ioctl handler and by indicating receiving packets
+ *              to the NICE receive handler. Broadcom NICE will only be
+ *              enabled by a NICE-aware intermediate driver, such as
+ *              Broadcom Advanced Server Program Driver (BASP). When NICE
+ *              is not enabled, the modified network device drivers
+ *              functions exactly as other non-NICE aware drivers.
+ *
+ * Author:      Frankie Fan
+ *
+ * Created:     September 17, 2000
+ *
+ ****************************************************************************/
+#ifndef _nicext_h_
+#define _nicext_h_
+
+/*
+ * ioctl for NICE
+ */
+#define SIOCNICE	SIOCDEVPRIVATE+7
+
+/*
+ * SIOCNICE:
+ *
+ * The following structure needs to be less than IFNAMSIZ (16 bytes) because
+ * we're overloading ifreq.ifr_ifru.
+ *
+ * If 16 bytes is not enough, we should consider relaxing this because
+ * this is no field after ifr_ifru in the ifreq structure. But we may
+ * run into future compatiability problem in case of changing struct ifreq.
+ */
+struct nice_req
+{
+    __u32 cmd;
+
+    union
+    {
+#ifdef __KERNEL__
+	/* cmd = NICE_CMD_SET_RX or NICE_CMD_GET_RX */
+	struct
+	{
+	    void (*nrqus1_rx)( struct sk_buff*, void* );
+	    void* nrqus1_ctx;
+	} nrqu_nrqus1;
+
+	/* cmd = NICE_CMD_QUERY_SUPPORT */
+	struct
+	{
+	    __u32 nrqus2_magic;
+	    __u32 nrqus2_support_rx:1;
+	    __u32 nrqus2_support_vlan:1;
+	    __u32 nrqus2_support_get_speed:1;
+	} nrqu_nrqus2;
+#endif
+
+	/* cmd = NICE_CMD_GET_SPEED */
+	struct
+	{
+	    unsigned int nrqus3_speed; /* 0 if link is down, */
+				       /* otherwise speed in Mbps */
+	} nrqu_nrqus3;
+
+	/* cmd = NICE_CMD_BLINK_LED */
+	struct
+	{
+	    unsigned int nrqus4_blink_time; /* blink duration in seconds */
+	} nrqu_nrqus4;
+
+    } nrq_nrqu;
+};
+
+#define nrq_rx           nrq_nrqu.nrqu_nrqus1.nrqus1_rx
+#define nrq_ctx          nrq_nrqu.nrqu_nrqus1.nrqus1_ctx
+#define nrq_support_rx   nrq_nrqu.nrqu_nrqus2.nrqus2_support_rx
+#define nrq_magic        nrq_nrqu.nrqu_nrqus2.nrqus2_magic
+#define nrq_support_vlan nrq_nrqu.nrqu_nrqus2.nrqus2_support_vlan
+#define nrq_support_get_speed nrq_nrqu.nrqu_nrqus2.nrqus2_support_get_speed
+#define nrq_speed        nrq_nrqu.nrqu_nrqus3.nrqus3_speed
+#define nrq_blink_time   nrq_nrqu.nrqu_nrqus4.nrqus4_blink_time
+
+/*
+ * magic constants
+ */
+#define NICE_REQUESTOR_MAGIC            0x4543494E /* NICE in ascii */
+#define NICE_DEVICE_MAGIC               0x4E494345 /* ECIN in ascii */
+
+/*
+ * command field
+ */
+#define NICE_CMD_QUERY_SUPPORT          0x00000001
+#define NICE_CMD_SET_RX                 0x00000002
+#define NICE_CMD_GET_RX                 0x00000003
+#define NICE_CMD_GET_SPEED              0x00000004
+#define NICE_CMD_BLINK_LED              0x00000005
+
+#endif  /* _nicext_h_ */
diff --git a/marvell/uboot/drivers/net/npe/IxEthAcc.c b/marvell/uboot/drivers/net/npe/IxEthAcc.c
new file mode 100644
index 0000000..05a9e05
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthAcc.c
@@ -0,0 +1,237 @@
+/**
+ * @file IxEthAcc.c
+ *
+ * @author Intel Corporation
+ * @date 20-Feb-2001
+ *
+ * @brief This file contains the implementation of the IXP425 Ethernet Access Component
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+
+#include "IxEthAcc.h"
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+#include "IxEthDB.h"
+#endif
+#include "IxFeatureCtrl.h"
+
+#include "IxEthAcc_p.h"
+#include "IxEthAccMac_p.h"
+#include "IxEthAccMii_p.h"
+
+/**
+ * @addtogroup IxEthAcc
+ *@{
+ */
+
+
+/**
+ * @brief System-wide information data strucure.
+ *
+ * @ingroup IxEthAccPri
+ *
+ */
+
+IxEthAccInfo ixEthAccDataInfo;
+extern PUBLIC IxEthAccMacState ixEthAccMacState[];
+extern PUBLIC IxOsalMutex ixEthAccControlInterfaceMutex;
+
+/**
+ * @brief System-wide information
+ *
+ * @ingroup IxEthAccPri
+ *
+ */
+BOOL ixEthAccServiceInit = false;
+
+/* global filtering bit mask */
+PUBLIC UINT32 ixEthAccNewSrcMask;
+
+/**
+ * @brief Per port information data strucure.
+ *
+ * @ingroup IxEthAccPri
+ *
+ */
+
+IxEthAccPortDataInfo ixEthAccPortData[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+PUBLIC IxEthAccStatus ixEthAccInit()
+{
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+  /*
+   * Initialize Control plane
+   */
+  if (ixEthDBInit() != IX_ETH_DB_SUCCESS)
+  {
+      IX_ETH_ACC_WARNING_LOG("ixEthAccInit: EthDB init failed\n", 0, 0, 0, 0, 0, 0);
+
+      return IX_ETH_ACC_FAIL;
+  }
+#endif
+
+  if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
+  {
+      ixEthAccNewSrcMask = (~0); /* want all the bits */
+  }
+  else
+  {
+      ixEthAccNewSrcMask = (~IX_ETHACC_NE_NEWSRCMASK); /* want all but the NewSrc bit */
+  }
+
+  /*
+   * Initialize Data plane
+   */
+   if ( ixEthAccInitDataPlane()  != IX_ETH_ACC_SUCCESS )
+   {
+      IX_ETH_ACC_WARNING_LOG("ixEthAccInit: data plane init failed\n", 0, 0, 0, 0, 0, 0);
+
+       return IX_ETH_ACC_FAIL;
+   }
+
+
+   if ( ixEthAccQMgrQueuesConfig() != IX_ETH_ACC_SUCCESS )
+   {
+      IX_ETH_ACC_WARNING_LOG("ixEthAccInit: queue config failed\n", 0, 0, 0, 0, 0, 0);
+
+       return IX_ETH_ACC_FAIL;
+   }
+
+   /*
+    * Initialize MII
+    */
+   if ( ixEthAccMiiInit() != IX_ETH_ACC_SUCCESS )
+   {
+      IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mii init failed\n", 0, 0, 0, 0, 0, 0);
+
+       return IX_ETH_ACC_FAIL;
+   }
+
+   /*
+    * Initialize MAC I/O memory
+    */
+   if (ixEthAccMacMemInit() != IX_ETH_ACC_SUCCESS)
+   {
+      IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mac init failed\n", 0, 0, 0, 0, 0, 0);
+
+     return IX_ETH_ACC_FAIL;
+   }
+
+   /*
+    * Initialize control plane interface lock
+    */
+   if (ixOsalMutexInit(&ixEthAccControlInterfaceMutex) != IX_SUCCESS)
+   {
+       IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Control plane interface lock initialization failed\n", 0, 0, 0, 0, 0, 0);
+
+       return IX_ETH_ACC_FAIL;
+   }
+
+   /* initialiasation is complete */
+   ixEthAccServiceInit = true;
+
+   return IX_ETH_ACC_SUCCESS;
+
+}
+
+PUBLIC void ixEthAccUnload(void)
+{
+    IxEthAccPortId portId;
+
+    if ( IX_ETH_ACC_IS_SERVICE_INITIALIZED() )
+    {
+       /* check none of the port is still active */
+       for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+       {
+	   if ( IX_ETH_IS_PORT_INITIALIZED(portId) )
+	   {
+	       if (ixEthAccMacState[portId].portDisableState == ACTIVE)
+	       {
+		   IX_ETH_ACC_WARNING_LOG("ixEthAccUnload: port %u still active, bail out\n", portId, 0, 0, 0, 0, 0);
+		   return;
+	       }
+	   }
+       }
+
+       /* unmap the memory areas */
+       ixEthAccMiiUnload();
+       ixEthAccMacUnload();
+
+       /* set all ports as uninitialized */
+       for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+       {
+	       ixEthAccPortData[portId].portInitialized = false;
+       }
+
+       /* uninitialize the service */
+       ixEthAccServiceInit = false;
+   }
+}
+
+PUBLIC IxEthAccStatus ixEthAccPortInit( IxEthAccPortId portId)
+{
+
+  IxEthAccStatus ret=IX_ETH_ACC_SUCCESS;
+
+   if ( ! IX_ETH_ACC_IS_SERVICE_INITIALIZED() )
+   {
+	return(IX_ETH_ACC_FAIL);
+   }
+
+   /*
+    * Check for valid port
+    */
+
+   if ( ! IX_ETH_ACC_IS_PORT_VALID(portId) )
+   {
+       return (IX_ETH_ACC_INVALID_PORT);
+   }
+
+   if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+   {
+       IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Eth port.\n",(INT32) portId,0,0,0,0,0);
+       return IX_ETH_ACC_SUCCESS ;
+   }
+
+   if ( IX_ETH_IS_PORT_INITIALIZED(portId) )
+   {
+	/* Already initialized */
+	return(IX_ETH_ACC_FAIL);
+   }
+
+   if(ixEthAccMacInit(portId)!=IX_ETH_ACC_SUCCESS)
+   {
+       return IX_ETH_ACC_FAIL;
+   }
+
+   /*
+     * Set the port init flag.
+     */
+
+    ixEthAccPortData[portId].portInitialized = true;
+
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+    /* init learning/filtering database structures for this port */
+    ixEthDBPortInit(portId);
+#endif
+
+    return(ret);
+}
+
+
diff --git a/marvell/uboot/drivers/net/npe/IxEthAccCommon.c b/marvell/uboot/drivers/net/npe/IxEthAccCommon.c
new file mode 100644
index 0000000..8249737
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthAccCommon.c
@@ -0,0 +1,1025 @@
+/**
+ * @file IxEthAccCommon.c
+ *
+ * @author Intel Corporation
+ * @date 12-Feb-2002
+ *
+ * @brief This file contains the implementation common support routines for the component
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/*
+ * Component header files
+ */
+
+#include "IxOsal.h"
+#include "IxEthAcc.h"
+#include "IxEthDB.h"
+#include "IxNpeMh.h"
+#include "IxEthDBPortDefs.h"
+#include "IxFeatureCtrl.h"
+#include "IxEthAcc_p.h"
+#include "IxEthAccQueueAssign_p.h"
+
+#include "IxEthAccDataPlane_p.h"
+#include "IxEthAccMii_p.h"
+
+/**
+ * @addtogroup IxEthAccPri
+ *@{
+ */
+
+extern IxEthAccInfo   ixEthAccDataInfo;
+
+/**
+ *
+ * @brief Maximum number of RX queues set to be the maximum number
+ * of traffic calsses.
+ *
+ */
+#define IX_ETHACC_MAX_RX_QUEUES \
+      (IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY \
+      - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY \
+      + 1)
+
+/**
+ *
+ * @brief Maximum number of 128 entry RX queues
+ *
+ */
+#define IX_ETHACC_MAX_LARGE_RX_QUEUES 4
+
+/**
+ *
+ * @brief Data structure template for Default RX Queues
+ *
+ */
+IX_ETH_ACC_PRIVATE
+IxEthAccQregInfo ixEthAccQmgrRxDefaultTemplate =
+  {
+    IX_ETH_ACC_RX_FRAME_ETH_Q,	     /**< Queue ID */
+    "Eth Rx Q",
+    ixEthRxFrameQMCallback,          /**< Functional callback */
+    (IxQMgrCallbackId) 0,	     /**< Callback tag	      */
+    IX_QMGR_Q_SIZE128,		     /**< Allocate Max Size Q */
+    IX_QMGR_Q_ENTRY_SIZE1,	     /**< Queue Entry Sizes - all Q entries are single word entries   */
+    true,			     /**< Enable Q notification at startup */
+    IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE,/**< Q Condition to drive callback   */
+    IX_QMGR_Q_WM_LEVEL0,	     /**< Q Low water mark */
+    IX_QMGR_Q_WM_LEVEL1,	     /**< Q High water mark - needed by NPE */
+  };
+
+/**
+ *
+ * @brief Data structure template for Small RX Queues
+ *
+ */
+IX_ETH_ACC_PRIVATE
+IxEthAccQregInfo ixEthAccQmgrRxSmallTemplate =
+  {
+    IX_ETH_ACC_RX_FRAME_ETH_Q,	     /**< Queue ID */
+    "Eth Rx Q",
+    ixEthRxFrameQMCallback,          /**< Functional callback */
+    (IxQMgrCallbackId) 0,	     /**< Callback tag	      */
+    IX_QMGR_Q_SIZE64,		     /**< Allocate Smaller Q */
+    IX_QMGR_Q_ENTRY_SIZE1,	     /**< Queue Entry Sizes - all Q entries are single word entries   */
+    true,			     /**< Enable Q notification at startup */
+    IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE,/**< Q Condition to drive callback   */
+    IX_QMGR_Q_WM_LEVEL0,	     /**< Q Low water mark */
+    IX_QMGR_Q_WM_LEVEL1,	     /**< Q High water mark - needed by NPE */
+  };
+
+
+/**
+ *
+ * @brief Data structure used to register & initialize the Queues
+ *
+ */
+IX_ETH_ACC_PRIVATE
+IxEthAccQregInfo ixEthAccQmgrStaticInfo[]=
+{
+  {
+    IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q,
+    "Eth Rx Fr Q 1",
+    ixEthRxFreeQMCallback,
+    (IxQMgrCallbackId) IX_ETH_PORT_1,
+    IX_QMGR_Q_SIZE128,		     /**< Allocate Max Size Q */
+    IX_QMGR_Q_ENTRY_SIZE1,	     /**< Queue Entry Sizes - all Q entries are single word entries   */
+    false,			     /**< Disable Q notification at startup */
+    IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE, /**< Q Condition to drive callback  */
+    IX_QMGR_Q_WM_LEVEL0,	     /***< Q Low water mark */
+    IX_QMGR_Q_WM_LEVEL64,	     /**< Q High water mark */
+  },
+
+  {
+    IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q,
+    "Eth Rx Fr Q 2",
+    ixEthRxFreeQMCallback,
+    (IxQMgrCallbackId) IX_ETH_PORT_2,
+    IX_QMGR_Q_SIZE128,		     /**< Allocate Max Size Q */
+    IX_QMGR_Q_ENTRY_SIZE1,	     /**< Queue Entry Sizes - all Q entries are single word entries   */
+    false,			     /**< Disable Q notification at startup */
+    IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE,  /**< Q Condition to drive callback  */
+    IX_QMGR_Q_WM_LEVEL0,	     /**< Q Low water mark */
+    IX_QMGR_Q_WM_LEVEL64,	     /**< Q High water mark */
+  },
+#ifdef __ixp46X
+  {
+    IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q,
+    "Eth Rx Fr Q 3",
+    ixEthRxFreeQMCallback,
+    (IxQMgrCallbackId) IX_ETH_PORT_3,
+    IX_QMGR_Q_SIZE128,		     /**< Allocate Max Size Q */
+    IX_QMGR_Q_ENTRY_SIZE1,	     /**< Queue Entry Sizes - all Q entries are single word entries   */
+    false,			     /**< Disable Q notification at startup */
+    IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE,  /**< Q Condition to drive callback  */
+    IX_QMGR_Q_WM_LEVEL0,	     /**< Q Low water mark */
+    IX_QMGR_Q_WM_LEVEL64,	     /**< Q High water mark */
+  },
+#endif
+  {
+     IX_ETH_ACC_TX_FRAME_ENET0_Q,
+    "Eth Tx Q 1",
+     ixEthTxFrameQMCallback,
+     (IxQMgrCallbackId) IX_ETH_PORT_1,
+    IX_QMGR_Q_SIZE128,		     /**< Allocate Max Size Q */
+    IX_QMGR_Q_ENTRY_SIZE1,	     /**< Queue Entry Sizes - all Q entries are single word entries   */
+    false,			     /**< Disable Q notification at startup */
+    IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE,	 /**< Q Condition to drive callback  */
+    IX_QMGR_Q_WM_LEVEL0,	     /**< Q Low water mark */
+    IX_QMGR_Q_WM_LEVEL64,	     /**< Q High water mark */
+  },
+
+  {
+     IX_ETH_ACC_TX_FRAME_ENET1_Q,
+    "Eth Tx Q 2",
+     ixEthTxFrameQMCallback,
+     (IxQMgrCallbackId) IX_ETH_PORT_2,
+    IX_QMGR_Q_SIZE128,		     /**< Allocate Max Size Q */
+    IX_QMGR_Q_ENTRY_SIZE1,	     /**< Queue Entry Sizes - all Q entries are single word entries   */
+    false,			     /**< Disable Q notification at startup */
+    IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE,	     /**< Q Condition to drive callback  */
+    IX_QMGR_Q_WM_LEVEL0,	     /**< Q Low water mark */
+    IX_QMGR_Q_WM_LEVEL64,	     /**< Q High water mark */
+  },
+#ifdef __ixp46X
+  {
+     IX_ETH_ACC_TX_FRAME_ENET2_Q,
+    "Eth Tx Q 3",
+     ixEthTxFrameQMCallback,
+     (IxQMgrCallbackId) IX_ETH_PORT_3,
+    IX_QMGR_Q_SIZE128,		     /**< Allocate Max Size Q */
+    IX_QMGR_Q_ENTRY_SIZE1,	     /** Queue Entry Sizes - all Q entries are single ord entries   */
+    false,			     /** Disable Q notification at startup */
+    IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE,	     /** Q Condition to drive callback  */
+    IX_QMGR_Q_WM_LEVEL0,	     /* No queues use almost empty */
+    IX_QMGR_Q_WM_LEVEL64,	      /** Q High water mark - needed used  */
+  },
+#endif
+  {
+     IX_ETH_ACC_TX_FRAME_DONE_ETH_Q,
+    "Eth Tx Done Q",
+     ixEthTxFrameDoneQMCallback,
+     (IxQMgrCallbackId) 0,
+    IX_QMGR_Q_SIZE128,		     /**< Allocate Max Size Q */
+    IX_QMGR_Q_ENTRY_SIZE1,	     /**< Queue Entry Sizes - all Q entries are single word entries   */
+    true,			     /**< Enable Q notification at startup */
+    IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE, /**< Q Condition to drive callback  */
+    IX_QMGR_Q_WM_LEVEL0,	     /**< Q Low water mark */
+    IX_QMGR_Q_WM_LEVEL2,	     /**< Q High water mark - needed by NPE */
+  },
+
+  {  /* Null Termination entry
+      */
+     (IxQMgrQId)0,
+     (char *) NULL,
+     (IxQMgrCallback) NULL,
+     (IxQMgrCallbackId) 0,
+     0,
+     0,
+     0,
+     0,
+     0,
+     0
+  }
+
+};
+
+/**
+ *
+ * @brief Data structure used to register & initialize the Queues
+ *
+ * The structure will be filled at run time depending on the NPE
+ * image already loaded and the QoS configured in ethDB.
+ *
+ */
+IX_ETH_ACC_PRIVATE
+IxEthAccQregInfo ixEthAccQmgrRxQueuesInfo[IX_ETHACC_MAX_RX_QUEUES+1]=
+{
+  {  /* PlaceHolder for rx queues
+      * depending on the QoS configured
+      */
+     (IxQMgrQId)0,
+     (char *) NULL,
+     (IxQMgrCallback) NULL,
+     (IxQMgrCallbackId) 0,
+     0,
+     0,
+     0,
+     0,
+     0,
+     0
+  },
+
+  {  /* PlaceHolder for rx queues
+      * depending on the QoS configured
+      */
+     (IxQMgrQId)0,
+     (char *) NULL,
+     (IxQMgrCallback) NULL,
+     (IxQMgrCallbackId) 0,
+     0,
+     0,
+     0,
+     0,
+     0,
+     0
+  },
+
+  {  /* PlaceHolder for rx queues
+      * depending on the QoS configured
+      */
+     (IxQMgrQId)0,
+     (char *) NULL,
+     (IxQMgrCallback) NULL,
+     (IxQMgrCallbackId) 0,
+     0,
+     0,
+     0,
+     0,
+     0,
+     0
+  },
+
+  {  /* PlaceHolder for rx queues
+      * depending on the QoS configured
+      */
+     (IxQMgrQId)0,
+     (char *) NULL,
+     (IxQMgrCallback) NULL,
+     (IxQMgrCallbackId) 0,
+     0,
+     0,
+     0,
+     0,
+     0,
+     0
+  },
+
+  {  /* PlaceHolder for rx queues
+      * depending on the QoS configured
+      */
+     (IxQMgrQId)0,
+     (char *) NULL,
+     (IxQMgrCallback) NULL,
+     (IxQMgrCallbackId) 0,
+     0,
+     0,
+     0,
+     0,
+     0,
+     0
+  },
+
+  {  /* PlaceHolder for rx queues
+      * depending on the QoS configured
+      */
+      (IxQMgrQId)0,
+     (char *) NULL,
+     (IxQMgrCallback) NULL,
+     (IxQMgrCallbackId) 0,
+     0,
+     0,
+     0,
+     0,
+     0,
+     0
+  },
+
+  {  /* PlaceHolder for rx queues
+      * depending on the QoS configured
+      */
+     (IxQMgrQId)0,
+     (char *) NULL,
+     (IxQMgrCallback) NULL,
+     (IxQMgrCallbackId) 0,
+     0,
+     0,
+     0,
+     0,
+     0,
+     0
+  },
+
+  {  /* PlaceHolder for rx queues
+      * depending on the QoS configured
+      */
+     (IxQMgrQId)0,
+     (char *) NULL,
+     (IxQMgrCallback) NULL,
+     (IxQMgrCallbackId) 0,
+     0,
+     0,
+     0,
+     0,
+     0,
+     0
+  },
+
+  {  /* Null Termination entry
+      */
+     (IxQMgrQId)0,
+     (char *) NULL,
+     (IxQMgrCallback) NULL,
+     (IxQMgrCallbackId) 0,
+     0,
+     0,
+     0,
+     0,
+     0,
+     0
+  }
+
+};
+
+/* forward declarations */
+IX_ETH_ACC_PRIVATE IxEthAccStatus
+ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes);
+
+/**
+ * @fn ixEthAccQMgrQueueSetup(void)
+ *
+ * @brief Setup one queue and its event, and register the callback required
+ * by this component to the QMgr
+ *
+ * @internal
+ */
+IX_ETH_ACC_PRIVATE IxEthAccStatus
+ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes)
+{
+    /*
+     * Configure each Q.
+     */
+    if ( ixQMgrQConfig( qInfoDes->qName,
+			qInfoDes->qId,
+			qInfoDes->qSize,
+			qInfoDes->qWords) != IX_SUCCESS)
+    {
+	return IX_ETH_ACC_FAIL;
+    }
+
+    if ( ixQMgrWatermarkSet( qInfoDes->qId,
+			     qInfoDes->AlmostEmptyThreshold,
+			     qInfoDes->AlmostFullThreshold
+			     ) != IX_SUCCESS)
+    {
+	return IX_ETH_ACC_FAIL;
+    }
+
+    /*
+     * Set dispatcher priority.
+     */
+    if ( ixQMgrDispatcherPrioritySet( qInfoDes->qId,
+				      IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY)
+	 != IX_SUCCESS)
+    {
+	return IX_ETH_ACC_FAIL;
+    }
+
+    /*
+     * Register callbacks for each Q.
+     */
+    if ( ixQMgrNotificationCallbackSet(qInfoDes->qId,
+				       qInfoDes->qCallback,
+				       qInfoDes->callbackTag)
+	 != IX_SUCCESS )
+    {
+	return IX_ETH_ACC_FAIL;
+    }
+
+    /*
+     * Set notification condition for Q
+     */
+    if (qInfoDes->qNotificationEnableAtStartup == true)
+    {
+	if (   ixQMgrNotificationEnable(qInfoDes->qId,
+					qInfoDes->qConditionSource)
+	       != IX_SUCCESS )
+	{
+	    return IX_ETH_ACC_FAIL;
+	}
+    }
+
+    return(IX_ETH_ACC_SUCCESS);
+}
+
+/**
+ * @fn ixEthAccQMgrQueuesConfig(void)
+ *
+ * @brief Setup all the queues and register all callbacks required
+ * by this component to the QMgr
+ *
+ * The RxFree queues, tx queues, rx queues are configured statically
+ *
+ * Rx queues configuration is driven by QoS setup.
+ * Many Rx queues may be required when QoS is enabled (this depends
+ * on IxEthDB setup and the images being downloaded). The configuration
+ * of the rxQueues is done in many steps as follows:
+ *
+ * @li select all Rx queues as configured by ethDB for all ports
+ * @li sort the queues by traffic class
+ * @li build the priority dependency for all queues
+ * @li fill the configuration for all rx queues
+ * @li configure all statically configured queues
+ * @li configure all dynamically configured queues
+ *
+ * @param none
+ *
+ * @return IxEthAccStatus
+ *
+ * @internal
+ */
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccQMgrQueuesConfig(void)
+{
+    struct
+    {
+	int npeCount;
+	UINT32 npeId;
+	IxQMgrQId qId;
+	IxEthDBProperty trafficClass;
+    } rxQueues[IX_ETHACC_MAX_RX_QUEUES];
+
+    UINT32 rxQueue = 0;
+    UINT32 rxQueueCount = 0;
+    IxQMgrQId ixQId =IX_QMGR_MAX_NUM_QUEUES;
+    IxEthDBStatus ixEthDBStatus = IX_ETH_DB_SUCCESS;
+    IxEthDBPortId ixEthDbPortId = 0;
+    IxEthAccPortId ixEthAccPortId = 0;
+    UINT32 ixNpeId = 0;
+    UINT32 ixHighestNpeId = 0;
+    UINT32 sortIterations = 0;
+    IxEthAccStatus ret = IX_ETH_ACC_SUCCESS;
+    IxEthAccQregInfo *qInfoDes = NULL;
+    IxEthDBProperty ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
+    IxEthDBPropertyType ixEthDBPropertyType = IX_ETH_DB_INTEGER_PROPERTY;
+    UINT32 ixEthDBParameter = 0;
+    BOOL completelySorted = false;
+
+    /* Fill the corspondance between ports and queues
+     * This defines the mapping from port to queue Ids.
+     */
+
+    ixEthAccPortData[IX_ETH_PORT_1].ixEthAccRxData.rxFreeQueue
+	= IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q;
+    ixEthAccPortData[IX_ETH_PORT_2].ixEthAccRxData.rxFreeQueue
+	= IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q;
+#ifdef __ixp46X
+    ixEthAccPortData[IX_ETH_PORT_3].ixEthAccRxData.rxFreeQueue
+	= IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q;
+#endif
+    ixEthAccPortData[IX_ETH_PORT_1].ixEthAccTxData.txQueue
+	= IX_ETH_ACC_TX_FRAME_ENET0_Q;
+    ixEthAccPortData[IX_ETH_PORT_2].ixEthAccTxData.txQueue
+	= IX_ETH_ACC_TX_FRAME_ENET1_Q;
+#ifdef __ixp46X
+    ixEthAccPortData[IX_ETH_PORT_3].ixEthAccTxData.txQueue
+	= IX_ETH_ACC_TX_FRAME_ENET2_Q;
+#endif
+    /* Fill the corspondance between ports and NPEs
+     * This defines the mapping from port to npeIds.
+     */
+
+    ixEthAccPortData[IX_ETH_PORT_1].npeId = IX_NPEMH_NPEID_NPEB;
+    ixEthAccPortData[IX_ETH_PORT_2].npeId = IX_NPEMH_NPEID_NPEC;
+#ifdef __ixp46X
+    ixEthAccPortData[IX_ETH_PORT_3].npeId = IX_NPEMH_NPEID_NPEA;
+#endif
+    /* set the default rx scheduling discipline */
+    ixEthAccDataInfo.schDiscipline = FIFO_NO_PRIORITY;
+
+    /*
+     * Queue Selection step:
+     *
+     * The following code selects all the queues and build
+     * a temporary array which contains for each queue
+     * - the queue Id,
+     * - the highest traffic class (in case of many
+     * priorities configured for the same queue on different
+     * ports)
+     * - the number of different Npes which are
+     * configured to write to this queue.
+     *
+     * The output of this loop is a temporary array of RX queues
+     * in any order.
+     *
+     */
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+    for (ixEthAccPortId = 0;
+	 (ixEthAccPortId < IX_ETH_ACC_NUMBER_OF_PORTS)
+	     && (ret == IX_ETH_ACC_SUCCESS);
+	 ixEthAccPortId++)
+    {
+	/* map between ethDb and ethAcc port Ids */
+	ixEthDbPortId = (IxEthDBPortId)ixEthAccPortId;
+
+	/* map between npeId and ethAcc port Ids */
+	ixNpeId = IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId);
+
+	/* Iterate thru the different priorities */
+	for (ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
+	     ixEthDBTrafficClass <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY;
+	     ixEthDBTrafficClass++)
+	{
+	    ixEthDBStatus = ixEthDBFeaturePropertyGet(
+	      ixEthDbPortId,
+	      IX_ETH_DB_VLAN_QOS,
+	      ixEthDBTrafficClass,
+	      &ixEthDBPropertyType,
+	      (void *)&ixEthDBParameter);
+
+	    if (ixEthDBStatus == IX_ETH_DB_SUCCESS)
+	    {
+		/* This port and QoS class are mapped to
+		 * a RX queue.
+		 */
+		if (ixEthDBPropertyType == IX_ETH_DB_INTEGER_PROPERTY)
+		{
+		    /* remember the highest npe Id supporting ethernet */
+		    if (ixNpeId > ixHighestNpeId)
+		    {
+			ixHighestNpeId = ixNpeId;
+		    }
+
+		    /* search the queue in the list of queues
+		     * already used by an other port or QoS
+		     */
+		    for (rxQueue = 0;
+			 rxQueue < rxQueueCount;
+			 rxQueue++)
+		    {
+			if (rxQueues[rxQueue].qId == (IxQMgrQId)ixEthDBParameter)
+			{
+			    /* found an existing setup, update the number of ports
+			     * for this queue if the port maps to
+			     * a different NPE.
+			     */
+			    if (rxQueues[rxQueue].npeId != ixNpeId)
+			    {
+				rxQueues[rxQueue].npeCount++;
+				rxQueues[rxQueue].npeId = ixNpeId;
+			    }
+			    /* get the highest traffic class for this queue */
+			    if (rxQueues[rxQueue].trafficClass > ixEthDBTrafficClass)
+			    {
+				rxQueues[rxQueue].trafficClass = ixEthDBTrafficClass;
+			    }
+			    break;
+			}
+		    }
+		    if (rxQueue == rxQueueCount)
+		    {
+			/* new queue not found in the current list,
+			 * add a new entry.
+			 */
+			IX_OSAL_ASSERT(rxQueueCount < IX_ETHACC_MAX_RX_QUEUES);
+			rxQueues[rxQueueCount].qId = ixEthDBParameter;
+			rxQueues[rxQueueCount].npeCount = 1;
+			rxQueues[rxQueueCount].npeId = ixNpeId;
+			rxQueues[rxQueueCount].trafficClass = ixEthDBTrafficClass;
+			rxQueueCount++;
+		    }
+		}
+		else
+		{
+		    /* unexpected property type (not Integer) */
+		    ret = IX_ETH_ACC_FAIL;
+
+                    IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: unexpected property type returned by EthDB\n", 0, 0, 0, 0, 0, 0);
+
+		    /* no point to continue to iterate */
+		    break;
+		}
+	    }
+	    else
+	    {
+		/* No Rx queue configured for this port
+		 * and this traffic class. Do nothing.
+		 */
+	    }
+	}
+
+        /* notify EthDB that queue initialization is complete and traffic class allocation is frozen */
+        ixEthDBFeaturePropertySet(ixEthDbPortId,
+            IX_ETH_DB_VLAN_QOS,
+            IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE,
+            NULL /* ignored */);
+    }
+
+#else
+
+    ixNpeId = IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId);
+    rxQueues[0].qId = 4;
+    rxQueues[0].npeCount = 1;
+    rxQueues[0].npeId = ixNpeId;
+    rxQueues[0].trafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
+    rxQueueCount++;
+
+#endif
+
+    /* check there is at least 1 rx queue : there is no point
+     * to continue if there is no rx queue configured
+     */
+    if ((rxQueueCount == 0) || (ret == IX_ETH_ACC_FAIL))
+    {
+        IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: no queues configured, bailing out\n", 0, 0, 0, 0, 0, 0);
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    /* Queue sort step:
+     *
+     * Re-order the array of queues by decreasing traffic class
+     * using a bubble sort. (trafficClass 0 is the lowest
+     * priority traffic, trafficClass 7 is the highest priority traffic)
+     *
+     * Primary sort order is traffic class
+     * Secondary sort order is npeId
+     *
+     * Note that a bubble sort algorithm is not very efficient when
+     * the number of queues grows . However, this is not a very bad choice
+     * considering the very small number of entries to sort. Also, bubble
+     * sort is extremely fast when the list is already sorted.
+     *
+     * The output of this loop is a sorted array of queues.
+     *
+     */
+    sortIterations = 0;
+    do
+    {
+	sortIterations++;
+	completelySorted = true;
+	for (rxQueue = 0;
+	     rxQueue < rxQueueCount - sortIterations;
+	     rxQueue++)
+	{
+	    /* compare adjacent elements */
+	    if ((rxQueues[rxQueue].trafficClass <
+		rxQueues[rxQueue+1].trafficClass)
+		|| ((rxQueues[rxQueue].trafficClass ==
+		     rxQueues[rxQueue+1].trafficClass)
+		    &&(rxQueues[rxQueue].npeId <
+		       rxQueues[rxQueue+1].npeId)))
+	    {
+		/* swap adjacent elements */
+		int npeCount = rxQueues[rxQueue].npeCount;
+		UINT32 npeId = rxQueues[rxQueue].npeId;
+		IxQMgrQId qId = rxQueues[rxQueue].qId;
+		IxEthDBProperty trafficClass = rxQueues[rxQueue].trafficClass;
+		rxQueues[rxQueue].npeCount = rxQueues[rxQueue+1].npeCount;
+		rxQueues[rxQueue].npeId = rxQueues[rxQueue+1].npeId;
+		rxQueues[rxQueue].qId = rxQueues[rxQueue+1].qId;
+		rxQueues[rxQueue].trafficClass = rxQueues[rxQueue+1].trafficClass;
+		rxQueues[rxQueue+1].npeCount = npeCount;
+		rxQueues[rxQueue+1].npeId = npeId;
+		rxQueues[rxQueue+1].qId = qId;
+		rxQueues[rxQueue+1].trafficClass = trafficClass;
+		completelySorted = false;
+	    }
+	}
+    }
+    while (!completelySorted);
+
+    /* Queue traffic class list:
+     *
+     * Fill an array of rx queues linked by ascending traffic classes.
+     *
+     * If the queues are configured as follows
+     *   qId 6 -> traffic class 0 (lowest)
+     *   qId 7 -> traffic class 0
+     *   qId 8 -> traffic class 6
+     *   qId 12 -> traffic class 7 (highest)
+     *
+     * Then the output of this loop will be
+     *
+     * higherPriorityQueue[6] = 8
+     * higherPriorityQueue[7] = 8
+     * higherPriorityQueue[8] = 12
+     * higherPriorityQueue[12] = Invalid queueId
+     * higherPriorityQueue[...] = Invalid queueId
+     *
+     * Note that this queue ordering does not handle all possibilities
+     * that could result from different rules associated with different
+     * ports, and inconsistencies in the rules. In all cases, the
+     * output of this  algorithm is a simple linked list of queues,
+     * without closed circuit.
+
+     * This list is implemented as an array with invalid values initialized
+     * with an "invalid" queue id which is the maximum number of queues.
+     *
+     */
+
+    /*
+     * Initialise the rx queue list.
+     */
+    for (rxQueue = 0; rxQueue < IX_QMGR_MAX_NUM_QUEUES; rxQueue++)
+    {
+	ixEthAccDataInfo.higherPriorityQueue[rxQueue] = IX_QMGR_MAX_NUM_QUEUES;
+    }
+
+    /* build the linked list for this NPE.
+     */
+    for (ixNpeId = 0;
+	 ixNpeId <= ixHighestNpeId;
+	 ixNpeId++)
+    {
+	/* iterate thru the sorted list of queues
+	 */
+	ixQId = IX_QMGR_MAX_NUM_QUEUES;
+	for (rxQueue = 0;
+	     rxQueue < rxQueueCount;
+	     rxQueue++)
+	{
+	    if (rxQueues[rxQueue].npeId == ixNpeId)
+	    {
+		ixEthAccDataInfo.higherPriorityQueue[rxQueues[rxQueue].qId] = ixQId;
+		/* iterate thru queues with the same traffic class
+		 * than the current queue. (queues are ordered by descending
+		 * traffic classes and npeIds).
+		 */
+		while ((rxQueue < rxQueueCount - 1)
+		       && (rxQueues[rxQueue].trafficClass
+			   == rxQueues[rxQueue+1].trafficClass)
+		       && (ixNpeId == rxQueues[rxQueue].npeId))
+		{
+		    rxQueue++;
+		    ixEthAccDataInfo.higherPriorityQueue[rxQueues[rxQueue].qId] = ixQId;
+		}
+		ixQId = rxQueues[rxQueue].qId;
+	    }
+	}
+    }
+
+    /* point on the first dynamic queue description */
+    qInfoDes = ixEthAccQmgrRxQueuesInfo;
+
+    /* update the list of queues with the rx queues */
+    for (rxQueue = 0;
+	 (rxQueue < rxQueueCount) && (ret == IX_ETH_ACC_SUCCESS);
+	 rxQueue++)
+    {
+	/* Don't utilize more than IX_ETHACC_MAX_LARGE_RX_QUEUES queues
+	 * with the full 128 entries.  For the lower priority queues, use
+	 * a smaller number of entries.  This ensures queue resources
+	 * remain available for other components.
+	 */
+	if( (rxQueueCount > IX_ETHACC_MAX_LARGE_RX_QUEUES) &&
+	    (rxQueue < rxQueueCount - IX_ETHACC_MAX_LARGE_RX_QUEUES) )
+	{
+	    /* add the small RX Queue setup template to the list of queues */
+	    memcpy(qInfoDes, &ixEthAccQmgrRxSmallTemplate, sizeof(*qInfoDes));
+	} else {
+	    /* add the default RX Queue setup template to the list of queues */
+	    memcpy(qInfoDes, &ixEthAccQmgrRxDefaultTemplate, sizeof(*qInfoDes));
+	}
+
+	/* setup the RxQueue ID */
+	qInfoDes->qId = rxQueues[rxQueue].qId;
+
+	/* setup the RxQueue watermark level
+	 *
+	 * Each queue can be filled by many NPEs. To avoid the
+	 * NPEs to write to a full queue, need to set the
+	 * high watermark level for nearly full condition.
+	 * (the high watermark level are a power of 2
+	 * starting from the top of the queue)
+	 *
+	 * Number of     watermark
+         *   ports        level
+         *    1             0
+	 *    2             1
+	 *    3             2
+	 *    4             4
+	 *    5             4
+	 *    6             8
+	 *    n          approx. 2**ceil(log2(n))
+	 */
+	if (rxQueues[rxQueue].npeCount == 1)
+	{
+	    qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL0;
+	}
+	else if (rxQueues[rxQueue].npeCount == 2)
+	{
+	    qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL1;
+	}
+	else if (rxQueues[rxQueue].npeCount == 3)
+	{
+	    qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL2;
+	}
+	else
+	{
+	    /* reach the maximum number for CSR 2.0 */
+            IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: maximum number of NPEs per queue reached, bailing out\n", 0, 0, 0, 0, 0, 0);
+	    ret = IX_ETH_ACC_FAIL;
+	    break;
+	}
+
+	/* move to next queue entry */
+	++qInfoDes;
+    }
+
+    /* configure the static list (RxFree, Tx and TxDone queues) */
+    for (qInfoDes = ixEthAccQmgrStaticInfo;
+	 (qInfoDes->qCallback != (IxQMgrCallback) NULL )
+	     && (ret == IX_ETH_ACC_SUCCESS);
+	 ++qInfoDes)
+    {
+	ret = ixEthAccQMgrQueueSetup(qInfoDes);
+    }
+
+    /* configure the dynamic list (Rx queues) */
+    for (qInfoDes = ixEthAccQmgrRxQueuesInfo;
+	 (qInfoDes->qCallback != (IxQMgrCallback) NULL )
+	     && (ret == IX_ETH_ACC_SUCCESS);
+	 ++qInfoDes)
+    {
+	ret = ixEthAccQMgrQueueSetup(qInfoDes);
+    }
+
+    return(ret);
+}
+
+/**
+ * @fn ixEthAccQMgrRxQEntryGet(UINT32 *rxQueueEntries)
+ *
+ * @brief Add and return the total number of entries in all Rx queues
+ *
+ * @param UINT32 rxQueueEntries[in] number of entries in all queues
+ *
+ * @return void
+ *
+ * @note Rx queues configuration is driven by Qos Setup. There is a
+ * variable number of rx queues which are set at initialisation.
+ *
+ * @internal
+ */
+IX_ETH_ACC_PUBLIC
+void ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries)
+{
+    UINT32 rxQueueLevel;
+    IxEthAccQregInfo *qInfoDes;;
+
+    *numRxQueueEntries = 0;
+
+    /* iterate thru rx queues */
+    for (qInfoDes = ixEthAccQmgrRxQueuesInfo;
+	 qInfoDes->qCallback != (IxQMgrCallback)NULL;
+	 ++qInfoDes)
+    {
+	/* retrieve the rx queue level */
+	rxQueueLevel = 0;
+	ixQMgrQNumEntriesGet(qInfoDes->qId, &rxQueueLevel);
+	(*numRxQueueEntries) += rxQueueLevel;
+    }
+}
+
+/**
+ * @fn ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback)
+ *
+ * @brief Change the callback registered to all rx queues.
+ *
+ * @param IxQMgrCallback ixQMgrCallback[in] QMgr callback to register
+ *
+ * @return IxEthAccStatus
+ *
+ * @note The user may decide to use different Rx mechanisms
+ * (e.g. receive many frames at the same time , or receive
+ *  one frame at a time, depending on the overall application
+ *  performances). A different QMgr callback is registered. This
+ *  way, there is no excessive pointer checks in the datapath.
+ *
+ * @internal
+ */
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback)
+{
+    IxEthAccQregInfo *qInfoDes;
+    IxEthAccStatus ret = IX_ETH_ACC_SUCCESS;
+
+    /* parameter check */
+    if (NULL == ixQMgrCallback)
+    {
+	ret = IX_ETH_ACC_FAIL;
+    }
+
+    /* iterate thru rx queues */
+    for (qInfoDes = ixEthAccQmgrRxQueuesInfo;
+	 (qInfoDes->qCallback != (IxQMgrCallback) NULL )
+	     && (ret == IX_ETH_ACC_SUCCESS);
+	 ++qInfoDes)
+    {
+	/* register the rx callback for all queues */
+	if (ixQMgrNotificationCallbackSet(qInfoDes->qId,
+					     ixQMgrCallback,
+					     qInfoDes->callbackTag
+					     ) != IX_SUCCESS)
+	{
+	    ret = IX_ETH_ACC_FAIL;
+	}
+    }
+    return(ret);
+}
+
+/**
+ * @fn ixEthAccSingleEthNpeCheck(IxEthAccPortId portId)
+ *
+ * @brief Check the npe exists for this port
+ *
+ * @param IxEthAccPortId portId[in] port
+ *
+ * @return IxEthAccStatus
+ *
+ * @internal
+ */
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId portId)
+{
+
+    /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */
+    if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+        (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+        || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+      {
+            if ((IX_ETH_PORT_1 == portId) &&
+                (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
+                 IX_FEATURE_CTRL_COMPONENT_ENABLED))
+            {
+                return IX_ETH_ACC_SUCCESS;
+            }
+
+            if ((IX_ETH_PORT_2 == portId) &&
+                (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
+                 IX_FEATURE_CTRL_COMPONENT_ENABLED))
+            {
+                return IX_ETH_ACC_SUCCESS;
+            }
+
+            if ((IX_ETH_PORT_3 == portId) &&
+                (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) ==
+                 IX_FEATURE_CTRL_COMPONENT_ENABLED))
+            {
+                return IX_ETH_ACC_SUCCESS;
+            }
+
+            return IX_ETH_ACC_FAIL;
+      }
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+/**
+ * @fn ixEthAccStatsShow(void)
+ *
+ * @brief Displays all EthAcc stats
+ *
+ * @return void
+ *
+ */
+void ixEthAccStatsShow(IxEthAccPortId portId)
+{
+    ixEthAccMdioShow();
+
+    printf("\nPort %u\nUnicast MAC : ", portId);
+    ixEthAccPortUnicastAddressShow(portId);
+    ixEthAccPortMulticastAddressShow(portId);
+    printf("\n");
+
+    ixEthAccDataPlaneShow();
+}
+
+
+
diff --git a/marvell/uboot/drivers/net/npe/IxEthAccControlInterface.c b/marvell/uboot/drivers/net/npe/IxEthAccControlInterface.c
new file mode 100644
index 0000000..dbe32e1
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthAccControlInterface.c
@@ -0,0 +1,509 @@
+/**
+ * @file IxEthAccControlInterface.c
+ *
+ * @author Intel Corporation
+ * @date 
+ *
+ * @brief IX_ETH_ACC_PUBLIC wrappers for control plane functions
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+#include "IxEthAcc.h"
+#include "IxEthAcc_p.h"
+
+PUBLIC IxOsalMutex ixEthAccControlInterfaceMutex;
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortEnable(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+        printf("EthAcc: (Mac) cannot enable port %d, service not initialized\n", portId);
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortEnablePriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus 
+ixEthAccPortDisable(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    /* check the context is iinitialized */
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortDisablePriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortEnabledQueryPriv(portId, enabled);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus 
+ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortPromiscuousModeClearPriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus 
+ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortPromiscuousModeSetPriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus 
+ixEthAccPortUnicastMacAddressSet(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortUnicastMacAddressSetPriv(portId, macAddr);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortUnicastMacAddressGet(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortUnicastMacAddressGetPriv(portId, macAddr);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressJoin(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortMulticastAddressJoinPriv(portId, macAddr);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressJoinAll(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortMulticastAddressJoinAllPriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressLeave(IxEthAccPortId portId, IxEthAccMacAddr *macAddr)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortMulticastAddressLeavePriv(portId, macAddr);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressLeaveAll(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortMulticastAddressLeaveAllPriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus 
+ixEthAccPortUnicastAddressShow(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+ 
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortUnicastAddressShowPriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC void 
+ixEthAccPortMulticastAddressShow(IxEthAccPortId portId)
+{
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return;
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    ixEthAccPortMulticastAddressShowPriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus 
+ixEthAccPortDuplexModeSet(IxEthAccPortId portId, IxEthAccDuplexMode mode)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortDuplexModeSetPriv(portId, mode);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus 
+ixEthAccPortDuplexModeGet(IxEthAccPortId portId, IxEthAccDuplexMode *mode)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortDuplexModeGetPriv(portId, mode);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendPaddingEnable(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+     
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortTxFrameAppendPaddingEnablePriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendPaddingDisable(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortTxFrameAppendPaddingDisablePriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendFCSEnable(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortTxFrameAppendFCSEnablePriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendFCSDisable(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortTxFrameAppendFCSDisablePriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortRxFrameAppendFCSEnable(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortRxFrameAppendFCSEnablePriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccPortRxFrameAppendFCSDisable(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortRxFrameAppendFCSDisablePriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccTxSchedulingDisciplineSet(IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccTxSchedulingDisciplineSetPriv(portId, sched);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus
+ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccRxSchedulingDisciplineSetPriv(sched);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus 
+ixEthAccPortNpeLoopbackEnable(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccNpeLoopbackEnablePriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus 
+ixEthAccPortTxEnable(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortTxEnablePriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus 
+ixEthAccPortRxEnable(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortRxEnablePriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus 
+ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccNpeLoopbackDisablePriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus 
+ixEthAccPortTxDisable(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortTxDisablePriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus 
+ixEthAccPortRxDisable(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortRxDisablePriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus 
+ixEthAccPortMacReset(IxEthAccPortId portId)
+{
+    IxEthAccStatus result;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER);
+    result = ixEthAccPortMacResetPriv(portId);
+    ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex);
+    return result;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxEthAccDataPlane.c b/marvell/uboot/drivers/net/npe/IxEthAccDataPlane.c
new file mode 100644
index 0000000..c0b82d9
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthAccDataPlane.c
@@ -0,0 +1,2459 @@
+/**
+ * @file IxEthDataPlane.c
+ *
+ * @author Intel Corporation
+ * @date 12-Feb-2002
+ *
+ * @brief This file contains the implementation of the IXPxxx
+ * Ethernet Access Data plane component
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxNpeMh.h"
+#include "IxEthAcc.h"
+#include "IxEthDB.h"
+#include "IxOsal.h"
+#include "IxEthDBPortDefs.h"
+#include "IxFeatureCtrl.h"
+#include "IxEthAcc_p.h"
+#include "IxEthAccQueueAssign_p.h"
+
+extern PUBLIC IxEthAccMacState ixEthAccMacState[];
+extern PUBLIC UINT32 ixEthAccNewSrcMask;
+
+/**
+ * private functions prototype
+ */
+PRIVATE IX_OSAL_MBUF *
+ixEthAccEntryFromQConvert(UINT32 qEntry, UINT32 mask);
+
+PRIVATE UINT32
+ixEthAccMbufRxQPrepare(IX_OSAL_MBUF *mbuf);
+
+PRIVATE UINT32
+ixEthAccMbufTxQPrepare(IX_OSAL_MBUF *mbuf);
+
+PRIVATE IxEthAccStatus
+ixEthAccTxSwQHighestPriorityGet(IxEthAccPortId portId,
+				IxEthAccTxPriority *priorityPtr);
+
+PRIVATE IxEthAccStatus
+ixEthAccTxFromSwQ(IxEthAccPortId portId,
+		  IxEthAccTxPriority priority);
+
+PRIVATE IxEthAccStatus
+ixEthAccRxFreeFromSwQ(IxEthAccPortId portId);
+
+PRIVATE void
+ixEthAccMbufFromTxQ(IX_OSAL_MBUF *mbuf);
+
+PRIVATE void
+ixEthAccMbufFromRxQ(IX_OSAL_MBUF *mbuf);
+
+PRIVATE IX_STATUS
+ixEthAccQmgrLockTxWrite(IxEthAccPortId portId,
+			UINT32 qBuffer);
+
+PRIVATE IX_STATUS
+ixEthAccQmgrLockRxWrite(IxEthAccPortId portId,
+			UINT32 qBuffer);
+
+PRIVATE IX_STATUS
+ixEthAccQmgrTxWrite(IxEthAccPortId portId,
+		    UINT32 qBuffer,
+		    UINT32 priority);
+
+/**
+ * @addtogroup IxEthAccPri
+ *@{
+ */
+
+/* increment a counter only when stats are enabled */
+#define TX_STATS_INC(port,field) \
+        IX_ETH_ACC_STATS_INC(ixEthAccPortData[port].ixEthAccTxData.stats.field)
+#define RX_STATS_INC(port,field) \
+        IX_ETH_ACC_STATS_INC(ixEthAccPortData[port].ixEthAccRxData.stats.field)
+
+/* always increment the counter (mainly used for unexpected errors) */
+#define TX_INC(port,field) \
+        ixEthAccPortData[port].ixEthAccTxData.stats.field++
+#define RX_INC(port,field) \
+        ixEthAccPortData[port].ixEthAccRxData.stats.field++
+
+PRIVATE IxEthAccDataPlaneStats     ixEthAccDataStats;
+
+extern IxEthAccPortDataInfo   ixEthAccPortData[];
+extern IxEthAccInfo   ixEthAccDataInfo;
+
+PRIVATE IxOsalFastMutex txWriteMutex[IX_ETH_ACC_NUMBER_OF_PORTS];
+PRIVATE IxOsalFastMutex rxWriteMutex[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+/**
+ *
+ * @brief Mbuf header conversion macros : they implement the
+ *  different conversions using a temporary value. They also double-check
+ *  that the parameters can be converted to/from NPE format.
+ *
+ */
+#if defined(__wince) && !defined(IN_KERNEL)
+#define PTR_VIRT2NPE(ptrSrc,dst) \
+  do { UINT32 temp; \
+      IX_OSAL_ENSURE(sizeof(ptrSrc) == sizeof(UINT32), "Wrong parameter type"); \
+      IX_OSAL_ENSURE(sizeof(dst) == sizeof(UINT32), "Wrong parameter type"); \
+      temp = (UINT32)IX_OSAL_MBUF_MBUF_VIRTUAL_TO_PHYSICAL_TRANSLATION((IX_OSAL_MBUF*)ptrSrc); \
+      (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \
+  while(0)
+
+#define PTR_NPE2VIRT(type,src,ptrDst) \
+  do { void *temp; \
+      IX_OSAL_ENSURE(sizeof(type) == sizeof(UINT32), "Wrong parameter type"); \
+      IX_OSAL_ENSURE(sizeof(src) == sizeof(UINT32), "Wrong parameter type"); \
+      IX_OSAL_ENSURE(sizeof(ptrDst) == sizeof(UINT32), "Wrong parameter type"); \
+      temp = (void *)IX_OSAL_SWAP_BE_SHARED_LONG(src); \
+      (ptrDst) = (type)IX_OSAL_MBUF_MBUF_PHYSICAL_TO_VIRTUAL_TRANSLATION(temp); } \
+  while(0)
+#else
+#define PTR_VIRT2NPE(ptrSrc,dst) \
+  do { UINT32 temp; \
+      IX_OSAL_ENSURE(sizeof(ptrSrc) == sizeof(UINT32), "Wrong parameter type"); \
+      IX_OSAL_ENSURE(sizeof(dst) == sizeof(UINT32), "Wrong parameter type"); \
+      temp = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS(ptrSrc); \
+      (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \
+  while(0)
+
+#define PTR_NPE2VIRT(type,src,ptrDst) \
+  do { void *temp; \
+      IX_OSAL_ENSURE(sizeof(type) == sizeof(UINT32), "Wrong parameter type"); \
+      IX_OSAL_ENSURE(sizeof(src) == sizeof(UINT32), "Wrong parameter type"); \
+      IX_OSAL_ENSURE(sizeof(ptrDst) == sizeof(UINT32), "Wrong parameter type"); \
+      temp = (void *)IX_OSAL_SWAP_BE_SHARED_LONG(src); \
+      (ptrDst) = (type)IX_OSAL_MMU_PHYS_TO_VIRT(temp); } \
+  while(0)
+#endif
+
+/**
+ *
+ * @brief Mbuf payload pointer conversion macros : Wince has its own
+ *  method to convert the buffer pointers
+ */
+#if defined(__wince) && !defined(IN_KERNEL)
+#define DATAPTR_VIRT2NPE(ptrSrc,dst) \
+  do { UINT32 temp; \
+      temp = (UINT32)IX_OSAL_MBUF_DATA_VIRTUAL_TO_PHYSICAL_TRANSLATION(ptrSrc); \
+      (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \
+  while(0)
+
+#else
+#define DATAPTR_VIRT2NPE(ptrSrc,dst) PTR_VIRT2NPE(IX_OSAL_MBUF_MDATA(ptrSrc),dst)
+#endif
+
+
+/* Flush the shared part of the mbuf header */
+#define IX_ETHACC_NE_CACHE_FLUSH(mbufPtr) \
+  do { \
+      IX_OSAL_CACHE_FLUSH(IX_ETHACC_NE_SHARED(mbufPtr), \
+			      sizeof(IxEthAccNe)); \
+    } \
+  while(0)
+
+/* Invalidate the shared part of the mbuf header */
+#define IX_ETHACC_NE_CACHE_INVALIDATE(mbufPtr) \
+  do { \
+      IX_OSAL_CACHE_INVALIDATE(IX_ETHACC_NE_SHARED(mbufPtr), \
+				   sizeof(IxEthAccNe)); \
+    } \
+  while(0)
+
+/* Preload one cache line (shared mbuf headers are aligned
+ * and their size is 1 cache line)
+ *
+ * IX_OSAL_CACHED  is defined when the mbuf headers are
+ * allocated from cached memory.
+ *
+ * Other processor on emulation environment may not implement
+ * preload function
+ */
+#ifdef IX_OSAL_CACHED
+	#if (CPU!=SIMSPARCSOLARIS) && !defined (__wince)
+		#define IX_ACC_DATA_CACHE_PRELOAD(ptr) \
+		do { /* preload a cache line (Xscale Processor) */ \
+			__asm__ (" pld [%0]\n": : "r" (ptr)); \
+		} \
+		while(0)
+	#else
+		/* preload not implemented on different processor */
+		#define IX_ACC_DATA_CACHE_PRELOAD(mbufPtr) \
+		do { /* nothing */ } while (0)
+	#endif
+#else
+	/* preload not needed if cache is not enabled */
+	#define IX_ACC_DATA_CACHE_PRELOAD(mbufPtr) \
+	do { /* nothing */ } while (0)
+#endif
+
+/**
+ *
+ * @brief function to retrieve the correct pointer from
+ * a queue entry posted by the NPE
+ *
+ * @param qEntry : entry from qmgr queue
+ *        mask : applicable mask for this queue
+ *        (4 most significant bits are used for additional informations)
+ *
+ * @return IX_OSAL_MBUF * pointer to mbuf header
+ *
+ * @internal
+ */
+PRIVATE IX_OSAL_MBUF *
+ixEthAccEntryFromQConvert(UINT32 qEntry, UINT32 mask)
+{
+    IX_OSAL_MBUF *mbufPtr;
+
+    if (qEntry != 0)
+    {
+        /* mask NPE bits (e.g. priority, port ...) */
+        qEntry &= mask;
+
+#if IX_ACC_DRAM_PHYS_OFFSET != 0
+        /* restore the original address pointer (if PHYS_OFFSET is not 0) */
+        qEntry |= (IX_ACC_DRAM_PHYS_OFFSET & ~IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);
+#endif
+        /* get the mbuf pointer address from the npe-shared address */
+        qEntry -= offsetof(IX_OSAL_MBUF,ix_ne);
+
+        /* phys2virt mbuf */
+        mbufPtr = (IX_OSAL_MBUF *)IX_OSAL_MMU_PHYS_TO_VIRT(qEntry);
+
+        /* preload the cacheline shared with NPE */
+        IX_ACC_DATA_CACHE_PRELOAD(IX_ETHACC_NE_SHARED(mbufPtr));
+
+        /* preload the cacheline used by xscale */
+        IX_ACC_DATA_CACHE_PRELOAD(mbufPtr);
+    }
+    else
+    {
+	mbufPtr = NULL;
+    }
+
+    return mbufPtr;
+}
+
+/* Convert the mbuf header for NPE transmission */
+PRIVATE UINT32
+ixEthAccMbufTxQPrepare(IX_OSAL_MBUF *mbuf)
+{
+    UINT32 qbuf;
+    UINT32 len;
+
+    /* endianess swap for tci and flags
+       note: this is done only once, even for chained buffers */
+    IX_ETHACC_NE_FLAGS(mbuf)   = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_FLAGS(mbuf));
+    IX_ETHACC_NE_VLANTCI(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_VLANTCI(mbuf));
+
+    /* test for unchained mbufs */
+    if (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) == NULL)
+    {
+	/* "best case" scenario : unchained mbufs */
+	IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedTxMBufs);
+
+	/* payload pointer conversion */
+	DATAPTR_VIRT2NPE(mbuf, IX_ETHACC_NE_DATA(mbuf));
+
+	/* unchained mbufs : the frame length is the mbuf length
+	 * and the 2 identical lengths are stored in the same
+	 * word.
+	 */
+	len = IX_OSAL_MBUF_MLEN(mbuf);
+
+	/* set the length in both length and pktLen 16-bits fields */
+	len |= (len << IX_ETHNPE_ACC_LENGTH_OFFSET);
+	IX_ETHACC_NE_LEN(mbuf) = IX_OSAL_SWAP_BE_SHARED_LONG(len);
+
+	/* unchained mbufs : next contains 0 */
+	IX_ETHACC_NE_NEXT(mbuf) = 0;
+
+	/* flush shared header after all address conversions */
+	IX_ETHACC_NE_CACHE_FLUSH(mbuf);
+    }
+    else
+    {
+	/* chained mbufs */
+	IX_OSAL_MBUF *ptr = mbuf;
+	IX_OSAL_MBUF *nextPtr;
+	UINT32 frmLen;
+
+	/* get the frame length from the header of the first buffer */
+	frmLen = IX_OSAL_MBUF_PKT_LEN(mbuf);
+
+	do
+	{
+	    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedTxMBufs);
+
+	    /* payload pointer */
+	    DATAPTR_VIRT2NPE(ptr,IX_ETHACC_NE_DATA(ptr));
+	    /* Buffer length and frame length are stored in the same word */
+	    len = IX_OSAL_MBUF_MLEN(ptr);
+	    len = frmLen | (len << IX_ETHNPE_ACC_LENGTH_OFFSET);
+	    IX_ETHACC_NE_LEN(ptr) = IX_OSAL_SWAP_BE_SHARED_LONG(len);
+
+	    /* get the virtual next chain pointer */
+	    nextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr);
+	    if (nextPtr != NULL)
+	    {
+		/* shared pointer of the next buffer is chained */
+		PTR_VIRT2NPE(IX_ETHACC_NE_SHARED(nextPtr),
+			     IX_ETHACC_NE_NEXT(ptr));
+	    }
+	    else
+	    {
+		IX_ETHACC_NE_NEXT(ptr) = 0;
+	    }
+
+	    /* flush shared header after all address conversions */
+	    IX_ETHACC_NE_CACHE_FLUSH(ptr);
+
+	    /* move to next buffer */
+	    ptr = nextPtr;
+
+	    /* the frame length field is set only in the first buffer
+	     * and is zeroed in the next buffers
+	     */
+	    frmLen = 0;
+	}
+	while(ptr != NULL);
+
+    }
+
+    /* virt2phys mbuf itself */
+    qbuf = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS(
+		  IX_ETHACC_NE_SHARED(mbuf));
+
+    /* Ensure the bits which are reserved to exchange information with
+     * the NPE are cleared
+     *
+     * If the mbuf address is not correctly aligned, or from an
+     * incompatible memory range, there is no point to continue
+     */
+    IX_OSAL_ENSURE(((qbuf & ~IX_ETHNPE_QM_Q_TXENET_ADDR_MASK) == 0),
+	      "Invalid address range");
+
+    return qbuf;
+}
+
+/* Convert the mbuf header for NPE reception */
+PRIVATE UINT32
+ixEthAccMbufRxQPrepare(IX_OSAL_MBUF *mbuf)
+{
+    UINT32 len;
+    UINT32 qbuf;
+
+    if (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) == NULL)
+    {
+	/* "best case" scenario : unchained mbufs */
+	IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedRxFreeMBufs);
+
+	/* unchained mbufs : payload pointer */
+	DATAPTR_VIRT2NPE(mbuf, IX_ETHACC_NE_DATA(mbuf));
+
+	/* unchained mbufs : set the buffer length
+	* and the frame length field is zeroed
+	*/
+	len = (IX_OSAL_MBUF_MLEN(mbuf) << IX_ETHNPE_ACC_LENGTH_OFFSET);
+	IX_ETHACC_NE_LEN(mbuf) = IX_OSAL_SWAP_BE_SHARED_LONG(len);
+
+	/* unchained mbufs : next pointer is null */
+	IX_ETHACC_NE_NEXT(mbuf) = 0;
+
+	/* flush shared header after all address conversions */
+	IX_ETHACC_NE_CACHE_FLUSH(mbuf);
+
+	/* remove shared header cache line */
+	IX_ETHACC_NE_CACHE_INVALIDATE(mbuf);
+    }
+    else
+    {
+	/* chained mbufs */
+	IX_OSAL_MBUF *ptr = mbuf;
+	IX_OSAL_MBUF *nextPtr;
+
+	do
+	{
+	    /* chained mbufs */
+	    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedRxFreeMBufs);
+
+	    /* we must save virtual next chain pointer */
+	    nextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr);
+
+	    if (nextPtr != NULL)
+	    {
+		/* chaining pointer for NPE */
+		PTR_VIRT2NPE(IX_ETHACC_NE_SHARED(nextPtr),
+			     IX_ETHACC_NE_NEXT(ptr));
+	    }
+	    else
+	    {
+		IX_ETHACC_NE_NEXT(ptr) = 0;
+	    }
+
+	    /* payload pointer */
+	    DATAPTR_VIRT2NPE(ptr,IX_ETHACC_NE_DATA(ptr));
+
+	    /* buffer length */
+	    len = (IX_OSAL_MBUF_MLEN(ptr) << IX_ETHNPE_ACC_LENGTH_OFFSET);
+	    IX_ETHACC_NE_LEN(ptr) = IX_OSAL_SWAP_BE_SHARED_LONG(len);
+
+	    /* flush shared header after all address conversions */
+	    IX_ETHACC_NE_CACHE_FLUSH(ptr);
+
+	    /* remove shared header cache line */
+	    IX_ETHACC_NE_CACHE_INVALIDATE(ptr);
+
+	    /* next mbuf in the chain */
+	    ptr = nextPtr;
+	}
+	while(ptr != NULL);
+    }
+
+    /* virt2phys mbuf itself */
+    qbuf = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS(
+		  IX_ETHACC_NE_SHARED(mbuf));
+
+    /* Ensure the bits which are reserved to exchange information with
+     * the NPE are cleared
+     *
+     * If the mbuf address is not correctly aligned, or from an
+     * incompatible memory range, there is no point to continue
+     */
+    IX_OSAL_ENSURE(((qbuf & ~IX_ETHNPE_QM_Q_RXENET_ADDR_MASK) == 0),
+	      "Invalid address range");
+
+    return qbuf;
+}
+
+/* Convert the mbuf header after NPE transmission
+ * Since there is nothing changed by the NPE, there is no need
+ * to process anything but the update of internal stats
+ * when they are enabled
+*/
+PRIVATE void
+ixEthAccMbufFromTxQ(IX_OSAL_MBUF *mbuf)
+{
+#ifndef NDEBUG
+    /* test for unchained mbufs */
+    if (IX_ETHACC_NE_NEXT(mbuf) == 0)
+    {
+	/* unchained mbufs : update the stats */
+	IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedTxDoneMBufs);
+    }
+    else
+    {
+	/* chained mbufs : walk the chain and update the stats */
+	IX_OSAL_MBUF *ptr = mbuf;
+
+	do
+	{
+	    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedTxDoneMBufs);
+	    ptr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr);
+	}
+	while (ptr != NULL);
+    }
+#endif
+}
+
+/* Convert the mbuf header after NPE reception */
+PRIVATE void
+ixEthAccMbufFromRxQ(IX_OSAL_MBUF *mbuf)
+{
+    UINT32 len;
+
+    /* endianess swap for tci and flags
+       note: this is done only once, even for chained buffers */
+    IX_ETHACC_NE_FLAGS(mbuf)   = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_FLAGS(mbuf));
+    IX_ETHACC_NE_VLANTCI(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_VLANTCI(mbuf));
+
+    /* test for unchained mbufs */
+    if (IX_ETHACC_NE_NEXT(mbuf) == 0)
+    {
+	/* unchained mbufs */
+	IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedRxMBufs);
+
+	/* get the frame length. it is the same than the buffer length */
+	len = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(mbuf));
+	len &= IX_ETHNPE_ACC_PKTLENGTH_MASK;
+	IX_OSAL_MBUF_PKT_LEN(mbuf) = IX_OSAL_MBUF_MLEN(mbuf) = len;
+
+        /* clears the next packet field */
+	IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) = NULL;
+    }
+    else
+    {
+	IX_OSAL_MBUF *ptr = mbuf;
+	IX_OSAL_MBUF *nextPtr;
+	UINT32 frmLen;
+
+	/* convert the frame length */
+	frmLen = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(mbuf));
+	IX_OSAL_MBUF_PKT_LEN(mbuf) = (frmLen & IX_ETHNPE_ACC_PKTLENGTH_MASK);
+
+        /* chained mbufs */
+	do
+	{
+	    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedRxMBufs);
+
+	    /* convert the length */
+	    len = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(ptr));
+	    IX_OSAL_MBUF_MLEN(ptr) = (len >> IX_ETHNPE_ACC_LENGTH_OFFSET);
+
+            /* get the next pointer */
+	    PTR_NPE2VIRT(IX_OSAL_MBUF *,IX_ETHACC_NE_NEXT(ptr), nextPtr);
+	    if (nextPtr != NULL)
+	    {
+		nextPtr = (IX_OSAL_MBUF *)((UINT8 *)nextPtr - offsetof(IX_OSAL_MBUF,ix_ne));
+	    }
+	    /* set the next pointer */
+	    IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr) = nextPtr;
+
+	    /* move to the next buffer */
+	    ptr = nextPtr;
+	}
+	while (ptr != NULL);
+    }
+}
+
+/* write to qmgr if possible and report an overflow if not possible
+ * Use a fast lock to protect the queue write.
+ * This way, the tx feature is reentrant.
+ */
+PRIVATE IX_STATUS
+ixEthAccQmgrLockTxWrite(IxEthAccPortId portId, UINT32 qBuffer)
+{
+    IX_STATUS qStatus;
+    if (ixOsalFastMutexTryLock(&txWriteMutex[portId]) == IX_SUCCESS)
+    {
+	qStatus = ixQMgrQWrite(
+	       IX_ETH_ACC_PORT_TO_TX_Q_ID(portId),
+	       &qBuffer);
+#ifndef NDEBUG
+	if (qStatus != IX_SUCCESS)
+	{
+	    TX_STATS_INC(portId, txOverflow);
+	}
+#endif
+	ixOsalFastMutexUnlock(&txWriteMutex[portId]);
+    }
+    else
+    {
+	TX_STATS_INC(portId, txLock);
+	qStatus = IX_QMGR_Q_OVERFLOW;
+    }
+    return qStatus;
+}
+
+/* write to qmgr if possible and report an overflow if not possible
+ * Use a fast lock to protect the queue write.
+ * This way, the Rx feature is reentrant.
+ */
+PRIVATE IX_STATUS
+ixEthAccQmgrLockRxWrite(IxEthAccPortId portId, UINT32 qBuffer)
+{
+    IX_STATUS qStatus;
+    if (ixOsalFastMutexTryLock(&rxWriteMutex[portId]) == IX_SUCCESS)
+    {
+	qStatus = ixQMgrQWrite(
+	       IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId),
+	       &qBuffer);
+#ifndef NDEBUG
+	if (qStatus != IX_SUCCESS)
+	{
+	    RX_STATS_INC(portId, rxFreeOverflow);
+	}
+#endif
+	ixOsalFastMutexUnlock(&rxWriteMutex[portId]);
+    }
+    else
+    {
+	RX_STATS_INC(portId, rxFreeLock);
+	qStatus = IX_QMGR_Q_OVERFLOW;
+    }
+    return qStatus;
+}
+
+/*
+ * Set the priority and write to a qmgr queue.
+ */
+PRIVATE IX_STATUS
+ixEthAccQmgrTxWrite(IxEthAccPortId portId, UINT32 qBuffer, UINT32 priority)
+{
+    /* fill the priority field */
+    qBuffer |= (priority << IX_ETHNPE_QM_Q_FIELD_PRIOR_R);
+
+    return ixEthAccQmgrLockTxWrite(portId, qBuffer);
+}
+
+/**
+ *
+ * @brief This function will discover the highest priority S/W Tx Q that
+ *        has entries in it
+ *
+ * @param portId - (in) the id of the port whose S/W Tx queues are to be searched
+ *        priorityPtr - (out) the priority of the highest priority occupied q will be written
+ *                      here
+ *
+ * @return IX_ETH_ACC_SUCCESS if an occupied Q is found
+ *         IX_ETH_ACC_FAIL if no Q has entries
+ *
+ * @internal
+ */
+PRIVATE IxEthAccStatus
+ixEthAccTxSwQHighestPriorityGet(IxEthAccPortId portId,
+				IxEthAccTxPriority *priorityPtr)
+{
+    if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline
+	== FIFO_NO_PRIORITY)
+    {
+	if(IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId].
+	       ixEthAccTxData.txQ[IX_ETH_ACC_TX_DEFAULT_PRIORITY]))
+	{
+	    return IX_ETH_ACC_FAIL;
+	}
+	else
+	{
+	    *priorityPtr = IX_ETH_ACC_TX_DEFAULT_PRIORITY;
+	    TX_STATS_INC(portId,txPriority[*priorityPtr]);
+	    return IX_ETH_ACC_SUCCESS;
+	}
+    }
+    else
+    {
+	IxEthAccTxPriority highestPriority = IX_ETH_ACC_TX_PRIORITY_7;
+	while(1)
+	{
+	    if(!IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId].
+	       ixEthAccTxData.txQ[highestPriority]))
+	    {
+
+		*priorityPtr = highestPriority;
+		TX_STATS_INC(portId,txPriority[highestPriority]);
+		return IX_ETH_ACC_SUCCESS;
+
+	    }
+	    if (highestPriority == IX_ETH_ACC_TX_PRIORITY_0)
+	    {
+		return IX_ETH_ACC_FAIL;
+	    }
+	    highestPriority--;
+	}
+    }
+}
+
+/**
+ *
+ * @brief This function will take a buffer from a TX S/W Q and attempt
+ *        to add it to the relevant TX H/W Q
+ *
+ * @param portId - the port whose TX queue is to be written to
+ *        priority - identifies the queue from which the entry is to be read
+ *
+ * @internal
+ */
+PRIVATE IxEthAccStatus
+ixEthAccTxFromSwQ(IxEthAccPortId portId,
+		  IxEthAccTxPriority priority)
+{
+    IX_OSAL_MBUF        *mbuf;
+    IX_STATUS	   qStatus;
+
+    IX_OSAL_ENSURE((UINT32)priority <= (UINT32)7, "Invalid priority");
+
+    IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD(
+	ixEthAccPortData[portId].ixEthAccTxData.txQ[priority],
+	mbuf);
+
+    if (mbuf != NULL)
+    {
+	/*
+	 * Add the Tx buffer to the H/W Tx Q
+	 * We do not need to flush here as it is already done
+	 * in TxFrameSubmit().
+	 */
+	qStatus = ixEthAccQmgrTxWrite(
+	      portId,
+	      IX_OSAL_MMU_VIRT_TO_PHYS((UINT32)IX_ETHACC_NE_SHARED(mbuf)),
+	      priority);
+
+	if (qStatus == IX_SUCCESS)
+	{
+	    TX_STATS_INC(portId,txFromSwQOK);
+	    return IX_SUCCESS;
+	}
+	else if (qStatus == IX_QMGR_Q_OVERFLOW)
+	{
+	    /*
+	     * H/W Q overflow, need to save the buffer
+	     * back on the s/w Q.
+	     * we must put it back on the head of the q to avoid
+	     * reordering packet tx
+	     */
+	    TX_STATS_INC(portId,txFromSwQDelayed);
+	    IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(
+		ixEthAccPortData[portId].ixEthAccTxData.txQ[priority],
+		mbuf);
+
+	    /*enable Q notification*/
+	    qStatus = ixQMgrNotificationEnable(
+		IX_ETH_ACC_PORT_TO_TX_Q_ID(portId),
+		IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId));
+
+            if (qStatus != IX_SUCCESS && qStatus != IX_QMGR_WARNING)
+            {
+		TX_INC(portId,txUnexpectedError);
+		IX_ETH_ACC_FATAL_LOG(
+	            "ixEthAccTxFromSwQ:Unexpected Error: %u\n",
+	            qStatus, 0, 0, 0, 0, 0);
+            }
+	}
+	else
+	{
+	    TX_INC(portId,txUnexpectedError);
+
+	    /* recovery attempt */
+	    IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(
+		ixEthAccPortData[portId].ixEthAccTxData.txQ[priority],
+		mbuf);
+
+	    IX_ETH_ACC_FATAL_LOG(
+		"ixEthAccTxFromSwQ:Error: unexpected QM status 0x%08X\n",
+		qStatus, 0, 0, 0, 0, 0);
+	}
+    }
+    else
+    {
+	/* sw queue is empty */
+    }
+    return IX_ETH_ACC_FAIL;
+}
+
+/**
+ *
+ * @brief This function will take a buffer from a RXfree S/W Q and attempt
+ *        to add it to the relevant RxFree H/W Q
+ *
+ * @param portId - the port whose RXFree queue is to be written to
+ *
+ * @internal
+ */
+PRIVATE IxEthAccStatus
+ixEthAccRxFreeFromSwQ(IxEthAccPortId portId)
+{
+    IX_OSAL_MBUF        *mbuf;
+    IX_STATUS	   qStatus = IX_SUCCESS;
+
+    IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD(
+	  ixEthAccPortData[portId].ixEthAccRxData.freeBufferList,
+	  mbuf);
+    if (mbuf != NULL)
+    {
+	/*
+	 * Add The Rx Buffer to the H/W Free buffer Q if possible
+	 */
+	qStatus = ixEthAccQmgrLockRxWrite(portId,
+		  IX_OSAL_MMU_VIRT_TO_PHYS(
+			 (UINT32)IX_ETHACC_NE_SHARED(mbuf)));
+
+	if (qStatus == IX_SUCCESS)
+	{
+	    RX_STATS_INC(portId,rxFreeRepFromSwQOK);
+	    /*
+	     * Buffer added to h/w Q.
+	     */
+	    return IX_SUCCESS;
+	}
+	else if (qStatus == IX_QMGR_Q_OVERFLOW)
+	{
+	    /*
+	     * H/W Q overflow, need to save the buffer back on the s/w Q.
+	     */
+	    RX_STATS_INC(portId,rxFreeRepFromSwQDelayed);
+
+	    IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(
+		   ixEthAccPortData[portId].ixEthAccRxData.freeBufferList,
+		   mbuf);
+	}
+	else
+	{
+	    /* unexpected qmgr error */
+	    RX_INC(portId,rxUnexpectedError);
+
+	    IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(
+		    ixEthAccPortData[portId].ixEthAccRxData.freeBufferList,
+		    mbuf);
+
+	    IX_ETH_ACC_FATAL_LOG("IxEthAccRxFreeFromSwQ:Error: unexpected QM status 0x%08X\n",
+				 qStatus, 0, 0, 0, 0, 0);
+	}
+    }
+    else
+    {
+	/* sw queue is empty */
+    }
+    return IX_ETH_ACC_FAIL;
+}
+
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccInitDataPlane()
+{
+    UINT32 portId;
+
+    /*
+     * Initialize the service and register callback to other services.
+     */
+
+    IX_ETH_ACC_MEMSET(&ixEthAccDataStats,
+		      0,
+		      sizeof(ixEthAccDataStats));
+
+    for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+    {
+	ixOsalFastMutexInit(&txWriteMutex[portId]);
+	ixOsalFastMutexInit(&rxWriteMutex[portId]);
+
+	IX_ETH_ACC_MEMSET(&ixEthAccPortData[portId],
+			  0,
+			  sizeof(ixEthAccPortData[portId]));
+
+	ixEthAccPortData[portId].ixEthAccTxData.schDiscipline = FIFO_NO_PRIORITY;
+    }
+
+    return (IX_ETH_ACC_SUCCESS);
+}
+
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccPortTxDoneCallbackRegister(IxEthAccPortId portId,
+						  IxEthAccPortTxDoneCallback
+						  txCallbackFn,
+						  UINT32 callbackTag)
+{
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+    {
+	return (IX_ETH_ACC_INVALID_PORT);
+    }
+
+/* HACK: removing this code to enable NPE-A preliminary testing
+ *    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+ *    {
+ *        IX_ETH_ACC_WARNING_LOG("ixEthAccPortTxDoneCallbackRegister: Unavailable Eth %d: Cannot register TxDone Callback.\n",(INT32)portId,0,0,0,0,0);
+ *        return IX_ETH_ACC_SUCCESS ;
+ *    }
+ */
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+    if (txCallbackFn == 0)
+	/* Check for null function pointer here. */
+    {
+	return (IX_ETH_ACC_INVALID_ARG);
+    }
+    ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = txCallbackFn;
+    ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = callbackTag;
+    return (IX_ETH_ACC_SUCCESS);
+}
+
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccPortRxCallbackRegister(IxEthAccPortId portId,
+					      IxEthAccPortRxCallback
+					      rxCallbackFn,
+					      UINT32 callbackTag)
+{
+    IxEthAccPortId port;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+    {
+	return (IX_ETH_ACC_INVALID_PORT);
+    }
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("ixEthAccPortRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /* Check for null function pointer here. */
+    if (rxCallbackFn == NULL)
+    {
+	return (IX_ETH_ACC_INVALID_ARG);
+    }
+
+    /* Check the user is not changing the callback type
+     * when the port is enabled.
+    */
+    if (ixEthAccMacState[portId].portDisableState == ACTIVE)
+    {
+	for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++)
+	{
+	    if ((ixEthAccMacState[port].portDisableState == ACTIVE)
+		&& (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == true))
+	    {
+		/* one of the active ports has a different rx callback type.
+		 * Changing the callback type when the port is enabled
+		 * is not safe
+		 */
+		return (IX_ETH_ACC_INVALID_ARG);
+	    }
+	}
+    }
+
+    /* update the callback pointer : this is done before
+     * registering the new qmgr callback
+     */
+    ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = rxCallbackFn;
+    ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = callbackTag;
+
+    /* update the qmgr callback for rx queues */
+    if (ixEthAccQMgrRxCallbacksRegister(ixEthRxFrameQMCallback)
+	!= IX_ETH_ACC_SUCCESS)
+    {
+	/* unexpected qmgr error */
+        IX_ETH_ACC_FATAL_LOG("ixEthAccPortRxCallbackRegister: unexpected QMgr error, " \
+            "could not register Rx single-buffer callback\n", 0, 0, 0, 0, 0, 0);
+
+	RX_INC(portId,rxUnexpectedError);
+	return (IX_ETH_ACC_INVALID_ARG);
+    }
+
+    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = false;
+
+    return (IX_ETH_ACC_SUCCESS);
+}
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccPortMultiBufferRxCallbackRegister(
+			 IxEthAccPortId portId,
+			 IxEthAccPortMultiBufferRxCallback
+			 rxCallbackFn,
+			 UINT32 callbackTag)
+{
+    IxEthAccPortId port;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+    {
+	return (IX_ETH_ACC_INVALID_PORT);
+    }
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("ixEthAccPortMultiBufferRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /* Check for null function pointer here. */
+    if (rxCallbackFn == NULL)
+    {
+	return (IX_ETH_ACC_INVALID_ARG);
+    }
+
+    /* Check the user is not changing the callback type
+     * when the port is enabled.
+    */
+    if (ixEthAccMacState[portId].portDisableState == ACTIVE)
+    {
+	for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++)
+	{
+	    if ((ixEthAccMacState[port].portDisableState == ACTIVE)
+		&& (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == false))
+	    {
+		/* one of the active ports has a different rx callback type.
+		 * Changing the callback type when the port is enabled
+		 * is not safe
+		 */
+		return (IX_ETH_ACC_INVALID_ARG);
+	    }
+	}
+    }
+
+    /* update the callback pointer : this is done before
+     * registering the new qmgr callback
+     */
+    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = rxCallbackFn;
+    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = callbackTag;
+
+    /* update the qmgr callback for rx queues */
+    if (ixEthAccQMgrRxCallbacksRegister(ixEthRxMultiBufferQMCallback)
+	!= IX_ETH_ACC_SUCCESS)
+    {
+	/* unexpected qmgr error */
+	RX_INC(portId,rxUnexpectedError);
+
+        IX_ETH_ACC_FATAL_LOG("ixEthAccPortMultiBufferRxCallbackRegister: unexpected QMgr error, " \
+            "could not register Rx multi-buffer callback\n", 0, 0, 0, 0, 0, 0);
+
+	return (IX_ETH_ACC_INVALID_ARG);
+    }
+
+    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = true;
+
+    return (IX_ETH_ACC_SUCCESS);
+}
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccPortTxFrameSubmit(IxEthAccPortId portId,
+					 IX_OSAL_MBUF *buffer,
+					 IxEthAccTxPriority priority)
+{
+    IX_STATUS	qStatus = IX_SUCCESS;
+    UINT32      qBuffer;
+    IxEthAccTxPriority highestPriority;
+    IxQMgrQStatus txQStatus;
+
+#ifndef NDEBUG
+    if (buffer == NULL)
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+    {
+	return (IX_ETH_ACC_INVALID_PORT);
+    }
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_FATAL_LOG("ixEthAccPortTxFrameSubmit: Unavailable Eth %d: Cannot submit Tx Frame.\n",
+			     (INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_PORT_UNINITIALIZED ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+    if ((UINT32)priority > (UINT32)IX_ETH_ACC_TX_PRIORITY_7)
+    {
+	return (IX_ETH_ACC_INVALID_ARG);
+    }
+#endif
+
+    /*
+     * Need to Flush the MBUF and its contents (data) as it may be
+     * read from the NPE. Convert virtual addresses to physical addresses also.
+     */
+    qBuffer = ixEthAccMbufTxQPrepare(buffer);
+
+    /*
+     * If no fifo priority set on Xscale ...
+     */
+    if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline ==
+	FIFO_NO_PRIORITY)
+    {
+	/*
+	 * Add The Tx Buffer to the H/W Tx Q if possible
+	 * (the priority is passed to the NPE, because
+	 * the NPE is able to reorder the frames
+	 * before transmission to the underlying hardware)
+	 */
+	qStatus = ixEthAccQmgrTxWrite(portId,
+				      qBuffer,
+				      IX_ETH_ACC_TX_DEFAULT_PRIORITY);
+
+	if (qStatus == IX_SUCCESS)
+	{
+	    TX_STATS_INC(portId,txQOK);
+
+	    /*
+	     * "best case" scenario : Buffer added to h/w Q.
+	     */
+	    return (IX_SUCCESS);
+	}
+	else if (qStatus == IX_QMGR_Q_OVERFLOW)
+	{
+	    /*
+	     * We were unable to write the buffer to the
+	     * appropriate H/W Q,  Save it in the sw Q.
+	     * (use the default priority queue regardless of
+	     * input parameter)
+	     */
+	    priority = IX_ETH_ACC_TX_DEFAULT_PRIORITY;
+	}
+	else
+	{
+	    /* unexpected qmgr error */
+	    TX_INC(portId,txUnexpectedError);
+	    IX_ETH_ACC_FATAL_LOG(
+		"ixEthAccPortTxFrameSubmit:Error: qStatus = %u\n",
+		(UINT32)qStatus, 0, 0, 0, 0, 0);
+	    return (IX_ETH_ACC_FAIL);
+	}
+    }
+    else if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline ==
+	     FIFO_PRIORITY)
+    {
+
+	/*
+	 * For priority transmission, put the frame directly on the H/W queue
+	 * if the H/W queue is empty, otherwise, put it in a S/W Q
+	 */
+	ixQMgrQStatusGet(IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), &txQStatus);
+	if((txQStatus & IX_QMGR_Q_STATUS_E_BIT_MASK) != 0)
+	{
+	    /*The tx queue is empty, check whether there are buffers on the s/w queues*/
+	    if(ixEthAccTxSwQHighestPriorityGet(portId,  &highestPriority)
+	       !=IX_ETH_ACC_FAIL)
+	    {
+		/*there are buffers on the s/w queues, submit them*/
+		ixEthAccTxFromSwQ(portId, highestPriority);
+
+		/* the queue was empty, 1 buffer is already supplied
+		 * but is likely to be immediately transmitted and the
+		 * hw queue is likely to be empty again, so submit
+		 * more from the sw queues
+		 */
+		if(ixEthAccTxSwQHighestPriorityGet(portId,  &highestPriority)
+		   !=IX_ETH_ACC_FAIL)
+		{
+		    ixEthAccTxFromSwQ(portId, highestPriority);
+		    /*
+		     * and force the buffer supplied to be placed
+		     * on a priority queue
+		     */
+		    qStatus = IX_QMGR_Q_OVERFLOW;
+		}
+		else
+		{
+		    /*there are no buffers in the s/w queues, submit directly*/
+		    qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority);
+		}
+	    }
+	    else
+	    {
+		/*there are no buffers in the s/w queues, submit directly*/
+		qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority);
+	    }
+	}
+	else
+	{
+	    qStatus = IX_QMGR_Q_OVERFLOW;
+	}
+    }
+    else
+    {
+	TX_INC(portId,txUnexpectedError);
+	IX_ETH_ACC_FATAL_LOG(
+	    "ixEthAccPortTxFrameSubmit:Error: wrong schedule discipline setup\n",
+	    0, 0, 0, 0, 0, 0);
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    if(qStatus == IX_SUCCESS )
+    {
+	TX_STATS_INC(portId,txQOK);
+	return IX_ETH_ACC_SUCCESS;
+    }
+    else if(qStatus == IX_QMGR_Q_OVERFLOW)
+    {
+	TX_STATS_INC(portId,txQDelayed);
+	/*
+	 * We were unable to write the buffer to the
+	 * appropriate H/W Q,  Save it in a s/w Q.
+	 */
+	IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL(
+		ixEthAccPortData[portId].
+		ixEthAccTxData.txQ[priority],
+		buffer);
+
+	qStatus = ixQMgrNotificationEnable(
+		IX_ETH_ACC_PORT_TO_TX_Q_ID(portId),
+		IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId));
+
+        if (qStatus != IX_SUCCESS)
+	{
+	    if (qStatus == IX_QMGR_WARNING)
+	    {
+		/* notification is enabled for a queue
+		 * which is already empty (the condition is already met)
+		 * and there will be no more queue event to drain the sw queue
+		 */
+		TX_STATS_INC(portId,txLateNotificationEnabled);
+
+		/* pull a buffer from the sw queue */
+		if(ixEthAccTxSwQHighestPriorityGet(portId,  &highestPriority)
+		   !=IX_ETH_ACC_FAIL)
+		{
+		    /*there are buffers on the s/w queues, submit from them*/
+		    ixEthAccTxFromSwQ(portId, highestPriority);
+		}
+	    }
+	    else
+	    {
+		TX_INC(portId,txUnexpectedError);
+		IX_ETH_ACC_FATAL_LOG(
+		     "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n",
+		     qStatus, 0, 0, 0, 0, 0);
+	    }
+        }
+    }
+    else
+    {
+	TX_INC(portId,txUnexpectedError);
+	IX_ETH_ACC_FATAL_LOG(
+	     "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n",
+	     qStatus, 0, 0, 0, 0, 0);
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    return (IX_ETH_ACC_SUCCESS);
+}
+
+
+/**
+ *
+ * @brief replenish: convert a chain of mbufs to the format
+ *        expected by the NPE
+ *
+  */
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccPortRxFreeReplenish(IxEthAccPortId portId,
+					   IX_OSAL_MBUF *buffer)
+{
+    IX_STATUS	qStatus = IX_SUCCESS;
+    UINT32      qBuffer;
+
+    /*
+     * Check buffer is valid.
+     */
+
+#ifndef NDEBUG
+    /* check parameter value */
+    if (buffer == 0)
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+    {
+	return (IX_ETH_ACC_INVALID_PORT);
+    }
+
+    /* check initialisation is done */
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_FATAL_LOG(" ixEthAccPortRxFreeReplenish: Unavailable Eth %d: Cannot replenish Rx Free Q.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_PORT_UNINITIALIZED ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+    /* check boundaries and constraints */
+    if (IX_OSAL_MBUF_MLEN(buffer) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN)
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+#endif
+
+    qBuffer = ixEthAccMbufRxQPrepare(buffer);
+
+    /*
+     * Add The Rx Buffer to the H/W Free buffer Q if possible
+     */
+    qStatus = ixEthAccQmgrLockRxWrite(portId, qBuffer);
+
+    if (qStatus == IX_SUCCESS)
+    {
+	RX_STATS_INC(portId,rxFreeRepOK);
+	/*
+	 * Buffer added to h/w Q.
+	 */
+	return (IX_SUCCESS);
+    }
+    else if (qStatus == IX_QMGR_Q_OVERFLOW)
+    {
+	RX_STATS_INC(portId,rxFreeRepDelayed);
+	/*
+	 * We were unable to write the buffer to the approprate H/W Q,
+	 * Save it in a s/w Q.
+	 */
+	IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL(
+	    ixEthAccPortData[portId].ixEthAccRxData.freeBufferList,
+	    buffer);
+
+	qStatus = ixQMgrNotificationEnable(
+	    IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId),
+	    IX_ETH_ACC_PORT_TO_RX_FREE_Q_SOURCE(portId));
+
+        if (qStatus != IX_SUCCESS)
+	{
+	    if (qStatus == IX_QMGR_WARNING)
+	    {
+		/* notification is enabled for a queue
+		 * which is already empty (the condition is already met)
+		 * and there will be no more queue event to drain the sw queue
+		 * move an entry from the sw queue to the hw queue */
+		RX_STATS_INC(portId,rxFreeLateNotificationEnabled);
+		ixEthAccRxFreeFromSwQ(portId);
+	    }
+	    else
+	    {
+		RX_INC(portId,rxUnexpectedError);
+		IX_ETH_ACC_FATAL_LOG(
+		     "ixEthAccRxPortFreeReplenish:Error: %u\n",
+		     qStatus, 0, 0, 0, 0, 0);
+	    }
+        }
+    }
+    else
+    {
+	RX_INC(portId,rxUnexpectedError);
+	IX_ETH_ACC_FATAL_LOG(
+	    "ixEthAccRxPortFreeReplenish:Error: qStatus = %u\n",
+	    (UINT32)qStatus, 0, 0, 0, 0, 0);
+        return(IX_ETH_ACC_FAIL);
+    }
+    return (IX_ETH_ACC_SUCCESS);
+}
+
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccTxSchedulingDisciplineSetPriv(IxEthAccPortId portId,
+						 IxEthAccSchedulerDiscipline
+						 sched)
+{
+    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+    {
+	return (IX_ETH_ACC_INVALID_PORT);
+    }
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("ixEthAccTxSchedulingDisciplineSet: Unavailable Eth %d: Cannot set Tx Scheduling Discipline.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY)
+    {
+	return (IX_ETH_ACC_INVALID_ARG);
+    }
+
+    ixEthAccPortData[portId].ixEthAccTxData.schDiscipline = sched;
+    return (IX_ETH_ACC_SUCCESS);
+}
+
+IX_ETH_ACC_PUBLIC
+IxEthAccStatus ixEthAccRxSchedulingDisciplineSetPriv(IxEthAccSchedulerDiscipline
+						 sched)
+{
+    if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY)
+    {
+	return (IX_ETH_ACC_INVALID_ARG);
+    }
+
+    ixEthAccDataInfo.schDiscipline = sched;
+
+    return (IX_ETH_ACC_SUCCESS);
+}
+
+
+/**
+ * @fn ixEthRxFrameProcess(IxEthAccPortId portId, IX_OSAL_MBUF *mbufPtr)
+ *
+ * @brief process incoming frame :
+ *
+ * @param @ref IxQMgrCallback IxQMgrMultiBufferCallback
+ *
+ * @return none
+ *
+ * @internal
+ *
+ */
+IX_ETH_ACC_PRIVATE BOOL
+ixEthRxFrameProcess(IxEthAccPortId portId, IX_OSAL_MBUF *mbufPtr)
+{
+    UINT32 flags;
+    IxEthDBStatus result;
+
+#ifndef NDEBUG
+    /* Prudent to at least check the port is within range */
+    if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
+    {
+	ixEthAccDataStats.unexpectedError++;
+	IX_ETH_ACC_FATAL_LOG(
+	     "ixEthRxFrameProcess: Illegal port: %u\n",
+	     (UINT32)portId, 0, 0, 0, 0, 0);
+	return false;
+    }
+#endif
+
+    /* convert fields from mbuf header */
+    ixEthAccMbufFromRxQ(mbufPtr);
+
+    /* check about any special processing for this frame */
+    flags = IX_ETHACC_NE_FLAGS(mbufPtr);
+    if ((flags & (IX_ETHACC_NE_FILTERMASK | IX_ETHACC_NE_NEWSRCMASK)) == 0)
+    {
+	/* "best case" scenario : nothing special to do for this frame */
+	return true;
+    }
+
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+    /* if a new source MAC address is detected by the NPE,
+     * update IxEthDB with the portId and the MAC address.
+     */
+    if ((flags & IX_ETHACC_NE_NEWSRCMASK & ixEthAccNewSrcMask) != 0)
+    {
+        result = ixEthDBFilteringDynamicEntryProvision(portId,
+			  (IxEthDBMacAddr *) IX_ETHACC_NE_SOURCEMAC(mbufPtr));
+
+	if (result != IX_ETH_DB_SUCCESS && result != IX_ETH_DB_FEATURE_UNAVAILABLE)
+	{
+            if ((ixEthAccMacState[portId].portDisableState == ACTIVE) && (result != IX_ETH_DB_BUSY))
+            {
+	        RX_STATS_INC(portId, rxUnexpectedError);
+                IX_ETH_ACC_FATAL_LOG("ixEthRxFrameProcess: Failed to add source MAC \
+                                    to the Learning/Filtering database\n", 0, 0, 0, 0, 0, 0);
+            }
+            else
+            {
+                /* we expect this to fail during PortDisable, as EthDB is disabled for
+                 * that port and will refuse to learn new addresses
+		 */
+            }
+	}
+	else
+	{
+	    RX_STATS_INC(portId, rxUnlearnedMacAddress);
+	}
+    }
+#endif
+
+    /* check if this frame should have been filtered
+     * by the NPE and take the appropriate action
+     */
+    if (((flags & IX_ETHACC_NE_FILTERMASK) != 0)
+        && (ixEthAccMacState[portId].portDisableState == ACTIVE))
+    {
+        /* If the mbuf was allocated with a small data size, or the current data pointer is not
+         * within the allocated data area, then the buffer is non-standard and has to be
+         * replenished with the minimum size only
+         */
+        if( (IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN)
+           || ((UINT8 *)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr) > IX_OSAL_MBUF_MDATA(mbufPtr))
+           || ((UINT8 *)(IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr) +
+              IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr))
+               < IX_OSAL_MBUF_MDATA(mbufPtr)) )
+        {
+            /* set to minimum length */
+            IX_OSAL_MBUF_MLEN(mbufPtr) = IX_OSAL_MBUF_PKT_LEN(mbufPtr) =
+                IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN;
+        }
+        else
+        {
+            /* restore original length */
+            IX_OSAL_MBUF_MLEN(mbufPtr) = IX_OSAL_MBUF_PKT_LEN(mbufPtr) =
+                ( IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr) -
+                 (IX_OSAL_MBUF_MDATA(mbufPtr) - (UINT8 *)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr)) );
+        }
+
+        /* replenish from here */
+        if (ixEthAccPortRxFreeReplenish(portId, mbufPtr) != IX_ETH_ACC_SUCCESS)
+        {
+                IX_ETH_ACC_FATAL_LOG("ixEthRxFrameProcess: Failed to replenish with filtered frame\
+                                      on port %d\n", portId, 0, 0, 0, 0, 0);
+        }
+
+        RX_STATS_INC(portId, rxFiltered);
+
+        /* indicate that frame should not be subjected to further processing */
+        return false;
+    }
+
+    return true;
+}
+
+
+/**
+ * @fn ixEthRxFrameQMCallback
+ *
+ * @brief receive callback for Frame receive Q from NPE
+ *
+ * Frames are passed one-at-a-time to the user
+ *
+ * @param @ref IxQMgrCallback
+ *
+ * @return none
+ *
+ * @internal
+ *
+ * Design note : while processing the entry X, entry X+1 is preloaded
+ * into memory to reduce the number of stall cycles
+ *
+ */
+void ixEthRxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
+{
+    IX_OSAL_MBUF    *mbufPtr;
+    IX_OSAL_MBUF    *nextMbufPtr;
+    UINT32     qEntry;
+    UINT32     nextQEntry;
+    UINT32     *qEntryPtr;
+    UINT32     portId;
+    UINT32     destPortId;
+    UINT32     npeId;
+    UINT32     rxQReadStatus;
+
+    /*
+     * Design note : entries are read in a buffer, This buffer contains
+     * an extra zeroed entry so the loop will
+     * always terminate on a null entry, whatever the result of Burst read is.
+     */
+    UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1];
+
+    /*
+     * Indication of the number of times the callback is used.
+     */
+    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter);
+
+    do
+    {
+	/*
+	 * Indication of the number of times the queue is drained
+	 */
+	IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead);
+
+	/* ensure the last entry of the array contains a zeroed value */
+	qEntryPtr = rxQEntry;
+	qEntryPtr[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK] = 0;
+
+	rxQReadStatus = ixQMgrQBurstRead(qId,
+		 IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK,
+		 qEntryPtr);
+
+#ifndef NDEBUG
+	if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW)
+	    && (rxQReadStatus != IX_SUCCESS))
+	{
+	    ixEthAccDataStats.unexpectedError++;
+	    /*major error*/
+	    IX_ETH_ACC_FATAL_LOG(
+		"ixEthRxFrameQMCallback:Error: %u\n",
+		(UINT32)rxQReadStatus, 0, 0, 0, 0, 0);
+	    return;
+	}
+#endif
+
+	/* convert and preload the next entry
+	 * (the conversion function takes care about null pointers which
+	 * are used to mark the end of the loop)
+	 */
+	nextQEntry = *qEntryPtr;
+	nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry,
+			  IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);
+
+	while(nextQEntry != 0)
+	{
+	    /* get the next entry */
+	    qEntry = nextQEntry;
+	    mbufPtr = nextMbufPtr;
+
+#ifndef NDEBUG
+	    if (mbufPtr == NULL)
+	    {
+		ixEthAccDataStats.unexpectedError++;
+		IX_ETH_ACC_FATAL_LOG(
+		    "ixEthRxFrameQMCallback: Null Mbuf Ptr\n",
+		    0, 0, 0, 0, 0, 0);
+		return;
+	    }
+#endif
+
+	    /* convert the next entry
+	     * (the conversion function takes care about null pointers which
+	     * are used to mark the end of the loop)
+	     */
+	    nextQEntry = *(++qEntryPtr);
+	    nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry,
+			      IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);
+
+	    /*
+	     * Get Port and Npe ID from message.
+	     */
+	    npeId = ((IX_ETHNPE_QM_Q_RXENET_NPEID_MASK &
+		      qEntry) >> IX_ETHNPE_QM_Q_FIELD_NPEID_R);
+	    portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
+
+	    /* process frame, check the return code and skip the remaining of
+	     * the loop if the frame is to be filtered out
+	     */
+            if (ixEthRxFrameProcess(portId, mbufPtr))
+            {
+	        /* destination portId for this packet */
+	        destPortId = IX_ETHACC_NE_DESTPORTID(mbufPtr);
+
+                if (destPortId != IX_ETH_DB_UNKNOWN_PORT)
+                {
+                    destPortId = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(destPortId);
+                }
+
+	        /* test if QoS is enabled in ethAcc
+	        */
+	        if (ixEthAccDataInfo.schDiscipline == FIFO_PRIORITY)
+	        {
+		    /* check if there is a higher priority queue
+		    * which may require processing and then process it.
+		    */
+		    if (ixEthAccDataInfo.higherPriorityQueue[qId] < IX_QMGR_MAX_NUM_QUEUES)
+		    {
+		        ixEthRxFrameQMCallback(ixEthAccDataInfo.higherPriorityQueue[qId],
+					    callbackId);
+		    }
+	        }
+
+	        /*
+	        * increment priority stats
+	        */
+	        RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]);
+
+	        /*
+	        * increment callback count stats
+	        */
+	        RX_STATS_INC(portId,rxFrameClientCallback);
+
+	        /*
+	        * Call user level callback.
+	        */
+	        ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn(
+		    ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag,
+		    mbufPtr,
+		    destPortId);
+            }
+	}
+    } while (rxQReadStatus == IX_SUCCESS);
+}
+
+/**
+ * @fn ixEthRxMultiBufferQMCallback
+ *
+ * @brief receive callback for Frame receive Q from NPE
+ *
+ * Frames are passed as an array to the user
+ *
+ * @param @ref IxQMgrCallback
+ *
+ * @return none
+ *
+ * @internal
+ *
+ * Design note : while processing the entry X, entry X+1 is preloaded
+ * into memory to reduce the number of stall cycles
+ *
+ */
+void ixEthRxMultiBufferQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
+{
+    IX_OSAL_MBUF    *mbufPtr;
+    IX_OSAL_MBUF    *nextMbufPtr;
+    UINT32     qEntry;
+    UINT32     nextQEntry;
+    UINT32     *qEntryPtr;
+    UINT32     portId;
+    UINT32     npeId;
+    UINT32     rxQReadStatus;
+    /*
+     * Design note : entries are read in a static buffer, This buffer contains
+     * an extra zeroed entry so the loop will
+     * always terminate on a null entry, whatever the result of Burst read is.
+     */
+    static UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1];
+    static IX_OSAL_MBUF *rxMbufPortArray[IX_ETH_ACC_NUMBER_OF_PORTS][IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1];
+    IX_OSAL_MBUF **rxMbufPtr[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+    for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+    {
+	rxMbufPtr[portId] = rxMbufPortArray[portId];
+    }
+
+    /*
+     * Indication of the number of times the callback is used.
+     */
+    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter);
+
+    do
+    {
+	/*
+	 * Indication of the number of times the queue is drained
+	 */
+	IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead);
+
+	/* ensure the last entry of the array contains a zeroed value */
+	qEntryPtr = rxQEntry;
+	qEntryPtr[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK] = 0;
+
+	rxQReadStatus = ixQMgrQBurstRead(qId,
+		 IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK,
+		 qEntryPtr);
+
+#ifndef NDEBUG
+	if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW)
+	    && (rxQReadStatus != IX_SUCCESS))
+	{
+	    ixEthAccDataStats.unexpectedError++;
+	    /*major error*/
+	    IX_ETH_ACC_FATAL_LOG(
+		"ixEthRxFrameMultiBufferQMCallback:Error: %u\n",
+		(UINT32)rxQReadStatus, 0, 0, 0, 0, 0);
+	    return;
+	}
+#endif
+
+	/* convert and preload the next entry
+	 * (the conversion function takes care about null pointers which
+	 * are used to mark the end of the loop)
+	 */
+	nextQEntry = *qEntryPtr;
+	nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry,
+			  IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);
+
+	while(nextQEntry != 0)
+	{
+	    /* get the next entry */
+	    qEntry = nextQEntry;
+	    mbufPtr = nextMbufPtr;
+
+#ifndef NDEBUG
+	    if (mbufPtr == NULL)
+	    {
+		ixEthAccDataStats.unexpectedError++;
+		IX_ETH_ACC_FATAL_LOG(
+		    "ixEthRxFrameMultiBufferQMCallback:Error: Null Mbuf Ptr\n",
+		    0, 0, 0, 0, 0, 0);
+		return;
+	    }
+#endif
+
+	    /* convert the next entry
+	     * (the conversion function takes care about null pointers which
+	     * are used to mark the end of the loop)
+	     */
+	    nextQEntry = *(++qEntryPtr);
+	    nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry,
+			      IX_ETHNPE_QM_Q_RXENET_ADDR_MASK);
+
+	    /*
+	     * Get Port and Npe ID from message.
+	     */
+	    npeId = ((IX_ETHNPE_QM_Q_RXENET_NPEID_MASK &
+		      qEntry) >>
+		     IX_ETHNPE_QM_Q_FIELD_NPEID_R);
+	    portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
+
+	    /* skip the remaining of the loop if the frame is
+	     * to be filtered out
+	     */
+	    if (ixEthRxFrameProcess(portId, mbufPtr))
+	    {
+		/* store a mbuf pointer in an array */
+		*rxMbufPtr[portId]++ = mbufPtr;
+
+		/*
+		 * increment priority stats
+		 */
+		RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]);
+	    }
+
+	    /* test for QoS enabled in ethAcc */
+	    if (ixEthAccDataInfo.schDiscipline == FIFO_PRIORITY)
+	    {
+		/* check if there is a higher priority queue
+		 * which may require processing and then process it.
+		 */
+		if (ixEthAccDataInfo.higherPriorityQueue[qId] < IX_QMGR_MAX_NUM_QUEUES)
+		{
+		    ixEthRxMultiBufferQMCallback(ixEthAccDataInfo.higherPriorityQueue[qId],
+						 callbackId);
+		}
+	    }
+	}
+
+	/* check if any of the the arrays contains any entry */
+	for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+	{
+	    if (rxMbufPtr[portId] != rxMbufPortArray[portId])
+	    {
+		/* add a last NULL pointer at the end of the
+		 * array of mbuf pointers
+		 */
+		*rxMbufPtr[portId] = NULL;
+
+		/*
+		 * increment callback count stats
+		 */
+		RX_STATS_INC(portId,rxFrameClientCallback);
+
+		/*
+		 * Call user level callback with an array of
+		 * buffers (NULL terminated)
+		 */
+		ixEthAccPortData[portId].ixEthAccRxData.
+		    rxMultiBufferCallbackFn(
+			    ixEthAccPortData[portId].ixEthAccRxData.
+			           rxMultiBufferCallbackTag,
+			    rxMbufPortArray[portId]);
+
+		/* reset the buffer pointer to the beginning of
+		 * the array
+		 */
+		rxMbufPtr[portId] = rxMbufPortArray[portId];
+	    }
+	}
+
+    } while (rxQReadStatus == IX_SUCCESS);
+}
+
+
+/**
+ * @brief  rxFree low event handler
+ *
+ */
+void ixEthRxFreeQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
+{
+    IxEthAccPortId	portId = (IxEthAccPortId) callbackId;
+    int		        lockVal;
+    UINT32		maxQWritesToPerform = IX_ETH_ACC_MAX_RX_FREE_BUFFERS_LOAD;
+    IX_STATUS	        qStatus = IX_SUCCESS;
+
+    /*
+     * We have reached a low threshold on one of the Rx Free Qs
+     */
+
+    /*note that due to the fact that we are working off an Empty threshold, this callback
+      need only write a single entry to the Rx Free queue in order to re-arm the notification
+    */
+
+    RX_STATS_INC(portId,rxFreeLowCallback);
+
+    /*
+     * Get buffers from approprite S/W Rx freeBufferList Q.
+     */
+
+#ifndef NDEBUG
+    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+    {
+	ixEthAccDataStats.unexpectedError++;
+	IX_ETH_ACC_FATAL_LOG(
+	    "ixEthRxFreeQMCallback:Error: Invalid Port 0x%08X\n",
+	    portId, 0, 0, 0, 0, 0);
+	return;
+    }
+#endif
+    IX_ETH_ACC_DATA_PLANE_LOCK(lockVal);
+    if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId].
+					ixEthAccRxData.freeBufferList))
+    {
+	/*
+	 * Turn off Q callback notification for Q in Question.
+	 */
+	qStatus = ixQMgrNotificationDisable(
+	    IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId));
+
+
+	IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);
+
+	if (qStatus != IX_SUCCESS)
+	{
+	    RX_INC(portId,rxUnexpectedError);
+	    IX_ETH_ACC_FATAL_LOG(
+		"ixEthRxFreeQMCallback:Error: unexpected QM status 0x%08X\n",
+		qStatus, 0, 0, 0, 0, 0);
+	    return;
+	}
+    }
+    else
+    {
+	IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);
+	/*
+	 * Load the H/W Q with buffers from the s/w Q.
+	 */
+
+	do
+	{
+	    /*
+	     * Consume Q entries. - Note Q contains Physical addresss,
+	     * and have already been flushed to memory,
+	     * And endianess converted if required.
+	     */
+	    if (ixEthAccRxFreeFromSwQ(portId) != IX_SUCCESS)
+	    {
+		/*
+		 * No more entries in s/w Q.
+		 * Turn off Q callback indication
+		 */
+
+		IX_ETH_ACC_DATA_PLANE_LOCK(lockVal);
+		if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId].
+		    ixEthAccRxData.freeBufferList))
+		{
+		    qStatus = ixQMgrNotificationDisable(
+			IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId));
+		}
+		IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);
+		break;
+	    }
+	}
+	while (--maxQWritesToPerform);
+    }
+}
+/**
+ * @fn Tx queue low event handler
+ *
+ */
+void
+ixEthTxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
+{
+    IxEthAccPortId portId = (IxEthAccPortId) callbackId;
+    int		   lockVal;
+    UINT32	   maxQWritesToPerform = IX_ETH_ACC_MAX_TX_FRAME_TX_CONSUME_PER_CALLBACK;
+    IX_STATUS	   qStatus = IX_SUCCESS;
+    IxEthAccTxPriority highestPriority;
+
+
+    /*
+     * We have reached a low threshold on the Tx Q, and are being asked to
+     * supply a buffer for transmission from our S/W TX queues
+     */
+    TX_STATS_INC(portId,txLowThreshCallback);
+
+    /*
+     * Get buffers from approprite Q.
+     */
+
+#ifndef NDEBUG
+    if (!IX_ETH_ACC_IS_PORT_VALID(portId))
+    {
+	ixEthAccDataStats.unexpectedError++;
+	IX_ETH_ACC_FATAL_LOG(
+	    "ixEthTxFrameQMCallback:Error: Invalid Port 0x%08X\n",
+	    portId, 0, 0, 0, 0, 0);
+	return;
+    }
+#endif
+
+    do
+    {
+	/*
+	 * Consume Q entries. - Note Q contains Physical addresss,
+	 * and have already been flushed to memory,
+	 * and endianess already sone if required.
+	 */
+
+	IX_ETH_ACC_DATA_PLANE_LOCK(lockVal);
+
+	if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) ==
+	   IX_ETH_ACC_FAIL)
+	{
+	    /*
+	     * No more entries in s/w Q.
+	     * Turn off Q callback indication
+	     */
+	    qStatus = ixQMgrNotificationDisable(
+		IX_ETH_ACC_PORT_TO_TX_Q_ID(portId));
+
+	    IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);
+
+	    if (qStatus != IX_SUCCESS)
+	    {
+		ixEthAccDataStats.unexpectedError++;
+		IX_ETH_ACC_FATAL_LOG(
+		    "ixEthTxFrameQMCallback:Error: unexpected QM status 0x%08X\n",
+		    qStatus, 0, 0, 0, 0, 0);
+	    }
+
+	    return;
+	}
+	else
+	{
+	    IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);
+	    if (ixEthAccTxFromSwQ(portId,highestPriority)!=IX_SUCCESS)
+	    {
+                /* nothing left in the sw queue or the hw queues are
+                * full. There is no point to continue to drain the
+                * sw queues
+                */
+		return;
+	    }
+	}
+    }
+    while (--maxQWritesToPerform);
+}
+
+/**
+ * @brief TxDone event handler
+ *
+ * Design note : while processing the entry X, entry X+1 is preloaded
+ * into memory to reduce the number of stall cycles
+ *
+ */
+
+void
+ixEthTxFrameDoneQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId)
+{
+    IX_OSAL_MBUF    *mbufPtr;
+    UINT32     qEntry;
+    UINT32     *qEntryPtr;
+    UINT32     txDoneQReadStatus;
+    UINT32     portId;
+    UINT32     npeId;
+
+    /*
+     * Design note : entries are read in a static buffer, This buffer contains
+     * an extra entyry (which is zeroed by the compiler), so the loop will
+     * always terminate on a null entry, whatever the result of Burst read is.
+     */
+    static UINT32 txDoneQEntry[IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK + 1];
+
+    /*
+     * Indication that Tx frames have been transmitted from the NPE.
+     */
+
+    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.txDoneCallbackCounter);
+
+    do{
+	qEntryPtr = txDoneQEntry;
+	txDoneQReadStatus = ixQMgrQBurstRead(IX_ETH_ACC_TX_FRAME_DONE_ETH_Q,
+		     IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK,
+		     qEntryPtr);
+
+#ifndef NDEBUG
+	if (txDoneQReadStatus != IX_QMGR_Q_UNDERFLOW
+	    && (txDoneQReadStatus != IX_SUCCESS))
+	{
+	    /*major error*/
+	    ixEthAccDataStats.unexpectedError++;
+	    IX_ETH_ACC_FATAL_LOG(
+		"ixEthTxFrameDoneQMCallback:Error: %u\n",
+		(UINT32)txDoneQReadStatus, 0, 0, 0, 0, 0);
+	    return;
+	}
+#endif
+
+	qEntry = *qEntryPtr;
+
+	while(qEntry != 0)
+	{
+	    mbufPtr = ixEthAccEntryFromQConvert(qEntry,
+		      IX_ETHNPE_QM_Q_TXENET_ADDR_MASK);
+
+#ifndef NDEBUG
+	    if (mbufPtr == NULL)
+	    {
+		ixEthAccDataStats.unexpectedError++;
+		IX_ETH_ACC_FATAL_LOG(
+		    "ixEthTxFrameDoneQMCallback:Error: Null Mbuf Ptr\n",
+		    0, 0, 0, 0, 0, 0);
+		return;
+	    }
+#endif
+
+	    /* endianness conversions and stats updates */
+	    ixEthAccMbufFromTxQ(mbufPtr);
+
+	    /*
+	     * Get NPE id from message, then convert to portId.
+	     */
+	    npeId = ((IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK &
+		       qEntry) >>
+		      IX_ETHNPE_QM_Q_FIELD_NPEID_R);
+	    portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
+
+#ifndef NDEBUG
+	    /* Prudent to at least check the port is within range */
+	    if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
+	    {
+		ixEthAccDataStats.unexpectedError++;
+		IX_ETH_ACC_FATAL_LOG(
+		    "ixEthTxFrameDoneQMCallback: Illegal port: %u\n",
+		    (UINT32)portId, 0, 0, 0, 0, 0);
+		return;
+	    }
+#endif
+
+	    TX_STATS_INC(portId,txDoneClientCallback);
+
+	    /*
+	     * Call user level callback.
+	     */
+	    ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn(
+		ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag,
+		mbufPtr);
+
+	    /* move to next queue entry */
+	    qEntry = *(++qEntryPtr);
+
+	}
+    } while( txDoneQReadStatus == IX_SUCCESS );
+}
+
+IX_ETH_ACC_PUBLIC
+void ixEthAccDataPlaneShow(void)
+{
+    UINT32 numTx0Entries;
+    UINT32 numTx1Entries;
+    UINT32 numTxDoneEntries;
+    UINT32 numRxEntries;
+    UINT32 numRxFree0Entries;
+    UINT32 numRxFree1Entries;
+    UINT32 portId;
+#ifdef __ixp46X
+    UINT32 numTx2Entries;
+    UINT32 numRxFree2Entries;
+#endif
+#ifndef NDEBUG
+    UINT32 priority;
+    UINT32 numBuffersInRx=0;
+    UINT32 numBuffersInTx=0;
+    UINT32 numBuffersInSwQ=0;
+    UINT32 totalBuffers=0;
+    UINT32 rxFreeCallbackCounter = 0;
+    UINT32 txCallbackCounter = 0;
+#endif
+    UINT32 key;
+
+    /* snapshot of stats */
+    IxEthAccTxDataStats tx[IX_ETH_ACC_NUMBER_OF_PORTS];
+    IxEthAccRxDataStats rx[IX_ETH_ACC_NUMBER_OF_PORTS];
+    IxEthAccDataPlaneStats stats;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return;
+    }
+
+    /* get a reliable snapshot */
+    key = ixOsalIrqLock();
+
+    numTx0Entries = 0;
+    ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET0_Q, &numTx0Entries);
+    numTx1Entries = 0;
+    ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET1_Q, &numTx1Entries);
+    numTxDoneEntries = 0;
+    ixQMgrQNumEntriesGet( IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, &numTxDoneEntries);
+    numRxEntries = 0;
+    ixEthAccQMgrRxQEntryGet(&numRxEntries);
+    numRxFree0Entries = 0;
+    ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q, &numRxFree0Entries);
+    numRxFree1Entries = 0;
+    ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q, &numRxFree1Entries);
+
+#ifdef __ixp46X
+    numTx2Entries = 0;
+    ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET2_Q, &numTx2Entries);
+    numRxFree2Entries = 0;
+    ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q, &numRxFree2Entries);
+#endif
+
+    for(portId=IX_ETH_PORT_1; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+    {
+	memcpy(&tx[portId],
+	       &ixEthAccPortData[portId].ixEthAccTxData.stats,
+	       sizeof(tx[portId]));
+	memcpy(&rx[portId],
+	       &ixEthAccPortData[portId].ixEthAccRxData.stats,
+	       sizeof(rx[portId]));
+    }
+    memcpy(&stats, &ixEthAccDataStats, sizeof(stats));
+
+    ixOsalIrqUnlock(key);
+
+#ifdef NDEBUG
+    printf("Detailed statistics collection not supported in this load\n");
+#endif
+
+    /* print snapshot */
+    for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+    {
+        /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */
+        if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+	     (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+	    || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+        {
+                if ((IX_ETH_PORT_1 == portId) &&
+                    (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
+                     IX_FEATURE_CTRL_COMPONENT_DISABLED))
+                {
+                   continue ;
+                }
+                if ((IX_ETH_PORT_2 == portId) &&
+                    (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
+                     IX_FEATURE_CTRL_COMPONENT_DISABLED))
+                {
+                    continue ;
+                }
+                if ((IX_ETH_PORT_3 == portId) &&
+                    (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) ==
+                     IX_FEATURE_CTRL_COMPONENT_DISABLED))
+                {
+                    continue ;
+                }
+        }
+
+	printf("PORT %u --------------------------------\n",
+	       portId);
+#ifndef NDEBUG
+	printf("Tx Done Frames                : %u\n",
+	       tx[portId].txDoneClientCallback +
+	       tx[portId].txDoneSwQDuringDisable +
+	       tx[portId].txDoneDuringDisable);
+	printf("Tx Frames                     : %u\n",
+	       tx[portId].txQOK + tx[portId].txQDelayed);
+	printf("Tx H/W Q Added OK             : %u\n",
+	       tx[portId].txQOK);
+	printf("Tx H/W Q Delayed              : %u\n",
+	       tx[portId].txQDelayed);
+	printf("Tx From S/W Q Added OK        : %u\n",
+	       tx[portId].txFromSwQOK);
+	printf("Tx From S/W Q Delayed         : %u\n",
+	       tx[portId].txFromSwQDelayed);
+	printf("Tx Overflow                   : %u\n",
+	       tx[portId].txOverflow);
+	printf("Tx Mutual Lock                : %u\n",
+	       tx[portId].txLock);
+	printf("Tx Late Ntf Enabled           : %u\n",
+	       tx[portId].txLateNotificationEnabled);
+	printf("Tx Low Thresh CB              : %u\n",
+	       tx[portId].txLowThreshCallback);
+	printf("Tx Done from H/W Q (Disable)  : %u\n",
+	       tx[portId].txDoneDuringDisable);
+	printf("Tx Done from S/W Q (Disable)  : %u\n",
+	       tx[portId].txDoneSwQDuringDisable);
+	for (priority = IX_ETH_ACC_TX_PRIORITY_0;
+	     priority <= IX_ETH_ACC_TX_PRIORITY_7;
+	     priority++)
+	{
+	    if (tx[portId].txPriority[priority])
+	    {
+		printf("Tx Priority %u                 : %u\n",
+		       priority,
+		       tx[portId].txPriority[priority]);
+	    }
+	}
+#endif
+	printf("Tx unexpected errors          : %u (should be 0)\n",
+	       tx[portId].txUnexpectedError);
+
+#ifndef NDEBUG
+	printf("Rx Frames                     : %u\n",
+	       rx[portId].rxFrameClientCallback +
+	       rx[portId].rxSwQDuringDisable+
+	       rx[portId].rxDuringDisable);
+	printf("Rx Free Replenish             : %u\n",
+	       rx[portId].rxFreeRepOK + rx[portId].rxFreeRepDelayed);
+	printf("Rx Free H/W Q Added OK        : %u\n",
+	       rx[portId].rxFreeRepOK);
+	printf("Rx Free H/W Q Delayed         : %u\n",
+	       rx[portId].rxFreeRepDelayed);
+	printf("Rx Free From S/W Q Added OK   : %u\n",
+	       rx[portId].rxFreeRepFromSwQOK);
+	printf("Rx Free From S/W Q Delayed    : %u\n",
+	       rx[portId].rxFreeRepFromSwQDelayed);
+	printf("Rx Free Overflow              : %u\n",
+	       rx[portId].rxFreeOverflow);
+	printf("Rx Free Mutual Lock           : %u\n",
+	       rx[portId].rxFreeLock);
+	printf("Rx Free Late Ntf Enabled      : %u\n",
+	       rx[portId].rxFreeLateNotificationEnabled);
+	printf("Rx Free Low CB                : %u\n",
+	       rx[portId].rxFreeLowCallback);
+	printf("Rx From H/W Q (Disable)       : %u\n",
+	       rx[portId].rxDuringDisable);
+	printf("Rx From S/W Q (Disable)       : %u\n",
+	       rx[portId].rxSwQDuringDisable);
+	printf("Rx unlearned Mac Address      : %u\n",
+	       rx[portId].rxUnlearnedMacAddress);
+        printf("Rx Filtered (Rx => RxFree)    : %u\n",
+            rx[portId].rxFiltered);
+
+	for (priority = IX_ETH_ACC_TX_PRIORITY_0;
+	     priority <= IX_ETH_ACC_TX_PRIORITY_7;
+	     priority++)
+	{
+	    if (rx[portId].rxPriority[priority])
+	    {
+		printf("Rx Priority %u                 : %u\n",
+		       priority,
+		       rx[portId].rxPriority[priority]);
+	    }
+	}
+#endif
+	printf("Rx unexpected errors          : %u (should be 0)\n",
+	       rx[portId].rxUnexpectedError);
+
+#ifndef NDEBUG
+	numBuffersInTx = tx[portId].txQOK +
+	    tx[portId].txQDelayed -
+	    tx[portId].txDoneClientCallback -
+	    tx[portId].txDoneSwQDuringDisable -
+	    tx[portId].txDoneDuringDisable;
+
+	printf("# Tx Buffers currently for transmission : %u\n",
+	       numBuffersInTx);
+
+	numBuffersInRx = rx[portId].rxFreeRepOK +
+	    rx[portId].rxFreeRepDelayed -
+	    rx[portId].rxFrameClientCallback -
+	    rx[portId].rxSwQDuringDisable -
+	    rx[portId].rxDuringDisable;
+
+	printf("# Rx Buffers currently for reception    : %u\n",
+	       numBuffersInRx);
+
+	totalBuffers += numBuffersInRx + numBuffersInTx;
+#endif
+    }
+
+    printf("---------------------------------------\n");
+
+#ifndef NDEBUG
+    printf("\n");
+    printf("Mbufs :\n");
+    printf("Tx Unchained mbufs            : %u\n",
+	   stats.unchainedTxMBufs);
+    printf("Tx Chained bufs               : %u\n",
+	   stats.chainedTxMBufs);
+    printf("TxDone Unchained mbufs        : %u\n",
+	   stats.unchainedTxDoneMBufs);
+    printf("TxDone Chained bufs           : %u\n",
+	   stats.chainedTxDoneMBufs);
+    printf("RxFree Unchained mbufs        : %u\n",
+	   stats.unchainedRxFreeMBufs);
+    printf("RxFree Chained bufs           : %u\n",
+	   stats.chainedRxFreeMBufs);
+    printf("Rx Unchained mbufs            : %u\n",
+	   stats.unchainedRxMBufs);
+    printf("Rx Chained bufs               : %u\n",
+	   stats.chainedRxMBufs);
+
+    printf("\n");
+    printf("Software queue usage :\n");
+    printf("Buffers added to S/W Q        : %u\n",
+	   stats.addToSwQ);
+    printf("Buffers removed from S/W Q    : %u\n",
+	   stats.removeFromSwQ);
+
+    printf("\n");
+    printf("Hardware queues callbacks :\n");
+
+    for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+    {
+	rxFreeCallbackCounter += rx[portId].rxFreeLowCallback;
+	txCallbackCounter += tx[portId].txLowThreshCallback;
+    }
+    printf("Tx Done QM Callback invoked   : %u\n",
+	   stats.txDoneCallbackCounter);
+    printf("Tx QM Callback invoked        : %u\n",
+	   txCallbackCounter);
+    printf("Rx QM Callback invoked        : %u\n",
+	   stats.rxCallbackCounter);
+    printf("Rx QM Callback burst read     : %u\n",
+	   stats.rxCallbackBurstRead);
+    printf("Rx Free QM Callback invoked   : %u\n",
+	   rxFreeCallbackCounter);
+#endif
+    printf("Unexpected errors in CB       : %u (should be 0)\n",
+	   stats.unexpectedError);
+    printf("\n");
+
+    printf("Hardware queues levels :\n");
+    printf("Transmit Port 1 Q             : %u \n",numTx0Entries);
+    printf("Transmit Port 2 Q             : %u \n",numTx1Entries);
+#ifdef __ixp46X
+    printf("Transmit Port 3 Q             : %u \n",numTx2Entries);
+#endif
+    printf("Transmit Done Q               : %u \n",numTxDoneEntries);
+    printf("Receive Q                     : %u \n",numRxEntries);
+    printf("Receive Free Port 1 Q         : %u \n",numRxFree0Entries);
+    printf("Receive Free Port 2 Q         : %u \n",numRxFree1Entries);
+#ifdef __ixp46X
+    printf("Receive Free Port 3 Q         : %u \n",numRxFree2Entries);
+#endif
+
+#ifndef NDEBUG
+    printf("\n");
+    printf("# Total Buffers accounted for : %u\n",
+	   totalBuffers);
+
+    numBuffersInSwQ = ixEthAccDataStats.addToSwQ -
+	ixEthAccDataStats.removeFromSwQ;
+
+    printf("    Buffers in S/W Qs         : %u\n",
+	   numBuffersInSwQ);
+    printf("    Buffers in H/W Qs or NPEs : %u\n",
+	   totalBuffers - numBuffersInSwQ);
+#endif
+
+    printf("Rx QoS Discipline             : %s\n",
+	   (ixEthAccDataInfo.schDiscipline ==
+	    FIFO_PRIORITY ) ? "Enabled" : "Disabled");
+
+    for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++)
+    {
+	printf("Tx QoS Discipline port %u      : %s\n",
+	       portId,
+	       (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline ==
+		FIFO_PRIORITY ) ? "Enabled" : "Disabled");
+    }
+    printf("\n");
+}
+
+
+
+
+
diff --git a/marvell/uboot/drivers/net/npe/IxEthAccMac.c b/marvell/uboot/drivers/net/npe/IxEthAccMac.c
new file mode 100644
index 0000000..6511344
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthAccMac.c
@@ -0,0 +1,2617 @@
+/**
+ * @file IxEthAccMac.c
+ *
+ * @author Intel Corporation
+ * @date
+ *
+ * @brief  MAC control functions
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+#include "IxNpeMh.h"
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+#include "IxEthDB.h"
+#endif
+#include "IxEthDBPortDefs.h"
+#include "IxEthNpe.h"
+#include "IxEthAcc.h"
+#include "IxEthAccDataPlane_p.h"
+#include "IxEthAcc_p.h"
+#include "IxEthAccMac_p.h"
+
+/* Maximum number of retries during ixEthAccPortDisable, which
+ * is approximately 10 seconds
+*/
+#define IX_ETH_ACC_MAX_RETRY 500
+
+/* Maximum number of retries during ixEthAccPortDisable when expecting
+ * timeout
+ */
+#define IX_ETH_ACC_MAX_RETRY_TIMEOUT 5
+
+#define IX_ETH_ACC_VALIDATE_PORT_ID(portId) \
+    do                                                           \
+    {                                                            \
+        if(!IX_ETH_ACC_IS_PORT_VALID(portId))   \
+        {                                                        \
+	    return IX_ETH_ACC_INVALID_PORT;                      \
+        }                                                        \
+    } while(0)
+
+PUBLIC IxEthAccMacState ixEthAccMacState[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+PRIVATE UINT32 ixEthAccMacBase[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+/*Forward function declarations*/
+PRIVATE void
+ixEthAccPortDisableRx (IxEthAccPortId portId,
+		       IX_OSAL_MBUF * mBufPtr,
+		       BOOL useMultiBufferCallback);
+
+PRIVATE void
+ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId,
+				   IX_OSAL_MBUF * mBufPtr,
+				   BOOL useMultiBufferCallback);
+
+PRIVATE void
+ixEthAccPortDisableTxDone (UINT32 cbTag,
+			   IX_OSAL_MBUF *mbuf);
+
+PRIVATE void
+ixEthAccPortDisableTxDoneAndSubmit (UINT32 cbTag,
+				    IX_OSAL_MBUF *mbuf);
+
+PRIVATE void
+ixEthAccPortDisableRxCallback (UINT32 cbTag,
+			       IX_OSAL_MBUF * mBufPtr,
+			       UINT32 learnedPortId);
+
+PRIVATE void
+ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag,
+					  IX_OSAL_MBUF **mBufPtr);
+
+PRIVATE IxEthAccStatus
+ixEthAccPortDisableTryTransmit(UINT32 portId);
+
+PRIVATE IxEthAccStatus
+ixEthAccPortDisableTryReplenish(UINT32 portId);
+
+PRIVATE IxEthAccStatus
+ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId,
+				    IxEthAccMacAddr *macAddr);
+
+PRIVATE IxEthAccStatus
+ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId,
+				   IxEthAccMacAddr *macAddr);
+
+PRIVATE void
+ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId,
+				    IxNpeMhMessage msg);
+
+PRIVATE void
+ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId,
+					 IxNpeMhMessage msg);
+
+PRIVATE void
+ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId,
+				    IxNpeMhMessage msg);
+
+PRIVATE void
+ixEthAccMulticastAddressSet(IxEthAccPortId portId);
+
+PRIVATE BOOL
+ixEthAccMacEqual(IxEthAccMacAddr *macAddr1,
+		 IxEthAccMacAddr *macAddr2);
+
+PRIVATE void
+ixEthAccMacPrint(IxEthAccMacAddr *m);
+
+PRIVATE void
+ixEthAccMacStateUpdate(IxEthAccPortId portId);
+
+IxEthAccStatus
+ixEthAccMacMemInit(void)
+{
+    ixEthAccMacBase[IX_ETH_PORT_1] =
+	(UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE,
+				 IX_OSAL_IXP400_ETHA_MAP_SIZE);
+    ixEthAccMacBase[IX_ETH_PORT_2] =
+	(UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_1_BASE,
+				 IX_OSAL_IXP400_ETHB_MAP_SIZE);
+#ifdef __ixp46X
+    ixEthAccMacBase[IX_ETH_PORT_3] =
+	(UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_2_BASE,
+				 IX_OSAL_IXP400_ETH_NPEA_MAP_SIZE);
+    if (ixEthAccMacBase[IX_ETH_PORT_3] == 0)
+    {
+	ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
+		  IX_OSAL_LOG_DEV_STDOUT,
+		  "EthAcc: Could not map MAC I/O memory\n",
+		  0, 0, 0, 0, 0 ,0);
+
+	return IX_ETH_ACC_FAIL;
+    }
+#endif
+
+    if (ixEthAccMacBase[IX_ETH_PORT_1] == 0
+	|| ixEthAccMacBase[IX_ETH_PORT_2] == 0)
+    {
+	ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
+		  IX_OSAL_LOG_DEV_STDOUT,
+		  "EthAcc: Could not map MAC I/O memory\n",
+		  0, 0, 0, 0, 0 ,0);
+
+	return IX_ETH_ACC_FAIL;
+    }
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+void
+ixEthAccMacUnload(void)
+{
+    IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_1]);
+    IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_2]);
+#ifdef __ixp46X
+    IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_3]);
+    ixEthAccMacBase[IX_ETH_PORT_3] = 0;
+#endif
+    ixEthAccMacBase[IX_ETH_PORT_2] = 0;
+    ixEthAccMacBase[IX_ETH_PORT_1] = 0;
+}
+
+IxEthAccStatus
+ixEthAccPortEnablePriv(IxEthAccPortId portId)
+{
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+        printf("EthAcc: (Mac) cannot enable port %d, port not initialized\n", portId);
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    if (ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn == NULL)
+    {
+        /* TxDone callback not registered */
+        printf("EthAcc: (Mac) cannot enable port %d, TxDone callback not registered\n", portId);
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    if ((ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn == NULL)
+	&& (ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn == NULL))
+    {
+        /* Receive callback not registered */
+        printf("EthAcc: (Mac) cannot enable port %d, Rx callback not registered\n", portId);
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    if(!ixEthAccMacState[portId].initDone)
+    {
+        printf("EthAcc: (Mac) cannot enable port %d, MAC address not set\n", portId);
+	return (IX_ETH_ACC_MAC_UNINITIALIZED);
+    }
+
+    /* if the state is being set to what it is already at, do nothing*/
+    if (ixEthAccMacState[portId].enabled)
+    {
+        return IX_ETH_ACC_SUCCESS;
+    }
+
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+    /* enable ethernet database for this port */
+    if (ixEthDBPortEnable(portId) != IX_ETH_DB_SUCCESS)
+    {
+        printf("EthAcc: (Mac) cannot enable port %d, EthDB failure\n", portId);
+        return IX_ETH_ACC_FAIL;
+    }
+#endif
+
+    /* set the MAC core registers */
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_TX_CNTRL2,
+	      IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_RANDOM_SEED,
+	      IX_ETH_ACC_RANDOM_SEED_DEFAULT);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_THRESH_P_EMPTY,
+	      IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_THRESH_P_FULL,
+	      IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_TX_DEFER,
+	      IX_ETH_ACC_MAC_TX_DEFER_DEFAULT);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_TX_TWO_DEFER_1,
+	      IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_TX_TWO_DEFER_2,
+	      IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_SLOT_TIME,
+	      IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_INT_CLK_THRESH,
+	      IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_BUF_SIZE_TX,
+	      IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_TX_CNTRL1,
+	      IX_ETH_ACC_TX_CNTRL1_DEFAULT);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_RX_CNTRL1,
+	      IX_ETH_ACC_RX_CNTRL1_DEFAULT);
+
+    /* set the global state */
+    ixEthAccMacState[portId].portDisableState = ACTIVE;
+    ixEthAccMacState[portId].enabled = true;
+
+    /* rewrite the setup (including mac filtering) depending
+     * on current options
+     */
+    ixEthAccMacStateUpdate(portId);
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+/*
+ * PortDisable local variables. They contain the intermediate steps
+ * while the port is being disabled and the buffers being drained out
+ * of the NPE.
+ */
+typedef void (*IxEthAccPortDisableRx)(IxEthAccPortId portId,
+				      IX_OSAL_MBUF * mBufPtr,
+				      BOOL useMultiBufferCallback);
+static IxEthAccPortRxCallback
+ixEthAccPortDisableFn[IX_ETH_ACC_NUMBER_OF_PORTS];
+static IxEthAccPortMultiBufferRxCallback
+ixEthAccPortDisableMultiBufferFn[IX_ETH_ACC_NUMBER_OF_PORTS];
+static IxEthAccPortDisableRx
+ixEthAccPortDisableRxTable[IX_ETH_ACC_NUMBER_OF_PORTS];
+static UINT32
+ixEthAccPortDisableCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];
+static UINT32
+ixEthAccPortDisableMultiBufferCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+static IxEthAccPortTxDoneCallback
+ixEthAccPortDisableTxDoneFn[IX_ETH_ACC_NUMBER_OF_PORTS];
+static UINT32
+ixEthAccPortDisableTxDoneCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+static UINT32
+ixEthAccPortDisableUserBufferCount[IX_ETH_ACC_NUMBER_OF_PORTS];
+
+/*
+ * PortDisable private callbacks functions. They handle the user
+ * traffic, and the special buffers (one for tx, one for rx) used
+ * in portDisable.
+ */
+PRIVATE void
+ixEthAccPortDisableTxDone(UINT32 cbTag,
+			  IX_OSAL_MBUF *mbuf)
+{
+    IxEthAccPortId portId = (IxEthAccPortId)cbTag;
+    volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;
+
+    /* check for the special mbuf used in portDisable */
+    if (mbuf == ixEthAccMacState[portId].portDisableTxMbufPtr)
+    {
+        *txState = TRANSMIT_DONE;
+    }
+    else
+    {
+	/* increment the count of user traffic during portDisable */
+	ixEthAccPortDisableUserBufferCount[portId]++;
+
+       /* call client TxDone function */
+        ixEthAccPortDisableTxDoneFn[portId](ixEthAccPortDisableTxDoneCbTag[portId], mbuf);
+    }
+}
+
+PRIVATE IxEthAccStatus
+ixEthAccPortDisableTryTransmit(UINT32 portId)
+{
+    int key;
+    IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
+    volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;
+    /* transmit the special buffer again if it is transmitted
+     * and update the txState
+     * This section is protected because the portDisable context
+     * run an identical code, so the system keeps transmitting at the
+     * maximum rate.
+     */
+    key = ixOsalIrqLock();
+    if (*txState == TRANSMIT_DONE)
+    {
+	IX_OSAL_MBUF *mbufTxPtr = ixEthAccMacState[portId].portDisableTxMbufPtr;
+	*txState = TRANSMIT;
+	status = ixEthAccPortTxFrameSubmit(portId,
+					   mbufTxPtr,
+					   IX_ETH_ACC_TX_DEFAULT_PRIORITY);
+    }
+    ixOsalIrqUnlock(key);
+
+    return status;
+}
+
+PRIVATE void
+ixEthAccPortDisableTxDoneAndSubmit(UINT32 cbTag,
+				   IX_OSAL_MBUF *mbuf)
+{
+    IxEthAccPortId portId = (IxEthAccPortId)cbTag;
+
+    /* call the callback which forwards the traffic to the client */
+    ixEthAccPortDisableTxDone(cbTag, mbuf);
+
+    /* try to transmit the buffer used in portDisable
+     * if seen in TxDone
+     */
+    ixEthAccPortDisableTryTransmit(portId);
+}
+
+PRIVATE void
+ixEthAccPortDisableRx (IxEthAccPortId portId,
+		       IX_OSAL_MBUF * mBufPtr,
+		       BOOL useMultiBufferCallback)
+{
+    volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
+    IX_OSAL_MBUF *mNextPtr;
+
+    while (mBufPtr)
+    {
+	mNextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr);
+	IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr) = NULL;
+
+	/* check for the special mbuf used in portDisable */
+	if (mBufPtr == ixEthAccMacState[portId].portDisableRxMbufPtr)
+	{
+            *rxState = RECEIVE;
+	}
+	else
+	{
+	    /* increment the count of user traffic during portDisable */
+	    ixEthAccPortDisableUserBufferCount[portId]++;
+
+	    /* reset the received payload length during portDisable */
+	    IX_OSAL_MBUF_MLEN(mBufPtr)    = 0;
+	    IX_OSAL_MBUF_PKT_LEN(mBufPtr) = 0;
+
+	    if (useMultiBufferCallback)
+	    {
+		/* call the user callback with one unchained
+		 * buffer, without payload. A small array is built
+		 * to be used as a parameter (the user callback expects
+		 * to receive an array ended by a NULL pointer.
+		 */
+		IX_OSAL_MBUF *mBufPtrArray[2];
+
+		mBufPtrArray[0] = mBufPtr;
+		mBufPtrArray[1] = NULL;
+		ixEthAccPortDisableMultiBufferFn[portId](
+			 ixEthAccPortDisableMultiBufferCbTag[portId],
+			 mBufPtrArray);
+	    }
+	    else
+	    {
+		/* call the user callback with a unchained
+		 * buffer, without payload and the destination port is
+		 * unknown.
+		 */
+		ixEthAccPortDisableFn[portId](
+		      ixEthAccPortDisableCbTag[portId],
+		      mBufPtr,
+		      IX_ETH_DB_UNKNOWN_PORT /* port not found */);
+	    }
+        }
+
+        mBufPtr = mNextPtr;
+    }
+}
+
+PRIVATE IxEthAccStatus
+ixEthAccPortDisableTryReplenish(UINT32 portId)
+{
+    int key;
+    IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
+    volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
+    /* replenish with the special buffer again if it is received
+     * and update the rxState
+     * This section is protected because the portDisable context
+     * run an identical code, so the system keeps replenishing at the
+     * maximum rate.
+     */
+    key = ixOsalIrqLock();
+    if (*rxState == RECEIVE)
+    {
+	IX_OSAL_MBUF *mbufRxPtr = ixEthAccMacState[portId].portDisableRxMbufPtr;
+	*rxState = REPLENISH;
+	IX_OSAL_MBUF_MLEN(mbufRxPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE;
+	status = ixEthAccPortRxFreeReplenish(portId, mbufRxPtr);
+    }
+    ixOsalIrqUnlock(key);
+
+    return status;
+}
+
+PRIVATE void
+ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId,
+				   IX_OSAL_MBUF * mBufPtr,
+				   BOOL useMultiBufferCallback)
+{
+    /* call the callback which forwards the traffic to the client */
+    ixEthAccPortDisableRx(portId, mBufPtr, useMultiBufferCallback);
+
+    /* try to replenish with the buffer used in portDisable
+     * if seen in Rx
+     */
+    ixEthAccPortDisableTryReplenish(portId);
+}
+
+PRIVATE void
+ixEthAccPortDisableRxCallback (UINT32 cbTag,
+			       IX_OSAL_MBUF * mBufPtr,
+			       UINT32 learnedPortId)
+{
+    IxEthAccPortId portId = (IxEthAccPortId)cbTag;
+
+    /* call the portDisable receive callback */
+   (ixEthAccPortDisableRxTable[portId])(portId, mBufPtr, false);
+}
+
+PRIVATE void
+ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag,
+					  IX_OSAL_MBUF **mBufPtr)
+{
+    IxEthAccPortId portId = (IxEthAccPortId)cbTag;
+
+    while (*mBufPtr)
+    {
+	/* call the portDisable receive callback with one buffer at a time */
+	(ixEthAccPortDisableRxTable[portId])(portId, *mBufPtr++, true);
+    }
+}
+
+IxEthAccStatus
+ixEthAccPortDisablePriv(IxEthAccPortId portId)
+{
+    IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
+    int key;
+    int retry, retryTimeout;
+    volatile IxEthAccPortDisableState *state = &ixEthAccMacState[portId].portDisableState;
+    volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
+    volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;
+
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable port.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /* if the state is being set to what it is already at, do nothing */
+    if (!ixEthAccMacState[portId].enabled)
+    {
+        return IX_ETH_ACC_SUCCESS;
+    }
+
+    *state = DISABLED;
+
+    /* disable MAC receive first */
+    ixEthAccPortRxDisablePriv(portId);
+
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+    /* disable ethernet database for this port - It is done now to avoid
+     * issuing ELT maintenance after requesting 'port disable' in an NPE
+     */
+    if (ixEthDBPortDisable(portId) != IX_ETH_DB_SUCCESS)
+    {
+	status = IX_ETH_ACC_FAIL;
+        IX_ETH_ACC_FATAL_LOG("ixEthAccPortDisable: failed to disable EthDB for this port\n", 0, 0, 0, 0, 0, 0);
+    }
+#endif
+
+    /* enter the critical section */
+    key = ixOsalIrqLock();
+
+    /* swap the Rx and TxDone callbacks */
+    ixEthAccPortDisableFn[portId]            = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn;
+    ixEthAccPortDisableMultiBufferFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn;
+    ixEthAccPortDisableCbTag[portId]         = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag;
+    ixEthAccPortDisableMultiBufferCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag;
+    ixEthAccPortDisableTxDoneFn[portId]      = ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn;
+    ixEthAccPortDisableTxDoneCbTag[portId]   = ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag;
+    ixEthAccPortDisableRxTable[portId]       =  ixEthAccPortDisableRx;
+
+    /* register temporary callbacks */
+    ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn            = ixEthAccPortDisableRxCallback;
+    ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag           = portId;
+
+    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferRxCallback;
+    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = portId;
+
+    ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn  = ixEthAccPortDisableTxDone;
+    ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag           = portId;
+
+    /* initialise the Rx state and Tx states */
+    *txState = TRANSMIT_DONE;
+    *rxState = RECEIVE;
+
+    /* exit the critical section */
+    ixOsalIrqUnlock(key);
+
+    /* enable a NPE loopback */
+    if (ixEthAccNpeLoopbackEnablePriv(portId) != IX_ETH_ACC_SUCCESS)
+    {
+	status = IX_ETH_ACC_FAIL;
+    }
+
+    if (status == IX_ETH_ACC_SUCCESS)
+    {
+	retry = 0;
+
+	/* Step 1 : Drain Tx traffic and TxDone queues :
+	 *
+	 * Transmit and replenish at least once with the
+	 * special buffers until both of them are seen
+	 * in the callback hook
+	 *
+	 * (the receive callback keeps replenishing, so once we see
+	 * the special Tx buffer, we can be sure that Tx drain is complete)
+	 */
+	ixEthAccPortDisableRxTable[portId]
+	    =  ixEthAccPortDisableRxAndReplenish;
+	ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
+	    = ixEthAccPortDisableTxDone;
+
+	do
+	{
+	    /* keep replenishing */
+	    status = ixEthAccPortDisableTryReplenish(portId);
+	    if (status == IX_ETH_ACC_SUCCESS)
+	    {
+		/* keep transmitting */
+		status = ixEthAccPortDisableTryTransmit(portId);
+	    }
+	    if (status == IX_ETH_ACC_SUCCESS)
+	    {
+		/* wait for some traffic being processed */
+		ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
+	    }
+	}
+	while ((status == IX_ETH_ACC_SUCCESS)
+	       && (retry++ < IX_ETH_ACC_MAX_RETRY)
+	       && (*txState == TRANSMIT));
+
+	/* Step 2 : Drain Rx traffic, RxFree and Rx queues :
+	 *
+	 * Transmit and replenish at least once with the
+	 * special buffers until both of them are seen
+	 * in the callback hook
+	 * (the transmit callback keeps transmitting, and when we see
+	 * the special Rx buffer, we can be sure that rxFree drain
+	 * is complete)
+	 *
+	 * The nested loop helps to retry if the user was keeping
+	 * replenishing or transmitting during portDisable.
+	 *
+	 * The 2 nested loops ensure more retries if user traffic is
+	 * seen during portDisable : the user should not replenish
+	 * or transmit while portDisable is running. However, because of
+	 * the queueing possibilities in ethAcc dataplane, it is possible
+	 * that a lot of traffic is left in the queues (e.g. when
+	 * transmitting over a low speed link) and therefore, more
+	 * retries are allowed to help flushing the buffers out.
+	 */
+	ixEthAccPortDisableRxTable[portId]
+	    =  ixEthAccPortDisableRx;
+	ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
+	    = ixEthAccPortDisableTxDoneAndSubmit;
+
+	do
+	{
+	    do
+	    {
+		ixEthAccPortDisableUserBufferCount[portId] = 0;
+
+		/* keep replenishing */
+		status = ixEthAccPortDisableTryReplenish(portId);
+		if (status == IX_ETH_ACC_SUCCESS)
+		{
+		    /* keep transmitting */
+		    status = ixEthAccPortDisableTryTransmit(portId);
+		}
+		if (status == IX_ETH_ACC_SUCCESS)
+		{
+		    /* wait for some traffic being processed */
+		    ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
+		}
+	    }
+	    while ((status == IX_ETH_ACC_SUCCESS)
+		   && (retry++ < IX_ETH_ACC_MAX_RETRY)
+		   && ((ixEthAccPortDisableUserBufferCount[portId] != 0)
+		       || (*rxState == REPLENISH)));
+
+	    /* After the first iteration, change the receive callbacks,
+	     * to process only 1 buffer at a time
+	     */
+	    ixEthAccPortDisableRxTable[portId]
+		= ixEthAccPortDisableRx;
+	    ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
+		= ixEthAccPortDisableTxDone;
+
+	    /* repeat the whole process while user traffic is seen in TxDone
+	     *
+	     * The conditions to stop the loop are
+	     * - Xscale has both Rx and Tx special buffers
+	     *   (txState = transmit, rxState = receive)
+	     * - any error in txSubmit or rxReplenish
+	     * - no user traffic seen
+	     * - an excessive amount of retries
+	     */
+	}
+	while ((status == IX_ETH_ACC_SUCCESS)
+	       && (retry < IX_ETH_ACC_MAX_RETRY)
+	       && (*txState == TRANSMIT));
+
+	/* check the loop exit conditions. The NPE should not hold
+	 * the special buffers.
+	 */
+	if ((*rxState == REPLENISH) || (*txState == TRANSMIT))
+	{
+	    status = IX_ETH_ACC_FAIL;
+	}
+
+	if (status == IX_ETH_ACC_SUCCESS)
+	{
+	    /* Step 3 : Replenish without transmitting until a timeout
+	     * occurs, in order to drain the internal NPE fifos
+	     *
+	     * we can expect a few frames srill held
+	     * in the NPE.
+	     *
+	     * The 2 nested loops take care about the NPE dropping traffic
+	     * (including loopback traffic) when the Rx queue is full.
+	     *
+	     * The timeout value is very conservative
+	     * since the loopback used keeps replenishhing.
+	     *
+	     */
+	    do
+	    {
+		ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRxAndReplenish;
+		ixEthAccPortDisableUserBufferCount[portId] = 0;
+		retryTimeout = 0;
+		do
+		{
+		    /* keep replenishing */
+		    status = ixEthAccPortDisableTryReplenish(portId);
+		    if (status == IX_ETH_ACC_SUCCESS)
+		    {
+			/* wait for some traffic being processed */
+			ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
+		    }
+		}
+		while ((status == IX_ETH_ACC_SUCCESS)
+		       && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT));
+
+		/* Step 4 : Transmit once. Stop replenish
+		 *
+		 * After the Rx timeout, we are sure that the NPE does not
+		 * hold any frame in its internal NPE fifos.
+		 *
+		 * At this point, the NPE still holds the last rxFree buffer.
+		 * By transmitting a single frame, this should unblock the
+		 * last rxFree buffer. This code just transmit once and
+		 * wait for both frames seen in TxDone and in rxFree.
+		 *
+		 */
+		ixEthAccPortDisableRxTable[portId] =  ixEthAccPortDisableRx;
+		status = ixEthAccPortDisableTryTransmit(portId);
+
+		/* the NPE should immediatelyt release
+		 * the last Rx buffer and the last transmitted buffer
+		 * unless the last Tx frame was dropped (rx queue full)
+		 */
+		if (status == IX_ETH_ACC_SUCCESS)
+		{
+		    retryTimeout = 0;
+		    do
+		    {
+			ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
+		    }
+		    while ((*rxState == REPLENISH)
+			   && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT));
+		}
+
+		/* the NPE may have dropped the traffic because of Rx
+		 * queue being full. This code ensures that the last
+		 * Tx and Rx frames are both received.
+		 */
+	    }
+	    while ((status == IX_ETH_ACC_SUCCESS)
+		   && (retry++ < IX_ETH_ACC_MAX_RETRY)
+		   && ((*txState == TRANSMIT)
+		       || (*rxState == REPLENISH)
+		       || (ixEthAccPortDisableUserBufferCount[portId] != 0)));
+
+	    /* Step 5 : check the final states : the NPE has
+	     * no buffer left, nor in Tx , nor in Rx directions.
+	     */
+	    if ((*rxState == REPLENISH) || (*txState == TRANSMIT))
+	    {
+		status = IX_ETH_ACC_FAIL;
+	    }
+	}
+
+        /* now all the buffers are drained, disable NPE loopback
+	 * This is done regardless of the logic to drain the queues and
+	 * the internal buffers held by the NPE.
+	 */
+	if (ixEthAccNpeLoopbackDisablePriv(portId) != IX_ETH_ACC_SUCCESS)
+	{
+	    status = IX_ETH_ACC_FAIL;
+	}
+    }
+
+    /* disable MAC Tx and Rx services */
+    ixEthAccMacState[portId].enabled = false;
+    ixEthAccMacStateUpdate(portId);
+
+    /* restore the Rx and TxDone callbacks (within a critical section) */
+    key = ixOsalIrqLock();
+
+    ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn            = ixEthAccPortDisableFn[portId];
+    ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag           = ixEthAccPortDisableCbTag[portId];
+    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferFn[portId];
+    ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = ixEthAccPortDisableMultiBufferCbTag[portId];
+    ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn  = ixEthAccPortDisableTxDoneFn[portId];
+    ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag           = ixEthAccPortDisableTxDoneCbTag[portId];
+
+    ixOsalIrqUnlock(key);
+
+    /* the MAC core rx/tx disable may left the MAC hardware in an
+     * unpredictable state. A hw reset is executed before resetting
+     * all the MAC parameters to a known value.
+     */
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_CORE_CNTRL,
+	      IX_ETH_ACC_CORE_RESET);
+
+    ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);
+
+    /* rewrite all parameters to their current value */
+    ixEthAccMacStateUpdate(portId);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_INT_CLK_THRESH,
+	      IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_CORE_CNTRL,
+	      IX_ETH_ACC_CORE_MDC_EN);
+
+    return status;
+}
+
+IxEthAccStatus
+ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled)
+{
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0);
+
+        /* Since Eth NPE is not available, port must be disabled */
+        *enabled = false ;
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+        /* Since Eth NPE is not available, port must be disabled */
+        *enabled = false ;
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    *enabled = ixEthAccMacState[portId].enabled;
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortMacResetPriv(IxEthAccPortId portId)
+{
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot reset Ethernet coprocessor.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_CORE_CNTRL,
+	      IX_ETH_ACC_CORE_RESET);
+
+    ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);
+
+    /* rewrite all parameters to their current value */
+    ixEthAccMacStateUpdate(portId);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_INT_CLK_THRESH,
+	      IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_CORE_CNTRL,
+	      IX_ETH_ACC_CORE_MDC_EN);
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortLoopbackEnable(IxEthAccPortId portId)
+{
+    UINT32 regval;
+
+    /* Turn off promiscuous mode */
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable loopback.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /* read register */
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_RX_CNTRL1,
+	     regval);
+
+    /* update register */
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_RX_CNTRL1,
+	      regval | IX_ETH_ACC_RX_CNTRL1_LOOP_EN);
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+PRIVATE void
+ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId,
+				    IxNpeMhMessage msg)
+{
+    IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
+
+#ifndef NDEBUG
+    /* Prudent to at least check the port is within range */
+    if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
+    {
+	IX_ETH_ACC_FATAL_LOG("IXETHACC:ixEthAccPortDisableMessageCallback: Illegal port: %u\n",
+            (UINT32) portId, 0, 0, 0, 0, 0);
+
+	return;
+    }
+#endif
+
+    /* unlock message reception mutex */
+    ixOsalMutexUnlock(&ixEthAccMacState[portId].npeLoopbackMessageLock);
+}
+
+IxEthAccStatus
+ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId)
+{
+    IX_STATUS npeMhStatus;
+    IxNpeMhMessage message;
+    IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
+
+    /* Turn off promiscuous mode */
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /* enable NPE loopback (lsb of the message contains the value 1) */
+    message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL)
+	| 0x01;
+    message.data[1] = 0;
+
+    npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
+		message,
+		IX_ETHNPE_SETLOOPBACK_MODE_ACK,
+		ixEthAccNpeLoopbackMessageCallback,
+		IX_NPEMH_SEND_RETRIES_DEFAULT);
+
+    if (npeMhStatus != IX_SUCCESS)
+    {
+        status = IX_ETH_ACC_FAIL;
+    }
+    else
+    {
+	/* wait for NPE loopbackEnable response */
+        if (ixOsalMutexLock(&ixEthAccMacState[portId]. npeLoopbackMessageLock,
+			    IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS)
+	    != IX_SUCCESS)
+        {
+            status = IX_ETH_ACC_FAIL;
+        }
+    }
+
+    return status;
+}
+
+IxEthAccStatus
+ixEthAccPortTxEnablePriv(IxEthAccPortId portId)
+{
+    UINT32 regval;
+
+    /* Turn off promiscuous mode */
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable TX.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /* read register */
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_TX_CNTRL1,
+	     regval);
+
+    /* update register */
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_TX_CNTRL1,
+	      regval | IX_ETH_ACC_TX_CNTRL1_TX_EN);
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortRxEnablePriv(IxEthAccPortId portId)
+{
+    UINT32 regval;
+
+    /* Turn off promiscuous mode */
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable RX.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /* read register */
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_RX_CNTRL1,
+	     regval);
+
+    /* update register */
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_RX_CNTRL1,
+	      regval | IX_ETH_ACC_RX_CNTRL1_RX_EN);
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortLoopbackDisable(IxEthAccPortId portId)
+{
+    UINT32 regval;
+
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable loopback.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /*disable MAC loopabck */
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_RX_CNTRL1,
+	     regval);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_RX_CNTRL1,
+	      (regval & ~IX_ETH_ACC_RX_CNTRL1_LOOP_EN));
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId)
+{
+    IX_STATUS npeMhStatus;
+    IxNpeMhMessage message;
+    IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
+
+    /* Turn off promiscuous mode */
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /* disable NPE loopback (lsb of the message contains the value 0) */
+    message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL);
+    message.data[1] = 0;
+
+    npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
+		message,
+		IX_ETHNPE_SETLOOPBACK_MODE_ACK,
+		ixEthAccNpeLoopbackMessageCallback,
+		IX_NPEMH_SEND_RETRIES_DEFAULT);
+
+    if (npeMhStatus != IX_SUCCESS)
+    {
+        status = IX_ETH_ACC_FAIL;
+    }
+    else
+    {
+	/* wait for NPE loopbackEnable response */
+        if (ixOsalMutexLock(&ixEthAccMacState[portId].npeLoopbackMessageLock,
+			    IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS)
+	    != IX_SUCCESS)
+        {
+            status = IX_ETH_ACC_FAIL;
+        }
+    }
+
+    return status;
+}
+
+IxEthAccStatus
+ixEthAccPortTxDisablePriv(IxEthAccPortId portId)
+{
+    UINT32 regval;
+
+    /* Turn off promiscuous mode */
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable TX.\n", (INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /* read register */
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_TX_CNTRL1,
+	     regval);
+
+    /* update register */
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_TX_CNTRL1,
+	      (regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN));
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortRxDisablePriv(IxEthAccPortId portId)
+{
+    UINT32 regval;
+
+    /* Turn off promiscuous mode */
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable RX.\n", (INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /* read register */
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_RX_CNTRL1,
+	     regval);
+
+    /* update register */
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_RX_CNTRL1,
+	      (regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN));
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId)
+{
+    UINT32 regval;
+
+    /* Turn off promiscuous mode */
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear promiscuous mode.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /*set bit 5 of Rx control 1 - enable address filtering*/
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_RX_CNTRL1,
+	     regval);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_RX_CNTRL1,
+	      regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN);
+
+    ixEthAccMacState[portId].promiscuous = false;
+
+    ixEthAccMulticastAddressSet(portId);
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId)
+{
+    UINT32 regval;
+
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set promiscuous mode.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /*
+     * Set bit 5 of Rx control 1 - We enable address filtering even in
+     * promiscuous mode because we want the MAC to set the appropriate
+     * bits in m_flags which doesn't happen if we turn off filtering.
+     */
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_RX_CNTRL1,
+	     regval);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_RX_CNTRL1,
+	      regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN);
+
+    ixEthAccMacState[portId].promiscuous = true;
+
+    ixEthAccMulticastAddressSet(portId);
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortUnicastMacAddressSetPriv (IxEthAccPortId portId,
+				  IxEthAccMacAddr *macAddr)
+{
+    UINT32 i;
+
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+
+    if (macAddr == NULL)
+    {
+	return IX_ETH_ACC_FAIL;
+    }
+
+    if ( macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT )
+    {
+	/* This is a multicast/broadcast address cant set it ! */
+	return IX_ETH_ACC_FAIL;
+    }
+
+    if ( macAddr->macAddress[0] == 0 &&
+	 macAddr->macAddress[1] == 0 &&
+	 macAddr->macAddress[2] == 0 &&
+	 macAddr->macAddress[3] == 0 &&
+	 macAddr->macAddress[4] == 0 &&
+	 macAddr->macAddress[5] == 0  )
+    {
+	/* This is an invalid mac address cant set it ! */
+	return IX_ETH_ACC_FAIL;
+    }
+
+#ifdef CONFIG_IXP425_COMPONENT_ETHDB
+    /* update the MAC address in the ethernet database */
+    if (ixEthDBPortAddressSet(portId, (IxEthDBMacAddr *) macAddr) != IX_ETH_DB_SUCCESS)
+    {
+        return IX_ETH_ACC_FAIL;
+    }
+#endif
+
+    /*Set the Unicast MAC to the specified value*/
+    for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
+    {
+	REG_WRITE(ixEthAccMacBase[portId],
+		  IX_ETH_ACC_MAC_UNI_ADDR_1 + i*sizeof(UINT32),
+		  macAddr->macAddress[i]);
+    }
+    ixEthAccMacState[portId].initDone = true;
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortUnicastMacAddressGetPriv (IxEthAccPortId portId,
+				  IxEthAccMacAddr *macAddr)
+{
+    /*Return the current value of the Unicast MAC from h/w
+      for the specified port*/
+    UINT32 i;
+
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0);
+        /* Since Eth Npe is unavailable, return invalid MAC Address = 00:00:00:00:00:00 */
+        for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
+        {
+	    macAddr->macAddress[i] = 0;
+        }
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if(!ixEthAccMacState[portId].initDone)
+    {
+	return (IX_ETH_ACC_MAC_UNINITIALIZED);
+    }
+
+    if (macAddr == NULL)
+    {
+	return IX_ETH_ACC_FAIL;
+    }
+
+
+    for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
+    {
+	REG_READ(ixEthAccMacBase[portId],
+		 IX_ETH_ACC_MAC_UNI_ADDR_1 + i*sizeof(UINT32),
+		 macAddr->macAddress[i]);
+    }
+    return IX_ETH_ACC_SUCCESS;
+}
+
+PRIVATE IxEthAccStatus
+ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId,
+				    IxEthAccMacAddr *macAddr)
+{
+    /*Return the current value of the Multicast MAC from h/w
+      for the specified port*/
+    UINT32 i;
+
+    for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
+    {
+
+	REG_READ(ixEthAccMacBase[portId],
+		 IX_ETH_ACC_MAC_ADDR_1 + i*sizeof(UINT32),
+		 macAddr->macAddress[i]);
+    }
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+PRIVATE IxEthAccStatus
+ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId,
+				   IxEthAccMacAddr *macAddr)
+{
+    /*Return the current value of the Multicast MAC from h/w
+      for the specified port*/
+    UINT32 i;
+
+    for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
+    {
+
+	REG_READ(ixEthAccMacBase[portId],
+		 IX_ETH_ACC_MAC_ADDR_MASK_1 + i*sizeof(UINT32),
+		 macAddr->macAddress[i]);
+    }
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortMulticastAddressJoinPriv (IxEthAccPortId portId,
+				  IxEthAccMacAddr *macAddr)
+{
+    UINT32 i;
+    IxEthAccMacAddr broadcastAddr = {{0xff,0xff,0xff,0xff,0xff,0xff}};
+
+    /*Check that the port parameter is valid*/
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join Multicast Mac Address.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /*Check that the mac address is valid*/
+    if(macAddr == NULL)
+    {
+	return IX_ETH_ACC_FAIL;
+    }
+
+    /* Check that this is a multicast address */
+    if (!(macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT))
+    {
+	return IX_ETH_ACC_FAIL;
+    }
+
+    /* We don't add the Broadcast address */
+    if(ixEthAccMacEqual(&broadcastAddr, macAddr))
+    {
+	return IX_ETH_ACC_FAIL;
+    }
+
+    for (i = 0;
+	 i<ixEthAccMacState[portId].mcastAddrIndex;
+	 i++)
+    {
+	/*Check if the current entry already match an existing matches*/
+	if(ixEthAccMacEqual(&ixEthAccMacState[portId].mcastAddrsTable[i], macAddr))
+	{
+	    /* Address found in the list and already configured,
+	     * return a success status
+	     */
+	    return IX_ETH_ACC_SUCCESS;
+	}
+    }
+
+    /* check for availability at the end of the current table */
+    if(ixEthAccMacState[portId].mcastAddrIndex >= IX_ETH_ACC_MAX_MULTICAST_ADDRESSES)
+    {
+	return IX_ETH_ACC_FAIL;
+    }
+
+    /*First add the address to the multicast table for the
+      specified port*/
+    i=ixEthAccMacState[portId].mcastAddrIndex;
+
+    memcpy(&ixEthAccMacState[portId].mcastAddrsTable[i],
+	   &macAddr->macAddress,
+	   IX_IEEE803_MAC_ADDRESS_SIZE);
+
+    /*Increment the index into the table, this must be done here
+     as MulticastAddressSet below needs to know about the latest
+     entry.
+    */
+    ixEthAccMacState[portId].mcastAddrIndex++;
+
+    /*Then calculate the new value to be written to the address and
+      address mask registers*/
+    ixEthAccMulticastAddressSet(portId);
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+
+IxEthAccStatus
+ixEthAccPortMulticastAddressJoinAllPriv (IxEthAccPortId portId)
+{
+    IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};
+
+    /*Check that the port parameter is valid*/
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join all Multicast Address.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /* remove all entries from the database and
+    *  insert a multicast entry
+    */
+    memcpy(&ixEthAccMacState[portId].mcastAddrsTable[0],
+	   &mcastMacAddr.macAddress,
+	   IX_IEEE803_MAC_ADDRESS_SIZE);
+
+    ixEthAccMacState[portId].mcastAddrIndex = 1;
+    ixEthAccMacState[portId].joinAll = true;
+
+    ixEthAccMulticastAddressSet(portId);
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortMulticastAddressLeavePriv (IxEthAccPortId portId,
+				   IxEthAccMacAddr *macAddr)
+{
+    UINT32 i;
+    IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};
+
+    /*Check that the port parameter is valid*/
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot leave Multicast Address.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /*Check that the mac address is valid*/
+    if(macAddr == NULL)
+    {
+	return IX_ETH_ACC_FAIL;
+    }
+    /* Remove this mac address from the mask for the specified port
+     * we copy down all entries above the blanked entry, and
+     * decrement the index
+     */
+    i=0;
+
+    while(i<ixEthAccMacState[portId].mcastAddrIndex)
+    {
+	/*Check if the current entry matches*/
+	if(ixEthAccMacEqual(&ixEthAccMacState[portId].mcastAddrsTable[i],
+			    macAddr))
+	{
+	    if(ixEthAccMacEqual(macAddr, &mcastMacAddr))
+	    {
+		ixEthAccMacState[portId].joinAll = false;
+	    }
+	    /*Decrement the index into the multicast address table
+	      for the current port*/
+	    ixEthAccMacState[portId].mcastAddrIndex--;
+
+	    /*Copy down all entries above the current entry*/
+	    while(i<ixEthAccMacState[portId].mcastAddrIndex)
+	    {
+		memcpy(&ixEthAccMacState[portId].mcastAddrsTable[i],
+		       &ixEthAccMacState[portId].mcastAddrsTable[i+1],
+		       IX_IEEE803_MAC_ADDRESS_SIZE);
+                i++;
+	    }
+	    /*recalculate the mask and write it to the MAC*/
+	    ixEthAccMulticastAddressSet(portId);
+
+	    return IX_ETH_ACC_SUCCESS;
+	}
+	/* search the next entry */
+	i++;
+    }
+    /* no matching entry found */
+    return IX_ETH_ACC_NO_SUCH_ADDR;
+}
+
+IxEthAccStatus
+ixEthAccPortMulticastAddressLeaveAllPriv (IxEthAccPortId portId)
+{
+    /*Check that the port parameter is valid*/
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot leave all Multicast Address.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    ixEthAccMacState[portId].mcastAddrIndex = 0;
+    ixEthAccMacState[portId].joinAll = false;
+
+    ixEthAccMulticastAddressSet(portId);
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+
+IxEthAccStatus
+ixEthAccPortUnicastAddressShowPriv (IxEthAccPortId portId)
+{
+    IxEthAccMacAddr macAddr;
+
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot show Unicast Address.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    /*Get the MAC (UINICAST) address from hardware*/
+    if(ixEthAccPortUnicastMacAddressGetPriv(portId, &macAddr) != IX_ETH_ACC_SUCCESS)
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: MAC address uninitialised port %u\n",
+			       (INT32)portId,0,0,0,0,0);
+	return IX_ETH_ACC_MAC_UNINITIALIZED;
+    }
+
+    /*print it out*/
+    ixEthAccMacPrint(&macAddr);
+    printf("\n");
+    return IX_ETH_ACC_SUCCESS;
+}
+
+
+
+void
+ixEthAccPortMulticastAddressShowPriv(IxEthAccPortId portId)
+{
+    IxEthAccMacAddr macAddr;
+    UINT32 i;
+
+    if(!IX_ETH_ACC_IS_PORT_VALID(portId))
+    {
+        return;
+    }
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot show Multicast Address.\n",(INT32)portId,0,0,0,0,0);
+        return ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return;
+    }
+
+    printf("Multicast MAC: ");
+    /*Get the MAC (MULTICAST) address from hardware*/
+    ixEthAccPortMulticastMacAddressGet(portId, &macAddr);
+    /*print it out*/
+    ixEthAccMacPrint(&macAddr);
+    /*Get the MAC (MULTICAST) filter from hardware*/
+    ixEthAccPortMulticastMacFilterGet(portId, &macAddr);
+    /*print it out*/
+    printf(" ( ");
+    ixEthAccMacPrint(&macAddr);
+    printf(" )\n");
+    printf("Constituent Addresses:\n");
+    for(i=0;i<ixEthAccMacState[portId].mcastAddrIndex;i++)
+    {
+	ixEthAccMacPrint(&ixEthAccMacState[portId].mcastAddrsTable[i]);
+	printf("\n");
+    }
+    return;
+}
+
+/*Set the duplex mode*/
+IxEthAccStatus
+ixEthAccPortDuplexModeSetPriv (IxEthAccPortId portId,
+			   IxEthAccDuplexMode mode)
+{
+    UINT32 txregval;
+    UINT32 rxregval;
+
+    /*This is bit 1 of the transmit control reg, set to 1 for half
+      duplex, 0 for full duplex*/
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set Duplex Mode.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_TX_CNTRL1,
+	     txregval);
+
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_RX_CNTRL1,
+	     rxregval);
+
+    if (mode ==  IX_ETH_ACC_FULL_DUPLEX)
+    {
+	/*Clear half duplex bit in TX*/
+	REG_WRITE(ixEthAccMacBase[portId],
+		  IX_ETH_ACC_MAC_TX_CNTRL1,
+		  txregval & ~IX_ETH_ACC_TX_CNTRL1_DUPLEX);
+
+	/*We must set the pause enable in the receive logic when in
+	  full duplex mode*/
+	REG_WRITE(ixEthAccMacBase[portId],
+		  IX_ETH_ACC_MAC_RX_CNTRL1,
+		  rxregval | IX_ETH_ACC_RX_CNTRL1_PAUSE_EN);
+	ixEthAccMacState[portId].fullDuplex = true;
+
+    }
+    else if (mode ==  IX_ETH_ACC_HALF_DUPLEX)
+    {
+	/*Set half duplex bit in TX*/
+	REG_WRITE(ixEthAccMacBase[portId],
+		  IX_ETH_ACC_MAC_TX_CNTRL1,
+		  txregval | IX_ETH_ACC_TX_CNTRL1_DUPLEX);
+
+	/*We must clear pause enable in the receive logic when in
+	  half duplex mode*/
+	REG_WRITE(ixEthAccMacBase[portId],
+		  IX_ETH_ACC_MAC_RX_CNTRL1,
+		  rxregval & ~IX_ETH_ACC_RX_CNTRL1_PAUSE_EN);
+
+	ixEthAccMacState[portId].fullDuplex = false;
+    }
+    else
+    {
+	return IX_ETH_ACC_FAIL;
+    }
+
+
+    return IX_ETH_ACC_SUCCESS;
+
+}
+
+
+
+IxEthAccStatus
+ixEthAccPortDuplexModeGetPriv (IxEthAccPortId portId,
+			   IxEthAccDuplexMode *mode)
+{
+    /*Return the duplex mode for the specified port*/
+    UINT32 regval;
+
+    /*This is bit 1 of the transmit control reg, set to 1 for half
+      duplex, 0 for full duplex*/
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get Duplex Mode.\n",(INT32)portId,0,0,0,0,0);
+        /* return hald duplex */
+        *mode = IX_ETH_ACC_HALF_DUPLEX ;
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    if (mode == NULL)
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_TX_CNTRL1,
+	     regval);
+
+    if( regval & IX_ETH_ACC_TX_CNTRL1_DUPLEX)
+    {
+	*mode = IX_ETH_ACC_HALF_DUPLEX;
+    }
+    else
+    {
+	*mode = IX_ETH_ACC_FULL_DUPLEX;
+    }
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+
+
+IxEthAccStatus
+ixEthAccPortTxFrameAppendPaddingEnablePriv (IxEthAccPortId portId)
+{
+    UINT32 regval;
+    /*Enable FCS computation by the MAC and appending to the
+      frame*/
+
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Tx Frame Append Padding.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_TX_CNTRL1,
+	     regval);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_TX_CNTRL1,
+	      regval |
+	      IX_ETH_ACC_TX_CNTRL1_PAD_EN);
+
+    ixEthAccMacState[portId].txPADAppend = true;
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortTxFrameAppendPaddingDisablePriv (IxEthAccPortId portId)
+{
+    UINT32 regval;
+
+    /*disable FCS computation and appending*/
+    /*Set bit 4 of Tx control register one to zero*/
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disble Tx Frame Append Padding.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_TX_CNTRL1,
+	     regval);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_TX_CNTRL1,
+	      regval & ~IX_ETH_ACC_TX_CNTRL1_PAD_EN);
+
+    ixEthAccMacState[portId].txPADAppend = false;
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortTxFrameAppendFCSEnablePriv (IxEthAccPortId portId)
+{
+    UINT32 regval;
+
+    /*Enable FCS computation by the MAC and appending to the
+      frame*/
+
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Tx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_TX_CNTRL1,
+	     regval);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_TX_CNTRL1,
+	      regval | IX_ETH_ACC_TX_CNTRL1_FCS_EN);
+
+    ixEthAccMacState[portId].txFCSAppend = true;
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortTxFrameAppendFCSDisablePriv (IxEthAccPortId portId)
+{
+    UINT32 regval;
+
+    /*disable FCS computation and appending*/
+    /*Set bit 4 of Tx control register one to zero*/
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable Tx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_TX_CNTRL1,
+	     regval);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_TX_CNTRL1,
+	      regval & ~IX_ETH_ACC_TX_CNTRL1_FCS_EN);
+
+    ixEthAccMacState[portId].txFCSAppend = false;
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortRxFrameAppendFCSEnablePriv (IxEthAccPortId portId)
+{
+    /*Set bit 2 of Rx control 1*/
+    UINT32 regval;
+
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Rx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_RX_CNTRL1,
+	     regval);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_RX_CNTRL1,
+	      regval | IX_ETH_ACC_RX_CNTRL1_CRC_EN);
+
+    ixEthAccMacState[portId].rxFCSAppend = true;
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccPortRxFrameAppendFCSDisablePriv (IxEthAccPortId portId)
+{
+    UINT32 regval;
+
+    /*Clear bit 2 of Rx control 1*/
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable Rx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    REG_READ(ixEthAccMacBase[portId],
+	     IX_ETH_ACC_MAC_RX_CNTRL1,
+	     regval);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_RX_CNTRL1,
+	      regval & ~IX_ETH_ACC_RX_CNTRL1_CRC_EN);
+
+    ixEthAccMacState[portId].rxFCSAppend = false;
+    return IX_ETH_ACC_SUCCESS;
+}
+
+
+
+PRIVATE void
+ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId,
+				    IxNpeMhMessage msg)
+{
+    IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
+
+#ifndef NDEBUG
+    /* Prudent to at least check the port is within range */
+    if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
+    {
+	IX_ETH_ACC_FATAL_LOG(
+     "IXETHACC:ixEthAccMacNpeStatsMessageCallback: Illegal port: %u\n",
+     (UINT32)portId, 0, 0, 0, 0, 0);
+	return;
+    }
+#endif
+
+    /*Unblock Stats Get call*/
+    ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsLock);
+
+}
+
+PRIVATE void
+ixEthAccMibIIStatsEndianConvert (IxEthEthObjStats *retStats)
+{
+    /* endianness conversion */
+
+    /* Rx stats */
+    retStats->dot3StatsAlignmentErrors =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsAlignmentErrors);
+    retStats->dot3StatsFCSErrors =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsFCSErrors);
+    retStats->dot3StatsInternalMacReceiveErrors =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacReceiveErrors);
+    retStats->RxOverrunDiscards =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxOverrunDiscards);
+    retStats->RxLearnedEntryDiscards =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLearnedEntryDiscards);
+    retStats->RxLargeFramesDiscards =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLargeFramesDiscards);
+    retStats->RxSTPBlockedDiscards =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxSTPBlockedDiscards);
+    retStats->RxVLANTypeFilterDiscards =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANTypeFilterDiscards);
+    retStats->RxVLANIdFilterDiscards =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANIdFilterDiscards);
+    retStats->RxInvalidSourceDiscards =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxInvalidSourceDiscards);
+    retStats->RxBlackListDiscards =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxBlackListDiscards);
+    retStats->RxWhiteListDiscards =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxWhiteListDiscards);
+    retStats->RxUnderflowEntryDiscards =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxUnderflowEntryDiscards);
+
+    /* Tx stats */
+    retStats->dot3StatsSingleCollisionFrames =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsSingleCollisionFrames);
+    retStats->dot3StatsMultipleCollisionFrames =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsMultipleCollisionFrames);
+    retStats->dot3StatsDeferredTransmissions =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsDeferredTransmissions);
+    retStats->dot3StatsLateCollisions =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsLateCollisions);
+    retStats->dot3StatsExcessiveCollsions =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsExcessiveCollsions);
+    retStats->dot3StatsInternalMacTransmitErrors =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacTransmitErrors);
+    retStats->dot3StatsCarrierSenseErrors =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsCarrierSenseErrors);
+    retStats->TxLargeFrameDiscards =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxLargeFrameDiscards);
+    retStats->TxVLANIdFilterDiscards =
+	IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxVLANIdFilterDiscards);
+}
+
+IxEthAccStatus
+ixEthAccMibIIStatsGet (IxEthAccPortId portId,
+		       IxEthEthObjStats *retStats )
+{
+    IxNpeMhMessage message;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+        printf("EthAcc: ixEthAccMibIIStatsGet (Mac) EthAcc service is not initialized\n");
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (retStats == NULL)
+    {
+        printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NULL argument\n");
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NPE for port %d is not available\n", portId);
+
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get MIB II Stats.\n",(INT32)portId,0,0,0,0,0);
+
+        /* Return all zero stats */
+        IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats));
+
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+        printf("EthAcc: ixEthAccMibIIStatsGet (Mac) port %d is not initialized\n", portId);
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats));
+
+    message.data[0] = IX_ETHNPE_GETSTATS << IX_ETH_ACC_MAC_MSGID_SHL;
+    message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats);
+
+    /* Permit only one task to request MIB statistics Get operation
+       at a time */
+    ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetAccessLock, IX_OSAL_WAIT_FOREVER);
+
+    if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
+				      message,
+				      IX_ETHNPE_GETSTATS,
+				      ixEthAccMacNpeStatsMessageCallback,
+				      IX_NPEMH_SEND_RETRIES_DEFAULT)
+       != IX_SUCCESS)
+    {
+	ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock);
+
+        printf("EthAcc: (Mac) StatsGet failed to send NPE message\n");
+
+	return IX_ETH_ACC_FAIL;
+    }
+
+    /* Wait for callback invocation indicating response to
+       this request - we need this mutex in order to ensure
+       that the return from this function is synchronous */
+    ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS);
+
+    /* Permit other tasks to perform MIB statistics Get operation */
+    ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock);
+
+    ixEthAccMibIIStatsEndianConvert (retStats);
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+
+PRIVATE void
+ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId,
+					 IxNpeMhMessage msg)
+{
+    IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
+
+#ifndef NDEBUG
+    /* Prudent to at least check the port is within range */
+    if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
+    {
+	IX_ETH_ACC_FATAL_LOG(
+     "IXETHACC:ixEthAccMacNpeStatsResetMessageCallback: Illegal port: %u\n",
+     (UINT32)portId, 0, 0, 0, 0, 0);
+	return;
+    }
+#endif
+
+    /*Unblock Stats Get & reset call*/
+    ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsResetLock);
+
+}
+
+
+
+IxEthAccStatus
+ixEthAccMibIIStatsGetClear (IxEthAccPortId portId,
+			    IxEthEthObjStats *retStats)
+{
+    IxNpeMhMessage message;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+        printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) EthAcc service is not initialized\n");
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (retStats == NULL)
+    {
+        printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NULL argument\n");
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NPE for port %d is not available\n", portId);
+
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get and clear MIB II Stats.\n", (INT32)portId, 0, 0, 0, 0, 0);
+
+        /* Return all zero stats */
+        IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats));
+
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
+    {
+        printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) port %d is not initialized\n", portId);
+	return (IX_ETH_ACC_PORT_UNINITIALIZED);
+    }
+
+    IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats));
+
+    message.data[0] = IX_ETHNPE_RESETSTATS << IX_ETH_ACC_MAC_MSGID_SHL;
+    message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats);
+
+    /* Permit only one task to request MIB statistics Get-Reset operation at a time */
+    ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock, IX_OSAL_WAIT_FOREVER);
+
+    if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
+				      message,
+				      IX_ETHNPE_RESETSTATS,
+				      ixEthAccMacNpeStatsResetMessageCallback,
+				      IX_NPEMH_SEND_RETRIES_DEFAULT)
+       != IX_SUCCESS)
+    {
+	ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);
+
+        printf("EthAcc: (Mac) ixEthAccMibIIStatsGetClear failed to send NPE message\n");
+
+	return IX_ETH_ACC_FAIL;
+    }
+
+    /* Wait for callback invocation indicating response to this request */
+    ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS);
+
+    /* permit other tasks to get and reset MIB stats*/
+    ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);
+
+    ixEthAccMibIIStatsEndianConvert(retStats);
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+IxEthAccStatus
+ixEthAccMibIIStatsClear (IxEthAccPortId portId)
+{
+    static IxEthEthObjStats retStats;
+    IxEthAccStatus status;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear MIB II Stats.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    /* there is no reset operation without a corresponding Get */
+    status = ixEthAccMibIIStatsGetClear(portId, &retStats);
+
+    return status;
+}
+
+/* Initialize the ethernet MAC settings */
+IxEthAccStatus
+ixEthAccMacInit(IxEthAccPortId portId)
+{
+    IX_OSAL_MBUF_POOL* portDisablePool;
+    UINT8 *data;
+
+    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
+
+    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
+    {
+        IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Mac.\n",(INT32)portId,0,0,0,0,0);
+        return IX_ETH_ACC_SUCCESS ;
+    }
+
+    if(ixEthAccMacState[portId].macInitialised == false)
+    {
+	ixEthAccMacState[portId].fullDuplex  = true;
+	ixEthAccMacState[portId].rxFCSAppend = true;
+	ixEthAccMacState[portId].txFCSAppend = true;
+	ixEthAccMacState[portId].txPADAppend = true;
+	ixEthAccMacState[portId].enabled     = false;
+	ixEthAccMacState[portId].promiscuous = true;
+	ixEthAccMacState[portId].joinAll     = false;
+	ixEthAccMacState[portId].initDone    = false;
+	ixEthAccMacState[portId].macInitialised = true;
+
+        /* initialize MIB stats mutexes */
+        ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsLock);
+        ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_OSAL_WAIT_FOREVER);
+
+        ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsResetLock);
+        ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_OSAL_WAIT_FOREVER);
+
+        ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetAccessLock);
+
+        ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);
+
+        ixOsalMutexInit(&ixEthAccMacState[portId].npeLoopbackMessageLock);
+
+	ixEthAccMacState[portId].portDisableRxMbufPtr = NULL;
+        ixEthAccMacState[portId].portDisableTxMbufPtr = NULL;
+
+	portDisablePool = IX_OSAL_MBUF_POOL_INIT(2,
+			  IX_ETHACC_RX_MBUF_MIN_SIZE,
+			  "portDisable Pool");
+
+        IX_OSAL_ENSURE(portDisablePool != NULL, "Failed to initialize PortDisable pool");
+
+	ixEthAccMacState[portId].portDisableRxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool);
+        ixEthAccMacState[portId].portDisableTxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool);
+
+	IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableRxMbufPtr != NULL,
+		  "Pool allocation failed");
+        IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableTxMbufPtr != NULL,
+		  "Pool allocation failed");
+	/* fill the payload of the Rx mbuf used in portDisable */
+        IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableRxMbufPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE;
+
+        memset(IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableRxMbufPtr),
+	       0xAA,
+	       IX_ETHACC_RX_MBUF_MIN_SIZE);
+
+	/* fill the payload of the Tx mbuf used in portDisable (64 bytes) */
+        IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64;
+        IX_OSAL_MBUF_PKT_LEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64;
+
+        data = (UINT8 *) IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableTxMbufPtr);
+        memset(data, 0xBB, 64);
+        data[0] = 0x00; /* unicast destination MAC address */
+        data[6] = 0x00; /* unicast source MAC address */
+        data[12] = 0x08; /* typelength : IP frame */
+        data[13] = 0x00; /* typelength : IP frame */
+
+	IX_OSAL_CACHE_FLUSH(data, 64);
+    }
+
+    IX_OSAL_ASSERT (ixEthAccMacBase[portId] != 0);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_CORE_CNTRL,
+	      IX_ETH_ACC_CORE_RESET);
+
+    ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_CORE_CNTRL,
+	      IX_ETH_ACC_CORE_MDC_EN);
+
+    REG_WRITE(ixEthAccMacBase[portId],
+	      IX_ETH_ACC_MAC_INT_CLK_THRESH,
+	      IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
+
+    ixEthAccMacStateUpdate(portId);
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+/* PRIVATE Functions*/
+
+PRIVATE void
+ixEthAccMacStateUpdate(IxEthAccPortId portId)
+{
+    UINT32 regval;
+
+    if ( ixEthAccMacState[portId].enabled == false )
+    {
+	/*  Just disable both the transmitter and reciver in the MAC.  */
+        REG_READ(ixEthAccMacBase[portId],
+		 IX_ETH_ACC_MAC_RX_CNTRL1,
+		 regval);
+	REG_WRITE(ixEthAccMacBase[portId],
+		  IX_ETH_ACC_MAC_RX_CNTRL1,
+		  regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN);
+
+        REG_READ(ixEthAccMacBase[portId],
+		 IX_ETH_ACC_MAC_TX_CNTRL1,
+		 regval);
+	REG_WRITE(ixEthAccMacBase[portId],
+		  IX_ETH_ACC_MAC_TX_CNTRL1,
+		  regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN);
+    }
+
+    if(ixEthAccMacState[portId].fullDuplex)
+    {
+	ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_FULL_DUPLEX);
+    }
+    else
+    {
+	ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_HALF_DUPLEX);
+    }
+
+    if(ixEthAccMacState[portId].rxFCSAppend)
+    {
+	ixEthAccPortRxFrameAppendFCSEnablePriv (portId);
+    }
+    else
+    {
+	ixEthAccPortRxFrameAppendFCSDisablePriv (portId);
+    }
+
+    if(ixEthAccMacState[portId].txFCSAppend)
+    {
+	ixEthAccPortTxFrameAppendFCSEnablePriv (portId);
+    }
+    else
+    {
+	ixEthAccPortTxFrameAppendFCSDisablePriv (portId);
+    }
+
+    if(ixEthAccMacState[portId].txPADAppend)
+    {
+	ixEthAccPortTxFrameAppendPaddingEnablePriv (portId);
+    }
+    else
+    {
+	ixEthAccPortTxFrameAppendPaddingDisablePriv (portId);
+    }
+
+    if(ixEthAccMacState[portId].promiscuous)
+    {
+	ixEthAccPortPromiscuousModeSetPriv(portId);
+    }
+    else
+    {
+	ixEthAccPortPromiscuousModeClearPriv(portId);
+    }
+
+    if ( ixEthAccMacState[portId].enabled == true )
+    {
+        /*   Enable both the transmitter and reciver in the MAC.  */
+        REG_READ(ixEthAccMacBase[portId],
+		 IX_ETH_ACC_MAC_RX_CNTRL1,
+		 regval);
+        REG_WRITE(ixEthAccMacBase[portId],
+		  IX_ETH_ACC_MAC_RX_CNTRL1,
+		  regval | IX_ETH_ACC_RX_CNTRL1_RX_EN);
+
+        REG_READ(ixEthAccMacBase[portId],
+		 IX_ETH_ACC_MAC_TX_CNTRL1,
+		 regval);
+	REG_WRITE(ixEthAccMacBase[portId],
+		  IX_ETH_ACC_MAC_TX_CNTRL1,
+		  regval | IX_ETH_ACC_TX_CNTRL1_TX_EN);
+    }
+}
+
+
+PRIVATE BOOL
+ixEthAccMacEqual(IxEthAccMacAddr *macAddr1,
+		 IxEthAccMacAddr *macAddr2)
+{
+    UINT32 i;
+    for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE; i++)
+    {
+	if(macAddr1->macAddress[i] != macAddr2->macAddress[i])
+	{
+	    return false;
+	}
+    }
+    return true;
+}
+
+PRIVATE void
+ixEthAccMacPrint(IxEthAccMacAddr *m)
+{
+    printf("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
+	   m->macAddress[0], m->macAddress[1],
+	   m->macAddress[2], m->macAddress[3],
+	   m->macAddress[4], m->macAddress[5]);
+}
+
+/* Set the multicast address and address mask registers
+ *
+ * A bit in the address mask register must be set if
+ * all multicast addresses always have that bit set, or if
+ * all multicast addresses always have that bit cleared.
+ *
+ * A bit in the address register must be set if all multicast
+ * addresses have that bit set, otherwise, it should be cleared
+ */
+
+PRIVATE void
+ixEthAccMulticastAddressSet(IxEthAccPortId portId)
+{
+    UINT32 i;
+    UINT32 j;
+    IxEthAccMacAddr addressMask;
+    IxEthAccMacAddr address;
+    IxEthAccMacAddr alwaysClearBits;
+    IxEthAccMacAddr alwaysSetBits;
+
+    /* calculate alwaysClearBits and alwaysSetBits:
+     * alwaysClearBits is calculated by ORing all
+     * multicast addresses, those bits that are always
+     * clear are clear in the result
+     *
+     * alwaysSetBits is calculated by ANDing all
+     * multicast addresses, those bits that are always set
+     * are set in the result
+     */
+
+    if (ixEthAccMacState[portId].promiscuous == true)
+    {
+	/* Promiscuous Mode is set, and filtering
+	 * allow all packets, and enable the mcast and
+	 * bcast detection.
+	 */
+	memset(&addressMask.macAddress,
+	       0,
+	       IX_IEEE803_MAC_ADDRESS_SIZE);
+	memset(&address.macAddress,
+	       0,
+	       IX_IEEE803_MAC_ADDRESS_SIZE);
+    }
+    else
+    {
+	if(ixEthAccMacState[portId].joinAll == true)
+	{
+	    /* Join all is set. The mask and address are
+	     * the multicast settings.
+	     */
+	    IxEthAccMacAddr macAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};
+
+	    memcpy(addressMask.macAddress,
+		   macAddr.macAddress,
+		   IX_IEEE803_MAC_ADDRESS_SIZE);
+	    memcpy(address.macAddress,
+		   macAddr.macAddress,
+		   IX_IEEE803_MAC_ADDRESS_SIZE);
+	}
+	else if(ixEthAccMacState[portId].mcastAddrIndex == 0)
+	{
+	    /* No entry in the filtering database,
+	     * Promiscuous Mode is cleared, Broadcast filtering
+	     * is configured.
+	     */
+	    memset(addressMask.macAddress,
+		   IX_ETH_ACC_MAC_ALL_BITS_SET,
+		   IX_IEEE803_MAC_ADDRESS_SIZE);
+	    memset(address.macAddress,
+		   IX_ETH_ACC_MAC_ALL_BITS_SET,
+		   IX_IEEE803_MAC_ADDRESS_SIZE);
+	}
+	else
+	{
+	    /* build a mask and an address which mix all entreis
+	     * from the list of multicast addresses
+	     */
+	    memset(alwaysClearBits.macAddress,
+		   0,
+		   IX_IEEE803_MAC_ADDRESS_SIZE);
+	    memset(alwaysSetBits.macAddress,
+		   IX_ETH_ACC_MAC_ALL_BITS_SET,
+		   IX_IEEE803_MAC_ADDRESS_SIZE);
+
+	    for(i=0;i<ixEthAccMacState[portId].mcastAddrIndex;i++)
+	    {
+		for(j=0;j<IX_IEEE803_MAC_ADDRESS_SIZE;j++)
+		{
+		    alwaysClearBits.macAddress[j] |=
+			ixEthAccMacState[portId].mcastAddrsTable[i].macAddress[j];
+		    alwaysSetBits.macAddress[j] &=
+			ixEthAccMacState[portId].mcastAddrsTable[i].macAddress[j];
+		}
+	    }
+
+	    for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
+	    {
+		addressMask.macAddress[i] = alwaysSetBits.macAddress[i]
+		    | ~alwaysClearBits.macAddress[i];
+		address.macAddress[i] = alwaysSetBits.macAddress[i];
+	    }
+	}
+    }
+
+    /*write the new addr filtering to h/w*/
+    for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
+    {
+	REG_WRITE(ixEthAccMacBase[portId],
+		  IX_ETH_ACC_MAC_ADDR_MASK_1+i*sizeof(UINT32),
+		  addressMask.macAddress[i]);
+	REG_WRITE(ixEthAccMacBase[portId],
+		  IX_ETH_ACC_MAC_ADDR_1+i*sizeof(UINT32),
+		  address.macAddress[i]);
+    }
+}
diff --git a/marvell/uboot/drivers/net/npe/IxEthAccMii.c b/marvell/uboot/drivers/net/npe/IxEthAccMii.c
new file mode 100644
index 0000000..bfe606f
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthAccMii.c
@@ -0,0 +1,386 @@
+/**
+ * @file IxEthAccMii.c
+ *
+ * @author Intel Corporation
+ * @date 
+ *
+ * @brief  MII control functions
+ *
+ * Design Notes:
+ *
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+#include "IxEthAcc.h"
+#include "IxEthAcc_p.h"
+#include "IxEthAccMac_p.h"
+#include "IxEthAccMii_p.h"
+
+
+PRIVATE UINT32 miiBaseAddressVirt;
+PRIVATE IxOsalMutex miiAccessLock;
+
+PUBLIC UINT32 ixEthAccMiiRetryCount    = IX_ETH_ACC_MII_TIMEOUT_10TH_SECS;
+PUBLIC UINT32 ixEthAccMiiAccessTimeout = IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS;
+
+/* -----------------------------------
+ * private function prototypes
+ */
+PRIVATE void
+ixEthAccMdioCmdWrite(UINT32 mdioCommand);
+
+PRIVATE void
+ixEthAccMdioCmdRead(UINT32 *data);
+
+PRIVATE void
+ixEthAccMdioStatusRead(UINT32 *data);
+
+
+PRIVATE void
+ixEthAccMdioCmdWrite(UINT32 mdioCommand)
+{
+    REG_WRITE(miiBaseAddressVirt,
+	      IX_ETH_ACC_MAC_MDIO_CMD_1,
+	      mdioCommand & 0xff);
+
+    REG_WRITE(miiBaseAddressVirt,
+	      IX_ETH_ACC_MAC_MDIO_CMD_2,
+	      (mdioCommand >> 8) & 0xff);
+
+    REG_WRITE(miiBaseAddressVirt,
+	      IX_ETH_ACC_MAC_MDIO_CMD_3,
+	      (mdioCommand >> 16) & 0xff);
+
+    REG_WRITE(miiBaseAddressVirt,
+	      IX_ETH_ACC_MAC_MDIO_CMD_4,
+	      (mdioCommand >> 24) & 0xff);
+}
+
+PRIVATE void
+ixEthAccMdioCmdRead(UINT32 *data)
+{
+    UINT32 regval;
+
+    REG_READ(miiBaseAddressVirt,
+	     IX_ETH_ACC_MAC_MDIO_CMD_1,
+	     regval);
+
+    *data = regval & 0xff;
+
+    REG_READ(miiBaseAddressVirt,
+	     IX_ETH_ACC_MAC_MDIO_CMD_2,
+	     regval);
+
+    *data |= (regval & 0xff) << 8;
+
+    REG_READ(miiBaseAddressVirt,
+	     IX_ETH_ACC_MAC_MDIO_CMD_3,
+	     regval);
+
+    *data |= (regval & 0xff) << 16;
+
+    REG_READ(miiBaseAddressVirt,
+	     IX_ETH_ACC_MAC_MDIO_CMD_4,
+	     regval);
+
+    *data |= (regval & 0xff) << 24;
+
+}
+
+PRIVATE void
+ixEthAccMdioStatusRead(UINT32 *data)
+{
+    UINT32 regval;
+
+    REG_READ(miiBaseAddressVirt,
+	     IX_ETH_ACC_MAC_MDIO_STS_1,
+	     regval);
+
+    *data = regval & 0xff;
+
+    REG_READ(miiBaseAddressVirt,
+	     IX_ETH_ACC_MAC_MDIO_STS_2,
+	     regval);
+
+    *data |= (regval & 0xff) << 8;
+
+    REG_READ(miiBaseAddressVirt,
+	     IX_ETH_ACC_MAC_MDIO_STS_3,
+	     regval);
+
+    *data |= (regval & 0xff) << 16;
+
+    REG_READ(miiBaseAddressVirt,
+	     IX_ETH_ACC_MAC_MDIO_STS_4,
+	     regval);
+    
+    *data |= (regval & 0xff) << 24;
+    
+}
+
+
+/********************************************************************
+ * ixEthAccMiiInit
+ */
+IxEthAccStatus
+ixEthAccMiiInit()
+{
+    if(ixOsalMutexInit(&miiAccessLock)!= IX_SUCCESS)
+    {
+	return IX_ETH_ACC_FAIL;
+    }
+
+    miiBaseAddressVirt = (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, IX_OSAL_IXP400_ETHA_MAP_SIZE);
+    
+    if (miiBaseAddressVirt == 0)
+    {
+      ixOsalLog(IX_OSAL_LOG_LVL_FATAL, 
+		IX_OSAL_LOG_DEV_STDOUT, 
+		"EthAcc: Could not map MII I/O mapped memory\n", 
+		0, 0, 0, 0, 0, 0);
+      
+      return IX_ETH_ACC_FAIL;
+    }
+    
+    return IX_ETH_ACC_SUCCESS;
+}
+
+void
+ixEthAccMiiUnload(void)
+{
+    IX_OSAL_MEM_UNMAP(miiBaseAddressVirt);
+  
+    miiBaseAddressVirt = 0;
+}
+
+PUBLIC IxEthAccStatus
+ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount)
+{
+    if (retryCount < 1) return IX_ETH_ACC_FAIL;
+
+    ixEthAccMiiRetryCount    = retryCount;
+    ixEthAccMiiAccessTimeout = timeout;
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+/*********************************************************************
+ * ixEthAccMiiReadRtn - read a 16 bit value from a PHY
+ */
+IxEthAccStatus      
+ixEthAccMiiReadRtn (UINT8 phyAddr, 
+		    UINT8 phyReg, 
+		    UINT16 *value)
+{
+    UINT32 mdioCommand;
+    UINT32 regval;
+    UINT32 miiTimeout;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR) 
+	|| (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    if (value == NULL)
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
+    mdioCommand = phyReg <<  IX_ETH_ACC_MII_REG_SHL 
+	| phyAddr << IX_ETH_ACC_MII_ADDR_SHL;
+    mdioCommand |= IX_ETH_ACC_MII_GO;
+
+    ixEthAccMdioCmdWrite(mdioCommand);
+    
+    miiTimeout = ixEthAccMiiRetryCount;
+
+    while(miiTimeout)
+    {
+	
+	ixEthAccMdioCmdRead(&regval);
+     
+	if((regval & IX_ETH_ACC_MII_GO) == 0x0)
+	{	    
+	    break;
+	}
+	/* Sleep for a while */
+	ixOsalSleep(ixEthAccMiiAccessTimeout);
+	miiTimeout--;
+    }
+    
+
+    
+    if(miiTimeout == 0)
+    {	
+	ixOsalMutexUnlock(&miiAccessLock);
+	*value = 0xffff;
+	return IX_ETH_ACC_FAIL;
+    }
+    
+    
+    ixEthAccMdioStatusRead(&regval);
+    if(regval & IX_ETH_ACC_MII_READ_FAIL)
+    {
+	ixOsalMutexUnlock(&miiAccessLock);
+	*value = 0xffff;
+	return IX_ETH_ACC_FAIL;
+    }
+
+    *value = regval & 0xffff;
+    ixOsalMutexUnlock(&miiAccessLock);
+    return IX_ETH_ACC_SUCCESS;
+    
+}
+
+
+/*********************************************************************
+ * ixEthAccMiiWriteRtn - write a 16 bit value to a PHY
+ */
+IxEthAccStatus
+ixEthAccMiiWriteRtn (UINT8 phyAddr, 
+		     UINT8 phyReg, 
+		     UINT16 value)
+{
+    UINT32 mdioCommand;
+    UINT32 regval;
+    UINT16 readVal;
+    UINT32 miiTimeout;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR) 
+	|| (phyReg >= IXP425_ETH_ACC_MII_MAX_REG))
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+   
+    /* ensure that a PHY is present at this address */
+    if(ixEthAccMiiReadRtn(phyAddr,
+                          IX_ETH_ACC_MII_CTRL_REG,
+                          &readVal) != IX_ETH_ACC_SUCCESS)
+    {
+        return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
+    mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL
+	| phyAddr << IX_ETH_ACC_MII_ADDR_SHL ;
+    mdioCommand |= IX_ETH_ACC_MII_GO | IX_ETH_ACC_MII_WRITE | value;
+
+    ixEthAccMdioCmdWrite(mdioCommand);
+    
+    miiTimeout = ixEthAccMiiRetryCount;
+
+    while(miiTimeout)
+    {
+	
+	ixEthAccMdioCmdRead(&regval);
+
+	/*The "GO" bit is reset to 0 when the write completes*/
+	if((regval & IX_ETH_ACC_MII_GO) == 0x0)
+	{		    
+	    break;
+	}
+	/* Sleep for a while */
+	ixOsalSleep(ixEthAccMiiAccessTimeout);
+        miiTimeout--;
+    }
+    
+    ixOsalMutexUnlock(&miiAccessLock);
+    if(miiTimeout == 0)
+    {
+	return IX_ETH_ACC_FAIL;
+    }
+    return IX_ETH_ACC_SUCCESS;
+}
+
+
+/*****************************************************************
+ *
+ *  Phy query functions
+ *
+ */
+IxEthAccStatus
+ixEthAccMiiStatsShow (UINT32 phyAddr)
+{
+    UINT16 regval;
+    printf("Regisers on PHY at address 0x%x\n", phyAddr);
+    ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_CTRL_REG, &regval);
+    printf("    Control Register                  :      0x%4.4x\n", regval);
+    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_STAT_REG, &regval);
+    printf("    Status Register                   :      0x%4.4x\n", regval);
+    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_PHY_ID1_REG, &regval);
+    printf("    PHY ID1 Register                  :      0x%4.4x\n", regval);
+    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_PHY_ID2_REG, &regval);
+    printf("    PHY ID2 Register                  :      0x%4.4x\n", regval);
+    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_AN_ADS_REG, &regval);
+    printf("    Auto Neg ADS Register             :      0x%4.4x\n", regval);
+    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_AN_PRTN_REG, &regval);
+    printf("    Auto Neg Partner Ability Register :      0x%4.4x\n", regval);
+    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_AN_EXP_REG, &regval);
+    printf("    Auto Neg Expansion Register       :      0x%4.4x\n", regval);
+    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_ACC_MII_AN_NEXT_REG, &regval);
+    printf("    Auto Neg Next Register            :      0x%4.4x\n", regval);
+
+    return IX_ETH_ACC_SUCCESS;
+}
+
+
+/*****************************************************************
+ *
+ *  Interface query functions
+ *
+ */
+IxEthAccStatus
+ixEthAccMdioShow (void)
+{
+    UINT32 regval;
+
+    if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
+    {
+	return (IX_ETH_ACC_FAIL);
+    }
+
+    ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
+    ixEthAccMdioCmdRead(&regval);
+    ixOsalMutexUnlock(&miiAccessLock);
+    
+    printf("MDIO command register\n");
+    printf("    Go bit      : 0x%x\n", (regval & BIT(31)) >> 31);
+    printf("    MDIO Write  : 0x%x\n", (regval & BIT(26)) >> 26);
+    printf("    PHY address : 0x%x\n", (regval >> 21) & 0x1f);
+    printf("    Reg address : 0x%x\n", (regval >> 16) & 0x1f);
+	
+    ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER);
+    ixEthAccMdioStatusRead(&regval);
+    ixOsalMutexUnlock(&miiAccessLock);
+
+    printf("MDIO status register\n");
+    printf("    Read OK     : 0x%x\n", (regval & BIT(31)) >> 31);
+    printf("    Read Data   : 0x%x\n", (regval >> 16) & 0xff);
+
+    return IX_ETH_ACC_SUCCESS;   
+}
+
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBAPI.c b/marvell/uboot/drivers/net/npe/IxEthDBAPI.c
new file mode 100644
index 0000000..023cf50
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBAPI.c
@@ -0,0 +1,424 @@
+/**
+ * @file IxEthDBAPI.c
+ *
+ * @brief Implementation of the public API
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+#include "IxFeatureCtrl.h"
+
+extern HashTable dbHashtable;
+extern IxEthDBPortMap overflowUpdatePortList;
+extern BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_REFERENCE(macAddr);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
+
+    return ixEthDBTriggerAddPortUpdate(macAddr, portID, true);
+}
+    
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+        
+    IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
+
+    return ixEthDBTriggerAddPortUpdate(macAddr, portID, false);
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr)
+{
+    HashNode *searchResult;
+
+    IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+    searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
+
+    if (searchResult == NULL)
+    {
+        return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
+    }
+    
+    ixEthDBReleaseHashNode(searchResult);
+    
+    /* build a remove event and place it on the event queue */
+    return ixEthDBTriggerRemovePortUpdate(macAddr, ((MacDescriptor *) searchResult->data)->portID);
+}
+       
+IX_ETH_DB_PUBLIC
+void ixEthDBDatabaseMaintenance()
+{
+    HashIterator iterator;
+    UINT32 portIndex;
+    BOOL agingRequired = false;
+
+    /* ports who will have deleted records and therefore will need updating */
+    IxEthDBPortMap triggerPorts;
+
+    if (IX_FEATURE_CTRL_SWCONFIG_ENABLED !=
+        ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
+    {
+        return;
+    }
+
+    SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
+
+    /* check if there's at least a port that needs aging */
+    for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+    {
+        if (ixEthDBPortInfo[portIndex].agingEnabled && ixEthDBPortInfo[portIndex].enabled)
+        {
+            agingRequired = true;
+        }
+    }
+
+    if (agingRequired)
+    {
+        /* ask each NPE port to write back the database for aging inspection */
+        for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+        {
+            if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE
+                && ixEthDBPortInfo[portIndex].agingEnabled
+                && ixEthDBPortInfo[portIndex].enabled)
+            {
+                IxNpeMhMessage message;
+                IX_STATUS result;
+                
+                /* send EDB_GetMACAddressDatabase message */
+                FILL_GETMACADDRESSDATABASE(message, 
+                    0 /* unused */, 
+                    IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone));
+
+                IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), message, result);
+
+                if (result == IX_SUCCESS)
+                {
+                    /* analyze NPE copy */
+                    ixEthDBNPESyncScan(portIndex, ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone, FULL_ELT_BYTE_SIZE);
+
+                    IX_ETH_DB_SUPPORT_TRACE("DB: (API) Finished scanning NPE tree on port %d\n", portIndex);
+                }
+                else
+                {
+                    ixEthDBPortInfo[portIndex].agingEnabled                = false;
+                    ixEthDBPortInfo[portIndex].updateMethod.updateEnabled  = false;
+                    ixEthDBPortInfo[portIndex].updateMethod.userControlled = true;
+
+                    ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
+                        IX_OSAL_LOG_DEV_STDOUT, 
+                        "EthDB: (Maintenance) warning, disabling aging and updates for port %d (assumed dead)\n",
+                        portIndex, 0, 0, 0, 0, 0);
+
+                    ixEthDBDatabaseClear(portIndex, IX_ETH_DB_ALL_RECORD_TYPES);
+                }
+            }
+        }
+
+        /* browse database and age entries */
+        BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
+
+        while (IS_ITERATOR_VALID(&iterator))
+        {
+            MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
+            UINT32 *age               = NULL;
+            BOOL staticEntry          = true;
+
+            if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
+            {
+                age         = &descriptor->recordData.filteringData.age;
+                staticEntry = descriptor->recordData.filteringData.staticEntry;
+            }
+            else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
+            {
+                age         = &descriptor->recordData.filteringVlanData.age;
+                staticEntry = descriptor->recordData.filteringVlanData.staticEntry;
+            }
+            else
+            {
+                staticEntry = true;
+            }
+
+            if (ixEthDBPortInfo[descriptor->portID].agingEnabled && (staticEntry == false))
+            {
+                /* manually increment the age if the port has no such capability */
+                if ((ixEthDBPortDefinitions[descriptor->portID].capabilities & IX_ETH_ENTRY_AGING) == 0)
+                {
+                    *age += (IX_ETH_DB_MAINTENANCE_TIME / 60);
+                }
+
+                /* age entry if it exceeded the maximum time to live */
+                if (*age >= (IX_ETH_DB_LEARNING_ENTRY_AGE_TIME / 60))
+                {
+                    /* add port to the set of update trigger ports */
+                    JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
+
+                    /* delete entry */
+                    BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
+                }
+                else
+                {
+                    /* move to the next record */
+                    BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
+                }
+            }
+            else
+            {
+                /* move to the next record */
+                BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
+            }
+        }
+
+        /* update ports which lost records */
+        ixEthDBUpdatePortLearningTrees(triggerPorts);
+    }
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType)
+{
+    IxEthDBPortMap triggerPorts;
+    HashIterator iterator;
+
+    if (portID >= IX_ETH_DB_NUMBER_OF_PORTS && portID != IX_ETH_DB_ALL_PORTS)
+    {
+        return IX_ETH_DB_INVALID_PORT;
+    }
+
+    /* check if the user passes some extra bits */
+    if ((recordType | IX_ETH_DB_ALL_RECORD_TYPES) != IX_ETH_DB_ALL_RECORD_TYPES)
+    {
+        return IX_ETH_DB_INVALID_ARG;
+    }
+
+    SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
+    
+    /* browse database and age entries */
+    BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
+
+    while (IS_ITERATOR_VALID(&iterator))
+    {
+        MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
+
+        if (((descriptor->portID == portID) || (portID == IX_ETH_DB_ALL_PORTS))
+            && ((descriptor->type & recordType) != 0))
+        {
+            /* add to trigger if automatic updates are required */
+            if (ixEthDBPortUpdateRequired[descriptor->type])
+            {
+                /* add port to the set of update trigger ports */
+                JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
+            }
+
+            /* delete entry */
+            BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
+        }
+        else
+        {
+            /* move to the next record */
+            BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
+        }
+    }
+
+    /* update ports which lost records */
+    ixEthDBUpdatePortLearningTrees(triggerPorts);
+    
+    return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+    HashNode *searchResult;
+    IxEthDBStatus result = IX_ETH_DB_NO_SUCH_ADDR;
+
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
+
+    searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
+
+    if (searchResult == NULL)
+    {
+        return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
+    }
+
+    if (((MacDescriptor *) (searchResult->data))->portID == portID)
+    {
+        result = IX_ETH_DB_SUCCESS; /* address and port match */
+    }
+
+    ixEthDBReleaseHashNode(searchResult);
+
+    return result;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
+{
+    HashNode *searchResult;
+
+    IX_ETH_DB_CHECK_REFERENCE(portID);
+    
+    IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+    searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
+
+    if (searchResult == NULL)
+    {
+        return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
+    }
+
+    /* return the port ID */
+    *portID = ((MacDescriptor *) searchResult->data)->portID;
+
+    ixEthDBReleaseHashNode(searchResult);
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
+
+    ixEthDBPortInfo[portID].agingEnabled = false;
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
+
+    ixEthDBPortInfo[portID].agingEnabled = true;
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
+{
+    HashNode *searchResult;
+    MacDescriptor *descriptor;
+
+    IX_ETH_DB_CHECK_REFERENCE(portID);
+    
+    IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+    searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
+
+    if (searchResult == NULL)
+    {
+        return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
+    }
+    
+    descriptor = (MacDescriptor *) searchResult->data;
+
+    /* return the port ID */
+    *portID = descriptor->portID;
+
+    /* reset entry age */
+    if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
+    {
+        descriptor->recordData.filteringData.age = 0;
+    }
+    else
+    {
+        descriptor->recordData.filteringVlanData.age = 0;
+    }
+
+    ixEthDBReleaseHashNode(searchResult);
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
+
+    /* force bit at offset 255 to 0 (reserved) */
+    dependencyPortMap[31] &= 0xFE;
+
+    COPY_DEPENDENCY_MAP(ixEthDBPortInfo[portID].dependencyPortMap, dependencyPortMap);
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
+
+    COPY_DEPENDENCY_MAP(dependencyPortMap, ixEthDBPortInfo[portID].dependencyPortMap);
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);    
+
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
+
+    ixEthDBPortInfo[portID].updateMethod.updateEnabled  = enableUpdate;
+    ixEthDBPortInfo[portID].updateMethod.userControlled = true;
+
+    return IX_ETH_DB_SUCCESS;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBAPISupport.c b/marvell/uboot/drivers/net/npe/IxEthDBAPISupport.c
new file mode 100644
index 0000000..c265d94
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBAPISupport.c
@@ -0,0 +1,651 @@
+/**
+ * @file IxEthDBAPISupport.c
+ *
+ * @brief Public API support functions
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include <IxEthDB.h>
+#include <IxNpeMh.h>
+#include <IxFeatureCtrl.h>
+
+#include "IxEthDB_p.h"
+#include "IxEthDBMessages_p.h"
+#include "IxEthDB_p.h"
+#include "IxEthDBLog_p.h"
+
+#ifdef IX_UNIT_TEST
+
+int dbAccessCounter = 0;
+int overflowEvent   = 0;
+
+#endif
+
+/*
+ * External declaration
+ */
+extern HashTable dbHashtable;
+
+/*
+ * Internal declaration
+ */
+IX_ETH_DB_PUBLIC
+PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS];
+
+IX_ETH_DB_PRIVATE
+struct
+{
+    BOOL saved;
+    IxEthDBPriorityTable priorityTable;
+    IxEthDBVlanSet vlanMembership;
+    IxEthDBVlanSet transmitTaggingInfo;
+    IxEthDBFrameFilter frameFilter;
+    IxEthDBTaggingAction taggingAction;
+    IxEthDBFirewallMode firewallMode;
+    BOOL stpBlocked;
+    BOOL srcAddressFilterEnabled;
+    UINT32 maxRxFrameSize;
+    UINT32 maxTxFrameSize;
+} ixEthDBPortState[IX_ETH_DB_NUMBER_OF_PORTS];
+
+#define IX_ETH_DB_DEFAULT_FRAME_SIZE (1518)
+
+/**
+ * @brief initializes a port
+ *
+ * @param portID ID of the port to be initialized
+ *
+ * Note that redundant initializations are silently
+ * dealt with and do not constitute an error
+ *
+ * This function is fully documented in the main
+ * header file, IxEthDB.h
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBPortInit(IxEthDBPortId portID)
+{
+    PortInfo *portInfo;
+
+    if (portID >= IX_ETH_DB_NUMBER_OF_PORTS)
+    {
+        return;
+    }
+
+    portInfo = &ixEthDBPortInfo[portID];
+
+    if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS)
+    {
+        WARNING_LOG("EthDB: Unavailable Eth %d: Cannot initialize EthDB Port.\n", (UINT32) portID);
+
+        return;
+    }
+
+    if (portInfo->initialized)
+    {
+        /* redundant */
+        return;
+    }
+
+    /* initialize core fields */
+    portInfo->portID = portID;
+    SET_DEPENDENCY_MAP(portInfo->dependencyPortMap, portID);
+
+    /* default values */
+    portInfo->agingEnabled       = false;
+    portInfo->enabled            = false;
+    portInfo->macAddressUploaded = false;
+    portInfo->maxRxFrameSize     = IX_ETHDB_DEFAULT_FRAME_SIZE;
+    portInfo->maxTxFrameSize     = IX_ETHDB_DEFAULT_FRAME_SIZE;
+
+    /* default update control values */
+    portInfo->updateMethod.searchTree              = NULL;
+    portInfo->updateMethod.searchTreePendingWrite  = false;
+    portInfo->updateMethod.treeInitialized         = false;
+    portInfo->updateMethod.updateEnabled           = false;
+    portInfo->updateMethod.userControlled          = false;
+
+    /* default WiFi parameters */
+    memset(portInfo->bbsid, 0, sizeof (portInfo->bbsid));
+    portInfo->frameControlDurationID = 0;
+
+    /* Ethernet NPE-specific initializations */
+    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+    {
+        /* update handler */
+        portInfo->updateMethod.updateHandler = ixEthDBNPEUpdateHandler;
+    }
+
+    /* initialize state save */
+    ixEthDBPortState[portID].saved = false;
+
+    portInfo->initialized = true;
+}
+
+/**
+ * @brief enables a port
+ *
+ * @param portID ID of the port to enable
+ *
+ * This function is fully documented in the main
+ * header file, IxEthDB.h
+ *
+ * @return IX_ETH_DB_SUCCESS if enabling was
+ * accomplished, or a meaningful error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID)
+{
+    IxEthDBPortMap triggerPorts;
+    PortInfo *portInfo;
+
+    IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    portInfo = &ixEthDBPortInfo[portID];
+
+    if (portInfo->enabled)
+    {
+        /* redundant */
+        return IX_ETH_DB_SUCCESS;
+    }
+
+    SET_DEPENDENCY_MAP(triggerPorts, portID);
+
+    /* mark as enabled */
+    portInfo->enabled = true;
+
+    /* Operation stops here when Ethernet Learning is not enabled */
+    if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
+       ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
+    {
+        return IX_ETH_DB_SUCCESS;
+    }
+
+    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE && !portInfo->macAddressUploaded)
+    {
+        IX_ETH_DB_SUPPORT_TRACE("DB: (Support) MAC address not set on port %d, enable failed\n", portID);
+
+        /* must use UnicastAddressSet() before enabling an NPE port */
+        return IX_ETH_DB_MAC_UNINITIALIZED;
+    }
+
+    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+    {
+        IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Attempting to enable the NPE callback for port %d...\n", portID);
+
+        if (!portInfo->updateMethod.userControlled
+                && ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0))
+        {
+            portInfo->updateMethod.updateEnabled = true;
+        }
+
+        /* if this is first time initialization then we already have
+           write access to the tree and can AccessRelease directly */
+        if (!portInfo->updateMethod.treeInitialized)
+        {
+            IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Initializing tree for port %d\n", portID);
+
+            /* create an initial tree and release access into it */
+            ixEthDBUpdatePortLearningTrees(triggerPorts);
+
+            /* mark tree as being initialized */
+            portInfo->updateMethod.treeInitialized = true;
+        }
+    }
+
+    if (ixEthDBPortState[portID].saved)
+    {
+        /* previous configuration data stored, restore state */
+        if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
+        {
+            ixEthDBFirewallModeSet(portID, ixEthDBPortState[portID].firewallMode);
+            ixEthDBFirewallInvalidAddressFilterEnable(portID, ixEthDBPortState[portID].srcAddressFilterEnabled);
+        }
+
+#if 0 /* test-only */
+        if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
+        {
+            ixEthDBAcceptableFrameTypeSet(portID, ixEthDBPortState[portID].frameFilter);
+            ixEthDBIngressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].taggingAction);
+
+            ixEthDBEgressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].transmitTaggingInfo);
+            ixEthDBPortVlanMembershipSet(portID, ixEthDBPortState[portID].vlanMembership);
+
+            ixEthDBPriorityMappingTableSet(portID, ixEthDBPortState[portID].priorityTable);
+        }
+#endif
+
+        if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
+        {
+            ixEthDBSpanningTreeBlockingStateSet(portID, ixEthDBPortState[portID].stpBlocked);
+        }
+
+        ixEthDBFilteringPortMaximumRxFrameSizeSet(portID, ixEthDBPortState[portID].maxRxFrameSize);
+        ixEthDBFilteringPortMaximumTxFrameSizeSet(portID, ixEthDBPortState[portID].maxTxFrameSize);
+
+        /* discard previous save */
+        ixEthDBPortState[portID].saved = false;
+    }
+
+    IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Enabling succeeded for port %d\n", portID);
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief disables a port
+ *
+ * @param portID ID of the port to disable
+ *
+ * This function is fully documented in the
+ * main header file, IxEthDB.h
+ *
+ * @return IX_ETH_DB_SUCCESS if disabling was
+ * successful or an appropriate error message
+ * otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID)
+{
+    HashIterator iterator;
+    IxEthDBPortMap triggerPorts; /* ports who will have deleted records and therefore will need updating */
+    BOOL result;
+    PortInfo *portInfo;
+    IxEthDBFeature learningEnabled;
+#if 0 /* test-only */
+    IxEthDBPriorityTable classZeroTable;
+#endif
+
+    IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    portInfo = &ixEthDBPortInfo[portID];
+
+    if (!portInfo->enabled)
+    {
+        /* redundant */
+        return IX_ETH_DB_SUCCESS;
+    }
+
+    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+    {
+        /* save filtering state */
+        ixEthDBPortState[portID].firewallMode            = portInfo->firewallMode;
+        ixEthDBPortState[portID].frameFilter             = portInfo->frameFilter;
+        ixEthDBPortState[portID].taggingAction           = portInfo->taggingAction;
+        ixEthDBPortState[portID].stpBlocked              = portInfo->stpBlocked;
+        ixEthDBPortState[portID].srcAddressFilterEnabled = portInfo->srcAddressFilterEnabled;
+        ixEthDBPortState[portID].maxRxFrameSize          = portInfo->maxRxFrameSize;
+        ixEthDBPortState[portID].maxTxFrameSize          = portInfo->maxTxFrameSize;
+
+        memcpy(ixEthDBPortState[portID].vlanMembership, portInfo->vlanMembership, sizeof (IxEthDBVlanSet));
+        memcpy(ixEthDBPortState[portID].transmitTaggingInfo, portInfo->transmitTaggingInfo, sizeof (IxEthDBVlanSet));
+        memcpy(ixEthDBPortState[portID].priorityTable, portInfo->priorityTable, sizeof (IxEthDBPriorityTable));
+
+        ixEthDBPortState[portID].saved = true;
+
+        /* now turn off all EthDB filtering features on the port */
+
+#if 0 /* test-only */
+        /* VLAN & QoS */
+        if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
+        {
+            ixEthDBPortVlanMembershipRangeAdd((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID);
+            ixEthDBEgressVlanRangeTaggingEnabledSet((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID, false);
+            ixEthDBAcceptableFrameTypeSet((IxEthDBPortId) portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
+            ixEthDBIngressVlanTaggingEnabledSet((IxEthDBPortId) portID, IX_ETH_DB_PASS_THROUGH);
+
+            memset(classZeroTable, 0, sizeof (classZeroTable));
+            ixEthDBPriorityMappingTableSet((IxEthDBPortId) portID, classZeroTable);
+        }
+#endif
+
+        /* STP */
+        if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
+        {
+            ixEthDBSpanningTreeBlockingStateSet((IxEthDBPortId) portID, false);
+        }
+
+        /* Firewall */
+        if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
+        {
+            ixEthDBFirewallModeSet((IxEthDBPortId) portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
+            ixEthDBFirewallTableDownload((IxEthDBPortId) portID);
+            ixEthDBFirewallInvalidAddressFilterEnable((IxEthDBPortId) portID, false);
+        }
+
+        /* Frame size filter */
+        ixEthDBFilteringPortMaximumFrameSizeSet((IxEthDBPortId) portID, IX_ETH_DB_DEFAULT_FRAME_SIZE);
+
+        /* WiFi */
+        if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
+        {
+            ixEthDBWiFiConversionTableDownload((IxEthDBPortId) portID);
+        }
+
+        /* save and disable the learning feature bit */
+        learningEnabled          = portInfo->featureStatus & IX_ETH_DB_LEARNING;
+        portInfo->featureStatus &= ~IX_ETH_DB_LEARNING;
+    }
+    else
+    {
+        /* save the learning feature bit */
+        learningEnabled          = portInfo->featureStatus & IX_ETH_DB_LEARNING;
+    }
+
+    SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
+
+    ixEthDBUpdateLock();
+
+    /* wipe out current entries for this port */
+    BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
+
+    while (IS_ITERATOR_VALID(&iterator))
+    {
+        MacDescriptor *descriptor =  (MacDescriptor *) iterator.node->data;
+
+        /* check if the port match. If so, remove the entry  */
+        if (descriptor->portID == portID
+                && (descriptor->type == IX_ETH_DB_FILTERING_RECORD || descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
+                && !descriptor->recordData.filteringData.staticEntry)
+        {
+            /* delete entry */
+            BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
+
+            /* add port to the set of update trigger ports */
+            JOIN_PORT_TO_MAP(triggerPorts, portID);
+        }
+        else
+        {
+            /* move to the next record */
+            BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
+        }
+    }
+
+    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+    {
+        if (portInfo->updateMethod.searchTree != NULL)
+        {
+            ixEthDBFreeMacTreeNode(portInfo->updateMethod.searchTree);
+            portInfo->updateMethod.searchTree = NULL;
+        }
+
+        ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FILTERING_RECORD);
+    }
+
+    /* mark as disabled */
+    portInfo->enabled = false;
+
+    /* disable updates unless the user has specifically altered the default behavior */
+    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+    {
+        if (!portInfo->updateMethod.userControlled)
+        {
+            portInfo->updateMethod.updateEnabled = false;
+        }
+
+        /* make sure we re-initialize the NPE learning tree when the port is re-enabled */
+        portInfo->updateMethod.treeInitialized = false;
+    }
+
+    ixEthDBUpdateUnlock();
+
+    /* restore learning feature bit */
+    portInfo->featureStatus |= learningEnabled;
+
+    /* if we've removed any records or lost any events make sure to force an update */
+    IS_EMPTY_DEPENDENCY_MAP(result, triggerPorts);
+
+    if (!result)
+    {
+        ixEthDBUpdatePortLearningTrees(triggerPorts);
+    }
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief sends the updated maximum Tx/Rx frame lengths to the NPE
+ *
+ * @param portID ID of the port to update
+ *
+ * @return IX_ETH_DB_SUCCESS if the update completed
+ * successfully or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBPortFrameLengthsUpdate(IxEthDBPortId portID)
+{
+    IxNpeMhMessage message;
+    PortInfo *portInfo = &ixEthDBPortInfo[portID];
+    IX_STATUS result;
+
+    FILL_SETMAXFRAMELENGTHS_MSG(message, portID, portInfo->maxRxFrameSize, portInfo->maxTxFrameSize);
+
+    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+    return result;
+}
+
+/**
+ * @brief sets the port maximum Rx frame size
+ *
+ * @param portID ID of the port to set the frame size on
+ * @param maximumRxFrameSize maximum Rx frame size
+ *
+ * This function updates the internal data structures and
+ * calls ixEthDBPortFrameLengthsUpdate() for NPE update.
+ *
+ * This function is fully documented in the main header
+ * file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation was
+ * successfull or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize)
+{
+    IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+	if (!ixEthDBPortInfo[portID].initialized)
+	{
+		return IX_ETH_DB_PORT_UNINITIALIZED;
+	}
+
+    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+    {
+	if ((maximumRxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
+	    (maximumRxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
+	{
+	    return IX_ETH_DB_INVALID_ARG;
+	}
+    }
+    else
+    {
+        return IX_ETH_DB_NO_PERMISSION;
+    }
+
+    /* update internal structure */
+    ixEthDBPortInfo[portID].maxRxFrameSize = maximumRxFrameSize;
+
+    /* update the maximum frame size in the NPE */
+    return ixEthDBPortFrameLengthsUpdate(portID);
+}
+
+/**
+ * @brief sets the port maximum Tx frame size
+ *
+ * @param portID ID of the port to set the frame size on
+ * @param maximumTxFrameSize maximum Tx frame size
+ *
+ * This function updates the internal data structures and
+ * calls ixEthDBPortFrameLengthsUpdate() for NPE update.
+ *
+ * This function is fully documented in the main header
+ * file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation was
+ * successfull or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize)
+{
+    IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+	if (!ixEthDBPortInfo[portID].initialized)
+	{
+		return IX_ETH_DB_PORT_UNINITIALIZED;
+	}
+
+    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+    {
+	if ((maximumTxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
+	    (maximumTxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
+	{
+	    return IX_ETH_DB_INVALID_ARG;
+	}
+    }
+    else
+    {
+        return IX_ETH_DB_NO_PERMISSION;
+    }
+
+    /* update internal structure */
+    ixEthDBPortInfo[portID].maxTxFrameSize = maximumTxFrameSize;
+
+    /* update the maximum frame size in the NPE */
+    return ixEthDBPortFrameLengthsUpdate(portID);
+}
+
+/**
+ * @brief sets the port maximum Tx and Rx frame sizes
+ *
+ * @param portID ID of the port to set the frame size on
+ * @param maximumFrameSize maximum Tx and Rx frame sizes
+ *
+ * This function updates the internal data structures and
+ * calls ixEthDBPortFrameLengthsUpdate() for NPE update.
+ *
+ * Note that both the maximum Tx and Rx frame size are set
+ * to the same value. This function is kept for compatibility
+ * reasons.
+ *
+ * This function is fully documented in the main header
+ * file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation was
+ * successfull or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize)
+{
+    IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    if (!ixEthDBPortInfo[portID].initialized)
+    {
+        return IX_ETH_DB_PORT_UNINITIALIZED;
+    }
+
+    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+    {
+	if ((maximumFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
+	    (maximumFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
+	{
+	    return IX_ETH_DB_INVALID_ARG;
+	}
+    }
+    else
+    {
+        return IX_ETH_DB_NO_PERMISSION;
+    }
+
+    /* update internal structure */
+    ixEthDBPortInfo[portID].maxRxFrameSize = maximumFrameSize;
+    ixEthDBPortInfo[portID].maxTxFrameSize = maximumFrameSize;
+
+    /* update the maximum frame size in the NPE */
+    return ixEthDBPortFrameLengthsUpdate(portID);
+}
+
+/**
+ * @brief sets the MAC address of an NPE port
+ *
+ * @param portID port ID to set the MAC address on
+ * @param macAddr pointer to the 6-byte MAC address
+ *
+ * This function is called by the EthAcc
+ * ixEthAccUnicastMacAddressSet() and should not be
+ * manually invoked unless required by special circumstances.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation succeeded
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+    IxNpeMhMessage message;
+    IX_STATUS result;
+
+    /* use this macro instead CHECK_PORT
+       as the port doesn't need to be enabled */
+    IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+    IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+    if (!ixEthDBPortInfo[portID].initialized)
+    {
+        return IX_ETH_DB_PORT_UNINITIALIZED;
+    }
+
+    /* Operation stops here when Ethernet Learning is not enabled */
+    if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
+       ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
+    {
+        return IX_ETH_DB_SUCCESS;
+    }
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    /* exit if the port is not an Ethernet NPE */
+    if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE)
+    {
+        return IX_ETH_DB_INVALID_PORT;
+    }
+
+    /* populate message */
+    FILL_SETPORTADDRESS_MSG(message, portID, macAddr->macAddress);
+
+    IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Sending SetPortAddress on port %d...\n", portID);
+
+    /* send a SetPortAddress message */
+    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+    if (result == IX_SUCCESS)
+    {
+        ixEthDBPortInfo[portID].macAddressUploaded = true;
+    }
+
+    return result;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBCore.c b/marvell/uboot/drivers/net/npe/IxEthDBCore.c
new file mode 100644
index 0000000..3d3050d
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBCore.c
@@ -0,0 +1,439 @@
+/**
+ * @file IxEthDBDBCore.c
+ *
+ * @brief Database support functions
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+
+/* list of database hashtables */
+IX_ETH_DB_PUBLIC HashTable dbHashtable;
+IX_ETH_DB_PUBLIC MatchFunction matchFunctions[IX_ETH_DB_MAX_KEY_INDEX + 1];
+IX_ETH_DB_PUBLIC BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
+IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyType[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
+
+/* private initialization flag */
+IX_ETH_DB_PRIVATE BOOL ethDBInitializationComplete = false;
+
+/**
+ * @brief initializes EthDB
+ *
+ * This function must be called to initialize the component.
+ *
+ * It does the following things:
+ * - checks the port definition structure
+ * - scans the capabilities of the NPE images and sets the
+ *   capabilities of the ports accordingly
+ * - initializes the memory pools internally used in EthDB
+ *   for storing database records and handling data
+ * - registers automatic update handlers for add and remove
+ *   operations
+ * - registers hashing match functions, depending on key sets
+ * - initializes the main database hashtable
+ * - allocates contiguous memory zones to be used for NPE
+ *   updates
+ * - registers the serialize methods used to convert data
+ *   into NPE-readable format
+ * - starts the event processor
+ *
+ * Note that this function is documented in the public
+ * component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS or an appropriate error if the
+ * component failed to initialize correctly
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBInit(void)
+{
+    IxEthDBStatus result;
+
+    if (ethDBInitializationComplete)
+    {
+        /* redundant */
+        return IX_ETH_DB_SUCCESS;
+    }
+
+    /* trap an invalid port definition structure */
+    IX_ETH_DB_PORTS_ASSERTION;
+
+    /* memory management */
+    ixEthDBInitMemoryPools();
+
+    /* register hashing search methods */
+    ixEthDBMatchMethodsRegister(matchFunctions);
+
+    /* register type-based automatic port updates */
+    ixEthDBUpdateTypeRegister(ixEthDBPortUpdateRequired);
+
+    /* register record to key type mappings */
+    ixEthDBKeyTypeRegister(ixEthDBKeyType);
+
+    /* hash table */
+    ixEthDBInitHash(&dbHashtable, NUM_BUCKETS, ixEthDBEntryXORHash, matchFunctions, (FreeFunction) ixEthDBFreeMacDescriptor);
+
+    /* NPE update zones */
+    ixEthDBNPEUpdateAreasInit();
+
+    /* register record serialization methods */
+    ixEthDBRecordSerializeMethodsRegister();
+
+    /* start the event processor */
+    result = ixEthDBEventProcessorInit();
+
+    /* scan NPE features */
+    if (result == IX_ETH_DB_SUCCESS)
+    {
+        ixEthDBFeatureCapabilityScan();
+    }
+
+    ethDBInitializationComplete = true;
+
+    return result;
+}
+
+/**
+ * @brief prepares EthDB for unloading
+ *
+ * This function must be called before removing the
+ * EthDB component from memory (e.g. doing rmmod in
+ * Linux) if the component is to be re-initialized again
+ * without rebooting the platform.
+ *
+ * All the EthDB ports must be disabled before this
+ * function is to be called. Failure to disable all
+ * the ports will return the IX_ETH_DB_BUSY error.
+ *
+ * This function will destroy mutexes, deallocate
+ * memory and stop the event processor.
+ *
+ * Note that this function is fully documented in the
+ * main component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if de-initialization
+ * completed successfully or an appropriate error
+ * message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBUnload(void)
+{
+    IxEthDBPortId portIndex;
+
+    if (!ethDBInitializationComplete)
+    {
+        /* redundant */
+        return IX_ETH_DB_SUCCESS;
+    }
+
+    /* check if any ports are enabled */
+    for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+    {
+        if (ixEthDBPortInfo[portIndex].enabled)
+        {
+            return IX_ETH_DB_BUSY;
+        }
+    }
+
+    /* free port resources */
+    for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+    {
+        if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
+        {
+            ixOsalMutexDestroy(&ixEthDBPortInfo[portIndex].npeAckLock);
+        }
+
+        ixEthDBPortInfo[portIndex].initialized = false;
+    }
+
+    /* shutdown event processor */
+    ixEthDBStopLearningFunction();
+
+    /* deallocate NPE update zones */
+    ixEthDBNPEUpdateAreasUnload();
+
+    ethDBInitializationComplete = false;
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief adds a new entry to the Ethernet database
+ *
+ * @param newRecordTemplate address of the record template to use
+ * @param updateTrigger port map containing the update triggers
+ * resulting from this update operation
+ *
+ * Creates a new database entry, populates it with the data
+ * copied from the given template and adds the record to the
+ * database hash table.
+ * It also checks whether the new record type is registered to trigger
+ * automatic updates; if it is, the update trigger will contain the
+ * port on which the record insertion was performed, as well as the
+ * old port in case the addition was a record migration (from one port
+ * to the other). The caller can use the updateTrigger to trigger
+ * automatic updates on the ports changed as a result of this addition.
+ *
+ * @retval IX_ETH_DB_SUCCESS addition successful
+ * @retval IX_ETH_DB_NOMEM insertion failed, no memory left in the mac descriptor memory pool
+ * @retval IX_ETH_DB_BUSY database busy, cannot insert due to locking
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger)
+{
+    IxEthDBStatus result;
+    MacDescriptor *newDescriptor;
+    IxEthDBPortId originalPortID;
+    HashNode *node = NULL;
+
+    BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, ixEthDBKeyType[newRecordTemplate->type], newRecordTemplate, &node));
+
+    TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
+
+    if (node == NULL)
+    {
+        /* not found, create a new one */
+        newDescriptor = ixEthDBAllocMacDescriptor();
+
+        if (newDescriptor == NULL)
+        {
+            return IX_ETH_DB_NOMEM; /* no memory */
+        }
+
+        /* old port does not exist, avoid unnecessary updates */
+        originalPortID = newRecordTemplate->portID;
+    }
+    else
+    {
+        /* a node with the same key exists, will update node */
+        newDescriptor = (MacDescriptor *) node->data;
+
+        /* save original port id */
+        originalPortID = newDescriptor->portID;
+    }
+
+    /* copy/update fields into new record */
+    memcpy(newDescriptor->macAddress, newRecordTemplate->macAddress, sizeof (IxEthDBMacAddr));
+    memcpy(&newDescriptor->recordData, &newRecordTemplate->recordData, sizeof (IxEthDBRecordData));
+
+    newDescriptor->type   = newRecordTemplate->type;
+    newDescriptor->portID = newRecordTemplate->portID;
+    newDescriptor->user   = newRecordTemplate->user;
+
+    if (node == NULL)
+    {
+        /* new record, insert into hashtable */
+        BUSY_RETRY_WITH_RESULT(ixEthDBAddHashEntry(&dbHashtable, newDescriptor), result);
+
+        if (result != IX_ETH_DB_SUCCESS)
+        {
+            ixEthDBFreeMacDescriptor(newDescriptor);
+
+            return result; /* insertion failed */
+        }
+    }
+
+    if (node != NULL)
+    {
+        /* release access */
+        ixEthDBReleaseHashNode(node);
+    }
+
+    /* trigger add/remove update if required by type */
+    if (updateTrigger != NULL &&
+        ixEthDBPortUpdateRequired[newRecordTemplate->type])
+    {
+        /* add new port to update list */
+        JOIN_PORT_TO_MAP(updateTrigger, newRecordTemplate->portID);
+
+        /* check if record has moved, we'll need to update the old port as well */
+        if (originalPortID != newDescriptor->portID)
+        {
+            JOIN_PORT_TO_MAP(updateTrigger, originalPortID);
+        }
+    }
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief remove a record from the Ethernet database
+ *
+ * @param templateRecord template record used to determine
+ * what record is to be removed
+ * @param updateTrigger port map containing the update triggers
+ * resulting from this update operation
+ *
+ * This function will examine the template record it receives
+ * and attempts to delete a record of the same type and containing
+ * the same keys as the template record. If deletion is successful
+ * and the record type is registered for automatic port updates the
+ * port will also be set in the updateTrigger port map, so that the
+ * client can perform an update of the port.
+ *
+ * @retval IX_ETH_DB_SUCCESS removal was successful
+ * @retval IX_ETH_DB_NO_SUCH_ADDR the record with the given MAC address was not found
+ * @retval IX_ETH_DB_BUSY database busy, cannot remove due to locking
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger)
+{
+    IxEthDBStatus result;
+
+    TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
+
+    BUSY_RETRY_WITH_RESULT(ixEthDBRemoveHashEntry(&dbHashtable, ixEthDBKeyType[templateRecord->type], templateRecord), result);
+
+    if (result != IX_ETH_DB_SUCCESS)
+    {
+        return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
+    }
+
+    /* trigger add/remove update if required by type */
+    if (updateTrigger != NULL
+        &&ixEthDBPortUpdateRequired[templateRecord->type])
+    {
+        /* add new port to update list */
+        JOIN_PORT_TO_MAP(updateTrigger, templateRecord->portID);
+    }
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief register record key types
+ *
+ * This function registers the appropriate key types,
+ * depending on record types.
+ *
+ * All filtering records use the MAC address as the key.
+ * WiFi and Firewall records use a compound key consisting
+ * in both the MAC address and the port ID.
+ *
+ * @return the number of registered record types
+ */
+IX_ETH_DB_PUBLIC
+UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType)
+{
+    /* safety */
+    memset(keyType, 0, sizeof (keyType));
+
+    /* register all known record types */
+    keyType[IX_ETH_DB_FILTERING_RECORD]      = IX_ETH_DB_MAC_KEY;
+    keyType[IX_ETH_DB_FILTERING_VLAN_RECORD] = IX_ETH_DB_MAC_KEY;
+    keyType[IX_ETH_DB_ALL_FILTERING_RECORDS] = IX_ETH_DB_MAC_KEY;
+    keyType[IX_ETH_DB_WIFI_RECORD]           = IX_ETH_DB_MAC_PORT_KEY;
+    keyType[IX_ETH_DB_FIREWALL_RECORD]       = IX_ETH_DB_MAC_PORT_KEY;
+
+    return 5;
+}
+
+/**
+ * @brief Sets a user-defined field into a database record
+ *
+ * Note that this function is fully documented in the main component
+ * header file.
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field)
+{
+    HashNode *result = NULL;
+
+    if (macAddr == NULL)
+    {
+        return IX_ETH_DB_INVALID_ARG;
+    }
+
+    if (recordType == IX_ETH_DB_FILTERING_RECORD)
+    {
+        result = ixEthDBSearch(macAddr, recordType);
+    }
+    else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD)
+    {
+        result = ixEthDBVlanSearch(macAddr, vlanID, recordType);
+    }
+    else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD)
+    {
+        IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+        result = ixEthDBPortSearch(macAddr, portID, recordType);
+    }
+    else
+    {
+        return IX_ETH_DB_INVALID_ARG;
+    }
+
+    if (result == NULL)
+    {
+        return IX_ETH_DB_NO_SUCH_ADDR;
+    }
+
+    ((MacDescriptor *) result->data)->user = field;
+
+    ixEthDBReleaseHashNode(result);
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief Retrieves a user-defined field from a database record
+ *
+ * Note that this function is fully documented in the main component
+ * header file.
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void **field)
+{
+    HashNode *result = NULL;
+
+    if (macAddr == NULL || field == NULL)
+    {
+        return IX_ETH_DB_INVALID_ARG;
+    }
+
+    if (recordType == IX_ETH_DB_FILTERING_RECORD)
+    {
+        result = ixEthDBSearch(macAddr, recordType);
+    }
+    else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD)
+    {
+        result = ixEthDBVlanSearch(macAddr, vlanID, recordType);
+    }
+    else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD)
+    {
+        IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+        result = ixEthDBPortSearch(macAddr, portID, recordType);
+    }
+    else
+    {
+        return IX_ETH_DB_INVALID_ARG;
+    }
+
+    if (result == NULL)
+    {
+        return IX_ETH_DB_NO_SUCH_ADDR;
+    }
+
+    *field = ((MacDescriptor *) result->data)->user;
+
+    ixEthDBReleaseHashNode(result);
+
+    return IX_ETH_DB_SUCCESS;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBEvents.c b/marvell/uboot/drivers/net/npe/IxEthDBEvents.c
new file mode 100644
index 0000000..5b3be0b
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBEvents.c
@@ -0,0 +1,496 @@
+/**
+ * @file IxEthDBEvents.c
+ *
+ * @brief Implementation of the event processor component
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include <IxNpeMh.h>
+#include <IxFeatureCtrl.h>
+
+#include "IxEthDB_p.h"
+
+/* forward prototype declarations */
+IX_ETH_DB_PUBLIC void ixEthDBEventProcessorLoop(void *); 
+IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
+IX_ETH_DB_PRIVATE void ixEthDBProcessEvent(PortEvent *local_event, IxEthDBPortMap triggerPorts);
+IX_ETH_DB_PRIVATE IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void);
+
+/* data */
+IX_ETH_DB_PRIVATE IxOsalSemaphore eventQueueSemaphore;
+IX_ETH_DB_PRIVATE PortEventQueue eventQueue;
+IX_ETH_DB_PRIVATE IxOsalMutex eventQueueLock;
+IX_ETH_DB_PRIVATE IxOsalMutex portUpdateLock;
+
+IX_ETH_DB_PRIVATE BOOL ixEthDBLearningShutdown      = false;
+IX_ETH_DB_PRIVATE BOOL ixEthDBEventProcessorRunning = false;
+
+/* imported data */
+extern HashTable dbHashtable;
+
+/**
+ * @brief initializes the event processor
+ *
+ * Initializes the event processor queue and processing thread.
+ * Called from ixEthDBInit() DB-subcomponent master init function.
+ *
+ * @warning do not call directly
+ *
+ * @retval IX_ETH_DB_SUCCESS initialization was successful
+ * @retval IX_ETH_DB_FAIL initialization failed (OSAL or mutex init failure)
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBEventProcessorInit(void)
+{
+    if (ixOsalMutexInit(&portUpdateLock) != IX_SUCCESS)
+    {
+        return IX_ETH_DB_FAIL;
+    }
+
+    if (ixOsalMutexInit(&eventQueueLock) != IX_SUCCESS)
+    {
+        return IX_ETH_DB_FAIL;
+    }
+
+    if (IX_FEATURE_CTRL_SWCONFIG_ENABLED ==
+        ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
+    {
+
+        /* start processor loop thread */
+        if (ixEthDBStartLearningFunction() != IX_ETH_DB_SUCCESS)
+        {
+            return IX_ETH_DB_FAIL;
+        }
+    }
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief initializes the event queue and the event processor
+ *
+ * This function is called by the component initialization
+ * function, ixEthDBInit().
+ *
+ * @warning do not call directly
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or IX_ETH_DB_FAIL otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBStartLearningFunction(void)
+{
+    IxOsalThread eventProcessorThread;
+    IxOsalThreadAttr threadAttr;
+
+    threadAttr.name      = "EthDB event thread";
+    threadAttr.stackSize = 32 * 1024; /* 32kbytes */
+    threadAttr.priority  = 128;
+
+    /* reset event queue */
+    ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER);
+
+    RESET_QUEUE(&eventQueue);
+
+    ixOsalMutexUnlock(&eventQueueLock);
+
+    /* init event queue semaphore */
+    if (ixOsalSemaphoreInit(&eventQueueSemaphore, 0) != IX_SUCCESS)
+    {
+        return IX_ETH_DB_FAIL;
+    }
+
+    ixEthDBLearningShutdown = false;
+
+    /* create processor loop thread */
+    if (ixOsalThreadCreate(&eventProcessorThread, &threadAttr, ixEthDBEventProcessorLoop, NULL) != IX_SUCCESS)
+    {
+        return IX_ETH_DB_FAIL;
+    }
+
+    /* start event processor */
+    ixOsalThreadStart(&eventProcessorThread);
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief stops the event processor
+ *
+ * Stops the event processor and frees the event queue semaphore
+ * Called by the component de-initialization function, ixEthDBUnload()
+ *
+ * @warning do not call directly
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed 
+ * successfully or IX_ETH_DB_FAIL otherwise;
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBStopLearningFunction(void)
+{
+    ixEthDBLearningShutdown = true;
+
+    /* wake up event processing loop to actually process the shutdown event */
+    ixOsalSemaphorePost(&eventQueueSemaphore);
+
+    if (ixOsalSemaphoreDestroy(&eventQueueSemaphore) != IX_SUCCESS)
+    {
+        return IX_ETH_DB_FAIL;
+    }
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief default NPE event processing callback
+ *
+ * @param npeID ID of the NPE that generated the event
+ * @param msg NPE message (encapsulated event)
+ *
+ * Creates an event object on the Ethernet event processor queue
+ * and signals the new event by incrementing the event queue semaphore.
+ * Events are processed by @ref ixEthDBEventProcessorLoop() which runs
+ * at user level.
+ *
+ * @see ixEthDBEventProcessorLoop()
+ *
+ * @warning do not call directly
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg)
+{
+    PortEvent *local_event;
+
+    IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) new event received by processor callback from port %d, id 0x%X\n", IX_ETH_DB_NPE_TO_PORT_ID(npeID), NPE_MSG_ID(msg), 0, 0, 0, 0);
+
+    if (CAN_ENQUEUE(&eventQueue))
+    {
+        TEST_FIXTURE_LOCK_EVENT_QUEUE;
+
+        local_event = QUEUE_HEAD(&eventQueue);
+
+        /* create event structure on queue */
+        local_event->eventType = NPE_MSG_ID(msg);
+        local_event->portID    = IX_ETH_DB_NPE_TO_PORT_ID(npeID);
+        
+        /* update queue */
+        PUSH_UPDATE_QUEUE(&eventQueue);
+
+        TEST_FIXTURE_UNLOCK_EVENT_QUEUE;
+
+        IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Waking up main processor loop...\n", 0, 0, 0, 0, 0, 0);
+
+        /* increment event queue semaphore */
+        ixOsalSemaphorePost(&eventQueueSemaphore);
+    }
+    else
+    {
+        IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Warning: could not enqueue event (overflow)\n", 0, 0, 0, 0, 0, 0);
+    }
+}
+
+/**
+ * @brief Ethernet event processor loop
+ *
+ * Extracts at most EVENT_PROCESSING_LIMIT batches of events and
+ * sends them for processing to @ref ixEthDBProcessEvent().
+ * Triggers port updates which normally follow learning events.
+ *
+ * @warning do not call directly, executes in separate thread
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBEventProcessorLoop(void *unused1)
+{
+    IxEthDBPortMap triggerPorts;
+    IxEthDBPortId portIndex;
+
+    ixEthDBEventProcessorRunning = true;
+
+    IX_ETH_DB_EVENTS_TRACE("DB: (Events) Event processor loop was started\n");
+
+    while (!ixEthDBLearningShutdown)
+    {
+        BOOL keepProcessing    = true;
+        UINT32 processedEvents = 0;
+
+        IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Waiting for new learning event...\n");
+
+        ixOsalSemaphoreWait(&eventQueueSemaphore, IX_OSAL_WAIT_FOREVER);
+
+        IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Received new event\n");
+
+        if (!ixEthDBLearningShutdown)
+        {
+            /* port update handling */
+            SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
+
+            while (keepProcessing)
+            {
+                PortEvent local_event;
+                UINT32 intLockKey;
+
+                /* lock queue */
+                ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER);
+
+                /* lock NPE interrupts */
+                intLockKey = ixOsalIrqLock();
+
+                /* extract event */
+                local_event = *(QUEUE_TAIL(&eventQueue));
+
+                SHIFT_UPDATE_QUEUE(&eventQueue);
+
+                ixOsalIrqUnlock(intLockKey);
+
+                ixOsalMutexUnlock(&eventQueueLock);
+
+                IX_ETH_DB_EVENTS_TRACE("DB: (Events) Processing event with ID 0x%X\n", local_event.eventType);
+
+                ixEthDBProcessEvent(&local_event, triggerPorts);
+
+                processedEvents++;
+
+                if (processedEvents > EVENT_PROCESSING_LIMIT /* maximum burst reached? */
+                    || ixOsalSemaphoreTryWait(&eventQueueSemaphore) != IX_SUCCESS) /* or empty queue? */
+                {
+                    keepProcessing = false;
+                }
+            }
+
+            ixEthDBUpdatePortLearningTrees(triggerPorts);
+        }
+    }
+
+    /* turn off automatic updates */
+    for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+    {
+        ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = false;
+    }
+
+    ixEthDBEventProcessorRunning = false;
+}
+
+/**
+ * @brief event processor routine
+ *
+ * @param event event to be processed
+ * @param triggerPorts port map accumulating ports to be updated
+ *
+ * Processes learning events by synchronizing the database with
+ * newly learnt data. Called only by @ref ixEthDBEventProcessorLoop().
+ *
+ * @warning do not call directly
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBProcessEvent(PortEvent *local_event, IxEthDBPortMap triggerPorts)
+{
+    MacDescriptor recordTemplate;
+
+    switch (local_event->eventType)
+    {
+        case IX_ETH_DB_ADD_FILTERING_RECORD:
+            /* add record */
+            memset(&recordTemplate, 0, sizeof (recordTemplate));
+            memcpy(recordTemplate.macAddress, local_event->macAddr.macAddress, sizeof (IxEthDBMacAddr));
+            
+            recordTemplate.type   = IX_ETH_DB_FILTERING_RECORD;
+            recordTemplate.portID = local_event->portID;
+            recordTemplate.recordData.filteringData.staticEntry = local_event->staticEntry;
+            
+            ixEthDBAdd(&recordTemplate, triggerPorts);
+
+            IX_ETH_DB_EVENTS_TRACE("DB: (Events) Added record on port %d\n", local_event->portID);
+
+            break;
+
+        case IX_ETH_DB_REMOVE_FILTERING_RECORD:
+            /* remove record */
+            memset(&recordTemplate, 0, sizeof (recordTemplate));
+            memcpy(recordTemplate.macAddress, local_event->macAddr.macAddress, sizeof (IxEthDBMacAddr));
+            
+            recordTemplate.type = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD;
+            
+            ixEthDBRemove(&recordTemplate, triggerPorts);
+            
+            IX_ETH_DB_EVENTS_TRACE("DB: (Events) Removed record on port %d\n", local_event->portID);
+
+            break;
+
+        default:
+            /* can't handle/not interested in this event type */
+            ERROR_LOG("DB: (Events) Event processor received an unknown event type (0x%X)\n", local_event->eventType);
+
+            return;
+    }
+}
+
+/**
+ * @brief asynchronously adds a filtering record
+ * by posting an ADD_FILTERING_RECORD event to the event queue
+ *
+ * @param macAddr MAC address of the new record
+ * @param portID port ID of the new record
+ * @param staticEntry true if record is static, false if dynamic
+ *
+ * @return IX_ETH_DB_SUCCESS if the event creation was
+ * successfull or IX_ETH_DB_BUSY if the event queue is full
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry)
+{
+    MacDescriptor reference;
+    
+    TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
+
+    /* fill search fields */
+    memcpy(reference.macAddress, macAddr, sizeof (IxEthDBMacAddr));
+    reference.portID = portID;
+    
+    /* set acceptable record types */
+    reference.type = IX_ETH_DB_ALL_FILTERING_RECORDS;
+
+    if (ixEthDBPeekHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference) == IX_ETH_DB_SUCCESS)
+    {
+        /* already have an identical record */
+        return IX_ETH_DB_SUCCESS;
+    }
+    else
+    {
+        return ixEthDBTriggerPortUpdate(IX_ETH_DB_ADD_FILTERING_RECORD, macAddr, portID, staticEntry);
+    }
+}
+
+/**
+ * @brief asynchronously removes a filtering record
+ * by posting a REMOVE_FILTERING_RECORD event to the event queue
+ *
+ * @param macAddr MAC address of the record to remove
+ * @param portID port ID of the record to remove
+ *
+ * @return IX_ETH_DB_SUCCESS if the event creation was
+ * successfull or IX_ETH_DB_BUSY if the event queue is full
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID)
+{
+    if (ixEthDBPeek(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS) != IX_ETH_DB_NO_SUCH_ADDR)
+    {
+        return ixEthDBTriggerPortUpdate(IX_ETH_DB_REMOVE_FILTERING_RECORD, macAddr, portID, false);
+    }
+    else
+    {
+        return IX_ETH_DB_NO_SUCH_ADDR;
+    }
+}
+
+/**
+ * @brief adds an ADD or REMOVE event to the main event queue
+ *
+ * @param eventType event type - IX_ETH_DB_ADD_FILTERING_RECORD 
+ * to add and IX_ETH_DB_REMOVE_FILTERING_RECORD to remove a
+ * record.
+ *
+ * @return IX_ETH_DB_SUCCESS if the event was successfully
+ * sent or IX_ETH_DB_BUSY if the event queue is full
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry)
+{
+    UINT32 intLockKey;
+
+    /* lock interrupts to protect queue */
+    intLockKey = ixOsalIrqLock();
+
+    if (CAN_ENQUEUE(&eventQueue))
+    {
+        PortEvent *queueEvent = QUEUE_HEAD(&eventQueue);
+
+        /* update fields on the queue */
+        memcpy(queueEvent->macAddr.macAddress, macAddr->macAddress, sizeof (IxEthDBMacAddr));
+        
+        queueEvent->eventType     = eventType;
+        queueEvent->portID        = portID;
+        queueEvent->staticEntry   = staticEntry;
+
+        PUSH_UPDATE_QUEUE(&eventQueue);
+
+        /* imcrement event queue semaphore */
+        ixOsalSemaphorePost(&eventQueueSemaphore);
+        
+        /* unlock interrupts */
+        ixOsalIrqUnlock(intLockKey);
+
+        return IX_ETH_DB_SUCCESS;
+    }
+    else /* event queue full */
+    {
+        /* unlock interrupts */
+        ixOsalIrqUnlock(intLockKey);
+
+        return IX_ETH_DB_BUSY;
+    }
+}
+
+/**
+ * @brief Locks learning tree updates and port disable
+ *
+ *
+ * This function locks portUpdateLock single mutex. It is primarily used
+ * to avoid executing 'port disable' during ELT maintenance.
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBUpdateLock(void)
+{
+    ixOsalMutexLock(&portUpdateLock, IX_OSAL_WAIT_FOREVER);
+}
+
+/**
+ * @brief Unlocks learning tree updates and port disable
+ *
+ *
+ * This function unlocks a portUpdateLock mutex. It is primarily used
+ * to avoid executing 'port disable' during ELT maintenance.
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBUpdateUnlock(void)
+{
+    ixOsalMutexUnlock(&portUpdateLock);
+}
+
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBFeatures.c b/marvell/uboot/drivers/net/npe/IxEthDBFeatures.c
new file mode 100644
index 0000000..1f76240
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBFeatures.c
@@ -0,0 +1,638 @@
+/**
+ * @file IxEthDBFeatures.c
+ *
+ * @brief Implementation of the EthDB feature control API
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxNpeDl.h"
+#include "IxEthDBQoS.h"
+#include "IxEthDB_p.h"
+
+/**
+ * @brief scans the capabilities of the loaded NPE images
+ *
+ * This function MUST be called by the ixEthDBInit() function.
+ * No EthDB features (including learning and filtering) are enabled
+ * before this function is called.
+ *
+ * @return none
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBFeatureCapabilityScan(void)
+{
+    IxNpeDlImageId imageId, npeAImageId;
+    IxEthDBPortId portIndex;
+    PortInfo *portInfo;
+    IxEthDBPriorityTable defaultPriorityTable;
+    IX_STATUS result;
+    UINT32 queueIndex;
+    UINT32 queueStructureIndex;
+    UINT32 trafficClassDefinitionIndex;
+
+    /* read version of NPE A - required to set the AQM queues for B and C */
+    npeAImageId.functionalityId = 0;
+    ixNpeDlLoadedImageGet(IX_NPEDL_NPEID_NPEA, &npeAImageId);
+
+    for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+    {
+        IxNpeMhMessage msg;
+
+        portInfo = &ixEthDBPortInfo[portIndex];
+
+        /* check and bypass if NPE B or C is fused out */
+        if (ixEthDBSingleEthNpeCheck(portIndex) != IX_ETH_DB_SUCCESS) continue;
+
+        /* all ports are capable of LEARNING by default */
+        portInfo->featureCapability |= IX_ETH_DB_LEARNING;
+        portInfo->featureStatus     |= IX_ETH_DB_LEARNING;
+
+        if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
+        {
+
+            if (ixNpeDlLoadedImageGet(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), &imageId) != IX_SUCCESS)
+            {
+                WARNING_LOG("DB: (FeatureScan) NpeDl did not provide the image ID for NPE port %d\n", portIndex);
+            }
+            else
+            {
+                /* initialize and empty NPE response mutex */
+                ixOsalMutexInit(&portInfo->npeAckLock);
+                ixOsalMutexLock(&portInfo->npeAckLock, IX_OSAL_WAIT_FOREVER);
+
+                /* check NPE response to GetStatus */
+                msg.data[0] = IX_ETHNPE_NPE_GETSTATUS << 24;
+                msg.data[1] = 0;
+                IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), msg, result);
+                if (result != IX_SUCCESS)
+                {
+                    WARNING_LOG("DB: (FeatureScan) warning, could not send message to the NPE\n");
+                    continue;
+                }
+
+
+                if (imageId.functionalityId == 0x00
+                    || imageId.functionalityId == 0x03
+                    || imageId.functionalityId == 0x04
+                    || imageId.functionalityId == 0x80)
+                {
+                    portInfo->featureCapability |= IX_ETH_DB_FILTERING;
+                    portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
+                    portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
+                }
+                else if (imageId.functionalityId == 0x01
+                         || imageId.functionalityId == 0x81)
+                {
+                    portInfo->featureCapability |= IX_ETH_DB_FILTERING;
+                    portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
+                    portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
+                    portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS;
+                }
+                else if (imageId.functionalityId == 0x02
+                         || imageId.functionalityId == 0x82)
+                {
+                    portInfo->featureCapability |= IX_ETH_DB_WIFI_HEADER_CONVERSION;
+                    portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
+                    portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
+                    portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS;
+                }
+
+                /* reset AQM queues */
+                memset(portInfo->ixEthDBTrafficClassAQMAssignments, 0, sizeof (portInfo->ixEthDBTrafficClassAQMAssignments));
+
+                /* ensure there's at least one traffic class record in the definition table, otherwise we have no default case, hence no queues */
+                IX_ENSURE(sizeof (ixEthDBTrafficClassDefinitions) != 0, "DB: no traffic class definitions found, check IxEthDBQoS.h");
+
+                /* find the traffic class definition index compatible with the current NPE A functionality ID */
+                for (trafficClassDefinitionIndex = 0 ;
+                    trafficClassDefinitionIndex < ARRAY_SIZE(ixEthDBTrafficClassDefinitions);
+                    trafficClassDefinitionIndex++)
+                {
+                    if (ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX] == npeAImageId.functionalityId)
+                    {
+                        /* found it */
+                        break;
+                    }
+                }
+
+                /* select the default case if we went over the array boundary */
+                if (trafficClassDefinitionIndex == ARRAY_SIZE(ixEthDBTrafficClassDefinitions))
+                {
+                    trafficClassDefinitionIndex = 0; /* the first record is the default case */
+                }
+
+                /* select queue assignment structure based on the traffic class configuration index */
+                queueStructureIndex = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX];
+
+                /* only traffic class 0 is active at initialization time */
+                portInfo->ixEthDBTrafficClassCount = 1;
+
+                /* enable port, VLAN and Firewall feature bits to initialize QoS/VLAN/Firewall configuration */
+                portInfo->featureStatus |= IX_ETH_DB_VLAN_QOS;
+                portInfo->featureStatus |= IX_ETH_DB_FIREWALL;
+                portInfo->enabled        = true;
+
+#define CONFIG_WITH_VLAN  /* test-only: VLAN support not included to save space!!! */
+#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
+                /* set VLAN initial configuration (permissive) */
+                if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) /* QoS-enabled image */
+                {
+                    /* QoS capable */
+                    portInfo->ixEthDBTrafficClassAvailable = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX];
+
+                    /* set AQM queues */
+                    for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++)
+                    {
+                        portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] = ixEthDBQueueAssignments[queueStructureIndex][queueIndex];
+                    }
+
+                    /* set default PVID (0) and default traffic class 0 */
+                    ixEthDBPortVlanTagSet(portIndex, 0);
+
+                    /* enable reception of all frames */
+                    ixEthDBAcceptableFrameTypeSet(portIndex, IX_ETH_DB_ACCEPT_ALL_FRAMES);
+
+                    /* clear full VLAN membership */
+                    ixEthDBPortVlanMembershipRangeRemove(portIndex, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID);
+
+                    /* clear TTI table - no VLAN tagged frames will be transmitted */
+                    ixEthDBEgressVlanRangeTaggingEnabledSet(portIndex, 0, 4094, false);
+
+                    /* set membership on 0, otherwise no Tx or Rx is working */
+                    ixEthDBPortVlanMembershipAdd(portIndex, 0);
+                }
+                else /* QoS not available in this image */
+#endif /* test-only */
+                {
+                    /* initialize traffic class availability (only class 0 is available) */
+                    portInfo->ixEthDBTrafficClassAvailable = 1;
+
+                    /* point all AQM queues to traffic class 0 */
+                    for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++)
+                    {
+                        portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] =
+                            ixEthDBQueueAssignments[queueStructureIndex][0];
+                    }
+                }
+
+#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
+                /* download priority mapping table and Rx queue configuration */
+                memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable));
+                ixEthDBPriorityMappingTableSet(portIndex, defaultPriorityTable);
+#endif
+
+                /* by default we turn off invalid source MAC address filtering */
+                ixEthDBFirewallInvalidAddressFilterEnable(portIndex, false);
+
+                /* disable port, VLAN, Firewall feature bits */
+                portInfo->featureStatus &= ~IX_ETH_DB_VLAN_QOS;
+                portInfo->featureStatus &= ~IX_ETH_DB_FIREWALL;
+                portInfo->enabled        = false;
+
+                /* enable filtering by default if present */
+                if ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0)
+                {
+                    portInfo->featureStatus |= IX_ETH_DB_FILTERING;
+                }
+            }
+        }
+    }
+}
+
+/**
+ * @brief returns the capability of a port
+ *
+ * @param portID ID of the port
+ * @param featureSet location to store the port capability in
+ *
+ * This function will save the capability set of the given port
+ * into the given location. Capabilities are bit-ORed, each representing
+ * a bit of the feature set.
+ *
+ * Note that this function is documented in the main component
+ * public header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or IX_ETH_DB_INVALID_PORT if the given port is invalid
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet)
+{
+    IX_ETH_DB_CHECK_PORT_INITIALIZED(portID);
+
+    IX_ETH_DB_CHECK_REFERENCE(featureSet);
+
+    *featureSet = ixEthDBPortInfo[portID].featureCapability;
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief enables or disables a port capability
+ *
+ * @param portID ID of the port
+ * @param feature feature to enable or disable
+ * @param enabled true to enable the selected feature or false to disable it
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enable)
+{
+    PortInfo *portInfo;
+    IxEthDBPriorityTable defaultPriorityTable;
+    IxEthDBVlanSet vlanSet;
+    IxEthDBStatus status = IX_ETH_DB_SUCCESS;
+    BOOL portEnabled;
+
+    IX_ETH_DB_CHECK_PORT_INITIALIZED(portID);
+
+    portInfo    = &ixEthDBPortInfo[portID];
+    portEnabled = portInfo->enabled;
+
+    /* check that only one feature is selected */
+    if (!ixEthDBCheckSingleBitValue(feature))
+    {
+        return IX_ETH_DB_FEATURE_UNAVAILABLE;
+    }
+
+    /* port capable of this feature? */
+    if ((portInfo->featureCapability & feature) == 0)
+    {
+        return IX_ETH_DB_FEATURE_UNAVAILABLE;
+    }
+
+    /* mutual exclusion between learning and WiFi header conversion */
+    if (enable && ((feature | portInfo->featureStatus) & (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION))
+            == (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION))
+    {
+        return IX_ETH_DB_NO_PERMISSION;
+    }
+
+    /* learning must be enabled before filtering */
+    if (enable && (feature == IX_ETH_DB_FILTERING) && ((portInfo->featureStatus & IX_ETH_DB_LEARNING) == 0))
+    {
+        return IX_ETH_DB_NO_PERMISSION;
+    }
+
+    /* filtering must be disabled before learning */
+    if (!enable && (feature == IX_ETH_DB_LEARNING) && ((portInfo->featureStatus & IX_ETH_DB_FILTERING) != 0))
+    {
+        return IX_ETH_DB_NO_PERMISSION;
+    }
+
+    /* redundant enabling or disabling */
+    if ((!enable && ((portInfo->featureStatus & feature) == 0))
+        || (enable && ((portInfo->featureStatus & feature) != 0)))
+    {
+        /* do nothing */
+        return IX_ETH_DB_SUCCESS;
+    }
+
+    /* force port enabled */
+    portInfo->enabled = true;
+
+    if (enable)
+    {
+        /* turn on enable bit */
+        portInfo->featureStatus |= feature;
+
+#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
+        /* if this is VLAN/QoS set the default priority table */
+        if (feature == IX_ETH_DB_VLAN_QOS)
+        {
+            /* turn on VLAN/QoS (most permissive mode):
+                - set default 802.1Q priority mapping table, in accordance to the
+                  availability of traffic classes
+                - set the acceptable frame filter to accept all
+                - set the Ingress tagging mode to pass-through
+                - set full VLAN membership list
+                - set full TTI table
+                - set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0)
+                - enable TPID port extraction
+            */
+
+            portInfo->ixEthDBTrafficClassCount = portInfo->ixEthDBTrafficClassAvailable;
+
+            /* set default 802.1Q priority mapping table - note that C indexing starts from 0, so we substract 1 here */
+            memcpy (defaultPriorityTable,
+                (const void *) ixEthIEEE802_1QUserPriorityToTrafficClassMapping[portInfo->ixEthDBTrafficClassCount - 1],
+                sizeof (defaultPriorityTable));
+
+            /* update priority mapping and AQM queue assignments */
+            status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable);
+
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
+            }
+
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH);
+            }
+
+            /* set membership and TTI tables */
+            memset (vlanSet, 0xFF, sizeof (vlanSet));
+
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                /* use the internal function to bypass PVID check */
+                status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet);
+            }
+
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                /* use the internal function to bypass PVID check */
+                status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet);
+            }
+
+            /* reset the PVID */
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                status = ixEthDBPortVlanTagSet(portID, 0);
+            }
+
+            /* enable TPID port extraction */
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                status = ixEthDBVlanPortExtractionEnable(portID, true);
+            }
+        }
+        else if (feature == IX_ETH_DB_FIREWALL)
+#endif
+        {
+            /* firewall starts in black-list mode unless otherwise configured before *
+             * note that invalid source MAC address filtering is disabled by default */
+            if (portInfo->firewallMode != IX_ETH_DB_FIREWALL_BLACK_LIST
+                && portInfo->firewallMode != IX_ETH_DB_FIREWALL_WHITE_LIST)
+            {
+                status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
+
+                if (status == IX_ETH_DB_SUCCESS)
+                {
+                    status = ixEthDBFirewallInvalidAddressFilterEnable(portID, false);
+                }
+            }
+        }
+
+        if (status != IX_ETH_DB_SUCCESS)
+        {
+            /* checks failed, disable */
+            portInfo->featureStatus &= ~feature;
+        }
+    }
+    else
+    {
+        /* turn off features */
+        if (feature == IX_ETH_DB_FIREWALL)
+        {
+            /* turning off the firewall is equivalent to:
+                - set to black-list mode
+                - clear all the entries and download the new table
+                - turn off the invalid source address checking
+            */
+
+            status = ixEthDBDatabaseClear(portID, IX_ETH_DB_FIREWALL_RECORD);
+
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
+            }
+
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                status = ixEthDBFirewallInvalidAddressFilterEnable(portID, false);
+            }
+
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                status = ixEthDBFirewallTableDownload(portID);
+            }
+        }
+        else if (feature == IX_ETH_DB_WIFI_HEADER_CONVERSION)
+        {
+            /* turn off header conversion */
+            status = ixEthDBDatabaseClear(portID, IX_ETH_DB_WIFI_RECORD);
+
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                status = ixEthDBWiFiConversionTableDownload(portID);
+            }
+        }
+#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
+        else if (feature == IX_ETH_DB_VLAN_QOS)
+        {
+            /* turn off VLAN/QoS:
+                - set a priority mapping table with one traffic class
+                - set the acceptable frame filter to accept all
+                - set the Ingress tagging mode to pass-through
+                - clear the VLAN membership list
+                - clear the TTI table
+                - set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0)
+                - disable TPID port extraction
+            */
+
+            /* initialize all => traffic class 0 priority mapping table */
+            memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable));
+            portInfo->ixEthDBTrafficClassCount = 1;
+            status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable);
+
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
+            }
+
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH);
+            }
+
+            /* clear membership and TTI tables */
+            memset (vlanSet, 0, sizeof (vlanSet));
+
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                /* use the internal function to bypass PVID check */
+                status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet);
+            }
+
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                /* use the internal function to bypass PVID check */
+                status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet);
+            }
+
+            /* reset the PVID */
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                status = ixEthDBPortVlanTagSet(portID, 0);
+            }
+
+            /* disable TPID port extraction */
+            if (status == IX_ETH_DB_SUCCESS)
+            {
+                status = ixEthDBVlanPortExtractionEnable(portID, false);
+            }
+        }
+#endif
+
+        if (status == IX_ETH_DB_SUCCESS)
+        {
+            /* checks passed, disable */
+            portInfo->featureStatus &= ~feature;
+        }
+    }
+
+    /* restore port enabled state */
+    portInfo->enabled = portEnabled;
+
+    return status;
+}
+
+/**
+ * @brief returns the status of a feature
+ *
+ * @param portID port ID
+ * @param present location to store a boolean value indicating
+ * if the feature is present (true) or not (false)
+ * @param enabled location to store a booleam value indicating
+ * if the feature is present (true) or not (false)
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled)
+{
+    PortInfo *portInfo;
+
+    IX_ETH_DB_CHECK_PORT(portID);
+
+    IX_ETH_DB_CHECK_REFERENCE(present);
+
+    IX_ETH_DB_CHECK_REFERENCE(enabled);
+
+    portInfo = &ixEthDBPortInfo[portID];
+
+    *present = (portInfo->featureCapability & feature) != 0;
+    *enabled = (portInfo->featureStatus & feature) != 0;
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief returns the value of an EthDB property
+ *
+ * @param portID ID of the port
+ * @param feature feature owning the property
+ * @param property ID of the property
+ * @param type location to store the property type into
+ * @param value location to store the property value into
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value)
+{
+    IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+    IX_ETH_DB_CHECK_REFERENCE(type);
+
+    IX_ETH_DB_CHECK_REFERENCE(value);
+
+    if (feature == IX_ETH_DB_VLAN_QOS)
+    {
+        if (property == IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY)
+        {
+            * (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount;
+            *type              = IX_ETH_DB_INTEGER_PROPERTY;
+
+            return IX_ETH_DB_SUCCESS;
+        }
+        else if (property >= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY
+            && property <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY)
+        {
+            UINT32 classDelta = property - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
+
+            if (classDelta >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount)
+            {
+                return IX_ETH_DB_FAIL;
+            }
+
+            * (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[classDelta];
+            *type              = IX_ETH_DB_INTEGER_PROPERTY;
+
+            return IX_ETH_DB_SUCCESS;
+        }
+    }
+
+    return IX_ETH_DB_INVALID_ARG;
+}
+
+/**
+ * @brief sets the value of an EthDB property
+ *
+ * @param portID ID of the port
+ * @param feature feature owning the property
+ * @param property ID of the property
+ * @param value location containing the property value
+ *
+ * This function implements a private property intended
+ * only for EthAcc usage. Upon setting the IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE
+ * property (the value is ignored), the availability of traffic classes is
+ * frozen to whatever traffic class structure is currently in use.
+ * This means that if VLAN_QOS has been enabled before EthAcc
+ * initialization then all the defined traffic classes will be available;
+ * otherwise only one traffic class (0) will be available.
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h as not accepting any parameters. The
+ * current implementation is only intended for the private use of EthAcc.
+ *
+ * Also note that once this function is called the effect is irreversible,
+ * unless EthDB is complete unloaded and re-initialized.
+ *
+ * @return IX_ETH_DB_INVALID_ARG (no read-write properties are
+ * supported in this release)
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value)
+{
+    IX_ETH_DB_CHECK_PORT_EXISTS(portID);
+
+    if ((feature == IX_ETH_DB_VLAN_QOS) && (property == IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE))
+    {
+        ixEthDBPortInfo[portID].ixEthDBTrafficClassAvailable = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount;
+
+        return IX_ETH_DB_SUCCESS;
+    }
+
+    return IX_ETH_DB_INVALID_ARG;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBFirewall.c b/marvell/uboot/drivers/net/npe/IxEthDBFirewall.c
new file mode 100644
index 0000000..c0ae562
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBFirewall.c
@@ -0,0 +1,242 @@
+/**
+ * @file IxEthDBFirewall.c
+ *
+ * @brief Implementation of the firewall API
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#include "IxEthDB_p.h"
+
+/**
+ * @brief updates the NPE firewall operating mode and 
+ * firewall address table
+ *
+ * @param portID ID of the port
+ * @param epDelta initial entry point for binary searches (NPE optimization)
+ * @param address address of the firewall MAC address table
+ *
+ * This function will send a message to the NPE configuring the
+ * firewall mode (white list or black list), invalid source 
+ * address filtering and downloading a new MAC address database 
+ * to be used for firewall matching.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed 
+ * successfully or IX_ETH_DB_FAIL otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta)
+{
+    IxNpeMhMessage message;
+    IX_STATUS result;
+    
+    UINT32 mode        = 0;    
+    PortInfo *portInfo = &ixEthDBPortInfo[portID];
+
+    mode = (portInfo->srcAddressFilterEnabled != false) << 1 | (portInfo->firewallMode == IX_ETH_DB_FIREWALL_WHITE_LIST);
+
+    FILL_SETFIREWALLMODE_MSG(message, 
+        IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 
+        epDelta, 
+        mode, 
+        IX_OSAL_MMU_VIRT_TO_PHYS(address));
+
+    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+    
+    return result;
+}
+
+/**
+ * @brief configures the firewall white list/black list
+ * access mode
+ *
+ * @param portID ID of the port
+ * @param mode firewall filtering mode (IX_ETH_DB_FIREWALL_WHITE_LIST
+ * or IX_ETH_DB_FIREWALL_BLACK_LIST)
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+     
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
+    
+    if (mode != IX_ETH_DB_FIREWALL_WHITE_LIST
+        && mode != IX_ETH_DB_FIREWALL_BLACK_LIST)
+    {
+        return IX_ETH_DB_INVALID_ARG;
+    }    
+    
+    ixEthDBPortInfo[portID].firewallMode = mode;
+    
+    return ixEthDBFirewallTableDownload(portID);
+}
+
+/**
+ * @brief enables or disables the invalid source MAC address filter
+ *
+ * @param portID ID of the port
+ * @param enable true to enable invalid source MAC address filtering
+ * or false to disable it
+ *
+ * The invalid source MAC address filter will discard, when enabled,
+ * frames whose source MAC address is a multicast or the broadcast MAC
+ * address.
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed 
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
+
+    ixEthDBPortInfo[portID].srcAddressFilterEnabled = enable;
+    
+    return ixEthDBFirewallTableDownload(portID);
+}
+
+/**
+ * @brief adds a firewall record
+ *
+ * @param portID ID of the port
+ * @param macAddr MAC address of the new record
+ *
+ * This function will add a new firewall record
+ * on the specified port, using the specified 
+ * MAC address. If the record already exists this
+ * function will silently return IX_ETH_DB_SUCCESS,
+ * although no duplicate records are added.
+ *
+ * Note that this function is documented in the main
+ * component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+    MacDescriptor recordTemplate;
+
+    IX_ETH_DB_CHECK_PORT(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
+    
+    memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
+    
+    recordTemplate.type   = IX_ETH_DB_FIREWALL_RECORD;
+    recordTemplate.portID = portID;
+    
+    return ixEthDBAdd(&recordTemplate, NULL);
+}
+
+/**
+ * @brief removes a firewall record
+ *
+ * @param portID ID of the port
+ * @param macAddr MAC address of the record to remove
+ *
+ * This function will attempt to remove a firewall
+ * record from the given port, using the specified
+ * MAC address.
+ *
+ * Note that this function is documented in the main
+ * component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully of an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+    MacDescriptor recordTemplate;
+    
+    IX_ETH_DB_CHECK_PORT(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    IX_ETH_DB_CHECK_REFERENCE(macAddr);
+
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
+    
+    memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
+    
+    recordTemplate.type   = IX_ETH_DB_FIREWALL_RECORD;
+    recordTemplate.portID = portID;
+    
+    return ixEthDBRemove(&recordTemplate, NULL);
+}
+
+/**
+ * @brief downloads the firewall address table to an NPE
+ *
+ * @param portID ID of the port
+ *
+ * This function will download the firewall address table to
+ * an NPE port.
+ *
+ * Note that this function is documented in the main 
+ * component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or IX_ETH_DB_FAIL otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID)
+{
+    IxEthDBPortMap query;
+    IxEthDBStatus result;
+    
+    IX_ETH_DB_CHECK_PORT(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL);
+    
+    SET_DEPENDENCY_MAP(query, portID);
+
+    ixEthDBUpdateLock();
+    
+    ixEthDBPortInfo[portID].updateMethod.searchTree = ixEthDBQuery(NULL, query, IX_ETH_DB_FIREWALL_RECORD, MAX_FW_SIZE);
+    
+    result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FIREWALL_RECORD);
+
+    ixEthDBUpdateUnlock();
+
+    return result;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBHashtable.c b/marvell/uboot/drivers/net/npe/IxEthDBHashtable.c
new file mode 100644
index 0000000..9493a5b
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBHashtable.c
@@ -0,0 +1,618 @@
+/**
+ * @file ethHash.c
+ *
+ * @brief Hashtable implementation
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#include "IxEthDB_p.h"
+#include "IxEthDBLocks_p.h"
+
+/**
+ * @addtogroup EthDB
+ *
+ * @{
+ */
+
+/**
+ * @brief initializes a hash table object
+ *
+ * @param hashTable uninitialized hash table structure
+ * @param numBuckets number of buckets to use
+ * @param entryHashFunction hash function used 
+ * to hash entire hash node data block (for adding)
+ * @param matchFunctions array of match functions, indexed on type,
+ * used to differentiate records with the same hash value
+ * @param freeFunction function used to free node data blocks
+ *
+ * Initializes the given hash table object.
+ *
+ * @internal
+ */
+void ixEthDBInitHash(HashTable *hashTable, 
+                     UINT32 numBuckets, 
+                     HashFunction entryHashFunction, 
+                     MatchFunction *matchFunctions, 
+                     FreeFunction freeFunction)
+{
+    UINT32 bucketIndex;
+    UINT32 hashSize = numBuckets * sizeof(HashNode *);
+
+    /* entry hashing, matching and freeing methods */
+    hashTable->entryHashFunction  = entryHashFunction;
+    hashTable->matchFunctions     = matchFunctions;
+    hashTable->freeFunction       = freeFunction;
+
+    /* buckets */
+    hashTable->numBuckets = numBuckets;
+
+    /* set to 0 all buckets */
+    memset(hashTable->hashBuckets, 0, hashSize);
+
+    /* init bucket locks - note that initially all mutexes are unlocked after MutexInit()*/
+    for (bucketIndex = 0 ; bucketIndex < numBuckets ; bucketIndex++)
+    {
+        ixOsalFastMutexInit(&hashTable->bucketLocks[bucketIndex]);
+    }
+}
+
+/**
+ * @brief adds an entry to the hash table
+ *
+ * @param hashTable hash table to add the entry to
+ * @param entry entry to add
+ *
+ * The entry will be hashed using the entry hashing function and added to the
+ * hash table, unless a locking blockage occurs, in which case the caller
+ * should retry.
+ *
+ * @retval IX_ETH_DB_SUCCESS if adding <i>entry</i> has succeeded
+ * @retval IX_ETH_DB_NOMEM if there's no memory left in the hash node pool
+ * @retval IX_ETH_DB_BUSY if there's a locking failure on the insertion path
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry)
+{
+    UINT32 hashValue   = hashTable->entryHashFunction(entry);
+    UINT32 bucketIndex = hashValue % hashTable->numBuckets;
+    HashNode *bucket   = hashTable->hashBuckets[bucketIndex];
+    HashNode *newNode;
+
+    LockStack locks;
+
+    INIT_STACK(&locks);
+
+    /* lock bucket */
+    PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]);
+
+    /* lock insertion element (first in chain), if any */
+    if (bucket != NULL)
+    {
+        PUSH_LOCK(&locks, &bucket->lock);
+    }
+
+    /* get new node */
+    newNode = ixEthDBAllocHashNode();
+
+    if (newNode == NULL)
+    {
+        /* unlock everything */
+        UNROLL_STACK(&locks);
+
+        return IX_ETH_DB_NOMEM;
+    }
+
+    /* init lock - note that mutexes are unlocked after MutexInit */
+    ixOsalFastMutexInit(&newNode->lock);
+
+    /* populate new link */
+    newNode->data = entry;
+
+    /* add to bucket */
+    newNode->next                       = bucket;
+    hashTable->hashBuckets[bucketIndex] = newNode;
+
+    /* unlock bucket and insertion point */
+    UNROLL_STACK(&locks);
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief removes an entry from the hashtable
+ *
+ * @param hashTable hash table to remove entry from
+ * @param keyType type of record key used for matching
+ * @param reference reference key used to identify the entry
+ *
+ * The reference key will be hashed using the key hashing function,
+ * the entry is searched using the hashed value and then examined
+ * against the reference entry using the match function. A positive
+ * match will trigger the deletion of the entry.
+ * Locking failures are reported and the caller should retry.
+ *
+ * @retval IX_ETH_DB_SUCCESS if the removal was successful
+ * @retval IX_ETH_DB_NO_SUCH_ADDR if the entry was not found
+ * @retval IX_ETH_DB_BUSY if a locking failure occured during the process
+ *
+ * @internal
+ */
+IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference)
+{
+    UINT32 hashValue       = hashTable->entryHashFunction(reference);
+    UINT32 bucketIndex     = hashValue % hashTable->numBuckets;
+    HashNode *node         = hashTable->hashBuckets[bucketIndex];
+    HashNode *previousNode = NULL;
+    
+    LockStack locks;
+
+    INIT_STACK(&locks);
+
+    while (node != NULL)
+    {
+        /* try to lock node */
+        PUSH_LOCK(&locks, &node->lock);
+
+        if (hashTable->matchFunctions[keyType](reference, node->data))
+        {
+            /* found entry */
+            if (node->next != NULL)
+            {
+                PUSH_LOCK(&locks, &node->next->lock);
+            }
+
+            if (previousNode == NULL)
+            {
+                /* node is head of chain */
+                PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]);
+
+                hashTable->hashBuckets[bucketIndex] = node->next;
+
+                POP_LOCK(&locks);
+            }
+            else
+            {
+                /* relink */
+                previousNode->next = node->next;
+            }
+
+            UNROLL_STACK(&locks);
+
+            /* free node */
+            hashTable->freeFunction(node->data);
+            ixEthDBFreeHashNode(node);
+
+            return IX_ETH_DB_SUCCESS;
+        }
+        else
+        {
+            if (previousNode != NULL)
+            {
+                /* unlock previous node */
+                SHIFT_STACK(&locks);
+            }
+
+            /* advance to next element in chain */
+            previousNode = node;
+            node         = node->next;
+        }
+    }
+
+    UNROLL_STACK(&locks);
+
+    /* not found */
+    return IX_ETH_DB_NO_SUCH_ADDR;
+}
+
+/**
+ * @brief retrieves an entry from the hash table
+ *
+ * @param hashTable hash table to perform the search into
+ * @param reference search key (a MAC address)
+ * @param keyType type of record key used for matching
+ * @param searchResult pointer where a reference to the located hash node 
+ * is placed
+ *
+ * Searches the entry with the same key as <i>reference</i> and places the
+ * pointer to the resulting node in <i>searchResult</i>.
+ * An implicit write access lock is granted after a search, which gives the 
+ * caller the opportunity to modify the entry.
+ * Access should be released as soon as possible using @ref ixEthDBReleaseHashNode().
+ *
+ * @see ixEthDBReleaseHashNode()
+ *
+ * @retval IX_ETH_DB_SUCCESS if the search was completed successfully
+ * @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found
+ * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case
+ * the caller should retry
+ *
+ * @warning unless the return value is <b>IX_ETH_DB_SUCCESS</b> the searchResult
+ * location is NOT modified and therefore using a NULL comparison test when the
+ * value was not properly initialized would be an error
+ *
+ * @internal
+ */
+IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult)
+{
+    UINT32 hashValue;
+    HashNode *node;
+
+    hashValue = hashTable->entryHashFunction(reference);
+    node      = hashTable->hashBuckets[hashValue % hashTable->numBuckets];
+
+    while (node != NULL)
+    {
+        TRY_LOCK(&node->lock);
+
+        if (hashTable->matchFunctions[keyType](reference, node->data))
+        {
+            *searchResult = node;
+
+            return IX_ETH_DB_SUCCESS;
+        }
+        else
+        {
+            UNLOCK(&node->lock);
+
+            node = node->next;
+        }
+    }
+
+    /* not found */
+    return IX_ETH_DB_NO_SUCH_ADDR;
+}
+
+/**
+ * @brief reports the existence of an entry in the hash table
+ *
+ * @param hashTable hash table to perform the search into
+ * @param reference search key (a MAC address)
+ * @param keyType type of record key used for matching
+ *
+ * Searches the entry with the same key as <i>reference</i>.
+ * No implicit write access lock is granted after a search, hence the 
+ * caller cannot access or modify the entry. The result is only temporary.
+ *
+ * @see ixEthDBReleaseHashNode()
+ *
+ * @retval IX_ETH_DB_SUCCESS if the search was completed successfully
+ * @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found
+ * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case
+ * the caller should retry
+ *
+ * @internal
+ */
+IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference)
+{
+    UINT32 hashValue;
+    HashNode *node;
+
+    hashValue = hashTable->entryHashFunction(reference);
+    node      = hashTable->hashBuckets[hashValue % hashTable->numBuckets];
+
+    while (node != NULL)
+    {
+        TRY_LOCK(&node->lock);
+
+        if (hashTable->matchFunctions[keyType](reference, node->data))
+        {
+            UNLOCK(&node->lock);
+
+            return IX_ETH_DB_SUCCESS;
+        }
+        else
+        {
+            UNLOCK(&node->lock);
+
+            node = node->next;
+        }
+    }
+
+    /* not found */
+    return IX_ETH_DB_NO_SUCH_ADDR;
+}
+
+/**
+ * @brief releases the write access lock
+ *
+ * @pre the node should have been obtained via @ref ixEthDBSearchHashEntry()
+ *
+ * @see ixEthDBSearchHashEntry()
+ *
+ * @internal
+ */
+void ixEthDBReleaseHashNode(HashNode *node)
+{
+    UNLOCK(&node->lock);
+}
+
+/**
+ * @brief initializes a hash iterator
+ *
+ * @param hashTable hash table to be iterated
+ * @param iterator iterator object
+ *
+ * If the initialization is successful the iterator will point to the
+ * first hash table record (if any).
+ * Testing if the iterator has not passed the end of the table should be
+ * done using the IS_ITERATOR_VALID(iteratorPtr) macro.
+ * An implicit write access lock is granted on the entry pointed by the iterator.
+ * The access is automatically revoked when the iterator is incremented.
+ * If the caller decides to terminate the iteration before the end of the table is
+ * passed then the manual access release method, @ref ixEthDBReleaseHashIterator,
+ * must be called.
+ *
+ * @see ixEthDBReleaseHashIterator()
+ *
+ * @retval IX_ETH_DB_SUCCESS if initialization was successful and the iterator points
+ * to the first valid table node
+ * @retval IX_ETH_DB_FAIL if the table is empty
+ * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
+ * should retry
+ *
+ * @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this
+ * might place the database in a permanent invalid lock state
+ *
+ * @internal
+ */
+IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator)
+{
+    iterator->bucketIndex  = 0;
+    iterator->node         = NULL;
+    iterator->previousNode = NULL;
+
+    return ixEthDBIncrementHashIterator(hashTable, iterator);
+}
+
+/**
+ * @brief releases the write access locks of the iterator nodes
+ *
+ * @warning use of this function is required only when the caller terminates an iteration
+ * before reaching the end of the table
+ *
+ * @see ixEthDBInitHashIterator()
+ * @see ixEthDBIncrementHashIterator()
+ *
+ * @param iterator iterator whose node(s) should be unlocked
+ *
+ * @internal
+ */
+void ixEthDBReleaseHashIterator(HashIterator *iterator)
+{
+    if (iterator->previousNode != NULL)
+    {
+        UNLOCK(&iterator->previousNode->lock);
+    }
+
+    if (iterator->node != NULL)
+    {
+        UNLOCK(&iterator->node->lock);
+    }
+}
+
+/**
+ * @brief incremenents an iterator so that it points to the next valid entry of the table
+ * (if any)
+ *
+ * @param hashTable hash table to iterate
+ * @param iterator iterator object
+ *
+ * @pre the iterator object must be initialized using @ref ixEthDBInitHashIterator()
+ *
+ * If the increment operation is successful the iterator will point to the
+ * next hash table record (if any).
+ * Testing if the iterator has not passed the end of the table should be
+ * done using the IS_ITERATOR_VALID(iteratorPtr) macro.
+ * An implicit write access lock is granted on the entry pointed by the iterator.
+ * The access is automatically revoked when the iterator is re-incremented.
+ * If the caller decides to terminate the iteration before the end of the table is
+ * passed then the manual access release method, @ref ixEthDBReleaseHashIterator,
+ * must be called.
+ * Is is guaranteed that no other thread can remove or change the iterated entry until
+ * the iterator is incremented successfully.
+ *
+ * @see ixEthDBReleaseHashIterator()
+ *
+ * @retval IX_ETH_DB_SUCCESS if the operation was successful and the iterator points
+ * to the next valid table node
+ * @retval IX_ETH_DB_FAIL if the iterator has passed the end of the table
+ * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
+ * should retry
+ *
+ * @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this
+ * might place the database in a permanent invalid lock state
+ *
+ * @internal
+ */
+IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator)
+{
+    /* unless iterator is just initialized... */
+    if (iterator->node != NULL)
+    {
+        /* try next in chain */
+        if (iterator->node->next != NULL)
+        {
+            TRY_LOCK(&iterator->node->next->lock);
+
+            if (iterator->previousNode != NULL)
+            {
+                UNLOCK(&iterator->previousNode->lock);
+            }
+
+            iterator->previousNode = iterator->node;
+            iterator->node         = iterator->node->next;
+
+            return IX_ETH_DB_SUCCESS;
+        }
+        else
+        {
+            /* last in chain, prepare for next bucket */
+            iterator->bucketIndex++;
+        }
+    }
+
+   /* try next used bucket */
+    for (; iterator->bucketIndex < hashTable->numBuckets ; iterator->bucketIndex++)
+    {
+        HashNode **nodePtr = &(hashTable->hashBuckets[iterator->bucketIndex]);
+        HashNode *node = *nodePtr;
+#if (CPU!=SIMSPARCSOLARIS) && !defined (__wince)
+        if (((iterator->bucketIndex & IX_ETHDB_BUCKET_INDEX_MASK) == 0) &&
+            (iterator->bucketIndex < (hashTable->numBuckets - IX_ETHDB_BUCKETPTR_AHEAD)))
+        {
+            /* preload next cache line (2 cache line ahead) */
+            nodePtr += IX_ETHDB_BUCKETPTR_AHEAD;
+            __asm__ ("pld [%0];\n": : "r" (nodePtr));
+        }
+#endif
+        if (node != NULL)
+        {
+            TRY_LOCK(&node->lock);
+
+            /* unlock last one or two nodes in the previous chain */
+            if (iterator->node != NULL)
+            {
+                UNLOCK(&iterator->node->lock);
+
+                if (iterator->previousNode != NULL)
+                {
+                    UNLOCK(&iterator->previousNode->lock);
+                }
+            }
+            
+            /* redirect iterator */
+            iterator->previousNode = NULL;
+            iterator->node         = node;
+
+            return IX_ETH_DB_SUCCESS;
+        }
+    }
+
+    /* could not advance iterator */
+    if (iterator->node != NULL)
+    {
+        UNLOCK(&iterator->node->lock);
+
+        if (iterator->previousNode != NULL)
+        {
+            UNLOCK(&iterator->previousNode->lock);
+        }
+
+        iterator->node = NULL;
+    }
+
+    return IX_ETH_DB_END;
+}
+
+/**
+ * @brief removes an entry pointed by an iterator
+ *
+ * @param hashTable iterated hash table
+ * @param iterator iterator object
+ *
+ * Removes the entry currently pointed by the iterator and repositions the iterator
+ * on the next valid entry (if any). Handles locking issues automatically and
+ * implicitely grants write access lock to the new pointed entry.
+ * Failures due to concurrent threads having write access locks in the same region
+ * preserve the state of the database and the iterator object, leaving the caller
+ * free to retry without loss of access. It is guaranteed that only the thread owning
+ * the iterator can remove the object pointed by the iterator.
+ *
+ * @retval IX_ETH_DB_SUCCESS if removal has succeeded
+ * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller
+ * should retry
+ *
+ * @internal
+ */
+IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator)
+{
+    HashIterator nextIteratorPos;
+    LockStack locks;
+
+    INIT_STACK(&locks);
+
+    /* set initial bucket index for next position */
+    nextIteratorPos.bucketIndex = iterator->bucketIndex;
+
+    /* compute iterator position before removing anything and lock ahead */
+    if (iterator->node->next != NULL)
+    {
+        PUSH_LOCK(&locks, &iterator->node->next->lock);
+
+        /* reposition on the next node in the chain */
+        nextIteratorPos.node         = iterator->node->next;
+        nextIteratorPos.previousNode = iterator->previousNode;
+    }
+    else
+    {
+        /* try next chain - don't know yet if we'll find anything */
+        nextIteratorPos.node = NULL;
+
+        /* if we find something it's a chain head */
+        nextIteratorPos.previousNode = NULL;
+
+        /* browse up in the buckets to find a non-null chain */
+        while (++nextIteratorPos.bucketIndex < hashTable->numBuckets)
+        {
+            nextIteratorPos.node = hashTable->hashBuckets[nextIteratorPos.bucketIndex];
+
+            if (nextIteratorPos.node != NULL)
+            {
+                /* found a non-empty chain, try to lock head */
+                PUSH_LOCK(&locks, &nextIteratorPos.node->lock);
+
+                break;
+            }
+        }
+    }
+
+    /* restore links over the to-be-deleted item */
+    if (iterator->previousNode == NULL)
+    {
+        /* first in chain, lock bucket */
+        PUSH_LOCK(&locks, &hashTable->bucketLocks[iterator->bucketIndex]);
+
+        hashTable->hashBuckets[iterator->bucketIndex] = iterator->node->next;
+
+        POP_LOCK(&locks);
+    }
+    else
+    {
+        /* relink */
+        iterator->previousNode->next = iterator->node->next;
+
+        /* unlock last remaining node in current chain when moving between chains */
+        if (iterator->node->next == NULL)
+        {
+            UNLOCK(&iterator->previousNode->lock);
+        }
+    }
+
+    /* delete entry */
+    hashTable->freeFunction(iterator->node->data);
+    ixEthDBFreeHashNode(iterator->node);
+
+    /* reposition iterator */
+    *iterator = nextIteratorPos;
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @}
+ */
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBLearning.c b/marvell/uboot/drivers/net/npe/IxEthDBLearning.c
new file mode 100644
index 0000000..1080d11
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBLearning.c
@@ -0,0 +1,125 @@
+/**
+ * @file IxEthDBLearning.c
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+
+/**
+ * @brief hashes the mac address in a mac descriptor with a XOR function
+ *
+ * @param entry pointer to a mac descriptor to be hashed
+ * 
+ * This function only extracts the mac address and employs ixEthDBKeyXORHash()
+ * to do the actual hashing.
+ * Used only to add a whole entry to a hash table, as opposed to searching which
+ * takes only a key and uses the key hashing directly.
+ *
+ * @see ixEthDBKeyXORHash()
+ *
+ * @return the hash value
+ *
+ * @internal
+ */
+UINT32 ixEthDBEntryXORHash(void *entry)
+{
+    MacDescriptor *descriptor = (MacDescriptor *) entry;
+
+    return ixEthDBKeyXORHash(descriptor->macAddress);
+}
+
+/**
+ * @brief hashes a mac address
+ *
+ * @param key pointer to a 6 byte structure (typically an IxEthDBMacAddr pointer)
+ * to be hashed
+ *
+ * Given a 6 bytes MAC address, the hash used is:
+ *
+ * hash(MAC[0:5]) = MAC[0:1] ^ MAC[2:3] ^ MAC[4:5]
+ *
+ * Used by the hash table to search and remove entries based
+ * solely on their keys (mac addresses).
+ *
+ * @return the hash value
+ *
+ * @internal
+ */
+UINT32 ixEthDBKeyXORHash(void *key)
+{
+    UINT32 hashValue;
+    UINT8 *value = (UINT8 *) key;
+    
+    hashValue  = (value[5] << 8) | value[4];
+    hashValue ^= (value[3] << 8) | value[2];
+    hashValue ^= (value[1] << 8) | value[0];
+
+    return hashValue;
+}
+
+/**
+ * @brief mac descriptor match function
+ *
+ * @param reference mac address (typically an IxEthDBMacAddr pointer) structure
+ * @param entry pointer to a mac descriptor whose key (mac address) is to be 
+ * matched against the reference key
+ *
+ * Used by the hash table to retrieve entries. Hashing entries can produce
+ * collisions, i.e. descriptors with different mac addresses and the same
+ * hash value, where this function is used to differentiate entries.
+ *
+ * @retval true if the entry matches the reference key (equal addresses)
+ * @retval false if the entry does not match the reference key
+ *
+ * @internal
+ */
+BOOL ixEthDBAddressMatch(void *reference, void *entry)
+{
+    return (ixEthDBAddressCompare(reference, ((MacDescriptor *) entry)->macAddress) == 0);
+}
+
+/**
+ * @brief compares two mac addresses
+ *
+ * @param mac1 first mac address to compare
+ * @param mac2 second mac address to compare
+ * 
+ * This comparison works in a similar way to strcmp, producing similar results.
+ * Used to insert values keyed on mac addresses into binary search trees.
+ *
+ * @retval -1 if mac1 < mac2
+ * @retval 0 if ma1 == mac2
+ * @retval 1 if mac1 > mac2
+ */
+UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2)
+{
+    UINT32 local_index;
+
+    for (local_index = 0 ; local_index < IX_IEEE803_MAC_ADDRESS_SIZE ; local_index++)
+    {
+        if (mac1[local_index] > mac2[local_index])
+        {
+            return 1;
+        }
+        else if (mac1[local_index] < mac2[local_index])
+        {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBMem.c b/marvell/uboot/drivers/net/npe/IxEthDBMem.c
new file mode 100644
index 0000000..78fce4b
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBMem.c
@@ -0,0 +1,625 @@
+/**
+ * @file IxEthDBDBMem.c
+ *
+ * @brief Memory handling routines for the MAC address database
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#include "IxEthDB_p.h"
+
+IX_ETH_DB_PRIVATE HashNode *nodePool     = NULL;
+IX_ETH_DB_PRIVATE MacDescriptor *macPool = NULL;
+IX_ETH_DB_PRIVATE MacTreeNode *treePool  = NULL;
+
+IX_ETH_DB_PRIVATE HashNode nodePoolArea[NODE_POOL_SIZE];
+IX_ETH_DB_PRIVATE MacDescriptor macPoolArea[MAC_POOL_SIZE];
+IX_ETH_DB_PRIVATE MacTreeNode treePoolArea[TREE_POOL_SIZE];
+
+IX_ETH_DB_PRIVATE IxOsalMutex nodePoolLock;
+IX_ETH_DB_PRIVATE IxOsalMutex macPoolLock;
+IX_ETH_DB_PRIVATE IxOsalMutex treePoolLock;
+
+#define LOCK_NODE_POOL   { ixOsalMutexLock(&nodePoolLock, IX_OSAL_WAIT_FOREVER); }
+#define UNLOCK_NODE_POOL { ixOsalMutexUnlock(&nodePoolLock); }
+
+#define LOCK_MAC_POOL    { ixOsalMutexLock(&macPoolLock, IX_OSAL_WAIT_FOREVER); }
+#define UNLOCK_MAC_POOL  { ixOsalMutexUnlock(&macPoolLock); }
+
+#define LOCK_TREE_POOL   { ixOsalMutexLock(&treePoolLock, IX_OSAL_WAIT_FOREVER); }
+#define UNLOCK_TREE_POOL { ixOsalMutexUnlock(&treePoolLock); }
+
+/* private function prototypes */
+IX_ETH_DB_PRIVATE MacDescriptor* ixEthDBPoolAllocMacDescriptor(void);
+IX_ETH_DB_PRIVATE void ixEthDBPoolFreeMacDescriptor(MacDescriptor *macDescriptor);
+
+/**
+ * @addtogroup EthMemoryManagement
+ *
+ * @{
+ */
+
+/**
+ * @brief initializes the memory pools used by the ethernet database component
+ *
+ * Initializes the hash table node, mac descriptor and mac tree node pools.
+ * Called at initialization time by @ref ixEthDBInit().
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBInitMemoryPools(void)
+{
+    int local_index;
+
+    /* HashNode pool */
+    ixOsalMutexInit(&nodePoolLock);
+
+    for (local_index = 0 ; local_index < NODE_POOL_SIZE ; local_index++)
+    {
+        HashNode *freeNode = &nodePoolArea[local_index];
+
+        freeNode->nextFree = nodePool;
+        nodePool           = freeNode;
+    }
+
+    /* MacDescriptor pool */
+    ixOsalMutexInit(&macPoolLock);
+
+    for (local_index = 0 ; local_index < MAC_POOL_SIZE ; local_index++)
+    {
+        MacDescriptor *freeDescriptor = &macPoolArea[local_index];
+
+        freeDescriptor->nextFree = macPool;
+        macPool                  = freeDescriptor;
+    }
+
+    /* MacTreeNode pool */
+    ixOsalMutexInit(&treePoolLock);
+
+    for (local_index = 0 ; local_index < TREE_POOL_SIZE ; local_index++)
+    {
+        MacTreeNode *freeNode = &treePoolArea[local_index];
+
+        freeNode->nextFree = treePool;
+        treePool           = freeNode;
+    }
+}
+
+/**
+ * @brief allocates a hash node from the pool
+ *
+ * Allocates a hash node and resets its value.
+ *
+ * @return the allocated hash node or NULL if the pool is empty
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+HashNode* ixEthDBAllocHashNode(void)
+{
+    HashNode *allocatedNode = NULL;
+
+    if (nodePool != NULL)
+    {
+        LOCK_NODE_POOL;
+
+        allocatedNode = nodePool;
+        nodePool      = nodePool->nextFree;
+
+        UNLOCK_NODE_POOL;
+
+        memset(allocatedNode, 0, sizeof(HashNode));
+    }
+
+    return allocatedNode;
+}
+
+/**
+ * @brief frees a hash node into the pool
+ *
+ * @param hashNode node to be freed
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBFreeHashNode(HashNode *hashNode)
+{
+    if (hashNode != NULL)
+    {
+        LOCK_NODE_POOL;
+
+        hashNode->nextFree = nodePool;
+        nodePool           = hashNode;
+
+        UNLOCK_NODE_POOL;
+    }
+}
+
+/**
+ * @brief allocates a mac descriptor from the pool
+ *
+ * Allocates a mac descriptor and resets its value.
+ * This function is not used directly, instead @ref ixEthDBAllocMacDescriptor()
+ * is used, which keeps track of the pointer reference count.
+ *
+ * @see ixEthDBAllocMacDescriptor()
+ * 
+ * @warning this function is not used directly by any other function
+ * apart from ixEthDBAllocMacDescriptor()
+ *
+ * @return the allocated mac descriptor or NULL if the pool is empty
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+MacDescriptor* ixEthDBPoolAllocMacDescriptor(void)
+{
+    MacDescriptor *allocatedDescriptor = NULL;
+
+    if (macPool != NULL)
+    {
+        LOCK_MAC_POOL;
+
+        allocatedDescriptor = macPool;
+        macPool             = macPool->nextFree;
+
+        UNLOCK_MAC_POOL;
+
+        memset(allocatedDescriptor, 0, sizeof(MacDescriptor));
+    }
+
+    return allocatedDescriptor;
+}
+
+/**
+ * @brief allocates and initializes a mac descriptor smart pointer
+ *
+ * Uses @ref ixEthDBPoolAllocMacDescriptor() to allocate a mac descriptor
+ * from the pool and initializes its reference count.
+ *
+ * @see ixEthDBPoolAllocMacDescriptor()
+ *
+ * @return the allocated mac descriptor or NULL if the pool is empty
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+MacDescriptor* ixEthDBAllocMacDescriptor(void)
+{
+    MacDescriptor *allocatedDescriptor = ixEthDBPoolAllocMacDescriptor();
+
+    if (allocatedDescriptor != NULL)
+    {
+        LOCK_MAC_POOL;
+
+        allocatedDescriptor->refCount++;
+
+        UNLOCK_MAC_POOL;
+    }
+
+    return allocatedDescriptor;
+}
+
+/**
+ * @brief frees a mac descriptor back into the pool
+ *
+ * @param macDescriptor mac descriptor to be freed
+ *
+ * @warning this function is not to be called by anyone but
+ * ixEthDBFreeMacDescriptor()
+ *
+ * @see ixEthDBFreeMacDescriptor()
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBPoolFreeMacDescriptor(MacDescriptor *macDescriptor)
+{
+    LOCK_MAC_POOL;
+
+    macDescriptor->nextFree = macPool;
+    macPool                 = macDescriptor;
+
+    UNLOCK_MAC_POOL;
+}
+
+/**
+ * @brief frees or reduces the usage count of a mac descriptor smart pointer
+ *
+ * If the reference count reaches 0 (structure is no longer used anywhere)
+ * then the descriptor is freed back into the pool using ixEthDBPoolFreeMacDescriptor().
+ *
+ * @see ixEthDBPoolFreeMacDescriptor()
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBFreeMacDescriptor(MacDescriptor *macDescriptor)
+{
+    if (macDescriptor != NULL)
+    {
+        LOCK_MAC_POOL;
+
+        if (macDescriptor->refCount > 0)
+        {
+            macDescriptor->refCount--;
+
+            if (macDescriptor->refCount == 0)
+            {
+                UNLOCK_MAC_POOL;
+
+                ixEthDBPoolFreeMacDescriptor(macDescriptor);
+            }
+            else
+            {
+                UNLOCK_MAC_POOL;
+            }
+        }
+        else
+        {
+            UNLOCK_MAC_POOL;
+        }
+    }
+}
+
+/**
+ * @brief clones a mac descriptor smart pointer
+ *
+ * @param macDescriptor mac descriptor to clone
+ *
+ * Increments the usage count of the smart pointer
+ *
+ * @returns the cloned smart pointer
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor)
+{
+    LOCK_MAC_POOL;
+
+    if (macDescriptor->refCount == 0)
+    {
+        UNLOCK_MAC_POOL;
+
+        return NULL;
+    }
+
+    macDescriptor->refCount++;
+
+    UNLOCK_MAC_POOL;
+
+    return macDescriptor;
+}
+
+/**
+ * @brief allocates a mac tree node from the pool
+ *
+ * Allocates and initializes a mac tree node from the pool.
+ *
+ * @return the allocated mac tree node or NULL if the pool is empty
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+MacTreeNode* ixEthDBAllocMacTreeNode(void)
+{
+    MacTreeNode *allocatedNode = NULL;
+
+    if (treePool != NULL)
+    {
+        LOCK_TREE_POOL;
+
+        allocatedNode = treePool;
+        treePool      = treePool->nextFree;
+
+        UNLOCK_TREE_POOL;
+
+        memset(allocatedNode, 0, sizeof(MacTreeNode));
+    }
+
+    return allocatedNode;
+}
+
+/**
+ * @brief frees a mac tree node back into the pool
+ *
+ * @param macNode mac tree node to be freed
+ *
+ * @warning not to be used except from ixEthDBFreeMacTreeNode().
+ *
+ * @see ixEthDBFreeMacTreeNode()
+ *
+ * @internal
+ */
+void ixEthDBPoolFreeMacTreeNode(MacTreeNode *macNode)
+{
+    if (macNode != NULL)
+    {
+        LOCK_TREE_POOL;
+
+        macNode->nextFree = treePool;
+        treePool          = macNode;
+
+        UNLOCK_TREE_POOL;
+    }
+}
+
+/**
+ * @brief frees or reduces the usage count of a mac tree node smart pointer
+ *
+ * @param macNode mac tree node to free
+ *
+ * Reduces the usage count of the given mac node. If the usage count
+ * reaches 0 the node is freed back into the pool using ixEthDBPoolFreeMacTreeNode()
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBFreeMacTreeNode(MacTreeNode *macNode)
+{
+    if (macNode->descriptor != NULL)
+    {
+        ixEthDBFreeMacDescriptor(macNode->descriptor);
+    }
+
+    if (macNode->left != NULL)
+    {
+        ixEthDBFreeMacTreeNode(macNode->left);
+    }
+
+    if (macNode->right != NULL)
+    {
+        ixEthDBFreeMacTreeNode(macNode->right);
+    }
+
+    ixEthDBPoolFreeMacTreeNode(macNode);
+}
+
+/**
+ * @brief clones a mac tree node
+ *
+ * @param macNode mac tree node to be cloned
+ *
+ * Increments the usage count of the node, <i>its associated descriptor 
+ * and <b>recursively</b> of all its child nodes</i>.
+ *
+ * @warning this function is recursive and clones whole trees/subtrees, use only for
+ * root nodes
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *macNode)
+{
+    if (macNode != NULL)
+    {
+        MacTreeNode *clonedMacNode = ixEthDBAllocMacTreeNode();
+
+        if (clonedMacNode != NULL)
+        {
+            if (macNode->right != NULL)
+            {
+                clonedMacNode->right = ixEthDBCloneMacTreeNode(macNode->right);
+            }
+
+            if (macNode->left != NULL)
+            {
+                clonedMacNode->left = ixEthDBCloneMacTreeNode(macNode->left);
+            }
+
+            if (macNode->descriptor != NULL)
+            {
+                clonedMacNode->descriptor = ixEthDBCloneMacDescriptor(macNode->descriptor);
+            }
+        }
+
+        return clonedMacNode;
+    }
+    else
+    {
+        return NULL;
+    }
+}
+
+#ifndef NDEBUG
+/* Debug statistical functions for memory usage */
+
+extern HashTable dbHashtable;
+int ixEthDBNumHashElements(void);
+
+int ixEthDBNumHashElements(void)
+{   
+    UINT32 bucketIndex;
+    int numElements = 0;
+    HashTable *hashTable = &dbHashtable;
+
+    for (bucketIndex = 0 ; bucketIndex < hashTable->numBuckets ; bucketIndex++)
+    {
+        if (hashTable->hashBuckets[bucketIndex] != NULL)
+        {
+            HashNode *node = hashTable->hashBuckets[bucketIndex];
+
+            while (node != NULL)
+            {
+                numElements++;
+
+                node = node->next;
+            }
+        }
+    }
+
+    return numElements;
+}
+
+UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree)
+{
+    if (tree == NULL)
+    {
+        return 0;
+    }
+    else
+    {
+        return 1 /* this node */ + ixEthDBSearchTreeUsageGet(tree->left) + ixEthDBSearchTreeUsageGet(tree->right);
+    }
+}
+
+int ixEthDBShowMemoryStatus(void)
+{
+    MacDescriptor *mac;
+    MacTreeNode *tree;
+    HashNode *node;
+
+    int macCounter  = 0;
+    int treeCounter = 0;
+    int nodeCounter = 0;
+
+    int totalTreeUsage            = 0;
+    int totalDescriptorUsage      = 0;
+    int totalCloneDescriptorUsage = 0;
+    int totalNodeUsage            = 0;
+
+    UINT32 portIndex;
+
+    LOCK_NODE_POOL;
+    LOCK_MAC_POOL;
+    LOCK_TREE_POOL;
+
+    mac  = macPool;
+    tree = treePool;
+    node = nodePool;
+
+    while (mac != NULL)
+    {
+        macCounter++;
+
+        mac = mac->nextFree;
+
+        if (macCounter > MAC_POOL_SIZE)
+        {
+            break;
+        }
+    }
+
+    while (tree != NULL)
+    {
+        treeCounter++;
+
+        tree = tree->nextFree;
+
+        if (treeCounter > TREE_POOL_SIZE)
+        {
+            break;
+        }
+    }
+
+    while (node != NULL)
+    {
+        nodeCounter++;
+
+        node = node->nextFree;
+
+        if (nodeCounter > NODE_POOL_SIZE)
+        {
+            break;
+        }
+    }
+
+    for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+    {
+        int treeUsage = ixEthDBSearchTreeUsageGet(ixEthDBPortInfo[portIndex].updateMethod.searchTree);
+
+        totalTreeUsage            += treeUsage;
+        totalCloneDescriptorUsage += treeUsage; /* each tree node contains a descriptor */
+    }
+
+    totalNodeUsage        = ixEthDBNumHashElements();
+    totalDescriptorUsage += totalNodeUsage; /* each hash table entry contains a descriptor */
+
+    UNLOCK_NODE_POOL;
+    UNLOCK_MAC_POOL;
+    UNLOCK_TREE_POOL;
+
+    printf("Ethernet database memory usage stats:\n\n");
+
+    if (macCounter <= MAC_POOL_SIZE)
+    {
+        printf("\tMAC descriptor pool  : %d free out of %d entries (%d%%)\n", macCounter, MAC_POOL_SIZE, macCounter * 100 / MAC_POOL_SIZE);
+    }
+    else
+    {
+        printf("\tMAC descriptor pool  : invalid state (ring within the pool), normally %d entries\n", MAC_POOL_SIZE);
+    }
+
+    if (treeCounter <= TREE_POOL_SIZE)
+    {
+	printf("\tTree node pool       : %d free out of %d entries (%d%%)\n", treeCounter, TREE_POOL_SIZE, treeCounter * 100 / TREE_POOL_SIZE);
+    }
+    else
+    {
+        printf("\tTREE descriptor pool  : invalid state (ring within the pool), normally %d entries\n", TREE_POOL_SIZE);
+    }
+
+    if (nodeCounter <= NODE_POOL_SIZE)
+    {
+	printf("\tHash node pool       : %d free out of %d entries (%d%%)\n", nodeCounter, NODE_POOL_SIZE, nodeCounter * 100 / NODE_POOL_SIZE);
+    }
+    else
+    {
+        printf("\tNODE descriptor pool  : invalid state (ring within the pool), normally %d entries\n", NODE_POOL_SIZE);
+    }
+
+    printf("\n");
+    printf("\tMAC descriptor usage : %d entries, %d cloned\n", totalDescriptorUsage, totalCloneDescriptorUsage);
+    printf("\tTree node usage      : %d entries\n", totalTreeUsage);
+    printf("\tHash node usage      : %d entries\n", totalNodeUsage);
+    printf("\n");
+
+    /* search for duplicate nodes in the mac pool */
+    {
+        MacDescriptor *reference = macPool;
+
+        while (reference != NULL)
+        {
+            MacDescriptor *comparison = reference->nextFree;
+
+            while (comparison != NULL)
+            {
+                if (reference == comparison)
+                {
+                    printf("Warning: reached a duplicate (%p), invalid MAC pool state\n", reference);
+
+                    return 1;
+                }
+
+                comparison = comparison->nextFree;
+            }
+
+            reference = reference->nextFree;
+        }
+    }
+
+    printf("No duplicates found in the MAC pool (sanity check ok)\n");
+
+    return 0;
+}
+
+#endif /* NDEBUG */
+
+/**
+ * @} EthMemoryManagement
+ */
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBNPEAdaptor.c b/marvell/uboot/drivers/net/npe/IxEthDBNPEAdaptor.c
new file mode 100644
index 0000000..30e1f61
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBNPEAdaptor.c
@@ -0,0 +1,695 @@
+/**
+ * @file IxEthDBDBNPEAdaptor.c
+ *
+ * @brief Routines that read and write learning/search trees in NPE-specific format
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+#include "IxEthDBLog_p.h"
+
+/* forward prototype declarations */
+IX_ETH_DB_PUBLIC void ixEthDBELTShow(IxEthDBPortId portID);
+IX_ETH_DB_PUBLIC void ixEthDBShowNpeMsgHistory(void);
+
+/* data */
+UINT8* ixEthDBNPEUpdateArea[IX_ETH_DB_NUMBER_OF_PORTS];
+UINT32 dumpEltSize;
+
+/* private data */
+IX_ETH_DB_PRIVATE IxEthDBNoteWriteFn ixEthDBNPENodeWrite[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
+
+#define IX_ETH_DB_MAX_DELTA_ZONES (6) /* at most 6 EP Delta zones, according to NPE FS */
+IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDeltaOffset[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES]; 
+IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDelta[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES];
+
+/**
+ * @brief allocates non-cached or contiguous NPE tree update areas for all the ports
+ *
+ * This function is called only once at initialization time from
+ * @ref ixEthDBInit().
+ *
+ * @warning do not call manually
+ *
+ * @see ixEthDBInit()
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBNPEUpdateAreasInit(void)
+{
+    UINT32 portIndex;
+    PortUpdateMethod *update;
+
+    for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+    {
+        update = &ixEthDBPortInfo[portIndex].updateMethod;
+
+        if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
+        {
+            update->npeUpdateZone   = IX_OSAL_CACHE_DMA_MALLOC(FULL_ELT_BYTE_SIZE);
+            update->npeGwUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_GW_BYTE_SIZE);
+            update->vlanUpdateZone  = IX_OSAL_CACHE_DMA_MALLOC(FULL_VLAN_BYTE_SIZE);
+
+            if (update->npeUpdateZone == NULL
+                || update->npeGwUpdateZone == NULL
+                || update->vlanUpdateZone == NULL)
+            {
+                ERROR_LOG("Fatal error: IX_ACC_DRV_DMA_MALLOC() returned NULL, no NPE update zones available\n");
+            }
+            else
+            {
+                memset(update->npeUpdateZone, 0, FULL_ELT_BYTE_SIZE);
+                memset(update->npeGwUpdateZone, 0, FULL_GW_BYTE_SIZE);
+                memset(update->vlanUpdateZone, 0, FULL_VLAN_BYTE_SIZE);
+            }
+        }
+        else
+        {
+            /* unused */
+            update->npeUpdateZone   = NULL;
+            update->npeGwUpdateZone = NULL;
+            update->vlanUpdateZone  = NULL;
+        }
+    }
+}
+
+/**
+ * @brief deallocates the NPE update areas for all the ports
+ *
+ * This function is called at component de-initialization time
+ * by @ref ixEthDBUnload().
+ *
+ * @warning do not call manually
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBNPEUpdateAreasUnload(void)
+{
+    UINT32 portIndex;
+
+    for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+    {
+        if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
+        {
+            IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone);
+            IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.npeGwUpdateZone);
+            IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.vlanUpdateZone);
+        }
+    }
+}
+
+/**
+ * @brief general-purpose NPE callback function
+ *
+ * @param npeID NPE ID
+ * @param msg NPE message
+ *
+ * This function will unblock the caller by unlocking
+ * the npeAckLock mutex defined for each NPE port
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg)
+{
+    IxEthDBPortId portID = IX_ETH_DB_NPE_TO_PORT_ID(npeID);
+    PortInfo *portInfo;
+
+    if (portID >= IX_ETH_DB_NUMBER_OF_PORTS)
+    {
+        /* invalid port */
+        return;
+    }
+
+    if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE)
+    {
+        /* not an NPE */
+        return;
+    }
+
+    portInfo = &ixEthDBPortInfo[portID];
+    
+    ixOsalMutexUnlock(&portInfo->npeAckLock);
+}
+
+/**
+ * @brief synchronizes the database with tree
+ *
+ * @param portID port ID of the NPE whose tree is to be scanned
+ * @param eltBaseAddress memory base address of the NPE serialized tree
+ * @param eltSize size in bytes of the NPE serialized tree
+ *
+ * Scans the NPE learning tree and resets the age of active database records.
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize)
+{
+    UINT32 eltEntryOffset;
+    UINT32 entryPortID;
+
+    /* invalidate cache */
+    IX_OSAL_CACHE_INVALIDATE(eltBaseAddress, eltSize);
+
+    for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE)
+    {
+        /* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node
+         *
+         * the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit]
+         * therefore we can just use the pointer for database searches as only the first 6 bytes are checked
+         */
+        void *eltNodeAddress       = (void *) ((UINT32) eltBaseAddress + eltEntryOffset);
+
+        /* debug */
+        IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) checking node at offset %d...\n", eltEntryOffset / ELT_ENTRY_SIZE);
+
+        if (IX_EDB_NPE_NODE_VALID(eltNodeAddress) != true)
+        {
+            IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is empty\n");
+        }
+        else if (eltEntryOffset == ELT_ROOT_OFFSET)
+        {
+            IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is root\n");
+        }
+
+        if (IX_EDB_NPE_NODE_VALID(eltNodeAddress))
+        {
+            entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress));
+
+            /* check only active entries belonging to this port */
+            if (ixEthDBPortInfo[portID].agingEnabled && IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) && (portID == entryPortID)
+                && ((ixEthDBPortDefinitions[portID].capabilities & IX_ETH_ENTRY_AGING) == 0))
+            {
+                /* search record */
+                HashNode *node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_FILTERING_RECORDS);
+
+                /* safety check, maybe user deleted record right before sync? */
+                if (node != NULL)
+                {
+                    /* found record */
+                    MacDescriptor *descriptor = (MacDescriptor *) node->data;
+
+                    IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) synced entry [%s] already in the database, updating fields\n", mac2string(eltNodeAddress));
+
+                    /* reset age - set to -1 so that maintenance will restore it to 0 (or more) when incrementing */
+                    if (!descriptor->recordData.filteringData.staticEntry)
+                    {
+                        if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
+                        {
+                            descriptor->recordData.filteringData.age = AGE_RESET;
+                        }
+                        else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
+                        {
+                            descriptor->recordData.filteringVlanData.age = AGE_RESET;
+                        }
+                    }
+
+                    /* end transaction */
+                    ixEthDBReleaseHashNode(node);
+                }
+            }
+            else
+            {
+                IX_ETH_DB_NPE_VERBOSE_TRACE("\t... found portID %d, we check only port %d\n", entryPortID, portID);
+            }
+        }
+    }
+}
+
+/**
+ * @brief writes a search tree in NPE format
+ *
+ * @param type type of records to be written into the NPE update zone
+ * @param totalSize maximum size of the linearized tree
+ * @param baseAddress memory base address where to write the NPE tree into
+ * @param tree search tree to write in NPE format
+ * @param blocks number of written 64-byte blocks
+ * @param startIndex optimal binary search start index
+ *
+ * Serializes the given tree in NPE linear format
+ *
+ * @return none
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *epDelta, UINT32 *blocks)
+{
+    MacTreeNodeStack *stack;
+    UINT32 maxOffset = 0;
+    UINT32 emptyOffset;
+
+    stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack));
+    
+    if (stack == NULL)
+    {
+        ERROR_LOG("DB: (NPEAdaptor) failed to allocate the node stack for learning tree linearization, out of memory?\n");
+        return;
+    }
+
+    /* zero out empty root */
+    memset(baseAddress, 0, ELT_ENTRY_SIZE);
+
+    NODE_STACK_INIT(stack);
+
+    if (tree != NULL)
+    {
+        /* push tree root at offset 1 */
+        NODE_STACK_PUSH(stack, tree, 1);
+
+        maxOffset = 1;
+    }
+
+    while (NODE_STACK_NONEMPTY(stack))
+    {
+        MacTreeNode *node;
+        UINT32 offset;
+
+        NODE_STACK_POP(stack, node, offset);
+
+        /* update maximum offset */
+        if (offset > maxOffset)
+        {
+            maxOffset = offset;
+        }
+
+        IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) writing MAC [%s] at offset %d\n", mac2string(node->descriptor->macAddress), offset);
+
+        /* add node to NPE ELT at position indicated by offset */
+        if (offset < MAX_ELT_SIZE)
+        {
+            ixEthDBNPENodeWrite[type]((void *) (((UINT32) baseAddress) + offset * ELT_ENTRY_SIZE), node);
+        }
+
+        if (node->left != NULL)
+        {
+            NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset));
+        }
+        else
+        {
+            /* ensure this entry is zeroed */
+            memset((void *) ((UINT32) baseAddress + LEFT_CHILD_OFFSET(offset) * ELT_ENTRY_SIZE), 0, ELT_ENTRY_SIZE);
+        }
+
+        if (node->right != NULL)
+        {
+            NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset));
+        }
+        else
+        {
+            /* ensure this entry is zeroed */
+            memset((void *) ((UINT32) baseAddress + RIGHT_CHILD_OFFSET(offset) * ELT_ENTRY_SIZE), 0, ELT_ENTRY_SIZE);
+        }
+    }
+    
+    emptyOffset = maxOffset + 1;
+
+    /* zero out rest of the tree */
+    IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Emptying tree from offset %d, address 0x%08X, %d bytes\n", 
+        emptyOffset, ((UINT32) baseAddress) + emptyOffset * ELT_ENTRY_SIZE, totalSize - (emptyOffset * ELT_ENTRY_SIZE));
+
+    if (emptyOffset < MAX_ELT_SIZE - 1)
+    {
+        memset((void *) (((UINT32) baseAddress) + (emptyOffset * ELT_ENTRY_SIZE)), 0, totalSize - (emptyOffset * ELT_ENTRY_SIZE));
+    }
+
+    /* flush cache */
+    IX_OSAL_CACHE_FLUSH(baseAddress, totalSize);
+
+    /* debug */
+    IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Ethernet learning/filtering tree XScale wrote at address 0x%08X (max %d bytes):\n\n",
+        (UINT32) baseAddress, FULL_ELT_BYTE_SIZE);
+
+    IX_ETH_DB_NPE_DUMP_ELT(baseAddress, FULL_ELT_BYTE_SIZE);
+    
+    /* compute number of 64-byte blocks */
+    if (blocks != NULL)
+    {
+        *blocks = maxOffset != 0 ? 1 + maxOffset / 8 : 0;
+
+        IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Wrote %d 64-byte blocks\n", *blocks);
+    }
+    
+    /* compute epDelta - start index for binary search */
+    if (epDelta != NULL)
+    {
+        UINT32 deltaIndex = 0;
+
+        *epDelta = 0;
+        
+        for (; deltaIndex < IX_ETH_DB_MAX_DELTA_ZONES ; deltaIndex ++)
+        {
+            if (ixEthDBEPDeltaOffset[type][deltaIndex] >= maxOffset)
+            {
+                *epDelta = ixEthDBEPDelta[type][deltaIndex];
+                break;
+            }
+        }
+
+        IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Computed epDelta %d (based on maxOffset %d)\n", *epDelta, maxOffset);
+    }
+
+    ixOsalCacheDmaFree(stack);
+}
+
+/**
+ * @brief implements a dummy node serialization function
+ *
+ * @param address address of where the node is to be serialized (unused)
+ * @param node tree node to be serialized (unused)
+ *
+ * This function is registered for safety reasons and should
+ * never be called. It will display an error message if this
+ * function is called.
+ *
+ * @return none
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBNullSerialize(void *address, MacTreeNode *node)
+{
+    IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Warning, the NullSerialize function was called, wrong record type?\n");
+}
+
+/**
+ * @brief writes a filtering entry in NPE linear format
+ *
+ * @param address memory address to write node to
+ * @param node node to be written
+ *
+ * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
+ * in NPE-readable format.
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBNPELearningNodeWrite(void *address, MacTreeNode *node)
+{
+    /* copy mac address */
+    memcpy(address, node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
+
+    /* copy port ID */
+    NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET) = IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(node->descriptor->portID);
+
+    /* copy flags (valid and not active, as the NPE sets it to active) and clear reserved section (bits 2-7) */
+    NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) = (UINT8) IX_EDB_FLAGS_INACTIVE_VALID;
+
+    IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) writing ELT node 0x%08x:0x%08x\n", * (UINT32 *) address, * (((UINT32 *) (address)) + 1));
+}
+
+/**
+ * @brief writes a WiFi header conversion record in
+ * NPE linear format
+ *
+ * @param address memory address to write node to
+ * @param node node to be written
+ *
+ * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
+ * in NPE-readable format.
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBNPEWiFiNodeWrite(void *address, MacTreeNode *node)
+{
+    /* copy mac address */
+    memcpy(address, node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
+
+    /* copy index */
+    NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_WIFI_INDEX_OFFSET) = node->descriptor->recordData.wifiData.gwAddressIndex;
+
+    /* copy flags (type and valid) */
+    NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_WIFI_FLAGS_OFFSET) = node->descriptor->recordData.wifiData.type << 1 | IX_EDB_FLAGS_VALID;
+}
+
+/**
+ * @brief writes a WiFi gateway header conversion record in
+ * NPE linear format
+ *
+ * @param address memory address to write node to
+ * @param node node to be written
+ *
+ * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
+ * in NPE-readable format.
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node)
+{
+    /* copy mac address */
+    memcpy(address, node->descriptor->recordData.wifiData.gwMacAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
+
+    /* set reserved field, two bytes */
+    NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET)     = 0;
+    NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET + 1) = 0;
+}
+
+/**
+ * @brief writes a firewall record in
+ * NPE linear format
+ *
+ * @param address memory address to write node to
+ * @param node node to be written
+ *
+ * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
+ * in NPE-readable format.
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBNPEFirewallNodeWrite(void *address, MacTreeNode *node)
+{
+    /* set reserved field */
+    NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET) = 0;
+
+    /* set flags */
+    NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_FLAGS_OFFSET) = IX_EDB_FLAGS_VALID;
+
+    /* copy mac address */
+    memcpy((void *) ((UINT32) address + IX_EDB_NPE_NODE_FW_ADDR_OFFSET), node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
+}
+
+/**
+ * @brief registers the NPE serialization methods
+ *
+ * This functions registers NPE serialization methods
+ * for writing the following types of records in NPE
+ * readable linear format:
+ * - filtering records
+ * - WiFi header conversion records
+ * - WiFi gateway header conversion records
+ * - firewall records
+ *
+ * Note that this function should be called by the
+ * component initialization function.
+ *
+ * @return number of registered record types
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+UINT32 ixEthDBRecordSerializeMethodsRegister()
+{
+    int i;
+    
+    /* safety - register a blank method for everybody first */
+    for ( i = 0 ; i < IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1 ; i++)
+    {
+        ixEthDBNPENodeWrite[i] = ixEthDBNullSerialize;
+    }
+    
+    /* register real methods */
+    ixEthDBNPENodeWrite[IX_ETH_DB_FILTERING_RECORD]      = ixEthDBNPELearningNodeWrite;
+    ixEthDBNPENodeWrite[IX_ETH_DB_FILTERING_VLAN_RECORD] = ixEthDBNPELearningNodeWrite;
+    ixEthDBNPENodeWrite[IX_ETH_DB_WIFI_RECORD]           = ixEthDBNPEWiFiNodeWrite;
+    ixEthDBNPENodeWrite[IX_ETH_DB_FIREWALL_RECORD]       = ixEthDBNPEFirewallNodeWrite;
+    ixEthDBNPENodeWrite[IX_ETH_DB_GATEWAY_RECORD]        = ixEthDBNPEGatewayNodeWrite;
+    
+    /* EP Delta arrays */
+    memset(ixEthDBEPDeltaOffset, 0, sizeof (ixEthDBEPDeltaOffset));
+    memset(ixEthDBEPDelta, 0, sizeof (ixEthDBEPDelta));
+    
+    /* filtering records */
+    ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][0] = 1;
+    ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][0]       = 0;
+    
+    ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][1] = 3;
+    ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][1]       = 7;
+    
+    ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][2] = 511;
+    ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][2]       = 14;
+    
+    /* wifi records */
+    ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][0] = 1;
+    ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][0]       = 0;
+    
+    ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][1] = 3;
+    ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][1]       = 7;
+    
+    ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][2] = 511;
+    ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][2]       = 14;
+
+    /* firewall records */
+    ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][0] = 0;
+    ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][0]       = 0;
+    
+    ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][1] = 1;
+    ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][1]       = 5;
+    
+    ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][2] = 3;
+    ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][2]       = 13;
+    
+    ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][3] = 7;
+    ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][3]       = 21;
+    
+    ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][4] = 15;
+    ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][4]       = 29;
+    
+    ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][5] = 31;
+    ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][5]       = 37;
+    
+    return 5; /* 5 methods registered */
+}
+
+#ifndef IX_NDEBUG
+
+IX_ETH_DB_PUBLIC UINT32 npeMsgHistory[IX_ETH_DB_NPE_MSG_HISTORY_DEPTH][2];
+IX_ETH_DB_PUBLIC UINT32 npeMsgHistoryLen = 0;
+
+/**
+ * When compiled in DEBUG mode, this function can be used to display
+ * the history of messages sent to the NPEs (up to 100).
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBShowNpeMsgHistory()
+{
+    UINT32 i = 0;
+    UINT32 base, len;
+
+    if (npeMsgHistoryLen <= IX_ETH_DB_NPE_MSG_HISTORY_DEPTH)
+    {
+        base = 0;
+        len  = npeMsgHistoryLen;
+    }
+    else
+    {
+        base = npeMsgHistoryLen % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
+        len  = IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
+    }
+
+    printf("NPE message history [last %d messages, from least to most recent]:\n", len);
+
+    for (; i < len ; i++)
+    {
+        UINT32 pos = (base + i) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
+        printf("msg[%d]: 0x%08x:0x%08x\n", i, npeMsgHistory[pos][0], npeMsgHistory[pos][1]);
+    }
+}
+
+IX_ETH_DB_PUBLIC
+void ixEthDBELTShow(IxEthDBPortId portID)
+{
+    IxNpeMhMessage message;
+    IX_STATUS result;
+    
+    /* send EDB_GetMACAddressDatabase message */
+    FILL_GETMACADDRESSDATABASE(message, 
+        0 /* reserved */, 
+        IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portID].updateMethod.npeUpdateZone));
+
+    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+    if (result == IX_SUCCESS)
+    {
+        /* analyze NPE copy */
+        UINT32 eltEntryOffset;
+        UINT32 entryPortID;
+
+        UINT32 eltBaseAddress = (UINT32) ixEthDBPortInfo[portID].updateMethod.npeUpdateZone;
+        UINT32 eltSize        = FULL_ELT_BYTE_SIZE;
+
+        /* invalidate cache */
+        IX_OSAL_CACHE_INVALIDATE((void *) eltBaseAddress, eltSize);
+
+        printf("Listing records in main learning tree for port %d\n", portID);
+
+        for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE)
+        {
+            /* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node
+            *
+            * the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit]
+            * therefore we can just use the pointer for database searches as only the first 6 bytes are checked
+            */
+            void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset);
+
+            if (IX_EDB_NPE_NODE_VALID(eltNodeAddress))
+            {
+                HashNode *node;
+
+                entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress));
+
+                /* search record */
+                node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_RECORD_TYPES);
+
+                printf("%s - port %d - %s ", mac2string((unsigned char *) eltNodeAddress), entryPortID, 
+                    IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) ? "active" : "inactive");
+
+                /* safety check, maybe user deleted record right before sync? */
+                if (node != NULL)
+                {
+                    /* found record */
+                    MacDescriptor *descriptor = (MacDescriptor *) node->data;
+
+                    printf("- %s ",
+                        descriptor->type == IX_ETH_DB_FILTERING_RECORD ? "filtering" :
+                        descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD ? "vlan" :
+                        descriptor->type == IX_ETH_DB_WIFI_RECORD ? "wifi" : "other (check main DB)");
+
+                    if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) printf("- age %d - %s ", 
+                        descriptor->recordData.filteringData.age,
+                        descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
+
+                    if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) printf("- age %d - %s - tci %d ",
+                        descriptor->recordData.filteringVlanData.age,
+                        descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic",
+                        descriptor->recordData.filteringVlanData.ieee802_1qTag);
+
+                    /* end transaction */
+                    ixEthDBReleaseHashNode(node);
+                }
+                else
+                {
+                    printf("- not synced");
+                }
+
+                printf("\n");
+            }
+        }
+    }
+    else
+    {
+        ixOsalLog(IX_OSAL_LOG_LVL_FATAL, IX_OSAL_LOG_DEV_STDOUT, 
+            "EthDB: (ShowELT) Could not complete action (communication failure)\n",
+            portID, 0, 0, 0, 0, 0);
+    }
+}
+
+#endif
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBPortUpdate.c b/marvell/uboot/drivers/net/npe/IxEthDBPortUpdate.c
new file mode 100644
index 0000000..92af331
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBPortUpdate.c
@@ -0,0 +1,716 @@
+/**
+ * @file IxEthDBDBPortUpdate.c
+ *
+ * @brief Implementation of dependency and port update handling
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+
+/* forward prototype declarations */
+IX_ETH_DB_PRIVATE MacTreeNode* ixEthDBTreeInsert(MacTreeNode *searchTree, MacDescriptor *descriptor);
+IX_ETH_DB_PRIVATE void ixEthDBCreateTrees(IxEthDBPortMap updatePorts);
+IX_ETH_DB_PRIVATE MacTreeNode* ixEthDBTreeRebalance(MacTreeNode *searchTree);
+IX_ETH_DB_PRIVATE void ixEthDBRebalanceTreeToVine(MacTreeNode *root, UINT32 *size);
+IX_ETH_DB_PRIVATE void ixEthDBRebalanceVineToTree(MacTreeNode *root, UINT32 size);
+IX_ETH_DB_PRIVATE void ixEthDBRebalanceCompression(MacTreeNode *root, UINT32 count);
+IX_ETH_DB_PRIVATE UINT32 ixEthDBRebalanceLog2Floor(UINT32 x);
+
+extern HashTable dbHashtable;
+
+/**
+ * @brief register types requiring automatic updates
+ *
+ * @param typeArray array indexed on record types, each
+ * element indicating whether the record type requires an
+ * automatic update (true) or not (false)
+ * 
+ * Automatic updates are done for registered record types
+ * upon adding, updating (that is, updating the record portID) 
+ * and removing records. Whenever an automatic update is triggered
+ * the appropriate ports will be provided with new database
+ * information.
+ *
+ * It is assumed that the typeArray parameter is allocated large
+ * enough to hold all the user defined types. Also, the type
+ * array should be initialized to false as this function only
+ * caters for types which do require automatic updates.
+ *
+ * Note that this function should be called by the component
+ * initialization function.
+ *
+ * @return number of record types registered for automatic
+ * updates
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+UINT32 ixEthDBUpdateTypeRegister(BOOL *typeArray)
+{
+    typeArray[IX_ETH_DB_FILTERING_RECORD]      = true;
+    typeArray[IX_ETH_DB_FILTERING_VLAN_RECORD] = true;
+
+    return 2;
+}
+
+/**
+ * @brief computes dependencies and triggers port learning tree updates
+ *
+ * @param triggerPorts port map consisting in the ports which triggered the update
+ *
+ * This function browses through all the ports and determines how to waterfall the update
+ * event from the trigger ports to all other ports depending on them.
+ *
+ * Once the list of ports to be updated is determined this function 
+ * calls @ref ixEthDBCreateTrees.
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBUpdatePortLearningTrees(IxEthDBPortMap triggerPorts)
+{
+    IxEthDBPortMap updatePorts;
+    UINT32 portIndex;
+    
+    ixEthDBUpdateLock();
+    
+    SET_EMPTY_DEPENDENCY_MAP(updatePorts);
+    
+    for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+    {
+        PortInfo *port   = &ixEthDBPortInfo[portIndex];
+        BOOL mapsCollide;
+        
+        MAPS_COLLIDE(mapsCollide, triggerPorts, port->dependencyPortMap);
+
+        if (mapsCollide                                   /* do triggers influence this port? */
+            && !IS_PORT_INCLUDED(portIndex, updatePorts)  /* and it's not already in the update list */
+            && port->updateMethod.updateEnabled)          /* and we're allowed to update it */
+        {
+            IX_ETH_DB_UPDATE_TRACE("DB: (Update) Adding port %d to update set\n", portIndex);
+
+            JOIN_PORT_TO_MAP(updatePorts, portIndex);
+        }
+        else
+        {
+            IX_ETH_DB_UPDATE_TRACE("DB: (Update) Didn't add port %d to update set, reasons follow:\n", portIndex);
+
+            if (!mapsCollide)
+            {
+                IX_ETH_DB_UPDATE_TRACE("\tMaps don't collide on port %d\n", portIndex);
+            }
+
+            if (IS_PORT_INCLUDED(portIndex, updatePorts))
+            {
+                IX_ETH_DB_UPDATE_TRACE("\tPort %d is already in the update set\n", portIndex);
+            }
+
+            if (!port->updateMethod.updateEnabled)
+            {
+                IX_ETH_DB_UPDATE_TRACE("\tPort %d doesn't have updateEnabled set\n", portIndex);
+            }
+        }
+    }
+    
+    IX_ETH_DB_UPDATE_TRACE("DB: (Update) Updating port set\n");
+
+    ixEthDBCreateTrees(updatePorts);
+        
+    ixEthDBUpdateUnlock();
+}
+
+/**
+ * @brief creates learning trees and calls the port update handlers
+ *
+ * @param updatePorts set of ports in need of learning trees
+ *
+ * This function determines the optimal method of creating learning
+ * trees using a minimal number of database queries, keeping in mind
+ * that different ports can either use the same learning trees or they
+ * can partially share them. The actual tree building routine is
+ * @ref ixEthDBQuery.
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBCreateTrees(IxEthDBPortMap updatePorts)
+{
+    UINT32 portIndex;
+    BOOL result;
+    BOOL portsLeft = true;
+
+    while (portsLeft)
+    {
+        /* get port with minimal dependency map and NULL search tree */
+        UINT32 minPortIndex = MAX_PORT_SIZE;
+        UINT32 minimalSize  = MAX_PORT_SIZE;
+
+        for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+        {
+            UINT32 size;
+            PortInfo *port = &ixEthDBPortInfo[portIndex];
+
+            /* generate trees only for ports that need them */
+            if (!port->updateMethod.searchTreePendingWrite && IS_PORT_INCLUDED(portIndex, updatePorts))
+            {
+                GET_MAP_SIZE(port->dependencyPortMap, size);
+                
+                IX_ETH_DB_UPDATE_TRACE("DB: (Update) Dependency map for port %d: size %d\n",
+                    portIndex, size);
+
+                if (size < minimalSize)
+                {
+                    minPortIndex = portIndex;
+                    minimalSize  = size;
+                }
+            }
+            else
+            {
+                IX_ETH_DB_UPDATE_TRACE("DB: (Update) Skipped port %d from tree diff (%s)\n", portIndex,
+                    port->updateMethod.searchTreePendingWrite ? "pending write access" : "ignored by query");
+            }            
+        }
+
+        /* if a port was found than minimalSize is not MAX_PORT_SIZE */
+        if (minimalSize != MAX_PORT_SIZE)
+        {
+            /* minPortIndex is the port we seek */
+            PortInfo *port = &ixEthDBPortInfo[minPortIndex];
+
+            IxEthDBPortMap query;
+            MacTreeNode *baseTree;
+
+            /* now try to find a port with minimal map difference */
+            PortInfo *minimalDiffPort = NULL;
+            UINT32 minimalDiff        = MAX_PORT_SIZE;
+            
+            IX_ETH_DB_UPDATE_TRACE("DB: (Update) Minimal size port is %d\n", minPortIndex);
+
+            for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+            {   
+                PortInfo *diffPort = &ixEthDBPortInfo[portIndex];
+                BOOL mapIsSubset;
+                
+                IS_MAP_SUBSET(mapIsSubset, diffPort->dependencyPortMap, port->dependencyPortMap);
+                
+
+                if (portIndex != minPortIndex
+                    && diffPort->updateMethod.searchTree != NULL
+                    && mapIsSubset)
+                {
+                    /* compute size and pick only minimal size difference */
+                    UINT32 diffPortSize;
+                    UINT32 sizeDifference;
+
+                    GET_MAP_SIZE(diffPort->dependencyPortMap, diffPortSize);
+                     
+                    IX_ETH_DB_UPDATE_TRACE("DB: (Update) Checking port %d for differences...\n", portIndex);
+
+                    sizeDifference = minimalSize - diffPortSize;
+
+                    if (sizeDifference < minimalDiff)
+                    {
+                        minimalDiffPort = diffPort;
+                        minimalDiff     = sizeDifference;
+                        
+                        IX_ETH_DB_UPDATE_TRACE("DB: (Update) Minimal difference 0x%x was found on port %d\n",
+                            minimalDiff, portIndex);
+                    }
+                }
+            }
+
+            /* check if filtering is enabled on this port */
+            if ((port->featureStatus & IX_ETH_DB_FILTERING) != 0)
+            {
+                /* if minimalDiff is not MAX_PORT_SIZE minimalDiffPort points to the most similar port */
+                if (minimalDiff != MAX_PORT_SIZE)
+                {
+                    baseTree = ixEthDBCloneMacTreeNode(minimalDiffPort->updateMethod.searchTree);
+                    DIFF_MAPS(query, port->dependencyPortMap , minimalDiffPort->dependencyPortMap);
+                    
+                    IX_ETH_DB_UPDATE_TRACE("DB: (Update) Found minimal diff, extending tree %d on query\n",
+                        minimalDiffPort->portID);
+                }
+                else /* .. otherwise no similar port was found, build tree from scratch */
+                {
+                    baseTree = NULL;
+                    
+                    COPY_DEPENDENCY_MAP(query, port->dependencyPortMap);
+                    
+                    IX_ETH_DB_UPDATE_TRACE("DB: (Update) No similar diff, creating tree from query\n");
+                }
+
+                IS_EMPTY_DEPENDENCY_MAP(result, query);
+                
+                if (!result) /* otherwise we don't need anything more on top of the cloned tree */
+                {
+                    IX_ETH_DB_UPDATE_TRACE("DB: (Update) Adding query tree to port %d\n", minPortIndex);
+                        
+                    /* build learning tree */
+                    port->updateMethod.searchTree = ixEthDBQuery(baseTree, query, IX_ETH_DB_ALL_FILTERING_RECORDS, MAX_ELT_SIZE);
+                }
+                else
+                {
+                    IX_ETH_DB_UPDATE_TRACE("DB: (Update) Query is empty, assuming identical nearest tree\n");
+                      
+                    port->updateMethod.searchTree = baseTree;
+                }
+            }
+            else
+            {
+                /* filtering is not enabled, will download an empty tree */
+                if (port->updateMethod.searchTree != NULL)
+                {
+                    ixEthDBFreeMacTreeNode(port->updateMethod.searchTree);
+                }
+
+                port->updateMethod.searchTree = NULL;
+            }
+
+            /* mark tree as valid */
+            port->updateMethod.searchTreePendingWrite = true;
+        }
+        else
+        {
+            portsLeft = false;
+
+            IX_ETH_DB_UPDATE_TRACE("DB: (Update) No trees to create this round\n");            
+        }
+    }
+    
+    for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+    {
+        PortInfo *updatePort = &ixEthDBPortInfo[portIndex];
+
+        if (updatePort->updateMethod.searchTreePendingWrite)
+        {
+            IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) Starting procedure to upload new search tree (%snull) into NPE %d\n", 
+                updatePort->updateMethod.searchTree != NULL ? "not " : "",
+                portIndex);
+
+            updatePort->updateMethod.updateHandler(portIndex, IX_ETH_DB_FILTERING_RECORD);
+        }
+    }
+}
+
+/**
+ * @brief standard NPE update handler
+ *
+ * @param portID id of the port to be updated
+ * @param type record type to be pushed during this update
+ *
+ * The NPE update handler manages updating the NPE databases
+ * given a certain record type.
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type)
+{
+    UINT32 epDelta, blockCount;
+    IxNpeMhMessage message;
+    UINT32 treeSize = 0;
+    PortInfo *port = &ixEthDBPortInfo[portID];
+
+    /* size selection and type check */
+    if (type == IX_ETH_DB_FILTERING_RECORD || type == IX_ETH_DB_WIFI_RECORD)
+    {
+        treeSize = FULL_ELT_BYTE_SIZE;
+    }
+    else if (type == IX_ETH_DB_FIREWALL_RECORD)
+    {
+        treeSize = FULL_FW_BYTE_SIZE;
+    }
+    else
+    {
+        return IX_ETH_DB_INVALID_ARG;
+    }
+    
+    /* serialize tree into memory */
+    ixEthDBNPETreeWrite(type, treeSize, port->updateMethod.npeUpdateZone, port->updateMethod.searchTree, &epDelta, &blockCount);
+
+    /* free internal copy */
+    if (port->updateMethod.searchTree != NULL)
+    {
+        ixEthDBFreeMacTreeNode(port->updateMethod.searchTree);
+    }
+
+    /* forget last used search tree */
+    port->updateMethod.searchTree             = NULL;
+    port->updateMethod.searchTreePendingWrite = false;
+
+    /* dependending on the update type we do different things */
+    if (type == IX_ETH_DB_FILTERING_RECORD || type == IX_ETH_DB_WIFI_RECORD)
+    {
+        IX_STATUS result;
+
+        FILL_SETMACADDRESSDATABASE_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 
+            epDelta, blockCount, 
+            IX_OSAL_MMU_VIRT_TO_PHYS(port->updateMethod.npeUpdateZone));
+
+        IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+        if (result == IX_SUCCESS)
+	{
+            IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) Finished downloading NPE tree on port %d\n", portID);
+        }
+        else
+        {
+            ixEthDBPortInfo[portID].agingEnabled                = false;
+            ixEthDBPortInfo[portID].updateMethod.updateEnabled  = false;
+            ixEthDBPortInfo[portID].updateMethod.userControlled = true;
+
+            ERROR_LOG("EthDB: (PortUpdate) disabling aging and updates on port %d (assumed dead)\n", portID);
+
+            ixEthDBDatabaseClear(portID, IX_ETH_DB_ALL_RECORD_TYPES);
+
+            return IX_ETH_DB_FAIL;
+        }
+
+	return IX_ETH_DB_SUCCESS;
+    }
+    else if (type == IX_ETH_DB_FIREWALL_RECORD)
+    {
+        return ixEthDBFirewallUpdate(portID, port->updateMethod.npeUpdateZone, epDelta);
+    }
+    
+    return IX_ETH_DB_INVALID_ARG;
+}
+
+/**
+ * @brief queries the database for a set of records to be inserted into a given tree
+ *
+ * @param searchTree pointer to a tree where insertions will be performed; can be NULL
+ * @param query set of ports that a database record must match to be inserted into the tree
+ *
+ * The query method browses through the database, extracts all the descriptors matching
+ * the given query parameter and inserts them into the given learning tree.
+ * Note that this is an append procedure, the given tree needs not to be empty.
+ * A "descriptor matching the query" is a descriptor whose port id is in the query map.
+ * If the given tree is empty (NULL) a new tree is created and returned.
+ * 
+ * @return the tree root
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maxEntries)
+{
+    HashIterator iterator;
+    UINT32 entryCount = 0;
+
+    /* browse database */
+    BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
+
+    while (IS_ITERATOR_VALID(&iterator))
+    {
+        MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
+
+        IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) querying [%s]:%d on port map ... ", 
+            mac2string(descriptor->macAddress), 
+            descriptor->portID);
+
+	if ((descriptor->type & recordFilter) != 0 
+            && IS_PORT_INCLUDED(descriptor->portID, query))
+	{
+            MacDescriptor *descriptorClone = ixEthDBCloneMacDescriptor(descriptor);
+
+            IX_ETH_DB_UPDATE_TRACE("match\n");
+
+            if (descriptorClone != NULL)
+            {
+                /* add descriptor to tree */
+                searchTree = ixEthDBTreeInsert(searchTree, descriptorClone);
+
+                entryCount++;
+            }
+        }
+        else
+        {
+            IX_ETH_DB_UPDATE_TRACE("no match\n");
+        }
+
+        if (entryCount < maxEntries)
+        {
+            /* advance to the next record */
+	        BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
+        }
+        else
+        {
+            /* the NPE won't accept more entries so we can stop now */
+            ixEthDBReleaseHashIterator(&iterator);
+
+            IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) number of elements reached maximum supported by port\n");
+
+            break;
+        }
+    }
+
+    IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) query inserted %d records in the search tree\n", entryCount);
+
+    return ixEthDBTreeRebalance(searchTree);
+}
+
+/**
+ * @brief inserts a mac descriptor into an tree
+ *
+ * @param searchTree tree where the insertion is to be performed (may be NULL)
+ * @param descriptor descriptor to insert into tree
+ *
+ * @return the tree root
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+MacTreeNode* ixEthDBTreeInsert(MacTreeNode *searchTree, MacDescriptor *descriptor)
+{
+    MacTreeNode *currentNode    = searchTree;
+    MacTreeNode *insertLocation = NULL;
+    MacTreeNode *newNode;
+    INT32 insertPosition = RIGHT;
+
+    if (descriptor == NULL)
+    {
+        return searchTree;
+    }
+
+    /* create a new node */
+    newNode = ixEthDBAllocMacTreeNode();
+
+    if (newNode == NULL)
+    {
+        /* out of memory */
+        ERROR_LOG("Warning: ixEthDBAllocMacTreeNode returned NULL in file %s:%d (out of memory?)\n", __FILE__, __LINE__);
+
+        ixEthDBFreeMacDescriptor(descriptor);
+
+        return NULL;
+    }
+
+    /* populate node */
+    newNode->descriptor = descriptor;
+
+    /* an empty initial tree is a special case */
+    if (searchTree == NULL)
+    {
+        return newNode;
+    }
+
+    /* get insertion location */
+    while (insertLocation == NULL)
+    {
+        MacTreeNode *nextNode;
+
+        /* compare given key with current node key */
+        insertPosition = ixEthDBAddressCompare(descriptor->macAddress, currentNode->descriptor->macAddress);
+
+        /* navigate down */
+        if (insertPosition == RIGHT)
+        {
+            nextNode = currentNode->right;
+        }
+        else if (insertPosition == LEFT)
+        {
+            nextNode = currentNode->left;
+        }
+        else
+        {
+            /* error, duplicate key */
+            ERROR_LOG("Warning: trapped insertion of a duplicate MAC address in an NPE search tree\n");
+
+            /* this will free the MAC descriptor as well */
+            ixEthDBFreeMacTreeNode(newNode);
+
+            return searchTree;
+        }
+
+        /* when we can no longer dive through the tree we found the insertion place */
+        if (nextNode != NULL)
+        {
+            currentNode = nextNode;
+        }
+        else
+        {
+            insertLocation = currentNode;
+        }
+    }
+
+    /* insert node */
+    if (insertPosition == RIGHT)
+    {
+        insertLocation->right = newNode;
+    }
+    else
+    {
+        insertLocation->left = newNode;
+    }
+
+    return searchTree;
+}
+
+/**
+ * @brief balance a tree
+ *
+ * @param searchTree tree to balance
+ *
+ * Converts a tree into a balanced tree and returns the root of
+ * the balanced tree. The resulting tree is <i>route balanced</i>
+ * not <i>perfectly balanced</i>. This makes no difference to the
+ * average tree search time which is the same in both cases, O(log2(n)).
+ *
+ * @return root of the balanced tree or NULL if there's no memory left
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+MacTreeNode* ixEthDBTreeRebalance(MacTreeNode *searchTree)
+{
+    MacTreeNode *pseudoRoot = ixEthDBAllocMacTreeNode();
+    UINT32 size;
+
+    if (pseudoRoot == NULL)
+    {
+        /* out of memory */
+        return NULL;
+    }
+
+    pseudoRoot->right = searchTree;
+
+    ixEthDBRebalanceTreeToVine(pseudoRoot, &size);
+    ixEthDBRebalanceVineToTree(pseudoRoot, size);
+
+    searchTree = pseudoRoot->right;
+
+    /* remove pseudoRoot right branch, otherwise it will free the entire tree */
+    pseudoRoot->right = NULL;
+
+    ixEthDBFreeMacTreeNode(pseudoRoot);
+
+    return searchTree;
+}
+
+/**
+ * @brief converts a tree into a vine
+ *
+ * @param root root of tree to convert
+ * @param size depth of vine (equal to the number of nodes in the tree)
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBRebalanceTreeToVine(MacTreeNode *root, UINT32 *size)
+{
+    MacTreeNode *vineTail  = root;
+    MacTreeNode *remainder = vineTail->right;
+    MacTreeNode *tempPtr;
+
+    *size = 0;
+
+    while (remainder != NULL)
+    {
+        if (remainder->left == NULL)
+        {
+            /* move tail down one */
+            vineTail  = remainder;
+            remainder = remainder->right;
+            (*size)++;
+        }
+        else
+        {
+            /* rotate around remainder */
+            tempPtr         = remainder->left;
+            remainder->left = tempPtr->right;
+            tempPtr->right  = remainder;
+            remainder       = tempPtr;
+            vineTail->right = tempPtr;
+        }
+    }
+}
+
+/**
+ * @brief converts a vine into a balanced tree
+ *
+ * @param root vine to convert
+ * @param size depth of vine
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBRebalanceVineToTree(MacTreeNode *root, UINT32 size)
+{
+    UINT32 leafCount = size + 1 - (1 << ixEthDBRebalanceLog2Floor(size + 1));
+
+    ixEthDBRebalanceCompression(root, leafCount);
+
+    size = size - leafCount;
+
+    while (size > 1)
+    {
+        ixEthDBRebalanceCompression(root, size / 2);
+
+        size /= 2;
+    }
+}
+
+/**
+ * @brief compresses a vine/tree stage into a more balanced vine/tree
+ *
+ * @param root root of the tree to compress
+ * @param count number of "spine" nodes
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBRebalanceCompression(MacTreeNode *root, UINT32 count)
+{
+    MacTreeNode *scanner = root;
+    MacTreeNode *child;
+    UINT32 local_index;
+
+    for (local_index = 0 ; local_index < count ; local_index++)
+    {
+        child          = scanner->right;
+        scanner->right = child->right;
+        scanner        = scanner->right;
+        child->right   = scanner->left;
+        scanner->left  = child;
+    }
+}
+
+/**
+ * @brief computes |_log2(x)_| (a.k.a. floor(log2(x)))
+ *
+ * @param x number to compute |_log2(x)_| for
+ *
+ * @return |_log2(x)_|
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+UINT32 ixEthDBRebalanceLog2Floor(UINT32 x)
+{
+    UINT32 log = 0;
+    UINT32 val = 1;
+
+    while (val < x)
+    {
+        log++;
+        val <<= 1;
+    }
+
+    return val == x ? log : log - 1;
+}
+
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBReports.c b/marvell/uboot/drivers/net/npe/IxEthDBReports.c
new file mode 100644
index 0000000..d74f121
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBReports.c
@@ -0,0 +1,628 @@
+/**
+ * @file IxEthDBAPI.c
+ *
+ * @brief Implementation of the public API
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+
+extern HashTable dbHashtable;
+IX_ETH_DB_PRIVATE void ixEthDBPortInfoShow(IxEthDBPortId portID, IxEthDBRecordType recordFilter);
+IX_ETH_DB_PRIVATE IxEthDBStatus ixEthDBHeaderShow(IxEthDBRecordType recordFilter);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDependencyPortMapShow(IxEthDBPortId portID, IxEthDBPortMap map);
+
+/**
+ * @brief displays a port dependency map
+ *
+ * @param portID ID of the port
+ * @param map port map to display
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully
+ */ 
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBDependencyPortMapShow(IxEthDBPortId portID, IxEthDBPortMap map)
+{
+    UINT32 portIndex;
+    BOOL mapSelf = true, mapNone = true, firstPort = true;
+    
+    /* dependency port maps */
+    printf("Dependency port map: ");
+    
+    /* browse the port map */
+    for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+    {
+        if (IS_PORT_INCLUDED(portIndex, map))
+        {
+            mapNone   = false;
+            
+            if (portIndex != portID)
+            {
+                mapSelf = false;
+            }
+            
+            printf("%s%d", firstPort ? "{" : ", ", portIndex);
+            
+            firstPort = false;
+        }
+    }
+    
+    if (mapNone)
+    {
+        mapSelf = false;
+    }
+    
+    printf("%s (%s)\n", firstPort ? "" : "}", mapSelf ? "self" : mapNone ? "none" : "group");
+    
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief displays all the filtering records belonging to a port
+ *
+ * @param portID ID of the port to display
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords() 
+ * instead. Calling this function is equivalent to calling
+ * ixEthDBFilteringDatabaseShowRecords(portID, IX_ETH_DB_FILTERING_RECORD)
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID)
+{
+    IxEthDBStatus local_result;
+    HashIterator iterator;
+    PortInfo *portInfo;
+    UINT32 recordCount = 0;
+
+    IX_ETH_DB_CHECK_PORT(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    portInfo = &ixEthDBPortInfo[portID];
+
+    /* display table header */
+    printf("Ethernet database records for port ID [%d]\n", portID);
+    
+    ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap);
+    
+    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
+    {
+        printf("NPE updates are %s\n\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled");
+    }
+    else
+    {
+        printf("updates disabled (not an NPE)\n\n");
+    }
+
+    printf("    MAC address    |   Age  | Type \n");
+    printf("___________________________________\n");
+
+    /* browse database */
+    BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
+
+    while (IS_ITERATOR_VALID(&iterator))
+    {
+      MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
+
+      if (descriptor->portID == portID && descriptor->type == IX_ETH_DB_FILTERING_RECORD)
+      {
+          recordCount++;
+
+          /* display entry */
+          printf(" %02X:%02X:%02X:%02X:%02X:%02X | %5d  | %s\n",
+              descriptor->macAddress[0],
+              descriptor->macAddress[1],
+              descriptor->macAddress[2],
+              descriptor->macAddress[3],
+              descriptor->macAddress[4],
+              descriptor->macAddress[5],
+              descriptor->recordData.filteringData.age,
+              descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
+      }
+
+      /* move to the next record */
+      BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result);
+
+      /* debug */
+      if (local_result == IX_ETH_DB_BUSY)
+      {
+          return IX_ETH_DB_FAIL;
+      }
+    }
+
+    /* display number of records */
+    printf("\nFound %d records\n", recordCount);
+
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief displays all the filtering records belonging to all the ports
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords() 
+ * instead. Calling this function is equivalent to calling
+ * ixEthDBFilteringDatabaseShowRecords(IX_ETH_DB_ALL_PORTS, IX_ETH_DB_FILTERING_RECORD)
+ */
+IX_ETH_DB_PUBLIC
+void ixEthDBFilteringDatabaseShowAll()
+{
+    IxEthDBPortId portIndex;
+
+    printf("\nEthernet learning/filtering database: listing %d ports\n\n", (UINT32) IX_ETH_DB_NUMBER_OF_PORTS);
+
+    for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
+    {
+        ixEthDBFilteringDatabaseShow(portIndex);
+
+        if (portIndex < IX_ETH_DB_NUMBER_OF_PORTS - 1)
+        {
+            printf("\n");
+        }
+    }
+}
+
+/**
+ * @brief displays one record in a format depending on the record filter
+ *
+ * @param descriptor pointer to the record
+ * @param recordFilter format filter
+ *
+ * This function will display the fields in a record depending on the
+ * selected record filter.
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBRecordShow(MacDescriptor *descriptor, IxEthDBRecordType recordFilter)
+{
+    if (recordFilter == IX_ETH_DB_FILTERING_VLAN_RECORD
+        || recordFilter == (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD))
+    {
+        /* display VLAN record header - leave this commented code in place, its purpose is to align the print format with the header
+        printf("    MAC address    |   Age  |   Type   | VLAN ID | CFI | QoS class \n");
+        printf("___________________________________________________________________\n"); */
+
+        if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
+        {
+            printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s | %d | %d | %d\n",
+                descriptor->macAddress[0],
+                descriptor->macAddress[1],
+                descriptor->macAddress[2],
+                descriptor->macAddress[3],
+                descriptor->macAddress[4],
+                descriptor->macAddress[5],
+                descriptor->recordData.filteringVlanData.age,
+                descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic",
+                IX_ETH_DB_GET_VLAN_ID(descriptor->recordData.filteringVlanData.ieee802_1qTag),
+                (descriptor->recordData.filteringVlanData.ieee802_1qTag & 0x1000) >> 12,
+                IX_ETH_DB_GET_QOS_PRIORITY(descriptor->recordData.filteringVlanData.ieee802_1qTag));
+         }
+         else if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
+         {
+            printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s | - | - | -\n",
+                descriptor->macAddress[0],
+                descriptor->macAddress[1],
+                descriptor->macAddress[2],
+                descriptor->macAddress[3],
+                descriptor->macAddress[4],
+                descriptor->macAddress[5],
+                descriptor->recordData.filteringData.age,
+                descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
+         }
+    }
+    else if (recordFilter == IX_ETH_DB_FILTERING_RECORD)
+    {
+        /* display filtering record header - leave this commented code in place, its purpose is to align the print format with the header
+        printf("    MAC address    |   Age  |   Type   \n");
+        printf("_______________________________________\n");  */
+
+        if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
+        {
+         printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s \n",
+             descriptor->macAddress[0],
+             descriptor->macAddress[1],
+             descriptor->macAddress[2],
+             descriptor->macAddress[3],
+             descriptor->macAddress[4],
+             descriptor->macAddress[5],
+             descriptor->recordData.filteringData.age,
+             descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
+        }
+    }
+    else if (recordFilter == IX_ETH_DB_WIFI_RECORD)
+    {
+        /* display WiFi record header - leave this commented code in place, its purpose is to align the print format with the header 
+        printf("    MAC address    |   GW MAC address  \n");
+        printf("_______________________________________\n"); */
+
+        if (descriptor->type == IX_ETH_DB_WIFI_RECORD)
+        {
+            if (descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
+            {
+                /* gateway address present */
+                printf("%02X:%02X:%02X:%02X:%02X:%02X | %02X:%02X:%02X:%02X:%02X:%02X \n",
+                    descriptor->macAddress[0],
+                    descriptor->macAddress[1],
+                    descriptor->macAddress[2],
+                    descriptor->macAddress[3],
+                    descriptor->macAddress[4],
+                    descriptor->macAddress[5],
+                    descriptor->recordData.wifiData.gwMacAddress[0],
+                    descriptor->recordData.wifiData.gwMacAddress[1],
+                    descriptor->recordData.wifiData.gwMacAddress[2],
+                    descriptor->recordData.wifiData.gwMacAddress[3],
+                    descriptor->recordData.wifiData.gwMacAddress[4],
+                    descriptor->recordData.wifiData.gwMacAddress[5]);
+            }
+            else
+            {
+                /* no gateway */
+                printf("%02X:%02X:%02X:%02X:%02X:%02X | ----no gateway----- \n",
+                    descriptor->macAddress[0],
+                    descriptor->macAddress[1],
+                    descriptor->macAddress[2],
+                    descriptor->macAddress[3],
+                    descriptor->macAddress[4],
+                    descriptor->macAddress[5]);
+            }
+        }
+    }
+    else if (recordFilter == IX_ETH_DB_FIREWALL_RECORD)
+    {
+        /* display Firewall record header - leave this commented code in place, its purpose is to align the print format with the header 
+        printf("    MAC address   \n");
+        printf("__________________\n"); */
+
+        if (descriptor->type == IX_ETH_DB_FIREWALL_RECORD)
+        {
+            printf("%02X:%02X:%02X:%02X:%02X:%02X \n",
+                descriptor->macAddress[0],
+                descriptor->macAddress[1],
+                descriptor->macAddress[2],
+                descriptor->macAddress[3],
+                descriptor->macAddress[4],
+                descriptor->macAddress[5]);
+        }
+    }
+    else if (recordFilter == IX_ETH_DB_ALL_RECORD_TYPES)
+    {
+        /* display composite record header - leave this commented code in place, its purpose is to align the print format with the header 
+        printf("    MAC address   | Record | Age|  Type   | VLAN |CFI| QoS |  GW MAC address   \n");
+        printf("_______________________________________________________________________________\n"); */
+
+        if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
+        {
+            printf("%02X:%02X:%02X:%02X:%02X:%02X |  VLAN  | %2d | %s | %4d | %1d |  %1d  | -----------------\n",
+                descriptor->macAddress[0],
+                descriptor->macAddress[1],
+                descriptor->macAddress[2],
+                descriptor->macAddress[3],
+                descriptor->macAddress[4],
+                descriptor->macAddress[5],
+                descriptor->recordData.filteringVlanData.age,
+                descriptor->recordData.filteringVlanData.staticEntry ? "static " : "dynamic",
+                IX_ETH_DB_GET_VLAN_ID(descriptor->recordData.filteringVlanData.ieee802_1qTag),
+                (descriptor->recordData.filteringVlanData.ieee802_1qTag & 0x1000) >> 12,
+                IX_ETH_DB_GET_QOS_PRIORITY(descriptor->recordData.filteringVlanData.ieee802_1qTag));
+         }
+         else if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
+         {
+            printf("%02X:%02X:%02X:%02X:%02X:%02X | Filter | %2d | %s | ---- | - | --- | -----------------\n",
+                descriptor->macAddress[0],
+                descriptor->macAddress[1],
+                descriptor->macAddress[2],
+                descriptor->macAddress[3],
+                descriptor->macAddress[4],
+                descriptor->macAddress[5],
+                descriptor->recordData.filteringData.age,
+                descriptor->recordData.filteringData.staticEntry ? "static " : "dynamic");
+         }
+        else if (descriptor->type == IX_ETH_DB_WIFI_RECORD)
+        {
+            if (descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
+            {
+                /* gateway address present */
+                printf("%02X:%02X:%02X:%02X:%02X:%02X |  WiFi  | -- | AP=>AP  | ---- | - | --- | %02X:%02X:%02X:%02X:%02X:%02X\n",
+                    descriptor->macAddress[0],
+                    descriptor->macAddress[1],
+                    descriptor->macAddress[2],
+                    descriptor->macAddress[3],
+                    descriptor->macAddress[4],
+                    descriptor->macAddress[5],
+                    descriptor->recordData.wifiData.gwMacAddress[0],
+                    descriptor->recordData.wifiData.gwMacAddress[1],
+                    descriptor->recordData.wifiData.gwMacAddress[2],
+                    descriptor->recordData.wifiData.gwMacAddress[3],
+                    descriptor->recordData.wifiData.gwMacAddress[4],
+                    descriptor->recordData.wifiData.gwMacAddress[5]);
+            }
+            else
+            {
+                /* no gateway */
+                printf("%02X:%02X:%02X:%02X:%02X:%02X |  WiFi  | -- | AP=>ST  | ---- | - | --- | -- no gateway -- \n",
+                    descriptor->macAddress[0],
+                    descriptor->macAddress[1],
+                    descriptor->macAddress[2],
+                    descriptor->macAddress[3],
+                    descriptor->macAddress[4],
+                    descriptor->macAddress[5]);
+            }
+        }
+        else if (descriptor->type == IX_ETH_DB_FIREWALL_RECORD)
+        {
+            printf("%02X:%02X:%02X:%02X:%02X:%02X |   FW   | -- | ------- | ---- | - | --- | -----------------\n",
+                descriptor->macAddress[0],
+                descriptor->macAddress[1],
+                descriptor->macAddress[2],
+                descriptor->macAddress[3],
+                descriptor->macAddress[4],
+                descriptor->macAddress[5]);
+        }
+    }
+    else
+    {
+        printf("invalid record filter\n");
+    }
+}
+
+/**
+ * @brief displays the status, records and configuration information of a port
+ *
+ * @param portID ID of the port
+ * @param recordFilter record filter to display
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBPortInfoShow(IxEthDBPortId portID, IxEthDBRecordType recordFilter)
+{
+    PortInfo *portInfo = &ixEthDBPortInfo[portID];
+    UINT32 recordCount = 0;
+    HashIterator iterator;
+    IxEthDBStatus local_result;
+
+    /* display port status */
+    printf("== Port ID %d ==\n", portID);
+
+    /* display capabilities */
+    printf("- Capabilities: ");
+
+    if ((portInfo->featureCapability & IX_ETH_DB_LEARNING) != 0)
+    {
+        printf("Learning (%s) ", ((portInfo->featureStatus & IX_ETH_DB_LEARNING) != 0) ? "on" : "off");
+    }
+
+    if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
+    {
+        printf("VLAN/QoS (%s) ", ((portInfo->featureStatus & IX_ETH_DB_VLAN_QOS) != 0) ? "on" : "off");
+    }
+
+    if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
+    {
+        printf("Firewall (%s) ", ((portInfo->featureStatus & IX_ETH_DB_FIREWALL) != 0) ? "on" : "off");
+    }
+
+    if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
+    {
+        printf("WiFi (%s) ", ((portInfo->featureStatus & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) ? "on" : "off");
+    }
+
+    if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
+    {
+        printf("STP (%s) ", ((portInfo->featureStatus & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0) ? "on" : "off");
+    }
+
+    printf("\n");
+
+    /* dependency map */
+    ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap);
+
+    /* NPE dynamic updates */
+    if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) 
+    {
+        printf(" - NPE dynamic update is %s\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled");
+    }
+    else
+    {
+        printf(" - dynamic update disabled (not an NPE)\n");
+    }
+
+    if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
+    {
+        if ((portInfo->featureStatus & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
+        {
+            /* WiFi header conversion */
+            if ((portInfo->frameControlDurationID 
+                + portInfo->bbsid[0] 
+                + portInfo->bbsid[1] 
+                + portInfo->bbsid[2] 
+                + portInfo->bbsid[3] 
+                + portInfo->bbsid[4] 
+                + portInfo->bbsid[5]) == 0)
+            {
+                printf(" - WiFi header conversion not configured\n");
+            }
+            else
+            {  
+                printf(" - WiFi header conversion: BBSID [%02X:%02X:%02X:%02X:%02X:%02X], Frame Control 0x%X, Duration/ID 0x%X\n", 
+                    portInfo->bbsid[0],
+                    portInfo->bbsid[1],
+                    portInfo->bbsid[2],
+                    portInfo->bbsid[3],
+                    portInfo->bbsid[4],
+                    portInfo->bbsid[5],
+                    portInfo->frameControlDurationID >> 16,
+                    portInfo->frameControlDurationID & 0xFFFF);
+            }
+        }
+        else
+        {
+            printf(" - WiFi header conversion not enabled\n");
+        }
+    }
+
+    /* Firewall */
+    if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
+    {
+        if ((portInfo->featureStatus & IX_ETH_DB_FIREWALL) != 0)
+        {
+            printf(" - Firewall is in %s-list mode\n", portInfo->firewallMode == IX_ETH_DB_FIREWALL_BLACK_LIST ? "black" : "white");
+            printf(" - Invalid source MAC address filtering is %s\n", portInfo->srcAddressFilterEnabled ? "enabled" : "disabled");
+        }
+        else
+        {
+            printf(" - Firewall not enabled\n");
+        }
+    }
+  
+    /* browse database if asked to display records */
+    if (recordFilter != IX_ETH_DB_NO_RECORD_TYPE)
+    {
+        printf("\n");
+        ixEthDBHeaderShow(recordFilter);
+
+        BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
+
+        while (IS_ITERATOR_VALID(&iterator))
+        {
+            MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
+
+            if (descriptor->portID == portID && (descriptor->type & recordFilter) != 0)
+            {
+                recordCount++;
+
+                /* display entry */
+                ixEthDBRecordShow(descriptor, recordFilter);
+            }
+
+            /* move to the next record */
+            BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result);
+
+            /* debug */
+            if (local_result == IX_ETH_DB_BUSY)
+            {
+                printf("EthDB (API): Error, database browser failed (no access), giving up\n");
+            }
+        }
+        
+        printf("\nFound %d records\n\n", recordCount);
+    }
+}
+
+/**
+ * @brief displays a record header
+ *
+ * @param recordFilter record type filter
+ *
+ * This function displays a record header, depending on
+ * the given record type filter. It is useful when used
+ * in conjunction with ixEthDBRecordShow which will display
+ * record fields formatted for the header, provided the same
+ * record filter is used.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or IX_ETH_DB_INVALID_ARG if the recordFilter
+ * parameter is invalid or not supported
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBHeaderShow(IxEthDBRecordType recordFilter)
+{
+  if (recordFilter == IX_ETH_DB_FILTERING_VLAN_RECORD
+      || recordFilter == (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD))
+  {
+    /* display VLAN record header */
+    printf("    MAC address    |   Age  |   Type   | VLAN ID | CFI | QoS class \n");
+    printf("___________________________________________________________________\n");
+  }
+  else if (recordFilter == IX_ETH_DB_FILTERING_RECORD)
+  {
+    /* display filtering record header */
+    printf("    MAC address    |   Age  |   Type   \n");
+    printf("_______________________________________\n");
+  }
+  else if (recordFilter == IX_ETH_DB_WIFI_RECORD)
+  {
+    /* display WiFi record header */
+    printf("    MAC address    |   GW MAC address  \n");
+    printf("_______________________________________\n");
+  }
+  else if (recordFilter == IX_ETH_DB_FIREWALL_RECORD)
+  {
+    /* display Firewall record header */
+    printf("    MAC address   \n");
+    printf("__________________\n");
+  }
+  else if (recordFilter == IX_ETH_DB_ALL_RECORD_TYPES)
+  {
+    /* display composite record header */
+    printf("    MAC address   | Record | Age|  Type   | VLAN |CFI| QoS |  GW MAC address   \n");
+    printf("_______________________________________________________________________________\n");
+  }
+  else
+  {
+    return IX_ETH_DB_INVALID_ARG;
+  }
+  
+  return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief displays database information (records and port information)
+ *
+ * @param portID ID of the port to display (or IX_ETH_DB_ALL_PORTS for all the ports)
+ * @param recordFilter record filter (use IX_ETH_DB_NO_RECORD_TYPE to display only
+ * port information)
+ * 
+ * Note that this function is documented in the main component header
+ * file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully or
+ * an appropriate error code otherwise
+ * 
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter)
+{
+  IxEthDBPortId currentPort;
+  BOOL showAllPorts = (portID == IX_ETH_DB_ALL_PORTS);
+  
+  IX_ETH_DB_CHECK_PORT_ALL(portID);
+
+  printf("\nEthernet learning/filtering database: listing %d port(s)\n\n", showAllPorts ? (UINT32) IX_ETH_DB_NUMBER_OF_PORTS : 1);
+  
+  currentPort = showAllPorts ? 0 : portID;
+  
+  while (currentPort != IX_ETH_DB_NUMBER_OF_PORTS)
+  {
+    /* display port info */
+    ixEthDBPortInfoShow(currentPort, recordFilter);
+    
+    /* next port */
+    currentPort = showAllPorts ? currentPort + 1 : IX_ETH_DB_NUMBER_OF_PORTS;
+  }
+  
+  return IX_ETH_DB_SUCCESS;
+}
+
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBSearch.c b/marvell/uboot/drivers/net/npe/IxEthDBSearch.c
new file mode 100644
index 0000000..4fd28da
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBSearch.c
@@ -0,0 +1,303 @@
+/**
+ * @file IxEthDBSearch.c
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+
+extern HashTable dbHashtable;
+
+/**
+ * @brief matches two database records based on their MAC addresses
+ *
+ * @param untypedReference record to match against
+ * @param untypedEntry record to match
+ *
+ * @return true if the match is successful or false otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry)
+{
+    MacDescriptor *entry     = (MacDescriptor *) untypedEntry;
+    MacDescriptor *reference = (MacDescriptor *) untypedReference;
+    
+    /* check accepted record types */
+    if ((entry->type & reference->type) == 0) return false;
+       
+    return (ixEthDBAddressCompare((UINT8 *) entry->macAddress, (UINT8 *) reference->macAddress) == 0);
+}
+
+/**
+ * @brief matches two database records based on their MAC addresses
+ * and VLAN IDs
+ *
+ * @param untypedReference record to match against
+ * @param untypedEntry record to match
+ *
+ * @return true if the match is successful or false otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry)
+{
+    MacDescriptor *entry     = (MacDescriptor *) untypedEntry;
+    MacDescriptor *reference = (MacDescriptor *) untypedReference;
+    
+    /* check accepted record types */
+    if ((entry->type & reference->type) == 0) return false;
+    
+    return (IX_ETH_DB_GET_VLAN_ID(entry->recordData.filteringVlanData.ieee802_1qTag) ==
+        IX_ETH_DB_GET_VLAN_ID(reference->recordData.filteringVlanData.ieee802_1qTag)) &&
+        (ixEthDBAddressCompare(entry->macAddress, reference->macAddress) == 0);
+}
+
+/**
+ * @brief matches two database records based on their MAC addresses
+ * and port IDs
+ *
+ * @param untypedReference record to match against
+ * @param untypedEntry record to match
+ *
+ * @return true if the match is successful or false otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry)
+{
+    MacDescriptor *entry     = (MacDescriptor *) untypedEntry;
+    MacDescriptor *reference = (MacDescriptor *) untypedReference;
+    
+    /* check accepted record types */
+    if ((entry->type & reference->type) == 0) return false;
+    
+    return (entry->portID == reference->portID) &&
+        (ixEthDBAddressCompare(entry->macAddress, reference->macAddress) == 0);
+}
+
+/**
+ * @brief dummy matching function, registered for safety
+ *
+ * @param reference record to match against (unused)
+ * @param entry record to match (unused)
+ *
+ * This function is registered in the matching functions
+ * array on invalid types. Calling it will display an 
+ * error message, indicating an error in the component logic.
+ *
+ * @return false
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+BOOL ixEthDBNullMatch(void *reference, void *entry)
+{
+    /* display an error message */
+
+    ixOsalLog(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, "DB: (Search) The NullMatch function was called, wrong key type?\n", 0, 0, 0, 0, 0, 0);
+
+
+    return false;
+}
+
+/**
+ * @brief registers hash matching methods
+ *
+ * @param matchFunctions table of match functions to be populated
+ *
+ * This function registers the available record matching functions
+ * by indexing them on record types into the given function array.
+ * 
+ * Note that it is compulsory to call this in ixEthDBInit(), 
+ * otherwise hashtable searching and removal will not work
+ *
+ * @return number of registered functions
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions)
+{
+    UINT32 i;
+    
+    /* safety first */
+    for ( i = 0 ; i < IX_ETH_DB_MAX_KEY_INDEX + 1 ; i++)
+    {
+        matchFunctions[i] = ixEthDBNullMatch;
+    }
+    
+    /* register MAC search method */
+    matchFunctions[IX_ETH_DB_MAC_KEY] = ixEthDBAddressRecordMatch;
+    
+    /* register MAC/PortID search method */
+    matchFunctions[IX_ETH_DB_MAC_PORT_KEY] = ixEthDBPortRecordMatch;
+    
+    /* register MAC/VLAN ID search method */
+    matchFunctions[IX_ETH_DB_MAC_VLAN_KEY] = ixEthDBVlanRecordMatch;
+    
+    return 3; /* three methods */
+}
+
+/**
+ * @brief search a record in the Ethernet datbase
+ *
+ * @param macAddress MAC address to perform the search on
+ * @param typeFilter type of records to consider for matching
+ *
+ * @warning if searching is successful an implicit write lock
+ * to the search result is granted, therefore unlock the 
+ * entry using @ref ixEthDBReleaseHashNode() as soon as possible.
+ *
+ * @see ixEthDBReleaseHashNode()
+ *
+ * @return the search result, or NULL if a record with the given
+ * MAC address was not found
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter)
+{
+    HashNode *searchResult = NULL;
+    MacDescriptor reference;
+    
+    TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
+
+    if (macAddress == NULL)
+    {
+        return NULL;
+    }
+
+    /* fill search fields */
+    memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
+    
+    /* set acceptable record types */
+    reference.type = typeFilter;
+    
+    BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference, &searchResult));
+
+    return searchResult;
+}
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter)
+{
+    MacDescriptor reference;
+    IxEthDBStatus result;
+    
+    TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER;
+
+    if (macAddress == NULL)
+    {
+        return IX_ETH_DB_INVALID_ARG;
+    }
+
+    /* fill search fields */
+    memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
+    
+    /* set acceptable record types */
+    reference.type = typeFilter;
+    
+    result = ixEthDBPeekHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference);
+
+    return result;
+}
+
+/**
+ * @brief search a record in the Ethernet datbase
+ *
+ * @param macAddress MAC address to perform the search on
+ * @param portID port ID to perform the search on
+ * @param typeFilter type of records to consider for matching
+ *
+ * @warning if searching is successful an implicit write lock
+ * to the search result is granted, therefore unlock the 
+ * entry using @ref ixEthDBReleaseHashNode() as soon as possible.
+ *
+ * @see ixEthDBReleaseHashNode()
+ *
+ * @return the search result, or NULL if a record with the given
+ * MAC address/port ID combination was not found
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter)
+{
+    HashNode *searchResult = NULL;
+    MacDescriptor reference;
+    
+    if (macAddress == NULL)
+    {
+        return NULL;
+    }
+    
+    /* fill search fields */
+    memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
+    reference.portID = portID;
+    
+    /* set acceptable record types */
+    reference.type = typeFilter;
+
+    BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference, &searchResult));
+
+    return searchResult;
+}
+
+/**
+ * @brief search a record in the Ethernet datbase
+ *
+ * @param macAddress MAC address to perform the search on
+ * @param vlanID VLAN ID to perform the search on
+ * @param typeFilter type of records to consider for matching
+ *
+ * @warning if searching is successful an implicit write lock
+ * to the search result is granted, therefore unlock the 
+ * entry using @ref ixEthDBReleaseHashNode() as soon as possible.
+ *
+ * @see ixEthDBReleaseHashNode()
+ *
+ * @return the search result, or NULL if a record with the given
+ * MAC address/VLAN ID combination was not found
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter)
+{
+    HashNode *searchResult = NULL;
+    MacDescriptor reference;
+    
+    if (macAddress == NULL)
+    {
+        return NULL;
+    }
+    
+    /* fill search fields */
+    memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr));
+    reference.recordData.filteringVlanData.ieee802_1qTag = 
+            IX_ETH_DB_SET_VLAN_ID(reference.recordData.filteringVlanData.ieee802_1qTag, vlanID);
+    
+    /* set acceptable record types */
+    reference.type = typeFilter;
+
+    BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_VLAN_KEY, &reference, &searchResult));
+
+    return searchResult;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBSpanningTree.c b/marvell/uboot/drivers/net/npe/IxEthDBSpanningTree.c
new file mode 100644
index 0000000..e12be0d
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBSpanningTree.c
@@ -0,0 +1,83 @@
+/**
+ * @file IxEthDBSpanningTree.c
+ *
+ * @brief Implementation of the STP API
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#include "IxEthDB_p.h"
+
+/**
+ * @brief sets the STP blocking state of a port
+ *
+ * @param portID ID of the port
+ * @param blocked true to block the port or false to unblock it
+ * 
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked)
+{
+    IxNpeMhMessage message;
+    IX_STATUS result;
+    
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+ 
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL);
+    
+    ixEthDBPortInfo[portID].stpBlocked = blocked;
+
+    FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked);
+    
+    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+    
+    return result;
+}
+
+/**
+ * @brief retrieves the STP blocking state of a port
+ *
+ * @param portID ID of the port
+ * @param blocked address to write the blocked status into
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+ 
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL);
+    
+    IX_ETH_DB_CHECK_REFERENCE(blocked);
+    
+    *blocked = ixEthDBPortInfo[portID].stpBlocked;
+    
+    return IX_ETH_DB_SUCCESS;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBUtil.c b/marvell/uboot/drivers/net/npe/IxEthDBUtil.c
new file mode 100644
index 0000000..40d4470
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBUtil.c
@@ -0,0 +1,96 @@
+/**
+ * @file ethUtil.c
+ *
+ * @brief Utility functions
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#include "IxFeatureCtrl.h"
+#include "IxEthDB_p.h"
+
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portID)
+{
+    /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */ 
+    if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != 
+        (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+        || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+    {  
+        if ((portID == 0) && 
+            (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
+             IX_FEATURE_CTRL_COMPONENT_DISABLED))
+        {
+	    return IX_ETH_DB_FAIL;
+        }
+
+        if ((portID == 1) &&
+            (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
+             IX_FEATURE_CTRL_COMPONENT_DISABLED))
+        {
+	    return IX_ETH_DB_FAIL;	    
+        }
+
+        if ((portID == 2) &&
+            (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) ==
+             IX_FEATURE_CTRL_COMPONENT_DISABLED))
+        {
+	    return IX_ETH_DB_FAIL;	    
+        }
+    }
+    
+    return IX_ETH_DB_SUCCESS;
+}
+
+IX_ETH_DB_PUBLIC
+BOOL ixEthDBCheckSingleBitValue(UINT32 value)
+{
+#if (CPU != SIMSPARCSOLARIS) && !defined (__wince)
+    UINT32 shift;
+    
+    /* use the count-leading-zeros XScale instruction */
+    __asm__ ("clz %0, %1\n" : "=r" (shift) : "r" (value));
+    
+    return ((value << shift) == 0x80000000UL);
+    
+#else
+	
+    while (value != 0)
+    {
+        if (value == 1) return true;
+        else if ((value & 1) == 1) return false;
+
+        value >>= 1;
+    }
+    
+    return false;
+
+#endif
+}
+
+const char *mac2string(const unsigned char *mac)
+{
+  static char str[19];
+  
+  if (mac == NULL)
+  {
+    return NULL;
+  }  
+
+  sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+  return str;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBVlan.c b/marvell/uboot/drivers/net/npe/IxEthDBVlan.c
new file mode 100644
index 0000000..483e348
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBVlan.c
@@ -0,0 +1,1155 @@
+/**
+ * @file IxEthDBVlan.c
+ *
+ * @brief Implementation of the VLAN API
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB.h"
+#include "IxEthDB_p.h"
+
+/* forward prototypes */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex);
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet);
+
+/* contants used by various functions as "action" parameter */
+#define ADD_VLAN    (0x1)
+#define REMOVE_VLAN (0x2)
+
+/**
+ * @brief adds or removes a VLAN from a VLAN set
+ *
+ * @param vlanID VLAN ID to add or remove
+ * @param table VLAN set to add into or remove from
+ * @param action ADD_VLAN or REMOVE_VLAN
+ * 
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+void ixEthDBLocalVlanMembershipChange(UINT32 vlanID, IxEthDBVlanSet table, UINT32 action)
+{
+    UINT32 setOffset;
+    
+    /* add/remove VID to membership table */
+    setOffset = VLAN_SET_OFFSET(vlanID); /* we need 9 bits to index the 512 byte membership array */
+
+    if (action == ADD_VLAN)
+    {
+        table[setOffset] |= 1 << VLAN_SET_MASK(vlanID);
+    }
+    else if (action == REMOVE_VLAN)
+    {
+        table[setOffset] &= ~(1 << VLAN_SET_MASK(vlanID));
+    }
+}
+
+/**
+ * @brief updates a set of 8 VLANs in an NPE
+ *
+ * @param portID ID of the port
+ * @param setOffset offset of the 8 VLANs
+ *
+ * This function updates the VLAN membership table
+ * and Transmit Tagging Info table for 8 consecutive
+ * VLAN IDs indexed by setOffset.
+ *
+ * For example, a setOffset of 0 indexes VLAN IDs 0
+ * through 7, 1 indexes VLAN IDs 8 through 9 etc.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBVlanTableEntryUpdate(IxEthDBPortId portID, UINT32 setOffset)
+{
+    PortInfo *portInfo = &ixEthDBPortInfo[portID];
+    IxNpeMhMessage message;
+    IX_STATUS result;
+        
+    FILL_SETPORTVLANTABLEENTRY_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 
+        2 * setOffset, 
+        portInfo->vlanMembership[setOffset], 
+        portInfo->transmitTaggingInfo[setOffset]);
+    
+    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+    
+    return result;
+}
+
+/**
+ * @brief updates a VLAN range in an NPE
+ *
+ * @param portID ID of the port
+ *
+ * This function is similar to @ref ixEthDBVlanTableEntryUpdate
+ * except that it can update more than one VLAN set (up to
+ * the entire VLAN membership and TTI tables if the offset is 0
+ * and length is sizeof (IxEthDBVlanSet) (512 bytes).
+ *
+ * Updating the NPE via this method is slower as it requires
+ * a memory copy from SDRAM, hence it is recommended that the
+ * ixEthDBVlanTableEntryUpdate function is used where possible.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBVlanTableRangeUpdate(IxEthDBPortId portID)
+{
+    PortInfo *portInfo    = &ixEthDBPortInfo[portID];
+    UINT8 *vlanUpdateZone = (UINT8 *) portInfo->updateMethod.vlanUpdateZone;
+    IxNpeMhMessage message;
+    UINT32 setIndex;
+    IX_STATUS result;
+
+    /* copy membership info and transmit tagging into into exchange area */
+    for (setIndex = 0 ; setIndex < sizeof (portInfo->vlanMembership) ; setIndex++)
+    {
+        /* membership and TTI data are interleaved */
+        vlanUpdateZone[setIndex * 2]     = portInfo->vlanMembership[setIndex];
+        vlanUpdateZone[setIndex * 2 + 1] = portInfo->transmitTaggingInfo[setIndex];
+    }
+
+    IX_OSAL_CACHE_FLUSH(vlanUpdateZone, FULL_VLAN_BYTE_SIZE);
+    
+    /* build NPE message */
+    FILL_SETPORTVLANTABLERANGE_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 0, 0, 
+        IX_OSAL_MMU_VIRT_TO_PHYS(vlanUpdateZone));
+
+    /* send message */    
+    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+    return result;
+}
+
+/**
+ * @brief adds or removes a VLAN from a port's VLAN membership table
+ * or Transmit Tagging Information table
+ *
+ * @param portID ID of the port
+ * @param vlanID VLAN ID to add or remove
+ * @param table to add or remove from
+ * @param action ADD_VLAN or REMOVE_VLAN
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBPortVlanMembershipChange(IxEthDBPortId portID, IxEthDBVlanId vlanID, IxEthDBVlanSet table, UINT32 action)
+{
+    /* change VLAN in local membership table */
+    ixEthDBLocalVlanMembershipChange(vlanID, table, action);
+    
+    /* send updated entry to NPE */
+    return ixEthDBVlanTableEntryUpdate(portID, VLAN_SET_OFFSET(vlanID));
+}
+
+/**
+ * @brief sets the default port VLAN tag (the lower 3 bytes are the PVID)
+ *
+ * @param portID ID of the port
+ * @param vlanTag port VLAN tag (802.1Q tag)
+ * 
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag)
+{
+    IxNpeMhMessage message;
+    IX_STATUS result;
+    
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+ 
+    IX_ETH_DB_CHECK_VLAN_TAG(vlanTag);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+        
+    /* add VLAN ID to local membership table */
+    ixEthDBPortVlanMembershipChange(portID, 
+        vlanTag & IX_ETH_DB_802_1Q_VLAN_MASK, 
+        ixEthDBPortInfo[portID].vlanMembership, 
+        ADD_VLAN);
+        
+    /* set tag in portInfo */
+    ixEthDBPortInfo[portID].vlanTag = vlanTag;
+    
+    /* build VLAN_SetDefaultRxVID message */
+    FILL_SETDEFAULTRXVID_MSG(message, 
+        IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 
+        IX_IEEE802_1Q_VLAN_TPID, 
+        vlanTag);
+    
+    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+    
+    return result;
+}
+
+/**
+ * @brief retrieves the default port VLAN tag (the lower 3 bytes are the PVID)
+ *
+ * @param portID ID of the port
+ * @param vlanTag address to write the port VLAN tag (802.1Q tag) into
+ * 
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+    
+    IX_ETH_DB_CHECK_REFERENCE(vlanTag);
+    
+    *vlanTag = ixEthDBPortInfo[portID].vlanTag;
+    
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief sets the VLAN tag (the lower 3 bytes are the PVID) of a 
+ * database filtering record
+ *
+ * @param portID ID of the port
+ * @param vlanTag VLAN tag (802.1Q tag)
+ * 
+ * Important: filtering records are automatically converted to 
+ * IX_ETH_DB_FILTERING_VLAN record when added a VLAN tag.
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag)
+{
+    HashNode *searchResult;
+    MacDescriptor *descriptor;
+    
+    IX_ETH_DB_CHECK_REFERENCE(macAddr);
+    
+    IX_ETH_DB_CHECK_VLAN_TAG(vlanTag);
+    
+    searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
+    
+    if (searchResult == NULL)
+    {
+        return IX_ETH_DB_NO_SUCH_ADDR;
+    }
+    
+    descriptor = (MacDescriptor *) searchResult->data;
+    
+    /* set record type to VLAN if not already set */
+    descriptor->type = IX_ETH_DB_FILTERING_VLAN_RECORD;
+    
+    /* add vlan tag */
+    descriptor->recordData.filteringVlanData.ieee802_1qTag = vlanTag;
+    
+    /* transaction completed */
+    ixEthDBReleaseHashNode(searchResult);
+    
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief retrieves the VLAN tag (the lower 3 bytes are the PVID) from a 
+ * database VLAN filtering record
+ *
+ * @param portID ID of the port
+ * @param vlanTag address to write the VLAN tag (802.1Q tag) into
+ * 
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag)
+{
+    HashNode *searchResult;
+    MacDescriptor *descriptor;
+    
+    IX_ETH_DB_CHECK_REFERENCE(macAddr);
+    
+    IX_ETH_DB_CHECK_REFERENCE(vlanTag);
+    
+    searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_FILTERING_VLAN_RECORD);
+    
+    if (searchResult == NULL)
+    {
+        return IX_ETH_DB_NO_SUCH_ADDR;
+    }
+    
+    descriptor = (MacDescriptor *) searchResult->data;
+        
+    /* get vlan tag */
+    *vlanTag = descriptor->recordData.filteringVlanData.ieee802_1qTag;
+    
+    /* transaction completed */
+    ixEthDBReleaseHashNode(searchResult);
+    
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief adds a VLAN to a port's VLAN membership table
+ *
+ * @param portID ID of the port
+ * @param vlanID VLAN ID to add
+ * 
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    IX_ETH_DB_CHECK_VLAN_ID(vlanID);
+
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+    return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN);
+}
+
+/**
+ * @brief removes a VLAN from a port's VLAN membership table
+ *
+ * @param portID ID of the port
+ * @param vlanID VLAN ID to remove
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+    IX_ETH_DB_CHECK_VLAN_ID(vlanID);
+
+    /* for safety isolate only the VLAN ID in the tag (the lower 12 bits) */
+    vlanID = vlanID & IX_ETH_DB_802_1Q_VLAN_MASK;
+    
+    /* check we're not asked to remove the default port VID */
+    if (vlanID == IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag))
+    {
+        return IX_ETH_DB_NO_PERMISSION;
+    }
+    
+    return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN);
+}
+
+/**
+ * @brief adds or removes a VLAN range from a port's 
+ * VLAN membership table or TTI table
+ *
+ * @param portID ID of the port
+ * @param vlanIDMin start of the VLAN range
+ * @param vlanIDMax end of the VLAN range
+ * @param table VLAN set to add or remove from
+ * @param action ADD_VLAN or REMOVE_VLAN
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBPortVlanMembershipRangeChange(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, IxEthDBVlanSet table, UINT32 action)
+{
+    UINT32 setOffsetMin, setOffsetMax;
+    
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+    
+    IX_ETH_DB_CHECK_VLAN_ID(vlanIDMin);
+    
+    IX_ETH_DB_CHECK_VLAN_ID(vlanIDMax);
+    
+    /* for safety isolate only the VLAN ID in the tags (the lower 12 bits) */
+    vlanIDMin = vlanIDMin & IX_ETH_DB_802_1Q_VLAN_MASK;
+    vlanIDMax = vlanIDMax & IX_ETH_DB_802_1Q_VLAN_MASK;
+    
+    /* is this a range? */
+    if (vlanIDMax < vlanIDMin)
+    {
+        return IX_ETH_DB_INVALID_VLAN;
+    }
+    
+    /* check that we're not specifically asked to remove the default port VID */
+    if (action == REMOVE_VLAN && vlanIDMax == vlanIDMin && IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag) == vlanIDMin)
+    {
+        return IX_ETH_DB_NO_PERMISSION;
+    }
+    
+    /* compute set offsets */
+    setOffsetMin = VLAN_SET_OFFSET(vlanIDMin);
+    setOffsetMax = VLAN_SET_OFFSET(vlanIDMax);
+
+    /* change VLAN range */
+    for (; vlanIDMin <= vlanIDMax ; vlanIDMin++)
+    {
+        /* change vlan in local membership table */
+        ixEthDBLocalVlanMembershipChange(vlanIDMin, table, action);
+    }
+
+    /* if the range is within one set (max 8 VLANs in one table byte) we can just update that entry in the NPE */
+    if (setOffsetMin == setOffsetMax)
+    {
+        /* send updated entry to NPE */
+        return ixEthDBVlanTableEntryUpdate(portID, setOffsetMin);
+    }
+    else
+    {
+        /* update a zone of the membership/transmit tag info table */
+        return ixEthDBVlanTableRangeUpdate(portID);
+    }
+}
+
+/**
+ * @brief adds a VLAN range to a port's VLAN membership table
+ *
+ * @param portID ID of the port
+ * @param vlanIDMin start of the VLAN range
+ * @param vlanIDMax end of the VLAN range
+ * 
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN);
+}
+
+/**
+ * @brief removes a VLAN range from a port's VLAN membership table
+ *
+ * @param portID ID of the port
+ * @param vlanIDMin start of the VLAN range
+ * @param vlanIDMax end of the VLAN range
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN);
+}
+
+/**
+ * @brief sets a port's VLAN membership table or TTI table and
+ * updates the NPE VLAN configuration
+ *
+ * @param portID ID of the port
+ * @param portVlanTable port VLAN table to set
+ * @param vlanSet new set contents
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+    
+    IX_ETH_DB_CHECK_REFERENCE(vlanSet);
+
+    memcpy(portVlanTable, vlanSet, sizeof (IxEthDBVlanSet));
+    
+    return ixEthDBVlanTableRangeUpdate(portID);
+}
+
+/**
+ * @brief retireves a port's VLAN membership table or TTI table
+ *
+ * @param portID ID of the port
+ * @param portVlanTable port VLAN table to retrieve
+ * @param vlanSet address to 
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+    
+    IX_ETH_DB_CHECK_REFERENCE(vlanSet);
+    
+    memcpy(vlanSet, portVlanTable, sizeof (IxEthDBVlanSet));
+    
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief sets a port's VLAN membership table
+ *
+ * @param portID ID of the port
+ * @param vlanSet new VLAN membership table
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+{
+    IxEthDBVlanId vlanID;
+
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    IX_ETH_DB_CHECK_REFERENCE(vlanSet);
+
+    /* set the bit corresponding to the PVID just in case */
+    vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag);
+    vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID);
+    
+    return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet);
+}
+
+/**
+ * @brief retrieves a port's VLAN membership table
+ *
+ * @param portID ID of the port
+ * @param vlanSet location to store the port's VLAN membership table
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet);
+}
+
+/**
+ * @brief enables or disables Egress tagging for one VLAN ID
+ *
+ * @param portID ID of the port
+ * @param vlanID VLAN ID to enable or disable Egress tagging on
+ * @param enabled true to enable and false to disable tagging
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    IX_ETH_DB_CHECK_VLAN_ID(vlanID);
+
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+    return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN);
+}
+
+/**
+ * @brief retrieves the Egress tagging status for one VLAN ID
+ *
+ * @param portID ID of the port
+ * @param vlanID VLAN ID to retrieve the tagging status for
+ * @param enabled location to store the tagging status
+ * (true - tagging enabled, false - tagging disabled)
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+    
+    IX_ETH_DB_CHECK_REFERENCE(enabled);
+
+    IX_ETH_DB_CHECK_VLAN_ID(vlanID);
+    
+    *enabled = ((ixEthDBPortInfo[portID].transmitTaggingInfo[VLAN_SET_OFFSET(vlanID)] & (1 << VLAN_SET_MASK(vlanID))) != 0);
+    
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief enables or disables Egress VLAN tagging for a VLAN range
+ *
+ * @param portID ID of the port
+ * @param vlanIDMin start of VLAN range
+ * @param vlanIDMax end of VLAN range
+ * @param enabled true to enable or false to disable VLAN tagging
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN);
+}
+
+/**
+ * @brief sets the Egress VLAN tagging table (the Transmit Tagging
+ * Information table)
+ *
+ * @param portID ID of the port
+ * @param vlanSet new TTI table
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+{
+    IxEthDBVlanId vlanID;
+
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    IX_ETH_DB_CHECK_REFERENCE(vlanSet);
+
+    /* set the PVID bit just in case */
+    vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag);
+    vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID);
+    
+    return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet);
+}
+
+/**
+ * @brief retrieves the Egress VLAN tagging table (the Transmit 
+ * Tagging Information table)
+ *
+ * @param portID ID of the port
+ * @param vlanSet location to store the port's TTI table
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet);
+}
+
+/**
+ * @brief sends the NPE the updated frame filter and default
+ * Ingress tagging
+ *
+ * @param portID ID of the port
+ * 
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBIngressVlanModeUpdate(IxEthDBPortId portID)
+{
+    PortInfo *portInfo = &ixEthDBPortInfo[portID];
+    IxNpeMhMessage message;
+    IX_STATUS result;
+
+    FILL_SETRXTAGMODE_MSG(message, portID, portInfo->npeFrameFilter, portInfo->npeTaggingAction);
+    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+    return result;
+}
+
+/**
+ * @brief sets the default Ingress tagging behavior
+ *
+ * @param portID ID of the port
+ * @param taggingAction default tagging behavior
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction)
+{
+    PortInfo *portInfo;
+    
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+    
+    portInfo = &ixEthDBPortInfo[portID];
+    
+    if (taggingAction == IX_ETH_DB_PASS_THROUGH)
+    {
+        portInfo->npeTaggingAction = 0x00;
+    }
+    else if (taggingAction == IX_ETH_DB_ADD_TAG)
+    {
+        portInfo->npeTaggingAction = 0x02;
+    }
+    else if (taggingAction == IX_ETH_DB_REMOVE_TAG)
+    {
+        portInfo->npeTaggingAction = 0x01;
+    }
+    else
+    {
+        return IX_ETH_DB_INVALID_ARG;
+    }
+    
+    portInfo->taggingAction = taggingAction;
+    
+    return ixEthDBIngressVlanModeUpdate(portID);
+}
+
+/**
+ * @brief retrieves the default Ingress tagging behavior of a port
+ *
+ * @param portID ID of the port
+ * @param taggingAction location to save the default tagging behavior
+ * 
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+    IX_ETH_DB_CHECK_REFERENCE(taggingAction);
+    
+    *taggingAction = ixEthDBPortInfo[portID].taggingAction;
+    
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief sets the Ingress acceptable frame type filter
+ *
+ * @param portID ID of the port
+ * @param frameFilter acceptable frame type filter
+ * 
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter)
+{
+    PortInfo *portInfo;
+    IxEthDBStatus result = IX_ETH_DB_SUCCESS;
+        
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+    
+    /* check parameter range 
+       the ORed value of the valid values is 0x7
+       a value having extra bits is invalid */
+    if ((frameFilter | 0x7) != 0x7 || frameFilter == 0)
+    {
+        return IX_ETH_DB_INVALID_ARG;
+    }
+    
+    portInfo = &ixEthDBPortInfo[portID];
+    
+    portInfo->frameFilter    = frameFilter;
+    portInfo->npeFrameFilter = 0; /* allow all by default */
+    
+    /* if accepting priority tagged but not all VLAN tagged
+       set the membership table to contain only VLAN ID 0 
+       hence remove vlans 1-4094 and add VLAN ID 0 */
+    if (((frameFilter & IX_ETH_DB_PRIORITY_TAGGED_FRAMES) != 0)
+        && ((frameFilter & IX_ETH_DB_VLAN_TAGGED_FRAMES) == 0))
+    {
+        result = ixEthDBPortVlanMembershipRangeChange(portID, 
+            1, IX_ETH_DB_802_1Q_MAX_VLAN_ID, portInfo->vlanMembership, REMOVE_VLAN);
+
+        if (result == IX_ETH_DB_SUCCESS)
+        {
+            ixEthDBLocalVlanMembershipChange(0, portInfo->vlanMembership, ADD_VLAN);
+            result = ixEthDBVlanTableRangeUpdate(portID);
+        }
+    }
+    
+    /* untagged only? */
+    if (frameFilter == IX_ETH_DB_UNTAGGED_FRAMES)
+    {
+        portInfo->npeFrameFilter = 0x01;
+    }
+    
+    /* tagged only? */
+    if ((frameFilter & IX_ETH_DB_UNTAGGED_FRAMES) == 0)
+    {
+        portInfo->npeFrameFilter = 0x02;
+    }
+
+    if (result == IX_ETH_DB_SUCCESS)
+    {
+        result = ixEthDBIngressVlanModeUpdate(portID);
+    }
+
+    return result;
+}
+
+/**
+ * @brief retrieves the acceptable frame type filter for a port
+ *
+ * @param portID ID of the port
+ * @param frameFilter location to store the frame filter
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+    
+    IX_ETH_DB_CHECK_REFERENCE(frameFilter);
+    
+    *frameFilter = ixEthDBPortInfo[portID].frameFilter;
+    
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief sends an NPE the updated configuration related
+ * to one QoS priority (associated traffic class and AQM mapping)
+ *
+ * @param portID ID of the port
+ * @param classIndex QoS priority (traffic class index)
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex)
+{
+    IxNpeMhMessage message;
+    IX_STATUS result;
+
+    UINT32 trafficClass = ixEthDBPortInfo[portID].priorityTable[classIndex];
+    UINT32 aqmQueue     = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[trafficClass];
+    
+    FILL_SETRXQOSENTRY(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), classIndex, trafficClass, aqmQueue);
+    
+    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+    
+    return result;
+}
+
+/**
+ * @brief sets the priority mapping table
+ *
+ * @param portID ID of the port
+ * @param priorityTable new priority mapping table
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable)
+{
+    UINT32 classIndex;
+    
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+    
+    IX_ETH_DB_CHECK_REFERENCE(priorityTable);
+           
+    for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++)
+    {
+        /* check range */
+        if (priorityTable[classIndex] >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount)
+        {
+            return IX_ETH_DB_INVALID_PRIORITY;
+        }
+    }
+    
+    /* set new traffic classes */
+    for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++)
+    {
+        ixEthDBPortInfo[portID].priorityTable[classIndex] = priorityTable[classIndex];
+        
+        if (ixEthDBUpdateTrafficClass(portID, classIndex) != IX_ETH_DB_SUCCESS)
+        {
+            return IX_ETH_DB_FAIL;
+        }
+    }
+    
+    return IX_ETH_DB_SUCCESS;
+ }
+
+/**
+ * @brief retrieves a port's priority mapping table
+ *
+ * @param portID ID of the port
+ * @param priorityTable location to store the priority table
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+    
+    IX_ETH_DB_CHECK_REFERENCE(priorityTable);
+    
+    memcpy(priorityTable, ixEthDBPortInfo[portID].priorityTable, sizeof (IxEthDBPriorityTable));
+    
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief sets one QoS priority => traffic class mapping
+ *
+ * @param portID ID of the port
+ * @param userPriority QoS (user) priority
+ * @param trafficClass associated traffic class
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+    /* check ranges for userPriority and trafficClass */
+    if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT || trafficClass >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount)
+    {
+        return IX_ETH_DB_INVALID_PRIORITY;
+    }
+    
+    ixEthDBPortInfo[portID].priorityTable[userPriority] = trafficClass;
+    
+    return ixEthDBUpdateTrafficClass(portID, userPriority);
+}
+
+/**
+ * @brief retrieves one QoS priority => traffic class mapping
+ *
+ * @param portID ID of the port
+ * @param userPriority QoS (user) priority
+ * @param trafficClass location to store the associated traffic class
+ * 
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+    
+    IX_ETH_DB_CHECK_REFERENCE(trafficClass);
+    
+    /* check userPriority range */
+    if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT)
+    {
+        return IX_ETH_DB_INVALID_PRIORITY;
+    }
+    
+    *trafficClass = ixEthDBPortInfo[portID].priorityTable[userPriority];
+    
+    return IX_ETH_DB_SUCCESS;
+}
+
+/**
+ * @brief enables or disables the source port extraction
+ * from the VLAN TPID field
+ *
+ * @param portID ID of the port
+ * @param enable true to enable or false to disable
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable)
+{
+    IxNpeMhMessage message;
+    IX_STATUS result;
+
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
+
+    FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable);
+
+    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+    
+    return result;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxEthDBWiFi.c b/marvell/uboot/drivers/net/npe/IxEthDBWiFi.c
new file mode 100644
index 0000000..44edd47
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthDBWiFi.c
@@ -0,0 +1,456 @@
+/**
+ * @file IxEthDBAPI.c
+ *
+ * @brief Implementation of the public API
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxEthDB_p.h"
+
+/* forward prototypes */
+IX_ETH_DB_PUBLIC
+MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations);
+
+/**
+ * @brief sets the BBSID value for the WiFi header conversion feature
+ *
+ * @param portID ID of the port
+ * @param bbsid pointer to the 6-byte BBSID value
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid)
+{
+    IxNpeMhMessage message;
+    IX_STATUS result;
+    
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
+ 
+    IX_ETH_DB_CHECK_REFERENCE(bbsid);
+    
+    memcpy(ixEthDBPortInfo[portID].bbsid, bbsid, sizeof (IxEthDBMacAddr));
+
+    FILL_SETBBSID_MSG(message, portID, bbsid);
+
+    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+    
+    return result;
+}
+
+/**
+ * @brief updates the Frame Control and Duration/ID WiFi header
+ * conversion parameters in an NPE
+ *
+ * @param portID ID of the port
+ *
+ * This function will send a message to the NPE updating the 
+ * frame conversion parameters for 802.3 => 802.11 header conversion.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or IX_ETH_DB_FAIL otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBWiFiFrameControlDurationIDUpdate(IxEthDBPortId portID)
+{
+    IxNpeMhMessage message;
+    IX_STATUS result;
+
+    FILL_SETFRAMECONTROLDURATIONID(message, portID, ixEthDBPortInfo[portID].frameControlDurationID);
+    
+    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+    
+    return result;
+}
+
+/**
+ * @brief sets the Duration/ID WiFi frame header conversion parameter
+ *
+ * @param portID ID of the port
+ * @param durationID 16-bit value containing the new Duration/ID parameter
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
+
+    ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF0000) | durationID;
+    
+    return ixEthDBWiFiFrameControlDurationIDUpdate(portID);
+}
+
+/**
+ * @brief sets the Frame Control WiFi frame header conversion parameter
+ *
+ * @param portID ID of the port
+ * @param durationID 16-bit value containing the new Frame Control parameter
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl)
+{
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
+
+    ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF) | (frameControl << 16); 
+    
+    return ixEthDBWiFiFrameControlDurationIDUpdate(portID);
+}
+
+/**
+ * @brief removes a WiFi header conversion record
+ *
+ * @param portID ID of the port
+ * @param macAddr MAC address of the record to remove
+ *
+ * Note that this function is documented in the main
+ * component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+    MacDescriptor recordTemplate;
+    
+    IX_ETH_DB_CHECK_PORT(portID);
+    
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_REFERENCE(macAddr);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
+    
+    memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
+    
+    recordTemplate.type   = IX_ETH_DB_WIFI_RECORD;
+    recordTemplate.portID = portID;
+    
+    return ixEthDBRemove(&recordTemplate, NULL);
+}
+
+/**
+ * @brief adds a WiFi header conversion record
+ *
+ * @param portID ID of the port
+ * @param macAddr MAC address of the record to add
+ * @param gatewayMacAddr address of the gateway (or
+ * NULL if this is a station record)
+ *
+ * This function adds a record of type AP_TO_AP (gateway is not NULL)
+ * or AP_TO_STA (gateway is NULL) in the main database as a 
+ * WiFi header conversion record.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ *
+ * @internal
+ */
+IX_ETH_DB_PRIVATE
+IxEthDBStatus ixEthDBWiFiEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
+{
+    MacDescriptor recordTemplate;
+
+    IX_ETH_DB_CHECK_PORT(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+
+    IX_ETH_DB_CHECK_REFERENCE(macAddr);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
+
+    memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
+    
+    recordTemplate.type   = IX_ETH_DB_WIFI_RECORD;
+    recordTemplate.portID = portID;
+    
+    if (gatewayMacAddr != NULL)
+    {
+        memcpy(recordTemplate.recordData.wifiData.gwMacAddress, gatewayMacAddr, sizeof (IxEthDBMacAddr));
+        
+        recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_AP;
+    }
+    else
+    {
+        memset(recordTemplate.recordData.wifiData.gwMacAddress, 0, sizeof (IxEthDBMacAddr));
+
+        recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_STA;
+    }
+    
+    return ixEthDBAdd(&recordTemplate, NULL);
+}
+
+/**
+ * @brief adds a WiFi header conversion record
+ *
+ * @param portID ID of the port
+ * @param macAddr MAC address of the record to add
+ * @param gatewayMacAddr address of the gateway 
+ *
+ * This function adds a record of type AP_TO_AP
+ * in the main database as a WiFi header conversion record.
+ *
+ * This is simply a wrapper over @ref ixEthDBWiFiEntryAdd().
+ *
+ * Note that this function is documented in the main
+ * component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
+{
+    IX_ETH_DB_CHECK_REFERENCE(gatewayMacAddr);
+
+    return ixEthDBWiFiEntryAdd(portID, macAddr, gatewayMacAddr);
+}
+
+/**
+ * @brief adds a WiFi header conversion record
+ *
+ * @param portID ID of the port
+ * @param macAddr MAC address of the record to add
+ *
+ * This function adds a record of type AP_TO_STA
+ * in the main database as a WiFi header conversion record.
+ *
+ * This is simply a wrapper over @ref ixEthDBWiFiEntryAdd().
+ *
+ * Note that this function is documented in the main
+ * component header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed
+ * successfully or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+{
+    return ixEthDBWiFiEntryAdd(portID, macAddr, NULL);
+}
+
+/**
+ * @brief selects a set of gateways from a tree of 
+ * WiFi header conversion records
+ *
+ * @param stations binary tree containing pointers to WiFi header
+ * conversion records
+ *
+ * This function browses through the input binary tree, identifies
+ * records of type AP_TO_AP, clones these records and appends them
+ * to a vine (a single right-branch binary tree) which is returned
+ * as result. A maximum of MAX_GW_SIZE entries containing gateways
+ * will be cloned from the original tree.
+ *
+ * @return vine (linear binary tree) containing record
+ * clones of AP_TO_AP type, which have a gateway field
+ *
+ * @internal
+ */
+IX_ETH_DB_PUBLIC
+MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations)
+{
+    MacTreeNodeStack *stack;
+    MacTreeNode *gateways, *insertionPlace;
+    UINT32 gwIndex = 1; /* skip the empty root */
+    
+    if (stations == NULL)
+    {
+        return NULL;
+    }
+
+    stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack));
+
+    if (stack == NULL)
+    {
+        ERROR_LOG("DB: (WiFi) failed to allocate the node stack for gateway tree linearization, out of memory?\n");
+        return NULL;
+    }
+    
+    /* initialize root node */
+    gateways = insertionPlace = NULL;
+        
+    /* start browsing the station tree */
+    NODE_STACK_INIT(stack);
+    
+    /* initialize stack by pushing the tree root at offset 0 */
+    NODE_STACK_PUSH(stack, stations, 0);
+    
+    while (NODE_STACK_NONEMPTY(stack))
+    {
+        MacTreeNode *node;
+        UINT32 offset;
+       
+        NODE_STACK_POP(stack, node, offset);
+
+        /* we can store maximum 31 (32 total, 1 empty root) entries in the gateway tree */
+        if (offset > (MAX_GW_SIZE - 1)) break;
+        
+        /* check if this record has a gateway address */
+        if (node->descriptor != NULL && node->descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
+        {
+            /* found a record, create an insertion place */
+            if (insertionPlace != NULL)
+            {
+                insertionPlace->right = ixEthDBAllocMacTreeNode();
+                insertionPlace        = insertionPlace->right;
+            }
+            else
+            {
+                gateways       = ixEthDBAllocMacTreeNode();
+                insertionPlace = gateways;
+            }
+
+            if (insertionPlace == NULL)
+            {
+                /* no nodes left, bail out with what we have */
+                ixOsalCacheDmaFree(stack);
+                return gateways;
+            }
+            
+            /* clone the original record for the gateway tree */
+            insertionPlace->descriptor = ixEthDBCloneMacDescriptor(node->descriptor);
+            
+            /* insert and update the offset in the original record */
+            node->descriptor->recordData.wifiData.gwAddressIndex = gwIndex++;
+        }
+        
+        /* browse the tree */
+        if (node->left != NULL)
+        {
+            NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset));
+        }
+
+        if (node->right != NULL)
+        {
+            NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset));
+        }
+    }
+    
+    ixOsalCacheDmaFree(stack);
+    return gateways;    
+}
+
+/**
+ * @brief downloads the WiFi header conversion table to an NPE
+ *
+ * @param portID ID of the port
+ *
+ * This function prepares the WiFi header conversion tables and
+ * downloads them to the specified NPE port.
+ *
+ * The header conversion tables consist in the main table of
+ * addresses and the secondary table of gateways. AP_TO_AP records
+ * from the first table contain index fields into the second table
+ * for gateway selection.
+ *
+ * Note that this function is documented in the main component
+ * header file, IxEthDB.h.
+ *
+ * @return IX_ETH_DB_SUCCESS if the operation completed successfully
+ * or an appropriate error message otherwise
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID)
+{
+    IxEthDBPortMap query;
+    MacTreeNode *stations = NULL, *gateways = NULL, *gateway = NULL;
+    IxNpeMhMessage message;
+    PortInfo *portInfo;
+    IX_STATUS result;
+
+    IX_ETH_DB_CHECK_PORT(portID);
+
+    IX_ETH_DB_CHECK_SINGLE_NPE(portID);
+    
+    IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
+
+    portInfo = &ixEthDBPortInfo[portID];
+   
+    SET_DEPENDENCY_MAP(query, portID);
+    
+    ixEthDBUpdateLock();
+
+    stations = ixEthDBQuery(NULL, query, IX_ETH_DB_WIFI_RECORD, MAX_ELT_SIZE);
+    gateways = ixEthDBGatewaySelect(stations);
+    
+    /* clean up gw area */
+    memset((void *) portInfo->updateMethod.npeGwUpdateZone, FULL_GW_BYTE_SIZE, 0);
+
+    /* write all gateways */
+    gateway = gateways;
+
+    while (gateway != NULL)
+    {
+        ixEthDBNPEGatewayNodeWrite((void *) (((UINT32) portInfo->updateMethod.npeGwUpdateZone) 
+            + gateway->descriptor->recordData.wifiData.gwAddressIndex * ELT_ENTRY_SIZE), 
+            gateway);
+
+        gateway = gateway->right;
+    }
+
+    /* free the gateway tree */
+    if (gateways != NULL)
+    {
+        ixEthDBFreeMacTreeNode(gateways);
+    }
+
+    FILL_SETAPMACTABLE_MSG(message, 
+        IX_OSAL_MMU_VIRT_TO_PHYS(portInfo->updateMethod.npeGwUpdateZone));
+
+    IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
+
+    if (result == IX_SUCCESS)
+    {
+        /* update the main tree (the stations tree) */
+        portInfo->updateMethod.searchTree = stations;
+        
+        result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_WIFI_RECORD);
+    }
+
+    ixEthDBUpdateUnlock();
+
+    return result;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxEthMii.c b/marvell/uboot/drivers/net/npe/IxEthMii.c
new file mode 100644
index 0000000..27f3548
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxEthMii.c
@@ -0,0 +1,473 @@
+/**
+ * @file IxEthMii.c
+ *
+ * @author Intel Corporation
+ * @date
+ *
+ * @brief  MII control functions
+ *
+ * Design Notes:
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+
+#include "IxEthAcc.h"
+#include "IxEthMii_p.h"
+
+#ifdef __wince
+#include "IxOsPrintf.h"
+#endif
+
+/* Array to store the phy IDs of the discovered phys */
+PRIVATE UINT32 ixEthMiiPhyId[IXP425_ETH_ACC_MII_MAX_ADDR];
+
+/*********************************************************
+ *
+ * Scan for PHYs on the MII bus. This function returns
+ * an array of booleans, one for each PHY address.
+ * If a PHY is found at a particular address, the
+ * corresponding entry in the array is set to true.
+ *
+ */
+
+PUBLIC IX_STATUS
+ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount)
+{
+    UINT32 i;
+    UINT16 regval, regvalId1, regvalId2;
+
+    /*Search for PHYs on the MII*/
+    /*Search for existant phys on the MDIO bus*/
+
+    if ((phyPresent == NULL) || 
+	(maxPhyCount > IXP425_ETH_ACC_MII_MAX_ADDR))
+    {
+	return IX_FAIL;
+    }
+
+    /* fill the array */
+    for(i=0;
+        i<IXP425_ETH_ACC_MII_MAX_ADDR;
+	i++)
+    {
+	phyPresent[i] = false;
+    }
+
+    /* iterate through the PHY addresses */
+    for(i=0;
+	maxPhyCount > 0 && i<IXP425_ETH_ACC_MII_MAX_ADDR;
+	i++)
+    {
+	ixEthMiiPhyId[i] = IX_ETH_MII_INVALID_PHY_ID;
+	if(ixEthAccMiiReadRtn(i,
+			      IX_ETH_MII_CTRL_REG,
+			      &regval) == IX_ETH_ACC_SUCCESS)
+	{
+	    if((regval & 0xffff) != 0xffff)
+	    {
+		maxPhyCount--;
+		/*Need to read the register twice here to flush PHY*/
+		ixEthAccMiiReadRtn(i,  IX_ETH_MII_PHY_ID1_REG, &regvalId1);
+		ixEthAccMiiReadRtn(i,  IX_ETH_MII_PHY_ID1_REG, &regvalId1);
+		ixEthAccMiiReadRtn(i,  IX_ETH_MII_PHY_ID2_REG, &regvalId2);
+		ixEthMiiPhyId[i] = (regvalId1 << IX_ETH_MII_REG_SHL) | regvalId2;
+		if ((ixEthMiiPhyId[i] == IX_ETH_MII_KS8995_PHY_ID)
+		    || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT971_PHY_ID)
+		    || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT972_PHY_ID)
+		    || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT973_PHY_ID)
+		    || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT973A3_PHY_ID)
+		    || (ixEthMiiPhyId[i] == IX_ETH_MII_LXT9785_PHY_ID)
+		    )
+		{
+		    /* supported phy */
+		    phyPresent[i] = true;
+		} /* end of if(ixEthMiiPhyId) */
+		else
+		{
+		    if (ixEthMiiPhyId[i] != IX_ETH_MII_INVALID_PHY_ID)
+		    {
+			/* unsupported phy */
+                        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+                                   IX_OSAL_LOG_DEV_STDOUT,
+				    "ixEthMiiPhyScan : unexpected Mii PHY ID %8.8x\n", 
+				    ixEthMiiPhyId[i], 2, 3, 4, 5, 6);
+			ixEthMiiPhyId[i] = IX_ETH_MII_UNKNOWN_PHY_ID;
+			phyPresent[i] = true;
+		    }
+		} 
+	    }
+	}
+    }
+    return IX_SUCCESS;
+}
+
+/************************************************************
+ *
+ * Configure the PHY at the specified address
+ *
+ */
+PUBLIC IX_STATUS
+ixEthMiiPhyConfig(UINT32 phyAddr,
+		  BOOL speed100,
+		  BOOL fullDuplex,
+		  BOOL autonegotiate)
+{
+    UINT16 regval=0;
+
+    /* parameter check */
+    if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
+	(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
+    {
+    /*
+     * set the control register
+     */
+	if(autonegotiate)
+	{
+	    regval |= IX_ETH_MII_CR_AUTO_EN | IX_ETH_MII_CR_RESTART;
+	}
+	else
+	{
+	    if(speed100)
+	    {
+		regval |= IX_ETH_MII_CR_100;
+	    }
+	    if(fullDuplex)
+	    {
+		regval |= IX_ETH_MII_CR_FDX;
+	    }
+	} /* end of if-else() */
+	if (ixEthAccMiiWriteRtn(phyAddr, 
+				IX_ETH_MII_CTRL_REG, 
+				regval) == IX_ETH_ACC_SUCCESS)
+	{
+	    return IX_SUCCESS;
+	}
+    } /* end of if(phyAddr) */
+    return IX_FAIL;
+}
+
+/******************************************************************
+ *
+ *  Enable the PHY Loopback at the specified address
+ */
+PUBLIC IX_STATUS
+ixEthMiiPhyLoopbackEnable (UINT32 phyAddr)
+{
+  UINT16 regval ;  
+
+  if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) && 
+      (IX_ETH_MII_INVALID_PHY_ID != ixEthMiiPhyId[phyAddr]))
+  {
+      /* read/write the control register */
+      if(ixEthAccMiiReadRtn (phyAddr,
+			     IX_ETH_MII_CTRL_REG, 
+			     &regval) 
+	 == IX_ETH_ACC_SUCCESS)
+      {
+	  if(ixEthAccMiiWriteRtn (phyAddr, 
+				  IX_ETH_MII_CTRL_REG, 
+				  regval | IX_ETH_MII_CR_LOOPBACK)
+	     == IX_ETH_ACC_SUCCESS)
+	  {
+	      return IX_SUCCESS;
+	  }
+      }
+  }
+  return IX_FAIL;
+}
+
+/******************************************************************
+ *
+ *  Disable the PHY Loopback at the specified address
+ */
+PUBLIC IX_STATUS
+ixEthMiiPhyLoopbackDisable (UINT32 phyAddr)
+{
+  UINT16 regval ;  
+
+  if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) && 
+      (IX_ETH_MII_INVALID_PHY_ID != ixEthMiiPhyId[phyAddr]))
+  {
+      /* read/write the control register */
+      if(ixEthAccMiiReadRtn (phyAddr,
+			     IX_ETH_MII_CTRL_REG, 
+			     &regval) 
+	 == IX_ETH_ACC_SUCCESS)
+      {
+	  if(ixEthAccMiiWriteRtn (phyAddr, 
+				  IX_ETH_MII_CTRL_REG, 
+				  regval & (~IX_ETH_MII_CR_LOOPBACK))
+	     == IX_ETH_ACC_SUCCESS)
+	  {
+	      return IX_SUCCESS;
+	  }
+      }
+  }
+  return IX_FAIL;
+}
+
+/******************************************************************
+ *
+ *  Reset the PHY at the specified address
+ */
+PUBLIC IX_STATUS
+ixEthMiiPhyReset(UINT32 phyAddr)
+{
+    UINT32 timeout;
+    UINT16 regval;
+
+    if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
+	(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
+    {
+	if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID)	||
+	    (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID)	||
+	    (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT973_PHY_ID)	||
+	    (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT973A3_PHY_ID)	||
+		(ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID)
+	    )
+	{
+	    /* use the control register to reset the phy */
+	    ixEthAccMiiWriteRtn(phyAddr, 
+				IX_ETH_MII_CTRL_REG,
+				IX_ETH_MII_CR_RESET);
+	 
+	    /* poll until the reset bit is cleared */
+	    timeout = 0;
+	    do
+	    {
+		ixOsalSleep (IX_ETH_MII_RESET_POLL_MS);
+
+		/* read the control register and check for timeout */
+		ixEthAccMiiReadRtn(phyAddr, 
+				   IX_ETH_MII_CTRL_REG,
+				   &regval);
+		if ((regval & IX_ETH_MII_CR_RESET) == 0)
+		{
+		    /* timeout bit is self-cleared */
+		    break;
+		}
+		timeout += IX_ETH_MII_RESET_POLL_MS;
+	    }
+	    while (timeout < IX_ETH_MII_RESET_DELAY_MS);
+
+	    /* check for timeout */
+	    if (timeout >= IX_ETH_MII_RESET_DELAY_MS)
+	    {
+		ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
+				    IX_ETH_MII_CR_NORM_EN);
+		return IX_FAIL;
+	    }
+
+	    return IX_SUCCESS;
+	} /* end of if(ixEthMiiPhyId) */
+	else if (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_KS8995_PHY_ID)
+	{
+	    /* reset bit is reserved, just reset the control register */
+	    ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
+				IX_ETH_MII_CR_NORM_EN);
+	    return IX_SUCCESS;
+	}
+	else
+	{
+	    /* unknown PHY, set the control register reset bit,
+	     * wait 2 s. and clear the control register.
+	     */
+	    ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
+				IX_ETH_MII_CR_RESET);
+	    
+	    ixOsalSleep (IX_ETH_MII_RESET_DELAY_MS);
+	    
+	    ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG,
+				IX_ETH_MII_CR_NORM_EN);
+	    return IX_SUCCESS;
+	} /* end of if-else(ixEthMiiPhyId) */
+    } /* end of if(phyAddr) */
+    return IX_FAIL;
+}
+
+/*****************************************************************
+ *
+ *  Link state query functions
+ */
+
+PUBLIC IX_STATUS
+ixEthMiiLinkStatus(UINT32 phyAddr,
+           BOOL *linkUp,
+           BOOL *speed100,
+           BOOL *fullDuplex,
+           BOOL *autoneg)
+{
+    UINT16 ctrlRegval, statRegval, regval, regval4, regval5;
+
+    /* check the parameters */
+    if ((linkUp == NULL) || 
+	(speed100 == NULL) || 
+	(fullDuplex == NULL) ||
+	(autoneg == NULL))
+    {
+	return IX_FAIL;
+    }
+
+    *linkUp = false;
+    *speed100 = false;
+    *fullDuplex = false;
+    *autoneg = false;
+
+    if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) &&
+	(ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID))
+    {
+	if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID)	||
+	    (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID)	||
+	    (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID)
+		)
+	{
+	    /* --------------------------------------------------*/
+	    /* Retrieve information from PHY specific register   */
+	    /* --------------------------------------------------*/
+	    if (ixEthAccMiiReadRtn(phyAddr, 
+				   IX_ETH_MII_STAT2_REG, 
+				   &regval) != IX_ETH_ACC_SUCCESS)
+	    {
+		return IX_FAIL;
+	    }
+	    *linkUp = ((regval & IX_ETH_MII_SR2_LINK) != 0);
+	    *speed100 = ((regval & IX_ETH_MII_SR2_100) != 0);
+	    *fullDuplex = ((regval & IX_ETH_MII_SR2_FD) != 0);
+	    *autoneg = ((regval & IX_ETH_MII_SR2_AUTO) != 0);
+	    return IX_SUCCESS;
+	} /* end of if(ixEthMiiPhyId) */
+	else
+	{    
+	    /* ----------------------------------------------------*/
+	    /* Retrieve information from status and ctrl registers */
+	    /* ----------------------------------------------------*/
+	    if (ixEthAccMiiReadRtn(phyAddr,  
+				   IX_ETH_MII_CTRL_REG, 
+				   &ctrlRegval) != IX_ETH_ACC_SUCCESS)
+	    {
+		return IX_FAIL;
+	    }
+	    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_MII_STAT_REG, &statRegval);
+	    
+	    *linkUp = ((statRegval & IX_ETH_MII_SR_LINK_STATUS) != 0);
+	    if (*linkUp)
+	    {
+		*autoneg = ((ctrlRegval & IX_ETH_MII_CR_AUTO_EN) != 0) &&
+		    ((statRegval &  IX_ETH_MII_SR_AUTO_SEL) != 0) &&
+		    ((statRegval & IX_ETH_MII_SR_AUTO_NEG) != 0);
+		
+		if (*autoneg)
+		{
+		    /* mask the current stat values with the capabilities */
+		    ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_ADS_REG, &regval4);
+		    ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_PRTN_REG, &regval5);
+		    /* merge the flags from the 3 registers */
+		    regval = (statRegval & ((regval4 & regval5) << 6));
+		    /* initialise from status register values */
+		    if ((regval & IX_ETH_MII_SR_TX_FULL_DPX) != 0)
+		    {
+			/* 100 Base X full dplx */
+			*speed100 = true;
+			*fullDuplex = true;
+			return IX_SUCCESS;
+		    }
+		    if ((regval & IX_ETH_MII_SR_TX_HALF_DPX) != 0)
+		    {
+			/* 100 Base X half dplx */
+			*speed100 = true;
+			return IX_SUCCESS;
+		    }
+		    if ((regval & IX_ETH_MII_SR_10T_FULL_DPX) != 0)
+		    {
+			/* 10 mb full dplx */
+			*fullDuplex = true;
+			return IX_SUCCESS;
+		    }
+		    if ((regval & IX_ETH_MII_SR_10T_HALF_DPX) != 0)
+		    {
+			/* 10 mb half dplx */
+			return IX_SUCCESS;
+		    }
+		} /* end of if(autoneg) */
+		else
+		{
+		    /* autonegotiate not complete, return setup parameters */
+		    *speed100 = ((ctrlRegval & IX_ETH_MII_CR_100) != 0);
+		    *fullDuplex = ((ctrlRegval & IX_ETH_MII_CR_FDX) != 0);
+		}
+	    } /* end of if(linkUp) */
+	} /* end of if-else(ixEthMiiPhyId) */
+    } /* end of if(phyAddr) */
+    else
+    {
+	return IX_FAIL;
+    } /* end of if-else(phyAddr) */
+    return IX_SUCCESS;
+}
+
+/*****************************************************************
+ *
+ *  Link state display functions
+ */
+
+PUBLIC IX_STATUS
+ixEthMiiPhyShow (UINT32 phyAddr)
+{
+    BOOL linkUp, speed100, fullDuplex, autoneg;
+    UINT16 cregval;
+    UINT16 sregval;
+    
+
+    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_MII_STAT_REG, &sregval);
+    ixEthAccMiiReadRtn(phyAddr,  IX_ETH_MII_CTRL_REG, &cregval);
+
+    /* get link information */
+    if (ixEthMiiLinkStatus(phyAddr,
+			   &linkUp,
+			   &speed100,
+			   &fullDuplex,
+			   &autoneg) != IX_ETH_ACC_SUCCESS)
+    {
+	printf("PHY Status unknown\n");
+	return IX_FAIL;
+    }
+
+    printf("PHY ID [phyAddr]: %8.8x\n",ixEthMiiPhyId[phyAddr]);
+    printf( " Status reg:  %4.4x\n",sregval);
+    printf( " control reg: %4.4x\n",cregval);
+    /* display link information */
+    printf("PHY Status:\n");
+    printf("    Link is %s\n",
+	   (linkUp ? "Up" : "Down"));
+    if((sregval & IX_ETH_MII_SR_REMOTE_FAULT) != 0)
+    {
+	printf("    Remote fault detected\n");
+    }
+    printf("    Auto Negotiation %s\n",
+	   (autoneg ? "Completed" : "Not Completed"));
+
+    printf("PHY Configuration:\n");
+    printf("    Speed %sMb/s\n",
+	   (speed100 ? "100" : "10"));
+    printf("    %s Duplex\n",
+	   (fullDuplex ? "Full" : "Half"));
+    printf("    Auto Negotiation %s\n",
+	   (autoneg ? "Enabled" : "Disabled"));
+    return IX_SUCCESS;
+}
+
diff --git a/marvell/uboot/drivers/net/npe/IxFeatureCtrl.c b/marvell/uboot/drivers/net/npe/IxFeatureCtrl.c
new file mode 100644
index 0000000..0b6807d
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxFeatureCtrl.c
@@ -0,0 +1,398 @@
+/**
+ * @file IxFeatureCtrl.c
+ *
+ * @author Intel Corporation
+ * @date 29-Jan-2003
+ *
+ * @brief Feature Control Public API Implementation
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+#include "IxOsal.h"
+#include "IxVersionId.h"
+#include "IxFeatureCtrl.h"
+
+/* Macro to read from the Feature Control Register */
+#define IX_FEATURE_CTRL_READ(result) \
+do { \
+ixFeatureCtrlExpMap(); \
+(result) = IX_OSAL_READ_LONG(ixFeatureCtrlRegister); \
+} while (0)
+
+/* Macro to write to the Feature Control Register */
+#define IX_FEATURE_CTRL_WRITE(value) \
+do { \
+ixFeatureCtrlExpMap(); \
+IX_OSAL_WRITE_LONG(ixFeatureCtrlRegister, (value)); \
+} while (0)
+
+/*
+ * This is the offset of the feature register relative to the base of the
+ * Expansion Bus Controller MMR.
+ */
+#define IX_FEATURE_CTRL_REG_OFFSET (0x00000028)
+
+
+/* Boolean to mark the fact that the EXP_CONFIG address space was mapped */
+PRIVATE BOOL ixFeatureCtrlExpCfgRegionMapped = false;
+
+/* Pointer holding the virtual address of the Feature Control Register */
+PRIVATE VUINT32 *ixFeatureCtrlRegister = NULL;
+
+/* Place holder to store the software configuration */
+PRIVATE BOOL swConfiguration[IX_FEATURECTRL_SWCONFIG_MAX];
+
+/* Flag to control swConfiguration[] is initialized once */
+PRIVATE BOOL swConfigurationFlag = false ;
+
+/* Array containing component mask values */
+#ifdef __ixp42X
+UINT32 componentMask[IX_FEATURECTRL_MAX_COMPONENTS] = {
+    (0x1<<IX_FEATURECTRL_RCOMP),
+    (0x1<<IX_FEATURECTRL_USB),
+    (0x1<<IX_FEATURECTRL_HASH),
+    (0x1<<IX_FEATURECTRL_AES),
+    (0x1<<IX_FEATURECTRL_DES),
+    (0x1<<IX_FEATURECTRL_HDLC),
+    (0x1<<IX_FEATURECTRL_AAL),
+    (0x1<<IX_FEATURECTRL_HSS),
+    (0x1<<IX_FEATURECTRL_UTOPIA),
+    (0x1<<IX_FEATURECTRL_ETH0),
+    (0x1<<IX_FEATURECTRL_ETH1),
+    (0x1<<IX_FEATURECTRL_NPEA),
+    (0x1<<IX_FEATURECTRL_NPEB),
+    (0x1<<IX_FEATURECTRL_NPEC),
+    (0x1<<IX_FEATURECTRL_PCI),
+    IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
+    (0x3<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT),
+    (0x1<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT_BIT2),
+    IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
+    IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
+    IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
+    IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE,
+    IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE
+};
+#elif defined (__ixp46X)
+UINT32 componentMask[IX_FEATURECTRL_MAX_COMPONENTS] = {
+    (0x1<<IX_FEATURECTRL_RCOMP),
+    (0x1<<IX_FEATURECTRL_USB),
+    (0x1<<IX_FEATURECTRL_HASH),
+    (0x1<<IX_FEATURECTRL_AES),
+    (0x1<<IX_FEATURECTRL_DES),
+    (0x1<<IX_FEATURECTRL_HDLC),
+    IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE,  /* AAL component is always on */
+    (0x1<<IX_FEATURECTRL_HSS),
+    (0x1<<IX_FEATURECTRL_UTOPIA),
+    (0x1<<IX_FEATURECTRL_ETH0),
+    (0x1<<IX_FEATURECTRL_ETH1),
+    (0x1<<IX_FEATURECTRL_NPEA),
+    (0x1<<IX_FEATURECTRL_NPEB),
+    (0x1<<IX_FEATURECTRL_NPEC),
+    (0x1<<IX_FEATURECTRL_PCI),
+    (0x1<<IX_FEATURECTRL_ECC_TIMESYNC),
+    (0x3<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT),
+    (0x1<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT_BIT2), /* NOT TO BE USED */
+    (0x1<<IX_FEATURECTRL_USB_HOST_CONTROLLER),
+    (0x1<<IX_FEATURECTRL_NPEA_ETH),
+    (0x1<<IX_FEATURECTRL_NPEB_ETH),
+    (0x1<<IX_FEATURECTRL_RSA),
+    (0x3<<IX_FEATURECTRL_XSCALE_MAX_FREQ),
+    (0x1<<IX_FEATURECTRL_XSCALE_MAX_FREQ_BIT2)
+};
+#endif /* __ixp42X */
+
+/**
+ * Forward declaration
+ */
+PRIVATE
+void ixFeatureCtrlExpMap(void);
+
+PRIVATE 
+void ixFeatureCtrlSwConfigurationInit(void);
+
+/**
+ * Function to map EXP_CONFIG space
+ */
+PRIVATE
+void ixFeatureCtrlExpMap(void)
+{
+    UINT32 expCfgBaseAddress = 0;
+
+    /* If the EXP Configuration space has already been mapped then
+     * return */
+    if (ixFeatureCtrlExpCfgRegionMapped == true)
+    {
+	return;
+    }
+
+    /* Map (get virtual address) for the EXP_CONFIG space */
+    expCfgBaseAddress = (UINT32)
+	(IX_OSAL_MEM_MAP(IX_OSAL_IXP400_EXP_BUS_REGS_PHYS_BASE,
+			   IX_OSAL_IXP400_EXP_REG_MAP_SIZE));
+
+    /* Assert that the mapping operation succeeded */
+    IX_OSAL_ASSERT(expCfgBaseAddress);
+
+    /* Set the address of the Feature register */
+    ixFeatureCtrlRegister =
+	(VUINT32 *) (expCfgBaseAddress + IX_FEATURE_CTRL_REG_OFFSET);
+
+    /* Mark the fact that the EXP_CONFIG space has already been mapped */
+    ixFeatureCtrlExpCfgRegionMapped = true;
+}
+
+/**
+ * Function definition: ixFeatureCtrlSwConfigurationInit
+ * This function will only initialize software configuration once.
+ */
+PRIVATE void ixFeatureCtrlSwConfigurationInit(void)
+{
+  UINT32 i;
+  if (false == swConfigurationFlag)
+  {
+    for (i=0; i<IX_FEATURECTRL_SWCONFIG_MAX ; i++)
+    {
+        /* By default, all software configuration are enabled */
+        swConfiguration[i]= true ;
+    }
+    /*Make sure this function only initializes swConfiguration[] once*/
+    swConfigurationFlag = true ;
+  }  
+}
+
+/**
+ * Function definition: ixFeatureCtrlRead
+ */
+IxFeatureCtrlReg 
+ixFeatureCtrlRead (void)
+{
+    IxFeatureCtrlReg result;
+
+#if CPU!=SIMSPARCSOLARIS
+    /* Read the feature control register */
+    IX_FEATURE_CTRL_READ(result);
+    return result;
+#else
+    /* Return an invalid value for VxWorks simulation */
+    result = 0xFFFFFFFF;
+    return result;
+#endif
+}
+
+/**
+ * Function definition: ixFeatureCtrlWrite
+ */
+void
+ixFeatureCtrlWrite (IxFeatureCtrlReg expUnitReg)
+{
+#if CPU!=SIMSPARCSOLARIS
+    /* Write value to feature control register */
+    IX_FEATURE_CTRL_WRITE(expUnitReg);
+#endif
+}
+
+
+/**
+ * Function definition: ixFeatureCtrlHwCapabilityRead
+ */
+IxFeatureCtrlReg
+ixFeatureCtrlHwCapabilityRead (void)
+{ 
+  IxFeatureCtrlReg currentReg, hwCapability;
+  
+  /* Capture a copy of feature control register */
+  currentReg = ixFeatureCtrlRead(); 
+
+  /* Try to enable all hardware components. 
+   * Only software disable hardware can be enabled again */
+  ixFeatureCtrlWrite(0);
+  
+  /* Read feature control register to know the hardware capability. */ 
+  hwCapability = ixFeatureCtrlRead();
+     
+  /* Restore initial feature control value */
+  ixFeatureCtrlWrite(currentReg);
+
+  /* return Hardware Capability */
+  return hwCapability;  
+}
+
+
+/**
+ * Function definition: ixFeatureCtrlComponentCheck
+ */
+IX_STATUS 
+ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType)
+{
+  IxFeatureCtrlReg expUnitReg; 
+  UINT32 mask = 0;
+
+  /* Lookup mask of component */
+  mask=componentMask[componentType];
+
+  /* Check if mask is available or not */
+  if(IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE == mask)
+  {
+      return IX_FEATURE_CTRL_COMPONENT_DISABLED;
+  }
+
+  if(IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE == mask)
+  {
+      return IX_FEATURE_CTRL_COMPONENT_ENABLED;
+  }
+
+  /* Read feature control register to know current hardware capability. */ 
+  expUnitReg = ixFeatureCtrlRead();
+
+  /* For example: To check for Hashing Coprocessor (bit-2) 
+   *                   expUniteg    = 0x0010
+   *                  ~expUnitReg   = 0x1101 
+   *                  componentType = 0x0100
+   *    ~expUnitReg & componentType = 0x0100 (Not zero)                      
+   */
+ 
+  /* 
+   * Inverse the bit value because available component is 0 in value 
+   */
+  expUnitReg = ~expUnitReg ;
+
+  if (expUnitReg & mask)
+  {
+     return (IX_FEATURE_CTRL_COMPONENT_ENABLED);
+  }   
+  else
+  {  
+     return (IX_FEATURE_CTRL_COMPONENT_DISABLED);
+  } 
+}
+
+
+/**
+ * Function definition: ixFeatureCtrlProductIdRead
+ */
+IxFeatureCtrlProductId
+ixFeatureCtrlProductIdRead ()
+{
+#if CPU!=SIMSPARCSOLARIS
+  IxFeatureCtrlProductId  pdId = 0 ;
+   
+  /* Use ARM instruction to move register0 from coprocessor to ARM register */ 
+    
+#ifndef __wince
+    __asm__("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(pdId) :);
+#else
+      
+#ifndef IN_KERNEL
+        BOOL  mode;
+#endif
+    extern  IxFeatureCtrlProductId AsmixFeatureCtrlProductIdRead();
+    
+#ifndef IN_KERNEL
+    mode = SetKMode(true);
+#endif
+    pdId = AsmixFeatureCtrlProductIdRead();
+#ifndef IN_KERNEL
+    SetKMode(mode);
+#endif
+
+#endif
+  return (pdId);
+#else
+  /* Return an invalid value for VxWorks simulation */
+  return 0xffffffff;
+#endif
+}
+
+/**
+ * Function definition: ixFeatureCtrlDeviceRead
+ */
+IxFeatureCtrlDeviceId
+ixFeatureCtrlDeviceRead ()
+{
+  return ((ixFeatureCtrlProductIdRead() >> IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET) 
+             & IX_FEATURE_CTRL_DEVICE_TYPE_MASK);
+} /* End function ixFeatureCtrlDeviceRead */
+
+
+/**
+ * Function definition: ixFeatureCtrlSwConfigurationCheck
+ */
+IX_STATUS
+ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType)
+{
+  if (swConfigType >= IX_FEATURECTRL_SWCONFIG_MAX)  
+  {
+     ixOsalLog(IX_OSAL_LOG_LVL_WARNING, 
+               IX_OSAL_LOG_DEV_STDOUT,
+               "FeatureCtrl: Invalid software configuraiton input.\n",
+               0, 0, 0, 0, 0, 0);  
+
+     return IX_FEATURE_CTRL_SWCONFIG_DISABLED;
+  }
+
+  /* The function will only initialize once. */
+  ixFeatureCtrlSwConfigurationInit();
+  
+  /* Check and return software configuration */
+  return  ((swConfiguration[(UINT32)swConfigType] == true) ? IX_FEATURE_CTRL_SWCONFIG_ENABLED: IX_FEATURE_CTRL_SWCONFIG_DISABLED);
+}
+
+/**
+ * Function definition: ixFeatureCtrlSwConfigurationWrite
+ */
+void
+ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled)
+{
+  if (swConfigType >= IX_FEATURECTRL_SWCONFIG_MAX)  
+  {
+     ixOsalLog(IX_OSAL_LOG_LVL_WARNING, 
+               IX_OSAL_LOG_DEV_STDOUT,
+               "FeatureCtrl: Invalid software configuraiton input.\n",
+               0, 0, 0, 0, 0, 0);  
+
+     return;
+  }
+
+  /* The function will only initialize once. */
+  ixFeatureCtrlSwConfigurationInit();
+  
+  /* Write software configuration */
+  swConfiguration[(UINT32)swConfigType]=enabled ;
+}
+
+/**
+ * Function definition: ixFeatureCtrlIxp400SwVersionShow
+ */
+void
+ixFeatureCtrlIxp400SwVersionShow (void)
+{
+    printf ("\nIXP400 Software Release %s %s\n\n", IX_VERSION_ID, IX_VERSION_INTERNAL_ID);
+
+}
+
+/**
+ * Function definition: ixFeatureCtrlSoftwareBuildGet
+ */
+IxFeatureCtrlBuildDevice
+ixFeatureCtrlSoftwareBuildGet (void)
+{
+    #ifdef __ixp42X
+    return IX_FEATURE_CTRL_SW_BUILD_IXP42X;
+    #else
+    return IX_FEATURE_CTRL_SW_BUILD_IXP46X;
+    #endif
+}
diff --git a/marvell/uboot/drivers/net/npe/IxNpeDl.c b/marvell/uboot/drivers/net/npe/IxNpeDl.c
new file mode 100644
index 0000000..0e5c428
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxNpeDl.c
@@ -0,0 +1,916 @@
+/**
+ * @file IxNpeDl.c
+ *
+ * @author Intel Corporation
+ * @date 08 January 2002
+ *
+ * @brief This file contains the implementation of the public API for the
+ *        IXP425 NPE Downloader component
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Put the system defined include files required
+ */
+
+/*
+ * Put the user defined include files required
+ */
+#include "IxNpeDl.h"
+#include "IxNpeDlImageMgr_p.h"
+#include "IxNpeDlNpeMgr_p.h"
+#include "IxNpeDlMacros_p.h"
+#include "IxFeatureCtrl.h"
+#include "IxOsal.h"
+/*
+ * #defines used in this file
+ */
+ #define IMAGEID_MAJOR_NUMBER_DEFAULT 0
+ #define IMAGEID_MINOR_NUMBER_DEFAULT 0
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+typedef struct
+{
+    BOOL validImage;
+    IxNpeDlImageId imageId;
+} IxNpeDlNpeState;
+
+/* module statistics counters */
+typedef struct
+{
+    UINT32 attemptedDownloads;
+    UINT32 successfulDownloads;
+    UINT32 criticalFailDownloads;
+} IxNpeDlStats;
+
+/*
+ * Variable declarations global to this file only.  Externs are followed
+ * by static variables.
+ */
+static IxNpeDlNpeState ixNpeDlNpeState[IX_NPEDL_NPEID_MAX] =
+{
+    {false, {IX_NPEDL_NPEID_MAX, 0, 0, 0}},
+    {false, {IX_NPEDL_NPEID_MAX, 0, 0, 0}},
+    {false, {IX_NPEDL_NPEID_MAX, 0, 0, 0}}
+};
+
+static IxNpeDlStats ixNpeDlStats;
+
+/*
+ * Software guard to prevent NPE from being started multiple times.
+ */
+static BOOL ixNpeDlNpeStarted[IX_NPEDL_NPEID_MAX] ={false, false, false} ;
+
+
+/*
+ * static function prototypes.
+ */
+PRIVATE IX_STATUS
+ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary, UINT32 imageId);
+
+/*
+ * Function definition: ixNpeDlImageDownload
+ */
+PUBLIC IX_STATUS
+ixNpeDlImageDownload (IxNpeDlImageId *imageIdPtr,
+                      BOOL verify)
+{
+    UINT32        imageSize;
+    UINT32       *imageCodePtr  = NULL;
+    IX_STATUS     status;
+    IxNpeDlNpeId  npeId           = imageIdPtr->npeId;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Entering ixNpeDlImageDownload\n");
+
+    ixNpeDlStats.attemptedDownloads++;
+
+    /* Check input parameters */
+    if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
+    {
+        status = IX_NPEDL_PARAM_ERR;
+        IX_NPEDL_ERROR_REPORT ("ixNpeDlImageDownload - invalid parameter\n");
+    }
+    else
+    {
+        /* Ensure initialisation has been completed */
+        ixNpeDlNpeMgrInit();
+
+	/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
+	if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+	     (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+	    || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+	{
+            if (npeId == IX_NPEDL_NPEID_NPEA)
+            {
+                if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
+                    IX_FEATURE_CTRL_COMPONENT_DISABLED)
+                {
+                    IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
+                                            " not exist\n");
+                    return IX_SUCCESS;
+                }
+            } /* end of if(npeId) */
+            else if (npeId == IX_NPEDL_NPEID_NPEB)
+            {
+                if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
+                    IX_FEATURE_CTRL_COMPONENT_DISABLED)
+                {
+                    IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified"
+                                            " does not exist\n");
+                    return IX_SUCCESS;
+                }
+            } /* end of elseif(npeId) */
+            else if (npeId == IX_NPEDL_NPEID_NPEC)
+            {
+                if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
+                    IX_FEATURE_CTRL_COMPONENT_DISABLED)
+                {
+                    IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified"
+                                            " does not exist\n");
+                    return IX_SUCCESS;
+                }
+            } /* end of elseif(npeId) */
+        } /* end of if(IX_FEATURE_CTRL_SILICON_TYPE_B0) */ /*End of Silicon Type Check*/
+
+        /* stop and reset the NPE */
+        if (IX_SUCCESS != ixNpeDlNpeStopAndReset (npeId))
+        {
+            IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n");
+            return IX_FAIL;
+        }
+
+        /* Locate image */
+        status = ixNpeDlImageMgrImageLocate (imageIdPtr, &imageCodePtr,
+                                             &imageSize);
+        if (IX_SUCCESS == status)
+        {
+            /*
+             * If download was successful, store image Id in list of
+             * currently loaded images. If a critical error occured
+             * during download, record that the NPE has an invalid image
+             */
+            status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr,
+                                             verify);
+            if (IX_SUCCESS == status)
+            {
+                ixNpeDlNpeState[npeId].imageId = *imageIdPtr;
+                ixNpeDlNpeState[npeId].validImage = true;
+                ixNpeDlStats.successfulDownloads++;
+
+                status =  ixNpeDlNpeExecutionStart (npeId);
+            }
+            else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) ||
+                     (status == IX_NPEDL_CRITICAL_MICROCODE_ERR))
+            {
+                ixNpeDlNpeState[npeId].imageId = *imageIdPtr;
+                ixNpeDlNpeState[npeId].validImage = false;
+                ixNpeDlStats.criticalFailDownloads++;
+            }
+        } /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */
+    } /* end of if-else(npeId) */ /* condition: parameter checks ok */
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Exiting ixNpeDlImageDownload : status = %d\n", status);
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlAvailableImagesCountGet
+ */
+PUBLIC IX_STATUS
+ixNpeDlAvailableImagesCountGet (UINT32 *numImagesPtr)
+{
+    IX_STATUS status;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Entering ixNpeDlAvailableImagesCountGet\n");
+
+    /* Check input parameters */
+    if (numImagesPtr == NULL)
+    {
+        status = IX_NPEDL_PARAM_ERR;
+        IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesCountGet - "
+                               "invalid parameter\n");
+    }
+    else
+    {
+        /*
+         * Use ImageMgr module to get no. of images listed in Image Library Header.
+         * If NULL is passed as imageListPtr parameter to following function,
+         * it will only fill number of images into numImagesPtr
+         */
+        status = ixNpeDlImageMgrImageListExtract (NULL, numImagesPtr);
+    } /* end of if-else(numImagesPtr) */
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Exiting ixNpeDlAvailableImagesCountGet : "
+                     "status = %d\n", status);
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlAvailableImagesListGet
+ */
+PUBLIC IX_STATUS
+ixNpeDlAvailableImagesListGet (IxNpeDlImageId *imageIdListPtr,
+                               UINT32 *listSizePtr)
+{
+    IX_STATUS status;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Entering ixNpeDlAvailableImagesListGet\n");
+
+    /* Check input parameters */
+    if ((imageIdListPtr == NULL) || (listSizePtr == NULL))
+    {
+        status = IX_NPEDL_PARAM_ERR;
+        IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesListGet - "
+                               "invalid parameter\n");
+    }
+    else
+    {
+        /* Call ImageMgr to get list of images listed in Image Library Header */
+        status = ixNpeDlImageMgrImageListExtract (imageIdListPtr,
+                                                  listSizePtr);
+    } /* end of if-else(imageIdListPtr) */
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Exiting ixNpeDlAvailableImagesListGet : status = %d\n",
+                     status);
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlLoadedImageGet
+ */
+PUBLIC IX_STATUS
+ixNpeDlLoadedImageGet (IxNpeDlNpeId npeId,
+                       IxNpeDlImageId *imageIdPtr)
+{
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Entering ixNpeDlLoadedImageGet\n");
+
+    /* Check input parameters */
+    if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0) || (imageIdPtr == NULL))
+    {
+        status = IX_NPEDL_PARAM_ERR;
+        IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageGet - invalid parameter\n");
+    }
+    else
+    {
+
+         /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
+         if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+	      (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+	     || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+        {
+            if (npeId == IX_NPEDL_NPEID_NPEA &&
+                (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
+                 IX_FEATURE_CTRL_COMPONENT_DISABLED))
+            {
+                IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
+                                        " not exist\n");
+                return IX_SUCCESS;
+            } /* end of if(npeId) */
+
+            if (npeId == IX_NPEDL_NPEID_NPEB &&
+                (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) ==
+                 IX_FEATURE_CTRL_COMPONENT_DISABLED))
+            {
+                IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does"
+                                        " not exist\n");
+                return IX_SUCCESS;
+            } /* end of if(npeId) */
+
+            if (npeId == IX_NPEDL_NPEID_NPEC &&
+                (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) ==
+                 IX_FEATURE_CTRL_COMPONENT_DISABLED))
+            {
+                IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does"
+                                        " not exist\n");
+                return IX_SUCCESS;
+            } /* end of if(npeId) */
+        } /* end of if not IXP42x-A0 silicon */
+
+        if (ixNpeDlNpeState[npeId].validImage)
+        {
+            /* use npeId to get imageId from list of currently loaded
+               images */
+            *imageIdPtr = ixNpeDlNpeState[npeId].imageId;
+        }
+        else
+        {
+            status = IX_FAIL;
+        } /* end of if-else(ixNpeDlNpeState) */
+    } /* end of if-else(npeId) */
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Exiting ixNpeDlLoadedImageGet : status = %d\n",
+                     status);
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlLatestImageGet
+ */
+PUBLIC IX_STATUS
+ixNpeDlLatestImageGet (
+    IxNpeDlNpeId npeId,
+    IxNpeDlFunctionalityId functionalityId,
+    IxNpeDlImageId *imageIdPtr)
+{
+    IX_STATUS status;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Entering ixNpeDlLatestImageGet\n");
+
+    /* Check input parameters */
+    if ((npeId >= IX_NPEDL_NPEID_MAX) ||
+        (npeId < 0) ||
+        (imageIdPtr == NULL))
+    {
+        status = IX_NPEDL_PARAM_ERR;
+        IX_NPEDL_ERROR_REPORT ("ixNpeDlLatestImageGet - "
+                               "invalid parameter\n");
+    } /* end of if(npeId) */
+    else
+    {
+
+	/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
+	if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+	     (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+	    || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+        {
+            if (npeId == IX_NPEDL_NPEID_NPEA &&
+                (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
+                 IX_FEATURE_CTRL_COMPONENT_DISABLED))
+            {
+                IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
+                                        " not exist\n");
+                return IX_SUCCESS;
+            } /* end of if(npeId) */
+
+            if (npeId == IX_NPEDL_NPEID_NPEB &&
+                (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) ==
+                 IX_FEATURE_CTRL_COMPONENT_DISABLED))
+            {
+                IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does"
+                                        " not exist\n");
+                return IX_SUCCESS;
+            } /* end of if(npeId) */
+
+            if (npeId == IX_NPEDL_NPEID_NPEC &&
+                (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) ==
+                 IX_FEATURE_CTRL_COMPONENT_DISABLED))
+            {
+                IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does"
+                                        " not exist\n");
+                return IX_SUCCESS;
+            } /* end of if(npeId) */
+        } /* end of if not IXP42x-A0 silicon */
+
+        imageIdPtr->npeId = npeId;
+        imageIdPtr->functionalityId = functionalityId;
+        imageIdPtr->major = IMAGEID_MAJOR_NUMBER_DEFAULT;
+        imageIdPtr->minor = IMAGEID_MINOR_NUMBER_DEFAULT;
+        /* Call ImageMgr to get list of images listed in Image Library Header */
+        status = ixNpeDlImageMgrLatestImageExtract(imageIdPtr);
+    } /* end of if-else(npeId) */
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Exiting ixNpeDlLatestImageGet : status = %d\n",
+                     status);
+
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlNpeStopAndReset
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeStopAndReset (IxNpeDlNpeId npeId)
+{
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Entering ixNpeDlNpeStopAndReset\n");
+
+    /* Ensure initialisation has been completed */
+    ixNpeDlNpeMgrInit();
+
+    /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
+    if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+	 (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+	|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+    {
+        /*
+         * Check whether NPE is present
+         */
+        if (IX_NPEDL_NPEID_NPEA == npeId)
+        {
+            /* Check whether NPE A is present */
+            if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
+                IX_FEATURE_CTRL_COMPONENT_DISABLED)
+            {
+                /* NPE A does not present */
+                IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEA does not present.\n");
+                return IX_SUCCESS;
+            }
+        } /* end of if(IX_NPEDL_NPEID_NPEA) */
+        else if (IX_NPEDL_NPEID_NPEB == npeId)
+        {
+            /* Check whether NPE B is present */
+            if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
+                IX_FEATURE_CTRL_COMPONENT_DISABLED)
+            {
+                /* NPE B does not present */
+                IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEB does not present.\n");
+                return IX_SUCCESS;
+            }
+        } /* end of elseif(IX_NPEDL_NPEID_NPEB) */
+        else if (IX_NPEDL_NPEID_NPEC == npeId)
+        {
+            /* Check whether NPE C is present */
+            if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
+                IX_FEATURE_CTRL_COMPONENT_DISABLED)
+            {
+                /* NPE C does not present */
+                IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEC does not present.\n");
+                return IX_SUCCESS;
+            }
+        } /* end of elseif(IX_NPEDL_NPEID_NPEC) */
+        else
+        {
+            /* Invalid NPE ID */
+            IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeStopAndReset - invalid Npe ID\n");
+            status = IX_NPEDL_PARAM_ERR;
+        } /* end of if-else(IX_NPEDL_NPEID_NPEC) */
+    } /* end of if not IXP42x-A0 Silicon */
+
+    if (status == IX_SUCCESS)
+    {
+        /* call NpeMgr function to stop the NPE */
+        status = ixNpeDlNpeMgrNpeStop (npeId);
+        if (status == IX_SUCCESS)
+        {
+            /* call NpeMgr function to reset the NPE */
+            status = ixNpeDlNpeMgrNpeReset (npeId);
+        }
+    } /* end of if(status) */
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Exiting ixNpeDlNpeStopAndReset : status = %d\n", status);
+
+    if (IX_SUCCESS == status)
+    {
+        /* Indicate NPE has been stopped */
+        ixNpeDlNpeStarted[npeId] = false ;
+    }
+
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlNpeExecutionStart
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeExecutionStart (IxNpeDlNpeId npeId)
+{
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Entering ixNpeDlNpeExecutionStart\n");
+
+    /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
+    if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+	 (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+	|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+    {
+        /*
+         * Check whether NPE is present
+         */
+        if (IX_NPEDL_NPEID_NPEA == npeId)
+        {
+            /* Check whether NPE A is present */
+            if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
+                IX_FEATURE_CTRL_COMPONENT_DISABLED)
+            {
+                /* NPE A does not present */
+                IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEA does not present.\n");
+                return IX_SUCCESS;
+            }
+        } /* end of if(IX_NPEDL_NPEID_NPEA) */
+        else if (IX_NPEDL_NPEID_NPEB == npeId)
+        {
+            /* Check whether NPE B is present */
+            if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
+                IX_FEATURE_CTRL_COMPONENT_DISABLED)
+            {
+                /* NPE B does not present */
+                IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEB does not present.\n");
+                return IX_SUCCESS;
+            }
+        } /* end of elseif(IX_NPEDL_NPEID_NPEB) */
+        else if (IX_NPEDL_NPEID_NPEC ==  npeId)
+        {
+            /* Check whether NPE C is present */
+            if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
+                IX_FEATURE_CTRL_COMPONENT_DISABLED)
+            {
+                /* NPE C does not present */
+                IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEC does not present.\n");
+                return IX_SUCCESS;
+            }
+        } /* end of elseif(IX_NPEDL_NPEID_NPEC) */
+        else
+        {
+            /* Invalid NPE ID */
+            IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStart - invalid Npe ID\n");
+            return IX_NPEDL_PARAM_ERR;
+        } /* end of if-else(IX_NPEDL_NPEID_NPEC) */
+    } /* end of if not IXP42x-A0 Silicon */
+
+    if (true == ixNpeDlNpeStarted[npeId])
+    {
+        /* NPE has been started. */
+        return IX_SUCCESS ;
+    }
+
+    /* Ensure initialisation has been completed */
+    ixNpeDlNpeMgrInit();
+
+    /* call NpeMgr function to start the NPE */
+    status = ixNpeDlNpeMgrNpeStart (npeId);
+
+    if (IX_SUCCESS == status)
+    {
+        /* Indicate NPE has started */
+        ixNpeDlNpeStarted[npeId] = true ;
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Exiting ixNpeDlNpeExecutionStart : status = %d\n",
+                     status);
+
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlNpeExecutionStop
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeExecutionStop (IxNpeDlNpeId npeId)
+{
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Entering ixNpeDlNpeExecutionStop\n");
+
+    /* Ensure initialisation has been completed */
+    ixNpeDlNpeMgrInit();
+
+    /* If not IXP42X A0 stepping, proceed to check for existence of npe's */
+    if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+	 (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+	|| (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+    {
+        /*
+         * Check whether NPE is present
+         */
+        if (IX_NPEDL_NPEID_NPEA == npeId)
+        {
+            /* Check whether NPE A is present */
+            if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)==
+                IX_FEATURE_CTRL_COMPONENT_DISABLED)
+            {
+                /* NPE A does not present */
+                IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEA does not present.\n");
+                return IX_SUCCESS;
+            }
+        } /* end of if(IX_NPEDL_NPEID_NPEA) */
+        else if (IX_NPEDL_NPEID_NPEB == npeId)
+        {
+            /* Check whether NPE B is present */
+            if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
+                IX_FEATURE_CTRL_COMPONENT_DISABLED)
+            {
+                /* NPE B does not present */
+                IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEB does not present.\n");
+                return IX_SUCCESS;
+            }
+        } /* end of elseif(IX_NPEDL_NPEID_NPEB) */
+        else if (IX_NPEDL_NPEID_NPEC == npeId)
+        {
+            /* Check whether NPE C is present */
+            if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
+                IX_FEATURE_CTRL_COMPONENT_DISABLED)
+            {
+                /* NPE C does not present */
+                IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEC does not present.\n");
+                return IX_SUCCESS;
+            }
+        } /* end of elseif(IX_NPEDL_NPEID_NPEC) */
+        else
+        {
+            /* Invalid NPE ID */
+            IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStop - invalid Npe ID\n");
+            status = IX_NPEDL_PARAM_ERR;
+        } /* end of if-else(IX_NPEDL_NPEID_NPEC) */
+    } /* end of if not IXP42X-AO Silicon */
+
+    if (status == IX_SUCCESS)
+    {
+        /* call NpeMgr function to stop the NPE */
+        status = ixNpeDlNpeMgrNpeStop (npeId);
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Exiting ixNpeDlNpeExecutionStop : status = %d\n",
+                     status);
+
+    if (IX_SUCCESS == status)
+    {
+        /* Indicate NPE has been stopped */
+        ixNpeDlNpeStarted[npeId] = false ;
+    }
+
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlUnload
+ */
+PUBLIC IX_STATUS
+ixNpeDlUnload (void)
+{
+    IX_STATUS status;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Entering ixNpeDlUnload\n");
+
+    status = ixNpeDlNpeMgrUninit();
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Exiting ixNpeDlUnload : status = %d\n",
+                     status);
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlStatsShow
+ */
+PUBLIC void
+ixNpeDlStatsShow (void)
+{
+    ixOsalLog (IX_OSAL_LOG_LVL_USER,
+               IX_OSAL_LOG_DEV_STDOUT,
+               "\nixNpeDlStatsShow:\n"
+               "\tDownloads Attempted by user: %u\n"
+               "\tSuccessful Downloads: %u\n"
+               "\tFailed Downloads (due to Critical Error): %u\n\n",
+               ixNpeDlStats.attemptedDownloads,
+               ixNpeDlStats.successfulDownloads,
+               ixNpeDlStats.criticalFailDownloads,
+               0,0,0);
+
+    ixNpeDlImageMgrStatsShow ();
+    ixNpeDlNpeMgrStatsShow ();
+}
+
+/*
+ * Function definition: ixNpeDlStatsReset
+ */
+PUBLIC void
+ixNpeDlStatsReset (void)
+{
+    ixNpeDlStats.attemptedDownloads = 0;
+    ixNpeDlStats.successfulDownloads = 0;
+    ixNpeDlStats.criticalFailDownloads = 0;
+
+    ixNpeDlImageMgrStatsReset ();
+    ixNpeDlNpeMgrStatsReset ();
+}
+
+/*
+ * Function definition: ixNpeDlNpeInitAndStartInternal
+ */
+PRIVATE IX_STATUS
+ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary,
+                                UINT32 imageId)
+{
+    UINT32        imageSize;
+    UINT32       *imageCodePtr  = NULL;
+    IX_STATUS     status;
+    IxNpeDlNpeId  npeId = IX_NPEDL_NPEID_FROM_IMAGEID_GET(imageId);
+    IxFeatureCtrlDeviceId deviceId = IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId);
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Entering ixNpeDlNpeInitAndStartInternal\n");
+
+    ixNpeDlStats.attemptedDownloads++;
+
+    /* Check input parameter device correctness */
+    if ((deviceId >= IX_FEATURE_CTRL_DEVICE_TYPE_MAX) ||
+        (deviceId < IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X))
+    {
+        status = IX_NPEDL_PARAM_ERR;
+        IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
+                               "invalid parameter\n");
+    } /* End valid device id checking */
+
+    /* Check input parameters */
+    else if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
+    {
+        status = IX_NPEDL_PARAM_ERR;
+        IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
+                               "invalid parameter\n");
+    }
+
+    else
+    {
+        /* Ensure initialisation has been completed */
+        ixNpeDlNpeMgrInit();
+
+        /* Checking if image being loaded is meant for device that is running.
+         * Image is forward compatible. i.e Image built for IXP42X should run
+         * on IXP46X but not vice versa.*/
+        if (deviceId > (ixFeatureCtrlDeviceRead() & IX_FEATURE_CTRL_DEVICE_TYPE_MASK))
+        {
+            IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - "
+                                   "Device type mismatch. NPE Image not "
+                                   "meant for device in use \n");
+            return IX_NPEDL_DEVICE_ERR;
+        }/* if statement - matching image device and current device */
+
+	/* If not IXP42X A0 stepping, proceed to check for existence of npe's */
+	if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 !=
+	     (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
+	    || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
+        {
+            if (npeId == IX_NPEDL_NPEID_NPEA)
+            {
+                if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
+                    IX_FEATURE_CTRL_COMPONENT_DISABLED)
+                {
+                    IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does"
+                                            " not exist\n");
+                    return IX_SUCCESS;
+                }
+            } /* end of if(npeId) */
+            else if (npeId == IX_NPEDL_NPEID_NPEB)
+            {
+                if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)==
+                    IX_FEATURE_CTRL_COMPONENT_DISABLED)
+                {
+                    IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified"
+                                            " does not exist\n");
+                    return IX_SUCCESS;
+                }
+            } /* end of elseif(npeId) */
+            else if (npeId == IX_NPEDL_NPEID_NPEC)
+            {
+                if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)==
+                    IX_FEATURE_CTRL_COMPONENT_DISABLED)
+                {
+                    IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified"
+                                            " does not exist\n");
+                    return IX_SUCCESS;
+                }
+            } /* end of elseif(npeId) */
+        } /* end of if not IXP42X-A0 Silicon */
+
+        /* stop and reset the NPE */
+        status = ixNpeDlNpeStopAndReset (npeId);
+        if (IX_SUCCESS != status)
+        {
+            IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n");
+            return status;
+        }
+
+        /* Locate image */
+        status = ixNpeDlImageMgrImageFind (imageLibrary, imageId,
+                                           &imageCodePtr, &imageSize);
+        if (IX_SUCCESS == status)
+        {
+            /*
+             * If download was successful, store image Id in list of
+             * currently loaded images. If a critical error occured
+             * during download, record that the NPE has an invalid image
+             */
+            status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr, true);
+            if (IX_SUCCESS == status)
+            {
+                ixNpeDlNpeState[npeId].validImage = true;
+                ixNpeDlStats.successfulDownloads++;
+
+                status = ixNpeDlNpeExecutionStart (npeId);
+            }
+            else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) ||
+                     (status == IX_NPEDL_CRITICAL_MICROCODE_ERR))
+            {
+                ixNpeDlNpeState[npeId].validImage = false;
+                ixNpeDlStats.criticalFailDownloads++;
+            }
+
+            /* NOTE - The following section of code is here to support
+             * a deprecated function ixNpeDlLoadedImageGet().  When that
+             * function is removed from the API, this code should be revised.
+             */
+            ixNpeDlNpeState[npeId].imageId.npeId = npeId;
+            ixNpeDlNpeState[npeId].imageId.functionalityId =
+                IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId);
+            ixNpeDlNpeState[npeId].imageId.major =
+                IX_NPEDL_MAJOR_FROM_IMAGEID_GET(imageId);
+            ixNpeDlNpeState[npeId].imageId.minor =
+                IX_NPEDL_MINOR_FROM_IMAGEID_GET(imageId);
+        } /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */
+    } /* end of if-else(npeId-deviceId) */ /* condition: parameter checks ok */
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+                     "Exiting ixNpeDlNpeInitAndStartInternal : "
+                     "status = %d\n", status);
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlCustomImageNpeInitAndStart
+ */
+PUBLIC IX_STATUS
+ixNpeDlCustomImageNpeInitAndStart (UINT32 *imageLibrary,
+                                   UINT32 imageId)
+{
+    IX_STATUS status;
+
+    if (imageLibrary == NULL)
+    {
+        status = IX_NPEDL_PARAM_ERR;
+        IX_NPEDL_ERROR_REPORT ("ixNpeDlCustomImageNpeInitAndStart "
+                               "- invalid parameter\n");
+    }
+    else
+    {
+        status = ixNpeDlNpeInitAndStartInternal (imageLibrary, imageId);
+    } /* end of if-else(imageLibrary) */
+
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlNpeInitAndStart
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeInitAndStart (UINT32 imageId)
+{
+    return ixNpeDlNpeInitAndStartInternal (NULL, imageId);
+}
+
+/*
+ * Function definition: ixNpeDlLoadedImageFunctionalityGet
+ */
+PUBLIC IX_STATUS
+ixNpeDlLoadedImageFunctionalityGet (IxNpeDlNpeId npeId,
+                                    UINT8 *functionalityId)
+{
+    /* Check input parameters */
+    if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0))
+    {
+        IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet "
+                               "- invalid parameter\n");
+        return IX_NPEDL_PARAM_ERR;
+    }
+    if (functionalityId == NULL)
+    {
+        IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet "
+                               "- invalid parameter\n");
+        return IX_NPEDL_PARAM_ERR;
+    }
+
+    if (ixNpeDlNpeState[npeId].validImage)
+    {
+        *functionalityId = ixNpeDlNpeState[npeId].imageId.functionalityId;
+        return IX_SUCCESS;
+    }
+    else
+    {
+        return IX_FAIL;
+    }
+}
diff --git a/marvell/uboot/drivers/net/npe/IxNpeDlImageMgr.c b/marvell/uboot/drivers/net/npe/IxNpeDlImageMgr.c
new file mode 100644
index 0000000..52f73d7
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxNpeDlImageMgr.c
@@ -0,0 +1,663 @@
+/**
+ * @file IxNpeDlImageMgr.c
+ *
+ * @author Intel Corporation
+ * @date 09 January 2002
+ *
+ * @brief This file contains the implementation of the private API for the 
+ *        IXP425 NPE Downloader ImageMgr module
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+/*
+ * Put the system defined include files required.
+ */
+#include "IxOsal.h"
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxNpeDlImageMgr_p.h"
+#include "IxNpeDlMacros_p.h"
+
+/*
+ * define the flag which toggles the firmare inclusion
+ */
+#define IX_NPE_MICROCODE_FIRMWARE_INCLUDED 1
+#include "IxNpeMicrocode.h"
+
+/*
+ * Indicates the start of an NPE Image, in new NPE Image Library format.
+ * 2 consecutive occurances indicates the end of the NPE Image Library
+ */
+#define NPE_IMAGE_MARKER 0xfeedf00d
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/*
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+typedef struct
+{
+    UINT32 size;
+    UINT32 offset;
+    UINT32 id;
+} IxNpeDlImageMgrImageEntry;
+
+/*
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+typedef union
+{
+    IxNpeDlImageMgrImageEntry image;
+    UINT32 eohMarker;
+} IxNpeDlImageMgrHeaderEntry;
+
+/*
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+typedef struct
+{
+    UINT32 signature;
+    /* 1st entry in the header (there may be more than one) */
+    IxNpeDlImageMgrHeaderEntry entry[1];
+} IxNpeDlImageMgrImageLibraryHeader;
+
+
+/*
+ * NPE Image Header definition, used in new NPE Image Library format
+ */
+typedef struct
+{
+    UINT32 marker;
+    UINT32 id;
+    UINT32 size;
+} IxNpeDlImageMgrImageHeader;
+
+/* module statistics counters */
+typedef struct
+{
+    UINT32 invalidSignature;
+    UINT32 imageIdListOverflow;
+    UINT32 imageIdNotFound;
+} IxNpeDlImageMgrStats;
+
+
+/*
+ * Variable declarations global to this file only.  Externs are followed by
+ * static variables.
+ */
+static IxNpeDlImageMgrStats ixNpeDlImageMgrStats;
+
+static UINT32* getIxNpeMicroCodeImageLibrary(void)
+{
+	char *s;
+
+	if ((s = getenv("npe_ucode")) != NULL)
+		return (UINT32*) simple_strtoul(s, NULL, 16);
+	else
+		return NULL;
+}
+
+/*
+ * static function prototypes.
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary);
+
+PRIVATE void  
+ixNpeDlImageMgrImageIdFormat (UINT32 rawImageId, IxNpeDlImageId *imageId);
+
+PRIVATE BOOL
+ixNpeDlImageMgrImageIdCompare (IxNpeDlImageId *imageIdA, 
+				 IxNpeDlImageId *imageIdB);
+				 
+PRIVATE BOOL
+ixNpeDlImageMgrNpeFunctionIdCompare (IxNpeDlImageId *imageIdA,
+				       IxNpeDlImageId *imageIdB);
+
+#if 0
+PRIVATE IX_STATUS
+ixNpeDlImageMgrImageFind_legacy (UINT32 *imageLibrary,
+                                 UINT32 imageId,
+                                 UINT32 **imagePtr,
+                                 UINT32 *imageSize);
+
+/*
+ * Function definition: ixNpeDlImageMgrMicrocodeImageLibraryOverride
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrMicrocodeImageLibraryOverride (
+    UINT32 *clientImageLibrary)
+{
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Entering ixNpeDlImageMgrMicrocodeImageLibraryOverride\n");
+
+    if (ixNpeDlImageMgrSignatureCheck (clientImageLibrary))
+    {
+	IxNpeMicroCodeImageLibrary = clientImageLibrary;
+    }
+    else
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrMicrocodeImageLibraryOverride: "
+			       "Client-supplied image has invalid signature\n");
+	status = IX_FAIL;
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Exiting ixNpeDlImageMgrMicrocodeImageLibraryOverride: status = %d\n",
+		     status);
+    return status;
+}
+#endif
+
+/*
+ * Function definition: ixNpeDlImageMgrImageListExtract
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrImageListExtract (
+    IxNpeDlImageId *imageListPtr,
+    UINT32 *numImages)
+{
+    UINT32 rawImageId;
+    IxNpeDlImageId formattedImageId;
+    IX_STATUS status = IX_SUCCESS;
+    UINT32 imageCount = 0;
+    IxNpeDlImageMgrImageLibraryHeader *header;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Entering ixNpeDlImageMgrImageListExtract\n");
+
+    header = (IxNpeDlImageMgrImageLibraryHeader *) getIxNpeMicroCodeImageLibrary();
+
+    if (ixNpeDlImageMgrSignatureCheck (getIxNpeMicroCodeImageLibrary()))
+    {
+	/* for each image entry in the image header ... */
+	while (header->entry[imageCount].eohMarker !=
+	       IX_NPEDL_IMAGEMGR_END_OF_HEADER)
+	{
+	    /*
+	     * if the image list container from calling function has capacity,
+	     * add the image id to the list 
+	     */
+	    if ((imageListPtr != NULL) && (imageCount < *numImages))
+	    {
+		rawImageId = header->entry[imageCount].image.id;
+	        ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
+		imageListPtr[imageCount] = formattedImageId;
+	    }
+	    /* imageCount reflects no. of image entries in image library header */
+	    imageCount++;  
+	}
+	
+	/*
+	 * if image list container from calling function was too small to
+	 * contain all image ids in the header, set return status to FAIL
+	 */
+	if ((imageListPtr != NULL) && (imageCount > *numImages))
+	{
+	    status = IX_FAIL;
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: "
+				   "number of Ids found exceeds list capacity\n");
+	    ixNpeDlImageMgrStats.imageIdListOverflow++;
+	}
+	/* return number of image ids found in image library header */
+	*numImages = imageCount;  
+    }
+    else
+    {
+	status = IX_FAIL;
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: "
+			       "invalid signature in image\n");
+    }
+    
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Exiting ixNpeDlImageMgrImageListExtract: status = %d\n",
+		     status);
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageLocate
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrImageLocate (
+    IxNpeDlImageId *imageId,
+    UINT32 **imagePtr,
+    UINT32 *imageSize)
+{
+    UINT32 imageOffset;
+    UINT32 rawImageId;
+    IxNpeDlImageId formattedImageId;
+    /* used to index image entries in image library header */
+    UINT32 imageCount = 0;   
+    IX_STATUS status = IX_FAIL;
+    IxNpeDlImageMgrImageLibraryHeader *header;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlImageMgrImageLocate\n");
+
+    header = (IxNpeDlImageMgrImageLibraryHeader *) getIxNpeMicroCodeImageLibrary();
+
+    if (ixNpeDlImageMgrSignatureCheck (getIxNpeMicroCodeImageLibrary()))
+    {
+	/* for each image entry in the image library header ... */
+	while (header->entry[imageCount].eohMarker !=
+	       IX_NPEDL_IMAGEMGR_END_OF_HEADER)
+	{
+	    rawImageId = header->entry[imageCount].image.id;
+	    ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
+	    /* if a match for imageId is found in the image library header... */
+	    if (ixNpeDlImageMgrImageIdCompare (imageId, &formattedImageId))
+	    {
+		/*
+		 * get pointer to the image in the image library using offset from
+		 * 1st word in image library
+		 */
+		UINT32 *tmp=getIxNpeMicroCodeImageLibrary();
+		imageOffset = header->entry[imageCount].image.offset;
+		*imagePtr = &tmp[imageOffset];
+		/* get the image size */
+		*imageSize = header->entry[imageCount].image.size;
+		status = IX_SUCCESS;
+		break;
+	    }
+	    imageCount++;
+	}
+	if (status != IX_SUCCESS)
+	{
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: "
+				   "imageId not found in image library header\n");
+	    ixNpeDlImageMgrStats.imageIdNotFound++;
+	}
+    }
+    else
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: "
+			       "invalid signature in image library\n");
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlImageMgrImageLocate: status = %d\n", status);
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlImageMgrLatestImageExtract
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrLatestImageExtract (IxNpeDlImageId *imageId)
+{
+    UINT32 imageCount = 0; 
+    UINT32 rawImageId;
+    IxNpeDlImageId formattedImageId;
+    IX_STATUS status = IX_FAIL;
+    IxNpeDlImageMgrImageLibraryHeader *header;
+    
+    
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlImageMgrLatestImageExtract\n");
+		     
+    header = (IxNpeDlImageMgrImageLibraryHeader *) getIxNpeMicroCodeImageLibrary();
+    
+    if (ixNpeDlImageMgrSignatureCheck (getIxNpeMicroCodeImageLibrary()))
+    {
+	/* for each image entry in the image library header ... */
+	while (header->entry[imageCount].eohMarker !=
+	       IX_NPEDL_IMAGEMGR_END_OF_HEADER)
+	{
+	    rawImageId = header->entry[imageCount].image.id;
+	    ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
+	    /* 
+	     * if a match for the npe Id and functionality Id of the imageId is
+	     *  found in the image library header... 
+	     */
+            if(ixNpeDlImageMgrNpeFunctionIdCompare(imageId, &formattedImageId))
+            {
+                if(imageId->major <= formattedImageId.major)
+                {
+                    if(imageId->minor < formattedImageId.minor)
+                    {
+                        imageId->minor = formattedImageId.minor;
+                    }
+                    imageId->major = formattedImageId.major;
+                }
+                status = IX_SUCCESS;
+            }
+            imageCount++;
+	}
+	if (status != IX_SUCCESS)
+	{
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageExtract: "
+				   "imageId not found in image library header\n");
+	    ixNpeDlImageMgrStats.imageIdNotFound++;
+	}
+    }
+    else
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageGet: "
+			       "invalid signature in image library\n");
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlImageMgrLatestImageGet: status = %d\n", status);
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlImageMgrSignatureCheck
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary)
+{
+    IxNpeDlImageMgrImageLibraryHeader *header =
+	(IxNpeDlImageMgrImageLibraryHeader *) microCodeImageLibrary;
+    BOOL result = true;
+
+    if (!header || header->signature != IX_NPEDL_IMAGEMGR_SIGNATURE)
+    {
+	result = false;
+	ixNpeDlImageMgrStats.invalidSignature++;
+    }
+
+    return result;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageIdFormat
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE void
+ixNpeDlImageMgrImageIdFormat (
+    UINT32 rawImageId, 
+    IxNpeDlImageId *imageId)
+{  
+    imageId->npeId = (rawImageId >>
+				IX_NPEDL_IMAGEID_NPEID_OFFSET) &
+	IX_NPEDL_NPEIMAGE_FIELD_MASK;
+    imageId->functionalityId = (rawImageId >> 
+				  IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET) &
+	IX_NPEDL_NPEIMAGE_FIELD_MASK;
+    imageId->major = (rawImageId >>
+				IX_NPEDL_IMAGEID_MAJOR_OFFSET) &
+	IX_NPEDL_NPEIMAGE_FIELD_MASK;
+    imageId->minor = (rawImageId >>
+				IX_NPEDL_IMAGEID_MINOR_OFFSET) &
+	IX_NPEDL_NPEIMAGE_FIELD_MASK;
+
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageIdCompare
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrImageIdCompare (
+    IxNpeDlImageId *imageIdA,
+    IxNpeDlImageId *imageIdB)
+{
+    if ((imageIdA->npeId   == imageIdB->npeId)   &&
+	(imageIdA->functionalityId == imageIdB->functionalityId) &&
+	(imageIdA->major   == imageIdB->major)   &&
+	(imageIdA->minor   == imageIdB->minor))
+    {
+	return true;
+    }
+    else
+    {
+	return false;
+    }
+}
+
+/*
+ * Function definition: ixNpeDlImageMgrNpeFunctionIdCompare
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrNpeFunctionIdCompare (
+    IxNpeDlImageId *imageIdA,
+    IxNpeDlImageId *imageIdB)
+{
+    if ((imageIdA->npeId   == imageIdB->npeId)   &&
+	(imageIdA->functionalityId == imageIdB->functionalityId))
+    {
+	return true;
+    }
+    else
+    {
+	return false;
+    }
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrStatsShow
+ */
+void
+ixNpeDlImageMgrStatsShow (void)
+{
+    ixOsalLog (IX_OSAL_LOG_LVL_USER,
+               IX_OSAL_LOG_DEV_STDOUT,
+               "\nixNpeDlImageMgrStatsShow:\n"
+               "\tInvalid Image Signatures: %u\n"
+               "\tImage Id List capacity too small: %u\n"
+               "\tImage Id not found: %u\n\n",
+               ixNpeDlImageMgrStats.invalidSignature,
+               ixNpeDlImageMgrStats.imageIdListOverflow,
+               ixNpeDlImageMgrStats.imageIdNotFound,
+               0,0,0);
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrStatsReset
+ */
+void
+ixNpeDlImageMgrStatsReset (void)
+{
+    ixNpeDlImageMgrStats.invalidSignature = 0;
+    ixNpeDlImageMgrStats.imageIdListOverflow = 0;
+    ixNpeDlImageMgrStats.imageIdNotFound = 0;
+}
+
+
+#if 0
+/*
+ * Function definition: ixNpeDlImageMgrImageFind_legacy
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE IX_STATUS
+ixNpeDlImageMgrImageFind_legacy (
+    UINT32 *imageLibrary,
+    UINT32 imageId,
+    UINT32 **imagePtr,
+    UINT32 *imageSize)
+{
+    UINT32 imageOffset;
+    /* used to index image entries in image library header */
+    UINT32 imageCount = 0;   
+    IX_STATUS status = IX_FAIL;
+    IxNpeDlImageMgrImageLibraryHeader *header;
+    BOOL imageFound = false;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlImageMgrImageFind\n");
+
+
+    /* If user didn't specify a library to use, use the default
+     * one from IxNpeMicrocode.h
+     */
+    if (imageLibrary == NULL)
+    {
+	imageLibrary = IxNpeMicroCodeImageLibrary;
+    }
+    
+    if (ixNpeDlImageMgrSignatureCheck (imageLibrary))
+    {
+	header = (IxNpeDlImageMgrImageLibraryHeader *) imageLibrary;
+    
+	/* for each image entry in the image library header ... */
+	while ((header->entry[imageCount].eohMarker !=
+               IX_NPEDL_IMAGEMGR_END_OF_HEADER) && !(imageFound))
+	{
+	    /* if a match for imageId is found in the image library header... */
+	    if (imageId == header->entry[imageCount].image.id)
+	    {
+		/*
+		 * get pointer to the image in the image library using offset from
+		 * 1st word in image library
+		 */
+		imageOffset = header->entry[imageCount].image.offset;
+		*imagePtr = &imageLibrary[imageOffset];
+		/* get the image size */
+		*imageSize = header->entry[imageCount].image.size;
+		status = IX_SUCCESS;
+		imageFound = true;
+	    }
+	    imageCount++;
+	}
+	if (status != IX_SUCCESS)
+	{
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+				   "imageId not found in image library header\n");
+	    ixNpeDlImageMgrStats.imageIdNotFound++;
+	}
+    }
+    else
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+			       "invalid signature in image library\n");
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlImageMgrImageFind: status = %d\n", status);
+    return status;
+}
+#endif
+
+/*
+ * Function definition: ixNpeDlImageMgrImageFind
+ */
+IX_STATUS
+ixNpeDlImageMgrImageFind (
+    UINT32 *imageLibrary,
+    UINT32 imageId,
+    UINT32 **imagePtr,
+    UINT32 *imageSize)
+{
+    IxNpeDlImageMgrImageHeader *image;
+    UINT32 offset = 0;
+
+    /* If user didn't specify a library to use, use the default
+     * one from IxNpeMicrocode.h
+     */
+    if (imageLibrary == NULL)
+    {
+#ifdef IX_NPEDL_READ_MICROCODE_FROM_FILE
+	if (ixNpeMicrocode_binaryArray == NULL)
+        {
+	    printk (KERN_ERR "ixp400.o:  ERROR, no Microcode found in memory\n");
+	    return IX_FAIL;
+	}
+	else
+	{
+	    imageLibrary = ixNpeMicrocode_binaryArray;
+	}
+#else
+	imageLibrary = getIxNpeMicroCodeImageLibrary();
+	if (imageLibrary == NULL)
+        {
+	    printf ("npe:  ERROR, no Microcode found in memory\n");
+	    return IX_FAIL;
+	}
+#endif /* IX_NPEDL_READ_MICROCODE_FROM_FILE */
+    }
+
+#if 0
+    /* For backward's compatibility with previous image format */
+    if (ixNpeDlImageMgrSignatureCheck(imageLibrary))
+    {
+        return ixNpeDlImageMgrImageFind_legacy(imageLibrary,
+                                               imageId,
+                                               imagePtr,
+                                               imageSize);
+    }
+#endif
+
+    while (*(imageLibrary+offset) == NPE_IMAGE_MARKER)
+    {
+        image = (IxNpeDlImageMgrImageHeader *)(imageLibrary+offset);
+        offset += sizeof(IxNpeDlImageMgrImageHeader)/sizeof(UINT32);
+        
+        if (image->id == imageId)
+        {
+            *imagePtr = imageLibrary + offset;
+            *imageSize = image->size;
+            return IX_SUCCESS;
+        }
+        /* 2 consecutive NPE_IMAGE_MARKER's indicates end of library */
+        else if (image->id == NPE_IMAGE_MARKER)
+        {
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+				   "imageId not found in image library header\n");
+	    ixNpeDlImageMgrStats.imageIdNotFound++;
+            /* reached end of library, image not found */
+            return IX_FAIL;
+        }
+        offset += image->size;
+    }
+
+    /* If we get here, our image library may be corrupted */
+    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+                           "image library format may be invalid or corrupted\n");
+    return IX_FAIL;
+}
+
diff --git a/marvell/uboot/drivers/net/npe/IxNpeDlNpeMgr.c b/marvell/uboot/drivers/net/npe/IxNpeDlNpeMgr.c
new file mode 100644
index 0000000..8d94dfa
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxNpeDlNpeMgr.c
@@ -0,0 +1,907 @@
+/**
+ * @file IxNpeDlNpeMgr.c
+ *
+ * @author Intel Corporation
+ * @date 09 January 2002
+ *
+ * @brief This file contains the implementation of the private API for the
+ *        IXP425 NPE Downloader NpeMgr module
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxOsal.h"
+#include "IxNpeDl.h"
+#include "IxNpeDlNpeMgr_p.h"
+#include "IxNpeDlNpeMgrUtils_p.h"
+#include "IxNpeDlNpeMgrEcRegisters_p.h"
+#include "IxNpeDlMacros_p.h"
+#include "IxFeatureCtrl.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+#define IX_NPEDL_BYTES_PER_WORD                   4
+
+/* used to read download map from version in microcode image */
+#define IX_NPEDL_BLOCK_TYPE_INSTRUCTION           0x00000000
+#define IX_NPEDL_BLOCK_TYPE_DATA                  0x00000001
+#define IX_NPEDL_BLOCK_TYPE_STATE                 0x00000002
+#define IX_NPEDL_END_OF_DOWNLOAD_MAP              0x0000000F
+
+/*
+ * masks used to extract address info from State information context
+ * register addresses as read from microcode image 
+ */
+#define IX_NPEDL_MASK_STATE_ADDR_CTXT_REG         0x0000000F
+#define IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM         0x000000F0
+
+/* LSB offset of Context Number field in State-Info Context Address */
+#define IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM       4
+
+/* size (in words) of single State Information entry (ctxt reg address|data) */
+#define IX_NPEDL_STATE_INFO_ENTRY_SIZE            2
+
+
+ #define IX_NPEDL_RESET_NPE_PARITY  0x0800
+ #define IX_NPEDL_PARITY_BIT_MASK   0x3F00FFFF
+ #define IX_NPEDL_CONFIG_CTRL_REG_MASK  0x3F3FFFFF
+
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+typedef struct
+{
+    UINT32 type;
+    UINT32 offset;
+} IxNpeDlNpeMgrDownloadMapBlockEntry;
+
+typedef union
+{
+    IxNpeDlNpeMgrDownloadMapBlockEntry block;
+    UINT32 eodmMarker;
+} IxNpeDlNpeMgrDownloadMapEntry;
+
+typedef struct
+{
+    /* 1st entry in the download map (there may be more than one) */
+    IxNpeDlNpeMgrDownloadMapEntry entry[1];
+} IxNpeDlNpeMgrDownloadMap;
+
+
+/* used to access an instruction or data block in a microcode image */
+typedef struct
+{
+    UINT32 npeMemAddress;
+    UINT32 size;
+    UINT32 data[1];
+} IxNpeDlNpeMgrCodeBlock;
+
+/* used to access each Context Reg entry state-information block */
+typedef struct
+{
+    UINT32 addressInfo;
+    UINT32 value;
+} IxNpeDlNpeMgrStateInfoCtxtRegEntry;
+
+/* used to access a state-information block in a microcode image */
+typedef struct
+{
+    UINT32 size;
+    IxNpeDlNpeMgrStateInfoCtxtRegEntry ctxtRegEntry[1];
+} IxNpeDlNpeMgrStateInfoBlock;
+ 
+/* used to store some useful NPE information for easy access */
+typedef struct
+{
+    UINT32 baseAddress;
+    UINT32 insMemSize;
+    UINT32 dataMemSize;
+} IxNpeDlNpeInfo;
+
+/* used to distinguish instruction and data memory operations */
+typedef enum 
+{
+  IX_NPEDL_MEM_TYPE_INSTRUCTION = 0,
+  IX_NPEDL_MEM_TYPE_DATA
+} IxNpeDlNpeMemType;
+
+/* used to hold a reset value for a particular ECS register */
+typedef struct
+{
+    UINT32 regAddr;
+    UINT32 regResetVal;
+} IxNpeDlEcsRegResetValue;
+
+/* prototype of function to write either Instruction or Data memory */
+typedef IX_STATUS (*IxNpeDlNpeMgrMemWrite) (UINT32 npeBaseAddress,
+					    UINT32 npeMemAddress,
+					    UINT32 npeMemData,
+					    BOOL verify);
+
+/* module statistics counters */
+typedef struct
+{
+    UINT32 instructionBlocksLoaded;
+    UINT32 dataBlocksLoaded;
+    UINT32 stateInfoBlocksLoaded;
+    UINT32 criticalNpeErrors;
+    UINT32 criticalMicrocodeErrors;
+    UINT32 npeStarts;
+    UINT32 npeStops;
+    UINT32 npeResets;
+} IxNpeDlNpeMgrStats;
+
+
+/*
+ * Variable declarations global to this file only.  Externs are followed by
+ * static variables.
+ */
+static IxNpeDlNpeInfo ixNpeDlNpeInfo[] =
+{
+    {
+	0,
+	IX_NPEDL_INS_MEMSIZE_WORDS_NPEA,
+	IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA
+    },
+    {
+	0,
+	IX_NPEDL_INS_MEMSIZE_WORDS_NPEB,
+	IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB
+    },
+    {
+	0,
+	IX_NPEDL_INS_MEMSIZE_WORDS_NPEC,
+	IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC
+    }
+};
+
+/* contains Reset values for Context Store Registers  */
+static UINT32 ixNpeDlCtxtRegResetValues[] =
+{
+    IX_NPEDL_CTXT_REG_RESET_STEVT,
+    IX_NPEDL_CTXT_REG_RESET_STARTPC,
+    IX_NPEDL_CTXT_REG_RESET_REGMAP,
+    IX_NPEDL_CTXT_REG_RESET_CINDEX,
+};
+
+/* contains Reset values for Context Store Registers  */
+static IxNpeDlEcsRegResetValue ixNpeDlEcsRegResetValues[] =
+{
+    {IX_NPEDL_ECS_BG_CTXT_REG_0,    IX_NPEDL_ECS_BG_CTXT_REG_0_RESET},
+    {IX_NPEDL_ECS_BG_CTXT_REG_1,    IX_NPEDL_ECS_BG_CTXT_REG_1_RESET},
+    {IX_NPEDL_ECS_BG_CTXT_REG_2,    IX_NPEDL_ECS_BG_CTXT_REG_2_RESET},
+    {IX_NPEDL_ECS_PRI_1_CTXT_REG_0, IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET},
+    {IX_NPEDL_ECS_PRI_1_CTXT_REG_1, IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET},
+    {IX_NPEDL_ECS_PRI_1_CTXT_REG_2, IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET},
+    {IX_NPEDL_ECS_PRI_2_CTXT_REG_0, IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET},
+    {IX_NPEDL_ECS_PRI_2_CTXT_REG_1, IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET},
+    {IX_NPEDL_ECS_PRI_2_CTXT_REG_2, IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET},
+    {IX_NPEDL_ECS_DBG_CTXT_REG_0,   IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET},
+    {IX_NPEDL_ECS_DBG_CTXT_REG_1,   IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET},
+    {IX_NPEDL_ECS_DBG_CTXT_REG_2,   IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET},
+    {IX_NPEDL_ECS_INSTRUCT_REG,     IX_NPEDL_ECS_INSTRUCT_REG_RESET}
+};
+
+static IxNpeDlNpeMgrStats ixNpeDlNpeMgrStats;
+
+/* Set when NPE register memory has been mapped */
+static BOOL ixNpeDlMemInitialised = false;
+
+
+/*
+ * static function prototypes.
+ */
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrMemLoad (IxNpeDlNpeId npeId, UINT32 npeBaseAddress,
+		      IxNpeDlNpeMgrCodeBlock *codeBlockPtr,
+		      BOOL verify, IxNpeDlNpeMemType npeMemType);
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrStateInfoLoad (UINT32 npeBaseAddress,
+			    IxNpeDlNpeMgrStateInfoBlock *codeBlockPtr,
+			    BOOL verify);
+PRIVATE BOOL
+ixNpeDlNpeMgrBitsSetCheck (UINT32 npeBaseAddress, UINT32 regOffset,
+			   UINT32 expectedBitsSet);
+
+PRIVATE UINT32
+ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId);
+
+/*
+ * Function definition: ixNpeDlNpeMgrBaseAddressGet
+ */
+PRIVATE UINT32
+ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId)
+{
+    IX_OSAL_ASSERT (ixNpeDlMemInitialised);
+    return ixNpeDlNpeInfo[npeId].baseAddress;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrInit
+ */
+void
+ixNpeDlNpeMgrInit (void)
+{
+    /* Only map the memory once */
+    if (!ixNpeDlMemInitialised)
+    {
+	UINT32 virtAddr;
+
+	/* map the register memory for NPE-A */
+	virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEA,
+					    IX_OSAL_IXP400_NPEA_MAP_SIZE); 
+	IX_OSAL_ASSERT(virtAddr);
+	ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = virtAddr;
+
+	/* map the register memory for NPE-B */
+	virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEB,
+					    IX_OSAL_IXP400_NPEB_MAP_SIZE); 
+	IX_OSAL_ASSERT(virtAddr);
+	ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = virtAddr;
+
+	/* map the register memory for NPE-C */
+	virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEC,
+					    IX_OSAL_IXP400_NPEC_MAP_SIZE); 
+	IX_OSAL_ASSERT(virtAddr);
+	ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = virtAddr;
+
+	ixNpeDlMemInitialised = true;
+    }
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrUninit
+ */
+IX_STATUS
+ixNpeDlNpeMgrUninit (void)
+{
+    if (!ixNpeDlMemInitialised)
+    {
+	return IX_FAIL;
+    }
+
+    IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress);
+    IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress);
+    IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress);
+
+    ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = 0;
+    ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = 0;
+    ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = 0;
+
+    ixNpeDlMemInitialised = false;
+
+    return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeDlNpeMgrImageLoad
+ */
+IX_STATUS
+ixNpeDlNpeMgrImageLoad (
+    IxNpeDlNpeId npeId,
+    UINT32 *imageCodePtr,
+    BOOL verify)
+{
+    UINT32 npeBaseAddress;
+    IxNpeDlNpeMgrDownloadMap *downloadMap;
+    UINT32 *blockPtr;
+    UINT32 mapIndex = 0;
+    IX_STATUS status = IX_SUCCESS;
+    
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlNpeMgrImageLoad\n");
+
+    /* get base memory address of NPE from npeId */
+    npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
+
+    /* check execution status of NPE to verify NPE Stop was successful */
+    if (!ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL,
+				    IX_NPEDL_EXCTL_STATUS_STOP))
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageDownload - "
+			       "NPE was not stopped before download\n");
+	status = IX_FAIL;
+    }
+    else
+    {
+	/*
+	 * Read Download Map, checking each block type and calling
+	 * appropriate function to perform download 
+	 */
+	downloadMap = (IxNpeDlNpeMgrDownloadMap *) imageCodePtr;
+	while ((downloadMap->entry[mapIndex].eodmMarker != 
+		IX_NPEDL_END_OF_DOWNLOAD_MAP)
+	       && (status == IX_SUCCESS))
+	{
+	    /* calculate pointer to block to be downloaded */
+	    blockPtr = imageCodePtr +
+		downloadMap->entry[mapIndex].block.offset;
+
+	    switch (downloadMap->entry[mapIndex].block.type)
+	    {
+	    case IX_NPEDL_BLOCK_TYPE_INSTRUCTION:
+		status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress, 
+					     (IxNpeDlNpeMgrCodeBlock *)blockPtr,
+					       verify,
+					       IX_NPEDL_MEM_TYPE_INSTRUCTION);
+		break;
+	    case IX_NPEDL_BLOCK_TYPE_DATA:
+		status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress,
+                                             (IxNpeDlNpeMgrCodeBlock *)blockPtr,
+					       verify, IX_NPEDL_MEM_TYPE_DATA);
+		break;
+	    case IX_NPEDL_BLOCK_TYPE_STATE:
+		status = ixNpeDlNpeMgrStateInfoLoad (npeBaseAddress,
+				       (IxNpeDlNpeMgrStateInfoBlock *) blockPtr,
+						     verify);
+		break;
+	    default:
+		IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageLoad: "
+				       "unknown block type in download map\n");
+		status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
+		ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
+		break;
+	    }
+	    mapIndex++;
+	}/* loop: for each entry in download map, while status == SUCCESS */
+    }/* condition: NPE stopped before attempting download */
+    
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Exiting ixNpeDlNpeMgrImageLoad : status = %d\n",
+		     status);
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrMemLoad
+ */
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrMemLoad (
+    IxNpeDlNpeId npeId,
+    UINT32 npeBaseAddress,
+    IxNpeDlNpeMgrCodeBlock *blockPtr,
+    BOOL verify,
+    IxNpeDlNpeMemType npeMemType)
+{
+    UINT32 npeMemAddress;
+    UINT32 blockSize;
+    UINT32 memSize = 0;
+    IxNpeDlNpeMgrMemWrite memWriteFunc = NULL;
+    UINT32 localIndex = 0;
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlNpeMgrMemLoad\n");
+    
+    /*
+     * select NPE EXCTL reg read/write commands depending on memory
+     * type (instruction/data) to be accessed
+     */
+    if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION)
+    {
+	memSize = ixNpeDlNpeInfo[npeId].insMemSize;
+	memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrInsMemWrite;
+    }
+    else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA)
+    {
+	memSize = ixNpeDlNpeInfo[npeId].dataMemSize;
+	memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrDataMemWrite;
+    }
+
+    /*
+     * NPE memory is loaded contiguously from each block, so only address
+     * of 1st word in block is needed
+     */
+    npeMemAddress = blockPtr->npeMemAddress;
+    /* number of words of instruction/data microcode in block to download */
+    blockSize = blockPtr->size;
+    if ((npeMemAddress + blockSize) > memSize)
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: "
+			       "Block size too big for NPE memory\n");
+	status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
+	ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
+    }
+    else
+    {
+	for (localIndex = 0; localIndex < blockSize; localIndex++)
+	{
+	    status = memWriteFunc (npeBaseAddress, npeMemAddress,
+				   blockPtr->data[localIndex], verify);
+
+	    if (status != IX_SUCCESS)
+	    {
+		IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: "
+				       "write to NPE memory failed\n");
+		status = IX_NPEDL_CRITICAL_NPE_ERR;
+		ixNpeDlNpeMgrStats.criticalNpeErrors++;
+		break;   /* abort download */
+	    }
+	    /* increment target (word)address in NPE memory */
+	    npeMemAddress++;   
+	}
+    }/* condition: block size will fit in NPE memory */
+
+    if (status == IX_SUCCESS)
+    {
+	if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION)
+	{
+	    ixNpeDlNpeMgrStats.instructionBlocksLoaded++;
+	}
+	else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA)
+	{
+	    ixNpeDlNpeMgrStats.dataBlocksLoaded++;
+	}
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlNpeMgrMemLoad : status = %d\n", status);
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrStateInfoLoad
+ */
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrStateInfoLoad (
+    UINT32 npeBaseAddress,
+    IxNpeDlNpeMgrStateInfoBlock *blockPtr,
+    BOOL verify)
+{
+    UINT32 blockSize;
+    UINT32 ctxtRegAddrInfo; 
+    UINT32 ctxtRegVal;
+    IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
+    UINT32 ctxtNum;            /* identifies Context number (0-16)   */
+    UINT32 i;
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlNpeMgrStateInfoLoad\n");
+
+    /* block size contains number of words of state-info in block */
+    blockSize = blockPtr->size;
+    
+    ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);
+
+    /* for each state-info context register entry in block */
+    for (i = 0; i < (blockSize/IX_NPEDL_STATE_INFO_ENTRY_SIZE); i++)
+    {
+	/* each state-info entry is 2 words (address, value) in length */
+	ctxtRegAddrInfo = (blockPtr->ctxtRegEntry[i]).addressInfo;
+	ctxtRegVal      = (blockPtr->ctxtRegEntry[i]).value;
+	
+	ctxtReg = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_REG);
+	ctxtNum = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM) >> 
+	    IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM;
+	
+	/* error-check Context Register No. and Context Number values  */
+	/* NOTE that there is no STEVT register for Context 0 */
+	if ((ctxtReg < 0) ||
+	    (ctxtReg >= IX_NPEDL_CTXT_REG_MAX) ||
+	    (ctxtNum > IX_NPEDL_CTXT_NUM_MAX) ||
+	    ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
+	{
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: "
+				   "invalid Context Register Address\n");
+	    status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
+	    ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
+	    break;   /* abort download */
+	}    
+	
+	status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum, ctxtReg,
+					    ctxtRegVal, verify);
+	if (status != IX_SUCCESS)
+	{
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: "
+				   "write of state-info to NPE failed\n");
+	    status = IX_NPEDL_CRITICAL_NPE_ERR;
+	    ixNpeDlNpeMgrStats.criticalNpeErrors++;
+	    break;   /* abort download */
+	}
+    }/* loop: for each context reg entry in State Info block */
+    
+    ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);
+
+    if (status == IX_SUCCESS)
+    {
+	ixNpeDlNpeMgrStats.stateInfoBlocksLoaded++;
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlNpeMgrStateInfoLoad : status = %d\n",
+		     status);
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrNpeReset
+ */
+IX_STATUS
+ixNpeDlNpeMgrNpeReset (
+    IxNpeDlNpeId npeId)
+{
+    UINT32 npeBaseAddress;
+    IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
+    UINT32 ctxtNum;            /* identifies Context number (0-16)   */
+    UINT32 regAddr;
+    UINT32 regVal;
+    UINT32 localIndex;
+    UINT32 indexMax;
+    IX_STATUS status = IX_SUCCESS;
+    IxFeatureCtrlReg unitFuseReg;
+    UINT32 ixNpeConfigCtrlRegVal;
+    
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Entering ixNpeDlNpeMgrNpeReset\n");
+    
+    /* get base memory address of NPE from npeId */
+    npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
+
+    /* pre-store the NPE Config Control Register Value */
+    IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, &ixNpeConfigCtrlRegVal);
+    
+    ixNpeConfigCtrlRegVal |= 0x3F000000;
+    
+    /* disable the parity interrupt */
+    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, (ixNpeConfigCtrlRegVal & IX_NPEDL_PARITY_BIT_MASK));
+    
+    ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);
+
+    /*
+     * clear the FIFOs
+     */
+    while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
+				      IX_NPEDL_REG_OFFSET_WFIFO,
+				      IX_NPEDL_MASK_WFIFO_VALID))
+    {
+	/* read from the Watch-point FIFO until empty */
+	IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WFIFO,
+			   &regVal);
+    }
+    
+    while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
+					  IX_NPEDL_REG_OFFSET_STAT,
+				      IX_NPEDL_MASK_STAT_OFNE))
+    {
+	/* read from the outFIFO until empty */
+	IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_FIFO,
+			   &regVal);
+    }
+    
+    while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
+				      IX_NPEDL_REG_OFFSET_STAT,
+				      IX_NPEDL_MASK_STAT_IFNE))
+    {
+	/*
+	 * step execution of the NPE intruction to read inFIFO using
+	 * the Debug Executing Context stack
+	 */
+	status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
+					   IX_NPEDL_INSTR_RD_FIFO, 0, 0);
+
+    if (IX_SUCCESS != status)
+    {
+        return status;   
+    }
+    
+    }
+    
+    /*
+     * Reset the mailbox reg
+     */
+    /* ...from XScale side */
+    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_MBST,
+			IX_NPEDL_REG_RESET_MBST);
+    /* ...from NPE side */
+    status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
+				       IX_NPEDL_INSTR_RESET_MBOX, 0, 0);
+
+    if (IX_SUCCESS != status)
+    {
+        return status;   
+    }
+
+    /* 
+     *   Reset the physical registers in the NPE register file:
+     *   Note: no need to save/restore REGMAP for Context 0 here
+     *   since all Context Store regs are reset in subsequent code
+     */
+    for (regAddr = 0;
+	 (regAddr < IX_NPEDL_TOTAL_NUM_PHYS_REG) && (status != IX_FAIL);
+	 regAddr++)
+    {
+	/* for each physical register in the NPE reg file, write 0 : */
+	status = ixNpeDlNpeMgrPhysicalRegWrite (npeBaseAddress, regAddr,
+						0, true);
+	if (status != IX_SUCCESS)
+	{
+	    return status;  /* abort reset */
+	}
+    }
+    
+
+    /*
+     * Reset the context store:
+     */
+    for (ctxtNum = IX_NPEDL_CTXT_NUM_MIN;
+	 ctxtNum <= IX_NPEDL_CTXT_NUM_MAX; ctxtNum++)
+    {	
+	/* set each context's Context Store registers to reset values: */
+	for (ctxtReg = 0; ctxtReg < IX_NPEDL_CTXT_REG_MAX; ctxtReg++)
+	{
+	    /* NOTE that there is no STEVT register for Context 0 */
+	    if (!((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
+	    { 
+		regVal = ixNpeDlCtxtRegResetValues[ctxtReg];
+		status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum,
+						    ctxtReg, regVal, true);
+		if (status != IX_SUCCESS)
+		{
+		    return status;  /* abort reset */
+		}
+	    }
+	}
+    }
+
+    ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);
+
+    /* write Reset values to Execution Context Stack registers */
+    indexMax = sizeof (ixNpeDlEcsRegResetValues) /
+	sizeof (IxNpeDlEcsRegResetValue);
+    for (localIndex = 0; localIndex < indexMax; localIndex++)
+    {
+	regAddr = ixNpeDlEcsRegResetValues[localIndex].regAddr;
+	regVal = ixNpeDlEcsRegResetValues[localIndex].regResetVal;
+	ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, regAddr, regVal);
+    }
+    
+    /* clear the profile counter */
+    ixNpeDlNpeMgrCommandIssue (npeBaseAddress, 
+			       IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT);
+    
+    /* clear registers EXCT, AP0, AP1, AP2 and AP3 */
+    for (regAddr = IX_NPEDL_REG_OFFSET_EXCT;
+	     regAddr <= IX_NPEDL_REG_OFFSET_AP3;
+	 regAddr += IX_NPEDL_BYTES_PER_WORD)
+    {
+	IX_NPEDL_REG_WRITE (npeBaseAddress, regAddr, 0);
+    }
+    
+    /* Reset the Watch-count register */
+    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, 0);
+    
+    /*
+     * WR IXA00055043 - Remove IMEM Parity Introduced by NPE Reset Operation
+     */
+
+    /*
+     * Call the feature control API to fused out and reset the NPE and its
+     * coprocessor - to reset internal states and remove parity error
+     */
+    unitFuseReg = ixFeatureCtrlRead ();
+    unitFuseReg |= (IX_NPEDL_RESET_NPE_PARITY << npeId);
+    ixFeatureCtrlWrite (unitFuseReg);
+
+    /* call the feature control API to un-fused and un-reset the NPE & COP */
+    unitFuseReg &= (~(IX_NPEDL_RESET_NPE_PARITY << npeId));
+    ixFeatureCtrlWrite (unitFuseReg);
+
+    /*
+     * Call NpeMgr function to stop the NPE again after the Feature Control
+     * has unfused and Un-Reset the NPE and its associated Coprocessors
+     */
+    status = ixNpeDlNpeMgrNpeStop (npeId);
+
+    /* restore NPE configuration bus Control Register - Parity Settings  */
+    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, 
+        (ixNpeConfigCtrlRegVal & IX_NPEDL_CONFIG_CTRL_REG_MASK));
+
+    ixNpeDlNpeMgrStats.npeResets++;
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlNpeMgrNpeReset : status = %d\n", status);
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrNpeStart
+ */
+IX_STATUS
+ixNpeDlNpeMgrNpeStart (
+    IxNpeDlNpeId npeId)
+{
+    UINT32    npeBaseAddress;
+    UINT32    ecsRegVal;
+    BOOL      npeRunning;
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Entering ixNpeDlNpeMgrNpeStart\n");
+
+    /* get base memory address of NPE from npeId */
+    npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
+
+    /*
+     * ensure only Background Context Stack Level is Active by turning off
+     * the Active bit in each of the other Executing Context Stack levels
+     */
+    ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
+					     IX_NPEDL_ECS_PRI_1_CTXT_REG_0);
+    ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
+    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_1_CTXT_REG_0,
+				  ecsRegVal);
+
+    ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
+					     IX_NPEDL_ECS_PRI_2_CTXT_REG_0);
+    ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
+    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_2_CTXT_REG_0,
+				  ecsRegVal);
+
+    ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
+					     IX_NPEDL_ECS_DBG_CTXT_REG_0);
+    ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
+    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
+				  ecsRegVal);
+    
+    /* clear the pipeline */
+    ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
+    
+    /* start NPE execution by issuing command through EXCTL register on NPE */
+    ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_START);
+
+    /*
+     * check execution status of NPE to verify NPE Start operation was
+     * successful
+     */
+    npeRunning = ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
+					    IX_NPEDL_REG_OFFSET_EXCTL,
+					    IX_NPEDL_EXCTL_STATUS_RUN);
+    if (npeRunning)
+    {
+	ixNpeDlNpeMgrStats.npeStarts++;
+    }
+    else
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStart: "
+			       "failed to start NPE execution\n");
+	status = IX_FAIL;
+    }
+
+    
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlNpeMgrNpeStart : status = %d\n", status);
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrNpeStop
+ */
+IX_STATUS
+ixNpeDlNpeMgrNpeStop (
+    IxNpeDlNpeId npeId)
+{
+    UINT32    npeBaseAddress;
+    IX_STATUS status = IX_SUCCESS;
+    
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlNpeMgrNpeStop\n");
+    
+    /* get base memory address of NPE from npeId */
+    npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
+
+    /* stop NPE execution by issuing command through EXCTL register on NPE */
+    ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STOP);
+
+    /* verify that NPE Stop was successful */
+    if (! ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL,
+				     IX_NPEDL_EXCTL_STATUS_STOP))
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStop: "
+			       "failed to stop NPE execution\n");
+	status = IX_FAIL;
+    }
+
+    ixNpeDlNpeMgrStats.npeStops++;
+    
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlNpeMgrNpeStop : status = %d\n", status);
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrBitsSetCheck
+ */
+PRIVATE BOOL
+ixNpeDlNpeMgrBitsSetCheck (
+    UINT32 npeBaseAddress,
+    UINT32 regOffset,
+    UINT32 expectedBitsSet)
+{
+    UINT32 regVal;
+    IX_NPEDL_REG_READ (npeBaseAddress, regOffset, &regVal);
+
+    return expectedBitsSet == (expectedBitsSet & regVal);
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrStatsShow
+ */
+void
+ixNpeDlNpeMgrStatsShow (void)
+{
+    ixOsalLog (IX_OSAL_LOG_LVL_USER,
+               IX_OSAL_LOG_DEV_STDOUT,
+               "\nixNpeDlNpeMgrStatsShow:\n"
+               "\tInstruction Blocks loaded: %u\n"
+               "\tData Blocks loaded: %u\n"
+               "\tState Information Blocks loaded: %u\n"
+               "\tCritical NPE errors: %u\n"
+               "\tCritical Microcode errors: %u\n",
+               ixNpeDlNpeMgrStats.instructionBlocksLoaded,
+               ixNpeDlNpeMgrStats.dataBlocksLoaded,
+               ixNpeDlNpeMgrStats.stateInfoBlocksLoaded,
+               ixNpeDlNpeMgrStats.criticalNpeErrors,
+               ixNpeDlNpeMgrStats.criticalMicrocodeErrors,
+               0);
+
+    ixOsalLog (IX_OSAL_LOG_LVL_USER,
+               IX_OSAL_LOG_DEV_STDOUT,
+               "\tSuccessful NPE Starts: %u\n"
+               "\tSuccessful NPE Stops: %u\n"
+               "\tSuccessful NPE Resets: %u\n\n",
+               ixNpeDlNpeMgrStats.npeStarts,
+               ixNpeDlNpeMgrStats.npeStops,
+               ixNpeDlNpeMgrStats.npeResets,
+               0,0,0);
+
+    ixNpeDlNpeMgrUtilsStatsShow ();
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrStatsReset
+ */
+void
+ixNpeDlNpeMgrStatsReset (void)
+{
+    ixNpeDlNpeMgrStats.instructionBlocksLoaded = 0;
+    ixNpeDlNpeMgrStats.dataBlocksLoaded = 0;
+    ixNpeDlNpeMgrStats.stateInfoBlocksLoaded = 0;
+    ixNpeDlNpeMgrStats.criticalNpeErrors = 0;
+    ixNpeDlNpeMgrStats.criticalMicrocodeErrors = 0;
+    ixNpeDlNpeMgrStats.npeStarts = 0;
+    ixNpeDlNpeMgrStats.npeStops = 0;
+    ixNpeDlNpeMgrStats.npeResets = 0;
+
+    ixNpeDlNpeMgrUtilsStatsReset ();
+}
diff --git a/marvell/uboot/drivers/net/npe/IxNpeDlNpeMgrUtils.c b/marvell/uboot/drivers/net/npe/IxNpeDlNpeMgrUtils.c
new file mode 100644
index 0000000..db50d22
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxNpeDlNpeMgrUtils.c
@@ -0,0 +1,782 @@
+/**
+ * @file IxNpeDlNpeMgrUtils.c
+ *
+ * @author Intel Corporation
+ * @date 18 February 2002
+ *
+ * @brief This file contains the implementation of the private API for the 
+ *        IXP425 NPE Downloader NpeMgr Utils module
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+/*
+ * Put the system defined include files required.
+ */
+#define IX_NPE_DL_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of
+                                              * retries before
+                                              * timeout
+					                          */  
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxOsal.h"
+#include "IxNpeDl.h"
+#include "IxNpeDlNpeMgrUtils_p.h"
+#include "IxNpeDlNpeMgrEcRegisters_p.h"
+#include "IxNpeDlMacros_p.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/* used to bit-mask a number of bytes */
+#define IX_NPEDL_MASK_LOWER_BYTE_OF_WORD  0x000000FF
+#define IX_NPEDL_MASK_LOWER_SHORT_OF_WORD 0x0000FFFF
+#define IX_NPEDL_MASK_FULL_WORD           0xFFFFFFFF
+
+#define IX_NPEDL_BYTES_PER_WORD           4
+#define IX_NPEDL_BYTES_PER_SHORT          2
+
+#define IX_NPEDL_REG_SIZE_BYTE            8
+#define IX_NPEDL_REG_SIZE_SHORT           16
+#define IX_NPEDL_REG_SIZE_WORD            32
+
+/*
+ * Introduce extra read cycles after issuing read command to NPE
+ * so that we read the register after the NPE has updated it
+ * This is to overcome race condition between XScale and NPE
+ */
+#define IX_NPEDL_DELAY_READ_CYCLES        2
+/*
+ * To mask top three MSBs of 32bit word to download into NPE IMEM
+ */
+#define IX_NPEDL_MASK_UNUSED_IMEM_BITS    0x1FFFFFFF;
+
+
+/*
+ * typedefs
+ */
+typedef struct
+{
+    UINT32 regAddress;
+    UINT32 regSize;
+} IxNpeDlCtxtRegAccessInfo;
+
+/* module statistics counters */
+typedef struct
+{
+    UINT32 insMemWrites;
+    UINT32 insMemWriteFails;
+    UINT32 dataMemWrites;
+    UINT32 dataMemWriteFails;
+    UINT32 ecsRegWrites;
+    UINT32 ecsRegReads;
+    UINT32 dbgInstructionExecs;
+    UINT32 contextRegWrites;
+    UINT32 physicalRegWrites;
+    UINT32 nextPcWrites;
+} IxNpeDlNpeMgrUtilsStats;
+
+
+/*
+ * Variable declarations global to this file only.  Externs are followed by
+ * static variables.
+ */
+
+/* 
+ * contains useful address and function pointers to read/write Context Regs, 
+ * eliminating some switch or if-else statements in places
+ */
+static IxNpeDlCtxtRegAccessInfo ixNpeDlCtxtRegAccInfo[IX_NPEDL_CTXT_REG_MAX] =
+{
+    {
+	IX_NPEDL_CTXT_REG_ADDR_STEVT,
+	IX_NPEDL_REG_SIZE_BYTE
+    },
+    {
+	IX_NPEDL_CTXT_REG_ADDR_STARTPC,
+	IX_NPEDL_REG_SIZE_SHORT
+    },
+    {
+	IX_NPEDL_CTXT_REG_ADDR_REGMAP,
+	IX_NPEDL_REG_SIZE_SHORT
+    },
+    {
+	IX_NPEDL_CTXT_REG_ADDR_CINDEX,
+	IX_NPEDL_REG_SIZE_BYTE
+    }
+};
+
+static UINT32 ixNpeDlSavedExecCount = 0;
+static UINT32 ixNpeDlSavedEcsDbgCtxtReg2 = 0;
+
+static IxNpeDlNpeMgrUtilsStats ixNpeDlNpeMgrUtilsStats;
+
+
+/*
+ * static function prototypes.
+ */
+PRIVATE __inline__ void
+ixNpeDlNpeMgrWriteCommandIssue (UINT32 npeBaseAddress, UINT32 cmd,
+				UINT32 addr, UINT32 data);
+
+PRIVATE __inline__ UINT32
+ixNpeDlNpeMgrReadCommandIssue (UINT32 npeBaseAddress, UINT32 cmd, UINT32 addr);
+
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrLogicalRegRead (UINT32 npeBaseAddress, UINT32 regAddr,
+			     UINT32 regSize, UINT32 ctxtNum, UINT32 *regVal);
+
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrLogicalRegWrite (UINT32 npeBaseAddress, UINT32 regAddr,
+			      UINT32 regVal, UINT32 regSize,
+			      UINT32 ctxtNum, BOOL verify);
+
+/*
+ * Function definition: ixNpeDlNpeMgrWriteCommandIssue
+ */
+PRIVATE __inline__ void
+ixNpeDlNpeMgrWriteCommandIssue (
+    UINT32 npeBaseAddress,
+    UINT32 cmd,
+    UINT32 addr,
+    UINT32 data)
+{
+    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, data);
+    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr);
+    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd);
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrReadCommandIssue
+ */
+PRIVATE __inline__ UINT32
+ixNpeDlNpeMgrReadCommandIssue (
+    UINT32 npeBaseAddress,
+    UINT32 cmd,
+    UINT32 addr)
+{
+    UINT32 data = 0;
+    int i;
+
+    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr);
+    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd);
+    for (i = 0; i <= IX_NPEDL_DELAY_READ_CYCLES; i++)
+    {
+	IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, &data);
+    }
+
+    return data;
+}
+
+/*
+ * Function definition: ixNpeDlNpeMgrInsMemWrite
+ */
+IX_STATUS
+ixNpeDlNpeMgrInsMemWrite (
+    UINT32 npeBaseAddress,
+    UINT32 insMemAddress,
+    UINT32 insMemData,
+    BOOL verify)
+{
+    UINT32 insMemDataRtn;
+
+    ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
+				    IX_NPEDL_EXCTL_CMD_WR_INS_MEM,
+				    insMemAddress, insMemData);
+    if (verify)
+    {
+        /* write invalid data to this reg, so we can see if we're reading 
+	   the EXDATA register too early */
+	IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA,
+			    ~insMemData);
+
+        /*Disabled since top 3 MSB are not used for Azusa hardware Refer WR:IXA00053900*/
+        insMemData&=IX_NPEDL_MASK_UNUSED_IMEM_BITS;
+
+        insMemDataRtn=ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
+                                           IX_NPEDL_EXCTL_CMD_RD_INS_MEM,
+                                           insMemAddress);
+
+        insMemDataRtn&=IX_NPEDL_MASK_UNUSED_IMEM_BITS;
+
+	if (insMemData != insMemDataRtn)
+	{
+	    ixNpeDlNpeMgrUtilsStats.insMemWriteFails++;
+	    return IX_FAIL;
+	}
+    }
+
+    ixNpeDlNpeMgrUtilsStats.insMemWrites++;
+    return IX_SUCCESS;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrDataMemWrite
+ */
+IX_STATUS
+ixNpeDlNpeMgrDataMemWrite (
+    UINT32 npeBaseAddress,
+    UINT32 dataMemAddress,
+    UINT32 dataMemData,
+    BOOL verify)
+{
+    ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
+				    IX_NPEDL_EXCTL_CMD_WR_DATA_MEM,
+				    dataMemAddress, dataMemData);
+    if (verify)
+    {
+        /* write invalid data to this reg, so we can see if we're reading 
+	   the EXDATA register too early */
+	IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, ~dataMemData);
+
+	if (dataMemData !=
+	    ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
+					   IX_NPEDL_EXCTL_CMD_RD_DATA_MEM,
+					   dataMemAddress))
+	{
+	    ixNpeDlNpeMgrUtilsStats.dataMemWriteFails++;
+	    return IX_FAIL;
+	}
+    }
+
+    ixNpeDlNpeMgrUtilsStats.dataMemWrites++;
+    return IX_SUCCESS;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrExecAccRegWrite
+ */
+void
+ixNpeDlNpeMgrExecAccRegWrite (
+    UINT32 npeBaseAddress,
+    UINT32 regAddress,
+    UINT32 regData)
+{
+    ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
+				    IX_NPEDL_EXCTL_CMD_WR_ECS_REG,
+				    regAddress, regData);
+    ixNpeDlNpeMgrUtilsStats.ecsRegWrites++;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrExecAccRegRead
+ */
+UINT32
+ixNpeDlNpeMgrExecAccRegRead (
+    UINT32 npeBaseAddress,
+    UINT32 regAddress)
+{
+    ixNpeDlNpeMgrUtilsStats.ecsRegReads++;
+    return ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
+					  IX_NPEDL_EXCTL_CMD_RD_ECS_REG,
+					  regAddress);
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrCommandIssue
+ */
+void
+ixNpeDlNpeMgrCommandIssue (
+    UINT32 npeBaseAddress,
+    UINT32 command)     
+{
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlNpeMgrCommandIssue\n");
+
+    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, command);
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlNpeMgrCommandIssue\n");
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrDebugInstructionPreExec
+ */
+void
+ixNpeDlNpeMgrDebugInstructionPreExec(
+    UINT32 npeBaseAddress)
+{
+    /* turn off the halt bit by clearing Execution Count register. */
+    /* save reg contents 1st and restore later */
+    IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT,
+		       &ixNpeDlSavedExecCount);
+    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT, 0);
+
+    /* ensure that IF and IE are on (temporarily), so that we don't end up
+     * stepping forever */
+    ixNpeDlSavedEcsDbgCtxtReg2 = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
+				                   IX_NPEDL_ECS_DBG_CTXT_REG_2);
+
+    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2,
+				  (ixNpeDlSavedEcsDbgCtxtReg2 |
+				   IX_NPEDL_MASK_ECS_DBG_REG_2_IF |
+				   IX_NPEDL_MASK_ECS_DBG_REG_2_IE));
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrDebugInstructionExec
+ */
+IX_STATUS
+ixNpeDlNpeMgrDebugInstructionExec(
+    UINT32 npeBaseAddress,
+    UINT32 npeInstruction,
+    UINT32 ctxtNum,
+    UINT32 ldur)
+{
+    UINT32 ecsDbgRegVal;
+    UINT32 oldWatchcount, newWatchcount;
+    UINT32 retriesCount = 0;
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlNpeMgrDebugInstructionExec\n");
+
+    /* set the Active bit, and the LDUR, in the debug level */
+    ecsDbgRegVal = IX_NPEDL_MASK_ECS_REG_0_ACTIVE |
+	(ldur << IX_NPEDL_OFFSET_ECS_REG_0_LDUR);
+
+    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
+				  ecsDbgRegVal);
+
+    /*
+     * set CCTXT at ECS DEBUG L3 to specify in which context to execute the
+     * instruction, and set SELCTXT at ECS DEBUG Level to specify which context
+     * store to access.
+     * Debug ECS Level Reg 1 has form  0x000n000n, where n = context number
+     */
+    ecsDbgRegVal = (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_CCTXT) |
+	(ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT);
+
+    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_1,
+				  ecsDbgRegVal);
+
+    /* clear the pipeline */
+    ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
+
+    /* load NPE instruction into the instruction register */
+    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_INSTRUCT_REG,
+				  npeInstruction);
+
+    /* we need this value later to wait for completion of NPE execution step */
+    IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, &oldWatchcount);
+
+    /* issue a Step One command via the Execution Control register */
+    ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STEP);
+
+	/* Watch Count register increments when NPE completes an instruction */
+	IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC,
+        &newWatchcount);
+        
+    /*
+     * force the XScale to wait until the NPE has finished execution step
+     * NOTE that this delay will be very small, just long enough to allow a
+     * single NPE instruction to complete execution; if instruction execution
+     * is not completed before timeout retries, exit the while loop
+     */
+    while ((IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount) 
+        && (newWatchcount == oldWatchcount))
+    {
+	    /* Watch Count register increments when NPE completes an instruction */
+	    IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC,
+		    &newWatchcount);
+			   
+        retriesCount++;
+    }    
+
+    if (IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount)
+    {
+        ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs++;
+    }
+    else
+    {
+        /* Return timeout status as the instruction has not been executed
+         * after maximum retries */
+        status = IX_NPEDL_CRITICAL_NPE_ERR;
+    }
+    
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlNpeMgrDebugInstructionExec\n");
+		     
+    return status;
+}    
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrDebugInstructionPostExec
+ */
+void
+ixNpeDlNpeMgrDebugInstructionPostExec(
+    UINT32 npeBaseAddress)
+{
+    /* clear active bit in debug level */
+    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
+				  0);
+
+    /* clear the pipeline */
+    ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
+    
+    /* restore Execution Count register contents. */
+    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT,
+			ixNpeDlSavedExecCount);
+
+    /* restore IF and IE bits to original values */
+    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2,
+				  ixNpeDlSavedEcsDbgCtxtReg2);
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrLogicalRegRead
+ */
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrLogicalRegRead (
+    UINT32 npeBaseAddress, 
+    UINT32 regAddr,
+    UINT32 regSize,
+    UINT32 ctxtNum,
+    UINT32 *regVal)
+{
+    IX_STATUS status = IX_SUCCESS;
+    UINT32 npeInstruction = 0;
+    UINT32 mask = 0;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlNpeMgrLogicalRegRead\n");
+
+    switch (regSize)
+    {
+    case IX_NPEDL_REG_SIZE_BYTE:
+      npeInstruction = IX_NPEDL_INSTR_RD_REG_BYTE;
+      mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD;  break;
+    case IX_NPEDL_REG_SIZE_SHORT:
+      npeInstruction = IX_NPEDL_INSTR_RD_REG_SHORT;
+      mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD;  break;
+    case IX_NPEDL_REG_SIZE_WORD:
+      npeInstruction = IX_NPEDL_INSTR_RD_REG_WORD;
+      mask = IX_NPEDL_MASK_FULL_WORD;  break;
+    }
+
+    /* make regAddr be the SRC and DEST operands (e.g. movX d0, d0) */
+    npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_SRC) |
+	(regAddr << IX_NPEDL_OFFSET_INSTR_DEST);
+
+    /* step execution of NPE intruction using Debug Executing Context stack */
+    status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress, npeInstruction,
+				       ctxtNum, IX_NPEDL_RD_INSTR_LDUR);
+
+    if (IX_SUCCESS != status)
+    {
+        return status;
+    }
+    
+    /* read value of register from Execution Data register */
+    IX_NPEDL_REG_READ (npeBaseAddress,	IX_NPEDL_REG_OFFSET_EXDATA, regVal);
+
+   /* align value from left to right */
+    *regVal = (*regVal >> (IX_NPEDL_REG_SIZE_WORD - regSize)) & mask;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlNpeMgrLogicalRegRead\n");
+    
+    return IX_SUCCESS;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrLogicalRegWrite
+ */
+PRIVATE IX_STATUS
+ixNpeDlNpeMgrLogicalRegWrite (
+    UINT32 npeBaseAddress, 
+    UINT32 regAddr,
+    UINT32 regVal,
+    UINT32 regSize,
+    UINT32 ctxtNum,
+    BOOL verify)
+{
+    UINT32 npeInstruction = 0;
+    UINT32 mask = 0;
+    IX_STATUS status = IX_SUCCESS;
+    UINT32 retRegVal;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlNpeMgrLogicalRegWrite\n");
+
+    if (regSize == IX_NPEDL_REG_SIZE_WORD)
+    {
+	/* NPE register addressing is left-to-right: e.g. |d0|d1|d2|d3| */
+	/* Write upper half-word (short) to |d0|d1| */
+	status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr,
+				      regVal >> IX_NPEDL_REG_SIZE_SHORT,
+				      IX_NPEDL_REG_SIZE_SHORT,
+				      ctxtNum, verify);
+				      
+	if (IX_SUCCESS != status)
+	{
+	    return status;
+	}
+	
+	/* Write lower half-word (short) to |d2|d3| */
+	status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress,
+				      regAddr + IX_NPEDL_BYTES_PER_SHORT,
+                                    regVal & IX_NPEDL_MASK_LOWER_SHORT_OF_WORD,
+				      IX_NPEDL_REG_SIZE_SHORT,
+				      ctxtNum, verify);
+    
+    if (IX_SUCCESS != status)
+	{
+	    return status;
+	}
+	}
+    else
+    {
+        switch (regSize)
+	{ 
+	case IX_NPEDL_REG_SIZE_BYTE:
+	    npeInstruction = IX_NPEDL_INSTR_WR_REG_BYTE;
+	    mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD;  break;
+	case IX_NPEDL_REG_SIZE_SHORT:
+            npeInstruction = IX_NPEDL_INSTR_WR_REG_SHORT;
+	    mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD;  break;
+	}
+	/* mask out any redundant bits, so verify will work later */
+	regVal &= mask;
+
+	/* fill dest operand field of  instruction with destination reg addr */
+	npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_DEST);
+
+	/* fill src operand field of instruction with least-sig 5 bits of val*/
+	npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA) <<
+			   IX_NPEDL_OFFSET_INSTR_SRC);
+
+	/* fill coprocessor field of instruction with most-sig 11 bits of val*/
+	npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA) <<
+			   IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA);
+
+	/* step execution of NPE intruction using Debug ECS */
+	status = ixNpeDlNpeMgrDebugInstructionExec(npeBaseAddress, npeInstruction,
+					  ctxtNum, IX_NPEDL_WR_INSTR_LDUR);
+					  
+	if (IX_SUCCESS != status)
+	{
+	    return status;  
+	} 
+    }/* condition: if reg to be written is 8-bit or 16-bit (not 32-bit) */
+
+    if (verify)
+    {
+	status = ixNpeDlNpeMgrLogicalRegRead (npeBaseAddress, regAddr,
+						   regSize, ctxtNum, &retRegVal);
+						   
+        if (IX_SUCCESS == status)
+        {
+            if (regVal != retRegVal)
+            {
+                status = IX_FAIL;
+            }
+        }        
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlNpeMgrLogicalRegWrite : status = %d\n",
+		     status);
+    
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrPhysicalRegWrite
+ */
+IX_STATUS
+ixNpeDlNpeMgrPhysicalRegWrite (
+    UINT32 npeBaseAddress,
+    UINT32 regAddr,
+    UINT32 regValue,
+    BOOL verify)
+{
+    IX_STATUS status;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlNpeMgrPhysicalRegWrite\n");
+
+/*
+ * There are 32 physical registers used in an NPE.  These are
+ * treated as 16 pairs of 32-bit registers.  To write one of the pair,
+ * write the pair number (0-16) to the REGMAP for Context 0.  Then write
+ * the value to register  0 or 4 in the regfile, depending on which
+ * register of the pair is to be written
+ */
+
+    /*
+     * set REGMAP for context 0 to (regAddr >> 1) to choose which pair (0-16)
+     * of physical registers to write 
+     */
+    status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress,
+					   IX_NPEDL_CTXT_REG_ADDR_REGMAP,
+					   (regAddr >>
+					  IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP),
+					   IX_NPEDL_REG_SIZE_SHORT, 0, verify);
+    if (status == IX_SUCCESS)
+    {
+	/* regAddr = 0 or 4  */
+	regAddr = (regAddr & IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR) *
+	    IX_NPEDL_BYTES_PER_WORD;
+    
+    status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr, regValue, 
+					   IX_NPEDL_REG_SIZE_WORD, 0, verify);
+    }
+    
+    if (status != IX_SUCCESS)
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrPhysicalRegWrite: "
+			       "error writing to physical register\n");
+    }
+
+    ixNpeDlNpeMgrUtilsStats.physicalRegWrites++;
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlNpeMgrPhysicalRegWrite : status = %d\n",
+		     status);
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrCtxtRegWrite
+ */
+IX_STATUS
+ixNpeDlNpeMgrCtxtRegWrite (
+    UINT32 npeBaseAddress,
+    UINT32 ctxtNum,
+    IxNpeDlCtxtRegNum ctxtReg,
+    UINT32 ctxtRegVal,
+    BOOL verify)
+{
+    UINT32 tempRegVal;
+    UINT32 ctxtRegAddr;
+    UINT32 ctxtRegSize;
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Entering ixNpeDlNpeMgrCtxtRegWrite\n");
+
+    /*
+     * Context 0 has no STARTPC. Instead, this value is used to set
+     * NextPC for Background ECS, to set where NPE starts executing code
+     */
+    if ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STARTPC))
+    {
+	/* read BG_CTXT_REG_0, update NEXTPC bits, and write back to reg */
+	tempRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
+						  IX_NPEDL_ECS_BG_CTXT_REG_0);
+	tempRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_NEXTPC;
+	tempRegVal |= (ctxtRegVal << IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC) &
+	    IX_NPEDL_MASK_ECS_REG_0_NEXTPC;
+	
+	ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress,
+				      IX_NPEDL_ECS_BG_CTXT_REG_0, tempRegVal);
+
+	ixNpeDlNpeMgrUtilsStats.nextPcWrites++;
+    }
+    else
+    {
+	ctxtRegAddr = ixNpeDlCtxtRegAccInfo[ctxtReg].regAddress;
+	ctxtRegSize = ixNpeDlCtxtRegAccInfo[ctxtReg].regSize;
+	status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, ctxtRegAddr,
+					       ctxtRegVal, ctxtRegSize,
+					       ctxtNum, verify);
+	if (status != IX_SUCCESS)
+	{
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrCtxtRegWrite: "
+				   "error writing to context store register\n");
+	}
+	
+	ixNpeDlNpeMgrUtilsStats.contextRegWrites++;
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Exiting ixNpeDlNpeMgrCtxtRegWrite : status = %d\n",
+		     status);
+
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrUtilsStatsShow
+ */
+void
+ixNpeDlNpeMgrUtilsStatsShow (void)
+{
+    ixOsalLog (IX_OSAL_LOG_LVL_USER,
+               IX_OSAL_LOG_DEV_STDOUT,
+               "\nixNpeDlNpeMgrUtilsStatsShow:\n"
+               "\tInstruction Memory writes: %u\n"
+               "\tInstruction Memory writes failed: %u\n"
+               "\tData Memory writes: %u\n"
+               "\tData Memory writes failed: %u\n",
+               ixNpeDlNpeMgrUtilsStats.insMemWrites,
+               ixNpeDlNpeMgrUtilsStats.insMemWriteFails,
+               ixNpeDlNpeMgrUtilsStats.dataMemWrites,
+               ixNpeDlNpeMgrUtilsStats.dataMemWriteFails,
+               0,0);
+
+    ixOsalLog (IX_OSAL_LOG_LVL_USER,
+               IX_OSAL_LOG_DEV_STDOUT,
+               "\tExecuting Context Stack Register writes: %u\n"
+               "\tExecuting Context Stack Register reads: %u\n"
+               "\tPhysical Register writes: %u\n"
+               "\tContext Store Register writes: %u\n"
+               "\tExecution Backgound Context NextPC writes: %u\n"
+               "\tDebug Instructions Executed: %u\n\n",
+               ixNpeDlNpeMgrUtilsStats.ecsRegWrites,
+               ixNpeDlNpeMgrUtilsStats.ecsRegReads,
+               ixNpeDlNpeMgrUtilsStats.physicalRegWrites,
+               ixNpeDlNpeMgrUtilsStats.contextRegWrites,
+               ixNpeDlNpeMgrUtilsStats.nextPcWrites,
+               ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs);
+}
+
+
+/*
+ * Function definition: ixNpeDlNpeMgrUtilsStatsReset
+ */
+void
+ixNpeDlNpeMgrUtilsStatsReset (void)
+{
+    ixNpeDlNpeMgrUtilsStats.insMemWrites = 0;
+    ixNpeDlNpeMgrUtilsStats.insMemWriteFails = 0;
+    ixNpeDlNpeMgrUtilsStats.dataMemWrites = 0;
+    ixNpeDlNpeMgrUtilsStats.dataMemWriteFails = 0;
+    ixNpeDlNpeMgrUtilsStats.ecsRegWrites = 0;
+    ixNpeDlNpeMgrUtilsStats.ecsRegReads = 0;
+    ixNpeDlNpeMgrUtilsStats.physicalRegWrites = 0;
+    ixNpeDlNpeMgrUtilsStats.contextRegWrites = 0;
+    ixNpeDlNpeMgrUtilsStats.nextPcWrites = 0;
+    ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs = 0;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxNpeMh.c b/marvell/uboot/drivers/net/npe/IxNpeMh.c
new file mode 100644
index 0000000..5adabd8
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxNpeMh.c
@@ -0,0 +1,558 @@
+/**
+ * @file IxNpeMh.c
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the implementation of the public API for the
+ * IXP425 NPE Message Handler component.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Put the system defined include files required.
+ */
+
+/*
+ * Put the user defined include files required.
+ */
+
+#include "IxOsal.h"
+#include "IxNpeMhMacros_p.h"
+
+#include "IxNpeMh.h"
+
+#include "IxNpeMhConfig_p.h"
+#include "IxNpeMhReceive_p.h"
+#include "IxNpeMhSend_p.h"
+#include "IxNpeMhSolicitedCbMgr_p.h"
+#include "IxNpeMhUnsolicitedCbMgr_p.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/*
+ * Variable declarations global to this file only.  Externs are followed by
+ * static variables.
+ */
+
+PRIVATE BOOL ixNpeMhInitialized = false;
+
+/*
+ * Extern function prototypes.
+ */
+
+/*
+ * Static function prototypes.
+ */
+
+/*
+ * Function definition: ixNpeMhInitialize
+ */
+
+PUBLIC IX_STATUS ixNpeMhInitialize (
+    IxNpeMhNpeInterrupts npeInterrupts)
+{
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhInitialize\n");
+
+    /* check the npeInterrupts parameter */
+    if ((npeInterrupts != IX_NPEMH_NPEINTERRUPTS_NO) &&
+        (npeInterrupts != IX_NPEMH_NPEINTERRUPTS_YES))
+    {
+        IX_NPEMH_ERROR_REPORT ("Illegal npeInterrupts parameter value\n");
+        return IX_FAIL;
+    }
+
+    /* parameters are ok ... */
+
+    /* initialize the Receive module */
+    ixNpeMhReceiveInitialize ();
+
+    /* initialize the Solicited Callback Manager module */
+    ixNpeMhSolicitedCbMgrInitialize ();
+
+    /* initialize the Unsolicited Callback Manager module */
+    ixNpeMhUnsolicitedCbMgrInitialize ();
+
+    /* initialize the Configuration module
+     *
+     * NOTE: This module was originally configured before the
+     * others, but the sequence was changed so that interrupts
+     * would only be enabled after the handler functions were
+     * set up.  The above modules need to be initialised to
+     * handle the NPE interrupts.  See SCR #2231.
+     */
+    ixNpeMhConfigInitialize (npeInterrupts);
+
+    ixNpeMhInitialized = true;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhInitialize\n");
+
+    return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhUnload
+ */
+
+PUBLIC IX_STATUS ixNpeMhUnload (void)
+{
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhUnload\n");
+
+    if (!ixNpeMhInitialized)
+    {
+	return IX_FAIL;
+    }
+
+    /* Uninitialize the Configuration module */
+    ixNpeMhConfigUninit ();
+
+    ixNpeMhInitialized = false;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhUnload\n");
+
+    return IX_SUCCESS;
+}
+
+
+/*
+ * Function definition: ixNpeMhUnsolicitedCallbackRegister
+ */
+
+PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackRegister (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessageId messageId,
+    IxNpeMhCallback unsolicitedCallback)
+{
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhUnsolicitedCallbackRegister\n");
+
+    /* check that we are initialized */
+    if (!ixNpeMhInitialized)
+    {
+        IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
+        return IX_FAIL;
+    }
+
+    /* check the npeId parameter */
+    if (!ixNpeMhConfigNpeIdIsValid (npeId))
+    {
+        IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
+        return IX_FAIL;
+    }
+
+    /* check the messageId parameter */
+    if ((messageId < IX_NPEMH_MIN_MESSAGE_ID)
+        || (messageId > IX_NPEMH_MAX_MESSAGE_ID))
+    {
+        IX_NPEMH_ERROR_REPORT ("Message ID is out of range\n");
+        return IX_FAIL;
+    }
+
+    /* the unsolicitedCallback parameter is allowed to be NULL */
+
+    /* parameters are ok ... */
+
+    /* get the lock to prevent other clients from entering */
+    ixNpeMhConfigLockGet (npeId);
+
+    /* save the unsolicited callback for the message ID */
+    ixNpeMhUnsolicitedCbMgrCallbackSave (
+        npeId, messageId, unsolicitedCallback);
+
+    /* release the lock to allow other clients back in */
+    ixNpeMhConfigLockRelease (npeId);
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhUnsolicitedCallbackRegister\n");
+
+    return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhUnsolicitedCallbackForRangeRegister
+ */
+
+PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackForRangeRegister (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessageId minMessageId,
+    IxNpeMhMessageId maxMessageId,
+    IxNpeMhCallback unsolicitedCallback)
+{
+    IxNpeMhMessageId messageId;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhUnsolicitedCallbackForRangeRegister\n");
+
+    /* check that we are initialized */
+    if (!ixNpeMhInitialized)
+    {
+        IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
+        return IX_FAIL;
+    }
+
+    /* check the npeId parameter */
+    if (!ixNpeMhConfigNpeIdIsValid (npeId))
+    {
+        IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
+        return IX_FAIL;
+    }
+
+    /* check the minMessageId parameter */
+    if ((minMessageId < IX_NPEMH_MIN_MESSAGE_ID)
+        || (minMessageId > IX_NPEMH_MAX_MESSAGE_ID))
+    {
+        IX_NPEMH_ERROR_REPORT ("Min message ID is out of range\n");
+        return IX_FAIL;
+    }
+
+    /* check the maxMessageId parameter */
+    if ((maxMessageId < IX_NPEMH_MIN_MESSAGE_ID)
+        || (maxMessageId > IX_NPEMH_MAX_MESSAGE_ID))
+    {
+        IX_NPEMH_ERROR_REPORT ("Max message ID is out of range\n");
+        return IX_FAIL;
+    }
+
+    /* check the semantics of the message range parameters */
+    if (minMessageId > maxMessageId)
+    {
+        IX_NPEMH_ERROR_REPORT ("Min message ID greater than max message "
+                               "ID\n");
+        return IX_FAIL;
+    }
+
+    /* the unsolicitedCallback parameter is allowed to be NULL */
+
+    /* parameters are ok ... */
+
+    /* get the lock to prevent other clients from entering */
+    ixNpeMhConfigLockGet (npeId);
+
+    /* for each message ID in the range ... */
+    for (messageId = minMessageId; messageId <= maxMessageId; messageId++)
+    {
+        /* save the unsolicited callback for the message ID */
+        ixNpeMhUnsolicitedCbMgrCallbackSave (
+            npeId, messageId, unsolicitedCallback);
+    }
+
+    /* release the lock to allow other clients back in */
+    ixNpeMhConfigLockRelease (npeId);
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhUnsolicitedCallbackForRangeRegister\n");
+
+    return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhMessageSend
+ */
+
+PUBLIC IX_STATUS ixNpeMhMessageSend (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessage message,
+    UINT32 maxSendRetries)
+{
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhMessageSend\n");
+
+    /* check that we are initialized */
+    if (!ixNpeMhInitialized)
+    {
+        IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
+        return IX_FAIL;
+    }
+
+    /* check the npeId parameter */
+    if (!ixNpeMhConfigNpeIdIsValid (npeId))
+    {
+        IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
+        return IX_FAIL;
+    }
+
+    /* parameters are ok ... */
+
+    /* get the lock to prevent other clients from entering */
+    ixNpeMhConfigLockGet (npeId);
+
+    /* send the message */
+    status = ixNpeMhSendMessageSend (npeId, message, maxSendRetries);
+    if (status != IX_SUCCESS)
+    {
+        IX_NPEMH_ERROR_REPORT ("Failed to send message\n");
+    }
+
+    /* release the lock to allow other clients back in */
+    ixNpeMhConfigLockRelease (npeId);
+
+    IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhMessageSend"
+                     " : status = %d\n", status);
+
+    return status;
+}
+
+/*
+ * Function definition: ixNpeMhMessageWithResponseSend
+ */
+
+PUBLIC IX_STATUS ixNpeMhMessageWithResponseSend (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessage message,
+    IxNpeMhMessageId solicitedMessageId,
+    IxNpeMhCallback solicitedCallback,
+    UINT32 maxSendRetries)
+{
+    IX_STATUS status = IX_SUCCESS;
+    IxNpeMhCallback unsolicitedCallback = NULL;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhMessageWithResponseSend\n");
+
+    /* check that we are initialized */
+    if (!ixNpeMhInitialized)
+    {
+        IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
+        return IX_FAIL;
+    }
+
+    /* the solicitecCallback parameter is allowed to be NULL.  this */
+    /* signifies the client is not interested in the response message */
+
+    /* check the npeId parameter */
+    if (!ixNpeMhConfigNpeIdIsValid (npeId))
+    {
+        IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
+        return IX_FAIL;
+    }
+
+    /* check the solicitedMessageId parameter */
+    if ((solicitedMessageId < IX_NPEMH_MIN_MESSAGE_ID)
+        || (solicitedMessageId > IX_NPEMH_MAX_MESSAGE_ID))
+    {
+        IX_NPEMH_ERROR_REPORT ("Solicited message ID is out of range\n");
+        return IX_FAIL;
+    }
+
+    /* check the solicitedMessageId parameter.  if an unsolicited */
+    /* callback has been registered for the specified message ID then */
+    /* report an error and return failure */
+    ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
+        npeId, solicitedMessageId, &unsolicitedCallback);
+    if (unsolicitedCallback != NULL)
+    {
+        IX_NPEMH_ERROR_REPORT ("Solicited message ID conflicts with "
+                               "unsolicited message ID\n");
+        return IX_FAIL;
+    }
+
+    /* parameters are ok ... */
+
+    /* get the lock to prevent other clients from entering */
+    ixNpeMhConfigLockGet (npeId);
+
+    /* send the message */
+    status = ixNpeMhSendMessageWithResponseSend (
+        npeId, message, solicitedMessageId, solicitedCallback,
+        maxSendRetries);
+    if (status != IX_SUCCESS)
+    {
+        IX_NPEMH_ERROR_REPORT ("Failed to send message\n");
+    }
+
+    /* release the lock to allow other clients back in */
+    ixNpeMhConfigLockRelease (npeId);
+
+    IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhMessageWithResponseSend"
+                     " : status = %d\n", status);
+
+    return status;
+}
+
+/*
+ * Function definition: ixNpeMhMessagesReceive
+ */
+
+PUBLIC IX_STATUS ixNpeMhMessagesReceive (
+    IxNpeMhNpeId npeId)
+{
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhMessagesReceive\n");
+
+    /* check that we are initialized */
+    if (!ixNpeMhInitialized)
+    {
+        IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
+        return IX_FAIL;
+    }
+
+    /* check the npeId parameter */
+    if (!ixNpeMhConfigNpeIdIsValid (npeId))
+    {
+        IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
+        return IX_FAIL;
+    }
+
+    /* parameters are ok ... */
+
+    /* get the lock to prevent other clients from entering */
+    ixNpeMhConfigLockGet (npeId);
+
+    /* receive messages from the NPE */
+    status = ixNpeMhReceiveMessagesReceive (npeId);
+
+    if (status != IX_SUCCESS)
+    {
+        IX_NPEMH_ERROR_REPORT ("Failed to receive message\n");
+    }
+
+    /* release the lock to allow other clients back in */
+    ixNpeMhConfigLockRelease (npeId);
+
+    IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhMessagesReceive"
+                     " : status = %d\n", status);
+
+    return status;
+}
+
+/*
+ * Function definition: ixNpeMhShow
+ */
+
+PUBLIC IX_STATUS ixNpeMhShow (
+    IxNpeMhNpeId npeId)
+{
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhShow\n");
+
+    /* check that we are initialized */
+    if (!ixNpeMhInitialized)
+    {
+        IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
+        return IX_FAIL;
+    }
+
+    /* check the npeId parameter */
+    if (!ixNpeMhConfigNpeIdIsValid (npeId))
+    {
+        IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
+        return IX_FAIL;
+    }
+
+    /* parameters are ok ... */
+
+    /* note we don't get the lock here as printing the statistics */
+    /* to a console may take some time and we don't want to impact */
+    /* system performance.  this means that the statistics displayed */
+    /* may be in a state of flux and make not represent a consistent */
+    /* snapshot. */
+
+    /* display a header */
+    ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
+	       "Current state of NPE ID %d:\n\n", npeId, 0, 0, 0, 0, 0);
+
+    /* show the current state of each module */
+
+    /* show the current state of the Configuration module */
+    ixNpeMhConfigShow (npeId);
+
+    /* show the current state of the Receive module */
+    ixNpeMhReceiveShow (npeId);
+
+    /* show the current state of the Send module */
+    ixNpeMhSendShow (npeId);
+
+    /* show the current state of the Solicited Callback Manager module */
+    ixNpeMhSolicitedCbMgrShow (npeId);
+
+    /* show the current state of the Unsolicited Callback Manager module */
+    ixNpeMhUnsolicitedCbMgrShow (npeId);
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhShow\n");
+
+    return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhShowReset
+ */
+
+PUBLIC IX_STATUS ixNpeMhShowReset (
+    IxNpeMhNpeId npeId)
+{
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhShowReset\n");
+
+    /* check that we are initialized */
+    if (!ixNpeMhInitialized)
+    {
+        IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n");
+        return IX_FAIL;
+    }
+
+    /* check the npeId parameter */
+    if (!ixNpeMhConfigNpeIdIsValid (npeId))
+    {
+        IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n");
+        return IX_FAIL;
+    }
+
+    /* parameters are ok ... */
+
+    /* note we don't get the lock here as resetting the statistics */
+    /* shouldn't impact system performance. */
+
+    /* reset the current state of each module */
+
+    /* reset the current state of the Configuration module */
+    ixNpeMhConfigShowReset (npeId);
+
+    /* reset the current state of the Receive module */
+    ixNpeMhReceiveShowReset (npeId);
+
+    /* reset the current state of the Send module */
+    ixNpeMhSendShowReset (npeId);
+
+    /* reset the current state of the Solicited Callback Manager module */
+    ixNpeMhSolicitedCbMgrShowReset (npeId);
+
+    /* reset the current state of the Unsolicited Callback Manager module */
+    ixNpeMhUnsolicitedCbMgrShowReset (npeId);
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhShowReset\n");
+
+    return IX_SUCCESS;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxNpeMhConfig.c b/marvell/uboot/drivers/net/npe/IxNpeMhConfig.c
new file mode 100644
index 0000000..eaa9a21
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxNpeMhConfig.c
@@ -0,0 +1,584 @@
+/**
+ * @file IxNpeMhConfig.c
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the implementation of the private API for the
+ * Configuration module.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Put the system defined include files required.
+ */
+
+
+/*
+ * Put the user defined include files required.
+ */
+
+#include "IxOsal.h"
+
+#include "IxNpeMhMacros_p.h"
+
+#include "IxNpeMhConfig_p.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+#define IX_NPE_MH_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of
+                                              * retries before
+                                              * timeout
+					                          */  
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/**
+ * @struct IxNpeMhConfigStats
+ *
+ * @brief This structure is used to maintain statistics for the
+ * Configuration module.
+ */
+
+typedef struct
+{
+    UINT32 outFifoReads;        /**< outFifo reads */
+    UINT32 inFifoWrites;        /**< inFifo writes */
+    UINT32 maxInFifoFullRetries;   /**< max retries if inFIFO full   */
+    UINT32 maxOutFifoEmptyRetries; /**< max retries if outFIFO empty */
+} IxNpeMhConfigStats;
+
+/*
+ * Variable declarations global to this file only.  Externs are followed by
+ * static variables.
+ */
+
+IxNpeMhConfigNpeInfo ixNpeMhConfigNpeInfo[IX_NPEMH_NUM_NPES] =
+{
+    {
+        0,
+        IX_NPEMH_NPEA_INT,
+	0,
+        0,
+        0,
+        0,
+        0,
+        NULL,
+        false
+    },
+    {
+        0,
+        IX_NPEMH_NPEB_INT,
+	0,
+	0,
+        0,
+        0,
+        0,
+        NULL,
+        false
+    },
+    {
+        0,
+        IX_NPEMH_NPEC_INT,
+        0,
+        0,
+        0,
+        0,
+        0,
+        NULL,
+        false
+    }
+};
+
+PRIVATE IxNpeMhConfigStats ixNpeMhConfigStats[IX_NPEMH_NUM_NPES];
+
+/*
+ * Extern function prototypes.
+ */
+
+/*
+ * Static function prototypes.
+ */
+PRIVATE
+void ixNpeMhConfigIsr (void *parameter);
+
+/*
+ * Function definition: ixNpeMhConfigIsr
+ */
+
+PRIVATE
+void ixNpeMhConfigIsr (void *parameter)
+{
+    IxNpeMhNpeId npeId = (IxNpeMhNpeId)parameter;
+    UINT32 ofint;
+    volatile UINT32 *statusReg =
+        (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhConfigIsr\n");
+
+    /* get the OFINT (OutFifo interrupt) bit of the status register */
+    IX_NPEMH_REGISTER_READ_BITS (statusReg, &ofint, IX_NPEMH_NPE_STAT_OFINT);
+
+    /* if the OFINT status bit is set */
+    if (ofint)
+    {
+        /* if there is an ISR registered for this NPE */
+        if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
+        {
+            /* invoke the ISR routine */
+            ixNpeMhConfigNpeInfo[npeId].isr (npeId);
+        }
+        else
+        {
+            /* if we don't service the interrupt the NPE will continue */
+            /* to trigger the interrupt indefinitely */
+            IX_NPEMH_ERROR_REPORT ("No ISR registered to service "
+                                   "interrupt\n");
+        }
+    }
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhConfigIsr\n");
+}
+
+/*
+ * Function definition: ixNpeMhConfigInitialize
+ */
+
+void ixNpeMhConfigInitialize (
+    IxNpeMhNpeInterrupts npeInterrupts)
+{
+    IxNpeMhNpeId npeId;
+    UINT32 virtualAddr[IX_NPEMH_NUM_NPES];
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhConfigInitialize\n");
+
+    /* Request a mapping for the NPE-A config register address space */
+    virtualAddr[IX_NPEMH_NPEID_NPEA] =
+	(UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEA_BASE,
+				     IX_OSAL_IXP400_NPEA_MAP_SIZE);
+    IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEA]);
+
+    /* Request a mapping for the NPE-B config register address space */
+    virtualAddr[IX_NPEMH_NPEID_NPEB] =
+	(UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEB_BASE,
+				     IX_OSAL_IXP400_NPEB_MAP_SIZE);
+    IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEB]);
+    
+    /* Request a mapping for the NPE-C config register address space */
+    virtualAddr[IX_NPEMH_NPEID_NPEC] =
+	(UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEC_BASE,
+				     IX_OSAL_IXP400_NPEC_MAP_SIZE);
+    IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEC]);
+
+    /* for each NPE ... */
+    for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
+    {
+        /* declare a convenience pointer */
+        IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
+	
+	/* store the virtual addresses of the NPE registers for later use */
+	npeInfo->virtualRegisterBase  = virtualAddr[npeId];
+	npeInfo->statusRegister  = virtualAddr[npeId] + IX_NPEMH_NPESTAT_OFFSET;
+	npeInfo->controlRegister = virtualAddr[npeId] + IX_NPEMH_NPECTL_OFFSET;
+	npeInfo->inFifoRegister  = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET;
+	npeInfo->outFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET;
+
+        /* for test purposes - to verify the register addresses */
+        IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d status register  = "
+                         "0x%08X\n", npeId, npeInfo->statusRegister);
+        IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d control register = "
+                         "0x%08X\n", npeId, npeInfo->controlRegister);
+        IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d inFifo register  = "
+                         "0x%08X\n", npeId, npeInfo->inFifoRegister);
+        IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d outFifo register = "
+                         "0x%08X\n", npeId, npeInfo->outFifoRegister);
+
+        /* connect our ISR to the NPE interrupt */
+        (void) ixOsalIrqBind (
+            npeInfo->interruptId, ixNpeMhConfigIsr, (void *)npeId);
+
+        /* initialise a mutex for this NPE */
+        (void) ixOsalMutexInit (&npeInfo->mutex);
+
+        /* if we should service the NPE's "outFIFO not empty" interrupt */
+        if (npeInterrupts == IX_NPEMH_NPEINTERRUPTS_YES)
+        {
+            /* enable the NPE's "outFIFO not empty" interrupt */
+            ixNpeMhConfigNpeInterruptEnable (npeId);
+        }
+        else
+        {
+            /* disable the NPE's "outFIFO not empty" interrupt */
+            ixNpeMhConfigNpeInterruptDisable (npeId);
+        }
+    }
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhConfigInitialize\n");
+}
+
+/*
+ * Function definition: ixNpeMhConfigUninit
+ */
+
+void ixNpeMhConfigUninit (void)
+{
+    IxNpeMhNpeId npeId;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhConfigUninit\n");
+
+    /* for each NPE ... */
+    for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
+    {
+        /* declare a convenience pointer */
+        IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
+        
+        /* disconnect ISR */
+        ixOsalIrqUnbind(npeInfo->interruptId);
+
+        /* destroy mutex associated with this NPE */
+        ixOsalMutexDestroy(&npeInfo->mutex);
+	
+	IX_OSAL_MEM_UNMAP (npeInfo->virtualRegisterBase);
+
+	npeInfo->virtualRegisterBase  = 0;
+	npeInfo->statusRegister  = 0;
+	npeInfo->controlRegister = 0;
+	npeInfo->inFifoRegister  = 0;
+	npeInfo->outFifoRegister = 0;
+    }
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhConfigUninit\n");
+}
+
+/*
+ * Function definition: ixNpeMhConfigIsrRegister
+ */
+
+void ixNpeMhConfigIsrRegister (
+    IxNpeMhNpeId npeId,
+    IxNpeMhConfigIsr isr)
+{
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhConfigIsrRegister\n");
+
+    /* check if there is already an ISR registered for this NPE */
+    if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
+    {
+        IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, "Over-writing registered NPE ISR\n");
+    }
+
+    /* save the ISR routine with the NPE info */
+    ixNpeMhConfigNpeInfo[npeId].isr = isr;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhConfigIsrRegister\n");
+}
+
+/*
+ * Function definition: ixNpeMhConfigNpeInterruptEnable
+ */
+
+BOOL ixNpeMhConfigNpeInterruptEnable (
+    IxNpeMhNpeId npeId)
+{
+    UINT32 ofe;
+    volatile UINT32 *controlReg =
+        (UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
+
+    /* get the OFE (OutFifoEnable) bit of the control register */
+    IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
+
+    /* if the interrupt is disabled then we must enable it */
+    if (!ofe)
+    {
+        /* set the OFE (OutFifoEnable) bit of the control register */
+        /* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */
+        /* time for the write to have effect */
+        IX_NPEMH_REGISTER_WRITE_BITS (controlReg,
+                                      (IX_NPEMH_NPE_CTL_OFE |
+                                       IX_NPEMH_NPE_CTL_OFEWE),
+                                      (IX_NPEMH_NPE_CTL_OFE |
+                                       IX_NPEMH_NPE_CTL_OFEWE));
+    }
+
+    /* return the previous state of the interrupt */
+    return (ofe != 0);
+}
+
+/*
+ * Function definition: ixNpeMhConfigNpeInterruptDisable
+ */
+
+BOOL ixNpeMhConfigNpeInterruptDisable (
+    IxNpeMhNpeId npeId)
+{
+    UINT32 ofe;
+    volatile UINT32 *controlReg =
+        (UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
+
+    /* get the OFE (OutFifoEnable) bit of the control register */
+    IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
+
+    /* if the interrupt is enabled then we must disable it */
+    if (ofe)
+    {
+        /* unset the OFE (OutFifoEnable) bit of the control register */
+        /* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */
+        /* time for the write to have effect */
+        IX_NPEMH_REGISTER_WRITE_BITS (controlReg,
+                                      (0                    |
+                                       IX_NPEMH_NPE_CTL_OFEWE),
+                                      (IX_NPEMH_NPE_CTL_OFE |
+                                       IX_NPEMH_NPE_CTL_OFEWE));
+    }
+
+    /* return the previous state of the interrupt */
+    return (ofe != 0);
+}
+
+/*
+ * Function definition: ixNpeMhConfigMessageIdGet
+ */
+
+IxNpeMhMessageId ixNpeMhConfigMessageIdGet (
+    IxNpeMhMessage message)
+{
+    /* return the most-significant byte of the first word of the */
+    /* message */
+    return ((IxNpeMhMessageId) ((message.data[0] >> 24) & 0xFF));
+}
+
+/*
+ * Function definition: ixNpeMhConfigNpeIdIsValid
+ */
+
+BOOL ixNpeMhConfigNpeIdIsValid (
+    IxNpeMhNpeId npeId)
+{
+    /* check that the npeId parameter is within the range of valid IDs */
+    return (npeId >= 0 && npeId < IX_NPEMH_NUM_NPES);
+}
+
+/*
+ * Function definition: ixNpeMhConfigLockGet
+ */
+
+void ixNpeMhConfigLockGet (
+    IxNpeMhNpeId npeId)
+{
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhConfigLockGet\n");
+
+    /* lock the mutex for this NPE */
+    (void) ixOsalMutexLock (&ixNpeMhConfigNpeInfo[npeId].mutex, 
+			    IX_OSAL_WAIT_FOREVER);
+
+    /* disable the NPE's "outFIFO not empty" interrupt */
+    ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
+        ixNpeMhConfigNpeInterruptDisable (npeId);
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhConfigLockGet\n");
+}
+
+/*
+ * Function definition: ixNpeMhConfigLockRelease
+ */
+
+void ixNpeMhConfigLockRelease (
+    IxNpeMhNpeId npeId)
+{
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhConfigLockRelease\n");
+
+    /* if the interrupt was previously enabled */
+    if (ixNpeMhConfigNpeInfo[npeId].oldInterruptState)
+    {
+        /* enable the NPE's "outFIFO not empty" interrupt */
+        ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
+            ixNpeMhConfigNpeInterruptEnable (npeId);
+    }
+
+    /* unlock the mutex for this NPE */
+    (void) ixOsalMutexUnlock (&ixNpeMhConfigNpeInfo[npeId].mutex);
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhConfigLockRelease\n");
+}
+
+/*
+ * Function definition: ixNpeMhConfigInFifoWrite
+ */
+
+IX_STATUS ixNpeMhConfigInFifoWrite (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessage message)
+{
+    volatile UINT32 *npeInFifo =
+        (UINT32 *)ixNpeMhConfigNpeInfo[npeId].inFifoRegister;
+    UINT32 retriesCount = 0;
+
+    /* write the first word of the message to the NPE's inFIFO */
+    IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[0]);
+
+    /* need to wait for room to write second word - see SCR #493,
+       poll for maximum number of retries, if exceed maximum
+       retries, exit from while loop */
+    while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount)
+        && ixNpeMhConfigInFifoIsFull (npeId))
+    {
+        retriesCount++;
+    }
+
+    /* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
+    if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
+    {
+        return IX_NPEMH_CRITICAL_NPE_ERR;   
+    }    
+    
+    /* write the second word of the message to the NPE's inFIFO */
+    IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[1]);
+
+    /* record in the stats the maximum number of retries needed */
+    if (ixNpeMhConfigStats[npeId].maxInFifoFullRetries < retriesCount)
+    {
+	ixNpeMhConfigStats[npeId].maxInFifoFullRetries = retriesCount;
+    }
+
+    /* update statistical info */
+    ixNpeMhConfigStats[npeId].inFifoWrites++;
+    
+    return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhConfigOutFifoRead
+ */
+
+IX_STATUS ixNpeMhConfigOutFifoRead (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessage *message)
+{
+    volatile UINT32 *npeOutFifo =
+        (UINT32 *)ixNpeMhConfigNpeInfo[npeId].outFifoRegister;
+    UINT32 retriesCount = 0;
+
+    /* read the first word of the message from the NPE's outFIFO */
+    IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[0]);
+
+    /* need to wait for NPE to write second word - see SCR #493 
+       poll for maximum number of retries, if exceed maximum
+       retries, exit from while loop */
+    while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount)
+        && ixNpeMhConfigOutFifoIsEmpty (npeId))
+    {
+        retriesCount++;
+    }
+
+    /* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
+    if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
+    {
+        return IX_NPEMH_CRITICAL_NPE_ERR;   
+    } 
+    
+    /* read the second word of the message from the NPE's outFIFO */
+    IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[1]);
+
+    /* record in the stats the maximum number of retries needed */
+    if (ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries < retriesCount)
+    {
+	ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = retriesCount;
+    }
+
+    /* update statistical info */
+    ixNpeMhConfigStats[npeId].outFifoReads++;
+    
+    return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhConfigShow
+ */
+
+void ixNpeMhConfigShow (
+    IxNpeMhNpeId npeId)
+{
+    /* show the message fifo read counter */
+    IX_NPEMH_SHOW ("Message FIFO reads",
+                   ixNpeMhConfigStats[npeId].outFifoReads);
+
+    /* show the message fifo write counter */
+    IX_NPEMH_SHOW ("Message FIFO writes",
+                   ixNpeMhConfigStats[npeId].inFifoWrites);
+
+    /* show the max retries performed when inFIFO full */
+    IX_NPEMH_SHOW ("Max inFIFO Full retries",
+		   ixNpeMhConfigStats[npeId].maxInFifoFullRetries);
+
+    /* show the max retries performed when outFIFO empty */
+    IX_NPEMH_SHOW ("Max outFIFO Empty retries",
+		   ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries);
+
+    /* show the current status of the inFifo */
+    ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
+	       "InFifo is %s and %s\n",
+	       (ixNpeMhConfigInFifoIsEmpty (npeId) ? 
+		(int) "EMPTY" : (int) "NOT EMPTY"),
+	       (ixNpeMhConfigInFifoIsFull (npeId) ? 
+		(int) "FULL" : (int) "NOT FULL"),
+	       0, 0, 0, 0);
+
+    /* show the current status of the outFifo */
+    ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
+	       "OutFifo is %s and %s\n",
+	       (ixNpeMhConfigOutFifoIsEmpty (npeId) ? 
+		(int) "EMPTY" : (int) "NOT EMPTY"),
+	       (ixNpeMhConfigOutFifoIsFull (npeId) ? 
+		(int) "FULL" : (int) "NOT FULL"),
+	       0, 0, 0, 0);
+}
+
+/*
+ * Function definition: ixNpeMhConfigShowReset
+ */
+
+void ixNpeMhConfigShowReset (
+    IxNpeMhNpeId npeId)
+{
+    /* reset the message fifo read counter */
+    ixNpeMhConfigStats[npeId].outFifoReads = 0;
+
+    /* reset the message fifo write counter */
+    ixNpeMhConfigStats[npeId].inFifoWrites = 0;
+
+    /* reset the max inFIFO Full retries counter */
+    ixNpeMhConfigStats[npeId].maxInFifoFullRetries = 0;
+
+    /* reset the max outFIFO empty retries counter */
+    ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = 0;
+}
+
+
diff --git a/marvell/uboot/drivers/net/npe/IxNpeMhReceive.c b/marvell/uboot/drivers/net/npe/IxNpeMhReceive.c
new file mode 100644
index 0000000..273c373
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxNpeMhReceive.c
@@ -0,0 +1,296 @@
+/**
+ * @file IxNpeMhReceive.c
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the implementation of the private API for the
+ * Receive module.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Put the system defined include files required.
+ */
+
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxOsal.h"
+#include "IxNpeMhMacros_p.h"
+#include "IxNpeMhConfig_p.h"
+#include "IxNpeMhReceive_p.h"
+#include "IxNpeMhSolicitedCbMgr_p.h"
+#include "IxNpeMhUnsolicitedCbMgr_p.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/**
+ * @struct IxNpeMhReceiveStats
+ *
+ * @brief This structure is used to maintain statistics for the Receive
+ * module.
+ */
+
+typedef struct
+{
+    UINT32 isrs;        /**< receive ISR invocations */
+    UINT32 receives;    /**< receive messages invocations */
+    UINT32 messages;    /**< messages received */
+    UINT32 solicited;   /**< solicited messages received */
+    UINT32 unsolicited; /**< unsolicited messages received */
+    UINT32 callbacks;   /**< callbacks invoked */
+} IxNpeMhReceiveStats;
+
+/*
+ * Variable declarations global to this file only.  Externs are followed by
+ * static variables.
+ */
+
+PRIVATE IxNpeMhReceiveStats ixNpeMhReceiveStats[IX_NPEMH_NUM_NPES];
+
+/*
+ * Extern function prototypes.
+ */
+
+/*
+ * Static function prototypes.
+ */
+PRIVATE
+void ixNpeMhReceiveIsr (int npeId);
+
+PRIVATE
+void ixNpeMhReceiveIsr (int npeId)
+{
+    int lockKey;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhReceiveIsr\n");
+
+    lockKey = ixOsalIrqLock ();
+
+    /* invoke the message receive routine to get messages from the NPE */
+    ixNpeMhReceiveMessagesReceive (npeId);
+
+    /* update statistical info */
+    ixNpeMhReceiveStats[npeId].isrs++;
+
+    ixOsalIrqUnlock (lockKey);
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhReceiveIsr\n");
+}
+
+/*
+ * Function definition: ixNpeMhReceiveInitialize
+ */
+
+void ixNpeMhReceiveInitialize (void)
+{
+    IxNpeMhNpeId npeId = 0;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhReceiveInitialize\n");
+
+    /* for each NPE ... */
+    for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
+    {
+        /* register our internal ISR for the NPE to handle "outFIFO not */
+        /* empty" interrupts */
+        ixNpeMhConfigIsrRegister (npeId, ixNpeMhReceiveIsr);
+    }
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhReceiveInitialize\n");
+}
+
+/*
+ * Function definition: ixNpeMhReceiveMessagesReceive
+ */
+
+IX_STATUS ixNpeMhReceiveMessagesReceive (
+    IxNpeMhNpeId npeId)
+{
+    IxNpeMhMessage message = { { 0, 0 } };
+    IxNpeMhMessageId messageId = 0;
+    IxNpeMhCallback callback = NULL;
+    IX_STATUS status;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhReceiveMessagesReceive\n");
+
+    /* update statistical info */
+    ixNpeMhReceiveStats[npeId].receives++;
+
+    /* while the NPE has messages in its outFIFO */
+    while (!ixNpeMhConfigOutFifoIsEmpty (npeId))
+    {
+        /* read a message from the NPE's outFIFO */
+        status = ixNpeMhConfigOutFifoRead (npeId, &message);
+
+        if (IX_SUCCESS != status)
+        {
+            return status;
+        }
+        
+        /* get the ID of the message */
+        messageId = ixNpeMhConfigMessageIdGet (message);
+
+	    IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG,
+			 "Received message from NPE %d with ID 0x%02X\n",
+			 npeId, messageId);
+
+        /* update statistical info */
+        ixNpeMhReceiveStats[npeId].messages++;
+
+        /* try to find a matching unsolicited callback for this message. */
+
+        /* we assume the message is unsolicited.  only if there is no */
+        /* unsolicited callback for this message type do we assume the */
+        /* message is solicited.  it is much faster to check for an */
+        /* unsolicited callback, so doing this check first should result */
+        /* in better performance. */
+
+        ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
+            npeId, messageId, &callback);
+
+        if (callback != NULL)
+        {
+	    IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG,
+			     "Found matching unsolicited callback\n");
+
+            /* update statistical info */
+            ixNpeMhReceiveStats[npeId].unsolicited++;
+        }
+
+        /* if no unsolicited callback was found try to find a matching */
+        /* solicited callback for this message */
+        if (callback == NULL)
+        {
+            ixNpeMhSolicitedCbMgrCallbackRetrieve (
+                npeId, messageId, &callback);
+
+            if (callback != NULL)
+            {
+		IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG,
+				 "Found matching solicited callback\n");
+
+                /* update statistical info */
+                ixNpeMhReceiveStats[npeId].solicited++;
+            }
+        }
+
+        /* if a callback (either unsolicited or solicited) was found */
+        if (callback != NULL)
+        {
+            /* invoke the callback to pass the message back to the client */
+            callback (npeId, message);
+
+            /* update statistical info */
+            ixNpeMhReceiveStats[npeId].callbacks++;
+        }
+        else /* no callback (neither unsolicited nor solicited) was found */
+        {
+	    IX_NPEMH_TRACE2 (IX_NPEMH_WARNING,
+			     "No matching callback for NPE %d"
+			     " and ID 0x%02X, discarding message\n",
+			     npeId, messageId);
+
+            /* the message will be discarded.  this is normal behaviour */
+            /* if the client passes a NULL solicited callback when */
+            /* sending a message.  this indicates that the client is not */
+            /* interested in receiving the response.  alternatively a */
+            /* NULL callback here may signify an unsolicited message */
+            /* with no appropriate registered callback. */
+        }
+    }
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhReceiveMessagesReceive\n");
+    
+    return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhReceiveShow
+ */
+
+void ixNpeMhReceiveShow (
+    IxNpeMhNpeId npeId)
+{
+    /* show the ISR invocation counter */
+    IX_NPEMH_SHOW ("Receive ISR invocations",
+                   ixNpeMhReceiveStats[npeId].isrs);
+
+    /* show the receive message invocation counter */
+    IX_NPEMH_SHOW ("Receive messages invocations",
+                   ixNpeMhReceiveStats[npeId].receives);
+
+    /* show the message received counter */
+    IX_NPEMH_SHOW ("Messages received",
+                   ixNpeMhReceiveStats[npeId].messages);
+
+    /* show the solicited message counter */
+    IX_NPEMH_SHOW ("Solicited messages received",
+                   ixNpeMhReceiveStats[npeId].solicited);
+
+    /* show the unsolicited message counter */
+    IX_NPEMH_SHOW ("Unsolicited messages received",
+                   ixNpeMhReceiveStats[npeId].unsolicited);
+
+    /* show the callback invoked counter */
+    IX_NPEMH_SHOW ("Callbacks invoked",
+                   ixNpeMhReceiveStats[npeId].callbacks);
+
+    /* show the message discarded counter */
+    IX_NPEMH_SHOW ("Received messages discarded",
+                   (ixNpeMhReceiveStats[npeId].messages -
+                    ixNpeMhReceiveStats[npeId].callbacks));
+}
+
+/*
+ * Function definition: ixNpeMhReceiveShowReset
+ */
+
+void ixNpeMhReceiveShowReset (
+    IxNpeMhNpeId npeId)
+{
+    /* reset the ISR invocation counter */
+    ixNpeMhReceiveStats[npeId].isrs = 0;
+
+    /* reset the receive message invocation counter */
+    ixNpeMhReceiveStats[npeId].receives = 0;
+
+    /* reset the message received counter */
+    ixNpeMhReceiveStats[npeId].messages = 0;
+
+    /* reset the solicited message counter */
+    ixNpeMhReceiveStats[npeId].solicited = 0;
+
+    /* reset the unsolicited message counter */
+    ixNpeMhReceiveStats[npeId].unsolicited = 0;
+
+    /* reset the callback invoked counter */
+    ixNpeMhReceiveStats[npeId].callbacks = 0;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxNpeMhSend.c b/marvell/uboot/drivers/net/npe/IxNpeMhSend.c
new file mode 100644
index 0000000..8b70388
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxNpeMhSend.c
@@ -0,0 +1,283 @@
+/**
+ * @file IxNpeMhSend.c
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the implementation of the private API for the
+ * Send module.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Put the system defined include files required.
+ */
+
+
+/*
+ * Put the user defined include files required.
+ */
+
+#include "IxNpeMhMacros_p.h"
+
+#include "IxNpeMhConfig_p.h"
+#include "IxNpeMhSend_p.h"
+#include "IxNpeMhSolicitedCbMgr_p.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/**
+ * @def IX_NPEMH_INFIFO_RETRY_DELAY_US
+ *
+ * @brief Amount of time (uSecs) to delay between retries
+ * while inFIFO is Full when attempting to send a message
+ */
+#define IX_NPEMH_INFIFO_RETRY_DELAY_US (1)
+
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/**
+ * @struct IxNpeMhSendStats
+ *
+ * @brief This structure is used to maintain statistics for the Send
+ * module.
+ */
+
+typedef struct
+{
+    UINT32 sends;             /**< send invocations */
+    UINT32 sendWithResponses; /**< send with response invocations */
+    UINT32 queueFulls;        /**< fifo queue full occurrences */
+    UINT32 queueFullRetries;  /**< fifo queue full retry occurrences */
+    UINT32 maxQueueFullRetries; /**< max fifo queue full retries */
+    UINT32 callbackFulls;     /**< callback list full occurrences */
+} IxNpeMhSendStats;
+
+/*
+ * Variable declarations global to this file only.  Externs are followed by
+ * static variables.
+ */
+
+PRIVATE IxNpeMhSendStats ixNpeMhSendStats[IX_NPEMH_NUM_NPES];
+
+/*
+ * Extern function prototypes.
+ */
+
+/*
+ * Static function prototypes.
+ */
+PRIVATE
+BOOL ixNpeMhSendInFifoIsFull(
+    IxNpeMhNpeId npeId,
+    UINT32 maxSendRetries);
+
+/*
+ * Function definition: ixNpeMhSendInFifoIsFull
+ */
+
+PRIVATE
+BOOL ixNpeMhSendInFifoIsFull(
+    IxNpeMhNpeId npeId,
+    UINT32 maxSendRetries)
+{
+    BOOL isFull = false;
+    UINT32 numRetries = 0;
+
+    /* check the NPE's inFIFO */
+    isFull = ixNpeMhConfigInFifoIsFull (npeId);
+
+    /* we retry a few times, just to give the NPE a chance to read from */
+    /* the FIFO if the FIFO is currently full */
+    while (isFull && (numRetries++ < maxSendRetries))
+    {
+	if (numRetries >= IX_NPEMH_SEND_RETRIES_DEFAULT)
+	{
+	    /* Delay here for as short a time as possible (1 us). */
+	    /* Adding a delay here should ensure we are not hogging */
+	    /* the AHB bus while we are retrying                    */
+	    ixOsalBusySleep (IX_NPEMH_INFIFO_RETRY_DELAY_US);
+	}
+
+        /* re-check the NPE's inFIFO */
+        isFull = ixNpeMhConfigInFifoIsFull (npeId);
+
+        /* update statistical info */
+        ixNpeMhSendStats[npeId].queueFullRetries++;
+    }
+
+    /* record the highest number of retries that occurred */
+    if (ixNpeMhSendStats[npeId].maxQueueFullRetries < numRetries)
+    {
+	ixNpeMhSendStats[npeId].maxQueueFullRetries = numRetries;
+    }
+
+    if (isFull)
+    {
+        /* update statistical info */
+        ixNpeMhSendStats[npeId].queueFulls++;
+    }
+
+    return isFull;
+}
+
+/*
+ * Function definition: ixNpeMhSendMessageSend
+ */
+
+IX_STATUS ixNpeMhSendMessageSend (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessage message,
+    UINT32 maxSendRetries)
+{
+    IX_STATUS status;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhSendMessageSend\n");
+
+    /* update statistical info */
+    ixNpeMhSendStats[npeId].sends++;
+
+    /* check if the NPE's inFIFO is full - if so return an error */
+    if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries))
+    {
+        IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n");
+        return IX_FAIL;
+    }
+
+    /* write the message to the NPE's inFIFO */
+    status = ixNpeMhConfigInFifoWrite (npeId, message);
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhSendMessageSend\n");
+
+    return status;
+}
+
+/*
+ * Function definition: ixNpeMhSendMessageWithResponseSend
+ */
+
+IX_STATUS ixNpeMhSendMessageWithResponseSend (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessage message,
+    IxNpeMhMessageId solicitedMessageId,
+    IxNpeMhCallback solicitedCallback,
+    UINT32 maxSendRetries)
+{
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhSendMessageWithResponseSend\n");
+
+    /* update statistical info */
+    ixNpeMhSendStats[npeId].sendWithResponses++;
+
+    /* sr: this sleep will call the receive routine (no interrupts used!!!) */
+    ixOsalSleep (IX_NPEMH_INFIFO_RETRY_DELAY_US);
+
+    /* check if the NPE's inFIFO is full - if so return an error */
+    if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries))
+    {
+        IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n");
+        return IX_FAIL;
+    }
+
+    /* save the solicited callback */
+    status = ixNpeMhSolicitedCbMgrCallbackSave (
+        npeId, solicitedMessageId, solicitedCallback);
+    if (status != IX_SUCCESS)
+    {
+        IX_NPEMH_ERROR_REPORT ("Failed to save solicited callback\n");
+
+        /* update statistical info */
+        ixNpeMhSendStats[npeId].callbackFulls++;
+
+        return status;
+    }
+
+    /* write the message to the NPE's inFIFO */
+    status = ixNpeMhConfigInFifoWrite (npeId, message);
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhSendMessageWithResponseSend\n");
+
+    return status;
+}
+
+/*
+ * Function definition: ixNpeMhSendShow
+ */
+
+void ixNpeMhSendShow (
+    IxNpeMhNpeId npeId)
+{
+    /* show the message send invocation counter */
+    IX_NPEMH_SHOW ("Send invocations",
+                   ixNpeMhSendStats[npeId].sends);
+
+    /* show the message send with response invocation counter */
+    IX_NPEMH_SHOW ("Send with response invocations",
+                   ixNpeMhSendStats[npeId].sendWithResponses);
+
+    /* show the fifo queue full occurrence counter */
+    IX_NPEMH_SHOW ("Fifo queue full occurrences",
+                   ixNpeMhSendStats[npeId].queueFulls);
+
+    /* show the fifo queue full retry occurrence counter */
+    IX_NPEMH_SHOW ("Fifo queue full retry occurrences",
+                   ixNpeMhSendStats[npeId].queueFullRetries);
+
+    /* show the fifo queue full maximum retries counter */
+    IX_NPEMH_SHOW ("Maximum fifo queue full retries",
+                   ixNpeMhSendStats[npeId].maxQueueFullRetries);
+
+    /* show the callback list full occurrence counter */
+    IX_NPEMH_SHOW ("Solicited callback list full occurrences",
+                   ixNpeMhSendStats[npeId].callbackFulls);
+}
+
+/*
+ * Function definition: ixNpeMhSendShowReset
+ */
+
+void ixNpeMhSendShowReset (
+    IxNpeMhNpeId npeId)
+{
+    /* reset the message send invocation counter */
+    ixNpeMhSendStats[npeId].sends = 0;
+
+    /* reset the message send with response invocation counter */
+    ixNpeMhSendStats[npeId].sendWithResponses = 0;
+
+    /* reset the fifo queue full occurrence counter */
+    ixNpeMhSendStats[npeId].queueFulls = 0;
+
+    /* reset the fifo queue full retry occurrence counter */
+    ixNpeMhSendStats[npeId].queueFullRetries = 0;
+
+    /* reset the max fifo queue full retries counter */
+    ixNpeMhSendStats[npeId].maxQueueFullRetries = 0;
+
+    /* reset the callback list full occurrence counter */
+    ixNpeMhSendStats[npeId].callbackFulls = 0;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxNpeMhSolicitedCbMgr.c b/marvell/uboot/drivers/net/npe/IxNpeMhSolicitedCbMgr.c
new file mode 100644
index 0000000..c539d09
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxNpeMhSolicitedCbMgr.c
@@ -0,0 +1,334 @@
+/**
+ * @file IxNpeMhSolicitedCbMgr.c
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the implementation of the private API for the
+ * Solicited Callback Manager module.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+#ifndef IXNPEMHCONFIG_P_H
+#	define IXNPEMHSOLICITEDCBMGR_C
+#else
+#	error "Error, IxNpeMhConfig_p.h should not be included before this definition."
+#endif
+
+/*
+ * Put the system defined include files required.
+ */
+
+
+/*
+ * Put the user defined include files required.
+ */
+
+#include "IxOsal.h"
+
+#include "IxNpeMhMacros_p.h"
+#include "IxNpeMhSolicitedCbMgr_p.h"
+#include "IxNpeMhConfig_p.h"
+/*
+ * #defines and macros used in this file.
+ */
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/**
+ * @struct IxNpeMhSolicitedCallbackListEntry
+ *
+ * @brief This structure is used to store the information associated with
+ * an entry in the callback list.  This consists of the ID of the send
+ * message (which indicates the ID of the corresponding response message)
+ * and the callback function pointer itself.
+ *
+ */
+
+typedef struct IxNpeMhSolicitedCallbackListEntry
+{
+    /** message ID */
+    IxNpeMhMessageId messageId;
+
+    /** callback function pointer */
+    IxNpeMhCallback callback;
+
+    /** pointer to next entry in the list */
+    struct IxNpeMhSolicitedCallbackListEntry *next;
+} IxNpeMhSolicitedCallbackListEntry;
+
+/**
+ * @struct IxNpeMhSolicitedCallbackList
+ *
+ * @brief This structure is used to maintain the list of response
+ * callbacks.  The number of entries in this list will be variable, and
+ * they will be stored in a linked list fashion for ease of addition and
+ * removal.  The entries themselves are statically allocated, and are
+ * organised into a "free" list and a "callback" list.  Adding an entry
+ * means taking an entry from the "free" list and adding it to the
+ * "callback" list.  Removing an entry means removing it from the
+ * "callback" list and returning it to the "free" list.
+ */
+
+typedef struct
+{
+    /** pointer to the head of the free list */
+    IxNpeMhSolicitedCallbackListEntry *freeHead;
+
+    /** pointer to the head of the callback list */
+    IxNpeMhSolicitedCallbackListEntry *callbackHead;
+
+    /** pointer to the tail of the callback list */
+    IxNpeMhSolicitedCallbackListEntry *callbackTail;
+
+    /** array of entries - the first entry is used as a dummy entry to */
+    /* avoid the scenario of having an empty list, hence '+ 1' */
+    IxNpeMhSolicitedCallbackListEntry entries[IX_NPEMH_MAX_CALLBACKS + 1];
+} IxNpeMhSolicitedCallbackList;
+
+/**
+ * @struct IxNpeMhSolicitedCbMgrStats
+ *
+ * @brief This structure is used to maintain statistics for the Solicited
+ * Callback Manager module.
+ */
+
+typedef struct
+{
+    UINT32 saves;     /**< callback list saves */
+    UINT32 retrieves; /**< callback list retrieves */
+} IxNpeMhSolicitedCbMgrStats;
+
+/*
+ * Variable declarations global to this file only.  Externs are followed by
+ * static variables.
+ */
+
+PRIVATE IxNpeMhSolicitedCallbackList
+ixNpeMhSolicitedCbMgrCallbackLists[IX_NPEMH_NUM_NPES];
+
+PRIVATE IxNpeMhSolicitedCbMgrStats
+ixNpeMhSolicitedCbMgrStats[IX_NPEMH_NUM_NPES];
+
+/*
+ * Extern function prototypes.
+ */
+
+/*
+ * Static function prototypes.
+ */
+
+/*
+ * Function definition: ixNpeMhSolicitedCbMgrInitialize
+ */
+
+void ixNpeMhSolicitedCbMgrInitialize (void)
+{
+    IxNpeMhNpeId npeId;
+    UINT32 localIndex;
+    IxNpeMhSolicitedCallbackList *list = NULL;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhSolicitedCbMgrInitialize\n");
+
+    /* for each NPE ... */
+    for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
+    {
+        /* initialise a pointer to the list for convenience */
+        list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
+
+        /* for each entry in the list, after the dummy entry ... */
+        for (localIndex = 1; localIndex <= IX_NPEMH_MAX_CALLBACKS; localIndex++)
+        {
+            /* initialise the entry */
+            list->entries[localIndex].messageId = 0x00;
+            list->entries[localIndex].callback = NULL;
+
+            /* if this entry is before the last entry */
+            if (localIndex < IX_NPEMH_MAX_CALLBACKS)
+            {
+                /* chain this entry to the following entry */
+                list->entries[localIndex].next = &(list->entries[localIndex + 1]);
+            }
+            else /* this entry is the last entry */
+            {
+                /* the last entry isn't chained to anything */
+                list->entries[localIndex].next = NULL;
+            }
+        }
+
+        /* set the free list pointer to point to the first real entry */
+        /* (all real entries begin chained together on the free list) */
+        list->freeHead = &(list->entries[1]);
+
+        /* set the callback list pointers to point to the dummy entry */
+        /* (the callback list is initially empty) */
+        list->callbackHead = &(list->entries[0]);
+        list->callbackTail = &(list->entries[0]);
+    }
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhSolicitedCbMgrInitialize\n");
+}
+
+/*
+ * Function definition: ixNpeMhSolicitedCbMgrCallbackSave
+ */
+
+IX_STATUS ixNpeMhSolicitedCbMgrCallbackSave (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessageId solicitedMessageId,
+    IxNpeMhCallback solicitedCallback)
+{
+    IxNpeMhSolicitedCallbackList *list = NULL;
+    IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhSolicitedCbMgrCallbackSave\n");
+
+    /* initialise a pointer to the list for convenience */
+    list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
+
+    /* check to see if there are any entries in the free list */
+    if (list->freeHead == NULL)
+    {
+        IX_NPEMH_ERROR_REPORT ("Solicited callback list is full\n");
+        return IX_FAIL;
+    }
+
+    /* there is an entry in the free list we can use */
+
+    /* update statistical info */
+    ixNpeMhSolicitedCbMgrStats[npeId].saves++;
+
+    /* remove a callback entry from the start of the free list */
+    callbackEntry = list->freeHead;
+    list->freeHead = callbackEntry->next;
+
+    /* fill in the callback entry with the new data */
+    callbackEntry->messageId = solicitedMessageId;
+    callbackEntry->callback = solicitedCallback;
+
+    /* the new callback entry will be added to the tail of the callback */
+    /* list, so it isn't chained to anything */
+    callbackEntry->next = NULL;
+
+    /* chain new callback entry to the last entry of the callback list */
+    list->callbackTail->next = callbackEntry;
+    list->callbackTail = callbackEntry;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhSolicitedCbMgrCallbackSave\n");
+
+    return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixNpeMhSolicitedCbMgrCallbackRetrieve
+ */
+
+void ixNpeMhSolicitedCbMgrCallbackRetrieve (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessageId solicitedMessageId,
+    IxNpeMhCallback *solicitedCallback)
+{
+    IxNpeMhSolicitedCallbackList *list = NULL;
+    IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL;
+    IxNpeMhSolicitedCallbackListEntry *previousEntry = NULL;
+
+    /* initialise a pointer to the list for convenience */
+    list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
+
+    /* initialise the callback entry to the first entry of the callback */
+    /* list - we must skip over the dummy entry, which is the previous */
+    callbackEntry = list->callbackHead->next;
+    previousEntry = list->callbackHead;
+
+    /* traverse the callback list looking for an entry with a matching */
+    /* message ID.  note we also save the previous entry's pointer to */
+    /* allow us to unchain the matching entry from the callback list */
+    while ((callbackEntry != NULL) &&
+           (callbackEntry->messageId != solicitedMessageId))
+    {
+        previousEntry = callbackEntry;
+        callbackEntry = callbackEntry->next;
+    }
+
+    /* if we didn't find a matching callback entry */
+    if (callbackEntry == NULL)
+    {
+        /* return a NULL callback in the outgoing parameter */
+        *solicitedCallback = NULL;
+    }
+    else /* we found a matching callback entry */
+    {
+        /* update statistical info */
+        ixNpeMhSolicitedCbMgrStats[npeId].retrieves++;
+
+        /* return the callback in the outgoing parameter */
+        *solicitedCallback = callbackEntry->callback;
+
+        /* unchain callback entry by chaining previous entry to next */
+        previousEntry->next = callbackEntry->next;
+
+        /* if the callback entry is at the tail of the list */
+        if (list->callbackTail == callbackEntry)
+        {
+            /* update the tail of the callback list */
+            list->callbackTail = previousEntry;
+        }
+
+        /* re-initialise the callback entry */
+        callbackEntry->messageId = 0x00;
+        callbackEntry->callback = NULL;
+
+        /* add the callback entry to the start of the free list */
+        callbackEntry->next = list->freeHead;
+        list->freeHead = callbackEntry;
+    }
+}
+
+/*
+ * Function definition: ixNpeMhSolicitedCbMgrShow
+ */
+
+void ixNpeMhSolicitedCbMgrShow (
+    IxNpeMhNpeId npeId)
+{
+    /* show the solicited callback list save counter */
+    IX_NPEMH_SHOW ("Solicited callback list saves",
+                   ixNpeMhSolicitedCbMgrStats[npeId].saves);
+
+    /* show the solicited callback list retrieve counter */
+    IX_NPEMH_SHOW ("Solicited callback list retrieves",
+                   ixNpeMhSolicitedCbMgrStats[npeId].retrieves);
+}
+
+/*
+ * Function definition: ixNpeMhSolicitedCbMgrShowReset
+ */
+
+void ixNpeMhSolicitedCbMgrShowReset (
+    IxNpeMhNpeId npeId)
+{
+    /* reset the solicited callback list save counter */
+    ixNpeMhSolicitedCbMgrStats[npeId].saves = 0;
+
+    /* reset the solicited callback list retrieve counter */
+    ixNpeMhSolicitedCbMgrStats[npeId].retrieves = 0;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxNpeMhUnsolicitedCbMgr.c b/marvell/uboot/drivers/net/npe/IxNpeMhUnsolicitedCbMgr.c
new file mode 100644
index 0000000..082f677
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxNpeMhUnsolicitedCbMgr.c
@@ -0,0 +1,222 @@
+/**
+ * @file IxNpeMhUnsolicitedCbMgr.c
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the implementation of the private API for
+ * the Unsolicited Callback Manager module.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Put the system defined include files required.
+ */
+
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxOsal.h"
+
+#include "IxNpeMhMacros_p.h"
+
+#include "IxNpeMhUnsolicitedCbMgr_p.h"
+
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/**
+ * @struct IxNpeMhUnsolicitedCallbackTable
+ *
+ * @brief This structure is used to maintain the list of registered
+ * callbacks.  One entry exists for each message ID, and a NULL entry will
+ * signify that no callback has been registered for that ID.
+ */
+
+typedef struct
+{
+    /** array of entries */
+    IxNpeMhCallback entries[IX_NPEMH_MAX_MESSAGE_ID + 1];
+} IxNpeMhUnsolicitedCallbackTable;
+
+/**
+ * @struct IxNpeMhUnsolicitedCbMgrStats
+ *
+ * @brief This structure is used to maintain statistics for the Unsolicited
+ * Callback Manager module.
+ */
+
+typedef struct
+{
+    UINT32 saves;      /**< callback table saves */
+    UINT32 overwrites; /**< callback table overwrites */
+} IxNpeMhUnsolicitedCbMgrStats;
+
+/*
+ * Variable declarations global to this file only.  Externs are followed by
+ * static variables.
+ */
+
+PRIVATE IxNpeMhUnsolicitedCallbackTable
+ixNpeMhUnsolicitedCallbackTables[IX_NPEMH_NUM_NPES];
+
+PRIVATE IxNpeMhUnsolicitedCbMgrStats
+ixNpeMhUnsolicitedCbMgrStats[IX_NPEMH_NUM_NPES];
+
+/*
+ * Extern function prototypes.
+ */
+
+/*
+ * Static function prototypes.
+ */
+
+/*
+ * Function definition: ixNpeMhUnsolicitedCbMgrInitialize
+ */
+
+void ixNpeMhUnsolicitedCbMgrInitialize (void)
+{
+    IxNpeMhNpeId npeId = 0;
+    IxNpeMhUnsolicitedCallbackTable *table = NULL;
+    IxNpeMhMessageId messageId = 0;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhUnsolicitedCbMgrInitialize\n");
+
+    /* for each NPE ... */
+    for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
+    {
+        /* initialise a pointer to the table for convenience */
+        table = &ixNpeMhUnsolicitedCallbackTables[npeId];
+
+        /* for each message ID ... */
+        for (messageId = IX_NPEMH_MIN_MESSAGE_ID;
+             messageId <= IX_NPEMH_MAX_MESSAGE_ID; messageId++)
+        {
+            /* initialise the callback for this message ID to NULL */
+            table->entries[messageId] = NULL;
+        }
+    }
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhUnsolicitedCbMgrInitialize\n");
+}
+
+/*
+ * Function definition: ixNpeMhUnsolicitedCbMgrCallbackSave
+ */
+
+void ixNpeMhUnsolicitedCbMgrCallbackSave (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessageId unsolicitedMessageId,
+    IxNpeMhCallback unsolicitedCallback)
+{
+    IxNpeMhUnsolicitedCallbackTable *table = NULL;
+
+    /* initialise a pointer to the table for convenience */
+    table = &ixNpeMhUnsolicitedCallbackTables[npeId];
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
+                     "ixNpeMhUnsolicitedCbMgrCallbackSave\n");
+
+    /* update statistical info */
+    ixNpeMhUnsolicitedCbMgrStats[npeId].saves++;
+
+    /* check if there is a callback already registered for this NPE and */
+    /* message ID */
+    if (table->entries[unsolicitedMessageId] != NULL)
+    {
+	/* if we are overwriting an existing callback */
+	if (unsolicitedCallback != NULL)
+	{
+	    IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "Unsolicited callback "
+			     "overwriting existing callback for NPE ID %d "
+			     "message ID 0x%02X\n", npeId, unsolicitedMessageId);
+	}
+	else /* if we are clearing an existing callback */
+	{
+	    IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NULL unsolicited callback "
+			     "clearing existing callback for NPE ID %d "
+			     "message ID 0x%02X\n", npeId, unsolicitedMessageId);
+	}
+
+        /* update statistical info */
+        ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites++;
+    }
+
+    /* save the callback into the table */
+    table->entries[unsolicitedMessageId] = unsolicitedCallback;
+
+    IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
+                     "ixNpeMhUnsolicitedCbMgrCallbackSave\n");
+}
+
+/*
+ * Function definition: ixNpeMhUnsolicitedCbMgrCallbackRetrieve
+ */
+
+void ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessageId unsolicitedMessageId,
+    IxNpeMhCallback *unsolicitedCallback)
+{
+    IxNpeMhUnsolicitedCallbackTable *table = NULL;
+
+    /* initialise a pointer to the table for convenience */
+    table = &ixNpeMhUnsolicitedCallbackTables[npeId];
+
+    /* retrieve the callback from the table */
+    *unsolicitedCallback = table->entries[unsolicitedMessageId];
+}
+
+/*
+ * Function definition: ixNpeMhUnsolicitedCbMgrShow
+ */
+
+void ixNpeMhUnsolicitedCbMgrShow (
+    IxNpeMhNpeId npeId)
+{
+    /* show the unsolicited callback table save counter */
+    IX_NPEMH_SHOW ("Unsolicited callback table saves",
+                   ixNpeMhUnsolicitedCbMgrStats[npeId].saves);
+
+    /* show the unsolicited callback table overwrite counter */
+    IX_NPEMH_SHOW ("Unsolicited callback table overwrites",
+                   ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites);
+}
+
+/*
+ * Function definition: ixNpeMhUnsolicitedCbMgrShowReset
+ */
+
+void ixNpeMhUnsolicitedCbMgrShowReset (
+    IxNpeMhNpeId npeId)
+{
+    /* reset the unsolicited callback table save counter */
+    ixNpeMhUnsolicitedCbMgrStats[npeId].saves = 0;
+
+    /* reset the unsolicited callback table overwrite counter */
+    ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites = 0;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxOsalBufferMgt.c b/marvell/uboot/drivers/net/npe/IxOsalBufferMgt.c
new file mode 100644
index 0000000..f70ba05
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxOsalBufferMgt.c
@@ -0,0 +1,776 @@
+/**
+ * @file IxOsalBufferMgt.c
+ *
+ * @brief Default buffer pool management and buffer management
+ *        Implementation.
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/*
+ * OS may choose to use default bufferMgt by defining
+ * IX_OSAL_USE_DEFAULT_BUFFER_MGT in IxOsalOsBufferMgt.h  
+ */
+
+#include "IxOsal.h"
+
+#define IX_OSAL_BUFFER_FREE_PROTECTION  /* Define this to enable Illegal MBuf Freed Protection*/
+
+/*
+ * The implementation is only used when the following
+ * is defined.
+ */
+#ifdef IX_OSAL_USE_DEFAULT_BUFFER_MGT
+
+
+#define IX_OSAL_MBUF_SYS_SIGNATURE				(0x8BADF00D)
+#define IX_OSAL_MBUF_SYS_SIGNATURE_MASK				(0xEFFFFFFF)
+#define IX_OSAL_MBUF_USED_FLAG					(0x10000000)
+#define IX_OSAL_MBUF_SYS_SIGNATURE_INIT(bufPtr)        		IX_OSAL_MBUF_SIGNATURE (bufPtr) = (UINT32)IX_OSAL_MBUF_SYS_SIGNATURE
+
+/* 
+*  This implementation is protect, the buffer pool management's  ixOsalMBufFree 
+*  against an invalid MBUF pointer argument that already has been freed earlier 
+*  or in other words resides in the free pool of MBUFs. This added feature, 
+*  checks the MBUF "USED" FLAG. The Flag tells if the MBUF is still not freed 
+*  back to the Buffer Pool.
+*  Disable this feature for performance reasons by undef 
+*  IX_OSAL_BUFFER_FREE_PROTECTION macro.
+*/
+#ifdef IX_OSAL_BUFFER_FREE_PROTECTION  /*IX_OSAL_BUFFER_FREE_PROTECTION With Buffer Free protection*/
+
+#define IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr)		(IX_OSAL_MBUF_SIGNATURE (bufPtr)&(IX_OSAL_MBUF_SYS_SIGNATURE_MASK) )
+#define IX_OSAL_MBUF_SET_SYS_SIGNATURE(bufPtr)    do {																											\
+																									IX_OSAL_MBUF_SIGNATURE (bufPtr)&(~IX_OSAL_MBUF_SYS_SIGNATURE_MASK);\
+														    									IX_OSAL_MBUF_SIGNATURE (bufPtr)|=IX_OSAL_MBUF_SYS_SIGNATURE;			\
+																									}while(0)
+
+#define IX_OSAL_MBUF_SET_USED_FLAG(bufPtr)   IX_OSAL_MBUF_SIGNATURE (bufPtr)|=IX_OSAL_MBUF_USED_FLAG
+#define IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)&=~IX_OSAL_MBUF_USED_FLAG
+#define IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr) (IX_OSAL_MBUF_SIGNATURE (bufPtr)&IX_OSAL_MBUF_USED_FLAG)
+
+#else
+
+#define IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr)	 IX_OSAL_MBUF_SIGNATURE (bufPtr)
+#define IX_OSAL_MBUF_SET_SYS_SIGNATURE(bufPtr)   IX_OSAL_MBUF_SIGNATURE (bufPtr) = IX_OSAL_MBUF_SYS_SIGNATURE
+
+#endif /*IX_OSAL_BUFFER_FREE_PROTECTION With Buffer Free protection*/
+/*
+ * Variable declarations global to this file only.  Externs are followed by
+ * static variables.
+ */
+
+/* 
+ * A unit of 32, used to provide bit-shift for pool
+ * management. Needs some work if users want more than 32 pools.
+ */
+#define IX_OSAL_BUFF_FREE_BITS 32
+
+PRIVATE UINT32 ixOsalBuffFreePools[IX_OSAL_MBUF_MAX_POOLS /
+    IX_OSAL_BUFF_FREE_BITS];
+
+PUBLIC IX_OSAL_MBUF_POOL ixOsalBuffPools[IX_OSAL_MBUF_MAX_POOLS];
+
+static int ixOsalBuffPoolsInUse = 0;
+
+#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
+PRIVATE IX_OSAL_MBUF *
+ixOsalBuffPoolMbufInit (UINT32 mbufSizeAligned,
+                      UINT32 dataSizeAligned,
+                      IX_OSAL_MBUF_POOL *poolPtr);
+#endif
+
+PRIVATE IX_OSAL_MBUF_POOL * ixOsalPoolAlloc (void);                      
+
+/*
+ * Function definition: ixOsalPoolAlloc
+ */
+
+/****************************/
+
+PRIVATE IX_OSAL_MBUF_POOL *
+ixOsalPoolAlloc (void)
+{
+    register unsigned int i = 0;
+
+    /*
+     * Scan for the first free buffer. Free buffers are indicated by 0
+     * on the corrsponding bit in ixOsalBuffFreePools. 
+     */
+    if (ixOsalBuffPoolsInUse >= IX_OSAL_MBUF_MAX_POOLS)
+    {
+        /*
+         * Fail to grab a ptr this time 
+         */
+        return NULL;
+    }
+
+    while (ixOsalBuffFreePools[i / IX_OSAL_BUFF_FREE_BITS] &
+        (1 << (i % IX_OSAL_BUFF_FREE_BITS)))
+        i++;
+    /*
+     * Free buffer found. Mark it as busy and initialize. 
+     */
+    ixOsalBuffFreePools[i / IX_OSAL_BUFF_FREE_BITS] |=
+        (1 << (i % IX_OSAL_BUFF_FREE_BITS));
+
+    memset (&ixOsalBuffPools[i], 0, sizeof (IX_OSAL_MBUF_POOL));
+
+    ixOsalBuffPools[i].poolIdx = i;
+    ixOsalBuffPoolsInUse++;
+
+    return &ixOsalBuffPools[i];
+}
+
+
+#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
+PRIVATE IX_OSAL_MBUF *
+ixOsalBuffPoolMbufInit (UINT32 mbufSizeAligned,
+                      UINT32 dataSizeAligned,
+                      IX_OSAL_MBUF_POOL *poolPtr)
+{
+    UINT8 *dataPtr;
+    IX_OSAL_MBUF *realMbufPtr;
+    /* Allocate cache-aligned memory for mbuf header */
+    realMbufPtr = (IX_OSAL_MBUF *) IX_OSAL_CACHE_DMA_MALLOC (mbufSizeAligned);
+    IX_OSAL_ASSERT (realMbufPtr != NULL);
+    memset (realMbufPtr, 0, mbufSizeAligned);
+
+    /* Allocate cache-aligned memory for mbuf data */
+    dataPtr = (UINT8 *) IX_OSAL_CACHE_DMA_MALLOC (dataSizeAligned);
+    IX_OSAL_ASSERT (dataPtr != NULL);
+    memset (dataPtr, 0, dataSizeAligned);
+
+    /* Fill in mbuf header fields */
+    IX_OSAL_MBUF_MDATA (realMbufPtr) = dataPtr;
+    IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (realMbufPtr) = (UINT32)dataPtr;
+
+    IX_OSAL_MBUF_MLEN (realMbufPtr) = dataSizeAligned;
+    IX_OSAL_MBUF_ALLOCATED_BUFF_LEN (realMbufPtr) = dataSizeAligned;
+
+    IX_OSAL_MBUF_NET_POOL (realMbufPtr) = (IX_OSAL_MBUF_POOL *) poolPtr;
+
+    IX_OSAL_MBUF_SYS_SIGNATURE_INIT(realMbufPtr);
+
+    /* update some statistical information */
+    poolPtr->mbufMemSize += mbufSizeAligned;
+    poolPtr->dataMemSize += dataSizeAligned;
+
+    return realMbufPtr;
+}
+#endif /* #ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY */
+
+/*
+ * Function definition: ixOsalBuffPoolInit
+ */
+
+PUBLIC IX_OSAL_MBUF_POOL *
+ixOsalPoolInit (UINT32 count, UINT32 size, const char *name)
+{
+
+    /* These variables are only used if UX_OSAL_BUFFER_ALLOC_SEPERATELY
+     * is defined .
+     */
+#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
+    UINT32 i, mbufSizeAligned, dataSizeAligned;
+    IX_OSAL_MBUF *currentMbufPtr = NULL;
+#else
+    void *poolBufPtr;
+    void *poolDataPtr;
+    int mbufMemSize;
+    int dataMemSize;
+#endif
+
+    IX_OSAL_MBUF_POOL *poolPtr = NULL;
+    
+    if (count <= 0)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalPoolInit(): " "count = 0 \n", 0, 0, 0, 0, 0, 0);
+        return NULL;        
+    }
+
+    if (name == NULL)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalPoolInit(): " "NULL name \n", 0, 0, 0, 0, 0, 0);
+        return NULL;        
+    }
+    
+    if (strlen (name) > IX_OSAL_MBUF_POOL_NAME_LEN)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalPoolInit(): "
+            "ERROR - name length should be no greater than %d  \n",
+            IX_OSAL_MBUF_POOL_NAME_LEN, 0, 0, 0, 0, 0);
+        return NULL;
+    }
+
+/* OS can choose whether to allocate all buffers all together (if it 
+ * can handle a huge single alloc request), or to allocate buffers 
+ * separately by the defining IX_OSAL_BUFFER_ALLOC_SEPARATELY.
+ */
+#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
+    /* Get a pool Ptr */
+    poolPtr = ixOsalPoolAlloc ();
+
+    if (poolPtr == NULL)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalPoolInit(): " "Fail to Get PoolPtr \n", 0, 0, 0, 0, 0, 0);    
+        return NULL;
+    }
+
+    mbufSizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
+    dataSizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN(size);
+
+    poolPtr->nextFreeBuf = NULL;    
+    poolPtr->mbufMemPtr = NULL;    
+    poolPtr->dataMemPtr = NULL;
+    poolPtr->bufDataSize = dataSizeAligned;
+    poolPtr->totalBufsInPool = count;
+    poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC;
+    strcpy (poolPtr->name, name);
+
+
+    for (i = 0; i < count; i++)
+    {
+	    /* create an mbuf */
+	    currentMbufPtr = ixOsalBuffPoolMbufInit (mbufSizeAligned,
+					         dataSizeAligned,
+					         poolPtr);
+
+#ifdef IX_OSAL_BUFFER_FREE_PROTECTION 		
+/* Set the Buffer USED Flag. If not, ixOsalMBufFree will fail.
+   ixOsalMbufFree used here is in a special case whereby, it's 
+   used to add MBUF to the Pool. By specification, ixOsalMbufFree 
+   deallocates an allocated MBUF from Pool.
+*/ 			         
+      IX_OSAL_MBUF_SET_USED_FLAG(currentMbufPtr);
+#endif                             
+	    /* Add it to the pool */
+	    ixOsalMbufFree (currentMbufPtr);
+
+	    /* flush the pool information to RAM */
+	    IX_OSAL_CACHE_FLUSH (currentMbufPtr, mbufSizeAligned);
+    }
+    
+    /*
+     * update the number of free buffers in the pool 
+     */
+    poolPtr->freeBufsInPool = count;
+
+#else 
+/* Otherwise allocate buffers in a continuous block fashion */    
+    poolBufPtr = IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC (count, mbufMemSize);
+    IX_OSAL_ASSERT (poolBufPtr != NULL);
+    poolDataPtr =
+        IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC (count, size, dataMemSize);
+    IX_OSAL_ASSERT (poolDataPtr != NULL);
+
+    poolPtr = ixOsalNoAllocPoolInit (poolBufPtr, poolDataPtr,
+        count, size, name);
+    if (poolPtr == NULL)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalPoolInit(): " "Fail to get pool ptr \n", 0, 0, 0, 0, 0, 0);
+        return NULL;
+    }
+
+    poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC;
+
+#endif /* IX_OSAL_BUFFER_ALLOC_SEPARATELY */
+    return poolPtr;
+}
+
+PUBLIC IX_OSAL_MBUF_POOL *
+ixOsalNoAllocPoolInit (void *poolBufPtr,
+    void *poolDataPtr, UINT32 count, UINT32 size, const char *name)
+{
+    UINT32 i,  mbufSizeAligned, sizeAligned;
+    IX_OSAL_MBUF *currentMbufPtr = NULL;
+    IX_OSAL_MBUF *nextMbufPtr = NULL;
+    IX_OSAL_MBUF_POOL *poolPtr = NULL;
+
+    /*
+     * check parameters 
+     */
+    if (poolBufPtr == NULL)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalNoAllocPoolInit(): "
+            "ERROR - NULL poolBufPtr \n", 0, 0, 0, 0, 0, 0);
+        return NULL;
+    }
+
+    if (count <= 0)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalNoAllocPoolInit(): "
+            "ERROR - count must > 0   \n", 0, 0, 0, 0, 0, 0);
+        return NULL;
+    }
+
+    if (name == NULL)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalNoAllocPoolInit(): "
+            "ERROR - NULL name ptr  \n", 0, 0, 0, 0, 0, 0);
+        return NULL;
+    }
+
+    if (strlen (name) > IX_OSAL_MBUF_POOL_NAME_LEN)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalNoAllocPoolInit(): "
+            "ERROR - name length should be no greater than %d  \n",
+            IX_OSAL_MBUF_POOL_NAME_LEN, 0, 0, 0, 0, 0);
+        return NULL;
+    }
+
+    poolPtr = ixOsalPoolAlloc ();
+
+    if (poolPtr == NULL)
+    {
+        return NULL;
+    }
+
+    /*
+     * Adjust sizes to ensure alignment on cache line boundaries 
+     */
+    mbufSizeAligned =
+        IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
+    /*
+     * clear the mbuf memory area 
+     */
+    memset (poolBufPtr, 0, mbufSizeAligned * count);
+
+    if (poolDataPtr != NULL)
+    {
+        /*
+         * Adjust sizes to ensure alignment on cache line boundaries 
+         */
+        sizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN (size);
+        /*
+         * clear the data memory area 
+         */
+        memset (poolDataPtr, 0, sizeAligned * count);
+    }
+    else
+    {
+        sizeAligned = 0;
+    }
+
+    /*
+     * initialise pool fields 
+     */
+    strcpy ((poolPtr)->name, name);
+
+    poolPtr->dataMemPtr = poolDataPtr;
+    poolPtr->mbufMemPtr = poolBufPtr;
+    poolPtr->bufDataSize = sizeAligned;
+    poolPtr->totalBufsInPool = count;
+    poolPtr->mbufMemSize = mbufSizeAligned * count;
+    poolPtr->dataMemSize = sizeAligned * count;
+
+    currentMbufPtr = (IX_OSAL_MBUF *) poolBufPtr;
+
+    poolPtr->nextFreeBuf = currentMbufPtr;
+
+    for (i = 0; i < count; i++)
+    {
+        if (i < (count - 1))
+        {
+            nextMbufPtr =
+                (IX_OSAL_MBUF *) ((unsigned) currentMbufPtr +
+                mbufSizeAligned);
+        }
+        else
+        {                       /* last mbuf in chain */
+            nextMbufPtr = NULL;
+        }
+        IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (currentMbufPtr) = nextMbufPtr;
+        IX_OSAL_MBUF_NET_POOL (currentMbufPtr) = poolPtr;
+
+        IX_OSAL_MBUF_SYS_SIGNATURE_INIT(currentMbufPtr);
+
+        if (poolDataPtr != NULL)
+        {
+            IX_OSAL_MBUF_MDATA (currentMbufPtr) = poolDataPtr;
+            IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(currentMbufPtr) = (UINT32) poolDataPtr;
+
+            IX_OSAL_MBUF_MLEN (currentMbufPtr) = sizeAligned;
+            IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(currentMbufPtr) = sizeAligned;
+
+            poolDataPtr = (void *) ((unsigned) poolDataPtr + sizeAligned);
+        }
+
+        currentMbufPtr = nextMbufPtr;
+    }
+
+    /*
+     * update the number of free buffers in the pool 
+     */
+    poolPtr->freeBufsInPool = count;
+
+    poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC;
+
+    return poolPtr;
+}
+
+/* 
+ * Get a mbuf ptr from the pool
+ */
+PUBLIC IX_OSAL_MBUF *
+ixOsalMbufAlloc (IX_OSAL_MBUF_POOL * poolPtr)
+{
+    int lock;
+    IX_OSAL_MBUF *newBufPtr = NULL;
+
+    /*
+     * check parameters 
+     */
+    if (poolPtr == NULL)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalMbufAlloc(): "
+            "ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
+        return NULL;
+    }
+
+    lock = ixOsalIrqLock ();
+
+    newBufPtr = poolPtr->nextFreeBuf;
+    if (newBufPtr)
+    {
+        poolPtr->nextFreeBuf =
+            IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (newBufPtr);
+        IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (newBufPtr) = NULL;
+
+        /*
+         * update the number of free buffers in the pool 
+         */
+        poolPtr->freeBufsInPool--;
+    }
+    else
+    {
+        /* Return NULL to indicate to caller that request is denied. */
+        ixOsalIrqUnlock (lock);
+
+        return NULL;
+    }
+
+#ifdef IX_OSAL_BUFFER_FREE_PROTECTION
+	/* Set Buffer Used Flag to indicate state.*/
+    IX_OSAL_MBUF_SET_USED_FLAG(newBufPtr);
+#endif
+
+    ixOsalIrqUnlock (lock);
+
+    return newBufPtr;
+}
+
+PUBLIC IX_OSAL_MBUF *
+ixOsalMbufFree (IX_OSAL_MBUF * bufPtr)
+{
+    int lock;
+    IX_OSAL_MBUF_POOL *poolPtr;
+
+    IX_OSAL_MBUF *nextBufPtr = NULL;
+
+    /*
+     * check parameters 
+     */
+    if (bufPtr == NULL)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalMbufFree(): "
+            "ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
+        return NULL;
+    }
+
+
+
+    lock = ixOsalIrqLock ();
+
+#ifdef IX_OSAL_BUFFER_FREE_PROTECTION
+	
+	/* Prevention for Buffer freed more than once*/
+    if(!IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr))
+    {
+   	return NULL;
+    }
+    IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr);
+#endif
+	
+    poolPtr = IX_OSAL_MBUF_NET_POOL (bufPtr);
+
+    /*
+     * check the mbuf wrapper signature (if mbuf wrapper was used) 
+     */
+    if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
+    {
+        IX_OSAL_ENSURE ( (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) == IX_OSAL_MBUF_SYS_SIGNATURE),
+            "ixOsalBuffPoolBufFree: ERROR - Invalid mbuf signature.");
+    }
+
+    nextBufPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr);
+
+    IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr) = poolPtr->nextFreeBuf;
+    poolPtr->nextFreeBuf = bufPtr;
+
+    /*
+     * update the number of free buffers in the pool 
+     */
+    poolPtr->freeBufsInPool++;
+
+    ixOsalIrqUnlock (lock);
+
+    return nextBufPtr;
+}
+
+PUBLIC void
+ixOsalMbufChainFree (IX_OSAL_MBUF * bufPtr)
+{
+    while ((bufPtr = ixOsalMbufFree (bufPtr)));
+}
+
+/*
+ * Function definition: ixOsalBuffPoolShow
+ */
+PUBLIC void
+ixOsalMbufPoolShow (IX_OSAL_MBUF_POOL * poolPtr)
+{
+    IX_OSAL_MBUF *nextBufPtr;
+    int count = 0;
+    int lock;
+
+    /*
+     * check parameters 
+     */
+    if (poolPtr == NULL)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalBuffPoolShow(): "
+            "ERROR - Invalid Parameter", 0, 0, 0, 0, 0, 0);
+        /*
+         * return IX_FAIL; 
+         */
+        return;
+    }
+
+    lock = ixOsalIrqLock ();
+    count = poolPtr->freeBufsInPool;
+    nextBufPtr = poolPtr->nextFreeBuf;
+    ixOsalIrqUnlock (lock);
+
+    ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,
+        IX_OSAL_LOG_DEV_STDOUT, "=== POOL INFORMATION ===\n", 0, 0, 0,
+        0, 0, 0);
+    ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+        "Pool Name:                   %s\n",
+        (unsigned int) poolPtr->name, 0, 0, 0, 0, 0);
+    ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+        "Pool Allocation Type:        %d\n",
+        (unsigned int) poolPtr->poolAllocType, 0, 0, 0, 0, 0);
+    ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+        "Pool Mbuf Mem Usage (bytes): %d\n",
+        (unsigned int) poolPtr->mbufMemSize, 0, 0, 0, 0, 0);
+    ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+        "Pool Data Mem Usage (bytes): %d\n",
+        (unsigned int) poolPtr->dataMemSize, 0, 0, 0, 0, 0);
+    ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+        "Mbuf Data Capacity  (bytes): %d\n",
+        (unsigned int) poolPtr->bufDataSize, 0, 0, 0, 0, 0);
+    ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+        "Total Mbufs in Pool:         %d\n",
+        (unsigned int) poolPtr->totalBufsInPool, 0, 0, 0, 0, 0);
+    ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+        "Available Mbufs:             %d\n", (unsigned int) count, 0,
+        0, 0, 0, 0);
+    ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+        "Next Available Mbuf:         %p\n", (unsigned int) nextBufPtr,
+        0, 0, 0, 0, 0);
+
+    if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "Mbuf Mem Area Start address: %p\n",
+            (unsigned int) poolPtr->mbufMemPtr, 0, 0, 0, 0, 0);
+        ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
+            "Data Mem Area Start address: %p\n",
+            (unsigned int) poolPtr->dataMemPtr, 0, 0, 0, 0, 0);
+    }
+}
+
+PUBLIC void
+ixOsalMbufDataPtrReset (IX_OSAL_MBUF * bufPtr)
+{
+    IX_OSAL_MBUF_POOL *poolPtr;
+    UINT8 *poolDataPtr;
+
+    if (bufPtr == NULL)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalBuffPoolBufDataPtrReset"
+            ": ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
+        return;
+    }
+
+    poolPtr = (IX_OSAL_MBUF_POOL *) IX_OSAL_MBUF_NET_POOL (bufPtr);
+    poolDataPtr = poolPtr->dataMemPtr;
+
+    if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
+    {
+        if (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) != IX_OSAL_MBUF_SYS_SIGNATURE)
+        {
+            ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
+                "ixOsalBuffPoolBufDataPtrReset"
+                ": invalid mbuf, cannot reset mData pointer\n", 0, 0,
+                0, 0, 0, 0);
+            return;
+        }
+        IX_OSAL_MBUF_MDATA (bufPtr) = (UINT8*)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (bufPtr);
+    }
+    else
+    {
+        if (poolDataPtr)
+        {
+            unsigned int bufSize = poolPtr->bufDataSize;
+            unsigned int bufDataAddr =
+                (unsigned int) IX_OSAL_MBUF_MDATA (bufPtr);
+            unsigned int poolDataAddr = (unsigned int) poolDataPtr;
+
+            /*
+             * the pointer is still pointing somewhere in the mbuf payload.
+             * This operation moves the pointer to the beginning of the 
+             * mbuf payload
+             */
+            bufDataAddr = ((bufDataAddr - poolDataAddr) / bufSize) * bufSize;
+            IX_OSAL_MBUF_MDATA (bufPtr) = &poolDataPtr[bufDataAddr];
+        }
+        else
+        {
+            ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT,
+                "ixOsalBuffPoolBufDataPtrReset"
+                ": cannot be used if user supplied NULL pointer for pool data area "
+                "when pool was created\n", 0, 0, 0, 0, 0, 0);
+            return;
+        }
+    }
+
+}
+
+/*
+ * Function definition: ixOsalBuffPoolUninit
+ */
+PUBLIC IX_STATUS
+ixOsalBuffPoolUninit (IX_OSAL_MBUF_POOL * pool)
+{
+    if (!pool)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalBuffPoolUninit: NULL ptr \n", 0, 0, 0, 0, 0, 0);
+        return IX_FAIL;
+    }
+
+    if (pool->freeBufsInPool != pool->totalBufsInPool)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalBuffPoolUninit: need to return all ptrs to the pool first! \n",
+            0, 0, 0, 0, 0, 0);
+        return IX_FAIL;
+    }
+
+    if (pool->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
+    {
+#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
+				UINT32 i;
+				IX_OSAL_MBUF* pBuf;
+				
+				pBuf = pool->nextFreeBuf;
+				/* Freed the Buffer one by one till all the Memory is freed*/
+				for (i= pool->freeBufsInPool; i >0 && pBuf!=NULL ;i--){
+						IX_OSAL_MBUF* pBufTemp;
+						pBufTemp = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(pBuf);
+						/* Freed MBUF Data Memory area*/
+						IX_OSAL_CACHE_DMA_FREE( (void *) (IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(pBuf)) );
+						/* Freed MBUF Struct Memory area*/
+						IX_OSAL_CACHE_DMA_FREE(pBuf);
+						pBuf = pBufTemp;
+				}
+				
+#else    	
+        IX_OSAL_CACHE_DMA_FREE (pool->mbufMemPtr);
+        IX_OSAL_CACHE_DMA_FREE (pool->dataMemPtr);
+#endif        
+    }
+
+    ixOsalBuffFreePools[pool->poolIdx / IX_OSAL_BUFF_FREE_BITS] &=
+        ~(1 << (pool->poolIdx % IX_OSAL_BUFF_FREE_BITS));
+    ixOsalBuffPoolsInUse--;
+    return IX_SUCCESS;
+}
+
+/*
+ * Function definition: ixOsalBuffPoolDataAreaSizeGet
+ */
+PUBLIC UINT32
+ixOsalBuffPoolDataAreaSizeGet (int count, int size)
+{
+    UINT32 memorySize;
+    memorySize = count * IX_OSAL_MBUF_POOL_SIZE_ALIGN (size);
+    return memorySize;
+}
+
+/*
+ * Function definition: ixOsalBuffPoolMbufAreaSizeGet
+ */
+PUBLIC UINT32
+ixOsalBuffPoolMbufAreaSizeGet (int count)
+{
+    UINT32 memorySize;
+    memorySize =
+        count * IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
+    return memorySize;
+}
+
+/*
+ * Function definition: ixOsalBuffPoolFreeCountGet
+ */
+PUBLIC UINT32 ixOsalBuffPoolFreeCountGet(IX_OSAL_MBUF_POOL * poolPtr)
+
+{
+
+   return poolPtr->freeBufsInPool;
+
+}
+
+#endif /* IX_OSAL_USE_DEFAULT_BUFFER_MGT */
diff --git a/marvell/uboot/drivers/net/npe/IxOsalIoMem.c b/marvell/uboot/drivers/net/npe/IxOsalIoMem.c
new file mode 100644
index 0000000..bf3acdc
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxOsalIoMem.c
@@ -0,0 +1,307 @@
+/**
+ * @file IxOsalIoMem.c 
+ *
+ * @brief OS-independent IO/Mem implementation 
+ * 
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/* Access to the global mem map is only allowed in this file */
+#define IxOsalIoMem_C
+
+#include "IxOsal.h"
+
+#define SEARCH_PHYSICAL_ADDRESS (1)
+#define SEARCH_VIRTUAL_ADDRESS  (2)
+
+/*
+ * Searches for map using one of the following criteria:
+ * 
+ * - enough room to include a zone starting with the physical "requestedAddress" of size "size" (for mapping)
+ * - includes the virtual "requestedAddress" in its virtual address space (already mapped, for unmapping)
+ * - correct coherency
+ *
+ * Returns a pointer to the map or NULL if a suitable map is not found.
+ */
+PRIVATE IxOsalMemoryMap *
+ixOsalMemMapFind (UINT32 requestedAddress,
+    UINT32 size, UINT32 searchCriteria, UINT32 requestedEndianType)
+{
+    UINT32 mapIndex;
+
+    UINT32 numMapElements = ARRAY_SIZE(ixOsalGlobalMemoryMap);
+
+    for (mapIndex = 0; mapIndex < numMapElements; mapIndex++)
+    {
+        IxOsalMemoryMap *map = &ixOsalGlobalMemoryMap[mapIndex];
+
+        if (searchCriteria == SEARCH_PHYSICAL_ADDRESS
+            && requestedAddress >= map->physicalAddress
+            && (requestedAddress + size) <= (map->physicalAddress + map->size)
+            && (map->mapEndianType & requestedEndianType) != 0)
+        {
+            return map;
+        }
+        else if (searchCriteria == SEARCH_VIRTUAL_ADDRESS
+            && requestedAddress >= map->virtualAddress
+            && requestedAddress <= (map->virtualAddress + map->size)
+            && (map->mapEndianType & requestedEndianType) != 0)
+        {
+            return map;
+        }
+        else if (searchCriteria == SEARCH_PHYSICAL_ADDRESS)
+        {
+            ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+                IX_OSAL_LOG_DEV_STDOUT,
+                "Osal: Checking [phys addr 0x%x:size 0x%x:endianType %d]\n",
+                map->physicalAddress, map->size, map->mapEndianType, 0, 0, 0);
+        }
+    }
+
+    /*
+     * not found 
+     */
+    return NULL;
+}
+
+/*
+ * This function maps an I/O mapped physical memory zone of the given size
+ * into a virtual memory zone accessible by the caller and returns a cookie - 
+ * the start address of the virtual memory zone. 
+ * IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned 
+ * virtual address.
+ * The memory zone is to be unmapped using ixOsalMemUnmap once the caller has
+ * finished using this zone (e.g. on driver unload) using the cookie as 
+ * parameter.
+ * The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write 
+ * the mapped memory, adding the necessary offsets to the address cookie.
+ *
+ * Note: this function is not to be used directly. Use IX_OSAL_MEM_MAP 
+ * instead.
+ */
+PUBLIC void *
+ixOsalIoMemMap (UINT32 requestedAddress,
+    UINT32 size, IxOsalMapEndianessType requestedEndianType)
+{
+    IxOsalMemoryMap *map;
+
+    ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+        IX_OSAL_LOG_DEV_STDOUT,
+        "OSAL: Mapping [addr 0x%x:size 0x%x:endianType %d]\n",
+        requestedAddress, size, requestedEndianType, 0, 0, 0);
+
+    if (requestedEndianType == IX_OSAL_LE)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalIoMemMap: Please specify component coherency mode to use MEM functions \n",
+            0, 0, 0, 0, 0, 0);
+        return (NULL);
+    }
+    map = ixOsalMemMapFind (requestedAddress,
+        size, SEARCH_PHYSICAL_ADDRESS, requestedEndianType);
+    if (map != NULL)
+    {
+        UINT32 offset = requestedAddress - map->physicalAddress;
+
+        ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+            IX_OSAL_LOG_DEV_STDOUT, "OSAL: Found map [", 0, 0, 0, 0, 0, 0);
+        ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+            IX_OSAL_LOG_DEV_STDOUT, map->name, 0, 0, 0, 0, 0, 0);
+        ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+            IX_OSAL_LOG_DEV_STDOUT,
+            ":addr 0x%x: virt 0x%x:size 0x%x:ref %d:endianType %d]\n",
+            map->physicalAddress, map->virtualAddress,
+            map->size, map->refCount, map->mapEndianType, 0);
+
+        if (map->type == IX_OSAL_DYNAMIC_MAP && map->virtualAddress == 0)
+        {
+            if (map->mapFunction != NULL)
+            {
+                map->mapFunction (map);
+
+                if (map->virtualAddress == 0)
+                {
+                    /*
+                     * failed 
+                     */
+                    ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
+                        IX_OSAL_LOG_DEV_STDERR,
+                        "OSAL: Remap failed - [addr 0x%x:size 0x%x:endianType %d]\n",
+                        requestedAddress, size, requestedEndianType, 0, 0, 0);
+                    return NULL;
+                }
+            }
+            else
+            {
+                /*
+                 * error, no map function for a dynamic map 
+                 */
+                ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
+                    IX_OSAL_LOG_DEV_STDERR,
+                    "OSAL: No map function for a dynamic map - "
+                    "[addr 0x%x:size 0x%x:endianType %d]\n",
+                    requestedAddress, size, requestedEndianType, 0, 0, 0);
+
+                return NULL;
+            }
+        }
+
+        /*
+         * increment reference count 
+         */
+        map->refCount++;
+
+        return (void *) (map->virtualAddress + offset);
+    }
+
+    /*
+     * requested address is not described in the global memory map 
+     */
+    ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
+        IX_OSAL_LOG_DEV_STDERR,
+        "OSAL: No mapping found - [addr 0x%x:size 0x%x:endianType %d]\n",
+        requestedAddress, size, requestedEndianType, 0, 0, 0);
+    return NULL;
+}
+
+/*
+ * This function unmaps a previously mapped I/O memory zone using
+ * the cookie obtained in the mapping operation. The memory zone in question
+ * becomes unavailable to the caller once unmapped and the cookie should be
+ * discarded.
+ *
+ * This function cannot fail if the given parameter is correct and does not
+ * return a value.
+ *
+ * Note: this function is not to be used directly. Use IX_OSAL_MEM_UNMAP
+ * instead.
+ */
+PUBLIC void
+ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 endianType)
+{
+    IxOsalMemoryMap *map;
+
+    if (endianType == IX_OSAL_LE)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalIoMemUnmap: Please specify component coherency mode to use MEM functions \n",
+            0, 0, 0, 0, 0, 0);
+        return;
+    }
+
+    if (requestedAddress == 0)
+    {
+        /*
+         * invalid virtual address 
+         */
+        return;
+    }
+
+    map =
+        ixOsalMemMapFind (requestedAddress, 0, SEARCH_VIRTUAL_ADDRESS,
+        endianType);
+
+    if (map != NULL)
+    {
+        if (map->refCount > 0)
+        {
+            /*
+             * decrement reference count 
+             */
+            map->refCount--;
+
+            if (map->refCount == 0)
+            {
+                /*
+                 * no longer used, deallocate 
+                 */
+                if (map->type == IX_OSAL_DYNAMIC_MAP
+                    && map->unmapFunction != NULL)
+                {
+                    map->unmapFunction (map);
+                }
+            }
+        }
+    }
+    else
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_WARNING,
+            IX_OSAL_LOG_DEV_STDERR,
+            "OSAL: ixOsServMemUnmap didn't find the requested map "
+            "[virt addr 0x%x: endianType %d], ignoring call\n",
+            requestedAddress, endianType, 0, 0, 0, 0);
+    }
+}
+
+/* 
+ * This function Converts a virtual address into a physical 
+ * address, including the dynamically mapped memory.
+ * 
+ * Parameters	virtAddr - virtual address to convert
+ * Return value: corresponding physical address, or NULL 
+ *               if there is no physical address addressable 
+ *               by the given virtual address
+ * OS:	VxWorks, Linux, WinCE, QNX, eCos
+ * Reentrant: Yes
+ * IRQ safe: Yes
+ */
+PUBLIC UINT32
+ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 requestedCoherency)
+{
+    IxOsalMemoryMap *map =
+        ixOsalMemMapFind (virtualAddress, 0, SEARCH_VIRTUAL_ADDRESS,
+        requestedCoherency);
+
+    if (map != NULL)
+    {
+        return map->physicalAddress + virtualAddress - map->virtualAddress;
+    }
+    else
+    {
+        return (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS (virtualAddress);
+    }
+}
+
+/* 
+ * This function Converts a virtual address into a physical 
+ * address, including the dynamically mapped memory.
+ * 
+ * Parameters	virtAddr - virtual address to convert
+ * Return value: corresponding physical address, or NULL 
+ *               if there is no physical address addressable 
+ *               by the given virtual address
+ * OS:	VxWorks, Linux, WinCE, QNX, eCos
+ * Reentrant: Yes
+ * IRQ safe: Yes
+ */
+PUBLIC UINT32
+ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 requestedCoherency)
+{
+    IxOsalMemoryMap *map =
+        ixOsalMemMapFind (physicalAddress, 0, SEARCH_PHYSICAL_ADDRESS,
+        requestedCoherency);
+
+    if (map != NULL)
+    {
+        return map->virtualAddress + physicalAddress - map->physicalAddress;
+    }
+    else
+    {
+        return (UINT32) IX_OSAL_MMU_PHYS_TO_VIRT (physicalAddress);
+    }
+}
diff --git a/marvell/uboot/drivers/net/npe/IxOsalOsCacheMMU.c b/marvell/uboot/drivers/net/npe/IxOsalOsCacheMMU.c
new file mode 100644
index 0000000..72d22e5
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxOsalOsCacheMMU.c
@@ -0,0 +1,43 @@
+/**
+ * @file IxOsalOsCacheMMU.c (linux)
+ *
+ * @brief Cache MemAlloc and MemFree.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 1.5
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+
+#include <malloc.h>
+
+/*
+ * Allocate on a cache line boundary (null pointers are
+ * not affected by this operation). This operation is NOT cache safe.
+ */
+void *
+ixOsalCacheDmaMalloc (UINT32 n)
+{
+	return malloc(n);
+}
+
+/*
+ *
+ */
+void
+ixOsalCacheDmaFree (void *ptr)
+{
+	free(ptr);
+}
diff --git a/marvell/uboot/drivers/net/npe/IxOsalOsMsgQ.c b/marvell/uboot/drivers/net/npe/IxOsalOsMsgQ.c
new file mode 100644
index 0000000..5fe368b
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxOsalOsMsgQ.c
@@ -0,0 +1,55 @@
+/**
+ * @file IxOsalOsMsgQ.c (eCos)
+ *
+ * @brief OS-specific Message Queue implementation.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 1.5
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+
+/*******************************
+ * Public functions
+ *******************************/
+PUBLIC IX_STATUS
+ixOsalMessageQueueCreate (IxOsalMessageQueue * queue,
+    UINT32 msgCount, UINT32 msgLen)
+{
+    diag_printf("%s called\n", __FUNCTION__);
+    return IX_FAIL;
+}
+
+PUBLIC IX_STATUS
+ixOsalMessageQueueDelete (IxOsalMessageQueue * queue)
+{
+    diag_printf("%s called\n", __FUNCTION__);
+    return IX_FAIL;
+}
+
+PUBLIC IX_STATUS
+ixOsalMessageQueueSend (IxOsalMessageQueue * queue, UINT8 * message)
+{
+    diag_printf("%s called\n", __FUNCTION__);
+    return IX_FAIL;
+}
+
+PUBLIC IX_STATUS
+ixOsalMessageQueueReceive (IxOsalMessageQueue * queue, UINT8 * message)
+{
+    diag_printf("%s called\n", __FUNCTION__);
+    return IX_FAIL;
+}
+
diff --git a/marvell/uboot/drivers/net/npe/IxOsalOsSemaphore.c b/marvell/uboot/drivers/net/npe/IxOsalOsSemaphore.c
new file mode 100644
index 0000000..33de7f6
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxOsalOsSemaphore.c
@@ -0,0 +1,209 @@
+/**
+ * @file IxOsalOsSemaphore.c (eCos)
+ *
+ * @brief Implementation for semaphore and mutex.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 1.5
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+#include "IxNpeMhReceive_p.h"
+
+/* Define a large number */
+#define IX_OSAL_MAX_LONG (0x7FFFFFFF)
+
+/* Max timeout in MS, used to guard against possible overflow */
+#define IX_OSAL_MAX_TIMEOUT_MS (IX_OSAL_MAX_LONG/HZ)
+
+
+PUBLIC IX_STATUS
+ixOsalSemaphoreInit (IxOsalSemaphore * sid, UINT32 start_value)
+{
+    diag_printf("%s called\n", __FUNCTION__);
+    return IX_SUCCESS;
+}
+
+/**
+ * DESCRIPTION: If the semaphore is 'empty', the calling thread is blocked.
+ *              If the semaphore is 'full', it is taken and control is returned
+ *              to the caller. If the time indicated in 'timeout' is reached,
+ *              the thread will unblock and return an error indication. If the
+ *              timeout is set to 'IX_OSAL_WAIT_NONE', the thread will never block;
+ *              if it is set to 'IX_OSAL_WAIT_FOREVER', the thread will block until
+ *              the semaphore is available.
+ *
+ *
+ */
+
+
+PUBLIC IX_STATUS
+ixOsalSemaphoreWait (IxOsalOsSemaphore * sid, INT32 timeout)
+{
+    diag_printf("%s called\n", __FUNCTION__);
+    return IX_SUCCESS;
+}
+
+/*
+ * Attempt to get semaphore, return immediately,
+ * no error info because users expect some failures
+ * when using this API.
+ */
+PUBLIC IX_STATUS
+ixOsalSemaphoreTryWait (IxOsalSemaphore * sid)
+{
+    diag_printf("%s called\n", __FUNCTION__);
+    return IX_FAIL;
+}
+
+/**
+ *
+ * DESCRIPTION: This function causes the next available thread in the pend queue
+ *              to be unblocked. If no thread is pending on this semaphore, the
+ *              semaphore becomes 'full'.
+ */
+PUBLIC IX_STATUS
+ixOsalSemaphorePost (IxOsalSemaphore * sid)
+{
+    diag_printf("%s called\n", __FUNCTION__);
+    return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixOsalSemaphoreGetValue (IxOsalSemaphore * sid, UINT32 * value)
+{
+    diag_printf("%s called\n", __FUNCTION__);
+    return IX_FAIL;
+}
+
+PUBLIC IX_STATUS
+ixOsalSemaphoreDestroy (IxOsalSemaphore * sid)
+{
+    diag_printf("%s called\n", __FUNCTION__);
+    return IX_FAIL;
+}
+
+/****************************
+ *    Mutex
+ ****************************/
+
+static void drv_mutex_init(IxOsalMutex *mutex)
+{
+	*mutex = 0;
+}
+
+static void drv_mutex_destroy(IxOsalMutex *mutex)
+{
+	*mutex = -1;
+}
+
+static int drv_mutex_trylock(IxOsalMutex *mutex)
+{
+	int result = true;
+
+	if (*mutex == 1)
+		result = false;
+
+	return result;
+}
+
+static void drv_mutex_unlock(IxOsalMutex *mutex)
+{
+	if (*mutex == 1)
+		printf("Trying to unlock unlocked mutex!");
+
+	*mutex = 0;
+}
+
+PUBLIC IX_STATUS
+ixOsalMutexInit (IxOsalMutex * mutex)
+{
+    drv_mutex_init(mutex);
+    return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixOsalMutexLock (IxOsalMutex * mutex, INT32 timeout)
+{
+    int tries;
+
+    if (timeout == IX_OSAL_WAIT_NONE) {
+	if (drv_mutex_trylock(mutex))
+	    return IX_SUCCESS;
+	else
+	    return IX_FAIL;
+    }
+
+    tries = (timeout * 1000) / 50;
+    while (1) {
+	if (drv_mutex_trylock(mutex))
+	    return IX_SUCCESS;
+	if (timeout != IX_OSAL_WAIT_FOREVER && tries-- <= 0)
+	    break;
+	udelay(50);
+    }
+    return IX_FAIL;
+}
+
+PUBLIC IX_STATUS
+ixOsalMutexUnlock (IxOsalMutex * mutex)
+{
+    drv_mutex_unlock(mutex);
+    return IX_SUCCESS;
+}
+
+/*
+ * Attempt to get mutex, return immediately,
+ * no error info because users expect some failures
+ * when using this API.
+ */
+PUBLIC IX_STATUS
+ixOsalMutexTryLock (IxOsalMutex * mutex)
+{
+    if (drv_mutex_trylock(mutex))
+	return IX_SUCCESS;
+    return IX_FAIL;
+}
+
+PUBLIC IX_STATUS
+ixOsalMutexDestroy (IxOsalMutex * mutex)
+{
+    drv_mutex_destroy(mutex);
+    return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixOsalFastMutexInit (IxOsalFastMutex * mutex)
+{
+    return ixOsalMutexInit(mutex);
+}
+
+PUBLIC IX_STATUS ixOsalFastMutexTryLock(IxOsalFastMutex *mutex)
+{
+    return ixOsalMutexTryLock(mutex);
+}
+
+
+PUBLIC IX_STATUS
+ixOsalFastMutexUnlock (IxOsalFastMutex * mutex)
+{
+    return ixOsalMutexUnlock(mutex);
+}
+
+PUBLIC IX_STATUS
+ixOsalFastMutexDestroy (IxOsalFastMutex * mutex)
+{
+    return ixOsalMutexDestroy(mutex);
+}
diff --git a/marvell/uboot/drivers/net/npe/IxOsalOsServices.c b/marvell/uboot/drivers/net/npe/IxOsalOsServices.c
new file mode 100644
index 0000000..a9aa368
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxOsalOsServices.c
@@ -0,0 +1,227 @@
+/**
+ * @file IxOsalOsServices.c (linux)
+ *
+ * @brief Implementation for Irq, Mem, sleep.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 1.5
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include <config.h>
+#include <common.h>
+#include "IxOsal.h"
+#include <IxEthAcc.h>
+#include <IxEthDB.h>
+#include <IxNpeDl.h>
+#include <IxQMgr.h>
+#include <IxNpeMh.h>
+
+static char *traceHeaders[] = {
+    "",
+    "[fatal] ",
+    "[error] ",
+    "[warning] ",
+    "[message] ",
+    "[debug1] ",
+    "[debug2] ",
+    "[debug3] ",
+    "[all]"
+};
+
+/* by default trace all but debug message */
+PRIVATE int ixOsalCurrLogLevel = IX_OSAL_LOG_LVL_MESSAGE;
+
+/**************************************
+ * Irq services
+ *************************************/
+
+PUBLIC IX_STATUS
+ixOsalIrqBind (UINT32 vector, IxOsalVoidFnVoidPtr routine, void *parameter)
+{
+    return IX_FAIL;
+}
+
+PUBLIC IX_STATUS
+ixOsalIrqUnbind (UINT32 vector)
+{
+    return IX_FAIL;
+}
+
+PUBLIC UINT32
+ixOsalIrqLock ()
+{
+    return 0;
+}
+
+/* Enable interrupts and task scheduling,
+ * input parameter: irqEnable status returned
+ * by ixOsalIrqLock().
+ */
+PUBLIC void
+ixOsalIrqUnlock (UINT32 lockKey)
+{
+}
+
+PUBLIC UINT32
+ixOsalIrqLevelSet (UINT32 level)
+{
+    return IX_FAIL;
+}
+
+PUBLIC void
+ixOsalIrqEnable (UINT32 irqLevel)
+{
+}
+
+PUBLIC void
+ixOsalIrqDisable (UINT32 irqLevel)
+{
+}
+
+/*********************
+ * Log function
+ *********************/
+
+INT32
+ixOsalLog (IxOsalLogLevel level,
+    IxOsalLogDevice device,
+    char *format, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6)
+{
+    /*
+     * Return -1 for custom display devices
+     */
+    if ((device != IX_OSAL_LOG_DEV_STDOUT)
+        && (device != IX_OSAL_LOG_DEV_STDERR))
+    {
+        debug("ixOsalLog: only IX_OSAL_LOG_DEV_STDOUT and IX_OSAL_LOG_DEV_STDERR are supported \n");
+        return (IX_OSAL_LOG_ERROR);
+    }
+
+    if (level <= ixOsalCurrLogLevel && level != IX_OSAL_LOG_LVL_NONE)
+    {
+#if 0 /* sr: U-Boots printf or debug doesn't return a length */
+        int headerByteCount = (level == IX_OSAL_LOG_LVL_USER) ? 0 : diag_printf(traceHeaders[level - 1]);
+
+        return headerByteCount + diag_printf (format, arg1, arg2, arg3, arg4, arg5, arg6);
+#else
+        int headerByteCount = (level == IX_OSAL_LOG_LVL_USER) ? 0 : strlen(traceHeaders[level - 1]);
+
+        return headerByteCount + strlen(format);
+#endif
+    }
+    else
+    {
+        /*
+         * Return error
+         */
+        return (IX_OSAL_LOG_ERROR);
+    }
+}
+
+PUBLIC UINT32
+ixOsalLogLevelSet (UINT32 level)
+{
+    UINT32 oldLevel;
+
+    /*
+     * Check value first
+     */
+    if ((level < IX_OSAL_LOG_LVL_NONE) || (level > IX_OSAL_LOG_LVL_ALL))
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalLogLevelSet: Log Level is between %d and%d \n",
+            IX_OSAL_LOG_LVL_NONE, IX_OSAL_LOG_LVL_ALL, 0, 0, 0, 0);
+        return IX_OSAL_LOG_LVL_NONE;
+    }
+    oldLevel = ixOsalCurrLogLevel;
+
+    ixOsalCurrLogLevel = level;
+
+    return oldLevel;
+}
+
+/**************************************
+ * Task services
+ *************************************/
+
+PUBLIC void
+ixOsalBusySleep (UINT32 microseconds)
+{
+	udelay(microseconds);
+}
+
+PUBLIC void
+ixOsalSleep (UINT32 milliseconds)
+{
+    if (milliseconds != 0) {
+#if 1
+	/*
+	 * sr: We poll while we wait because interrupts are off in U-Boot
+	 * and CSR expects messages, etc to be dispatched while sleeping.
+	 */
+	int i;
+	IxQMgrDispatcherFuncPtr qDispatcherFunc;
+
+	ixQMgrDispatcherLoopGet(&qDispatcherFunc);
+
+	while (milliseconds--) {
+		for (i = 1; i <= 2; i++)
+			ixNpeMhMessagesReceive(i);
+		(*qDispatcherFunc)(IX_QMGR_QUELOW_GROUP);
+
+		udelay(1000);
+	}
+#endif
+    }
+}
+
+/**************************************
+ * Memory functions
+ *************************************/
+
+void *
+ixOsalMemAlloc (UINT32 size)
+{
+    return (void *)0;
+}
+
+void
+ixOsalMemFree (void *ptr)
+{
+}
+
+/*
+ * Copy count bytes from src to dest ,
+ * returns pointer to the dest mem zone.
+ */
+void *
+ixOsalMemCopy (void *dest, void *src, UINT32 count)
+{
+    IX_OSAL_ASSERT (dest != NULL);
+    IX_OSAL_ASSERT (src != NULL);
+    return (memcpy (dest, src, count));
+}
+
+/*
+ * Fills a memory zone with a given constant byte,
+ * returns pointer to the memory zone.
+ */
+void *
+ixOsalMemSet (void *ptr, UINT8 filler, UINT32 count)
+{
+    IX_OSAL_ASSERT (ptr != NULL);
+    return (memset (ptr, filler, count));
+}
diff --git a/marvell/uboot/drivers/net/npe/IxOsalOsThread.c b/marvell/uboot/drivers/net/npe/IxOsalOsThread.c
new file mode 100644
index 0000000..b3caae1
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxOsalOsThread.c
@@ -0,0 +1,74 @@
+/**
+ * @file IxOsalOsThread.c (eCos)
+ *
+ * @brief OS-specific thread implementation.
+ *
+ *
+ * @par
+ * IXP400 SW Release version 1.5
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxOsal.h"
+
+/* Thread attribute is ignored */
+PUBLIC IX_STATUS
+ixOsalThreadCreate (IxOsalThread * ptrTid,
+    IxOsalThreadAttr * threadAttr, IxOsalVoidFnVoidPtr entryPoint, void *arg)
+{
+    return IX_SUCCESS;
+}
+
+/*
+ * Start thread after given its thread handle
+ */
+PUBLIC IX_STATUS
+ixOsalThreadStart (IxOsalThread * tId)
+{
+    /* Thread already started upon creation */
+    return IX_SUCCESS;
+}
+
+/*
+ * In Linux threadKill does not actually destroy the thread,
+ * it will stop the signal handling.
+ */
+PUBLIC IX_STATUS
+ixOsalThreadKill (IxOsalThread * tid)
+{
+    return IX_SUCCESS;
+}
+
+PUBLIC void
+ixOsalThreadExit (void)
+{
+}
+
+PUBLIC IX_STATUS
+ixOsalThreadPrioritySet (IxOsalOsThread * tid, UINT32 priority)
+{
+    return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixOsalThreadSuspend (IxOsalThread * tId)
+{
+    return IX_SUCCESS;
+
+}
+
+PUBLIC IX_STATUS
+ixOsalThreadResume (IxOsalThread * tId)
+{
+    return IX_SUCCESS;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxQMgrAqmIf.c b/marvell/uboot/drivers/net/npe/IxQMgrAqmIf.c
new file mode 100644
index 0000000..69138cc
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxQMgrAqmIf.c
@@ -0,0 +1,939 @@
+/* 
+ * @file:    IxQMgrAqmIf.c
+ *
+ * @author Intel Corporation
+ * @date     30-Oct-2001
+ *
+ * @brief    This component provides a set of functions for
+ * perfoming I/O on the AQM hardware.
+ * 
+ * Design Notes: 
+ *              These functions are intended to be as fast as possible
+ * and as a result perform NO PARAMETER CHECKING.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Inlines are compiled as function when this is defined.
+ * N.B. Must be placed before #include of "IxQMgrAqmIf_p.h
+ */
+#ifndef IXQMGRAQMIF_P_H
+#    define IXQMGRAQMIF_C
+#else
+#    error
+#endif
+
+/*
+ * User defined include files.
+ */
+#include "IxOsal.h"
+#include "IxQMgr.h"
+#include "IxQMgrAqmIf_p.h"
+#include "IxQMgrLog_p.h"
+
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/* These defines are the bit offsets of the various fields of
+ * the queue configuration register
+ */
+#define IX_QMGR_Q_CONFIG_WRPTR_OFFSET       0x00
+#define IX_QMGR_Q_CONFIG_RDPTR_OFFSET       0x07
+#define IX_QMGR_Q_CONFIG_BADDR_OFFSET       0x0E
+#define IX_QMGR_Q_CONFIG_ESIZE_OFFSET       0x16
+#define IX_QMGR_Q_CONFIG_BSIZE_OFFSET       0x18
+#define IX_QMGR_Q_CONFIG_NE_OFFSET          0x1A
+#define IX_QMGR_Q_CONFIG_NF_OFFSET          0x1D
+
+#define IX_QMGR_BASE_ADDR_16_WORD_ALIGN     0x40
+#define IX_QMGR_BASE_ADDR_16_WORD_SHIFT     0x6
+
+#define IX_QMGR_NE_NF_CLEAR_MASK            0x03FFFFFF
+#define IX_QMGR_NE_MASK                     0x7
+#define IX_QMGR_NF_MASK                     0x7
+#define IX_QMGR_SIZE_MASK                   0x3
+#define IX_QMGR_ENTRY_SIZE_MASK             0x3
+#define IX_QMGR_BADDR_MASK                  0x003FC000
+#define IX_QMGR_RDPTR_MASK                  0x7F
+#define IX_QMGR_WRPTR_MASK                  0x7F
+#define IX_QMGR_RDWRPTR_MASK                0x00003FFF
+
+#define IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS 0x1000
+
+/* Base address of AQM SRAM */
+#define IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET \
+((IX_QMGR_QUECONFIG_BASE_OFFSET) + (IX_QMGR_QUECONFIG_SIZE))
+
+/* Min buffer size used for generating buffer size in QUECONFIG */
+#define IX_QMGR_MIN_BUFFER_SIZE 16
+
+/* Reset values of QMgr hardware registers */
+#define IX_QMGR_QUELOWSTAT_RESET_VALUE    0x33333333
+#define IX_QMGR_QUEUOSTAT_RESET_VALUE     0x00000000
+#define IX_QMGR_QUEUPPSTAT0_RESET_VALUE   0xFFFFFFFF
+#define IX_QMGR_QUEUPPSTAT1_RESET_VALUE   0x00000000
+#define IX_QMGR_INT0SRCSELREG_RESET_VALUE 0x00000000
+#define IX_QMGR_QUEIEREG_RESET_VALUE      0x00000000
+#define IX_QMGR_QINTREG_RESET_VALUE       0xFFFFFFFF
+#define IX_QMGR_QUECONFIG_RESET_VALUE     0x00000000
+
+#define IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS IX_OSAL_IXP400_QMGR_PHYS_BASE
+
+#define IX_QMGR_QUELOWSTAT_BITS_PER_Q (BITS_PER_WORD/IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)
+
+#define IX_QMGR_QUELOWSTAT_QID_MASK 0x7
+#define IX_QMGR_Q_CONFIG_ADDR_GET(qId)\
+        (((qId) * IX_QMGR_NUM_BYTES_PER_WORD) +\
+                  IX_QMGR_QUECONFIG_BASE_OFFSET)
+
+#define IX_QMGR_ENTRY1_OFFSET 0
+#define IX_QMGR_ENTRY2_OFFSET 1
+#define IX_QMGR_ENTRY4_OFFSET 3
+
+/*
+ * Variable declarations global to this file. Externs are followed by
+ * statics.
+ */
+UINT32 aqmBaseAddress = 0;
+/* Store addresses and bit-masks for certain queue access and status registers.
+ * This is to facilitate inlining of QRead, QWrite and QStatusGet functions
+ * in IxQMgr,h
+ */
+extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+UINT32 * ixQMgrAqmIfQueAccRegAddr[IX_QMGR_MAX_NUM_QUEUES];
+UINT32 ixQMgrAqmIfQueLowStatRegAddr[IX_QMGR_MIN_QUEUPP_QID];
+UINT32 ixQMgrAqmIfQueLowStatBitsOffset[IX_QMGR_MIN_QUEUPP_QID];
+UINT32 ixQMgrAqmIfQueLowStatBitsMask;
+UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
+UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
+UINT32 ixQMgrAqmIfQueUppStat0BitMask[IX_QMGR_MIN_QUEUPP_QID];
+UINT32 ixQMgrAqmIfQueUppStat1BitMask[IX_QMGR_MIN_QUEUPP_QID];
+
+/* 
+ * Fast mutexes, one for each queue, used to protect peek & poke functions
+ */
+IxOsalFastMutex ixQMgrAqmIfPeekPokeFastMutex[IX_QMGR_MAX_NUM_QUEUES];
+
+/*
+ * Function prototypes
+ */
+PRIVATE unsigned
+watermarkToAqmWatermark (IxQMgrWMLevel watermark );
+
+PRIVATE unsigned
+entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize);
+
+PRIVATE unsigned
+bufferSizeToAqmBufferSize (unsigned bufferSizeInWords);
+
+PRIVATE void
+ixQMgrAqmIfRegistersReset (void);
+
+PRIVATE void
+ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex,
+			    UINT32 configRegWord,
+			    unsigned int qEntrySizeInwords,
+			    unsigned int qSizeInWords,
+			    UINT32 **address);
+/*
+ * Function definitions
+ */
+void
+ixQMgrAqmIfInit (void)
+{
+    UINT32 aqmVirtualAddr;
+    int i;
+
+    /* The value of aqmBaseAddress depends on the logical address
+     * assigned by the MMU.
+     */
+    aqmVirtualAddr =
+	(UINT32) IX_OSAL_MEM_MAP(IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS,
+				    IX_OSAL_IXP400_QMGR_MAP_SIZE);
+    IX_OSAL_ASSERT (aqmVirtualAddr);
+    
+    ixQMgrAqmIfBaseAddressSet (aqmVirtualAddr);
+
+    ixQMgrAqmIfRegistersReset ();
+
+    for (i = 0; i< IX_QMGR_MAX_NUM_QUEUES; i++)
+    {
+	ixOsalFastMutexInit(&ixQMgrAqmIfPeekPokeFastMutex[i]);
+
+	/********************************************************************
+	 * Register addresses and bit masks are calculated and stored here to
+	 * facilitate inlining of QRead, QWrite and QStatusGet functions in
+	 * IxQMgr.h.
+	 * These calculations are normally performed dynamically in inlined
+	 * functions in IxQMgrAqmIf_p.h, and their semantics are reused here.
+	 */
+
+	/* AQM Queue access reg addresses, per queue */
+	ixQMgrAqmIfQueAccRegAddr[i] = 
+	    (UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i));
+	ixQMgrQInlinedReadWriteInfo[i].qAccRegAddr = 
+	    (volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i));
+
+
+	ixQMgrQInlinedReadWriteInfo[i].qConfigRegAddr = 
+	    (volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(i));
+
+	/* AQM Queue lower-group (0-31), only */
+	if (i < IX_QMGR_MIN_QUEUPP_QID)
+	{
+	    /* AQM Q underflow/overflow status register addresses, per queue */
+	    ixQMgrQInlinedReadWriteInfo[i].qUOStatRegAddr = 
+		(volatile UINT32 *)(aqmBaseAddress +
+		IX_QMGR_QUEUOSTAT0_OFFSET +
+		((i / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD) *
+		 IX_QMGR_NUM_BYTES_PER_WORD));
+
+	    /* AQM Q underflow status bit masks for status register per queue */
+	    ixQMgrQInlinedReadWriteInfo[i].qUflowStatBitMask = 
+		(IX_QMGR_UNDERFLOW_BIT_OFFSET + 1) <<
+		((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) *
+		 (BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD));
+
+	    /* AQM Q overflow status bit masks for status register, per queue */
+	    ixQMgrQInlinedReadWriteInfo[i].qOflowStatBitMask = 
+		(IX_QMGR_OVERFLOW_BIT_OFFSET + 1) <<
+		((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) *
+		 (BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD));
+
+	    /* AQM Q lower-group (0-31) status register addresses, per queue */
+	    ixQMgrAqmIfQueLowStatRegAddr[i] = aqmBaseAddress +
+		IX_QMGR_QUELOWSTAT0_OFFSET +
+		((i / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) *
+		 IX_QMGR_NUM_BYTES_PER_WORD);
+
+	    /* AQM Q lower-group (0-31) status register bit offset */
+	    ixQMgrAqmIfQueLowStatBitsOffset[i] =
+		(i & (IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD - 1)) * 
+		(BITS_PER_WORD / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD);
+	}
+	else /* AQM Q upper-group (32-63), only */
+	{
+	    /* AQM Q upper-group (32-63) Nearly Empty status reg bit masks */
+	    ixQMgrAqmIfQueUppStat0BitMask[i - IX_QMGR_MIN_QUEUPP_QID] =
+		(1 << (i - IX_QMGR_MIN_QUEUPP_QID));
+
+	    /* AQM Q upper-group (32-63) Full status register bit masks */
+	    ixQMgrAqmIfQueUppStat1BitMask[i - IX_QMGR_MIN_QUEUPP_QID] =
+		(1 << (i - IX_QMGR_MIN_QUEUPP_QID));
+	}
+    }
+
+    /* AQM Q lower-group (0-31) status register bit mask */
+    ixQMgrAqmIfQueLowStatBitsMask = (1 <<
+				    (BITS_PER_WORD /
+				     IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)) - 1;
+
+    /* AQM Q upper-group (32-63) Nearly Empty status register address */
+    ixQMgrAqmIfQueUppStat0RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET;
+    
+    /* AQM Q upper-group (32-63) Full status register address */
+    ixQMgrAqmIfQueUppStat1RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET;
+}
+
+/*
+ * Uninitialise the AqmIf module by unmapping memory, etc
+ */
+void
+ixQMgrAqmIfUninit (void)
+{
+    UINT32 virtAddr;
+
+    ixQMgrAqmIfBaseAddressGet (&virtAddr);
+    IX_OSAL_MEM_UNMAP (virtAddr);
+    ixQMgrAqmIfBaseAddressSet (0);
+}
+
+/*
+ * Set the the logical base address of AQM
+ */
+void
+ixQMgrAqmIfBaseAddressSet (UINT32 address)
+{
+    aqmBaseAddress = address;
+}
+
+/*
+ * Get the logical base address of AQM
+ */
+void
+ixQMgrAqmIfBaseAddressGet (UINT32 *address)
+{
+    *address = aqmBaseAddress;
+}
+
+/*
+ * Get the logical base address of AQM SRAM
+ */
+void
+ixQMgrAqmIfSramBaseAddressGet (UINT32 *address)
+{
+    *address = aqmBaseAddress                +
+	IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET;
+}
+
+/*
+ * This function will write the status bits of a queue
+ * specified by qId.
+ */
+void
+ixQMgrAqmIfQRegisterBitsWrite (IxQMgrQId qId, 
+			       UINT32 registerBaseAddrOffset,
+			       unsigned queuesPerRegWord,
+			       UINT32 value)
+{
+    volatile UINT32 *registerAddress;
+    UINT32 registerWord;
+    UINT32 statusBitsMask;
+    UINT32 bitsPerQueue;
+
+    bitsPerQueue = BITS_PER_WORD / queuesPerRegWord;
+
+    /*
+     * Calculate the registerAddress
+     * multiple queues split accross registers
+     */
+    registerAddress = (UINT32*)(aqmBaseAddress +
+				registerBaseAddrOffset +
+				((qId / queuesPerRegWord) *
+				 IX_QMGR_NUM_BYTES_PER_WORD));    
+
+    /* Read the current data */
+    ixQMgrAqmIfWordRead (registerAddress, &registerWord);
+
+
+    if( (registerBaseAddrOffset == IX_QMGR_INT0SRCSELREG0_OFFSET) &&
+        (qId == IX_QMGR_QUEUE_0) )
+    {
+      statusBitsMask = 0x7 ;   
+
+      /* Queue 0 at INT0SRCSELREG should not corrupt the value bit-3  */
+      value &=  0x7 ;        
+    }
+    else
+    {     
+      /* Calculate the mask for the status bits for this queue. */
+      statusBitsMask = ((1 << bitsPerQueue) - 1);
+      statusBitsMask <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue);
+
+      /* Mask out bits in value that would overwrite other q data */
+      value <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue);
+      value &= statusBitsMask;
+    }
+
+    /* Mask out bits to write to */
+    registerWord &= ~statusBitsMask;
+    
+
+    /* Set the write bits */
+    registerWord |= value;
+
+    /*
+     * Write the data
+     */
+    ixQMgrAqmIfWordWrite (registerAddress, registerWord);
+}
+
+/*
+ * This function generates the parameters that can be used to
+ * check if a Qs status matches the specified source select.
+ * It calculates which status word to check (statusWordOffset),
+ * the value to check the status against (checkValue) and the
+ * mask (mask) to mask out all but the bits to check in the status word.
+ */
+void
+ixQMgrAqmIfQStatusCheckValsCalc (IxQMgrQId qId,
+				 IxQMgrSourceId srcSel,
+				 unsigned int *statusWordOffset,
+				 UINT32 *checkValue,
+				 UINT32 *mask)
+{
+    UINT32 shiftVal;
+   
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {
+	switch (srcSel)
+	{
+	    case IX_QMGR_Q_SOURCE_ID_E:
+		*checkValue = IX_QMGR_Q_STATUS_E_BIT_MASK;
+		*mask = IX_QMGR_Q_STATUS_E_BIT_MASK;
+		break;
+	    case IX_QMGR_Q_SOURCE_ID_NE:
+		*checkValue = IX_QMGR_Q_STATUS_NE_BIT_MASK;
+		*mask = IX_QMGR_Q_STATUS_NE_BIT_MASK;
+		break;
+	    case IX_QMGR_Q_SOURCE_ID_NF:
+		*checkValue = IX_QMGR_Q_STATUS_NF_BIT_MASK;
+		*mask = IX_QMGR_Q_STATUS_NF_BIT_MASK;
+		break;
+	    case IX_QMGR_Q_SOURCE_ID_F:
+		*checkValue = IX_QMGR_Q_STATUS_F_BIT_MASK;
+		*mask = IX_QMGR_Q_STATUS_F_BIT_MASK;
+		break;
+	    case IX_QMGR_Q_SOURCE_ID_NOT_E:
+		*checkValue = 0;
+		*mask = IX_QMGR_Q_STATUS_E_BIT_MASK;
+		break;
+	    case IX_QMGR_Q_SOURCE_ID_NOT_NE:
+		*checkValue = 0;
+		*mask = IX_QMGR_Q_STATUS_NE_BIT_MASK;
+		break;
+	    case IX_QMGR_Q_SOURCE_ID_NOT_NF:
+		*checkValue = 0;
+		*mask = IX_QMGR_Q_STATUS_NF_BIT_MASK;
+		break;
+	    case IX_QMGR_Q_SOURCE_ID_NOT_F:
+		*checkValue = 0;
+		*mask = IX_QMGR_Q_STATUS_F_BIT_MASK;
+		break;
+	    default:
+		/* Should never hit */
+		IX_OSAL_ASSERT(0);
+		break;
+	}
+
+	/* One nibble of status per queue so need to shift the
+	 * check value and mask out to the correct position.
+	 */
+	shiftVal = (qId % IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) * 
+	    IX_QMGR_QUELOWSTAT_BITS_PER_Q;
+
+	/* Calculate the which status word to check from the qId,
+	 * 8 Qs status per word
+	 */
+	*statusWordOffset = qId / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD;
+
+	*checkValue <<= shiftVal;
+	*mask <<= shiftVal;
+    }
+    else
+    {
+	/* One status word */
+	*statusWordOffset = 0;
+	/* Single bits per queue and int source bit hardwired  NE,
+	 * Qs start at 32.
+	 */
+	*mask = 1 << (qId - IX_QMGR_MIN_QUEUPP_QID);
+	*checkValue = *mask;
+    }
+}
+
+void
+ixQMgrAqmIfQInterruptEnable (IxQMgrQId qId)
+{
+    volatile UINT32 *registerAddress;
+    UINT32 registerWord;
+    UINT32 actualBitOffset;
+    
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {    
+	registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET);
+    }
+    else
+    {
+	registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET);
+    }
+
+    actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID);
+
+    ixQMgrAqmIfWordRead (registerAddress, &registerWord);
+    ixQMgrAqmIfWordWrite (registerAddress, (registerWord | actualBitOffset));
+}
+
+void
+ixQMgrAqmIfQInterruptDisable (IxQMgrQId qId)
+{
+    volatile UINT32 *registerAddress;
+    UINT32 registerWord;
+    UINT32 actualBitOffset;
+
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {    
+	registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET);
+    }
+    else
+    {
+	registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET);
+    }
+
+    actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID);
+
+    ixQMgrAqmIfWordRead (registerAddress, &registerWord);
+    ixQMgrAqmIfWordWrite (registerAddress, registerWord & (~actualBitOffset));
+}
+
+void
+ixQMgrAqmIfQueCfgWrite (IxQMgrQId qId,
+		       IxQMgrQSizeInWords qSizeInWords,
+		       IxQMgrQEntrySizeInWords entrySizeInWords,
+		       UINT32 freeSRAMAddress)
+{
+    volatile UINT32 *cfgAddress = NULL;
+    UINT32 qCfg = 0;
+    UINT32 baseAddress = 0;
+    unsigned aqmEntrySize = 0;
+    unsigned aqmBufferSize = 0;
+
+    /* Build config register */
+    aqmEntrySize = entrySizeToAqmEntrySize (entrySizeInWords);
+    qCfg |= (aqmEntrySize&IX_QMGR_ENTRY_SIZE_MASK) <<
+	IX_QMGR_Q_CONFIG_ESIZE_OFFSET;
+
+    aqmBufferSize = bufferSizeToAqmBufferSize (qSizeInWords);
+    qCfg |= (aqmBufferSize&IX_QMGR_SIZE_MASK) << IX_QMGR_Q_CONFIG_BSIZE_OFFSET;
+
+    /* baseAddress, calculated relative to aqmBaseAddress and start address  */
+    baseAddress = freeSRAMAddress -
+	(aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET);
+		   
+    /* Verify base address aligned to a 16 word boundary */
+    if ((baseAddress % IX_QMGR_BASE_ADDR_16_WORD_ALIGN) != 0)
+    {
+	IX_QMGR_LOG_ERROR0("ixQMgrAqmIfQueCfgWrite () address is not on 16 word boundary\n");
+    }
+    /* Now convert it to a 16 word pointer as required by QUECONFIG register */
+    baseAddress >>= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
+    
+    
+    qCfg |= (baseAddress << IX_QMGR_Q_CONFIG_BADDR_OFFSET);
+
+
+    cfgAddress = (UINT32*)(aqmBaseAddress +
+			IX_QMGR_Q_CONFIG_ADDR_GET(qId));
+
+
+    /* NOTE: High and Low watermarks are set to zero */
+    ixQMgrAqmIfWordWrite (cfgAddress, qCfg);
+}
+
+void
+ixQMgrAqmIfQueCfgRead (IxQMgrQId qId,
+		       unsigned int numEntries,
+		       UINT32 *baseAddress,
+		       unsigned int *ne,
+		       unsigned int *nf,
+		       UINT32 *readPtr,
+		       UINT32 *writePtr)
+{
+    UINT32 qcfg;
+    UINT32 *cfgAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
+    unsigned int qEntrySizeInwords;
+    unsigned int qSizeInWords;
+    UINT32 *readPtr_ = NULL;
+	
+    /* Read the queue configuration register */
+    ixQMgrAqmIfWordRead (cfgAddress, &qcfg);
+    
+    /* Extract the base address */
+    *baseAddress = (UINT32)((qcfg & IX_QMGR_BADDR_MASK) >>
+			    (IX_QMGR_Q_CONFIG_BADDR_OFFSET));
+
+    /* Base address is a 16 word pointer from the start of AQM SRAM.
+     * Convert to absolute word address.
+     */
+    *baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
+    *baseAddress += (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET;
+
+    /*
+     * Extract the watermarks. 0->0 entries, 1->1 entries, 2->2 entries, 3->4 entries......
+     * If ne > 0 ==> neInEntries = 2^(ne - 1)
+     * If ne == 0 ==> neInEntries = 0
+     * The same applies.
+     */
+    *ne = ((qcfg) >> (IX_QMGR_Q_CONFIG_NE_OFFSET)) & IX_QMGR_NE_MASK;
+    *nf = ((qcfg) >> (IX_QMGR_Q_CONFIG_NF_OFFSET)) & IX_QMGR_NF_MASK;
+
+    if (0 != *ne)
+    {
+	*ne = 1 << (*ne - 1);	
+    }
+    if (0 != *nf)
+    {
+	*nf = 1 << (*nf - 1);
+    }
+
+    /* Get the queue entry size in words */
+    qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
+
+    /* Get the queue size in words */
+    qSizeInWords = ixQMgrQSizeInWordsGet (qId);
+
+    ixQMgrAqmIfEntryAddressGet (0/* Entry 0. i.e the readPtr*/,
+				qcfg,
+				qEntrySizeInwords,
+				qSizeInWords,
+				&readPtr_);
+    *readPtr = (UINT32)readPtr_;
+    *readPtr -= (UINT32)aqmBaseAddress;/* Offset, not absolute address */
+
+    *writePtr = (qcfg >> IX_QMGR_Q_CONFIG_WRPTR_OFFSET) & IX_QMGR_WRPTR_MASK;
+    *writePtr = *baseAddress + (*writePtr * (IX_QMGR_NUM_BYTES_PER_WORD));
+    return;
+}
+
+unsigned
+ixQMgrAqmIfLog2 (unsigned number)
+{
+    unsigned count = 0;
+
+    /*
+     * N.B. this function will return 0
+     * for ixQMgrAqmIfLog2 (0)
+     */
+    while (number/2)
+    {
+	number /=2;
+	count++;	
+    }
+
+    return count;
+}
+
+void ixQMgrAqmIfIntSrcSelReg0Bit3Set (void)
+{
+
+    volatile UINT32 *registerAddress;
+    UINT32 registerWord; 
+
+    /*
+     * Calculate the registerAddress
+     * multiple queues split accross registers
+     */
+    registerAddress = (UINT32*)(aqmBaseAddress +
+				IX_QMGR_INT0SRCSELREG0_OFFSET);    
+
+    /* Read the current data */
+    ixQMgrAqmIfWordRead (registerAddress, &registerWord);
+
+    /* Set the write bits */
+    registerWord |= (1<<IX_QMGR_INT0SRCSELREG0_BIT3) ;
+
+    /*
+     * Write the data
+     */
+    ixQMgrAqmIfWordWrite (registerAddress, registerWord);
+}  
+
+
+void
+ixQMgrAqmIfIntSrcSelWrite (IxQMgrQId qId,
+			  IxQMgrSourceId sourceId)
+{
+    ixQMgrAqmIfQRegisterBitsWrite (qId,
+				   IX_QMGR_INT0SRCSELREG0_OFFSET,
+				   IX_QMGR_INTSRC_NUM_QUE_PER_WORD,
+				   sourceId);
+}
+
+
+
+void
+ixQMgrAqmIfWatermarkSet (IxQMgrQId qId,
+			unsigned ne,
+			unsigned nf)
+{
+    volatile UINT32 *address = 0;
+    UINT32 value = 0;
+    unsigned aqmNeWatermark = 0;
+    unsigned aqmNfWatermark = 0;
+
+    address = (UINT32*)(aqmBaseAddress +
+		     IX_QMGR_Q_CONFIG_ADDR_GET(qId));
+
+    aqmNeWatermark = watermarkToAqmWatermark (ne);
+    aqmNfWatermark = watermarkToAqmWatermark (nf);
+
+    /* Read the current watermarks */
+    ixQMgrAqmIfWordRead (address, &value);
+
+    /* Clear out the old watermarks */
+    value &=  IX_QMGR_NE_NF_CLEAR_MASK;
+    
+    /* Generate the value to write */
+    value |= (aqmNeWatermark << IX_QMGR_Q_CONFIG_NE_OFFSET) |
+	(aqmNfWatermark << IX_QMGR_Q_CONFIG_NF_OFFSET); 
+
+    ixQMgrAqmIfWordWrite (address, value);
+
+}
+
+PRIVATE void
+ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex,
+			    UINT32 configRegWord,
+			    unsigned int qEntrySizeInwords,
+			    unsigned int qSizeInWords,
+			    UINT32 **address)
+{
+    UINT32 readPtr;
+    UINT32 baseAddress;
+    UINT32 *topOfAqmSram;
+
+    topOfAqmSram = ((UINT32 *)aqmBaseAddress + IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS);
+
+    /* Extract the base address */
+    baseAddress = (UINT32)((configRegWord & IX_QMGR_BADDR_MASK) >>
+			   (IX_QMGR_Q_CONFIG_BADDR_OFFSET));
+
+    /* Base address is a 16 word pointer from the start of AQM SRAM.
+     * Convert to absolute word address.
+     */
+    baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
+    baseAddress += ((UINT32)aqmBaseAddress + (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET);
+
+    /* Extract the read pointer. Read pointer is a word pointer */
+    readPtr = (UINT32)((configRegWord >>
+			IX_QMGR_Q_CONFIG_RDPTR_OFFSET)&IX_QMGR_RDPTR_MASK);
+
+    /* Read/Write pointers(word pointers)  are offsets from the queue buffer space base address.
+     * Calculate the absolute read pointer address. NOTE: Queues are circular buffers.
+     */
+    readPtr  = (readPtr + (entryIndex * qEntrySizeInwords)) & (qSizeInWords - 1); /* Mask by queue size */
+    *address = (UINT32 *)(baseAddress + (readPtr * (IX_QMGR_NUM_BYTES_PER_WORD)));
+
+    switch (qEntrySizeInwords)
+    {
+	case IX_QMGR_Q_ENTRY_SIZE1:
+	    IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY1_OFFSET) < topOfAqmSram);	    
+	    break;
+	case IX_QMGR_Q_ENTRY_SIZE2:
+	    IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY2_OFFSET) < topOfAqmSram);
+	    break;
+	case IX_QMGR_Q_ENTRY_SIZE4:
+	    IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY4_OFFSET) < topOfAqmSram);
+	    break;
+	default:
+	    IX_QMGR_LOG_ERROR0("Invalid Q Entry size passed to ixQMgrAqmIfEntryAddressGet");
+	    break;
+    }
+    
+}
+
+IX_STATUS
+ixQMgrAqmIfQPeek (IxQMgrQId qId,
+		  unsigned int entryIndex,
+		  unsigned int *entry)
+{
+    UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
+    UINT32 *entryAddress = NULL;
+    UINT32 configRegWordOnEntry;
+    UINT32 configRegWordOnExit;
+    unsigned int qEntrySizeInwords;
+    unsigned int qSizeInWords;
+
+    /* Get the queue entry size in words */
+    qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
+
+    /* Get the queue size in words */
+    qSizeInWords = ixQMgrQSizeInWordsGet (qId);
+
+    /* Read the config register */
+    ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry);
+
+    /* Get the entry address */
+    ixQMgrAqmIfEntryAddressGet (entryIndex,
+				configRegWordOnEntry,
+				qEntrySizeInwords,
+				qSizeInWords,
+				&entryAddress);
+
+    /* Get the lock or return busy */
+    if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId]))
+    {
+	return IX_FAIL;
+    }
+
+    while(qEntrySizeInwords--)
+    {
+	ixQMgrAqmIfWordRead (entryAddress++, entry++);
+    }
+
+    /* Release the lock */
+    ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]);
+
+    /* Read the config register */
+    ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit);
+
+    /* Check that the read and write pointers have not changed */
+    if (configRegWordOnEntry != configRegWordOnExit)
+    {
+	return IX_FAIL;
+    }
+
+    return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrAqmIfQPoke (IxQMgrQId qId,
+		  unsigned entryIndex,
+		  unsigned int *entry)
+{
+    UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId));
+    UINT32 *entryAddress = NULL;
+    UINT32 configRegWordOnEntry;
+    UINT32 configRegWordOnExit;
+    unsigned int qEntrySizeInwords;
+    unsigned int qSizeInWords;
+    
+    /* Get the queue entry size in words */
+    qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId);
+
+    /* Get the queue size in words */
+    qSizeInWords = ixQMgrQSizeInWordsGet (qId);
+
+    /* Read the config register */
+    ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry);
+
+    /* Get the entry address */
+    ixQMgrAqmIfEntryAddressGet (entryIndex,
+				configRegWordOnEntry,
+				qEntrySizeInwords,
+				qSizeInWords,
+				&entryAddress);
+
+    /* Get the lock or return busy */
+    if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId]))
+    {
+	return IX_FAIL;
+    }
+
+    /* Else read the entry directly from SRAM. This will not move the read pointer */
+    while(qEntrySizeInwords--)
+    {
+	ixQMgrAqmIfWordWrite (entryAddress++, *entry++);
+    }
+
+    /* Release the lock */
+    ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]);
+
+    /* Read the config register */
+    ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit);
+
+    /* Check that the read and write pointers have not changed */
+    if (configRegWordOnEntry != configRegWordOnExit)
+    {
+	return IX_FAIL;
+    }
+
+    return IX_SUCCESS;
+}
+
+PRIVATE unsigned
+watermarkToAqmWatermark (IxQMgrWMLevel watermark )
+{
+    unsigned aqmWatermark = 0;
+
+    /*
+     * Watermarks 0("000"),1("001"),2("010"),4("011"),
+     * 8("100"),16("101"),32("110"),64("111")
+     */
+    aqmWatermark = ixQMgrAqmIfLog2 (watermark * 2);
+    
+    return aqmWatermark;
+}
+
+PRIVATE unsigned
+entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize)
+{
+    /* entrySize  1("00"),2("01"),4("10") */
+    return (ixQMgrAqmIfLog2 (entrySize));
+}
+
+PRIVATE unsigned
+bufferSizeToAqmBufferSize (unsigned bufferSizeInWords)
+{
+    /* bufferSize 16("00"),32("01),64("10"),128("11") */
+    return (ixQMgrAqmIfLog2 (bufferSizeInWords / IX_QMGR_MIN_BUFFER_SIZE));
+}
+
+/*
+ * Reset AQM registers to default values.
+ */
+PRIVATE void
+ixQMgrAqmIfRegistersReset (void)
+{
+    volatile UINT32 *qConfigWordAddress = NULL;
+    unsigned int i;
+
+    /*
+     * Need to initialize AQM hardware registers to an initial
+     * value as init may have been called as a result of a soft
+     * reset. i.e. soft reset does not reset hardware registers.
+     */
+
+    /* Reset queues 0..31 status registers 0..3 */
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT0_OFFSET), 
+			 IX_QMGR_QUELOWSTAT_RESET_VALUE);
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT1_OFFSET), 
+			 IX_QMGR_QUELOWSTAT_RESET_VALUE);
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT2_OFFSET), 
+			 IX_QMGR_QUELOWSTAT_RESET_VALUE);
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT3_OFFSET), 
+			 IX_QMGR_QUELOWSTAT_RESET_VALUE);
+
+    /* Reset underflow/overflow status registers 0..1 */
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT0_OFFSET), 
+			 IX_QMGR_QUEUOSTAT_RESET_VALUE);
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT1_OFFSET), 
+			 IX_QMGR_QUEUOSTAT_RESET_VALUE);
+    
+    /* Reset queues 32..63 nearly empty status registers */
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET),
+			 IX_QMGR_QUEUPPSTAT0_RESET_VALUE);
+
+    /* Reset queues 32..63 full status registers */
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET),
+			 IX_QMGR_QUEUPPSTAT1_RESET_VALUE);
+
+    /* Reset int0 status flag source select registers 0..3 */
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG0_OFFSET),
+			 IX_QMGR_INT0SRCSELREG_RESET_VALUE);
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG1_OFFSET),
+			 IX_QMGR_INT0SRCSELREG_RESET_VALUE);
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG2_OFFSET),
+			 IX_QMGR_INT0SRCSELREG_RESET_VALUE);
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG3_OFFSET),
+			 IX_QMGR_INT0SRCSELREG_RESET_VALUE);
+	 
+    /* Reset queue interrupt enable register 0..1 */
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET),
+			 IX_QMGR_QUEIEREG_RESET_VALUE);
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET),
+			 IX_QMGR_QUEIEREG_RESET_VALUE);
+
+    /* Reset queue interrupt register 0..1 */
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG0_OFFSET),
+			 IX_QMGR_QINTREG_RESET_VALUE);
+    ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG1_OFFSET),
+			 IX_QMGR_QINTREG_RESET_VALUE);
+
+    /* Reset queue configuration words 0..63 */
+    qConfigWordAddress = (UINT32 *)(aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET);
+    for (i = 0; i < (IX_QMGR_QUECONFIG_SIZE / sizeof(UINT32)); i++)
+    {
+	ixQMgrAqmIfWordWrite(qConfigWordAddress,
+			     IX_QMGR_QUECONFIG_RESET_VALUE);
+	/* Next word */
+	qConfigWordAddress++;
+    }
+}
+
diff --git a/marvell/uboot/drivers/net/npe/IxQMgrDispatcher.c b/marvell/uboot/drivers/net/npe/IxQMgrDispatcher.c
new file mode 100644
index 0000000..2baeaaf
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxQMgrDispatcher.c
@@ -0,0 +1,1320 @@
+/**
+ * @file    IxQMgrDispatcher.c
+ *
+ * @author Intel Corporation
+ * @date    20-Dec-2001
+ *    
+ * @brief   This file contains the implementation of the Dispatcher sub component
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * User defined include files.
+ */
+#include "IxQMgr.h"
+#include "IxQMgrAqmIf_p.h"
+#include "IxQMgrQCfg_p.h"
+#include "IxQMgrDispatcher_p.h"
+#include "IxQMgrLog_p.h"
+#include "IxQMgrDefines_p.h"
+#include "IxFeatureCtrl.h"
+#include "IxOsal.h"
+
+
+
+/*
+ * #defines and macros used in this file.
+ */
+
+
+/*
+ * This constant is used to indicate the number of priority levels supported
+ */
+#define IX_QMGR_NUM_PRIORITY_LEVELS 3
+
+/* 
+ * This constant is used to set the size of the array of status words
+ */
+#define MAX_Q_STATUS_WORDS      4
+
+/*
+ * This macro is used to check if a given priority is valid
+ */
+#define IX_QMGR_DISPATCHER_PRIORITY_CHECK(priority) \
+(((priority) >= IX_QMGR_Q_PRIORITY_0) && ((priority) <= IX_QMGR_Q_PRIORITY_2))
+
+/*
+ * This macto is used to check that a given interrupt source is valid
+ */
+#define IX_QMGR_DISPATCHER_SOURCE_ID_CHECK(srcSel) \
+(((srcSel) >= IX_QMGR_Q_SOURCE_ID_E) && ((srcSel) <= IX_QMGR_Q_SOURCE_ID_NOT_F))
+
+/*
+ * Number of times a dummy callback is called before logging a trace
+ * message
+ */
+#define LOG_THROTTLE_COUNT 1000000
+
+/* Priority tables limits */
+#define IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX (0)
+#define IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX (16)
+#define IX_QMGR_MAX_LOW_QUE_PRIORITY_TABLE_INDEX (31)
+#define IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX (32)
+#define IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX (48)
+#define IX_QMGR_MAX_UPP_QUE_PRIORITY_TABLE_INDEX (63)
+ 
+/*
+ * This macro is used to check if a given callback type is valid
+ */
+#define IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type) \
+            (((type) >= IX_QMGR_TYPE_REALTIME_OTHER) && \
+            ((type) <= IX_QMGR_TYPE_REALTIME_SPORADIC))
+
+/* 
+ * define max index in lower queue to use in loops 
+ */
+#define IX_QMGR_MAX_LOW_QUE_TABLE_INDEX (31)
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/*
+ * Information on a queue needed by the Dispatcher
+ */
+typedef struct 
+{
+    IxQMgrCallback callback;       /* Notification callback                  */
+    IxQMgrCallbackId callbackId;   /* Notification callback identifier       */
+    unsigned dummyCallbackCount;   /* Number of times runs of dummy callback */
+    IxQMgrPriority priority;       /* Dispatch priority                      */
+    unsigned int statusWordOffset; /* Offset to the status word to check     */
+    UINT32 statusMask;             /* Status mask                            */    
+    UINT32 statusCheckValue;       /* Status check value                     */
+    UINT32 intRegCheckMask;	   /* Interrupt register check mask          */
+} IxQMgrQInfo;
+
+/*
+ * Variable declarations global to this file. Externs are followed by
+ * statics.
+ */
+
+/* 
+ * Flag to keep record of what dispatcher set in featureCtrl when ixQMgrInit()
+ * is called. This is needed because it is possible that a client might
+ * change whether the live lock prevention dispatcher is used between
+ * calls to ixQMgrInit() and ixQMgrDispatcherLoopGet(). 
+ */
+PRIVATE IX_STATUS ixQMgrOrigB0Dispatcher = IX_FEATURE_CTRL_COMPONENT_ENABLED;
+
+/* 
+ * keep record of Q types - not in IxQMgrQInfo for performance as
+ * it is only used with ixQMgrDispatcherLoopRunB0LLP()
+ */
+PRIVATE IxQMgrType ixQMgrQTypes[IX_QMGR_MAX_NUM_QUEUES];
+
+/*
+ * This array contains a list of queue identifiers ordered by priority. The table
+ * is split logically between queue identifiers 0-31 and 32-63.
+ */
+static IxQMgrQId priorityTable[IX_QMGR_MAX_NUM_QUEUES];
+
+/*
+ * This flag indicates to the dispatcher that the priority table needs to be rebuilt.
+ */
+static BOOL rebuildTable = false;
+
+/* Dispatcher statistics */
+static IxQMgrDispatcherStats dispatcherStats;
+
+/* Table of queue information */
+static IxQMgrQInfo dispatchQInfo[IX_QMGR_MAX_NUM_QUEUES];
+
+/* Masks use to identify the first queues in the priority tables 
+*  when comparing with the interrupt register
+*/
+static unsigned int lowPriorityTableFirstHalfMask;
+static unsigned int uppPriorityTableFirstHalfMask;
+
+/*
+ * Static function prototypes
+ */
+
+/*
+ * This function is the default callback for all queues
+ */
+PRIVATE void
+dummyCallback (IxQMgrQId qId,	      
+	       IxQMgrCallbackId cbId);
+
+PRIVATE void
+ixQMgrDispatcherReBuildPriorityTable (void);
+
+/*
+ * Function definitions.
+ */
+void
+ixQMgrDispatcherInit (void)
+{
+    int i;
+    IxFeatureCtrlProductId productId = 0;
+    IxFeatureCtrlDeviceId deviceId = 0;
+    BOOL stickyIntSilicon = true;
+
+    /* Set default priorities */
+    for (i=0; i< IX_QMGR_MAX_NUM_QUEUES; i++)
+    {
+	dispatchQInfo[i].callback = dummyCallback;
+	dispatchQInfo[i].callbackId = 0;
+	dispatchQInfo[i].dummyCallbackCount = 0;
+	dispatchQInfo[i].priority = IX_QMGR_Q_PRIORITY_2;
+	dispatchQInfo[i].statusWordOffset = 0;
+	dispatchQInfo[i].statusCheckValue = 0;
+	dispatchQInfo[i].statusMask = 0;  
+        /* 
+	 * There are two interrupt registers, 32 bits each. One for the lower
+	 * queues(0-31) and one for the upper queues(32-63). Therefore need to
+	 * mod by 32 i.e the min upper queue identifier.
+	 */
+	dispatchQInfo[i].intRegCheckMask = (1<<(i%(IX_QMGR_MIN_QUEUPP_QID)));
+
+        /* 
+         * Set the Q types - will only be used with livelock 
+         */
+        ixQMgrQTypes[i] = IX_QMGR_TYPE_REALTIME_OTHER;
+
+	/* Reset queue statistics */
+	dispatcherStats.queueStats[i].callbackCnt = 0;
+	dispatcherStats.queueStats[i].priorityChangeCnt = 0;
+	dispatcherStats.queueStats[i].intNoCallbackCnt = 0;
+	dispatcherStats.queueStats[i].intLostCallbackCnt = 0;
+        dispatcherStats.queueStats[i].notificationEnabled = false;
+        dispatcherStats.queueStats[i].srcSel = 0;
+
+    }
+
+    /* Priority table. Order the table from queue 0 to 63 */
+    ixQMgrDispatcherReBuildPriorityTable();
+
+    /* Reset statistics */
+    dispatcherStats.loopRunCnt = 0;
+
+    /* Get the device ID for the underlying silicon */
+    deviceId = ixFeatureCtrlDeviceRead();
+    
+    /* Get the product ID for the underlying silicon */
+    productId = ixFeatureCtrlProductIdRead();
+
+    /* 
+     * Check featureCtrl to see if Livelock prevention is required 
+     */
+    ixQMgrOrigB0Dispatcher = ixFeatureCtrlSwConfigurationCheck( 
+                                 IX_FEATURECTRL_ORIGB0_DISPATCHER);
+
+    /*
+     * Check if the silicon supports the sticky interrupt feature.
+     * IF (IXP42X AND A0) -> No sticky interrupt feature supported 
+     */
+    if ((IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X == 
+        (IX_FEATURE_CTRL_DEVICE_TYPE_MASK & deviceId)) &&
+        (IX_FEATURE_CTRL_SILICON_TYPE_A0 == 
+        (IX_FEATURE_CTRL_SILICON_STEPPING_MASK & productId))) 
+    {
+       stickyIntSilicon = false;
+    }
+
+    /*
+     * IF user wants livelock prev option AND silicon supports sticky interrupt 
+     * feature -> enable the sticky interrupt bit
+     */
+    if ((IX_FEATURE_CTRL_SWCONFIG_DISABLED == ixQMgrOrigB0Dispatcher) &&
+         stickyIntSilicon)  
+    {
+        ixQMgrStickyInterruptRegEnable();
+    }
+}
+
+IX_STATUS
+ixQMgrDispatcherPrioritySet (IxQMgrQId qId,
+			     IxQMgrPriority priority)
+{   
+    int ixQMgrLockKey;
+
+    if (!ixQMgrQIsConfigured(qId))
+    {
+	return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+    
+    if (!IX_QMGR_DISPATCHER_PRIORITY_CHECK(priority))
+    {
+	return IX_QMGR_Q_INVALID_PRIORITY;
+    }
+
+    ixQMgrLockKey = ixOsalIrqLock();
+    
+    /* Change priority */
+    dispatchQInfo[qId].priority = priority;
+    /* Set flag */
+    rebuildTable = true;
+
+    ixOsalIrqUnlock(ixQMgrLockKey);
+
+#ifndef NDEBUG
+    /* Update statistics */
+    dispatcherStats.queueStats[qId].priorityChangeCnt++;
+#endif
+
+    return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrNotificationCallbackSet (IxQMgrQId qId,
+			       IxQMgrCallback callback,
+			       IxQMgrCallbackId callbackId)
+{
+    if (!ixQMgrQIsConfigured(qId))
+    {
+	return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+
+    if (NULL == callback)
+    {
+	/* Reset to dummy callback */
+	dispatchQInfo[qId].callback = dummyCallback;
+	dispatchQInfo[qId].dummyCallbackCount = 0;
+	dispatchQInfo[qId].callbackId = 0;
+    }
+    else 
+    {
+	dispatchQInfo[qId].callback = callback;
+	dispatchQInfo[qId].callbackId = callbackId;
+    }
+
+    return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrNotificationEnable (IxQMgrQId qId, 
+			  IxQMgrSourceId srcSel)
+{
+    IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */
+    IxQMgrQStatus qStatusOnExit; /* to this function               */
+    int ixQMgrLockKey;
+
+#ifndef NDEBUG
+    if (!ixQMgrQIsConfigured (qId))
+    {
+	return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+
+    if ((qId < IX_QMGR_MIN_QUEUPP_QID) &&
+       !IX_QMGR_DISPATCHER_SOURCE_ID_CHECK(srcSel))
+    {
+	/* QId 0-31 source id invalid */
+	return IX_QMGR_INVALID_INT_SOURCE_ID;
+    }
+
+    if ((IX_QMGR_Q_SOURCE_ID_NE != srcSel) &&
+	(qId >= IX_QMGR_MIN_QUEUPP_QID))
+    {
+	/*
+	 * For queues 32-63 the interrupt source is fixed to the Nearly
+	 * Empty status flag and therefore should have a srcSel of NE.
+	 */
+	return IX_QMGR_INVALID_INT_SOURCE_ID;
+    }
+#endif
+
+#ifndef NDEBUG
+    dispatcherStats.queueStats[qId].notificationEnabled = true;
+    dispatcherStats.queueStats[qId].srcSel = srcSel;
+#endif
+
+    /* Get the current queue status */
+    ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry);
+  
+    /* 
+     * Enabling interrupts results in Read-Modify-Write
+     * so need critical section
+     */
+
+    ixQMgrLockKey = ixOsalIrqLock();
+
+    /* Calculate the checkMask and checkValue for this q */
+    ixQMgrAqmIfQStatusCheckValsCalc (qId,
+				     srcSel,
+				     &dispatchQInfo[qId].statusWordOffset,
+				     &dispatchQInfo[qId].statusCheckValue,
+				     &dispatchQInfo[qId].statusMask);
+
+
+    /* Set the interrupt source is this queue is in the range 0-31 */
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {
+	ixQMgrAqmIfIntSrcSelWrite (qId, srcSel);
+    }
+
+    /* Enable the interrupt */
+    ixQMgrAqmIfQInterruptEnable (qId);
+
+    ixOsalIrqUnlock(ixQMgrLockKey);
+    
+    /* Get the current queue status */
+    ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit);
+  
+    /* If the status has changed return a warning */
+    if (qStatusOnEntry != qStatusOnExit)
+    {
+	return IX_QMGR_WARNING;
+    }
+    
+    return IX_SUCCESS;
+}
+
+
+IX_STATUS
+ixQMgrNotificationDisable (IxQMgrQId qId)
+{
+    int ixQMgrLockKey;
+
+#ifndef NDEBUG
+    /* Validate parameters */
+    if (!ixQMgrQIsConfigured (qId))
+    {
+	return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+#endif
+  
+    /* 
+     * Enabling interrupts results in Read-Modify-Write
+     * so need critical section
+     */
+#ifndef NDEBUG
+    dispatcherStats.queueStats[qId].notificationEnabled = false;
+#endif
+
+    ixQMgrLockKey = ixOsalIrqLock();
+
+    ixQMgrAqmIfQInterruptDisable (qId);
+    
+    ixOsalIrqUnlock(ixQMgrLockKey);
+
+    return IX_SUCCESS;    
+}
+
+void 
+ixQMgrStickyInterruptRegEnable(void)
+{
+ /* Use Aqm If function to set Interrupt Register0 Bit-3 */ 
+ ixQMgrAqmIfIntSrcSelReg0Bit3Set ();   
+}
+
+#if !defined __XSCALE__ || defined __linux
+
+/* Count the number of leading zero bits in a word,
+ * and return the same value than the CLZ instruction.
+ *
+ * word (in)    return value (out)
+ * 0x80000000   0
+ * 0x40000000   1
+ * ,,,          ,,,
+ * 0x00000002   30
+ * 0x00000001   31
+ * 0x00000000   32
+ *
+ * The C version of this function is used as a replacement 
+ * for system not providing the equivalent of the CLZ 
+ * assembly language instruction.
+ *
+ * Note that this version is big-endian
+ */
+unsigned int
+ixQMgrCountLeadingZeros(UINT32 word)
+{
+  unsigned int leadingZerosCount = 0;
+
+  if (word == 0)
+  {
+      return 32;
+  }
+  /* search the first bit set by testing the MSB and shifting the input word */
+  while ((word & 0x80000000) == 0)
+  {
+      word <<= 1;
+      leadingZerosCount++;
+  }
+  return leadingZerosCount;
+}
+#endif /* not  __XSCALE__ or __linux */
+
+void
+ixQMgrDispatcherLoopGet (IxQMgrDispatcherFuncPtr *qDispatcherFuncPtr)
+{
+  IxFeatureCtrlProductId productId = 0;
+  IxFeatureCtrlDeviceId deviceId = 0;
+  
+  /* Get the device ID for the underlying silicon */
+  deviceId = ixFeatureCtrlDeviceRead();
+
+  /* Get the product ID for the underlying silicon */
+  productId = ixFeatureCtrlProductIdRead ();
+
+  /* IF (IXP42X AND A0 silicon) -> use ixQMgrDispatcherLoopRunA0 */
+  if ((IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X ==
+      (IX_FEATURE_CTRL_DEVICE_TYPE_MASK & deviceId)) &&
+      (IX_FEATURE_CTRL_SILICON_TYPE_A0 ==  
+      (IX_FEATURE_CTRL_SILICON_STEPPING_MASK & productId)))  
+  {
+    /*For IXP42X A0 silicon */
+    *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunA0 ;
+  } 
+  else /*For IXP42X B0 or IXP46X silicon*/ 
+  { 
+    if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixQMgrOrigB0Dispatcher)
+    {
+        /* Default for IXP42X B0 and IXP46X silicon */
+        *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunB0;
+    }
+    else 
+    {
+        /* FeatureCtrl indicated that livelock dispatcher be used */
+        *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunB0LLP;
+    }
+  }
+}
+
+void
+ixQMgrDispatcherLoopRunA0 (IxQMgrDispatchGroup group)
+{
+    UINT32 intRegVal;                /* Interrupt reg val */
+    UINT32 intRegValAfterWrite;      /* Interrupt reg val after writing back */
+    UINT32 intRegCheckMask;          /* Mask for checking interrupt bits */
+    UINT32 qStatusWordsB4Write[MAX_Q_STATUS_WORDS];  /* Status b4 interrupt write */
+    UINT32 qStatusWordsAfterWrite[MAX_Q_STATUS_WORDS]; /* Status after interrupt write */
+    IxQMgrQInfo *currDispatchQInfo;
+    BOOL statusChangeFlag;
+
+    int priorityTableIndex;/* Priority table index */
+    int qIndex;            /* Current queue being processed */
+    int endIndex;          /* Index of last queue to process */
+
+#ifndef NDEBUG
+    IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || 
+	      (group == IX_QMGR_QUELOW_GROUP));
+#endif
+
+    /* Read Q status registers before interrupt status read/write */
+    ixQMgrAqmIfQStatusRegsRead (group, qStatusWordsB4Write);
+
+    /* Read the interrupt register */
+    ixQMgrAqmIfQInterruptRegRead (group, &intRegVal);
+
+    /* No bit set : nothing to process (the reaminder of the algorithm is
+    * based on the fact that the interrupt register value contains at
+    * least one bit set
+    */
+    if (intRegVal == 0) 
+    {
+#ifndef NDEBUG
+	/* Update statistics */
+	dispatcherStats.loopRunCnt++;
+#endif
+
+	/* Rebuild the priority table if needed */
+	if (rebuildTable)
+	{
+	    ixQMgrDispatcherReBuildPriorityTable ();
+	}
+
+	return;
+    }
+   
+    /* Write it back to clear the interrupt */
+    ixQMgrAqmIfQInterruptRegWrite (group, intRegVal);
+
+    /* Read Q status registers after interrupt status read/write */
+    ixQMgrAqmIfQStatusRegsRead (group, qStatusWordsAfterWrite);
+ 
+    /* get the first queue Id from the interrupt register value */
+    qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal);
+
+    /* check if any change occured during hw register modifications */ 
+    if (IX_QMGR_QUELOW_GROUP == group)
+    {
+	statusChangeFlag = 
+	    (qStatusWordsB4Write[0] != qStatusWordsAfterWrite[0]) ||
+	    (qStatusWordsB4Write[1] != qStatusWordsAfterWrite[1]) ||
+	    (qStatusWordsB4Write[2] != qStatusWordsAfterWrite[2]) ||
+	    (qStatusWordsB4Write[3] != qStatusWordsAfterWrite[3]);
+    }
+    else
+    {
+	statusChangeFlag = 
+	    (qStatusWordsB4Write[0] != qStatusWordsAfterWrite[0]);
+	/* Set the queue range based on the queue group to proccess */
+	qIndex += IX_QMGR_MIN_QUEUPP_QID;
+    }
+
+    if (statusChangeFlag == false)
+    {
+	/* check if the interrupt register contains 
+	 * only 1 bit set (happy day scenario)
+	 */
+	currDispatchQInfo = &dispatchQInfo[qIndex];
+	if (intRegVal == currDispatchQInfo->intRegCheckMask)
+	{
+	    /* only 1 queue event triggered a notification *
+	     * Call the callback function for this queue 
+	     */
+	    currDispatchQInfo->callback (qIndex,
+					 currDispatchQInfo->callbackId);  
+#ifndef NDEBUG
+	    /* Update statistics */
+	    dispatcherStats.queueStats[qIndex].callbackCnt++;
+#endif
+	}
+	else 
+	{
+	    /* the event is triggered by more than 1 queue, 
+	     * the queue search will be starting from the beginning
+	     * or the middle of the priority table
+	     *
+	     * the serach will end when all the bits of the interrupt
+	     * register are cleared. There is no need to maintain
+	     * a seperate value and test it at each iteration.
+	     */
+	    if (IX_QMGR_QUELOW_GROUP == group)
+	    {
+		/* check if any bit related to queues in the first
+		 * half of the priority table is set
+		 */
+		if (intRegVal & lowPriorityTableFirstHalfMask)
+		{
+		    priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
+		}
+		else
+		{
+		    priorityTableIndex = IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX;
+		}
+	    }
+	    else 
+	    {
+		/* check if any bit related to queues in the first
+		 * half of the priority table is set
+		 */
+		if (intRegVal & uppPriorityTableFirstHalfMask)
+		{
+		    priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;
+		}
+		else
+		{
+		    priorityTableIndex = IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX;
+		}
+	    }
+	    
+	    /* iterate following the priority table until all the bits 
+	     * of the interrupt register are cleared.
+	     */
+	    do
+	    {
+		qIndex = priorityTable[priorityTableIndex++];
+		currDispatchQInfo = &dispatchQInfo[qIndex];
+		intRegCheckMask = currDispatchQInfo->intRegCheckMask;
+		
+		/* If this queue caused this interrupt to be raised */
+		if (intRegVal & intRegCheckMask)
+		{
+		    /* Call the callback function for this queue */
+		    currDispatchQInfo->callback (qIndex,
+						 currDispatchQInfo->callbackId);
+#ifndef NDEBUG
+		    /* Update statistics */
+		    dispatcherStats.queueStats[qIndex].callbackCnt++;
+#endif
+		    
+		    /* Clear the interrupt register bit */
+		    intRegVal &= ~intRegCheckMask;
+		}
+	    }
+	    while(intRegVal);
+	}
+    }
+    else
+    {
+    /* A change in queue status occured during the hw interrupt
+     * register update. To maintain the interrupt consistency, it
+     * is necessary to iterate through all queues of the queue group.
+     */
+
+    /* Read interrupt status again */
+    ixQMgrAqmIfQInterruptRegRead (group, &intRegValAfterWrite);
+
+    if (IX_QMGR_QUELOW_GROUP == group)
+    {
+	priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
+	endIndex = IX_QMGR_MAX_LOW_QUE_PRIORITY_TABLE_INDEX;
+    }
+    else
+    {
+	priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;
+	endIndex = IX_QMGR_MAX_UPP_QUE_PRIORITY_TABLE_INDEX;
+    }
+
+    for ( ; priorityTableIndex<=endIndex; priorityTableIndex++)
+    {
+	qIndex = priorityTable[priorityTableIndex];
+	currDispatchQInfo = &dispatchQInfo[qIndex];
+	intRegCheckMask = currDispatchQInfo->intRegCheckMask;
+
+	/* If this queue caused this interrupt to be raised */
+	if (intRegVal & intRegCheckMask)
+	{  
+	    /* Call the callback function for this queue */
+	    currDispatchQInfo->callback (qIndex,
+					 currDispatchQInfo->callbackId);
+#ifndef NDEBUG
+	    /* Update statistics */
+	    dispatcherStats.queueStats[qIndex].callbackCnt++;
+#endif
+	    
+	} /* if (intRegVal .. */
+
+	/* 
+	 * If interrupt bit is set in intRegValAfterWrite don't
+	 * proceed as this will be caught in next interrupt
+	 */
+	else if ((intRegValAfterWrite & intRegCheckMask) == 0)
+	{
+	    /* Check if an interrupt was lost for this Q */
+	    if (ixQMgrAqmIfQStatusCheck(qStatusWordsB4Write,
+					qStatusWordsAfterWrite,
+					currDispatchQInfo->statusWordOffset,
+					currDispatchQInfo->statusCheckValue,
+					currDispatchQInfo->statusMask))
+	    {
+		/* Call the callback function for this queue */
+		currDispatchQInfo->callback (qIndex, 
+					     dispatchQInfo[qIndex].callbackId);                 
+#ifndef NDEBUG
+		/* Update statistics */
+		dispatcherStats.queueStats[qIndex].callbackCnt++;
+		dispatcherStats.queueStats[qIndex].intLostCallbackCnt++;
+#endif
+	    } /* if ixQMgrAqmIfQStatusCheck(.. */
+	} /* else if ((intRegValAfterWrite ... */
+    } /* for (priorityTableIndex=0 ... */
+    }
+
+    /* Rebuild the priority table if needed */
+    if (rebuildTable)
+    {
+	ixQMgrDispatcherReBuildPriorityTable ();
+    }
+
+#ifndef NDEBUG
+    /* Update statistics */
+    dispatcherStats.loopRunCnt++;
+#endif
+}
+
+
+
+void
+ixQMgrDispatcherLoopRunB0 (IxQMgrDispatchGroup group)
+{
+    UINT32 intRegVal;                /* Interrupt reg val */
+    UINT32 intRegCheckMask;          /* Mask for checking interrupt bits */
+    IxQMgrQInfo *currDispatchQInfo;
+
+
+    int priorityTableIndex; /* Priority table index */
+    int qIndex;             /* Current queue being processed */
+
+#ifndef NDEBUG
+    IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) ||
+              (group == IX_QMGR_QUELOW_GROUP));
+    IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || 
+	      (group == IX_QMGR_QUELOW_GROUP));
+#endif
+
+    /* Read the interrupt register */
+    ixQMgrAqmIfQInterruptRegRead (group, &intRegVal);
+
+
+    /* No queue has interrupt register set */
+    if (intRegVal != 0)
+    {
+
+            /* Write it back to clear the interrupt */
+            ixQMgrAqmIfQInterruptRegWrite (group, intRegVal);
+
+            /* get the first queue Id from the interrupt register value */
+            qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal);
+
+            if (IX_QMGR_QUEUPP_GROUP == group)
+            {
+                /* Set the queue range based on the queue group to proccess */
+                qIndex += IX_QMGR_MIN_QUEUPP_QID;
+            }
+
+            /* check if the interrupt register contains
+             * only 1 bit set
+             * For example:
+             *                                        intRegVal = 0x0010
+             *               currDispatchQInfo->intRegCheckMask = 0x0010
+             *    intRegVal == currDispatchQInfo->intRegCheckMask is true.
+             */
+             currDispatchQInfo = &dispatchQInfo[qIndex];
+             if (intRegVal == currDispatchQInfo->intRegCheckMask)
+             {
+                /* only 1 queue event triggered a notification *
+                 * Call the callback function for this queue
+                 */
+                currDispatchQInfo->callback (qIndex,
+                                     currDispatchQInfo->callbackId);
+#ifndef NDEBUG
+                /* Update statistics */
+                dispatcherStats.queueStats[qIndex].callbackCnt++;
+#endif
+             }
+             else
+             {
+                 /* the event is triggered by more than 1 queue,
+                  * the queue search will be starting from the beginning
+                  * or the middle of the priority table
+                  *
+                  * the serach will end when all the bits of the interrupt
+                  * register are cleared. There is no need to maintain
+                  * a seperate value and test it at each iteration.
+                  */
+                 if (IX_QMGR_QUELOW_GROUP == group)
+                 {
+                     /* check if any bit related to queues in the first
+                      * half of the priority table is set
+                      */
+                     if (intRegVal & lowPriorityTableFirstHalfMask)
+                     {
+                         priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
+                     }
+                     else
+                     {
+                         priorityTableIndex = IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX;
+                     }
+                 }
+                else
+                 {
+                     /* check if any bit related to queues in the first
+                      * half of the priority table is set
+                      */
+                     if (intRegVal & uppPriorityTableFirstHalfMask)
+                     {
+                         priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;
+                     }
+                     else
+                     {
+                         priorityTableIndex = IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX;
+                     }
+                 }
+
+                 /* iterate following the priority table until all the bits
+                  * of the interrupt register are cleared.
+                  */
+                 do
+                 {
+                     qIndex = priorityTable[priorityTableIndex++];
+                     currDispatchQInfo = &dispatchQInfo[qIndex];
+                     intRegCheckMask = currDispatchQInfo->intRegCheckMask;
+
+                     /* If this queue caused this interrupt to be raised */
+                     if (intRegVal & intRegCheckMask)
+                     {
+                         /* Call the callback function for this queue */
+                         currDispatchQInfo->callback (qIndex,
+                                              currDispatchQInfo->callbackId);
+#ifndef NDEBUG
+                         /* Update statistics */
+                         dispatcherStats.queueStats[qIndex].callbackCnt++;
+#endif
+
+                         /* Clear the interrupt register bit */
+                         intRegVal &= ~intRegCheckMask;
+                     }
+                  }
+                  while(intRegVal);
+             } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */
+     } /* End of intRegVal != 0 */
+
+#ifndef NDEBUG
+    /* Update statistics */
+    dispatcherStats.loopRunCnt++;
+#endif
+
+    /* Rebuild the priority table if needed */
+    if (rebuildTable)
+    {
+        ixQMgrDispatcherReBuildPriorityTable ();
+    }
+}
+
+void
+ixQMgrDispatcherLoopRunB0LLP (IxQMgrDispatchGroup group)
+{
+    UINT32 intRegVal =0;                /* Interrupt reg val */
+    UINT32 intRegCheckMask;          /* Mask for checking interrupt bits */
+    IxQMgrQInfo *currDispatchQInfo;
+
+    int priorityTableIndex; /* Priority table index */
+    int qIndex;             /* Current queue being processed */
+
+    UINT32 intRegValCopy = 0;
+    UINT32 intEnableRegVal = 0;
+    UINT8 i = 0;
+
+#ifndef NDEBUG
+    IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) ||
+              (group == IX_QMGR_QUELOW_GROUP));
+#endif
+
+    /* Read the interrupt register */
+    ixQMgrAqmIfQInterruptRegRead (group, &intRegVal);
+
+    /* 
+     * mask any interrupts that are not enabled 
+     */
+    ixQMgrAqmIfQInterruptEnableRegRead (group, &intEnableRegVal);
+    intRegVal &= intEnableRegVal;
+
+    /* No queue has interrupt register set */
+    if (intRegVal != 0)
+    {
+        if (IX_QMGR_QUELOW_GROUP == group)
+        {
+            /*
+             * As the sticky bit is set, the interrupt register will 
+             * not clear if write back at this point because the condition
+             * has not been cleared. Take a copy and write back later after
+             * the condition has been cleared
+             */
+            intRegValCopy = intRegVal;
+        }
+        else
+        {
+            /* no sticky for upper Q's, so write back now */
+            ixQMgrAqmIfQInterruptRegWrite (group, intRegVal);
+        }
+
+        /* get the first queue Id from the interrupt register value */
+        qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal);
+
+        if (IX_QMGR_QUEUPP_GROUP == group)
+        {
+            /* Set the queue range based on the queue group to proccess */
+            qIndex += IX_QMGR_MIN_QUEUPP_QID;
+        }
+
+        /* check if the interrupt register contains
+        * only 1 bit set
+        * For example:
+        *                                        intRegVal = 0x0010
+        *               currDispatchQInfo->intRegCheckMask = 0x0010
+        *    intRegVal == currDispatchQInfo->intRegCheckMask is true.
+        */
+        currDispatchQInfo = &dispatchQInfo[qIndex];
+        if (intRegVal == currDispatchQInfo->intRegCheckMask)
+        {
+
+            /* 
+             * check if Q type periodic -  only lower queues can
+             * have there type set to periodic 
+             */
+            if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex])
+            {
+                /* 
+                 * Disable the notifications on any sporadics 
+                 */
+                for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)
+                {
+                    if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i])
+                    {
+                        ixQMgrNotificationDisable(i);
+#ifndef NDEBUG
+                        /* Update statistics */
+                        dispatcherStats.queueStats[i].disableCount++;
+#endif
+                    }
+                }
+            }
+
+            currDispatchQInfo->callback (qIndex,
+                                         currDispatchQInfo->callbackId);
+#ifndef NDEBUG
+            /* Update statistics */
+            dispatcherStats.queueStats[qIndex].callbackCnt++;
+#endif
+        }
+        else
+        {
+            /* the event is triggered by more than 1 queue,
+            * the queue search will be starting from the beginning
+            * or the middle of the priority table
+            *
+            * the serach will end when all the bits of the interrupt
+            * register are cleared. There is no need to maintain
+            * a seperate value and test it at each iteration.
+            */
+            if (IX_QMGR_QUELOW_GROUP == group)
+            {
+                /* check if any bit related to queues in the first
+                 * half of the priority table is set
+                 */
+                if (intRegVal & lowPriorityTableFirstHalfMask)
+                {
+                    priorityTableIndex =
+                                       IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
+                }
+                else
+                {
+                    priorityTableIndex =
+                                       IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX;
+                }
+            }
+            else
+            {
+                /* check if any bit related to queues in the first
+                 * half of the priority table is set
+                 */
+                if (intRegVal & uppPriorityTableFirstHalfMask)
+                {
+                    priorityTableIndex =
+                                       IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;
+                }
+                else
+                {
+                    priorityTableIndex =
+                                       IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX;
+                }
+            }
+
+            /* iterate following the priority table until all the bits
+             * of the interrupt register are cleared.
+             */
+            do
+            {
+                qIndex = priorityTable[priorityTableIndex++];
+                currDispatchQInfo = &dispatchQInfo[qIndex];
+                intRegCheckMask = currDispatchQInfo->intRegCheckMask;
+
+                /* If this queue caused this interrupt to be raised */
+                if (intRegVal & intRegCheckMask)
+                {
+                    /* 
+                     * check if Q type periodic - only lower queues can
+                     * have there type set to periodic. There can only be one
+                     * periodic queue, so the sporadics are only disabled once.
+                     */
+                    if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex])
+                    {
+                        /* 
+                         * Disable the notifications on any sporadics 
+                         */
+                        for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)
+                        {
+                            if (IX_QMGR_TYPE_REALTIME_SPORADIC == 
+                                    ixQMgrQTypes[i])
+                            {
+                                ixQMgrNotificationDisable(i);
+                                /* 
+                                 * remove from intRegVal as we don't want 
+                                 * to service any sporadics now
+                                 */
+                                intRegVal &= ~dispatchQInfo[i].intRegCheckMask;
+#ifndef NDEBUG
+                                /* Update statistics */
+                                dispatcherStats.queueStats[i].disableCount++;
+#endif
+                            }
+                        }
+                    }
+
+                    currDispatchQInfo->callback (qIndex,
+                                                 currDispatchQInfo->callbackId);
+#ifndef NDEBUG
+                    /* Update statistics */
+                    dispatcherStats.queueStats[qIndex].callbackCnt++;
+#endif
+                    /* Clear the interrupt register bit */
+                    intRegVal &= ~intRegCheckMask;
+                }
+            }
+            while(intRegVal);
+        } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */
+    } /* End of intRegVal != 0 */
+
+#ifndef NDEBUG
+    /* Update statistics */
+    dispatcherStats.loopRunCnt++;
+#endif
+
+    if ((intRegValCopy != 0) && (IX_QMGR_QUELOW_GROUP == group))
+    {
+        /* 
+         * lower groups (therefore sticky) AND at least one enabled interrupt
+         * Write back to clear the interrupt 
+         */
+        ixQMgrAqmIfQInterruptRegWrite (IX_QMGR_QUELOW_GROUP, intRegValCopy);
+    }
+
+    /* Rebuild the priority table if needed */
+    if (rebuildTable)
+    {
+        ixQMgrDispatcherReBuildPriorityTable ();
+    }
+}
+
+PRIVATE void
+ixQMgrDispatcherReBuildPriorityTable (void)
+{
+    UINT32 qIndex;
+    UINT32 priority;
+    int lowQuePriorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;
+    int uppQuePriorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;
+
+    /* Reset the rebuild flag */
+    rebuildTable = false;
+
+    /* initialize the mak used to identify the queues in the first half
+     * of the priority table
+     */
+    lowPriorityTableFirstHalfMask = 0;
+    uppPriorityTableFirstHalfMask = 0;
+    
+    /* For each priority level */
+    for(priority=0; priority<IX_QMGR_NUM_PRIORITY_LEVELS; priority++)
+    {
+	/* Foreach low queue in this priority */
+	for(qIndex=0; qIndex<IX_QMGR_MIN_QUEUPP_QID; qIndex++)
+	{
+	    if (dispatchQInfo[qIndex].priority == priority)
+	    { 
+		/* build the priority table bitmask which match the
+		 * queues of the first half of the priority table 
+		 */
+		if (lowQuePriorityTableIndex < IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX) 
+		{
+		    lowPriorityTableFirstHalfMask |= dispatchQInfo[qIndex].intRegCheckMask;
+		}
+		/* build the priority table */
+		priorityTable[lowQuePriorityTableIndex++] = qIndex;
+	    }
+	}
+	/* Foreach upp queue */
+	for(qIndex=IX_QMGR_MIN_QUEUPP_QID; qIndex<=IX_QMGR_MAX_QID; qIndex++)
+	{
+	    if (dispatchQInfo[qIndex].priority == priority)
+	    {
+		/* build the priority table bitmask which match the
+		 * queues of the first half of the priority table 
+		 */
+		if (uppQuePriorityTableIndex < IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX) 
+		{
+		    uppPriorityTableFirstHalfMask |= dispatchQInfo[qIndex].intRegCheckMask;
+		}
+		/* build the priority table */
+		priorityTable[uppQuePriorityTableIndex++] = qIndex;
+	    }
+	}
+    }
+}
+
+IxQMgrDispatcherStats*
+ixQMgrDispatcherStatsGet (void)
+{
+    return &dispatcherStats;
+}
+
+PRIVATE void
+dummyCallback (IxQMgrQId qId,
+	       IxQMgrCallbackId cbId)
+{
+    /* Throttle the trace message */
+    if ((dispatchQInfo[qId].dummyCallbackCount % LOG_THROTTLE_COUNT) == 0)
+    {
+	IX_QMGR_LOG_WARNING2("--> dummyCallback: qId (%d), callbackId (%d)\n",qId,cbId);
+    }
+    dispatchQInfo[qId].dummyCallbackCount++;
+
+#ifndef NDEBUG
+    /* Update statistcs */
+    dispatcherStats.queueStats[qId].intNoCallbackCnt++;
+#endif
+}
+void
+ixQMgrLLPShow (int resetStats)
+{
+#ifndef NDEBUG
+    UINT8 i = 0;
+    UINT32 intEnableRegVal = 0;
+
+    printf ("Livelock statistics are printed on the fly.\n");
+    printf ("qId Type     EnableCnt DisableCnt IntEnableState Callbacks\n");
+    printf ("=== ======== ========= ========== ============== =========\n");
+
+    for (i=0; i<= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)
+    {
+        if (ixQMgrQTypes[i] != IX_QMGR_TYPE_REALTIME_OTHER)
+        {
+            printf (" %2d ", i);
+
+            if (ixQMgrQTypes[i] == IX_QMGR_TYPE_REALTIME_SPORADIC)
+            {
+                printf ("Sporadic");
+            }
+            else
+            {
+                printf ("Periodic");
+            }
+
+           
+            ixQMgrAqmIfQInterruptEnableRegRead (IX_QMGR_QUELOW_GROUP, 
+                                                    &intEnableRegVal);
+            	
+
+	    intEnableRegVal &= dispatchQInfo[i].intRegCheckMask;
+            intEnableRegVal = intEnableRegVal >> i;
+
+            printf (" %10d %10d %10d %10d\n",
+                    dispatcherStats.queueStats[i].enableCount,
+                    dispatcherStats.queueStats[i].disableCount,
+                    intEnableRegVal,
+                    dispatcherStats.queueStats[i].callbackCnt);
+
+            if (resetStats)
+            {
+                dispatcherStats.queueStats[i].enableCount =
+                dispatcherStats.queueStats[i].disableCount = 
+                dispatcherStats.queueStats[i].callbackCnt = 0;
+            }
+        }
+    }
+#else
+    IX_QMGR_LOG0("Livelock Prevention statistics are only collected in debug mode\n");
+#endif
+}
+
+void
+ixQMgrPeriodicDone (void)
+{
+    UINT32 i = 0;
+    UINT32 ixQMgrLockKey = 0;
+
+    /* 
+     * for the lower queues
+     */
+    for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)
+    {
+        /*
+         * check for sporadics 
+         */
+        if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i])
+        {
+             /* 
+              * enable any sporadics 
+              */
+             ixQMgrLockKey = ixOsalIrqLock();
+             ixQMgrAqmIfQInterruptEnable(i);
+             ixOsalIrqUnlock(ixQMgrLockKey);
+#ifndef NDEBUG
+             /* 
+              * Update statistics 
+              */
+             dispatcherStats.queueStats[i].enableCount++;
+             dispatcherStats.queueStats[i].notificationEnabled = true;
+#endif
+        }
+    }
+}
+IX_STATUS
+ixQMgrCallbackTypeSet (IxQMgrQId qId, 
+                       IxQMgrType type)
+{
+    UINT32 ixQMgrLockKey = 0;
+    IxQMgrType ixQMgrOldType =0;
+
+#ifndef NDEBUG
+    if (!ixQMgrQIsConfigured(qId))
+    {
+        return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+    if (qId >= IX_QMGR_MIN_QUEUPP_QID)
+    {
+        return IX_QMGR_PARAMETER_ERROR;
+    }
+    if(!IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type))
+    {
+        return IX_QMGR_PARAMETER_ERROR;
+    }
+#endif
+
+    ixQMgrOldType = ixQMgrQTypes[qId];
+    ixQMgrQTypes[qId] = type;
+
+    /*
+     * check if Q has been changed from type SPORADIC
+     */
+    if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrOldType)
+    {
+       /* 
+        * previously Q was a SPORADIC, this means that LLP
+        * might have had it disabled. enable it now.
+        */
+       ixQMgrLockKey = ixOsalIrqLock();
+       ixQMgrAqmIfQInterruptEnable(qId);
+       ixOsalIrqUnlock(ixQMgrLockKey);
+
+#ifndef NDEBUG
+       /* 
+        * Update statistics 
+        */
+       dispatcherStats.queueStats[qId].enableCount++;
+#endif
+    }
+
+    return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrCallbackTypeGet (IxQMgrQId qId, 
+                       IxQMgrType *type)
+{
+#ifndef NDEBUG
+    if (!ixQMgrQIsConfigured(qId))
+    {
+        return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+    if (qId >= IX_QMGR_MIN_QUEUPP_QID)
+    {
+        return IX_QMGR_PARAMETER_ERROR;
+    }
+    if(type == NULL)
+    {
+         return IX_QMGR_PARAMETER_ERROR;
+    }
+#endif
+
+    *type = ixQMgrQTypes[qId];
+    return IX_SUCCESS;
+}
diff --git a/marvell/uboot/drivers/net/npe/IxQMgrInit.c b/marvell/uboot/drivers/net/npe/IxQMgrInit.c
new file mode 100644
index 0000000..14687e6
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxQMgrInit.c
@@ -0,0 +1,209 @@
+/**
+ * @file    IxQMgrInit.c
+ *
+ * @author Intel Corporation
+ * @date    30-Oct-2001
+ *
+ * @brief:  Provided initialization of the QMgr component and its subcomponents.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * System defined include files.
+ */
+
+/*
+ * User defined include files.
+ */
+#include "IxOsal.h"
+#include "IxQMgr.h"
+#include "IxQMgrQCfg_p.h"
+#include "IxQMgrDispatcher_p.h"
+#include "IxQMgrLog_p.h"
+#include "IxQMgrQAccess_p.h"
+#include "IxQMgrDefines_p.h"
+#include "IxQMgrAqmIf_p.h"
+
+/*
+ * Set to true if initialized
+ * N.B. global so integration/unit tests can reinitialize
+ */
+BOOL qMgrIsInitialized = false;
+
+/*
+ * Function definitions.
+ */
+IX_STATUS
+ixQMgrInit (void)
+{
+    if (qMgrIsInitialized)
+    {
+	IX_QMGR_LOG0("ixQMgrInit: IxQMgr already initialised\n");
+	return IX_FAIL;
+    }
+
+    /* Initialise the QCfg component */
+    ixQMgrQCfgInit ();
+
+    /* Initialise the Dispatcher component */
+    ixQMgrDispatcherInit ();
+
+    /* Initialise the Access component */
+    ixQMgrQAccessInit ();
+
+    /* Initialization complete */
+    qMgrIsInitialized = true;
+
+    return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrUnload (void)
+{
+    if (!qMgrIsInitialized)
+    {
+	return IX_FAIL;
+    }
+
+    /* Uninitialise the QCfg component */
+    ixQMgrQCfgUninit ();
+
+    /* Uninitialization complete */
+    qMgrIsInitialized = false;
+
+    return IX_SUCCESS;
+}
+
+void
+ixQMgrShow (void)
+{
+    IxQMgrQCfgStats *qCfgStats = NULL;
+    IxQMgrDispatcherStats *dispatcherStats = NULL;
+    int i;
+    UINT32 lowIntRegRead, upIntRegRead;
+
+    qCfgStats = ixQMgrQCfgStatsGet ();
+    dispatcherStats = ixQMgrDispatcherStatsGet ();
+    ixQMgrAqmIfQInterruptRegRead (IX_QMGR_QUELOW_GROUP, &lowIntRegRead);
+    ixQMgrAqmIfQInterruptRegRead (IX_QMGR_QUEUPP_GROUP, &upIntRegRead);
+    printf("Generic Stats........\n");
+    printf("=====================\n");
+    printf("Loop Run Count..........%u\n",dispatcherStats->loopRunCnt);
+    printf("Watermark set count.....%d\n", qCfgStats->wmSetCnt);
+    printf("===========================================\n");
+    printf("On the fly Interrupt Register Stats........\n");
+    printf("===========================================\n");
+    printf("Lower Interrupt Register............0x%08x\n",lowIntRegRead);
+    printf("Upper Interrupt Register............0x%08x\n",upIntRegRead);
+    printf("==============================================\n");
+    printf("Queue Specific Stats........\n");
+    printf("============================\n");
+
+    for (i=0; i<IX_QMGR_MAX_NUM_QUEUES; i++)
+    {
+	if (ixQMgrQIsConfigured(i))
+	{
+	    ixQMgrQShow(i);
+	}
+    }
+
+    printf("============================\n");
+}
+
+IX_STATUS
+ixQMgrQShow (IxQMgrQId qId)
+{
+    IxQMgrQCfgStats *qCfgStats = NULL;
+    IxQMgrDispatcherStats *dispatcherStats = NULL; 
+
+    if (!ixQMgrQIsConfigured(qId))
+    {
+	return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+    
+    dispatcherStats = ixQMgrDispatcherStatsGet ();
+    qCfgStats = ixQMgrQCfgQStatsGet (qId);
+
+    printf("QId %d\n", qId);
+    printf("======\n");
+    printf("  IxQMgrQCfg Stats\n");
+    printf("    Name..................... \"%s\"\n", qCfgStats->qStats[qId].qName);
+    printf("    Size in words............ %u\n", qCfgStats->qStats[qId].qSizeInWords);
+    printf("    Entry size in words...... %u\n", qCfgStats->qStats[qId].qEntrySizeInWords);
+    printf("    Nearly empty watermark... %u\n", qCfgStats->qStats[qId].ne);
+    printf("    Nearly full watermark.... %u\n", qCfgStats->qStats[qId].nf);
+    printf("    Number of full entries... %u\n", qCfgStats->qStats[qId].numEntries);
+    printf("    Sram base address........ 0x%X\n", qCfgStats->qStats[qId].baseAddress);
+    printf("    Read pointer............. 0x%X\n", qCfgStats->qStats[qId].readPtr);
+    printf("    Write pointer............ 0x%X\n", qCfgStats->qStats[qId].writePtr);
+
+#ifndef NDEBUG
+    if (dispatcherStats->queueStats[qId].notificationEnabled)
+    {
+        char *localEvent = "none ????";
+        switch (dispatcherStats->queueStats[qId].srcSel)
+        {
+            case IX_QMGR_Q_SOURCE_ID_E:
+                localEvent = "Empty";
+                break;
+            case IX_QMGR_Q_SOURCE_ID_NE:
+                localEvent = "Nearly Empty";
+                break;
+            case IX_QMGR_Q_SOURCE_ID_NF:
+                localEvent = "Nearly Full";
+                break;
+            case IX_QMGR_Q_SOURCE_ID_F:
+                localEvent = "Full";
+                break;
+            case IX_QMGR_Q_SOURCE_ID_NOT_E:
+                localEvent = "Not Empty";
+                break;
+            case IX_QMGR_Q_SOURCE_ID_NOT_NE:
+                localEvent = "Not Nearly Empty";
+                break;
+            case IX_QMGR_Q_SOURCE_ID_NOT_NF:
+                localEvent = "Not Nearly Full";
+                break;
+            case IX_QMGR_Q_SOURCE_ID_NOT_F:
+                localEvent = "Not Full";
+                break;
+            default :
+                break;
+        }
+        printf("    Notifications localEvent...... %s\n", localEvent);
+    }
+    else
+    {
+        printf("    Notifications............ not enabled\n");
+    }
+    printf("  IxQMgrDispatcher Stats\n");
+    printf("    Callback count................%d\n",
+	  dispatcherStats->queueStats[qId].callbackCnt);
+    printf("    Priority change count.........%d\n",
+	  dispatcherStats->queueStats[qId].priorityChangeCnt);
+    printf("    Interrupt no callback count...%d\n",
+	  dispatcherStats->queueStats[qId].intNoCallbackCnt);
+    printf("    Interrupt lost callback count...%d\n",
+	  dispatcherStats->queueStats[qId].intLostCallbackCnt);
+#endif
+
+    return IX_SUCCESS;
+}
+
+
+
+
diff --git a/marvell/uboot/drivers/net/npe/IxQMgrQAccess.c b/marvell/uboot/drivers/net/npe/IxQMgrQAccess.c
new file mode 100644
index 0000000..13ee0f4
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxQMgrQAccess.c
@@ -0,0 +1,772 @@
+/**
+ * @file    IxQMgrQAccess.c
+ *
+ * @author Intel Corporation
+ * @date    30-Oct-2001
+ *
+ * @brief   This file contains functions for putting entries on a queue and
+ * removing entries from a queue.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * Inlines are compiled as function when this is defined.
+ * N.B. Must be placed before #include of "IxQMgr.h"
+ */
+#ifndef IXQMGR_H
+#    define IXQMGRQACCESS_C
+#else
+#    error
+#endif
+
+/*
+ * System defined include files.
+ */
+
+/*
+ * User defined include files.
+ */
+#include "IxQMgr.h"
+#include "IxQMgrAqmIf_p.h"
+#include "IxQMgrQAccess_p.h"
+#include "IxQMgrQCfg_p.h"
+#include "IxQMgrDefines_p.h"
+
+/*
+ * Global variables and extern definitions
+ */
+extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+
+/*
+ * Function definitions.
+ */
+void
+ixQMgrQAccessInit (void)
+{   
+}
+
+IX_STATUS
+ixQMgrQReadWithChecks (IxQMgrQId qId,
+                       UINT32 *entry)
+{
+    IxQMgrQEntrySizeInWords entrySizeInWords;
+    IxQMgrQInlinedReadWriteInfo *infoPtr;
+
+    if (NULL == entry)
+    {
+	return IX_QMGR_PARAMETER_ERROR;
+    }
+
+    /* Check QId */
+    if (!ixQMgrQIsConfigured(qId))
+    {
+	return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+
+    /* Get the q entry size in words */
+    entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId);
+
+    ixQMgrAqmIfQPop (qId, entrySizeInWords, entry);	    
+
+    /* reset the current read count if the counter wrapped around 
+    * (unsigned arithmetic)
+    */
+    infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+    if (infoPtr->qReadCount-- > infoPtr->qSizeInEntries)
+    {
+	infoPtr->qReadCount = 0;
+    }
+
+    /* Check if underflow occurred on the read */
+    if (ixQMgrAqmIfUnderflowCheck (qId))
+    {
+	return IX_QMGR_Q_UNDERFLOW;
+    }
+    
+    return IX_SUCCESS;
+}
+
+/* this function reads the remaining of the q entry
+ * for queues configured with many words.
+ * (the first word of the entry is already read 
+ * in the inlined function and the entry pointer already
+ * incremented
+ */
+IX_STATUS
+ixQMgrQReadMWordsMinus1 (IxQMgrQId qId,
+			 UINT32 *entry)
+{
+    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+    UINT32 entrySize = infoPtr->qEntrySizeInWords;
+    volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
+    
+    while (--entrySize)
+    {
+	/* read the entry and accumulate the result */
+	*(++entry) = IX_OSAL_READ_LONG(++qAccRegAddr);
+    }
+    /* underflow is available for lower queues only */
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {
+	/* get the queue status */
+	UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
+	
+	/* check the underflow status */
+	if (status & infoPtr->qUflowStatBitMask)
+	{
+	    /* the queue is empty 
+	     *  clear the underflow status bit if it was set 
+	     */
+	    IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
+				 status & ~infoPtr->qUflowStatBitMask);
+	    return IX_QMGR_Q_UNDERFLOW;
+	}
+    }
+    return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrQWriteWithChecks (IxQMgrQId qId,
+                        UINT32 *entry)
+{
+    IxQMgrQEntrySizeInWords entrySizeInWords;
+    IxQMgrQInlinedReadWriteInfo *infoPtr;
+
+    if (NULL == entry)
+    {
+	return IX_QMGR_PARAMETER_ERROR;
+    }
+
+    /* Check QId */
+    if (!ixQMgrQIsConfigured(qId))
+    {
+	return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+
+    /* Get the q entry size in words */
+    entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId);
+    
+    ixQMgrAqmIfQPush (qId, entrySizeInWords, entry);
+
+    /* reset the current read count if the counter wrapped around 
+    * (unsigned arithmetic)
+    */
+    infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+    if (infoPtr->qWriteCount++ >= infoPtr->qSizeInEntries)
+    {
+	infoPtr->qWriteCount = infoPtr->qSizeInEntries;
+    }
+
+    /* Check if overflow occurred on the write*/
+    if (ixQMgrAqmIfOverflowCheck (qId))
+    {
+	return IX_QMGR_Q_OVERFLOW;
+    }
+         
+    return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrQPeek (IxQMgrQId qId,
+	     unsigned int entryIndex,
+	     UINT32 *entry)
+{
+    unsigned int numEntries;
+
+#ifndef NDEBUG
+    if ((NULL == entry) || (entryIndex >= IX_QMGR_Q_SIZE_INVALID))
+    {
+	return IX_QMGR_PARAMETER_ERROR;
+    }
+
+    if (!ixQMgrQIsConfigured(qId))
+    {
+	return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+#endif
+    
+    if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries))
+    {
+	return IX_FAIL;
+    }
+
+    if (entryIndex >= numEntries) /* entryIndex starts at 0 */
+    {
+	return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS;
+    }
+
+    return ixQMgrAqmIfQPeek (qId, entryIndex, entry);
+}
+
+IX_STATUS
+ixQMgrQPoke (IxQMgrQId qId,
+	     unsigned entryIndex,
+	     UINT32 *entry)
+{
+    unsigned int numEntries;
+
+#ifndef NDEBUG
+    if ((NULL == entry) || (entryIndex > 128))
+    {
+	return IX_QMGR_PARAMETER_ERROR;
+    }
+
+    if (!ixQMgrQIsConfigured(qId))
+    {
+	return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+#endif
+        
+    if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries))
+    {
+	return IX_FAIL;
+    }
+
+    if (numEntries < (entryIndex + 1)) /* entryIndex starts at 0 */
+    {
+	return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS;
+    }
+
+    return ixQMgrAqmIfQPoke (qId, entryIndex, entry);
+}
+
+IX_STATUS
+ixQMgrQStatusGetWithChecks (IxQMgrQId qId,
+                            IxQMgrQStatus *qStatus)
+{
+    if (NULL == qStatus)
+    {
+	return IX_QMGR_PARAMETER_ERROR;
+    }
+   
+    if (!ixQMgrQIsConfigured (qId)) 
+    {
+        return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+
+    ixQMgrAqmIfQueStatRead (qId, qStatus);
+
+    return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrQNumEntriesGet (IxQMgrQId qId,
+		      unsigned *numEntriesPtr)
+{
+    UINT32 qPtrs;
+    UINT32 qStatus;
+    unsigned numEntries;
+    IxQMgrQInlinedReadWriteInfo *infoPtr;
+
+
+#ifndef NDEBUG
+    if (NULL == numEntriesPtr)
+    {
+	return IX_QMGR_PARAMETER_ERROR;
+    }
+
+    /* Check QId */
+    if (!ixQMgrQIsConfigured(qId))
+    {
+	return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+#endif
+
+    /* get fast access data */
+    infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+
+    /* get snapshot */
+    qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
+
+    /* Mod subtraction of pointers to get number of words in Q. */
+    numEntries = (qPtrs - (qPtrs >> 7)) & 0x7f;
+  
+    if (numEntries == 0)
+    {
+	/* 
+	 * Could mean either full or empty queue
+	 * so look at status
+	 */
+	ixQMgrAqmIfQueStatRead (qId, &qStatus);
+
+	if (qId < IX_QMGR_MIN_QUEUPP_QID)
+	{
+	    if (qStatus & IX_QMGR_Q_STATUS_E_BIT_MASK)
+	    {
+		/* Empty */
+		*numEntriesPtr = 0;
+	    }
+	    else if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK)
+	    {
+		/* Full */
+		*numEntriesPtr = infoPtr->qSizeInEntries;
+	    }
+	    else
+	    {	    
+		/* 
+		 * Queue status and read/write pointers are volatile.
+		 * The queue state has changed since we took the
+		 * snapshot of the read and write pointers.
+		 * Client can retry if they wish
+		 */
+		*numEntriesPtr = 0;
+		return IX_QMGR_WARNING;
+	    }
+	}
+	else /* It is an upper queue which does not have an empty status bit maintained */
+	{
+	    if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK)
+	    {
+		/* The queue is Full at the time of snapshot. */
+		*numEntriesPtr = infoPtr->qSizeInEntries;
+	    }
+	    else
+	    {
+	       /* The queue is either empty, either moving,
+	        * Client can retry if they wish
+	        */
+		*numEntriesPtr = 0;
+	        return IX_QMGR_WARNING;
+	    }
+	}
+    }
+    else
+    {
+	*numEntriesPtr = (numEntries / infoPtr->qEntrySizeInWords) & (infoPtr->qSizeInEntries - 1);
+    }
+    
+    return IX_SUCCESS;
+}
+
+#if defined(__wince) && defined(NO_INLINE_APIS)
+
+PUBLIC IX_STATUS
+ixQMgrQRead (IxQMgrQId qId,
+      UINT32 *entryPtr)
+{
+    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+    UINT32 entry, entrySize;
+
+    /* get a new entry */
+    entrySize = infoPtr->qEntrySizeInWords;
+    entry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr);
+
+    if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
+    { 
+    *entryPtr = entry;
+  /* process the remaining part of the entry */
+   return ixQMgrQReadMWordsMinus1(qId, entryPtr);
+    }
+
+    /* underflow is available for lower queues only */
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {
+ /* the counter of queue entries is decremented. In happy 
+    * day scenario there are many entries in the queue
+  * and the counter does not reach zero.
+  */
+     if (infoPtr->qReadCount-- == 0)
+ {
+       /* There is maybe no entry in the queue
+      * qReadCount is now negative, but will be corrected before
+      * the function returns.
+         */
+     UINT32 qPtrs; /* queue internal pointers */
+
+     /* when a queue is empty, the hw guarantees to return 
+       * a null value. If the value is not null, the queue is
+      * not empty.
+        */
+     if (entry == 0)
+     {
+       /* get the queue status */
+      UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
+   
+        /* check the underflow status */
+        if (status & infoPtr->qUflowStatBitMask)
+        {
+           /* the queue is empty 
+          *  clear the underflow status bit if it was set 
+            */
+          IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
+                    status & ~infoPtr->qUflowStatBitMask);
+         *entryPtr = 0;
+          infoPtr->qReadCount = 0;
+            return IX_QMGR_Q_UNDERFLOW;
+     }
+       }
+       /* store the result */
+      *entryPtr = entry;
+
+      /* No underflow occured : someone is filling the queue
+       * or the queue contains null entries.
+       * The current counter needs to be
+       * updated from the current number of entries in the queue
+       */
+
+     /* get snapshot of queue pointers */
+        qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
+
+       /* Mod subtraction of pointers to get number of words in Q. */
+      qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f; 
+  
+       if (qPtrs == 0)
+     {
+       /* no entry in the queue */
+     infoPtr->qReadCount = 0;
+        }
+       else
+        {
+       /* convert the number of words inside the queue
+      * to a number of entries 
+       */
+     infoPtr->qReadCount = qPtrs & (infoPtr->qSizeInEntries - 1);
+        }
+       return IX_SUCCESS;
+  }
+    }
+    *entryPtr = entry;
+    return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixQMgrQBurstRead (IxQMgrQId qId,
+          UINT32 numEntries,
+          UINT32 *entries)
+{
+    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+    UINT32 nullCheckEntry;
+
+    if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
+    {
+    volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
+
+    /* the code is optimized to take care of data dependencies:
+  * Durig a read, there are a few cycles needed to get the 
+   * read complete. During these cycles, it is poossible to
+    * do some CPU, e.g. increment pointers and decrement 
+   * counters.
+     */
+
+ /* fetch a queue entry */
+   nullCheckEntry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr);
+
+ /* iterate the specified number of queue entries */ 
+    while (--numEntries)
+    {
+       /* check the result of the previous read */
+     if (nullCheckEntry == 0)
+        {
+       /* if we read a NULL entry, stop. We have underflowed */
+        break;
+      }
+       else
+        {
+       /* write the entry */
+       *entries = nullCheckEntry;
+      /* fetch next entry */
+      nullCheckEntry = IX_OSAL_READ_LONG(qAccRegAddr);
+      /* increment the write address */
+       entries++;
+      }
+   }
+   /* write the pre-fetched entry */
+   *entries = nullCheckEntry;
+    }
+    else
+    {
+    IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
+  /* read the specified number of queue entries */
+    nullCheckEntry = 0;
+ while (numEntries--)
+    {
+       int i;
+
+      for (i = 0; i < entrySizeInWords; i++)
+      {
+       *entries = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr + i);
+       nullCheckEntry |= *entries++;
+       }
+
+       /* if we read a NULL entry, stop. We have underflowed */
+        if (nullCheckEntry == 0)
+        {
+       break;
+      }
+       nullCheckEntry = 0;
+ }
+    }
+
+    /* reset the current read count : next access to the read function 
+     * will force a underflow status check 
+     */
+    infoPtr->qWriteCount = 0;
+
+    /* Check if underflow occurred on the read */
+    if (nullCheckEntry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID)
+    {
+  /* get the queue status */
+  UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
+
+   if (status & infoPtr->qUflowStatBitMask)
+    {
+       /* clear the underflow status bit if it was set */
+      IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
+                status & ~infoPtr->qUflowStatBitMask);
+     return IX_QMGR_Q_UNDERFLOW;
+ }
+    }
+
+    return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixQMgrQWrite (IxQMgrQId qId,
+         UINT32 *entry)
+{
+    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+    UINT32 entrySize;
+
+    /* write the entry */
+    IX_OSAL_WRITE_LONG(infoPtr->qAccRegAddr, *entry);
+    entrySize = infoPtr->qEntrySizeInWords;
+
+    if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
+    {   
+    /* process the remaining part of the entry */
+   volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
+    while (--entrySize)
+ {
+       ++entry;
+        IX_OSAL_WRITE_LONG(++qAccRegAddr, *entry);
+    }
+   entrySize = infoPtr->qEntrySizeInWords;
+    }
+
+    /* overflow is available for lower queues only */
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {   
+  UINT32 qSize = infoPtr->qSizeInEntries;
+ /* increment the current number of entries in the queue
+  * and check for overflow 
+   */
+ if (infoPtr->qWriteCount++ == qSize)
+    {
+       /* the queue may have overflow */
+       UINT32 qPtrs; /* queue internal pointers */
+  
+       /* get the queue status */
+      UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
+
+       /* read the status twice because the status may 
+         * not be immediately ready after the write operation
+        */
+     if ((status & infoPtr->qOflowStatBitMask) ||
+        ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))
+         & infoPtr->qOflowStatBitMask))
+     {
+       /* the queue is full, clear the overflow status
+      *  bit if it was set 
+       */
+     IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
+                    status & ~infoPtr->qOflowStatBitMask);
+     infoPtr->qWriteCount = infoPtr->qSizeInEntries;
+     return IX_QMGR_Q_OVERFLOW;
+      }
+       /* No overflow occured : someone is draining the queue
+       * and the current counter needs to be
+       * updated from the current number of entries in the queue
+       */
+
+     /* get q pointer snapshot */
+        qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);
+
+       /* Mod subtraction of pointers to get number of words in Q. */
+      qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f; 
+
+     if (qPtrs == 0)
+     {
+       /* the queue may be full at the time of the 
+         * snapshot. Next access will check 
+         * the overflow status again.
+        */
+     infoPtr->qWriteCount = qSize;
+       }
+       else 
+       {
+       /* convert the number of words to a number of entries */
+        if (entrySize == IX_QMGR_Q_ENTRY_SIZE1)
+     {
+           infoPtr->qWriteCount = qPtrs & (qSize - 1);
+     }
+       else
+        {
+           infoPtr->qWriteCount = (qPtrs / entrySize) & (qSize - 1);
+       }
+       }
+   }
+    }
+    return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixQMgrQBurstWrite (IxQMgrQId qId,
+          unsigned numEntries,
+        UINT32 *entries)
+{
+    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+    UINT32 status;
+
+    /* update the current write count */
+    infoPtr->qWriteCount += numEntries;
+
+    if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
+    {
+    volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
+    while (numEntries--)
+    {
+       IX_OSAL_WRITE_LONG(qAccRegAddr, *entries);
+        entries++;
+  }
+    }
+    else
+    {
+ IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
+  int i;
+
+  /* write each queue entry */
+    while (numEntries--)
+    {
+       /* write the queueEntrySize number of words for each entry */
+       for (i = 0; i < entrySizeInWords; i++)
+      {
+       IX_OSAL_WRITE_LONG((infoPtr->qAccRegAddr + i), *entries);
+     entries++;
+      }
+   }
+    }
+
+    /* check if the write count overflows */
+    if (infoPtr->qWriteCount > infoPtr->qSizeInEntries)
+    {
+  /* reset the current write count */
+ infoPtr->qWriteCount = infoPtr->qSizeInEntries;
+    }
+
+    /* Check if overflow occurred on the write operation */
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {
+   /* get the queue status */
+  status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
+
+  /* read the status twice because the status may 
+     * not be ready at the time of the write
+     */
+ if ((status & infoPtr->qOflowStatBitMask) ||
+        ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))
+         & infoPtr->qOflowStatBitMask))
+ {
+       /* clear the underflow status bit if it was set */
+      IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
+                status & ~infoPtr->qOflowStatBitMask);
+     return IX_QMGR_Q_OVERFLOW;
+  }
+    }
+
+    return IX_SUCCESS;
+}
+
+PUBLIC IX_STATUS
+ixQMgrQStatusGet (IxQMgrQId qId,
+          IxQMgrQStatus *qStatus)
+{
+    /* read the status of a queue in the range 0-31 */
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {
+  extern UINT32 ixQMgrAqmIfQueLowStatRegAddr[];
+   extern UINT32 ixQMgrAqmIfQueLowStatBitsOffset[];
+    extern UINT32 ixQMgrAqmIfQueLowStatBitsMask;
+    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+   volatile UINT32 *lowStatRegAddr = (UINT32*)ixQMgrAqmIfQueLowStatRegAddr[qId];
+   volatile UINT32 *qUOStatRegAddr = infoPtr->qUOStatRegAddr;
+
+  UINT32 lowStatBitsOffset = ixQMgrAqmIfQueLowStatBitsOffset[qId];
+    UINT32 lowStatBitsMask   = ixQMgrAqmIfQueLowStatBitsMask;
+   UINT32 underflowBitMask  = infoPtr->qUflowStatBitMask;
+  UINT32 overflowBitMask   = infoPtr->qOflowStatBitMask;
+
+  /* read the status register for this queue */
+   *qStatus = IX_OSAL_READ_LONG(lowStatRegAddr);
+ /* mask out the status bits relevant only to this queue */
+  *qStatus = (*qStatus >> lowStatBitsOffset) & lowStatBitsMask;
+
+   /* Check if the queue has overflowed */
+ if (IX_OSAL_READ_LONG(qUOStatRegAddr) & overflowBitMask)
+  {
+       /* clear the overflow status bit if it was set */
+       IX_OSAL_WRITE_LONG(qUOStatRegAddr,
+                 (IX_OSAL_READ_LONG(qUOStatRegAddr) &
+               ~overflowBitMask));
+       *qStatus |= IX_QMGR_Q_STATUS_OF_BIT_MASK;
+   }
+
+   /* Check if the queue has underflowed */
+        if (IX_OSAL_READ_LONG(qUOStatRegAddr) & underflowBitMask)
+ {
+       /* clear the underflow status bit if it was set */
+      IX_OSAL_WRITE_LONG(qUOStatRegAddr,
+                 (IX_OSAL_READ_LONG(qUOStatRegAddr) &
+               ~underflowBitMask));
+      *qStatus |= IX_QMGR_Q_STATUS_UF_BIT_MASK;
+   }
+    }
+    else /* read status of a queue in the range 32-63 */
+    {
+ extern UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
+    extern UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
+    extern UINT32 ixQMgrAqmIfQueUppStat0BitMask[];
+  extern UINT32 ixQMgrAqmIfQueUppStat1BitMask[];
+
+  volatile UINT32 *qNearEmptyStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat0RegAddr;
+    volatile UINT32 *qFullStatRegAddr      = (UINT32*)ixQMgrAqmIfQueUppStat1RegAddr;
+    int maskIndex = qId - IX_QMGR_MIN_QUEUPP_QID;
+   UINT32 qNearEmptyStatBitMask = ixQMgrAqmIfQueUppStat0BitMask[maskIndex];
+    UINT32 qFullStatBitMask      = ixQMgrAqmIfQueUppStat1BitMask[maskIndex];
+
+    /* Reset the status bits */
+ *qStatus = 0;
+
+   /* Check if the queue is nearly empty */
+    if (IX_OSAL_READ_LONG(qNearEmptyStatRegAddr) & qNearEmptyStatBitMask)
+ {
+       *qStatus |= IX_QMGR_Q_STATUS_NE_BIT_MASK;
+   }
+
+   /* Check if the queue is full */
+    if (IX_OSAL_READ_LONG(qFullStatRegAddr) & qFullStatBitMask)
+   {
+       *qStatus |= IX_QMGR_Q_STATUS_F_BIT_MASK;
+    }
+    }
+    return IX_SUCCESS;
+}
+#endif /* def NO_INLINE_APIS */
diff --git a/marvell/uboot/drivers/net/npe/IxQMgrQCfg.c b/marvell/uboot/drivers/net/npe/IxQMgrQCfg.c
new file mode 100644
index 0000000..b64bb2d
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/IxQMgrQCfg.c
@@ -0,0 +1,519 @@
+/**
+ * @file    QMgrQCfg.c
+ *
+ * @author Intel Corporation
+ * @date    30-Oct-2001
+ * 
+ * @brief   This modules provides an interface for setting up the static
+ * configuration of AQM queues.This file contains the following
+ * functions:
+ *
+ * 
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/*
+ * System defined include files.
+ */
+
+/*
+ * User defined include files.
+ */
+#include "IxOsal.h"
+#include "IxQMgr.h"
+#include "IxQMgrAqmIf_p.h"
+#include "IxQMgrQCfg_p.h"
+#include "IxQMgrDefines_p.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+#define IX_QMGR_MIN_ENTRY_SIZE_IN_WORDS 16
+
+/* Total size of SRAM */
+#define IX_QMGR_AQM_SRAM_SIZE_IN_BYTES 0x4000
+
+/*
+ * Check that qId is a valid queue identifier. This is provided to
+ * make the code easier to read.
+ */
+#define IX_QMGR_QID_IS_VALID(qId) \
+(((qId) >= (IX_QMGR_MIN_QID)) && ((qId) <= (IX_QMGR_MAX_QID)))
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/*
+ * This struct describes an AQM queue.
+ * N.b. bufferSizeInWords and qEntrySizeInWords are stored in the queue
+ * as these are requested by Access in the data path. sizeInEntries is
+ * not required by the data path so it can be calculated dynamically.
+ * 
+ */
+typedef struct
+{
+    char qName[IX_QMGR_MAX_QNAME_LEN+1];       /* Textual description of a queue*/
+    IxQMgrQSizeInWords qSizeInWords;           /* The number of words in the queue */
+    IxQMgrQEntrySizeInWords qEntrySizeInWords; /* Number of words per queue entry*/
+    BOOL isConfigured;                         /* This flag is true if the queue has
+                                                *   been configured
+                                                */
+} IxQMgrCfgQ;
+
+/*
+ * Variable declarations global to this file. Externs are followed by
+ * statics.
+ */
+
+extern UINT32 * ixQMgrAqmIfQueAccRegAddr[]; 
+
+/* Store data required to inline read and write access
+ */
+IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[IX_QMGR_MAX_NUM_QUEUES];
+
+static IxQMgrCfgQ cfgQueueInfo[IX_QMGR_MAX_NUM_QUEUES];
+
+/* This pointer holds the starting address of AQM SRAM not used by
+ * the AQM queues.
+ */
+static UINT32 freeSramAddress=0;
+
+/* 4 words of zeroed memory for inline access */
+static UINT32 zeroedPlaceHolder[4] = { 0, 0, 0, 0 };
+
+static BOOL cfgInitialized = false;
+
+static IxOsalMutex ixQMgrQCfgMutex;
+
+/*
+ * Statistics
+ */
+static IxQMgrQCfgStats stats;
+
+/*
+ * Function declarations
+ */
+PRIVATE BOOL
+watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level);
+
+PRIVATE BOOL
+qSizeInWordsIsOk (IxQMgrQSizeInWords qSize);
+
+PRIVATE BOOL
+qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize);
+
+/*
+ * Function definitions.
+ */
+void
+ixQMgrQCfgInit (void)
+{
+    int loopIndex;
+    
+    for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
+    {
+	/* info for code inlining */
+	ixQMgrAqmIfQueAccRegAddr[loopIndex] = zeroedPlaceHolder;
+
+	/* info for code inlining */
+	ixQMgrQInlinedReadWriteInfo[loopIndex].qReadCount = 0;
+	ixQMgrQInlinedReadWriteInfo[loopIndex].qWriteCount = 0;
+	ixQMgrQInlinedReadWriteInfo[loopIndex].qAccRegAddr = zeroedPlaceHolder;
+	ixQMgrQInlinedReadWriteInfo[loopIndex].qUOStatRegAddr = zeroedPlaceHolder;
+	ixQMgrQInlinedReadWriteInfo[loopIndex].qUflowStatBitMask = 0;
+	ixQMgrQInlinedReadWriteInfo[loopIndex].qOflowStatBitMask = 0;
+	ixQMgrQInlinedReadWriteInfo[loopIndex].qEntrySizeInWords = 0;
+	ixQMgrQInlinedReadWriteInfo[loopIndex].qSizeInEntries = 0;
+	ixQMgrQInlinedReadWriteInfo[loopIndex].qConfigRegAddr = zeroedPlaceHolder;
+   }
+
+    /* Initialise the AqmIf component */
+    ixQMgrAqmIfInit ();
+   
+    /* Reset all queues to have queue name = NULL, entry size = 0 and
+     * isConfigured = false
+     */
+    for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++)
+    {
+	strcpy (cfgQueueInfo[loopIndex].qName, "");
+	cfgQueueInfo[loopIndex].qSizeInWords = 0;
+	cfgQueueInfo[loopIndex].qEntrySizeInWords = 0;
+	cfgQueueInfo[loopIndex].isConfigured = false;
+
+	/* Statistics */
+	stats.qStats[loopIndex].isConfigured = false;
+	stats.qStats[loopIndex].qName = cfgQueueInfo[loopIndex].qName;
+    }
+
+    /* Statistics */
+    stats.wmSetCnt = 0;
+
+    ixQMgrAqmIfSramBaseAddressGet (&freeSramAddress);
+    
+    ixOsalMutexInit(&ixQMgrQCfgMutex);
+
+    cfgInitialized = true;
+}
+
+void
+ixQMgrQCfgUninit (void)
+{
+    cfgInitialized = false;
+
+    /* Uninitialise the AqmIf component */
+    ixQMgrAqmIfUninit ();
+}
+
+IX_STATUS
+ixQMgrQConfig (char *qName,
+	      IxQMgrQId qId,
+	      IxQMgrQSizeInWords qSizeInWords,
+	      IxQMgrQEntrySizeInWords qEntrySizeInWords)
+{
+    UINT32 aqmLocalBaseAddress;
+
+    if (!cfgInitialized)
+    {
+        return IX_FAIL;
+    }
+    
+    if (!IX_QMGR_QID_IS_VALID(qId))
+    {
+	return IX_QMGR_INVALID_Q_ID;
+    }
+    
+    else if (NULL == qName)
+    {
+	return IX_QMGR_PARAMETER_ERROR;
+    }
+    
+    else if (strlen (qName) > IX_QMGR_MAX_QNAME_LEN)
+    {
+	return IX_QMGR_PARAMETER_ERROR;
+    }
+
+    else if (!qSizeInWordsIsOk (qSizeInWords))
+    {
+	return IX_QMGR_INVALID_QSIZE;
+    }
+
+    else if (!qEntrySizeInWordsIsOk (qEntrySizeInWords))
+    {
+	return IX_QMGR_INVALID_Q_ENTRY_SIZE;
+    }
+    
+    else if (cfgQueueInfo[qId].isConfigured)
+    {
+	return IX_QMGR_Q_ALREADY_CONFIGURED;
+    }
+   
+    ixOsalMutexLock(&ixQMgrQCfgMutex, IX_OSAL_WAIT_FOREVER);
+
+    /* Write the config register */
+    ixQMgrAqmIfQueCfgWrite (qId,
+			   qSizeInWords,
+			   qEntrySizeInWords,
+			   freeSramAddress);
+
+
+    strcpy (cfgQueueInfo[qId].qName, qName);
+    cfgQueueInfo[qId].qSizeInWords = qSizeInWords;
+    cfgQueueInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
+
+    /* store pre-computed information in the same cache line
+     * to facilitate inlining of QRead and QWrite functions 
+     * in IxQMgr.h
+     */
+    ixQMgrQInlinedReadWriteInfo[qId].qReadCount = 0;
+    ixQMgrQInlinedReadWriteInfo[qId].qWriteCount = 0;
+    ixQMgrQInlinedReadWriteInfo[qId].qEntrySizeInWords = qEntrySizeInWords;
+    ixQMgrQInlinedReadWriteInfo[qId].qSizeInEntries = 
+		(UINT32)qSizeInWords / (UINT32)qEntrySizeInWords;
+
+    /* Calculate the new freeSramAddress from the size of the queue
+     * currently being configured.
+     */
+    freeSramAddress += (qSizeInWords * IX_QMGR_NUM_BYTES_PER_WORD);
+
+    /* Get the virtual SRAM address */
+    ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
+
+    IX_OSAL_ASSERT((freeSramAddress - (aqmLocalBaseAddress + (IX_QMGR_QUEBUFFER_SPACE_OFFSET))) <=
+	      IX_QMGR_QUE_BUFFER_SPACE_SIZE);
+
+    /* The queue is now configured */
+    cfgQueueInfo[qId].isConfigured = true;
+
+    ixOsalMutexUnlock(&ixQMgrQCfgMutex);
+
+#ifndef NDEBUG
+    /* Update statistics */
+    stats.qStats[qId].isConfigured = true;
+    stats.qStats[qId].qName = cfgQueueInfo[qId].qName;
+#endif
+    return IX_SUCCESS;
+}
+
+IxQMgrQSizeInWords
+ixQMgrQSizeInWordsGet (IxQMgrQId qId)
+{
+    /* No parameter checking as this is used on the data path */
+    return (cfgQueueInfo[qId].qSizeInWords);
+}
+
+IX_STATUS
+ixQMgrQSizeInEntriesGet (IxQMgrQId qId,
+			 unsigned *qSizeInEntries)
+{
+    if (!ixQMgrQIsConfigured(qId))
+    {
+        return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+
+    if(NULL == qSizeInEntries)
+    {
+        return IX_QMGR_PARAMETER_ERROR;
+    }
+
+    *qSizeInEntries = (UINT32)(cfgQueueInfo[qId].qSizeInWords) /
+        (UINT32)cfgQueueInfo[qId].qEntrySizeInWords;
+
+    return IX_SUCCESS;
+}
+
+IxQMgrQEntrySizeInWords
+ixQMgrQEntrySizeInWordsGet (IxQMgrQId qId)
+{
+    /* No parameter checking as this is used on the data path */
+    return (cfgQueueInfo[qId].qEntrySizeInWords);
+}
+
+IX_STATUS
+ixQMgrWatermarkSet (IxQMgrQId qId,
+		    IxQMgrWMLevel ne,
+		    IxQMgrWMLevel nf)
+{    
+    IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */
+    IxQMgrQStatus qStatusOnExit; /* to this function               */
+
+    if (!ixQMgrQIsConfigured(qId))
+    {
+        return IX_QMGR_Q_NOT_CONFIGURED;
+    }
+
+    if (!watermarkLevelIsOk (qId, ne))
+    {
+	return IX_QMGR_INVALID_Q_WM;
+    }
+
+    if (!watermarkLevelIsOk (qId, nf))
+    {
+	return IX_QMGR_INVALID_Q_WM;
+    }
+
+    /* Get the current queue status */
+    ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry);
+
+#ifndef NDEBUG
+    /* Update statistics */
+    stats.wmSetCnt++;
+#endif
+
+    ixQMgrAqmIfWatermarkSet (qId,
+			    ne,
+			    nf);
+
+    /* Get the current queue status */
+    ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit);
+  
+    /* If the status has changed return a warning */
+    if (qStatusOnEntry != qStatusOnExit)
+    {
+	return IX_QMGR_WARNING;
+    }
+
+    return IX_SUCCESS;
+}
+
+IX_STATUS
+ixQMgrAvailableSramAddressGet (UINT32 *address,
+			      unsigned *sizeOfFreeRam)
+{
+    UINT32 aqmLocalBaseAddress;
+
+    if ((NULL == address)||(NULL == sizeOfFreeRam)) 
+    {
+	return IX_QMGR_PARAMETER_ERROR;
+    }
+    if (!cfgInitialized)
+    {
+	return IX_FAIL;
+    }
+
+    *address = freeSramAddress;
+
+    /* Get the virtual SRAM address */
+    ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress);
+
+    /* 
+     * Calculate the size in bytes of free sram 
+     * i.e. current free SRAM virtual pointer from
+     *      (base + total size)
+     */
+    *sizeOfFreeRam = 
+	(aqmLocalBaseAddress +
+	IX_QMGR_AQM_SRAM_SIZE_IN_BYTES) -
+	freeSramAddress;
+
+    if (0 == *sizeOfFreeRam)
+    {
+	return IX_QMGR_NO_AVAILABLE_SRAM;
+    }
+
+    return IX_SUCCESS;
+}
+
+BOOL
+ixQMgrQIsConfigured (IxQMgrQId qId)
+{
+    if (!IX_QMGR_QID_IS_VALID(qId))
+    {
+	return false;
+    }
+
+    return cfgQueueInfo[qId].isConfigured;
+}
+
+IxQMgrQCfgStats*
+ixQMgrQCfgStatsGet (void)
+{
+    return &stats;
+}
+
+IxQMgrQCfgStats*
+ixQMgrQCfgQStatsGet (IxQMgrQId qId)
+{
+    unsigned int ne;
+    unsigned int nf;
+    UINT32 baseAddress;
+    UINT32 readPtr;
+    UINT32 writePtr;
+
+    stats.qStats[qId].qSizeInWords = cfgQueueInfo[qId].qSizeInWords;
+    stats.qStats[qId].qEntrySizeInWords = cfgQueueInfo[qId].qEntrySizeInWords;
+    
+    if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
+    {
+        if (IX_QMGR_WARNING != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries))
+        {
+	   IX_QMGR_LOG_WARNING1("Failed to get the number of entries in queue.... %d\n", qId);
+        }
+    }
+
+    ixQMgrAqmIfQueCfgRead (qId,
+			   stats.qStats[qId].numEntries,
+			   &baseAddress,
+			   &ne,
+			   &nf,
+			   &readPtr,
+			   &writePtr);
+        
+    stats.qStats[qId].baseAddress = baseAddress;
+    stats.qStats[qId].ne = ne;
+    stats.qStats[qId].nf = nf;
+    stats.qStats[qId].readPtr = readPtr;
+    stats.qStats[qId].writePtr = writePtr;
+
+    return &stats;
+}
+
+/* 
+ * Static function definitions
+ */
+
+PRIVATE BOOL
+watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level)
+{
+    unsigned qSizeInEntries;
+
+    switch (level)
+    {
+	case IX_QMGR_Q_WM_LEVEL0: 
+	case IX_QMGR_Q_WM_LEVEL1: 
+	case IX_QMGR_Q_WM_LEVEL2: 
+	case IX_QMGR_Q_WM_LEVEL4: 
+	case IX_QMGR_Q_WM_LEVEL8: 
+	case IX_QMGR_Q_WM_LEVEL16:
+	case IX_QMGR_Q_WM_LEVEL32:
+	case IX_QMGR_Q_WM_LEVEL64:
+	    break;
+	default:
+	    return false;
+    }
+
+    /* Check watermark is not bigger than the qSizeInEntries */
+    ixQMgrQSizeInEntriesGet(qId, &qSizeInEntries);
+
+    if ((unsigned)level > qSizeInEntries)
+    {
+	return false;
+    }
+
+    return true;
+}
+
+PRIVATE BOOL
+qSizeInWordsIsOk (IxQMgrQSizeInWords qSize)
+{
+    BOOL status;
+
+    switch (qSize)
+    {	
+	case IX_QMGR_Q_SIZE16:
+	case IX_QMGR_Q_SIZE32:
+	case IX_QMGR_Q_SIZE64:
+	case IX_QMGR_Q_SIZE128:
+	    status = true;
+	    break;
+	default:
+	    status = false;
+	    break;
+    }
+
+    return status;
+}
+
+PRIVATE BOOL
+qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize)
+{
+    BOOL status;
+
+    switch (entrySize)
+    {
+	case IX_QMGR_Q_ENTRY_SIZE1:
+	case IX_QMGR_Q_ENTRY_SIZE2:
+	case IX_QMGR_Q_ENTRY_SIZE4:
+	    status = true;
+	    break;
+	default:
+	    status = false;
+	    break;
+    }
+
+    return status;
+}
diff --git a/marvell/uboot/drivers/net/npe/Makefile b/marvell/uboot/drivers/net/npe/Makefile
new file mode 100644
index 0000000..0779255
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/Makefile
@@ -0,0 +1,60 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+LOCAL_CFLAGS  += -I$(TOPDIR)/drivers/net/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB -D__linux
+CFLAGS  += $(LOCAL_CFLAGS)
+CPPFLAGS  += $(LOCAL_CFLAGS) # needed for depend
+
+obj-y := npe.o \
+	miiphy.o \
+	IxOsalBufferMgt.o \
+	IxOsalIoMem.o \
+	IxOsalOsCacheMMU.o \
+	IxOsalOsMsgQ.o \
+	IxOsalOsSemaphore.o \
+	IxOsalOsServices.o \
+	IxOsalOsThread.o \
+	IxEthAcc.o \
+	IxEthAccCommon.o \
+	IxEthAccControlInterface.o \
+	IxEthAccDataPlane.o \
+	IxEthAccMac.o \
+	IxEthAccMii.o \
+	IxEthDBAPI.o \
+	IxEthDBAPISupport.o \
+	IxEthDBCore.o \
+	IxEthDBEvents.o \
+	IxEthDBFeatures.o \
+	IxEthDBFirewall.o \
+	IxEthDBHashtable.o \
+	IxEthDBLearning.o \
+	IxEthDBMem.o \
+	IxEthDBNPEAdaptor.o \
+	IxEthDBPortUpdate.o \
+	IxEthDBReports.o \
+	IxEthDBSearch.o \
+	IxEthDBSpanningTree.o \
+	IxEthDBUtil.o \
+	IxEthDBVlan.o \
+	IxEthDBWiFi.o \
+	IxEthMii.o \
+	IxQMgrAqmIf.o \
+	IxQMgrDispatcher.o \
+	IxQMgrInit.o \
+	IxQMgrQAccess.o \
+	IxQMgrQCfg.o \
+	IxFeatureCtrl.o \
+	IxNpeDl.o \
+	IxNpeDlImageMgr.o \
+	IxNpeDlNpeMgr.o \
+	IxNpeDlNpeMgrUtils.o \
+	IxNpeMh.o \
+	IxNpeMhConfig.o \
+	IxNpeMhReceive.o \
+	IxNpeMhSend.o \
+	IxNpeMhSolicitedCbMgr.o \
+	IxNpeMhUnsolicitedCbMgr.o
diff --git a/marvell/uboot/drivers/net/npe/include/IxAssert.h b/marvell/uboot/drivers/net/npe/include/IxAssert.h
new file mode 100644
index 0000000..8be0caf
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxAssert.h
@@ -0,0 +1,47 @@
+/**
+ * @file IxAssert.h
+ *
+ * @date 21-MAR-2002 (replaced by OSAL)
+ *
+ * @brief This file contains assert and ensure macros used by the IXP400 software
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxAssert IXP400 Assertion Macros (IxAssert) API
+ *
+ * @brief Assertion support
+ *
+ * @{
+ */
+
+#ifndef IXASSERT_H
+
+#ifndef __doxygen_HIDE
+#define IXASSERT_H
+#endif /* __doxygen_HIDE */
+
+#include "IxOsalBackward.h"
+
+#endif /* IXASSERT_H */
+
+/**
+ * @} addtogroup IxAssert
+ */
+
+
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxAtmSch.h b/marvell/uboot/drivers/net/npe/include/IxAtmSch.h
new file mode 100644
index 0000000..7d74771
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxAtmSch.h
@@ -0,0 +1,480 @@
+/**
+ * @file    IxAtmSch.h
+ *
+ * @date    23-NOV-2001
+ *
+ * @brief   Header file for the IXP400 ATM Traffic Shaper
+ *
+ * This component demonstrates an ATM Traffic Shaper implementation. It
+ * will perform shaping on upto 12 ports and total of 44 VCs accross all ports,
+ * 32 are intended for AAL0/5 and 12 for OAM (1 per port).
+ * The supported traffic types are;1 rt-VBR VC where PCR = SCR.
+ * (Effectively CBR) and Up-to 44 VBR VCs.
+ *
+ * This component models the ATM ports and VCs and is capable of producing
+ * a schedule of ATM cells per port which can be supplied to IxAtmdAcc
+ * for execution on the data path.
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ *
+ * @sa IxAtmm.h
+ *
+ */
+
+/**
+ * @defgroup IxAtmSch IXP400 ATM Transmit Scheduler (IxAtmSch) API
+ *
+ * @brief IXP400 ATM scheduler component Public API
+ *
+ * @{
+ */
+
+#ifndef IXATMSCH_H
+#define IXATMSCH_H
+
+#include "IxOsalTypes.h"
+#include "IxAtmTypes.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/* Return codes */
+
+/** 
+ * @ingroup IxAtmSch
+ *
+ * @def IX_ATMSCH_RET_NOT_ADMITTED
+ * @brief Indicates that CAC function has rejected VC registration due
+ *         to insufficient line capacity.
+*/
+#define IX_ATMSCH_RET_NOT_ADMITTED 2
+
+/**  
+ * @ingroup IxAtmSch
+ *
+ * @def IX_ATMSCH_RET_QUEUE_FULL
+ *  @brief Indicates that the VC queue is full, no more demand can be
+ *         queued at this time.
+ */
+#define IX_ATMSCH_RET_QUEUE_FULL 3
+
+/**  
+ * @ingroup IxAtmSch
+ *
+ *  @def IX_ATMSCH_RET_QUEUE_EMPTY
+ *  @brief Indicates that all VC queues on this port are empty and
+ *         therefore there are no cells to be scheduled at this time.
+ */
+#define IX_ATMSCH_RET_QUEUE_EMPTY 4
+
+/*
+ * Function declarations
+ */
+
+/**  
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchInit(void)
+ *
+ *  @brief This function is used to initialize the ixAtmSch component. It
+ *         should be called before any other IxAtmSch API function.
+ *
+ * @param None
+ *
+ * @return
+ * - <b>IX_SUCCESS :</b> indicates that
+ *          -# The ATM scheduler component has been successfully initialized.
+ *          -# The scheduler is ready to accept Port modelling requests.
+ * - <b>IX_FAIL :</b> Some internal error has prevented the scheduler component
+ *          from initialising.
+ */
+PUBLIC IX_STATUS
+ixAtmSchInit(void);
+
+/**  
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchPortModelInitialize( IxAtmLogicalPort port,
+                                       unsigned int portRate,
+                                       unsigned int minCellsToSchedule)
+ *
+ * @brief This function shall be called first to initialize an ATM port before
+ *         any other ixAtmSch API calls may be made for that port.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - The specific port to initialize.  Valid
+ *          values range from 0 to IX_UTOPIA_MAX_PORTS - 1, representing a 
+ *          maximum of IX_UTOPIA_MAX_PORTS possible ports.
+ *
+ * @param portRate unsigned int [in] - Value indicating the upstream capacity
+ *          of the indicated port.  The value should be supplied in
+ *          units of ATM (53 bytes) cells per second.
+ *          A port rate of 800Kbits/s is the equivalent 
+ *          of 1886 cells per second
+ *
+ * @param minCellsToSchedule unsigned int [in] - This parameter specifies the minimum
+ *          number of cells which the scheduler will put in a schedule
+ *          table for this port. This value sets the worst case CDVT for VCs
+ *          on this port i.e. CDVT = 1*minCellsToSchedule/portRate.
+ * @return
+ *    - <b>IX_SUCCESS :</b> indicates that
+ *          -# The ATM scheduler has been successfully initialized.
+ *          -# The requested port model has been established.
+ *          -# The scheduler is ready to accept VC modelling requests
+ *            on the ATM port.
+ *    - <b>IX_FAIL :</b> indicates the requested port could not be
+ * initialized.  */
+PUBLIC IX_STATUS
+ixAtmSchPortModelInitialize( IxAtmLogicalPort port,
+                                       unsigned int portRate,
+                                       unsigned int minCellsToSchedule);
+
+/**  
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchPortRateModify( IxAtmLogicalPort port,
+                        unsigned int portRate)
+ *
+ *  @brief This function is called to modify the portRate on a
+ *         previously initialized port, typically in the event that
+ *         the line condition of the port changes.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port which is to be
+ *          modified.
+ *
+ * @param portRate unsigned int [in] - Value indicating the new upstream
+ *          capacity for this port in cells/second.
+ *          A port rate of 800Kbits/s is the equivalent 
+ *          of 1886 cells per second
+ *
+ * @return
+ * - <b>IX_SUCCESS :</b> The port rate has been successfully modified.<br>
+ * - <b>IX_FAIL :</b> The port rate could not be modified, either
+ *      because the input data was invalid, or the new port rate is
+ *      insufficient to support established ATM VC contracts on this
+ *      port.
+ *
+ * @warning The IxAtmSch component will validate the supplied port
+ *          rate is sufficient to support all established VC
+ *          contracts on the port.  If the new port rate is
+ *          insufficient to support all established contracts then
+ *          the request to modify the port rate will be rejected.
+ *          In this event, the user is expected to remove
+ *          established contracts using the ixAtmSchVcModelRemove
+ *          interface and then retry this interface.
+ *
+ * @sa ixAtmSchVcModelRemove() */
+PUBLIC IX_STATUS
+ixAtmSchPortRateModify( IxAtmLogicalPort port,
+                        unsigned int portRate);
+
+
+/**  
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchVcModelSetup( IxAtmLogicalPort port,
+                      IxAtmTrafficDescriptor *trafficDesc,
+                      IxAtmSchedulerVcId *vcId)
+ *
+ *  @brief A client calls this interface to set up an upstream
+ *         (transmitting) virtual connection model (VC) on the
+ *         specified ATM port.  This function also provides the
+ *         virtual * connection admission control (CAC) service to the
+ *         client.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the upstream
+ *          VC is to be established.
+ *
+ * @param *trafficDesc @ref IxAtmTrafficDescriptor [in] - Pointer to a structure
+ *          describing the requested traffic contract of the VC to be
+ *          established.  This structure contains the typical ATM
+ *          traffic descriptor values (e.g. PCR, SCR, MBS, CDVT, etc.)
+ *          defined by the ATM standard.
+ *
+ * @param *vcId @ref IxAtmSchedulerVcId [out] - This value will be filled with the
+ *              port-unique identifier for this virtual connection.  A
+ *              valid identification is a non-negative number.
+ *
+ * @return
+ * - <b>IX_SUCCESS :</b> The VC has been successfully established on
+ *      this port.  The client may begin to submit demand on this VC.
+ * - <b>IX_ATMSCH_RET_NOT_ADMITTED :</b> The VC cannot be established
+ *      on this port because there is insufficient upstream capacity
+ *      available to support the requested traffic contract descriptor
+ * - <b>IX_FAIL :</b>Input data are invalid.  VC has not been
+ *      established.
+ */
+PUBLIC IX_STATUS
+ixAtmSchVcModelSetup( IxAtmLogicalPort port,
+                      IxAtmTrafficDescriptor *trafficDesc,
+                      IxAtmSchedulerVcId *vcId);
+
+/**  
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchVcConnIdSet( IxAtmLogicalPort port,
+                     IxAtmSchedulerVcId vcId,
+                     IxAtmConnId vcUserConnId)
+ *
+ *  @brief A client calls this interface to set the vcUserConnId for a VC on
+ *         the specified ATM port. This vcUserConnId will default to
+ *         IX_ATM_IDLE_CELLS_CONNID if this function is not called for a VC.
+ *         Hence if the client does not call this function for a VC then only idle
+ *         cells will be scheduled for this VC.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the upstream
+ *        VC is has been established.
+ *
+ * @param vcId @ref IxAtmSchedulerVcId [in] - This is the unique identifier for this virtual
+ *        connection. A valid identification is a non-negative number and is
+ *        all ports.
+ *
+ * @param vcUserConnId @ref IxAtmConnId [in] - The connId is used to refer to a VC in schedule
+ *        table entries. It is treated as the Id by which the scheduler client
+ *        knows the VC. It is used in any communicatations from the Scheduler
+ *        to the scheduler user e.g. schedule table entries.
+ *
+ * @return
+ * - <b>IX_SUCCESS :</b> The id has successfully been set.
+ * - <b>IX_FAIL :</b>Input data are invalid. connId id is not established.
+ */
+PUBLIC IX_STATUS
+ixAtmSchVcConnIdSet( IxAtmLogicalPort port,
+                     IxAtmSchedulerVcId vcId,
+                     IxAtmConnId vcUserConnId);
+
+/**  
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchVcModelRemove( IxAtmLogicalPort port,
+                       IxAtmSchedulerVcId vcId)
+ *
+ *  @brief Interface called by the client to remove a previously
+ *         established VC on a particular port.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be
+ *          removed is established.
+ *
+ * @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be removed.  This is the
+ *          value returned by the @ref ixAtmSchVcModelSetup call which
+ *          established the relevant VC.
+ *
+ * @return
+ * - <b>IX_SUCCESS :</b> The VC has been successfully removed from
+ *      this port. It is no longer modelled on this port.
+ * - <b>IX_FAIL :</b>Input data are invalid. The VC is still being modeled
+ *      by the traffic shaper.
+ *
+ * @sa ixAtmSchVcModelSetup() 
+ */
+PUBLIC IX_STATUS
+ixAtmSchVcModelRemove( IxAtmLogicalPort port,
+                       IxAtmSchedulerVcId vcId);
+
+/**  
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchVcQueueUpdate( IxAtmLogicalPort port,
+                       IxAtmSchedulerVcId vcId,
+                       unsigned int numberOfCells)
+ *
+ *  @brief The client calls this function to notify IxAtmSch that the
+ *         user of a VC has submitted cells for transmission.
+ *
+ *  This information is stored, aggregated from a number of calls to
+ *  ixAtmSchVcQueueUpdate and eventually used in the call to
+ *  ixAtmSchTableUpdate.
+ *
+ *  Normally IxAtmSch will update the VC queue by adding the number of
+ *  cells to the current queue length.  However, if IxAtmSch
+ *  determines that the user has over-submitted for the VC and
+ *  exceeded its transmission quota the queue request can be rejected.
+ *  The user should resubmit the request later when the queue has been
+ *  depleted.
+ *
+ *  This implementation of ixAtmSchVcQueueUpdate uses no operating
+ *  system or external facilities, either directly or indirectly.
+ *  This allows clients to call this function form within an interrupt handler.
+ *
+ *  This interface is structurally compatible with the
+ *  IxAtmdAccSchQueueUpdate callback type definition required for
+ *  IXP400 ATM scheduler interoperability.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be
+ *          updated is established.
+ *
+ * @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be updated.  This is the
+ *          value returned by the @ref ixAtmSchVcModelSetup call which
+ *          established the relevant VC.
+ *
+ * @param numberOfCells unsigned int [in] - Indicates how many ATM cells should
+ *          be added to the queue for this VC.
+ *
+ * @return
+ *  - <b>IX_SUCCESS :</b> The VC queue has been successfully updated.
+ *  - <b>IX_ATMSCH_RET_QUEUE_FULL :</b> The VC queue has reached a
+ *       preset limit.  This indicates the client has over-submitted
+ *       and exceeded its transmission quota.  The request is
+ *       rejected.  The VC queue is not updated.  The VC user is
+ *       advised to resubmit the request later.
+ *  - <b>IX_FAIL :</b> The input are invalid.  No VC queue is updated.
+ *
+ * @warning IxAtmSch assumes that the calling software ensures that
+ *          calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and
+ *          ixAtmSchTableUpdate are both self and mutually exclusive
+ *          for the same port.
+ *
+ * @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate().  */
+PUBLIC IX_STATUS
+ixAtmSchVcQueueUpdate( IxAtmLogicalPort port,
+                       IxAtmSchedulerVcId vcId,
+                       unsigned int numberOfCells);
+
+/**  
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchVcQueueClear( IxAtmLogicalPort port,
+                      IxAtmSchedulerVcId vcId)
+ *
+ *  @brief The client calls this function to remove all currently
+ *         queued cells from a registered VC.  The pending cell count
+ *         for the specified VC is reset to zero.
+ *
+ *  This interface is structurally compatible with the
+ *  IxAtmdAccSchQueueClear callback type definition required for
+ *  IXP400 ATM scheduler interoperability.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be
+ *          cleared is established.
+ *
+ * @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be cleared.  This is the
+ *          value returned by the @ref ixAtmSchVcModelSetup call which
+ *          established the relevant VC.
+ *
+ * @return
+ *  - <b>IX_SUCCESS :</b> The VC queue has been successfully cleared.
+ *  - <b>IX_FAIL :</b> The input are invalid.  No VC queue is modified.
+ *
+ * @warning IxAtmSch assumes that the calling software ensures that
+ *          calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and
+ *          ixAtmSchTableUpdate are both self and mutually exclusive
+ *          for the same port.
+ *
+ * @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate().  */
+PUBLIC IX_STATUS
+ixAtmSchVcQueueClear( IxAtmLogicalPort port,
+                      IxAtmSchedulerVcId vcId);
+
+/**  
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchTableUpdate( IxAtmLogicalPort port,
+                     unsigned int maxCells,
+                     IxAtmScheduleTable **rettable)
+ *
+ *  @brief The client calls this function to request an update of the
+ *         schedule table for a particular ATM port.
+ *
+ *  This is called when the client decides it needs a new sequence of
+ *  cells to send (probably because the transmit queue is near to
+ *  empty for this ATM port).  The scheduler will use its stored
+ *  information on the cells submitted for transmit (i.e. data
+ *  supplied via @ref ixAtmSchVcQueueUpdate function) with the traffic
+ *  descriptor information of all established VCs on the ATM port to
+ *  decide the sequence of cells to be sent and fill the schedule
+ *  table for a period of time into the future.
+ *
+ *  IxAtmSch will guarantee a minimum of minCellsToSchedule if there
+ *  is at least one cell ready to send. If there are no cells then
+ *  IX_ATMSCH_RET_QUEUE_EMPTY is returned.
+ *
+ *  This implementation of ixAtmSchTableUpdate uses no operating
+ *  system or external facilities, either directly or indirectly.
+ *  This allows clients to call this function form within an FIQ
+ *  interrupt handler.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port for which requested
+ *          schedule table is to be generated.
+ *
+ * @param maxCells unsigned [in] - Specifies the maximum number of cells
+ *          that must be scheduled in the supplied table during any
+ *          call to the interface.
+ *
+ * @param **table @ref IxAtmScheduleTable [out] - A pointer to an area of
+ *              storage is returned which contains the generated
+ *              schedule table.  The client should not modify the
+ *              contents of this table.
+ *
+ * @return
+ *  - <b>IX_SUCCESS :</b> The schedule table has been published.
+ *       Currently there is at least one VC queue that is nonempty.
+ *  - <b>IX_ATMSCH_RET_QUEUE_EMPTY :</b> Currently all VC queues on
+ *       this port are empty.  The schedule table returned is set to
+ *       NULL.  The client is not expected to invoke this function
+ *       again until more cells have been submitted on this port
+ *       through the @ref ixAtmSchVcQueueUpdate function.
+ *  - <b>IX_FAIL :</b> The input are invalid.  No action is taken.
+ *
+ * @warning IxAtmSch assumes that the calling software ensures that
+ *          calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and
+ *          ixAtmSchTableUpdate are both self and mutually exclusive
+ *          for the same port.
+ *
+ * @warning Subsequent calls to this function for the same port will
+ *          overwrite the contents of previously supplied schedule
+ *          tables.  The client must be completely finished with the
+ *          previously supplied schedule table before calling this
+ *          function again for the same port.
+ *
+ * @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate().  */
+PUBLIC IX_STATUS
+ixAtmSchTableUpdate( IxAtmLogicalPort port,
+                     unsigned int maxCells,
+                     IxAtmScheduleTable **rettable);
+
+/**  
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchShow(void)
+ *
+ *  @brief Utility function which will print statistics on the current
+ *         and accumulated state of VCs and traffic in the ATM
+ *         scheduler component.  Output is sent to the default output
+ *         device.
+ *
+ * @param none
+ * @return none
+ */
+PUBLIC void
+ixAtmSchShow(void);
+
+/**  
+ * @ingroup IxAtmSch
+ *
+ * @fn ixAtmSchStatsClear(void)
+ *
+ *  @brief Utility function which will reset all counter statistics in
+ *         the ATM scheduler to zero.
+ *
+ * @param none
+ * @return none
+ */
+PUBLIC void
+ixAtmSchStatsClear(void);
+
+#endif
+/* IXATMSCH_H */
+
+/** @} */
diff --git a/marvell/uboot/drivers/net/npe/include/IxAtmTypes.h b/marvell/uboot/drivers/net/npe/include/IxAtmTypes.h
new file mode 100644
index 0000000..6c8d12f
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxAtmTypes.h
@@ -0,0 +1,385 @@
+/**
+ * @file IxAtmTypes.h
+ *
+ * @date 24-MAR-2002
+ *
+ * @brief This file contains Atm types common to a number of Atm components.
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/* ------------------------------------------------------
+   Doxygen group definitions
+   ------------------------------------------------------ */
+/**
+ * @defgroup IxAtmTypes IXP400 ATM Types (IxAtmTypes)
+ *
+ * @brief The common set of types used in many Atm components
+ *
+ * @{ */
+
+#ifndef IXATMTYPES_H
+#define IXATMTYPES_H
+
+#include "IxNpeA.h"
+
+/**
+ * @enum IxAtmLogicalPort
+ *
+ * @brief Logical Port Definitions  :
+ *
+ * Only 1 port is available in SPHY configuration
+ * 12 ports are enabled in MPHY configuration
+ *
+ */
+typedef enum
+{
+    IX_UTOPIA_PORT_0 = 0,  /**< Port 0 */
+#ifdef IX_NPE_MPHYMULTIPORT
+    IX_UTOPIA_PORT_1,      /**< Port 1 */
+    IX_UTOPIA_PORT_2,      /**< Port 2 */
+    IX_UTOPIA_PORT_3,      /**< Port 3 */
+    IX_UTOPIA_PORT_4,      /**< Port 4 */
+    IX_UTOPIA_PORT_5,      /**< Port 5 */
+    IX_UTOPIA_PORT_6,      /**< Port 6 */
+    IX_UTOPIA_PORT_7,      /**< Port 7 */
+    IX_UTOPIA_PORT_8,      /**< Port 8 */
+    IX_UTOPIA_PORT_9,      /**< Port 9 */
+    IX_UTOPIA_PORT_10,     /**< Port 10 */
+    IX_UTOPIA_PORT_11,     /**< Port 11 */
+#endif /* IX_NPE_MPHY */
+    IX_UTOPIA_MAX_PORTS    /**< Not a port - just a definition for the
+                           * maximum possible ports
+                           */
+} IxAtmLogicalPort;
+
+/**
+ * @def IX_ATM_CELL_PAYLOAD_SIZE
+ * @brief Size of a ATM cell payload
+ */
+#define IX_ATM_CELL_PAYLOAD_SIZE             (48)
+
+/**
+ * @def IX_ATM_CELL_SIZE
+ * @brief Size of a ATM cell, including header
+ */
+#define IX_ATM_CELL_SIZE                     (53)
+
+/**
+ * @def IX_ATM_CELL_SIZE_NO_HEC
+ * @brief Size of a ATM cell, excluding HEC byte
+ */
+#define IX_ATM_CELL_SIZE_NO_HEC              (IX_ATM_CELL_SIZE - 1)
+
+/**
+ * @def IX_ATM_OAM_CELL_SIZE_NO_HEC
+ * @brief Size of a OAM cell, excluding HEC byte
+ */
+#define IX_ATM_OAM_CELL_SIZE_NO_HEC          IX_ATM_CELL_SIZE_NO_HEC
+
+/**
+ * @def IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE
+ * @brief Size of a AAL0 48 Cell payload
+ */
+#define IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE     IX_ATM_CELL_PAYLOAD_SIZE
+
+/**
+ * @def IX_ATM_AAL5_CELL_PAYLOAD_SIZE
+ * @brief Size of a AAL5 Cell payload
+ */
+#define IX_ATM_AAL5_CELL_PAYLOAD_SIZE        IX_ATM_CELL_PAYLOAD_SIZE
+
+/**
+ * @def IX_ATM_AAL0_52_CELL_SIZE_NO_HEC
+ * @brief Size of a AAL0 52 Cell, excluding HEC byte
+ */
+#define IX_ATM_AAL0_52_CELL_SIZE_NO_HEC      IX_ATM_CELL_SIZE_NO_HEC
+
+
+/**
+ * @def IX_ATM_MAX_VPI
+ * @brief Maximum value of an ATM VPI
+ */
+#define IX_ATM_MAX_VPI 255
+
+/**
+ * @def IX_ATM_MAX_VCI
+ * @brief Maximum value of an ATM VCI
+ */
+#define IX_ATM_MAX_VCI 65535
+
+ /**
+ * @def IX_ATM_MAX_NUM_AAL_VCS
+ * @brief Maximum number of active AAL5/AAL0 VCs in the system
+ */
+#define IX_ATM_MAX_NUM_AAL_VCS 32
+
+/**
+ * @def IX_ATM_MAX_NUM_VC
+ * @brief Maximum number of active AAL5/AAL0 VCs in the system
+ * The use of this macro is depreciated, it is retained for
+ * backward compatiblity. For current software release
+ * and beyond the define IX_ATM_MAX_NUM_AAL_VC should be used.
+ */
+#define IX_ATM_MAX_NUM_VC IX_ATM_MAX_NUM_AAL_VCS
+
+
+
+/**
+ * @def IX_ATM_MAX_NUM_OAM_TX_VCS
+ * @brief Maximum number of active OAM Tx VCs in the system, 
+ *        1 OAM VC per port
+ */
+#define IX_ATM_MAX_NUM_OAM_TX_VCS IX_UTOPIA_MAX_PORTS
+
+/**
+ * @def IX_ATM_MAX_NUM_OAM_RX_VCS
+ * @brief Maximum number of active OAM Rx VCs in the system, 
+ *        1 OAM VC shared accross all ports
+ */
+#define IX_ATM_MAX_NUM_OAM_RX_VCS 1
+
+/**
+ * @def IX_ATM_MAX_NUM_AAL_OAM_TX_VCS
+ * @brief Maximum number of active AAL5/AAL0/OAM Tx VCs in the system
+ */
+#define IX_ATM_MAX_NUM_AAL_OAM_TX_VCS (IX_ATM_MAX_NUM_AAL_VCS + IX_ATM_MAX_NUM_OAM_TX_VCS)
+
+/**
+ * @def IX_ATM_MAX_NUM_AAL_OAM_RX_VCS
+ * @brief Maximum number of active AAL5/AAL0/OAM Rx VCs in the system
+ */
+#define IX_ATM_MAX_NUM_AAL_OAM_RX_VCS (IX_ATM_MAX_NUM_AAL_VCS + IX_ATM_MAX_NUM_OAM_RX_VCS)
+
+/**
+ *  @def IX_ATM_IDLE_CELLS_CONNID
+ *  @brief VC Id used to indicate idle cells in the returned schedule table.
+ */
+#define IX_ATM_IDLE_CELLS_CONNID 0
+
+
+/**
+ *  @def IX_ATM_CELL_HEADER_VCI_GET
+ *  @brief get the VCI field from a cell header
+ */
+#define IX_ATM_CELL_HEADER_VCI_GET(cellHeader) \
+    (((cellHeader) >> 4) & IX_OAM_VCI_BITS_MASK);
+
+/**
+ *  @def IX_ATM_CELL_HEADER_VPI_GET
+ *  @brief get the VPI field from a cell header
+ */
+#define IX_ATM_CELL_HEADER_VPI_GET(cellHeader) \
+    (((cellHeader) >> 20) & IX_OAM_VPI_BITS_MASK);
+
+/**
+ *  @def IX_ATM_CELL_HEADER_PTI_GET
+ *  @brief get the PTI field from a cell header
+ */
+#define IX_ATM_CELL_HEADER_PTI_GET(cellHeader) \
+    ((cellHeader) >> 1) & IX_OAM_PTI_BITS_MASK;
+
+/**
+ * @typedef IxAtmCellHeader
+ *
+ * @brief ATM Cell Header, does not contain 4 byte HEC, added by NPE-A 
+ */
+typedef unsigned int IxAtmCellHeader;
+
+
+/**
+ * @enum IxAtmServiceCategory
+ *
+ * @brief Enumerated type representing available ATM service categories.
+ *   For more informatoin on these categories, see "Traffic Management
+ *   Specification" v4.1, published by the ATM Forum -
+ *   http://www.atmforum.com
+ */
+typedef enum
+{
+    IX_ATM_CBR,    /**< Constant Bit Rate */
+    IX_ATM_RTVBR,  /**< Real Time Variable Bit Rate */
+    IX_ATM_VBR,    /**< Variable Bit Rate */
+    IX_ATM_UBR,    /**< Unspecified Bit Rate */
+    IX_ATM_ABR     /**< Available Bit Rate (not supported) */
+
+} IxAtmServiceCategory;
+
+/**
+ *
+ * @enum IxAtmRxQueueId
+ *
+ * @brief Rx Queue Type for RX traffic
+ *
+ * IxAtmRxQueueId defines the queues involved for receiving data.
+ *
+ * There are two queues to facilitate prioritisation handling
+ * and processing the 2 queues with different algorithms and
+ * constraints
+ *
+ * e.g. : one queue can carry voice (or time-critical traffic), the
+ * other queue can carry non-voice traffic
+ *
+ */
+typedef enum
+{
+    IX_ATM_RX_A = 0,      /**< RX queue A */
+    IX_ATM_RX_B,          /**< RX queue B */
+    IX_ATM_MAX_RX_STREAMS /**< Maximum number of RX streams */
+} IxAtmRxQueueId;
+
+/**
+ * @brief Structure describing an ATM traffic contract for a Virtual
+ *         Connection (VC).
+ *
+ * Structure is used to specify the requested traffic contract for a
+ * VC to the IxAtmSch component using the @ref ixAtmSchVcModelSetup
+ * interface.
+ *
+ * These parameters are defined by the ATM forum working group
+ * (http://www.atmforum.com).
+ *
+ * @note Typical values for a voice channel 64 Kbit/s
+ * - atmService @a IX_ATM_RTVBR
+ * - pcr   400  (include IP overhead, and AAL5 trailer)
+ * - cdvt  5000000 (5 ms)
+ * - scr = pcr
+ *
+ * @note Typical values for a data channel 800 Kbit/s
+ * - atmService @a IX_ATM_UBR
+ * - pcr   1962  (include IP overhead, and AAL5 trailer)
+ * - cdvt  5000000 (5 ms)
+ *
+ */
+typedef struct
+{
+    IxAtmServiceCategory atmService; /**< ATM service category */
+    unsigned pcr;   /**< Peak Cell Rate - cells per second */
+    unsigned cdvt;  /**< Cell Delay Variation Tolerance - in nanoseconds */
+    unsigned scr;   /**< Sustained Cell Rate - cells per second */
+    unsigned mbs;   /**< Max Burst Size - cells */
+    unsigned mcr;   /**< Minimum Cell Rate - cells per second */
+    unsigned mfs;   /**< Max Frame Size - cells */
+} IxAtmTrafficDescriptor;
+
+/**
+ * @typedef IxAtmConnId
+ *
+ * @brief ATM VC data connection identifier.
+ *
+ * This is is generated by IxAtmdAcc when a successful connection is
+ * made on a VC. The is the ID by which IxAtmdAcc knows an active
+ * VC and should be used in IxAtmdAcc API calls to reference a
+ * specific VC.
+ */
+typedef unsigned int IxAtmConnId;
+
+/**
+ * @typedef IxAtmSchedulerVcId
+ *
+ * @brief ATM VC scheduling connection identifier.
+ *
+ * This id is generated and used by ATM Tx controller, generally
+ * the traffic shaper (e.g. IxAtmSch). The IxAtmdAcc component
+ * will request one of these Ids whenever a data connection on
+ * a Tx VC is requested. This ID will be used in callbacks to
+ * the ATM Transmission Ctrl s/w (e.g. IxAtmm) to reference a
+ * particular VC.
+ */
+typedef int IxAtmSchedulerVcId;
+
+/**
+ * @typedef IxAtmNpeRxVcId
+ *
+ * @brief ATM Rx VC identifier used by the ATM Npe.
+ *
+ * This Id is generated by IxAtmdAcc when a successful data connection
+ * is made on a rx VC.
+ */
+typedef unsigned int IxAtmNpeRxVcId;
+
+/**
+ * @brief ATM Schedule Table entry
+ *
+ * This IxAtmScheduleTableEntry is used by an ATM scheduler to inform
+ * IxAtmdAcc about the data to transmit (in term of cells per VC)
+ *
+ * This structure defines
+ * @li the number of cells to be transmitted (numberOfCells)
+ * @li the VC connection to be used for transmission (connId).
+ *
+ * @note - When the connection Id value is IX_ATM_IDLE_CELLS_CONNID, the
+ * corresponding number of idle cells will be transmitted to the hardware.
+ *
+ */
+typedef struct
+{
+    IxAtmConnId connId; /**< connection Id
+                 *
+                 * Identifier of VC from which cells are to be transmitted.
+                 * When this valus is IX_ATM_IDLE_CELLS_CONNID, this indicates
+                 * that the system should transmit the specified number
+                 * of idle cells. Unknown connIds result in the transmission
+                 * idle cells.
+                 */
+    unsigned int numberOfCells; /**< number of cells to transmit
+                 *
+                 * The number of contiguous cells to schedule from this VC
+                 * at this point. The valid range is from 1 to
+                 * @a IX_ATM_SCHEDULETABLE_MAXCELLS_PER_ENTRY. This
+                 * number can swap over mbufs and pdus. OverSchduling results
+                 * in the transmission of idle cells.
+                 */
+} IxAtmScheduleTableEntry;
+
+/**
+ * @brief This structure defines a schedule table which gives details
+ *         on which data (from which VCs) should be transmitted for a
+ *         forthcoming period of time for a particular port and the
+ *         order in which that data should be transmitted.
+ *
+ *  The schedule table consists of a series of entries each of which
+ *  will schedule one or more cells from a particular registered VC.
+ *  The total number of cells scheduled and the total number of
+ *  entries in the table are also indicated.
+ *
+ */
+typedef struct
+{
+    unsigned tableSize;      /**< Number of entries
+                              *
+                              * Indicates the total number of
+                              *   entries in the table.
+                              */
+    unsigned totalCellSlots; /**< Number of cells
+                              *
+                              * Indicates the total number of ATM
+                              *   cells which are scheduled by all the
+                              *   entries in the table.
+                              */
+    IxAtmScheduleTableEntry *table; /**< Pointer to schedule entries
+                                     *
+                                     * Pointer to an array
+                                     *   containing tableSize entries
+                                     */
+} IxAtmScheduleTable;
+
+#endif /* IXATMTYPES_H */
+
+/**
+ * @} defgroup IxAtmTypes
+ */
+
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxAtmdAcc.h b/marvell/uboot/drivers/net/npe/include/IxAtmdAcc.h
new file mode 100644
index 0000000..b37c615
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxAtmdAcc.h
@@ -0,0 +1,1169 @@
+/**
+ * @file    IxAtmdAcc.h
+ *
+ * @date    07-Nov-2001
+ *
+ * @brief IxAtmdAcc Public API
+ *
+ * This file contains the public API of IxAtmdAcc, related to the
+ * data functions of the component
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/* ------------------------------------------------------
+   Doxygen group definitions
+   ------------------------------------------------------ */
+
+/**
+ *
+ * @defgroup IxAtmdAccAPI IXP400 ATM Driver Access (IxAtmdAcc) API
+ *
+ * @brief The public API for the IXP400 Atm Driver Data component
+ *
+ * IxAtmdAcc is the low level interface by which AAL0/AAL5 and
+ * OAM data gets transmitted to,and received from the Utopia bus.
+ *
+ * For AAL0/AAL5 services transmit and receive connections may
+ * be established independantly for unique combinations of
+ * port,VPI,and VCI.
+ *
+ * Two AAL0 services supporting 48 or 52 byte cell data are provided.
+ * Submitted AAL0 PDUs must be a multiple of the cell data size (48/52).
+ * AAL0_52 is a raw cell service the client must format
+ * the PDU with an ATM cell header (excluding HEC) at the start of
+ * each cell, note that AtmdAcc does not validate the cell headers in
+ * a submitted PDU.
+ *
+ * OAM cells cannot be received over the AAL0 service but instead
+ * are received over a dedicated OAM service.
+ *
+ * For the OAM service an "OAM Tx channel" may be enabled for a port
+ * by establishing a single dedicated OAM Tx connection on that port.
+ * A single "OAM Rx channel" for all ports may be  enabled by
+ * establishing a dedicated OAM Rx connection.
+ *
+ * The OAM service allows buffers containing 52 byte OAM F4/F5 cells
+ * to be transmitted and received over the dedicated OAM channels.
+ * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM
+ * service offered by AtmdAcc is a raw cell transport service.
+ * It is assumed that ITU I.610 procedures that make use of this
+ * service are implemented above AtmdAcc.
+ *
+ * Note that the dedicated OAM connections are established on
+ * reserved VPI,VCI, and (in the case of Rx) port values defined below.
+ * These values are used purely to descriminate the dedicated OAM channels
+ * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be
+ * realised for particluar VPI/VCIs by manipulating the VPI,VCI
+ * fields of the ATM cell headers of cells in the buffers passed
+ * to AtmdAcc. Note that AtmdAcc does not validate the cell headers
+ * in a submitted OAM PDU.
+ *
+ *
+ *
+ * This part is related to the User datapath processing
+ *
+ * @{
+ */
+
+#ifndef IXATMDACC_H
+#define IXATMDACC_H
+
+#include "IxAtmTypes.h"
+
+/* ------------------------------------------------------
+   AtmdAcc Data Types definition
+   ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_WARNING
+ *
+ * @brief Warning return code
+ *
+ * This constant is used to tell IxAtmDAcc user about a special case.
+ *
+ */
+#define IX_ATMDACC_WARNING 2
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_BUSY
+ *
+ * @brief Busy return code
+ *
+ * This constant is used to tell IxAtmDAcc user that the request
+ * is correct, but cannot be processed because the IxAtmAcc resources
+ * are already used. The user has to retry its request later
+ *
+ */
+#define IX_ATMDACC_BUSY 3
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_RESOURCES_STILL_ALLOCATED
+ *
+ * @brief Disconnect return code
+ *
+ * This constant is used to tell IxAtmDAcc user that the disconnect
+ * functions are not complete because the resources used by the driver
+ * are not yet released. The user has to retry the disconnect call
+ * later.
+ *
+ */
+#define IX_ATMDACC_RESOURCES_STILL_ALLOCATED 4
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_DEFAULT_REPLENISH_COUNT
+ *
+ * @brief Default resources usage for RxVcFree replenish mechanism
+ *
+ * This constant is used to tell IxAtmDAcc to allocate and use
+ * the minimum of resources for rx free replenish.
+ *
+ * @sa ixAtmdAccRxVcConnect
+ */
+#define IX_ATMDACC_DEFAULT_REPLENISH_COUNT 0
+
+
+/**
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_OAM_TX_VPI
+ *
+ * @brief The reserved value used for the dedicated OAM
+ * Tx connection. This "well known" value is used by atmdAcc and
+ * its clients to dsicriminate the OAM channel, and should be chosen so
+ * that it does not coencide with the VPI value used in an AAL0/AAL5 connection.
+ * Any attempt to connect a service type other than OAM on this VPI will fail.
+ *
+ *
+ */
+#define IX_ATMDACC_OAM_TX_VPI 0
+
+/**
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_OAM_TX_VCI
+ *
+ * @brief The reserved value used for the dedicated OAM
+ * Tx connection. This "well known" value is used by atmdAcc and
+ * its clients to dsicriminate the OAM channel, and should be chosen so
+ * that it does not coencide with the VCI value used in an AAL0/AAL5 connection.
+ * Any attempt to connect a service type other than OAM on this VCI will fail.
+ */
+#define IX_ATMDACC_OAM_TX_VCI 0
+
+
+ /**
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_OAM_RX_PORT
+ *
+ * @brief The reserved dummy PORT used for all dedicated OAM
+ * Rx connections. Note that this is not a real port but must
+ * have a value that lies within the valid range of port values.
+ */
+#define IX_ATMDACC_OAM_RX_PORT IX_UTOPIA_PORT_0
+
+ /**
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_OAM_RX_VPI
+ *
+ * @brief The reserved value value used for the dedicated OAM
+ * Rx connection. This value should be chosen so that it does not
+ * coencide with the VPI value used in an AAL0/AAL5 connection.
+ * Any attempt to connect a service type other than OAM on this VPI will fail.
+ */
+#define IX_ATMDACC_OAM_RX_VPI 0
+
+/**
+ * @ingroup IxAtmdAccAPI
+ *
+ * @def IX_ATMDACC_OAM_RX_VCI
+ *
+ * @brief The reserved value value used for the dedicated OAM
+ * Rx connection. This value should be chosen so that it does not
+ * coencide with the VCI value used in an AAL0/AAL5 connection.
+ * Any attempt to connect a service type other than OAM on this VCI will fail.
+ */
+#define IX_ATMDACC_OAM_RX_VCI 0
+
+
+/**
+ * @enum IxAtmdAccPduStatus
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @brief IxAtmdAcc Pdu status :
+ *
+ * IxAtmdAccPduStatus is used during a RX operation to indicate
+ * the status of the received PDU
+ *
+ */
+
+typedef enum
+{
+    IX_ATMDACC_AAL0_VALID = 0,    /**< aal0 pdu */
+    IX_ATMDACC_OAM_VALID,         /**< OAM pdu */
+    IX_ATMDACC_AAL2_VALID,        /**< aal2 pdu @b reserved for future use */
+    IX_ATMDACC_AAL5_VALID,        /**< aal5 pdu complete and trailer is valid */
+    IX_ATMDACC_AAL5_PARTIAL,      /**< aal5 pdu not complete, trailer is missing */
+    IX_ATMDACC_AAL5_CRC_ERROR,    /**< aal5 pdu not complete, crc error/length error */
+    IX_ATMDACC_MBUF_RETURN        /**< empty buffer returned to the user */
+} IxAtmdAccPduStatus;
+
+
+/**
+ *
+ * @enum IxAtmdAccAalType
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @brief IxAtmdAcc AAL Service Type :
+ *
+ * IxAtmdAccAalType defines the type of traffic to run on this VC
+ *
+ */
+typedef enum
+{
+    IX_ATMDACC_AAL5,                /**< ITU-T AAL5 */
+    IX_ATMDACC_AAL2,                /**< ITU-T AAL2 @b reserved for future use */
+    IX_ATMDACC_AAL0_48,             /**< AAL0 48 byte payloads (cell header is added by NPE)*/
+    IX_ATMDACC_AAL0_52,             /**< AAL0 52 byte cell data (HEC is added by NPE) */
+    IX_ATMDACC_OAM,                 /**< OAM cell transport service (HEC is added by NPE)*/
+    IX_ATMDACC_MAX_SERVICE_TYPE     /**< not a service, used for parameter validation */
+} IxAtmdAccAalType;
+
+/**
+ *
+ * @enum IxAtmdAccClpStatus
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @brief IxAtmdAcc CLP indication
+ *
+ * IxAtmdAccClpStatus defines the CLP status of the current PDU
+ *
+ */
+typedef enum
+{
+    IX_ATMDACC_CLP_NOT_SET = 0,     /**< CLP indication is not set */
+    IX_ATMDACC_CLP_SET = 1     /**< CLP indication is set */
+} IxAtmdAccClpStatus;
+
+/**
+ * @typedef IxAtmdAccUserId
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @brief User-supplied Id
+ *
+ * IxAtmdAccUserId is passed through callbacks and allows the
+ * IxAtmdAcc user to identify the source of a call back. The range of
+ * this user-owned Id is [0...2^32-1)].
+ *
+ * The user provides this own Ids on a per-channel basis as a parameter
+ * in a call to @a ixAtmdAccRxVcConnect() or @a ixAtmdAccRxVcConnect()
+ *
+ * @sa ixAtmdAccRxVcConnect
+ * @sa ixAtmdAccTxVcConnect
+ *
+ */
+typedef unsigned int IxAtmdAccUserId;
+
+/* ------------------------------------------------------
+   Part of the IxAtmdAcc interface related to RX traffic
+   ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @brief  Rx callback prototype
+ *
+ * IxAtmdAccRxVcRxCallback is the prototype of the Rx callback user
+ * function called once per PDU to pass a receive Pdu to a user on a
+ * partilcular connection. The callback is likely to push the mbufs
+ * to a protocol layer, and recycle the mbufs for a further use.
+ *
+ * @note -This function is called ONLY in the context of
+ *        the @a ixAtmdAccRxDispatch() function
+ *
+ * @sa ixAtmdAccRxDispatch
+ * @sa ixAtmdAccRxVcConnect
+ *
+ * @param port @ref IxAtmLogicalPort [in] - the port on which this PDU was received
+ *        a logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ * @param userId @ref IxAtmdAccUserId [in] - user Id provided in the call
+ *        to @a ixAtmdAccRxVcConnect()
+ * @param status @ref IxAtmdAccPduStatus [in] - an indication about the PDU validity.
+ *        In the case of AAL0 the only possibile value is
+ *        AAL0_VALID, in this case the client may optionally determine
+ *        that an rx timeout occured by checking if the mbuf is
+ *        compleletly or only partially filled, the later case
+ *        indicating a timeout.
+ *        In the case of OAM the only possible value is OAM valid.
+ *        The status is set to @a IX_ATMDACC_MBUF_RETURN when
+ *        the mbuf is released during a disconnect process.
+ * @param clp @ref IxAtmdAccClpStatus [in] - clp indication for this PDU.
+ *        For AAL5/AAL0_48 this information
+ *        is set if the clp bit of any rx cell is set
+ *        For AAL0-52/OAM the client may inspect the CLP in individual
+ *        cell headers in the PDU, and this parameter is set to 0.
+ * @param *mbufPtr @ref IX_OSAL_MBUF [in] - depending on the servive type a pointer to
+ *        an mbuf (AAL5/AAL0/OAM) or mbuf chain (AAL5 only),
+ *        that comprises the complete PDU data.
+ *
+ *        This parameter is guaranteed not to be a null pointer.
+ *
+ */
+typedef void (*IxAtmdAccRxVcRxCallback) (IxAtmLogicalPort port,
+                       IxAtmdAccUserId userId,
+                       IxAtmdAccPduStatus status,
+                       IxAtmdAccClpStatus clp,
+                       IX_OSAL_MBUF * mbufPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @brief Callback prototype for free buffer level is low.
+ *
+ * IxAtmdAccRxVcFreeLowCallback is the prototype of the user function
+ * which get called on a per-VC basis, when more  mbufs are needed to
+ * continue the ATM data reception. This function is likely to supply
+ * more available mbufs by one or many calls to the replenish function
+ * @a ixAtmdAccRxVcFreeReplenish()
+ *
+ * This function is called when the number of available buffers for
+ * reception is going under the threshold level as defined
+ * in @a ixAtmdAccRxVcFreeLowCallbackRegister()
+ *
+ * This function is called inside an Qmgr dispatch context. No system
+ * resource or interrupt-unsafe feature should be used inside this
+ * callback.
+ *
+ * @sa ixAtmdAccRxVcFreeLowCallbackRegister
+ * @sa IxAtmdAccRxVcFreeLowCallback
+ * @sa ixAtmdAccRxVcFreeReplenish
+ * @sa ixAtmdAccRxVcFreeEntriesQuery
+ * @sa ixAtmdAccRxVcConnect
+ *
+ * @param userId @ref IxAtmdAccUserId [in] - user Id provided in the call
+ * to @a ixAtmdAccRxVcConnect()
+ *
+ * @return None
+ *
+ */
+typedef void (*IxAtmdAccRxVcFreeLowCallback) (IxAtmdAccUserId userId);
+
+/* ------------------------------------------------------
+   Part of the IxAtmdAcc interface related to TX traffic
+   ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @brief  Buffer callback prototype.
+ *
+ * This function is called to relinguish ownership of a transmitted
+ * buffer chain to the user.
+ *
+ * @note -In the case of a chained mbuf the AmtdAcc component can
+ * chain many user buffers together and pass ownership to the user in
+ * one function call.
+ *
+ * @param userId @ref IxAtmdAccUserId [in] - user If provided at registration of this
+ *        callback.
+ * @param mbufPtr @ref IX_OSAL_MBUF [in] - a pointer to mbufs or chain of mbufs and is
+ *        guaranteed not to be a null pointer.
+ *
+ */
+typedef void (*IxAtmdAccTxVcBufferReturnCallback) (IxAtmdAccUserId userId,
+                        IX_OSAL_MBUF * mbufPtr);
+
+/* ------------------------------------------------------
+   Part of the IxAtmdAcc interface related to Initialisation
+   ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccInit (void)
+ *
+ * @brief Initialise the IxAtmdAcc Component
+ *
+ * This function initialise the IxAtmdAcc component. This function shall
+ * be called before any other function of the API. Its role is to
+ * initialise all internal resources of the IxAtmdAcc component.
+ *
+ * The ixQmgr component needs to be initialized prior the use of
+ * @a ixAtmdAccInit()
+ *
+ * @param none
+ *
+ * Failing to initilialize the IxAtmdAcc API before any use of it will
+ * result in a failed status.
+ * If the specified component is not present, a success status will still be 
+ * returned, however, a warning indicating the NPE to download to is not
+ * present will be issued.
+ *
+ * @return @li IX_SUCCESS initialisation is complete (in case of component not
+ *             being present, a warning is clearly indicated)
+ * @return @li IX_FAIL unable to process this request either
+ *             because this IxAtmdAcc is already initialised
+ *             or some unspecified error has occrred.
+ */
+PUBLIC IX_STATUS ixAtmdAccInit (void);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccShow (void)
+ *
+ * @brief Show IxAtmdAcc configuration on a per port basis
+ *
+ * @param none
+ *
+ * @return none
+ *
+ * @note - Display use printf() and are redirected to stdout
+ */
+PUBLIC void
+ixAtmdAccShow (void);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ * 
+ * @fn ixAtmdAccStatsShow (void)
+ *
+ * @brief Show all IxAtmdAcc stats
+ *
+ * @param none
+ *
+ * @return none
+ *
+ * @note - Stats display use printf() and are redirected to stdout
+ */
+PUBLIC void
+ixAtmdAccStatsShow (void);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccStatsReset (void)
+ *
+ * @brief Reset all IxAtmdAcc stats
+ *
+ * @param none
+ *
+ * @return none
+ *
+ */
+PUBLIC void
+ixAtmdAccStatsReset (void);
+
+/* ------------------------------------------------------
+   Part of the IxAtmdAcc interface related to RX traffic
+   ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccRxVcConnect (IxAtmLogicalPort port,
+                      unsigned int vpi,
+                      unsigned int vci,
+                      IxAtmdAccAalType aalServiceType,
+                      IxAtmRxQueueId rxQueueId,
+                      IxAtmdAccUserId userCallbackId,
+                      IxAtmdAccRxVcRxCallback rxCallback,
+                      unsigned int minimumReplenishCount,
+                      IxAtmConnId * connIdPtr,
+                      IxAtmNpeRxVcId * npeVcIdPtr )
+ *
+ * @brief Connect to a Aal Pdu receive service for a particular
+ *        port/vpi/vci, and service type.
+ *
+ * This function allows a user to connect to an Aal5/Aal0/OAM Pdu receive service
+ * for a particular port/vpi/vci. It registers the callback and allocates
+ * internal resources and a Connection Id to be used in further API calls
+ * related to this VCC.
+ *
+ * The function will setup VC receive service on the specified rx queue.
+ *
+ * This function is blocking and makes use internal locks, and hence
+ * should not be called from an interrupt context.
+ *
+ * On return from @a ixAtmdAccRxVcConnect() with a failure status, the
+ * connection Id parameter is unspecified. Its value cannot be used.
+ * A connId is the reference by which IxAtmdAcc refers to a
+ * connected VC. This identifier is the result of a succesful call
+ * to a connect function. This identifier is invalid after a
+ * sucessful call to a disconnect function.
+ *
+ * Calling this function for the same combination of Vpi, Vci and more
+ * than once without calling @a ixAtmdAccRxVcTryDisconnect() will result in a
+ * failure status.
+ *
+ * If this function returns success the user should supply receive
+ * buffers by calling @a ixAtmdAccRxVcFreeReplenish() and then call
+ * @a ixAtmdAccRxVcEnable() to begin receiving pdus.
+ *
+ * There is a choice of two receive Qs on which the VC pdus could be
+ * receive. The user must associate the VC with one of these. Essentially
+ * having two qs allows more flexible system configuration such as have
+ * high prioriy traffic on one q (e.g. voice) and low priority traffic on
+ * the other (e.g. data). The high priority Q could be serviced in
+ * preference to the low priority Q. One queue may be configured to be
+ * serviced as soon as there is traffic, the other queue may be configured
+ * to be serviced by a polling mechanism running at idle time.
+ *
+ * Two AAL0 services supporting 48 or 52 byte cell data are provided.
+ * Received AAL0 PDUs will be be a multiple of the cell data size (48/52).
+ * AAL0_52 is a raw cell service and includes an ATM cell header
+ * (excluding HEC) at the start of each cell.
+ *
+ * A single "OAM Rx channel" for all ports may be  enabled by
+ * establishing a dedicated OAM Rx connection.
+ *
+ * The OAM service allows buffers containing 52 byte OAM F4/F5 cells
+ * to be transmitted and received over the dedicated OAM channels.
+ * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM
+ * service offered by AtmdAcc is a raw cell transport service.
+ * It is assumed that ITU I.610 procedures that make use of this
+ * service are implemented above AtmdAcc.
+ *
+ * Note that the dedicated OAM connections are established on
+ * reserved VPI,VCI, and (in the case of Rx) port values.
+ * These values are used purely to descriminate the dedicated OAM channels
+ * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be
+ * realised for particluar VPI/VCIs by manipulating the VPI,VCI
+ * fields of the ATM cell headers of cells in the buffers passed
+ * to AtmdAcc.
+ *
+ * Calling this function prior to enable the port will fail.
+ *
+ * @sa ixAtmdAccRxDispatch
+ * @sa ixAtmdAccRxVcEnable
+ * @sa ixAtmdAccRxVcDisable
+ * @sa ixAtmdAccRxVcTryDisconnect
+ * @sa ixAtmdAccPortEnable
+ *
+ * @param port @ref IxAtmLogicalPort [in] - VC identification : logical PHY port
+ *                  [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ * @param vpi unsigned int [in] - VC identification : ATM Vpi [0..255] or IX_ATMDACC_OAM_VPI
+ * @param vci unsigned int [in] - VC identification : ATM Vci [0..65535] or IX_ATMDACC_OAM_VCI
+ * @param aalServiceType @ref IxAtmdAccAalType [in] - type of service: AAL5, AAL0_48, AAL0_52, or OAM
+ * @param rxQueueId @ref IxAtmRxQueueId [in] - this identifieds which of two Qs the VC
+ *     should use.when icoming traffic is processed
+ * @param userCallbackId @ref IxAtmdAccUserId [in] - user Id used later as a parameter to
+ *     the supplied rxCallback.
+ * @param rxCallback [in] @ref IxAtmdAccRxVxRxCallback - function called when mbufs are received.
+ *     This parameter cannot be a null pointer.
+ * @param bufferFreeCallback [in] - function to be called to return
+ *     ownership of buffers to IxAtmdAcc user.
+ * @param minimumReplenishCount unsigned int [in] -  For AAL5/AAL0 the number of free mbufs
+ *     to be used with this channel. Use a high number when the expected traffic
+ *     rate on this channel is high, or when the user's mbufs are small, or when
+ *     the RxVcFreeLow Notification has to be invoked less often. When this
+ *     value is IX_ATMDACC_DEFAULT_REPLENISH_COUNT, the minimum of
+ *     resources  will be used. Depending on traffic rate, pdu
+ *     size and mbuf size, rxfree queue size, polling/interrupt rate, this value may
+ *     require to be replaced by a different value in the range 1-128
+ *     For OAM the rxFree queue size is fixed by atmdAcc and this parameter is ignored.
+ * @param connIdPtr @ref IxAtmConnId [out] - pointer to a connection Id
+ *     This parameter cannot be a null pointer.
+ * @param npeVcIdPtr @ref IxAtmNpeRxVcId [out] - pointer to an npe Vc Id
+ *     This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS successful call to IxAtmdAccRxVcConnect
+ * @return @li IX_ATMDACC_BUSY cannot process this request :
+ *         no VC is available
+ * @return @li IX_FAIL
+ *             parameter error,
+ *             VC already in use,
+ *             attempt to connect AAL service on reserved OAM VPI/VCI,
+ *             attempt to connect OAM service on VPI/VCI other than the reserved OAM VPI/VCI,
+ *             port is not initialised,
+ *             or some other error occurs during processing.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxVcConnect (IxAtmLogicalPort port,
+                      unsigned int vpi,
+                      unsigned int vci,
+                      IxAtmdAccAalType aalServiceType,
+                      IxAtmRxQueueId rxQueueId,
+                      IxAtmdAccUserId userCallbackId,
+                      IxAtmdAccRxVcRxCallback rxCallback,
+                      unsigned int minimumReplenishCount,
+                      IxAtmConnId * connIdPtr,
+                      IxAtmNpeRxVcId * npeVcIdPtr );
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ * 
+ * @fn ixAtmdAccRxVcFreeReplenish (IxAtmConnId connId,
+                        IX_OSAL_MBUF * mbufPtr)
+ *
+ * @brief Provide free mbufs for data reception on a connection.
+ *
+ * This function provides mbufs for data reception by the hardware. This
+ * function needs to be called by the user on a regular basis to ensure
+ * no packet loss. Providing free buffers is a connection-based feature;
+ * each connection can have different requirements in terms of buffer size
+ * number of buffers, recycling rate. This function could be invoked from
+ * within the context of a @a IxAtmdAccRxVcFreeLowCallback() callback
+ * for a particular VC
+ *
+ * Mbufs provided through this function call can be chained. They will be
+ * unchained internally. A call to this function with chained mbufs or
+ * multiple calls with unchained mbufs are equivalent, but calls with
+ * unchained mbufs are more efficients.
+ *
+ * Mbufs provided to this interface need to be able to hold at least one
+ * full cell payload (48/52 bytes, depending on service type).
+ * Chained buffers with a size less than the size supported by the hardware
+ * will be returned through the rx callback provided during the connect step.
+ *
+ * Failing to invoke this function prior to enabling the RX traffic
+ * can result in packet loss.
+ *
+ * This function is not reentrant for the same connId.
+ *
+ * This function does not use system resources and can be
+ * invoked from an interrupt context.
+ *
+ * @note - Over replenish is detected, and extra mbufs are returned through
+ *         the rx callback provided during the connect step.
+ *
+ * @note - Mbuf provided to the replenish function should have a length greater or
+ *         equal to 48/52 bytes according to service type.
+ *
+ * @note - The memory cache of mMbuf payload should be invalidated prior to Mbuf
+ *         submission. Flushing the Mbuf headers is handled by IxAtmdAcc.
+ *
+ * @note - When a chained mbuf is provided, this function process the mbufs
+ *         up to the hardware limit and invokes the user-supplied callback
+ *         to release extra buffers.
+ *
+ * @sa ixAtmdAccRxVcFreeLowCallbackRegister
+ * @sa IxAtmdAccRxVcFreeLowCallback
+ * @sa ixAtmdAccRxVcConnect
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as returned from a succesfull call to
+ *        @a IxAtmdAccRxVcConnect()
+ * @param mbufPtr @ref IX_OSAL_MBUF [in] - pointer to a mbuf structure to be used for data
+ *        reception. The mbuf pointed to by this parameter can be chained
+ *        to an other mbuf.
+ *
+ * @return @li IX_SUCCESS successful call to @a ixAtmdAccRxVcFreeReplenish()
+ *          and the mbuf is now ready to use for incoming traffic.
+ * @return @li IX_ATMDACC_BUSY cannot process this request because
+ *         the max number of outstanding free buffers has been reached
+ *         or the internal resources have exhausted for this VC.
+ *         The user is responsible for retrying this request later.
+ * @return @li IX_FAIL cannot process this request because of parameter
+ *         errors or some unspecified internal error has occurred.
+ *
+ * @note - It is not always guaranteed the replenish step to be as fast as the
+ *   hardware is consuming Rx Free mbufs. There is nothing in IxAtmdAcc to
+ *   guarantee that replenish reaches the rxFree threshold level. If the
+ *   threshold level is not reached, the next rxFree low notification for
+ *   this channel will not be triggered.
+ *   The preferred ways to replenish can be as follows (depending on
+ *   applications and implementations) :
+ *   @li Replenish in a rxFree low notification until the function
+ *       ixAtmdAccRxVcFreeReplenish() returns IX_ATMDACC_BUSY
+ *   @li Query the queue level using @sa ixAtmdAccRxVcFreeEntriesQuery, then
+ *     , replenish using @a ixAtmdAccRxVcFreeReplenish(), then query the queue
+ *       level again, and replenish if the threshold is still not reached.
+ *   @li Trigger replenish from an other event source and use rxFree starvation
+ *       to throttle the Rx traffic.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxVcFreeReplenish (IxAtmConnId connId,
+                        IX_OSAL_MBUF * mbufPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ * 
+ * @fn ixAtmdAccRxVcFreeLowCallbackRegister (IxAtmConnId connId,
+                                    unsigned int numberOfMbufs,
+                                    IxAtmdAccRxVcFreeLowCallback callback)
+ *
+ * @brief Configure the RX Free threshold value and register a callback
+ * to handle threshold notifications.
+ *
+ * The function ixAtmdAccRxVcFreeLowCallbackRegister sets the threshold value for
+ * a particular RX VC. When the number of buffers reaches this threshold
+ * the callback is invoked.
+ *
+ * This function should be called once per VC before RX traffic is
+ * enabled.This function will fail if the curent level of the free buffers
+ * is equal or less than the threshold value.
+ *
+ * @sa ixAtmdAccRxVcFreeLowCallbackRegister
+ * @sa IxAtmdAccRxVcFreeLowCallback
+ * @sa ixAtmdAccRxVcFreeReplenish
+ * @sa ixAtmdAccRxVcFreeEntriesQuery
+ * @sa ixAtmdAccRxVcConnect
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call
+ *        to @a IxAtmdAccRxVcConnect()
+ * @param numberOfMbufs unsigned int [in] - threshold number of buffers. This number
+ *        has to be a power of 2, one of the values 0,1,2,4,8,16,32....
+ *        The maximum value cannot be more than half of the rxFree queue
+ *        size (which can be retrieved using @a ixAtmdAccRxVcFreeEntriesQuery()
+ *        before any use of the @a ixAtmdAccRxVcFreeReplenish() function)
+ * @param callback @ref IxAtmdAccRxVcFreeLowCallback [in] - function telling the user that the number of
+ *        free buffers has reduced to the threshold value.
+ *
+ * @return @li IX_SUCCESS Threshold set successfully.
+ * @return @li IX_FAIL parameter error or the current number of free buffers
+ *              is less than or equal to the threshold supplied or some
+ *              unspecified error has occrred.
+ *
+ * @note - the callback will be called when the threshold level will drop from
+ *        exactly (numberOfMbufs + 1) to (numberOfMbufs).
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxVcFreeLowCallbackRegister (IxAtmConnId connId,
+    unsigned int numberOfMbufs,
+    IxAtmdAccRxVcFreeLowCallback callback);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccRxVcFreeEntriesQuery (IxAtmConnId connId,
+                         unsigned int *numberOfMbufsPtr)
+ *
+ * @brief Get the number of rx mbufs the system can accept to replenish the
+ *       the rx reception mechanism on a particular channel
+ *
+ * The ixAtmdAccRxVcFreeEntriesQuery function is used to retrieve the current
+ * number of available mbuf entries for reception, on a per-VC basis. This
+ * function can be used to know the number of mbufs which can be provided
+ * using @a ixAtmdAccRxVcFreeReplenish().
+ *
+ * This function can be used from a timer context, or can be associated
+ * with a threshold event, or can be used inside an active polling
+ * mechanism which is under user control.
+ *
+ * This function is reentrant and does not use system resources and can
+ * be invoked from an interrupt context.
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call
+ *        to @a IxAtmdAccRxVcConnect()
+ * @param numberOfMbufsPtr unsigned int [out] - Pointer to the number of available entries.
+ *      . This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS the current number of mbufs not yet used for incoming traffic
+ * @return @li IX_FAIL invalid parameter
+ *
+ * @sa ixAtmdAccRxVcFreeReplenish
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxVcFreeEntriesQuery (IxAtmConnId connId,
+                         unsigned int *numberOfMbufsPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccRxVcEnable (IxAtmConnId connId)
+ *
+ * @brief Start the RX service on a VC.
+ *
+ * This functions kicks-off the traffic reception for a particular VC.
+ * Once invoked, incoming PDUs will be made available by the hardware
+ * and are eventually directed to the @a IxAtmdAccRxVcRxCallback() callback
+ * registered for the connection.
+ *
+ * If the traffic is already running, this function returns IX_SUCCESS.
+ * This function can be invoked many times.
+ *
+ * IxAtmdAccRxVcFreeLowCallback event will occur only after
+ * @a ixAtmdAccRxVcEnable() function is invoked.
+ *
+ * Before using this function, the @a ixAtmdAccRxVcFreeReplenish() function
+ * has to be used to replenish the RX Free queue. If not, incoming traffic
+ * may be discarded.and in the case of interrupt driven reception the
+ * @a IxAtmdAccRxVcFreeLowCallback() callback may be invoked as a side effect
+ * during a replenish action.
+ *
+ * This function is not reentrant and should not be used inside an
+ * interrupt context.
+ *
+ * For an VC connection this function can be called after a call to
+ * @a ixAtmdAccRxVcDisable() and should not be called after
+ * @a ixAtmdAccRxVcTryDisconnect()
+ *
+ * @sa ixAtmdAccRxVcDisable
+ * @sa ixAtmdAccRxVcConnect
+ * @sa ixAtmdAccRxVcFreeReplenish
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call
+ * to @a IxAtmdAccRxVcConnect()
+ *
+ * @return @li IX_SUCCESS successful call to ixAtmdAccRxVcEnable
+ * @return @li IX_ATMDACC_WARNING the channel is already enabled
+ * @return @li IX_FAIL invalid parameters or some unspecified internal
+ *         error occured.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxVcEnable (IxAtmConnId connId);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ * 
+ * @fn ixAtmdAccRxVcDisable (IxAtmConnId connId)
+ *
+ * @brief Stop the RX service on a VC.
+ *
+ * This functions stops the traffic reception for a particular VC connection.
+ *
+ * Once invoked, incoming Pdus are discarded by the hardware. Any Pdus
+ * pending will be freed to the user
+ *
+ * Hence once this function returns no more receive callbacks will be
+ * called for that VC. However, buffer free callbacks will be invoked
+ * until such time as all buffers supplied by the user have been freed
+ * back to the user
+ *
+ * Calling this function doe not invalidate the connId.
+ * @a ixAtmdAccRxVcEnable() can be invoked to enable Pdu reception again.
+ *
+ * If the traffic is already stopped, this function returns IX_SUCCESS.
+ *
+ * This function is not reentrant and should not be used inside an
+ * interrupt context.
+ *
+ * @sa ixAtmdAccRxVcConnect
+ * @sa ixAtmdAccRxVcEnable
+ * @sa ixAtmdAccRxVcDisable
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to @a
+ *     IxAtmdAccRxVcConnect()
+ *
+ * @return @li IX_SUCCESS successful call to @a ixAtmdAccRxVcDisable().
+ * @return @li IX_ATMDACC_WARNING the channel is already disabled
+ * @return @li IX_FAIL invalid parameters or some unspecified internal error occured
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxVcDisable (IxAtmConnId connId);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ * 
+ * @fn ixAtmdAccRxVcTryDisconnect (IxAtmConnId connId)
+ *
+ * @brief Disconnect a VC from the RX service.
+ *
+ * This function deregisters the VC and guarantees that all resources
+ * associated with this VC are free. After its execution, the connection
+ * Id is not available.
+ *
+ * This function will fail until such time as all resources allocated to
+ * the VC connection have been freed. The user is responsible to delay and
+ * call again this function many times until a success status is returned.
+ *
+ * This function needs internal locks and should not be called from an
+ * interrupt context
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to
+ * @a IxAtmdAccRxVcConnect()
+ *
+ * @return @li IX_SUCCESS successful call to ixAtmdAccRxVcDisable
+ * @return @li IX_ATMDACC_RESOURCES_STILL_ALLOCATED not all resources
+ *         associated with the connection have been freed.
+ * @return @li IX_FAIL cannot process this request because of a parameter
+ *         error
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxVcTryDisconnect (IxAtmConnId connId);
+
+/* ------------------------------------------------------
+   Part of the IxAtmdAcc interface related to TX traffic
+   ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ * 
+ * @fn ixAtmdAccTxVcConnect (IxAtmLogicalPort port,
+                      unsigned int vpi,
+                      unsigned int vci,
+                      IxAtmdAccAalType aalServiceType,
+                      IxAtmdAccUserId userId,
+                      IxAtmdAccTxVcBufferReturnCallback bufferFreeCallback,
+                      IxAtmConnId * connIdPtr)
+ *
+ * @brief Connect to a Aal Pdu transmit service for a particular
+ *        port/vpi/vci and service type.
+ *
+ * This function allows a user to connect to an Aal5/Aal0/OAM Pdu transmit service
+ * for a particular port/vpi/vci. It registers the callback and allocates
+ * internal resources and a Connection Id to be used in further API calls
+ * related to this VC.
+ *
+ * The function will setup VC transmit service on the specified on the
+ * specified port. A connId is the reference by which IxAtmdAcc refers to a
+ * connected VC. This identifier is the result of a succesful call
+ * to a connect function. This identifier is invalid after a
+ * sucessful call to a disconnect function.
+ *
+ * This function needs internal locks, and hence  should not be called
+ * from an interrupt context.
+ *
+ * On return from @a ixAtmdAccTxVcConnect() with a failure status, the
+ * connection Id parameter is unspecified. Its value cannot be used.
+ *
+ * Calling this function for the same combination of port, Vpi, Vci and
+ * more than once without calling @a ixAtmdAccTxVcTryDisconnect() will result
+ * in a failure status.
+ *
+ * Two AAL0 services supporting 48 or 52 byte cell data are provided.
+ * Submitted AAL0 PDUs must be a multiple of the cell data size (48/52).
+ * AAL0_52 is a raw cell service the client must format
+ * the PDU with an ATM cell header (excluding HEC) at the start of
+ * each cell, note that AtmdAcc does not validate the cell headers in
+ * a submitted PDU.
+ *
+ * For the OAM service an "OAM Tx channel" may be enabled for a port
+ * by establishing a single dedicated OAM Tx connection on that port.
+ *
+ * The OAM service allows buffers containing 52 byte OAM F4/F5 cells
+ * to be transmitted and received over the dedicated OAM channels.
+ * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM
+ * service offered by AtmdAcc is a raw cell transport service.
+ * It is assumed that ITU I.610 procedures that make use of this
+ * service are implemented above AtmdAcc.
+ *
+ * Note that the dedicated OAM connections are established on
+ * reserved VPI,VCI, and (in the case of Rx) port values.
+ * These values are used purely to descriminate the dedicated OAM channels
+ * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be
+ * realised for particluar VPI/VCIs by manipulating the VPI,VCI
+ * fields of the ATM cell headers of cells in the buffers passed
+ * to AtmdAcc.
+ *
+ * Calling this function before enabling the port will fail.
+ *
+ * @sa ixAtmdAccTxVcTryDisconnect
+ * @sa ixAtmdAccPortTxScheduledModeEnable
+ * @sa ixAtmdAccPortEnable
+ *
+ * @param port @ref IxAtmLogicalPort [in] - VC identification : logical PHY port
+ *                  [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ * @param vpi unsigned int  [in] - VC identification : ATM Vpi [0..255] or IX_ATMDACC_OAM_VPI
+ * @param vci unsigned int [in] - VC identification : ATM Vci [0..65535] or IX_ATMDACC_OAM_VCI
+ * @param aalServiceType @ref IxAtmdAccAalType [in] - type of service AAL5, AAL0_48, AAL0_52, or OAM
+ * @param userId @ref IxAtmdAccUserId [in] - user id to be used later during callbacks related
+ *        to this channel
+ * @param bufferFreeCallback @ref IxAtmdAccTxVcBufferReturnCallback [in] - function called when mbufs
+ *        transmission is complete. This parameter cannot be a null
+ *        pointer.
+ * @param connIdPtr @ref IxAtmConnId [out] - Pointer to a connection Id.
+ *        This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS successful call to @a IxAtmdAccRxVcConnect().
+ * @return @li IX_ATMDACC_BUSY cannot process this request
+ *         because no VC is available
+ * @return @li IX_FAIL
+ *             parameter error,
+ *             VC already in use,
+ *             attempt to connect AAL service on reserved OAM VPI/VCI,
+ *             attempt to connect OAM service on VPI/VCI other than the reserved OAM VPI/VCI,
+ *             port is not initialised,
+ *             or some other error occurs during processing.
+ *
+ * @note - Unscheduled mode is not supported in ixp425 1.0. Therefore, the
+ *       function @a ixAtmdAccPortTxScheduledModeEnable() need to be called
+ *       for this port before any establishing a Tx Connection
+ */
+PUBLIC IX_STATUS ixAtmdAccTxVcConnect (IxAtmLogicalPort port,
+                      unsigned int vpi,
+                      unsigned int vci,
+                      IxAtmdAccAalType aalServiceType,
+                      IxAtmdAccUserId userId,
+                      IxAtmdAccTxVcBufferReturnCallback bufferFreeCallback,
+                      IxAtmConnId * connIdPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccTxVcPduSubmit (IxAtmConnId connId,
+                    IX_OSAL_MBUF * mbufPtr,
+                    IxAtmdAccClpStatus clp,
+                    unsigned int numberOfCells)
+ *
+ * @brief Submit a Pdu for transmission on connection.
+ *
+ * A data user calls this function to submit an mbufs containing a Pdu
+ * to be transmitted. The buffer supplied can be chained and the Pdu it
+ * contains must be complete.
+ *
+ * The transmission behavior of this call depends on the operational mode
+ * of the port on which the connection is made.
+ *
+ * In unscheduled mode the mbuf will be submitted to the hardware
+ * immediately if sufficent resource is available. Otherwise the function
+ * will return failure.
+ *
+ * In scheduled mode the buffer is queued internally in IxAtmdAcc. The cell
+ * demand is made known to the traffic shaping entity. Cells from the
+ * buffers are MUXed onto the port some time later as dictated by the
+ * traffic shaping entity. The traffic shaping entity does this by sending
+ * transmit schedules to IxAtmdAcc via @a ixAtmdAccPortTxProcess() function call.
+ *
+ * Note that the dedicated OAM channel is scheduled just like any
+ * other channel. This means that any OAM traffic relating to an
+ * active AAL0/AAL5 connection will be scheduled independantly of the
+ * AAL0/AAL5 traffic for that connection.
+ *
+ * When transmission is complete, the TX Done mechanism will give the
+ * owmnership of these buffers back to the customer. The tx done mechanism
+ * must be in operation before transmission is attempted.
+ *
+ * For AAL0/OAM submitted AAL0 PDUs must be a multiple of the cell data
+ * size (48/52). AAL0_52 and OAM are raw cell services, and the client
+ * must format the PDU with an ATM cell header (excluding HEC) at the
+ * start of each cell, note that AtmdAcc does not validate the cell headers in
+ * a submitted PDU.
+ *
+ *
+ * @sa IxAtmdAccTxVcBufferReturnCallback
+ * @sa ixAtmdAccTxDoneDispatch
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to
+ *        @a ixAtmdAccTxVcConnect()
+ * @param mbufPtr @ref IX_OSAL_MBUF [in] - pointer to a chained structure of mbufs to transmit.
+ *       This parameter cannot be a null pointer.
+ * @param clp @ref IxAtmdAccClpStatus [in] - clp indication for this PDU. All cells of this pdu
+ *       will be sent with the clp bit set
+ * @param numberOfCells unsigned int [in] - number of cells in the PDU.
+ *
+ * @return @li IX_SUCCESS successful call to @a ixAtmdAccTxVcPduSubmit()
+ *             The pdu pointed by the mbufPtr parameter will be
+ *             transmitted
+ * @return @li IX_ATMDACC_BUSY unable to process this request because
+ *             internal resources are all used. The caller is responsible
+ *             for retrying this request later.
+ * @return @li IX_FAIL unable to process this request because of error
+ *             in the parameters (wrong connId supplied,
+ *             or wrong mbuf pointer supplied), the total length of all buffers
+ *             in the chain should be a multiple of the cell size
+ *             ( 48/52 depending on the service type ),
+ *             or unspecified error during processing
+ *
+ * @note - This function in not re-entrant for the same VC (e.g. : two
+ *         thread cannot send PDUs for the same VC). But two threads can
+ *         safely call this function with a different connection Id
+ *
+ * @note - In unscheduled mode, this function is not re-entrant on a per
+ *         port basis. The size of pdus is limited to 8Kb.
+ *
+ * @note - 0-length mbufs should be removed from the chain before submission.
+ *         The total length of the pdu (sdu + padding +trailer) has to be
+ *         updated in the header of the first mbuf of a chain of mbufs.
+ *
+ * @note - Aal5 trailer information (UUI, CPI, SDU length) has to be supplied
+ *         before submission.
+ *
+ * @note - The payload memory cache should be flushed, if needed, prior to
+ *         transmission. Mbuf headers are flushed by IxAtmdAcc
+ *
+ * @note - This function does not use system resources and can be used
+ *         inside an interrupt context
+ */
+PUBLIC IX_STATUS ixAtmdAccTxVcPduSubmit (IxAtmConnId connId,
+                    IX_OSAL_MBUF * mbufPtr,
+                    IxAtmdAccClpStatus clp,
+                    unsigned int numberOfCells);
+
+/**
+ *
+ * @ingroup IxAtmdAccAPI
+ *
+ * @fn ixAtmdAccTxVcTryDisconnect (IxAtmConnId connId)
+ *
+ * @brief Disconnect from a Aal Pdu transmit service for a particular
+ *        port/vpi/vci.
+ *
+ * This function deregisters the VC and guarantees that all resources
+ * associated with this VC are free. After its execution, the connection
+ * Id is not available.
+ *
+ * This function will fail until such time as all resources allocated to
+ * the VC connection have been freed. The user is responsible to delay
+ * and call again this function many times until a success status is
+ * returned.
+ *
+ * After its execution, the connection Id is not available.
+ *
+ * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to
+ *        @a ixAtmdAccTxVcConnect()
+ *
+ * @return @li IX_SUCCESS successful call to @a ixAtmdAccTxVcTryDisconnect()
+ * @return @li IX_ATMDACC_RESOURCES_STILL_ALLOCATED not all resources
+ *     associated with the connection have been freed. This condition will
+ *     disappear after Tx and TxDone is complete for this channel.
+ * @return @li IX_FAIL unable to process this request because of errors
+ *                     in the parameters (wrong connId supplied)
+ *
+ * @note - This function needs internal locks and should not be called
+ *         from an interrupt context
+ *
+ * @note - If the @a IX_ATMDACC_RESOURCES_STILL_ALLOCATED error does not
+ *     clear after a while, this may be linked to a previous problem
+ *     of cell overscheduling. Diabling the port and retry a disconnect
+ *     will free the resources associated with this channel.
+ *
+ * @sa ixAtmdAccPortTxProcess
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccTxVcTryDisconnect (IxAtmConnId connId);
+
+#endif /* IXATMDACC_H */
+
+/**
+ * @} defgroup IxAtmdAccAPI
+ */
+
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxAtmdAccCtrl.h b/marvell/uboot/drivers/net/npe/include/IxAtmdAccCtrl.h
new file mode 100644
index 0000000..ecbb005
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxAtmdAccCtrl.h
@@ -0,0 +1,1933 @@
+/**
+ * @file    IxAtmdAccCtrl.h
+ *
+ * @date    20-Mar-2002
+ *
+ * @brief IxAtmdAcc Public API
+ *
+ * This file contains the public API of IxAtmdAcc, related to the
+ * control functions of the component.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/* ------------------------------------------------------
+   Doxygen group definitions
+   ------------------------------------------------------ */
+
+/**
+ *
+ * @defgroup IxAtmdAccCtrlAPI IXP400 ATM Driver Access (IxAtmdAcc) Control API
+ *
+ * @brief The public API for the IXP400 Atm Driver Control component
+ *
+ * IxAtmdAcc is the low level interface by which AAL PDU get transmitted
+ * to,and received from the Utopia bus
+ *
+ * This part is related to the Control configuration
+ *
+ * @{
+ */
+
+#ifndef IXATMDACCCTRL_H
+#define IXATMDACCCTRL_H
+
+#include "IxAtmdAcc.h"
+
+/* ------------------------------------------------------
+   AtmdAccCtrl Data Types definition
+   ------------------------------------------------------ */
+
+/**
+*
+* @ingroup IxAtmdAccCtrlAPI
+*
+* @def IX_ATMDACC_PORT_DISABLE_IN_PROGRESS
+*
+* @brief Port enable return code
+*
+* This constant is used to tell IxAtmDAcc user that the port disable
+* functions are not complete. The user can call ixAtmdAccPortDisableComplete()
+* to find out when the disable has finished. The port enable can then proceed.
+*
+*/
+#define IX_ATMDACC_PORT_DISABLE_IN_PROGRESS 5
+
+/**
+*
+* @ingroup IxAtmdAccCtrlAPI
+*
+* @def IX_ATMDACC_ALLPDUS
+*
+* @brief All PDUs
+*
+* This constant is used to tell IxAtmDAcc to process all PDUs from
+* the RX queue or the TX Done
+*
+* @sa IxAtmdAccRxDispatcher
+* @sa IxAtmdAccTxDoneDispatcher
+*
+*/
+#define IX_ATMDACC_ALLPDUS 0xffffffff
+
+/* ------------------------------------------------------
+   Part of the IxAtmdAcc interface related to RX traffic
+   ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @brief Callback prototype for notification of available PDUs for
+ * an Rx Q.
+ *
+ * This a protoype for a function which is called when there is at
+ * least one Pdu available for processing on a particular Rx Q.
+ *
+ * This function should call @a ixAtmdAccRxDispatch() with
+ * the aprropriate number of parameters to read and process the Rx Q.
+ *
+ * @sa ixAtmdAccRxDispatch
+ * @sa ixAtmdAccRxVcConnect
+ * @sa ixAtmdAccRxDispatcherRegister
+ *
+ * @param rxQueueId @ref IxAtmRxQueueId [in] indicates which RX queue to has Pdus to process.
+ * @param numberOfPdusToProcess unsigned int [in] indicates the minimum number of
+ *        PDUs available to process all PDUs from the queue.
+ * @param reservedPtr unsigned int* [out] pointer to a int location which can
+ *        be written to, but does not retain written values. This is
+ *        provided to make this prototype compatible
+ *        with @a ixAtmdAccRxDispatch()
+ *
+ * @return @li int - ignored.
+ *
+ */
+typedef IX_STATUS (*IxAtmdAccRxDispatcher) (IxAtmRxQueueId rxQueueId,
+                         unsigned int numberOfPdusToProcess,
+                         unsigned int *reservedPtr);
+
+/* ------------------------------------------------------
+   Part of the IxAtmdAcc interface related to TX traffic
+   ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @brief Callback prototype for transmitted mbuf when threshold level is
+ *        crossed.
+ *
+ * IxAtmdAccTxDoneDispatcher is the prototype of the user function
+ * which get called when pdus are completely transmitted. This function
+ * is likely to call the @a ixAtmdAccTxDoneDispatch() function.
+ *
+ * This function is called when the number of available pdus for
+ * reception is crossing the threshold level as defined
+ * in @a ixAtmdAccTxDoneDispatcherRegister()
+ *
+ * This function is called inside an Qmgr dispatch context. No system
+ * resource or interrupt-unsafe feature should be used inside this
+ * callback.
+ *
+ * Transmitted buffers recycling implementation is a sytem-wide mechanism
+ * and needs to be set before any traffic is started. If this threshold
+ * mechanism is not used, the user is responsible for polling the
+ * transmitted buffers with @a ixAtmdAccTxDoneDispatch()
+ * and @a ixAtmdAccTxDoneLevelQuery() functions.
+ *
+ * @sa ixAtmdAccTxDoneDispatcherRegister
+ * @sa ixAtmdAccTxDoneDispatch
+ * @sa ixAtmdAccTxDoneLevelQuery
+ *
+ * @param numberOfPdusToProcess unsigned int [in] - The current number of pdus currently
+ *        available for recycling
+ * @param *reservedPtr unsigned int [out] - pointer to a int location which can be
+ *        written to but does not retain written values. This is provided
+ *        to make this prototype compatible
+ *        with @a ixAtmdAccTxDoneDispatch()
+ *
+ * @return @li IX_SUCCESS This is provided to make
+ *    this prototype compatible with @a ixAtmdAccTxDoneDispatch()
+ * @return @li IX_FAIL invalid parameters or some unspecified internal
+ *    error occured. This is provided to make
+ *    this prototype compatible with @a ixAtmdAccTxDoneDispatch()
+ *
+ */
+typedef IX_STATUS (*IxAtmdAccTxDoneDispatcher) (unsigned int numberOfPdusToProcess,
+                                                unsigned int *reservedPtr);
+
+/**
+*
+* @ingroup IxAtmdAccCtrlAPI
+*
+* @brief Notification that the threshold number of scheduled cells
+* remains in a port's transmit Q.
+*
+* The is the prototype for of the user notification function which
+* gets called on a per-port basis, when the number of remaining
+* scheduled cells to be transmitted decreases to the threshold level.
+* The number of cells passed as a parameter can be used for scheduling
+* purposes as the maximum number of cells that can be passed in a
+* schedule table to the @a ixAtmdAccPortTxProcess() function.
+*
+* @sa ixAtmdAccPortTxCallbackRegister
+* @sa ixAtmdAccPortTxProcess
+* @sa ixAtmdAccPortTxFreeEntriesQuery
+*
+* @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+* @param numberOfAvailableCells unsigned int [in] - number of available
+*        cell entries.for the port
+*
+* @note - This functions shall not use system resources when used
+*         inside an interrupt context.
+*
+*/
+typedef void (*IxAtmdAccPortTxLowCallback) (IxAtmLogicalPort port,
+                           unsigned int numberOfAvailableCells);
+
+/**
+*
+* @ingroup IxAtmdAccCtrlAPI
+*
+* @brief  Prototype to submit cells for transmission
+*
+* IxAtmdAccTxVcDemandUpdateCallback is the prototype of the callback
+* function used by AtmD to notify an ATM Scheduler that the user of
+* a VC has submitted cells for transmission.
+*
+* @sa IxAtmdAccTxVcDemandUpdateCallback
+* @sa IxAtmdAccTxVcDemandClearCallback
+* @sa IxAtmdAccTxSchVcIdGetCallback
+* @sa ixAtmdAccPortTxScheduledModeEnable
+*
+* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be updated
+*        is established
+* @param vcId int [in] - Identifies the VC to be updated. This is the value
+*        returned by the @a IxAtmdAccTxSchVcIdGetCallback() call .
+* @param numberOfCells unsigned int [in] - Indicates how many ATM cells should be added
+*        to the queue for this VC.
+*
+* @return @li IX_SUCCESS the function is registering the cell demand for
+*        this VC.
+* @return @li IX_FAIL the function cannot register cell for this VC : the
+*         scheduler maybe overloaded or misconfigured
+*
+*/
+typedef IX_STATUS (*IxAtmdAccTxVcDemandUpdateCallback) (IxAtmLogicalPort port,
+                        int vcId,
+                        unsigned int numberOfCells);
+
+/**
+*
+* @ingroup IxAtmdAccCtrlAPI
+*
+* @brief  prototype to  remove all currently queued cells from a
+* registered VC
+*
+* IxAtmdAccTxVcDemandClearCallback is the prototype of the function
+* to remove all currently queued cells from a registered VC. The
+* pending cell count for the specified VC is reset to zero. After the
+* use of this callback, the scheduler shall not schedule more cells
+* for this VC.
+*
+* This callback function is called during a VC disconnection
+* @a ixAtmdAccTxVcTryDisconnect()
+*
+* @sa IxAtmdAccTxVcDemandUpdateCallback
+* @sa IxAtmdAccTxVcDemandClearCallback
+* @sa IxAtmdAccTxSchVcIdGetCallback
+* @sa ixAtmdAccPortTxScheduledModeEnable
+* @sa ixAtmdAccTxVcTryDisconnect
+*
+* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be cleared
+*        is established
+* @param vcId int [in] - Identifies the VC to be cleared. This is the value
+*        returned by the @a IxAtmdAccTxSchVcIdGetCallback() call .
+*
+* @return none
+*
+*/
+typedef void (*IxAtmdAccTxVcDemandClearCallback) (IxAtmLogicalPort port,
+                             int vcId);
+
+/**
+*
+* @ingroup IxAtmdAccCtrlAPI
+*
+* @brief  prototype to get a scheduler vc id
+*
+* IxAtmdAccTxSchVcIdGetCallback is the prototype of the function to get
+* a scheduler vcId
+*
+* @sa IxAtmdAccTxVcDemandUpdateCallback
+* @sa IxAtmdAccTxVcDemandClearCallback
+* @sa IxAtmdAccTxSchVcIdGetCallback
+* @sa ixAtmdAccPortTxScheduledModeEnable
+*
+* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM logical port on which the VC is
+*        established
+* @param vpi unsigned int [in] - For AAL0/AAL5 specifies the ATM vpi on which the 
+*                 VC is established.
+*                 For OAM specifies the dedicated "OAM Tx channel" VPI.
+* @param vci unsigned int [in] - For AAL0/AAL5 specifies the ATM vci on which the 
+*                 VC is established.
+*                 For OAM specifies the dedicated "OAM Tx channel" VCI.
+* @param connId @ref IxAtmConnId [in] - specifies the IxAtmdAcc connection Id already
+*        associated with this VC
+* @param vcId int* [out] - pointer to a vcId
+*
+* @return @li IX_SUCCESS the function is returning a Scheduler vcId for this
+*         VC
+* @return @li IX_FAIL the function cannot process scheduling for this VC.
+*                 the contents of vcId is unspecified
+*
+*/
+typedef IX_STATUS (*IxAtmdAccTxSchVcIdGetCallback) (IxAtmLogicalPort port,
+                               unsigned int vpi,
+                               unsigned int vci,
+                               IxAtmConnId connId,
+                               int *vcId);
+
+/* ------------------------------------------------------
+   Part of the IxAtmdAcc interface related to RX traffic
+   ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccRxDispatcherRegister (
+                          IxAtmRxQueueId queueId,
+                          IxAtmdAccRxDispatcher callback)
+ *
+ * @brief Register a notification callback to be invoked when there is
+ * at least one entry on a particular Rx queue.
+ *
+ * This function registers a callback to be invoked when there is at
+ * least one entry in a particular queue. The registered callback is
+ * called every time when the hardware adds one or more pdus to the
+ * specified Rx queue.
+ *
+ * This function cannot be used when a Rx Vc using this queue is
+ * already existing.
+ *
+ * @note -The callback function can be the API function
+ *       @a ixAtmdAccRxDispatch() : every time the threhold level
+ *       of the queue is reached, the ixAtmdAccRxDispatch() is
+ *       invoked to remove all entries from the queue.
+ *
+ * @sa ixAtmdAccRxDispatch
+ * @sa IxAtmdAccRxDispatcher
+ *
+ * @param queueId @ref IxAtmRxQueueId [in] RX queue identification
+ * @param callback @ref IxAtmdAccRxDispatcher [in] function triggering the delivery of incoming
+ *        traffic. This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS Successful call to @a ixAtmdAccRxDispatcherRegister()
+ * @return @li IX_FAIL error in the parameters, or there is an
+ *             already active RX VC for this queue or some unspecified
+ *             internal error occurred.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxDispatcherRegister (
+                          IxAtmRxQueueId queueId,
+                          IxAtmdAccRxDispatcher callback);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccRxDispatch (IxAtmRxQueueId rxQueueId,
+    unsigned int numberOfPdusToProcess,
+    unsigned int *numberOfPdusProcessedPtr)
+ *
+ *
+ * @brief Control function which executes Rx processing for a particular
+ * Rx stream.
+ *
+ * The @a IxAtmdAccRxDispatch() function is used to process received Pdus
+ * available from one of the two incoming RX streams. When this function
+ * is invoked, the incoming traffic (up to the number of PDUs passed as
+ * a parameter) will be transferred to the IxAtmdAcc users through the
+ * callback @a IxAtmdAccRxVcRxCallback(), as registered during the
+ * @a ixAtmdAccRxVcConnect() call.
+ *
+ * The user receive callbacks will be executed in the context of this
+ * function.
+ *
+ * Failing to use this function on a regular basis when there is traffic
+ * will block incoming traffic and can result in Pdus being dropped by
+ * the hardware.
+ *
+ * This should be used to control when received pdus are handed off from
+ * the hardware to Aal users from a particluar stream. The function can
+ * be used from a timer context, or can be registered as a callback in
+ * response to an rx stream threshold event, or can be used inside an
+ * active polling mechanism which is under user control.
+ *
+ * @note - The signature of this function is directly compatible with the
+ * callback prototype which can be register with @a ixAtmdAccRxDispatcherRegister().
+ *
+ * @sa ixAtmdAccRxDispatcherRegister
+ * @sa IxAtmdAccRxVcRxCallback
+ * @sa ixAtmdAccRxVcFreeEntriesQuery
+ *
+ * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which RX queue to process.
+ * @param numberOfPdusToProcess unsigned int [in] - indicates the maxiumum number of PDU to
+ *     remove from the RX queue. A value of IX_ATMDACC_ALLPDUS indicates
+ *     to process all PDUs from the queue. This includes at least the PDUs
+ *     in the queue when the fuction is invoked. Because of real-time
+ *     constraints, there is no guarantee thatthe queue will be empty
+ *     when the function exits. If this parameter is greater than the
+ *     number of entries of the queues, the function will succeed
+ *     and the parameter numberOfPdusProcessedPtr will reflect the exact
+ *     number of PDUs processed.
+ * @param *numberOfPdusProcessedPtr unsigned int [out] - indicates the actual number of PDU
+ *     processed during this call. This parameter cannot be a null
+ *     pointer.
+ *
+ * @return @li IX_SUCCESS the number of PDUs as indicated in
+ *     numberOfPdusProcessedPtr are removed from the RX queue and the VC callback
+ *     are called.
+ * @return @li IX_FAIL invalid parameters or some unspecified internal
+ *     error occured.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxDispatch (IxAtmRxQueueId rxQueueId,
+    unsigned int numberOfPdusToProcess,
+    unsigned int *numberOfPdusProcessedPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ * 
+ * @fn ixAtmdAccRxLevelQuery (IxAtmRxQueueId rxQueueId,
+                     unsigned int *numberOfPdusPtr)
+ *
+ * @brief Query the number of entries in a particular RX queue.
+ *
+ * This function is used to retrieve the number of pdus received by
+ * the hardware and ready for distribution to users.
+ *
+ * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which of two RX queues to query.
+ * @param numberOfPdusPtr unsigned int* [out] - Pointer to store the number of available
+ *        PDUs in the RX queue. This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS the value in numberOfPdusPtr specifies the
+ *         number of incoming pdus waiting in this queue
+ * @return @li IX_FAIL an error occurs during processing.
+ *         The value in numberOfPdusPtr is unspecified.
+ *
+ * @note - This function is reentrant, doesn't use system resources
+ *         and can be used from an interrupt context.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxLevelQuery (IxAtmRxQueueId rxQueueId,
+                     unsigned int *numberOfPdusPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccRxQueueSizeQuery (IxAtmRxQueueId rxQueueId,
+                     unsigned int *numberOfPdusPtr)
+ *
+ * @brief Query the size of a particular RX queue.
+ *
+ * This function is used to retrieve the number of pdus the system is
+ * able to queue when reception is complete.
+ *
+ * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which of two RX queues to query.
+ * @param numberOfPdusPtr unsigned int* [out] - Pointer to store the number of pdus
+ *         the system is able to queue in the RX queue. This parameter
+ *         cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS the value in numberOfPdusPtr specifies the
+ *         number of pdus the system is able to queue.
+ * @return @li IX_FAIL an error occurs during processing.
+ *         The value in numberOfPdusPtr is unspecified.
+ *
+ * @note - This function is reentrant, doesn't use system resources
+ *         and can be used from an interrupt context.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccRxQueueSizeQuery (IxAtmRxQueueId rxQueueId,
+                     unsigned int *numberOfPdusPtr);
+
+/* ------------------------------------------------------
+   Part of the IxAtmdAcc interface related to TX traffic
+   ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccPortTxFreeEntriesQuery (IxAtmLogicalPort port,
+                         unsigned int *numberOfCellsPtr)
+ *
+ * @brief Get the number of available cells the system can accept for
+ *       transmission.
+ *
+ * The function is used to retrieve the number of cells that can be
+ * queued for transmission to the hardware.
+ *
+ * This number is based on the worst schedule table where one cell
+ * is stored in one schedule table entry, depending on the pdus size
+ * and mbuf size and fragmentation.
+ *
+ * This function doesn't use system resources and can be used from a
+ * timer context, or can be associated with a threshold event, or can
+ * be used inside an active polling mechanism
+ *
+ * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ * @param numberOfCellsPtr unsigned int* [out] - number of available cells.
+ *                   This parameter cannot be a null pointer.
+ *
+ * @sa ixAtmdAccPortTxProcess
+ *
+ * @return @li IX_SUCCESS numberOfCellsPtr contains the number of cells that can be scheduled
+ *         for this port.
+ * @return @li IX_FAIL error in the parameters, or some processing error
+ *         occured.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccPortTxFreeEntriesQuery (IxAtmLogicalPort port,
+                         unsigned int *numberOfCellsPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ * 
+ * @fn ixAtmdAccPortTxCallbackRegister (IxAtmLogicalPort port,
+                       unsigned int numberOfCells,
+                       IxAtmdAccPortTxLowCallback callback)
+ *
+ * @brief Configure the Tx port threshold value and register a callback to handle
+ * threshold notifications.
+ *
+ * This function sets the threshold in cells
+ *
+ * @sa ixAtmdAccPortTxCallbackRegister
+ * @sa ixAtmdAccPortTxProcess
+ * @sa ixAtmdAccPortTxFreeEntriesQuery
+ *
+ * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ * @param numberOfCells unsigned int [in] - threshold value which triggers the callback
+ *        invocation, This number has to be one of the
+ *        values 0,1,2,4,8,16,32 ....
+ *        The maximum value cannot be more than half of the txVc queue
+ *        size (which can be retrieved using @a ixAtmdAccPortTxFreeEntriesQuery()
+ *        before any Tx traffic is sent for this port)
+ * @param callback @ref IxAtmdAccPortTxLowCallback [in] - callback function to invoke when the threshold
+ *                 level is reached.
+ *                 This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS Successful call to @a ixAtmdAccPortTxCallbackRegister()
+ * @return @li IX_FAIL error in the parameters, Tx channel already set for this port
+ *             threshold level is not correct or within the range regarding the
+ *             queue size:or unspecified error during processing:
+ *
+ * @note - This callback function get called when the threshold level drops from
+ *         (numberOfCells+1) cells to (numberOfCells) cells
+ *
+ * @note - This function should be called during system initialisation,
+ *         outside an interrupt context
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccPortTxCallbackRegister (IxAtmLogicalPort port,
+                       unsigned int numberOfCells,
+                       IxAtmdAccPortTxLowCallback callback);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccPortTxScheduledModeEnable (IxAtmLogicalPort port,
+    IxAtmdAccTxVcDemandUpdateCallback vcDemandUpdateCallback,
+    IxAtmdAccTxVcDemandClearCallback vcDemandClearCallback,
+    IxAtmdAccTxSchVcIdGetCallback vcIdGetCallback)
+ *
+ * @brief Put the port into Scheduled Mode
+ *
+ * This function puts the specified port into scheduled mode of
+ * transmission which means an external s/w entity controls the
+ * transmission of cells on this port. This faciltates traffic shaping on
+ * the port.
+ *
+ * Any buffers submitted on a VC for this port will be queued in IxAtmdAcc.
+ * The transmission of these buffers to and by the hardware will be driven
+ * by a transmit schedule submitted regulary in calls to
+ * @a ixAtmdAccPortTxProcess() by traffic shaping entity.
+ *
+ * The transmit schedule is expected to be dynamic in nature based on
+ * the demand in cells for each VC on the port. Hence the callback
+ * parameters provided to this function allow IxAtmdAcc to inform the
+ * shaping entity of demand changes for each VC on the port.
+ *
+ * By default a port is in Unscheduled Mode so if this function is not
+ * called, transmission of data is done without sheduling rules, on a
+ * first-come, first-out basis.
+ *
+ * Once a port is put in scheduled mode it cannot be reverted to
+ * un-scheduled mode. Note that unscheduled mode is not supported
+ * in ixp425 1.0
+ *
+ * @note - This function should be called before any VCs have be
+ * connected on a port. Otherwise this function call will return failure.
+ *
+ * @note - This function uses internal locks and should not be called from
+ * an interrupt context
+ *
+ * @sa IxAtmdAccTxVcDemandUpdateCallback
+ * @sa IxAtmdAccTxVcDemandClearCallback
+ * @sa IxAtmdAccTxSchVcIdGetCallback
+ * @sa ixAtmdAccPortTxProcess
+ *
+ * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ * @param vcDemandUpdateCallback @ref IxAtmdAccTxVcDemandUpdateCallback [in] - callback function used to update
+ *     the number of outstanding cells for transmission. This parameter
+ *     cannot be a null pointer.
+ * @param vcDemandClearCallback @ref IxAtmdAccTxVcDemandClearCallback [in] - callback function used to remove all
+ *     clear the number of outstanding cells for a VC. This parameter
+ *     cannot be a null pointer.
+ * @param vcIdGetCallback @ref IxAtmdAccTxSchVcIdGetCallback [in] - callback function used to exchange vc
+ *     Identifiers between IxAtmdAcc and the entity supplying the
+ *     transmit schedule. This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS scheduler registration is complete and the port
+ *         is now in scheduled mode.
+ * @return @li IX_FAIL failed (wrong parameters, or traffic is already
+ *         enabled on this port, possibly without ATM shaping)
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccPortTxScheduledModeEnable (IxAtmLogicalPort port,
+    IxAtmdAccTxVcDemandUpdateCallback vcDemandUpdateCallback,
+    IxAtmdAccTxVcDemandClearCallback vcDemandClearCallback,
+    IxAtmdAccTxSchVcIdGetCallback vcIdGetCallback);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccPortTxProcess (IxAtmLogicalPort port,
+    IxAtmScheduleTable* scheduleTablePtr)
+ *
+ * @brief Transmit queue cells to the H/W based on the supplied schedule
+ *        table.
+ *
+ * This function @a ixAtmdAccPortTxProcess() process the schedule
+ * table provided as a parameter to the function. As a result cells are
+ * sent to the underlaying hardware for transmission.
+ *
+ * The schedule table is executed in its entirety or not at all. So the
+ * onus is on the caller not to submit a table containing more cells than
+ * can be transmitted at that point. The maximum numbers that can be
+ * transmitted is guaranteed to be the number of cells as returned by the
+ * function @a ixAtmdAccPortTxFreeEntriesQuery().
+ *
+ * When the scheduler is invoked on a threshold level, IxAtmdAcc gives the
+ * minimum number of cells (to ensure the callback will fire again later)
+ * and the maximum number of cells that @a ixAtmdAccPortTxProcess()
+ * will be able to process (assuming the ATM scheduler is able
+ * to produce the worst-case schedule table, i.e. one entry per cell).
+ *
+ * When invoked ouside a threshold level, the overall number of cells of
+ * the schedule table should be less than the number of cells returned
+ * by the @a ixAtmdAccPortTxFreeEntriesQuery() function.
+ *
+ * After invoking the @a ixAtmdAccPortTxProcess() function, it is the
+ * user choice to query again the queue level with the function
+ * @a ixAtmdAccPortTxFreeEntriesQuery() and, depending on a new cell
+ * number, submit an other schedule table.
+ *
+ * IxAtmdAcc will check that the number of cells in the schedule table
+ * is compatible with the current transmit level. If the
+ *
+ * Obsolete or invalid connection Id will be silently discarded.
+ *
+ * This function is not reentrant for the same port.
+ *
+ * This functions doesn't use system resources and can be used inside an
+ * interrupt context.
+ *
+ * This function is used as a response to the hardware requesting more
+ * cells to transmit.
+ *
+ * @sa ixAtmdAccPortTxScheduledModeEnable
+ * @sa ixAtmdAccPortTxFreeEntriesQuery
+ * @sa ixAtmdAccPortTxCallbackRegister
+ * @sa ixAtmdAccPortEnable
+ *
+ * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ * @param scheduleTablePtr @ref IxAtmScheduleTable* [in] - pointer to a scheduler update table. The
+ *     content of this table is not modified by this function. This
+ *     parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS the schedule table process is complete
+ *             and cells are transmitted to the hardware
+ * @return @li IX_ATMDACC_WARNING : Traffic will be dropped: the schedule table exceed
+ *     the hardware capacity  If this error is ignored, further traffic
+ *     and schedule will work correctly.
+ *     Overscheduling does not occur when the schedule table does
+ *     not contain more entries that the number of free entries returned
+ *     by @a ixAtmdAccPortTxFreeEntriesQuery().
+ *     However, Disconnect attempts just after this error will fail permanently
+ *     with the error code @a IX_ATMDACC_RESOURCES_STILL_ALLOCATED, and it is
+ *     necessary to disable the port to make @a ixAtmdAccTxVcTryDisconnect()
+ *     successful.
+ * @return @li IX_FAIL a wrong parameter is supplied, or the format of
+ *     the schedule table is invalid, or the port is not Enabled, or
+ *     an internal severe error occured. No cells is transmitted to the hardware
+ *
+ * @note - If the failure is linked to an overschedule of data cells
+ *     the result is an inconsistency in the output traffic (one or many
+ *     cells may be missing and the traffic contract is not respected).
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccPortTxProcess (IxAtmLogicalPort port,
+    IxAtmScheduleTable* scheduleTablePtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccTxDoneDispatch (unsigned int numberOfPdusToProcess,
+                unsigned int *numberOfPdusProcessedPtr)
+ *
+ * @brief Process a number of pending transmit done pdus from the hardware.
+ *
+ * As a by-product of Atm transmit operation buffers which transmission
+ * is complete need to be recycled to users. This function is invoked
+ * to service the oustanding list of transmitted buffers and pass them
+ * to VC users.
+ *
+ * Users are handed back pdus by invoking the free callback registered
+ * during the @a ixAtmdAccTxVcConnect() call.
+ *
+ * There is a single Tx done stream servicing all active Atm Tx ports
+ * which can contain a maximum of 64 entries. If this stream fills port
+ * transmission will stop so this function must be call sufficently
+ * frequently to ensure no disruption to the transmit operation.
+ *
+ * This function can be used from a timer context, or can be associated
+ * with a TxDone level threshold event (see @a ixAtmdAccTxDoneDispatcherRegister() ),
+ * or can be used inside an active polling mechanism under user control.
+ *
+ * For ease of use the signature of this function is compatible with the
+ * TxDone threshold event callback prototype.
+ *
+ * This functions can be used inside an interrupt context.
+ *
+ * @sa ixAtmdAccTxDoneDispatcherRegister
+ * @sa IxAtmdAccTxVcBufferReturnCallback
+ * @sa ixAtmdAccTxDoneLevelQuery
+ *
+ * @param numberOfPdusToProcess unsigned int [in] - maxiumum number of pdus to remove
+ *     from the TX Done queue
+ * @param *numberOfPdusProcessedPtr unsigned int [out] - number of pdus removed from
+ *     the TX Done queue. This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS the number of pdus as indicated in
+ *     numberOfPdusToProcess are removed from the TX Done hardware
+ *     and passed to the user through the Tx Done callback registered
+ *     during a call to @a ixAtmdAccTxVcConnect()
+ * @return @li IX_FAIL invalid parameters or numberOfPdusProcessedPtr is
+ *     a null pointer or some unspecified internal error occured.
+ *
+ */
+PUBLIC IX_STATUS
+ixAtmdAccTxDoneDispatch (unsigned int numberOfPdusToProcess,
+                unsigned int *numberOfPdusProcessedPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ * 
+ * @fn ixAtmdAccTxDoneLevelQuery (unsigned int *numberOfPdusPtr)
+ *
+ * @brief Query the current number of transmit pdus ready for
+ *        recycling.
+ *
+ * This function is used to get the number of transmitted pdus which
+ * the hardware is ready to hand back to user.
+ *
+ * This function can be used from a timer context, or can be associated
+ * with a threshold event, on can be used inside an active polling
+ * mechanism
+ *
+ * @sa ixAtmdAccTxDoneDispatch
+ *
+ * @param *numberOfPdusPtr unsigned int [out] - Pointer to the number of pdus transmitted
+ *        at the time of this function call, and ready for recycling
+ *        This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS numberOfPdusPtr contains the number of pdus
+ *        ready for recycling at the time of this function call
+ *
+ * @return @li IX_FAIL wrong parameter (null pointer as parameter).or
+ *         unspecified rocessing error occurs..The value in numberOfPdusPtr
+ *         is unspecified.
+ *
+ */
+PUBLIC IX_STATUS
+ixAtmdAccTxDoneLevelQuery (unsigned int *numberOfPdusPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccTxDoneQueueSizeQuery (unsigned int *numberOfPdusPtr)
+ *
+ * @brief Query the TxDone queue size.
+ *
+ * This function is used to get the number of pdus which
+ * the hardware is able to store after transmission is complete
+ *
+ * The returned value can be used to set a threshold and enable
+ * a callback to be notified when the number of pdus is going over
+ * the threshold.
+ *
+ * @sa ixAtmdAccTxDoneDispatcherRegister
+ *
+ * @param *numberOfPdusPtr unsigned int [out] - Pointer to the number of pdus the system
+ *        is able to queue after transmission
+ *
+ * @return @li IX_SUCCESS numberOfPdusPtr contains the the number of
+ *        pdus the system is able to queue after transmission
+ * @return @li IX_FAIL wrong parameter (null pointer as parameter).or
+ *         unspecified rocessing error occurs..The value in numberOfPdusPtr
+ *         is unspecified.
+ *
+ * @note - This function is reentrant, doesn't use system resources
+ *         and can be used from an interrupt context.
+ */
+PUBLIC IX_STATUS
+ixAtmdAccTxDoneQueueSizeQuery (unsigned int *numberOfPdusPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ * 
+ * @fn ixAtmdAccTxDoneDispatcherRegister (unsigned int numberOfPdus,
+   IxAtmdAccTxDoneDispatcher notificationCallback)
+ *
+ * @brief Configure the Tx Done stream threshold value and register a
+ * callback to handle threshold notifications.
+ *
+ * This function sets the threshold level in term of number of pdus at
+ * which the supplied notification function should be called.
+ *
+ * The higher the threshold value is, the less events will be necessary
+ * to process transmitted buffers.
+ *
+ * Transmitted buffers recycling implementation is a sytem-wide mechanism
+ * and needs to be set prior any traffic is started. If this threshold
+ * mechanism is not used, the user is responsible for polling the
+ * transmitted buffers thanks to @a ixAtmdAccTxDoneDispatch() and
+ * @a ixAtmdAccTxDoneLevelQuery() functions.
+ *
+ * This function should be called during system initialisation outside
+ * an interrupt context
+ *
+ * @sa ixAtmdAccTxDoneDispatcherRegister
+ * @sa ixAtmdAccTxDoneDispatch
+ * @sa ixAtmdAccTxDoneLevelQuery
+ *
+ * @param numberOfPdus unsigned int [in] - The number of TxDone pdus which triggers the
+ *        callback invocation This number has to be a power of 2, one of the
+ *        values 0,1,2,4,8,16,32 ...
+ *        The maximum value cannot be more than half of the txDone queue
+ *        size (which can be retrieved using @a ixAtmdAccTxDoneQueueSizeQuery())
+ * @param notificationCallback @ref IxAtmdAccTxDoneDispatcher [in] - The function to invoke. (This
+ *        parameter can be @a ixAtmdAccTxDoneDispatch()).This
+ *        parameter ust not be a null pointer.
+ *
+ * @return @li IX_SUCCESS Successful call to ixAtmdAccTxDoneDispatcherRegister
+ * @return @li IX_FAIL error in the parameters:
+ *
+ * @note - The notificationCallback will be called exactly when the threshold level
+ *         will increase from (numberOfPdus) to (numberOfPdus+1)
+ *
+ * @note - If there is no Tx traffic, there is no guarantee that TxDone Pdus will
+ *       be released to the user (when txDone level is permanently under the threshold
+ *       level. One of the preffered way to return resources to the user is to use
+ *       a mix of txDone notifications, used together with a slow
+ *       rate timer and an exclusion mechanism protecting from re-entrancy
+ *
+ * @note - The TxDone threshold will only hand back buffers when the threshold level is
+ *      crossed. Setting this threshold to a great number reduce the interrupt rate
+ *      and the cpu load, but also increase the number of outstanding mbufs and has
+ *      a system wide impact when these mbufs are needed by other components.
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccTxDoneDispatcherRegister (unsigned int numberOfPdus,
+   IxAtmdAccTxDoneDispatcher notificationCallback);
+
+/* ------------------------------------------------------
+   Part of the IxAtmdAcc interface related to Utopia config
+   ------------------------------------------------------ */
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @defgroup IxAtmdAccUtopiaCtrlAPI IXP400 ATM Driver Access (IxAtmdAcc) Utopia Control API
+ *
+ * @brief The public API for the IXP400 Atm Driver Control component
+ *
+ * IxAtmdAcc is the low level interface by which AAL PDU get
+ * transmitted to,and received from the Utopia bus
+ *
+ * This part is related to the UTOPIA configuration.
+ *
+ * @{
+ */
+
+/**
+ *
+ * @brief Utopia configuration
+ *
+ * This structure is used to set the Utopia parameters
+ * @li contains the values of Utopia registers, to be set during initialisation
+ * @li contains debug commands for NPE, to be used during development steps
+ *
+ * @note - the exact description of all parameters is done in the Utopia reference
+ *   documents.
+ *
+ */
+typedef struct
+{
+    /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+    * @struct UtTxConfig_
+    * @brief Utopia Tx Config Register
+    */
+    struct UtTxConfig_
+    {
+
+    unsigned int reserved_1:1;  /**< [31] These bits are always 0.*/
+    unsigned int txInterface:1;     /**< [30] Utopia Transmit Interface. The following encoding
+                                   * is used to set the Utopia Transmit interface as ATM master
+                                   * or PHY slave:
+                                   * @li 1 - PHY
+                                   * @li 0 - ATM
+                                   */
+    unsigned int txMode:1;      /**< [29] Utopia Transmit Mode. The following encoding is used
+    *  to set the Utopia Transmit mode to SPHY or MPHY:
+    *  @li 1 - SPHY
+    *  @li 0 - MPHY
+    */
+    unsigned int txOctet:1;  /**< [28] Utopia Transmit cell transfer protocol. Used to set
+    * the Utopia cell transfer protocol to Octet-level handshaking.
+    * Note this is only applicable in SPHY mode.
+    * @li 1 - Octet-handshaking enabled
+    * @li 0 - Cell-handshaking enabled
+    */
+    unsigned int txParity:1;    /**< [27] Utopia Transmit parity enabled when set. TxEvenParity
+    * defines the parity format odd/even.
+    * @li 1 - Enable Parity generation.
+    * @li 0 - ut_op_prty held low.
+    */
+    unsigned int txEvenParity:1; /**< [26] Utopia Transmit Parity Mode
+    * @li 1 - Even Parity Generated.
+    * @li 0 - Odd Parity Generated.
+    */
+    unsigned int txHEC:1; /**< [25] Header Error Check Insertion Mode. Specifies if the transmit
+    * cell header check byte is calculated and inserted when set.
+    * @li 1 - Generate HEC.
+    * @li 0 - Disable HEC generation.
+    */
+    unsigned int txCOSET:1;    /**< [24] If enabled the HEC is Exclusive-OR'ed with the value 0x55 before
+  * being presented on the Utopia bus.
+  * @li 1 - Enable HEC ExOR with value 0x55
+  * @li 0 - Use generated HEC value.
+  */
+
+    unsigned int reserved_2:1;    /**< [23] These bits are always 0
+    */
+    unsigned int txCellSize:7;    /**< [22:16] Transmit expected cell size. Configures the cell size
+    * for the transmit module: Values between 52-64 are valid.
+    */
+    unsigned int reserved_3:3;  /**< [15:13] These bits are always 0 */
+    unsigned int txAddrRange:5;       /**< [12:8] When configured as an ATM master in MPHY mode this
+    * register specifies the upper limit of the PHY polling logical
+    * range. The number of active PHYs are TxAddrRange + 1.
+    */
+    unsigned int reserved_4:3;      /**< [7:5] These bits are always 0 */
+    unsigned int txPHYAddr:5;     /**< [4:0] When configured as a slave in an MPHY system this register
+    * specifies the physical address of the PHY.
+    */
+    }
+
+    utTxConfig;       /**< Tx config Utopia register */
+
+   /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+   * @struct UtTxStatsConfig_
+   * @brief Utopia Tx stats Register
+    */
+    struct UtTxStatsConfig_
+    {
+
+    unsigned int vpi:12;  /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0]
+    @li Note: if VCStatsTxGFC is set to 0 the GFC field is ignored in test. */
+
+    unsigned int vci:16;  /**< [19:4] ATM VCI [15:0] or PHY Address[4] */
+
+    unsigned int pti:3;  /**< [3:1] ATM PTI [2:0] or PHY Address[3:1]
+  @li Note: if VCStatsTxPTI is set to 0 the PTI field is ignored in test.
+  @li Note: if VCStatsTxEnb is set to 0 only the transmit PHY port
+  address as defined by this register is used for ATM statistics [4:0]. */
+
+    unsigned int clp:1;  /**< [0] ATM CLP or PHY Address [0]
+  @li Note: if VCStatsTxCLP is set to 0 the CLP field is ignored in test.
+  @li Note: if VCStatsTxEnb is set to 0 only the transmit PHY port
+  address as defined by this register is used for ATM statistics [4:0]. */
+    }
+
+    utTxStatsConfig;       /**< Tx stats config Utopia register */
+
+       /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+       * @struct UtTxDefineIdle_
+       * @brief Utopia Tx idle cells Register
+    */
+    struct UtTxDefineIdle_
+    {
+
+    unsigned int vpi:12;  /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0]
+    @li Note: if VCIdleTxGFC is set to 0 the GFC field is ignored in test. */
+
+    unsigned int vci:16;  /**< [19:4] ATM VCI [15:0] */
+
+    unsigned int pti:3;  /**< [3:1] ATM PTI PTI [2:0]
+  @li Note: if VCIdleTxPTI is set to 0 the PTI field is ignored in test.*/
+
+    unsigned int clp:1;  /**< [0] ATM CLP [0]
+  @li Note: if VCIdleTxCLP is set to 0 the CLP field is ignored in test.*/
+    }
+
+    utTxDefineIdle;      /**< Tx idle cell config Utopia register */
+
+      /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+      * @struct UtTxEnableFields_
+      * @brief Utopia Tx ienable fields Register
+    */
+    struct UtTxEnableFields_
+    {
+
+    unsigned int defineTxIdleGFC:1;    /**< [31] This register is used to include or exclude the GFC
+    field of the ATM header when testing for Idle cells.
+    @li 1 - GFC field is valid.
+    @li 0 - GFC field ignored.*/
+
+    unsigned int defineTxIdlePTI:1;    /**< [30] This register is used to include or exclude the PTI
+    field of the ATM header when testing for Idle cells.
+    @li 1 - PTI field is valid
+    @li    0 - PTI field ignored.*/
+
+    unsigned int defineTxIdleCLP:1;    /**< [29] This register is used to include or
+    exclude the CLP field of the ATM header when testing for Idle cells.
+    @li 1 - CLP field is valid.
+    @li 0 - CLP field ignored. */
+
+    unsigned int phyStatsTxEnb:1;    /**< [28] This register is used to enable or disable ATM
+  statistics gathering based on the specified PHY address as defined
+  in TxStatsConfig register.
+  @li 1 - Enable statistics for specified transmit PHY address.
+    @li 0 - Disable statistics for specified transmit PHY address. */
+
+    unsigned int vcStatsTxEnb:1;  /**< [27] This register is used to change the ATM
+      statistics-gathering mode from the specified logical PHY address
+      to a specific VPI/VCI address.
+      @li 1 - Enable statistics for specified VPI/VCI address.
+      @li 0 - Disable statistics for specified VPI/VCI address */
+
+    unsigned int vcStatsTxGFC:1;  /**< [26] This register is used to include or exclude the GFC
+      field of the ATM header when ATM VPI/VCI statistics are enabled.
+      GFC is only available at the UNI and uses the first 4-bits of
+      the VPI field.
+      @li 1 - GFC field is valid
+      @li 0 - GFC field ignored.*/
+
+    unsigned int vcStatsTxPTI:1;  /**< [25] This register is used to include or exclude the PTI
+      field of the ATM header when ATM VPI/VCI statistics are enabled.
+      @li 1 - PTI field is valid
+      @li 0 - PTI field ignored.*/
+
+    unsigned int vcStatsTxCLP:1;  /**< [24] This register is used to include or exclude the CLP
+      field of the ATM header when ATM VPI/VCI statistics are enabled.
+      @li 1 - CLP field is valid
+      @li 0 - CLP field ignored. */
+
+    unsigned int reserved_1:3;  /**< [23-21] These bits are always 0 */
+
+    unsigned int txPollStsInt:1;    /**< [20] Enable the assertion of the ucp_tx_poll_sts condition
+  where there is a change in polling status.
+  @li 1 - ucp_tx_poll_sts asserted whenever there is a change in status
+  @li    0 - ucp_tx_poll_sts asserted if ANY transmit PHY is available
+  */
+    unsigned int txCellOvrInt:1;    /**< [19] Enable TxCellCount overflow CBI Transmit Status condition
+      assertion.
+      @li 1 - If TxCellCountOvr is set assert the Transmit Status Condition.
+      @li 0 - No CBI Transmit Status condition assertion */
+
+    unsigned int txIdleCellOvrInt:1;  /**< [18] Enable TxIdleCellCount overflow Transmit Status Condition
+    @li 1 - If TxIdleCellCountOvr is set assert the Transmit Status Condition
+      @li 0 - No CBI Transmit Status condition assertion..*/
+
+    unsigned int enbIdleCellCnt:1;    /**< [17] Enable Transmit Idle Cell Count.
+    @li 1 - Enable count of Idle cells transmitted.
+      @li 0 - No count is maintained. */
+
+    unsigned int enbTxCellCnt:1;    /**< [16] Enable Transmit Valid Cell Count of non-idle/non-error cells
+      @li 1 - Enable count of valid cells transmitted- non-idle/non-error
+      @li 0 - No count is maintained.*/
+
+    unsigned int reserved_2:16;   /**< [15:0] These bits are always 0 */
+    } utTxEnableFields;  /**< Tx enable Utopia register */
+
+    /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+    * @struct UtTxTransTable0_
+    * @brief Utopia Tx translation table Register
+    */
+    struct UtTxTransTable0_
+    {
+
+    unsigned int phy0:5;  /**< [31-27] Tx Mapping value of logical phy 0 */
+
+    unsigned int phy1:5;  /**< [26-22] Tx Mapping value of logical phy 1 */
+
+    unsigned int phy2:5;  /**< [21-17] Tx Mapping value of logical phy 2 */
+
+    unsigned int reserved_1:1;  /**< [16] These bits are always 0.*/
+
+    unsigned int phy3:5;  /**< [15-11] Tx Mapping value of logical phy 3 */
+
+    unsigned int phy4:5;  /**< [10-6] Tx Mapping value of logical phy 4 */
+
+    unsigned int phy5:5;  /**< [5-1] Tx Mapping value of logical phy 5 */
+
+    unsigned int reserved_2:1;  /**< [0] These bits are always 0 */
+    } utTxTransTable0;  /**< Tx translation table */
+
+  /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+  * @struct UtTxTransTable1_
+  * @brief Utopia Tx translation table Register
+    */
+    struct UtTxTransTable1_
+    {
+
+    unsigned int phy6:5;  /**< [31-27] Tx Mapping value of logical phy 6 */
+
+    unsigned int phy7:5;  /**< [26-22] Tx Mapping value of logical phy 7 */
+
+    unsigned int phy8:5;  /**< [21-17] Tx Mapping value of logical phy 8 */
+
+    unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+    unsigned int phy9:5;  /**< [15-11] Tx Mapping value of logical phy 3 */
+
+    unsigned int phy10:5;   /**< [10-6] Tx Mapping value of logical phy 4 */
+
+    unsigned int phy11:5;   /**< [5-1] Tx Mapping value of logical phy 5 */
+
+    unsigned int reserved_2:1;  /**< [0] These bits are always 0 */
+    } utTxTransTable1;  /**< Tx translation table */
+
+    /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+    * @struct UtTxTransTable2_
+    * @brief Utopia Tx translation table Register
+    */
+    struct UtTxTransTable2_
+    {
+
+    unsigned int phy12:5;   /**< [31-27] Tx Mapping value of logical phy 6 */
+
+    unsigned int phy13:5;   /**< [26-22] Tx Mapping value of logical phy 7 */
+
+    unsigned int phy14:5;   /**< [21-17] Tx Mapping value of logical phy 8 */
+
+    unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+    unsigned int phy15:5;   /**< [15-11] Tx Mapping value of logical phy 3 */
+
+    unsigned int phy16:5;   /**< [10-6] Tx Mapping value of logical phy 4 */
+
+    unsigned int phy17:5;   /**< [5-1] Tx Mapping value of logical phy 5 */
+
+    unsigned int reserved_2:1;  /**< [0] These bits are always 0 */
+    } utTxTransTable2;    /**< Tx translation table */
+
+    /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+    * @struct UtTxTransTable3_
+    * @brief Utopia Tx translation table Register
+    */
+    struct UtTxTransTable3_
+    {
+
+    unsigned int phy18:5;   /**< [31-27] Tx Mapping value of logical phy 6 */
+
+    unsigned int phy19:5;   /**< [26-22] Tx Mapping value of logical phy 7 */
+
+    unsigned int phy20:5;   /**< [21-17] Tx Mapping value of logical phy 8 */
+
+    unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+    unsigned int phy21:5;   /**< [15-11] Tx Mapping value of logical phy 3 */
+
+    unsigned int phy22:5;   /**< [10-6] Tx Mapping value of logical phy 4 */
+
+    unsigned int phy23:5;   /**< [5-1] Tx Mapping value of logical phy 5 */
+
+    unsigned int reserved_2:1;  /**< [0] These bits are always 0 */
+    } utTxTransTable3;  /**< Tx translation table */
+
+    /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+    * @struct UtTxTransTable4_
+    * @brief Utopia Tx translation table Register
+    */
+    struct UtTxTransTable4_
+    {
+
+    unsigned int phy24:5;   /**< [31-27] Tx Mapping value of logical phy 6 */
+
+    unsigned int phy25:5;   /**< [26-22] Tx Mapping value of logical phy 7 */
+
+    unsigned int phy26:5;   /**< [21-17] Tx Mapping value of logical phy 8 */
+
+    unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+    unsigned int phy27:5;   /**< [15-11] Tx Mapping value of logical phy 3 */
+
+    unsigned int phy28:5;   /**< [10-6] Tx Mapping value of logical phy 4 */
+
+    unsigned int phy29:5;   /**< [5-1] Tx Mapping value of logical phy 5 */
+
+    unsigned int reserved_2:1;  /**< [0] These bits are always 0 */
+    } utTxTransTable4;  /**< Tx translation table */
+
+    /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+    * @struct UtTxTransTable5_
+    * @brief Utopia Tx translation table Register
+    */
+    struct UtTxTransTable5_
+    {
+
+    unsigned int phy30:5;   /**< [31-27] Tx Mapping value of logical phy 6 */
+
+    unsigned int reserved_1:27;     /**< [26-0] These bits are always 0 */
+
+    } utTxTransTable5;  /**< Tx translation table */
+
+    /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+    * @struct UtRxConfig_
+    * @brief Utopia Rx config Register
+    */
+    struct UtRxConfig_
+    {
+
+    unsigned int rxInterface:1;    /**< [31] Utopia Receive Interface. The following encoding is used
+ to set the Utopia Receive interface as ATM master or PHY slave:
+ @li 1 - PHY
+    @li 0 - ATM */
+
+    unsigned int rxMode:1;      /**< [30] Utopia Receive Mode. The following encoding is used to set
+      the Utopia Receive mode to SPHY or MPHY:
+      @li 1 - SPHY
+    @li 0 - MPHY */
+
+    unsigned int rxOctet:1;  /**< [29] Utopia Receive cell transfer protocol. Used to set the Utopia
+  cell transfer protocol to Octet-level handshaking. Note this is only
+  applicable in SPHY mode.
+  @li 1 - Octet-handshaking enabled
+    @li 0 - Cell-handshaking enabled */
+
+    unsigned int rxParity:1;    /**< [28] Utopia Receive Parity Checking enable.
+    @li 1 - Parity checking enabled
+    @li 0 - Parity checking disabled */
+
+    unsigned int rxEvenParity:1;/**< [27] Utopia Receive Parity Mode
+    @li 1 - Check for Even Parity
+    @li 0 - Check for Odd Parity.*/
+
+    unsigned int rxHEC:1;    /**< [26] RxHEC    Header Error Check Mode. Enables/disables cell header
+    error checking on the received cell header.
+    @li 1 - HEC checking enabled
+    @li 0 - HEC checking disabled */
+
+    unsigned int rxCOSET:1;  /**< [25] If enabled the HEC is Exclusive-OR'ed with the value 0x55
+  before being tested with the received HEC.
+  @li 1 - Enable HEC ExOR with value 0x55.
+    @li 0 - Use generated HEC value.*/
+
+    unsigned int rxHECpass:1;    /**< [24] Specifies if the incoming cell HEC byte should be transferred
+     after optional processing to the NPE2 Coprocessor Bus Interface or
+     if it should be discarded.
+     @li 1 - HEC maintained 53-byte/UDC cell sent to NPE2.
+    @li 0 - HEC discarded 52-byte/UDC cell sent to NPE2 coprocessor.*/
+
+    unsigned int reserved_1:1;    /**< [23] These bits are always 0 */
+
+    unsigned int rxCellSize:7;    /**< [22:16] Receive cell size. Configures the receive cell size.
+      Values between 52-64 are valid */
+
+    unsigned int rxHashEnbGFC:1;      /**< [15] Specifies if the VPI field [11:8]/GFC field should be
+      included in the Hash data input or if the bits should be padded
+      with 1'b0.
+      @li 1 - VPI [11:8]/GFC field valid and used in Hash residue calculation.
+      @li 0 - VPI [11:8]/GFC field padded with 1'b0 */
+
+    unsigned int rxPreHash:1; /**< [14] Enable Pre-hash value generation. Specifies if the
+ incoming cell data should be pre-hashed to allow VPI/VCI header look-up
+ in a hash table.
+ @li 1 - Pre-hashing enabled
+      @li 0 - Pre-hashing disabled */
+
+    unsigned int reserved_2:1;    /**< [13] These bits are always 0 */
+
+    unsigned int rxAddrRange:5;     /**< [12:8] In ATM master, MPHY mode,
+     * this register specifies the upper
+     * limit of the PHY polling logical range. The number of active PHYs are
+     * RxAddrRange + 1.
+     */
+    unsigned int reserved_3:3;    /**< [7-5] These bits are always 0 .*/
+    unsigned int rxPHYAddr:5;     /**< [4:0] When configured as a slave in an MPHY system this register
+      * specifies the physical address of the PHY.
+      */
+    } utRxConfig;  /**< Rx config Utopia register */
+
+      /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+      * @struct UtRxStatsConfig_
+      * @brief Utopia Rx stats config Register
+    */
+    struct UtRxStatsConfig_
+    {
+
+    unsigned int vpi:12;  /**< [31:20] ATM VPI    VPI [11:0] OR GFC [3:0] and VPI [7:0]
+    @li Note: if VCStatsRxGFC is set to 0 the GFC field is ignored in test. */
+
+    unsigned int vci:16;  /**< [19:4] VCI [15:0] or PHY Address [4] */
+
+    unsigned int pti:3;  /**< [3:1] PTI [2:0] or or PHY Address [3:1]
+  @li Note: if VCStatsRxPTI is set to 0 the PTI field is ignored in test.
+  @li Note: if VCStatsRxEnb is set to 0 only the PHY port address is used
+  for statistics gathering.. */
+
+    unsigned int clp:1;  /**< [0] CLP [0] or PHY Address [0]
+  @li Note: if VCStatsRxCLP is set to 0 the CLP field is ignored in test.
+  @li Note: if VCStatsRxEnb is set to 0 only the PHY port address is used
+  for statistics gathering.. */
+    } utRxStatsConfig;  /**< Rx stats config Utopia register */
+
+  /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+  * @struct UtRxDefineIdle_
+  * @brief Utopia Rx idle cells config Register
+    */
+    struct UtRxDefineIdle_
+    {
+
+    unsigned int vpi:12;  /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0]
+    @li Note: if VCIdleRxGFC is set to 0 the GFC field is ignored in test. */
+
+    unsigned int vci:16;  /**< [19:4] ATM VCI [15:0] */
+
+    unsigned int pti:3;  /**< [3:1] ATM PTI PTI [2:0]
+  @li Note: if VCIdleRxPTI is set to 0 the PTI field is ignored in test.*/
+
+    unsigned int clp:1;  /**< [0] ATM CLP [0]
+  @li Note: if VCIdleRxCLP is set to 0 the CLP field is ignored in test.*/
+    } utRxDefineIdle;      /**< Rx idle cell config Utopia register */
+
+      /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+      * @struct UtRxEnableFields_
+      * @brief Utopia Rx enable Register
+    */
+    struct UtRxEnableFields_
+    {
+
+    unsigned int defineRxIdleGFC:1;/**< [31] This register is used to include or exclude the GFC
+ field of the ATM header when testing for Idle cells.
+ @li 1 - GFC field is valid.
+    @li 0 - GFC field ignored.*/
+
+    unsigned int defineRxIdlePTI:1;/**< [30] This register is used to include or exclude the PTI
+ field of the ATM header when testing for Idle cells.
+ @li 1 - PTI field is valid.
+    @li 0 - PTI field ignored.*/
+
+    unsigned int defineRxIdleCLP:1;/**< [29] This register is used to include or exclude the CLP
+ field of the ATM header when testing for Idle cells.
+ @li 1 - CLP field is valid.
+    @li    0 - CLP field ignored.*/
+
+    unsigned int phyStatsRxEnb:1;/**< [28] This register is used to enable or disable ATM statistics
+     gathering based on the specified PHY address as defined in RxStatsConfig
+     register.
+     @li 1 - Enable statistics for specified receive PHY address.
+    @li 0 - Disable statistics for specified receive PHY address.*/
+
+    unsigned int vcStatsRxEnb:1;/**< [27] This register is used to enable or disable ATM statistics
+    gathering based on a specific VPI/VCI address.
+    @li 1 - Enable statistics for specified VPI/VCI address.
+    @li 0 - Disable statistics for specified VPI/VCI address.*/
+
+    unsigned int vcStatsRxGFC:1;/**< [26] This register is used to include or exclude the GFC field
+    of the ATM header when ATM VPI/VCI statistics are enabled. GFC is only
+    available at the UNI and uses the first 4-bits of the VPI field.
+    @li 1 - GFC field is valid.
+    @li 0 - GFC field ignored. */
+
+    unsigned int vcStatsRxPTI:1;/**< [25] This register is used to include or exclude the PTI field
+    of the ATM header when ATM VPI/VCI statistics are enabled.
+    @li 1 - PTI field is valid.
+    @li 0 - PTI field ignored.*/
+
+    unsigned int vcStatsRxCLP:1;/**< [24] This register is used to include or exclude the CLP field
+    of the ATM header when ATM VPI/VCI statistics are enabled.
+    @li 1 - CLP field is valid.
+    @li 0 - CLP field ignored. */
+
+    unsigned int discardHecErr:1;/**< [23] Discard cells with an invalid HEC.
+     @li 1 - Discard cells with HEC errors
+    @li 0 - Cells with HEC errors are passed */
+
+    unsigned int discardParErr:1;/**< [22] Discard cells containing parity errors.
+     @li 1 - Discard cells with parity errors
+    @li 0 - Cells with parity errors are passed */
+
+    unsigned int discardIdle:1;    /**< [21] Discard Idle Cells based on DefineIdle register values
+ @li    1 - Discard IDLE cells
+    @li 0 - IDLE cells passed */
+
+    unsigned int enbHecErrCnt:1;/**< [20] Enable Receive HEC Error Count.
+    @li 1 - Enable count of received cells containing HEC errors
+    @li 0 - No count is maintained. */
+
+    unsigned int enbParErrCnt:1;/**< [19] Enable Parity Error Count
+    @li    1 - Enable count of received cells containing Parity errors
+    @li 0 - No count is maintained. */
+
+    unsigned int enbIdleCellCnt:1;/**< [18] Enable Receive Idle Cell Count.
+      @li 1 - Enable count of Idle cells received.
+    @li 0 - No count is maintained.*/
+
+    unsigned int enbSizeErrCnt:1;/**< [17] Enable Receive Size Error Count.
+     @li 1 - Enable count of received cells of incorrect size
+    @li    0 - No count is maintained. */
+
+    unsigned int enbRxCellCnt:1;/**< [16] Enable Receive Valid Cell Count of non-idle/non-error cells.
+    @li    1 - Enable count of valid cells received - non-idle/non-error
+    @li 0 - No count is maintained. */
+
+    unsigned int reserved_1:3;    /**< [15:13] These bits are always 0 */
+
+    unsigned int rxCellOvrInt:1;      /**< [12] Enable CBI Utopia Receive Status Condition if the RxCellCount
+      register overflows.
+      @li 1 - CBI Receive Status asserted.
+      @li    0 - No CBI Receive Status asserted.*/
+
+    unsigned int invalidHecOvrInt:1;  /**< [11] Enable CBI Receive Status Condition if the InvalidHecCount
+    register overflows.
+    @li    1 - CBI Receive Condition asserted.
+      @li 0 - No CBI Receive Condition asserted */
+
+    unsigned int invalidParOvrInt:1;  /**< [10] Enable CBI Receive Status Condition if the InvalidParCount
+    register overflows
+    @li    1 - CBI Receive Condition asserted.
+      @li 0 - No CBI Receive Condition asserted */
+
+    unsigned int invalidSizeOvrInt:1;   /**< [9] Enable CBI Receive Status Condition if the InvalidSizeCount
+     register overflows.
+     @li 1 - CBI Receive Status Condition asserted.
+     @li 0 - No CBI Receive Status asserted */
+
+    unsigned int rxIdleOvrInt:1;      /**< [8] Enable CBI Receive Status Condition if the RxIdleCount overflows.
+      @li 1 - CBI Receive Condition asserted.
+      @li 0 - No CBI Receive Condition asserted */
+
+    unsigned int reserved_2:3;    /**< [7:5] These bits are always 0 */
+
+    unsigned int rxAddrMask:5;    /**< [4:0] This register is used as a mask to allow the user to increase
+    the PHY receive address range. The register should be programmed with
+    the address-range limit, i.e. if set to 0x3 the address range increases
+  to a maximum of 4 addresses. */
+    } utRxEnableFields;      /**< Rx enable Utopia register */
+
+      /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+      * @struct UtRxTransTable0_
+      * @brief Utopia Rx translation table Register
+    */
+    struct UtRxTransTable0_
+    {
+
+    unsigned int phy0:5;  /**< [31-27] Rx Mapping value of logical phy 0 */
+
+    unsigned int phy1:5;  /**< [26-22] Rx Mapping value of logical phy 1 */
+
+    unsigned int phy2:5;  /**< [21-17] Rx Mapping value of logical phy 2 */
+
+    unsigned int reserved_1:1;  /**< [16] These bits are always 0 */
+
+    unsigned int phy3:5;  /**< [15-11] Rx Mapping value of logical phy 3 */
+
+    unsigned int phy4:5;  /**< [10-6] Rx Mapping value of logical phy 4 */
+
+    unsigned int phy5:5;  /**< [5-1] Rx Mapping value of logical phy 5 */
+
+    unsigned int reserved_2:1;  /**< [0] These bits are always 0 */
+    }
+
+    utRxTransTable0;  /**< Rx translation table */
+
+  /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+  * @struct UtRxTransTable1_
+  * @brief Utopia Rx translation table Register
+    */
+    struct UtRxTransTable1_
+    {
+
+    unsigned int phy6:5;  /**< [31-27] Rx Mapping value of logical phy 6 */
+
+    unsigned int phy7:5;  /**< [26-22] Rx Mapping value of logical phy 7 */
+
+    unsigned int phy8:5;  /**< [21-17] Rx Mapping value of logical phy 8 */
+
+    unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+    unsigned int phy9:5;  /**< [15-11] Rx Mapping value of logical phy 3 */
+
+    unsigned int phy10:5;   /**< [10-6] Rx Mapping value of logical phy 4 */
+
+    unsigned int phy11:5;   /**< [5-1] Rx Mapping value of logical phy 5 */
+
+    unsigned int reserved_2:1;  /**< [0] These bits are always 0 */
+    }
+
+    utRxTransTable1;  /**< Rx translation table */
+
+    /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+    * @struct UtRxTransTable2_
+    * @brief Utopia Rx translation table Register
+    */
+    struct UtRxTransTable2_
+    {
+
+    unsigned int phy12:5;   /**< [31-27] Rx Mapping value of logical phy 6 */
+
+    unsigned int phy13:5;   /**< [26-22] Rx Mapping value of logical phy 7 */
+
+    unsigned int phy14:5;   /**< [21-17] Rx Mapping value of logical phy 8 */
+
+    unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+    unsigned int phy15:5;   /**< [15-11] Rx Mapping value of logical phy 3 */
+
+    unsigned int phy16:5;   /**< [10-6] Rx Mapping value of logical phy 4 */
+
+    unsigned int phy17:5;   /**< [5-1] Rx Mapping value of logical phy 5 */
+
+    unsigned int reserved_2:1;  /**< [0] These bits are always 0 */
+    } utRxTransTable2;    /**< Rx translation table */
+
+    /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+    * @struct UtRxTransTable3_
+    * @brief Utopia Rx translation table Register
+    */
+    struct UtRxTransTable3_
+    {
+
+    unsigned int phy18:5;   /**< [31-27] Rx Mapping value of logical phy 6 */
+
+    unsigned int phy19:5;   /**< [26-22] Rx Mapping value of logical phy 7 */
+
+    unsigned int phy20:5;   /**< [21-17] Rx Mapping value of logical phy 8 */
+
+    unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+    unsigned int phy21:5;   /**< [15-11] Rx Mapping value of logical phy 3 */
+
+    unsigned int phy22:5;   /**< [10-6] Rx Mapping value of logical phy 4 */
+
+    unsigned int phy23:5;   /**< [5-1] Rx Mapping value of logical phy 5 */
+
+    unsigned int reserved_2:1;  /**< [0] These bits are always 0 */
+    } utRxTransTable3;  /**< Rx translation table */
+
+    /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+    * @struct UtRxTransTable4_
+    * @brief Utopia Rx translation table Register
+    */
+    struct UtRxTransTable4_
+    {
+
+    unsigned int phy24:5;   /**< [31-27] Rx Mapping value of logical phy 6 */
+
+    unsigned int phy25:5;   /**< [26-22] Rx Mapping value of logical phy 7 */
+
+    unsigned int phy26:5;   /**< [21-17] Rx Mapping value of logical phy 8 */
+
+    unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */
+
+    unsigned int phy27:5;   /**< [15-11] Rx Mapping value of logical phy 3 */
+
+    unsigned int phy28:5;   /**< [10-6] Rx Mapping value of logical phy 4 */
+
+    unsigned int phy29:5;   /**< [5-1] Rx Mapping value of logical phy 5 */
+
+    unsigned int reserved_2:1;  /**< [0] These bits are always 0 */
+    } utRxTransTable4;  /**< Rx translation table */
+
+    /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+    * @struct UtRxTransTable5_
+    * @brief Utopia Rx translation table Register
+    */
+    struct UtRxTransTable5_
+    {
+
+    unsigned int phy30:5;   /**< [31-27] Rx Mapping value of logical phy 6 */
+
+    unsigned int reserved_1:27;     /**< [26-0] These bits are always 0 */
+
+    } utRxTransTable5;  /**< Rx translation table */
+
+    /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+    * @struct UtSysConfig_
+    * @brief NPE setup Register
+    */
+    struct UtSysConfig_
+    {
+
+    unsigned int reserved_1:2;     /**< [31-30] These bits are always 0 */
+    unsigned int txEnbFSM:1;    /**< [29] Enables the operation ofthe Utopia Transmit FSM
+   * @li 1 - FSM enabled
+   * @li 0 - FSM inactive
+   */
+    unsigned int rxEnbFSM:1;    /**< [28] Enables the operation ofthe Utopia Revieve FSM
+   * @li 1 - FSM enabled
+   * @li 0 - FSM inactive
+   */
+    unsigned int disablePins:1;    /**< [27] Disable Utopia interface I/O pins forcing the signals to an
+   * inactive state.  Note that this bit is set on reset and must be
+   * de-asserted
+   * @li 0 - Normal data transfer
+   * @li    1 - Utopia interface pins are forced inactive
+    */
+    unsigned int tstLoop:1;    /**< [26] Test Loop Back Enable.
+    * @li Note: For loop back to function RxMode and Tx Mode must both be set
+    * to single PHY mode.
+    * @li 0 - Loop back
+    * @li 1 - Normal operating mode
+    */
+
+    unsigned int txReset:1;   /**< [25] Resets the Utopia Coprocessor transmit module to a known state.
+    * @li Note: All transmit configuration and status registers will be reset
+    * to their reset values.
+    * @li 0 - Normal operating mode
+    * @li 1 - Reset transmit modules
+    */
+
+    unsigned int rxReset:1;   /**< [24] Resets the Utopia Coprocessor receive module to a known state.
+    * @li Note: All receive configuration and status registers will be reset
+    * to their reset values.
+    * @li    0 - Normal operating mode
+    * @li 1 - Reset receive modules
+    */
+
+    unsigned int reserved_2:24;     /**< [23-0] These bits are always 0 */
+    } utSysConfig;  /**< NPE debug config */
+
+}
+IxAtmdAccUtopiaConfig;
+
+/**
+*
+* @brief Utopia status
+*
+* This structure is used to set/get the Utopia status parameters
+* @li contains debug cell counters, to be accessed during a read operation
+*
+* @note - the exact description of all parameters is done in the Utopia reference
+*   documents.
+*
+*/
+typedef struct
+{
+
+    unsigned int utTxCellCount;  /**< count of cells transmitted */
+
+    unsigned int utTxIdleCellCount;    /**< count of idle cells transmitted */
+
+    /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+    * @struct UtTxCellConditionStatus_
+    * @brief Utopia Tx Status Register
+    */
+    struct UtTxCellConditionStatus_
+    {
+
+    unsigned int reserved_1:2;   /**< [31:30] These bits are always 0 */
+    unsigned int txFIFO2Underflow:1; /**< [29] This bit is set if 64-byte
+                                     * Transmit FIFO2 indicates a FIFO underflow
+                                     * error condition.
+                                     */
+    unsigned int txFIFO1Underflow:1; /**< [28] This bit is set if
+                                     * 64-byte Transmit FIFO1 indicates a FIFO
+                                     * underflow error condition.
+                                     */
+    unsigned int txFIFO2Overflow:1;  /**< [27] This bit is set if 64-byte
+                                     * Transmit FIFO2 indicates a FIFO overflow
+                                     * error condition.
+                                     */
+    unsigned int txFIFO1Overflow:1; /**< [26] This bit is set if 64-byte
+                                    * Transmit FIFO1 indicates a FIFO overflow
+                                    * error condition.
+                                    */
+    unsigned int txIdleCellCountOvr:1; /**< [25] This bit is set if the
+                                       * TxIdleCellCount register overflows.
+                                       */
+    unsigned int txCellCountOvr:1; /**< [24] This bit is set if the
+                                   * TxCellCount register overflows
+                                   */
+    unsigned int reserved_2:24;    /**< [23:0] These bits are always 0 */
+    } utTxCellConditionStatus;    /**< Tx cells condition status */
+
+    unsigned int utRxCellCount; /**< count of cell received */
+    unsigned int utRxIdleCellCount;    /**< count of idle cell received */
+    unsigned int utRxInvalidHECount;     /**< count of invalid cell
+                                        * received because of HEC errors
+                                        */
+    unsigned int utRxInvalidParCount;  /**< count of invalid cell received
+                                        * because of parity errors
+                                        */
+    unsigned int utRxInvalidSizeCount;  /**< count of invalid cell
+                                        * received because of cell
+                                        * size errors
+                                        */
+
+    /**
+    * @ingroup IxAtmdAccUtopiaCtrlAPI
+    * @struct UtRxCellConditionStatus_
+    * @brief Utopia Rx Status Register
+    */
+    struct UtRxCellConditionStatus_
+    {
+
+    unsigned int reserved_1:3;  /**< [31:29] These bits are always 0.*/
+    unsigned int rxCellCountOvr:1;      /**< [28] This bit is set if the RxCellCount register overflows. */
+    unsigned int invalidHecCountOvr:1;    /**< [27] This bit is set if the InvalidHecCount register overflows.*/
+    unsigned int invalidParCountOvr:1;    /**< [26] This bit is set if the InvalidParCount register overflows.*/
+    unsigned int invalidSizeCountOvr:1;    /**< [25] This bit is set if the InvalidSizeCount register overflows.*/
+    unsigned int rxIdleCountOvr:1;      /**< [24] This bit is set if the RxIdleCount register overflows.*/
+    unsigned int reserved_2:4;  /**< [23:20] These bits are always 0 */
+    unsigned int rxFIFO2Underflow:1;  /**< [19] This bit is set if 64-byte Receive FIFO2
+                                      * indicates a FIFO underflow error condition.
+                                      */
+    unsigned int rxFIFO1Underflow:1;  /**< [18] This bit is set if 64-byte Receive
+                                      * FIFO1 indicates a FIFO underflow error condition
+                                    . */
+    unsigned int rxFIFO2Overflow:1;    /**< [17] This bit is set if 64-byte Receive FIFO2
+                                       * indicates a FIFO overflow error condition.
+                                        */
+    unsigned int rxFIFO1Overflow:1;    /**< [16] This bit is set if 64-byte Receive FIFO1
+                                    * indicates a FIFO overflow error condition.
+                                    */
+    unsigned int reserved_3:16;      /**< [15:0] These bits are always 0. */
+    } utRxCellConditionStatus;    /**< Rx cells condition status */
+
+} IxAtmdAccUtopiaStatus;
+
+/**
+ * @} defgroup IxAtmdAccUtopiaCtrlAPI
+ */
+
+ /**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccUtopiaConfigSet (const IxAtmdAccUtopiaConfig *
+                        ixAtmdAccUtopiaConfigPtr)
+ *
+ * @brief Send the configuration structure to the Utopia interface
+ *
+ * This function downloads the @a IxAtmdAccUtopiaConfig structure to
+ * the Utopia and has the following effects
+ *  @li setup the Utopia interface
+ *  @li initialise the NPE
+ *  @li reset the Utopia cell counters and status registers to known values
+ *
+ * This action has to be done once at initialisation. A lock is preventing
+ * the concurrent use of @a ixAtmdAccUtopiaStatusGet() and
+ * @A ixAtmdAccUtopiaConfigSet()
+ *
+ * @param *ixAtmdAccNPEConfigPtr @ref IxAtmdAccUtopiaConfig [in] - pointer to a structure to download to
+ *  Utopia. This parameter cannot be a null pointer.
+ *
+ * @return @li IX_SUCCESS successful download
+ * @return @li IX_FAIL error in the parameters, or configuration is not
+ *         complete or failed
+ *
+ * @sa ixAtmdAccUtopiaStatusGet
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccUtopiaConfigSet (const IxAtmdAccUtopiaConfig *
+                        ixAtmdAccUtopiaConfigPtr);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccUtopiaStatusGet (IxAtmdAccUtopiaStatus *
+                        ixAtmdAccUtopiaStatus)
+ *
+ * @brief Get the Utopia interface configuration.
+ *
+ * This function reads the Utopia registers and the Cell counts
+ * and fills the @a IxAtmdAccUtopiaStatus structure
+ *
+ * A lock is preventing the concurrent
+ * use of @a ixAtmdAccUtopiaStatusGet() and @A ixAtmdAccUtopiaConfigSet()
+ *
+ * @param ixAtmdAccUtopiaStatus @ref IxAtmdAccUtopiaStatus [out] - pointer to structure to be updated from internal
+ *        hardware counters. This parameter cannot be a NULL pointer.
+ *
+ * @return @li IX_SUCCESS successful read
+ * @return @li IX_FAIL error in the parameters null pointer, or
+ *          configuration read is not complete or failed
+ *
+ * @sa ixAtmdAccUtopiaConfigSet
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccUtopiaStatusGet (IxAtmdAccUtopiaStatus *
+                        ixAtmdAccUtopiaStatus);
+
+/**
+ *
+ * @ingroup IxAtmdAcc
+ *
+ * @fn ixAtmdAccPortEnable (IxAtmLogicalPort port)
+ *
+ * @brief enable a PHY logical port
+ *
+ * This function enables the transmission over one port. It should be
+ * called before accessing any resource from this port and before the
+ * establishment of a VC.
+ *
+ * When a port is enabled, the cell transmission to the Utopia interface
+ * is started. If there is no traffic already running, idle cells are
+ * sent over the interface.
+ *
+ * This function can be called multiple times.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ *
+ * @return @li IX_SUCCESS enable is complete
+ * @return @li IX_ATMDACC_WARNING port already enabled
+ * @return @li IX_FAIL enable failed, wrong parameter, or cannot
+ *         initialise this port (the port is maybe already in use,
+ *         or there is a hardware issue)
+ *
+ * @note - This function needs internal locks and should not be
+ *         called from an interrupt context
+ *
+ * @sa ixAtmdAccPortDisable
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccPortEnable (IxAtmLogicalPort port);
+
+/**
+ *
+ * @ingroup IxAtmdAccCtrlAPI
+ *
+ * @fn ixAtmdAccPortDisable (IxAtmLogicalPort port)
+ *
+ * @brief disable a PHY logical port
+ *
+ * This function disable the transmission over one port.
+ *
+ * When a port is disabled, the cell transmission to the Utopia interface
+ * is stopped.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+ *
+ * @return @li IX_SUCCESS disable is complete
+ * @return @li IX_ATMDACC_WARNING port already disabled
+ * @return @li IX_FAIL disable failed, wrong parameter .
+ *
+ * @note - This function needs internal locks and should not be called
+ *         from an interrupt context
+ *
+ * @note - The response from hardware is done through the txDone mechanism
+ *         to ensure the synchrnisation with tx resources. Therefore, the
+ *         txDone mechanism needs to be serviced to make a PortDisable complete.
+ *
+ * @sa ixAtmdAccPortEnable
+ * @sa ixAtmdAccPortDisableComplete
+ * @sa ixAtmdAccTxDoneDispatch
+ *
+ */
+PUBLIC IX_STATUS ixAtmdAccPortDisable (IxAtmLogicalPort port);
+
+/**
+*
+* @ingroup IxAtmdAccCtrlAPI
+*
+* @fn ixAtmdAccPortDisableComplete (IxAtmLogicalPort port)
+*
+* @brief disable a PHY logical port
+*
+* This function indicates if the port disable for a port has completed. This
+* function will return true if the port has never been enabled.
+*
+* @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1]
+*
+* @return @li true disable is complete
+* @return @li false disable failed, wrong parameter .
+*
+* @note - This function needs internal locks and should not be called
+*         from an interrupt context
+*
+* @sa ixAtmdAccPortEnable
+* @sa ixAtmdAccPortDisable
+*
+*/
+PUBLIC BOOL ixAtmdAccPortDisableComplete (IxAtmLogicalPort port);
+
+#endif /* IXATMDACCCTRL_H */
+
+/**
+ * @} defgroup IxAtmdAccCtrlAPI
+ */
+
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxAtmm.h b/marvell/uboot/drivers/net/npe/include/IxAtmm.h
new file mode 100644
index 0000000..805b8c9
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxAtmm.h
@@ -0,0 +1,771 @@
+/**
+ * @file    IxAtmm.h
+ *
+ * @date    3-DEC-2001
+ *
+ * @brief   Header file for the IXP400 ATM Manager component (IxAtmm)
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+/**
+ * @defgroup IxAtmm IXP400 ATM Manager (IxAtmm) API
+ *
+ * @brief IXP400 ATM Manager component Public API
+ *
+ * @{
+ */
+
+#ifndef IXATMM_H
+#define IXATMM_H
+
+/*
+ * Put the user defined include files required
+ */
+#include "IxAtmSch.h"
+#include "IxOsalTypes.h"
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/** 
+ * @def IX_ATMM_RET_ALREADY_INITIALIZED
+ * 
+ * @brief Component has already been initialized 
+ */
+#define IX_ATMM_RET_ALREADY_INITIALIZED 2
+
+/** 
+ * @def IX_ATMM_RET_INVALID_PORT
+ * 
+ * @brief Specified port does not exist or is out of range */
+#define IX_ATMM_RET_INVALID_PORT 3
+
+/** 
+ * @def IX_ATMM_RET_INVALID_VC_DESCRIPTOR
+ * 
+ * @brief The VC description does not adhere to ATM standards */
+#define IX_ATMM_RET_INVALID_VC_DESCRIPTOR 4
+
+/** 
+ * @def IX_ATMM_RET_VC_CONFLICT
+ * 
+ * @brief The VPI/VCI values supplied are either reserved, or they
+ *         conflict with a previously registered VC on this port */
+#define IX_ATMM_RET_VC_CONFLICT 5
+
+/** 
+ * @def IX_ATMM_RET_PORT_CAPACITY_IS_FULL
+ * 
+ * @brief The virtual connection cannot be established on the port
+ *         because the remaining port capacity is not sufficient to
+ *         support it */
+#define IX_ATMM_RET_PORT_CAPACITY_IS_FULL 6
+
+/** 
+ * @def IX_ATMM_RET_NO_SUCH_VC
+ * 
+ * @brief No registered VC, as described by the supplied VCI/VPI or
+ *         VC identifier values, exists on this port */
+#define IX_ATMM_RET_NO_SUCH_VC 7
+
+/** 
+ * @def IX_ATMM_RET_INVALID_VC_ID
+ * 
+ * @brief The specified VC identifier is out of range. */
+#define IX_ATMM_RET_INVALID_VC_ID 8
+
+/** 
+ * @def IX_ATMM_RET_INVALID_PARAM_PTR
+ * 
+ * @brief A pointer parameter was NULL. */
+#define IX_ATMM_RET_INVALID_PARAM_PTR 9
+
+/** 
+ * @def IX_ATMM_UTOPIA_SPHY_ADDR  
+ * 
+ * @brief The phy address when in SPHY mode */
+#define IX_ATMM_UTOPIA_SPHY_ADDR 31
+
+/**
+ * @def IX_ATMM_THREAD_PRI_HIGH
+ *
+ * @brief The value of high priority thread */
+#define IX_ATMM_THREAD_PRI_HIGH 90
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/** @brief Definition for use in the @ref IxAtmmVc structure.
+ *         Indicates the direction of a VC */
+typedef enum
+{
+    IX_ATMM_VC_DIRECTION_TX=0, /**< Atmm Vc direction transmit*/
+    IX_ATMM_VC_DIRECTION_RX, /**< Atmm Vc direction receive*/
+    IX_ATMM_VC_DIRECTION_INVALID /**< Atmm Vc direction invalid*/
+} IxAtmmVcDirection;
+
+/** @brief Definition for use with @ref IxAtmmVcChangeCallback
+ *         callback.  Indicates that the event type represented by the
+ *         callback for this VC. */
+typedef enum
+{
+    IX_ATMM_VC_CHANGE_EVENT_REGISTER=0, /**< Atmm Vc event register*/
+    IX_ATMM_VC_CHANGE_EVENT_DEREGISTER, /**< Atmm Vc event de-register*/
+    IX_ATMM_VC_CHANGE_EVENT_INVALID /**< Atmm Vc event invalid*/
+} IxAtmmVcChangeEvent;
+
+/** @brief Definitions for use with @ref ixAtmmUTOPIAInit interface to
+ *         indicate that UTOPIA loopback should be enabled or disabled
+ *         on initialisation. */
+typedef enum
+{
+    IX_ATMM_UTOPIA_LOOPBACK_DISABLED=0, /**< Atmm Utopia loopback mode disabled*/
+    IX_ATMM_UTOPIA_LOOPBACK_ENABLED, /**< Atmm Utopia loopback mode enabled*/
+    IX_ATMM_UTOPIA_LOOPBACK_INVALID /**< Atmm Utopia loopback mode invalid*/
+} IxAtmmUtopiaLoopbackMode;
+
+/** @brief This structure describes the required attributes of a
+ *         virtual connection.
+*/
+typedef struct {
+    unsigned vpi;  /**< VPI value of this virtual connection */
+    unsigned vci;  /**< VCI value of this virtual connection. */
+    IxAtmmVcDirection direction; /**< VC direction */
+
+    /** Traffic descriptor of this virtual connection.  This structure
+     *  is defined by the @ref IxAtmSch component.  */
+    IxAtmTrafficDescriptor trafficDesc;
+} IxAtmmVc;
+
+
+/** @brief Definitions for use with @ref ixAtmmUtopiaInit interface to
+ *         indicate that UTOPIA multi-phy/single-phy mode is used.
+ */
+typedef enum
+{
+    IX_ATMM_MPHY_MODE = 0, /**< Atmm phy mode mphy*/
+    IX_ATMM_SPHY_MODE, /**< Atmm phy mode sphy*/
+    IX_ATMM_PHY_MODE_INVALID /**< Atmm phy mode invalid*/
+} IxAtmmPhyMode;
+
+
+/** @brief Structure contains port-specific information required to
+ *         initialize IxAtmm, and specifically, the IXP400 UTOPIA
+ *         Level-2 device. */
+typedef struct {
+    unsigned reserved_1:11;     /**< [31:21] Should be zero */
+    unsigned UtopiaTxPhyAddr:5; /**< [20:16] Address of the
+     *   transmit (Tx) PHY for this
+     *   port on the 5-bit UTOPIA
+     *   Level-2 address bus */
+    unsigned reserved_2:11;     /**< [15:5] Should be zero */
+    unsigned UtopiaRxPhyAddr:5; /**< [4:0] Address of the receive
+     *   (Rx) PHY for this port on the
+     *   5-bit UTOPIA  Level-2
+     *   address bus */
+} IxAtmmPortCfg;
+
+/** @brief Callback type used with @ref ixAtmmVcChangeCallbackRegister interface
+ *         Defines a callback type  which will be used to notify registered
+ *         users of registration/deregistration events on a particular port
+ *
+ * @param eventType @ref IxAtmmVcChangeEvent [in] - Event indicating
+ *                        whether the VC supplied has been added or
+ *                        removed
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Specifies the port on which the event has
+ *                        occurred
+ *
+ * @param vcChanged @ref IxAtmmVc* [in] - Pointer to a structure which gives
+ *                              details of the VC which has been added
+ *                              or removed on the port
+ */
+typedef void (*IxAtmmVcChangeCallback) (IxAtmmVcChangeEvent eventType,
+					IxAtmLogicalPort port,
+					const IxAtmmVc* vcChanged);
+
+/*
+ * Variable declarations global to this file only. Externs are followed by
+ * static variables.
+ */
+
+/*
+ * Extern function prototypes
+ */
+
+/*
+ * Function declarations
+ */
+
+
+/** 
+ * @ingroup IxAtmm
+ *
+ * @fn ixAtmmInit (void)
+ *
+ * @brief Interface to initialize the IxAtmm software component.  Can
+ *         be called once only.
+ *
+ *  Must be called before any other IxAtmm API is called.
+ *
+ * @param "none"
+ *
+ *  @return @li  IX_SUCCESS : IxAtmm has been successfully initialized.
+ *      Calls to other IxAtmm interfaces may now be performed.
+ *  @return @li  IX_FAIL : IxAtmm has already been initialized.
+ */
+PUBLIC IX_STATUS
+ixAtmmInit (void);
+
+/**  
+ * @ingroup IxAtmm
+ * 
+ * @fn ixAtmmUtopiaInit (unsigned numPorts,
+		  IxAtmmPhyMode phyMode,
+		  IxAtmmPortCfg portCfgs[],
+		  IxAtmmUtopiaLoopbackMode loopbackMode)
+ *
+ * @brief Interface to initialize the UTOPIA Level-2 ATM coprocessor
+ *         for the specified number of physical ports.  The function
+ *         must be called before the ixAtmmPortInitialize interface
+ *         can operate successfully.
+ *
+ * @param numPorts unsigned [in] - Indicates the total number of logical
+ *          ports that are active on the device.  Up to 12 ports are
+ *          supported.
+ *
+ * @param phyMode @ref IxAtmmPhyMode [in] - Put the Utopia coprocessor in SPHY
+ *        or MPHY mode.
+ *
+ * @param portCfgs[] @ref IxAtmmPortCfg [in] - Pointer to an array of elements
+ *          detailing the UTOPIA specific port characteristics.  The
+ *          length of the array must be equal to the number of ports
+ *          activated.  ATM ports are referred to by the relevant
+ *          offset in this array in all subsequent IxAtmm interface
+ *          calls.
+ *
+ * @param loopbackMode @ref IxAtmmUtopiaLoopbackMode [in] - Value must be one of
+ *          @ref IX_ATMM_UTOPIA_LOOPBACK_ENABLED or @ref
+ *          IX_ATMM_UTOPIA_LOOPBACK_DISABLED indicating whether
+ *          loopback should be enabled on the device.  Loopback can
+ *          only be supported on a single PHY, therefore the numPorts
+ *          parameter must be 1 if loopback is enabled.
+ *
+ * @return @li IX_SUCCESS : Indicates that the  UTOPIA device has been
+ *      successfully initialized for the supplied ports.
+ * @return @li IX_ATMM_RET_ALREADY_INITIALIZED : The UTOPIA device has
+ *      already been initialized.
+ * @return @li IX_FAIL : The supplied parameters are invalid or have been
+ *     rejected by the UTOPIA-NPE device.
+ *
+ * @warning
+ * This interface may only be called once.
+ * Port identifiers are assumed to range from 0 to (numPorts - 1) in all 
+ * instances.
+ * In all subsequent calls to interfaces supplied by IxAtmm, the specified
+ * port value is expected to represent the offset in the portCfgs array
+ * specified in this interface.  i.e. The first port in this array will
+ * subsequently be represented as port 0, the second port as port 1,
+ * and so on.*/
+PUBLIC IX_STATUS
+ixAtmmUtopiaInit (unsigned numPorts,
+		  IxAtmmPhyMode phyMode,
+		  IxAtmmPortCfg portCfgs[],
+		  IxAtmmUtopiaLoopbackMode loopbackMode);
+
+
+/**   
+ * @ingroup IxAtmm
+ * 
+ * @fn ixAtmmPortInitialize (IxAtmLogicalPort port,
+		      unsigned txPortRate,
+		      unsigned rxPortRate)
+ *
+ * @brief The interface is called following @ref ixAtmmUtopiaInit ()
+ *         and before calls to any other IxAtmm interface.  It serves
+ *         to activate the registered ATM port with IxAtmm.
+ *
+ *  The transmit and receive port rates are specified in bits per
+ *  second.  This translates to ATM cells per second according to the
+ *  following formula: CellsPerSecond = portRate / (53*8)  The
+ *  IXP400 device supports only 53 byte cells. The client shall make
+ *  sure that the off-chip physical layer device has already been
+ *  initialized.
+ *
+ *  IxAtmm will configure IxAtmdAcc and IxAtmSch to enable scheduling
+ *  on the port.
+ *
+ *  This interface must be called once for each active port in the
+ *  system.  The first time the interface is invoked, it will configure
+ *  the mechanism by which the handling of transmit, transmit-done and
+ *  receive are driven with the IxAtmdAcc component.
+ *
+ *  This function is reentrant.
+ *
+ *  @note The minimum tx rate that will be accepted is 424 bit/s which equates
+ *        to 1 cell (53 bytes) per second.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Identifies the port which is to be
+ *          initialized.
+ *
+ * @param txPortRate unsigned [in] - Value specifies the
+ *          transmit port rate for this port in
+ *          bits/second.  This value is used by the ATM Scheduler
+ *          component is evaluating VC access requests for the port.
+ *
+ * @param rxPortRate unsigned [in] - Value specifies the
+ *          receive port rate for this port in bits/second.
+ *
+ * @return @li IX_SUCCESS : The specificed ATM port has been successfully
+ *       initialized. IxAtmm is ready to accept VC registrations on
+ *       this port.
+ *
+ * @return @li IX_ATMM_RET_ALREADY_INITIALIZED : ixAtmmPortInitialize has
+ *       already been called successfully on this port.  The current
+ *       call is rejected.
+ *
+ * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
+ *       input is not valid.  The request is rejected.
+ *
+ * @return @li IX_FAIL : IxAtmm could not initialize the port because the
+ * inputs are not understood.
+ *
+ * @sa ixAtmmPortEnable, ixAtmmPortDisable
+ *
+ */
+PUBLIC IX_STATUS
+ixAtmmPortInitialize (IxAtmLogicalPort port,
+		      unsigned txPortRate,
+		      unsigned rxPortRate);
+
+/**    
+ * @ingroup IxAtmm
+ * 
+ * @fn ixAtmmPortModify (IxAtmLogicalPort port,
+		  unsigned txPortRate,
+		  unsigned rxPortRate)
+ *
+ * @brief A client may call this interface to change the existing
+ *         port rate (expressed in bits/second) on an established ATM
+ *         port.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Identifies the port which is to be
+ *          initialized.
+ *
+ * @param txPortRate unsigned [in] -  Value specifies the``
+ *          transmit port rate for this port in
+ *          bits/second.  This value is used by the ATM Scheduler
+ *          component is evaluating VC access requests for the port.
+ *
+ * @param rxPortRate unsigned [in] - Value specifies the
+ *          receive port rate for this port in
+ *          bits/second.
+ *
+ * @return @li IX_SUCCESS : The indicated ATM port rates have been
+ *      successfully modified.
+ *
+ * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
+ *       input is not valid.  The request is rejected.
+ *
+ * @return @li IX_FAIL : IxAtmm could not update the port because the
+ *       inputs are not understood, or the interface was called before
+ * the port was initialized.  */
+PUBLIC IX_STATUS
+ixAtmmPortModify (IxAtmLogicalPort port,
+		  unsigned txPortRate,
+		  unsigned rxPortRate);
+
+/**    
+ * @ingroup IxAtmm
+ * 
+ * @fn ixAtmmPortQuery (IxAtmLogicalPort port,
+		 unsigned *txPortRate,
+		 unsigned *rxPortRate);
+
+ *
+ * @brief The client may call this interface to request details on
+ *          currently registered transmit and receive rates for an ATM
+ *          port.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Value identifies the port from which the
+ *          rate details are requested.
+ *
+ * @param *txPortRate unsigned [out] - Pointer to a value
+ *          which will be filled with the value of the transmit port
+ *          rate specified in bits/second.
+ *
+ * @param *rxPortRate unsigned [out] - Pointer to a value
+ *          which will be filled with the value of the receive port
+ *          rate specified in bits/second.
+ *
+ * @return @li IX_SUCCESS : The information requested on the specified
+ *       port has been successfully supplied in the output.
+ *
+ * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
+ *       input is not valid.  The request is rejected.
+ *
+ * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was
+ *       NULL.
+ *
+ * @return @li IX_FAIL : IxAtmm could not update the port because the
+ *       inputs are not understood, or the interface was called before
+ *       the port was initialized.  */
+PUBLIC IX_STATUS
+ixAtmmPortQuery (IxAtmLogicalPort port,
+		 unsigned *txPortRate,
+		 unsigned *rxPortRate);
+
+/**    
+ * @ingroup IxAtmm
+ * 
+ * @fn ixAtmmPortEnable(IxAtmLogicalPort port)
+ *
+ * @brief The client call this interface to enable transmit for an ATM
+ *          port. At initialisation, all the ports are disabled.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Value identifies the port
+ *
+ * @return @li IX_SUCCESS : Transmission over this port is started.
+ *
+ * @return @li IX_FAIL : The port parameter is not valid, or the
+ *       port is already enabled
+ *
+ * @note - When a port is disabled, Rx and Tx VC Connect requests will fail
+ *
+ * @note - This function uses system resources and should not be used
+ *        inside an interrupt context.
+ *
+ * @sa ixAtmmPortDisable  */
+PUBLIC IX_STATUS
+ixAtmmPortEnable(IxAtmLogicalPort port);
+
+/**    
+ * @ingroup IxAtmm
+ * 
+ * @fn ixAtmmPortDisable(IxAtmLogicalPort port)
+ *
+ * @brief The client call this interface to disable transmit for an ATM
+ *          port. At initialisation, all the ports are disabled.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Value identifies the port
+ *
+ * @return @li IX_SUCCESS : Transmission over this port is stopped.
+ *
+ * @return @li IX_FAIL : The port parameter is not valid, or the
+ *       port is already disabled
+ *
+ * @note - When a port is disabled, Rx and Tx VC Connect requests will fail
+ *
+ * @note - This function call does not stop RX traffic. It is supposed
+ *        that this function is invoked when a serious problem
+ *        is detected (e.g. physical layer broken). Then, the RX traffic
+ *        is not passing.
+ *
+ * @note - This function is blocking until the hw acknowledge that the
+ *        transmission is stopped.
+ *
+ * @note - This function uses system resources and should not be used
+ *        inside an interrupt context.
+ *
+ * @sa ixAtmmPortEnable  */
+PUBLIC IX_STATUS
+ixAtmmPortDisable(IxAtmLogicalPort port);
+
+/**    
+ * @ingroup IxAtmm
+ * 
+ * @fn ixAtmmVcRegister (IxAtmLogicalPort port,
+		  IxAtmmVc *vcToAdd,
+		  IxAtmSchedulerVcId *vcId)
+ *
+ * @brief This interface is used to register an ATM Virtual
+ *         Connection on the specified ATM port.
+ *
+ *  Each call to this interface registers a unidirectional virtual
+ *  connection with the parameters specified.  If a bi-directional VC
+ *  is needed, the function should be called twice (once for each
+ *  direction, Tx & Rx) where the VPI and VCI and port parameters in
+ *  each call are identical.
+ *
+ *  With the addition of each new VC to a port, a series of
+ *  callback functions are invoked by the IxAtmm component to notify
+ *  possible external components of the change.  The callback functions
+ *  are registered using the @ref ixAtmmVcChangeCallbackRegister interface.
+ *
+ *  The IxAtmSch component is notified of the registration of transmit
+ *  VCs.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the specified VC is
+ *          to be registered.
+ *
+ * @param *vcToAdd @ref IxAtmmVc [in] -  Pointer to an @ref IxAtmmVc structure
+ *          containing a description of the VC to be registered. The
+ *          client shall fill the vpi, vci and direction and relevant
+ *          trafficDesc members of this structure before calling this
+ *          function.
+ *
+ * @param *vcId @ref IxAtmSchedulerVcId [out] - Pointer to an integer value which is filled
+ *              with the per-port unique identifier value for this VC.
+ *              This identifier will be required when a request is
+ *              made to deregister or change this VC.  VC identifiers
+ *              for transmit VCs will have a value between 0-43,
+ *              i.e. 32 data Tx VCs + 12 OAM Tx Port VCs.
+ *              Receive VCs will have a value between 44-66,
+ *              i.e. 32 data Rx VCs + 1 OAM Rx VC.
+ *
+ * @return @li IX_SUCCESS : The VC has been successfully registered on
+ *       this port. The VC is ready for a client to configure IxAtmdAcc
+ *       for receive and transmit operations on the VC.
+ * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
+ *       input is not valid or has not been initialized.  The request
+ *       is rejected.
+ * @return @li IX_ATMM_RET_INVALID_VC_DESCRIPTOR : The descriptor
+ *       pointed to by vcToAdd is invalid.  The registration request
+ *       is rejected.
+ * @return @li IX_ATMM_RET_VC_CONFLICT : The VC requested conflicts with
+ *      reserved VPI and/or VCI values or with another VC already activated
+ *      on this port.
+ * @return @li IX_ATMM_RET_PORT_CAPACITY_IS_FULL : The VC cannot be
+ *       registered in the port becuase the port capacity is
+ *       insufficient to support the requested ATM traffic contract.
+ *       The registration request is rejected.
+ * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was
+ *       NULL.
+ *
+ * @warning IxAtmm has no capability of signaling or negotiating a virtual
+ *          connection. Negotiation of the admission of the VC to the network
+ *          is beyond the scope of this function.  This is assumed to be
+ *          performed by the calling client, if appropriate,
+ *          before or after this function is called.
+ */
+PUBLIC IX_STATUS
+ixAtmmVcRegister (IxAtmLogicalPort port,
+		  IxAtmmVc *vcToAdd,
+		  IxAtmSchedulerVcId *vcId);
+
+/**    
+ * @ingroup IxAtmm
+ * 
+ * @fn ixAtmmVcDeregister (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId)
+ *
+ * @brief Function called by a client to deregister a VC from the
+ *         system.
+ *
+ *  With the removal of each new VC from a port, a series of
+ *  registered callback functions are invoked by the IxAtmm component
+ *  to notify possible external components of the change.  The callback
+ *  functions are registered using the @ref ixAtmmVcChangeCallbackRegister.
+ *
+ *  The IxAtmSch component is notified of the removal of transmit VCs.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be
+ *          removed is currently registered.
+ *
+ * @param vcId @ref IxAtmSchedulerVcId [in] - VC identifier value of the VC to
+ *          be deregistered.  This value was supplied to the client when
+            the VC was originally registered.  This value can also be
+	    queried from the IxAtmm component through the @ref ixAtmmVcQuery
+ *          interface.
+ *
+ * @return @li IX_SUCCESS : The specified VC has been successfully
+ *       removed from this port.
+ * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
+ *       input is not valid or has not been initialized.  The request
+ *       is rejected.
+ * @return @li IX_FAIL : There is no registered VC associated with the
+ *       supplied identifier registered on this port. */
+PUBLIC IX_STATUS
+ixAtmmVcDeregister (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId);
+
+/**    
+ * @ingroup IxAtmm
+ * 
+ * @fn ixAtmmVcQuery (IxAtmLogicalPort port,
+	       unsigned vpi,
+	       unsigned vci,
+	       IxAtmmVcDirection direction,
+	       IxAtmSchedulerVcId *vcId,
+	       IxAtmmVc *vcDesc)
+ *
+ * @brief This interface supplies information about an active VC on a
+ *         particular port when supplied with the VPI, VCI and
+ *         direction of that VC.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be
+ *          queried is currently registered.
+ *
+ * @param vpi unsigned [in] - ATM VPI value of the requested VC.
+ *
+ * @param vci unsigned [in] - ATM VCI value of the requested VC.
+ *
+ * @param direction @ref IxAtmmVcDirection [in] - One of @ref
+ *          IX_ATMM_VC_DIRECTION_TX or @ref IX_ATMM_VC_DIRECTION_RX
+ *          indicating the direction (Tx or Rx) of the requested VC.
+ *
+ * @param *vcId @ref IxAtmSchedulerVcId [out] - Pointer to an integer value which will be
+ *              filled with the VC identifier value for the requested
+ *              VC (as returned by @ref ixAtmmVcRegister), if it
+ *              exists on this port.
+ *
+ * @param *vcDesc @ref IxAtmmVc [out] - Pointer to an @ref IxAtmmVc structure
+ *              which will be filled with the specific details of the
+ *              requested VC, if it exists on this port.
+ *
+ * @return @li IX_SUCCESS : The specified VC has been found on this port
+ *       and the requested details have been returned.
+ * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
+ *       input is not valid or has not been initialized.  The request
+ *       is rejected.
+ * @return @li IX_ATMM_RET_NO_SUCH_VC : No VC exists on the specified
+ *       port which matches the search criteria (VPI, VCI, direction)
+ *       given.  No data is returned.
+ * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was
+ *       NULL.
+ *
+ */
+PUBLIC IX_STATUS
+ixAtmmVcQuery (IxAtmLogicalPort port,
+	       unsigned vpi,
+	       unsigned vci,
+	       IxAtmmVcDirection direction,
+	       IxAtmSchedulerVcId *vcId,
+	       IxAtmmVc *vcDesc);
+
+
+/**    
+ * @ingroup IxAtmm
+ * 
+ * @fn ixAtmmVcIdQuery (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId, IxAtmmVc *vcDesc)
+ *
+ * @brief This interface supplies information about an active VC on a
+ *         particular port when supplied with a vcId for that VC.
+ *
+ * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be
+ *          queried is currently registered.
+ *
+ * @param vcId @ref IxAtmSchedulerVcId [in] - Value returned by @ref ixAtmmVcRegister which
+ *          uniquely identifies the requested VC on this port.
+ *
+ * @param *vcDesc @ref IxAtmmVc [out] - Pointer to an @ref IxAtmmVc structure
+ *              which will be filled with the specific details of the
+ *              requested VC, if it exists on this port.
+ *
+ * @return @li IX_SUCCESS : The specified VC has been found on this port
+ *       and the requested details have been returned.
+ * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the
+ *       input is not valid or has not been initialized.  The request
+ *       is rejected.
+ * @return @li IX_ATMM_RET_NO_SUCH_VC : No VC exists on the specified
+ *       port which matches the supplied identifier.  No data is
+ *       returned.
+ * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was
+ *       NULL.
+ */
+PUBLIC IX_STATUS
+ixAtmmVcIdQuery (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId, IxAtmmVc *vcDesc);
+
+/**    
+ * @ingroup IxAtmm
+ * 
+ * @fn ixAtmmVcChangeCallbackRegister (IxAtmmVcChangeCallback callback)
+ *
+ * @brief This interface is invoked to supply a function to IxAtmm
+ *         which will be called to notify the client if a new VC is
+ *         registered with IxAtmm or an existing VC is removed.
+ *
+ * The callback, when invoked, will run within the context of the call
+ * to @ref ixAtmmVcRegister or @ref ixAtmmVcDeregister which caused
+ * the change of state.
+ *
+ * A maximum of 32 calbacks may be registered in with IxAtmm.
+ *
+ * @param callback @ref IxAtmmVcChangeCallback [in] - Callback which complies
+ *          with the @ref IxAtmmVcChangeCallback definition.  This
+ *          function will be invoked by IxAtmm with the appropiate
+ *          parameters for the relevant VC when any VC has been
+ *          registered or deregistered with IxAtmm.
+ *
+ * @return @li IX_SUCCESS : The specified callback has been registered
+ *      successfully with IxAtmm and will be invoked when appropriate.
+ * @return @li IX_FAIL : Either the supplied callback is invalid, or
+ *      IxAtmm has already registered 32 and connot accommodate
+ *      any further registrations of this type.  The request is
+ *      rejected.
+ *
+ * @warning The client must not call either the @ref
+ *          ixAtmmVcRegister or @ref ixAtmmVcDeregister interfaces
+ *          from within the supplied callback function.  */
+PUBLIC IX_STATUS ixAtmmVcChangeCallbackRegister (IxAtmmVcChangeCallback callback);
+
+
+/**    
+ * @ingroup IxAtmm
+ * 
+ * @fn ixAtmmVcChangeCallbackDeregister (IxAtmmVcChangeCallback callback)
+ *
+ * @brief This interface is invoked to deregister a previously supplied
+ *         callback function.
+ *
+ * @param callback @ref IxAtmmVcChangeCallback [in] - Callback which complies
+ *          with the @ref IxAtmmVcChangeCallback definition.  This
+ *          function will removed from the table of callbacks.
+ *
+ * @return @li IX_SUCCESS : The specified callback has been deregistered
+ *      successfully from IxAtmm.
+ * @return @li IX_FAIL : Either the supplied callback is invalid, or
+ *      is not currently registered with IxAtmm.
+ */
+PUBLIC IX_STATUS
+ixAtmmVcChangeCallbackDeregister (IxAtmmVcChangeCallback callback);
+
+/**    
+ * @ingroup IxAtmm
+ * 
+ * @fn ixAtmmUtopiaStatusShow (void)
+ * 
+ *  @brief Display utopia status counters
+ *
+ * @param "none"
+ *
+ * @return @li IX_SUCCESS : Show function was successful
+ * @return @li IX_FAIL : Internal failure
+ */
+PUBLIC IX_STATUS
+ixAtmmUtopiaStatusShow (void);
+
+/**     
+ * @ingroup IxAtmm
+ * 
+ * @fn ixAtmmUtopiaCfgShow (void)
+ *
+ * @brief Display utopia information(config registers and status registers)
+ *
+ * @param "none"
+ *
+ * @return @li IX_SUCCESS : Show function was successful
+ * @return @li IX_FAIL : Internal failure
+ */
+PUBLIC IX_STATUS
+ixAtmmUtopiaCfgShow (void);
+
+#endif
+/* IXATMM_H */
+
+/** @} */
diff --git a/marvell/uboot/drivers/net/npe/include/IxDmaAcc.h b/marvell/uboot/drivers/net/npe/include/IxDmaAcc.h
new file mode 100644
index 0000000..a62e72c
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxDmaAcc.h
@@ -0,0 +1,236 @@
+/**
+ * @file IxDmaAcc.h
+ *
+ * @date	15 October 2002 
+ *
+ * @brief   API of the IXP400 DMA Access Driver Component (IxDma)
+ *
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/*---------------------------------------------------------------------
+   Doxygen group definitions
+  ---------------------------------------------------------------------*/
+
+#ifndef IXDMAACC_H
+#define IXDMAACC_H
+
+#include "IxOsal.h"
+#include "IxNpeDl.h"
+/**
+ * @defgroup IxDmaTypes IXP400 DMA Types (IxDmaTypes)
+ * @brief The common set of types used in the DMA component
+ * @{
+ */
+
+/** 
+ * @ingroup IxDmaTypes
+ * @enum IxDmaReturnStatus
+ * @brief Dma return status definitions
+ */
+typedef enum
+{
+    IX_DMA_SUCCESS = IX_SUCCESS,  /**< DMA Transfer Success */
+    IX_DMA_FAIL = IX_FAIL,        /**< DMA Transfer Fail */
+    IX_DMA_INVALID_TRANSFER_WIDTH, /**< Invalid transfer width */
+    IX_DMA_INVALID_TRANSFER_LENGTH, /**< Invalid transfer length */
+    IX_DMA_INVALID_TRANSFER_MODE, /**< Invalid transfer mode */
+    IX_DMA_INVALID_ADDRESS_MODE, /**< Invalid address mode */
+    IX_DMA_REQUEST_FIFO_FULL  /**< DMA request queue is full */
+} IxDmaReturnStatus;
+
+/** 
+ * @ingroup IxDmaTypes
+ * @enum IxDmaTransferMode
+ * @brief Dma transfer mode definitions
+ * @note Copy and byte swap, and copy and reverse modes only support multiples of word data length.
+ */
+typedef enum
+{
+    IX_DMA_COPY_CLEAR = 0,      /**< copy and clear source*/
+    IX_DMA_COPY,                /**< copy */
+    IX_DMA_COPY_BYTE_SWAP,      /**< copy and byte swap (endian) */
+    IX_DMA_COPY_REVERSE,        /**< copy and reverse */
+    IX_DMA_TRANSFER_MODE_INVALID /**< Invalid transfer mode */
+} IxDmaTransferMode;
+
+/** 
+ * @ingroup IxDmaTypes
+ * @enum IxDmaAddressingMode
+ * @brief Dma addressing mode definitions
+ * @note Fixed source address to fixed destination address addressing mode is not supported.
+ */
+typedef enum
+{
+    IX_DMA_INC_SRC_INC_DST = 0, /**< Incremental source address to incremental destination address */
+    IX_DMA_INC_SRC_FIX_DST,     /**< Incremental source address to incremental destination address */
+    IX_DMA_FIX_SRC_INC_DST,     /**< Incremental source address to incremental destination address */
+    IX_DMA_FIX_SRC_FIX_DST,     /**< Incremental source address to incremental destination address */
+    IX_DMA_ADDRESSING_MODE_INVALID /**< Invalid Addressing Mode */
+} IxDmaAddressingMode;
+
+/** 
+ * @ingroup IxDmaTypes
+ * @enum IxDmaTransferWidth
+ * @brief Dma transfer width definitions
+ * @Note Fixed addresses (either source or destination) do not support burst transfer width.
+ */
+typedef enum
+{
+    IX_DMA_32_SRC_32_DST = 0,  /**< 32-bit src to 32-bit dst */
+    IX_DMA_32_SRC_16_DST,      /**< 32-bit src to 16-bit dst */
+    IX_DMA_32_SRC_8_DST,       /**< 32-bit src to 8-bit dst */
+    IX_DMA_16_SRC_32_DST,      /**< 16-bit src to 32-bit dst */
+    IX_DMA_16_SRC_16_DST,      /**< 16-bit src to 16-bit dst */
+    IX_DMA_16_SRC_8_DST,       /**< 16-bit src to 8-bit dst */
+    IX_DMA_8_SRC_32_DST,       /**< 8-bit src to 32-bit dst */
+    IX_DMA_8_SRC_16_DST,       /**< 8-bit src to 16-bit dst */
+    IX_DMA_8_SRC_8_DST,        /**< 8-bit src to 8-bit dst */
+    IX_DMA_8_SRC_BURST_DST,    /**< 8-bit src to burst dst - Not supported for fixed destination address */
+    IX_DMA_16_SRC_BURST_DST,   /**< 16-bit src to burst dst - Not supported for fixed destination address */
+    IX_DMA_32_SRC_BURST_DST,   /**< 32-bit src to burst dst - Not supported for fixed destination address */
+    IX_DMA_BURST_SRC_8_DST,    /**< burst src to 8-bit dst  - Not supported for fixed source address */
+    IX_DMA_BURST_SRC_16_DST,   /**< burst src to 16-bit dst - Not supported for fixed source address */
+    IX_DMA_BURST_SRC_32_DST,   /**< burst src to 32-bit dst - Not supported for fixed source address*/
+    IX_DMA_BURST_SRC_BURST_DST, /**< burst src to burst dst  - Not supported for fixed source and destination address
+*/
+    IX_DMA_TRANSFER_WIDTH_INVALID /**< Invalid transfer width */
+} IxDmaTransferWidth;
+
+/** 
+ * @ingroup IxDmaTypes
+ * @enum IxDmaNpeId
+ * @brief NpeId numbers to identify NPE A, B or C
+ */
+typedef enum
+{
+    IX_DMA_NPEID_NPEA = 0, /**< Identifies NPE A */
+    IX_DMA_NPEID_NPEB,     /**< Identifies NPE B */
+    IX_DMA_NPEID_NPEC,     /**< Identifies NPE C */
+    IX_DMA_NPEID_MAX       /**< Total Number of NPEs */
+} IxDmaNpeId;
+/* @} */
+/**
+ * @defgroup IxDmaAcc IXP400 DMA Access Driver (IxDmaAcc) API
+ *
+ * @brief The public API for the IXP400 IxDmaAcc component
+ *
+ * @{
+ */
+
+/**
+ * @ingroup IxDmaAcc
+ * @brief DMA Request Id type
+ */
+typedef UINT32 IxDmaAccRequestId;
+
+/**
+ * @ingroup IxDmaAcc
+ * @def IX_DMA_REQUEST_FULL
+ * @brief DMA request queue is full
+ * This constant is a return value used to tell the user that the IxDmaAcc
+ * queue is full.
+ *
+ */
+#define IX_DMA_REQUEST_FULL 16
+
+/**
+ * @ingroup	IxDmaAcc
+ * @brief       DMA completion notification
+ * This function is called to notify a client that the DMA has been completed
+ * @param status @ref IxDmaReturnStatus [out] - reporting to client
+ *
+ */
+typedef void (*IxDmaAccDmaCompleteCallback) (IxDmaReturnStatus status);
+
+/**
+ * @ingroup	IxDmaAcc
+ * 
+ * @fn ixDmaAccInit(IxNpeDlNpeId npeId)
+ * 
+ * @brief	Initialise the DMA Access component
+ * This function will initialise the DMA Access component internals
+ * @param npeId @ref IxNpeDlNpeId [in] - NPE to use for Dma Transfer
+ * @return @li IX_SUCCESS succesfully initialised the component
+ * @return @li IX_FAIL Initialisation failed for some unspecified
+ * internal reason.
+ */
+PUBLIC IX_STATUS
+ixDmaAccInit(IxNpeDlNpeId npeId);
+
+/**
+ * @ingroup	IxDmaAcc
+ * 
+ * @fn ixDmaAccDmaTransfer(
+    IxDmaAccDmaCompleteCallback callback,
+    UINT32 SourceAddr,
+    UINT32 DestinationAddr,
+    UINT16 TransferLength,
+    IxDmaTransferMode TransferMode,
+    IxDmaAddressingMode AddressingMode,
+    IxDmaTransferWidth TransferWidth)
+ *
+ * @brief       Perform DMA transfer
+ * This function will perform DMA transfer between devices within the
+ * IXP400 memory map.
+ * @note The following are restrictions for IxDmaAccDmaTransfer:
+ *      @li The function is non re-entrant.
+ *      @li The function assumes host devices are operating in big-endian mode.
+ *      @li Fixed address does not suport burst transfer width
+ *      @li Fixed source address to fixed destinatiom address mode is not suported
+ *      @li The incrementing source address for expansion bus will not support a burst transfer width and copy and clear mode
+ *
+ * @param callback @ref IxDmaAccDmaCompleteCallback [in] - function pointer to be stored and called when the DMA transfer is completed. This cannot be NULL.
+ * @param SourceAddr UINT32 [in] -	Starting address of DMA source. Must be a valid IXP400 memory map address.
+ * @param DestinationAddr UINT32 [in] - Starting address of DMA destination. Must be a valid IXP400 memory map address.
+ * @param TransferLength UINT16 [in] - The size of DMA data transfer. The range must be from 1-64Kbyte
+ * @param TransferMode @ref IxDmaTransferMode [in] - The DMA transfer mode
+ * @param AddressingMode @ref IxDmaAddressingMode [in] - The DMA addressing mode
+ * @param TransferWidth	@ref IxDmaTransferWidth [in] - The DMA transfer width
+ *
+ * @return @li IX_DMA_SUCCESS	Notification that the DMA request is succesful
+ * @return @li IX_DMA_FAIL	IxDmaAcc not yet initialised or some internal error has occured
+ * @return @li IX_DMA_INVALID_TRANSFER_WIDTH Transfer width is nit valid
+ * @return @li IX_DMA_INVALID_TRANSFER_LENGTH Transfer length outside of valid range
+ * @return @li IX_DMA_INVALID_TRANSFER_MODE Transfer Mode not valid
+ * @return @li IX_DMA_REQUEST_FIFO_FULL IxDmaAcc request queue is full
+ */
+PUBLIC IxDmaReturnStatus
+ixDmaAccDmaTransfer(
+    IxDmaAccDmaCompleteCallback callback,
+    UINT32 SourceAddr,
+    UINT32 DestinationAddr,
+    UINT16 TransferLength,
+    IxDmaTransferMode TransferMode,
+    IxDmaAddressingMode AddressingMode,
+    IxDmaTransferWidth TransferWidth);
+/**
+ * @ingroup IxDmaAcc
+ *
+ * @fn ixDmaAccShow(void)
+ *
+ * @brief Display some component information for debug purposes
+ * Show some internal operation information relating to the DMA service.
+ * At a minimum the following will show.
+ * - the number of the DMA pend (in queue)
+ * @param None
+ * @return @li None
+ */
+PUBLIC IX_STATUS
+ixDmaAccShow(void);
+
+#endif /* IXDMAACC_H */
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthAcc.h b/marvell/uboot/drivers/net/npe/include/IxEthAcc.h
new file mode 100644
index 0000000..cc7e010
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthAcc.h
@@ -0,0 +1,2488 @@
+/** @file    IxEthAcc.h
+ *
+ * @brief this file contains the public API of @ref IxEthAcc component
+ *
+ * Design notes:
+ * The IX_OSAL_MBUF address is to be specified on bits [31-5] and must 
+ * be cache aligned (bits[4-0] cleared)
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ *
+ */
+
+#ifndef IxEthAcc_H
+#define IxEthAcc_H
+
+#include <IxOsBuffMgt.h>
+#include <IxTypes.h>
+
+/**
+ * @defgroup IxEthAcc IXP400 Ethernet Access (IxEthAcc) API
+ *
+ * @brief ethAcc is a library that does provides access to the internal IXP400 10/100Bt Ethernet MACs.
+ *
+ *@{
+ */
+
+/**
+ * @ingroup IxEthAcc
+ * @brief Definition of the Ethernet Access status
+ */
+typedef enum /* IxEthAccStatus */
+{
+    IX_ETH_ACC_SUCCESS = IX_SUCCESS, /**< return success*/
+    IX_ETH_ACC_FAIL = IX_FAIL, /**< return fail*/
+    IX_ETH_ACC_INVALID_PORT, /**< return invalid port*/
+    IX_ETH_ACC_PORT_UNINITIALIZED, /**< return uninitialized*/
+    IX_ETH_ACC_MAC_UNINITIALIZED, /**< return MAC uninitialized*/
+    IX_ETH_ACC_INVALID_ARG, /**< return invalid arg*/
+    IX_ETH_TX_Q_FULL, /**< return tx queue is full*/
+    IX_ETH_ACC_NO_SUCH_ADDR /**< return no such address*/
+} IxEthAccStatus;
+
+/**
+ * @ingroup IxEthAcc
+ * @enum IxEthAccPortId
+ * @brief Definition of the IXP400 Mac Ethernet device.
+ */
+typedef enum  
+{
+	IX_ETH_PORT_1 = 0, /**< Ethernet Port 1 */
+	IX_ETH_PORT_2 = 1  /**< Ethernet port 2 */
+	,IX_ETH_PORT_3 = 2 /**< Ethernet port 3 */
+} IxEthAccPortId;
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETH_ACC_NUMBER_OF_PORTS
+ *
+ * @brief  Definition of the number of ports
+ *
+ */
+#ifdef __ixp46X
+#define IX_ETH_ACC_NUMBER_OF_PORTS (3)
+#else
+#define IX_ETH_ACC_NUMBER_OF_PORTS (2)
+#endif
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_IEEE803_MAC_ADDRESS_SIZE
+ *
+ * @brief  Definition of the size of the MAC address
+ *
+ */
+#define IX_IEEE803_MAC_ADDRESS_SIZE (6)
+
+
+/**
+ *
+ * @brief Definition of the IEEE 802.3 Ethernet MAC address structure.
+ *
+ * The data should be packed with bytes xx:xx:xx:xx:xx:xx 
+ * @note
+ * The data must be packed in network byte order.
+ */
+typedef struct  
+{
+    UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< MAC address */
+} IxEthAccMacAddr;
+
+/**
+ * @ingroup IxEthAcc
+ * @def IX_ETH_ACC_NUM_TX_PRIORITIES
+ * @brief Definition of the number of transmit priorities
+ * 
+ */
+#define IX_ETH_ACC_NUM_TX_PRIORITIES (8)
+
+/**
+ * @ingroup IxEthAcc
+ * @enum IxEthAccTxPriority
+ * @brief Definition of the relative priority used to transmit a frame
+ * 
+ */
+typedef enum  
+{
+	IX_ETH_ACC_TX_PRIORITY_0 = 0, /**<Lowest Priority submission */
+	IX_ETH_ACC_TX_PRIORITY_1 = 1, /**<submission prority of 1 (0 is lowest)*/
+	IX_ETH_ACC_TX_PRIORITY_2 = 2, /**<submission prority of 2 (0 is lowest)*/
+	IX_ETH_ACC_TX_PRIORITY_3 = 3, /**<submission prority of 3 (0 is lowest)*/
+	IX_ETH_ACC_TX_PRIORITY_4 = 4, /**<submission prority of 4 (0 is lowest)*/
+	IX_ETH_ACC_TX_PRIORITY_5 = 5, /**<submission prority of 5 (0 is lowest)*/
+	IX_ETH_ACC_TX_PRIORITY_6 = 6, /**<submission prority of 6 (0 is lowest)*/
+	IX_ETH_ACC_TX_PRIORITY_7 = 7, /**<Highest priority submission */
+
+	IX_ETH_ACC_TX_DEFAULT_PRIORITY = IX_ETH_ACC_TX_PRIORITY_0 /**< By default send all 
+								 packets with lowest priority */
+} IxEthAccTxPriority;
+
+/**
+ * @ingroup IxEthAcc
+ * @enum IxEthAccRxFrameType
+ * @brief Identify the type of a frame.
+ * 
+ * @sa IX_ETHACC_NE_FLAGS
+ * @sa IX_ETHACC_NE_LINKMASK
+ */
+typedef enum  
+{
+	IX_ETHACC_RX_LLCTYPE = 0x00, /**< 802.3 - 8802, with LLC/SNAP */
+	IX_ETHACC_RX_ETHTYPE = 0x10, /**< 802.3 (Ethernet) without LLC/SNAP */
+	IX_ETHACC_RX_STATYPE = 0x20, /**< 802.11, AP <=> STA */
+	IX_ETHACC_RX_APTYPE  = 0x30  /**< 802.11, AP <=> AP */
+} IxEthAccRxFrameType;
+
+/**
+ * @ingroup IxEthAcc
+ * @enum IxEthAccDuplexMode
+ * @brief Definition to provision the duplex mode of the MAC. 
+ * 
+ */
+typedef enum
+{
+    IX_ETH_ACC_FULL_DUPLEX, /**< Full duplex operation of the MAC */
+    IX_ETH_ACC_HALF_DUPLEX  /**< Half duplex operation of the MAC */
+} IxEthAccDuplexMode;
+
+
+/**
+ * @ingroup IxEthAcc
+ * @struct IxEthAccNe
+ * @brief Definition of service-specific informations.
+ * 
+ * This structure defines the Ethernet service-specific informations
+ * and enable QoS and VLAN features.
+ */
+typedef struct
+{
+    UINT32 ixReserved_next;    /**< reserved for chaining */
+    UINT32 ixReserved_lengths; /**< reserved for buffer lengths */
+    UINT32 ixReserved_data;    /**< reserved for buffer pointer */
+    UINT8  ixDestinationPortId; /**< Destination portId for this packet, if known by NPE */
+    UINT8  ixSourcePortId; /**< Source portId for this packet */
+    UINT16 ixFlags;        /**< BitField of option for this frame */
+    UINT8  ixQoS;          /**< QoS class of the frame */
+    UINT8  ixReserved;     /**< reserved */
+    UINT16 ixVlanTCI;      /**< Vlan TCI */
+    UINT8  ixDestMac[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< Destination MAC address */
+    UINT8  ixSourceMac[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< Source MAC address */
+} IxEthAccNe;
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_PORT_UNKNOWN
+ *
+ * @brief  Contents of the field @a IX_ETHACC_NE_DESTPORTID when no
+ * destination port can be found by the NPE for this frame.
+ *
+ */
+#define IX_ETHACC_NE_PORT_UNKNOWN   (0xff)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_DESTMAC
+ *
+ * @brief The location of the destination MAC address in the Mbuf header.
+ *
+ */
+#define IX_ETHACC_NE_DESTMAC(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixDestMac
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_SOURCEMAC
+ *
+ * @brief The location of the source MAC address in the Mbuf header.
+ *
+ */
+#define IX_ETHACC_NE_SOURCEMAC(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixSourceMac
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_VLANTCI
+ *
+ * @brief The VLAN Tag Control Information associated with this frame
+ * 
+ * The VLAN Tag Control Information associated with this frame. On Rx
+ * path, this field is extracted from the packet header.
+ * On Tx path, the value of this field is inserted in the frame when
+ * the port is configured to insert or replace vlan tags in the 
+ * egress frames.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ */
+#define IX_ETHACC_NE_VLANTCI(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixVlanTCI
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_SOURCEPORTID
+ *
+ * @brief The port where this frame came from.
+ *
+ * The port where this frame came from. This field is set on receive
+ * with the port information. This field is ignored on Transmit path.
+ */
+#define IX_ETHACC_NE_SOURCEPORTID(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixSourcePortId
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_DESTPORTID
+ *
+ * @brief The destination port where this frame should be sent.
+ *
+ * The destination port where this frame should be sent.
+ *
+ * @li In the transmit direction, this field contains the destination port
+ * and is ignored unless @a IX_ETHACC_NE_FLAG_DST is set.
+ * 
+ * @li In the receive direction, this field contains the port where the
+ * destination MAC addresses has been learned. If the destination
+ * MAC address is unknown, then this value is set to the reserved value
+ * @a IX_ETHACC_NE_PORT_UNKNOWN
+ *
+ */
+#define IX_ETHACC_NE_DESTPORTID(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixDestinationPortId
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_QOS
+ *
+ * @brief QualityOfService class (QoS) for this received frame.
+ *
+ */
+#define IX_ETHACC_NE_QOS(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixQoS
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_FLAGS
+ *
+ * @brief Bit Mask of the different flags associated with a frame
+ * 
+ * The flags are the bit-oring combination 
+ * of the following different fields :
+ *
+ *      @li IP flag (Rx @a IX_ETHACC_NE_IPMASK)
+ *      @li Spanning Tree flag (Rx @a IX_ETHACC_NE_STMASK)
+ *      @li Link layer type (Rx and Tx @a IX_ETHACC_NE_LINKMASK)
+ *      @li VLAN Tagged Frame (Rx @a IX_ETHACC_NE_VLANMASK)
+ *      @li New source MAC address (Rx @a IX_ETHACC_NE_NEWSRCMASK)
+ *      @li Multicast flag (Rx @a IX_ETHACC_NE_MCASTMASK)
+ *      @li Broadcast flag (Rx @a IX_ETHACC_NE_BCASTMASK)
+ *      @li Destination port flag (Tx @a IX_ETHACC_NE_PORTMASK)
+ *      @li Tag/Untag Tx frame (Tx @a IX_ETHACC_NE_TAGMODEMASK)
+ *      @li Overwrite destination port (Tx @a IX_ETHACC_NE_PORTOVERMASK)
+ *      @li Filtered frame (Rx @a IX_ETHACC_NE_STMASK)
+ *      @li VLAN Enabled (Rx and Tx @a IX_ETHACC_NE_VLANENABLEMASK)
+ */
+#define IX_ETHACC_NE_FLAGS(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixFlags
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_BCASTMASK
+ *
+ * @brief This mask defines if a received frame is a broadcast frame.
+ *
+ * This mask defines if a received frame is a broadcast frame.
+ * The BCAST flag is set when the destination MAC address of 
+ * a frame is broadcast.
+ *
+ * @sa IX_ETHACC_NE_FLAGS 
+ *
+ */
+#define IX_ETHACC_NE_BCASTMASK      (0x1)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_MCASTMASK
+ *
+ * @brief This mask defines if a received frame is a multicast frame.
+ *
+ * This mask defines if a received frame is a multicast frame.
+ * The MCAST flag is set when the destination MAC address of 
+ * a frame is multicast.
+ *
+ * @sa IX_ETHACC_NE_FLAGS 
+ *
+ */
+#define IX_ETHACC_NE_MCASTMASK      (0x1 << 1)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_IPMASK
+ *
+ * @brief This mask defines if a received frame is a IP frame.
+ *
+ * This mask applies to @a IX_ETHACC_NE_FLAGS and defines if a received 
+ * frame is a IP frame. The IP flag is set on Rx direction, depending on 
+ * the frame contents. The flag is set when the length/type field of a 
+ * received frame is 0x8000.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ *
+ */
+#define IX_ETHACC_NE_IPMASK         (0x1 << 2)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_VLANMASK
+ *
+ * @brief This mask defines if a received frame is VLAN tagged.
+ *
+ * This mask defines if a received frame is VLAN tagged.
+ * When set, the Rx frame is VLAN-tagged and the tag value 
+ * is available thru @a IX_ETHACC_NE_VLANID.
+ * Note that when sending frames which are already tagged
+ * this flag should be set, to avoid inserting another VLAN tag.
+ *
+ * @sa IX_ETHACC_NE_FLAGS 
+ * @sa IX_ETHACC_NE_VLANID
+ *
+ */
+#define IX_ETHACC_NE_VLANMASK       (0x1 << 3)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_LINKMASK
+ *
+ * @brief This mask is the link layer protocol indicator
+ *
+ * This mask applies to @a IX_ETHACC_NE_FLAGS.
+ * It reflects the state of a frame as it exits an NPE on the Rx path
+ * or enters an NPE on the Tx path. Its values are as follows:
+ *      @li 0x00 - IEEE802.3 - 8802 (Rx) / IEEE802.3 - 8802 (Tx)
+ *      @li 0x01 - IEEE802.3 - Ethernet (Rx) / IEEE802.3 - Ethernet (Tx)
+ *      @li 0x02 - IEEE802.11 AP -> STA (Rx) / IEEE802.11 STA -> AP (Tx)
+ *      @li 0x03 - IEEE802.11 AP -> AP (Rx) / IEEE802.11 AP->AP (Tx)
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ *
+ */
+#define IX_ETHACC_NE_LINKMASK       (0x3 << 4)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_STMASK
+ *
+ * @brief This mask defines if a received frame is a Spanning Tree frame.
+ *
+ * This mask applies to @a IX_ETHACC_NE_FLAGS.
+ * On rx direction, it defines if a received if frame is a Spanning Tree frame.
+ * Setting this fkag on transmit direction overrides the port settings 
+ * regarding the VLAN options and 
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ *
+ */
+#define IX_ETHACC_NE_STMASK         (0x1 << 6)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_FILTERMASK
+ *
+ * @brief This bit indicates whether a frame has been filtered by the Rx service.
+ *
+ * This mask applies to @a IX_ETHACC_NE_FLAGS.
+ * Certain frames, which should normally be fully filtered by the NPE to due
+ * the destination MAC address being on the same segment as the Rx port are
+ * still forwarded to the XScale (although the payload is invalid) in order
+ * to learn the MAC address of the transmitting station, if this is unknown.
+ * Normally EthAcc will filter and recycle these framess internally and no
+ * frames with the FILTER bit set will be received by the client.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ *
+ */
+#define IX_ETHACC_NE_FILTERMASK     (0x1 << 7)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_PORTMASK
+ *
+ * @brief This mask defines the rule to transmit a frame
+ *
+ * This mask defines the rule to transmit a frame. When set, a frame
+ * is transmitted to the destination port as set by the macro
+ * @a IX_ETHACC_NE_DESTPORTID. If not set, the destination port 
+ * is searched using the destination MAC address.
+ *
+ * @note This flag is meaningful only for multiport Network Engines.
+ * 
+ * @sa IX_ETHACC_NE_FLAGS 
+ * @sa IX_ETHACC_NE_DESTPORTID
+ *
+ */
+#define IX_ETHACC_NE_PORTOVERMASK   (0x1 << 8)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_TAGMODEMASK
+ *
+ * @brief This mask defines the tagging rules to apply to a transmit frame.
+ *
+ * This mask defines the tagging rules to apply to a transmit frame
+ * regardless of the default setting for a port. When used together 
+ * with @a IX_ETHACC_NE_TAGOVERMASK and when set, the 
+ * frame will be tagged prior to transmission. When not set,
+ * the frame will be untagged prior to transmission. This is accomplished
+ * irrespective of the Egress tagging rules, constituting a per-frame override.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ * @sa IX_ETHACC_NE_TAGOVERMASK 
+ *
+ */
+#define IX_ETHACC_NE_TAGMODEMASK    (0x1 << 9)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_TAGOVERMASK
+ *
+ * @brief This mask defines the rule to transmit a frame
+ *
+ * This mask defines the rule to transmit a frame. When set, the
+ * default transmit rules of a port are overriden.
+ * When not set, the default rules as set by @ref IxEthDB should apply.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ * @sa IX_ETHACC_NE_TAGMODEMASK
+ *
+ */
+#define IX_ETHACC_NE_TAGOVERMASK    (0x1 << 10)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_VLANENABLEMASK
+ *
+ * @brief This mask defines if a frame is a VLAN frame or not
+ *
+ * When set, frames undergo normal VLAN processing on the Tx path
+ * (membership filtering, tagging, tag removal etc). If this flag is
+ * not set, the frame is considered to be a regular non-VLAN frame
+ * and no VLAN processing will be performed.
+ *
+ * Note that VLAN-enabled NPE images will always set this flag in all
+ * Rx frames, and images which are not VLAN enabled will clear this
+ * flag for all received frames.
+ *
+ * @sa IX_ETHACC_NE_FLAGS
+ *
+ */
+#define IX_ETHACC_NE_VLANENABLEMASK (0x1 << 14)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IX_ETHACC_NE_NEWSRCMASK
+ *
+ * @brief This mask defines if a received frame has been learned.
+ *
+ * This mask defines if the source MAC address of a frame is 
+ * already known. If the bit is set, the source MAC address was
+ * unknown to the NPE at the time the frame was received.
+ *
+ * @sa IX_ETHACC_NE_FLAGS 
+ *
+ */
+#define IX_ETHACC_NE_NEWSRCMASK     (0x1 << 15)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @brief This defines the recommanded minimum size of MBUF's submitted
+ * to the frame receive service.
+ *
+ */
+#define IX_ETHACC_RX_MBUF_MIN_SIZE (2048)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @brief This defines the highest MII address of any attached PHYs 
+ * 
+ * The maximum number for PHY address is 31, add on for range checking.
+ *
+ */
+#define IXP425_ETH_ACC_MII_MAX_ADDR   32
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccInit(void)
+ * 
+ * @brief Initializes the IXP400 Ethernet Access Service.
+ * 
+ * @li Reentrant    - no
+ * @li ISR Callable - no
+ * 
+ * This should be called once per module initialization.
+ * @pre
+ *   The NPE must first be downloaded with the required microcode which supports all
+ *   required features.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL	:  Service has failed to initialize.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccInit(void);
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccUnload(void)
+ * 
+ * @brief Unload the Ethernet Access Service.
+ * 
+ * @li Reentrant    - no
+ * @li ISR Callable - no
+ *
+ * @return void 
+ *
+ * <hr>
+ */
+PUBLIC void ixEthAccUnload(void);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortInit( IxEthAccPortId portId)
+ *
+ * @brief Initializes an NPE/Ethernet MAC Port.
+ *
+ * The NPE/Ethernet port initialisation includes the following steps
+ * @li Initialize the NPE/Ethernet MAC hardware.
+ * @li Verify NPE downloaded and operational.
+ * @li The NPE shall be available for usage once this API returns.
+ * @li Verify that the Ethernet port is present before initializing
+ *
+ * @li Reentrant    - no
+ * @li ISR Callable - no
+ *
+ * This should be called once per mac device.
+ * The NPE/MAC shall be in disabled state after init.
+ *
+ * @pre
+ *   The component must be initialized via @a ixEthAccInit
+ *   The NPE must first be downloaded with the required microcode which supports all
+ *   required features.
+ *
+ * Dependant on Services: (Must be initialized before using this service may be initialized)
+ *	ixNPEmh - NPE Message handling service.
+ *	ixQmgr	- Queue Manager component.
+ *
+ * @param portId  @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS: if the ethernet port is not present, a warning is issued.
+ * @li @a IX_ETH_ACC_FAIL : The NPE processor has failed to initialize.
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccPortInit(IxEthAccPortId portId);
+
+
+/*************************************************************************
+
+ #####     ##     #####    ##            #####     ##     #####  #    #
+ #    #   #  #      #     #  #           #    #   #  #      #    #    #
+ #    #  #    #     #    #    #          #    #  #    #     #    ######
+ #    #  ######     #    ######          #####   ######     #    #    #
+ #    #  #    #     #    #    #          #       #    #     #    #    #
+ #####   #    #     #    #    #          #       #    #     #    #    #
+
+*************************************************************************/
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortTxFrameSubmit( 
+    IxEthAccPortId portId,
+    IX_OSAL_MBUF *buffer, 
+    IxEthAccTxPriority priority)
+ * 
+ * @brief This function shall be used to submit MBUFs buffers for transmission on a particular MAC device. 
+ *
+ * When the frame is transmitted, the buffer shall be returned thru the 
+ * callback @a IxEthAccPortTxDoneCallback.
+ *
+ * In case of over-submitting, the order of the frames on the 
+ * network may be modified.
+ *
+ * Buffers shall be not queued for transmission if the port is disabled.
+ * The port can be enabled using @a ixEthAccPortEnable
+ *
+ * 
+ * @li Reentrant    - yes
+ * @li ISR Callable - yes
+ *
+ *
+ * @pre 
+ *  @a ixEthAccPortTxDoneCallbackRegister must be called to register a function to allow this service to
+ *   return the buffer to the calling service. 
+ * 
+ * @note 
+ *  If the buffer submit fails for any reason the user has retained ownership of the buffer.
+ *
+ * @param portId @ref IxEthAccPortId [in] - MAC port ID to transmit Ethernet frame on.
+ * @param buffer @ref IX_OSAL_MBUF [in] - pointer to an MBUF formatted buffer. Chained buffers are supported for transmission.
+ *             Chained packets are not supported and the field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is ignored. 
+ * @param priority @ref IxEthAccTxPriority [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL  : Failed to queue frame for transmission. 
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+
+PUBLIC IxEthAccStatus ixEthAccPortTxFrameSubmit( 
+    IxEthAccPortId portId,
+    IX_OSAL_MBUF *buffer, 
+    IxEthAccTxPriority priority);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @brief Function prototype for Ethernet Tx Buffer Done callback. Registered 
+ *  via @a ixEthAccTxBufferDoneCallbackRegister 
+ * 
+ * This function is called once the previously submitted buffer is no longer required by this service.
+ * It may be returned upon successful transmission of the frame or during the shutdown of 
+ * the port prior to the transmission of a queued frame.
+ * The calling of this registered function is not a guarantee of successful transmission of the buffer.
+ *
+ *  
+ * @li Reentrant    - yes , The user provided function should be reentrant.
+ * @li ISR Callable - yes , The user provided function must be callable from an ISR.
+ *
+ *
+ * <b>Calling Context </b>: 
+ * @par
+ *   This callback is called in the context of the queue manager dispatch loop @a ixQmgrgrDispatcherLoopRun
+ *   within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. 
+ *   The decision is system specific.
+ *
+ * @param callbackTag UINT32 [in] - This tag is that provided when the callback was registered for a particular MAC 
+ * via @a ixEthAccPortTxDoneCallbackRegister. It allows the same callback to be used for multiple MACs.
+ * @param mbuf @ref IX_OSAL_MBUF [in] - Pointer to the Tx mbuf descriptor. 
+ * 
+ * @return void
+ *
+ * @note
+ * The field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is modified by the access layer and reset to NULL.
+ *
+ * <hr>
+ */
+typedef void (*IxEthAccPortTxDoneCallback) ( UINT32 callbackTag, IX_OSAL_MBUF *buffer );
+
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortTxDoneCallbackRegister( IxEthAccPortId portId, 
+					   IxEthAccPortTxDoneCallback txCallbackFn, 
+					   UINT32 callbackTag)
+ *
+ * @brief Register a callback function to allow 
+ * the transmitted buffers to return to the user.
+ * 
+ * This function registers the transmit buffer done function callback for a particular port.
+ *
+ * The registered callback function is called once the previously submitted buffer is no longer required by this service.
+ * It may be returned upon successful transmission of the frame or  shutdown of port prior to submission.
+ * The calling of this registered function is not a guarantee of successful transmission of the buffer.
+ *
+ * If called several times the latest callback shall be registered for a particular port.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - yes
+ *
+ * @pre
+ *	The port must be initialized via @a ixEthAccPortInit
+ *
+ *
+ * @param portId @ref IxEthAccPortId [in] - Register callback for a particular MAC device.
+ * @param txCallbackFn @ref IxEthAccPortTxDoneCallback [in] - Function to be called to return transmit buffers to the user.
+ * @param callbackTag UINT32 [in] -  This tag shall be provided to the callback function.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS 
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortTxDoneCallbackRegister(IxEthAccPortId portId,
+								   IxEthAccPortTxDoneCallback txCallbackFn,
+								   UINT32 callbackTag);
+
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @brief Function prototype for Ethernet Frame Rx callback. Registered via @a ixEthAccPortRxCallbackRegister 
+ * 
+ * It is the responsibility of the user function to free any MBUF's which it receives.
+ *  
+ * @li Reentrant    - yes , The user provided function should be reentrant.
+ * @li ISR Callable - yes , The user provided function must be callable from an ISR.
+ * @par
+ *
+ * This function dispatches frames to the user level
+ * via the provided function. The invocation shall be made for each
+ * frame dequeued from the Ethernet QM queue. The user is required to free any MBUF's 
+ * supplied via this callback. In addition the registered callback must free up MBUF's
+ * from the receive free queue when the port is disabled 
+ * 
+ * If called several times the latest callback shall be registered for a particular port.
+ *
+ * <b>Calling Context </b>: 
+ * @par
+ *   This callback is called in the context of the queue manager dispatch loop @a ixQmgrgrDispatcherLoopRun
+ *   within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. 
+ *   The decision is system specific.
+ *
+ *
+ * @param callbackTag UINT32 [in] - This tag is that provided when the callback was registered for a particular MAC 
+ * via @a ixEthAccPortRxCallbackRegister. It allows the same callback to be used for multiple MACs.
+ * @param mbuf @ref IX_OSAL_MBUF [in] - Pointer to the Rx mbuf header. Mbufs may be chained if 
+ *               the frame length is greater than the supplied mbuf length.
+ * @param reserved [in] - deprecated parameter The information is passed 
+ *      thru the IxEthAccNe header destination port ID field 
+ *      (@sa IX_ETHACC_NE_DESTPORTID). For backward 
+ *      compatibility,the value is equal to IX_ETH_DB_UNKNOWN_PORT (0xff). 
+ * 
+ * @return void
+ *
+ * @note
+ * Buffers may not be filled up to the length supplied in 
+ * @a ixEthAccPortRxFreeReplenish(). The firmware fills
+ * them to the previous 64 bytes boundary. The user has to be aware 
+ * that the length of the received mbufs may be smaller than the length
+ * of the supplied mbufs. 
+ * The mbuf header contains the following modified field
+ * @li @a IX_OSAL_MBUF_PKT_LEN is set in the header of the first mbuf and indicates
+ *  the total frame size
+ * @li @a IX_OSAL_MBUF_MLEN is set each mbuf header and indicates the payload length
+ * @li @a IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR contains a pointer to the next 
+ *     mbuf, or NULL at the end of a chain.
+ * @li @a IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is modified. Its value is reset to NULL
+ * @li @a IX_OSAL_MBUF_FLAGS contains the bit 4 set for a broadcast packet and the bit 5
+ *     set for a multicast packet. Other bits are unmodified.
+ *
+ * <hr>
+ */
+typedef void (*IxEthAccPortRxCallback) (UINT32 callbackTag, IX_OSAL_MBUF *buffer, UINT32 reserved);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @brief Function prototype for Ethernet Frame Rx callback. Registered via @a ixEthAccPortMultiBufferRxCallbackRegister 
+ * 
+ * It is the responsibility of the user function to free any MBUF's which it receives.
+ *  
+ * @li Reentrant    - yes , The user provided function should be reentrant.
+ * @li ISR Callable - yes , The user provided function must be callable from an ISR.
+ * @par
+ *
+ * This function dispatches many frames to the user level
+ * via the provided function. The invocation shall be made for multiple frames
+ * dequeued from the Ethernet QM queue. The user is required to free any MBUF's 
+ * supplied via this callback. In addition the registered callback must free up MBUF's
+ * from the receive free queue when the port is disabled 
+ * 
+ * If called several times the latest callback shall be registered for a particular port.
+ *
+ * <b>Calling Context </b>: 
+ * @par
+ *   This callback is called in the context of the queue manager dispatch loop @a ixQmgrDispatcherLoopRun
+ *   within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. 
+ *   The decision is system specific.
+ *
+ *
+ * @param callbackTag - This tag is that provided when the callback was registered for a particular MAC 
+ * via @a ixEthAccPortMultiBufferRxCallbackRegister. It allows the same callback to be used for multiple MACs.
+ * @param mbuf - Pointer to an array of Rx mbuf headers. Mbufs 
+ *               may be chained if 
+ *               the frame length is greater than the supplied mbuf length.
+ *               The end of the array contains a zeroed entry (NULL pointer).
+ *
+ * @return void
+ *
+ * @note The mbufs passed to this callback have the same structure than the
+ *  buffers passed to @a IxEthAccPortRxCallback interfac. 
+ *
+ * @note The usage of this callback is exclusive with the usage of
+ *  @a ixEthAccPortRxCallbackRegister and @a IxEthAccPortRxCallback 
+ *
+ * @sa ixEthAccPortMultiBufferRxCallbackRegister
+ * @sa IxEthAccPortMultiBufferRxCallback
+ * @sa ixEthAccPortRxCallbackRegister
+ * @sa IxEthAccPortRxCallback
+ * <hr>
+ */
+
+typedef void (*IxEthAccPortMultiBufferRxCallback) (UINT32 callbackTag, IX_OSAL_MBUF **buffer);
+
+
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortRxCallbackRegister( IxEthAccPortId portId, IxEthAccPortRxCallback rxCallbackFn, UINT32 callbackTag)
+ *
+ * @brief Register a callback function to allow 
+ * the reception of frames.
+ *
+ * The registered callback function is called once a frame is received  by this service.
+ *
+ * If called several times the latest callback shall be registered for a particular port.
+ *
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - yes
+ *
+ *
+ * @param portId @ref IxEthAccPortId [in] - Register callback for a particular MAC device.
+ * @param rxCallbackFn @ref IxEthAccPortRxCallback [in] - Function to be called when Ethernet frames are availble.
+ * @param callbackTag UINT32 [in] -  This tag shall be provided to the callback function.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS 
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortRxCallbackRegister(IxEthAccPortId portId,
+							   IxEthAccPortRxCallback rxCallbackFn,
+							   UINT32 callbackTag);
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortMultiBufferRxCallbackRegister( IxEthAccPortId portId, IxEthAccPortMultiBufferRxCallback rxCallbackFn, UINT32 callbackTag)
+ *
+ * @brief Register a callback function to allow 
+ * the reception of frames.
+ * 
+ * The registered callback function is called once a frame is 
+ * received  by this service. If many frames are already received, 
+ * the function is called once.
+ *
+ * If called several times the latest callback shall be registered for a particular port.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - yes
+ *
+ *
+ * @param portId - Register callback for a particular MAC device.
+ * @param rxCallbackFn - @a IxEthAccMultiBufferRxCallbackFn - Function to be called when Ethernet frames are availble.
+ * @param callbackTag -  This tag shall be provided to the callback function.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS 
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid.
+ *
+ * @sa ixEthAccPortMultiBufferRxCallbackRegister
+ * @sa IxEthAccPortMultiBufferRxCallback
+ * @sa ixEthAccPortRxCallbackRegister
+ * @sa IxEthAccPortRxCallback
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortMultiBufferRxCallbackRegister(IxEthAccPortId portId,
+										  IxEthAccPortMultiBufferRxCallback rxCallbackFn,
+										  UINT32 callbackTag);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortRxFreeReplenish( IxEthAccPortId portId, IX_OSAL_MBUF *buffer)
+ *
+ * @brief This function provides buffers for the Ethernet receive path. 
+ *
+ * This component does not have a buffer management mechanisms built in. All Rx buffers must be supplied to it
+ * via this interface. 
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - yes
+ *
+ * @param portId @ref IxEthAccPortId [in] - Provide buffers only to specific Rx MAC. 
+ * @param buffer @ref IX_OSAL_MBUF [in] - Provide an MBUF to the Ethernet receive mechanism. 
+ *                 Buffers size smaller than IX_ETHACC_RX_MBUF_MIN_SIZE may result in poor
+ *                 performances and excessive buffer chaining. Buffers
+ *                 larger than this size may be suitable for jumbo frames.
+ *                 Chained packets are not supported and the field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR must be NULL. 
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : Buffer has was not able to queue the 
+ *                     buffer in the receive service.
+ * @li @a IX_ETH_ACC_FAIL : Buffer size is less than IX_ETHACC_RX_MBUF_MIN_SIZE
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * @note
+ * If the buffer replenish operation fails it is the responsibility 
+ * of the user to free the buffer.
+ *
+ * @note
+ * Sufficient buffers must be supplied to the component to maintain
+ * receive throughput and avoid rx buffer underflow conditions.
+ * To meet this goal, It is expected that the user preload the 
+ * component with a sufficent number of buffers prior to enabling the
+ * NPE Ethernet receive path. The recommended minimum number of 
+ * buffers is 8.
+ *
+ * @note
+ * For maximum performances, the mbuf size should be greater 
+ * than the maximum frame size (Ethernet header, payload and FCS) + 64. 
+ * Supplying smaller mbufs to the service results in mbuf
+ * chaining and degraded performances. The recommended size
+ * is @a IX_ETHACC_RX_MBUF_MIN_SIZE, which is
+ * enough to take care of 802.3 frames and "baby jumbo" frames without
+ * chaining, and "jumbo" frame within chaining.
+ *
+ * @note
+ * Buffers may not be filled up to their length. The firware fills
+ * them up to the previous 64 bytes boundary. The user has to be aware 
+ * that the length of the received mbufs may be smaller than the length
+ * of the supplied mbufs.
+ *
+ * @warning This function checks the parameters if the NDEBUG 
+ * flag is not defined. Turning on the argument checking (disabled by 
+ * default) results in a lower EthAcc performance as this function
+ * is part of the data path.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortRxFreeReplenish( IxEthAccPortId portId, IX_OSAL_MBUF *buffer);
+
+
+
+/***************************************************************
+
+  ####    ####   #    #   #####  #####    ####   #
+ #    #  #    #  ##   #     #    #    #  #    #  #
+ #       #    #  # #  #     #    #    #  #    #  #
+ #       #    #  #  # #     #    #####   #    #  #
+ #    #  #    #  #   ##     #    #   #   #    #  #
+  ####    ####   #    #     #    #    #   ####   ######
+
+
+         #####   #         ##    #    #  ######
+         #    #  #        #  #   ##   #  #
+         #    #  #       #    #  # #  #  #####
+         #####   #       ######  #  # #  #
+         #       #       #    #  #   ##  #
+         #       ######  #    #  #    #  ######
+
+***************************************************************/
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortEnable(IxEthAccPortId portId)
+ *
+ * @brief This enables an Ethernet port for both Tx and Rx. 
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @pre The port must first be initialized via @a ixEthAccPortInit and the MAC address 
+ * must be set using @a ixEthAccUnicastMacAddressSet before enabling it
+ * The rx and Tx Done callbacks registration via @a
+ * ixEthAccPortTxDoneCallbackRegister amd @a  ixEthAccPortRxCallbackRegister
+ * has to be done before enabling the traffic.
+ * 
+ * @param  portId @ref IxEthAccPortId [in] - Port id to act upon.
+ * 
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS 
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is not initialized
+ * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccPortEnable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortDisable(IxEthAccPortId portId)
+ *
+ * @brief This disables an Ethernet port for both Tx and Rx. 
+ *
+ * Free MBufs are returned to the user via the registered callback when the port is disabled 
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @pre The port must be enabled with @a ixEthAccPortEnable, otherwise this
+ * function has no effect
+ *
+ * @param  portId @ref IxEthAccPortId [in] - Port id to act upon.
+ * 
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS 
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is not initialized
+ * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccPortDisable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled)
+ *
+ * @brief Get the enabled state of a port.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - yes
+ *
+ * @pre The port must first be initialized via @a ixEthAccPortInit
+ *
+ * @param  portId @ref IxEthAccPortId [in] - Port id to act upon.
+ * @param  enabled BOOL [out] - location to store the state of the port
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId)
+ *
+ * @brief Put the Ethernet MAC device in non-promiscuous mode.
+ * 
+ * In non-promiscuous mode the MAC filters all frames other than 
+ * destination MAC address which matches the following criteria:
+ * @li Unicast address provisioned via @a ixEthAccUnicastMacAddressSet
+ * @li All broadcast frames.
+ * @li Multicast addresses provisioned via @a ixEthAccMulticastAddressJoin
+ *
+ * Other functions modify the MAC filtering
+ *
+ * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast
+ *     frames are forwarded to the application
+ * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the
+ *     effects of @a ixEthAccPortMulticastAddressJoinAll()
+ * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new 
+ *     filtering address
+ * @li @a ixEthAccPortMulticastAddressJoin() - provision a new 
+ *     filtering address
+ * @li @a ixEthAccPortPromiscuousModeSet() - all frames are 
+ *     forwarded to the application regardless of the multicast 
+ *     address provisioned
+ * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded 
+ *     to the application following the multicast address provisioned
+ *
+ * In all cases, unicast and broadcast addresses are forwarded to 
+ * the application.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ * 
+ * @sa ixEthAccPortPromiscuousModeSet
+ * 
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ * 
+ * @return IxEthAccStatus 
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId);
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn  ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId)
+ *
+ * @brief Put the MAC device in promiscuous mode.
+ * 
+ * If the device is in promiscuous mode then all all received frames shall be forwared
+ * to the NPE for processing.
+ *
+ * Other functions modify the MAC filtering
+ *
+ * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast
+ *     frames are forwarded to the application
+ * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the
+ *     effects of @a ixEthAccPortMulticastAddressJoinAll()
+ * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new 
+ *     filtering address
+ * @li @a ixEthAccPortMulticastAddressJoin() - provision a new 
+ *     filtering address
+ * @li @a ixEthAccPortPromiscuousModeSet() - all frames are 
+ *     forwarded to the application regardless of the multicast 
+ *     address provisioned
+ * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded 
+ *     to the application following the multicast address provisioned
+ *
+ * In all cases, unicast and broadcast addresses are forwarded to 
+ * the application.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ * 
+ * @sa ixEthAccPortPromiscuousModeClear
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ * 
+ * @return IxEthAccStatus 
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortUnicastMacAddressSet(      IxEthAccPortId portId,
+                                                  IxEthAccMacAddr *macAddr)
+ *
+ * @brief Configure unicast MAC address for a particular port
+ *
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address.
+ *
+ * @return IxEthAccStatus 
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressSet(IxEthAccPortId portId,
+													   IxEthAccMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortUnicastMacAddressGet(	IxEthAccPortId portId, 
+					IxEthAccMacAddr *macAddr)
+ *
+ * @brief Get unicast MAC address for a particular MAC port 
+ *
+ * @pre
+ * The MAC address must first be set via @a ixEthAccMacPromiscuousModeSet
+ * If the MAC address has not been set, the function returns a 
+ * IX_ETH_ACC_MAC_UNINITIALIZED status
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ * @param *macAddr @ref IxEthAccMacAddr [out] - Ethernet MAC address.
+ *
+ * @return  IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized.
+ * @li @a IX_ETH_ACC_FAIL : macAddr is invalid.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortUnicastMacAddressGet(IxEthAccPortId portId,
+								 IxEthAccMacAddr *macAddr);
+
+
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortMulticastAddressJoin(      IxEthAccPortId portId,
+                                             IxEthAccMacAddr *macAddr)
+ *
+ * @brief Add a multicast address to the MAC address table.
+ *
+ *  @note
+ *  Due to the operation of the Ethernet MAC multicast filtering mechanism, frames which do not 
+ *  have a multicast destination address which were provisioned via this API may be forwarded 
+ *  to the NPE's. This is a result of the hardware comparison  algorithm used in the destination mac address logic
+ *  within the Ethernet MAC. 
+ *
+ *  See Also: IXP425 hardware development manual.
+ * 
+ * Other functions modify the MAC filtering
+ *
+ * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast
+ *     frames are forwarded to the application
+ * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the
+ *     effects of @a ixEthAccPortMulticastAddressJoinAll()
+ * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new 
+ *     filtering address
+ * @li @a ixEthAccPortMulticastAddressJoin() - provision a new 
+ *     filtering address
+ * @li @a ixEthAccPortPromiscuousModeSet() - all frames are 
+ *     forwarded to the application regardless of the multicast 
+ *     address provisioned
+ * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded 
+ *     to the application following the multicast address provisioned
+ *
+ * In all cases, unicast and broadcast addresses are forwarded to 
+ * the application.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address.
+ *
+ * @return IxEthAccStatus 
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : Error writing to the MAC registers
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressJoin(IxEthAccPortId portId,
+								 IxEthAccMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortMulticastAddressJoinAll(  IxEthAccPortId portId)
+ *
+ * @brief Filter all frames with multicast dest.
+ *
+ * This function clears the MAC address table, and then sets
+ * the MAC to forward ALL multicast frames to the NPE.
+ * Specifically, it forwards all frames whose destination address
+ * has the LSB of the highest byte set  (01:00:00:00:00:00).  This
+ * bit is commonly referred to as the "multicast bit".
+ * Broadcast frames will still be forwarded. 
+ *
+ * Other functions modify the MAC filtering
+ *
+ * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast
+ *     frames are forwarded to the application
+ * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the
+ *     effects of @a ixEthAccPortMulticastAddressJoinAll()
+ * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new 
+ *     filtering address
+ * @li @a ixEthAccPortMulticastAddressJoin() - provision a new 
+ *     filtering address
+ * @li @a ixEthAccPortPromiscuousModeSet() - all frames are 
+ *     forwarded to the application regardless of the multicast 
+ *     address provisioned
+ * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded 
+ *     to the application following the multicast address provisioned
+ *
+ * In all cases, unicast and broadcast addresses are forwarded to 
+ * the application.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ *
+ * @return IxEthAccStatus 
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressJoinAll(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortMulticastAddressLeave( IxEthAccPortId portId,
+                                         IxEthAccMacAddr *macAddr)
+ *
+ * @brief Remove a multicast address from the MAC address table.
+ *
+ * Other functions modify the MAC filtering
+ *
+ * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast
+ *     frames are forwarded to the application
+ * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the
+ *     effects of @a ixEthAccPortMulticastAddressJoinAll()
+ * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new 
+ *     filtering address
+ * @li @a ixEthAccPortMulticastAddressJoin() - provision a new 
+ *     filtering address
+ * @li @a ixEthAccPortPromiscuousModeSet() - all frames are 
+ *     forwarded to the application regardless of the multicast 
+ *     address provisioned
+ * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded 
+ *     to the application following the multicast address provisioned
+ *
+ * In all cases, unicast and broadcast addresses are forwarded to 
+ * the application.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_NO_SUCH_ADDR :  Failed if MAC address was not in the table.
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressLeave(IxEthAccPortId portId,
+								  IxEthAccMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortMulticastAddressLeaveAll( IxEthAccPortId portId)
+ *
+ * @brief This function unconfigures the multicast filtering settings
+ *
+ * This function first clears the MAC address table, and then sets
+ * the MAC as configured by the promiscuous mode current settings.
+ *
+ * Other functions modify the MAC filtering
+ *
+ * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast
+ *     frames are forwarded to the application
+ * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the
+ *     effects of @a ixEthAccPortMulticastAddressJoinAll()
+ * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new 
+ *     filtering address
+ * @li @a ixEthAccPortMulticastAddressJoin() - provision a new 
+ *     filtering address
+ * @li @a ixEthAccPortPromiscuousModeSet() - all frames are 
+ *     forwarded to the application regardless of the multicast 
+ *     address provisioned
+ * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded 
+ *     to the application following the multicast address provisioned
+ *
+ * In all cases, unicast and broadcast addresses are forwarded to 
+ * the application.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortMulticastAddressLeaveAll(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortUnicastAddressShow(IxEthAccPortId portId)
+ *
+ * @brief Displays unicast MAC address
+ *
+ * Displays unicast address which is configured using 
+ * @a ixEthAccUnicastMacAddressSet. This function also displays the MAC filter used
+ * to filter multicast frames.
+ *
+ * Other functions modify the MAC filtering
+ *
+ * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast
+ *     frames are forwarded to the application
+ * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the
+ *     effects of @a ixEthAccPortMulticastAddressJoinAll()
+ * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new 
+ *     filtering address
+ * @li @a ixEthAccPortMulticastAddressJoin() - provision a new 
+ *     filtering address
+ * @li @a ixEthAccPortPromiscuousModeSet() - all frames are 
+ *     forwarded to the application regardless of the multicast 
+ *     address provisioned
+ * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded 
+ *     to the application following the multicast address provisioned
+ *
+ * In all cases, unicast and broadcast addresses are forwarded to 
+ * the application.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ *
+ * @return void
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccPortUnicastAddressShow(IxEthAccPortId portId);
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortMulticastAddressShow( IxEthAccPortId portId)
+ *
+ * @brief Displays multicast MAC address
+ *
+ * Displays multicast address which have been configured using @a ixEthAccMulticastAddressJoin
+ * 
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ * 
+ * @param portId @ref IxEthAccPortId [in] - Ethernet port id.
+ *
+ * @return void
+ *
+ * <hr>
+ */
+PUBLIC void ixEthAccPortMulticastAddressShow( IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortDuplexModeSet( IxEthAccPortId portId, IxEthAccDuplexMode mode )
+ *
+ * @brief  Set the duplex mode for the MAC.
+ *
+ * Configure the IXP400 MAC to either full or half duplex. 
+ *
+ * @note 
+ * The configuration should match that provisioned on the PHY.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ * @param mode @ref IxEthAccDuplexMode [in]
+ *
+ * @return IxEthAccStatus 
+ * @li @a IX_ETH_ACC_SUCCESS 
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus 
+ixEthAccPortDuplexModeSet(IxEthAccPortId portId,IxEthAccDuplexMode mode);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortDuplexModeGet( IxEthAccPortId portId, IxEthAccDuplexMode *mode )
+ *
+ * @brief  Get the duplex mode for the MAC.
+ *
+ * return the duplex configuration of the IXP400 MAC.
+ *
+ * @note
+ * The configuration should match that provisioned on the PHY.
+ * See @a ixEthAccDuplexModeSet
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ * @param *mode @ref IxEthAccDuplexMode [out]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS 
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ *
+ */
+PUBLIC IxEthAccStatus 
+ixEthAccPortDuplexModeGet(IxEthAccPortId portId,IxEthAccDuplexMode *mode );
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortTxFrameAppendPaddingEnable( IxEthAccPortId portId)
+ *
+ * @brief  Enable padding bytes to be appended to runt frames submitted to
+ * this port
+ * 
+ * Enable up to 60 null-bytes padding bytes to be appended to runt frames 
+ * submitted to this port. This is the default behavior of the access 
+ * component.
+ *
+ * @warning Do not change this behaviour while the port is enabled.
+ *
+ * @note When Tx padding is enabled, Tx FCS generation is turned on
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @sa ixEthAccPortTxFrameAppendFCSDusable
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS 
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendPaddingEnable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortTxFrameAppendPaddingDisable( IxEthAccPortId portId)
+ *
+ * @brief  Disable padding bytes to be appended to runt frames submitted to
+ * this port
+ * 
+ * Disable padding bytes to be appended to runt frames 
+ * submitted to this port. This is not the default behavior of the access 
+ * component.
+ *
+ * @warning Do not change this behaviour while the port is enabled.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] 
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS 
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendPaddingDisable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortTxFrameAppendFCSEnable( IxEthAccPortId portId)
+ *
+ * @brief  Enable the appending of Ethernet FCS to all frames submitted to this port
+ * 
+ * When enabled, the FCS is added to the submitted frames. This is the default 
+ * behavior of the access component.
+ * Do not change this behaviour while the port is enabled.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in] 
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS 
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendFCSEnable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortTxFrameAppendFCSDisable( IxEthAccPortId portId)
+ *
+ * @brief  Disable the appending of Ethernet FCS to all frames submitted to this port.
+ * 
+ * When disabled, the Ethernet FCS is not added to the submitted frames. 
+ * This is not the default
+ * behavior of the access component.
+ *
+ * @note Since the FCS is not appended to the frame it is expected that the frame submitted to the 
+ * component includes a valid FCS at the end of the data, although this will not be validated.
+ *
+ * The component shall forward the frame to the Ethernet MAC WITHOUT modification.
+ *
+ * Do not change this behaviour while the port is enabled.
+ *
+ * @note Tx FCS append is not disabled while Tx padding is enabled.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @sa ixEthAccPortTxFrameAppendPaddingEnable
+ *
+ * @param portId @ref IxEthAccPortId [in] 
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS 
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortTxFrameAppendFCSDisable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortRxFrameAppendFCSEnable( IxEthAccPortId portId)
+ *
+ * @brief Forward frames with FCS included in the receive buffer.
+ *
+ * The FCS is not striped from the receive buffer. 
+ * The received frame length includes the FCS size (4 bytes). ie. 
+ * A minimum sized ethernet frame shall have a length of 64bytes.
+ *
+ * Frame FCS validity checks are still carried out on all received frames.
+ *
+ * This is not the default
+ * behavior of the access component.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS 
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortRxFrameAppendFCSEnable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccPortRxFrameAppendFCSDisable( IxEthAccPortId portId)
+ *
+ * @brief  Do not forward the FCS portion of the received Ethernet frame to the user. 
+ * The FCS is striped from the receive buffer. 
+ * The received frame length does not include the FCS size (4 bytes).
+ * Frame FCS validity checks are still carried out on all received frames.
+ *
+ * This is the default behavior of the component.
+ * Do not change this behaviour while the port is enabled.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS 
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccPortRxFrameAppendFCSDisable(IxEthAccPortId portId);
+
+
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @enum IxEthAccSchedulerDiscipline
+ *
+ * @brief  Definition for the port scheduling discipline
+ *
+ * Select the port scheduling discipline on receive and transmit path
+ * @li FIFO : No Priority : In this configuration all frames are processed
+ *                       in the access component in the strict order in which 
+ *                        the component received them.
+ * @li FIFO : Priority : This shall be a very simple priority mechanism. 
+ *                     Higher prior-ity frames shall be forwarded 
+ *                     before lower priority frames. There shall be no 
+ *                     fairness mechanisms applied across different 
+ *                     priorities. Higher priority frames could starve 
+ *                     lower priority frames indefinitely.
+ */
+typedef  enum 
+{
+    FIFO_NO_PRIORITY, /**<frames submitted with no priority*/
+    FIFO_PRIORITY /**<higher prority frames submitted before lower priority*/
+}IxEthAccSchedulerDiscipline;
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def IxEthAccTxSchedulerDiscipline
+ *
+ * @brief  Deprecated definition for the port transmit scheduling discipline
+ */ 
+#define IxEthAccTxSchedulerDiscipline IxEthAccSchedulerDiscipline
+
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccTxSchedulingDisciplineSet( IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched)
+ *
+ * @brief Set the port scheduling to one of @a IxEthAccSchedulerDiscipline
+ *
+ * The default behavior of the component is @a FIFO_NO_PRIORITY.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ *
+ * @param portId @ref IxEthAccPortId [in] 
+ * @param sched @ref IxEthAccSchedulerDiscipline [in] 
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : Set appropriate discipline.
+ * @li @a IX_ETH_ACC_FAIL :  Invalid/unsupported discipline.
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccTxSchedulingDisciplineSet(IxEthAccPortId portId, 
+								  IxEthAccSchedulerDiscipline sched);
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched)
+ *
+ * @brief Set the Rx scheduling to one of @a IxEthAccSchedulerDiscipline
+ *
+ * The default behavior of the component is @a FIFO_NO_PRIORITY.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @param sched : @a IxEthAccSchedulerDiscipline 
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : Set appropriate discipline.
+ * @li @a IX_ETH_ACC_FAIL :  Invalid/unsupported discipline.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn IxEthAccStatus ixEthAccNpeLoopbackEnable(IxEthAccPortId portId)
+ *
+ * @brief Enable NPE loopback
+ *
+ * When this loopback mode is enabled all the transmitted frames are
+ * received on the same port, without payload.
+ *
+ * This function is recommended for power-up diagnostic checks and
+ * should never be used under normal Ethernet traffic operations.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @param portId : ID of the port 
+ *
+ * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is
+ * guaranteed to restore correct Ethernet Tx/Rx operation.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : NPE loopback mode enabled
+ * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus 
+ixEthAccPortNpeLoopbackEnable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn IxEthAccStatus ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId)
+ *
+ * @brief Disable NPE loopback
+ *
+ * This function is used to disable the NPE loopback if previously
+ * enabled using ixEthAccNpeLoopbackEnable.
+ *
+ * This function is recommended for power-up diagnostic checks and
+ * should never be used under normal Ethernet traffic operations.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is
+ * guaranteed to restore correct Ethernet Tx/Rx operation.
+ *
+ * @param portId : ID of the port 
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : NPE loopback successfully disabled
+ * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus 
+ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn IxEthAccStatus ixEthAccPortTxEnable(IxEthAccPortId portId)
+ *
+ * @brief Enable Tx on the port
+ *
+ * This function is the complement of ixEthAccPortTxDisable and should
+ * be used only after Tx was disabled. A MAC core reset is required before
+ * this function is called (see @a ixEthAccPortMacReset).
+ *
+ * This function is the recommended usage scenario for emergency security
+ * shutdown and hardware failure recovery and should never be used for throttling 
+ * traffic.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is
+ * guaranteed to restore correct Ethernet Tx/Rx operation.
+ *
+ * @param portId : ID of the port 
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : Tx successfully enabled
+ * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus 
+ixEthAccPortTxEnable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn IxEthAccStatus ixEthAccPortTxDisable(IxEthAccPortId portId)
+ *
+ * @brief Disable Tx on the port
+ *
+ * This function can be used to disable Tx in the MAC core.
+ * Tx can be re-enabled, although this is not guaranteed, by performing
+ * a MAC core reset (@a ixEthAccPortMacReset) and calling ixEthAccPortTxEnable.
+ * Note that using this function is not recommended, except for shutting
+ * down Tx for emergency reasons. For proper port shutdown and re-enabling
+ * see ixEthAccPortEnable and ixEthAccPortDisable.
+ *
+ * This function is the recommended usage scenario for emergency security
+ * shutdown and hardware failure recovery and should never be used for throttling 
+ * traffic.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is
+ * guaranteed to restore correct Ethernet Tx/Rx operation.
+ *
+ * @pre
+ *
+ * @param portId : ID of the port 
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : Tx successfully disabled
+ * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus 
+ixEthAccPortTxDisable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn IxEthAccStatus ixEthAccPortRxEnable(IxEthAccPortId portId)
+ *
+ * @brief Enable Rx on the port
+ *
+ * This function is the complement of ixEthAccPortRxDisable and should
+ * be used only after Rx was disabled.
+ *
+ * This function is the recommended usage scenario for emergency security
+ * shutdown and hardware failure recovery and should never be used for throttling 
+ * traffic.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is
+ * guaranteed to restore correct Ethernet Tx/Rx operation.
+ *
+ * @pre
+ *
+ * @param portId : ID of the port 
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : Rx successfully enabled
+ * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus 
+ixEthAccPortRxEnable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn IxEthAccStatus ixEthAccPortRxDisable(IxEthAccPortId portId)
+ *
+ * @brief Disable Rx on the port
+ *
+ * This function can be used to disable Rx in the MAC core.
+ * Rx can be re-enabled, although this is not guaranteed, by performing
+ * a MAC core reset (@a ixEthAccPortMacReset) and calling ixEthAccPortRxEnable.
+ * Note that using this function is not recommended, except for shutting
+ * down Rx for emergency reasons. For proper port shutdown and re-enabling
+ * see ixEthAccPortEnable and ixEthAccPortDisable.
+ *
+ * This function is the recommended usage scenario for emergency security
+ * shutdown and hardware failure recovery and should never be used for throttling 
+ * traffic.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is
+ * guaranteed to restore correct Ethernet Tx/Rx operation.
+ *
+ * @param portId : ID of the port 
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : Rx successfully disabled
+ * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus 
+ixEthAccPortRxDisable(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn IxEthAccStatus ixEthAccPortMacReset(IxEthAccPortId portId)
+ *
+ * @brief Reset MAC core on the port
+ *
+ * This function will perform a MAC core reset (NPE Ethernet coprocessor).
+ * This function is inherently unsafe and the NPE recovery is not guaranteed
+ * after this function is called. The proper manner of performing port disable
+ * and enable (which will reset the MAC as well) is ixEthAccPortEnable/ixEthAccPortDisable.
+ *
+ * This function is the recommended usage scenario for hardware failure recovery
+ * and should never be used for throttling traffic.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is
+ * guaranteed to restore correct Ethernet Tx/Rx operation.
+ *
+ * @param portId : ID of the port 
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS : MAC core reset
+ * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus 
+ixEthAccPortMacReset(IxEthAccPortId portId);
+
+/*********************************************************************************
+  ####    #####    ##     #####     #     ####    #####     #     ####    ####
+ #          #     #  #      #       #    #          #       #    #    #  #
+  ####      #    #    #     #       #     ####      #       #    #        ####
+      #     #    ######     #       #         #     #       #    #            #
+ #    #     #    #    #     #       #    #    #     #       #    #    #  #    #
+  ####      #    #    #     #       #     ####      #       #     ####    ####
+**********************************************************************************/
+
+
+/**
+ *
+ * @brief This struct defines the statistics returned by this component.
+ *
+ * The component returns MIB2 EthObj variables which are obtained from the 
+ * hardware or maintained by this component. 
+ *
+ *
+ */
+typedef struct   
+{
+    UINT32 dot3StatsAlignmentErrors;            /**< link error count (rx) */
+    UINT32 dot3StatsFCSErrors;                  /**< link error count (rx) */
+    UINT32 dot3StatsInternalMacReceiveErrors;   /**< link error count (rx) */
+    UINT32 RxOverrunDiscards;                   /**< NPE: discarded frames count (rx) */
+    UINT32 RxLearnedEntryDiscards;                /**< NPE: discarded frames count(rx)  */
+    UINT32 RxLargeFramesDiscards;                 /**< NPE: discarded frames count(rx)  */
+    UINT32 RxSTPBlockedDiscards;                  /**< NPE: discarded frames count(rx)  */
+    UINT32 RxVLANTypeFilterDiscards;              /**< NPE: discarded frames count (rx) */
+    UINT32 RxVLANIdFilterDiscards;                /**< NPE: discarded frames count (rx) */
+    UINT32 RxInvalidSourceDiscards;               /**< NPE: discarded frames count (rx) */
+    UINT32 RxBlackListDiscards;                   /**< NPE: discarded frames count (rx) */
+    UINT32 RxWhiteListDiscards;                   /**< NPE: discarded frames count (rx) */
+    UINT32 RxUnderflowEntryDiscards;              /**< NPE: discarded frames count (rx) */
+    UINT32 dot3StatsSingleCollisionFrames;      /**< link error count (tx) */
+    UINT32 dot3StatsMultipleCollisionFrames;    /**< link error count (tx) */
+    UINT32 dot3StatsDeferredTransmissions;      /**< link error count (tx) */
+    UINT32 dot3StatsLateCollisions;             /**< link error count (tx) */
+    UINT32 dot3StatsExcessiveCollsions;         /**< link error count (tx) */
+    UINT32 dot3StatsInternalMacTransmitErrors;  /**< link error count (tx) */
+    UINT32 dot3StatsCarrierSenseErrors;         /**< link error count (tx) */
+    UINT32 TxLargeFrameDiscards;                /**< NPE: discarded frames count (tx) */
+    UINT32 TxVLANIdFilterDiscards;              /**< NPE: discarded frames count (tx) */
+
+}IxEthEthObjStats;
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMibIIStatsGet(IxEthAccPortId portId ,IxEthEthObjStats *retStats )
+ *
+ * @brief  Returns the statistics maintained for a port.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ *
+ * @param portId @ref IxEthAccPortId [in] 
+ * @param retStats @ref IxEthEthObjStats [out]
+ * @note Please note the user is responsible for cache coheriency of the retStat
+ * buffer. The data is actually populated via the NPE's. As such cache safe
+ * memory should be used in the retStats argument.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : Invalid arguments.
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccMibIIStatsGet(IxEthAccPortId portId, IxEthEthObjStats *retStats );
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMibIIStatsGetClear(IxEthAccPortId portId, IxEthEthObjStats *retStats)
+ * 
+ * @brief  Returns and clears the statistics maintained for a port. 
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - yes
+ *
+ * @pre
+ *
+ * @param portId @ref IxEthAccPortId [in] 
+ * @param retStats @ref IxEthEthObjStats [out]
+ * @note Please note the user is responsible for cache coheriency of the retStats
+ * buffer. The data is actually populated via the NPE's. As such cache safe
+ * memory should be used in the retStats argument.
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : invalid arguments.
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccMibIIStatsGetClear(IxEthAccPortId portId, IxEthEthObjStats *retStats);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMibIIStatsClear(IxEthAccPortId portId)
+ *
+ * @brief   Clears the statistics maintained for a port.
+ *
+ * @li Reentrant    - yes
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : Invalid arguments.
+ * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid.
+ * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccMibIIStatsClear(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMacInit(IxEthAccPortId portId)
+ * 
+ * @brief Initializes the ethernet MAC settings 
+ * 
+ * @li Reentrant    - no
+ * @li ISR Callable - no
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_INVALID_PORT	:  portId is invalid.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccMacInit(IxEthAccPortId portId);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccStatsShow(IxEthAccPortId portId)
+ *
+ *
+ * @brief Displays a ports statistics on the standard io console using printf.
+ *
+ * @li Reentrant    - no
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @param portId @ref IxEthAccPortId [in]
+ *
+ * @return void
+ *
+ * <hr>
+ */
+PUBLIC void ixEthAccStatsShow(IxEthAccPortId portId);
+
+/*************************************************************************
+
+ #    #     #       #            #    #  #####      #     ####
+ ##  ##     #       #            ##  ##  #    #     #    #    #
+ # ## #     #       #            # ## #  #    #     #    #    #
+ #    #     #       #            #    #  #    #     #    #    #
+ #    #     #       #            #    #  #    #     #    #    #
+ #    #     #       #            #    #  #####      #     ####
+
+*************************************************************************/
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMiiReadRtn (UINT8 phyAddr, 
+                           UINT8 phyReg, 
+	                   UINT16 *value)
+ *
+ *
+ * @brief Reads a 16 bit value from a PHY
+ *
+ * Reads a 16-bit word from a register of a MII-compliant PHY. Reading
+ * is performed through the MII management interface.  This function returns
+ * when the read operation has successfully completed, or when a timeout has elapsed.
+ *
+ * @li Reentrant    - no
+ * @li ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
+ *   
+ * @param phyAddr UINT8 [in] - the address of the Ethernet PHY (0-31)
+ * @param phyReg UINT8 [in] -  the number of the MII register to read (0-31)
+ * @param value UINT16 [in] -  the value read from the register
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : failed to read the register.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccMiiReadRtn (UINT8 phyAddr, UINT8 phyReg, UINT16 *value);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMiiWriteRtn (UINT8 phyAddr, 
+                            UINT8 phyReg, 
+	                    UINT16 value)
+ *
+ *
+ * @brief Writes a 16 bit value to a PHY
+ *
+ * Writes a 16-bit word from a register of a MII-compliant PHY. Writing
+ * is performed through the MII management interface.  This function returns
+ * when the write operation has successfully completed, or when a timeout has elapsed.
+ *
+ * @li Reentrant    - no
+ * @li ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
+ *   
+ * @param phyAddr UINT8 [in] - the address of the Ethernet PHY (0-31)
+ * @param phyReg UINT8 [in] -  the number of the MII register to write (0-31)
+ * @param value UINT16 [out] -  the value to write to the register
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : failed to write register.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccMiiWriteRtn (UINT8 phyAddr, UINT8 phyReg, UINT16 value);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMiiAccessTimeoutSet(UINT32 timeout)
+ *
+ * @brief Overrides the default timeout value and retry count when reading or 
+ * writing MII registers using ixEthAccMiiWriteRtn or ixEthAccMiiReadRtn
+ *
+ * The default behavior of the component is to use a IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS ms
+ * timeout (declared as 100 in IxEthAccMii_p.h) and a retry count of IX_ETH_ACC_MII_TIMEOUT_10TH_SECS
+ * (declared as 5 in IxEthAccMii_p.h).
+ *
+ * The MII read and write functions will attempt to read the status of the register up
+ * to the retry count times, delaying between each attempt with the timeout value.
+ *
+ * @li Reentrant    - no
+ * @li ISR Callable - no
+ *
+ * @pre
+ *
+ * @param timeout UINT32 [in] - new timeout value, in milliseconds
+ * @param timeout UINT32 [in] - new retry count (a minimum value of 1 must be used)
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : invalid parameter(s)
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus
+ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount);
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @fn ixEthAccMiiStatsShow (UINT32 phyAddr)
+ *
+ *
+ * @brief Displays detailed information on a specified PHY
+ *
+ * Displays the current values of the first eigth MII registers for a PHY, 
+ *
+ * @li Reentrant    - no
+ * @li ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and 
+ *      generating the MDIO clock.
+ *   
+ * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
+ *
+ * @return IxEthAccStatus
+ * @li @a IX_ETH_ACC_SUCCESS
+ * @li @a IX_ETH_ACC_FAIL : invalid arguments.
+ *
+ * <hr>
+ */
+PUBLIC IxEthAccStatus ixEthAccMiiStatsShow (UINT32 phyAddr);
+
+
+
+/******* BOARD SPECIFIC DEPRECATED API *********/
+
+/* The following functions are high level functions which rely
+ * on the properties and interface of some Ethernet PHYs. The
+ * implementation is hardware specific and has been moved to 
+ * the hardware-specific component IxEthMii.
+ */
+
+ #include "IxEthMii.h"
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def  ixEthAccMiiPhyScan
+ *
+ * @brief : deprecated API entry point. This definition 
+ * ensures backward compatibility
+ *
+ * See @ref ixEthMiiPhyScan
+ *
+ * @note this feature is board specific
+ *
+ */
+#define ixEthAccMiiPhyScan(phyPresent) ixEthMiiPhyScan(phyPresent,IXP425_ETH_ACC_MII_MAX_ADDR)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def ixEthAccMiiPhyConfig
+ *
+ * @brief : deprecated API entry point. This definition 
+ * ensures backward compatibility
+ *
+ * See @ref ixEthMiiPhyConfig
+ *
+ * @note this feature is board specific
+ */
+#define ixEthAccMiiPhyConfig(phyAddr,speed100,fullDuplex,autonegotiate) \
+           ixEthMiiPhyConfig(phyAddr,speed100,fullDuplex,autonegotiate)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def ixEthAccMiiPhyReset
+ *
+ * @brief : deprecated API entry point. This definition 
+ * ensures backward compatibility
+ *
+ * See @ref ixEthMiiPhyReset
+ *
+ * @note this feature is board specific
+ */
+#define ixEthAccMiiPhyReset(phyAddr) \
+           ixEthMiiPhyReset(phyAddr)
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def ixEthAccMiiLinkStatus
+ *
+ * @brief : deprecated API entry point. This definition 
+ * ensures backward compatibility
+ *
+ * See @ref ixEthMiiLinkStatus
+ *
+ * @note this feature is board specific
+ */
+#define ixEthAccMiiLinkStatus(phyAddr,linkUp,speed100,fullDuplex,autoneg) \
+           ixEthMiiLinkStatus(phyAddr,linkUp,speed100,fullDuplex,autoneg)
+
+
+
+/**
+ * @ingroup IxEthAcc
+ *
+ * @def ixEthAccMiiShow  
+ *
+ * @brief : deprecated API entry point. This definition 
+ * ensures backward compatibility
+ *
+ * See @ref ixEthMiiPhyShow
+ *
+ * @note this feature is board specific
+ */
+#define ixEthAccMiiShow(phyAddr) \
+        ixEthMiiPhyShow(phyAddr)
+
+#endif /* ndef IxEthAcc_H */
+/**
+ *@}
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthAccDataPlane_p.h b/marvell/uboot/drivers/net/npe/include/IxEthAccDataPlane_p.h
new file mode 100644
index 0000000..dce43d9
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthAccDataPlane_p.h
@@ -0,0 +1,221 @@
+/**
+ * @file IxEthAccDataPlane_p.h
+ *
+ * @author Intel Corporation
+ * @date 12-Feb-2002
+ *
+ * @brief  Internal Header file for IXP425 Ethernet Access component.
+ *
+ * Design Notes:
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+
+#ifndef IxEthAccDataPlane_p_H
+#define IxEthAccDataPlane_p_H
+
+#include <IxOsal.h>
+#include <IxQMgr.h>
+
+/**
+ * @addtogroup IxEthAccPri
+ *@{
+ */
+
+/* typedefs global to this file*/
+
+typedef struct
+{
+    IX_OSAL_MBUF *pHead;
+    IX_OSAL_MBUF *pTail;
+}IxEthAccDataPlaneQList;
+
+
+/**
+ * @struct  IxEthAccDataPlaneStats
+ * @brief   Statistics data structure associated with the data plane
+ *
+ */
+typedef struct
+{
+    UINT32 addToSwQ;
+    UINT32 removeFromSwQ;
+    UINT32 unchainedTxMBufs;
+    UINT32 chainedTxMBufs;
+    UINT32 unchainedTxDoneMBufs;
+    UINT32 chainedTxDoneMBufs;
+    UINT32 unchainedRxMBufs;
+    UINT32 chainedRxMBufs;
+    UINT32 unchainedRxFreeMBufs;
+    UINT32 chainedRxFreeMBufs;
+    UINT32 rxCallbackCounter;
+    UINT32 rxCallbackBurstRead;
+    UINT32 txDoneCallbackCounter;
+    UINT32 unexpectedError;
+} IxEthAccDataPlaneStats;
+
+/**
+ * @fn ixEthAccMbufFromSwQ
+ * @brief  used during disable steps to convert mbufs from 
+ *  swq format, ready to be pushed into hw queues for NPE, 
+ *  back into XScale format 
+ */
+IX_OSAL_MBUF *ixEthAccMbufFromSwQ(IX_OSAL_MBUF *mbuf);
+
+/**
+ * @fn ixEthAccDataPlaneShow
+ * @brief  Show function (for data plane statistics
+ */
+void ixEthAccDataPlaneShow(void);
+
+/*
+ * lock dataplane when atomic operation is required
+ */
+#define IX_ETH_ACC_DATA_PLANE_LOCK(arg) arg = ixOsalIrqLock();
+#define IX_ETH_ACC_DATA_PLANE_UNLOCK(arg) ixOsalIrqUnlock(arg);
+
+/*
+ * Use MBUF fields
+ */
+#define IX_ETHACC_NE_SHARED(mBufPtr) \
+ ((IxEthAccNe *)&((mBufPtr)->ix_ne))
+
+#if 1
+
+#define IX_ETHACC_NE_NEXT(mBufPtr) (mBufPtr)->ix_ne.reserved[0]
+
+/* tm - wrong!! len and pkt_len are in the second word - #define IX_ETHACC_NE_LEN(mBufPtr) (mBufPtr)->ix_ne.reserved[3] */
+#define IX_ETHACC_NE_LEN(mBufPtr) (mBufPtr)->ix_ne.reserved[1]
+
+#define IX_ETHACC_NE_DATA(mBufPtr)(mBufPtr)->ix_ne.reserved[2]
+
+#else
+
+#define IX_ETHACC_NE_NEXT(mBufPtr) \
+  IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_next
+
+#define IX_ETHACC_NE_LEN(mBufPtr) \
+  IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_lengths
+
+#define IX_ETHACC_NE_DATA(mBufPtr) \
+  IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_data
+#endif
+
+/*
+ * Use MBUF  next pointer field to chain data.
+ */
+#define IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER(mbuf) (mbuf)->ix_ctrl.ix_chain
+
+
+
+#define IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(mbuf_list) ((mbuf_list.pHead) == NULL)
+    
+
+#define IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(mbuf_list,mbuf_to_add) 		\
+  do {										\
+    int lockVal;								\
+    IX_ETH_ACC_DATA_PLANE_LOCK(lockVal);                                    	\
+    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.addToSwQ);                           \
+    if ( (mbuf_list.pHead) != NULL ) 						\
+    {										\
+      (IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add))) = (mbuf_list.pHead);\
+      (mbuf_list.pHead) = (mbuf_to_add);					\
+    } 										\
+    else {									\
+      (mbuf_list.pTail) = (mbuf_list.pHead) = (mbuf_to_add);			\
+      IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL;		\
+    } 										\
+    IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);					\
+  } while(0)
+
+
+#define IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL(mbuf_list,mbuf_to_add)   	\
+  do {										\
+    int lockVal;								\
+    IX_ETH_ACC_DATA_PLANE_LOCK(lockVal);                                    	\
+    IX_ETH_ACC_STATS_INC(ixEthAccDataStats.addToSwQ);                           \
+    if ( (mbuf_list.pHead) == NULL ) 						\
+    {										\
+      (mbuf_list.pHead) = mbuf_to_add;						\
+      IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL;		\
+    } 										\
+    else {									\
+      IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_list.pTail)) = (mbuf_to_add);	\
+      IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL;		\
+    } 										\
+    (mbuf_list.pTail) = mbuf_to_add;						\
+    IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);					\
+  } while (0)
+
+
+#define IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD(mbuf_list,mbuf_to_rem)   	\
+  do {										\
+    int lockVal;								\
+    IX_ETH_ACC_DATA_PLANE_LOCK(lockVal);                                    	\
+    if ( (mbuf_list.pHead) != NULL ) 						\
+    {										\
+      IX_ETH_ACC_STATS_INC(ixEthAccDataStats.removeFromSwQ);                    \
+      (mbuf_to_rem) = (mbuf_list.pHead) ;					\
+      (mbuf_list.pHead) = (IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_rem)));\
+    } 										\
+    else {									\
+      (mbuf_to_rem) = NULL;							\
+    } 										\
+    IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal);					\
+  } while (0)
+
+
+/**
+ * @brief message handler QManager entries for NPE id => port ID conversion (NPE_B => 0, NPE_C => 1)
+ */
+#define IX_ETH_ACC_PORT_TO_NPE_ID(port) \
+   ixEthAccPortData[(port)].npeId
+
+#define IX_ETH_ACC_NPE_TO_PORT_ID(npe) ((npe == 0 ? 2 : (npe == 1 ? 0 : ( npe == 2 ? 1 : -1 ))))
+
+#define IX_ETH_ACC_PORT_TO_TX_Q_ID(port)  \
+   ixEthAccPortData[(port)].ixEthAccTxData.txQueue
+
+#define IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(port) \
+   ixEthAccPortData[(port)].ixEthAccRxData.rxFreeQueue
+
+#define IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(port)    (port == IX_ETH_PORT_1 ? IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE : (port == IX_ETH_PORT_2 ? IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE : IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE))
+
+#define IX_ETH_ACC_PORT_TO_RX_FREE_Q_SOURCE(port) (port == IX_ETH_PORT_1 ? IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE : (port == IX_ETH_PORT_2 ? IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE : IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE ))
+
+/* Flush the mbufs chain and all data pointed to by the mbuf */
+
+#ifndef NDEBUG
+#define IX_ETH_ACC_STATS_INC(x) (x++)
+#else
+#define IX_ETH_ACC_STATS_INC(x)
+#endif
+
+#define IX_ETH_ACC_MAX_TX_FRAMES_TO_SUBMIT 128
+
+void ixEthRxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId);
+void ixEthRxMultiBufferQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId);
+void ixEthTxFrameDoneQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId);
+
+#endif /* IxEthAccDataPlane_p_H */
+
+
+/**
+ *@}
+ */
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthAccMac_p.h b/marvell/uboot/drivers/net/npe/include/IxEthAccMac_p.h
new file mode 100644
index 0000000..4eafab2
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthAccMac_p.h
@@ -0,0 +1,224 @@
+/*
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+#ifndef IxEthAccMac_p_H
+#define IxEthAccMac_p_H
+
+#include "IxOsal.h"
+
+#define IX_ETH_ACC_MAX_MULTICAST_ADDRESSES 256
+#define IX_ETH_ACC_NUM_PORTS 3
+#define IX_ETH_ACC_MAX_FRAME_SIZE_DEFAULT 1536
+#define IX_ETH_ACC_MAX_FRAME_SIZE_UPPER_RANGE (65536-64)
+#define IX_ETH_ACC_MAX_FRAME_SIZE_LOWER_RANGE 64
+
+/*
+ * 
+ * MAC register definitions
+ *
+ */
+#define IX_ETH_ACC_MAC_0_BASE IX_OSAL_IXP400_ETHA_PHYS_BASE
+#define IX_ETH_ACC_MAC_1_BASE IX_OSAL_IXP400_ETHB_PHYS_BASE
+#define IX_ETH_ACC_MAC_2_BASE IX_OSAL_IXP400_ETH_NPEA_PHYS_BASE
+
+#define IX_ETH_ACC_MAC_TX_CNTRL1       0x000
+#define IX_ETH_ACC_MAC_TX_CNTRL2       0x004
+#define IX_ETH_ACC_MAC_RX_CNTRL1       0x010
+#define IX_ETH_ACC_MAC_RX_CNTRL2       0x014
+#define IX_ETH_ACC_MAC_RANDOM_SEED     0x020
+#define IX_ETH_ACC_MAC_THRESH_P_EMPTY  0x030
+#define IX_ETH_ACC_MAC_THRESH_P_FULL   0x038
+#define IX_ETH_ACC_MAC_BUF_SIZE_TX     0x040
+#define IX_ETH_ACC_MAC_TX_DEFER        0x050
+#define IX_ETH_ACC_MAC_RX_DEFER        0x054
+#define IX_ETH_ACC_MAC_TX_TWO_DEFER_1  0x060
+#define IX_ETH_ACC_MAC_TX_TWO_DEFER_2  0x064
+#define IX_ETH_ACC_MAC_SLOT_TIME       0x070
+#define IX_ETH_ACC_MAC_MDIO_CMD_1      0x080
+#define IX_ETH_ACC_MAC_MDIO_CMD_2      0x084
+#define IX_ETH_ACC_MAC_MDIO_CMD_3      0x088
+#define IX_ETH_ACC_MAC_MDIO_CMD_4      0x08c
+#define IX_ETH_ACC_MAC_MDIO_STS_1      0x090
+#define IX_ETH_ACC_MAC_MDIO_STS_2      0x094
+#define IX_ETH_ACC_MAC_MDIO_STS_3      0x098
+#define IX_ETH_ACC_MAC_MDIO_STS_4      0x09c
+#define IX_ETH_ACC_MAC_ADDR_MASK_1     0x0A0
+#define IX_ETH_ACC_MAC_ADDR_MASK_2     0x0A4
+#define IX_ETH_ACC_MAC_ADDR_MASK_3     0x0A8
+#define IX_ETH_ACC_MAC_ADDR_MASK_4     0x0AC
+#define IX_ETH_ACC_MAC_ADDR_MASK_5     0x0B0
+#define IX_ETH_ACC_MAC_ADDR_MASK_6     0x0B4
+#define IX_ETH_ACC_MAC_ADDR_1          0x0C0
+#define IX_ETH_ACC_MAC_ADDR_2          0x0C4
+#define IX_ETH_ACC_MAC_ADDR_3          0x0C8
+#define IX_ETH_ACC_MAC_ADDR_4          0x0CC
+#define IX_ETH_ACC_MAC_ADDR_5          0x0D0
+#define IX_ETH_ACC_MAC_ADDR_6          0x0D4
+#define IX_ETH_ACC_MAC_INT_CLK_THRESH  0x0E0
+#define IX_ETH_ACC_MAC_UNI_ADDR_1      0x0F0
+#define IX_ETH_ACC_MAC_UNI_ADDR_2      0x0F4
+#define IX_ETH_ACC_MAC_UNI_ADDR_3      0x0F8
+#define IX_ETH_ACC_MAC_UNI_ADDR_4      0x0FC
+#define IX_ETH_ACC_MAC_UNI_ADDR_5      0x100
+#define IX_ETH_ACC_MAC_UNI_ADDR_6      0x104
+#define IX_ETH_ACC_MAC_CORE_CNTRL      0x1FC
+
+
+/*
+ *
+ *Bit definitions
+ *
+ */
+
+/* TX Control Register 1*/
+
+#define IX_ETH_ACC_TX_CNTRL1_TX_EN         BIT(0)
+#define IX_ETH_ACC_TX_CNTRL1_DUPLEX        BIT(1)
+#define IX_ETH_ACC_TX_CNTRL1_RETRY         BIT(2)
+#define IX_ETH_ACC_TX_CNTRL1_PAD_EN        BIT(3)
+#define IX_ETH_ACC_TX_CNTRL1_FCS_EN        BIT(4)
+#define IX_ETH_ACC_TX_CNTRL1_2DEFER        BIT(5)
+#define IX_ETH_ACC_TX_CNTRL1_RMII          BIT(6)
+
+/* TX Control Register 2 */
+#define IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK  0xf
+
+/* RX Control Register 1 */
+#define IX_ETH_ACC_RX_CNTRL1_RX_EN         BIT(0)
+#define IX_ETH_ACC_RX_CNTRL1_PADSTRIP_EN   BIT(1)
+#define IX_ETH_ACC_RX_CNTRL1_CRC_EN        BIT(2)
+#define IX_ETH_ACC_RX_CNTRL1_PAUSE_EN      BIT(3)
+#define IX_ETH_ACC_RX_CNTRL1_LOOP_EN       BIT(4)
+#define IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN  BIT(5)
+#define IX_ETH_ACC_RX_CNTRL1_RX_RUNT_EN    BIT(6)
+#define IX_ETH_ACC_RX_CNTRL1_BCAST_DIS     BIT(7)
+
+/* RX Control Register 2 */
+#define IX_ETH_ACC_RX_CNTRL2_DEFER_EN      BIT(0)
+
+
+
+/* Core Control Register */
+#define IX_ETH_ACC_CORE_RESET              BIT(0)
+#define IX_ETH_ACC_CORE_RX_FIFO_FLUSH      BIT(1)
+#define IX_ETH_ACC_CORE_TX_FIFO_FLUSH      BIT(2)
+#define IX_ETH_ACC_CORE_SEND_JAM           BIT(3)
+#define IX_ETH_ACC_CORE_MDC_EN             BIT(4)
+
+/* 1st bit of 1st MAC octet */
+#define IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT ( 1) 
+
+
+/*
+ *
+ * Default values
+ *
+ */
+
+
+#define IX_ETH_ACC_TX_CNTRL1_DEFAULT  (IX_ETH_ACC_TX_CNTRL1_TX_EN | \
+ IX_ETH_ACC_TX_CNTRL1_RETRY  | \
+ IX_ETH_ACC_TX_CNTRL1_FCS_EN | \
+ IX_ETH_ACC_TX_CNTRL1_2DEFER | \
+ IX_ETH_ACC_TX_CNTRL1_PAD_EN)
+
+#define IX_ETH_ACC_TX_MAX_RETRIES_DEFAULT      0x0f 
+
+#define IX_ETH_ACC_RX_CNTRL1_DEFAULT    (IX_ETH_ACC_RX_CNTRL1_CRC_EN    \
+					 | IX_ETH_ACC_RX_CNTRL1_RX_EN)
+
+#define IX_ETH_ACC_RX_CNTRL2_DEFAULT           0x0
+
+/* Thresholds determined by NPE firmware FS */
+#define IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT  0x12
+#define IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT   0x30
+
+/* Number of bytes that must be in the tx fifo before
+   transmission commences*/
+#define IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT     0x8
+
+/* One-part deferral values */
+#define IX_ETH_ACC_MAC_TX_DEFER_DEFAULT        0x15
+#define IX_ETH_ACC_MAC_RX_DEFER_DEFAULT        0x16
+
+/* Two-part deferral values... */
+#define IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT  0x08
+#define IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT  0x07
+
+/* This value applies to MII */
+#define IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT       0x80
+
+/* This value applies to RMII */
+#define IX_ETH_ACC_MAC_SLOT_TIME_RMII_DEFAULT  0xFF
+
+#define IX_ETH_ACC_MAC_ADDR_MASK_DEFAULT       0xFF
+
+#define IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT  0x1
+/*The following is a value chosen at random*/
+#define IX_ETH_ACC_RANDOM_SEED_DEFAULT         0x8
+
+/*By default we must configure the MAC to generate the 
+  MDC clock*/
+#define IX_ETH_ACC_CORE_DEFAULT                (IX_ETH_ACC_CORE_MDC_EN)
+
+#define IXP425_ETH_ACC_MAX_PHY 2
+#define IXP425_ETH_ACC_MAX_AN_ENTRIES 20
+#define IX_ETH_ACC_MAC_RESET_DELAY    1
+
+#define IX_ETH_ACC_MAC_ALL_BITS_SET   0xFF
+
+#define IX_ETH_ACC_MAC_MSGID_SHL      24
+
+#define IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS 20
+#define IX_ETH_ACC_PORT_DISABLE_DELAY_COUNT 200  /* 4 seconds timeout */
+#define IX_ETH_ACC_PORT_DISABLE_RETRY_COUNT 3
+#define IX_ETH_ACC_MIB_STATS_DELAY_MSECS 2000 /* 2 seconds delay for ethernet stats */ 
+
+/*Register access macros*/
+#if  (CPU == SIMSPARCSOLARIS)
+extern void registerWriteStub (UINT32 base, UINT32 offset, UINT32 val);
+extern UINT32 registerReadStub (UINT32 base, UINT32 offset);
+
+#define REG_WRITE(b,o,v) registerWriteStub(b, o, v)
+#define REG_READ(b,o,v)  do { v = registerReadStub(b, o); } while (0)
+#else
+#define REG_WRITE(b,o,v) IX_OSAL_WRITE_LONG((volatile UINT32 *)(b + o), v)
+#define REG_READ(b,o,v)  (v = IX_OSAL_READ_LONG((volatile UINT32 *)(b + o)))
+
+#endif
+
+void ixEthAccMacUnload(void);
+IxEthAccStatus ixEthAccMacMemInit(void);
+
+/* MAC core loopback */
+IxEthAccStatus ixEthAccPortLoopbackEnable(IxEthAccPortId portId);
+IxEthAccStatus ixEthAccPortLoopbackDisable(IxEthAccPortId portId);
+
+/* MAC core traffic control */
+IxEthAccStatus ixEthAccPortTxEnablePriv(IxEthAccPortId portId);
+IxEthAccStatus ixEthAccPortTxDisablePriv(IxEthAccPortId portId);
+IxEthAccStatus ixEthAccPortRxEnablePriv(IxEthAccPortId portId);
+IxEthAccStatus ixEthAccPortRxDisablePriv(IxEthAccPortId portId);
+IxEthAccStatus ixEthAccPortMacResetPriv(IxEthAccPortId portId);
+
+/* NPE software loopback */
+IxEthAccStatus ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId);
+IxEthAccStatus ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId);
+
+#endif /*IxEthAccMac_p_H*/
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthAccMii_p.h b/marvell/uboot/drivers/net/npe/include/IxEthAccMii_p.h
new file mode 100644
index 0000000..aff30f0
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthAccMii_p.h
@@ -0,0 +1,73 @@
+/**
+ * @file IxEthAccMii_p.h
+ *
+ * @author Intel Corporation
+ * @date 
+ *
+ * @brief  MII Header file
+ *
+ * Design Notes:
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxEthAccMii_p_H
+#define IxEthAccMii_p_H
+
+/* MII definitions - these have been verified against the LXT971 and LXT972 PHYs*/
+
+#define IXP425_ETH_ACC_MII_MAX_REG      32      /* max register per phy */
+
+#define IX_ETH_ACC_MII_REG_SHL    16
+#define IX_ETH_ACC_MII_ADDR_SHL   21
+
+/* Definitions for MII access routines*/
+ 
+#define IX_ETH_ACC_MII_GO                  BIT(31)
+#define IX_ETH_ACC_MII_WRITE               BIT(26)
+#define IX_ETH_ACC_MII_TIMEOUT_10TH_SECS        5    
+#define IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS     100
+#define IX_ETH_ACC_MII_READ_FAIL           BIT(31)
+ 
+#define IX_ETH_ACC_MII_PHY_DEF_DELAY   300  /* max delay before link up, etc. */
+#define IX_ETH_ACC_MII_PHY_NO_DELAY    0x0  /* do not delay */
+#define IX_ETH_ACC_MII_PHY_NULL        0xff /* PHY is not present */
+#define IX_ETH_ACC_MII_PHY_DEF_ADDR    0x0  /* default PHY's logical address */
+
+#ifndef IX_ETH_ACC_MII_MONITOR_DELAY
+#   define IX_ETH_ACC_MII_MONITOR_DELAY   0x5    /* in seconds */
+#endif
+
+/* Register definition */  
+
+#define IX_ETH_ACC_MII_CTRL_REG	    0x0	/* Control Register */
+#define IX_ETH_ACC_MII_STAT_REG	    0x1	/* Status Register */
+#define IX_ETH_ACC_MII_PHY_ID1_REG  0x2	/* PHY identifier 1 Register */
+#define IX_ETH_ACC_MII_PHY_ID2_REG  0x3	/* PHY identifier 2 Register */
+#define IX_ETH_ACC_MII_AN_ADS_REG   0x4	/* Auto-Negotiation	  */
+					/* Advertisement Register */
+#define IX_ETH_ACC_MII_AN_PRTN_REG  0x5	/* Auto-Negotiation	    */
+					/* partner ability Register */
+#define IX_ETH_ACC_MII_AN_EXP_REG   0x6	/* Auto-Negotiation   */
+					/* Expansion Register */
+#define IX_ETH_ACC_MII_AN_NEXT_REG  0x7	/* Auto-Negotiation	       */
+					/* next-page transmit Register */
+
+IxEthAccStatus ixEthAccMdioShow (void);
+IxEthAccStatus ixEthAccMiiInit(void);
+void ixEthAccMiiUnload(void);
+
+#endif  /*IxEthAccMii_p_H*/
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthAccQueueAssign_p.h b/marvell/uboot/drivers/net/npe/include/IxEthAccQueueAssign_p.h
new file mode 100644
index 0000000..65661a0
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthAccQueueAssign_p.h
@@ -0,0 +1,113 @@
+/**
+ * @file IxEthAccQueueAssign_p.h
+ *
+ * @author Intel Corporation
+ * @date 06-Mar-2002
+ *
+ * @brief   Mapping from QMgr Q's to internal assignment
+ *
+ * Design Notes:
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @addtogroup IxEthAccPri
+ *@{
+ */
+
+/*
+ * Os/System dependancies.
+ */
+#include "IxOsal.h"
+
+/*
+ * Intermodule dependancies
+ */
+#include "IxQMgr.h"
+#include "IxQueueAssignments.h"
+
+/* Check range of Q's assigned to this component. */
+#if IX_ETH_ACC_RX_FRAME_ETH_Q >= (IX_QMGR_MIN_QUEUPP_QID ) |    	\
+ IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q  >=  (IX_QMGR_MIN_QUEUPP_QID) | 	\
+ IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q  >=  (IX_QMGR_MIN_QUEUPP_QID) | 	\
+ IX_ETH_ACC_TX_FRAME_ENET0_Q >=   (IX_QMGR_MIN_QUEUPP_QID) |  		\
+ IX_ETH_ACC_TX_FRAME_ENET1_Q >=   (IX_QMGR_MIN_QUEUPP_QID) | 		\
+ IX_ETH_ACC_TX_FRAME_DONE_ETH_Q  >=  (IX_QMGR_MIN_QUEUPP_QID)  
+#error "Not all Ethernet Access Queues are betweem 1-31, requires full functionalty Q's unless otherwise validated "
+#endif
+
+/**
+*
+* @typedef  IxEthAccQregInfo
+*
+* @brief 
+*
+*/
+typedef struct 
+{
+   IxQMgrQId qId;
+   char *qName;
+   IxQMgrCallback qCallback;
+   IxQMgrCallbackId callbackTag;
+   IxQMgrQSizeInWords qSize;
+   IxQMgrQEntrySizeInWords qWords; 
+   BOOL           qNotificationEnableAtStartup;
+   IxQMgrSourceId qConditionSource; 
+   IxQMgrWMLevel  AlmostEmptyThreshold;
+   IxQMgrWMLevel  AlmostFullThreshold;
+
+} IxEthAccQregInfo;
+
+/*
+ * Prototypes for all QM callbacks.
+ */
+
+/* 
+ * Rx Callbacks 
+ */
+IX_ETH_ACC_PUBLIC
+void  ixEthRxFrameQMCallback(IxQMgrQId, IxQMgrCallbackId);
+
+IX_ETH_ACC_PUBLIC
+void  ixEthRxMultiBufferQMCallback(IxQMgrQId, IxQMgrCallbackId);
+
+IX_ETH_ACC_PUBLIC
+void  ixEthRxFreeQMCallback(IxQMgrQId, IxQMgrCallbackId);
+
+/* 
+ * Tx Callback.
+ */
+IX_ETH_ACC_PUBLIC
+void  ixEthTxFrameQMCallback(IxQMgrQId, IxQMgrCallbackId);
+
+IX_ETH_ACC_PUBLIC
+void  ixEthTxFrameDoneQMCallback(IxQMgrQId, IxQMgrCallbackId );
+
+
+#define IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY (IX_QMGR_Q_PRIORITY_0) /* Highest priority */
+
+/*
+ * Queue watermarks
+ */
+#define IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE 		(IX_QMGR_Q_SOURCE_ID_NOT_E   )
+#define IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE 		(IX_QMGR_Q_SOURCE_ID_E   )   
+#define IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE 		(IX_QMGR_Q_SOURCE_ID_E   )
+#define IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE 		(IX_QMGR_Q_SOURCE_ID_E   )
+#define IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE 		(IX_QMGR_Q_SOURCE_ID_E   ) 
+#define IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE 		(IX_QMGR_Q_SOURCE_ID_E   )
+#define IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE 		(IX_QMGR_Q_SOURCE_ID_E   )
+#define IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE 		(IX_QMGR_Q_SOURCE_ID_NOT_E   )
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthAcc_p.h b/marvell/uboot/drivers/net/npe/include/IxEthAcc_p.h
new file mode 100644
index 0000000..1348f4e
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthAcc_p.h
@@ -0,0 +1,301 @@
+/**
+ * @file IxEthAcc_p.h
+ *
+ * @author Intel Corporation
+ * @date 12-Feb-2002
+ *
+ * @brief  Internal Header file for IXP425 Ethernet Access component.
+ *
+ * Design Notes:
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @addtogroup IxEthAccPri
+ *@{
+ */
+
+#ifndef IxEthAcc_p_H
+#define IxEthAcc_p_H
+
+/*
+ * Os/System dependancies.
+ */
+#include "IxOsal.h"
+
+/*
+ * Intermodule dependancies
+ */
+#include "IxNpeDl.h"
+#include "IxQMgr.h"
+
+#include "IxEthNpe.h"
+
+/* 
+ * Intra module dependancies
+ */
+
+#include "IxEthAccDataPlane_p.h"
+#include "IxEthAccMac_p.h"
+
+
+#define INLINE __inline__
+
+#ifdef NDEBUG
+
+#define IX_ETH_ACC_PRIVATE static
+
+#else
+
+#define IX_ETH_ACC_PRIVATE
+
+#endif /* ndef NDEBUG */
+
+#define IX_ETH_ACC_PUBLIC
+
+
+#define IX_ETH_ACC_IS_PORT_VALID(port) ((port) <  IX_ETH_ACC_NUMBER_OF_PORTS  ? true : false )
+
+
+
+#ifndef NDEBUG
+#define IX_ETH_ACC_FATAL_LOG(a,b,c,d,e,f,g)   { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
+#define IX_ETH_ACC_WARNING_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_WARNING,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
+#define IX_ETH_ACC_DEBUG_LOG(a,b,c,d,e,f,g)   { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
+#else
+#define IX_ETH_ACC_FATAL_LOG(a,b,c,d,e,f,g)   { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
+#define IX_ETH_ACC_WARNING_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_WARNING,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);}
+#define IX_ETH_ACC_DEBUG_LOG(a,b,c,d,e,f,g)   {}
+#endif
+
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccInitDataPlane(void);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccQMgrQueuesConfig(void);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC void ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries);
+
+/* prototypes for the private control plane functions (used by the control interface wrapper) */
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortEnablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDisablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressSetPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressGetPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressJoinPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressJoinAllPriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressLeavePriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressLeaveAllPriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastAddressShowPriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC void ixEthAccPortMulticastAddressShowPriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDuplexModeSetPriv(IxEthAccPortId portId, IxEthAccDuplexMode mode);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDuplexModeGetPriv(IxEthAccPortId portId, IxEthAccDuplexMode *mode);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendPaddingEnablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendPaddingDisablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendFCSEnablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendFCSDisablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortRxFrameAppendFCSEnablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortRxFrameAppendFCSDisablePriv(IxEthAccPortId portId);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccTxSchedulingDisciplineSetPriv(IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched);
+IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccRxSchedulingDisciplineSetPriv(IxEthAccSchedulerDiscipline sched);
+
+/**
+ * @struct  ixEthAccRxDataStats
+ * @brief   Stats data structures for data path. - Not obtained from h/w
+ *
+ */
+typedef struct
+{ 
+    UINT32 rxFrameClientCallback;
+    UINT32 rxFreeRepOK;
+    UINT32 rxFreeRepDelayed;
+    UINT32 rxFreeRepFromSwQOK;
+    UINT32 rxFreeRepFromSwQDelayed;
+    UINT32 rxFreeLateNotificationEnabled;
+    UINT32 rxFreeLowCallback;
+    UINT32 rxFreeOverflow;
+    UINT32 rxFreeLock;
+    UINT32 rxDuringDisable;
+    UINT32 rxSwQDuringDisable;
+    UINT32 rxUnlearnedMacAddress;
+    UINT32 rxPriority[IX_ETH_ACC_TX_PRIORITY_7 + 1];
+    UINT32 rxUnexpectedError;
+    UINT32 rxFiltered;
+} IxEthAccRxDataStats;
+
+/**
+ * @struct  IxEthAccTxDataStats
+ * @brief   Stats data structures for data path. - Not obtained from h/w
+ *
+ */
+typedef struct
+{   
+    UINT32 txQOK;
+    UINT32 txQDelayed;
+    UINT32 txFromSwQOK;
+    UINT32 txFromSwQDelayed;
+    UINT32 txLowThreshCallback;
+    UINT32 txDoneClientCallback;
+    UINT32 txDoneClientCallbackDisable;
+    UINT32 txOverflow;
+    UINT32 txLock;
+    UINT32 txPriority[IX_ETH_ACC_TX_PRIORITY_7 + 1];
+    UINT32 txLateNotificationEnabled;
+    UINT32 txDoneDuringDisable;
+    UINT32 txDoneSwQDuringDisable;
+    UINT32 txUnexpectedError;
+} IxEthAccTxDataStats;
+
+/* port Disable state machine : list of states */
+typedef enum
+{
+    /* general port states */
+    DISABLED = 0,
+    ACTIVE,
+
+    /* particular Tx/Rx states */
+    REPLENISH,
+    RECEIVE,
+    TRANSMIT,
+    TRANSMIT_DONE
+} IxEthAccPortDisableState;
+
+typedef struct
+{
+    BOOL fullDuplex;
+    BOOL rxFCSAppend;
+    BOOL txFCSAppend;
+    BOOL txPADAppend;
+    BOOL enabled;
+    BOOL promiscuous;
+    BOOL joinAll;
+    IxOsalMutex ackMIBStatsLock;
+    IxOsalMutex ackMIBStatsResetLock;
+    IxOsalMutex MIBStatsGetAccessLock;
+    IxOsalMutex MIBStatsGetResetAccessLock;
+    IxOsalMutex npeLoopbackMessageLock;
+    IxEthAccMacAddr mcastAddrsTable[IX_ETH_ACC_MAX_MULTICAST_ADDRESSES];
+    UINT32 mcastAddrIndex;
+    IX_OSAL_MBUF *portDisableTxMbufPtr;
+    IX_OSAL_MBUF *portDisableRxMbufPtr;
+
+    volatile IxEthAccPortDisableState portDisableState;
+    volatile IxEthAccPortDisableState rxState;
+    volatile IxEthAccPortDisableState txState;
+
+    BOOL initDone;
+    BOOL macInitialised;
+} IxEthAccMacState;
+
+/**
+ * @struct  IxEthAccRxInfo
+ * @brief   System-wide data structures associated with the data plane.
+ *
+ */
+typedef struct
+{
+  IxQMgrQId higherPriorityQueue[IX_QMGR_MAX_NUM_QUEUES]; /**< higher priority queue list */
+  IxEthAccSchedulerDiscipline schDiscipline; /**< Receive Xscale QoS type */
+} IxEthAccInfo; 
+
+/**
+ * @struct  IxEthAccRxDataInfo
+ * @brief   Per Port data structures associated with the receive data plane.
+ *
+ */
+typedef struct
+{
+  IxQMgrQId rxFreeQueue; /**< rxFree Queue for this port */
+  IxEthAccPortRxCallback rxCallbackFn;
+  UINT32  rxCallbackTag;
+  IxEthAccDataPlaneQList freeBufferList;
+  IxEthAccPortMultiBufferRxCallback rxMultiBufferCallbackFn;
+  UINT32  rxMultiBufferCallbackTag;
+  BOOL rxMultiBufferCallbackInUse;
+  IxEthAccRxDataStats stats; /**< Receive s/w stats */
+} IxEthAccRxDataInfo; 
+
+/**
+ * @struct  IxEthAccTxDataInfo
+ * @brief   Per Port data structures associated with the transmit data plane.
+ *
+ */
+typedef struct
+{
+  IxEthAccPortTxDoneCallback  txBufferDoneCallbackFn;
+  UINT32  txCallbackTag;
+  IxEthAccDataPlaneQList	txQ[IX_ETH_ACC_NUM_TX_PRIORITIES]; /**< Transmit Q */
+  IxEthAccSchedulerDiscipline schDiscipline; /**< Transmit Xscale QoS */
+  IxQMgrQId txQueue; /**< txQueue for this port */
+  IxEthAccTxDataStats stats; /**< Transmit s/w stats */
+} IxEthAccTxDataInfo; 
+
+
+/**
+ * @struct  IxEthAccPortDataInfo
+ * @brief   Per Port data structures associated with the port data plane.
+ *
+ */
+typedef struct
+{
+    BOOL               portInitialized;
+    UINT32 npeId; /**< NpeId for this port */
+    IxEthAccTxDataInfo ixEthAccTxData; /**< Transmit data control structures */
+    IxEthAccRxDataInfo ixEthAccRxData; /**< Receive data control structures */
+} IxEthAccPortDataInfo; 
+
+extern IxEthAccPortDataInfo  ixEthAccPortData[];
+#define IX_ETH_IS_PORT_INITIALIZED(port) (ixEthAccPortData[port].portInitialized)
+
+extern BOOL ixEthAccServiceInit;
+#define IX_ETH_ACC_IS_SERVICE_INITIALIZED() (ixEthAccServiceInit == true )
+
+/* 
+ * Maximum number of frames to consume from the Rx Frame Q.
+ */
+
+#define IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK (128)
+
+/*
+ * Max number of times to load the Rx Free Q from callback.  
+ */
+#define IX_ETH_ACC_MAX_RX_FREE_BUFFERS_LOAD (256)  /* Set greater than depth of h/w Q + drain time at line rate */
+
+/*
+ *  Max number of times to read from the Tx Done Q in one sitting.
+ */
+
+#define IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK (256)
+
+/*
+ *  Max number of times to take buffers from S/w queues and write them to the H/w Tx
+ *  queues on receipt of a Tx low threshold callback 
+ */
+
+#define IX_ETH_ACC_MAX_TX_FRAME_TX_CONSUME_PER_CALLBACK (16)
+
+
+#define IX_ETH_ACC_FLUSH_CACHE(addr,size)  IX_OSAL_CACHE_FLUSH((addr),(size))
+#define IX_ETH_ACC_INVALIDATE_CACHE(addr,size)  IX_OSAL_CACHE_INVALIDATE((addr),(size))
+
+
+#define IX_ETH_ACC_MEMSET(start,value,size) memset(start,value,size)
+
+#endif /* ndef IxEthAcc_p_H */
+
+
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthDB.h b/marvell/uboot/drivers/net/npe/include/IxEthDB.h
new file mode 100644
index 0000000..9c4a6a4
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthDB.h
@@ -0,0 +1,2349 @@
+/** @file IxEthDB.h
+ *
+ * @brief this file contains the public API of @ref IxEthDB component
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ *
+ */
+ 
+#ifndef IxEthDB_H
+#define IxEthDB_H
+
+#include <IxOsBuffMgt.h>
+#include <IxTypes.h>
+
+/**
+ * @defgroup IxEthDB IXP400 Ethernet Database (IxEthDB) API
+ *
+ * @brief ethDB is a library that does provides a MAC address database learning/filtering capability
+ *
+ *@{
+ */
+
+#define INLINE __inline__
+
+#define IX_ETH_DB_PRIVATE PRIVATE /* imported from IxTypes.h */
+
+#define IX_ETH_DB_PUBLIC PUBLIC
+
+/**
+ * @brief port ID => message handler NPE id conversion (0 => NPE_B, 1 => NPE_C)
+ */
+#define IX_ETH_DB_PORT_ID_TO_NPE(id) (id == 0 ? 1 : (id == 1 ? 2 : (id == 2 ? 0 : -1)))
+
+/**
+ * @def IX_ETH_DB_NPE_TO_PORT_ID(npe)
+ * @brief message handler NPE id => port ID conversion (NPE_B => 0, NPE_C => 1)
+ */
+#define IX_ETH_DB_NPE_TO_PORT_ID(npe) (npe == 0 ? 2 : (npe == 1 ? 0 : (npe == 2 ? 1 : -1)))
+
+/* temporary define - won't work for Azusa */
+#define IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(id) (IX_ETH_DB_PORT_ID_TO_NPE(id) << 4)
+#define IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(id) (IX_ETH_DB_NPE_TO_PORT_ID(id >> 4))
+
+/**
+ * @def IX_IEEE803_MAC_ADDRESS_SIZE
+ * @brief The size of the MAC address
+ */
+#define IX_IEEE803_MAC_ADDRESS_SIZE (6)
+
+/**
+ * @def IX_IEEE802_1Q_QOS_PRIORITY_COUNT
+ * @brief Number of QoS priorities defined by IEEE802.1Q
+ */
+#define IX_IEEE802_1Q_QOS_PRIORITY_COUNT (8)
+
+/**
+ * @enum IxEthDBStatus
+ * @brief Ethernet Database API return values
+ */
+typedef enum /* IxEthDBStatus */
+{
+  IX_ETH_DB_SUCCESS = IX_SUCCESS,   /**< Success */
+  IX_ETH_DB_FAIL = IX_FAIL,         /**< Failure */
+  IX_ETH_DB_INVALID_PORT,           /**< Invalid port */
+  IX_ETH_DB_PORT_UNINITIALIZED,     /**< Port not initialized */
+  IX_ETH_DB_MAC_UNINITIALIZED,      /**< MAC not initialized */
+  IX_ETH_DB_INVALID_ARG,            /**< Invalid argument */
+  IX_ETH_DB_NO_SUCH_ADDR,           /**< Address not found for search or delete operations */
+  IX_ETH_DB_NOMEM,                  /**< Learning database memory full */
+  IX_ETH_DB_BUSY,                   /**< Learning database cannot complete operation, access temporarily blocked */
+  IX_ETH_DB_END,                    /**< Database browser passed the end of the record set */
+  IX_ETH_DB_INVALID_VLAN,           /**< Invalid VLAN ID (valid range is 0..4094, 0 signifies no VLAN membership, used for priority tagged frames) */
+  IX_ETH_DB_INVALID_PRIORITY,       /**< Invalid QoS priority/traffic class (valid range for QoS priority is 0..7, valid range for traffic class depends on run-time configuration) */
+  IX_ETH_DB_NO_PERMISSION,          /**< No permission for attempted operation */
+  IX_ETH_DB_FEATURE_UNAVAILABLE,    /**< Feature not available (or not enabled) */
+  IX_ETH_DB_INVALID_KEY,            /**< Invalid search key */
+  IX_ETH_DB_INVALID_RECORD_TYPE     /**< Invalid record type */
+} IxEthDBStatus;
+    
+/** @brief VLAN ID type, valid range is 0..4094, 0 signifying no VLAN membership */
+typedef UINT32 IxEthDBVlanId;
+
+/** @brief 802.1Q VLAN tag, contains 3 bits user priority, 1 bit CFI, 12 bits VLAN ID */
+typedef UINT32 IxEthDBVlanTag;
+
+/** @brief QoS priority/traffic class type, valid range is 0..7, 0 being the lowest */
+typedef UINT32 IxEthDBPriority;
+
+/** @brief Priority mapping table; 0..7 QoS priorities used to index, table contains traffic classes */
+typedef UINT8 IxEthDBPriorityTable[8];
+
+/** @brief A 4096 bit array used to map the complete VLAN ID range */
+typedef UINT8 IxEthDBVlanSet[512];
+
+#define IX_ETH_DB_802_1Q_VLAN_MASK (0xFFF)
+#define IX_ETH_DB_802_1Q_QOS_MASK  (0x7)
+
+#define IX_ETH_DB_802_1Q_MAX_VLAN_ID (0xFFE)
+
+/**
+ * @def IX_ETH_DB_SET_VLAN_ID
+ * @brief returns the given 802.1Q tag with the VLAN ID field substituted with the given VLAN ID
+ *
+ * This macro is used to change the VLAN ID in a 802.1Q tag.
+ *
+ * Example: 
+ * 
+ *  tag = IX_ETH_DB_SET_VLAN_ID(tag, 32)
+ *
+ * inserts the VLAN ID "32" in the given tag.
+ */
+#define IX_ETH_DB_SET_VLAN_ID(vlanTag, vlanID) (((vlanTag) & 0xF000) | ((vlanID) & IX_ETH_DB_802_1Q_VLAN_MASK))
+
+/**
+* @def IX_ETH_DB_GET_VLAN_ID
+* @brief returns the VLAN ID from the given 802.1Q tag
+*/
+#define IX_ETH_DB_GET_VLAN_ID(vlanTag) ((vlanTag) & IX_ETH_DB_802_1Q_VLAN_MASK)
+
+#define IX_ETH_DB_GET_QOS_PRIORITY(vlanTag) (((vlanTag) >> 13) & IX_ETH_DB_802_1Q_QOS_MASK)
+
+#define IX_ETH_DB_SET_QOS_PRIORITY(vlanTag, priority) (((vlanTag) & 0x1FFF) | (((priority) & IX_ETH_DB_802_1Q_QOS_MASK) << 13))
+
+#define IX_ETH_DB_CHECK_VLAN_TAG(vlanTag) { if(((vlanTag & 0xFFFF0000) != 0) || (IX_ETH_DB_GET_VLAN_ID(vlanTag) > 4094)) return IX_ETH_DB_INVALID_VLAN; }
+
+#define IX_ETH_DB_CHECK_VLAN_ID(vlanId) { if (vlanId > IX_ETH_DB_802_1Q_MAX_VLAN_ID) return IX_ETH_DB_INVALID_VLAN; }
+
+#define IX_IEEE802_1Q_VLAN_TPID (0x8100)
+    
+typedef enum
+{
+  IX_ETH_DB_UNTAGGED_FRAMES        = 0x1, /**< Accepts untagged frames */
+  IX_ETH_DB_VLAN_TAGGED_FRAMES     = 0x2, /**< Accepts tagged frames */
+  IX_ETH_DB_PRIORITY_TAGGED_FRAMES = 0x4, /**< Accepts tagged frames with VLAN ID set to 0 (no VLAN membership) */
+  IX_ETH_DB_ACCEPT_ALL_FRAMES      = 
+      IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES /**< Accepts all the frames */
+} IxEthDBFrameFilter;
+
+typedef enum
+{
+  IX_ETH_DB_PASS_THROUGH = 0x1, /**< Leave frame as-is */
+  IX_ETH_DB_ADD_TAG      = 0x2, /**< Add default port VLAN tag */
+  IX_ETH_DB_REMOVE_TAG   = 0x3  /**< Remove VLAN tag from frame */
+} IxEthDBTaggingAction;
+
+typedef enum
+{
+  IX_ETH_DB_FIREWALL_WHITE_LIST = 0x1,  /**< Firewall operates in white-list mode (MAC address based admission) */
+  IX_ETH_DB_FIREWALL_BLACK_LIST = 0x2   /**< Firewall operates in black-list mode (MAC address based blocking) */
+} IxEthDBFirewallMode;
+  
+typedef enum
+{
+  IX_ETH_DB_FILTERING_RECORD        = 0x01, /**< <table><caption> Filtering record </caption> 
+                                             *      <tr><td> MAC address <td> static/dynamic type <td> age 
+                                             *   </table> 
+                                             */
+  IX_ETH_DB_FILTERING_VLAN_RECORD   = 0x02, /**< <table><caption> VLAN-enabled filtering record </caption>
+                                             *      <tr><td> MAC address <td> static/dynamic type <td> age <td> 802.1Q tag 
+                                             *   </table> 
+                                             */
+  IX_ETH_DB_WIFI_RECORD             = 0x04, /**< <table><caption> WiFi header conversion record </caption>
+                                             *      <tr><td> MAC address <td> optional gateway MAC address <td> 
+                                             *   </table>
+                                             */
+  IX_ETH_DB_FIREWALL_RECORD         = 0x08, /**< <table><caption> Firewall record </caption>
+                                             *      <tr><td> MAC address 
+                                             *   </table>
+                                             */
+  IX_ETH_DB_GATEWAY_RECORD          = 0x10, /**< <i>For internal use only</i> */
+  IX_ETH_DB_MAX_RECORD_TYPE_INDEX   = 0x10, /**< <i>For internal use only</i> */
+  IX_ETH_DB_NO_RECORD_TYPE          = 0,    /**< None of the registered record types */
+  IX_ETH_DB_ALL_FILTERING_RECORDS   = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD, /**< All the filtering records */
+  IX_ETH_DB_ALL_RECORD_TYPES        = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD |
+      IX_ETH_DB_WIFI_RECORD | IX_ETH_DB_FIREWALL_RECORD /**< All the record types registered within EthDB */    
+} IxEthDBRecordType;
+  
+typedef enum
+{
+  IX_ETH_DB_LEARNING                = 0x01, /**< Learning feature; enables EthDB to learn MAC address (filtering) records, including 802.1Q enabled records */
+  IX_ETH_DB_FILTERING               = 0x02, /**< Filtering feature; enables EthDB to communicate with the NPEs for downloading filtering information in the NPEs; depends on the learning feature */
+  IX_ETH_DB_VLAN_QOS                = 0x04, /**< VLAN/QoS feature; enables EthDB to configure NPEs to operate in VLAN/QoS aware modes */
+  IX_ETH_DB_FIREWALL                = 0x08, /**< Firewall feature; enables EthDB to configure NPEs to operate in firewall mode, using white/black address lists */
+  IX_ETH_DB_SPANNING_TREE_PROTOCOL  = 0x10, /**< Spanning tree protocol feature; enables EthDB to configure the NPEs as STP nodes */
+  IX_ETH_DB_WIFI_HEADER_CONVERSION  = 0x20  /**< WiFi 802.3 to 802.11 header conversion feature; enables EthDB to handle WiFi conversion data */
+} IxEthDBFeature;
+  
+typedef UINT32 IxEthDBProperty;  /**< Property ID type */
+
+typedef enum
+{
+  IX_ETH_DB_INTEGER_PROPERTY  = 0x1, /**< 4 byte unsigned integer type */
+  IX_ETH_DB_STRING_PROPERTY   = 0x2, /**< NULL-terminated string type of maximum 255 characters (including the terminator) */
+  IX_ETH_DB_MAC_ADDR_PROPERTY = 0x3, /**< 6 byte MAC address type */
+  IX_ETH_DB_BOOL_PROPERTY     = 0x4  /**< 4 byte boolean type; can contain only true and false values */
+} IxEthDBPropertyType;
+
+/* list of supported properties for the IX_ETH_DB_VLAN_QOS feature */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY   (0x01)     /**< Property identifying number the supported number of traffic classes */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY (0x10)  /**< Rx queue assigned to traffic class 0 */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_1_RX_QUEUE_PROPERTY (0x11)  /**< Rx queue assigned to traffic class 1 */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_2_RX_QUEUE_PROPERTY (0x12)  /**< Rx queue assigned to traffic class 2 */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_3_RX_QUEUE_PROPERTY (0x13)  /**< Rx queue assigned to traffic class 3 */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_4_RX_QUEUE_PROPERTY (0x14)  /**< Rx queue assigned to traffic class 4 */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_5_RX_QUEUE_PROPERTY (0x15)  /**< Rx queue assigned to traffic class 5 */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_6_RX_QUEUE_PROPERTY (0x16)  /**< Rx queue assigned to traffic class 6 */
+#define IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY (0x17)  /**< Rx queue assigned to traffic class 7 */
+
+/* private property used by EthAcc to indicate queue configuration complete */
+#define IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE (0x18)
+      
+/**
+ *
+ * @brief The IEEE 802.3 Ethernet MAC address structure.
+ * 
+ * The data should be packed with bytes xx:xx:xx:xx:xx:xx 
+ *
+ * @note The data must be packed in network byte order.
+ */
+typedef struct  
+{
+   UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE];
+} IxEthDBMacAddr;
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @brief Definition of an IXP400 port.
+ */
+typedef UINT32 IxEthDBPortId;
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @brief Port dependency map definition
+ */
+typedef UINT8 IxEthDBPortMap[32];
+    
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBInit(void)
+ *
+ * @brief Initializes the Ethernet learning/filtering database
+ *
+ * @note calling this function multiple times does not constitute an error;
+ * redundant calls will be ignored, returning IX_ETH_DB_SUCCESS
+ *
+ * @retval IX_ETH_DB_SUCCESS initialization was successful
+ * @retval IX_ETH_DB_FAIL initialization failed (OS error)
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBInit(void);
+ 
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBUnload(void)
+ *
+ * @brief Stops and prepares the EthDB component for unloading.
+ *
+ * @retval IX_ETH_DB_SUCCESS de-initialization was successful
+ * @retval IX_ETH_DB_BUSY de-initialization failed, ports must be disabled first
+ * @retval IX_ETH_DB_FAIL de-initialization failed (OS error)
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBUnload(void);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn void ixEthDBPortInit(IxEthDBPortId portID)
+ *
+ * @brief Initializes a port
+ *
+ * This function is called automatically by the Ethernet Access
+ * ixEthAccPortInit() routine for Ethernet NPE ports and should be manually
+ * called for any user-defined port (any port that is not one of
+ * the two Ethernet NPEs). 
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to be initialized
+ *
+ * @see IxEthDBPortDefs.h for port definitions
+ *
+ * @note calling this function multiple times does not constitute an error;
+ * redundant calls will be ignored
+ */
+IX_ETH_DB_PUBLIC 
+void ixEthDBPortInit(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID)
+ *
+ * @brief Enables a port
+ *
+ * This function is called automatically from the Ethernet Access component
+ * ixEthAccPortEnable() routine for Ethernet NPE ports and should be manually
+ * called for any user-defined port (any port that is not one of
+ * the Ethernet NPEs). 
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to enable processing on
+ *
+ * @retval IX_ETH_DB_SUCCESS if enabling is successful
+ * @retval IX_ETH_DB_FAIL if the enabling was not successful due to
+ * a message handler error
+ * @retval IX_ETH_DB_MAC_UNINITIALIZED the MAC address of this port was
+ * not initialized (only for Ethernet NPEs)
+ * @retval IX_ETH_DB_INVALID_PORT if portID is invalid
+ *
+ * @pre ixEthDBPortAddressSet needs to be called prior to enabling the port events
+ * for Ethernet NPEs
+ *
+ * @see ixEthDBPortAddressSet
+ *
+ * @see IxEthDBPortDefs.h for port definitions
+ *
+ * @note calling this function multiple times does not constitute an error;
+ * redundant calls will be ignored
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID)
+ *
+ * @brief Disables processing on a port
+ *
+ * This function is called automatically from the Ethernet Access component
+ * ixEthAccPortDisable() routine for Ethernet NPE ports and should be manually
+ * called for any user-defined port (any port that is not one of
+ * the Ethernet NPEs).
+ *
+ * @note Calling ixEthAccPortDisable() will disable the respective Ethernet NPE.
+ * After Ethernet NPEs are disabled they are stopped therefore
+ * when re-enabled they need to be reset, downloaded with microcode and started.
+ * For learning to restart working the user needs to call again 
+ * ixEthAccPortUnicastMacAddressSet or ixEthDBUnicastAddressSet
+ * with the respective port MAC address.
+ * Residual MAC addresses learnt before the port was disabled are deleted as soon
+ * as the port is disabled. This only applies to dynamic (learnt) entries, static
+ * entries do not dissapear when the port is disabled.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to disable processing on
+ *
+ * @retval IX_ETH_DB_SUCCESS if disabling is successful
+ * @retval IX_ETH_DB_FAIL if the disabling was not successful due to
+ * a message handler error
+ * @retval IX_ETH_DB_INVALID_PORT if portID is invalid
+ *
+ * @note calling this function multiple times after the first time completed successfully
+ * does not constitute an error; redundant calls will be ignored and return IX_ETH_DB_SUCCESS
+*/
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Sets the port MAC address
+ *
+ * This function is to be called from the Ethernet Access component top-level
+ * ixEthDBUnicastAddressSet(). Event processing cannot be enabled for a port
+ * until its MAC address has been set.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port whose MAC address is set
+ * @param macAddr @ref IxEthDBMacAddr [in] - port MAC address
+ *
+ * @retval IX_ETH_DB_SUCCESS MAC address was set successfully
+ * @retval IX_ETH_DB_FAIL MAC address was not set due to a message handler failure
+ * @retval IX_ETH_DB_INVALID_PORT if the port is not an Ethernet NPE
+ *
+ * @see IxEthDBPortDefs.h for port definitions
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize)
+ *
+ * @brief Set the maximum frame size supported on the given port ID
+ *
+ * This functions set the maximum frame size supported on a specific port ID 
+ * 
+ * - Reentrant    - yes
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to configure
+ * @param maximumFrameSize UINT32 [in] - maximum frame size to configure
+ *
+ * @retval IX_ETH_DB_SUCCESS the port is configured
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED the port has not been initialized
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_INVALID_ARG size parameter is out of range
+ * @retval IX_ETH_DB_NO_PERMISSION selected port is not an Ethernet NPE
+ * @retval IX_FAIL unknown OS or NPE communication error
+ *
+ * @note
+ * This maximum frame size is used to filter the frames based on their
+ * destination addresses and the capabilities of the destination port.
+ * The mximum value that can be set for a NPE port is 16320.
+ * (IX_ETHNPE_ACC_FRAME_LENGTH_MAX)
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Populate the Ethernet learning/filtering database with a static MAC address
+ *
+ * Populates the Ethernet learning/filtering database with a static MAC address. The entry will not be subject to aging.
+ * If there is an entry (static or dynamic) with the corresponding MAC address on any port this entry will take precedence.
+ * Any other entry with the same MAC address will be removed.
+ *
+ * - Reentrant    - yes
+ * - ISR Callable - yes
+ * 
+ * @param portID @ref IxEthDBPortId [in] - port ID to add the static address to
+ * @param macAddr @ref IxEthDBMacAddr [in] - static MAC address to add
+ * 
+ * @retval IX_ETH_DB_SUCCESS the add was successful
+ * @retval IX_ETH_DB_FAIL failed to populate the database entry
+ * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Populate the Ethernet learning/filtering database with a dynamic MAC address
+ *
+ * Populates the Ethernet learning/filtering database with a dynamic MAC address. This entry will be subject to normal 
+ * aging function, if aging is enabled on its port.
+ * If there is an entry (static or dynamic) with the same MAC address on any port this entry will take precedence.
+ * Any other entry with the same MAC address will be removed.
+ *
+ * - Reentrant    - yes
+ * - ISR Callable - yes
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to add the dynamic address to
+ * @param macAddr @ref IxEthDBMacAddr [in] - static MAC address to add
+ *
+ * @retval IX_ETH_DB_SUCCESS the add was successful
+ * @retval IX_ETH_DB_FAIL failed to populate the database entry
+ * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr)
+ *
+ * @brief Removes a MAC address entry from the Ethernet learning/filtering database
+ *
+ * @param macAddr IxEthDBMacAddr [in] - MAC address to remove
+ *
+ * - Reentrant    - yes
+ * - ISR Callable - no
+ *
+ * @retval IX_ETH_DB_SUCCESS the removal was successful
+ * @retval IX_ETH_DB_NO_SUCH_ADDR failed to remove the address (not in the database)
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Search the Ethernet learning/filtering database for the given MAC address and port ID
+ *
+ * This functions searches the database for a specific port ID and MAC address. Both the port ID
+ * and the MAC address have to match in order for the record to be reported as found.
+ *
+ * - Reentrant    - yes
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to search for
+ * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to search for
+ *
+ * @retval IX_ETH_DB_SUCCESS the record exists in the database
+ * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument
+ * @retval IX_ETH_DB_NO_SUCH_ADDR the record was not found in the database
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Search the Ethernet learning/filtering database for a MAC address and return the port ID
+ *
+ * Searches the database for a MAC address. The function returns the portID for the 
+ * MAC address record, if found. If no match is found the function returns IX_ETH_DB_NO_SUCH_ADDR. 
+ * The portID is only valid if the function finds a match.
+ *
+ * - Reentrant    - yes
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID the address belongs to (populated only on a successful search)
+ * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to search for
+ *
+ * @retval IX_ETH_DB_SUCCESS the record exists in the database
+ * @retval IX_ETH_DB_NO_SUCH_ADDR the record was not found in the database
+ * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or portID pointer argument(s)
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Search the filtering database for a MAC address, return the port ID and reset the record age
+ *
+ * Searches the database for a MAC address. The function returns the portID for the 
+ * MAC address record and resets the entry age to 0, if found. 
+ * If no match is found the function returns IX_ETH_DB_NO_SUCH_ADDR. 
+ * The portID is only valid if the function finds a match.
+ *
+ * - Reentrant      - yes
+ * - ISR Callable   - no
+ *
+ * @retval IX_ETH_DB_SUCCESS the MAC address was found
+ * @retval IX_ETH_DB_NO_SUCH_ADDR the MAC address was not found
+ * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or portID pointer argument(s)
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @def IX_ETH_DB_MAINTENANCE_TIME
+ *
+ * @brief The @ref ixEthDBDatabaseMaintenance must be called by the user at a frequency of 
+ * IX_ETH_DB_MAINTENANCE_TIME
+ *
+ */
+#define IX_ETH_DB_MAINTENANCE_TIME (1 * 60) /* 1 Minute */
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @def IX_ETH_DB_LEARNING_ENTRY_AGE_TIME
+ *
+ * @brief The define specifies the filtering database age entry time. Static entries older than
+ * IX_ETH_DB_LEARNING_ENTRY_AGE_TIME +/- IX_ETH_DB_MAINTENANCE_TIME shall be removed.
+ *
+ */
+#define IX_ETH_DB_LEARNING_ENTRY_AGE_TIME (15 * 60 ) /* 15 Mins */
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID)
+ *
+ * @brief Disable the aging function for a specific port
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to disable aging on
+ *
+ * - Reentrant    - yes
+ * - ISR Callable - no
+ *
+ * @retval IX_ETH_DB_SUCCESS aging disabled successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID)
+ *
+ * @brief Enable the aging function for a specific port
+ * 
+ * Enables the aging of dynamic MAC address entries stored in the learning/filtering database
+ * 
+ * @note The aging function relies on the @ref ixEthDBDatabaseMaintenance being called with a period of 
+ * @ref IX_ETH_DB_MAINTENANCE_TIME seconds.
+ *
+ * - Reentrant    - yes
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to enable aging on
+ *
+ * @retval IX_ETH_DB_SUCCESS aging enabled successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn void ixEthDBDatabaseMaintenance(void)
+ *
+ * @brief Performs a maintenance operation on the Ethernet learning/filtering database
+ * 
+ * In order to perform a database maintenance this function must be called every
+ * @ref IX_ETH_DB_MAINTENANCE_TIME seconds. It should be called regardless of whether learning is
+ * enabled or not.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ * 
+ * @note this function call will be ignored if the learning feature is disabled
+ */
+IX_ETH_DB_PUBLIC 
+void ixEthDBDatabaseMaintenance(void);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId  portID)
+ *
+ * @brief This function displays the Mac Ethernet MAC address filtering tables.
+ *
+ * It displays the MAC address, port ID, entry type (dynamic/static),and age for 
+ * the given port ID.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to display the MAC address entries
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized
+ * @retval IX_ETH_DB_FAIL record browser failed due to an internal busy or lock condition
+ *
+ * @note this function is deprecated and kept for compatibility reasons; use @ref ixEthDBFilteringDatabaseShowRecords instead
+ * 
+ * @see ixEthDBFilteringDatabaseShowRecords
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID);
+
+/** 
+ * @ingroup IxEthDB
+ *
+ * @fn void ixEthDBFilteringDatabaseShowAll(void)
+ *
+ * @brief Displays the MAC address recorded in the filtering database for all registered
+ * ports (see IxEthDBPortDefs.h), grouped by port ID.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @retval void
+ *
+ * @note this function is deprecated and kept for compatibility reasons; use @ref ixEthDBFilteringDatabaseShowRecords instead
+ * 
+ * @see ixEthDBFilteringDatabaseShowRecords
+ */
+IX_ETH_DB_PUBLIC 
+void ixEthDBFilteringDatabaseShowAll(void);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter)
+ *
+ * @brief This function displays per port database records, given a record type filter
+ *
+ * The supported record type filters are:
+ * 
+ * - IX_ETH_DB_FILTERING_RECORD - displays the non-VLAN filtering records (MAC address, age, static/dynamic)
+ * - IX_ETH_DB_FILTERING_VLAN_RECORD - displays the VLAN filtering records (MAC address, age, static/dynamic, VLAN ID, CFI, QoS class)
+ * - IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD - displays the previous two types of records
+ * - IX_ETH_DB_WIFI_RECORD - displays the WiFi header conversion records (MAC address, optional gateway MAC address) and WiFi header conversion parameters (BBSID, Duration/ID)
+ * - IX_ETH_DB_FIREWALL_RECORD - displays the firewall MAC address table and firewall operating mode (white list/black list)
+ * - IX_ETH_DB_ALL_RECORD_TYPES - displays all the record types
+ * - IX_ETH_DB_NO_RECORD_TYPE - displays only the port status (no records are displayed)
+ * 
+ * Additionally, the status of each port will be displayed, containg the following information: type, capabilities, enabled status, 
+ * aging enabled status, group membership and maximum frame size.
+ *
+ * The port ID can either be an actual port or IX_ETH_DB_ALL_PORTS, in which case the requested information
+ * will be displayed for all the ports (grouped by port)
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID ID of the port to display information on (use IX_ETH_DB_ALL_PORTS for all the ports)
+ * @param recordFilter record type filter
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is invalid
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
+ *
+ * @brief Sets the dependency port map for a port
+ *
+ * @param portID ID of the port to set the dependency map to
+ * @param dependencyPortMap new dependency map (as bitmap, each bit set indicates a port being included)
+ *
+ * This function is used to share filtering information between ports.
+ * By adding a port into another port's dependency map the target port
+ * filtering data will import the filtering data from the port it depends on.
+ * Any changes to filtering data for a port - such as adding, updating or removing records -
+ * will trigger updates in the filtering information for all the ports depending on
+ * on the updated port.
+ *
+ * For example, if ports 2 and 3 are set in the port 0 dependency map the filtering
+ * information for port 0 will also include the filtering information from ports 2 and 3.
+ * Adding a record to port 2 will also trigger an update not only on port 2 but also on
+ * port 0.
+ *
+ * The dependency map is a 256 bit array where each bit corresponds to a port corresponding to the
+ * bit offset (bit 0 - port 0, bit 1 - port 1 etc). Setting a bit to 1 indicates that the corresponding
+ * port is the port map. For example, a dependency port map of 0x14 consists in the ports with IDs 2 and 4.
+ * Note that the last bit (offset 255) is reserved and should never be set (it will be automatically
+ * cleared by the function).
+ *
+ * By default, each port has a dependency port map consisting only of itself, i.e. 
+ *
+ * @verbatim
+    IxEthDBPortMap portMap;
+    
+    // clear all ports from port map
+    memset(portMap, 0, sizeof (portMap)); 
+    
+    // include portID in port map 
+    portMap[portID / 8] = 1 << (portID % 8);
+   @endverbatim
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @note Setting dependency maps is useful for NPE ports, which benefit from automatic updates
+ * of filtering information. Setting dependency maps for user-defined ports is not an error
+ * but will have no actual effect.
+ * 
+ * @note Including a port in its own dependency map is not compulsory, however note that
+ * in this case updating the port will not trigger an update on the port itself, which 
+ * might not be the intended behavior
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>dependencyPortMap</i> pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Filtering is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
+ *
+ * @brief Retrieves the dependency port map for a port
+ *
+ * @param portID ID of the port to set the dependency map to
+ * @param dependencyPortMap location where the port dependency map is to be copied
+ *
+ * This function will copy the port dependency map to a user specified location.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>dependencyPortMap</i> pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Filtering is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC
+IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag)
+ *
+ * @brief Sets the default 802.1Q VLAN tag for a given port
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to set the default VLAN tag to
+ * @param vlanTag @ref IxEthDBVlanTag [in] - default 802.1Q VLAN tag
+ *
+ * The tag format has 16 bits and it is defined in the IEEE802.1Q specification.
+ * This tag will be used for tagging untagged frames (if enabled) and classifying
+ * unexpedited traffic into an internal traffic class (using the user priority field).
+ *
+ * <table border="1"> <caption> 802.1Q tag format </caption>
+ *    <tr> <td>  <b> 3 bits   <td> <b> 1 bit <td> <b> 12 bits </b>
+ *    <tr> <td> user priority <td>  CFI  <td>   VID
+ * </table>
+ *
+ * User Priority : Defines user priority, giving eight (2^3) priority levels. IEEE 802.1P defines 
+ * the operation for these 3 user priority bits
+ * 
+ * CFI : Canonical Format Indicator is always set to zero for Ethernet switches. CFI is used for 
+ * compatibility reason between Ethernet type network and Token Ring type network. If a frame received 
+ * at an Ethernet port has a CFI set to 1, then that frame should not be forwarded as it is to an untagged port. 
+ *
+ * VID : VLAN ID is the identification of the VLAN, which is basically used by the standard 802.1Q. 
+ * It has 12 bits and allow the id entification of 4096 (2^12) VLANs. Of the 4096 possible VIDs, a VID of 0 
+ * is used to identify priority frames and value 4095 (FFF) is reserved, so the maximum possible VLAN 
+ * configurations are 4,094.
+ * 
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_ETH_DB_INVALID_VLAN <i>vlanTag</i> argument does not parse to a valid 802.1Q VLAN tag
+ *
+ * @note a VLAN ID value of 0 indicates that the port is not part of any VLAN
+ * @note the value of the cannonical frame indicator (CFI) field is ignored, the 
+ * field being used only in frame tagging operations
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag)
+ *
+ * @brief Retrieves the default 802.1Q port VLAN tag for a given port (see also @ref ixEthDBPortVlanTagSet)
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to retrieve the default VLAN tag from
+ * @param vlanTag @ref IxEthDBVlanTag [out] - location to write the default port 802.1Q VLAN tag to
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid vlanTag pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag)
+ *
+ * @brief Sets the 802.1Q VLAN tag for a database record
+ *
+ * @param macAddr MAC address
+ * @param vlanTag 802.1Q VLAN tag
+ *
+ * This function is used together with @ref ixEthDBVlanTagGet to provide MAC-based VLAN classification support.
+ * Please note that the bridging application must contain specific code to make use of this feature (see below).
+ * 
+ * VLAN tags can be set only in IX_ETH_DB_FILTERING_RECORD or IX_ETH_DB_FILTERING_VLAN_RECORD type records.
+ * If to an IX_ETH_DB_FILTERING_RECORD type record is added a VLAN tag the record type is automatically
+ * changed to IX_ETH_DB_FILTERING_VLAN_RECORD. Once this has occurred the record type will never
+ * revert to a non-VLAN type (unless deleted and re-added).
+ *
+ * Record types used for different purposes (such as IX_ETH_DB_WIFI_RECORD) will be ignored by
+ * this function.
+ *
+ * After using this function to associate a VLAN ID with a MAC address the VLAN ID can be extracted knowing the
+ * MAC address using @ref ixEthDBVlanTagGet. This mechanism can be used to implement MAC-based VLAN classification
+ * if a bridging application searches for the VLAN tag when receiving a frame based on the source MAC address 
+ * (contained in the <i>ixp_ne_src_mac</i> field of the buffer header).
+ * If found in the database, the application can instruct the NPE to tag the frame by writing the VLAN tag
+ * in the <i>ixp_ne_vlan_tci</i> field of the buffer header. This way the NPE will inspect the Egress tagging
+ * rule associated with the given VLAN ID on the Tx port and tag the frame if Egress tagging on the VLAN is
+ * allowed. Additionally, Egress tagging can be forced by setting the <i>ixp_ne_tx_flags.tag_over</i> and 
+ * <i>ixp_ne_tx_flags.tag_mode</i> flags in the buffer header.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @note this function will <b>not</b> add a filtering record, it can only be used to update an existing one
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer
+ * @retval IX_ETH_DB_NO_SUCH_ADDR a filtering record with the specified MAC address was not found
+ * @retval IX_ETH_DB_INVALID_VLAN <i>vlanTag</i> argument does not parse to a valid 802.1Q VLAN tag
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag)
+ *
+ * @brief Retrieves the 802.1Q VLAN tag from a database record given the record MAC address
+ *
+ * @param macAddr MAC address
+ * @param vlanTag location to write the record 802.1Q VLAN tag to
+ *
+ * @note VLAN tags can be retrieved only from IX_ETH_DB_FILTERING_VLAN_RECORD type records
+ * 
+ * This function is used together with ixEthDBVlanTagSet to provide MAC-based VLAN classification support.
+ * Please note that the bridging application must contain specific code to make use of this feature (see @ref ixEthDBVlanTagSet).
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> or <i>vlanTag</i> pointer
+ * @retval IX_ETH_DB_NO_SUCH_ADDR a filtering record with the specified MAC address was not found
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID)
+ *
+ * @brief Adds a VLAN ID to a port's VLAN membership table
+ *
+ * Adding a VLAN ID to a port's VLAN membership table will cause frames tagged with the specified 
+ * VLAN ID to be accepted by the frame filter, if Ingress VLAN membership filtering is enabled.
+ * 
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to add the VLAN ID membership to
+ * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be added to the port membership table
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_VLAN vlanID is not a valid VLAN ID
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ *
+ * @note A port's default VLAN ID is always in its own membership table, hence there
+ * is no need to explicitly add it using this function (although it is not an error
+ * to do so)
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax)
+ *
+ * @brief Adds a VLAN ID range to a port's VLAN membership table
+ *
+ * All the VLAN IDs in the specified range will be added to the port VLAN
+ * membership table, including the range start and end VLAN IDs. Tagged frames with
+ * VLAN IDs in the specified range will be accepted by the frame filter, if Ingress VLAN
+ * membership filtering is enabled.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to add the VLAN membership range into
+ * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN ID range
+ * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN ID range
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_VLAN the specified VLAN IDs are invalid or do not constitute a range
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ *
+ * @note Is is valid to use the same VLAN ID for both vlanIDMin and vlanIDMax, in which case this
+ * function will behave as @ref ixEthDBPortVlanMembershipAdd
+ *
+ * @note A port's default VLAN ID is always in its own membership table, hence there is no need
+ * to explicitly add it using this function (although it is not an error to do so)
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID)
+ *
+ * @brief Removes a VLAN ID from a port's VLAN membership table
+ *
+ * Frames tagged with a VLAN ID which is not in a port's VLAN membership table
+ * will be discarded by the frame filter, if Ingress membership filtering is enabled.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to remove the VLAN ID membership from
+ * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be removed from the port membership table
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_INVALID_VLAN vlanID is not a valid VLAN ID
+ * @retval IX_ETH_DB_NO_PERMISSION attempted to remove the default VLAN ID
+ * from the port membership table (vlanID was set to the default port VLAN ID)
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ *
+ * @note A port's default VLAN ID cannot be removed from the port's membership
+ * table; attempting it will return IX_ETH_DB_NO_PERMISSION
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax)
+ *
+ * @brief Removes a VLAN ID range from a port's VLAN membership table
+ *
+ * All the VLAN IDs in the specified range will be removed from the port VLAN
+ * membership table, including the range start and end VLAN IDs. Tagged frames
+ * with VLAN IDs in the range will be discarded by the frame filter, if Ingress
+ * membership filtering is enabled.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to remove the VLAN membership range from
+ * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN ID range
+ * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN ID range
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_VLAN the specified VLAN IDs are invalid or do not constitute a range
+ * @retval IX_ETH_DB_NO_PERMISSION attempted to remove the default VLAN ID
+ * from the port membership table (both vlanIDMin and vlanIDMax were set to the default port VLAN ID)
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ *
+ * @note Is is valid to use the same VLAN ID for both vlanIDMin and vlanIDMax, in which case
+ * function will behave as @ref ixEthDBPortVlanMembershipRemove
+ *
+ * @note If the given range overlaps the default port VLAN ID this function
+ * will remove all the VLAN IDs in the range except for the port VLAN ID from its 
+ * own membership table. This situation will be silently dealt with (no error message
+ * will be returned) as long as the range contains more than one value (i.e. at least 
+ * one other value, apart from the default port VLAN ID). If the function is called 
+ * with the vlanIDMin and vlanIDMax parameters both set to the port default VLAN ID, the 
+ * function will infer that an attempt was specifically made to remove the default port 
+ * VLAN ID from the port membership table, in which case the return value will be 
+ * IX_ETH_DB_NO_PERMISSION.
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+ *
+ * @brief Sets a port's VLAN membership table
+ *
+ * Sets a port's VLAN membership table from a complete VLAN table containing all the possible
+ * 4096 VLAN IDs. The table format is an array containing 4096 bits (512 bytes), where each bit
+ * indicates whether the VLAN at that bit index is in the port's membership list (if set) or
+ * not (unset).
+ *
+ * The bit at index 0, indicating VLAN ID 0, indicates no VLAN membership and therefore no
+ * other bit must be set if bit 0 is set.
+ *
+ * The bit at index 4095 is reserved and should never be set (it will be ignored if set).
+ *
+ * The bit referencing the same VLAN ID as the default port VLAN ID should always be set, as 
+ * the membership list must contain at least the default port VLAN ID.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to set the VLAN membership table to
+ * @param vlanSet @ref IxEthDBVlanSet [in] - pointer to the VLAN membership table
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>vlanSet</i> pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+ *
+ * @brief Retrieves a port's VLAN membership table
+ *
+ * Retrieves the complete VLAN membership table from a port, containing all the possible
+ * 4096 VLAN IDs. The table format is an array containing 4096 bits (512 bytes), where each bit
+ * indicates whether the VLAN at that bit index is in the port's membership list (if set) or
+ * not (unset).
+ *
+ * The bit at index 0, indicating VLAN ID 0, indicates no VLAN membership and therefore no
+ * other bit will be set if bit 0 is set.
+ *
+ * The bit at index 4095 is reserved and will not be set (it will be ignored if set).
+ *
+ * The bit referencing the same VLAN ID as the default port VLAN ID will always be set, as 
+ * the membership list must contain at least the default port VLAN ID.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to retrieve the VLAN membership table from
+ * @param vlanSet @ref IxEthDBVlanSet [out] - pointer a location where the VLAN membership table will be
+ *                written to 
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>vlanSet</i> pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter)
+ *
+ * @brief Sets a port's acceptable frame type filter
+ *
+ * The acceptable frame type is one (or a combination) of the following values:
+ *    - IX_ETH_DB_ACCEPT_ALL_FRAMES       - accepts all the frames
+ *    - IX_ETH_DB_UNTAGGED_FRAMES         - accepts untagged frames
+ *    - IX_ETH_DB_VLAN_TAGGED_FRAMES      - accepts tagged frames
+ *    - IX_ETH_DB_PRIORITY_TAGGED_FRAMES  - accepts tagged frames with VLAN ID set to 0 (no VLAN membership)
+ *
+ * Except for using the exact values given above only the following combinations are valid:
+ *    - IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES
+ *    - IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_PRIORITY_TAGGED_FRAMES
+ *
+ * Please note that IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES is equivalent
+ * to IX_ETH_DB_ACCEPT_ALL_FRAMES.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @note by default the acceptable frame type filter is set to IX_ETH_DB_ACCEPT_ALL_FRAMES
+ *
+ * @note setting the acceptable frame type to PRIORITY_TAGGED_FRAMES is internally
+ * accomplished by changing the frame filter to VLAN_TAGGED_FRAMES and setting the
+ * VLAN membership list to include only VLAN ID 0; the membership list will need
+ * to be restored manually to an appropriate value if the acceptable frame type
+ * filter is changed back to ACCEPT_ALL_FRAMES or VLAN_TAGGED_FRAMES; failure to do so
+ * will filter all VLAN traffic bar frames tagged with VLAN ID 0
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to set the acceptable frame type filter to
+ * @param frameFilter @ref IxEthDBFrameFilter [in] - acceptable frame type filter
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid frame type filter
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter)
+ *
+ * @brief Retrieves a port's acceptable frame type filter 
+ *
+ * For a description of the acceptable frame types see @ref ixEthDBAcceptableFrameTypeSet
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID to retrieve the acceptable frame type filter from
+ * @param frameFilter @ref IxEthDBFrameFilter [out] - location to store the acceptable frame type filter
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>frameFilter</i> pointer argument
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable)
+ *
+ * @brief Sets a port's priority mapping table
+ *
+ * The priority mapping table is an 8x2 table mapping a QoS (user) priority into an internal
+ * traffic class. There are 8 valid QoS priorities (0..7, 0 being the lowest) which can be
+ * mapped into one of the 4 available traffic classes (0..3, 0 being the lowest).
+ * If a custom priority mapping table is not specified using this function the following
+ * default priority table will be used (as per IEEE 802.1Q and IEEE 802.1D):
+ * 
+ * <table border="1"> <caption> QoS traffic classes  </caption>
+ *    <tr> <td> <b> QoS priority <td> <b> Default traffic class <td> <b> Traffic type </b>
+ *    <tr> <td>      0       <td>           1           <td> Best effort, default class for unexpedited traffic
+ *    <tr> <td>      1       <td>           0           <td> Background traffic
+ *    <tr> <td>      2       <td>           0           <td> Spare bandwidth
+ *    <tr> <td>      3       <td>           1           <td> Excellent effort
+ *    <tr> <td>      4       <td>           2           <td> Controlled load
+ *    <tr> <td>      5       <td>           2           <td> Video traffic
+ *    <tr> <td>      6       <td>           3           <td> Voice traffic
+ *    <tr> <td>      7       <td>           3           <td> Network control
+ * </table>
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - port ID of the port to set the priority mapping table to
+ * @param priorityTable @ref IxEthDBPriorityTable [in] - location of the user priority table
+ *
+ * @note The provided table will be copied into internal data structures in EthDB and 
+ * can be deallocated by the called after this function has completed its execution, if
+ * so desired
+ *
+ * @warning The number of available traffic classes differs depending on the NPE images
+ * and queue configuration. Check IxEthDBQoS.h for up-to-date information on the availability of
+ * traffic classes. Note that specifiying a traffic class in the priority map which exceeds
+ * the system availability will produce an IX_ETH_DB_INVALID_PRIORITY return error code and no
+ * priority will be remapped.
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>priorityTable</i> pointer
+ * @retval IX_ETH_DB_INVALID_PRIORITY at least one priority value exceeds
+ * the current number of available traffic classes
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable)
+ *
+ * @brief Retrieves a port's priority mapping table
+ *
+ * The priority mapping table for the given port will be copied in the location
+ * specified by the caller using "priorityTable"
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID ID @ref IxEthDBPortId [in] - of the port to retrieve the priority mapping table from
+ * @param priorityTable @ref IxEthDBPriorityTable [out] - pointer to a user specified location where the table will be copied to
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid priorityTable pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass)
+ *
+ * @brief Sets one QoS/user priority => traffic class mapping in a port's priority mapping table
+ *
+ * This function establishes a mapping between a user (QoS) priority and an internal traffic class.
+ * The mapping will be saved in the port's priority mapping table. Use this function when not all
+ * the QoS priorities need remapping (see also @ref ixEthDBPriorityMappingTableSet)
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to set the mapping to
+ * @param userPriority @ref IxEthDBPriority [in] - user (QoS) priority, between 0 and 7 (0 being the lowest)
+ * @param trafficClass @ref IxEthDBPriority [in] - internal traffic class, between 0 and 3 (0 being the lowest)
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_PRIORITY <i>userPriority</i> out of range or
+ * <i>trafficClass</i> is beyond the number of currently available traffic classes
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass)
+ *
+ * @brief Retrieves one QoS/user priority => traffic class mapping in a port's priority mapping table
+ *
+ * This function retrieves the internal traffic class associated with a QoS (user) priority from a given
+ * port's priority mapping table. Use this function when not all the QoS priority mappings are 
+ * required (see also @ref ixEthDBPriorityMappingTableGet)
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to set the mapping to
+ * @param userPriority @ref IxEthDBPriority [in] - user (QoS) priority, between 0 and 7 (0 being the lowest)
+ * @param trafficClass @ref IxEthDBPriority [out] - location to write the corresponding internal traffic class to
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_PRIORITY invalid userPriority value (out of range)
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>trafficClass</i> pointer argument
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled)
+ *
+ * @brief Enables or disables Egress VLAN tagging for a port and a given VLAN
+ *
+ * This function enables or disables Egress VLAN tagging for the given port and VLAN ID.
+ * If the VLAN tagging for a certain VLAN ID is enabled then all the frames to be
+ * transmitted on the given port tagged with the same VLAN ID will be transmitted in a tagged format.
+ * If tagging is not enabled for the given VLAN ID, the VLAN tag from the frames matching
+ * this VLAN ID will be removed (the frames will be untagged).
+ *
+ * VLAN ID 4095 is reserved and should never be used with this function.
+ * VLAN ID 0 has the special meaning of "No VLAN membership" and it is used in this
+ * context to allow the port to send priority-tagged frames or not.
+ *
+ * By default, no Egress VLAN tagging is enabled on any port.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the VLAN ID Egress tagging on
+ * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be matched against outgoing frames
+ * @param enabled BOOL [in] - true to enable Egress VLAN tagging on the port and given VLAN, and
+ *                false to disable Egress VLAN tagging
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range)
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled)
+ *
+ * @brief Retrieves the Egress VLAN tagging enabling status for a port and VLAN ID
+ *
+ * @param portID [in] - ID of the port to extract the Egress VLAN ID tagging status from
+ * @param vlanID VLAN [in] - ID whose tagging status is to be extracted
+ * @param enabled [in] - user-specifed location where the status is copied to; following
+ * the successfull execution of this function the value will be true if Egress VLAN
+ * tagging is enabled for the given port and VLAN ID, and false otherwise
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @see ixEthDBEgressVlanEntryTaggingEnabledGet
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range)
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>enabled</i> argument pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled)
+ *
+ * @brief Enables or disables Egress VLAN tagging for a port and given VLAN range
+ *
+ * This function is very similar to @ref ixEthDBEgressVlanEntryTaggingEnabledSet with the
+ * difference that it can manipulate the Egress tagging status on multiple VLAN IDs,
+ * defined by a contiguous range. Note that both limits in the range are explicitly 
+ * included in the execution of this function.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the VLAN ID Egress tagging on
+ * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN range to be matched against outgoing frames
+ * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN range to be matched against outgoing frames
+ * @param enabled BOOL [in] - true to enable Egress VLAN tagging on the port and given VLAN range,
+ *                and false to disable Egress VLAN tagging
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range), or do not constitute a range
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_ETH_DB_NO_PERMISSION attempted to explicitly remove the default port VLAN ID from the tagging table
+ * @retval IX_FAIL unknown OS or NPE communication error
+ *
+ * @note Specifically removing the default port VLAN ID from the Egress tagging table by setting both vlanIDMin and vlanIDMax
+ * to the VLAN ID portion of the PVID is not allowed by this function and will return IX_ETH_DB_NO_PERMISSION.
+ * However, this can be circumvented, should the user specifically desire this, by either using a 
+ * larger range (vlanIDMin < vlanIDMax) or by using ixEthDBEgressVlanEntryTaggingEnabledSet.
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+ *
+ * @brief Sets the complete Egress VLAN tagging table for a port
+ *
+ * This function is used to set the VLAN tagging/untagging per VLAN ID for a given port
+ * covering the entire VLAN ID range (0..4094). The <i>vlanSet</i> parameter is a 4096
+ * bit array, each bit indicating the Egress behavior for the corresponding VLAN ID.
+ * If a bit is set then outgoing frames with the corresponding VLAN ID will be transmitted
+ * with the VLAN tag, otherwise the frame will be transmitted without the VLAN tag.
+ *
+ * Bit 0 has a special significance, indicating tagging or tag removal for priority-tagged
+ * frames.
+ *
+ * Bit 4095 is reserved and should never be set (it will be ignored if set).
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port whose Egress VLAN tagging behavior is set
+ * @param vlanSet @ref IxEthDBVlanSet [in] - 4096 bit array controlling per-VLAN tagging and untagging 
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>vlanSet</i> pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ *
+ * @warning This function will automatically add the default port VLAN ID to the Egress tagging table
+ * every time it is called. The user should manually call ixEthDBEgressVlanEntryTaggingEnabledSet to
+ * prevent tagging on the default port VLAN ID if the default behavior is not intended.
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
+ *
+ * @brief Retrieves the complete Egress VLAN tagging table from a port
+ *
+ * This function copies the 4096 bit table controlling the Egress VLAN tagging into a user specified
+ * area. Each bit in the array indicates whether tagging for the corresponding VLAN (the bit position
+ * in the array) is enabled (the bit is set) or not (the bit is unset). 
+ *
+ * Bit 4095 is reserved and should not be set (it will be ignored if set).
+ *
+ * @see ixEthDBEgressVlanTaggingEnabledSet
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port whose Egress VLAN tagging behavior is retrieved
+ * @param vlanSet @ref IxEthDBVlanSet [out] - user location to copy the Egress tagging table into; should have
+ * room to store 4096 bits (512 bytes)
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>vlanSet</i> pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction)
+ *
+ * @brief Sets the Ingress VLAN tagging behavior for a port
+ *
+ * A port's Ingress tagging behavior is controlled by the taggingAction parameter,
+ * which can take one of the following values:
+ * 
+ * - IX_ETH_DB_PASS_THROUGH - leaves the frame unchanged (does not add or remove the VLAN tag)
+ * - IX_ETH_DB_ADD_TAG - adds the VLAN tag if not present, using the default port VID
+ * - IX_ETH_DB_REMOVE_TAG - removes the VLAN tag if present
+ * 
+ * @param portID @ref IxEthDBPortId [in] - ID of the port whose Ingress VLAN tagging behavior is set
+ * @param taggingAction @ref IxEthDBTaggingAction [in] - tagging behavior for the port
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>taggingAction</i> argument
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction)
+ *
+ * @brief Retrieves the Ingress VLAN tagging behavior from a port (see @ref ixEthDBIngressVlanTaggingEnabledSet)
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port whose Ingress VLAN tagging behavior is set
+ * @param taggingAction @ref IxEthDBTaggingAction [out] - location where the tagging behavior for the port is written to
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>taggingAction</i> pointer argument
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable)
+ *
+ * @brief Enables or disables port ID extraction
+ *
+ * This feature can be used in the situation when a multi-port device (e.g. a switch) 
+ * is connected to an IXP4xx port and the device can provide incoming frame port 
+ * identification by tagging the TPID field in the Ethernet frame. Enabling
+ * port extraction will instruct the NPE to copy the TPID field from the frame and 
+ * place it in the <i>ixp_ne_src_port</i> of the <i>ixp_buf</i> header. In addition,
+ * the NPE restores the TPID field to 0.
+ *
+ * If the frame is not tagged the NPE will fill the <i>ixp_ne_src_port</i> with the 
+ * port ID of the MII interface the frame was received from.
+ *
+ * The TPID field is the least significant byte of the type/length field, which is 
+ * normally set to 0x8100 for 802.1Q-tagged frames.
+ *
+ * This feature is disabled by default.
+ *
+ * @param portID ID of the port to configure port ID extraction on
+ * @param enable true to enable port ID extraction and false to disable it
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet)
+ *
+ * @brief Retrieves the feature capability set for a port
+ *
+ * This function retrieves the feature capability set for a port or the common capabilities shared between all 
+ * the ports, writing the feature capability set in a user specified location.
+ *
+ * The feature capability set will consist of a set formed by OR-ing one or more of the following values:
+ * - IX_ETH_DB_LEARNING - Learning feature; enables EthDB to learn MAC address (filtering) records, including 802.1Q enabled records
+ * - IX_ETH_DB_FILTERING - Filtering feature; enables EthDB to communicate with the NPEs for downloading filtering information in the NPEs; depends on the learning feature
+ * - IX_ETH_DB_VLAN_QOS - VLAN/QoS feature; enables EthDB to configure NPEs to operate in VLAN/QoS aware modes
+ * - IX_ETH_DB_FIREWALL - Firewall feature; enables EthDB to configure NPEs to operate in firewall mode, using white/black address lists
+ * - IX_ETH_DB_SPANNING_TREE_PROTOCOL - Spanning tree protocol feature; enables EthDB to configure the NPEs as STP nodes
+ * - IX_ETH_DB_WIFI_HEADER_CONVERSION - WiFi 802.3 to 802.11 header conversion feature; enables EthDB to handle WiFi conversion data
+ *
+ * Note that EthDB provides only the LEARNING feature for non-NPE ports.
+ * 
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to retrieve the capability set for 
+ * (use IX_ETH_DB_ALL_PORTS to retrieve the common capabilities shared between all the ports)
+ * @param featureSet @ref IxEthDBFeature [out] - location where the capability set will be written to
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>featureSet</i> pointer
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enabled)
+ *
+ * @brief Enables or disables one or more EthDB features
+ *
+ * Selects one or more features (see @ref ixEthDBFeatureCapabilityGet for a description of the supported
+ * features) to be enabled or disabled on the selected port (or all the ports).
+ *
+ * Note that some features are mutually incompatible:
+ * - IX_ETH_DB_FILTERING is incompatible with IX_ETH_DB_WIFI_HEADER_CONVERSION
+ *
+ * Also note that some features require other features to be enabled: 
+ * - IX_ETH_DB_FILTERING requires IX_ETH_DB_LEARNING
+ *
+ * This function will either enable the entire selected feature set for the selected port (or all the ports),
+ * in which case it will return IX_ETH_DB_SUCCESS, or in case of error it will not enable any feature at all
+ * and return an appropriate error message.
+ *
+ * The following features are enabled by default (for ports with the respective capability), 
+ * for compatibility reasons with previous versions of CSR:
+ * - IX_ETH_DB_LEARNING
+ * - IX_ETH_DB_FILTERING
+ *
+ * All other features are disabled by default and require manual enabling using ixEthDBFeatureEnable.
+ *
+ * <b>Default settings for VLAN, QoS, Firewall and WiFi header conversion features:</b>
+ *
+ * <i>VLAN</i>
+ *
+ * When the VLAN/QoS feature is enabled for a port for the first time the default VLAN behavior 
+ * of the port is set to be as <b>permissive</b> (it will accept all the frames) and 
+ * <b>non-interferential</b> (it will not change any frames) as possible:
+ * - the port VLAN ID (VID) is set to 0
+ * - the Ingress acceptable frame filter is set to accept all frames
+ * - the VLAN port membership is set to the complete VLAN range (0 - 4094)
+ * - the Ingress tagging mode is set to pass-through (will not change frames)
+ * - the Egress tagging mode is to send tagged frames in the entire VLAN range (0 - 4094)
+ *
+ * Note that further disabling and re-enabling the VLAN feature for a given port will not reset the port VLAN behavior
+ * to the settings listed above. Any VLAN settings made by the user are kept.
+ *
+ * <i>QoS</i>
+ *
+ * The following default priority mapping table will be used (as per IEEE 802.1Q and IEEE 802.1D):
+ * 
+ * <table border="1"> <caption> QoS traffic classes  </caption>
+ *    <tr> <td> <b> QoS priority <td> <b> Default traffic class <td> <b> Traffic type </b>
+ *    <tr> <td>      0       <td>           1           <td> Best effort, default class for unexpedited traffic
+ *    <tr> <td>      1       <td>           0           <td> Background traffic
+ *    <tr> <td>      2       <td>           0           <td> Spare bandwidth
+ *    <tr> <td>      3       <td>           1           <td> Excellent effort
+ *    <tr> <td>      4       <td>           2           <td> Controlled load
+ *    <tr> <td>      5       <td>           2           <td> Video traffic
+ *    <tr> <td>      6       <td>           3           <td> Voice traffic
+ *    <tr> <td>      7       <td>           3           <td> Network control
+ * </table>
+ *
+ * <i> Firewall </i>
+ *  
+ * The port firewall is configured by default in <b>black-list mode</b>, and the firewall address table is empty.
+ * This means the firewall will not filter any frames until the feature is configured and the firewall table is
+ * downloaded to the NPE.
+ *
+ * <i> Spanning Tree </i>
+ *
+ * The port is set to <b>STP unblocked mode</b>, therefore it will accept all frames until re-configured.
+ *
+ * <i> WiFi header conversion </i>
+ *
+ * The WiFi header conversion database is empty, therefore no actual header conversion will take place until this
+ * feature is configured and the conversion table downloaded to the NPE.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the features on (use IX_ETH_DB_ALL_PORTS for all the ports)
+ * @param feature @ref IxEthDBFeature [in] - feature or feature set to enable or disable
+ * @param enabled BOOL [in] - true to enable the feature and false to disable it
+ * 
+ * @note Certain features, from a functional point of view, cannot be disabled as such at NPE level;
+ * when such features are set to <i>disabled</i> using the EthDB API they will be configured in such
+ * a way to determine a behavior equivalent to the feature being disabled. As well as this, disabled
+ * features cannot be configured or accessed via the EthDB API (except for getting their status).
+ *
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_NO_PERMISSION attempted to enable mutually exclusive features, 
+ * or a feature that depends on another feature which is not present or enabled
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE at least one of the features selected is unavailable
+ * @retval IX_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enabled);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled)
+ *
+ * @brief Retrieves the availability and status of a feature set
+ *
+ * This function returns the availability and status for a feature set.
+ * Note that if more than one feature is selected (e.g. IX_ETH_DB_LEARNING | IX_ETH_DB_FILTERING)
+ * the "present" and "enabled" return values will be set to true only if all the features in the
+ * feature set are present and enabled (not only some). 
+ * 
+ * @param portID @ref IxEthDBPortId [in] - ID of the port 
+ * @param feature @ref IxEthDBFeature [in] - identifier of the feature to retrieve the status for
+ * @param present BOOL [out] - location where a boolean flag indicating whether this feature is present will be written to
+ * @param enabled BOOL [out] - location where a boolean flag indicating whether this feature is enabled will be written to
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG either <i>present</i> or <i>enabled</i> pointer argument is invalid
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value)
+ *
+ * @brief Retrieves the value of a feature property
+ *
+ * The EthDB features usually contain feature-specific properties describing or
+ * controlling how the feature operates. While essential properties (e.g. the
+ * firewall operating mode) have their own API, secondary properties can be 
+ * retrieved using this function.
+ *
+ * Properties can be read-only or read-write. ixEthDBFeaturePropertyGet operates with
+ * both types of features.
+ *
+ * Properties have types associated with them. A descriptor indicating the property
+ * type is returned in the <i>type</i> argument for convenience.
+ *
+ * The currently supported properties and their corresponding features are as follows:
+ *
+ * <table border="1"> <caption> Properties for IX_ETH_DB_VLAN_QOS </caption>
+ *    <tr> <td> <b>        Property identifier                  <td> <b> Property type          <td> <b> Property value                   <td> <b> Read-Only </b>
+ *    <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY      <td> IX_ETH_DB_INTEGER_PROPERTY <td> number of internal traffic classes   <td> Yes
+ *    <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 0 <td> Yes
+ *    <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_1_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 1 <td> Yes
+ *    <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_2_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 2 <td> Yes
+ *    <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_3_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 3 <td> Yes
+ *    <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_4_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 4 <td> Yes
+ *    <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_5_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 5 <td> Yes
+ *    <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_6_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 6 <td> Yes
+ *    <tr> <td> IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY <td> IX_ETH_DB_INTEGER_PROPERTY <td> queue assignment for traffic class 7 <td> Yes
+ * </table>
+ * 
+ * @see ixEthDBFeaturePropertySet
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port 
+ * @param feature @ref IxEthDBFeature [in] - EthDB feature for which the property is retrieved
+ * @param property @ref IxEthDBProperty [in] - property identifier
+ * @param type @ref IxEthDBPropertyType [out] - location where the property type will be stored
+ * @param value void [out] - location where the property value will be stored
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_INVALID_ARG invalid property identifier, <i>type</i> or <i>value</i> pointer arguments
+ * @retval IX_ETH_DB_FAIL incorrect property value or unknown error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value)
+ *
+ * @brief Sets the value of a feature property
+ *
+ * Unlike @ref ixEthDBFeaturePropertyGet, this function operates only with read-write properties
+ *
+ * The currently supported properties and their corresponding features are as follows:
+ *
+ *   - IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE (for IX_ETH_DB_VLAN_QOS): freezes the availability of traffic classes
+ *     to the number of traffic classes currently in use
+ *
+ * Note that this function creates deep copies of the property values; once the function is invoked the client 
+ * can free or reuse the memory area containing the original property value.
+ *
+ * Copy behavior for different property types is defined as follows:
+ *
+ *   - IX_ETH_DB_INTEGER_PROPERTY   - 4 bytes are copied from the source location
+ *   - IX_ETH_DB_STRING_PROPERTY    - the source string will be copied up to the NULL '\0' string terminator, maximum of 255 characters
+ *   - IX_ETH_DB_MAC_ADDR_PROPERTY  - 6 bytes are copied from the source location
+ *   - IX_ETH_DB_BOOL_PROPERTY      - 4 bytes are copied from the source location; the only allowed values are true (1L) and false (0L)
+ *
+ * @see ixEthDBFeaturePropertySet
+ *
+ * @warning IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE is provided for EthAcc internal use; 
+ * do not attempt to set this property directly
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port 
+ * @param feature @ref IxEthDBFeature [in] - EthDB feature for which the property is set
+ * @param property @ref IxEthDBProperty [in] - property identifier
+ * @param value void [in] - location where the property value is to be copied from
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_INVALID_ARG invalid property identifier, <i>value</i> pointer, or invalid property value
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType)
+ *
+ * @brief Deletes a set of record types from the Ethernet Database
+ *
+ * This function deletes all the records of certain types (specified in the recordType filter)
+ * associated with a port. Additionally, the IX_ETH_DB_ALL_PORTS value can be used as port ID
+ * to indicate that the specified record types should be deleted for all the ports.
+ *
+ * The record type filter can be an ORed combination of the following types:
+ *
+ * <caption> Record types </caption>
+ *    - IX_ETH_DB_FILTERING_RECORD      <table><caption> Filtering record </caption>
+ *                                               <tr><td> MAC address <td> static/dynamic type <td> age </tr>
+ *                                             </table> 
+ *
+ *    - IX_ETH_DB_FILTERING_VLAN_RECORD <table><caption> VLAN-enabled filtering record </caption>
+ *                                               <tr><td> MAC address <td> static/dynamic type <td> age <td> 802.1Q tag </tr>
+ *                                             </table> 
+ *
+ *    - IX_ETH_DB_WIFI_RECORD           <table><caption> WiFi header conversion record </caption>
+ *                                                <tr><td> MAC address <td> optional gateway MAC address <td> </tr>
+ *                                             </table>
+ *
+ *    - IX_ETH_DB_FIREWALL_RECORD       <table><caption> Firewall record </caption>
+ *                                                <tr><td> MAC address </tr>
+ *                                             </table>
+ *    - IX_ETH_DB_ALL_RECORD_TYPES
+ * 
+ * Any combination of the above types is valid e.g. 
+ *
+ *    (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD | IX_ETH_DB_FIREWALL_RECORD), 
+ *
+ * although some might be redundant (it is not an error to do so) e.g.
+ *
+ *    (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_ALL_RECORD_TYPES)
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param recordType @ref IxEthDBRecordType [in] - record type filter
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>recordType</i> filter
+ *
+ * @note If the record type filter contains any unrecognized value (hence the 
+ * IX_ETH_DB_INVALID_ARG error value is returned) no actual records will be deleted.
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Adds an "Access Point to Station" record to the database, for 802.3 => 802.11 frame 
+ * header conversion
+ *
+ * Frame header conversion is controlled by the set of MAC addresses
+ * added using @ref ixEthDBWiFiStationEntryAdd and @ref ixEthDBWiFiAccessPointEntryAdd.
+ * Conversion arguments are added using @ref ixEthDBWiFiFrameControlSet, 
+ * @ref ixEthDBWiFiDurationIDSet and @ref ixEthDBWiFiBBSIDSet.
+ *
+ * Note that adding the same MAC address twice will not return an error
+ * (but will not accomplish anything either), while re-adding a record previously added
+ * as an "Access Point to Access Point" will migrate the record to the "Access Point
+ * to Station" type.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port 
+ * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to add
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_INVALID_ARG macAddr is an invalid pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled 
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_NOMEM maximum number of records reached
+ * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
+ *
+ * @brief Adds an "Access Point to Access Point" record to the database
+ *
+ * @see ixEthDBWiFiStationEntryAdd
+ *
+ * Note that adding the same MAC address twice will simply overwrite the previously
+ * defined gateway MAC address value in the same record, if the record was previously of the
+ * "Access Point to Access Point" type.
+ *
+ * Re-adding a MAC address as "Access Point to Access Point", which was previously added as 
+ * "Access Point to Station" will migrate the record type to "Access Point to Access Point" and
+ * record the gateway MAC address.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port 
+ * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to add
+ * @param gatewayMacAddr @ref IxEthDBMacAddr [in] - MAC address of the gateway Access Point
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG macAddr is an invalid pointer
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled 
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> or <i>gatewayMacAddr</i> pointer argument
+ * @retval IX_ETH_DB_NOMEM maximum number of records reached
+ * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Removes a WiFi station record
+ *
+ * This function removes both types of WiFi records ("Access Point to Station" and
+ * "Access Point to Access Point").
+ * 
+ * @param portID @ref IxEthDBPortId [in] - ID of the port 
+ * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to remove
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_NO_SUCH_ADDR specified address was not found in the database
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled 
+ * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID)
+ *
+ * @brief Downloads the MAC address table for 802.3 => 802.11 frame header
+ * conversion to the NPE
+ *
+ * Note that the frame conversion MAC address table must be individually downloaded
+ * to each NPE for which the frame header conversion feature is enabled (i.e. it
+ * is not possible to specify IX_ETH_DB_ALL_PORTS).
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port 
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl)
+ *
+ * @brief Sets the GlobalFrameControl field
+ *
+ * The GlobalFrameControl field is a 2-byte value inserted in the <i>Frame Control</i>
+ * field for all 802.3 to 802.11 frame header conversions
+ * 
+ * @param portID @ref IxEthDBPortId [in] - ID of the port
+ * @param frameControl UINT16 [in] - GlobalFrameControl value
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID)
+ *
+ * @brief Sets the GlobalDurationID field
+ *
+ * The GlobalDurationID field is a 2-byte value inserted in the <i>Duration/ID</i>
+ * field for all 802.3 to 802.11 frame header conversions
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port 
+ * @param durationID UINT16 [in] - GlobalDurationID field
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid)
+ *
+ * @brief Sets the BBSID field
+ *
+ * The BBSID field is a 6-byte value which
+ * identifies the infrastructure of the service set managed 
+ * by the Access Point having the IXP400 as its processor. The value
+ * is written in the <i>BBSID</i> field of the 802.11 frame header.
+ * The BBSID value is the MAC address of the Access Point.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port 
+ * @param bbsid @ref IxEthDBMacAddr [in] - pointer to 6 bytes containing the BSSID
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>bbsid</i> pointer argument
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked)
+ *
+ * @brief Sets the STP blocked/unblocked state for a port
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port 
+ * @param blocked BOOL [in] - true to set the port as STP blocked, false to set it as unblocked
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Spanning Tree Protocol feature not enabled
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked)
+ *
+ * @brief Retrieves the STP blocked/unblocked state for a port
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port 
+ * @param blocked BOOL * [in] - set to true if the port is STP blocked, false otherwise
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>blocked</i> pointer argument
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Spanning Tree Protocol feature not enabled
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode)
+ *
+ * @brief Sets the firewall mode to use white or black listing
+ *
+ * When enabled, the NPE MAC address based firewall support operates in two modes:
+ *
+ * - white-list mode (MAC address based admission) 
+ *    - <i>mode</i> set to IX_ETH_DB_FIREWALL_WHITE_LIST
+ *    - only packets originating from MAC addresses contained in the firewall address list
+ *      are allowed on the Rx path
+ * - black-list mode (MAC address based blocking)  
+ *    - <i>mode</i> set to IX_ETH_DB_FIREWALL_BLACK_LIST
+ *    - packets originating from MAC addresses contained in the firewall address list
+ *      are discarded
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port 
+ * @param mode @ref IxEthDBFirewallMode [in] - firewall mode (IX_ETH_DB_FIREWALL_WHITE_LIST or IX_ETH_DB_FIREWALL_BLACK_LIST)
+ *
+ * @note by default the firewall operates in black-list mode with an empty address
+ * list, hence it doesn't filter any packets
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled 
+ * @retval IX_ETH_DB_INVALID_ARGUMENT <i>mode</i> argument is not a valid firewall configuration mode
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+*/
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable)
+ *
+ * @brief Enables or disables invalid MAC address filtering
+ *
+ * According to IEEE802 it is illegal for a source address to be a multicast
+ * or broadcast address. If this feature is enabled the NPE inspects the source
+ * MAC addresses of incoming frames and discards them if invalid addresses are
+ * detected.
+ *
+ * By default this service is enabled, if the firewall feature is supported by the
+ * NPE image.
+ *
+ * @param portID ID of the port 
+ * @param enable true to enable invalid MAC address filtering and false to disable it
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled 
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Adds a MAC address to the firewall address list
+ *
+ * Note that adding the same MAC address twice will not return an error
+ * but will not actually accomplish anything.
+ *
+ * The firewall MAC address list has a limited number of entries; once
+ * the maximum number of entries has been reached this function will failed
+ * to add more addresses, returning IX_ETH_DB_NOMEM.
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port 
+ * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to be added
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_NOMEM maximum number of records reached
+ * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled 
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
+ *
+ * @brief Removes a MAC address from the firewall address list
+ *
+ * @param portID @ref IxEthDBPortId [in] - ID of the port 
+ * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to be removed
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_NO_SUCH_ADDR address not found
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled 
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID)
+ *
+ * @brief Downloads the MAC firewall table to a port
+ *
+ * @param portID ID of the port 
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier
+ * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized
+ * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled 
+ * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field)
+ *
+ * @brief Adds a user-defined field to a database record
+ *
+ * This function associates a user-defined field to a database record.
+ * The user-defined field is passed as a <i>(void *)</i> parameter, hence it can be used
+ * for any purpose (such as identifying a structure). Retrieving the user-defined field from
+ * a record is done using @ref ixEthDBUserFieldGet. Note that EthDB never uses the user-defined
+ * field for any internal operation and it is not aware of the significance of its contents. The
+ * field is only stored as a pointer.
+ *
+ * The database record is identified using a combination of the given parameters, depending on the record type.
+ * All the record types require the record MAC address.
+ *
+ * - IX_ETH_DB_FILTERING_RECORD requires only the MAC address
+ * - IX_ETH_DB_VLAN_FILTERING_RECORD requires the MAC address and the VLAN ID
+ * - IX_ETH_DB_WIFI_RECORD requires the MAC address and the portID
+ * - IX_ETH_DB_FIREWALL_RECORD requires the MAC address and the portID
+ *
+ * Please note that if a parameter is not required it is completely ignored (it does not undergo parameter checking).
+ * The user-defined field can be cleared using a <b>NULL</b> <i>field</i> parameter.
+ *
+ * @param recordType @ref IxEthDBRecordType [in] - type of record (can be IX_ETH_DB_FILTERING_RECORD, 
+ * IX_ETH_DB_FILTERING_VLAN_RECORD, IX_ETH_DB_WIFI_RECORD or IX_ETH_DB_FIREWALL_RECORD)
+ * @param portID @ref IxEthDBPortId [in] - ID of the port (required only for WIFI and FIREWALL records) 
+ * @param macAddr @ref IxEthDBMacAddr * [in] - MAC address of the record
+ * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID of the record (required only for FILTERING_VLAN records)
+ * @param field void * [in] - user defined field
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID was required but it is not a valid port identifier
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> pointer argument
+ * @retval IX_ETH_DB_NO_SUCH_ADDR record not found
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field);
+
+/**
+ * @ingroup IxEthDB
+ *
+ * @fn IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void **field)
+ *
+ * @brief Retrieves a user-defined field from a database record
+ *
+ * The database record is identified using a combination of the given parameters, depending on the record type.
+ * All the record types require the record MAC address.
+ *
+ * - IX_ETH_DB_FILTERING_RECORD requires only the MAC address
+ * - IX_ETH_DB_VLAN_FILTERING_RECORD requires the MAC address and the VLAN ID
+ * - IX_ETH_DB_WIFI_RECORD requires the MAC address and the portID
+ * - IX_ETH_DB_FIREWALL_RECORD requires the MAC address and the portID
+ *
+ * Please note that if a parameter is not required it is completely ignored (it does not undergo parameter checking).
+ *
+ * If no user-defined field was registered with the specified record then <b>NULL</b> will be written
+ * at the location specified by <i>field</i>.
+ *
+ * @param recordType type of record (can be IX_ETH_DB_FILTERING_RECORD, IX_ETH_DB_FILTERING_VLAN_RECORD, IX_ETH_DB_WIFI_RECORD 
+ * or IX_ETH_DB_FIREWALL_RECORD)
+ * @param portID ID of the port (required only for WIFI and FIREWALL records) 
+ * @param macAddr MAC address of the record
+ * @param vlanID VLAN ID of the record (required only for FILTERING_VLAN records)
+ * @param field location to write the user defined field into
+ * 
+ * @retval IX_ETH_DB_SUCCESS operation completed successfully
+ * @retval IX_ETH_DB_INVALID_PORT portID was required but it is not a valid port identifier
+ * @retval IX_ETH_DB_INVALID_ARG invalid <i>macAddr</i> or <i>field</i> pointer arguments
+ * @retval IX_ETH_DB_NO_SUCH_ADDR record not found
+ */
+IX_ETH_DB_PUBLIC 
+IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portId, IxEthDBVlanId vlanID, void **field);
+
+/**
+ * @}
+ */
+
+#endif /* IxEthDB_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthDBLocks_p.h b/marvell/uboot/drivers/net/npe/include/IxEthDBLocks_p.h
new file mode 100644
index 0000000..91ab441
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthDBLocks_p.h
@@ -0,0 +1,98 @@
+/**
+ * @file IxEthAccDBLocks_p.h
+ *
+ * @brief Definition of transaction lock stacks and lock utility macros
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxEthAccDBLocks_p_H
+#define IxEthAccDBLocks_p_H
+
+#include "IxOsPrintf.h"
+
+/* Lock and lock stacks */
+typedef struct
+{
+    IxOsalFastMutex* locks[MAX_LOCKS];
+    UINT32 stackPointer, basePointer;
+} LockStack;
+
+#define TRY_LOCK(mutex) \
+    { \
+        if (ixOsalFastMutexTryLock(mutex) != IX_SUCCESS) \
+        { \
+            return IX_ETH_DB_BUSY; \
+        } \
+    }
+
+
+#define UNLOCK(mutex) { ixOsalFastMutexUnlock(mutex); }
+
+#define INIT_STACK(stack) \
+    { \
+        (stack)->basePointer  = 0; \
+        (stack)->stackPointer = 0; \
+    }
+
+#define PUSH_LOCK(stack, lock) \
+    { \
+        if ((stack)->stackPointer == MAX_LOCKS) \
+        { \
+            ERROR_LOG("Ethernet DB: maximum number of elements in a lock stack has been exceeded on push, heavy chaining?\n"); \
+            UNROLL_STACK(stack); \
+            \
+            return IX_ETH_DB_NOMEM; \
+        } \
+        \
+        if (ixOsalFastMutexTryLock(lock) == IX_SUCCESS) \
+        { \
+            (stack)->locks[(stack)->stackPointer++] = (lock); \
+        } \
+        else \
+        { \
+            UNROLL_STACK(stack); \
+            \
+            return IX_ETH_DB_BUSY; \
+        } \
+    }
+
+#define POP_LOCK(stack) \
+    { \
+        ixOsalFastMutexUnlock((stack)->locks[--(stack)->stackPointer]); \
+    }
+
+#define UNROLL_STACK(stack) \
+    { \
+        while ((stack)->stackPointer > (stack)->basePointer) \
+        { \
+            POP_LOCK(stack); \
+        } \
+    }
+
+#define SHIFT_STACK(stack) \
+    { \
+        if ((stack)->basePointer == MAX_LOCKS - 1) \
+        { \
+            ERROR_LOG("Ethernet DB: maximum number of elements in a lock stack has been exceeded on shift, heavy chaining?\n"); \
+            UNROLL_STACK(stack); \
+            \
+            return IX_ETH_DB_BUSY; \
+        } \
+        \
+        ixOsalFastMutexUnlock((stack)->locks[(stack)->basePointer++]); \
+    }
+
+#endif /* IxEthAccDBLocks_p_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthDBLog_p.h b/marvell/uboot/drivers/net/npe/include/IxEthDBLog_p.h
new file mode 100644
index 0000000..b357623
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthDBLog_p.h
@@ -0,0 +1,203 @@
+/**
+ * @file IxEthDBLog_p.h
+ *
+ * @brief definitions of log macros and log configuration
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include <IxOsal.h>
+
+#ifdef IX_UNIT_TEST
+#define NULL_PRINT_ROUTINE(format, arg...) /* nothing */
+#else
+#define NULL_PRINT_ROUTINE if(0) printf
+#endif
+
+/***************************************************
+ *                 Globals                         *
+ ***************************************************/
+/* safe to permanently leave these on */
+#define HAS_ERROR_LOG
+#define HAS_ERROR_IRQ_LOG
+#define HAS_WARNING_LOG
+
+/***************************************************
+ *              Log Configuration                  *
+ ***************************************************/
+
+/* debug output can be turned on unless specifically
+   declared as a non-debug build */
+#ifndef NDEBUG
+
+#undef HAS_EVENTS_TRACE
+#undef HAS_EVENTS_VERBOSE_TRACE
+
+#undef HAS_SUPPORT_TRACE
+#undef HAS_SUPPORT_VERBOSE_TRACE
+
+#undef HAS_NPE_TRACE
+#undef HAS_NPE_VERBOSE_TRACE
+#undef HAS_DUMP_NPE_TREE
+
+#undef HAS_UPDATE_TRACE
+#undef HAS_UPDATE_VERBOSE_TRACE
+
+#endif /* NDEBUG */
+
+
+/***************************************************
+ *              Log Macros                         *
+ ***************************************************/
+
+/************** Globals ******************/
+
+#ifdef HAS_ERROR_LOG
+
+    #define ERROR_LOG printf
+
+#else
+
+    #define ERROR_LOG NULL_PRINT_ROUTINE
+
+#endif
+
+#ifdef HAS_ERROR_IRQ_LOG
+
+    #define ERROR_IRQ_LOG(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6)
+
+#else
+
+    #define ERROR_IRQ_LOG(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */
+
+#endif
+
+#ifdef HAS_WARNING_LOG
+
+    #define WARNING_LOG printf
+
+#else
+
+    #define WARNING_LOG NULL_PRINT_ROUTINE
+
+#endif
+
+/************** Events *******************/
+
+#ifdef HAS_EVENTS_TRACE
+
+    #define IX_ETH_DB_EVENTS_TRACE     printf
+    #define IX_ETH_DB_IRQ_EVENTS_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6)
+
+    #ifdef HAS_EVENTS_VERBOSE_TRACE
+
+        #define IX_ETH_DB_EVENTS_VERBOSE_TRACE printf
+    
+    #else
+
+        #define IX_ETH_DB_EVENTS_VERBOSE_TRACE NULL_PRINT_ROUTINE
+
+    #endif /* HAS_EVENTS_VERBOSE_TRACE */
+
+#else
+
+    #define IX_ETH_DB_EVENTS_TRACE         NULL_PRINT_ROUTINE
+    #define IX_ETH_DB_EVENTS_VERBOSE_TRACE NULL_PRINT_ROUTINE
+    #define IX_ETH_DB_IRQ_EVENTS_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */
+
+#endif /* HAS_EVENTS_TRACE */
+
+/************** Support *******************/
+
+#ifdef HAS_SUPPORT_TRACE
+
+    #define IX_ETH_DB_SUPPORT_TRACE     printf
+    #define IX_ETH_DB_SUPPORT_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6)
+
+    #ifdef HAS_SUPPORT_VERBOSE_TRACE
+
+        #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE printf
+
+    #else
+
+        #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE NULL_PRINT_ROUTINE
+
+    #endif /* HAS_SUPPORT_VERBOSE_TRACE */
+
+#else
+
+    #define IX_ETH_DB_SUPPORT_TRACE         NULL_PRINT_ROUTINE
+    #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE NULL_PRINT_ROUTINE
+    #define IX_ETH_DB_SUPPORT_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */
+
+#endif /* HAS_SUPPORT_TRACE */
+
+/************** NPE Adaptor *******************/
+
+#ifdef HAS_NPE_TRACE
+
+    #define IX_ETH_DB_NPE_TRACE     printf
+    #define IX_ETH_DB_NPE_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6)
+
+    #ifdef HAS_NPE_VERBOSE_TRACE
+
+        #define IX_ETH_DB_NPE_VERBOSE_TRACE printf
+
+    #else
+
+        #define IX_ETH_DB_NPE_VERBOSE_TRACE NULL_PRINT_ROUTINE
+
+    #endif /* HAS_NPE_VERBOSE_TRACE */
+
+#else
+
+    #define IX_ETH_DB_NPE_TRACE         NULL_PRINT_ROUTINE
+    #define IX_ETH_DB_NPE_VERBOSE_TRACE NULL_PRINT_ROUTINE
+    #define IX_ETH_DB_NPE_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */
+
+#endif /* HAS_NPE_TRACE */
+
+#ifdef HAS_DUMP_NPE_TREE
+
+#define IX_ETH_DB_NPE_DUMP_ELT(eltBaseAddress, eltSize) ixEthELTDumpTree(eltBaseAddress, eltSize)
+
+#else
+
+#define IX_ETH_DB_NPE_DUMP_ELT(eltBaseAddress, eltSize) /* nothing */
+
+#endif /* HAS_DUMP_NPE_TREE */
+
+/************** Port Update *******************/
+
+#ifdef HAS_UPDATE_TRACE
+
+    #define IX_ETH_DB_UPDATE_TRACE printf
+
+    #ifdef HAS_UPDATE_VERBOSE_TRACE
+
+        #define IX_ETH_DB_UPDATE_VERBOSE_TRACE printf
+
+    #else
+
+        #define IX_ETH_DB_UPDATE_VERBOSE_TRACE NULL_PRINT_ROUTINE
+
+    #endif
+
+#else /* HAS_UPDATE_VERBOSE_TRACE */
+
+    #define IX_ETH_DB_UPDATE_TRACE         NULL_PRINT_ROUTINE
+    #define IX_ETH_DB_UPDATE_VERBOSE_TRACE NULL_PRINT_ROUTINE
+
+#endif /* HAS_UPDATE_TRACE */
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthDBMessages_p.h b/marvell/uboot/drivers/net/npe/include/IxEthDBMessages_p.h
new file mode 100644
index 0000000..5907fd5
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthDBMessages_p.h
@@ -0,0 +1,234 @@
+/**
+ * @file IxEthDBMessages_p.h
+ *
+ * @brief Definitions of NPE messages
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxEthDBMessages_p_H
+#define IxEthDBMessages_p_H
+
+#include <IxEthNpe.h>
+#include <IxOsCacheMMU.h>
+#include "IxEthDB_p.h"
+
+/* events watched by the Eth event processor */
+#define IX_ETH_DB_MIN_EVENT_ID        (IX_ETHNPE_EDB_GETMACADDRESSDATABASE)
+#define IX_ETH_DB_MAX_EVENT_ID        (IX_ETHNPE_PC_SETAPMACTABLE)
+
+/* macros to fill and extract data from NPE messages - place any endian conversions here */
+#define RESET_ELT_MESSAGE(message) { memset((void *) &(message), 0, sizeof((message))); }
+#define NPE_MSG_ID(msg) ((msg).data[0] >> 24)
+
+#define FILL_SETPORTVLANTABLEENTRY_MSG(message, portID, setOffset, vlanMembershipSet, ttiSet) \
+    do { \
+        message.data[0] = (IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY << 24) | (portID << 16) | (setOffset * 2); \
+        message.data[1] = (vlanMembershipSet << 8) | ttiSet; \
+    } while (0);
+
+#define FILL_SETPORTVLANTABLERANGE_MSG(message, portID, offset, length, zone) \
+    do { \
+        message.data[0] = IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE << 24 | portID << 16 | offset << 9 | length << 1; \
+        message.data[1] = (UINT32) zone; \
+    } while (0);
+
+#define FILL_SETDEFAULTRXVID_MSG(message, portID, tpid, vlanTag) \
+    do { \
+        message.data[0] = (IX_ETHNPE_VLAN_SETDEFAULTRXVID << 24) \
+            | (portID << 16); \
+        \
+        message.data[1] = (tpid << 16) | vlanTag; \
+    } while (0);
+
+#define FILL_SETRXTAGMODE_MSG(message, portID, filterMode, tagMode) \
+    do { \
+        message.data[0] = IX_ETHNPE_VLAN_SETRXTAGMODE << 24 \
+            | portID << 16 \
+            | filterMode << 2 \
+            | tagMode; \
+        \
+        message.data[1] = 0; \
+    } while (0);
+
+#define FILL_SETRXQOSENTRY(message, portID, classIndex, trafficClass, aqmQueue) \
+    do { \
+        message.data[0] = IX_ETHNPE_VLAN_SETRXQOSENTRY << 24 \
+            | portID << 16 \
+            | classIndex; \
+        \
+        message.data[1] = trafficClass << 24 \
+            | 0x1 << 23 \
+            | aqmQueue << 16 \
+            | aqmQueue << 4; \
+    } while (0);
+
+#define FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable) \
+    do { \
+        message.data[0] = IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE << 24 \
+            | portID << 16 \
+            | (enable ? 0x1 : 0x0); \
+        \
+        message.data[1] = 0; \
+    } while (0);
+
+
+#define FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked) \
+    do { \
+        message.data[0] = IX_ETHNPE_STP_SETBLOCKINGSTATE << 24 \
+            | portID << 16 \
+            | (blocked ? 0x1 : 0x0); \
+        \
+        message.data[1] = 0; \
+    } while (0);
+
+#define FILL_SETBBSID_MSG(message, portID, bbsid) \
+    do { \
+        message.data[0] = IX_ETHNPE_PC_SETBBSID << 24 \
+            | portID << 16 \
+            | bbsid->macAddress[0] << 8 \
+            | bbsid->macAddress[1]; \
+        \
+        message.data[1] = bbsid->macAddress[2] << 24 \
+            | bbsid->macAddress[3] << 16 \
+            | bbsid->macAddress[4] << 8 \
+            | bbsid->macAddress[5]; \
+    } while (0);
+
+#define FILL_SETFRAMECONTROLDURATIONID(message, portID, frameControlDurationID) \
+    do { \
+        message.data[0] = (IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID << 24) | (portID << 16); \
+        message.data[1] = frameControlDurationID; \
+    } while (0);
+
+#define FILL_SETAPMACTABLE_MSG(message, zone) \
+    do { \
+        message.data[0] = IX_ETHNPE_PC_SETAPMACTABLE << 24 \
+            | 0 << 8      /* always use index 0 */ \
+            | 64;         /* 32 entries, 8 bytes each, 4 bytes in a word */ \
+        message.data[1] = (UINT32) zone; \
+    } while (0);
+
+#define FILL_SETFIREWALLMODE_MSG(message, portID, epDelta, mode, address) \
+    do { \
+        message.data[0] = IX_ETHNPE_FW_SETFIREWALLMODE << 24 \
+            | portID << 16 \
+            | (epDelta & 0xFF) << 8 \
+            | mode; \
+        \
+        message.data[1] = (UINT32) address; \
+    } while (0);
+
+#define FILL_SETMACADDRESSDATABASE_MSG(message, portID, epDelta, blockCount, address) \
+    do { \
+        message.data[0] = IX_ETHNPE_EDB_SETMACADDRESSSDATABASE << 24 \
+                | (epDelta & 0xFF) << 8 \
+                | (blockCount & 0xFF); \
+        \
+        message.data[1] = (UINT32) address; \
+    } while (0);
+
+#define FILL_GETMACADDRESSDATABASE(message, npeId, zone) \
+    do { \
+        message.data[0] = IX_ETHNPE_EDB_GETMACADDRESSDATABASE << 24; \
+        message.data[1] = (UINT32) zone; \
+    } while (0);
+
+#define FILL_SETMAXFRAMELENGTHS_MSG(message, portID, maxRxFrameSize, maxTxFrameSize) \
+    do { \
+        message.data[0] = IX_ETHNPE_SETMAXFRAMELENGTHS << 24 \
+            | portID << 16 \
+            | ((maxRxFrameSize + 63) / 64) << 8  /* max Rx 64-byte blocks */ \
+            | (maxTxFrameSize + 63) / 64; /* max Tx 64-byte blocks */ \
+        \
+        message.data[1] = maxRxFrameSize << 16 | maxTxFrameSize; \
+    } while (0);
+
+#define FILL_SETPORTADDRESS_MSG(message, portID, macAddress) \
+    do { \
+        message.data[0] = IX_ETHNPE_EDB_SETPORTADDRESS << 24 \
+            | portID << 16 \
+            | macAddress[0] << 8 \
+            | macAddress[1]; \
+        \
+        message.data[1] = macAddress[2] << 24 \
+            | macAddress[3] << 16 \
+            | macAddress[4] << 8 \
+            | macAddress[5]; \
+    } while (0);
+
+/* access to a MAC node in the NPE tree */
+#define NPE_NODE_BYTE(eltNodeAddr, offset)      (((UINT8 *) (eltNodeAddr))[offset])
+
+/* browsing of the implicit linear binary tree structure of the NPE tree */
+#define LEFT_CHILD_OFFSET(offset)   ((offset) << 1)
+#define RIGHT_CHILD_OFFSET(offset)  (((offset) << 1) + 1)
+
+#define IX_EDB_FLAGS_ACTIVE         (0x2)
+#define IX_EDB_FLAGS_VALID          (0x1)
+#define IX_EDB_FLAGS_RESERVED       (0xfc)
+#define IX_EDB_FLAGS_INACTIVE_VALID (0x1)
+
+#define IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET (6)
+#define IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET   (7)
+#define IX_EDB_NPE_NODE_WIFI_INDEX_OFFSET  (6)
+#define IX_EDB_NPE_NODE_WIFI_FLAGS_OFFSET  (7)
+#define IX_EDB_NPE_NODE_FW_FLAGS_OFFSET    (1)
+#define IX_EDB_NPE_NODE_FW_RESERVED_OFFSET (6)
+#define IX_EDB_NPE_NODE_FW_ADDR_OFFSET     (2)
+
+#define IX_EDB_NPE_NODE_VALID(address)     ((NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) & IX_EDB_FLAGS_VALID) != 0)
+#define IX_EDB_NPE_NODE_ACTIVE(address)    ((NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) & IX_EDB_FLAGS_ACTIVE) != 0)
+#define IX_EDB_NPE_NODE_PORT_ID(address)   (NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET))
+
+/* macros to send messages to the NPEs */
+#define IX_ETHDB_ASYNC_SEND_NPE_MSG(npeId, msg, result) \
+    do { \
+        result = ixNpeMhMessageSend(npeId, msg, IX_NPEMH_SEND_RETRIES_DEFAULT); \
+        \
+        if (result != IX_SUCCESS) \
+        { \
+            ERROR_LOG("DB: Failed to send NPE message\n"); \
+        } \
+    } while (0);
+
+#define IX_ETHDB_SYNC_SEND_NPE_MSG(npeId, msg, result) \
+    do { \
+        result = ixNpeMhMessageWithResponseSend(npeId, msg, msg.data[0] >> 24, ixEthDBNpeMsgAck, IX_NPEMH_SEND_RETRIES_DEFAULT); \
+        \
+        if (result == IX_SUCCESS) \
+        { \
+            result = ixOsalMutexLock(&ixEthDBPortInfo[IX_ETH_DB_NPE_TO_PORT_ID(npeId)].npeAckLock, IX_ETH_DB_NPE_TIMEOUT); \
+            \
+            if (result != IX_SUCCESS) \
+            { \
+                ERROR_LOG("DB: NPE failed to respond within %dms\n", IX_ETH_DB_NPE_TIMEOUT); \
+            } \
+        } \
+        else \
+        { \
+            ERROR_LOG("DB: Failed to send NPE message\n"); \
+        } \
+    } while (0);
+
+#ifndef IX_NDEBUG
+#define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100)
+extern IX_ETH_DB_PUBLIC UINT32 npeMsgHistory[IX_ETH_DB_NPE_MSG_HISTORY_DEPTH][2];
+extern IX_ETH_DB_PUBLIC UINT32 npeMsgHistoryLen;
+#endif
+
+#define IX_ETHDB_SEND_NPE_MSG(npeId, msg, result) { LOG_NPE_MSG(msg); IX_ETHDB_SYNC_SEND_NPE_MSG(npeId, msg, result); }
+
+#endif /* IxEthDBMessages_p_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthDBPortDefs.h b/marvell/uboot/drivers/net/npe/include/IxEthDBPortDefs.h
new file mode 100644
index 0000000..9f5e467
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthDBPortDefs.h
@@ -0,0 +1,139 @@
+/**
+ * @file IxEthDBPortDefs.h
+ *
+ * @brief Public definition of the ports and port capabilities
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxEthDBPortDefs IXP400 Ethernet Database Port Definitions (IxEthDBPortDefs)
+ *
+ * @brief IXP400 Public definition of the ports and port capabilities
+ *
+ * @{
+ */
+
+#ifndef IxEthDBPortDefs_H
+#define IxEthDBPortDefs_H
+
+/** 
+ * @brief Port types - currently only Ethernet NPEs are recognized as specific types 
+ * All other (user-defined) ports must be specified as IX_ETH_GENERIC
+ */
+typedef enum
+{
+    IX_ETH_GENERIC = 0, /**< generic ethernet port */
+    IX_ETH_NPE          /**< specific Ethernet NPE */
+} IxEthDBPortType;
+
+/** 
+ * @brief Port capabilities - used by ixEthAccDatabaseMaintenance to decide whether it
+ * should manually age entries or not depending on the port capabilities.
+ *
+ * Ethernet NPEs have aging capabilities, meaning that they will age the entries
+ * automatically (by themselves).*/
+typedef enum
+{
+    IX_ETH_NO_CAPABILITIES = 0,   /**< no aging capabilities */
+    IX_ETH_ENTRY_AGING     = 0x1  /**< aging capabilities present */
+} IxEthDBPortCapability;
+
+/** 
+ * @brief Port Definition - a structure contains the Port type and capabilities 
+ */
+typedef struct
+{
+    IxEthDBPortType type;
+    IxEthDBPortCapability capabilities;
+} IxEthDBPortDefinition;
+
+/** 
+ * @brief Port definitions structure, indexed on the port ID
+ * @warning Ports 0 and 1 are used by the Ethernet access component therefore
+ * it is essential to be left untouched. Port 2 here (WAN) is given as 
+ * an example port. The NPE firmware also assumes the NPE B to be
+ * the port 0 and NPE C to be the port 1.
+ *
+ * @note that only 32 ports (0..31) are supported by EthDB
+ */
+static const IxEthDBPortDefinition ixEthDBPortDefinitions[] = 
+{
+    /*    id       type              capabilities */
+    {   /* 0 */    IX_ETH_NPE,       IX_ETH_NO_CAPABILITIES },    /* Ethernet NPE B */
+    {   /* 1 */    IX_ETH_NPE,       IX_ETH_NO_CAPABILITIES },    /* Ethernet NPE C */
+    {   /* 2 */    IX_ETH_NPE,       IX_ETH_NO_CAPABILITIES },    /* Ethernet NPE A */
+    {   /* 3 */    IX_ETH_GENERIC,   IX_ETH_NO_CAPABILITIES },    /* WAN port */
+};
+
+/** 
+ * @def IX_ETH_DB_NUMBER_OF_PORTS
+ * @brief number of supported ports 
+ */
+#define IX_ETH_DB_NUMBER_OF_PORTS ARRAY_SIZE(ixEthDBPortDefinitions)
+
+/**
+ * @def IX_ETH_DB_UNKNOWN_PORT
+ * @brief definition of an unknown port
+ */
+#define IX_ETH_DB_UNKNOWN_PORT (0xff)
+
+/** 
+ * @def IX_ETH_DB_ALL_PORTS
+ * @brief Special port ID indicating all the ports
+ * @note This port ID can be used only by a subset of the EthDB API; each
+ * function specifically mentions whether this is a valid parameter as the port ID
+ */
+#define IX_ETH_DB_ALL_PORTS (IX_ETH_DB_NUMBER_OF_PORTS + 1)
+
+/**
+ * @def IX_ETH_DB_PORTS_ASSERTION
+ * @brief catch invalid port definitions (<2) with a 
+ * compile-time assertion resulting in a duplicate case error. 
+ */
+#define IX_ETH_DB_PORTS_ASSERTION { switch(0) { case 0 : ; case 1 : ; case IX_ETH_DB_NUMBER_OF_PORTS : ; }}
+
+/** 
+ * @def IX_ETH_DB_CHECK_PORT(portID)
+ * @brief safety checks to verify whether the port is invalid or uninitialized
+ */
+#define IX_ETH_DB_CHECK_PORT(portID) \
+{ \
+  if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \
+  { \
+      return IX_ETH_DB_INVALID_PORT; \
+  } \
+  \
+  if (!ixEthDBPortInfo[(portID)].enabled) \
+  { \
+      return IX_ETH_DB_PORT_UNINITIALIZED; \
+  } \
+}
+
+/**
+ * @def IX_ETH_DB_CHECK_PORT_ALL(portID)
+ * @brief safety checks to verify whether the port is invalid or uninitialized; 
+ * tolerates the use of IX_ETH_DB_ALL_PORTS
+ */
+#define IX_ETH_DB_CHECK_PORT_ALL(portID) \
+{ \
+  if ((portID) != IX_ETH_DB_ALL_PORTS) \
+    IX_ETH_DB_CHECK_PORT(portID) \
+}
+
+#endif /* IxEthDBPortDefs_H */
+/**
+ *@}
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthDBQoS.h b/marvell/uboot/drivers/net/npe/include/IxEthDBQoS.h
new file mode 100644
index 0000000..6276930
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthDBQoS.h
@@ -0,0 +1,130 @@
+/**
+ * @file IxEthDBQoS.h
+ *
+ * @brief Public definitions for QoS traffic classes
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxEthDBPortDefs IXP400 Ethernet QoS definitions
+ *
+ * @brief IXP00 Public definitions for QoS traffic classes
+ *
+ * @{
+ */
+
+#ifndef IxEthDBQoS_H
+#define IxEthDBQoS_H
+
+/**
+ * @def IX_ETH_DB_QUEUE_UNAVAILABLE
+ * @brief alias to indicate a queue (traffic class) is not available
+ */
+#define IX_ETH_DB_QUEUE_UNAVAILABLE  (0)
+
+#ifndef IX_IEEE802_1Q_QOS_PRIORITY_COUNT
+/**
+ * @def IX_IEEE802_1Q_QOS_PRIORITY_COUNT
+ * @brief number of QoS priorities, according to IEEE 802.1Q
+ */
+#define IX_IEEE802_1Q_QOS_PRIORITY_COUNT (8)
+#endif
+
+/**
+ * @brief array containing all the supported traffic class configurations
+ */
+static const
+UINT8 ixEthDBQueueAssignments[][IX_IEEE802_1Q_QOS_PRIORITY_COUNT] = 
+{
+    { 4, 5, 6, 7, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE },
+    { 15, 16, 17, 18, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE },
+    { 11, 23, 26, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE,  IX_ETH_DB_QUEUE_UNAVAILABLE },
+    { 4, 5, 6, 7, 8, 9, 10, 11 }
+    /* add here all other cases of queue configuration structures and update ixEthDBTrafficClassDefinitions to use them */
+};
+
+/**
+ * @brief value used to index the NPE A functionality ID in the traffic class definition table
+ */
+#define IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX    (0)
+
+/**
+ * @brief value used to index the traffic class count in the traffic class definition table
+ */
+#define IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX       (1)
+
+/**
+ * @brief value used to index the queue assignment index in the traffic class definition table
+ */
+#define IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX          (2)
+
+/**
+ * @brief traffic class definitions
+ *
+ * This array contains the default traffic class definition configuration,
+ * as well as any special cases dictated by the functionality ID of NPE A.
+ *
+ * The default case should not be removed (otherwise the Ethernet
+ * components will assert a fatal failure on initialization).
+ */
+static const
+UINT8 ixEthDBTrafficClassDefinitions[][3] = 
+{
+    /* NPE A functionality ID | traffic class count | queue assignment index (points to the queue enumeration in ixEthDBQueueAssignments) */
+    {            0x00,                      4,                    0 }, /* default case - DO NOT REMOVE */
+    {            0x04,                      4,                    1 }, /* NPE A image ID 0.4.0.0 */
+    {            0x09,                      3,                    2 }, /* NPE A image ID 0.9.0.0 */
+    {            0x80,                      8,                    3 }, /* NPE A image ID 10.80.02.0 */
+    {            0x81,                      8,                    3 }, /* NPE A image ID 10.81.02.0 */
+    {            0x82,                      8,                    3 }  /* NPE A image ID 10.82.02.0 */
+};
+
+/**
+ * @brief IEEE 802.1Q recommended QoS Priority => traffic class maps
+ *
+ * @verbatim
+                    Number of available traffic classes
+                    1 2 3 4 5 6 7 8
+    QoS Priority
+        0           0 0 0 1 1 1 1 2
+        1           0 0 0 0 0 0 0 0
+        2           0 0 0 0 0 0 0 1
+        3           0 0 0 1 1 2 2 3
+        4           0 1 1 2 2 3 3 4
+        5           0 1 1 2 3 4 4 5
+        6           0 1 2 3 4 5 5 6
+        7           0 1 2 3 4 5 6 7
+
+    @endverbatim
+ */
+static const
+UINT8 ixEthIEEE802_1QUserPriorityToTrafficClassMapping[IX_IEEE802_1Q_QOS_PRIORITY_COUNT][IX_IEEE802_1Q_QOS_PRIORITY_COUNT] = 
+ {
+     { 0, 0, 0, 0, 0, 0, 0, 0 }, /* 1 traffic class available */
+     { 0, 0, 0, 0, 1, 1, 1, 1 }, /* 2 traffic classes available */
+     { 0, 0, 0, 0, 1, 1, 2, 2 }, /* 3 traffic classes available */
+     { 1, 0, 0, 1, 2, 2, 3, 3 }, /* 4 traffic classes available */
+     { 1, 0, 0, 1, 2, 3, 4, 4 }, /* 5 traffic classes available */
+     { 1, 0, 0, 2, 3, 4, 5, 5 }, /* 6 traffic classes available */
+     { 1, 0, 0, 2, 3, 4, 5, 6 }, /* 7 traffic classes available */
+     { 2, 0, 1, 3, 4, 5, 6, 7 }  /* 8 traffic classes available */
+ };
+
+#endif /* IxEthDBQoS_H */
+
+/**
+ *@}
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthDB_p.h b/marvell/uboot/drivers/net/npe/include/IxEthDB_p.h
new file mode 100644
index 0000000..ddc10a5
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthDB_p.h
@@ -0,0 +1,686 @@
+/**
+ * @file IxEthDB_p.h
+ *
+ * @brief Private MAC learning API
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxEthDB_p_H
+#define IxEthDB_p_H
+
+#include <IxTypes.h>
+#include <IxOsal.h>
+#include <IxEthDB.h>
+#include <IxNpeMh.h>
+#include <IxEthDBPortDefs.h>
+
+#include "IxEthDBMessages_p.h"
+#include "IxEthDBLog_p.h"
+
+#if (CPU==SIMSPARCSOLARIS)
+
+/* when running unit tests intLock() won't protect the event queue so we lock it manually */
+#define TEST_FIXTURE_LOCK_EVENT_QUEUE   { ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER); }
+#define TEST_FIXTURE_UNLOCK_EVENT_QUEUE { ixOsalMutexUnlock(&eventQueueLock); }
+
+#else
+
+#define TEST_FIXTURE_LOCK_EVENT_QUEUE   /* nothing */
+#define TEST_FIXTURE_UNLOCK_EVENT_QUEUE /* nothing */
+
+#endif /* #if(CPU==SIMSPARCSOLARIS) */
+
+#ifndef IX_UNIT_TEST
+
+#define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER /* nothing */
+#define TEST_FIXTURE_MARK_OVERFLOW_EVENT              /* nothing */
+
+#else
+
+extern int dbAccessCounter;
+extern int overflowEvent;
+
+#define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER { dbAccessCounter++; }
+#define TEST_FIXTURE_MARK_OVERFLOW_EVENT              { overflowEvent = 1; }
+
+#endif
+
+/* code readability markers */
+#define __mempool__      /* memory pool marker */
+#define __lock__         /* hash write locking marker */
+#define __smartpointer__ /* smart pointer marker - warning: use only clone() when duplicating! */
+#define __alignment__    /* marker for data used only as alignment zones */
+
+/* constants */
+#define IX_ETH_DB_NPE_TIMEOUT (100) /* NPE response timeout, in ms */
+
+/**
+ * number of hash table buckets
+ * it should be at least 8x the predicted number of entries for performance
+ * each bucket needs 8 bytes
+ */
+#define NUM_BUCKETS (8192)
+
+/**
+ * number of hash table buckets to preload when incrementing bucket iterator
+ * = two cache lines
+ */
+#define IX_ETHDB_CACHE_LINE_AHEAD (2)
+
+#define IX_ETHDB_BUCKETPTR_AHEAD  ((IX_ETHDB_CACHE_LINE_AHEAD * IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *))
+
+#define IX_ETHDB_BUCKET_INDEX_MASK   (((IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *)) - 1)
+
+/* locks */
+#define MAX_LOCKS (20) /**< maximum number of locks used simultaneously, do not tamper with */
+
+/* learning tree constants */
+#define INITIAL_ELT_SIZE    (8)                              /**< initial byte size of tree (empty unused root size) */
+#define MAX_ELT_SIZE        (512)                            /**< maximum number of entries (includes unused root) */
+#define MAX_GW_SIZE         (32)                             /**< maximum number of gateway entries (including unused root) */
+#define MAX_FW_SIZE         (32)                             /**< maximum number of firewall entries (including unused root) */
+#define ELT_ENTRY_SIZE      (8)                              /**< entry size, in bytes */
+#define ELT_ROOT_OFFSET     (ELT_ENTRY_SIZE)                 /**< tree root offset, in bytes - node preceeding root is unused */
+#define FULL_ELT_BYTE_SIZE  (MAX_ELT_SIZE * ELT_ENTRY_SIZE)  /**< full size of tree, in bytes, including unused root */
+#define FULL_GW_BYTE_SIZE   (MAX_GW_SIZE * ELT_ENTRY_SIZE)   /**< full size of gateway list, in bytes, including unused root */
+#define FULL_FW_BYTE_SIZE   (MAX_FW_SIZE * ELT_ENTRY_SIZE)   /**< full size of firewall table, in bytes, including unused root */
+
+/* maximum size of the VLAN table:
+ * 4096 bits (one per VLAN)
+ * 8 bits in one byte
+ * interleaved VLAN membership and VLAN TTI (*2) */
+#define FULL_VLAN_BYTE_SIZE (4096 / 8 * 2)
+
+/* upper 9 bits used as set index, lower 3 bits as byte index */
+#define VLAN_SET_OFFSET(vlanID) ((vlanID) >> 3)
+#define VLAN_SET_MASK(vlanID)   (0x7 - ((vlanID) & 0x7))
+
+/* Update zone definitions */
+#define NPE_TREE_MEM_SIZE (4096) /* ((511 entries + 1 unused root) * 8 bytes/entry) */
+
+/* check the above value, we rely on 4k */
+#if NPE_TREE_MEM_SIZE != 4096
+    #error NPE_TREE_MEM_SIZE is not defined to 4096 bytes!
+#endif
+
+/* Size Filtering limits (Jumbo frame filtering) */
+#define IX_ETHDB_MAX_FRAME_SIZE     65535 /* other ports than NPE ports */
+#define IX_ETHDB_MIN_FRAME_SIZE         1 /* other ports than NPE ports */
+#define IX_ETHDB_MAX_NPE_FRAME_SIZE 16320 /* NPE ports firmware limit */
+#define IX_ETHDB_MIN_NPE_FRAME_SIZE     1 /* NPE ports firmware limit */
+#define IX_ETHDB_DEFAULT_FRAME_SIZE  1522
+
+/* memory management pool sizes  */
+
+/*
+ * Note:
+ *
+ * NODE_POOL_SIZE controls the maximum number of elements in the database at any one time.
+ * It should be large enough to cover all the search trees of all the ports simultaneously.
+ *
+ * MAC_POOL_SIZE should be higher than NODE_POOL_SIZE by at least the total number of MAC addresses
+ * possible to be held at any time in all the ports.
+ *
+ * TREE_POOL_SIZE should follow the same guideline as for MAC_POOL_SIZE.
+ *
+ * The database structure described here (2000/4000/4000) is enough for two NPEs holding at most 511
+ * entries each plus one PCI NIC holding at most 900 entries.
+ */
+
+#define NODE_POOL_SIZE (2000) /**< number of HashNode objects - also master number of elements in the database; each entry has 16 bytes */
+#define MAC_POOL_SIZE  (4000) /**< number of MacDescriptor objects; each entry has 28 bytes */
+#define TREE_POOL_SIZE (4000) /**< number of MacTreeNode objects; each entry has 16 bytes */
+
+/* retry policies */
+#define BUSY_RETRY_ENABLED (true)  /**< if set to true the API will retry automatically calls returning BUSY */
+#define FOREVER_RETRY      (true)  /**< if set to true the API will retry forever BUSY calls */
+#define MAX_RETRIES        (400)   /**< upper retry limit - used only when FOREVER_RETRY is false */
+#define BUSY_RETRY_YIELD   (5)     /**< ticks to yield for every failed retry */
+
+/* event management */
+#define EVENT_QUEUE_SIZE       (500) /**< size of the sink collecting events from the Message Handler FIFO */
+#define EVENT_PROCESSING_LIMIT (100)  /**< batch processing control size (how many events are extracted from the queue at once) */
+
+/* MAC descriptors */
+#define STATIC_ENTRY  (true)
+#define DYNAMIC_ENTRY (false)
+
+/* age reset on next maintenance - incrementing by 1 will reset to 0 */
+#define AGE_RESET (0xFFFFFFFF)
+
+/* dependency maps */
+#define EMPTY_DEPENDENCY_MAP (0)
+
+/* trees */
+#define RIGHT (1)
+#define LEFT  (-1)
+
+/* macros */
+#define IX_ETH_DB_CHECK_PORT_EXISTS(portID) \
+{ \
+    if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \
+    { \
+        return IX_ETH_DB_INVALID_PORT; \
+    } \
+}
+
+#define IX_ETH_DB_CHECK_PORT_INITIALIZED(portID) \
+{ \
+    if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \
+    { \
+        return IX_ETH_DB_INVALID_PORT; \
+    } \
+    else \
+    { \
+        if (!ixEthDBPortInfo[portID].initialized) \
+        { \
+            return IX_ETH_DB_PORT_UNINITIALIZED; \
+        } \
+    } \
+}
+
+/* single NPE check */
+#define IX_ETH_DB_CHECK_SINGLE_NPE(portID) \
+    if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS) \
+    { \
+        WARNING_LOG("EthDB: port ID %d is unavailable\n",(UINT32) portID); \
+        \
+        return IX_ETH_DB_INVALID_PORT; \
+    }
+
+/* feature check */
+#define IX_ETH_DB_CHECK_FEATURE(portID, feature) \
+    if ((ixEthDBPortInfo[portID].featureStatus & feature) == 0) \
+    { \
+        return IX_ETH_DB_FEATURE_UNAVAILABLE; \
+    }
+
+/* busy retrying */
+#define BUSY_RETRY(functionCall) \
+    { \
+        UINT32 retries = 0; \
+        IxEthDBStatus br_result; \
+        \
+        while ((br_result = functionCall) == IX_ETH_DB_BUSY \
+            && BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \
+        \
+        if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (br_result == IX_ETH_DB_FAIL)) \
+        {\
+            ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY failed at %s:%d\n", __FILE__, __LINE__); \
+        }\
+    }
+
+#define BUSY_RETRY_WITH_RESULT(functionCall, brwr_result) \
+    { \
+        UINT32 retries = 0; \
+        \
+        while ((brwr_result = functionCall) == IX_ETH_DB_BUSY \
+            && BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \
+        \
+        if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (brwr_result == IX_ETH_DB_FAIL)) \
+        {\
+            ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY_WITH_RESULT failed at %s:%d\n", __FILE__, __LINE__); \
+        }\
+    }
+
+/* iterators */
+#define IS_ITERATOR_VALID(iteratorPtr) ((iteratorPtr)->node != NULL)
+
+/* dependency port maps */
+
+/* Warning: if port indexing starts from 1 replace (portID) with (portID - 1) in DEPENDENCY_MAP (and make sure IX_ETH_DB_NUMBER_OF_PORTS is big enough) */
+
+/* gives an empty dependency map */
+#define SET_EMPTY_DEPENDENCY_MAP(map)      { int i = 0; for (; i < 32 ; i++) map[i] = 0; }
+
+#define IS_EMPTY_DEPENDENCY_MAP(result, map)       { int i = 0 ; result = true; for (; i < 32 ; i++) if (map[i] != 0) { result = false; break; }}
+
+/**
+ * gives a map consisting only of 'portID'
+ */
+#define SET_DEPENDENCY_MAP(map, portID)    {SET_EMPTY_DEPENDENCY_MAP(map); map[portID >> 3] = 1 << (portID & 0x7);}
+
+/**
+ * gives a map resulting from joining map1 and map2
+ */
+#define JOIN_MAPS(map, map1, map2)         { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] | map2[i]; }
+
+/**
+ * gives the map resulting from joining portID and map
+ */
+#define JOIN_PORT_TO_MAP(map, portID)      { map[portID >> 3] |= 1 << (portID & 0x7); }
+
+/**
+ * gives the map resulting from excluding portID from map
+ */
+#define EXCLUDE_PORT_FROM_MAP(map, portID) { map[portID >> 3] &= ~(1 << (portID & 0x7); }
+
+/**
+ * returns true if map1 is a subset of map2 and false otherwise
+ */
+#define IS_MAP_SUBSET(result, map1, map2)  { int i = 0; result = true; for (; i < 32 ; i++) if ((map1[i] | map2[i]) != map2[i]) result = false; }
+
+/**
+ * returns true is portID is part of map and false otherwise
+ */
+#define IS_PORT_INCLUDED(portID, map)      ((map[portID >> 3] & (1 << (portID & 0x7))) != 0)
+
+/**
+ * returns the difference between map1 and map2 (ports included in map1 and not included in map2)
+ */
+#define DIFF_MAPS(map, map1, map2)         { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] ^ (map1[i] & map2[i]); }
+
+/**
+ * returns true if the maps collide (have at least one port in common) and false otherwise
+ */
+#define MAPS_COLLIDE(result, map1, map2)   { int i = 0; result = false; for (; i < 32 ; i++) if ((map1[i] & map2[i]) != 0) result = true; }
+
+/* size (number of ports) of a dependency map */
+#define GET_MAP_SIZE(map, size)            { int i = 0, b = 0; size = 0; for (; i < 32 ; i++) { char y = map[i]; for (; b < 8 && (y >>= 1); b++) size += (y & 1); }}
+
+/* copy map2 into map1 */
+#define COPY_DEPENDENCY_MAP(map1, map2)    { memcpy (map1, map2, sizeof (map1)); }
+
+/* definition of a port map size/port number which cannot be reached (we support at most 32 ports) */
+#define MAX_PORT_SIZE   (0xFF)
+#define MAX_PORT_NUMBER (0xFF)
+
+#define IX_ETH_DB_CHECK_REFERENCE(ptr)   { if ((ptr) == NULL) { return IX_ETH_DB_INVALID_ARG; } }
+#define IX_ETH_DB_CHECK_MAP(portID, map) { if (!IS_PORT_INCLUDED(portID, map)) { return IX_ETH_DB_INVALID_ARG; } }
+
+/* event queue macros */
+#define EVENT_QUEUE_WRAP(offset)            ((offset) >= EVENT_QUEUE_SIZE ? (offset) - EVENT_QUEUE_SIZE : (offset))
+
+#define CAN_ENQUEUE(eventQueuePtr)          ((eventQueuePtr)->length < EVENT_QUEUE_SIZE)
+
+#define QUEUE_HEAD(eventQueuePtr)           (&(eventQueuePtr)->queue[EVENT_QUEUE_WRAP((eventQueuePtr)->base + (eventQueuePtr)->length)])
+
+#define QUEUE_TAIL(eventQueuePtr)           (&(eventQueuePtr)->queue[(eventQueuePtr)->base])
+
+#define PUSH_UPDATE_QUEUE(eventQueuePtr)    { (eventQueuePtr)->length++; }
+
+#define SHIFT_UPDATE_QUEUE(eventQueuePtr) \
+        { \
+            (eventQueuePtr)->base = EVENT_QUEUE_WRAP((eventQueuePtr)->base + 1); \
+            (eventQueuePtr)->length--; \
+        }
+
+#define RESET_QUEUE(eventQueuePtr) \
+    { \
+        (eventQueuePtr)->base   = 0; \
+        (eventQueuePtr)->length = 0; \
+    }
+
+/* node stack macros - used to browse a tree without using a recursive function */
+#define NODE_STACK_INIT(stack)               { (stack)->nodeCount = 0; }
+#define NODE_STACK_PUSH(stack, node, offset) { (stack)->nodes[(stack)->nodeCount] = (node); (stack)->offsets[(stack)->nodeCount++] = (offset); }
+#define NODE_STACK_POP(stack, node, offset)  { (node) = (stack)->nodes[--(stack)->nodeCount]; offset = (stack)->offsets[(stack)->nodeCount]; }
+#define NODE_STACK_NONEMPTY(stack)           ((stack)->nodeCount != 0)
+
+#ifndef IX_NDEBUG
+#define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100)
+#define LOG_NPE_MSG(msg) \
+    do { \
+        UINT32 npeMsgHistoryIndex = (npeMsgHistoryLen++) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH; \
+        npeMsgHistory[npeMsgHistoryIndex][0] = msg.data[0]; \
+        npeMsgHistory[npeMsgHistoryIndex][1] = msg.data[1]; \
+    } while (0);
+#else
+#define LOG_NPE_MSG() /* nothing */
+#endif
+
+/* ----------- Data -------------- */
+
+/* typedefs */
+
+typedef UINT32 (*HashFunction)(void *entity);
+typedef BOOL (*MatchFunction)(void *reference, void *entry);
+typedef void (*FreeFunction)(void *entry);
+
+/**
+ * basic component of a hash table
+ */
+typedef struct HashNode_t
+{
+    void *data;                                 /**< specific data */
+    struct HashNode_t *next;                    /**< used for bucket chaining */
+
+    __mempool__ struct HashNode_t *nextFree;    /**< memory pool management */
+
+    __lock__ IxOsalFastMutex lock;              /**< node lock */
+} HashNode;
+
+/**
+ * @brief hash table iterator definition
+ *
+ * an iterator is an object which can be used
+ * to browse a hash table
+ */
+typedef struct
+{
+    UINT32 bucketIndex;     /**< index of the currently iterated bucket */
+    HashNode *previousNode; /**< reference to the previously iterated node within the current bucket */
+    HashNode *node;         /**< reference to the currently iterated node */
+} HashIterator;
+
+/**
+ * definition of a MAC descriptor (a database record)
+ */
+
+typedef enum
+{
+    IX_ETH_DB_WIFI_AP_TO_STA = 0x0,
+    IX_ETH_DB_WIFI_AP_TO_AP  = 0x1
+} IxEthDBWiFiRecordType;
+
+typedef union
+{
+    struct
+    {
+        UINT32 age;
+        BOOL staticEntry; /**< true if this address is static (doesn't age) */
+    } filteringData;
+
+    struct
+    {
+        UINT32 age;
+        BOOL staticEntry;
+        UINT32 ieee802_1qTag;
+      } filteringVlanData;
+
+    struct
+    {
+        IxEthDBWiFiRecordType type;  /**< AP_TO_AP (0x1) or AP_TO_STA (0x0) */
+        UINT32 gwAddressIndex; /**< used only when linearizing the entries for NPE usage */
+        UINT8 gwMacAddress[IX_IEEE803_MAC_ADDRESS_SIZE];
+
+        __alignment__ UINT8 reserved2[2];
+    } wifiData;
+} IxEthDBRecordData;
+
+typedef struct MacDescriptor_t
+{
+    UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE];
+
+    __alignment__ UINT8 reserved1[2];
+
+    UINT32 portID;
+    IxEthDBRecordType type;
+    IxEthDBRecordData recordData;
+
+    /* used for internal operations, such as NPE linearization */
+    void *internal;
+
+    /* custom user data */
+    void *user;
+
+    __mempool__ struct MacDescriptor_t *nextFree;   /**< memory pool management */
+    __smartpointer__ UINT32 refCount;               /**< smart pointer reference counter */
+} MacDescriptor;
+
+/**
+ * hash table definition
+ */
+typedef struct
+{
+    HashNode *hashBuckets[NUM_BUCKETS];
+    UINT32 numBuckets;
+
+    __lock__ IxOsalFastMutex bucketLocks[NUM_BUCKETS];
+
+    HashFunction entryHashFunction;
+    MatchFunction *matchFunctions;
+    FreeFunction freeFunction;
+} HashTable;
+
+typedef enum
+{
+    IX_ETH_DB_MAC_KEY       = 1,
+    IX_ETH_DB_MAC_PORT_KEY  = 2,
+    IX_ETH_DB_MAC_VLAN_KEY  = 3,
+    IX_ETH_DB_MAX_KEY_INDEX = 3
+} IxEthDBSearchKeyType;
+
+typedef struct MacTreeNode_t
+{
+    __smartpointer__  MacDescriptor *descriptor;
+    struct MacTreeNode_t *left, *right;
+
+    __mempool__ struct MacTreeNode_t *nextFree;
+} MacTreeNode;
+
+typedef IxEthDBStatus (*IxEthDBPortUpdateHandler)(IxEthDBPortId portID, IxEthDBRecordType type);
+
+typedef void (*IxEthDBNoteWriteFn)(void *address, MacTreeNode *node);
+
+typedef struct
+{
+    BOOL updateEnabled;                         /**< true if updates are enabled for port */
+    BOOL userControlled;                        /**< true if the user has manually used ixEthDBPortUpdateEnableSet */
+    BOOL treeInitialized;                       /**< true if the NPE has received an initial tree */
+    IxEthDBPortUpdateHandler updateHandler;     /**< port update handler routine */
+    void *npeUpdateZone;                        /**< port update memory zone */
+    void *npeGwUpdateZone;                      /**< port update memory zone for gateways */
+    void *vlanUpdateZone;                       /**< port update memory zone for VLAN tables */
+    MacTreeNode *searchTree;                    /**< internal search tree, in MacTreeNode representation */
+    BOOL searchTreePendingWrite;                /**< true if searchTree holds a tree pending write to the port */
+} PortUpdateMethod;
+
+typedef struct
+{
+    IxEthDBPortId portID;                   /**< port ID */
+    BOOL enabled;                           /**< true if the port is enabled */
+    BOOL agingEnabled;                      /**< true if aging on this port is enabled */
+    BOOL initialized;
+    IxEthDBPortMap dependencyPortMap;       /**< dependency port map for this port */
+    PortUpdateMethod updateMethod;          /**< update method structure */
+    BOOL macAddressUploaded;                /**< true if the MAC address was uploaded into the port */
+    UINT32 maxRxFrameSize;                  /**< maximum Rx frame size for this port */
+    UINT32 maxTxFrameSize;                  /**< maximum Rx frame size for this port */
+
+    UINT8 bbsid[6];
+    __alignment__ UINT8 reserved[2];
+    UINT32 frameControlDurationID;          /**< Frame Control - Duration/ID WiFi control */
+
+    IxEthDBVlanTag vlanTag;                  /**< default VLAN tag for port */
+    IxEthDBPriorityTable priorityTable;     /**< QoS <=> internal priority mapping */
+    IxEthDBVlanSet vlanMembership;
+    IxEthDBVlanSet transmitTaggingInfo;
+    IxEthDBFrameFilter frameFilter;
+    IxEthDBTaggingAction taggingAction;
+
+    UINT32 npeFrameFilter;
+    UINT32 npeTaggingAction;
+
+    IxEthDBFirewallMode firewallMode;
+    BOOL srcAddressFilterEnabled;
+
+    BOOL stpBlocked;
+
+    IxEthDBFeature featureCapability;
+    IxEthDBFeature featureStatus;
+
+    UINT32 ixEthDBTrafficClassAQMAssignments[IX_IEEE802_1Q_QOS_PRIORITY_COUNT];
+
+    UINT32 ixEthDBTrafficClassCount;
+
+    UINT32 ixEthDBTrafficClassAvailable;
+
+
+
+    __lock__ IxOsalMutex npeAckLock;
+} PortInfo;
+
+/* list of port information structures indexed on port Ids */
+extern IX_ETH_DB_PUBLIC PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS];
+
+typedef enum
+{
+    IX_ETH_DB_ADD_FILTERING_RECORD    = 0xFF0001,
+    IX_ETH_DB_REMOVE_FILTERING_RECORD = 0xFF0002
+} PortEventType;
+
+typedef struct
+{
+    UINT32 eventType;
+    IxEthDBPortId portID;
+    IxEthDBMacAddr macAddr;
+    BOOL staticEntry;
+} PortEvent;
+
+typedef struct
+{
+    PortEvent queue[EVENT_QUEUE_SIZE];
+    UINT32 base;
+    UINT32 length;
+} PortEventQueue;
+
+typedef struct
+{
+    IxEthDBPortId portID; /**< originating port */
+    MacDescriptor *macDescriptors[MAX_ELT_SIZE]; /**< addresses to be synced into db */
+    UINT32 addressCount; /**< number of addresses */
+} TreeSyncInfo;
+
+typedef struct
+{
+    MacTreeNode *nodes[MAX_ELT_SIZE];
+    UINT32 offsets[MAX_ELT_SIZE];
+    UINT32 nodeCount;
+} MacTreeNodeStack;
+
+/* Prototypes */
+
+/* ----------- Memory management -------------- */
+
+IX_ETH_DB_PUBLIC void ixEthDBInitMemoryPools(void);
+
+IX_ETH_DB_PUBLIC HashNode* ixEthDBAllocHashNode(void);
+IX_ETH_DB_PUBLIC void ixEthDBFreeHashNode(HashNode *);
+
+IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBAllocMacDescriptor(void);
+IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor);
+IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacDescriptor(MacDescriptor *);
+
+IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBAllocMacTreeNode(void);
+IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *);
+IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacTreeNode(MacTreeNode *);
+
+IX_ETH_DB_PUBLIC void ixEthDBPoolFreeMacTreeNode(MacTreeNode *);
+IX_ETH_DB_PUBLIC UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree);
+IX_ETH_DB_PUBLIC int ixEthDBShowMemoryStatus(void);
+
+/* Hash Table */
+IX_ETH_DB_PUBLIC void ixEthDBInitHash(HashTable *hashTable, UINT32 numBuckets, HashFunction entryHashFunction, MatchFunction *matchFunctions, FreeFunction freeFunction);
+
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference);
+IX_ETH_DB_PUBLIC void ixEthDBReleaseHashNode(HashNode *node);
+
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator);
+IX_ETH_DB_PUBLIC void ixEthDBReleaseHashIterator(HashIterator *iterator);
+
+/* API Support */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr);
+IX_ETH_DB_PUBLIC void ixEthDBMaximumFrameSizeAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
+
+/* DB Core functions */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInit(void);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger);
+IX_ETH_DB_PUBLIC HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter);
+
+/* Learning support */
+IX_ETH_DB_PUBLIC UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2);
+IX_ETH_DB_PUBLIC BOOL ixEthDBAddressMatch(void *reference, void *entry);
+IX_ETH_DB_PUBLIC UINT32 ixEthDBEntryXORHash(void *macDescriptor);
+IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyXORHash(void *macAddress);
+
+/* Port updates */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type);
+IX_ETH_DB_PUBLIC void ixEthDBUpdatePortLearningTrees(IxEthDBPortMap triggerPorts);
+IX_ETH_DB_PUBLIC void ixEthDBNPEAccessRequest(IxEthDBPortId portID);
+IX_ETH_DB_PUBLIC void ixEthDBUpdateLock(void);
+IX_ETH_DB_PUBLIC void ixEthDBUpdateUnlock(void);
+IX_ETH_DB_PUBLIC MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maximumEntries);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta);
+
+/* Init/unload */
+IX_ETH_DB_PUBLIC void ixEthDBPortSetAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBEventProcessorInit(void);
+IX_ETH_DB_PUBLIC void ixEthDBPortInit(IxEthDBPortId portID);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID);
+IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasInit(void);
+IX_ETH_DB_PUBLIC UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions);
+IX_ETH_DB_PUBLIC UINT32 ixEthDBRecordSerializeMethodsRegister(void);
+IX_ETH_DB_PUBLIC UINT32 ixEthDBUpdateTypeRegister(BOOL *typeArray);
+IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasUnload(void);
+IX_ETH_DB_PUBLIC void ixEthDBFeatureCapabilityScan(void);
+IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType);
+
+/* Event processing */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDefaultEventCallbackEnable(IxEthDBPortId portID, BOOL enable);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID);
+IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
+
+/* NPE adaptor */
+IX_ETH_DB_PUBLIC void ixEthDBGetMacDatabaseCbk(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
+IX_ETH_DB_PUBLIC void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg);
+IX_ETH_DB_PUBLIC void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize);
+IX_ETH_DB_PUBLIC void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *blocks, UINT32 *startIndex);
+IX_ETH_DB_PUBLIC void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node);
+
+/* Other public API functions */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate);
+
+/* Maximum Tx/Rx public functions */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize);
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize);
+
+/* VLAN-related */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet);
+
+/* Record search */
+IX_ETH_DB_PUBLIC BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry);
+IX_ETH_DB_PUBLIC BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry);
+IX_ETH_DB_PUBLIC BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry);
+IX_ETH_DB_PUBLIC BOOL ixEthDBNullMatch(void *reference, void *entry);
+IX_ETH_DB_PUBLIC HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter);
+IX_ETH_DB_PUBLIC HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter);
+
+/* Utilities */
+IX_ETH_DB_PUBLIC const char* mac2string(const unsigned char *mac);
+IX_ETH_DB_PUBLIC void showHashInfo(void);
+IX_ETH_DB_PUBLIC int ixEthDBAnalyzeHash(void);
+IX_ETH_DB_PUBLIC const char* errorString(IxEthDBStatus error);
+IX_ETH_DB_PUBLIC int numHashElements(void);
+IX_ETH_DB_PUBLIC void zapHashtable(void);
+IX_ETH_DB_PUBLIC BOOL ixEthDBCheckSingleBitValue(UINT32 value);
+
+/* Single Eth NPE Check */
+IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portId);
+
+#endif /* IxEthDB_p_H */
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthMii.h b/marvell/uboot/drivers/net/npe/include/IxEthMii.h
new file mode 100644
index 0000000..8d7de3d
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthMii.h
@@ -0,0 +1,246 @@
+/**
+ * @file    IxEthMii.h
+ *
+ * @brief this file contains the public API of @ref IxEthMii component
+ *
+ * Design notes :  
+ * The main intent of this API is to inplement MII high level fonctionalitoes
+ * to support the codelets provided with the IXP400 software releases. It 
+ * superceedes previous interfaces provided with @ref IxEThAcc component.
+ * 
+ * This API has been tested with the PHYs provided with the
+ * IXP400 development platforms. It may not work for specific Ethernet PHYs
+ * used on specific boards.
+ *
+ * This source code detects and interface the LXT972, LXT973 and KS6995
+ * Ethernet PHYs.
+ *
+ * This source code should be considered as an example which may need
+ * to be adapted for different hardware implementations.
+ *
+ * It is strongly recommended to use public domain and GPL utilities
+ * like libmii, mii-diag for MII interface support.
+ * 
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxEthMii_H
+#define IxEthMii_H
+
+#include <IxTypes.h>
+
+/**
+ * @defgroup IxEthMii IXP400 Ethernet Phy Access (IxEthMii) API
+ *
+ * @brief ethMii is a library that does provides access to the 
+ * Ethernet PHYs
+ *
+ *@{
+ */
+
+/**
+ * @ingroup IxEthMii
+ *
+ * @fn  ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount)
+ *
+ * @brief Scan the MDIO bus for PHYs
+ *  This function scans PHY addresses 0 through 31, and sets phyPresent[n] to 
+ *  true if a phy is discovered at address n.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
+ *
+ * @param phyPresent BOOL [in] - boolean array of IXP425_ETH_ACC_MII_MAX_ADDR entries
+ * @param maxPhyCount UINT32 [in] - number of PHYs to search for (the scan will stop when
+ *         the indicated number of PHYs is found).
+ *
+ * @return IX_STATUS
+ * - IX_ETH_ACC_SUCCESS
+ * - IX_ETH_ACC_FAIL : invalid arguments.
+ *
+ * <hr>
+ */
+PUBLIC IX_STATUS ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount);
+
+/**
+ * @ingroup IxEthMii
+ *
+ * @fn ixEthMiiPhyConfig(UINT32 phyAddr,
+		         BOOL speed100, 
+			 BOOL fullDuplex, 
+			 BOOL autonegotiate)
+ *
+ *
+ * @brief Configure a PHY
+ *   Configure a PHY's speed, duplex and autonegotiation status
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
+ *   
+ * @param phyAddr UINT32 [in] 
+ * @param speed100 BOOL [in] - set to true for 100Mbit/s operation, false for 10Mbit/s
+ * @param fullDuplex BOOL [in] - set to true for Full Duplex, false for Half Duplex
+ * @param autonegotiate BOOL [in] - set to true to enable autonegotiation
+ *
+ * @return IX_STATUS
+ * - IX_SUCCESS
+ * - IX_FAIL : invalid arguments.
+ *
+ * <hr>
+ */
+PUBLIC IX_STATUS ixEthMiiPhyConfig(UINT32 phyAddr,
+				    BOOL speed100, 
+				    BOOL fullDuplex, 
+				    BOOL autonegotiate);
+
+/**
+ * @ingroup IxEthMii
+ *
+ * @fn ixEthMiiPhyLoopbackEnable(UINT32 phyAddr)
+ *
+ *
+ * @brief Enable PHY Loopback in a specific Eth MII port
+ *
+ * @note When PHY Loopback is enabled, frames sent out to the PHY from the
+ * IXP400 will be looped back to the IXP400. They will not be transmitted out
+ * on the wire.
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
+ *
+ * @return IX_STATUS
+ * - IX_SUCCESS
+ * - IX_FAIL : invalid arguments.
+ * <hr>
+ */
+PUBLIC IX_STATUS
+ixEthMiiPhyLoopbackEnable (UINT32 phyAddr);
+
+/**
+ * @ingroup IxEthMii
+ *
+ * @fn ixEthMiiPhyLoopbackDisable(UINT32 phyAddr)
+ *
+ *
+ * @brief Disable PHY Loopback in a specific Eth MII port
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *   
+ * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
+ *
+ * @return IX_STATUS
+ * - IX_SUCCESS
+ * - IX_FAIL : invalid arguments.
+ * <hr>
+ */
+PUBLIC IX_STATUS
+ixEthMiiPhyLoopbackDisable (UINT32 phyAddr);
+
+/**
+ * @ingroup IxEthMii
+ *
+ * @fn ixEthMiiPhyReset(UINT32 phyAddr)
+ *
+ * @brief Reset a PHY
+ *   Reset a PHY
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
+ *   
+ * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
+ *
+ * @return IX_STATUS
+ * - IX_SUCCESS
+ * - IX_FAIL : invalid arguments.
+ *
+ * <hr>
+ */
+PUBLIC IX_STATUS ixEthMiiPhyReset(UINT32 phyAddr);
+
+
+/**
+ * @ingroup IxEthMii
+ *
+ * @fn ixEthMiiLinkStatus(UINT32 phyAddr, 
+			  BOOL *linkUp,
+			  BOOL *speed100, 
+			  BOOL *fullDuplex,
+		          BOOL *autoneg)
+ *
+ * @brief Retrieve the current status of a PHY
+ *   Retrieve the link, speed, duplex and autonegotiation status of a PHY
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
+ *   
+ * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
+ * @param linkUp BOOL [out] - set to true if the link is up
+ * @param speed100 BOOL [out] - set to true indicates 100Mbit/s, false indicates 10Mbit/s
+ * @param fullDuplex BOOL [out] - set to true indicates Full Duplex, false indicates Half Duplex
+ * @param autoneg BOOL [out] - set to true indicates autonegotiation is enabled, false indicates autonegotiation is disabled
+ *
+ * @return IX_STATUS
+ * - IX_SUCCESS
+ * - IX_FAIL : invalid arguments.
+ *
+ * <hr>
+ */
+PUBLIC IX_STATUS ixEthMiiLinkStatus(UINT32 phyAddr, 
+				     BOOL *linkUp,
+				     BOOL *speed100, 
+				     BOOL *fullDuplex,
+				     BOOL *autoneg);
+
+/**
+ * @ingroup IxEthMii
+ *
+ * @fn ixEthMiiPhyShow (UINT32 phyAddr)
+ *
+ *
+ * @brief Display information on a specified PHY
+ *   Display link status, speed, duplex and Auto Negotiation status
+ *
+ * - Reentrant    - no
+ * - ISR Callable - no
+ *
+ * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock.
+ *   
+ * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31)
+ *
+ * @return IX_STATUS
+ * - IX_SUCCESS
+ * - IX_FAIL : invalid arguments.
+ *
+ * <hr>
+ */
+PUBLIC IX_STATUS ixEthMiiPhyShow (UINT32 phyAddr);
+
+#endif /* ndef IxEthMii_H */
+/**
+ *@}
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthMii_p.h b/marvell/uboot/drivers/net/npe/include/IxEthMii_p.h
new file mode 100644
index 0000000..0c48a69
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthMii_p.h
@@ -0,0 +1,161 @@
+/**
+ * @file IxEthMii_p.h
+ *
+ * @author Intel Corporation
+ * @date 
+ *
+ * @brief  MII Header file
+ *
+ * Design Notes:
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxEthMii_p_H
+#define IxEthMii_p_H
+
+
+/* MII definitions - these have been verified against the LXT971 and
+ LXT972 PHYs*/
+
+#define IX_ETH_MII_MAX_REG_NUM  0x20  /* max number of registers */
+
+#define IX_ETH_MII_CTRL_REG     0x0	/* Control Register */
+#define IX_ETH_MII_STAT_REG	0x1	/* Status Register */
+#define IX_ETH_MII_PHY_ID1_REG  0x2	/* PHY identifier 1 Register */
+#define IX_ETH_MII_PHY_ID2_REG  0x3	/* PHY identifier 2 Register */
+#define IX_ETH_MII_AN_ADS_REG   0x4	/* Auto-Negotiation 	  */
+					/* Advertisement Register */
+#define IX_ETH_MII_AN_PRTN_REG  0x5	/* Auto-Negotiation 	    */
+					/* partner ability Register */
+#define IX_ETH_MII_AN_EXP_REG   0x6	/* Auto-Negotiation   */
+					/* Expansion Register */
+#define IX_ETH_MII_AN_NEXT_REG  0x7	/* Auto-Negotiation 	       */
+					/* next-page transmit Register */
+
+#define IX_ETH_MII_STAT2_REG    0x11    /* Status Register 2*/
+
+
+/* MII control register bit  */
+
+#define IX_ETH_MII_CR_COLL_TEST  0x0080  /* collision test */
+#define IX_ETH_MII_CR_FDX	 0x0100  /* FDX =1, half duplex =0 */
+#define IX_ETH_MII_CR_RESTART    0x0200  /* restart auto negotiation */
+#define IX_ETH_MII_CR_ISOLATE    0x0400  /* isolate PHY from MII */
+#define IX_ETH_MII_CR_POWER_DOWN 0x0800  /* power down */
+#define IX_ETH_MII_CR_AUTO_EN    0x1000  /* auto-negotiation enable */
+#define IX_ETH_MII_CR_100	 0x2000  /* 0 = 10mb, 1 = 100mb */
+#define IX_ETH_MII_CR_LOOPBACK   0x4000  /* 0 = normal, 1 = loopback */
+#define IX_ETH_MII_CR_RESET	 0x8000  /* 0 = normal, 1 = PHY reset */
+#define IX_ETH_MII_CR_NORM_EN    0x0000  /* just enable the PHY */
+#define IX_ETH_MII_CR_DEF_0_MASK 0xca7f  /* they must return zero */
+#define IX_ETH_MII_CR_RES_MASK   0x007f  /* reserved bits, return zero */
+
+/* MII Status register bit definitions */
+
+#define IX_ETH_MII_SR_LINK_STATUS   0x0004 /* link Status -- 1 = link */
+#define IX_ETH_MII_SR_AUTO_SEL      0x0008 /* auto speed select capable */
+#define IX_ETH_MII_SR_REMOTE_FAULT  0x0010 /* Remote fault detect */
+#define IX_ETH_MII_SR_AUTO_NEG      0x0020 /* auto negotiation complete */
+#define IX_ETH_MII_SR_10T_HALF_DPX  0x0800 /* 10BaseT HD capable */
+#define IX_ETH_MII_SR_10T_FULL_DPX  0x1000 /* 10BaseT FD capable */
+#define IX_ETH_MII_SR_TX_HALF_DPX   0x2000 /* TX HD capable */
+#define IX_ETH_MII_SR_TX_FULL_DPX   0x4000 /* TX FD capable */
+#define IX_ETH_MII_SR_T4            0x8000 /* T4 capable */
+#define IX_ETH_MII_SR_ABIL_MASK     0xff80 /* abilities mask */
+#define IX_ETH_MII_SR_EXT_CAP       0x0001 /* extended capabilities */
+
+
+/* LXT971/2 Status 2 register bit definitions */
+#define IX_ETH_MII_SR2_100          0x4000
+#define IX_ETH_MII_SR2_TX           0x2000
+#define IX_ETH_MII_SR2_RX           0x1000
+#define IX_ETH_MII_SR2_COL          0x0800
+#define IX_ETH_MII_SR2_LINK         0x0400
+#define IX_ETH_MII_SR2_FD           0x0200
+#define IX_ETH_MII_SR2_AUTO         0x0100
+#define IX_ETH_MII_SR2_AUTO_CMPLT   0x0080
+#define IX_ETH_MII_SR2_POLARITY     0x0020
+#define IX_ETH_MII_SR2_PAUSE        0x0010
+#define IX_ETH_MII_SR2_ERROR        0x0008
+
+/* MII Link Code word  bit definitions */
+
+#define IX_ETH_MII_BP_FAULT	0x2000       	/* remote fault */
+#define IX_ETH_MII_BP_ACK	0x4000       	/* acknowledge */
+#define IX_ETH_MII_BP_NP	0x8000       	/* nexp page is supported */
+
+/* MII Next Page bit definitions */
+
+#define IX_ETH_MII_NP_TOGGLE 0x0800       	/* toggle bit */
+#define IX_ETH_MII_NP_ACK2	 0x1000       	/* acknowledge two */
+#define IX_ETH_MII_NP_MSG	 0x2000       	/* message page */
+#define IX_ETH_MII_NP_ACK1	 0x4000       	/* acknowledge one */
+#define IX_ETH_MII_NP_NP	 0x8000       	/* nexp page will follow */
+
+/* MII Expansion Register bit definitions */
+
+#define IX_ETH_MII_EXP_FAULT    0x0010  /* parallel detection fault */
+#define IX_ETH_MII_EXP_PRTN_NP  0x0008  /* link partner next-page able */
+#define IX_ETH_MII_EXP_LOC_NP   0x0004  /* local PHY next-page able */
+#define IX_ETH_MII_EXP_PR	    0x0002  /* full page received */
+#define IX_ETH_MII_EXP_PRT_AN   0x0001  /* link partner auto neg able */
+
+/* technology ability field bit definitions */
+
+#define IX_ETH_MII_TECH_10BASE_T	  0x0020  /* 10Base-T */
+#define IX_ETH_MII_TECH_10BASE_FD	  0x0040  /* 10Base-T Full Duplex */
+#define IX_ETH_MII_TECH_100BASE_TX	  0x0080  /* 100Base-TX */
+#define IX_ETH_MII_TECH_100BASE_TX_FD 0x0100  /* 100Base-TX Full Duplex */
+
+#define IX_ETH_MII_TECH_100BASE_T4	0x0200	/* 100Base-T4 */
+#define IX_ETH_MII_ADS_TECH_MASK	0x1fe0	/* technology abilities mask */
+#define IX_ETH_MII_TECH_MASK	IX_ETH_MII_ADS_TECH_MASK
+#define IX_ETH_MII_ADS_SEL_MASK	0x001f	/* selector field mask */
+
+#define IX_ETH_MII_AN_FAIL     0x10    /* auto-negotiation fail */
+#define IX_ETH_MII_STAT_FAIL   0x20    /* errors in the status register */
+#define IX_ETH_MII_PHY_NO_ABLE 0x40    /* the PHY lacks some abilities */
+
+/* Definitions for MII access routines*/
+
+#define IX_ETH_MII_GO                  BIT(31)
+#define IX_ETH_MII_WRITE               BIT(26)
+#define IX_ETH_MII_TIMEOUT_10TH_SECS       (5)    
+#define IX_ETH_MII_10TH_SEC_IN_MILLIS    (100)              
+#define IX_ETH_MII_READ_FAIL           BIT(31)
+
+/* When we reset the PHY we delay for 2 seconds to allow the reset to 
+   complete*/
+#define IX_ETH_MII_RESET_DELAY_MS  (2000)     
+#define IX_ETH_MII_RESET_POLL_MS     (50)
+
+#define IX_ETH_MII_REG_SHL    16
+#define IX_ETH_MII_ADDR_SHL   21
+
+/* supported PHYs */
+#define IX_ETH_MII_LXT971_PHY_ID	0x001378E0
+#define IX_ETH_MII_LXT972_PHY_ID	0x001378E2
+#define IX_ETH_MII_LXT973_PHY_ID	0x00137A10
+#define IX_ETH_MII_LXT973A3_PHY_ID	0x00137A11
+#define IX_ETH_MII_KS8995_PHY_ID	0x00221450
+#define IX_ETH_MII_LXT9785_PHY_ID	0x001378FF	
+
+
+#define IX_ETH_MII_INVALID_PHY_ID 0x00000000
+#define IX_ETH_MII_UNKNOWN_PHY_ID 0xffffffff
+
+#endif  /*IxEthAccMii_p_H*/
diff --git a/marvell/uboot/drivers/net/npe/include/IxEthNpe.h b/marvell/uboot/drivers/net/npe/include/IxEthNpe.h
new file mode 100644
index 0000000..20bfa76
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxEthNpe.h
@@ -0,0 +1,671 @@
+#ifndef __doxygen_HIDE  /* This file is not part of the API */
+
+/**
+ * @file IxEthNpe.h
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxEthNpe IXP400 Ethernet NPE (IxEthNpe) API
+ *
+ * @brief Contains the API for Ethernet NPE.
+ * 
+ * All messages given to NPE, get back an acknowledgment. The acknowledgment 
+ * is identical to the message sent to the NPE (except for NPE_GETSTATUS message).
+ *
+ * @{
+ */
+
+
+/*--------------------------------------------------------------------------
+ * APB Message IDs - XScale->NPE
+ *------------------------------------------------------------------------*/
+
+/**
+ * @def IX_ETHNPE_NPE_GETSTATUS
+ *
+ * @brief Request from the XScale client for the NPE to return the firmware
+ * version of the currently executing image.
+ *
+ * Acknowledgment message id is same as the request message id. 
+ * NPE returns the firmware version ID to XScale.
+ */
+#define IX_ETHNPE_NPE_GETSTATUS                 0x00
+
+/**
+ * @def IX_ETHNPE_EDB_SETPORTADDRESS
+ *
+ * @brief Request from the XScale client for the NPE to set the Ethernet 
+ * port's port ID and MAC address. 
+ */
+#define IX_ETHNPE_EDB_SETPORTADDRESS            0x01
+
+/**
+ * @def IX_ETHNPE_EDB_GETMACADDRESSDATABASE
+ *
+ * @brief Request from XScale client to the NPE requesting upload of 
+ * Ethernet Filtering Database or Header Conversion Database from NPE's 
+ * data memory to XScale accessible SDRAM.
+ */
+#define IX_ETHNPE_EDB_GETMACADDRESSDATABASE     0x02
+
+/**
+ * @def IX_ETHNPE_EDB_SETMACADDRESSSDATABASE
+ *
+ * @brief Request from XScale client to the NPE requesting download of 
+ * Ethernet Filtering Database or Header Conversion Database from SDRAM
+ * to the NPE's datamemory.
+ */
+#define IX_ETHNPE_EDB_SETMACADDRESSSDATABASE    0x03
+
+/**
+ * @def IX_ETHNPE_GETSTATS
+ *
+ * @brief Request from the XScale client for the current MAC port statistics 
+ * data to be written to the (empty) statistics structure and the specified
+ * location in externa memory.
+ */
+#define IX_ETHNPE_GETSTATS                      0x04
+
+/**
+ * @def IX_ETHNPE_RESETSTATS
+ *
+ * @brief Request from the XScale client to the NPE to reset all of its internal 
+ * MAC port statistics state variables. 
+ *
+ * As a side effect, this message entails an implicit request that the NPE
+ *  write the current MAC port statistics into the MAC statistics structure 
+ * at the specified location in external memory.
+ */
+#define IX_ETHNPE_RESETSTATS                    0x05
+
+/**
+ * @def IX_ETHNPE_SETMAXFRAMELENGTHS
+ *
+ * @brief Request from the XScale client to the NPE to configure maximum framelengths
+ * and block sizes in receive and transmit direction.
+ */
+#define IX_ETHNPE_SETMAXFRAMELENGTHS            0x06
+
+/**
+ * @def IX_ETHNPE_VLAN_SETRXTAGMODE
+ *
+ * @brief Request from the XScale client to the NPE to configure VLAN frame type
+ * filtering and VLAN the tagging mode for the receiver.
+ */
+#define IX_ETHNPE_VLAN_SETRXTAGMODE             0x07
+
+/**
+ * @def IX_ETHNPE_VLAN_SETDEFAULTRXVID
+ *
+ * @brief Request from the XScale client to the NPE to set receiver's default 
+ * VLAN tag (PVID)and internal traffic class.
+ */
+#define IX_ETHNPE_VLAN_SETDEFAULTRXVID          0x08
+
+/**
+ * @def IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY
+ *
+ * @brief Request from the XScale client to the NPE to configure VLAN Port 
+ * membership and Tx tagging for 8 consecutive VLANID's.
+ */
+#define IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY    0x09
+
+/**
+ * @def IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE
+ *
+ * @brief Request from the XScale client to the NPE to configure VLAN Port
+ * membership and Tx tagging for a range of VLANID's.
+ */
+#define IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE    0x0A
+
+/**
+ * @def IX_ETHNPE_VLAN_SETRXQOSENTRY
+ *
+ * @brief Request from the XScale client to the NPE to map a user priority
+ * to QoS class and an AQM queue number.
+ */
+#define IX_ETHNPE_VLAN_SETRXQOSENTRY            0x0B
+
+/**
+ * @def IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE
+ *
+ * @brief Request from the XScale client to the NPE to enable or disable
+ * portID extraction from VLAN-tagged frames for the specified port.
+ */
+#define IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE  0x0C
+
+/**
+ * @def IX_ETHNPE_STP_SETBLOCKINGSTATE
+ *
+ * @brief Request from the XScale client to the NPE to block or unblock
+ * forwarding for spanning tree BPDUs.
+ */
+#define IX_ETHNPE_STP_SETBLOCKINGSTATE          0x0D
+
+/**
+ * @def IX_ETHNPE_FW_SETFIREWALLMODE
+ *
+ * @brief Request from the XScale client to the NPE to configure firewall
+ * services modes of operation and/or download Ethernet Firewall Database from
+ * SDRAM to NPE.
+ */
+#define IX_ETHNPE_FW_SETFIREWALLMODE            0x0E
+
+/**
+ * @def IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID 
+ *
+ * @brief Request from the XScale client to the NPE to set global frame control
+ * and duration/ID field for the 802.3 to 802.11 protocol header conversion
+ * service.
+ */
+#define IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID  0x0F
+
+/**
+ * @def IX_ETHNPE_PC_SETBBSID
+ *
+ * @brief Request from the XScale client to the NPE to set global BBSID field
+ * value for the 802.3 to 802.11 protocol header conversion service. 
+ */
+#define IX_ETHNPE_PC_SETBBSID                   0x10
+
+/**
+ * @def IX_ETHNPE_PC_SETAPMACTABLE
+ *
+ * @brief Request from the XScale client to the NPE to update a block/section/
+ * range of the AP MAC Address Table.
+ */
+#define IX_ETHNPE_PC_SETAPMACTABLE              0x11
+
+/**
+ * @def IX_ETHNPE_SETLOOPBACK_MODE
+ *
+ * @brief Turn on or off the NPE frame loopback.
+ */
+#define IX_ETHNPE_SETLOOPBACK_MODE              (0x12)
+
+/*--------------------------------------------------------------------------
+ * APB Message IDs - NPE->XScale
+ *------------------------------------------------------------------------*/
+
+/**
+ * @def IX_ETHNPE_NPE_GETSTATUS_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_NPE_GETSTATUS message. NPE firmware version 
+ * id is returned in the message.
+ */
+#define IX_ETHNPE_NPE_GETSTATUS_ACK                 0x00
+
+/**
+ * @def IX_ETHNPE_EDB_SETPORTADDRESS_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_EDB_SETPORTADDRESS message.
+ */
+#define IX_ETHNPE_EDB_SETPORTADDRESS_ACK            0x01
+
+/**
+ * @def IX_ETHNPE_EDB_GETMACADDRESSDATABASE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_EDB_GETMACADDRESSDATABASE message
+ */
+#define IX_ETHNPE_EDB_GETMACADDRESSDATABASE_ACK     0x02
+
+/**
+ * @def IX_ETHNPE_EDB_SETMACADDRESSSDATABASE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_EDB_SETMACADDRESSSDATABASE message.
+ */
+#define IX_ETHNPE_EDB_SETMACADDRESSSDATABASE_ACK    0x03
+
+/**
+ * @def IX_ETHNPE_GETSTATS_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_GETSTATS message.
+ */
+#define IX_ETHNPE_GETSTATS_ACK                      0x04
+
+/**
+ * @def IX_ETHNPE_RESETSTATS_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_RESETSTATS message.
+ */
+#define IX_ETHNPE_RESETSTATS_ACK                    0x05
+
+/**
+ * @def IX_ETHNPE_SETMAXFRAMELENGTHS_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_SETMAXFRAMELENGTHS message.
+ */
+#define IX_ETHNPE_SETMAXFRAMELENGTHS_ACK            0x06
+
+/**
+ * @def IX_ETHNPE_VLAN_SETRXTAGMODE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_VLAN_SETRXTAGMODE message.
+ */
+#define IX_ETHNPE_VLAN_SETRXTAGMODE_ACK             0x07
+
+/**
+ * @def IX_ETHNPE_VLAN_SETDEFAULTRXVID_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_VLAN_SETDEFAULTRXVID  message.
+ */
+#define IX_ETHNPE_VLAN_SETDEFAULTRXVID_ACK          0x08
+
+/**
+ * @def IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY message.
+ */
+#define IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY_ACK    0x09
+
+/**
+ * @def IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE message.
+ */
+#define IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE_ACK    0x0A
+
+/**
+ * @def IX_ETHNPE_VLAN_SETRXQOSENTRY_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_VLAN_SETRXQOSENTRY message.
+ */
+#define IX_ETHNPE_VLAN_SETRXQOSENTRY_ACK            0x0B
+
+/**
+ * @def IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE message.
+ */
+#define IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE_ACK  0x0C
+
+/**
+ * @def IX_ETHNPE_STP_SETBLOCKINGSTATE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_STP_SETBLOCKINGSTATE message.
+ */
+#define IX_ETHNPE_STP_SETBLOCKINGSTATE_ACK          0x0D
+
+/**
+ * @def IX_ETHNPE_FW_SETFIREWALLMODE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_FW_SETFIREWALLMODE message. 
+ */
+#define IX_ETHNPE_FW_SETFIREWALLMODE_ACK            0x0E
+
+/**
+ * @def IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID message.
+ */
+#define IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID_ACK  0x0F
+
+/**
+ * @def IX_ETHNPE_PC_SETBBSID_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_PC_SETBBSID message.
+ */
+#define IX_ETHNPE_PC_SETBBSID_ACK                   0x10
+
+/**
+ * @def IX_ETHNPE_PC_SETAPMACTABLE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_PC_SETAPMACTABLE message.
+ */
+#define IX_ETHNPE_PC_SETAPMACTABLE_ACK              0x11
+
+/**
+ * @def IX_ETHNPE_SETLOOPBACK_MODE_ACK
+ *
+ * @brief Acknowledgment to IX_ETHNPE_SETLOOPBACK_MODE message.
+ */
+#define IX_ETHNPE_SETLOOPBACK_MODE_ACK              (0x12)
+
+/*--------------------------------------------------------------------------
+ * Queue Manager Queue entry bit field boundary definitions
+ *------------------------------------------------------------------------*/
+
+/**
+ * @def MASK(hi,lo)
+ *
+ * @brief Macro for mask
+ */
+#define MASK(hi,lo)                    (((1 << (1 + ((hi) - (lo)))) - 1) << (lo))
+
+/**
+ * @def BITS(x,hi,lo)
+ *
+ * @brief Macro for bits
+ */
+#define BITS(x,hi,lo)                  (((x) & MASK(hi,lo)) >> (lo))
+
+/**
+ * @def IX_ETHNPE_QM_Q_RXENET_LENGTH_MASK
+ *
+ * @brief QMgr Queue LENGTH field mask
+ */
+#define IX_ETHNPE_QM_Q_RXENET_LENGTH_MASK   0x3fff
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_FLAG_R
+ *
+ * @brief QMgr Queue FLAG field right boundary
+ */
+#define IX_ETHNPE_QM_Q_FIELD_FLAG_R             20
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_FLAG_MASK
+ *
+ * @brief QMgr Queue FLAG field mask
+ *
+ * Multicast bit : BIT(4)
+ * Broadcast bit : BIT(5)
+ * IP bit        : BIT(6) (linux only)
+ *
+ */
+#ifdef __vxworks
+#define IX_ETHNPE_QM_Q_FIELD_FLAG_MASK           0x30
+#else
+#define IX_ETHNPE_QM_Q_FIELD_FLAG_MASK           0x70
+#endif
+
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_NPEID_L
+ *
+ * @brief QMgr Queue NPE ID field left boundary
+ */
+#define IX_ETHNPE_QM_Q_FIELD_NPEID_L            1
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_NPEID_R
+ *
+ * @brief QMgr Queue NPE ID field right boundary
+ */
+#define IX_ETHNPE_QM_Q_FIELD_NPEID_R            0
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_PRIOR_L
+ *
+ * @brief QMgr Queue Priority field left boundary
+ */
+#define IX_ETHNPE_QM_Q_FIELD_PRIOR_L            2
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_PRIOR_R
+ *
+ * @brief QMgr Queue Priority field right boundary
+ */
+#define IX_ETHNPE_QM_Q_FIELD_PRIOR_R            0
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_ADDR_L 
+ *
+ * @brief QMgr Queue Address field left boundary
+ */
+#define IX_ETHNPE_QM_Q_FIELD_ADDR_L             31
+
+/**
+ * @def IX_ETHNPE_QM_Q_FIELD_ADDR_R
+ *
+ * @brief QMgr Queue Address field right boundary
+ */
+#define IX_ETHNPE_QM_Q_FIELD_ADDR_R              5
+
+/*--------------------------------------------------------------------------
+ * Queue Manager Queue entry bit field masks
+ *------------------------------------------------------------------------*/
+
+/**
+ * @def IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK 
+ *
+ * @brief Macro to mask the Address field of the FreeEnet Queue Manager Entry
+ */
+#define IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK \
+            MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \
+                  IX_ETHNPE_QM_Q_FIELD_ADDR_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_RXENET_NPEID_MASK  
+ *
+ * @brief Macro to mask the NPE ID field of the RxEnet Queue Manager Entry
+ */
+#define IX_ETHNPE_QM_Q_RXENET_NPEID_MASK \
+            MASK (IX_ETHNPE_QM_Q_FIELD_NPEID_L, \
+                  IX_ETHNPE_QM_Q_FIELD_NPEID_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_RXENET_ADDR_MASK 
+ *
+ * @brief Macro to mask the Mbuf Address field of the RxEnet Queue Manager Entry
+ */
+#define IX_ETHNPE_QM_Q_RXENET_ADDR_MASK \
+            MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \
+                  IX_ETHNPE_QM_Q_FIELD_ADDR_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENET_PRIOR_MASK
+ *
+ * @brief Macro to mask the Priority field of the TxEnet Queue Manager Entry
+ */
+#define IX_ETHNPE_QM_Q_TXENET_PRIOR_MASK \
+            MASK (IX_ETHNPE_QM_Q_FIELD_PRIOR_L, \
+                  IX_ETHNPE_QM_Q_FIELD_PRIOR_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENET_ADDR_MASK 
+ *
+ * @brief Macro to mask the Mbuf Address field of the TxEnet Queue Manager Entry
+ */
+#define IX_ETHNPE_QM_Q_TXENET_ADDR_MASK \
+            MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \
+                  IX_ETHNPE_QM_Q_FIELD_ADDR_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK 
+ *
+ * @brief Macro to mask the NPE ID field of the TxEnetDone Queue Manager Entry
+ */
+#define IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK \
+            MASK (IX_ETHNPE_QM_Q_FIELD_NPEID_L, \
+                  IX_ETHNPE_QM_Q_FIELD_NPEID_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK 
+ * 
+ * @brief Macro to mask the Mbuf Address field of the TxEnetDone Queue Manager 
+ * Entry
+ */
+#define IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK \
+            MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \
+                  IX_ETHNPE_QM_Q_FIELD_ADDR_R)
+
+/*--------------------------------------------------------------------------
+ * Queue Manager Queue entry bit field value extraction macros
+ *------------------------------------------------------------------------*/
+
+/**
+ * @def IX_ETHNPE_QM_Q_FREEENET_ADDR_VAL(x)
+ *
+ * @brief Extraction macro for Address field of FreeNet Queue Manager Entry 
+ *
+ * Pointer to an mbuf buffer descriptor
+ */
+#define IX_ETHNPE_QM_Q_FREEENET_ADDR_VAL(x) \
+            ((x) & IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK)
+
+/**
+ * @def IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(x)
+ *
+ * @brief Extraction macro for NPE ID field of RxEnet Queue Manager Entry 
+ *
+ * Set to 0 for entries originating from the Eth0 NPE; 
+ * Set to 1 for entries originating from the Eth1 NPE.
+ */
+#define IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(x) \
+            BITS (x, IX_ETHNPE_QM_Q_FIELD_NPEID_L, \
+                     IX_ETHNPE_QM_Q_FIELD_NPEID_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_RXENET_PORTID_VAL(x)
+ *
+ * @brief Extraction macro for Port ID field of RxEnet Queue Manager Entry 
+ *
+ * 0-5: Assignable (by the XScale client) to any of the physical ports.
+ * 6: It is reserved
+ * 7: Indication that the NPE did not find the associated frame's destination MAC address within 
+ * its internal filtering database.
+ */
+#define IX_ETHNPE_QM_Q_RXENET_PORTID_VAL(x) \
+            BITS (x, IX_ETHNPE_QM_Q_FIELD_PORTID_L, \
+                     IX_ETHNPE_QM_Q_Field_PortID_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_RXENET_ADDR_VAL(x)
+ *
+ * @brief Extraction macro for Address field of RxEnet Queue Manager Entry
+ *
+ * Pointer to an mbuf buffer descriptor
+ */
+#define IX_ETHNPE_QM_Q_RXENET_ADDR_VAL(x) \
+            ((x) & IX_ETHNPE_QM_Q_RXENET_ADDR_MASK)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENET_PRIOR_VAL(x)
+ *
+ * @brief Extraction macro for Priority field of TxEnet Queue Manager Entry
+ *
+ * Priority of the packet (as described in IEEE 802.1D). This field is
+ * cleared upon return from the Ethernet NPE to the TxEnetDone queue.
+ */
+#define IX_ETHNPE_QM_Q_TXENET_PRIOR_VAL(x) \
+            BITS (x, IX_ETHNPE_QM_Q_FIELD_PRIOR_L, \
+                     IX_ETHNPE_QM_Q_FIELD_PRIOR_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENET_ADDR_VAL(x)
+ *
+ * @brief Extraction macro for Address field of Queue Manager TxEnet Queue 
+ * Manager Entry
+ *
+ * Pointer to an mbuf buffer descriptor
+ */
+#define IX_ETHNPE_QM_Q_TXENET_ADDR_VAL(x) \
+            ((x) & IX_ETHNPE_QM_Q_TXENET_ADDR_MASK)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENETDONE_NPEID_VAL(x)
+ *
+ * @brief Extraction macro for NPE ID field of TxEnetDone Queue Manager Entry
+ *
+ * Set to 0 for entries originating from the Eth0 NPE; set to 1 for en-tries 
+ * originating from the Eth1 NPE.
+ */
+#define IX_ETHNPE_QM_Q_TXENETDONE_NPEID_VAL(x) \
+            BITS (x, IX_ETHNPE_QM_Q_FIELD_NPEID_L, \
+                     IX_ETHNPE_QM_Q_FIELD_NPEID_R)
+
+/**
+ * @def IX_ETHNPE_QM_Q_TXENETDONE_ADDR_VAL(x)
+ *
+ * @brief Extraction macro for Address field of TxEnetDone Queue Manager Entry
+ *
+ * Pointer to an mbuf buffer descriptor
+ */
+#define IX_ETHNPE_QM_Q_TXENETDONE_ADDR_VAL(x) \
+            ((x) & IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK)
+
+
+/*--------------------------------------------------------------------------
+ * NPE limits
+ *------------------------------------------------------------------------*/
+
+/**
+ * @def IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN
+ * 
+ * @brief Macro to check the minimum length of a rx free buffer
+ */
+#define IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN (64)
+
+/**
+ * @def IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK
+ * 
+ * @brief Mask to apply to the mbuf length before submitting it to the NPE
+ * (the NPE handles only rx free mbufs which are multiple of 64)
+ * 
+ * @sa IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK
+ */
+#define IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK (~63)
+
+/**
+ * @def IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_UP(size)
+ * 
+ * @brief  Round up to get the size necessary to receive without chaining
+ * the frames which are (size) bytes (the NPE operates by multiple of 64)
+ * e.g. To receive 1514 bytes frames, the size of the buffers in replenish
+ * has to be at least (1514+63)&(~63) = 1536 bytes.
+ *
+ */
+#define IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_UP(size) (((size) + 63) & ~63)
+
+/**
+ * @def IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_DOWN(size)
+ *
+ * @brief Round down to apply to the mbuf length before submitting
+ * it to the NPE. (the NPE operates by multiple of 64)
+ *
+ */
+#define IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_DOWN(size) ((size) & ~63)
+
+/**
+ * @def IX_ETHNPE_ACC_FRAME_LENGTH_MAX
+ * 
+ * @brief maximum mbuf length supported by the NPE
+ * 
+ * @sa IX_ETHNPE_ACC_FRAME_LENGTH_MAX
+ */
+#define IX_ETHNPE_ACC_FRAME_LENGTH_MAX (16320)
+
+/**
+ * @def IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT
+ * 
+ * @brief default mbuf length supported by the NPE
+ * 
+ * @sa IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT
+ */
+#define IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT (1522)
+
+/**
+ * @def IX_ETHNPE_ACC_LENGTH_OFFSET
+ *
+ * @brief Offset of the cluster length field in the word shared with the NPEs
+ */
+#define IX_ETHNPE_ACC_LENGTH_OFFSET 16
+
+/**
+ * @def IX_ETHNPE_ACC_PKTLENGTH_MASK
+ *
+ * @brief Mask of the cluster length field in the word shared with the NPEs
+ */
+#define IX_ETHNPE_ACC_PKTLENGTH_MASK 0x3fff
+
+
+/**
+ *@}
+ */
+
+#endif /* __doxygen_HIDE */
diff --git a/marvell/uboot/drivers/net/npe/include/IxFeatureCtrl.h b/marvell/uboot/drivers/net/npe/include/IxFeatureCtrl.h
new file mode 100644
index 0000000..987b00b
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxFeatureCtrl.h
@@ -0,0 +1,718 @@
+/**
+ * @file IxFeatureCtrl.h
+ *
+ * @date 30-Jan-2003
+
+ * @brief This file contains the public API of the IXP400 Feature Control
+ *        component.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+/* ------------------------------------------------------
+   Doxygen group definitions
+   ------------------------------------------------------ */
+/**
+ * @defgroup IxFeatureCtrlAPI IXP400 Feature Control (IxFeatureCtrl) API
+ *
+ * @brief The Public API for the IXP400 Feature Control.
+ * 
+ * @{
+ */
+
+#ifndef IXFEATURECTRL_H
+#define IXFEATURECTRL_H
+
+/*
+ * User defined include files
+ */
+#include "IxOsal.h"
+
+/*
+ * #defines and macros
+ */
+
+/*************************************************************
+ * The following are IxFeatureCtrlComponentCheck return values.
+ ************************************************************/
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @def  IX_FEATURE_CTRL_COMPONENT_DISABLED
+ *
+ * @brief Hardware Component is disabled/unavailable.
+ *        Return status by ixFeatureCtrlComponentCheck()  
+ */
+#define  IX_FEATURE_CTRL_COMPONENT_DISABLED 0
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @def  IX_FEATURE_CTRL_COMPONENT_ENABLED
+ *
+ * @brief Hardware Component is available. 
+ *        Return status by ixFeatureCtrlComponentCheck()  
+ */
+#define  IX_FEATURE_CTRL_COMPONENT_ENABLED  1
+
+/***********************************************************************************
+ * Product ID in XScale CP15 - Register 0
+ *  - It contains information on the maximum XScale Core Frequency and
+ *    Silicon Stepping.  
+ *  - XScale Core Frequency Id indicates only the maximum XScale frequency
+ *    achievable and not the running XScale frequency (maybe stepped down).    
+ *  - The register is read by using ixFeatureCtrlProductIdRead.
+ *  - Usage example: 
+ *          productId = ixFeatureCtrlProductIdRead();
+ *          if( (productId & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) == 
+ *              IX_FEATURE_CTRL_SILICON_TYPE_A0 )
+ *          if( (productId & IX_FEATURE_CTRL_XSCALE_FREQ_MASK) == 
+ *              IX_FEATURE_CTRL_XSCALE_FREQ_533 )    
+ * 
+ *  31 28 27 24 23 20 19 16 15 12 11        9 8                   4 3              0  
+ *  -------------------------------------------------------------------------------- 
+ * | 0x6 | 0x9 | 0x0 | 0x5 | 0x4 | Device ID | XScale Core Freq Id | Si Stepping Id |    
+ *  --------------------------------------------------------------------------------
+ *
+ *   Maximum Achievable XScale Core Frequency Id :  533MHz  - 0x1C 
+ *                                                  400MHz  - 0x1D 
+ *                                                  266MHz  - 0x1F
+ *
+ *   <b>THE CORE FREQUENCY ID IS NOT APPLICABLE TO IXP46X <\b>
+ *  
+ *   The above is applicable to IXP42X only. CP15 in IXP46X does not contain any
+ *   Frequency ID. 
+ * 
+ *  Si Stepping Id            :  A       - 0x0    
+ *                               B       - 0x1 
+ *  
+ *  XScale Core freq Id - Device ID [11:9] : IXP42X - 0x0
+ *                                           IXP46X - 0x1
+ *************************************************************************************/
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @def IX_FEATURE_CTRL_SILICON_TYPE_A0
+ *
+ * @brief This is the value of A0 Silicon in product ID. 
+ */
+#define IX_FEATURE_CTRL_SILICON_TYPE_A0   0
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @def IX_FEATURE_CTRL_SILICON_TYPE_B0
+ *
+ * @brief This is the value of B0 Silicon in product ID.
+ */
+#define IX_FEATURE_CTRL_SILICON_TYPE_B0   1
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @def IX_FEATURE_CTRL_SILICON_STEPPING_MASK
+ *
+ * @brief This is the mask of silicon stepping in product ID. 
+ */
+#define IX_FEATURE_CTRL_SILICON_STEPPING_MASK  0xF 
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURE_CTRL_DEVICE_TYPE_MASK
+ *
+ * @brief This is the mask of silicon stepping in product ID.
+ */
+#define IX_FEATURE_CTRL_DEVICE_TYPE_MASK  (0x7) 
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET
+ *
+ * @brief This is the mask of silicon stepping in product ID.
+ */
+#define IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET  9
+
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @def IX_FEATURE_CTRL_XSCALE_FREQ_533
+ *
+ * @brief This is the value of 533MHz XScale Core in product ID.
+ */
+#define IX_FEATURE_CTRL_XSCALE_FREQ_533  ((0x1C)<<4)
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @def IX_FEATURE_CTRL_XSCALE_FREQ_400
+ *
+ * @brief This is the value of 400MHz XScale Core in product ID.
+ */
+#define IX_FEATURE_CTRL_XSCALE_FREQ_400  ((0x1D)<<4)
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @def IX_FEATURE_CTRL_XSCALE_FREQ_266
+ *
+ * @brief This is the value of 266MHz XScale Core in product ID.
+ */
+#define IX_FEATURE_CTRL_XSCALE_FREQ_266 ((0x1F)<<4)   
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @def IX_FEATURE_CTRL_XSCALE_FREQ_MASK
+ *
+ * @brief This is the mask of XScale Core in product ID.
+ */
+#define IX_FEATURE_CTRL_XSCALE_FREQ_MASK ((0xFF)<<4)  
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @def IX_FEATURECTRL_REG_UTOPIA_32PHY
+ *
+ * @brief Maximum  UTOPIA PHY available is 32.  
+ * 
+ */
+#define IX_FEATURECTRL_REG_UTOPIA_32PHY  0x0
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @def IX_FEATURECTRL_REG_UTOPIA_16PHY
+ *
+ * @brief Maximum  UTOPIA PHY available is 16.  
+ * 
+ */
+#define IX_FEATURECTRL_REG_UTOPIA_16PHY  0x1
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @def IX_FEATURECTRL_REG_UTOPIA_8PHY
+ *
+ * @brief Maximum  UTOPIA PHY available to is 8.  
+ * 
+ */
+#define IX_FEATURECTRL_REG_UTOPIA_8PHY   0x2
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @def IX_FEATURECTRL_REG_UTOPIA_4PHY
+ *
+ * @brief Maximum  UTOPIA PHY available to is 4.  
+ * 
+ */
+#define IX_FEATURECTRL_REG_UTOPIA_4PHY   0x3
+
+#ifdef __ixp46X
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_REG_XSCALE_533FREQ
+ *
+ * @brief Maximum  frequency available to IXP46x is 533 MHz.
+ *
+ */
+#define IX_FEATURECTRL_REG_XSCALE_533FREQ   0x0
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_REG_XSCALE_667FREQ
+ *
+ * @brief Maximum  frequency available to IXP46x is 667 MHz.
+ *
+ */
+#define IX_FEATURECTRL_REG_XSCALE_667FREQ   0x1
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_REG_XSCALE_400FREQ
+ *
+ * @brief Maximum  frequency available to IXP46x is 400 MHz.
+ *
+ */
+#define IX_FEATURECTRL_REG_XSCALE_400FREQ   0x2
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_REG_XSCALE_266FREQ
+ *
+ * @brief Maximum  frequency available to IXP46x is 266 MHz.
+ *
+ */
+#define IX_FEATURECTRL_REG_XSCALE_266FREQ   0x3
+
+#endif /* __ixp46X */
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE
+ *
+ * @brief Component selected is not available for device
+ *
+ */
+#define IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE  0x0000
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @def IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE
+ *
+ * @brief Component selected is not available for device
+ *
+ */
+#define IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE  0xffff
+
+/**
+ * @defgroup IxFeatureCtrlSwConfig Software Configuration for Access Component
+ *
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @brief This section describes software configuration in access component. The
+ *        configuration can be changed at run-time. ixFeatureCtrlSwConfigurationCheck( )
+ *        will be used across applicable access component to check the configuration.
+ *        ixFeatureCtrlSwConfigurationWrite( ) is used to write the software configuration.
+ *
+ * @note <b>All software configurations are default to be enabled.</b> 
+ *
+ * @{
+ */
+/**
+ * @ingroup IxFeatureCtrlSwConfig
+ *
+ * @def IX_FEATURE_CTRL_SWCONFIG_DISABLED
+ *
+ * @brief Software configuration is disabled. 
+ * 
+ */
+#define IX_FEATURE_CTRL_SWCONFIG_DISABLED 0  
+
+/**
+ * @ingroup IxFeatureCtrlSwConfig
+ *
+ * @def IX_FEATURE_CTRL_SWCONFIG_ENABLED
+ *
+ * @brief Software configuration is enabled. 
+ * 
+ */
+#define IX_FEATURE_CTRL_SWCONFIG_ENABLED 1  
+
+/**
+ * Section for enums
+ **/
+
+/**
+ * @ingroup IxFeatureCtrlBuildDevice
+ *
+ * @enum IxFeatureCtrlBuildDevice
+ *
+ * @brief Indicates software build type.
+ *
+ * Default build type is IXP42X
+ *
+ */
+typedef enum
+{
+    IX_FEATURE_CTRL_SW_BUILD_IXP42X = 0, /**<Build type is IXP42X */
+    IX_FEATURE_CTRL_SW_BUILD_IXP46X      /**<Build type is IXP46X */
+} IxFeatureCtrlBuildDevice;
+
+/**
+ * @ingroup IxFeatureCtrlSwConfig
+ *
+ * @enum IxFeatureCtrlSwConfig
+ *
+ * @brief Enumeration for software configuration in access components.
+ *
+ * Entry for new run-time software configuration should be added here.
+ */
+typedef enum
+{
+    IX_FEATURECTRL_ETH_LEARNING = 0,       /**< EthDB Learning Feature */
+    IX_FEATURECTRL_ORIGB0_DISPATCHER,  /**< IXP42X B0 and IXP46X dispatcher without 
+                                            livelock prevention functionality Feature */
+    IX_FEATURECTRL_SWCONFIG_MAX        /**< Maximum boudary for IxFeatureCtrlSwConfig  */
+} IxFeatureCtrlSwConfig;
+
+
+/************************************************************************
+ * IXP400 Feature Control Register
+ * - It contains the information (available/unavailable) of IXP425&IXP46X
+ *   hardware components in their corresponding bit location.
+ * - Bit value of 0 means the hardware component is available
+ *   or not software disabled. Hardware component that is available
+ *   can be software disabled.
+ * - Bit value of 1 means the hardware is unavailable or software
+ *   disabled.Hardware component that is unavailable cannot be software
+ *   enabled.
+ * - Use ixFeatureCtrlHwCapabilityRead() to read the hardware component's
+ *   availability.
+ * - Use ixFeatureCtrlRead() to get the current IXP425/IXP46X feature control
+ *   register value.
+ *
+ *   Bit            Field Description (Hardware Component Availability)
+ *   ---            ---------------------------------------------------
+ *    0             RComp Circuitry
+ *    1             USB Controller
+ *    2             Hashing Coprocessor
+ *    3             AES Coprocessor
+ *    4             DES Coprocessor
+ *    5             HDLC Coprocessor
+ *    6             AAL Coprocessor         - Always available in IXP46X
+ *    7             HSS Coprocesspr
+ *    8             Utopia Coprocessor
+ *    9             Ethernet 0 Coprocessor
+ *   10             Ethernet 1 Coprocessor
+ *   11             NPE A
+ *   12             NPE B
+ *   13             NPE C
+ *   14             PCI Controller
+ *   15             ECC/TimeSync Coprocessor -  Only applicable to IXP46X
+ *  16-17           Utopia PHY Limit Status : 0x0 - 32 PHY
+ *                                            0x1 - 16 PHY
+ *                                            0x2 -  8 PHY
+ *                                            0x3 -  4 PHY
+ *
+ *  Portions below are only applicable to IXP46X
+ *   18             USB Host Coprocessor
+ *   19             NPE A Ethernet - 0 for Enable if Utopia = 1
+ *   20             NPE B Ethernet coprocessor 1-3.
+ *   21             RSA Crypto Block coprocessor.
+ *  22-23           Processor frequency : 0x0 - 533 MHz
+ *                                        0x1 - 667 MHz
+ *                                        0x2 - 400 MHz
+ *                                        0x3 - 266 MHz
+ *  24-31           Reserved
+ *
+ ************************************************************************/
+/*Section generic to both IXP42X and IXP46X*/
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @enum IxFeatureCtrlComponentType
+ *
+ * @brief Enumeration for components availavble
+ *
+ */
+typedef enum
+{
+    IX_FEATURECTRL_RCOMP = 0, /**<bit location for RComp Circuitry*/
+    IX_FEATURECTRL_USB,       /**<bit location for USB Controller*/
+    IX_FEATURECTRL_HASH,      /**<bit location for Hashing Coprocessor*/
+    IX_FEATURECTRL_AES,       /**<bit location for AES Coprocessor*/
+    IX_FEATURECTRL_DES,       /**<bit location for DES Coprocessor*/
+    IX_FEATURECTRL_HDLC,      /**<bit location for HDLC Coprocessor*/
+    IX_FEATURECTRL_AAL,       /**<bit location for AAL Coprocessor*/
+    IX_FEATURECTRL_HSS,       /**<bit location for HSS Coprocessor*/
+    IX_FEATURECTRL_UTOPIA,    /**<bit location for UTOPIA Coprocessor*/
+    IX_FEATURECTRL_ETH0,      /**<bit location for Ethernet 0 Coprocessor*/
+    IX_FEATURECTRL_ETH1,      /**<bit location for Ethernet 1 Coprocessor*/
+    IX_FEATURECTRL_NPEA,      /**<bit location for NPE A*/
+    IX_FEATURECTRL_NPEB,      /**<bit location for NPE B*/
+    IX_FEATURECTRL_NPEC,      /**<bit location for NPE C*/
+    IX_FEATURECTRL_PCI,       /**<bit location for PCI Controller*/
+    IX_FEATURECTRL_ECC_TIMESYNC,     /**<bit location for TimeSync Coprocessor*/
+    IX_FEATURECTRL_UTOPIA_PHY_LIMIT, /**<bit location for Utopia PHY Limit Status*/
+    IX_FEATURECTRL_UTOPIA_PHY_LIMIT_BIT2, /**<2nd bit of PHY limit status*/
+    IX_FEATURECTRL_USB_HOST_CONTROLLER, /**<bit location for USB host controller*/
+    IX_FEATURECTRL_NPEA_ETH,  /**<bit location for NPE-A Ethernet Disable*/
+    IX_FEATURECTRL_NPEB_ETH,  /**<bit location for NPE-B Ethernet 1-3 Coprocessors Disable*/
+    IX_FEATURECTRL_RSA,       /**<bit location for RSA Crypto block Coprocessors Disable*/
+    IX_FEATURECTRL_XSCALE_MAX_FREQ, /**<bit location for XScale max frequency*/
+    IX_FEATURECTRL_XSCALE_MAX_FREQ_BIT2, /**<2nd xscale max freq bit NOT TO BE USED */
+    IX_FEATURECTRL_MAX_COMPONENTS
+} IxFeatureCtrlComponentType;
+
+/**
+ * @ingroup IxFeatureCtrlDeviceId
+ *
+ * @enum IxFeatureCtrlDeviceId
+ *
+ * @brief Enumeration for device type.
+ *
+ * @warning This enum is closely related to the npe image. Its format should comply
+ *          with formats used in the npe image ImageID. This is indicated by the  
+ *          first nibble of the image ID. This should also be in sync with the
+ *          with what is defined in CP15.  Current available formats are
+ *          - IXP42X - 0000
+ *          - IXP46X - 0001
+ *
+ */
+typedef enum
+{
+    IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X = 0, /**<Device type is IXP42X */
+    IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X, /**<Device type is IXP46X */
+    IX_FEATURE_CTRL_DEVICE_TYPE_MAX /**<Max devices */
+} IxFeatureCtrlDeviceId;
+
+
+/**
+ * @} addtogroup IxFeatureCtrlSwConfig
+ */
+
+/*
+ * Typedefs
+ */
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ * 
+ * @typedef IxFeatureCtrlReg
+ *
+ * @brief Feature Control Register that contains hardware components'
+ *        availability information.
+ */
+typedef UINT32 IxFeatureCtrlReg;
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ * 
+ * @typedef IxFeatureCtrlProductId
+ *
+ * @brief Product ID of Silicon that contains Silicon Stepping and 
+ *        Maximum XScale Core Frequency information.  
+ */
+typedef UINT32 IxFeatureCtrlProductId;
+
+/*
+ * Prototypes for interface functions
+ */
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @fn IxFeatureCtrlReg ixFeatureCtrlRead (void)
+ * 
+ * @brief This function reads out the CURRENT value of Feature Control Register.
+ *        The current value may not be the same as that of the hardware component 
+ *        availability.    
+ * 
+ * The bit location of each hardware component is defined above. 
+ * A value of '1' in bit means the hardware component is not available.  A value of '0'   
+ * means the hardware component is available.
+ *
+ * @return 
+ *      - IxFeatureCtrlReg - the current value of IXP400 Feature Control Register
+ */ 
+PUBLIC IxFeatureCtrlReg
+ixFeatureCtrlRead (void);
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @fn IxFeatureDeviceId ixFeatureCtrlDeviceRead (void)
+ *
+ * @brief This function gets the type of device that the software is currently running
+ *        on
+ *
+ * This function reads the feature Ctrl register specifically to obtain the device id.
+ * The definitions of the avilable IDs are as above.
+ *
+ * @return
+ *      - IxFeatureCtrlDeviceId - the type of device currently running
+ */
+IxFeatureCtrlDeviceId
+ixFeatureCtrlDeviceRead (void);
+
+/**
+ * @ingroup IxFeatureCtrlAPI
+ *
+ * @fn IxFeatureCtrlBuildDevice ixFeatureCtrlSoftwareBuildGet (void)
+ *
+ * @brief This function refers to  the value set by the compiler flag to determine
+ *        the type of device the software is built for.
+ *
+ * The function reads the compiler flag to determine the device the software is
+ * built for. When the user executes build in the command line, 
+ * a compile time flag (__ixp42X/__ixp46X is set. This API reads this 
+ * flag and returns the software build type to the calling client.
+ *
+ * @return
+ *      - IxFeatureCtrlBuildDevice - the type of device software is built for.
+ */
+IxFeatureCtrlBuildDevice
+ixFeatureCtrlSoftwareBuildGet (void);
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @fn IxFeatureCtrlReg ixFeatureCtrlHwCapabilityRead (void)
+ * 
+ * @brief This function reads out the hardware capability of a silicon type as defined in 
+ * feature control register.This value is different from that returned by 
+ * ixFeatureCtrlRead() because this function returns the actual hardware component
+ * availability.     
+ *
+ * The bit location of each hardware component is defined above. 
+ * A value of '1' in bit means the hardware component is not available.  A value of '0'   
+ * means the hardware component is available.
+ *
+ * @return 
+ *      - IxFeatureCtrlReg - the hardware capability of IXP400. 
+ *
+ * @warning
+ *      - This function must not be called when IXP400 is running as the result
+ *        is undefined.    
+ */ 
+PUBLIC IxFeatureCtrlReg
+ixFeatureCtrlHwCapabilityRead (void);
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @fn void ixFeatureCtrlWrite (IxFeatureCtrlReg expUnitReg)
+ * 
+ * @brief This function write the value stored in IxFeatureCtrlReg expUnitReg  
+ *        to the Feature Control Register. 
+ * 
+ * The bit location of each hardware component is defined above.
+ * The write is only effective on available hardware components. Writing '1' in a  
+ * bit will software disable the respective hardware component. A '0' will mean that  
+ * the hardware component will remain to be operable. 
+ *
+ * @param expUnitReg @ref IxFeatureCtrlReg [in] - The value to be written to feature control 
+ *                                          register.
+ *
+ * @return none
+ *
+ */ 
+PUBLIC void
+ixFeatureCtrlWrite (IxFeatureCtrlReg expUnitReg);
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @fn IX_STATUS ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType)
+ * 
+ * @brief This function will check the availability of hardware component specified
+ *        as componentType value. 
+ *
+ *        Usage Example:<br> 
+ *         -  if(IX_FEATURE_CTRL_COMPONENT_DISABLED != 
+ *              ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0)) <br>
+ *         -  if(IX_FEATURE_CTRL_COMPONENT_ENABLED == 
+ *              ixFeatureCtrlComponentCheck(IX_FEATURECTRL_PCI)) <br>
+ *
+ * This function is typically called during component initialization time. 
+ *
+ * @param componentType @ref IxFeatureCtrlComponentType [in] - the type of a component as
+ *        defined above as IX_FEATURECTRL_XXX (Exp: IX_FEATURECTRL_PCI, IX_FEATURECTRL_ETH0)           
+
+ *        
+ * @return 
+ *      - IX_FEATURE_CTRL_COMPONENT_ENABLED if component is available 
+ *      - IX_FEATURE_CTRL_COMPONENT_DISABLED if component is unavailable            
+ */ 
+PUBLIC IX_STATUS
+ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType);
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ * 
+ * @fn IxFeatureCtrlProductId ixFeatureCtrlProductIdRead (void)
+ * 
+ * @brief This function will return IXP400 product ID i.e. CP15,
+ *        Register 0.
+ *                                                
+ * @return 
+ *      - IxFeatureCtrlProductId - the value of product ID.
+ *
+ */ 
+PUBLIC IxFeatureCtrlProductId
+ixFeatureCtrlProductIdRead (void) ;
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @fn IX_STATUS ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType)
+ * 
+ * @brief This function checks whether the specified software configuration is
+ *        enabled or disabled. 
+ *
+ *        Usage Example:<br> 
+ *        - if(IX_FEATURE_CTRL_SWCONFIG_DISABLED != 
+ *            ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING)) <br>
+ *        - if(IX_FEATURE_CTRL_SWCONFIG_ENABLED == 
+ *            ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING)) <br>
+ *
+ * This function is typically called during access component initialization time. 
+ *
+ * @param swConfigType @ref IxFeatureCtrlSwConfig [in] - the type of a software configuration
+ *        defined in IxFeatureCtrlSwConfig enumeration.          
+ *        
+ * @return 
+ *      - IX_FEATURE_CTRL_SWCONFIG_ENABLED if software configuration is enabled. 
+ *      - IX_FEATURE_CTRL_SWCONFIG_DISABLED if software configuration is disabled.            
+ */ 
+PUBLIC IX_STATUS
+ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType);
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @fn void ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled)
+ * 
+ * @brief This function enable/disable the specified software configuration.  
+ *
+ *        Usage Example:<br> 
+ *        - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, true) is used
+ *          to enable Ethernet Learning Feature <br>
+ *        - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, false) is used
+ *          to disable Ethernet Learning Feature <br> 
+ *
+ * @param swConfigType IxFeatureCtrlSwConfig [in] - the type of a software configuration
+ *        defined in IxFeatureCtrlSwConfig enumeration. 
+ * @param enabled BOOL [in] - To enable(true) / disable (false) the specified software
+ *                           configuration.            
+ *
+ * @return none
+ *          
+ */ 
+PUBLIC void
+ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled);
+
+/**
+ * @ingroup IxFeatureCtrlAPI 
+ *
+ * @fn void ixFeatureCtrlIxp400SwVersionShow (void)
+ * 
+ * @brief This function shows the current software release information for IXP400 
+ *          
+ * @return none
+ *          
+ */ 
+PUBLIC void
+ixFeatureCtrlIxp400SwVersionShow (void);
+
+#endif /* IXFEATURECTRL_H */
+
+/**
+ * @} defgroup IxFeatureCtrlAPI
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxHssAcc.h b/marvell/uboot/drivers/net/npe/include/IxHssAcc.h
new file mode 100644
index 0000000..da71c42
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxHssAcc.h
@@ -0,0 +1,1292 @@
+/**
+ * @file IxHssAcc.h
+ * 
+ * @date 07-DEC-2001
+ *
+ * @brief This file contains the public API of the IXP400 HSS Access
+ * component
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+ 
+/* ------------------------------------------------------
+   Doxygen group definitions
+   ------------------------------------------------------ */
+/**
+ * @defgroup IxHssAccAPI IXP400 HSS Access (IxHssAcc) API
+ *
+ * @brief The public API for the IXP400 HssAccess component
+ *
+ * IxHssAcc is the access layer to the HSS packetised and channelised
+ * services
+ * 
+ * <b> Design Notes </b><br>
+ * <UL>
+ * <LI>When a packet-pipe is configured for 56Kbps RAW mode, byte alignment of 
+ *     the transmitted data is not preserved. All raw data that is transmitted 
+ *     will be received in proper order by the receiver, but the first bit of 
+ *     the packet may be seen at any offset within a byte; all subsequent bytes 
+ *     will have the same offset for the duration of the packet. The same offset 
+ *     also applies to all subsequent packets received on the packet-pipe too. 
+ *     (Similar results will occur for data received from remote end.) While 
+ *     this behavior will also occur for 56Kbps HDLC mode, the HDLC 
+ *     encoding/decoding will preserve the original byte alignment at the 
+ *     receiver end.
+ * </UL>
+ *
+ * <b> 56Kbps Packetised Service Bandwidth Limitation </b><br>
+ * <UL>
+ * <LI>IxHssAcc supports 56Kbps packetised service at a maximum aggregate rate
+ *     for all HSS ports/HDLC channels of 12.288Mbps[1] in each direction, i.e.
+ *     it supports 56Kbps packetised service on up to 8 T1 trunks. It does
+ *     not support 56Kbps packetised service on 8 E1 trunks (i.e. 4 trunks per 
+ *     HSS port) unless those trunks are running 'fractional E1' with maximum 
+ *     aggregate rate of 12.288 Mbps in each direction.<br>
+ *     [1] 12.288Mbps = 1.536Mbp * 8 T1
+ * </UL>
+ * @{ */
+
+#ifndef IXHSSACC_H
+#define IXHSSACC_H
+
+#include "IxOsal.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/**
+ * @def IX_HSSACC_TSLOTS_PER_HSS_PORT
+ *
+ * @brief The max number of TDM timeslots supported per HSS port - 4E1's =
+ *  32x4 = 128 
+ */
+#define IX_HSSACC_TSLOTS_PER_HSS_PORT 128
+
+/* -----------------------------------------------------------
+   The following are HssAccess return values returned through 
+   service interfaces. The globally defined IX_SUCCESS (0) and
+   IX_FAIL (1) in IxOsalTypes.h are also used.
+   ----------------------------------------------------------- */
+/**
+ * @def IX_HSSACC_PARAM_ERR
+ *
+ * @brief HssAccess function return value for a parameter error
+ */
+#define IX_HSSACC_PARAM_ERR 2
+
+/**
+ * @def IX_HSSACC_RESOURCE_ERR
+ *
+ * @brief HssAccess function return value for a resource error
+ */
+#define IX_HSSACC_RESOURCE_ERR 3
+
+/**
+ * @def IX_HSSACC_PKT_DISCONNECTING
+ *
+ * @brief Indicates that a disconnect call is progressing and will 
+ * disconnect soon
+ */
+#define IX_HSSACC_PKT_DISCONNECTING 4
+
+/**
+ * @def IX_HSSACC_Q_WRITE_OVERFLOW
+ *
+ * @brief Indicates that an attempt to Tx or to replenish an 
+ * RxFree Q failed due to Q overflow.  
+ */
+#define IX_HSSACC_Q_WRITE_OVERFLOW 5
+
+/* -------------------------------------------------------------------
+   The following errors are HSS/NPE errors returned on error retrieval
+   ------------------------------------------------------------------- */
+/**
+ * @def IX_HSSACC_NO_ERROR
+ *
+ * @brief HSS port no error present
+ */
+#define IX_HSSACC_NO_ERROR 0
+
+/**
+ * @def IX_HSSACC_TX_FRM_SYNC_ERR
+ *
+ * @brief HSS port TX Frame Sync error
+ */
+#define IX_HSSACC_TX_FRM_SYNC_ERR 1
+
+/**
+ * @def IX_HSSACC_TX_OVER_RUN_ERR
+ *
+ * @brief HSS port TX over-run error
+ */
+#define IX_HSSACC_TX_OVER_RUN_ERR 2
+
+/**
+ * @def IX_HSSACC_CHANNELISED_SW_TX_ERR
+ *
+ * @brief NPE software error in channelised TX
+ */
+#define IX_HSSACC_CHANNELISED_SW_TX_ERR 3
+
+/**
+ * @def IX_HSSACC_PACKETISED_SW_TX_ERR
+ *
+ * @brief NPE software error in packetised TX
+ */
+#define IX_HSSACC_PACKETISED_SW_TX_ERR 4
+
+/**
+ * @def IX_HSSACC_RX_FRM_SYNC_ERR
+ *
+ * @brief HSS port RX Frame Sync error
+ */
+#define IX_HSSACC_RX_FRM_SYNC_ERR 5
+
+/**
+ * @def IX_HSSACC_RX_OVER_RUN_ERR
+ *
+ * @brief HSS port RX over-run error
+ */
+#define IX_HSSACC_RX_OVER_RUN_ERR 6
+
+/**
+ * @def IX_HSSACC_CHANNELISED_SW_RX_ERR
+ *
+ * @brief NPE software error in channelised RX
+ */
+#define IX_HSSACC_CHANNELISED_SW_RX_ERR 7
+
+/**
+ * @def IX_HSSACC_PACKETISED_SW_RX_ERR
+ *
+ * @brief NPE software error in packetised TX
+ */
+#define IX_HSSACC_PACKETISED_SW_RX_ERR 8
+
+/* -----------------------------------
+   Packetised service specific defines
+   ----------------------------------- */
+
+/**
+ * @def IX_HSSACC_PKT_MIN_RX_MBUF_SIZE
+ *
+ * @brief Minimum size of the Rx mbuf in bytes which the client must supply 
+ * to the component. 
+ */
+#define IX_HSSACC_PKT_MIN_RX_MBUF_SIZE 64
+
+/* --------------------------------------------------------------------
+   Enumerated Types - these enumerated values may be used in setting up
+   the contents of hardware registers
+   -------------------------------------------------------------------- */
+/**
+ * @enum IxHssAccHssPort
+ * @brief The HSS port ID - There are two identical ports (0-1). 
+ * 
+ */
+typedef enum
+{
+    IX_HSSACC_HSS_PORT_0,   /**< HSS Port 0 */
+    IX_HSSACC_HSS_PORT_1,   /**< HSS Port 1 */
+    IX_HSSACC_HSS_PORT_MAX  /**< Delimiter for error checks */
+} IxHssAccHssPort;
+
+/**
+ * @enum IxHssAccHdlcPort
+ * @brief The HDLC port ID - There are four identical HDLC ports (0-3) per 
+ * HSS port and they correspond to the 4 E1/T1 trunks.
+ * 
+ */
+typedef enum
+{
+   IX_HSSACC_HDLC_PORT_0,   /**< HDLC Port 0 */
+   IX_HSSACC_HDLC_PORT_1,   /**< HDLC Port 1 */
+   IX_HSSACC_HDLC_PORT_2,   /**< HDLC Port 2 */
+   IX_HSSACC_HDLC_PORT_3,   /**< HDLC Port 3 */
+   IX_HSSACC_HDLC_PORT_MAX  /**< Delimiter for error checks */
+} IxHssAccHdlcPort;
+
+/**
+ * @enum IxHssAccTdmSlotUsage
+ * @brief The HSS TDM stream timeslot assignment types
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_TDMMAP_UNASSIGNED,    /**< Unassigned */
+    IX_HSSACC_TDMMAP_HDLC,          /**< HDLC - packetised */
+    IX_HSSACC_TDMMAP_VOICE56K,      /**< Voice56K - channelised */
+    IX_HSSACC_TDMMAP_VOICE64K,      /**< Voice64K - channelised */
+    IX_HSSACC_TDMMAP_MAX            /**< Delimiter for error checks */
+} IxHssAccTdmSlotUsage;
+
+/**
+ * @enum IxHssAccFrmSyncType
+ * @brief The HSS frame sync pulse type
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_FRM_SYNC_ACTIVE_LOW,   /**< Frame sync is sampled low */
+    IX_HSSACC_FRM_SYNC_ACTIVE_HIGH,  /**< sampled high */
+    IX_HSSACC_FRM_SYNC_FALLINGEDGE,  /**< sampled on a falling edge */
+    IX_HSSACC_FRM_SYNC_RISINGEDGE,   /**< sampled on a rising edge */
+    IX_HSSACC_FRM_SYNC_TYPE_MAX      /**< Delimiter for error checks */
+} IxHssAccFrmSyncType;
+
+/**
+ * @enum IxHssAccFrmSyncEnable
+ * @brief The IxHssAccFrmSyncEnable determines how the frame sync pulse is
+ * used
+ * */
+typedef enum
+{
+    IX_HSSACC_FRM_SYNC_INPUT,          /**< Frame sync is sampled as an input */
+    IX_HSSACC_FRM_SYNC_INVALID_VALUE,  /**< 1 is not used */
+    IX_HSSACC_FRM_SYNC_OUTPUT_FALLING, /**< Frame sync is an output generated 
+					  off a falling clock edge */
+    IX_HSSACC_FRM_SYNC_OUTPUT_RISING,  /**< Frame sync is an output generated 
+					  off a rising clock edge */
+    IX_HSSACC_FRM_SYNC_ENABLE_MAX      /**< Delimiter for error checks */
+} IxHssAccFrmSyncEnable;
+
+/**
+ * @enum IxHssAccClkEdge
+ * @brief IxHssAccClkEdge is used to determine the clk edge to use for 
+ * framing and data
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_CLK_EDGE_FALLING,  /**< Clock sampled off a falling edge */
+    IX_HSSACC_CLK_EDGE_RISING,   /**< Clock sampled off a rising edge */
+    IX_HSSACC_CLK_EDGE_MAX       /**< Delimiter for error checks */
+} IxHssAccClkEdge;
+
+/**
+ * @enum IxHssAccClkDir
+ * @brief The HSS clock direction
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_SYNC_CLK_DIR_INPUT,    /**< Clock is an input */
+    IX_HSSACC_SYNC_CLK_DIR_OUTPUT,   /**< Clock is an output */
+    IX_HSSACC_SYNC_CLK_DIR_MAX       /**< Delimiter for error checks */
+} IxHssAccClkDir;
+
+/**
+ * @enum IxHssAccFrmPulseUsage
+ * @brief The HSS frame pulse usage
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_FRM_PULSE_ENABLED,     /**< Generate/Receive frame pulses */
+    IX_HSSACC_FRM_PULSE_DISABLED,    /**< Disregard frame pulses */
+    IX_HSSACC_FRM_PULSE_MAX          /**< Delimiter for error checks */
+} IxHssAccFrmPulseUsage;
+
+/**
+ * @enum IxHssAccDataRate
+ * @brief The HSS Data rate in relation to the clock
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_CLK_RATE,      /**< Data rate is at the configured clk speed */
+    IX_HSSACC_HALF_CLK_RATE, /**< Data rate is half the configured clk speed */
+    IX_HSSACC_DATA_RATE_MAX  /**< Delimiter for error checks */
+} IxHssAccDataRate;
+
+/**
+ * @enum IxHssAccDataPolarity
+ * @brief The HSS data polarity type
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_DATA_POLARITY_SAME,   /**< Don't invert data between NPE and 
+				       HSS FIFOs */
+    IX_HSSACC_DATA_POLARITY_INVERT, /**< Invert data between NPE and HSS 
+				       FIFOs */
+    IX_HSSACC_DATA_POLARITY_MAX     /**< Delimiter for error checks */
+} IxHssAccDataPolarity;
+
+/**
+ * @enum IxHssAccBitEndian
+ * @brief HSS Data endianness
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_LSB_ENDIAN,    /**< TX/RX Least Significant Bit first */
+    IX_HSSACC_MSB_ENDIAN,    /**< TX/RX Most Significant Bit first */
+    IX_HSSACC_ENDIAN_MAX     /**< Delimiter for the purposes of error checks */
+} IxHssAccBitEndian;
+
+
+/**
+ * @enum IxHssAccDrainMode
+ * @brief Tx pin open drain mode
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_TX_PINS_NORMAL,       /**< Normal mode */
+    IX_HSSACC_TX_PINS_OPEN_DRAIN,   /**< Open Drain mode */
+    IX_HSSACC_TX_PINS_MAX           /**< Delimiter for error checks */
+} IxHssAccDrainMode;
+
+/**
+ * @enum IxHssAccSOFType
+ * @brief HSS start of frame types
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_SOF_FBIT,  /**< Framing bit transmitted and expected on rx */
+    IX_HSSACC_SOF_DATA,  /**< Framing bit not transmitted nor expected on rx */
+    IX_HSSACC_SOF_MAX    /**< Delimiter for error checks */
+} IxHssAccSOFType;
+
+/**
+ * @enum IxHssAccDataEnable
+ * @brief IxHssAccDataEnable is used to determine whether or not to drive 
+ * the data pins
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_DE_TRI_STATE,   /**< TRI-State the data pins */
+    IX_HSSACC_DE_DATA,        /**< Push data out the data pins */
+    IX_HSSACC_DE_MAX          /**< Delimiter for error checks */
+} IxHssAccDataEnable;
+
+/**
+ * @enum IxHssAccTxSigType
+ * @brief IxHssAccTxSigType is used to determine how to drive the data pins
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_TXSIG_LOW,        /**< Drive the data pins low */
+    IX_HSSACC_TXSIG_HIGH,       /**< Drive the data pins high */
+    IX_HSSACC_TXSIG_HIGH_IMP,   /**< Drive the data pins with high impedance */
+    IX_HSSACC_TXSIG_MAX         /**< Delimiter for error checks */
+} IxHssAccTxSigType;
+
+/**
+ * @enum IxHssAccFbType
+ * @brief IxHssAccFbType determines how to drive the Fbit
+ *
+ * @warning This will only be used for T1 @ 1.544MHz
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_FB_FIFO,        /**< Fbit is dictated in FIFO */
+    IX_HSSACC_FB_HIGH_IMP,    /**< Fbit is high impedance */
+    IX_HSSACC_FB_MAX          /**< Delimiter for error checks */
+} IxHssAccFbType;
+
+/**
+ * @enum IxHssAcc56kEndianness
+ * @brief 56k data endianness when using the 56k type
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_56KE_BIT_7_UNUSED,  /**< High bit is unused */
+    IX_HSSACC_56KE_BIT_0_UNUSED,  /**< Low bit is unused */
+    IX_HSSACC_56KE_MAX            /**< Delimiter for error checks */
+} IxHssAcc56kEndianness;
+
+/**
+ * @enum IxHssAcc56kSel
+ * @brief 56k data transmission type when using the 56k type
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_56KS_32_8_DATA,  /**< 32/8 bit data */
+    IX_HSSACC_56KS_56K_DATA,   /**< 56K data */
+    IX_HSSACC_56KS_MAX         /**< Delimiter for error checks */
+} IxHssAcc56kSel;
+
+
+/**
+ * @enum IxHssAccClkSpeed
+ * @brief IxHssAccClkSpeed represents the HSS clock speeds available
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_CLK_SPEED_512KHZ,     /**< 512KHz */
+    IX_HSSACC_CLK_SPEED_1536KHZ,    /**< 1.536MHz */
+    IX_HSSACC_CLK_SPEED_1544KHZ,    /**< 1.544MHz */
+    IX_HSSACC_CLK_SPEED_2048KHZ,    /**< 2.048MHz */
+    IX_HSSACC_CLK_SPEED_4096KHZ,    /**< 4.096MHz */
+    IX_HSSACC_CLK_SPEED_8192KHZ,    /**< 8.192MHz */
+    IX_HSSACC_CLK_SPEED_MAX      /**< Delimiter for error checking */
+} IxHssAccClkSpeed;
+
+/**
+ * @enum IxHssAccPktStatus
+ * @brief Indicates the status of packets passed to the client
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_PKT_OK,              /**< Error free.*/
+    IX_HSSACC_STOP_SHUTDOWN_ERROR, /**< Errored due to stop or shutdown 
+				      occurrance.*/
+    IX_HSSACC_HDLC_ALN_ERROR,      /**< HDLC alignment error */
+    IX_HSSACC_HDLC_FCS_ERROR,       /**< HDLC Frame Check Sum error.*/
+    IX_HSSACC_RXFREE_Q_EMPTY_ERROR,       /**< RxFree Q became empty 
+					     while receiving this packet.*/
+    IX_HSSACC_HDLC_MAX_FRAME_SIZE_EXCEEDED,      /**< HDLC frame size 
+						   received is greater than
+						   max specified at connect.*/
+    IX_HSSACC_HDLC_ABORT_ERROR,   /**< HDLC frame received is invalid due to an 
+				   abort sequence received.*/
+    IX_HSSACC_DISCONNECT_IN_PROGRESS     /**< Packet returned
+					    because a disconnect is in progress */
+} IxHssAccPktStatus;
+
+
+/**
+ * @enum IxHssAccPktCrcType
+ * @brief HDLC CRC type
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_PKT_16_BIT_CRC = 16,  /**< 16 bit CRC is being used */
+    IX_HSSACC_PKT_32_BIT_CRC = 32   /**< 32 bit CRC is being used */
+} IxHssAccPktCrcType;
+
+/**
+ * @enum IxHssAccPktHdlcIdleType
+ * @brief HDLC idle transmission type
+ *
+ */
+typedef enum
+{
+    IX_HSSACC_HDLC_IDLE_ONES,    /**< idle tx/rx will be a succession of ones */
+    IX_HSSACC_HDLC_IDLE_FLAGS    /**< idle tx/rx will be repeated flags */
+} IxHssAccPktHdlcIdleType;
+
+/**
+ * @brief Structure containing HSS port configuration parameters
+ *
+ * Note: All of these are used for TX. Only some are specific to RX.
+ *
+ */
+typedef struct
+{
+    IxHssAccFrmSyncType frmSyncType;     /**< frame sync pulse type (tx/rx) */
+    IxHssAccFrmSyncEnable frmSyncIO;     /**< how the frame sync pulse is 
+					    used (tx/rx) */
+    IxHssAccClkEdge frmSyncClkEdge;      /**< frame sync clock edge type 
+					    (tx/rx) */
+    IxHssAccClkEdge dataClkEdge;         /**< data clock edge type (tx/rx) */
+    IxHssAccClkDir clkDirection;         /**< clock direction (tx/rx) */
+    IxHssAccFrmPulseUsage frmPulseUsage; /**< whether to use the frame sync 
+					    pulse or not (tx/rx) */
+    IxHssAccDataRate dataRate;           /**< data rate in relation to the 
+					    clock (tx/rx) */
+    IxHssAccDataPolarity dataPolarity;   /**< data polarity type (tx/rx) */
+    IxHssAccBitEndian dataEndianness;    /**< data endianness (tx/rx) */
+    IxHssAccDrainMode drainMode;         /**< tx pin open drain mode (tx) */
+    IxHssAccSOFType fBitUsage;           /**< start of frame types (tx/rx) */
+    IxHssAccDataEnable dataEnable;       /**< whether or not to drive the data 
+					    pins (tx) */
+    IxHssAccTxSigType voice56kType;      /**< how to drive the data pins for 
+					    voice56k type (tx) */
+    IxHssAccTxSigType unassignedType;    /**< how to drive the data pins for 
+					    unassigned type (tx) */
+    IxHssAccFbType fBitType;             /**< how to drive the Fbit (tx) */
+    IxHssAcc56kEndianness voice56kEndian;/**< 56k data endianness when using 
+					    the 56k type (tx) */
+    IxHssAcc56kSel voice56kSel;          /**< 56k data transmission type when 
+					    using the 56k type (tx) */
+    unsigned frmOffset;                  /**< frame pulse offset in bits wrt 
+					    the first timeslot (0-1023) (tx/rx) */
+    unsigned maxFrmSize;                 /**< frame size in bits (1-1024) 
+					    (tx/rx) */
+} IxHssAccPortConfig;
+
+/**
+ * @brief Structure containing HSS configuration parameters
+ *
+ */
+typedef struct
+{
+    IxHssAccPortConfig txPortConfig; /**< HSS tx port configuration */
+    IxHssAccPortConfig rxPortConfig; /**< HSS rx port configuration */
+    unsigned numChannelised;         /**< The number of channelised 
+					timeslots (0-32) */
+    unsigned hssPktChannelCount;     /**< The number of packetised 
+					clients (0 - 4) */
+    UINT8 channelisedIdlePattern;    /**< The byte to be transmitted on 
+					channelised service when there 
+					is no client data to tx */
+    BOOL loopback;                   /**< The HSS loopback state */
+    unsigned packetizedIdlePattern;  /**< The data to be transmitted on 
+					packetised service when there is 
+					no client data to tx */
+    IxHssAccClkSpeed clkSpeed;       /**< The HSS clock speed */
+} IxHssAccConfigParams;
+
+/**
+ * @brief This structure contains 56Kbps, HDLC-mode configuration parameters
+ *
+ */
+typedef struct
+{
+    BOOL hdlc56kMode;                    /**< 56kbps(true)/64kbps(false) HDLC */
+    IxHssAcc56kEndianness hdlc56kEndian; /**< 56kbps data endianness 
+					    - ignored if hdlc56kMode is false*/
+    BOOL hdlc56kUnusedBitPolarity0;      /**< The polarity '0'(true)/'1'(false) of the unused
+					   bit while in 56kbps mode
+					   - ignored if hdlc56kMode is false*/
+} IxHssAccHdlcMode;
+
+/**
+ * @brief This structure contains information required by the NPE to 
+ * configure the HDLC co-processor
+ *
+ */
+typedef struct
+{
+    IxHssAccPktHdlcIdleType hdlcIdleType;   /**< What to transmit when a HDLC port is idle */
+    IxHssAccBitEndian dataEndian;           /**< The HDLC data endianness */
+    IxHssAccPktCrcType crcType;             /**< The CRC type to be used for this HDLC port */
+} IxHssAccPktHdlcFraming;
+
+/**
+ * @typedef UINT32 IxHssAccPktUserId
+ *
+ * @brief The client supplied value which will be supplied as a parameter
+ * with a given callback.
+ *
+ * This value will be passed into the ixHssAccPktPortConnect function once each
+ * with given callbacks.  This value will then be passed back to the client
+ * as one of the parameters to each of these callbacks, 
+ * when these callbacks are called.
+ */
+typedef UINT32 IxHssAccPktUserId;
+
+
+/**
+ * @typedef IxHssAccLastErrorCallback
+ * @brief Prototype of the clients function to accept notification of the 
+ * last error
+ *
+ * This function is registered through the config. The client will initiate
+ * the last error retrieval. The HssAccess component will send a message to
+ * the NPE through the NPE Message Handler. When a response to the read is
+ * received, the NPE Message Handler will callback the HssAccess component
+ * which will execute this function in the same IxNpeMh context. The client
+ * will be passed the last error and the related service port (packetised
+ * 0-3, channelised 0)
+ *
+ * @param lastHssError unsigned [in] - The last Hss error registered that
+ *                                      has been registered.
+ * @param servicePort unsigned [in] - This is the service port number.  
+ *                                     (packetised 0-3, channelised 0) 
+ * 
+ * @return void
+ */
+typedef void (*IxHssAccLastErrorCallback) (unsigned lastHssError, 
+					   unsigned servicePort);
+
+/**
+ * @typedef IxHssAccPktRxCallback
+ * @brief  Prototype of the clients function to accept notification of 
+ * packetised rx
+ *
+ * This function is registered through the ixHssAccPktPortConnect. hssPktAcc will pass
+ * received data in the form of mbufs to the client.  The mbuf passed back
+ * to the client could contain a chain of buffers, depending on the packet
+ * size received. 
+ * 
+ * @param *buffer @ref IX_OSAL_MBUF [in] - This is the mbuf which contains the 
+ * payload received.
+ * @param numHssErrs unsigned [in] - This is the number of hssErrors 
+ * the Npe has received
+ * @param pktStatus @ref IxHssAccPktStatus [in] - This is the status of the 
+ * mbuf that has been received.
+ * @param rxUserId @ref IxHssAccPktUserId [in] - This is the client supplied value 
+ * passed in at ixHssAccPktPortConnect time which is now returned to the client.			       
+ * 
+ * @return void
+ */
+typedef void (*IxHssAccPktRxCallback) (IX_OSAL_MBUF *buffer, 
+				       unsigned numHssErrs, 
+				       IxHssAccPktStatus pktStatus, 
+				       IxHssAccPktUserId rxUserId);
+
+/**
+ * @typedef IxHssAccPktRxFreeLowCallback
+ * @brief Prototype of the clients function to accept notification of 
+ * requirement of more Rx Free buffers
+ *
+ * The client can choose to register a callback of this type when
+ * calling a connecting. This function is registered through the ixHssAccPktPortConnect. 
+ * If defined, the access layer will provide the trigger for
+ * this callback. The callback will be responsible for supplying mbufs to
+ * the access layer for use on the receive path from the HSS using
+ * ixHssPktAccFreeBufReplenish. 
+ *
+ * @return void
+ */
+typedef void (*IxHssAccPktRxFreeLowCallback) (IxHssAccPktUserId rxFreeLowUserId);
+
+/**
+ * @typedef IxHssAccPktTxDoneCallback
+ * @brief  Prototype of the clients function to accept notification of 
+ * completion with Tx buffers
+ *
+ * This function is registered through the ixHssAccPktPortConnect.  It enables
+ * the hssPktAcc to pass buffers back to the client
+ * when transmission is complete.
+ *
+ * @param *buffer @ref IX_OSAL_MBUF [in] - This is the mbuf which contained 
+ * the payload that was for Tx.
+ * @param numHssErrs unsigned [in] - This is the number of hssErrors 
+ * the Npe has received
+ * @param pktStatus @ref IxHssAccPktStatus [in] - This is the status of the 
+ * mbuf that has been transmitted.
+ * @param txDoneUserId @ref IxHssAccPktUserId [in] - This is the client supplied value 
+ * passed in at ixHssAccPktPortConnect time which is now returned to the client.	 
+ *
+ * @return void
+ */
+typedef void (*IxHssAccPktTxDoneCallback) (IX_OSAL_MBUF *buffer, 
+					   unsigned numHssErrs,
+					   IxHssAccPktStatus pktStatus, 
+					   IxHssAccPktUserId txDoneUserId);
+
+/**
+ * @typedef IxHssAccChanRxCallback
+ * @brief Prototype of the clients function to accept notification of 
+ * channelised rx
+ *
+ * This callback, if defined by the client in the connect, will get called
+ * in the context of an IRQ. The IRQ will be triggered when the hssSyncQMQ
+ * is not empty. The queued entry will be dequeued and this function will
+ * be executed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort - The HSS port Id. There are two
+ * identical ports (0-1).
+ * @param txOffset unsigned [in] - an offset indicating from where within
+ * the txPtrList the NPE is currently transmitting from.
+ * @param rxOffset unsigned [in] - an offset indicating where within the
+ * receive buffers the NPE has just written the received data to.
+ * @param numHssErrs unsigned [in] - This is the number of hssErrors 
+ * the Npe has received
+ *
+ * @return void
+ */
+typedef void (*IxHssAccChanRxCallback) (IxHssAccHssPort hssPortId,
+					unsigned rxOffset, 
+					unsigned txOffset, 
+					unsigned numHssErrs);
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccPortInit (IxHssAccHssPort hssPortId, 
+               IxHssAccConfigParams *configParams, 
+               IxHssAccTdmSlotUsage *tdmMap, 
+               IxHssAccLastErrorCallback lastHssErrorCallback)
+ *
+ * @brief Initialise a HSS port. No channelised or packetised connections
+ * should exist in the HssAccess layer while this interface is being called.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1). 
+ * @param *configParams @ref IxHssAccConfigParams [in] - A pointer to the HSS 
+ * configuration structure
+ * @param *tdmMap @ref IxHssAccTdmSlotUsage [in] - A pointer to an array of size
+ * IX_HSSACC_TSLOTS_PER_HSS_PORT, defining the slot usage over the HSS port
+ * @param lastHssErrorCallback @ref IxHssAccLastErrorCallback [in] - Client 
+ * callback to report last error
+ *
+ * @return 
+ *         - IX_SUCCESS The function executed successfully
+ *         - IX_FAIL The function did not execute successfully
+ *         - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ *                          parameter error
+ */
+PUBLIC IX_STATUS 
+ixHssAccPortInit (IxHssAccHssPort hssPortId, 
+		  IxHssAccConfigParams *configParams, 
+		  IxHssAccTdmSlotUsage *tdmMap, 
+		  IxHssAccLastErrorCallback lastHssErrorCallback);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccLastErrorRetrievalInitiate (
+               IxHssAccHssPort hssPortId)
+ *
+ * @brief Initiate the retrieval of the last HSS error. The HSS port
+ * should be configured before attempting to call this interface.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - the HSS port ID
+ *
+ * @return 
+ *         - IX_SUCCESS The function executed successfully
+ *         - IX_FAIL The function did not execute successfully
+ *         - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ *                          parameter error
+ */
+PUBLIC IX_STATUS 
+ixHssAccLastErrorRetrievalInitiate (IxHssAccHssPort hssPortId);
+
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccInit ()
+ *
+ * @brief This function is responsible for initialising resources for use
+ * by the packetised and channelised clients. It should be called after 
+ * HSS NPE image has been downloaded into NPE-A and before any other
+ * HssAccess interface is called. 
+ * No other HssAccPacketised interface should be called while this interface
+ * is being processed.
+ *
+ * @return 
+ *         - IX_SUCCESS The function executed successfully
+ *         - IX_FAIL The function did not execute successfully
+ *         - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due
+ *                          to a resource error 
+ */
+PUBLIC IX_STATUS 
+ixHssAccInit (void);
+
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn ixHssAccPktPortConnect (IxHssAccHssPort hssPortId, 
+			IxHssAccHdlcPort hdlcPortId, 
+			BOOL hdlcFraming, 
+			IxHssAccHdlcMode hdlcMode,
+			BOOL hdlcBitInvert,
+			unsigned blockSizeInWords,
+			UINT32 rawIdleBlockPattern,
+			IxHssAccPktHdlcFraming hdlcTxFraming, 
+			IxHssAccPktHdlcFraming hdlcRxFraming, 
+			unsigned frmFlagStart, 
+			IxHssAccPktRxCallback rxCallback,
+			IxHssAccPktUserId rxUserId, 
+			IxHssAccPktRxFreeLowCallback rxFreeLowCallback, 
+			IxHssAccPktUserId rxFreeLowUserId,
+			IxHssAccPktTxDoneCallback txDoneCallback,
+			IxHssAccPktUserId txDoneUserId) 
+ *
+ * @brief This function is responsible for connecting a client to one of 
+ * the 4 available HDLC ports. The HSS port should be configured before 
+ * attempting a connect. No other HssAccPacketised interface should be
+ * called while this connect is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1). 
+ * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port and 
+ * it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 
+ * @param hdlcFraming BOOL [in] - This value determines whether the service 
+ * will use HDLC data or the debug, raw data type i.e. no HDLC processing
+ * @param hdlcMode @ref IxHssAccHdlcMode [in] - This structure contains 56Kbps, HDLC-mode
+ * configuration parameters
+ * @param hdlcBitInvert BOOL [in] - This value determines whether bit inversion
+ * will occur between HDLC and HSS co-processors i.e. post-HDLC processing for
+ * transmit and pre-HDLC processing for receive, for the specified HDLC Termination
+ * Point
+ * @param blockSizeInWords unsigned [in] -  The max tx/rx block size 
+ * @param rawIdleBlockPattern UINT32 [in] -  Tx idle pattern in raw mode 
+ * @param hdlcTxFraming @ref IxHssAccPktHdlcFraming [in] - This structure contains 
+ * the following information required by the NPE to configure the HDLC 
+ * co-processor for TX
+ * @param hdlcRxFraming @ref IxHssAccPktHdlcFraming [in] -  This structure contains 
+ * the following information required by the NPE to configure the HDLC 
+ * co-processor for RX
+ * @param frmFlagStart unsigned - Number of flags to precede to 
+ * transmitted flags (0-2).
+ * @param rxCallback @ref IxHssAccPktRxCallback [in] - Pointer to 
+ * the clients packet receive function.
+ * @param rxUserId @ref IxHssAccPktUserId [in] - The client supplied rx value
+ * to be passed back as an argument to the supplied rxCallback
+ * @param rxFreeLowCallback @ref IxHssAccPktRxFreeLowCallback [in] - Pointer to 
+ * the clients Rx free buffer request function.  If NULL, assume client will 
+ * trigger independently.
+ * @param rxFreeLowUserId @ref IxHssAccPktUserId [in] - The client supplied RxFreeLow value
+ * to be passed back as an argument to the supplied rxFreeLowCallback
+ * @param txDoneCallback @ref IxHssAccPktTxDoneCallback [in] - Pointer to the 
+ * clients Tx done callback function
+ * @param txDoneUserId @ref IxHssAccPktUserId [in] - The client supplied txDone value
+ * to be passed back as an argument to the supplied txDoneCallback
+ *
+ * @return 
+ *         - IX_SUCCESS The function executed successfully
+ *         - IX_FAIL The function did not execute successfully
+ *         - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ *                          parameter error
+ *         - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due
+ *                          to a resource error
+ */
+PUBLIC IX_STATUS 
+ixHssAccPktPortConnect (IxHssAccHssPort hssPortId, 
+			IxHssAccHdlcPort hdlcPortId, 
+			BOOL hdlcFraming, 
+			IxHssAccHdlcMode hdlcMode,
+			BOOL hdlcBitInvert,
+			unsigned blockSizeInWords,
+			UINT32 rawIdleBlockPattern,
+			IxHssAccPktHdlcFraming hdlcTxFraming, 
+			IxHssAccPktHdlcFraming hdlcRxFraming, 
+			unsigned frmFlagStart, 
+			IxHssAccPktRxCallback rxCallback,
+			IxHssAccPktUserId rxUserId, 
+			IxHssAccPktRxFreeLowCallback rxFreeLowCallback, 
+			IxHssAccPktUserId rxFreeLowUserId,
+			IxHssAccPktTxDoneCallback txDoneCallback,
+			IxHssAccPktUserId txDoneUserId);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccPktPortEnable (IxHssAccHssPort hssPortId, 
+           IxHssAccHdlcPort hdlcPortId)
+ *
+ * @brief This function is responsible for enabling a packetised service
+ * for the specified HSS/HDLC port combination. It enables the RX flow. The
+ * client must have already connected to a packetised service and is responsible 
+ * for ensuring an adequate amount of RX mbufs have been supplied to the access
+ * component before enabling the packetised service. This function must be called
+ * on a given port before any call to ixHssAccPktPortTx on the same port. 
+ * No other HssAccPacketised interface should be called while this interface is 
+ * being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1).   
+ * @param hdlcPortId @ref IxHssAccHdlcPort [in] - The port id (0,1,2,3) to enable the service
+ * on.
+ *
+ * @return 
+ *         - IX_SUCCESS The function executed successfully
+ *         - IX_FAIL The function did not execute successfully
+ *         - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ *                          parameter error
+ */
+PUBLIC IX_STATUS 
+ixHssAccPktPortEnable (IxHssAccHssPort hssPortId, 
+		       IxHssAccHdlcPort hdlcPortId);
+
+/**
+ * @fn IX_STATUS ixHssAccPktPortDisable (IxHssAccHssPort hssPortId, 
+           IxHssAccHdlcPort hdlcPortId)
+ *
+ * @brief This function is responsible for disabling a packetised service
+ * for the specified HSS/HDLC port combination. It disables the RX flow. 
+ * The client must have already connected to and enabled a packetised service 
+ * for the specified HDLC port. This disable interface can be called before a
+ * disconnect, but is not required to.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1). 
+ * @param hdlcPortId @ref IxHssAccHdlcPort [in] - The port id (0,1,2,3) to disable 
+ * the service on.
+ *
+ * @return 
+ *         - IX_SUCCESS The function executed successfully
+ *         - IX_FAIL The function did not execute successfully
+ *         - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ *                          parameter error
+ */
+PUBLIC IX_STATUS 
+ixHssAccPktPortDisable (IxHssAccHssPort hssPortId, 
+			IxHssAccHdlcPort hdlcPortId);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccPktPortDisconnect (IxHssAccHssPort hssPortId, 
+           IxHssAccHdlcPort hdlcPortId)
+ *
+ * @brief This function is responsible for disconnecting a client from one
+ * of the 4 available HDLC ports. It is not required that the Rx Flow 
+ * has been disabled before calling this function.  If the RX Flow has not been
+ * disabled, the disconnect will disable it before proceeding with the
+ * disconnect.  No other HssAccPacketised 
+ * interface should be called while this interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1). 
+ * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port
+ * to disconnect and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3
+ *
+ * @return 
+ *         - IX_SUCCESS The function executed successfully
+ *         - IX_FAIL The function did not execute successfully 
+ *         - IX_HSSACC_PKT_DISCONNECTING The function has initiated the disconnecting
+ *                             procedure but it has not completed yet.
+ */
+PUBLIC IX_STATUS 
+ixHssAccPktPortDisconnect (IxHssAccHssPort hssPortId, 
+			   IxHssAccHdlcPort hdlcPortId);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn BOOL ixHssAccPktPortIsDisconnectComplete (IxHssAccHssPort hssPortId, 
+           IxHssAccHdlcPort hdlcPortId)
+ *
+ * @brief This function is called to check if a given HSS/HDLC port 
+ * combination is in a connected state or not. This function may be called 
+ * at any time to determine a ports state.  No other HssAccPacketised 
+ * interface should be called while this interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1). 
+ * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port
+ * to disconnect and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3
+ *
+ * @return 
+ *         - true The state of this HSS/HDLC port combination is disconnected,
+ *                so if a disconnect was called, it is now completed.
+ *         - false The state of this HSS/HDLC port combination is connected,
+ *                so if a disconnect was called, it is not yet completed.
+ */
+PUBLIC BOOL 
+ixHssAccPktPortIsDisconnectComplete (IxHssAccHssPort hssPortId, 
+				     IxHssAccHdlcPort hdlcPortId);
+
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccPktPortRxFreeReplenish (IxHssAccHssPort hssPortId, 
+              IxHssAccHdlcPort hdlcPortId, 
+	      IX_OSAL_MBUF *buffer)
+ *
+ * @brief Function which the client calls at regular intervals to provide
+ * mbufs to the access component for RX. A connection should exist for
+ * the specified hssPortId/hdlcPortId combination before attempting to call this 
+ * interface. Also, the connection should not be in a disconnecting state.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1). 
+ * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port
+ * and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3
+ * @param *buffer @ref IX_OSAL_MBUF [in] - A pointer to a free mbuf to filled with payload.
+ *
+ * @return 
+ *         - IX_SUCCESS The function executed successfully
+ *         - IX_FAIL The function did not execute successfully
+ *         - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ *                          parameter error
+ *         - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due
+ *                          to a resource error
+ *         - IX_HSSACC_Q_WRITE_OVERFLOW The function did not succeed due to a Q
+ *                                      overflow
+ */
+PUBLIC IX_STATUS 
+ixHssAccPktPortRxFreeReplenish (IxHssAccHssPort hssPortId, 
+				IxHssAccHdlcPort hdlcPortId, 
+				IX_OSAL_MBUF *buffer);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccPktPortTx (IxHssAccHssPort hssPortId, 
+    IxHssAccHdlcPort hdlcPortId, 
+    IX_OSAL_MBUF *buffer)
+ *
+ * @brief Function which the client calls when it wants to transmit
+ * packetised data. An enabled connection should exist on the specified
+ * hssPortId/hdlcPortId combination before attempting to call this interface.
+ * No other HssAccPacketised 
+ * interface should be called while this interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1). 
+ * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port
+ * and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3
+ * @param *buffer @ref IX_OSAL_MBUF [in] - A pointer to a chain of mbufs which the
+ * client has filled with the payload
+ *
+ * @return 
+ *         - IX_SUCCESS The function executed successfully
+ *         - IX_FAIL The function did not execute successfully
+ *         - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ *                          parameter error
+ *         - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due
+ *                          to a resource error. See note.
+ *         - IX_HSSACC_Q_WRITE_OVERFLOW The function did not succeed due to a Q
+ *                                      overflow
+ *
+ * @note IX_HSSACC_RESOURCE_ERR is returned when a free descriptor cannot be
+ * obtained to send the chain of mbufs to the NPE.  This is a normal scenario.
+ * HssAcc has a pool of descriptors and this error means that they are currently
+ * all in use.
+ * The recommended approach to this is to retry until a descriptor becomes free
+ * and the packet is successfully transmitted.
+ * Alternatively, the user could wait until the next IxHssAccPktTxDoneCallback
+ * callback is triggered, and then retry, as it is this event that causes a
+ * transmit descriptor to be freed. 
+ */
+PUBLIC IX_STATUS 
+ixHssAccPktPortTx (IxHssAccHssPort hssPortId, 
+		   IxHssAccHdlcPort hdlcPortId, 
+		   IX_OSAL_MBUF *buffer);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccChanConnect (IxHssAccHssPort hssPortId, 
+           unsigned bytesPerTSTrigger, 
+	   UINT8 *rxCircular, 
+	   unsigned numRxBytesPerTS, 
+	   UINT32 *txPtrList, 
+	   unsigned numTxPtrLists, 
+	   unsigned numTxBytesPerBlk, 
+	   IxHssAccChanRxCallback rxCallback)
+ *
+ * @brief This function allows the client to connect to the Tx/Rx NPE
+ * Channelised Service. There can only be one client per HSS port. The
+ * client is responsible for ensuring that the HSS port is configured
+ * appropriately before its connect request. No other HssAccChannelised 
+ * interface should be called while this interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1). 
+ * @param bytesPerTSTrigger unsigned [in] - The NPE will trigger the access
+ * component after bytesPerTSTrigger have been received for all trunk
+ * timeslots. This figure is a multiple of 8 e.g. 8 for 1ms trigger, 16 for
+ * 2ms trigger.
+ * @param *rxCircular UINT8 [in] - A pointer to memory allocated by the
+ * client to be filled by data received. The buffer at this address is part
+ * of a pool of buffers to be accessed in a circular fashion. This address
+ * will be written to by the NPE. Therefore, it needs to be a physical address.
+ * @param numRxBytesPerTS unsigned [in] - The number of bytes allocated per
+ * timeslot within the receive memory. This figure will depend on the
+ * latency of the system. It needs to be deep enough for data to be read by
+ * the client before the NPE re-writes over that memory e.g. if the client
+ * samples at a rate of 40bytes per timeslot, numRxBytesPerTS may need to
+ * be 40bytes * 3. This would give the client 3 * 5ms of time before
+ * received data is over-written.
+ * @param *txPtrList UINT32 [in] - The address of an area of contiguous
+ * memory allocated by the client to be populated with pointers to data for
+ * transmission. Each pointer list contains a pointer per active channel.
+ * The txPtrs will point to data to be transmitted by the NPE. Therefore,
+ * they must point to physical addresses.
+ * @param numTxPtrLists unsigned [in] - The number of pointer lists in
+ * txPtrList. This figure is dependent on jitter.
+ * @param numTxBytesPerBlk unsigned [in] - The size of the Tx data, in
+ * bytes, that each pointer within the PtrList points to.
+ * @param rxCallback @ref IxHssAccChanRxCallback [in] - A client function
+ * pointer to be called back to handle the actual tx/rx of channelised
+ * data. If this is not NULL, an ISR will call this function. If this
+ * pointer is NULL, it implies that the client will use a polling mechanism
+ * to detect when the tx and rx of channelised data is to occur. The client
+ * will use hssChanAccStatus for this.
+ *
+ * @return
+ *         - IX_SUCCESS The function executed successfully
+ *         - IX_FAIL The function did not execute successfully
+ *         - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ *                          parameter error
+ */
+ 
+PUBLIC IX_STATUS 
+ixHssAccChanConnect (IxHssAccHssPort hssPortId, 
+		     unsigned bytesPerTSTrigger, 
+		     UINT8 *rxCircular, 
+		     unsigned numRxBytesPerTS, 
+		     UINT32 *txPtrList, 
+		     unsigned numTxPtrLists, 
+		     unsigned numTxBytesPerBlk, 
+		     IxHssAccChanRxCallback rxCallback);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccChanPortEnable (IxHssAccHssPort hssPortId)
+ *
+ * @brief This function is responsible for enabling a channelised service
+ * for the specified HSS port. It enables the NPE RX flow. The client must
+ * have already connected to a channelised service before enabling the
+ * channelised service. No other HssAccChannelised 
+ * interface should be called while this interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1). 
+ *
+ * @return
+ *         - IX_SUCCESS The function executed successfully
+ *         - IX_FAIL The function did not execute successfully
+ *         - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ *                          parameter error
+ */
+PUBLIC IX_STATUS 
+ixHssAccChanPortEnable (IxHssAccHssPort hssPortId);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccChanPortDisable (IxHssAccHssPort hssPortId)
+ *
+ * @brief This function is responsible for disabling a channelised service
+ * for the specified HSS port. It disables the NPE RX flow. The client must
+ * have already connected to and enabled a channelised service for the
+ * specified HSS port. This disable interface can be called before a
+ * disconnect, but is not required to. No other HssAccChannelised 
+ * interface should be called while this interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1). 
+ *
+ * @return 
+ *         - IX_SUCCESS The function executed successfully
+ *         - IX_FAIL The function did not execute successfully
+ *         - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ *                          parameter error
+ */
+PUBLIC IX_STATUS 
+ixHssAccChanPortDisable (IxHssAccHssPort hssPortId);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccChanDisconnect (IxHssAccHssPort hssPortId)
+ *
+ * @brief This function allows the client to Disconnect from a channelised
+ * service. If the NPE RX Flow has not been disabled, the disconnect will
+ * disable it before proceeding with other disconnect functionality.
+ * No other HssAccChannelised interface should be called while this 
+ * interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1). 
+ *
+ * @return 
+ *         - IX_SUCCESS The function executed successfully
+ *         - IX_FAIL The function did not execute successfully
+ *         - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ *                          parameter error
+ */
+PUBLIC IX_STATUS 
+ixHssAccChanDisconnect (IxHssAccHssPort hssPortId);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn IX_STATUS ixHssAccChanStatusQuery (IxHssAccHssPort hssPortId, 
+           BOOL *dataRecvd, 
+	   unsigned *rxOffset, 
+	   unsigned *txOffset, 
+	   unsigned *numHssErrs)
+ *
+ * @brief This function is called by the client to query whether or not
+ * channelised data has been received. If there is, hssChanAcc will return
+ * the details in the output parameters. An enabled connection should
+ * exist on the specified hssPortId before attempting to call this interface.  
+ * No other HssAccChannelised interface should be called while this 
+ * interface is being processed.
+ *
+ * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two
+ * identical ports (0-1). 
+ * @param *dataRecvd BOOL [out] - This BOOL indicates to the client whether
+ * or not the access component has read any data for the client. If
+ * false, the other output parameters will not have been written to.
+ * @param *rxOffset unsigned [out] - An offset to indicate to the client
+ * where within the receive buffers the NPE has just written the received
+ * data to.
+ * @param *txOffset unsigned [out] - An offset to indicate to the client
+ * from where within the txPtrList the NPE is currently transmitting from
+ * @param *numHssErrs unsigned [out] - The total number of HSS port errors
+ * since initial port configuration
+ *
+ *
+ * @return 
+ *         - IX_SUCCESS The function executed successfully
+ *         - IX_FAIL The function did not execute successfully
+ *         - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a
+ *                          parameter error
+ */
+PUBLIC IX_STATUS 
+ixHssAccChanStatusQuery (IxHssAccHssPort hssPortId, 
+			 BOOL *dataRecvd, 
+			 unsigned *rxOffset, 
+			 unsigned *txOffset, 
+			 unsigned *numHssErrs);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn void ixHssAccShow (void)
+ *
+ * @brief This function will display the current state of the IxHssAcc
+ * component. The output is sent to stdout.
+ *
+ * @return void
+ */
+PUBLIC void 
+ixHssAccShow (void);
+
+/**
+ *
+ * @ingroup IxHssAccAPI
+ *
+ * @fn void ixHssAccStatsInit (void)
+ *
+ * @brief This function will reset the IxHssAcc statistics.
+ *
+ * @return void
+ */
+PUBLIC void 
+ixHssAccStatsInit (void);
+
+#endif /* IXHSSACC_H */
+
+/**
+ * @} defgroup IxHssAcc
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxI2cDrv.h b/marvell/uboot/drivers/net/npe/include/IxI2cDrv.h
new file mode 100644
index 0000000..0331540
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxI2cDrv.h
@@ -0,0 +1,843 @@
+/**
+ * @file IxI2cDrv.h
+ *
+ * @brief  Header file for the IXP400 I2C Driver (IxI2cDrv)
+ *
+ * @version $Revision: 0.1 $
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxI2cDrv IXP400 I2C Driver(IxI2cDrv) API 
+ *
+ * @brief IXP400 I2C Driver Public API
+ *
+ * @{
+ */
+#ifndef IXI2CDRV_H
+#define IXI2CDRV_H
+
+#ifdef __ixp46X
+#include "IxOsal.h"
+
+/*
+ * Section for #define
+ */
+
+/**
+ * @ingroup IxI2cDrv
+ * @brief The interval of micro/mili seconds the IXP will wait before it polls for
+ *			status from the ixI2cIntrXferStatus; Every 20us is 1 byte @
+ *			400Kbps and 4 bytes	@ 100Kbps. This is dependent on delay type selected
+ *          through the API ixI2cDrvDelayTypeSelect.
+ */
+#define IX_I2C_US_POLL_FOR_XFER_STATUS	20
+
+/**
+ * @ingroup IxI2cDrv
+ * @brief The number of tries that will be attempted to call a callback
+ *          function if the callback does not or is unable to resolve the
+ *          issue it is called to resolve
+ */
+#define IX_I2C_NUM_OF_TRIES_TO_CALL_CALLBACK_FUNC	10
+
+
+/**
+ * @ingroup IxI2cDrv
+ * @brief Number of tries slave will poll the IDBR Rx full bit before it
+ *			gives up
+ */
+#define IX_I2C_NUM_TO_POLL_IDBR_RX_FULL 0x100
+
+/**
+ * @ingroup IxI2cDrv
+ * @brief Number of tries slave will poll the IDBR Tx empty bit before it
+ *			gives up
+ */
+#define IX_I2C_NUM_TO_POLL_IDBR_TX_EMPTY 0x100
+
+/*
+ * Section for enum
+ */
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @enum IxI2cMasterStatus
+ *
+ * @brief The master status - transfer complete, bus error or arbitration loss
+ */
+typedef enum
+{
+    IX_I2C_MASTER_XFER_COMPLETE = IX_SUCCESS,
+	IX_I2C_MASTER_XFER_BUS_ERROR,
+	IX_I2C_MASTER_XFER_ARB_LOSS
+} IxI2cMasterStatus;
+
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @enum IX_I2C_STATUS
+ *
+ * @brief The status that can be returned in a I2C driver initialization
+ */
+typedef enum
+{
+	IX_I2C_SUCCESS = IX_SUCCESS, /**< Success status */
+	IX_I2C_FAIL, /**< Fail status */
+	IX_I2C_NOT_SUPPORTED, /**< hardware does not have dedicated I2C hardware */
+	IX_I2C_NULL_POINTER, /**< parameter passed in is NULL */
+	IX_I2C_INVALID_SPEED_MODE_ENUM_VALUE, /**< speed mode selected is invalid */
+	IX_I2C_INVALID_FLOW_MODE_ENUM_VALUE, /**< flow mode selected is invalid */
+	IX_I2C_SLAVE_ADDR_CB_MISSING, /**< slave callback is NULL */
+	IX_I2C_GEN_CALL_CB_MISSING, /**< general callback is NULL */
+	IX_I2C_INVALID_SLAVE_ADDR, /**< invalid slave address specified */
+	IX_I2C_INT_BIND_FAIL, /**< interrupt bind fail */
+	IX_I2C_INT_UNBIND_FAIL, /**< interrupt unbind fail */
+	IX_I2C_NOT_INIT, /**< I2C is not initialized yet */
+	IX_I2C_MASTER_BUS_BUSY, /**< master detected a I2C bus busy */
+	IX_I2C_MASTER_ARB_LOSS, /**< master experienced arbitration loss */
+	IX_I2C_MASTER_XFER_ERROR, /**< master experienced a transfer error */
+	IX_I2C_MASTER_BUS_ERROR, /**< master detected a I2C bus error */
+	IX_I2C_MASTER_NO_BUFFER, /**< no buffer provided for master transfer */
+	IX_I2C_MASTER_INVALID_XFER_MODE, /**< xfer mode selected is invalid */
+	IX_I2C_SLAVE_ADDR_NOT_DETECTED, /**< polled slave addr not detected */
+	IX_I2C_GEN_CALL_ADDR_DETECTED, /**< polling detected general call */
+	IX_I2C_SLAVE_READ_DETECTED, /**< polling detected slave read request */
+	IX_I2C_SLAVE_WRITE_DETECTED, /**< polling detected slave write request */
+	IX_I2C_SLAVE_NO_BUFFER, /**< no buffer provided for slave transfers */
+	IX_I2C_DATA_SIZE_ZERO, /**< data size transfer is zero - invalid */
+	IX_I2C_SLAVE_WRITE_BUFFER_EMPTY, /**< slave buffer is used till empty */
+	IX_I2C_SLAVE_WRITE_ERROR, /**< slave write experienced an error */
+	IX_I2C_SLAVE_OR_GEN_READ_BUFFER_FULL, /**< slave buffer is filled up */
+	IX_I2C_SLAVE_OR_GEN_READ_ERROR /**< slave read experienced an error */
+} IX_I2C_STATUS;
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @enum IxI2cSpeedMode
+ *
+ * @brief Type of speed modes supported by the I2C hardware.
+ */
+typedef enum
+{
+    IX_I2C_NORMAL_MODE = 0x0,
+    IX_I2C_FAST_MODE
+} IxI2cSpeedMode;
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @enum IxI2cXferMode
+ *
+ * @brief Used for indicating it is a repeated start or normal transfer
+ */
+typedef enum
+{
+    IX_I2C_NORMAL = 0x0,
+    IX_I2C_REPEATED_START
+} IxI2cXferMode;
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @enum IxI2cFlowMode
+ *
+ * @brief Used for indicating it is a poll or interrupt mode
+ */
+typedef enum
+{
+    IX_I2C_POLL_MODE = 0x0,
+    IX_I2C_INTERRUPT_MODE
+} IxI2cFlowMode;
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @enum IxI2cDelayMode
+ *
+ * @brief Used for selecting looping delay or OS scheduler delay
+ */
+typedef enum
+{
+    IX_I2C_LOOP_DELAY = 1,  /**< delay in microseconds */
+    IX_I2C_SCHED_DELAY      /**< delay in miliseconds */
+} IxI2cDelayMode;
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @brief The pointer to the function that will be called when the master
+ *			has completed its receive. The parameter that is passed will
+ *			provide the status of the read (success, arb loss, or bus
+ *			error), the transfer mode (normal or repeated start, the
+ *			buffer pointer and number of bytes transferred.
+ */
+typedef void (*IxI2cMasterReadCallbackP)(IxI2cMasterStatus, IxI2cXferMode, char*, UINT32);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @brief The pointer to the function that will	be called when the master
+ *			has completed its transmit. The parameter that is passed will
+ *			provide the status of the write (success, arb loss, or buss
+ *			error), the transfer mode (normal or repeated start), the
+ *			buffer pointer and number of bytes transferred.
+ */
+typedef void (*IxI2cMasterWriteCallbackP)(IxI2cMasterStatus, IxI2cXferMode, char*, UINT32);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @brief The pointer to the function that will be called when a slave
+ *			address detected in interrupt mode for a read. The parameters
+ *			that is passed will provide the read status, buffer pointer,
+ *			buffer size, and the bytes received. When a start of a read
+ *			is initiated there will be no buffer allocated and this callback
+ *			will be called to request for a buffer. While receiving, if the
+ *			buffer gets filled, this callback will be called to request for
+ *			a new buffer while sending the filled buffer's pointer and size,
+ *			and data size received. When the receive is complete, this
+ *			callback will be called to process the data and free the memory
+ *			by passing the buffer's pointer and size, and data size received.
+ */
+typedef void (*IxI2cSlaveReadCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @brief The pointer to the function that will be called when a slave
+ *			address detected in interrupt mode for a write. The parameters
+ *			that is passed will provide the write status, buffer pointer,
+ *			buffer size, and the bytes received. When a start of a write is
+ *			initiated there will be no buffer allocated and this callback
+ *			will be called to request for a buffer and to fill it with data.
+ *			While transmitting, if the data in the buffer empties, this
+ *			callback will be called to request for more data to be filled in
+ *			the same or new buffer. When the transmit is complete, this
+ *			callback will be called to free the memory or other actions to
+ *			be taken.
+ */
+typedef void (*IxI2cSlaveWriteCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @brief The pointer to the function that will be called when a general
+ *			call detected in interrupt mode for a read. The parameters that
+ *			is passed will provide the read status, buffer pointer, buffer
+ *			size, and the bytes received. When a start of a read is
+ *			initiated there will be no buffer allocated and this callback
+ *			will be called to request for a buffer. While receiving, if the
+ *			buffer gets filled, this callback will be called to request for
+ *			a new buffer while sending the filled buffer's pointer and size,
+ *			and data size received. When the receive is complete, this
+ *			callback will be called to process the data and free the memory
+ *			by passing the buffer's pointer and size, and data size received.
+ */
+typedef void (*IxI2cGenCallCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32);
+
+/*
+ * Section for struct
+ */
+
+/**
+ * @brief contains all the variables required to initialize the I2C unit
+ * 
+ * Structure to be filled and used for calling initialization
+ */
+typedef struct
+{
+	IxI2cSpeedMode I2cSpeedSelect;	/**<Select either normal (100kbps)
+									or fast mode (400kbps)*/
+	IxI2cFlowMode I2cFlowSelect;	/**<Select interrupt or poll mode*/	
+	IxI2cMasterReadCallbackP MasterReadCBP;
+									/**<The master read callback pointer */
+	IxI2cMasterWriteCallbackP MasterWriteCBP;
+									/**<The master write callback pointer */
+	IxI2cSlaveReadCallbackP SlaveReadCBP;
+									/**<The slave read callback pointer */
+	IxI2cSlaveWriteCallbackP SlaveWriteCBP;
+									/**<The slave write callback pointer */
+	IxI2cGenCallCallbackP GenCallCBP;
+									/**<The general call callback pointer */
+	BOOL I2cGenCallResponseEnable;	/**<Enable/disable the unit to
+									respond to generall calls.*/
+	BOOL I2cSlaveAddrResponseEnable;/**<Enable/disable the unit to
+									respond to the slave address set in
+									ISAR*/
+	BOOL SCLEnable;					/**<Enable/disable the unit from
+									driving the SCL line during master
+									mode operation*/
+	UINT8 I2cHWAddr;				/**<The address the unit will
+									response to as a slave device*/
+} IxI2cInitVars;
+
+/**
+ * @brief contains results of counters and their overflow
+ * 
+ * Structure contains all values of counters and associated overflows.
+ */
+typedef struct
+{
+	UINT32 ixI2cMasterXmitCounter;			/**<Total bytes transmitted as
+											master.*/
+	UINT32 ixI2cMasterFailedXmitCounter;	/**<Total bytes failed for
+											transmission as master.*/
+	UINT32 ixI2cMasterRcvCounter;			/**<Total bytes received as
+											master.*/
+	UINT32 ixI2cMasterFailedRcvCounter;		/**<Total bytes failed for
+											receival as master.*/
+	UINT32 ixI2cSlaveXmitCounter;			/**<Total bytes transmitted as
+											slave.*/
+	UINT32 ixI2cSlaveFailedXmitCounter;		/**<Total bytes failed for
+											transmission as slave.*/
+	UINT32 ixI2cSlaveRcvCounter;			/**<Total bytes received as
+											slave.*/
+	UINT32 ixI2cSlaveFailedRcvCounter;		/**<Total bytes failed for
+											receival as slave.*/
+	UINT32 ixI2cGenAddrCallSucceedCounter;	/**<Total bytes successfully
+											transmitted for general address.*/
+	UINT32 ixI2cGenAddrCallFailedCounter;	/**<Total bytes failed transmission
+											for general address.*/
+	UINT32 ixI2cArbLossCounter;				/**<Total instances of arbitration
+											loss has occured.*/
+} IxI2cStatsCounters;
+
+
+/*
+ * Section for prototypes interface functions
+ */
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @fn ixI2cDrvInit(
+	IxI2cInitVars *InitVarsSelected)
+ *
+ * @brief Initializes the I2C Driver.
+ *
+ * @param "IxI2cInitVars [in] *InitVarsSelected" - struct containing required
+ *			variables for initialization 
+ *
+ * Global Data	:
+ *		- None.
+ *
+ * This API will check if the hardware supports this I2C driver and the validity
+ * of the parameters passed in. It will continue to process the parameters
+ * passed in by setting the speed of the I2C unit (100kbps or 400kbps), setting
+ * the flow to either interrupt or poll mode, setting the address of the I2C unit,
+ * enabling/disabling the respond to General Calls, enabling/disabling the respond
+ * to Slave Address and SCL line driving. If it is interrupt mode, then it will
+ * register the callback routines for master, slavetransfer and general call receive.
+ *
+ * @return 
+ *      - IX_I2C_SUCCESS - Successfully initialize and enable the I2C
+ *							hardware.
+ *		- IX_I2C_NOT_SUPPORTED - The hardware does not support or have a
+ *                              dedicated I2C unit to support this driver
+ *		- IX_I2C_NULL_POINTER - The parameter passed in is a NULL pointed
+ *		- IX_I2C_INVALID_SPEED_MODE_ENUM_VALUE - The speed mode selected in the
+ *												InitVarsSelected is invalid
+ *		- IX_I2C_INVALID_FLOW_MODE_ENUM_VALUE - The flow mode selected in the
+ *												InitVarsSelected is invalid
+ *		- IX_I2C_INVALID_SLAVE_ADDR - The address 0x0 is reserved for
+ *										general call.
+ *		- IX_I2C_SLAVE_ADDR_CB_MISSING - interrupt mode is selected but
+ *										slave address callback pointer is NULL
+ *		- IX_I2C_GEN_CALL_CB_MISSING - interrupt mode is selected but
+ *										general call callback pointer is NULL
+ *		- IX_I2C_INT_BIND_FAIL - The ISR for the I2C failed to bind
+ *		- IX_I2C_INT_UNBIND_FAIL - The ISR for the I2C failed to unbind
+ *
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvInit(IxI2cInitVars *InitVarsSelected);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @fn ixI2cDrvUninit(
+	void)
+ *
+ * @brief Disables the I2C hardware
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will disable the I2C hardware, unbind interrupt, and unmap memory.
+ *
+ * @return 
+ *      - IX_I2C_SUCCESS - successfully un-initialized I2C
+ *		- IX_I2C_INT_UNBIND_FAIL - failed to unbind the I2C interrupt
+ *		- IX_I2C_NOT_INIT - I2C not init yet.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvUninit(void);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @fn ixI2cDrvSlaveAddrSet(
+	UINT8 SlaveAddrSet)
+ *
+ * @brief Sets the I2C Slave Address
+ *
+ * @param "UINT8 [in] SlaveAddrSet" - Slave Address to be inserted into ISAR
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will insert the SlaveAddrSet into the ISAR.
+ *
+ * @return 
+ *      - IX_I2C_SUCCESS - successfuly set the slave addr
+ *		- IX_I2C_INVALID_SLAVE_ADDR - invalid slave address (zero) specified
+ *		- IX_I2C_NOT_INIT - I2C not init yet.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvSlaveAddrSet(UINT8 SlaveAddrSet);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @fn ixI2cDrvBusScan(
+	void)
+ *
+ * @brief scans the I2C bus for slave devices
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will prompt all slave addresses for a reply except its own
+ *
+ * @return 
+ *      - IX_I2C_SUCCESS - found at least one slave device
+ *		- IX_I2C_FAIL - Fail to find even one slave device
+ *		- IX_I2C_BUS_BUSY - The I2C bus is busy (held by another I2C master)
+ *		- IX_I2C_ARB_LOSS - The I2C bus was loss to another I2C master
+ *		- IX_I2C_NOT_INIT - I2C not init yet.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvBusScan(void);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @fn ixI2cDrvWriteTransfer(
+	UINT8 SlaveAddr,
+	char *bufP,
+	UINT32 dataSize,
+	IxI2cXferMode XferModeSelect)
+ *
+ * @param "UINT8 [in] SlaveAddr" - The slave address to request data from.
+ * @param "char [in] *bufP" - The pointer to the data to be transmitted.
+ * @param "UINT32 [in] dataSize" - The number of bytes requested.
+ * @param "IxI2cXferMode [in] XferModeSelect" - the transfer mode selected,
+ *			either repeated start (ends w/o stop) or normal (start and stop)
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will try to obtain master control of the I2C bus and transmit the
+ * number of bytes, specified by dataSize, to the user specified slave
+ * address from the buffer pointer. It will use either interrupt or poll mode
+ * depending on the method selected. 
+ *
+ * If in interrupt mode and IxI2cMasterWriteCallbackP is not NULL, the driver
+ * will initiate the transfer and return immediately. The function pointed to
+ * by IxI2cMasterWriteCallbackP will be called in the interrupt service
+ * handlers when the operation is complete.
+ *
+ * If in interrupt mode and IxI2cMasterWriteCallbackP is NULL, then the driver
+ * will wait for the operation to complete, and then return.
+ *
+ * And if the repeated start transfer mode is selected, then it will not send a
+ * stop signal at the end of all the transfers.
+ * *NOTE*: If repeated start transfer mode is selected, it has to end with a
+ *			normal mode transfer mode else the bus will continue to be held
+ *			by the IXP.
+ *
+ * @return 
+ *      - IX_I2C_SUCCESS - Successfuuly wrote data to slave.
+ *		- IX_I2C_MASTER_BUS_BUSY - The I2C bus is busy (held by another I2C master)
+ *		- IX_I2C_MASTER_ARB_LOSS - The I2C bus was loss to another I2C master
+ *		- IX_I2C_MASTER_XFER_ERROR - There was a transfer error
+ *      - IX_I2C_MASTER_BUS_ERROR - There was a bus error during transfer
+ *		- IX_I2C_MASTER_NO_BUFFER - buffer pointer is NULL
+ *      - IX_I2C_MASTER_INVALID_XFER_MODE - Xfer mode selected is invalid
+ *      - IX_I2C_DATA_SIZE_ZERO - dataSize passed in is zero, which is invalid
+ *		- IX_I2C_NOT_INIT - I2C not init yet.
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvWriteTransfer(
+	UINT8 SlaveAddr,
+	char *bufP,
+	UINT32 dataSize,
+	IxI2cXferMode XferModeSelect);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @fn ixI2cDrvReadTransfer(
+	UINT8 SlaveAddr,
+	char *bufP,
+	UINT32 dataSize,
+	IxI2cXferMode XferModeSelect)
+ *
+ * @brief Initiates a transfer to receive bytes of data from a slave
+ *			device through the I2C bus.
+ *
+ * @param "UINT8 [in] SlaveAddr" - The slave address to request data from.
+ * @param "char [out] *bufP" - The pointer to the buffer to store the
+ *			requested data.
+ * @param "UINT32 [in] dataSize" - The number of bytes requested.
+ * @param "IxI2cXferMode [in] XferModeSelect" - the transfer mode selected,
+ *			either repeated start (ends w/o stop) or normal (start and stop)
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will try to obtain master control of the I2C bus and receive the
+ * number of bytes, specified by dataSize, from the user specified address
+ * into the receive buffer. It will use either interrupt or poll mode depending
+ * on the mode selected.
+ *
+ * If in interrupt mode and IxI2cMasterReadCallbackP is not NULL, the driver
+ * will initiate the transfer and return immediately. The function pointed to
+ * by IxI2cMasterReadCallbackP will be called in the interrupt service
+ * handlers when the operation is complete.
+ *
+ * If in interrupt mode and IxI2cMasterReadCallbackP is NULL, then the driver will
+ * wait for the operation to complete, and then return.
+ *
+ * And if the repeated start transfer mode is selected, then it will not send a
+ * stop signal at the end of all the transfers.
+ * *NOTE*: If repeated start transfer mode is selected, it has to end with a
+ *			normal mode transfer mode else the bus will continue to be held
+ *			by the IXP.
+ *
+ * @return 
+ *      - IX_I2C_SUCCESS - Successfuuly read slave data
+ *		- IX_I2C_MASTER_BUS_BUSY - The I2C bus is busy (held by another I2C master)
+ *		- IX_I2C_MASTER_ARB_LOSS - The I2C bus was loss to another I2C master
+ *		- IX_I2C_MASTER_XFER_ERROR - There was a bus error during transfer
+ *      - IX_I2C_MASTER_BUS_ERROR - There was a bus error during transfer
+ *		- IX_I2C_MASTER_NO_BUFFER - buffer pointer is NULL
+ *      - IX_I2C_MASTER_INVALID_XFER_MODE - Xfer mode selected is invalid
+ *      - IX_I2C_INVALID_SLAVE_ADDR - invalid slave address (zero) specified
+ *      - IX_I2C_DATA_SIZE_ZERO - dataSize passed in is zero, which is invalid
+ *		- IX_I2C_NOT_INIT - I2C not init yet.
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvReadTransfer(
+	UINT8 SlaveAddr,
+	char *bufP,
+	UINT32 dataSize,
+	IxI2cXferMode XferModeSelect);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @fn ixI2cDrvSlaveAddrAndGenCallDetectedCheck(
+	void)
+ *
+ * @brief Checks the I2C Status Register to determine if a slave address is
+ *			detected
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API is used in polled mode to determine if the I2C unit is requested
+ * for a slave or general call transfer. If it is requested for a slave
+ * transfer then it will determine if it is a general call (read only), read,
+ * or write transfer requested.
+ *
+ * @return 
+ *      - IX_I2C_SLAVE_ADDR_NOT_DETECTED - The I2C unit is not requested for slave
+ *										transfer
+ *		- IX_I2C_GEN_CALL_ADDR_DETECTED - The I2C unit is not requested for slave
+ *									transfer but for general call
+ *      - IX_I2C_SLAVE_READ_DETECTED - The I2C unit is requested for a read
+ *      - IX_I2C_SLAVE_WRITE_DETECTED - The I2C unit is requested for a write
+ *		- IX_I2C_NOT_INIT - I2C not init yet.
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvSlaveAddrAndGenCallDetectedCheck(void);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @fn ixI2cDrvSlaveOrGenDataReceive(
+	char *bufP,
+	UINT32 bufSize,
+	UINT32 *dataSizeRcvd)
+ *
+ * @brief Performs the slave receive or general call receive data transfer
+ *
+ * @param	"char [in] *bufP" - the pointer to the buffer to store data
+ *			"UINT32 [in] bufSize" - the buffer size allocated
+ *			"UINT32 [in] *dataSizeRcvd" - the length of data received in bytes
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API is only used in polled mode to perform the slave read or general call
+ * receive data. It will continuously store the data received into bufP until
+ * complete or until bufP is full in which it will return
+ * IX_I2C_SLAVE_OR_GEN_READ_BUFFER_FULL. If in interrupt mode, the callback will be
+ * used.
+ *
+ * @return 
+ *      - IX_I2C_SUCCESS - The I2C driver transferred the data successfully.
+ *		- IX_I2C_SLAVE_OR_GEN_READ_BUFFER_FULL - The I2C driver has ran out of
+ *			space to store the received data.
+ *		- IX_I2C_SLAVE_OR_GEN_READ_ERROR - The I2C driver didn't manage to
+ *			detect the IDBR Rx Full bit
+ *      - IX_I2C_DATA_SIZE_ZERO - bufSize passed in is zero, which is invalid
+ *		- IX_I2C_SLAVE_NO_BUFFER - buffer pointer is NULL
+ *      - IX_I2C_NULL_POINTER - dataSizeRcvd is NULL
+ *		- IX_I2C_NOT_INIT - I2C not init yet.
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvSlaveOrGenDataReceive(
+	char *bufP,
+	UINT32 bufSize,
+	UINT32 *dataSizeRcvd);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @fn ixI2cDrvSlaveDataTransmit(
+	char *bufP,
+	UINT32 dataSize,
+	UINT32 *dataSizeXmtd)
+ *
+ * @brief Performs the slave write data transfer
+ *
+ * @param	"char [in] *bufP" - the pointer to the buffer for data to be
+ *				transmitted
+ *			"UINT32 [in] bufSize" - the buffer size allocated
+ *			"UINT32 [in] *dataSizeRcvd" - the length of data trasnmitted in
+ *				bytes
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API is only used in polled mode to perform the slave transmit data. It
+ * will continuously transmit the data from bufP until complete or until bufP
+ * is empty in which it will return IX_I2C_SLAVE_WRITE_BUFFER_EMPTY. If in
+ * interrupt mode, the callback will be used.
+ *
+ * @return 
+ *      - IX_I2C_SUCCESS - The I2C driver transferred the data successfully.
+ *      - IX_I2C_SLAVE_WRITE_BUFFER_EMPTY - The I2C driver needs more data to
+ *			transmit.
+ *      - IX_I2C_SLAVE_WRITE_ERROR -The I2C driver didn't manage to detect the
+ *          IDBR Tx empty bit or the slave stop bit.
+ *      - IX_I2C_DATA_SIZE_ZERO - dataSize passed in is zero, which is invalid
+ *		- IX_I2C_SLAVE_NO_BUFFER - buffer pointer is NULL
+ *      - IX_I2C_NULL_POINTER - dataSizeXmtd is NULL
+ *		- IX_I2C_NOT_INIT - I2C not init yet.
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvSlaveDataTransmit(
+	char *bufP,
+	UINT32 dataSize,
+	UINT32 *dataSizeXmtd);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @fn ixI2cDrvSlaveOrGenCallBufReplenish(
+	char *bufP,
+	UINT32 bufSize)
+ *
+ * @brief Replenishes the buffer which stores buffer info for both slave and
+ *			general call
+ *
+ * @param	"char [in] *bufP" - pointer to the buffer allocated
+ *			"UINT32 [in] bufSize" - size of the buffer
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API is only used in interrupt mode for replenishing the same buffer
+ * that is used by both slave and generall call by updating the buffer info
+ * with new info and clearing previous offsets set by previous transfers.
+ *
+ * @return 
+ *      - None
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC void
+ixI2cDrvSlaveOrGenCallBufReplenish(
+	char *bufP,
+	UINT32 bufSize);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @fn ixI2cDrvStatsGet(IxI2cStatsCounters *I2cStats)
+ *
+ * @brief Returns the I2C Statistics through the pointer passed in
+ *
+ * @param - "IxI2cStatsCounters [out] *I2cStats" - I2C statistics counter will
+ *			be read and written to the location pointed by this pointer.
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will return the statistics counters of the I2C driver.
+ *
+ * @return 
+ *      - IX_I2C_NULL_POINTER - pointer passed in is NULL
+ *		- IX_I2C_SUCCESS - successfully obtained I2C statistics
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvStatsGet(IxI2cStatsCounters *I2cStats);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @fn ixI2cDrvStatsReset(void)
+ *
+ * @brief Reset I2C statistics counters.
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will reset the statistics counters of the I2C driver.
+ *
+ * @return 
+ *      - None
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC void
+ixI2cDrvStatsReset(void);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @fn ixI2cDrvShow(void)
+ *
+ * @brief Displays the I2C status register and the statistics counter.
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will display the I2C Status register and is useful if any error
+ * occurs. It displays the detection of bus error, slave address, general call,
+ * address, IDBR receive full, IDBR transmit empty, arbitration loss, slave
+ * STOP signal, I2C bus busy, unit busy, ack/nack, and read/write mode. It will
+ * also call the ixI2cDrvGetStats and then display the statistics counter.
+ *
+ * @return 
+ *		- IX_I2C_SUCCESS - successfully displayed statistics and status register
+ *		- IX_I2C_NOT_INIT - I2C not init yet.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IX_I2C_STATUS
+ixI2cDrvShow(void);
+
+/**
+ * @ingroup IxI2cDrv
+ * 
+ * @fn ixI2cDrvDelayTypeSelect (IxI2cDelayMode delayMechanismSelect)
+ *
+ * @brief Sets the delay type of either looping delay or OS scheduler delay
+ *          according to the argument provided.
+ *
+ * @param - "IxI2cDelayMode [in] delayTypeSelect" - the I2C delay type selected
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will set the delay type used by the I2C Driver to either looping
+ * delay or OS scheduler delay.
+ *
+ * @return 
+ *		- None
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC void
+ixI2cDrvDelayTypeSelect (IxI2cDelayMode delayTypeSelect);
+
+#endif /* __ixp46X */
+#endif /* IXI2CDRV_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeA.h b/marvell/uboot/drivers/net/npe/include/IxNpeA.h
new file mode 100644
index 0000000..e145b43
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeA.h
@@ -0,0 +1,758 @@
+#ifndef __doxygen_HIDE  /* This file is not part of the API */
+
+/**
+ * @file    IxNpeA.h
+ *
+ * @date    22-Mar-2002
+ *
+ * @brief   Header file for the IXP400 ATM NPE API
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxNpeA IXP400 NPE-A (IxNpeA) API
+ *
+ * @brief The Public API for the IXP400 NPE-A
+ *
+ * @{
+ */
+
+#ifndef IX_NPE_A_H
+#define IX_NPE_A_H
+
+#include "IxQMgr.h"
+#include "IxOsal.h"
+#include "IxQueueAssignments.h"
+
+/* General Message Ids */
+
+/* ATM Message Ids */
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_UTOPIA_CONFIG_WRITE
+ *
+ * @brief ATM Message ID command to write the data to the offset in the
+ * Utopia Configuration Table
+ */
+#define IX_NPE_A_MSSG_ATM_UTOPIA_CONFIG_WRITE       0x20
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_UTOPIA_CONFIG_LOAD
+ *
+ * @brief ATM Message ID command triggers the NPE to copy the Utopia
+ * Configuration Table to the Utopia coprocessor
+ */
+#define IX_NPE_A_MSSG_ATM_UTOPIA_CONFIG_LOAD        0x21
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_UTOPIA_STATUS_UPLOAD
+ *
+ * @brief ATM Message ID command triggers the NPE to read-back the Utopia
+ * status registers and update the Utopia Status Table.
+ */
+#define IX_NPE_A_MSSG_ATM_UTOPIA_STATUS_UPLOAD      0x22
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_UTOPIA_STATUS_READ
+ *
+ * @brief ATM Message ID command to read the Utopia Status Table at the
+ * specified offset.
+ */
+#define IX_NPE_A_MSSG_ATM_UTOPIA_STATUS_READ        0x23
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_TX_ENABLE
+ *
+ * @brief ATM Message ID command triggers the NPE to re-enable processing
+ * of any entries on the TxVcQ for this port.
+ *
+ * This command will be ignored for a port already enabled
+ */
+#define IX_NPE_A_MSSG_ATM_TX_ENABLE                 0x25
+
+ /**
+ * @def IX_NPE_A_MSSG_ATM_TX_DISABLE
+ *
+ * @brief ATM Message ID command triggers the NPE to disable processing on
+ * this port
+ *
+ * This command will be ignored for a port already disabled
+ */
+#define IX_NPE_A_MSSG_ATM_TX_DISABLE                0x26
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_RX_ENABLE
+ *
+ * @brief ATM Message ID command triggers the NPE to process any received
+ * cells for this VC according to the VC Lookup Table.
+ *
+ * Re-issuing this command with different contents for a VC that is not
+ * disabled will cause unpredictable behavior.
+ */
+#define IX_NPE_A_MSSG_ATM_RX_ENABLE                 0x27
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_RX_DISABLE
+ *
+ * @brief ATM Message ID command triggers the NPE to disable processing for
+ * this VC.
+ *
+ * This command will be ignored for a VC already disabled
+ */
+#define IX_NPE_A_MSSG_ATM_RX_DISABLE                0x28
+
+/**
+ * @def IX_NPE_A_MSSG_ATM_STATUS_READ
+ *
+ * @brief ATM Message ID command to read the ATM status. The data is returned via
+ * a response message
+ */
+#define IX_NPE_A_MSSG_ATM_STATUS_READ               0x29
+
+/*--------------------------------------------------------------------------
+ * HSS Message IDs
+ *--------------------------------------------------------------------------*/
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PORT_CONFIG_WRITE
+ *
+ * @brief HSS Message ID command writes the ConfigWord value to the location
+ * in the HSS_CONFIG_TABLE specified by offset for HSS port hPort.
+ */
+#define IX_NPE_A_MSSG_HSS_PORT_CONFIG_WRITE         0x40
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PORT_CONFIG_LOAD
+ *
+ * @brief HSS Message ID command triggers the NPE to copy the contents of the
+ * HSS Configuration Table to the appropriate configuration registers in the
+ * HSS coprocessor for the port specified by hPort.
+ */
+#define IX_NPE_A_MSSG_HSS_PORT_CONFIG_LOAD          0x41
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PORT_ERROR_READ
+ *
+ * @brief HSS Message ID command triggers the NPE to return an HssErrorReadResponse
+ * message for HSS port hPort.
+ */
+#define IX_NPE_A_MSSG_HSS_PORT_ERROR_READ           0x42
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_FLOW_ENABLE
+ *
+ * @brief HSS Message ID command triggers the NPE to reset internal status and
+ * enable the HssChannelized operation on the HSS port specified by hPort.
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_FLOW_ENABLE          0x43
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_FLOW_DISABLE
+ *
+ * @brief HSS Message ID command triggers the NPE to disable the HssChannelized
+ * operation on the HSS port specified by hPort.
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_FLOW_DISABLE         0x44
+
+/**
+ * @def  IX_NPE_A_MSSG_HSS_CHAN_IDLE_PATTERN_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnC_IDLE_PATTERN value for HSS
+ * port hPort. (n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_IDLE_PATTERN_WRITE   0x45
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_NUM_CHANS_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnC_NUM_CHANNELS value for HSS
+ * port hPort. (n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_NUM_CHANS_WRITE      0x46
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_ADDR_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnC_RX_BUF_ADDR value for HSS
+ * port hPort. (n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_ADDR_WRITE    0x47
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_CFG_WRITE
+ *
+ * @brief HSS Message ID command  writes the HSSnC_RX_BUF_SIZEB and
+ * HSSnC_RX_TRIG_PERIOD values for HSS port hPort.  (n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_RX_BUF_CFG_WRITE     0x48
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_TX_BLK_CFG_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnC_TX_BLK1_SIZEB,
+ * HSSnC_TX_BLK1_SIZEW, HSSnC_TX_BLK2_SIZEB, and HSSnC_TX_BLK2_SIZEW  values
+ * for HSS port hPort. (n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_TX_BLK_CFG_WRITE     0x49
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_ADDR_WRITE
+ * @brief HSS Message ID command writes the HSSnC_TX_BUF_ADDR value for HSS
+ * port hPort. (n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_ADDR_WRITE    0x4A
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_SIZE_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnC_TX_BUF_SIZEN value for HSS
+ * port hPort. (n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_CHAN_TX_BUF_SIZE_WRITE    0x4B
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_PIPE_FLOW_ENABLE
+ *
+ * @brief HSS Message ID command triggers the NPE to reset internal status and
+ * enable the HssPacketized operation for the flow specified by pPipe on
+ * the HSS port specified by hPort.
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_PIPE_FLOW_ENABLE      0x50
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_PIPE_FLOW_DISABLE
+ * @brief HSS Message ID command triggers the NPE to disable the HssPacketized
+ * operation for the flow specified by pPipe on the HSS port specified by hPort.
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_PIPE_FLOW_DISABLE     0x51
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_NUM_PIPES_WRITE
+ * @brief HSS Message ID command writes the HSSnP_NUM_PIPES value for HSS
+ * port hPort.(n=hPort)
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_NUM_PIPES_WRITE       0x52
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_PIPE_FIFO_SIZEW_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnP_PIPEp_FIFOSIZEW value for
+ * packet-pipe pPipe on HSS port hPort.  (n=hPort, p=pPipe)
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_PIPE_FIFO_SIZEW_WRITE 0x53
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_PIPE_HDLC_CFG_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnP_PIPEp_HDLC_RXCFG and
+ * HSSnP_PIPEp_HDLC_TXCFG values for packet-pipe pPipe on HSS port hPort.
+ * (n=hPort, p=pPipe)
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_PIPE_HDLC_CFG_WRITE   0x54
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_PIPE_IDLE_PATTERN_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnP_PIPEp_IDLE_PATTERN value
+ * for packet-pipe pPipe on HSS port hPort.  (n=hPort, p=pPipe)
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_PIPE_IDLE_PATTERN_WRITE 0x55
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_PIPE_RX_SIZE_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnP_PIPEp_RXSIZEB value for
+ * packet-pipe pPipe on HSS port hPort.  (n=hPort, p=pPipe)
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_PIPE_RX_SIZE_WRITE    0x56
+
+/**
+ * @def IX_NPE_A_MSSG_HSS_PKT_PIPE_MODE_WRITE
+ *
+ * @brief HSS Message ID command writes the HSSnP_PIPEp_MODE value for
+ * packet-pipe pPipe on HSS port hPort.  (n=hPort, p=pPipe)
+ */
+#define IX_NPE_A_MSSG_HSS_PKT_PIPE_MODE_WRITE       0x57
+
+
+
+/* Queue Entry Masks */
+
+/*--------------------------------------------------------------------------
+ *  ATM Descriptor Structure offsets
+ *--------------------------------------------------------------------------*/
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_STATUS_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Status field
+ *
+ * It is used for descriptor error reporting.
+ */
+#define IX_NPE_A_RXDESCRIPTOR_STATUS_OFFSET          0
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_VCID_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor VC ID field
+ *
+ * It is used to hold an identifier number for this VC
+ */
+#define IX_NPE_A_RXDESCRIPTOR_VCID_OFFSET            1
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_CURRMBUFSIZE_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Current Mbuf
+ * Size field
+ *
+ * Number of bytes the current mbuf data buffer can hold
+ */
+#define IX_NPE_A_RXDESCRIPTOR_CURRMBUFSIZE_OFFSET    2
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_ATMHEADER_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor ATM Header
+ */
+#define IX_NPE_A_RXDESCRIPTOR_ATMHEADER_OFFSET       4
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_CURRMBUFLEN_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Current MBuf length
+ *
+ *
+ * RX - Initialized to zero.  The NPE updates this field as each cell is received and
+ * zeroes it with every new mbuf for chaining. Will not be bigger than currBbufSize.
+ */
+#define IX_NPE_A_RXDESCRIPTOR_CURRMBUFLEN_OFFSET    12
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_TIMELIMIT__OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Time Limit field
+ *
+ * Contains the Payload Reassembly Time Limit (used for aal0_xx only)
+ */
+#define IX_NPE_A_RXDESCRIPTOR_TIMELIMIT_OFFSET        14
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_PCURRMBUFF_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Current MBuf Pointer
+ *
+ * The current mbuf pointer of a chain of mbufs.
+ */
+#define IX_NPE_A_RXDESCRIPTOR_PCURRMBUFF_OFFSET     20
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_PCURRMBUFDATA_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Current MBuf Pointer
+ *
+ * Pointer to the next byte to be read or next free location to be written.
+ */
+#define IX_NPE_A_RXDESCRIPTOR_PCURRMBUFDATA_OFFSET  24
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_PNEXTMBUF_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Next MBuf Pointer
+ *
+ * Pointer to the next MBuf in a chain of MBufs.
+ */
+#define IX_NPE_A_RXDESCRIPTOR_PNEXTMBUF_OFFSET      28
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_TOTALLENGTH_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Total Length
+ *
+ * Total number of bytes written to the chain of MBufs by the NPE
+ */
+#define IX_NPE_A_RXDESCRIPTOR_TOTALLENGTH_OFFSET    32
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_AAL5CRCRESIDUE_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor AAL5 CRC Residue
+ *
+ * Current CRC value for a PDU
+ */
+#define IX_NPE_A_RXDESCRIPTOR_AAL5CRCRESIDUE_OFFSET 36
+
+/**
+ * @def IX_NPE_A_RXDESCRIPTOR_SIZE
+ *
+ * @brief ATM Descriptor structure offset for Receive Descriptor Size
+ *
+ * The size of the Receive descriptor
+ */
+#define IX_NPE_A_RXDESCRIPTOR_SIZE                  40
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_PORT_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor Port
+ *
+ * Port identifier.
+ */
+#define IX_NPE_A_TXDESCRIPTOR_PORT_OFFSET            0
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_RSVD_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor RSVD
+ */
+#define IX_NPE_A_TXDESCRIPTOR_RSVD_OFFSET            1
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_CURRMBUFLEN_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor Current MBuf Length
+ *
+ * TX - Initialized by the XScale to the number of bytes in the current MBuf data buffer.
+ * The NPE decrements this field for every transmitted cell.  Thus, when the NPE writes a
+ * descriptor the TxDone queue, this field will equal zero.
+ */
+#define IX_NPE_A_TXDESCRIPTOR_CURRMBUFLEN_OFFSET     2
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_ATMHEADER_OFFSET
+ * @brief ATM Descriptor structure offset for Transmit Descriptor ATM Header
+ */
+#define IX_NPE_A_TXDESCRIPTOR_ATMHEADER_OFFSET       4
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_PCURRMBUFF_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor Pointer to the current MBuf chain
+ */
+#define IX_NPE_A_TXDESCRIPTOR_PCURRMBUFF_OFFSET      8
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_PCURRMBUFDATA_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor Pointer to the current MBuf Data
+ *
+ * Pointer to the next byte to be read or next free location to be written.
+ */
+#define IX_NPE_A_TXDESCRIPTOR_PCURRMBUFDATA_OFFSET  12
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_PNEXTMBUF_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor Pointer to the Next MBuf chain
+ */
+#define IX_NPE_A_TXDESCRIPTOR_PNEXTMBUF_OFFSET      16
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_TOTALLENGTH_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor Total Length
+ *
+ * Total number of bytes written to the chain of MBufs by the NPE
+ */
+#define IX_NPE_A_TXDESCRIPTOR_TOTALLENGTH_OFFSET    20
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_AAL5CRCRESIDUE_OFFSET
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor AAL5 CRC Residue
+ *
+ * Current CRC value for a PDU
+ */
+#define IX_NPE_A_TXDESCRIPTOR_AAL5CRCRESIDUE_OFFSET 24
+
+/**
+ * @def IX_NPE_A_TXDESCRIPTOR_SIZE
+ *
+ * @brief ATM Descriptor structure offset for Transmit Descriptor Size
+ */
+#define IX_NPE_A_TXDESCRIPTOR_SIZE                  28
+
+/**
+ * @def IX_NPE_A_CHAIN_DESC_COUNT_MAX
+ *
+ * @brief Maximum number of chained MBufs that can be chained together
+ */
+#define IX_NPE_A_CHAIN_DESC_COUNT_MAX            256
+
+/*
+ *  Definition of the ATM cell header
+ *
+ * This would most conviently be defined as the bit field shown below.
+ * Endian portability prevents this, therefore a set of macros
+ * are defined to access the fields within the cell header assumed to
+ * be passed as a UINT32.
+ *
+ * Changes to field sizes or orders must be reflected in the offset
+ * definitions above.
+ *
+ *    typedef struct
+ *    {
+ *       unsigned int gfc:4;
+ *       unsigned int vpi:8;
+ *       unsigned int vci:16;
+ *       unsigned int pti:3;
+ *       unsigned int clp:1;
+ *    } IxNpeA_AtmCellHeader;
+ *
+ */
+
+/** Mask to acess GFC */
+#define GFC_MASK        0xf0000000
+
+/** return GFC from ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_GFC_GET( header ) \
+(((header) & GFC_MASK) >> 28)
+
+/** set GFC into ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_GFC_SET( header,gfc ) \
+do { \
+    (header) &= ~GFC_MASK; \
+    (header) |= (((gfc) << 28) & GFC_MASK); \
+} while(0)
+
+/** Mask to acess VPI */
+#define VPI_MASK        0x0ff00000
+
+/** return VPI from ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_VPI_GET( header ) \
+(((header) & VPI_MASK) >> 20)
+
+/** set VPI into ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_VPI_SET( header, vpi ) \
+do { \
+    (header) &= ~VPI_MASK; \
+    (header) |= (((vpi) << 20) & VPI_MASK); \
+} while(0)
+
+/** Mask to acess VCI */
+#define VCI_MASK        0x000ffff0
+
+/** return VCI from ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_VCI_GET( header ) \
+(((header) & VCI_MASK) >> 4)
+
+/** set VCI into ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_VCI_SET( header, vci ) \
+do { \
+    (header) &= ~VCI_MASK; \
+    (header) |= (((vci) << 4) & VCI_MASK); \
+} while(0)
+
+/** Mask to acess PTI */
+#define PTI_MASK        0x0000000e
+
+/** return PTI from ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_PTI_GET( header ) \
+(((header) & PTI_MASK) >> 1)
+
+/** set PTI into ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_PTI_SET( header, pti ) \
+do { \
+    (header) &= ~PTI_MASK; \
+    (header) |= (((pti) << 1) & PTI_MASK); \
+} while(0)
+
+/** Mask to acess CLP */
+#define CLP_MASK        0x00000001
+
+/** return CLP from ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_CLP_GET( header ) \
+((header) & CLP_MASK)
+
+/** set CLP into ATM cell header */
+#define IX_NPE_A_ATMCELLHEADER_CLP_SET( header, clp ) \
+do { \
+    (header) &= ~CLP_MASK; \
+    (header) |= ((clp) & CLP_MASK); \
+} while(0)
+
+
+/*
+* Definition of the Rx bitfield
+*
+* This would most conviently be defined as the bit field shown below.
+* Endian portability prevents this, therefore a set of macros
+* are defined to access the fields within the rxBitfield assumed to
+* be passed as a UINT32.
+*
+* Changes to field sizes or orders must be reflected in the offset
+* definitions above.
+*
+* Rx bitfield
+*    struct
+*    {   IX_NPEA_RXBITFIELD(
+*        unsigned int status:1,
+*        unsigned int port:7,
+*        unsigned int vcId:8,
+*        unsigned int currMbufSize:16);
+*    } rxBitField;
+*
+*/
+
+/** Mask to acess the rxBitField status */
+#define STATUS_MASK     0x80000000
+
+/** return the rxBitField status */
+#define IX_NPE_A_RXBITFIELD_STATUS_GET( rxbitfield ) \
+(((rxbitfield) & STATUS_MASK) >> 31)
+
+/** set the rxBitField status */
+#define IX_NPE_A_RXBITFIELD_STATUS_SET( rxbitfield, status ) \
+do { \
+    (rxbitfield) &= ~STATUS_MASK; \
+    (rxbitfield) |= (((status) << 31) & STATUS_MASK); \
+} while(0)
+
+/** Mask to acess the rxBitField port */
+#define PORT_MASK       0x7f000000
+
+/** return the rxBitField port */
+#define IX_NPE_A_RXBITFIELD_PORT_GET( rxbitfield ) \
+(((rxbitfield) & PORT_MASK) >> 24)
+
+/** set the rxBitField port */
+#define IX_NPE_A_RXBITFIELD_PORT_SET( rxbitfield, port ) \
+do { \
+    (rxbitfield) &= ~PORT_MASK; \
+    (rxbitfield) |= (((port) << 24) & PORT_MASK); \
+} while(0)
+
+/** Mask to acess the rxBitField vcId */
+#define VCID_MASK       0x00ff0000
+
+/** return the rxBitField vcId */
+#define IX_NPE_A_RXBITFIELD_VCID_GET( rxbitfield ) \
+(((rxbitfield) & VCID_MASK) >> 16)
+
+/** set the rxBitField vcId */
+#define IX_NPE_A_RXBITFIELD_VCID_SET( rxbitfield, vcid ) \
+do { \
+    (rxbitfield) &= ~VCID_MASK; \
+    (rxbitfield) |= (((vcid) << 16) & VCID_MASK); \
+} while(0)
+
+/** Mask to acess the rxBitField mbuf size */
+#define CURRMBUFSIZE_MASK       0x0000ffff
+
+/** return the rxBitField mbuf size */
+#define IX_NPE_A_RXBITFIELD_CURRMBUFSIZE_GET( rxbitfield ) \
+((rxbitfield) & CURRMBUFSIZE_MASK)
+
+/** set the rxBitField mbuf size */
+#define IX_NPE_A_RXBITFIELD_CURRMBUFSIZE_SET( rxbitfield, currmbufsize ) \
+do { \
+    (rxbitfield) &= ~CURRMBUFSIZE_MASK; \
+    (rxbitfield) |= ((currmbufsize) & CURRMBUFSIZE_MASK); \
+} while(0)
+
+
+
+/**
+ * @brief Tx Descriptor definition
+ */
+typedef struct
+{
+    UINT8 port;				/**< Tx Port number */
+    UINT8 aalType; 			/**< AAL Type */
+    UINT16 currMbufLen;			/**< mbuf length */
+    UINT32 atmCellHeader;		/**< ATM cell header */
+    IX_OSAL_MBUF *pCurrMbuf;	        /**< pointer to mbuf */
+    unsigned char *pCurrMbufData;	/**< Pointer to mbuf->dat */
+    IX_OSAL_MBUF *pNextMbuf;		/**< Pointer to next mbuf */
+    UINT32  totalLen;			/**< Total Length */
+    UINT32  aal5CrcResidue;		/**< AAL5 CRC Residue */
+} IxNpeA_TxAtmVc;
+
+/* Changes to field sizes or orders must be reflected in the offset
+ * definitions above. */
+
+
+
+
+/**
+ * @brief Rx Descriptor definition
+ */
+typedef struct
+{
+    UINT32  rxBitField;			/**< Received bit field */
+    UINT32  atmCellHeader;		/**< ATM Cell Header */
+    UINT32  rsvdWord0;                  /**< Reserved field */
+    UINT16  currMbufLen;		/**< Mbuf Length */
+    UINT8   timeLimit; 			/**< Payload Reassembly timeLimit (used for aal0_xx only) */
+    UINT8   rsvdByte0;                  /**< Reserved field */ 
+    UINT32  rsvdWord1;   		/**< Reserved field */
+    IX_OSAL_MBUF *pCurrMbuf;		/**< Pointer to current mbuf */
+    unsigned char *pCurrMbufData;	/**< Pointer to current mbuf->data */
+    IX_OSAL_MBUF *pNextMbuf;		/**< Pointer to next mbuf */
+    UINT32  totalLen;			/**< Total Length */
+    UINT32  aal5CrcResidue;		/**< AAL5 CRC Residue */
+} IxNpeA_RxAtmVc;
+
+
+/**
+ * @brief NPE-A AAL Type
+ */
+typedef enum
+{
+    IX_NPE_A_AAL_TYPE_INVALID = 0,	/**< Invalid AAL type */
+    IX_NPE_A_AAL_TYPE_0_48    = 0x1,	/**< AAL0 - 48 byte */
+    IX_NPE_A_AAL_TYPE_0_52    = 0x2,	/**< AAL0 - 52 byte */
+    IX_NPE_A_AAL_TYPE_5       = 0x5,	/**< AAL5 */
+    IX_NPE_A_AAL_TYPE_OAM     = 0xF	/**< OAM */
+} IxNpeA_AalType;
+
+/**
+ * @brief NPE-A Payload format 52-bytes & 48-bytes
+ */
+typedef enum
+{
+    IX_NPE_A_52_BYTE_PAYLOAD = 0,	/**< 52 byte payload */
+    IX_NPE_A_48_BYTE_PAYLOAD		/**< 48 byte payload */
+} IxNpeA_PayloadFormat;
+
+/**
+ * @brief  HSS Packetized NpePacket Descriptor Structure
+ */
+typedef struct
+{
+    UINT8   status;		/**< Status of the packet passed to the client */
+    UINT8   errorCount;		/**< Number of errors */
+    UINT8   chainCount;		/**< Mbuf chain count e.g. 0 - No mbuf chain */
+    UINT8   rsvdByte0;		/**< Reserved byte to make the descriptor word align */
+
+    UINT16  packetLength;	/**< Packet Length */
+    UINT16  rsvdShort0;		/**< Reserved short to make the descriptor a word align */
+
+    IX_OSAL_MBUF *pRootMbuf;	/**< Pointer to Root mbuf */
+    IX_OSAL_MBUF *pNextMbuf;	/**< Pointer to next mbuf */
+    UINT8   *pMbufData;		/**< Pointer to the current mbuf->data */
+    UINT32  mbufLength;		/**< Current mbuf length */
+
+} IxNpeA_NpePacketDescriptor;
+
+
+#endif
+/**
+ *@}
+ */
+
+#endif /* __doxygen_HIDE */
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeDl.h b/marvell/uboot/drivers/net/npe/include/IxNpeDl.h
new file mode 100644
index 0000000..f87ee4b
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeDl.h
@@ -0,0 +1,956 @@
+/**
+ * @file IxNpeDl.h
+ *
+ * @date 14 December 2001
+
+ * @brief This file contains the public API of the IXP400 NPE Downloader
+ *        component.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeDl IXP400 NPE-Downloader (IxNpeDl) API
+ *
+ * @brief The Public API for the IXP400 NPE Downloader
+ *
+ * @{
+ */
+
+#ifndef IXNPEDL_H
+#define IXNPEDL_H
+
+/*
+ * Put the user defined include files required
+ */
+#include "IxOsalTypes.h"
+#include "IxNpeMicrocode.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/**
+ * @def IX_NPEDL_PARAM_ERR
+ *
+ * @brief NpeDl function return value for a parameter error
+ */
+#define IX_NPEDL_PARAM_ERR               2
+
+/**
+ * @def IX_NPEDL_RESOURCE_ERR
+ *
+ * @brief NpeDl function return value for a resource error
+ */
+#define IX_NPEDL_RESOURCE_ERR            3
+
+/**
+ * @def IX_NPEDL_CRITICAL_NPE_ERR
+ *
+ * @brief NpeDl function return value for a Critical NPE error occuring during
+          download. Assume NPE is left in unstable condition if this value is
+          returned or NPE is hang / halt.
+ */
+#define IX_NPEDL_CRITICAL_NPE_ERR        4
+
+/**
+ * @def IX_NPEDL_CRITICAL_MICROCODE_ERR
+ *
+ * @brief NpeDl function return value for a Critical Microcode error
+ *        discovered during download. Assume NPE is left in unstable condition
+ *        if this value is returned.
+ */
+#define IX_NPEDL_CRITICAL_MICROCODE_ERR  5
+
+/**
+ * @def IX_NPEDL_DEVICE_ERR
+ *
+ * @brief NpeDl function return value when image being downloaded
+ *        is not meant for the device in use
+ */
+#define IX_NPEDL_DEVICE_ERR 6 
+
+/**
+ * @defgroup NPEImageID IXP400 NPE Image ID Definition
+ *
+ * @ingroup IxNpeDl
+ *
+ * @brief Definition of NPE Image ID to be passed to ixNpeDlNpeInitAndStart()
+ *        as input of type UINT32 which has the following fields format:
+ *
+ *               Field [Bit Location] <BR>
+ *               -------------------- <BR>
+ *               Device ID [31 - 28] <BR>
+ *               NPE ID [27 - 24] <BR>
+ *               NPE Functionality ID [23 - 16] <BR>
+ *               Major Release Number [15 -  8] <BR>
+ *               Minor Release Number [7 - 0] <BR>
+ *
+ *
+ * @{
+ */
+
+/**
+ * @def IX_NPEDL_NPEIMAGE_FIELD_MASK
+ *
+ * @brief Mask for NPE Image ID's Field
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IX_NPEDL_NPEIMAGE_FIELD_MASK  0xff
+
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEID_MASK
+ *
+ * @brief Mask for NPE Image NPE ID's Field
+ *
+ */
+#define IX_NPEDL_NPEIMAGE_NPEID_MASK  0xf
+
+/**
+ * @def IX_NPEDL_NPEIMAGE_DEVICEID_MASK
+ *
+ * @brief Mask for NPE Image Device ID's Field
+ *
+ */
+#define IX_NPEDL_NPEIMAGE_DEVICEID_MASK  0xf
+
+/**
+ * @def IX_NPEDL_NPEIMAGE_BIT_LOC_NPEID
+ *
+ * @brief Location of NPE ID field in term of bit.
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IX_NPEDL_NPEIMAGE_BIT_LOC_NPEID  24
+
+/**
+ * @def IX_NPEDL_NPEIMAGE_BIT_LOC_FUNCTIONALITYID
+ *
+ * @brief Location of Functionality ID field in term of bit.
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IX_NPEDL_NPEIMAGE_BIT_LOC_FUNCTIONALITYID  16
+
+/**
+ * @def IX_NPEDL_NPEIMAGE_BIT_LOC_MAJOR
+ *
+ * @brief Location of Major Release Number field in term of bit.
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IX_NPEDL_NPEIMAGE_BIT_LOC_MAJOR  8
+
+/**
+ * @def IX_NPEDL_NPEIMAGE_BIT_LOC_MINOR
+ *
+ * @brief Location of Minor Release Number field in term of bit.
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IX_NPEDL_NPEIMAGE_BIT_LOC_MINOR  0
+
+/**
+ * @} addtogroup NPEImageID
+ */
+
+/**
+ * @def ixNpeDlMicrocodeImageOverride(x)
+ *
+ * @brief  Map old terminology that uses term "image" to new term
+ *        "image library"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define ixNpeDlMicrocodeImageOverride(x) ixNpeDlMicrocodeImageLibraryOverride(x)
+
+/**
+ * @def IxNpeDlVersionId
+ *
+ * @brief  Map old terminology that uses term "version" to new term
+ *        "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IxNpeDlVersionId IxNpeDlImageId
+
+/**
+ * @def ixNpeDlVersionDownload
+ *
+ * @brief  Map old terminology that uses term "version" to new term
+ *        "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define ixNpeDlVersionDownload(x,y) ixNpeDlImageDownload(x,y)
+
+/**
+ * @def ixNpeDlAvailableVersionsCountGet
+ *
+ * @brief  Map old terminology that uses term "version" to new term
+ *        "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define ixNpeDlAvailableVersionsCountGet(x) ixNpeDlAvailableImagesCountGet(x)
+
+/**
+ * @def ixNpeDlAvailableVersionsListGet
+ *
+ * @brief  Map old terminology that uses term "version" to new term
+ *        "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define ixNpeDlAvailableVersionsListGet(x,y) ixNpeDlAvailableImagesListGet(x,y)
+
+ /**
+ * @def ixNpeDlLoadedVersionGet
+ *
+ * @brief  Map old terminology that uses term "version" to new term
+ *        "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define ixNpeDlLoadedVersionGet(x,y) ixNpeDlLoadedImageGet(x,y)
+
+ /**
+ * @def clientImage
+ *
+ * @brief  Map old terminology that uses term "image" to new term
+ *        "image library"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define clientImage clientImageLibrary
+
+ /**
+ * @def versionIdPtr
+ *
+ * @brief  Map old terminology that uses term "version" to new term
+ *        "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define versionIdPtr imageIdPtr
+
+ /**
+ * @def numVersionsPtr
+ *
+ * @brief  Map old terminology that uses term "version" to new term
+ *        "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define numVersionsPtr numImagesPtr
+
+/**
+ * @def versionIdListPtr
+ *
+ * @brief  Map old terminology that uses term "version" to new term
+ *        "image"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define versionIdListPtr imageIdListPtr
+
+/**
+ * @def IxNpeDlBuildId
+ *
+ * @brief  Map old terminology that uses term "buildId" to new term
+ *        "functionalityId"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IxNpeDlBuildId IxNpeDlFunctionalityId
+
+/**
+ * @def buildId
+ *
+ * @brief  Map old terminology that uses term "buildId" to new term
+ *        "functionalityId"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define buildId functionalityId
+
+/**
+ * @def IX_NPEDL_MicrocodeImage
+ *
+ * @brief  Map old terminology that uses term "image" to new term
+ *        "image library"
+ *
+ * @warning <b>THIS #define HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+#define IX_NPEDL_MicrocodeImage IX_NPEDL_MicrocodeImageLibrary
+
+/*
+ * Typedefs
+ */
+
+/**
+ * @typedef IxNpeDlFunctionalityId
+ * @brief Used to make up Functionality ID field of Image Id
+ *
+ * @warning <b>THIS typedef HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+typedef UINT8 IxNpeDlFunctionalityId;
+
+/**
+ * @typedef IxNpeDlMajor
+ * @brief Used to make up Major Release field of Image Id
+ *
+ * @warning <b>THIS typedef HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+typedef UINT8 IxNpeDlMajor;
+
+/**
+ * @typedef IxNpeDlMinor
+ * @brief Used to make up Minor Revision field of Image Id
+ *
+ * @warning <b>THIS typedef HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+typedef UINT8 IxNpeDlMinor;
+
+/*
+ * Enums
+ */
+
+/**
+ * @brief NpeId numbers to identify NPE A, B or C
+ * @note In this context, for IXP425 Silicon (B0):<br>
+ *      - NPE-A has HDLC, HSS, AAL and UTOPIA Coprocessors.<br>
+ *      - NPE-B has Ethernet Coprocessor.<br>
+ *      - NPE-C has Ethernet, AES, DES and HASH Coprocessors.<br>
+ *      - IXP400 Product Line have different combinations of coprocessors.
+ */
+typedef enum
+{
+  IX_NPEDL_NPEID_NPEA = 0,    /**< Identifies NPE A */
+  IX_NPEDL_NPEID_NPEB,        /**< Identifies NPE B */
+  IX_NPEDL_NPEID_NPEC,        /**< Identifies NPE C */
+  IX_NPEDL_NPEID_MAX          /**< Total Number of NPEs */
+} IxNpeDlNpeId;
+
+/*
+ * Structs
+ */
+
+/**
+ * @brief Image Id to identify each image contained in an image library
+ *
+ * @warning <b>THIS struct HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart for more information.
+ */
+typedef struct
+{
+    IxNpeDlNpeId   npeId;   /**< NPE ID */
+    IxNpeDlFunctionalityId functionalityId; /**< Build ID indicates functionality of image */
+    IxNpeDlMajor   major;   /**< Major Release Number */
+    IxNpeDlMinor   minor;   /**< Minor Revision Number */
+} IxNpeDlImageId;
+
+/*
+ * Prototypes for interface functions
+ */
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlNpeInitAndStart (UINT32 imageId)
+ *
+ * @brief Stop, reset, download microcode (firmware) and finally start NPE.
+ *
+ * @param imageId UINT32 [in] - Id of the microcode image to download.
+ *
+ * This function locates the image specified by the <i>imageId</i> parameter
+ * from the default microcode image library which is included internally by
+ * this component.
+ * It then stops and resets the NPE, loads the firmware image onto the NPE,
+ * and then restarts the NPE.
+ *
+ * @note A list of valid image IDs is included in this header file.
+ *       See #defines with prefix IX_NPEDL_NPEIMAGE_...
+ *
+ * @note This function, along with @ref ixNpeDlCustomImageNpeInitAndStart
+ *       and @ref ixNpeDlLoadedImageFunctionalityGet, supercedes the following
+ *       functions which are deprecated and will be removed completely in a
+ *       future release:
+ *       - @ref ixNpeDlImageDownload
+ *       - @ref ixNpeDlAvailableImagesCountGet
+ *       - @ref ixNpeDlAvailableImagesListGet
+ *       - @ref ixNpeDlLatestImageGet
+ *       - @ref ixNpeDlLoadedImageGet
+ *       - @ref ixNpeDlMicrocodeImageLibraryOverride
+ *       - @ref ixNpeDlNpeExecutionStop
+ *       - @ref ixNpeDlNpeStopAndReset
+ *       - @ref ixNpeDlNpeExecutionStart
+ *
+ * @pre
+ *         - The Client is responsible for ensuring mutual access to the NPE.
+ * @post
+ *         - The NPE Instruction Pipeline will be cleared if State Information
+ *           has been downloaded.
+ *         - If the download fails with a critical error, the NPE may
+ *           be left in an ususable state.
+ * @return
+ *         - IX_SUCCESS if the download was successful;
+ *         - IX_NPEDL_PARAM_ERR if a parameter error occured
+ *         - IX_NPEDL_CRITICAL_NPE_ERR if a critical NPE error occured during
+ *           download
+ *         - IX_NPEDL_CRITICAL_MICROCODE_ERR if a critical microcode error
+ *           occured during download
+ *         - IX_NPEDL_DEVICE_ERR if the image being loaded is not meant for 
+ *           the device currently running.
+ *         - IX_FAIL if NPE is not available or image is failed to be located.
+ *           A warning is issued if the NPE is not present.
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeInitAndStart (UINT32 npeImageId);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlCustomImageNpeInitAndStart (UINT32 *imageLibrary,
+                                                           UINT32 imageId)
+ *
+ * @brief Stop, reset, download microcode (firmware) and finally start NPE
+ *
+ * @param imageId UINT32 [in] - Id of the microcode image to download.
+ *
+ * This function locates the image specified by the <i>imageId</i> parameter
+ * from the specified microcode image library which is pointed to by the
+ * <i>imageLibrary</i> parameter.
+ * It then stops and resets the NPE, loads the firmware image onto the NPE,
+ * and then restarts the NPE.
+ *
+ * This is a facility for users who wish to use an image from an external
+ * library of NPE firmware images.  To use a standard image from the
+ * built-in library, see @ref ixNpeDlNpeInitAndStart instead.
+ *
+ * @note A list of valid image IDs is included in this header file.
+ *       See #defines with prefix IX_NPEDL_NPEIMAGE_...
+ *
+ * @note This function, along with @ref ixNpeDlNpeInitAndStart
+ *       and @ref ixNpeDlLoadedImageFunctionalityGet, supercedes the following
+ *       functions which are deprecated and will be removed completely in a
+ *       future release:
+ *       - @ref ixNpeDlImageDownload
+ *       - @ref ixNpeDlAvailableImagesCountGet
+ *       - @ref ixNpeDlAvailableImagesListGet
+ *       - @ref ixNpeDlLatestImageGet
+ *       - @ref ixNpeDlLoadedImageGet
+ *       - @ref ixNpeDlMicrocodeImageLibraryOverride
+ *       - @ref ixNpeDlNpeExecutionStop
+ *       - @ref ixNpeDlNpeStopAndReset
+ *       - @ref ixNpeDlNpeExecutionStart
+ *
+ * @pre
+ *         - The Client is responsible for ensuring mutual access to the NPE.
+ *         - The image library supplied must be in the correct format for use
+ *           by the NPE Downloader (IxNpeDl) component.  Details of the library
+ *           format are contained in the Functional Specification document for
+ *           IxNpeDl.
+ * @post
+ *         - The NPE Instruction Pipeline will be cleared if State Information
+ *           has been downloaded.
+ *         - If the download fails with a critical error, the NPE may
+ *           be left in an ususable state.
+ * @return
+ *         - IX_SUCCESS if the download was successful;
+ *         - IX_NPEDL_PARAM_ERR if a parameter error occured
+ *         - IX_NPEDL_CRITICAL_NPE_ERR if a critical NPE error occured during
+ *           download
+ *         - IX_NPEDL_CRITICAL_MICROCODE_ERR if a critical microcode error
+ *           occured during download
+ *         - IX_NPEDL_DEVICE_ERR if the image being loaded is not meant for 
+ *           the device currently running.
+ *         - IX_FAIL if NPE is not available or image is failed to be located.
+ *           A warning is issued if the NPE is not present.
+ */
+PUBLIC IX_STATUS
+ixNpeDlCustomImageNpeInitAndStart (UINT32 *imageLibrary,
+                    UINT32 npeImageId);
+
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlLoadedImageFunctionalityGet (IxNpeDlNpeId npeId,
+                                                        UINT8 *functionalityId)
+ *
+ * @brief Gets the functionality of the image last loaded on a particular NPE
+ *
+ * @param npeId  @ref IxNpeDlNpeId [in]      - Id of the target NPE.
+ * @param functionalityId UINT8* [out] - the functionality ID of the image
+ *                                       last loaded on the NPE.
+ *
+ * This function retrieves the functionality ID of the image most recently
+ * downloaded successfully to the specified NPE.  If the NPE does not contain
+ * a valid image, this function returns a FAIL status.
+ *
+ * @warning This function is not intended for general use, as a knowledge of
+ * how to interpret the functionality ID is required.  As such, this function
+ * should only be used by other Access Layer components of the IXP400 Software
+ * Release.
+ *
+ * @pre
+ *
+ * @post
+ *
+ * @return
+ *     -  IX_SUCCESS if the operation was successful
+ *     -  IX_NPEDL_PARAM_ERR if a parameter error occured
+ *     -  IX_FAIL if the NPE does not have a valid image loaded
+ */
+PUBLIC IX_STATUS
+ixNpeDlLoadedImageFunctionalityGet (IxNpeDlNpeId npeId,
+                                    UINT8 *functionalityId);
+
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn IX_STATUS ixNpeDlMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary)
+ *
+ * @brief This instructs NPE Downloader to use client-supplied microcode image library.
+ *
+ * @param clientImageLibrary UINT32* [in]  - Pointer to the client-supplied
+ *                                   NPE microcode image library
+ *
+ * This function sets NPE Downloader to use a client-supplied microcode image library
+ * instead of the standard image library which is included by the NPE Downloader.
+ * <b>This function is provided mainly for increased testability and should not
+ * be used in normal circumstances.</b> When not used, NPE Downloader will use
+ * a "built-in" image library, local to this component, which should always contain the
+ * latest microcode for the NPEs.
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @pre
+ *      - <i>clientImageLibrary</i> should point to a microcode image library valid for use
+ *        by the NPE Downloader component.
+ *
+ * @post
+ *      - the client-supplied image library will be used for all subsequent operations
+ *        performed by the NPE Downloader
+ *
+ * @return
+ *      - IX_SUCCESS if the operation was successful
+ *      - IX_NPEDL_PARAM_ERR if a parameter error occured
+ *      - IX_FAIL if the client-supplied image library did not contain a valid signature
+ */
+PUBLIC IX_STATUS
+ixNpeDlMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlImageDownload (IxNpeDlImageId *imageIdPtr,
+                                                BOOL verify)
+ *
+ * @brief Stop, reset, download microcode and finally start NPE.
+ *
+ * @param imageIdPtr @ref IxNpeDlImageId* [in] - Pointer to Id of the microcode
+ *                                              image to download.
+ * @param verify BOOL [in]     - ON/OFF option to verify the download. If ON
+ *                               (verify == true), the Downloader will read back
+ *                               each word written to the NPE registers to
+ *                               ensure the download operation was successful.
+ *
+ * Using the <i>imageIdPtr</i>, this function locates a particular image of
+ * microcode in the microcode image library in memory, and downloads the microcode
+ * to a particular NPE.
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @pre
+ *         - The Client is responsible for ensuring mutual access to the NPE.
+ *       - The Client should use ixNpeDlLatestImageGet() to obtain the latest
+ *         version of the image before attempting download.
+ * @post
+ *         - The NPE Instruction Pipeline will be cleared if State Information
+ *           has been downloaded.
+ *         - If the download fails with a critical error, the NPE may
+ *           be left in an ususable state.
+ * @return
+ *         - IX_SUCCESS if the download was successful;
+ *         - IX_NPEDL_PARAM_ERR if a parameter error occured
+ *         - IX_NPEDL_CRITICAL_NPE_ERR if a critical NPE error occured during
+ *           download
+ *         - IX_PARAM_CRITICAL_MICROCODE_ERR if a critical microcode error
+ *           occured during download
+ *         - IX_FAIL if NPE is not available or image is failed to be located.
+ *           A warning is issued if the NPE is not present.
+ */
+PUBLIC IX_STATUS
+ixNpeDlImageDownload (IxNpeDlImageId *imageIdPtr,
+            BOOL verify);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlAvailableImagesCountGet (UINT32 *numImagesPtr)
+ *
+ * @brief Get the number of Images available in a microcode image library
+ *
+ * @param numImagesPtr UINT32* [out] - A pointer to the number of images in
+ *                                       the image library.
+ *
+ * Gets the number of images available in the microcode image library.
+ * Then returns this in a variable pointed to by <i>numImagesPtr</i>.
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @pre
+ *     - The Client should declare the variable to which numImagesPtr points
+ *
+ * @post
+ *
+ * @return
+ *     - IX_SUCCESS if the operation was successful
+ *     - IX_NPEDL_PARAM_ERR if a parameter error occured
+ *     - IX_FAIL otherwise
+ */
+PUBLIC IX_STATUS
+ixNpeDlAvailableImagesCountGet (UINT32 *numImagesPtr);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlAvailableImagesListGet (IxNpeDlImageId *imageIdListPtr,
+                                                         UINT32 *listSizePtr)
+ *
+ * @brief Get a list of the images available in a microcode image library
+ *
+ * @param imageIdListPtr @ref IxNpeDlImageId* [out] - Array to contain list of
+ *                                                   image Ids (memory
+ *                                                   allocated by Client).
+ * @param listSizePtr UINT32* [inout]  - As an input, this param should point
+ *                                       to the max number of Ids the
+ *                                       <i>imageIdListPtr</i> array can
+ *                                       hold. NpeDl will replace the input
+ *                                       value of this parameter with the
+ *                                       number of image Ids actually filled
+ *                                       into the array before returning.
+ *
+ * Finds list of images available in the microcode image library.
+ * Fills these into the array pointed to by <i>imageIdListPtr</i>
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @pre
+ *     - The Client should declare the variable to which numImagesPtr points
+ *     - The Client should create an array (<i>imageIdListPtr</i>) large
+ *       enough to contain all the image Ids in the image library
+ *
+ * @post
+ *
+ * @return
+ *     - IX_SUCCESS if the operation was successful
+ *     - IX_NPEDL_PARAM_ERR if a parameter error occured
+ *     - IX_FAIL otherwise
+ */
+PUBLIC IX_STATUS
+ixNpeDlAvailableImagesListGet (IxNpeDlImageId *imageIdListPtr,
+                 UINT32 *listSizePtr);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlLoadedImageGet (IxNpeDlNpeId npeId,
+                                                IxNpeDlImageId *imageIdPtr)
+ *
+ * @brief Gets the Id of the image currently loaded on a particular NPE
+ *
+ * @param npeId @ref IxNpeDlNpeId [in]              - Id of the target NPE.
+ * @param imageIdPtr @ref IxNpeDlImageId* [out]     - Pointer to the where the
+ *                                               image id should be stored.
+ *
+ * If an image of microcode was previously downloaded successfully to the NPE
+ * by NPE Downloader, this function returns in <i>imageIdPtr</i> the image
+ * Id of that image loaded on the NPE.
+ *
+ * @pre
+ *     - The Client has allocated memory to the <i>imageIdPtr</i> pointer.
+ *
+ * @post
+ *
+ * @return
+ *     -  IX_SUCCESS if the operation was successful
+ *     -  IX_NPEDL_PARAM_ERR if a parameter error occured
+ *     -  IX_FAIL if the NPE doesn't currently have a image loaded
+ */
+PUBLIC IX_STATUS
+ixNpeDlLoadedImageGet (IxNpeDlNpeId npeId,
+             IxNpeDlImageId *imageIdPtr);
+
+/**
+ * @fn PUBLIC IX_STATUS ixNpeDlLatestImageGet (IxNpeDlNpeId npeId, IxNpeDlFunctionalityId
+                                        functionalityId, IxNpeDlImageId *imageIdPtr)
+ *
+ * @brief This instructs NPE Downloader to get Id of the latest version for an
+ * image that is specified by the client.
+ *
+ * @param npeId @ref IxNpeDlNpeId [in]                    - Id of the target NPE.
+ * @param functionalityId @ref IxNpeDlFunctionalityId [in]    - functionality of the image
+ * @param imageIdPtr @ref IxNpeDlImageId* [out]               - Pointer to the where the
+ *                                                         image id should be stored.
+ *
+ * This function sets NPE Downloader to return the id of the latest version for
+ * image.  The user will select the image by providing a particular NPE
+ * (specifying <i>npeId</i>) with particular functionality (specifying
+ * <i>FunctionalityId</i>). The most recent version available as determined by the
+ * highest Major and Minor revision numbers is returned in <i>imageIdPtr</i>.
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @return
+ *      - IX_SUCCESS if the operation was successful
+ *      - IX_NPEDL_PARAM_ERR if a parameter error occured
+ *      - IX_FAIL otherwise
+ */
+PUBLIC IX_STATUS
+ixNpeDlLatestImageGet (IxNpeDlNpeId npeId,
+             IxNpeDlFunctionalityId functionalityId,
+                    IxNpeDlImageId *imageIdPtr);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlNpeStopAndReset (IxNpeDlNpeId npeId)
+ *
+ * @brief Stops and Resets an NPE
+ *
+ * @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE.
+ *
+ * This function performs a soft NPE reset by writing reset values to
+ * particular NPE registers. Note that this does not reset NPE co-processors.
+ * This implicitly stops NPE code execution before resetting the NPE.
+ *
+ * @note It is no longer necessary to call this function before downloading
+ * a new image to the NPE.  It is left on the API only to allow greater control
+ * of NPE execution if required.  Where appropriate, use @ref ixNpeDlNpeInitAndStart
+ * or @ref ixNpeDlCustomImageNpeInitAndStart instead.
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @pre
+ *     - The Client is responsible for ensuring mutual access to the NPE.
+ *
+ * @post
+ *
+ * @return
+ *      - IX_SUCCESS if the operation was successful
+ *      - IX_NPEDL_PARAM_ERR if a parameter error occured
+ *      - IX_FAIL otherwise
+ *      - IX_NPEDL_CRITICAL_NPE_ERR failed to reset NPE due to timeout error. 
+ *        Timeout error could happen if NPE hang
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeStopAndReset (IxNpeDlNpeId npeId);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlNpeExecutionStart (IxNpeDlNpeId npeId)
+ *
+ * @brief Starts code execution on a NPE
+ *
+ * @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE
+ *
+ * Starts execution of code on a particular NPE.  A client would typically use
+ * this after a download to NPE is performed, to start/restart code execution
+ * on the NPE.
+ *
+ * @note It is no longer necessary to call this function after downloading
+ * a new image to the NPE.  It is left on the API only to allow greater control
+ * of NPE execution if required.  Where appropriate, use @ref ixNpeDlNpeInitAndStart
+ * or @ref ixNpeDlCustomImageNpeInitAndStart instead.
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @pre
+ *     - The Client is responsible for ensuring mutual access to the NPE.
+ *     - Note that this function does not set the NPE Next Program Counter
+ *       (NextPC), so it should be set beforehand if required by downloading
+ *       appropriate State Information (using ixNpeDlVersionDownload()).
+ *
+ * @post
+ *
+ * @return
+ *      - IX_SUCCESS if the operation was successful
+ *      - IX_NPEDL_PARAM_ERR if a parameter error occured
+ *      - IX_FAIL otherwise
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeExecutionStart (IxNpeDlNpeId npeId);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlNpeExecutionStop (IxNpeDlNpeId npeId)
+ *
+ * @brief Stops code execution on a NPE
+ *
+ * @param npeId @ref IxNpeDlNpeId [in] - Id of the target NPE
+ *
+ * Stops execution of code on a particular NPE.  This would typically be used
+ * by a client before a download to NPE is performed, to stop code execution on
+ * an NPE, unless ixNpeDlNpeStopAndReset() is used instead.  Unlike
+ * ixNpeDlNpeStopAndReset(), this function only halts the NPE and leaves
+ * all registers and settings intact. This is useful, for example, between
+ * stages of a multi-stage download, to stop the NPE prior to downloading the
+ * next image while leaving the current state of the NPE intact..
+ *
+ * @warning <b>THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.</b>
+ *       It will be removed in a future release.
+ *       See @ref ixNpeDlNpeInitAndStart and @ref ixNpeDlCustomImageNpeInitAndStart.
+ *
+ * @pre
+ *     - The Client is responsible for ensuring mutual access to the NPE.
+ *
+ * @post
+ *
+ * @return
+ *      - IX_SUCCESS if the operation was successful
+ *      - IX_NPEDL_PARAM_ERR if a parameter error occured
+ *      - IX_FAIL otherwise
+ */
+PUBLIC IX_STATUS
+ixNpeDlNpeExecutionStop (IxNpeDlNpeId npeId);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC IX_STATUS ixNpeDlUnload (void)
+ *
+ * @brief This function will uninitialise the IxNpeDl component.
+ *
+ * This function will uninitialise the IxNpeDl component.  It should only be
+ * called once, and only if the IxNpeDl component has already been initialised by
+ * calling any of the following functions:
+ * - @ref ixNpeDlNpeInitAndStart
+ * - @ref ixNpeDlCustomImageNpeInitAndStart
+ * - @ref ixNpeDlImageDownload     (deprecated)
+ * - @ref ixNpeDlNpeStopAndReset   (deprecated)
+ * - @ref ixNpeDlNpeExecutionStop  (deprecated)
+ * - @ref ixNpeDlNpeExecutionStart (deprecated)
+ *
+ * If possible, this function should be called before a soft reboot or unloading
+ * a kernel module to perform any clean up operations required for IxNpeDl.
+ *
+ * The following actions will be performed by this function:
+ * - Unmapping of any kernel memory mapped by IxNpeDl
+ *
+ * @return
+ *      - IX_SUCCESS if the operation was successful
+ *      - IX_FAIL otherwise
+ */
+
+PUBLIC IX_STATUS 
+ixNpeDlUnload (void);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC void ixNpeDlStatsShow (void)
+ *
+ * @brief This function will display run-time statistics from the IxNpeDl
+ *        component
+ *
+ * @return none
+ */
+PUBLIC void
+ixNpeDlStatsShow (void);
+
+/**
+ * @ingroup IxNpeDl
+ *
+ * @fn PUBLIC void ixNpeDlStatsReset (void)
+ *
+ * @brief This function will reset the statistics of the IxNpeDl component
+ *
+ * @return none
+ */
+PUBLIC void
+ixNpeDlStatsReset (void);
+
+#endif /* IXNPEDL_H */
+
+/**
+ * @} defgroup IxNpeDl
+ */
+
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeDlImageMgr_p.h b/marvell/uboot/drivers/net/npe/include/IxNpeDlImageMgr_p.h
new file mode 100644
index 0000000..34dd3a4
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeDlImageMgr_p.h
@@ -0,0 +1,339 @@
+/**
+ * @file IxNpeDlImageMgr_p.h
+ *
+ * @author Intel Corporation
+ * @date 14 December 2001
+
+ * @brief This file contains the private API for the ImageMgr module
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeDlImageMgr_p IxNpeDlImageMgr_p
+ *
+ * @brief The private API for the IxNpeDl ImageMgr module
+ * 
+ * @{
+ */
+
+#ifndef IXNPEDLIMAGEMGR_P_H
+#define IXNPEDLIMAGEMGR_P_H
+
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxNpeDl.h"
+#include "IxOsalTypes.h"
+
+
+/*
+ * #defines and macros
+ */
+
+/**
+ * @def IX_NPEDL_IMAGEMGR_SIGNATURE
+ *
+ * @brief Signature found as 1st word in a microcode image library
+ */
+#define IX_NPEDL_IMAGEMGR_SIGNATURE      0xDEADBEEF
+
+/**
+ * @def IX_NPEDL_IMAGEMGR_END_OF_HEADER
+ *
+ * @brief Marks end of header in a microcode image library
+ */
+#define IX_NPEDL_IMAGEMGR_END_OF_HEADER  0xFFFFFFFF
+
+/**
+ * @def IX_NPEDL_IMAGEID_NPEID_OFFSET
+ *
+ * @brief Offset from LSB of NPE ID field in Image ID
+ */
+#define IX_NPEDL_IMAGEID_NPEID_OFFSET      24
+
+/**
+ * @def IX_NPEDL_IMAGEID_DEVICEID_OFFSET
+ *
+ * @brief Offset from LSB of Device ID field in Image ID
+ */
+#define IX_NPEDL_IMAGEID_DEVICEID_OFFSET   28
+
+/**
+ * @def IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET
+ *
+ * @brief Offset from LSB of Functionality ID field in Image ID
+ */
+#define IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET 16
+
+/**
+ * @def IX_NPEDL_IMAGEID_MAJOR_OFFSET
+ *
+ * @brief Offset from LSB of Major revision field in Image ID
+ */
+#define IX_NPEDL_IMAGEID_MAJOR_OFFSET      8
+
+/**
+ * @def IX_NPEDL_IMAGEID_MINOR_OFFSET
+ *
+ * @brief Offset from LSB of Minor revision field in Image ID
+ */
+#define IX_NPEDL_IMAGEID_MINOR_OFFSET      0
+
+
+/**
+ * @def IX_NPEDL_NPEID_FROM_IMAGEID_GET
+ *
+ * @brief Macro to extract NPE ID field from Image ID
+ */
+#define IX_NPEDL_NPEID_FROM_IMAGEID_GET(imageId) \
+    (((imageId) >> IX_NPEDL_IMAGEID_NPEID_OFFSET) & \
+     IX_NPEDL_NPEIMAGE_NPEID_MASK)
+
+/**
+ * @def IX_NPEDL_DEVICEID_FROM_IMAGEID_GET
+ *
+ * @brief Macro to extract NPE ID field from Image ID
+ */
+#define IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId) \
+    (((imageId) >> IX_NPEDL_IMAGEID_DEVICEID_OFFSET) & \
+     IX_NPEDL_NPEIMAGE_DEVICEID_MASK)
+
+/**
+ * @def IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET
+ *
+ * @brief Macro to extract Functionality ID field from Image ID
+ */
+#define IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId) \
+    (((imageId) >> IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET) & \
+     IX_NPEDL_NPEIMAGE_FIELD_MASK)
+
+/**
+ * @def IX_NPEDL_MAJOR_FROM_IMAGEID_GET
+ *
+ * @brief Macro to extract Major revision field from Image ID
+ */
+#define IX_NPEDL_MAJOR_FROM_IMAGEID_GET(imageId) \
+    (((imageId) >> IX_NPEDL_IMAGEID_MAJOR_OFFSET) & \
+     IX_NPEDL_NPEIMAGE_FIELD_MASK)
+
+/**
+ * @def IX_NPEDL_MINOR_FROM_IMAGEID_GET
+ *
+ * @brief Macro to extract Minor revision field from Image ID
+ */
+#define IX_NPEDL_MINOR_FROM_IMAGEID_GET(imageId) \
+    (((imageId) >> IX_NPEDL_IMAGEID_MINOR_OFFSET) & \
+     IX_NPEDL_NPEIMAGE_FIELD_MASK)
+
+
+/*
+ * Prototypes for interface functions
+ */
+
+/**
+ * @fn IX_STATUS ixNpeDlImageMgrMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary)
+ * 
+ * @brief This instructs NPE Downloader to use client-supplied microcode image library.
+ *
+ * This function sets NPE Downloader to use a client-supplied microcode image library
+ * instead of the standard image library which is included by the NPE Downloader.
+ * 
+ * @note THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.
+ *       It will be removed in a future release.
+ *       See API header file IxNpeDl.h for more information.             
+ *
+ * @pre
+ *    - <i>clientImageLibrary</i> should point to a microcode image library valid for use
+ *      by the NPE Downloader component.
+ *
+ * @post
+ *    - the client-supplied image uibrary will be used for all subsequent operations
+ *      performed by the NPE Downloader
+ *
+ * @return
+ *      - IX_SUCCESS if the operation was successful
+ *      - IX_FAIL if the client-supplied image library did not contain a valid signature
+ */ 
+IX_STATUS
+ixNpeDlImageMgrMicrocodeImageLibraryOverride (UINT32 *clientImageLibrary);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlImageMgrImageListExtract (IxNpeDlImageId *imageListPtr,
+                                                    UINT32 *numImages)
+ * 
+ * @brief Extracts a list of images available in the NPE microcode image library.
+ *
+ * @param IxNpeDlImageId* [out] imageListPtr - pointer to array to contain
+ *                                                 a list of images. If NULL,
+ *                                                 only the number of images 
+ *                                                 is returned (in
+ *                                                 <i>numImages</i>)
+ * @param UINT32* [inout] numImages - As input, it points to a variable
+ *                                      containing the number of images which
+ *                                      can be stored in the
+ *                                      <i>imageListPtr</i> array. Its value
+ *                                      is ignored as input if
+ *                                      <i>imageListPtr</i> is NULL. As an
+ *                                      output, it will contain number of
+ *                                      images in the image library.
+ * 
+ * This function reads the header of the microcode image library and extracts a list of the
+ * images available in the image library.  It can also be used to find the number of
+ * images in the image library.
+ * 
+ * @note THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.
+ *       It will be removed in a future release.
+ *       See API header file IxNpeDl.h for more information.             
+ *
+ * @pre
+ *    - if <i>imageListPtr</i> != NULL, <i>numImages</i> should reflect the
+ *      number of image Id elements the <i>imageListPtr</i> can contain.
+ *
+ * @post
+ *    - <i>numImages</i> will reflect the number of image Id's found in the
+ *      microcode image library.
+ *
+ * @return
+ *      - IX_SUCCESS if the operation was successful
+ *      - IX_FAIL otherwise
+ */ 
+IX_STATUS
+ixNpeDlImageMgrImageListExtract (IxNpeDlImageId *imageListPtr,
+				   UINT32 *numImages);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlImageMgrImageLocate (IxNpeDlImageId *imageId,
+                                               UINT32 **imagePtr,
+                                               UINT32 *imageSize)
+ * 
+ * @brief Finds a image block in the NPE microcode image library. 
+ *
+ * @param IxNpeDlImageId* [in] imageId - the id of the image to locate
+ * @param UINT32** [out] imagePtr        - pointer to the image in memory
+ * @param UINT32* [out] imageSize        - size (in 32-bit words) of image
+ * 
+ * This function examines the header of the microcode image library for the location
+ * and size of the specified image.
+ * 
+ * @note THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.
+ *       It will be removed in a future release.
+ *       See API header file IxNpeDl.h for more information.             
+ *
+ * @pre
+ *
+ * @post
+ *
+ * @return 
+ *      - IX_SUCCESS if the operation was successful
+ *      - IX_FAIL otherwise
+ */ 
+IX_STATUS
+ixNpeDlImageMgrImageLocate (IxNpeDlImageId *imageId,
+			      UINT32 **imagePtr,
+			      UINT32 *imageSize);
+
+/**
+ * @fn IX_STATUS ixNpeDlImageMgrLatestImageExtract (IxNpeDlImageId *imageId)
+ * 
+ * @brief Finds the most recent version of an image in the NPE image library. 
+ *
+ * @param IxNpeDlImageId* [inout] imageId - the id of the image 
+ * 
+ * This function determines the most recent version of a specified image by its 
+ * higest major release and minor revision numbers
+ * 
+ * @note THIS FUNCTION HAS BEEN DEPRECATED AND SHOULD NOT BE USED.
+ *       It will be removed in a future release.
+ *       See API header file IxNpeDl.h for more information.             
+ *
+ * @pre
+ *
+ * @post
+ *
+ * @return 
+ *      - IX_SUCCESS if the operation was successful
+ *      - IX_FAIL otherwise
+ */ 
+IX_STATUS
+ixNpeDlImageMgrLatestImageExtract (IxNpeDlImageId *imageId);
+
+/**
+ * @fn void ixNpeDlImageMgrStatsShow (void)
+ *
+ * @brief This function will display the statistics of the IxNpeDl ImageMgr
+ *        module
+ *
+ * @return none
+ */
+void
+ixNpeDlImageMgrStatsShow (void);
+
+
+/**
+ * @fn void ixNpeDlImageMgrStatsReset (void)
+ *
+ * @brief This function will reset the statistics of the IxNpeDl ImageMgr
+ *        module
+ *
+ * @return none
+ */
+void
+ixNpeDlImageMgrStatsReset (void);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlImageMgrImageGet (UINT32 *imageLibrary,
+                                          UINT32 imageId,
+                                          UINT32 **imagePtr,
+                                          UINT32 *imageSize)
+ * 
+ * @brief Finds a image block in the NPE microcode image library. 
+ *
+ * @param UINT32*  [in]  imageLibrary - the image library to use
+ * @param UINT32   [in]  imageId      - the id of the image to locate
+ * @param UINT32** [out] imagePtr     - pointer to the image in memory
+ * @param UINT32*  [out] imageSize    - size (in 32-bit words) of image
+ * 
+ * This function examines the header of the specified microcode image library
+ * for the location and size of the specified image.  It returns a pointer to
+ * the image in the <i>imagePtr</i> parameter.
+ * If no image library is specified (imageLibrary == NULL), then the default
+ * built-in image library will be used.
+ * 
+ * @pre
+ *
+ * @post
+ *
+ * @return 
+ *      - IX_SUCCESS if the operation was successful
+ *      - IX_FAIL otherwise
+ */ 
+IX_STATUS
+ixNpeDlImageMgrImageFind (UINT32 *imageLibrary,
+                          UINT32 imageId,
+			  UINT32 **imagePtr,
+			  UINT32 *imageSize);
+
+
+#endif /* IXNPEDLIMAGEMGR_P_H */
+
+/**
+ * @} defgroup IxNpeDlImageMgr_p
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeDlMacros_p.h b/marvell/uboot/drivers/net/npe/include/IxNpeDlMacros_p.h
new file mode 100644
index 0000000..771fe74
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeDlMacros_p.h
@@ -0,0 +1,390 @@
+/**
+ * @file IxNpeDlMacros_p.h
+ *
+ * @author Intel Corporation
+ * @date 21 January 2002
+ *
+ * @brief This file contains the macros for the IxNpeDl component.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeDlMacros_p IxNpeDlMacros_p
+ *
+ * @brief Macros for the IxNpeDl component.
+ * 
+ * @{
+ */
+
+#ifndef IXNPEDLMACROS_P_H
+#define IXNPEDLMACROS_P_H
+
+
+/*
+ * Put the user defined include files required.
+ */
+#if (CPU != XSCALE)
+/* To support IxNpeDl unit tests... */
+#include <stdio.h>
+#include "test/IxNpeDlTestReg.h"
+
+#else   
+#include "IxOsal.h"
+
+#endif
+
+
+/*
+ * Typedefs
+ */
+
+/**
+ * @typedef IxNpeDlTraceTypes
+ * @brief Enumeration defining IxNpeDl trace levels
+ */
+typedef enum
+{
+    IX_NPEDL_TRACE_OFF,     /**< no trace */
+    IX_NPEDL_DEBUG,         /**< debug */
+    IX_NPEDL_FN_ENTRY_EXIT  /**< function entry/exit */
+} IxNpeDlTraceTypes;
+
+
+/*
+ * #defines and macros.
+ */
+
+/* Implementation of the following macros for use with IxNpeDl unit test code */
+#if (CPU != XSCALE)
+
+
+/**
+ * @def IX_NPEDL_TRACE_LEVEL
+ *
+ * @brief IxNpeDl debug trace level
+ */
+#define IX_NPEDL_TRACE_LEVEL IX_NPEDL_FN_ENTRY_EXIT
+
+/**
+ * @def IX_NPEDL_ERROR_REPORT
+ *
+ * @brief Mechanism for reporting IxNpeDl software errors
+ *
+ * @param char* [in] STR - Error string to report
+ *
+ * This macro simply prints the error string passed.
+ * Intended for use with IxNpeDl unit test code.
+ *
+ * @return none
+ */
+#define IX_NPEDL_ERROR_REPORT(STR) printf ("IxNpeDl ERROR: %s\n", (STR));
+
+/**
+ * @def IX_NPEDL_WARNING_REPORT
+ *
+ * @brief Mechanism for reporting IxNpeDl software errors
+ *
+ * @param char* [in] STR - Error string to report
+ *
+ * This macro simply prints the error string passed.
+ * Intended for use with IxNpeDl unit test code.
+ *
+ * @return none
+ */
+#define IX_NPEDL_WARNING_REPORT(STR) printf ("IxNpeDl WARNING: %s\n", (STR));
+
+/**
+ * @def IX_NPEDL_TRACE0
+ *
+ * @brief Mechanism for tracing debug for the IxNpeDl component, for no arguments
+ *
+ * @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
+ * @param char* [in] STR - Trace string
+ *
+ * This macro simply prints the trace string passed, if the level is supported. 
+ * Intended for use with IxNpeDl unit test code.
+ *
+ * @return none
+ */
+#define IX_NPEDL_TRACE0(LEVEL, STR) \
+{ \
+    if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
+    { \
+        printf ("IxNpeDl TRACE: "); \
+        printf ((STR)); \
+        printf ("\n"); \
+    } \
+}
+
+ /**
+ * @def IX_NPEDL_TRACE1
+ *
+ * @brief Mechanism for tracing debug for the IxNpeDl component, with 1 argument
+ *
+ * @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
+ * @param char* [in] STR - Trace string
+ * @param argType [in] ARG1 - Argument to trace
+ *
+ * This macro simply prints the trace string passed, if the level is supported.
+ * Intended for use with IxNpeDl unit test code.
+ *
+ * @return none
+ */
+#define IX_NPEDL_TRACE1(LEVEL, STR, ARG1) \
+{ \
+    if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
+    { \
+        printf ("IxNpeDl TRACE: "); \
+        printf (STR, ARG1); \
+        printf ("\n"); \
+    } \
+}
+
+/**
+ * @def IX_NPEDL_TRACE2
+ *
+ * @brief Mechanism for tracing debug for the IxNpeDl component, with 2 arguments
+ *
+ * @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
+ * @param char* [in] STR - Trace string
+ * @param argType [in] ARG1 - Argument to trace
+ * @param argType [in] ARG2 - Argument to trace
+ *
+ * This macro simply prints the trace string passed, if the level is supported. 
+ * Intended for use with IxNpeDl unit test code.
+ *
+ * @return none
+ */
+#define IX_NPEDL_TRACE2(LEVEL, STR, ARG1, ARG2) \
+{ \
+    if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
+    { \
+        printf ("IxNpeDl TRACE: "); \
+        printf (STR, ARG1, ARG2); \
+        printf ("\n"); \
+    } \
+}
+
+
+/**
+ * @def IX_NPEDL_REG_WRITE
+ *
+ * @brief Mechanism for writing to a memory-mapped register
+ *
+ * @param UINT32 [in] base   - Base memory address for this NPE's registers
+ * @param UINT32 [in] offset - Offset from base memory address
+ * @param UINT32 [in] value  - Value to write to register
+ *
+ * This macro calls a function from Unit Test code to write a register.  This
+ * allows extra flexibility for unit testing of the IxNpeDl component.
+ *
+ * @return none
+ */
+#define IX_NPEDL_REG_WRITE(base, offset, value) \
+{ \
+    ixNpeDlTestRegWrite (base, offset, value); \
+}
+
+
+/**
+ * @def IX_NPEDL_REG_READ
+ *
+ * @brief Mechanism for reading from a memory-mapped register
+ *
+ * @param UINT32 [in] base     - Base memory address for this NPE's registers
+ * @param UINT32 [in] offset   - Offset from base memory address
+ * @param UINT32 *[out] value  - Value read from register
+ *
+ * This macro calls a function from Unit Test code to read a register.  This
+ * allows extra flexibility for unit testing of the IxNpeDl component.
+ *
+ * @return none
+ */
+#define IX_NPEDL_REG_READ(base, offset, value) \
+{ \
+    ixNpeDlTestRegRead (base, offset, value); \
+}
+
+
+/* Implementation of the following macros when integrated with IxOsal */
+#else  /* #if (CPU != XSCALE) */
+
+
+/**
+ * @def IX_NPEDL_TRACE_LEVEL
+ *
+ * @brief IxNpeDl debug trace level
+ */
+#define IX_NPEDL_TRACE_LEVEL IX_NPEDL_DEBUG
+
+
+/**
+ * @def IX_NPEDL_ERROR_REPORT
+ *
+ * @brief Mechanism for reporting IxNpeDl software errors
+ *
+ * @param char* [in] STR - Error string to report
+ *
+ * This macro is used to report IxNpeDl software errors.
+ *
+ * @return none
+ */
+#define IX_NPEDL_ERROR_REPORT(STR) \
+    ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, STR, 0, 0, 0, 0, 0, 0);
+
+/**
+ * @def IX_NPEDL_WARNING_REPORT
+ *
+ * @brief Mechanism for reporting IxNpeDl software warnings
+ *
+ * @param char* [in] STR - Warning string to report
+ *
+ * This macro is used to report IxNpeDl software warnings.
+ *
+ * @return none
+ */
+#define IX_NPEDL_WARNING_REPORT(STR) \
+    ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, STR, 0, 0, 0, 0, 0, 0);
+
+
+/**
+ * @def IX_NPEDL_TRACE0
+ *
+ * @brief Mechanism for tracing debug for the IxNpeDl component, for no arguments
+ *
+ * @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
+ * @param char* [in] STR - Trace string
+ *
+ * This macro simply prints the trace string passed, if the level is supported.
+ *
+ * @return none
+ */
+#define IX_NPEDL_TRACE0(LEVEL, STR) \
+{ \
+    if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
+    { \
+        if (LEVEL == IX_NPEDL_FN_ENTRY_EXIT) \
+        { \
+            ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, IX_OSAL_LOG_DEV_STDOUT, STR, 0, 0, 0, 0, 0, 0); \
+        } \
+        else if (LEVEL == IX_NPEDL_DEBUG) \
+        { \
+            ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, STR, 0, 0, 0, 0, 0, 0); \
+        } \
+    } \
+}
+
+/**
+ * @def IX_NPEDL_TRACE1
+ *
+ * @brief Mechanism for tracing debug for the IxNpeDl component, with 1 argument
+ *
+ * @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
+ * @param char* [in] STR - Trace string
+ * @param argType [in] ARG1 - Argument to trace
+ *
+ * This macro simply prints the trace string passed, if the level is supported. 
+ *
+ * @return none
+ */
+#define IX_NPEDL_TRACE1(LEVEL, STR, ARG1) \
+{ \
+    if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
+    { \
+        if (LEVEL == IX_NPEDL_FN_ENTRY_EXIT) \
+        { \
+            ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, IX_OSAL_LOG_DEV_STDOUT, STR, ARG1, 0, 0, 0, 0, 0); \
+        } \
+        else if (LEVEL == IX_NPEDL_DEBUG) \
+        { \
+            ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, STR, ARG1, 0, 0, 0, 0, 0); \
+        } \
+    } \
+}
+
+/**
+ * @def IX_NPEDL_TRACE2
+ *
+ * @brief Mechanism for tracing debug for the IxNpeDl component, with 2 arguments
+ *
+ * @param unsigned [in] LEVEL - one of IxNpeDlTraceTypes enumerated values
+ * @param char* [in] STR - Trace string
+ * @param argType [in] ARG1 - Argument to trace
+ * @param argType [in] ARG2 - Argument to trace
+ *
+ * This macro simply prints the trace string passed, if the level is supported. 
+ *
+ * @return none
+ */
+#define IX_NPEDL_TRACE2(LEVEL, STR, ARG1, ARG2) \
+{ \
+    if (LEVEL <= IX_NPEDL_TRACE_LEVEL) \
+    { \
+        if (LEVEL == IX_NPEDL_FN_ENTRY_EXIT) \
+        { \
+            ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, IX_OSAL_LOG_DEV_STDOUT, STR, ARG1, ARG2, 0, 0, 0, 0); \
+        } \
+        else if (LEVEL == IX_NPEDL_DEBUG) \
+        { \
+            ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, STR, ARG1, ARG2, 0, 0, 0, 0); \
+        } \
+    } \
+}
+
+/**
+ * @def IX_NPEDL_REG_WRITE
+ *
+ * @brief Mechanism for writing to a memory-mapped register
+ *
+ * @param UINT32 [in] base   - Base memory address for this NPE's registers
+ * @param UINT32 [in] offset - Offset from base memory address
+ * @param UINT32 [in] value  - Value to write to register
+ *
+ * This macro forms the address of the register from base address + offset, and 
+ * dereferences that address to write the contents of the register.
+ *
+ * @return none
+ */
+#define IX_NPEDL_REG_WRITE(base, offset, value) \
+    IX_OSAL_WRITE_LONG(((base) + (offset)), (value))
+
+
+
+/**
+ * @def IX_NPEDL_REG_READ
+ *
+ * @brief Mechanism for reading from a memory-mapped register
+ *
+ * @param UINT32 [in] base    - Base memory address for this NPE's registers
+ * @param UINT32 [in] offset  - Offset from base memory address
+ * @param UINT32 *[out] value  - Value read from register
+ *
+ * This macro forms the address of the register from base address + offset, and 
+ * dereferences that address to read the register contents.
+ *
+ * @return none
+ */
+#define IX_NPEDL_REG_READ(base, offset, value) \
+    *(value) = IX_OSAL_READ_LONG(((base) + (offset)))
+
+#endif  /* #if (CPU != XSCALE) */
+
+#endif /* IXNPEDLMACROS_P_H */
+
+/**
+ * @} defgroup IxNpeDlMacros_p
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeDlNpeMgrEcRegisters_p.h b/marvell/uboot/drivers/net/npe/include/IxNpeDlNpeMgrEcRegisters_p.h
new file mode 100644
index 0000000..f6c2e46
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeDlNpeMgrEcRegisters_p.h
@@ -0,0 +1,869 @@
+/**
+ * @file IxNpeDlNpeMgrEcRegisters_p.h
+ *
+ * @author Intel Corporation
+ * @date 14 December 2001
+
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+#ifndef IXNPEDLNPEMGRECREGISTERS_P_H
+#define IXNPEDLNPEMGRECREGISTERS_P_H
+
+#include "IxOsal.h"
+
+/*
+ * Base Memory Addresses for accessing NPE registers
+ */
+
+#define IX_NPEDL_NPE_BASE (IX_OSAL_IXP400_PERIPHERAL_PHYS_BASE)
+
+#define IX_NPEDL_NPEA_OFFSET (0x6000) /**< NPE-A register base offset */
+#define IX_NPEDL_NPEB_OFFSET (0x7000) /**< NPE-B register base offset */
+#define IX_NPEDL_NPEC_OFFSET (0x8000) /**< NPE-C register base offset */
+
+/**
+ * @def IX_NPEDL_NPEBASEADDRESS_NPEA
+ * @brief Base Memory Address of NPE-A Configuration Bus registers
+ */
+#define IX_NPEDL_NPEBASEADDRESS_NPEA (IX_NPEDL_NPE_BASE + IX_NPEDL_NPEA_OFFSET)
+
+/**
+ * @def IX_NPEDL_NPEBASEADDRESS_NPEB
+ * @brief Base Memory Address of NPE-B Configuration Bus registers
+ */
+#define IX_NPEDL_NPEBASEADDRESS_NPEB (IX_NPEDL_NPE_BASE + IX_NPEDL_NPEB_OFFSET)
+
+/**
+ * @def IX_NPEDL_NPEBASEADDRESS_NPEC
+ * @brief Base Memory Address of NPE-C Configuration Bus registers
+ */
+#define IX_NPEDL_NPEBASEADDRESS_NPEC (IX_NPEDL_NPE_BASE + IX_NPEDL_NPEC_OFFSET)
+
+
+/*
+ * Instruction Memory Size (in words) for each NPE 
+ */
+
+/**
+ * @def IX_NPEDL_INS_MEMSIZE_WORDS_NPEA
+ * @brief Size (in words) of NPE-A Instruction Memory
+ */
+#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEA     4096
+
+/**
+ * @def IX_NPEDL_INS_MEMSIZE_WORDS_NPEB
+ * @brief Size (in words) of NPE-B Instruction Memory
+ */
+#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEB     2048
+
+/**
+ * @def IX_NPEDL_INS_MEMSIZE_WORDS_NPEC
+ * @brief Size (in words) of NPE-B Instruction Memory
+ */
+#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEC     2048
+
+
+/*
+ * Data Memory Size (in words) for each NPE 
+ */
+
+/**
+ * @def IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA
+ * @brief Size (in words) of NPE-A Data Memory
+ */
+#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA    2048
+
+/**
+ * @def IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB
+ * @brief Size (in words) of NPE-B Data Memory
+ */
+#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB    2048
+
+/**
+ * @def IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC
+ * @brief Size (in words) of NPE-C Data Memory
+ */
+#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC    2048
+
+
+/*
+ * Configuration Bus Register offsets (in bytes) from NPE Base Address
+ */
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_EXAD
+ * @brief Offset (in bytes) of EXAD (Execution Address) register from NPE Base
+ *        Address
+ */
+#define IX_NPEDL_REG_OFFSET_EXAD             0x00000000		
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_EXDATA
+ * @brief Offset (in bytes) of EXDATA (Execution Data) register from NPE Base
+ *        Address
+ */
+#define IX_NPEDL_REG_OFFSET_EXDATA           0x00000004
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_EXCTL
+ * @brief Offset (in bytes) of EXCTL (Execution Control) register from NPE Base
+ *        Address
+ */
+#define IX_NPEDL_REG_OFFSET_EXCTL            0x00000008		
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_EXCT
+ * @brief Offset (in bytes) of EXCT (Execution Count) register from NPE Base
+ *        Address
+ */
+#define IX_NPEDL_REG_OFFSET_EXCT 	     0x0000000C		
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_AP0
+ * @brief Offset (in bytes) of AP0 (Action Point 0) register from NPE Base
+ *        Address
+ */
+#define IX_NPEDL_REG_OFFSET_AP0	             0x00000010		
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_AP1
+ * @brief Offset (in bytes) of AP1 (Action Point 1) register from NPE Base
+ *        Address
+ */
+#define IX_NPEDL_REG_OFFSET_AP1	             0x00000014		
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_AP2
+ * @brief Offset (in bytes) of AP2 (Action Point 2) register from NPE Base
+ *        Address
+ */
+#define IX_NPEDL_REG_OFFSET_AP2	             0x00000018		
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_AP3
+ * @brief Offset (in bytes) of AP3 (Action Point 3) register from NPE Base
+ *        Address
+ */
+#define IX_NPEDL_REG_OFFSET_AP3	             0x0000001C		
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_WFIFO
+ * @brief Offset (in bytes) of WFIFO (Watchpoint FIFO) register from NPE Base
+ *        Address
+ */
+#define IX_NPEDL_REG_OFFSET_WFIFO            0x00000020
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_WC
+ * @brief Offset (in bytes) of WC (Watch Count) register from NPE Base
+ *        Address
+ */
+#define IX_NPEDL_REG_OFFSET_WC	             0x00000024 		
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_PROFCT
+ * @brief Offset (in bytes) of PROFCT (Profile Count) register from NPE Base
+ *        Address
+ */
+#define IX_NPEDL_REG_OFFSET_PROFCT           0x00000028		
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_STAT
+ * @brief Offset (in bytes) of STAT (Messaging Status) register from NPE Base
+ *        Address
+ */
+#define IX_NPEDL_REG_OFFSET_STAT	     0x0000002C		
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_CTL
+ * @brief Offset (in bytes) of CTL (Messaging Control) register from NPE Base
+ *        Address
+ */
+#define IX_NPEDL_REG_OFFSET_CTL	             0x00000030		
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_MBST
+ * @brief Offset (in bytes) of MBST (Mailbox Status) register from NPE Base
+ *        Address
+ */
+#define IX_NPEDL_REG_OFFSET_MBST	     0x00000034		
+
+/**
+ * @def IX_NPEDL_REG_OFFSET_FIFO
+ * @brief Offset (in bytes) of FIFO (messaging in/out FIFO) register from NPE
+ *        Base Address
+ */
+#define IX_NPEDL_REG_OFFSET_FIFO	     0x00000038		
+
+
+/*
+ * Non-zero reset values for the Configuration Bus registers
+ */
+
+/**
+ * @def IX_NPEDL_REG_RESET_FIFO
+ * @brief Reset value for Mailbox (MBST) register
+ *        NOTE that if used, it should be complemented with an NPE intruction
+ *        to clear the Mailbox at the NPE side as well
+ */
+#define IX_NPEDL_REG_RESET_MBST              0x0000F0F0
+
+
+/*
+ * Bit-masks used to read/write particular bits in Configuration Bus registers
+ */
+
+/**
+ * @def IX_NPEDL_MASK_WFIFO_VALID
+ * @brief Masks the VALID bit in the WFIFO register
+ */
+#define IX_NPEDL_MASK_WFIFO_VALID            0x80000000
+
+/**
+ * @def IX_NPEDL_MASK_STAT_OFNE
+ * @brief Masks the OFNE bit in the STAT register
+ */
+#define IX_NPEDL_MASK_STAT_OFNE              0x00010000
+
+/**
+ * @def IX_NPEDL_MASK_STAT_IFNE
+ * @brief Masks the IFNE bit in the STAT register
+ */
+#define IX_NPEDL_MASK_STAT_IFNE              0x00080000
+
+
+/*
+ * EXCTL (Execution Control) Register commands 
+*/
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_NPE_STEP
+ * @brief EXCTL Command to Step execution of an NPE Instruction
+ */
+
+#define IX_NPEDL_EXCTL_CMD_NPE_STEP          0x01
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_NPE_START
+ * @brief EXCTL Command to Start NPE execution
+ */
+#define IX_NPEDL_EXCTL_CMD_NPE_START         0x02
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_NPE_STOP
+ * @brief EXCTL Command to Stop NPE execution
+ */
+#define IX_NPEDL_EXCTL_CMD_NPE_STOP          0x03
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE
+ * @brief EXCTL Command to Clear NPE instruction pipeline
+ */
+#define IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE      0x04
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_RD_INS_MEM
+ * @brief EXCTL Command to read NPE instruction memory at address in EXAD
+ *        register and return value in EXDATA register
+ */
+#define IX_NPEDL_EXCTL_CMD_RD_INS_MEM        0x10
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_WR_INS_MEM
+ * @brief EXCTL Command to write NPE instruction memory at address in EXAD
+ *        register with data in EXDATA register
+ */
+#define IX_NPEDL_EXCTL_CMD_WR_INS_MEM        0x11
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_RD_DATA_MEM
+ * @brief EXCTL Command to read NPE data memory at address in EXAD
+ *        register and return value in EXDATA register
+ */
+#define IX_NPEDL_EXCTL_CMD_RD_DATA_MEM       0x12
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_WR_DATA_MEM
+ * @brief EXCTL Command to write NPE data memory at address in EXAD
+ *        register with data in EXDATA register
+ */
+#define IX_NPEDL_EXCTL_CMD_WR_DATA_MEM       0x13
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_RD_ECS_REG
+ * @brief EXCTL Command to read Execution Access register at address in EXAD
+ *        register and return value in EXDATA register
+ */
+#define IX_NPEDL_EXCTL_CMD_RD_ECS_REG        0x14
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_WR_ECS_REG
+ * @brief EXCTL Command to write Execution Access register at address in EXAD
+ *        register with data in EXDATA register
+ */
+#define IX_NPEDL_EXCTL_CMD_WR_ECS_REG        0x15
+
+/**
+ * @def IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT
+ * @brief EXCTL Command to clear Profile Count register
+ */
+#define IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT   0x0C
+
+
+/*
+ * EXCTL (Execution Control) Register status bit masks
+ */
+
+/**
+ * @def IX_NPEDL_EXCTL_STATUS_RUN
+ * @brief Masks the RUN status bit in the EXCTL register
+ */
+#define IX_NPEDL_EXCTL_STATUS_RUN            0x80000000
+
+/**
+ * @def IX_NPEDL_EXCTL_STATUS_STOP
+ * @brief Masks the STOP status bit in the EXCTL register
+ */
+#define IX_NPEDL_EXCTL_STATUS_STOP           0x40000000
+
+/**
+ * @def IX_NPEDL_EXCTL_STATUS_CLEAR
+ * @brief Masks the CLEAR status bit in the EXCTL register
+ */
+#define IX_NPEDL_EXCTL_STATUS_CLEAR          0x20000000
+
+/**
+ * @def IX_NPEDL_EXCTL_STATUS_ECS_K
+ * @brief Masks the K (pipeline Klean) status bit in the EXCTL register
+ */
+#define IX_NPEDL_EXCTL_STATUS_ECS_K          0x00800000
+
+
+/*
+ * Executing Context Stack (ECS) level registers 
+ */
+
+/**
+ * @def IX_NPEDL_ECS_BG_CTXT_REG_0
+ * @brief Execution Access register address for register 0 at Backgound 
+ *        Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_BG_CTXT_REG_0           0x00
+
+/**
+ * @def IX_NPEDL_ECS_BG_CTXT_REG_1
+ * @brief Execution Access register address for register 1 at Backgound 
+ *        Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_BG_CTXT_REG_1           0x01
+
+/**
+ * @def IX_NPEDL_ECS_BG_CTXT_REG_2
+ * @brief Execution Access register address for register 2 at Backgound 
+ *        Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_BG_CTXT_REG_2           0x02
+
+/**
+ * @def IX_NPEDL_ECS_PRI_1_CTXT_REG_0
+ * @brief Execution Access register address for register 0 at Priority 1
+ *        Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_0        0x04
+
+/**
+ * @def IX_NPEDL_ECS_PRI_1_CTXT_REG_1
+ * @brief Execution Access register address for register 1 at Priority 1
+ *        Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_1        0x05
+
+/**
+ * @def IX_NPEDL_ECS_PRI_1_CTXT_REG_2
+ * @brief Execution Access register address for register 2 at Priority 1
+ *        Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_2        0x06
+
+/**
+ * @def IX_NPEDL_ECS_PRI_2_CTXT_REG_0
+ * @brief Execution Access register address for register 0 at Priority 2
+ *        Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_0        0x08
+
+/**
+ * @def IX_NPEDL_ECS_PRI_2_CTXT_REG_1
+ * @brief Execution Access register address for register 1 at Priority 2
+ *        Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_1        0x09
+
+/**
+ * @def IX_NPEDL_ECS_PRI_2_CTXT_REG_2
+ * @brief Execution Access register address for register 2 at Priority 2
+ *        Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_2        0x0A
+
+/**
+ * @def IX_NPEDL_ECS_DBG_CTXT_REG_0
+ * @brief Execution Access register address for register 0 at Debug
+ *        Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_DBG_CTXT_REG_0          0x0C
+
+/**
+ * @def IX_NPEDL_ECS_DBG_CTXT_REG_1
+ * @brief Execution Access register address for register 1 at Debug 
+ *        Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_DBG_CTXT_REG_1          0x0D
+
+/**
+ * @def IX_NPEDL_ECS_DBG_CTXT_REG_2
+ * @brief Execution Access register address for register 2 at Debug 
+ *        Executing Context Stack level
+ */
+#define IX_NPEDL_ECS_DBG_CTXT_REG_2          0x0E
+
+/**
+ * @def IX_NPEDL_ECS_INSTRUCT_REG
+ * @brief Execution Access register address for NPE Instruction Register 
+ */
+#define IX_NPEDL_ECS_INSTRUCT_REG            0x11
+
+
+/*
+ * Execution Access register reset values
+ */
+
+/**
+ * @def IX_NPEDL_ECS_BG_CTXT_REG_0_RESET
+ * @brief Reset value for Execution Access Background ECS level register 0
+ */
+#define IX_NPEDL_ECS_BG_CTXT_REG_0_RESET     0xA0000000
+
+/**
+ * @def IX_NPEDL_ECS_BG_CTXT_REG_1_RESET
+ * @brief Reset value for Execution Access Background ECS level register 1
+ */
+#define IX_NPEDL_ECS_BG_CTXT_REG_1_RESET     0x01000000
+
+/**
+ * @def IX_NPEDL_ECS_BG_CTXT_REG_2_RESET
+ * @brief Reset value for Execution Access Background ECS level register 2
+ */
+#define IX_NPEDL_ECS_BG_CTXT_REG_2_RESET     0x00008000
+
+/**
+ * @def IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET
+ * @brief Reset value for Execution Access Priority 1 ECS level register 0
+ */
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET  0x20000080
+
+/**
+ * @def IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET
+ * @brief Reset value for Execution Access Priority 1 ECS level register 1
+ */
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET  0x01000000
+
+/**
+ * @def IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET
+ * @brief Reset value for Execution Access Priority 1 ECS level register 2
+ */
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET  0x00008000
+
+/**
+ * @def IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET
+ * @brief Reset value for Execution Access Priority 2 ECS level register 0
+ */
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET  0x20000080
+
+/**
+ * @def IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET
+ * @brief Reset value for Execution Access Priority 2 ECS level register 1
+ */
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET  0x01000000
+
+/**
+ * @def IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET
+ * @brief Reset value for Execution Access Priority 2 ECS level register 2
+ */
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET  0x00008000
+
+/**
+ * @def IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET
+ * @brief Reset value for Execution Access Debug ECS level register 0
+ */
+#define IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET    0x20000000
+
+/**
+ * @def IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET
+ * @brief Reset value for Execution Access Debug ECS level register 1
+ */
+#define IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET    0x00000000
+
+/**
+ * @def IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET
+ * @brief Reset value for Execution Access Debug ECS level register 2
+ */
+#define IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET    0x001E0000
+
+/**
+ * @def IX_NPEDL_ECS_INSTRUCT_REG_RESET
+ * @brief Reset value for Execution Access NPE Instruction Register
+ */
+#define IX_NPEDL_ECS_INSTRUCT_REG_RESET      0x1003C00F
+
+
+/*
+ * masks used to read/write particular bits in Execution Access registers
+ */
+
+/**
+ * @def IX_NPEDL_MASK_ECS_REG_0_ACTIVE
+ * @brief Mask the A (Active) bit in Execution Access Register 0 of all ECS
+ *        levels
+ */
+#define IX_NPEDL_MASK_ECS_REG_0_ACTIVE       0x80000000
+
+/**
+ * @def IX_NPEDL_MASK_ECS_REG_0_NEXTPC
+ * @brief Mask the NextPC bits in Execution Access Register 0 of all ECS
+ *        levels (except Debug ECS level)
+ */
+#define IX_NPEDL_MASK_ECS_REG_0_NEXTPC       0x1FFF0000
+
+/**
+ * @def IX_NPEDL_MASK_ECS_REG_0_LDUR
+ * @brief Mask the LDUR bits in Execution Access Register 0 of all ECS levels
+ */
+#define IX_NPEDL_MASK_ECS_REG_0_LDUR         0x00000700
+
+/**
+ * @def IX_NPEDL_MASK_ECS_REG_1_CCTXT
+ * @brief Mask the NextPC bits in Execution Access Register 1 of all ECS levels
+ */
+#define IX_NPEDL_MASK_ECS_REG_1_CCTXT        0x000F0000
+
+/**
+ * @def IX_NPEDL_MASK_ECS_REG_1_SELCTXT
+ * @brief Mask the NextPC bits in Execution Access Register 1 of all ECS levels
+ */
+#define IX_NPEDL_MASK_ECS_REG_1_SELCTXT      0x0000000F
+
+/**
+ * @def IX_NPEDL_MASK_ECS_DBG_REG_2_IF
+ * @brief Mask the IF bit in Execution Access Register 2 of Debug ECS level
+ */
+#define IX_NPEDL_MASK_ECS_DBG_REG_2_IF       0x00100000
+
+/**
+ * @def IX_NPEDL_MASK_ECS_DBG_REG_2_IE
+ * @brief Mask the IE bit in Execution Access Register 2 of Debug ECS level
+ */
+#define IX_NPEDL_MASK_ECS_DBG_REG_2_IE       0x00080000
+
+
+/*
+ * Bit-Offsets from LSB of particular bit-fields in Execution Access registers
+ */
+
+/**
+ * @def IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC
+ * @brief LSB-offset of NextPC field in Execution Access Register 0 of all ECS
+ *        levels (except Debug ECS level)
+ */
+#define IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC     16 
+
+/**
+ * @def IX_NPEDL_OFFSET_ECS_REG_0_LDUR
+ * @brief LSB-offset of LDUR field in Execution Access Register 0 of all ECS
+ *        levels
+ */
+#define IX_NPEDL_OFFSET_ECS_REG_0_LDUR        8
+
+/**
+ * @def IX_NPEDL_OFFSET_ECS_REG_1_CCTXT
+ * @brief LSB-offset of CCTXT field in Execution Access Register 1 of all ECS
+ *        levels
+ */
+#define IX_NPEDL_OFFSET_ECS_REG_1_CCTXT      16
+
+/**
+ * @def IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT
+ * @brief LSB-offset of SELCTXT field in Execution Access Register 1 of all ECS
+ *        levels
+ */
+#define IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT     0
+
+
+/*
+ * NPE core & co-processor instruction templates to load into NPE Instruction 
+ * Register, for read/write of NPE register file registers
+ */
+
+/**
+ * @def IX_NPEDL_INSTR_RD_REG_BYTE
+ * @brief NPE Instruction, used to read an 8-bit NPE internal logical register
+ *        and return the value in the EXDATA register (aligned to MSB).
+ *        NPE Assembler instruction:  "mov8 d0, d0  &&& DBG_WrExec"
+ */
+#define IX_NPEDL_INSTR_RD_REG_BYTE    0x0FC00000
+
+/**
+ * @def IX_NPEDL_INSTR_RD_REG_SHORT
+ * @brief NPE Instruction, used to read a 16-bit NPE internal logical register
+ *        and return the value in the EXDATA register (aligned to MSB).
+ *        NPE Assembler instruction:  "mov16 d0, d0  &&& DBG_WrExec"
+ */
+#define IX_NPEDL_INSTR_RD_REG_SHORT   0x0FC08010
+
+/**
+ * @def IX_NPEDL_INSTR_RD_REG_WORD
+ * @brief NPE Instruction, used to read a 16-bit NPE internal logical register
+ *        and return the value in the EXDATA register.
+ *        NPE Assembler instruction:  "mov32 d0, d0  &&& DBG_WrExec"
+ */
+#define IX_NPEDL_INSTR_RD_REG_WORD    0x0FC08210
+
+/**
+ * @def IX_NPEDL_INSTR_WR_REG_BYTE
+ * @brief NPE Immediate-Mode Instruction, used to write an 8-bit NPE internal
+ *        logical register.
+ *        NPE Assembler instruction:  "mov8 d0, #0"
+ */
+#define IX_NPEDL_INSTR_WR_REG_BYTE    0x00004000
+
+/**
+ * @def IX_NPEDL_INSTR_WR_REG_SHORT
+ * @brief NPE Immediate-Mode Instruction, used to write a 16-bit NPE internal
+ *        logical register.
+ *        NPE Assembler instruction:  "mov16 d0, #0"
+ */
+#define IX_NPEDL_INSTR_WR_REG_SHORT   0x0000C000
+
+/**
+ * @def IX_NPEDL_INSTR_RD_FIFO
+ * @brief NPE Immediate-Mode Instruction, used to write a 16-bit NPE internal
+ *        logical register.
+ *        NPE Assembler instruction:  "cprd32 d0    &&& DBG_RdInFIFO"
+ */
+#define IX_NPEDL_INSTR_RD_FIFO        0x0F888220    
+
+/**
+ * @def IX_NPEDL_INSTR_RESET_MBOX
+ * @brief NPE Instruction, used to reset Mailbox (MBST) register
+ *        NPE Assembler instruction:  "mov32 d0, d0  &&& DBG_ClearM"
+ */
+#define IX_NPEDL_INSTR_RESET_MBOX     0x0FAC8210
+
+
+/*
+ * Bit-offsets from LSB, of particular bit-fields in an NPE instruction
+ */
+
+/**
+ * @def IX_NPEDL_OFFSET_INSTR_SRC
+ * @brief LSB-offset to SRC (source operand) field of an NPE Instruction
+ */
+#define IX_NPEDL_OFFSET_INSTR_SRC              4
+
+/**
+ * @def IX_NPEDL_OFFSET_INSTR_DEST
+ * @brief LSB-offset to DEST (destination operand) field of an NPE Instruction
+ */
+#define IX_NPEDL_OFFSET_INSTR_DEST             9
+
+/**
+ * @def IX_NPEDL_OFFSET_INSTR_COPROC
+ * @brief LSB-offset to COPROC (coprocessor instruction) field of an NPE
+ *        Instruction
+ */
+#define IX_NPEDL_OFFSET_INSTR_COPROC          18
+
+
+/*
+ * masks used to read/write particular bits of an NPE Instruction
+ */
+
+/**
+ * @def IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA
+ * @brief Mask the bits of 16-bit data value (least-sig 5 bits) to be used in
+ *        SRC field of immediate-mode NPE instruction
+ */
+#define IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA         0x1F 
+
+/**
+ * @def IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA
+ * @brief Mask the bits of 16-bit data value (most-sig 11 bits) to be used in
+ *        COPROC field of immediate-mode NPE instruction
+ */
+#define IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA      0xFFE0
+
+/**
+ * @def IX_NPEDL_OFFSET_IMMED_INSTR_COPROC_DATA
+ * @brief LSB offset of the bit-field of 16-bit data value (most-sig 11 bits)
+ *        to be used in COPROC field of immediate-mode NPE instruction
+ */
+#define IX_NPEDL_OFFSET_IMMED_INSTR_COPROC_DATA    5
+
+/**
+ * @def IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA
+ * @brief Number of left-shifts required to align most-sig 11 bits of 16-bit
+ *        data value into COPROC field of immediate-mode NPE instruction
+ */
+#define IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA \
+     (IX_NPEDL_OFFSET_INSTR_COPROC - IX_NPEDL_OFFSET_IMMED_INSTR_COPROC_DATA)
+
+/**
+ * @def IX_NPEDL_WR_INSTR_LDUR
+ * @brief LDUR value used with immediate-mode NPE Instructions by the NpeDl
+ *        for writing to NPE internal logical registers
+ */
+#define IX_NPEDL_WR_INSTR_LDUR                     1
+
+/**
+ * @def IX_NPEDL_RD_INSTR_LDUR
+ * @brief LDUR value used with NON-immediate-mode NPE Instructions by the NpeDl
+ *        for reading from NPE internal logical registers
+ */
+#define IX_NPEDL_RD_INSTR_LDUR                     0
+
+
+/**
+ * @enum IxNpeDlCtxtRegNum
+ * @brief Numeric values to identify the NPE internal Context Store registers
+ */
+typedef enum
+{
+    IX_NPEDL_CTXT_REG_STEVT = 0,  /**< identifies STEVT   */
+    IX_NPEDL_CTXT_REG_STARTPC,    /**< identifies STARTPC */
+    IX_NPEDL_CTXT_REG_REGMAP,     /**< identifies REGMAP  */
+    IX_NPEDL_CTXT_REG_CINDEX,     /**< identifies CINDEX  */
+    IX_NPEDL_CTXT_REG_MAX         /**< Total number of Context Store registers */
+} IxNpeDlCtxtRegNum;
+
+
+/*
+ * NPE Context Store register logical addresses
+ */
+
+/**
+ * @def IX_NPEDL_CTXT_REG_ADDR_STEVT
+ * @brief Logical address of STEVT NPE internal Context Store register
+ */
+#define IX_NPEDL_CTXT_REG_ADDR_STEVT      0x0000001B
+
+/**
+ * @def IX_NPEDL_CTXT_REG_ADDR_STARTPC
+ * @brief Logical address of STARTPC NPE internal Context Store register
+ */
+#define IX_NPEDL_CTXT_REG_ADDR_STARTPC    0x0000001C
+
+/**
+ * @def IX_NPEDL_CTXT_REG_ADDR_REGMAP
+ * @brief Logical address of REGMAP NPE internal Context Store register
+ */
+#define IX_NPEDL_CTXT_REG_ADDR_REGMAP     0x0000001E
+
+/**
+ * @def IX_NPEDL_CTXT_REG_ADDR_CINDEX
+ * @brief Logical address of CINDEX NPE internal Context Store register
+ */
+#define IX_NPEDL_CTXT_REG_ADDR_CINDEX     0x0000001F
+
+
+/*
+ * NPE Context Store register reset values
+ */
+
+/**
+ * @def IX_NPEDL_CTXT_REG_RESET_STEVT
+ * @brief Reset value of STEVT NPE internal Context Store register
+ *        (STEVT = off, 0x80)
+ */
+#define IX_NPEDL_CTXT_REG_RESET_STEVT     0x80
+
+/**
+ * @def IX_NPEDL_CTXT_REG_RESET_STARTPC
+ * @brief Reset value of STARTPC NPE internal Context Store register
+ *        (STARTPC = 0x0000)
+ */
+#define IX_NPEDL_CTXT_REG_RESET_STARTPC   0x0000
+
+/**
+ * @def IX_NPEDL_CTXT_REG_RESET_REGMAP
+ * @brief Reset value of REGMAP NPE internal Context Store register
+ *        (REGMAP = d0->p0, d8->p2, d16->p4)
+ */
+#define IX_NPEDL_CTXT_REG_RESET_REGMAP    0x0820
+
+/**
+ * @def IX_NPEDL_CTXT_REG_RESET_CINDEX
+ * @brief Reset value of CINDEX NPE internal Context Store register
+ *        (CINDEX = 0)
+ */
+#define IX_NPEDL_CTXT_REG_RESET_CINDEX    0x00
+
+
+/*
+ * numeric range of context levels available on an NPE
+ */
+
+/**
+ * @def IX_NPEDL_CTXT_NUM_MIN
+ * @brief Lowest NPE Context number in range
+ */
+#define IX_NPEDL_CTXT_NUM_MIN             0
+
+/**
+ * @def IX_NPEDL_CTXT_NUM_MAX
+ * @brief Highest NPE Context number in range
+ */
+#define IX_NPEDL_CTXT_NUM_MAX             15
+
+
+/*
+ * Physical NPE internal registers
+ */
+
+/**
+ * @def IX_NPEDL_TOTAL_NUM_PHYS_REG
+ * @brief Number of Physical registers currently supported
+ *        Initial NPE implementations will have a 32-word register file.
+ *        Later implementations may have a 64-word register file.
+ */
+#define IX_NPEDL_TOTAL_NUM_PHYS_REG               32
+
+/**
+ * @def IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP
+ * @brief LSB-offset of Regmap number in Physical NPE register address, used
+ *        for Physical To Logical register address mapping in the NPE
+ */
+#define IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP      1
+
+/**
+ * @def IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR
+ * @brief Mask to extract a logical NPE register address from a physical
+ *        register address, used for Physical To Logical address mapping
+ */
+#define IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR   0x1
+
+#endif /* IXNPEDLNPEMGRECREGISTERS_P_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeDlNpeMgrUtils_p.h b/marvell/uboot/drivers/net/npe/include/IxNpeDlNpeMgrUtils_p.h
new file mode 100644
index 0000000..bb1f4ab
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeDlNpeMgrUtils_p.h
@@ -0,0 +1,381 @@
+/**
+ * @file IxNpeDlNpeMgrUtils_p.h
+ *
+ * @author Intel Corporation
+ * @date 18 February 2002
+ * @brief This file contains the private API for the NpeMgr module.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+/**
+ * @defgroup IxNpeDlNpeMgrUtils_p IxNpeDlNpeMgrUtils_p
+ *
+ * @brief The private API for the IxNpeDl NpeMgr Utils module
+ * 
+ * @{
+ */
+
+#ifndef IXNPEDLNPEMGRUTILS_P_H
+#define IXNPEDLNPEMGRUTILS_P_H
+
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxNpeDl.h"
+#include "IxOsalTypes.h"
+#include "IxNpeDlNpeMgrEcRegisters_p.h"
+
+
+/*
+ * Function Prototypes
+ */
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrInsMemWrite (UINT32 npeBaseAddress,
+                                           UINT32 insMemAddress,
+			                   UINT32 insMemData,
+                                           BOOL verify)
+ * 
+ * @brief Writes a word to NPE Instruction memory
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] insMemAddress  - NPE instruction memory address to write
+ * @param UINT32 [in] insMemData     - data to write to instruction memory
+ * @param BOOL   [in] verify         - if true, verify the memory location is
+ *                                     written successfully.
+ * 
+ * This function is used to write a single word of data to a location in NPE 
+ * instruction memory.  If the <i>verify</i> option is ON, NpeDl will read back
+ * from the memory location to verify that it was written successfully
+ * 
+ * @pre
+ *
+ * @post
+ *
+ * @return
+ *    - IX_FAIL if verify is true and the memory location was not written
+ *      successfully
+ *    - IX_SUCCESS otherwise
+ */ 
+IX_STATUS
+ixNpeDlNpeMgrInsMemWrite (UINT32 npeBaseAddress, UINT32 insMemAddress,
+			  UINT32 insMemData, BOOL verify);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrDataMemWrite (UINT32 npeBaseAddress,
+                                            UINT32 dataMemAddress,
+	                                    UINT32 dataMemData,
+                                            BOOL verify)
+ * 
+ * @brief Writes a word to NPE Data memory
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] dataMemAddress - NPE data memory address to write
+ * @param UINT32 [in] dataMemData    - data to write to NPE data memory
+ * @param BOOL   [in] verify         - if true, verify the memory location is
+ *                                     written successfully.
+ * 
+ * This function is used to write a single word of data to a location in NPE 
+ * data memory.  If the <i>verify</i> option is ON, NpeDl will read back from
+ * the memory location to verify that it was written successfully
+ * 
+ * @pre
+ *
+ * @post
+ *
+ * @return
+ *    - IX_FAIL if verify is true and the memory location was not written
+ *      successfully
+ *    - IX_SUCCESS otherwise
+ */ 
+IX_STATUS
+ixNpeDlNpeMgrDataMemWrite (UINT32 npeBaseAddress, UINT32 dataMemAddress,
+			   UINT32 dataMemData, BOOL verify);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrExecAccRegWrite (UINT32 npeBaseAddress,
+                                          UINT32 regAddress,
+                                          UINT32 regData)
+ * 
+ * @brief Writes a word to an NPE Execution Access register
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] regAddress     - NPE Execution Access register address
+ * @param UINT32 [in] regData        - data to write to register
+ * 
+ * This function is used to write a single word of data to an NPE Execution
+ * Access register.
+ * 
+ * @pre
+ *
+ * @post
+ *
+ * @return none
+ */ 
+void
+ixNpeDlNpeMgrExecAccRegWrite (UINT32 npeBaseAddress, UINT32 regAddress,
+			      UINT32 regData);
+
+
+/**
+ * @fn UINT32 ixNpeDlNpeMgrExecAccRegRead (UINT32 npeBaseAddress,
+                                           UINT32 regAddress)
+ * 
+ * @brief Reads the contents of an NPE Execution Access register
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] regAddress     - NPE Execution Access register address
+ * 
+ * This function is used to read the contents of an NPE Execution
+ * Access register.
+ * 
+ * @pre
+ *
+ * @post
+ *
+ * @return The value read from the Execution Access register
+ */ 
+UINT32
+ixNpeDlNpeMgrExecAccRegRead (UINT32 npeBaseAddress, UINT32 regAddress);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrCommandIssue (UINT32 npeBaseAddress,
+                                       UINT32 command)
+ * 
+ * @brief Issues an NPE Execution Control command
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] command        - Command to issue
+ * 
+ * This function is used to issue a stand-alone NPE Execution Control command
+ * (e.g. command to Stop NPE execution)
+ * 
+ * @pre
+ *
+ * @post
+ *
+ * @return none
+ */ 
+void
+ixNpeDlNpeMgrCommandIssue (UINT32 npeBaseAddress, UINT32 command);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrDebugInstructionPreExec (UINT32 npeBaseAddress)
+ * 
+ * @brief Prepare to executes one or more NPE instructions in the Debug
+ *        Execution Stack level.
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * 
+ * This function should be called once before a sequence of calls to 
+ * ixNpeDlNpeMgrDebugInstructionExec().
+ * 
+ * @pre
+ *
+ * @post
+ *     - ixNpeDlNpeMgrDebugInstructionPostExec() should be called to restore
+ *       registers values altered by this function
+ *
+ * @return none
+ */ 
+void
+ixNpeDlNpeMgrDebugInstructionPreExec (UINT32 npeBaseAddress);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrDebugInstructionExec (UINT32 npeBaseAddress,
+                                               UINT32 npeInstruction,
+                                               UINT32 ctxtNum,
+                                               UINT32 ldur)
+ * 
+ * @brief Executes a single instruction on the NPE at the Debug Execution Stack
+ *        level
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] npeInstruction - Value to write to INSTR (Instruction)
+ *                                     register
+ * @param UINT32 [in] ctxtNum        - context the instruction will be executed
+ *                                     in and which context store it may access
+ * @param UINT32 [in] ldur           - Long Immediate Duration, set to non-zero
+ *                                     to use long-immediate mode instruction
+ * 
+ * This function is used to execute a single instruction in the NPE pipeline at
+ * the debug Execution Context Stack level. It won't disturb the state of other
+ * executing contexts.  Its useful for performing NPE operations, such as
+ * writing to NPE Context Store registers and physical registers, that cannot
+ * be carried out directly using the Configuration Bus registers. This function
+ * will return TIMEOUT status if NPE not responding due to NPS is hang / halt.
+ * 
+ * @pre 
+ *     - The NPE should be stopped and in a clean state
+ *     - ixNpeDlNpeMgrDebugInstructionPreExec() should be called once before
+ *       a sequential of 1 or more calls to this function
+ *
+ * @post
+ *     - ixNpeDlNpeMgrDebugInstructionPostExec() should be called after 
+ *       a sequence of calls to this function
+ *
+ * @return 
+ *    - IX_NPEDL_CRITICAL_NPE_ERR if execution of instruction failed / timeout
+ *    - IX_SUCCESS otherwise 
+ */ 
+IX_STATUS
+ixNpeDlNpeMgrDebugInstructionExec (UINT32 npeBaseAddress,
+				   UINT32 npeInstruction,
+				   UINT32 ctxtNum, UINT32 ldur);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrDebugInstructionPostExec (UINT32 npeBaseAddress)
+ * 
+ * @brief Clean up after executing one or more NPE instructions in the
+ *        Debug Stack Level
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * 
+ * This function should be called once following a sequence of calls to 
+ * ixNpeDlNpeMgrDebugInstructionExec().
+ *
+ * @pre 
+ *    -  ixNpeDlNpeMgrDebugInstructionPreExec() was called earlier
+ *
+ * @post
+ *    -  The Instruction Pipeline will cleared
+ *
+ * @return none
+ */ 
+void
+ixNpeDlNpeMgrDebugInstructionPostExec (UINT32 npeBaseAddress);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrPhysicalRegWrite (UINT32 npeBaseAddress,
+                                                UINT32 regAddr,
+                                                UINT32 regValue,
+					        BOOL verify)
+ * 
+ * @brief Write one of the 32* 32-bit physical registers in the NPE data 
+ *        register file
+ *
+ * @param UINT32 [in] npeBaseAddress - Base Address of NPE
+ * @param UINT32 [in] regAddr        - number of the physical register (0-31)*
+ * @param UINT32 [in] regValue       - value to write to the physical register
+ * @param BOOL   [in] verify         - if true, verify the register is written
+ *                                     successfully.
+ * 
+ * This function writes a physical register in the NPE data register file.
+ * If the <i>verify</i> option is ON, NpeDl will read back the register to 
+ * verify that it was written successfully
+ * *Note that release 1.0 of this software supports 32 physical
+ * registers, but 64 may be supported in future versions.
+ * 
+ * @pre
+ *    - The NPE should be stopped and in a clean state
+ *    - ixNpeDlNpeMgrDebugInstructionPreExec() should be called once before
+ *      a sequential of 1 or more calls to this function
+ *
+ * @post
+ *    - Contents of REGMAP Context Store register for Context 0 will be altered
+ *    - ixNpeDlNpeMgrDebugInstructionPostExec() should be called after 
+ *      a sequence of calls to this function
+ *
+ * @return
+ *    - IX_FAIL if verify is true and the Context Register was not written
+ *      successfully
+ *    - IX_SUCCESS if Context Register was written successfully
+ *    - IX_NPEDL_CRITICAL_NPE_ERR if Context Register was not written 
+ *      successfully due to timeout error where NPE is not responding
+ */
+IX_STATUS
+ixNpeDlNpeMgrPhysicalRegWrite (UINT32 npeBaseAddress, UINT32 regAddr,
+			       UINT32 regValue, BOOL verify);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrCtxtRegWrite (UINT32 npeBaseAddress,
+                                            UINT32 ctxtNum,
+                                            IxNpeDlCtxtRegNum ctxtReg,
+                                            UINT32 ctxtRegVal,
+                                            BOOL verify)
+ * 
+ * @brief Writes a value to a Context Store register on an NPE
+ *
+ * @param UINT32 [in] npeBaseAddress     - Base Address of NPE
+ * @param UINT32 [in] ctxtNum            - context store to access
+ * @param IxNpeDlCtxtRegNum [in] ctxtReg - which Context Store reg to write
+ * @param UINT32 [in] ctxtRegVal         - value to write to the Context Store
+ *                                         register
+ * @param BOOL   [in] verify             - if true, verify the register is
+ *                                         written successfully.
+ * 
+ * This function writes the contents of a Context Store register in the NPE 
+ * register file. If the <i>verify</i> option is ON, NpeDl will read back the
+ * register to verify that it was written successfully
+ * 
+ * @pre
+ *    - The NPE should be stopped and in a clean state
+ *    - ixNpeDlNpeMgrDebugInstructionPreExec() should be called once before
+ *      a sequential of 1 or more calls to this function
+ *
+ * @post
+ *    - ixNpeDlNpeMgrDebugInstructionPostExec() should be called after 
+ *      a sequence of calls to this function
+ *
+ * @return
+ *    - IX_FAIL if verify is true and the Context Register was not written
+ *      successfully
+ *    - IX_SUCCESS if Context Register was written successfully
+ *    - IX_NPEDL_CRITICAL_NPE_ERR if Context Register was not written 
+ *      successfully due to timeout error where NPE is not responding
+ */
+IX_STATUS
+ixNpeDlNpeMgrCtxtRegWrite (UINT32 npeBaseAddress, UINT32 ctxtNum,
+			   IxNpeDlCtxtRegNum ctxtReg, UINT32 ctxtRegVal,
+			   BOOL verify);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrUtilsStatsShow (void)
+ *
+ * @brief This function will display the statistics of the IxNpeDl NpeMgrUtils
+ *        module
+ *
+ * @return none
+ */
+void
+ixNpeDlNpeMgrUtilsStatsShow (void);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrUtilsStatsReset (void)
+ *
+ * @brief This function will reset the statistics of the IxNpeDl NpeMgrUtils
+ *        module
+ *
+ * @return none
+ */
+void
+ixNpeDlNpeMgrUtilsStatsReset (void);
+
+
+#endif  /* IXNPEDLNPEMGRUTILS_P_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeDlNpeMgr_p.h b/marvell/uboot/drivers/net/npe/include/IxNpeDlNpeMgr_p.h
new file mode 100644
index 0000000..989db2c
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeDlNpeMgr_p.h
@@ -0,0 +1,236 @@
+/**
+ * @file IxNpeDlNpeMgr_p.h
+ *
+ * @author Intel Corporation
+ * @date 14 December 2001
+ * @brief This file contains the private API for the NpeMgr module.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+
+/**
+ * @defgroup IxNpeDlNpeMgr_p IxNpeDlNpeMgr_p
+ *
+ * @brief The private API for the IxNpeDl NpeMgr module
+ * 
+ * @{
+ */
+
+#ifndef IXNPEDLNPEMGR_P_H
+#define IXNPEDLNPEMGR_P_H
+
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxNpeDl.h"
+#include "IxOsalTypes.h"
+
+
+/*
+ * Function Prototypes
+ */
+
+
+/**
+ * @fn void ixNpeDlNpeMgrInit (void)
+ * 
+ * @brief Initialises the NpeMgr module
+ *
+ * @param none
+ * 
+ * This function initialises the NpeMgr module.
+ * It should be called before any other function in this module is called.
+ * It only needs to be called once, but can be called multiple times safely.
+ * The code will ASSERT on failure.
+ * 
+ * @pre
+ *     - It must be called before any other function in this module
+ *
+ * @post
+ *     - NPE Configuration Register memory space will be mapped using
+ *       IxOsal. This memory will not be unmapped by this module.
+ *
+ * @return none
+ */ 
+void
+ixNpeDlNpeMgrInit (void);
+
+
+/**
+ * @fn IX_STATUS ixNpeMhNpeMgrUninit (void)
+ *
+ * @brief This function will uninitialise the IxNpeDlNpeMgr sub-component.
+ *
+ * This function will uninitialise the IxNpeDlNpeMgr sub-component.
+ * It should only be called once, and only if the IxNpeDlNpeMgr sub-component
+ * has already been initialised by calling @ref ixNpeDlNpeMgrInit().
+ * No other IxNpeDlNpeMgr sub-component API functions should be called
+ * until @ref ixNpeDlNpeMgrInit() is called again.
+ * If possible, this function should be called before a soft reboot or unloading
+ * a kernel module to perform any clean up operations required for IxNpeMh.
+ *
+ * @return
+ *      - IX_SUCCESS if the operation was successful
+ *      - IX_FAIL otherwise
+ */
+
+IX_STATUS ixNpeDlNpeMgrUninit (void);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrImageLoad (IxNpeDlNpeId npeId,
+                                           UINT32 *imageCodePtr,
+                                           BOOL verify)
+ * 
+ * @brief Loads a image of microcode onto an NPE
+ *
+ * @param IxNpeDlNpeId [in] npeId     - Id of target NPE
+ * @param UINT32* [in] imageCodePtr - pointer to image code in image to be
+ *                                      downloaded
+ * @param BOOL [in] verify            - if true, verify each word written to
+ *                                      NPE memory.
+ * 
+ * This function loads a image containing blocks of microcode onto a
+ * particular NPE. If the <i>verify</i> option is ON, NpeDl will read back each
+ * word written and verify that it was written successfully
+ * 
+ * @pre
+ *     - The NPE should be stopped beforehand
+ *
+ * @post
+ *     - The NPE Instruction Pipeline may be flushed clean
+ *
+ * @return
+ *     - IX_SUCCESS if the download was successful
+ *     - IX_FAIL if the download failed
+ *     - IX_NPEDL_CRITICAL_NPE_ERR if the download failed due to timeout error 
+ *       where NPE is not responding
+ */ 
+IX_STATUS
+ixNpeDlNpeMgrImageLoad (IxNpeDlNpeId npeId, UINT32 *imageCodePtr,
+			  BOOL verify);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrNpeReset (IxNpeDlNpeId npeId)
+ * 
+ * @brief sets a NPE to RESET state
+ *
+ * @param IxNpeDlNpeId [in] npeId - id of target NPE
+ * 
+ * This function performs a soft NPE reset by writing reset values to the
+ * Configuration Bus Execution Control registers, the Execution Context Stack
+ * registers, the Physical Register file, and the Context Store registers for 
+ * each context number. It also clears inFIFO, outFIFO and Watchpoint FIFO.
+ * It does not reset NPE Co-processors.
+ * 
+ * @pre
+ *     - The NPE should be stopped beforehand
+ *
+ * @post
+ *     - NPE NextProgram Counter (NextPC) will be set to a fixed initial value,
+ *       such as 0.  This should be explicitly set by downloading State
+ *       Information before starting NPE Execution.
+ *     - The NPE Instruction Pipeline will be in a clean state.
+ *
+ * @return
+ *     - IX_SUCCESS if the operation was successful
+ *     - IX_FAIL if the operation failed
+ *     - IX_NPEDL_CRITICAL_NPE_ERR if the operation failed due to NPE hang
+ */ 
+IX_STATUS
+ixNpeDlNpeMgrNpeReset (IxNpeDlNpeId npeId);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrNpeStart (IxNpeDlNpeId npeId)
+ * 
+ * @brief Starts NPE Execution
+ *
+ * @param IxNpeDlNpeId [in] npeId - Id of target NPE
+ * 
+ * Ensures only background Execution Stack Level is Active, clears instruction
+ * pipeline, and starts Execution on a NPE by sending a Start NPE command to
+ * the NPE. Checks the execution status of the NPE to verify that it is
+ * running.
+ * 
+ * @pre
+ *     - The NPE should be stopped beforehand.
+ *     - Note that this function does not set the NPE Next Program Counter 
+ *       (NextPC), so it should be set beforehand if required by downloading 
+ *       appropriate State Information.
+ *
+ * @post
+ *
+ * @return
+ *     - IX_SUCCESS if the operation was successful
+ *     - IX_FAIL otherwise
+ */ 
+IX_STATUS
+ixNpeDlNpeMgrNpeStart (IxNpeDlNpeId npeId);
+
+
+/**
+ * @fn IX_STATUS ixNpeDlNpeMgrNpeStop (IxNpeDlNpeId npeId)
+ * 
+ * @brief Halts NPE Execution
+ *
+ * @param IxNpeDlNpeId [in] npeId - id of target NPE
+ * 
+ * Stops execution on an NPE by sending a Stop NPE command to the NPE.
+ * Checks the execution status of the NPE to verify that it has stopped.
+ *
+ * @pre
+ *
+ * @post
+ *
+ * @return 
+ *     - IX_SUCCESS if the operation was successful
+ *     - IX_FAIL otherwise
+ */ 
+IX_STATUS
+ixNpeDlNpeMgrNpeStop (IxNpeDlNpeId npeId);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrStatsShow (void)
+ *
+ * @brief This function will display statistics of the IxNpeDl NpeMgr module
+ *
+ * @return none
+ */
+void
+ixNpeDlNpeMgrStatsShow (void);
+
+
+/**
+ * @fn void ixNpeDlNpeMgrStatsReset (void)
+ *
+ * @brief This function will reset the statistics of the IxNpeDl NpeMgr module
+ *
+ * @return none
+ */
+void
+ixNpeDlNpeMgrStatsReset (void);
+
+
+#endif /* IXNPEDLIMAGEMGR_P_H */
+
+/**
+ * @} defgroup IxNpeDlNpeMgr_p
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeMh.h b/marvell/uboot/drivers/net/npe/include/IxNpeMh.h
new file mode 100644
index 0000000..3a2bf9f
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeMh.h
@@ -0,0 +1,473 @@
+/**
+ * @file IxNpeMh.h
+ *
+ * @date 14 Dec 2001
+ *
+ * @brief This file contains the public API for the IXP400 NPE Message
+ * Handler component.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeMh IXP400 NPE Message Handler (IxNpeMh) API
+ *
+ * @brief The public API for the IXP400 NPE Message Handler component.
+ * 
+ * @{
+ */
+
+#ifndef IXNPEMH_H
+#define IXNPEMH_H
+
+#include "IxOsalTypes.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+#define IX_NPEMH_MIN_MESSAGE_ID (0x00) /**< minimum valid message ID */
+#define IX_NPEMH_MAX_MESSAGE_ID (0xFF) /**< maximum valid message ID */
+
+#define IX_NPEMH_SEND_RETRIES_DEFAULT (3) /**< default msg send retries */
+
+
+/**
+ * @def IX_NPEMH_CRITICAL_NPE_ERR
+ *
+ * @brief NpeMH function return value for a Critical NPE error occuring during
+          sending/receiving message. Assume NPE hang / halt if this value is
+          returned.
+ */
+#define IX_NPEMH_CRITICAL_NPE_ERR        2
+
+/**
+ * @enum IxNpeMhNpeId
+ *
+ * @brief The ID of a particular NPE.
+ * @note In this context, for IXP425 Silicon (B0):<br> 
+ *      - NPE-A has HDLC, HSS, AAL and UTOPIA Coprocessors.<br> 
+ *      - NPE-B has Ethernet Coprocessor.<br>
+ *      - NPE-C has Ethernet, AES, DES and HASH Coprocessors.<br>
+ *      - IXP400 Product Line have different combinations of coprocessors. 
+ */
+
+typedef enum
+{
+    IX_NPEMH_NPEID_NPEA = 0, /**< ID for NPE-A */
+    IX_NPEMH_NPEID_NPEB,     /**< ID for NPE-B */
+    IX_NPEMH_NPEID_NPEC,     /**< ID for NPE-C */
+    IX_NPEMH_NUM_NPES        /**< Number of NPEs */
+} IxNpeMhNpeId;
+
+/**
+ * @enum IxNpeMhNpeInterrupts
+ *
+ * @brief Indicator specifying whether or not NPE interrupts should drive
+ * receiving of messages from the NPEs.
+ */
+
+typedef enum
+{
+    IX_NPEMH_NPEINTERRUPTS_NO = 0, /**< Don't use NPE interrupts */
+    IX_NPEMH_NPEINTERRUPTS_YES     /**< Do use NPE interrupts */
+} IxNpeMhNpeInterrupts;
+
+/**
+ * @brief The 2-word message structure to send to and receive from the
+ * NPEs.
+ */
+
+typedef struct
+{
+    UINT32 data[2]; /**< the actual data of the message */
+} IxNpeMhMessage;
+
+/** message ID */
+typedef UINT32 IxNpeMhMessageId;
+
+/**
+ * @typedef IxNpeMhCallback
+ *
+ * @brief This prototype shows the format of a message callback function.
+ *
+ * This prototype shows the format of a message callback function.  The
+ * message callback will be passed the message to be handled and will also
+ * be told from which NPE the message was received.  The message callback
+ * will either be registered by ixNpeMhUnsolicitedCallbackRegister() or
+ * passed as a parameter to ixNpeMhMessageWithResponseSend().  It will be
+ * called from within an ISR triggered by the NPE's "outFIFO not empty"
+ * interrupt (see ixNpeMhInitialize()).  The parameters passed are the ID
+ * of the NPE that the message was received from, and the message to be
+ * handled.<P><B>Re-entrancy:</B> This function is only a prototype, and
+ * will be implemented by the client.  It does not need to be re-entrant.
+ */
+
+typedef void (*IxNpeMhCallback) (IxNpeMhNpeId, IxNpeMhMessage);
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhInitialize (
+           IxNpeMhNpeInterrupts npeInterrupts)
+ *
+ * @brief This function will initialise the IxNpeMh component.
+ *
+ * @param npeInterrupts @ref IxNpeMhNpeInterrupts [in] - This parameter
+ * dictates whether or not the IxNpeMh component will service NPE "outFIFO
+ * not empty" interrupts to trigger receiving and processing of messages
+ * from the NPEs.  If not then the client must use ixNpeMhMessagesReceive()
+ * to control message receiving and processing.
+ *
+ * This function will initialise the IxNpeMh component.  It should only be
+ * called once, prior to using the IxNpeMh component.  The following
+ * actions will be performed by this function:<OL><LI>Initialization of
+ * internal data structures (e.g. solicited and unsolicited callback
+ * tables).</LI><LI>Configuration of the interface with the NPEs (e.g.
+ * enabling of NPE "outFIFO not empty" interrupts).</LI><LI>Registration of
+ * ISRs that will receive and handle messages when the NPEs' "outFIFO not
+ * empty" interrupts fire (if npeInterrupts equals
+ * IX_NPEMH_NPEINTERRUPTS_YES).</LI></OL>
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+PUBLIC IX_STATUS ixNpeMhInitialize (
+    IxNpeMhNpeInterrupts npeInterrupts);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhUnload (void)
+ *
+ * @brief This function will uninitialise the IxNpeMh component.
+ *
+ * This function will uninitialise the IxNpeMh component.  It should only be
+ * called once, and only if the IxNpeMh component has already been initialised.
+ * No other IxNpeMh API functions should be called until @ref ixNpeMhInitialize
+ * is called again.
+ * If possible, this function should be called before a soft reboot or unloading
+ * a kernel module to perform any clean up operations required for IxNpeMh.
+ *
+ * The following actions will be performed by this function:
+ * <OL><LI>Unmapping of kernel memory mapped by the function
+ * @ref ixNpeMhInitialize.</LI></OL>
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+PUBLIC IX_STATUS ixNpeMhUnload (void);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhUnsolicitedCallbackRegister (
+           IxNpeMhNpeId npeId,
+           IxNpeMhMessageId messageId,
+           IxNpeMhCallback unsolicitedCallback)
+ *
+ * @brief This function will register an unsolicited callback for a
+ * particular NPE and message ID.
+ *
+ * @param npeId @ref IxNpeMhNpeId [in] - The ID of the NPE whose messages
+ * the unsolicited callback will handle.
+ * @param messageId @ref IxNpeMhMessageId [in] - The ID of the messages the
+ * unsolicited callback will handle.
+ * @param unsolicitedCallback @ref IxNpeMhCallback [in] - The unsolicited
+ * callback function.  A value of NULL will deregister any previously
+ * registered callback for this NPE and message ID.
+ *
+ * This function will register an unsolicited message callback for a
+ * particular NPE and message ID.<P>If an unsolicited callback is already
+ * registered for the specified NPE and message ID then the callback will
+ * be overwritten.  Only one client will be responsible for handling a
+ * particular message ID associated with a NPE.  Registering a NULL
+ * unsolicited callback will deregister any previously registered
+ * callback.<P>The callback function will be called from an ISR that will
+ * be triggered by the NPE's "outFIFO not empty" interrupt (see
+ * ixNpeMhInitialize()) to handle any unsolicited messages of the specific
+ * message ID received from the NPE.  Unsolicited messages will be handled
+ * in the order they are received.<P>If no unsolicited callback can be
+ * found for a received message then it is assumed that the message is
+ * solicited.<P>If more than one client may be interested in a particular
+ * unsolicited message then the suggested strategy is to register a
+ * callback for the message that can itself distribute the message to
+ * multiple clients as necessary.<P>See also
+ * ixNpeMhUnsolicitedCallbackForRangeRegister().<P><B>Re-entrancy:</B> This
+ * function will be callable from any thread at any time.  IxOsal
+ * will be used for any necessary resource protection.
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackRegister (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessageId messageId,
+    IxNpeMhCallback unsolicitedCallback);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhUnsolicitedCallbackForRangeRegister (
+           IxNpeMhNpeId npeId,
+           IxNpeMhMessageId minMessageId,
+           IxNpeMhMessageId maxMessageId,
+           IxNpeMhCallback unsolicitedCallback)
+ *
+ * @brief This function will register an unsolicited callback for a
+ * particular NPE and range of message IDs.
+ *
+ * @param npeId @ref IxNpeMhNpeId [in] - The ID of the NPE whose messages the
+ * unsolicited callback will handle.
+ * @param minMessageId @ref IxNpeMhMessageId [in] - The minimum message ID in
+ * the range of message IDs the unsolicited callback will handle.
+ * @param maxMessageId @ref IxNpeMhMessageId [in] - The maximum message ID in
+ * the range of message IDs the unsolicited callback will handle.
+ * @param unsolicitedCallback @ref IxNpeMhCallback [in] - The unsolicited
+ * callback function.  A value of NULL will deregister any previously
+ * registered callback(s) for this NPE and range of message IDs.
+ *
+ * This function will register an unsolicited callback for a particular NPE
+ * and range of message IDs.  It is a convenience function that is
+ * effectively the same as calling ixNpeMhUnsolicitedCallbackRegister() for
+ * each ID in the specified range.  See
+ * ixNpeMhUnsolicitedCallbackRegister() for more
+ * information.<P><B>Re-entrancy:</B> This function will be callable from
+ * any thread at any time.  IxOsal will be used for any necessary
+ * resource protection.
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackForRangeRegister (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessageId minMessageId,
+    IxNpeMhMessageId maxMessageId,
+    IxNpeMhCallback unsolicitedCallback);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhMessageSend (
+           IxNpeMhNpeId npeId,
+           IxNpeMhMessage message,
+           UINT32 maxSendRetries)
+ *
+ * @brief This function will send a message to a particular NPE.
+ *
+ * @param npeId @ref IxNpeMhNpeId [in] - The ID of the NPE to send the message
+ * to.
+ * @param message @ref IxNpeMhMessage [in] - The message to send.
+ * @param maxSendRetries UINT32 [in] - Max num. of retries to perform
+ * if the NPE's inFIFO is full.
+ *
+ * This function will send a message to a particular NPE.  It will be the
+ * client's responsibility to ensure that the message is properly formed.
+ * The return status will signify to the client if the message was
+ * successfully sent or not.<P>If the message is sent to the NPE then this
+ * function will return a status of success.  Note that this will only mean
+ * the message has been placed in the NPE's inFIFO.  There will be no way
+ * of knowing that the NPE has actually read the message, but once in the
+ * incoming message queue it will be safe to assume that the NPE will
+ * process it.
+ * <P>The inFIFO may fill up sometimes if the Xscale is sending messages
+ * faster than the NPE can handle them. This forces us to retry attempts 
+ * to send the message until the NPE services the inFIFO. The client should
+ * specify a ceiling value for the number of retries suitable to their
+ * needs. IX_NPEMH_SEND_RETRIES_DEFAULT can be used as a default value for
+ * the <i>maxSendRetries</i> parameter for this function. Each retry
+ * exceeding this default number will incur a blocking delay of 1 microsecond,
+ * to avoid consuming too much AHB bus bandwidth while performing retries.
+ * <P>Note this function <B>must</B> only be used for messages.
+ * that do not solicit responses. If the message being sent will solicit a
+ * response then the ixNpeMhMessageWithResponseSend() function <B>must</B>
+ * be used to ensure that the response is correctly
+ * handled. <P> This function will return timeout status if NPE hang / halt 
+ * while sending message. The timeout error is not related to the 
+ * <i>maxSendRetries</i> as mentioned above. The timeout error will only occur 
+ * if the first word of the message has been sent to NPE (not exceeding 
+ * <i>maxSendRetries</i> when sending 1st message word), but the second word of
+ * the message can't be written to NPE's inFIFO due to NPE hang / halt after 
+ * maximum waiting time (IX_NPE_MH_MAX_NUM_OF_RETRIES). 
+ * <P><B>Re-entrancy:</B> This function will be callable from any
+ * thread at any time.  IxOsal will be used for any necessary
+ * resource protection.
+ *
+ * @return The function returns a status indicating success, failure or timeout.
+ */
+
+PUBLIC IX_STATUS ixNpeMhMessageSend (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessage message,
+    UINT32 maxSendRetries);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhMessageWithResponseSend (
+           IxNpeMhNpeId npeId,
+           IxNpeMhMessage message,
+           IxNpeMhMessageId solicitedMessageId,
+           IxNpeMhCallback solicitedCallback,
+           UINT32 maxSendRetries)
+ *
+ * @brief This function is equivalent to the ixNpeMhMessageSend() function,
+ * but must be used when the message being sent will solicited a response.
+ *
+ * @param npeId @ref IxNpeMhNpeId [in] - The ID of the NPE to send the message
+ * to.
+ * @param message @ref IxNpeMhMessage [in] - The message to send.
+ * @param solicitedMessageId @ref IxNpeMhMessageId [in] - The ID of the
+ * solicited response message.
+ * @param solicitedCallback @ref IxNpeMhCallback [in] - The function to use to
+ * pass the response message back to the client.  A value of NULL will
+ * cause the response message to be discarded.
+ * @param maxSendRetries UINT32 [in] - Max num. of retries to perform
+ * if the NPE's inFIFO is full.
+ *
+ * This function is equivalent to the ixNpeMhMessageSend() function, but
+ * must be used when the message being sent will solicited a
+ * response.<P>The client must specify the ID of the solicited response
+ * message to allow the response to be recognised when it is received.  The
+ * client must also specify a callback function to handle the received
+ * response.  The IxNpeMh component will not offer the facility to send a
+ * message to a NPE and receive a response within the same context.<P>Note
+ * if the client is not interested in the response, specifying a NULL
+ * callback will cause the response message to be discarded.<P>The
+ * solicited callback will be stored and called some time later from an ISR
+ * that will be triggered by the NPE's "outFIFO not empty" interrupt (see
+ * ixNpeMhInitialize()) to handle the response message corresponding to the
+ * message sent.  Response messages will be handled in the order they are
+ * received.<P>
+ * <P>The inFIFO may fill up sometimes if the Xscale is sending messages
+ * faster than the NPE can handle them. This forces us to retry attempts 
+ * to send the message until the NPE services the inFIFO. The client should
+ * specify a ceiling value for the number of retries suitable to their
+ * needs. IX_NPEMH_SEND_RETRIES_DEFAULT can be used as a default value for
+ * the <i>maxSendRetries</i> parameter for this function. Each retry
+ * exceeding this default number will incur a blocking delay of 1 microsecond,
+ * to avoid consuming too much AHB bus bandwidth while performing retries.
+ * <P> This function will return timeout status if NPE hang / halt 
+ * while sending message. The timeout error is not related to the 
+ * <i>maxSendRetries</i> as mentioned above. The timeout error will only occur 
+ * if the first word of the message has been sent to NPE (not exceeding 
+ * <i>maxSendRetries</i> when sending 1st message word), but the second word of
+ * the message can't be written to NPE's inFIFO due to NPE hang / halt after 
+ * maximum waiting time (IX_NPE_MH_MAX_NUM_OF_RETRIES). 
+ * <P><B>Re-entrancy:</B> This function will be callable from any
+ * thread at any time.  IxOsal will be used for any necessary
+ * resource protection.
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+PUBLIC IX_STATUS ixNpeMhMessageWithResponseSend (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessage message,
+    IxNpeMhMessageId solicitedMessageId,
+    IxNpeMhCallback solicitedCallback,
+    UINT32 maxSendRetries);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhMessagesReceive (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function will receive messages from a particular NPE and
+ * pass each message to the client via a solicited callback (for solicited
+ * messages) or an unsolicited callback (for unsolicited messages).
+ *
+ * @param npeId @ref IxNpeMhNpeId [in] - The ID of the NPE to receive and
+ * process messages from.
+ *
+ * This function will receive messages from a particular NPE and pass each
+ * message to the client via a solicited callback (for solicited messages)
+ * or an unsolicited callback (for unsolicited messages).<P>If the IxNpeMh
+ * component is initialised to service NPE "outFIFO not empty" interrupts
+ * (see ixNpeMhInitialize()) then there is no need to call this function.
+ * This function is only provided as an alternative mechanism to control
+ * the receiving and processing of messages from the NPEs.<P> This function
+ * will return timeout status if NPE hang / halt while receiving message. The
+ * timeout error will only occur if this function has read the first word of
+ * the message and can't read second word of the message from NPE's outFIFO
+ * after maximum retries (IX_NPE_MH_MAX_NUM_OF_RETRIES). 
+ * <P>Note this function cannot be called from within 
+ * an ISR as it will use resource protection mechanisms.<P><B>Re-entrancy:</B> 
+ * This function will be callable from any thread at any time.  IxOsal will be 
+ * used for any necessary resource protection.
+ *
+ * @return The function returns a status indicating success, failure or timeout.
+ */
+
+PUBLIC IX_STATUS ixNpeMhMessagesReceive (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhShow (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function will display the current state of the IxNpeMh
+ * component.
+ *
+ * <B>Re-entrancy:</B> This function will be callable from
+ * any thread at any time.  However, no resource protection will be used
+ * so as not to impact system performance.  As this function is only
+ * reading statistical information then this is acceptable.
+ *
+ * @param npeId @ref IxNpeMhNpeId [in] - The ID of the NPE to display state
+ * information for.
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+PUBLIC IX_STATUS ixNpeMhShow (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @ingroup IxNpeMh
+ *
+ * @fn IX_STATUS ixNpeMhShowReset (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function will reset the current state of the IxNpeMh
+ * component.
+ *
+ * <B>Re-entrancy:</B> This function will be callable from
+ * any thread at any time.  However, no resource protection will be used
+ * so as not to impact system performance.  As this function is only
+ * writing statistical information then this is acceptable.
+ *
+ * @param npeId @ref IxNpeMhNpeId [in] - The ID of the NPE to reset state
+ * information for.
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+PUBLIC IX_STATUS ixNpeMhShowReset (
+    IxNpeMhNpeId npeId);
+
+#endif /* IXNPEMH_H */
+
+/**
+ * @} defgroup IxNpeMh
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeMhConfig_p.h b/marvell/uboot/drivers/net/npe/include/IxNpeMhConfig_p.h
new file mode 100644
index 0000000..ca47f7f
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeMhConfig_p.h
@@ -0,0 +1,531 @@
+/**
+ * @file IxNpeMhConfig_p.h
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the private API for the Configuration module.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeMhConfig_p IxNpeMhConfig_p
+ *
+ * @brief The private API for the Configuration module.
+ * 
+ * @{
+ */
+
+#ifndef IXNPEMHCONFIG_P_H
+#define IXNPEMHCONFIG_P_H
+
+#include "IxOsal.h"
+
+#include "IxNpeMh.h"
+#include "IxNpeMhMacros_p.h"
+
+/*
+ * inline definition
+ */
+/* enable function inlining for performances */
+#ifdef IXNPEMHSOLICITEDCBMGR_C
+/* Non-inline functions will be defined in this translation unit. 
+	 Reason is that in GNU Compiler, if the Optimization is turn off, all extern inline
+	 functions will not be compiled.
+*/
+#		ifndef __wince
+#			ifndef IXNPEMHCONFIG_INLINE
+#				define IXNPEMHCONFIG_INLINE 
+#			endif
+#		else
+#			ifndef IXNPEMHCONFIG_INLINE
+#				define IXNPEMHCONFIG_INLINE IX_OSAL_INLINE_EXTERN
+#			endif
+#		endif /* __wince*/
+
+#else
+
+#		ifndef IXNPEMHCONFIG_INLINE
+#			define IXNPEMHCONFIG_INLINE IX_OSAL_INLINE_EXTERN
+#		endif /* IXNPEMHCONFIG_INLINE */
+#endif /* IXNPEMHSOLICITEDCBMGR_C */
+/*
+ * Typedefs and #defines, etc.
+ */
+ 
+typedef void (*IxNpeMhConfigIsr) (int); /**< ISR function pointer */
+
+/**
+ * @struct IxNpeMhConfigNpeInfo
+ *
+ * @brief This structure is used to maintain the configuration information
+ * associated with an NPE.
+ */
+
+typedef struct
+{
+    IxOsalMutex mutex;          /**< mutex */
+    UINT32 interruptId;     /**< interrupt ID */
+    UINT32 virtualRegisterBase; /**< register virtual base address */
+    UINT32 statusRegister;      /**< status register virtual address */
+    UINT32 controlRegister;     /**< control register virtual address */
+    UINT32 inFifoRegister;      /**< inFIFO register virutal address */
+    UINT32 outFifoRegister;     /**< outFIFO register virtual address */
+    IxNpeMhConfigIsr isr;   /**< isr routine for handling interrupt */
+    BOOL oldInterruptState; /**< old interrupt state (true => enabled) */
+} IxNpeMhConfigNpeInfo;
+
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/**< NPE register base address */
+#define IX_NPEMH_NPE_BASE (IX_OSAL_IXP400_PERIPHERAL_PHYS_BASE)
+
+#define IX_NPEMH_NPEA_OFFSET (0x6000) /**< NPE-A register base offset */
+#define IX_NPEMH_NPEB_OFFSET (0x7000) /**< NPE-B register base offset */
+#define IX_NPEMH_NPEC_OFFSET (0x8000) /**< NPE-C register base offset */
+
+#define IX_NPEMH_NPESTAT_OFFSET (0x002C) /**< NPE status register offset */
+#define IX_NPEMH_NPECTL_OFFSET  (0x0030) /**< NPE control register offset */
+#define IX_NPEMH_NPEFIFO_OFFSET (0x0038) /**< NPE FIFO register offset */
+
+/** NPE-A register base address */
+#define IX_NPEMH_NPEA_BASE (IX_NPEMH_NPE_BASE + IX_NPEMH_NPEA_OFFSET)
+/** NPE-B register base address */
+#define IX_NPEMH_NPEB_BASE (IX_NPEMH_NPE_BASE + IX_NPEMH_NPEB_OFFSET)
+/** NPE-C register base address */
+#define IX_NPEMH_NPEC_BASE (IX_NPEMH_NPE_BASE + IX_NPEMH_NPEC_OFFSET)
+
+/* NPE-A configuration */
+
+/** NPE-A interrupt */
+#define IX_NPEMH_NPEA_INT  (IX_OSAL_IXP400_NPEA_IRQ_LVL)
+/** NPE-A FIFO register */
+#define IX_NPEMH_NPEA_FIFO (IX_NPEMH_NPEA_BASE + IX_NPEMH_NPEFIFO_OFFSET)
+/** NPE-A control register */
+#define IX_NPEMH_NPEA_CTL  (IX_NPEMH_NPEA_BASE + IX_NPEMH_NPECTL_OFFSET)
+/** NPE-A status register */
+#define IX_NPEMH_NPEA_STAT (IX_NPEMH_NPEA_BASE + IX_NPEMH_NPESTAT_OFFSET)
+
+/* NPE-B configuration */
+
+/** NPE-B interrupt */
+#define IX_NPEMH_NPEB_INT  (IX_OSAL_IXP400_NPEB_IRQ_LVL)
+/** NPE-B FIFO register */
+#define IX_NPEMH_NPEB_FIFO (IX_NPEMH_NPEB_BASE + IX_NPEMH_NPEFIFO_OFFSET)
+/** NPE-B control register */
+#define IX_NPEMH_NPEB_CTL  (IX_NPEMH_NPEB_BASE + IX_NPEMH_NPECTL_OFFSET)
+/** NPE-B status register */
+#define IX_NPEMH_NPEB_STAT (IX_NPEMH_NPEB_BASE + IX_NPEMH_NPESTAT_OFFSET)
+
+/* NPE-C configuration */
+
+/** NPE-C interrupt */
+#define IX_NPEMH_NPEC_INT  (IX_OSAL_IXP400_NPEC_IRQ_LVL)
+/** NPE-C FIFO register */
+#define IX_NPEMH_NPEC_FIFO (IX_NPEMH_NPEC_BASE + IX_NPEMH_NPEFIFO_OFFSET)
+/** NPE-C control register */
+#define IX_NPEMH_NPEC_CTL  (IX_NPEMH_NPEC_BASE + IX_NPEMH_NPECTL_OFFSET)
+/** NPE-C status register */
+#define IX_NPEMH_NPEC_STAT (IX_NPEMH_NPEC_BASE + IX_NPEMH_NPESTAT_OFFSET)
+
+/* NPE control register bit definitions */
+#define IX_NPEMH_NPE_CTL_OFE   (1 << 16) /**< OutFifoEnable */
+#define IX_NPEMH_NPE_CTL_IFE   (1 << 17) /**< InFifoEnable */
+#define IX_NPEMH_NPE_CTL_OFEWE (1 << 24) /**< OutFifoEnableWriteEnable */
+#define IX_NPEMH_NPE_CTL_IFEWE (1 << 25) /**< InFifoEnableWriteEnable */
+
+/* NPE status register bit definitions */
+#define IX_NPEMH_NPE_STAT_OFNE  (1 << 16) /**< OutFifoNotEmpty */
+#define IX_NPEMH_NPE_STAT_IFNF  (1 << 17) /**< InFifoNotFull */
+#define IX_NPEMH_NPE_STAT_OFNF  (1 << 18) /**< OutFifoNotFull */
+#define IX_NPEMH_NPE_STAT_IFNE  (1 << 19) /**< InFifoNotEmpty */
+#define IX_NPEMH_NPE_STAT_MBINT (1 << 20) /**< Mailbox interrupt */
+#define IX_NPEMH_NPE_STAT_IFINT (1 << 21) /**< InFifo interrupt */
+#define IX_NPEMH_NPE_STAT_OFINT (1 << 22) /**< OutFifo interrupt */
+#define IX_NPEMH_NPE_STAT_WFINT (1 << 23) /**< WatchFifo interrupt */
+
+
+/**
+ * Variable declarations.  Externs are followed by static variables.
+ */
+extern IxNpeMhConfigNpeInfo ixNpeMhConfigNpeInfo[IX_NPEMH_NUM_NPES];
+
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @fn void ixNpeMhConfigInitialize (
+           IxNpeMhNpeInterrupts npeInterrupts)
+ *
+ * @brief This function initialises the Configuration module.
+ *
+ * @param IxNpeMhNpeInterrupts npeInterrupts (in) - whether or not to
+ * service the NPE "outFIFO not empty" interrupts.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhConfigInitialize (
+    IxNpeMhNpeInterrupts npeInterrupts);
+
+/**
+ * @fn void ixNpeMhConfigUninit (void)
+ *
+ * @brief This function uninitialises the Configuration module.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhConfigUninit (void);
+
+/**
+ * @fn void ixNpeMhConfigIsrRegister (
+           IxNpeMhNpeId npeId,
+           IxNpeMhConfigIsr isr)
+ *
+ * @brief This function registers an ISR to handle NPE "outFIFO not
+ * empty" interrupts.
+ *
+ * @param IxNpeMhNpeId npeId (in) - the ID of the NPE whose interrupt will
+ * be handled.
+ * @param IxNpeMhConfigIsr isr (in) - the ISR function pointer that the
+ * interrupt will trigger.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhConfigIsrRegister (
+    IxNpeMhNpeId npeId,
+    IxNpeMhConfigIsr isr);
+
+/**
+ * @fn BOOL ixNpeMhConfigNpeInterruptEnable (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function enables a NPE's "outFIFO not empty" interrupt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - the ID of the NPE whose interrupt will
+ * be enabled.
+ *
+ * @return Returns the previous state of the interrupt (true => enabled).
+ */
+
+BOOL ixNpeMhConfigNpeInterruptEnable (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn BOOL ixNpeMhConfigNpeInterruptDisable (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function disables a NPE's "outFIFO not empty" interrupt
+ *
+ * @param IxNpeMhNpeId npeId (in) - the ID of the NPE whose interrupt will
+ * be disabled.
+ *
+ * @return Returns the previous state of the interrupt (true => enabled).
+ */
+
+BOOL ixNpeMhConfigNpeInterruptDisable (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn IxNpeMhMessageId ixNpeMhConfigMessageIdGet (
+           IxNpeMhMessage message)
+ *
+ * @brief This function gets the ID of a message.
+ *
+ * @param IxNpeMhMessage message (in) - the message to get the ID of.
+ *
+ * @return the ID of the message
+ */
+
+IxNpeMhMessageId ixNpeMhConfigMessageIdGet (
+    IxNpeMhMessage message);
+
+/**
+ * @fn BOOL ixNpeMhConfigNpeIdIsValid (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function checks to see if a NPE ID is valid.
+ *
+ * @param IxNpeMhNpeId npeId (in) - the NPE ID to validate.
+ *
+ * @return true if the NPE ID is valid, otherwise false.
+ */
+
+BOOL ixNpeMhConfigNpeIdIsValid (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhConfigLockGet (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function gets a lock for exclusive NPE interaction, and
+ * disables the NPE's "outFIFO not empty" interrupt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which to get the
+ * lock and disable its interrupt.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhConfigLockGet (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhConfigLockRelease (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function releases a lock for exclusive NPE interaction, and
+ * enables the NPE's "outFIFO not empty" interrupt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which to release
+ * the lock and enable its interrupt.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhConfigLockRelease (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn BOOL ixNpeMhConfigInFifoIsEmpty (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This inline function checks if a NPE's inFIFO is empty.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which the inFIFO
+ * will be checked.
+ *
+ * @return true if the inFIFO is empty, otherwise false.
+ */
+
+IXNPEMHCONFIG_INLINE BOOL ixNpeMhConfigInFifoIsEmpty (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn BOOL ixNpeMhConfigInFifoIsFull (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This inline function checks if a NPE's inFIFO is full.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which the inFIFO
+ * will be checked.
+ *
+ * @return true if the inFIFO is full, otherwise false.
+ */
+
+IXNPEMHCONFIG_INLINE BOOL ixNpeMhConfigInFifoIsFull (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn BOOL ixNpeMhConfigOutFifoIsEmpty (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This inline function checks if a NPE's outFIFO is empty.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which the outFIFO
+ * will be checked.
+ *
+ * @return true if the outFIFO is empty, otherwise false.
+ */
+
+IXNPEMHCONFIG_INLINE BOOL ixNpeMhConfigOutFifoIsEmpty (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn BOOL ixNpeMhConfigOutFifoIsFull (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This inline function checks if a NPE's outFIFO is full.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which the outFIFO
+ * will be checked.
+ *
+ * @return true if the outFIFO is full, otherwise false.
+ */
+
+IXNPEMHCONFIG_INLINE BOOL ixNpeMhConfigOutFifoIsFull (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn IX_STATUS ixNpeMhConfigInFifoWrite (
+           IxNpeMhNpeId npeId,
+           IxNpeMhMessage message)
+ *
+ * @brief This function writes a message to a NPE's inFIFO.  The caller
+ * must first check that the NPE's inFifo is not full. After writing the first 
+ * word of the message, this function will keep polling NPE's inFIFO is not
+ * full to write the second word. If inFIFO is not available after maximum 
+ * retries (IX_NPE_MH_MAX_NUM_OF_RETRIES), this function will return TIMEOUT 
+ * status to indicate NPE hang / halt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which the inFIFO
+ * will be written to.
+ * @param IxNpeMhMessage message (in) - The message to write.
+ *
+ * @return The function returns a status indicating success, failure or timeout.
+ */
+
+IX_STATUS ixNpeMhConfigInFifoWrite (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessage message);
+
+/**
+ * @fn IX_STATUS ixNpeMhConfigOutFifoRead (
+           IxNpeMhNpeId npeId,
+           IxNpeMhMessage *message)
+ *
+ * @brief This function reads a message from a NPE's outFIFO.  The caller
+ * must first check that the NPE's outFifo is not empty. After reading the first 
+ * word of the message, this function will keep polling NPE's outFIFO is not
+ * empty to read the second word. If outFIFO is empty after maximum 
+ * retries (IX_NPE_MH_MAX_NUM_OF_RETRIES), this function will return TIMEOUT 
+ * status to indicate NPE hang / halt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE for which the outFIFO
+ * will be read from.
+ * @param IxNpeMhMessage message (out) - The message read.
+ *
+ * @return The function returns a status indicating success, failure or timeout.
+ */
+
+IX_STATUS ixNpeMhConfigOutFifoRead (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessage *message);
+
+/**
+ * @fn void ixNpeMhConfigShow (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function will display the current state of the Configuration
+ * module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to display state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhConfigShow (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhConfigShowReset (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function will reset the current state of the Configuration
+ * module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to reset state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhConfigShowReset (
+    IxNpeMhNpeId npeId);
+
+/*
+ * Inline functions
+ */
+ 
+/*
+ * This inline function checks if a NPE's inFIFO is empty.
+ */
+
+IXNPEMHCONFIG_INLINE
+BOOL ixNpeMhConfigInFifoIsEmpty (
+    IxNpeMhNpeId npeId)
+{
+    UINT32 ifne;
+    volatile UINT32 *statusReg =
+        (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
+
+    /* get the IFNE (InFifoNotEmpty) bit of the status register */
+    IX_NPEMH_REGISTER_READ_BITS (statusReg, &ifne, IX_NPEMH_NPE_STAT_IFNE);
+
+    /* if the IFNE status bit is unset then the inFIFO is empty */
+    return (ifne == 0);
+}
+
+
+/*
+ * This inline function checks if a NPE's inFIFO is full.
+ */
+IXNPEMHCONFIG_INLINE
+BOOL ixNpeMhConfigInFifoIsFull (
+    IxNpeMhNpeId npeId)
+{
+    UINT32 ifnf;
+    volatile UINT32 *statusReg =
+        (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
+
+    /* get the IFNF (InFifoNotFull) bit of the status register */
+    IX_NPEMH_REGISTER_READ_BITS (statusReg, &ifnf, IX_NPEMH_NPE_STAT_IFNF);
+
+    /* if the IFNF status bit is unset then the inFIFO is full */
+    return (ifnf == 0);
+}
+
+
+/*
+ * This inline function checks if a NPE's outFIFO is empty.
+ */
+IXNPEMHCONFIG_INLINE
+BOOL ixNpeMhConfigOutFifoIsEmpty (
+    IxNpeMhNpeId npeId)
+{
+    UINT32 ofne;
+    volatile UINT32 *statusReg =
+        (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
+
+    /* get the OFNE (OutFifoNotEmpty) bit of the status register */
+    IX_NPEMH_REGISTER_READ_BITS (statusReg, &ofne, IX_NPEMH_NPE_STAT_OFNE);
+
+    /* if the OFNE status bit is unset then the outFIFO is empty */
+    return (ofne == 0);
+}
+
+/*
+ * This inline function checks if a NPE's outFIFO is full.
+ */
+IXNPEMHCONFIG_INLINE
+BOOL ixNpeMhConfigOutFifoIsFull (
+    IxNpeMhNpeId npeId)
+{
+    UINT32 ofnf;
+    volatile UINT32 *statusReg =
+        (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
+
+    /* get the OFNF (OutFifoNotFull) bit of the status register */
+    IX_NPEMH_REGISTER_READ_BITS (statusReg, &ofnf, IX_NPEMH_NPE_STAT_OFNF);
+
+    /* if the OFNF status bit is unset then the outFIFO is full */
+    return (ofnf == 0);
+}
+
+#endif /* IXNPEMHCONFIG_P_H */
+
+/**
+ * @} defgroup IxNpeMhConfig_p
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeMhMacros_p.h b/marvell/uboot/drivers/net/npe/include/IxNpeMhMacros_p.h
new file mode 100644
index 0000000..51ee9e2
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeMhMacros_p.h
@@ -0,0 +1,272 @@
+/**
+ * @file IxNpeMhMacros_p.h
+ *
+ * @author Intel Corporation
+ * @date 21 Jan 2002
+ *
+ * @brief This file contains the macros for the IxNpeMh component.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeMhMacros_p IxNpeMhMacros_p
+ *
+ * @brief Macros for the IxNpeMh component.
+ * 
+ * @{
+ */
+
+#ifndef IXNPEMHMACROS_P_H
+#define IXNPEMHMACROS_P_H
+
+/* if we are running as a unit test */
+#ifdef IX_UNIT_TEST
+#undef NDEBUG
+#endif /* #ifdef IX_UNIT_TEST */
+
+#include "IxOsal.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+#define IX_NPEMH_SHOW_TEXT_WIDTH (40) /**< text width for stats display */
+#define IX_NPEMH_SHOW_STAT_WIDTH (10) /**< stat width for stats display */
+
+/**
+ * @def IX_NPEMH_SHOW
+ *
+ * @brief Macro for displaying a stat preceded by a textual description.
+ */
+
+#define IX_NPEMH_SHOW(TEXT, STAT) \
+    ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, \
+               "%-40s: %10d\n", (int) TEXT, (int) STAT, 0, 0, 0, 0)
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @typedef IxNpeMhTraceTypes
+ *
+ * @brief Enumeration defining IxNpeMh trace levels
+ */
+
+typedef enum
+{
+    IX_NPEMH_TRACE_OFF     = IX_OSAL_LOG_LVL_NONE,    /**< no trace */
+    IX_NPEMH_WARNING       = IX_OSAL_LOG_LVL_WARNING, /**< warning */
+    IX_NPEMH_DEBUG         = IX_OSAL_LOG_LVL_MESSAGE, /**< debug */
+    IX_NPEMH_FN_ENTRY_EXIT = IX_OSAL_LOG_LVL_DEBUG3   /**< function entry/exit */
+} IxNpeMhTraceTypes;
+
+#ifdef IX_UNIT_TEST
+#define IX_NPEMH_TRACE_LEVEL (IX_NPEMH_FN_ENTRY_EXIT) /**< trace level */
+#else
+#define IX_NPEMH_TRACE_LEVEL (IX_NPEMH_TRACE_OFF) /**< trace level */
+#endif
+
+/**
+ * @def IX_NPEMH_TRACE0
+ *
+ * @brief Trace macro taking 0 arguments.
+ */
+
+#define IX_NPEMH_TRACE0(LEVEL, STR) \
+    IX_NPEMH_TRACE6(LEVEL, STR, 0, 0, 0, 0, 0, 0)
+
+/**
+ * @def IX_NPEMH_TRACE1
+ *
+ * @brief Trace macro taking 1 argument.
+ */
+
+#define IX_NPEMH_TRACE1(LEVEL, STR, ARG1) \
+    IX_NPEMH_TRACE6(LEVEL, STR, ARG1, 0, 0, 0, 0, 0)
+
+/**
+ * @def IX_NPEMH_TRACE2
+ *
+ * @brief Trace macro taking 2 arguments.
+ */
+
+#define IX_NPEMH_TRACE2(LEVEL, STR, ARG1, ARG2) \
+    IX_NPEMH_TRACE6(LEVEL, STR, ARG1, ARG2, 0, 0, 0, 0)
+
+/**
+ * @def IX_NPEMH_TRACE3
+ *
+ * @brief Trace macro taking 3 arguments.
+ */
+
+#define IX_NPEMH_TRACE3(LEVEL, STR, ARG1, ARG2, ARG3) \
+    IX_NPEMH_TRACE6(LEVEL, STR, ARG1, ARG2, ARG3, 0, 0, 0)
+
+/**
+ * @def IX_NPEMH_TRACE4
+ *
+ * @brief Trace macro taking 4 arguments.
+ */
+
+#define IX_NPEMH_TRACE4(LEVEL, STR, ARG1, ARG2, ARG3, ARG4) \
+    IX_NPEMH_TRACE6(LEVEL, STR, ARG1, ARG2, ARG3, ARG4, 0, 0)
+
+/**
+ * @def IX_NPEMH_TRACE5
+ *
+ * @brief Trace macro taking 5 arguments.
+ */
+
+#define IX_NPEMH_TRACE5(LEVEL, STR, ARG1, ARG2, ARG3, ARG4, ARG5) \
+    IX_NPEMH_TRACE6(LEVEL, STR, ARG1, ARG2, ARG3, ARG4, ARG5, 0)
+
+/**
+ * @def IX_NPEMH_TRACE6
+ *
+ * @brief Trace macro taking 6 arguments.
+ */
+
+#define IX_NPEMH_TRACE6(LEVEL, STR, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \
+{ \
+    if (LEVEL <= IX_NPEMH_TRACE_LEVEL) \
+    { \
+        (void) ixOsalLog (LEVEL, IX_OSAL_LOG_DEV_STDOUT, (STR), \
+                          (int)(ARG1), (int)(ARG2), (int)(ARG3), \
+                          (int)(ARG4), (int)(ARG5), (int)(ARG6)); \
+    } \
+}
+
+/**
+ * @def IX_NPEMH_ERROR_REPORT
+ *
+ * @brief Error reporting facility.
+ */
+
+#define IX_NPEMH_ERROR_REPORT(STR) \
+{ \
+    (void) ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, \
+		      (STR), 0, 0, 0, 0, 0, 0); \
+}
+
+/* if we are running on XScale, i.e. real environment */
+#if CPU==XSCALE
+
+/**
+ * @def IX_NPEMH_REGISTER_READ
+ *
+ * @brief This macro reads a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_READ(registerAddress, value) \
+{ \
+    *value = IX_OSAL_READ_LONG(registerAddress); \
+}
+
+/**
+ * @def IX_NPEMH_REGISTER_READ_BITS
+ *
+ * @brief This macro partially reads a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_READ_BITS(registerAddress, value, mask) \
+{ \
+    *value = (IX_OSAL_READ_LONG(registerAddress) & mask); \
+}
+
+/**
+ * @def IX_NPEMH_REGISTER_WRITE
+ *
+ * @brief This macro writes a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_WRITE(registerAddress, value) \
+{ \
+    IX_OSAL_WRITE_LONG(registerAddress, value); \
+}
+
+/**
+ * @def IX_NPEMH_REGISTER_WRITE_BITS
+ *
+ * @brief This macro partially writes a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_WRITE_BITS(registerAddress, value, mask) \
+{ \
+    UINT32 orig = IX_OSAL_READ_LONG(registerAddress); \
+    orig &= (~mask); \
+    orig |= (value & mask); \
+    IX_OSAL_WRITE_LONG(registerAddress, orig); \
+}
+
+
+/* if we are running as a unit test */
+#else /* #if CPU==XSCALE */
+
+#include "IxNpeMhTestRegister.h"
+
+/**
+ * @def IX_NPEMH_REGISTER_READ
+ *
+ * @brief This macro reads a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_READ(registerAddress, value) \
+{ \
+    ixNpeMhTestRegisterRead (registerAddress, value); \
+}
+
+/**
+ * @def IX_NPEMH_REGISTER_READ_BITS
+ *
+ * @brief This macro partially reads a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_READ_BITS(registerAddress, value, mask) \
+{ \
+    ixNpeMhTestRegisterReadBits (registerAddress, value, mask); \
+}
+
+/**
+ * @def IX_NPEMH_REGISTER_WRITE
+ *
+ * @brief This macro writes a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_WRITE(registerAddress, value) \
+{ \
+    ixNpeMhTestRegisterWrite (registerAddress, value); \
+}
+
+/**
+ * @def IX_NPEMH_REGISTER_WRITE_BITS
+ *
+ * @brief This macro partially writes a memory-mapped register.
+ */
+
+#define IX_NPEMH_REGISTER_WRITE_BITS(registerAddress, value, mask) \
+{ \
+    ixNpeMhTestRegisterWriteBits (registerAddress, value, mask); \
+}
+
+#endif /* #if CPU==XSCALE */
+
+#endif /* IXNPEMHMACROS_P_H */
+
+/**
+ * @} defgroup IxNpeMhMacros_p
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeMhReceive_p.h b/marvell/uboot/drivers/net/npe/include/IxNpeMhReceive_p.h
new file mode 100644
index 0000000..7b2afa0
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeMhReceive_p.h
@@ -0,0 +1,115 @@
+/**
+ * @file IxNpeMhReceive_p.h
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the private API for the Receive module.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeMhReceive_p IxNpeMhReceive_p
+ *
+ * @brief The private API for the Receive module.
+ * 
+ * @{
+ */
+
+#ifndef IXNPEMHRECEIVE_P_H
+#define IXNPEMHRECEIVE_P_H
+
+#include "IxNpeMh.h"
+#include "IxOsalTypes.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @fn void ixNpeMhReceiveInitialize (void)
+ *
+ * @brief This function registers an internal ISR to handle the NPEs'
+ * "outFIFO not empty" interrupts and receive messages from the NPEs when
+ * they become available.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhReceiveInitialize (void);
+
+/**
+ * @fn IX_STATUS ixNpeMhReceiveMessagesReceive (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function reads messages from a particular NPE's outFIFO
+ * until the outFIFO is empty, and for each message looks first for an
+ * unsolicited callback, then a solicited callback, to pass the message
+ * back to the client.  If no callback can be found the message is
+ * discarded and an error reported. This function will return TIMEOUT 
+ * status if NPE hang / halt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to receive
+ * messages from.
+ *
+ * @return The function returns a status indicating success, failure or timeout.
+ */
+
+IX_STATUS ixNpeMhReceiveMessagesReceive (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhReceiveShow (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function will display the current state of the Receive
+ * module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to display state
+ * information for.
+ *
+ * @return No return status.
+ */
+
+void ixNpeMhReceiveShow (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhReceiveShowReset (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function will reset the current state of the Receive
+ * module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to reset state
+ * information for.
+ *
+ * @return No return status.
+ */
+
+void ixNpeMhReceiveShowReset (
+    IxNpeMhNpeId npeId);
+
+#endif /* IXNPEMHRECEIVE_P_H */
+
+/**
+ * @} defgroup IxNpeMhReceive_p
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeMhSend_p.h b/marvell/uboot/drivers/net/npe/include/IxNpeMhSend_p.h
new file mode 100644
index 0000000..0f060cc
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeMhSend_p.h
@@ -0,0 +1,139 @@
+/**
+ * @file IxNpeMhSend_p.h
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the private API for the Send module.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeMhSend_p IxNpeMhSend_p
+ *
+ * @brief The private API for the Send module.
+ * 
+ * @{
+ */
+
+#ifndef IXNPEMHSEND_P_H
+#define IXNPEMHSEND_P_H
+
+#include "IxNpeMh.h"
+#include "IxOsalTypes.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @fn IX_STATUS ixNpeMhSendMessageSend (
+           IxNpeMhNpeId npeId,
+           IxNpeMhMessage message,
+           UINT32 maxSendRetries)
+ *
+ * @brief This function writes a message to the specified NPE's inFIFO,
+ * and must be used when the message being sent does not solicit a response
+ * from the NPE. This function will return TIMEOUT status if NPE hang / halt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to send the message
+ * to.
+ * @param IxNpeMhMessage message (in) - The message to send.
+ * @param UINT32 maxSendRetries (in) - Max num. of retries to perform
+ * if the NPE's inFIFO is full.
+ *
+ * @return The function returns a status indicating success, failure or timeout.
+ */
+
+IX_STATUS ixNpeMhSendMessageSend (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessage message,
+    UINT32 maxSendRetries);
+
+/**
+ * @fn IX_STATUS ixNpeMhSendMessageWithResponseSend (
+           IxNpeMhNpeId npeId,
+           IxNpeMhMessage message,
+           IxNpeMhMessageId solicitedMessageId,
+           IxNpeMhCallback solicitedCallback,
+           UINT32 maxSendRetries)
+ *
+ * @brief This function writes a message to the specified NPE's inFIFO,
+ * and must be used when the message being sent solicits a response from
+ * the NPE.  The ID of the solicited response must be specified so that it
+ * can be recognised, and a callback provided to pass the response back to
+ * the client. This function will return TIMEOUT status if NPE hang / halt.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to send the message
+ * to.
+ * @param IxNpeMhMessage message (in) - The message to send.
+ * @param IxNpeMhMessageId solicitedMessageId (in) - The ID of the
+ * solicited response.
+ * @param IxNpeMhCallback solicitedCallback (in) - The callback to pass the
+ * solicited response back to the client.
+ * @param UINT32 maxSendRetries (in) - Max num. of retries to perform
+ * if the NPE's inFIFO is full.
+ *
+ * @return The function returns a status indicating success, failure or timeout.
+ */
+
+IX_STATUS ixNpeMhSendMessageWithResponseSend (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessage message,
+    IxNpeMhMessageId solicitedMessageId,
+    IxNpeMhCallback solicitedCallback,
+    UINT32 maxSendRetries);
+
+/**
+ * @fn void ixNpeMhSendShow (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function will display the current state of the Send module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to display state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhSendShow (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhSendShowReset (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function will reset the current state of the Send module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to reset state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhSendShowReset (
+    IxNpeMhNpeId npeId);
+
+#endif /* IXNPEMHSEND_P_H */
+
+/**
+ * @} defgroup IxNpeMhSend_p
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeMhSolicitedCbMgr_p.h b/marvell/uboot/drivers/net/npe/include/IxNpeMhSolicitedCbMgr_p.h
new file mode 100644
index 0000000..b094fd9
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeMhSolicitedCbMgr_p.h
@@ -0,0 +1,147 @@
+/**
+ * @file IxNpeMhSolicitedCbMgr_p.h
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the private API for the Solicited Callback
+ * Manager module.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeMhSolicitedCbMgr_p IxNpeMhSolicitedCbMgr_p
+ *
+ * @brief The private API for the Solicited Callback Manager module.
+ * 
+ * @{
+ */
+
+#ifndef IXNPEMHSOLICITEDCBMGR_P_H
+#define IXNPEMHSOLICITEDCBMGR_P_H
+
+#include "IxNpeMh.h"
+#include "IxOsalTypes.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/** Maximum number of solicited callbacks that can be stored in the list */
+#define IX_NPEMH_MAX_CALLBACKS (16)
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @fn void ixNpeMhSolicitedCbMgrInitialize (void)
+ *
+ * @brief This function initializes the Solicited Callback Manager module,
+ * setting up a callback data structure for each NPE.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhSolicitedCbMgrInitialize (void);
+
+/**
+ * @fn IX_STATUS ixNpeMhSolicitedCbMgrCallbackSave (
+           IxNpeMhNpeId npeId,
+           IxNpeMhMessageId solicitedMessageId,
+           IxNpeMhCallback solicitedCallback)
+ *
+ * @brief This function saves a callback in the specified NPE's callback
+ * list.  If the callback list is full the function will fail.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE in whose callback
+ * list the callback will be saved.
+ * @param IxNpeMhMessageId solicitedMessageId (in) - The ID of the message
+ * that this callback is for.
+ * @param IxNpeMhCallback solicitedCallback (in) - The callback function
+ * pointer to save.
+ *
+ * @return The function returns a status indicating success or failure.
+ */
+
+IX_STATUS ixNpeMhSolicitedCbMgrCallbackSave (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessageId solicitedMessageId,
+    IxNpeMhCallback solicitedCallback);
+
+/**
+ * @fn void ixNpeMhSolicitedCbMgrCallbackRetrieve (
+           IxNpeMhNpeId npeId,
+           IxNpeMhMessageId solicitedMessageId,
+           IxNpeMhCallback *solicitedCallback)
+ *
+ * @brief This function retrieves the first ID-matching callback from the
+ * specified NPE's callback list.  If no matching callback can be found the
+ * function will fail.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE from whose callback
+ * list the callback will be retrieved.
+ * @param IxNpeMhMessageId solicitedMessageId (in) - The ID of the message
+ * that the callback is for.
+ * @param IxNpeMhCallback solicitedCallback (out) - The callback function
+ * pointer retrieved.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhSolicitedCbMgrCallbackRetrieve (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessageId solicitedMessageId,
+    IxNpeMhCallback *solicitedCallback);
+
+/**
+ * @fn void ixNpeMhSolicitedCbMgrShow (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function will display the current state of the Solicited
+ * Callback Manager module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to display state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhSolicitedCbMgrShow (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhSolicitedCbMgrShowReset (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function will reset the current state of the Solicited
+ * Callback Manager module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to reset state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhSolicitedCbMgrShowReset (
+    IxNpeMhNpeId npeId);
+
+#endif /* IXNPEMHSOLICITEDCBMGR_P_H */
+
+/**
+ * @} defgroup IxNpeMhSolicitedCbMgr_p
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeMhUnsolicitedCbMgr_p.h b/marvell/uboot/drivers/net/npe/include/IxNpeMhUnsolicitedCbMgr_p.h
new file mode 100644
index 0000000..faf6638
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeMhUnsolicitedCbMgr_p.h
@@ -0,0 +1,145 @@
+/**
+ * @file IxNpeMhUnsolicitedCbMgr_p.h
+ *
+ * @author Intel Corporation
+ * @date 18 Jan 2002
+ *
+ * @brief This file contains the private API for the Unsolicited Callback
+ * Manager module.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxNpeMhUnsolicitedCbMgr_p IxNpeMhUnsolicitedCbMgr_p
+ *
+ * @brief The private API for the Unsolicited Callback Manager module.
+ * 
+ * @{
+ */
+
+#ifndef IXNPEMHUNSOLICITEDCBMGR_P_H
+#define IXNPEMHUNSOLICITEDCBMGR_P_H
+
+#include "IxNpeMh.h"
+#include "IxOsalTypes.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @fn void ixNpeMhUnsolicitedCbMgrInitialize (void)
+ *
+ * @brief This function initializes the Unsolicited Callback Manager
+ * module, setting up a callback data structure for each NPE.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhUnsolicitedCbMgrInitialize (void);
+
+/**
+ * @fn void ixNpeMhUnsolicitedCbMgrCallbackSave (
+           IxNpeMhNpeId npeId,
+           IxNpeMhMessageId unsolicitedMessageId,
+           IxNpeMhCallback unsolicitedCallback)
+ *
+ * @brief This function saves a callback in the specified NPE's callback
+ * table.  If a callback already exists for the specified ID then it will
+ * be overwritten.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE in whose callback
+ * table the callback will be saved.
+ * @param IxNpeMhMessageId unsolicitedMessageId (in) - The ID of the
+ * messages that this callback is for.
+ * @param IxNpeMhCallback unsolicitedCallback (in) - The callback function
+ * pointer to save.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhUnsolicitedCbMgrCallbackSave (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessageId unsolicitedMessageId,
+    IxNpeMhCallback unsolicitedCallback);
+
+/**
+ * @fn void ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
+           IxNpeMhNpeId npeId,
+           IxNpeMhMessageId unsolicitedMessageId,
+           IxNpeMhCallback *unsolicitedCallback)
+ *
+ * @brief This function retrieves the callback for the specified ID from
+ * the specified NPE's callback table.  If no callback is registered for
+ * the specified ID and NPE then a callback value of NULL will be returned.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE from whose callback
+ * table the callback will be retrieved.
+ * @param IxNpeMhMessageId unsolicitedMessageId (in) - The ID of the
+ * messages that the callback is for.
+ * @param IxNpeMhCallback unsolicitedCallback (out) - The callback function
+ * pointer retrieved.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhUnsolicitedCbMgrCallbackRetrieve (
+    IxNpeMhNpeId npeId,
+    IxNpeMhMessageId unsolicitedMessageId,
+    IxNpeMhCallback *unsolicitedCallback);
+
+/**
+ * @fn void ixNpeMhUnsolicitedCbMgrShow (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function will display the current state of the Unsolicited
+ * Callback Manager module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to display state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhUnsolicitedCbMgrShow (
+    IxNpeMhNpeId npeId);
+
+/**
+ * @fn void ixNpeMhUnsolicitedCbMgrShowReset (
+           IxNpeMhNpeId npeId)
+ *
+ * @brief This function will reset the current state of the Unsolicited
+ * Callback Manager module.
+ *
+ * @param IxNpeMhNpeId npeId (in) - The ID of the NPE to reset state
+ * information for.
+ *
+ * @return No return value.
+ */
+
+void ixNpeMhUnsolicitedCbMgrShowReset (
+    IxNpeMhNpeId npeId);
+
+#endif /* IXNPEMHUNSOLICITEDCBMGR_P_H */
+
+/**
+ * @} defgroup IxNpeMhUnsolicitedCbMgr_p
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxNpeMicrocode.h b/marvell/uboot/drivers/net/npe/include/IxNpeMicrocode.h
new file mode 100644
index 0000000..01dcd7a
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxNpeMicrocode.h
@@ -0,0 +1,272 @@
+/**
+ * @date   April 18, 2005
+ *
+ * @brief  IXP400 NPE Microcode Image file
+ *
+ * This file was generated by the IxNpeDlImageGen tool.
+ * It contains a NPE microcode image suitable for use
+ * with the NPE Downloader (IxNpeDl) component in the
+ * IXP400 Access Driver software library.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxNpeMicrocode IXP400 NPE Microcode Image Library
+ *
+ * @brief Library containing a set of NPE firmware images, for use
+ * with NPE Downloader s/w component
+ *
+ * @{
+ */
+
+/**
+ * @def IX_NPE_IMAGE_INCLUDE
+ *
+ * @brief Wrap the following Image identifiers with "#if IX_NPE_IMAGE_INCLUDE ... #endif" to include the image in the library
+ */
+#define IX_NPE_IMAGE_INCLUDE 1
+
+/**
+ * @def IX_NPE_IMAGE_OMIT
+ *
+ * @brief Wrap the following Image identifiers with "#if IX_NPE_IMAGE_OMIT ... #endif" to OMIT the image from the library
+ */
+#define IX_NPE_IMAGE_OMIT    0
+
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_HSS0
+ *
+ * @brief NPE Image Id for NPE-A with HSS-0 Only feature.  It supports 32 channelized and 4 packetized.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_HSS0 0x00010000
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_HSS0_ATM_SPHY_1_PORT
+ *
+ * @brief NPE Image Id for NPE-A with HSS-0 and ATM feature. For HSS, it supports 16/32 channelized and 4/0 packetized. For ATM, it supports AAL5, AAL0 and OAM for UTOPIA SPHY, 1 logical port, 32 VCs. It also has Fast Path support.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_HSS0_ATM_SPHY_1_PORT 0x00020000
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_HSS0_ATM_MPHY_1_PORT
+ *
+ * @brief NPE Image Id for NPE-A with HSS-0 and ATM feature. For HSS, it supports 16/32 channelized and 4/0 packetized. For ATM, it supports AAL5, AAL0 and OAM for UTOPIA MPHY, 1 logical port, 32 VCs. It also has Fast Path support.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_HSS0_ATM_MPHY_1_PORT 0x00030000
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_ATM_MPHY_12_PORT
+ *
+ * @brief NPE Image Id for NPE-A with ATM-Only feature. It supports AAL5, AAL0 and OAM for UTOPIA MPHY, 12 logical ports, 32 VCs. It also has Fast Path support.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_ATM_MPHY_12_PORT 0x00040000
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_DMA
+ *
+ * @brief NPE Image Id for NPE-A with DMA-Only feature.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_DMA 0x00150100
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_HSS_2_PORT
+ *
+ * @brief NPE Image Id for NPE-A with HSS-0 and HSS-1 feature. Each HSS port supports 32 channelized and 4 packetized.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_HSS_2_PORT 0x00090000
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_ETH
+ *
+ * @brief NPE Image Id for NPE-A with Basic Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_ETH 0x10800200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_FIREWALL
+ *
+ * @brief NPE Image Id for NPE-A with Basic Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_FIREWALL 0x10800200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS
+ *
+ * @brief NPE Image Id for NPE-A with Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL, VLAN_QOS
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS 0x10810200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEA_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+ *
+ * @brief NPE Image Id for NPE-A with Ethernet Rx/Tx which includes: SPANNING_TREE, FIREWALL, VLAN_QOS, HEADER_CONVERSION
+ */
+#define IX_NPEDL_NPEIMAGE_NPEA_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV 0x10820200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEB_ETH
+ *
+ * @brief NPE Image Id for NPE-B with Basic Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL
+ */
+#define IX_NPEDL_NPEIMAGE_NPEB_ETH 0x01000200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL
+ *
+ * @brief NPE Image Id for NPE-B with Basic Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL
+ */
+#define IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL 0x01000200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS
+ *
+ * @brief NPE Image Id for NPE-B with Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL, VLAN_QOS
+ */
+#define IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS 0x01010200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEB_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+ *
+ * @brief NPE Image Id for NPE-B with Ethernet Rx/Tx which includes: SPANNING_TREE, FIREWALL, VLAN_QOS, HEADER_CONVERSION
+ */
+#define IX_NPEDL_NPEIMAGE_NPEB_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV 0x01020200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEB_DMA
+ *
+ * @brief NPE Image Id for NPE-B with DMA-Only feature.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEB_DMA 0x01020100
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEC_ETH
+ *
+ * @brief NPE Image Id for NPE-C with Basic Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL
+ */
+#define IX_NPEDL_NPEIMAGE_NPEC_ETH 0x02000200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL
+ *
+ * @brief NPE Image Id for NPE-C with Basic Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL
+ */
+#define IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL 0x02000200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS
+ *
+ * @brief NPE Image Id for NPE-C with Ethernet Rx/Tx which includes: MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL, VLAN_QOS
+ */
+#define IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS 0x02010200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEC_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+ *
+ * @brief NPE Image Id for NPE-C with Ethernet Rx/Tx which includes: SPANNING_TREE, FIREWALL, VLAN_QOS, HEADER_CONVERSION
+ */
+#define IX_NPEDL_NPEIMAGE_NPEC_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV 0x02020200
+#endif
+
+#if IX_NPE_IMAGE_INCLUDE
+/**
+ * @def IX_NPEDL_NPEIMAGE_NPEC_DMA
+ *
+ * @brief NPE Image Id for NPE-C with DMA-Only feature.
+ */
+#define IX_NPEDL_NPEIMAGE_NPEC_DMA 0x02080100
+#endif
+
+/* Number of NPE firmware images in this library */
+#define IX_NPE_MICROCODE_AVAILABLE_VERSIONS_COUNT 17
+
+/* Location of Microcode Images */
+#ifdef IX_NPE_MICROCODE_FIRMWARE_INCLUDED
+#ifdef IX_NPEDL_READ_MICROCODE_FROM_FILE
+
+extern UINT32* ixNpeMicrocode_binaryArray;
+
+#else
+
+extern unsigned IxNpeMicrocode_array[];
+
+#endif
+#endif
+
+/*
+ * sr: undef all but the bare minimum to reduce flash usage for U-Boot
+ */
+#undef IX_NPEDL_NPEIMAGE_NPEA_HSS0
+#undef IX_NPEDL_NPEIMAGE_NPEA_HSS0_ATM_SPHY_1_PORT
+#undef IX_NPEDL_NPEIMAGE_NPEA_HSS0_ATM_MPHY_1_PORT
+#undef IX_NPEDL_NPEIMAGE_NPEA_ATM_MPHY_12_PORT
+#undef IX_NPEDL_NPEIMAGE_NPEA_DMA
+#undef IX_NPEDL_NPEIMAGE_NPEA_HSS_2_PORT
+#undef IX_NPEDL_NPEIMAGE_NPEA_ETH
+#undef IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_FIREWALL
+#undef IX_NPEDL_NPEIMAGE_NPEA_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS
+#undef IX_NPEDL_NPEIMAGE_NPEA_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+#undef IX_NPEDL_NPEIMAGE_NPEB_ETH
+#undef IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL
+/* #undef IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS */
+#undef IX_NPEDL_NPEIMAGE_NPEB_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+#undef IX_NPEDL_NPEIMAGE_NPEB_DMA
+#undef IX_NPEDL_NPEIMAGE_NPEC_ETH
+#undef IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL
+/* #undef IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS */
+#undef IX_NPEDL_NPEIMAGE_NPEC_ETH_SPAN_FIREWALL_VLAN_QOS_HDR_CONV
+#undef IX_NPEDL_NPEIMAGE_NPEC_DMA
+
+/**
+ * @} defgroup IxNpeMicrocode
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsBufLib.h b/marvell/uboot/drivers/net/npe/include/IxOsBufLib.h
new file mode 100644
index 0000000..68341dc
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsBufLib.h
@@ -0,0 +1,31 @@
+/**
+ * @file IxOsBufLib.h  (Replaced by OSAL)
+ *
+ * @date 9 Oct 2002
+ *
+ * @brief This file contains the mbuf pool initialisation entry point
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ *
+ */
+
+#ifndef IXOSBUFLIB_H
+#define IXOSBUFLIB_H
+
+#include "IxOsalBackward.h"
+
+#endif /* IXOSBUFLIB_H */
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsBuffMgt.h b/marvell/uboot/drivers/net/npe/include/IxOsBuffMgt.h
new file mode 100644
index 0000000..8b2ee96
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsBuffMgt.h
@@ -0,0 +1,28 @@
+/**
+ * @file (Replaced by OSAL)
+ *
+ * @brief This file includes the OS dependant MBUF header files.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#ifndef IxOsBuffMgt_inc
+#define IxOsBuffMgt_inc
+
+#include "IxOsalBackward.h"
+
+#endif /* ndef IxOsBuffMgt_inc */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsBuffPoolMgt.h b/marvell/uboot/drivers/net/npe/include/IxOsBuffPoolMgt.h
new file mode 100644
index 0000000..1e39be2
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsBuffPoolMgt.h
@@ -0,0 +1,50 @@
+/**
+ * @file IxOsBuffPoolMgt.h (Replaced by OSAL)
+ *
+ * @date 9 Oct 2002
+ *
+ * @brief This file contains the mbuf pool implementation API
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ * This module contains the implementation of the OS Services buffer pool
+ * management service.  This module provides routines for creating pools
+ * of buffers for exchange of network data, getting and returning buffers
+ * from and to the pool, and some other utility functions. 
+ * <P>
+ * Currently, the pool has 2 underlying implementations - one for the vxWorks
+ * OS, and another which attempts to be OS-agnostic so that it can be used on
+ * other OS's such as Linux.  The API is largely the same for all OS's,
+ * but there are some differences to be aware of.  These are documented
+ * in the API descriptions below.
+ * <P>
+ * The most significant difference is this: when this module is used with
+ * the WindRiver VxWorks OS, it will create a pool of vxWorks "MBufs".
+ * These can be used directly with the vxWorks "netBufLib" OS Library.
+ * For other OS's, it will create a pool of generic buffers.  These may need
+ * to be converted into other buffer types (sk_buff's in Linux, for example)
+ * before being used with any built-in OS routines available for
+ * manipulating network data buffers.
+ *
+ * @sa IxOsBuffMgt.h
+ */
+
+#ifndef IXOSBUFFPOOLMGT_H
+#define IXOSBUFFPOOLMGT_H
+
+#include "IxOsalBackward.h"
+
+#endif  /* IXOSBUFFPOOLMGT_H */
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsCacheMMU.h b/marvell/uboot/drivers/net/npe/include/IxOsCacheMMU.h
new file mode 100644
index 0000000..2632cef
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsCacheMMU.h
@@ -0,0 +1,36 @@
+/**
+ * @file IxOsCacheMMU.h
+ *
+ * @brief this file contains the API of the @ref IxCacheMMU component
+ * 
+ * <hr>
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsCacheMMU_H
+
+#ifndef __doxygen_hide
+#define IxOsCacheMMU_H
+#endif /* __doxygen_hide */
+
+#ifdef __doxygen_HIDE
+#define IX_OS_CACHE_DOXYGEN
+#endif /* __doxygen_HIDE */
+
+#include "IxOsalBackward.h"
+
+#endif /* IxOsCacheMMU_H */
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsPrintf.h b/marvell/uboot/drivers/net/npe/include/IxOsPrintf.h
new file mode 100644
index 0000000..7b573a4
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsPrintf.h
@@ -0,0 +1,78 @@
+/**
+ * @file IxOsPrintf.h
+ *
+ * @brief this file contains the API of the @ref IxOsServices component
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#include "IxTypes.h"
+
+#ifndef IxOsPrintf_H
+
+#ifndef __doxygen_hide
+#define IxOsPrintf_H
+#endif /* __doxygen_hide */
+
+#ifdef __wince
+
+#ifndef IX_USE_SERCONSOLE
+
+static int
+ixLogMsg(
+    char *pFormat, 
+    ...
+    )
+{    
+#ifndef IN_KERNEL
+    static WCHAR    pOutputString[256]; 
+	static char     pNarrowStr[256];
+    int             returnCnt = 0; 
+    va_list ap;
+    
+    pOutputString[0] = 0; 
+	pNarrowStr[0] = 0;	
+    
+    va_start(ap, pFormat);
+
+	returnCnt = _vsnprintf(pNarrowStr, 256, pFormat, ap);
+
+    MultiByteToWideChar(
+            CP_ACP, 
+            MB_PRECOMPOSED, 
+            pNarrowStr, 
+            -1, 
+            pOutputString, 
+            256
+            ); 
+
+    OutputDebugString(pOutputString);
+
+    return returnCnt; 
+#else
+    return 0; 
+#endif
+}
+#define printf ixLogMsg
+
+#endif /* IX_USE_SERCONSOLE */
+
+#endif /* __wince */
+
+/**
+ * @} IxOsPrintf
+ */
+
+#endif /* IxOsPrintf_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsServices.h b/marvell/uboot/drivers/net/npe/include/IxOsServices.h
new file mode 100644
index 0000000..d3b8850
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsServices.h
@@ -0,0 +1,31 @@
+/**
+ * @file (Replaced by OSAL)
+ *
+ * @brief this file contains the API of the @ref IxOsServices component
+ * 
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+#ifndef IxOsServices_H
+
+#ifndef __doxygen_hide
+#define IxOsServices_H
+#endif /* __doxygen_hide */
+
+#include "IxOsalBackward.h"
+
+#endif /* IxOsServices_H */
+
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsServicesComponents.h b/marvell/uboot/drivers/net/npe/include/IxOsServicesComponents.h
new file mode 100644
index 0000000..c5a6f68
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsServicesComponents.h
@@ -0,0 +1,110 @@
+/**
+ * @file IxOsServicesComponents.h (Replaced by OSAL)
+ *
+ * @brief Header file for memory access
+ *
+ * @par
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsServicesComponents_H
+#define IxOsServicesComponents_H
+
+#include "IxOsalBackward.h"
+ * codelets_parityENAcc
+ * timeSyncAcc
+ * parityENAcc
+ * sspAcc
+ * i2c
+ * integration_sspAcc
+ * integration_i2c
+#define ix_timeSyncAcc         36
+#define ix_parityENAcc         37
+#define ix_codelets_parityENAcc     38
+#define ix_sspAcc              39
+#define ix_i2c                 40
+#define ix_integration_sspAcc  41
+#define ix_integration_i2c     42
+#define ix_osal		       43
+#define ix_integration_parityENAcc  44
+#define ix_integration_timeSyncAcc  45
+
+/***************************
+ * timeSyncAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_timeSyncAcc)
+
+#if defined (IX_OSSERV_VXWORKS_LE)
+
+#define CSR_LE_DATA_COHERENT_MAPPING
+
+#endif /* IX_OSSERV_VXWORKS_LE */
+
+#endif /* timeSyncAcc */
+
+/***************************
+ * parityENAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_parityENAcc)
+
+#if defined (IX_OSSERV_VXWORKS_LE)
+
+#define CSR_LE_DATA_COHERENT_MAPPING
+
+#endif /* IX_OSSERV_VXWORKS_LE */
+
+#endif /* parityENAcc */
+
+/***************************
+ * codelets_parityENAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_parityENAcc)
+
+#if defined (IX_OSSERV_VXWORKS_LE)
+
+#define CSR_LE_DATA_COHERENT_MAPPING
+
+#endif /* IX_OSSERV_VXWORKS_LE */
+
+#endif /* codelets_parityENAcc */
+
+#endif /* IxOsServicesComponents_H */
+
+/***************************
+ * integration_timeSyncAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_integration_timeSyncAcc)
+
+#if defined (IX_OSSERV_VXWORKS_LE)
+
+#define CSR_LE_DATA_COHERENT_MAPPING
+
+#endif /* IX_OSSERV_VXWORKS_LE */
+
+#endif /* integration_timeSyncAcc */
+
+/***************************
+ * integration_parityENAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_integration_parityENAcc)
+
+#if defined (IX_OSSERV_VXWORKS_LE)
+
+#define CSR_LE_DATA_COHERENT_MAPPING
+
+#endif /* IX_OSSERV_VXWORKS_LE */
+
+#endif /* integration_parityENAcc */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsServicesEndianess.h b/marvell/uboot/drivers/net/npe/include/IxOsServicesEndianess.h
new file mode 100644
index 0000000..383e30a
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsServicesEndianess.h
@@ -0,0 +1,28 @@
+/** 
+ * @file IxOsServicesEndianess.h (Replaced by OSAL)
+ * 
+ * @brief Header file for determining system endianess and OS
+ * 
+ * @par
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+ 
+#ifndef IxOsServicesEndianess_H
+#define IxOsServicesEndianess_H
+
+#include "IxOsalBackward.h"
+
+#endif /* IxOsServicesEndianess_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsServicesMemAccess.h b/marvell/uboot/drivers/net/npe/include/IxOsServicesMemAccess.h
new file mode 100644
index 0000000..896db14
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsServicesMemAccess.h
@@ -0,0 +1,28 @@
+/** 
+ * @file IxOsServicesMemAccess.h (Replaced by OSAL)
+ * 
+ * @brief Header file for memory access
+ * 
+ * @par
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsServicesMemAccess_H
+#define IxOsServicesMemAccess_H
+
+#include "IxOsalBackward.h"
+
+#endif /* IxOsServicesMemAccess_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsServicesMemMap.h b/marvell/uboot/drivers/net/npe/include/IxOsServicesMemMap.h
new file mode 100644
index 0000000..8af1081
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsServicesMemMap.h
@@ -0,0 +1,30 @@
+/**
+ * @file IxOsServicesMemMap.h (Replaced by OSAL)
+ * 
+ * @brief Header file for memory access maps
+ * 
+ * @par
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsServicesMemMap_H
+#define IxOsServicesMemMap_H
+
+#include "IxOsalBackward.h"
+#define IX_OSSERV_ETH_NPEA_MAP_SIZE           (0x1000)     /**< Eth for NPEA map size */
+#define IX_OSSERV_ETH_NPEA_PHYS_BASE           IXP425_Eth_NPEA_BASE_PHYS
+
+#endif /* IxOsServicesMemMap_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsal.h b/marvell/uboot/drivers/net/npe/include/IxOsal.h
new file mode 100644
index 0000000..ac2631c
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsal.h
@@ -0,0 +1,1493 @@
+/**
+ * @file IxOsal.h
+ *
+ * @brief Top include file for OSAL 
+ * 
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsal_H
+#define IxOsal_H
+
+/* Basic types */
+#include "IxOsalTypes.h"
+
+/* Include assert */
+#include "IxOsalAssert.h"
+
+/* 
+ * Config header gives users option to choose IO MEM 
+ * and buffer management modules 
+ */
+
+#include "IxOsalConfig.h"
+
+/*
+ * Symbol file needed by some OS.
+ */
+#include "IxOsalUtilitySymbols.h"
+
+/* OS-specific header */
+#include "IxOsalOs.h"
+
+
+/**
+ * @defgroup IxOsal Operating System Abstraction Layer (IxOsal) API
+ *
+ * @brief This service provides a thin layer of OS dependency services. 
+ *
+ * This file contains the API to the functions which are some what OS dependant and would
+ * require porting to a particular OS. 
+ * A primary focus of the component development is to make them as OS independent as possible.
+ * All other components should abstract their OS dependency to this module.
+ * Services overview
+ *	-# Data types, constants, defines
+ *	-# Interrupts
+ *              - bind interrupts to handlers
+ *              - unbind interrupts from handlers
+ *             	- disables all interrupts 
+ *              - enables all interrupts 
+ *              - selectively disables interrupts 
+ *              - enables an interrupt level 
+ *              - disables an interrupt level 
+ *      -# Memory
+ *              - allocates memory
+ *              - frees memory 
+ *              - copies memory zones 
+ *              - fills a memory zone 
+ *              - allocates cache-safe memory 
+ *              - frees cache-safe memory 
+ *              - physical to virtual address translation 
+ *              - virtual to physical address translation 
+ *              - cache to memory flush 
+ *              - cache line invalidate 
+ *      -# Threads
+ *              - creates a new thread 
+ *              - starts a newly created thread 
+ *              - kills an existing thread 
+ *              - exits a running thread 
+ *              - sets the priority of an existing thread 
+ *              - suspends thread execution 
+ *              - resumes thread execution 
+ *      -# IPC
+ *              - creates a message queue 
+ *              - deletes a message queue 
+ *              - sends a message to a message queue 
+ *              - receives a message from a message queue
+ *      -# Thread Synchronisation
+ *              - initializes a mutex 
+ *              - locks a mutex 
+ *              - unlocks a mutex 
+ *              - non-blocking attempt to lock a mutex 
+ *              - destroys a mutex object 
+ *              - initializes a fast mutex 
+ *              - non-blocking attempt to lock a fast mutex 
+ *              - unlocks a fast mutex 
+ *              - destroys a fast mutex object 
+ *              - initializes a semaphore 
+ *              - posts to (increments) a semaphore 
+ *              - waits on (decrements) a semaphore 
+ *              - non-blocking wait on semaphore 
+ *              - gets semaphore value 
+ *              - destroys a semaphore object 
+ *              - yields execution of current thread 
+ *      -# Time functions
+ *              - yielding sleep for a number of milliseconds 
+ *              - busy sleep for a number of microseconds 
+ *              - value of the timestamp counter 
+ *              - resolution of the timestamp counter 
+ *              - system clock rate, in ticks 
+ *              - current system time 
+ *              - converts ixOsalTimeVal into ticks 
+ *              - converts ticks into ixOsalTimeVal 
+ *              - converts ixOsalTimeVal to milliseconds 
+ *              - converts milliseconds to IxOsalTimeval 
+ *              - "equal" comparison for IxOsalTimeval 
+ *              - "less than" comparison for IxOsalTimeval 
+ *              - "greater than" comparison for IxOsalTimeval 
+ *              - "add" operator for IxOsalTimeval 
+ *              - "subtract" operator for IxOsalTimeval 
+ *      -# Logging
+ *              - sets the current logging verbosity level 
+ *              - interrupt-safe logging function 
+ *      -# Timer services
+ *              - schedules a repeating timer 
+ *              - schedules a single-shot timer 
+ *              - cancels a running timer 
+ *              - displays all the running timers 
+ *      -# Optional Modules
+ *              - Buffer management module
+ *              - I/O memory and endianess support module
+ *
+ * @{
+ */
+
+
+/*
+ * Prototypes
+ */
+
+/* ==========================  Interrupts  ================================
+ * 
+ */
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Binds an interrupt handler to an interrupt level
+ *
+ * @param irqLevel (in)   - interrupt level
+ * @param irqHandler (in) - interrupt handler
+ * @param parameter (in)  - custom parameter to be passed to the
+ *                          interrupt handler
+ *
+ * Binds an interrupt handler to an interrupt level. The operation will
+ * fail if the wrong level is selected, if the handler is NULL, or if the
+ * interrupt is already bound. This functions binds the specified C
+ * routine to an interrupt level. When called, the "parameter" value will
+ * be passed to the routine.
+ *
+ * Reentrant: no
+ * IRQ safe:  no
+ *
+ * @return IX_SUCCESS if the operation succeeded or IX_FAIL otherwise
+ */
+PUBLIC IX_STATUS ixOsalIrqBind (UINT32 irqLevel,
+				IxOsalVoidFnVoidPtr irqHandler,
+				void *parameter);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Unbinds an interrupt handler from an interrupt level
+ *
+ * @param irqLevel (in)   - interrupt level
+ *
+ * Unbinds the selected interrupt level from any previously registered
+ * handler 
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return IX_SUCCESS if the operation succeeded or IX_FAIL otherwise
+ */
+PUBLIC IX_STATUS ixOsalIrqUnbind (UINT32 irqLevel);
+
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Disables all interrupts
+ *
+ * @param - none
+ *
+ * Disables all the interrupts and prevents tasks scheduling 
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  yes
+ *
+ * @return interrupt enable status prior to locking
+ */
+PUBLIC UINT32 ixOsalIrqLock (void);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Enables all interrupts
+ *
+ * @param irqEnable (in) - interrupt enable status, prior to interrupt
+ *                         locking 
+ *
+ * Enables the interrupts and task scheduling, cancelling the effect
+ * of ixOsalIrqLock() 
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  yes
+ *
+ * @return IX_SUCCESS if the operation succeeded or IX_FAIL otherwise
+ */
+PUBLIC void ixOsalIrqUnlock (UINT32 irqEnable);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Selectively disables interrupts
+ *
+ * @param irqLevel - new interrupt level
+ *
+ * Disables the interrupts below the specified interrupt level 
+ * 
+ * @li Reentrant: no
+ * @li IRQ safe:  yes
+ *
+ * @note Depending on the implementation this function can disable all
+ *       the interrupts 
+ *
+ * @return previous interrupt level
+ */
+PUBLIC UINT32 ixOsalIrqLevelSet (UINT32 irqLevel);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Enables an interrupt level
+ *
+ * @param irqLevel - interrupt level to enable
+ *
+ * Enables the specified interrupt level
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  yes
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalIrqEnable (UINT32 irqLevel);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Disables an interrupt level
+ *
+ * @param irqLevel - interrupt level to disable
+ *
+ * Disables the specified interrupt level
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  yes
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalIrqDisable (UINT32 irqLevel);
+
+
+/* =============================  Memory  =================================
+ * 
+ */
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Allocates memory
+ *
+ * @param size - memory size to allocate, in bytes
+ *
+ * Allocates a memory zone of a given size
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return Pointer to the allocated zone or NULL if the allocation failed
+ */
+PUBLIC void *ixOsalMemAlloc (UINT32 size);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Frees memory
+ *
+ * @param ptr - pointer to the memory zone
+ *
+ * Frees a previously allocated memory zone
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalMemFree (void *ptr);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Copies memory zones
+ *
+ * @param dest  - destination memory zone
+ * @param src   - source memory zone
+ * @param count - number of bytes to copy
+ *
+ * Copies count bytes from the source memory zone pointed by src into the
+ * memory zone pointed by dest.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  yes
+ *
+ * @return Pointer to the destination memory zone
+ */
+PUBLIC void *ixOsalMemCopy (void *dest, void *src, UINT32 count);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Fills a memory zone
+ *
+ * @param ptr - pointer to the memory zone
+ * @param filler - byte to fill the memory zone with
+ * @param count - number of bytes to fill
+ *
+ * Fills a memory zone with a given constant byte
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  yes
+ *
+ * @return Pointer to the memory zone
+ */
+PUBLIC void *ixOsalMemSet (void *ptr, UINT8 filler, UINT32 count);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Allocates cache-safe memory
+ *
+ * @param size - size, in bytes, of the allocated zone
+ *
+ * Allocates a cache-safe memory zone of at least "size" bytes and returns
+ * the pointer to the memory zone. This memory zone, depending on the
+ * platform, is either uncached or aligned on a cache line boundary to make
+ * the CACHE_FLUSH and CACHE_INVALIDATE macros safe to use. The memory
+ * allocated with this function MUST be freed with ixOsalCacheDmaFree(),
+ * otherwise memory corruption can occur.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return Pointer to the memory zone or NULL if allocation failed
+ *
+ * @note It is important to note that cache coherence is maintained in
+ * software by using the IX_OSAL_CACHE_FLUSH and IX_OSAL_CACHE_INVALIDATE
+ * macros to maintain consistency between cache and external memory.
+ */
+PUBLIC void *ixOsalCacheDmaMalloc (UINT32 size);
+
+/* Macros for ixOsalCacheDmaMalloc*/
+#define IX_OSAL_CACHE_DMA_MALLOC(size) ixOsalCacheDmaMalloc(size)
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Frees cache-safe memory
+ *
+ * @param ptr   - pointer to the memory zone
+ *
+ * Frees a memory zone previously allocated with ixOsalCacheDmaMalloc()
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalCacheDmaFree (void *ptr);
+
+#define IX_OSAL_CACHE_DMA_FREE(ptr)		ixOsalCacheDmaFree(ptr)
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief physical to virtual address translation
+ *
+ * @param physAddr - physical address
+ *
+ * Converts a physical address into its equivalent MMU-mapped virtual address
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  yes
+ *
+ * @return Corresponding virtual address, as UINT32
+ */
+#define IX_OSAL_MMU_PHYS_TO_VIRT(physAddr) \
+    IX_OSAL_OS_MMU_PHYS_TO_VIRT(physAddr)
+
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief virtual to physical address translation
+ *
+ * @param virtAddr - virtual address
+ *
+ * Converts a virtual address into its equivalent MMU-mapped physical address
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  yes
+ *
+ * @return Corresponding physical address, as UINT32
+ */
+#define IX_OSAL_MMU_VIRT_TO_PHYS(virtAddr)  \
+    IX_OSAL_OS_MMU_VIRT_TO_PHYS(virtAddr)
+
+
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief cache to memory flush
+ *
+ * @param addr - memory address to flush from cache
+ * @param size - number of bytes to flush (rounded up to a cache line)
+ *
+ * Flushes the cached value of the memory zone pointed by "addr" into memory,
+ * rounding up to a cache line. Use before the zone is to be read by a
+ * processing unit which is not cache coherent with the main CPU.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  yes
+ *
+ * @return - none
+ */
+#define IX_OSAL_CACHE_FLUSH(addr, size)  IX_OSAL_OS_CACHE_FLUSH(addr, size)
+
+
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief cache line invalidate
+ *
+ * @param addr - memory address to invalidate in cache
+ * @param size - number of bytes to invalidate (rounded up to a cache line)
+ *
+ * Invalidates the cached value of the memory zone pointed by "addr",
+ * rounding up to a cache line. Use before reading the zone from the main
+ * CPU, if the zone has been updated by a processing unit which is not cache
+ * coherent with the main CPU.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  yes
+ *
+ * @return - none
+ */
+#define IX_OSAL_CACHE_INVALIDATE(addr, size)  IX_OSAL_OS_CACHE_INVALIDATE(addr, size)
+
+
+/* =============================  Threads  =================================
+ * 
+ */
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Creates a new thread
+ *
+ * @param thread - handle of the thread to be created
+ * @param threadAttr - pointer to a thread attribute object
+ * @param startRoutine - thread entry point
+ * @param arg - argument given to the thread
+ *
+ * Creates a thread given a thread handle and a thread attribute object. The
+ * same thread attribute object can be used to create separate threads. "NULL"
+ * can be specified as the attribute, in which case the default values will
+ * be used. The thread needs to be explicitly started using ixOsalThreadStart().
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalThreadCreate (IxOsalThread * thread,
+				     IxOsalThreadAttr * threadAttr,
+				     IxOsalVoidFnVoidPtr startRoutine,
+				     void *arg);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Starts a newly created thread
+ *
+ * @param thread - handle of the thread to be started
+ *
+ * Starts a thread given its thread handle. This function is to be called
+ * only once, following the thread initialization.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalThreadStart (IxOsalThread * thread);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Kills an existing thread
+ *
+ * @param thread - handle of the thread to be killed
+ *
+ * Kills a thread given its thread handle.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @note It is not possible to kill threads in Linux kernel mode. This 
+ * function will only send a SIGTERM signal, and it is the responsibility
+ * of the thread to check for the presence of this signal with
+ * signal_pending().
+ *
+ * @return -  IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalThreadKill (IxOsalThread * thread);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Exits a running thread
+ *
+ * Terminates the calling thread
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - This function never returns
+ */
+PUBLIC void ixOsalThreadExit (void);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Sets the priority of an existing thread
+ *
+ * @param thread - handle of the thread
+ * @param priority - new priority, between 0 and 255 (0 being the highest)
+ *
+ * Sets the thread priority
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalThreadPrioritySet (IxOsalThread * thread,
+					  UINT32 priority);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Suspends thread execution
+ *
+ * @param thread - handle of the thread
+ *
+ * Suspends the thread execution
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalThreadSuspend (IxOsalThread * thread);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Resumes thread execution
+ *
+ * @param thread - handle of the thread
+ *
+ * Resumes the thread execution
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalThreadResume (IxOsalThread * thread);
+
+
+/* =======================  Message Queues (IPC) ==========================
+ * 
+ */
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Creates a message queue
+ *
+ * @param queue - queue handle
+ * @param msgCount - maximum number of messages to hold in the queue
+ * @param msgLen - maximum length of each message, in bytes
+ *
+ * Creates a message queue of msgCount messages, each containing msgLen bytes
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMessageQueueCreate (IxOsalMessageQueue * queue,
+					   UINT32 msgCount, UINT32 msgLen);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Deletes a message queue
+ *
+ * @param queue - queue handle
+ *
+ * Deletes a message queue
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMessageQueueDelete (IxOsalMessageQueue * queue);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Sends a message to a message queue
+ *
+ * @param queue - queue handle
+ * @param message - message to send
+ *
+ * Sends a message to the message queue. The message will be copied (at the
+ * configured size of the message) into the queue.
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMessageQueueSend (IxOsalMessageQueue * queue,
+					 UINT8 * message);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Receives a message from a message queue
+ *
+ * @param queue - queue handle
+ * @param message - pointer to where the message should be copied to
+ *
+ * Retrieves the first message from the message queue
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMessageQueueReceive (IxOsalMessageQueue * queue,
+					    UINT8 * message);
+
+
+/* =======================  Thread Synchronisation ========================
+ * 
+ */
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief initializes a mutex
+ *
+ * @param mutex - mutex handle
+ *
+ * Initializes a mutex object
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMutexInit (IxOsalMutex * mutex);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief locks a mutex
+ *
+ * @param mutex - mutex handle
+ * @param timeout - timeout in ms; IX_OSAL_WAIT_FOREVER (-1) to wait forever
+ *                  or IX_OSAL_WAIT_NONE to return immediately
+ *
+ * Locks a mutex object
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMutexLock (IxOsalMutex * mutex, INT32 timeout);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Unlocks a mutex
+ *
+ * @param mutex - mutex handle
+ *
+ * Unlocks a mutex object
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMutexUnlock (IxOsalMutex * mutex);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Non-blocking attempt to lock a mutex
+ *
+ * @param mutex - mutex handle
+ *
+ * Attempts to lock a mutex object, returning immediately with IX_SUCCESS if
+ * the lock was successful or IX_FAIL if the lock failed
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMutexTryLock (IxOsalMutex * mutex);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Destroys a mutex object
+ *
+ * @param mutex - mutex handle
+ * @param
+ *
+ * Destroys a mutex object; the caller should ensure that no thread is
+ * blocked on this mutex
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalMutexDestroy (IxOsalMutex * mutex);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Initializes a fast mutex
+ *
+ * @param mutex - fast mutex handle
+ *
+ * Initializes a fast mutex object
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalFastMutexInit (IxOsalFastMutex * mutex);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Non-blocking attempt to lock a fast mutex
+ *
+ * @param mutex - fast mutex handle
+ *
+ * Attempts to lock a fast mutex object, returning immediately with
+ * IX_SUCCESS if the lock was successful or IX_FAIL if the lock failed
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalFastMutexTryLock (IxOsalFastMutex * mutex);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Unlocks a fast mutex
+ *
+ * @param mutex - fast mutex handle
+ *
+ * Unlocks a fast mutex object
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalFastMutexUnlock (IxOsalFastMutex * mutex);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Destroys a fast mutex object
+ *
+ * @param mutex - fast mutex handle
+ *
+ * Destroys a fast mutex object
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalFastMutexDestroy (IxOsalFastMutex * mutex);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Initializes a semaphore
+ *
+ * @param semaphore - semaphore handle
+ * @param value - initial semaphore value
+ *
+ * Initializes a semaphore object
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalSemaphoreInit (IxOsalSemaphore * semaphore,
+				      UINT32 value);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Posts to (increments) a semaphore
+ *
+ * @param semaphore - semaphore handle
+ *
+ * Increments a semaphore object
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalSemaphorePost (IxOsalSemaphore * semaphore);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Waits on (decrements) a semaphore
+ *
+ * @param semaphore - semaphore handle
+ * @param timeout - timeout, in ms; IX_OSAL_WAIT_FOREVER (-1) if the thread
+ * is to block indefinitely or IX_OSAL_WAIT_NONE (0) if the thread is to
+ * return immediately even if the call fails
+ *
+ * Decrements a semaphore, blocking if the semaphore is
+ * unavailable (value is 0).
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalSemaphoreWait (IxOsalSemaphore * semaphore,
+				      INT32 timeout);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Non-blocking wait on semaphore
+ *
+ * @param semaphore - semaphore handle
+ *
+ * Decrements a semaphore, not blocking the calling thread if the semaphore
+ * is unavailable
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalSemaphoreTryWait (IxOsalSemaphore * semaphore);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Gets semaphore value
+ *
+ * @param semaphore - semaphore handle
+ * @param value - location to store the semaphore value
+ *
+ * Retrieves the current value of a semaphore object
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalSemaphoreGetValue (IxOsalSemaphore * semaphore,
+					  UINT32 * value);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Destroys a semaphore object
+ *
+ * @param semaphore - semaphore handle
+ *
+ * Destroys a semaphore object; the caller should ensure that no thread is
+ * blocked on this semaphore
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalSemaphoreDestroy (IxOsalSemaphore * semaphore);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Yields execution of current thread
+ *
+ * Yields the execution of the current thread
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalYield (void);
+
+
+/* ========================== Time functions  ===========================
+ * 
+ */
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Yielding sleep for a number of milliseconds
+ *
+ * @param milliseconds - number of milliseconds to sleep
+ *
+ * The calling thread will sleep for the specified number of milliseconds.
+ * This sleep is yielding, hence other tasks will be scheduled by the
+ * operating system during the sleep period. Calling this function with an
+ * argument of 0 will place the thread at the end of the current scheduling
+ * loop.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalSleep (UINT32 milliseconds);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Busy sleep for a number of microseconds
+ *
+ * @param microseconds - number of microseconds to sleep
+ *
+ * Sleeps for the specified number of microseconds, without explicitly
+ * yielding thread execution to the OS scheduler
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalBusySleep (UINT32 microseconds);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief XXX
+ *
+ * Retrieves the current timestamp
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - The current timestamp
+ *
+ * @note The implementation of this function is platform-specific. Not
+ * all the platforms provide a high-resolution timestamp counter.
+ */
+PUBLIC UINT32 ixOsalTimestampGet (void);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Resolution of the timestamp counter
+ *
+ * Retrieves the resolution (frequency) of the timestamp counter.
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - The resolution of the timestamp counter
+ *
+ * @note The implementation of this function is platform-specific. Not all
+ * the platforms provide a high-resolution timestamp counter.
+ */
+PUBLIC UINT32 ixOsalTimestampResolutionGet (void);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief System clock rate, in ticks
+ *
+ * Retrieves the resolution (number of ticks per second) of the system clock
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - The system clock rate
+ *
+ * @note The implementation of this function is platform and OS-specific.
+ * The system clock rate is not always available - e.g. Linux does not
+ * provide this information in user mode
+ */
+PUBLIC UINT32 ixOsalSysClockRateGet (void);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Current system time
+ *
+ * @param tv - pointer to an IxOsalTimeval structure to store the current
+ *             time in
+ *
+ * Retrieves the current system time (real-time)
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - none
+ *
+ * @note The implementation of this function is platform-specific. Not all
+ * platforms have a real-time clock.
+ */
+PUBLIC void ixOsalTimeGet (IxOsalTimeval * tv);
+
+
+
+/* Internal function to convert timer val to ticks.
+ * NOTE - This should not be called by the user.
+ * Use the macro IX_OSAL_TIMEVAL_TO_TICKS 
+ * OS-independent, implemented in framework.
+ */
+PUBLIC UINT32 ixOsalTimevalToTicks (IxOsalTimeval tv);
+
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Converts ixOsalTimeVal into ticks
+ *
+ * @param tv - an IxOsalTimeval structure
+ *
+ * Converts an IxOsalTimeval structure into OS ticks
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - Corresponding number of ticks
+ * 
+ * Note: This function is OS-independent. Implemented by core.
+ */
+#define IX_OSAL_TIMEVAL_TO_TICKS(tv)  ixOsalTimevalToTicks(tv)
+
+
+
+/* Internal function to convert ticks to timer val
+ * NOTE - This should not be called by the user.
+ * Use the macro IX_OSAL_TICKS_TO_TIMEVAL 
+ */
+
+PUBLIC void ixOsalTicksToTimeval (UINT32 ticks, IxOsalTimeval * pTv);
+
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Converts ticks into ixOsalTimeVal 
+ *
+ * @param ticks - number of ticks
+ * @param pTv - pointer to the destination structure
+ *
+ * Converts the specified number of ticks into an IxOsalTimeval structure
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - Corresponding IxOsalTimeval structure
+ * Note: This function is OS-independent. Implemented by core.
+ */
+#define IX_OSAL_TICKS_TO_TIMEVAL(ticks, pTv)  \
+    ixOsalTicksToTimeval(ticks, pTv)
+
+
+
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Converts ixOsalTimeVal to milliseconds
+ *
+ * @param tv - IxOsalTimeval structure to convert
+ *
+ * Converts an IxOsalTimeval structure into milliseconds
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - Corresponding number of milliseconds
+ * Note: This function is OS-independent. Implemented by core.
+ */
+#define IX_OSAL_TIMEVAL_TO_MS(tv)     ((tv.secs * 1000) + (tv.nsecs / 1000000))
+
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Converts milliseconds to IxOsalTimeval
+ *
+ * @param milliseconds - number of milliseconds to convert
+ * @param pTv - pointer to the destination structure
+ *
+ * Converts a millisecond value into an IxOsalTimeval structure
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - Corresponding IxOsalTimeval structure
+ * Note: This function is OS-independent. Implemented by core.
+ */
+#define IX_OSAL_MS_TO_TIMEVAL(milliseconds, pTv)  \
+   	    ((IxOsalTimeval *) pTv)->secs = milliseconds / 1000;			  \
+        ((IxOsalTimeval *) pTv)->nsecs = (milliseconds % 1000) * 1000000
+
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief "equal" comparison for IxOsalTimeval
+ *
+ * @param tvA, tvB - IxOsalTimeval structures to compare
+ *
+ * Compares two IxOsalTimeval structures for equality
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - true if the structures are equal
+ *         - false otherwise
+ * Note: This function is OS-independant
+ */
+#define IX_OSAL_TIME_EQ(tvA, tvB)        \
+        ((tvA).secs == (tvB).secs && (tvA).nsecs == (tvB).nsecs)
+
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief "less than" comparison for IxOsalTimeval
+ *
+ * @param tvA, tvB - IxOsalTimeval structures to compare
+ *
+ * Compares two IxOsalTimeval structures to determine if the first one is
+ * less than the second one
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - true if tvA < tvB
+ *         - false otherwise
+ * Note: This function is OS-independent. Implemented by core.
+ */
+#define IX_OSAL_TIME_LT(tvA,tvB) \
+        ((tvA).secs  < (tvB).secs ||	\
+        ((tvA).secs == (tvB).secs && (tvA).nsecs < (tvB).nsecs))
+
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief "greater than" comparison for IxOsalTimeval
+ *
+ * @param tvA, tvB - IxOsalTimeval structures to compare
+ *
+ * Compares two IxOsalTimeval structures to determine if the first one is
+ * greater than the second one
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - true if tvA > tvB
+ *         - false  otherwise
+ * Note: This function is OS-independent.
+ */
+#define IX_OSAL_TIME_GT(tvA, tvB)  \
+        ((tvA).secs  > (tvB).secs ||	\
+        ((tvA).secs == (tvB).secs && (tvA).nsecs > (tvB).nsecs))
+
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief "add" operator for IxOsalTimeval
+ *
+ * @param tvA, tvB - IxOsalTimeval structures to add
+ *
+ * Adds the second IxOsalTimevalStruct to the first one (equivalent to
+ * tvA += tvB)
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - none
+ * Note: This function is OS-independent.
+ */
+#define IX_OSAL_TIME_ADD(tvA, tvB)  \
+        (tvA).secs += (tvB).secs;   \
+        (tvA).nsecs += (tvB).nsecs; \
+        if ((tvA).nsecs >= IX_OSAL_BILLION) \
+    	{ \
+        (tvA).secs++; \
+        (tvA).nsecs -= IX_OSAL_BILLION; }
+
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief "subtract" operator for IxOsalTimeval
+ *
+ * @param tvA, tvB - IxOsalTimeval structures to subtract
+ *
+ * Subtracts the second IxOsalTimevalStruct from the first one (equivalent
+ * to tvA -= tvB)
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - none
+ * Note: This function is OS-independent. Implemented by core.
+ */
+#define IX_OSAL_TIME_SUB(tvA, tvB)   \
+        if ((tvA).nsecs >= (tvB).nsecs) \
+        { \
+          (tvA).secs -= (tvB).secs; \
+          (tvA).nsecs -= (tvB).nsecs; \
+        } \
+        else \
+        { \
+          (tvA).secs -= ((tvB).secs + 1); \
+          (tvA).nsecs += IX_OSAL_BILLION - (tvB).nsecs; \
+        }
+
+
+/* ============================= Logging  ==============================
+ * 
+ */
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Interrupt-safe logging function
+ *
+ * @param level - identifier prefix for the message
+ * @param device - output device
+ * @param format - message format, in a printf format
+ * @param ... - up to 6 arguments to be printed
+ *
+ * IRQ-safe logging function, similar to printf. Accepts up to 6 arguments
+ * to print (excluding the level, device and the format). This function will
+ * actually display the message only if the level is lower than the current
+ * verbosity level or if the IX_OSAL_LOG_USER level is used. An output device
+ * must be specified (see IxOsalTypes.h).
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - Beside the exceptions documented in the note below, the returned
+ * value is the number of printed characters, or -1 if the parameters are
+ * incorrect (NULL format, unknown output device)
+ *
+ * @note The exceptions to the return value are:
+ * VxWorks: The return value is 32 if the specified level is 1 and 64
+ * if the specified level is greater than 1 and less or equal than 9.
+ * WinCE: If compiled for EBOOT then the return value is always 0.
+ *
+ * @note The given print format should take into account the specified 
+ * output device. IX_OSAL_STDOUT supports all the usual print formats,
+ * however a custom hex display specified by IX_OSAL_HEX would support
+ * only a fixed number of hexadecimal digits.
+ */
+PUBLIC INT32 ixOsalLog (IxOsalLogLevel level,
+			IxOsalLogDevice device,
+			char *format,
+			int arg1,
+			int arg2, int arg3, int arg4, int arg5, int arg6);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief sets the current logging verbosity level
+ *
+ * @param level - new log verbosity level
+ *
+ * Sets the log verbosity level. The default value is IX_OSAL_LOG_ERROR.
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * @return - Old log verbosity level
+ */
+PUBLIC UINT32 ixOsalLogLevelSet (UINT32 level);
+
+
+/* ============================= Logging  ==============================
+ * 
+ */
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Schedules a repeating timer
+ *
+ * @param timer - handle of the timer object
+ * @param period - timer trigger period, in milliseconds
+ * @param priority - timer priority (0 being the highest)
+ * @param callback - user callback to invoke when the timer triggers
+ * @param param - custom parameter passed to the callback
+ *
+ * Schedules a timer to be called every period milliseconds. The timer
+ * will invoke the specified callback function possibly in interrupt
+ * context, passing the given parameter. If several timers trigger at the
+ * same time contention issues are dealt according to the specified timer
+ * priorities.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalRepeatingTimerSchedule (IxOsalTimer * timer,
+					       UINT32 period,
+					       UINT32 priority,
+					       IxOsalVoidFnVoidPtr callback,
+					       void *param);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Schedules a single-shot timer
+ *
+ * @param timer - handle of the timer object
+ * @param period - timer trigger period, in milliseconds
+ * @param priority - timer priority (0 being the highest)
+ * @param callback - user callback to invoke when the timer triggers
+ * @param param - custom parameter passed to the callback
+ *
+ * Schedules a timer to be called after period milliseconds. The timer
+ * will cease to function past its first trigger. The timer will invoke
+ * the specified callback function, possibly in interrupt context, passing
+ * the given parameter. If several timers trigger at the same time contention
+ * issues are dealt according to the specified timer priorities.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS
+ixOsalSingleShotTimerSchedule (IxOsalTimer * timer,
+			       UINT32 period,
+			       UINT32 priority,
+			       IxOsalVoidFnVoidPtr callback, void *param);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief Cancels a running timer
+ *
+ * @param timer - handle of the timer object
+ *
+ * Cancels a single-shot or repeating timer.
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  yes
+ *
+ * @return - IX_SUCCESS/IX_FAIL
+ */
+PUBLIC IX_STATUS ixOsalTimerCancel (IxOsalTimer * timer);
+
+/** 
+ * @ingroup IxOsal
+ *
+ * @brief displays all the running timers
+ *
+ * Displays a list with all the running timers and their parameters (handle,
+ * period, type, priority, callback and user parameter)
+ *
+ * @li Reentrant: no
+ * @li IRQ safe:  no
+ *
+ * @return - none
+ */
+PUBLIC void ixOsalTimersShow (void);
+
+
+/* ============================= Version  ==============================
+ * 
+ */
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief provides the name of the Operating System running
+ *
+ * @param osName - Pointer to a NULL-terminated string of characters
+ * that holds the name of the OS running.
+ * This is both an input and an ouput parameter
+ * @param maxSize - Input parameter that defines the maximum number of
+ * bytes that can be stored in osName
+ *
+ * Returns a string of characters that describe the Operating System name
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * return - IX_SUCCESS for successful retrieval
+ *        - IX_FAIL if (osType == NULL | maxSize =< 0)
+ */
+PUBLIC IX_STATUS ixOsalOsNameGet (INT8* osName, INT32 maxSize);
+
+/**
+ * @ingroup IxOsal
+ *
+ * @brief provides the version of the Operating System running
+ *
+ * @param osVersion - Pointer to a NULL terminated string of characters
+ * that holds the version of the OS running.
+ * This is both an input and an ouput parameter
+ * @param maxSize - Input parameter that defines the maximum number of
+ * bytes that can be stored in osVersion
+ *
+ * Returns a string of characters that describe the Operating System's version
+ *
+ * @li Reentrant: yes
+ * @li IRQ safe:  yes
+ *
+ * return - IX_SUCCESS for successful retrieval
+ *        - IX_FAIL if (osVersion == NULL | maxSize =< 0)
+ */
+PUBLIC IX_STATUS ixOsalOsVersionGet(INT8* osVersion, INT32 maxSize);
+
+
+
+/**
+ * @} IxOsal
+ */
+
+#endif /* IxOsal_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalAssert.h b/marvell/uboot/drivers/net/npe/include/IxOsalAssert.h
new file mode 100644
index 0000000..ac26bb6
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalAssert.h
@@ -0,0 +1,57 @@
+/*
+ * @file        IxOsalAssert.h 
+ * @author	Intel Corporation
+ * @date        25-08-2004
+ *
+ * @brief       description goes here
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_ASSERT_H
+#define IX_OSAL_ASSERT_H
+
+/*
+ * Put the system defined include files required
+ * @par
+ * <TAGGED>
+ */
+
+#include "IxOsalOsAssert.h"
+
+/**
+ * @brief Assert macro, assert the condition is true. This
+ *        will not be compiled out.
+ *        N.B. will result in a system crash if it is false.
+ */
+#define IX_OSAL_ASSERT(c) IX_OSAL_OS_ASSERT(c)
+
+
+/**
+ * @brief Ensure macro, ensure the condition is true.
+ *        This will be conditionally compiled out and
+ *        may be used for test purposes.
+ */
+#ifdef IX_OSAL_ENSURE_ON
+#define IX_OSAL_ENSURE(c, str) do { \
+if (!(c)) ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, str, \
+0, 0, 0, 0, 0, 0); } while (0)
+
+#else
+#define IX_OSAL_ENSURE(c, str)
+#endif
+
+
+#endif /* IX_OSAL_ASSERT_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalBackward.h b/marvell/uboot/drivers/net/npe/include/IxOsalBackward.h
new file mode 100644
index 0000000..8e4a6fb
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalBackward.h
@@ -0,0 +1,41 @@
+/** 
+ * This file is intended to provide backward 
+ * compatibility for main osService/OSSL 
+ * APIs. 
+ *
+ * It shall be phased out gradually and users
+ * are strongly recommended to use IX_OSAL API.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_BACKWARD_H
+#define IX_OSAL_BACKWARD_H
+
+#include "IxOsal.h"
+
+#include "IxOsalBackwardCacheMMU.h"
+
+#include "IxOsalBackwardOsServices.h"
+
+#include "IxOsalBackwardMemMap.h"
+
+#include "IxOsalBackwardBufferMgt.h"
+
+#include "IxOsalBackwardOssl.h"
+
+#include "IxOsalBackwardAssert.h"
+
+#endif /* IX_OSAL_BACKWARD_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalBackwardAssert.h b/marvell/uboot/drivers/net/npe/include/IxOsalBackwardAssert.h
new file mode 100644
index 0000000..cf50a7a
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalBackwardAssert.h
@@ -0,0 +1,30 @@
+/** 
+ * This file is intended to provide backward 
+ * compatibility for main osService/OSSL 
+ * APIs. 
+ *
+ * It shall be phased out gradually and users
+ * are strongly recommended to use IX_OSAL API.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_BACKWARD_ASSERT_H
+#define IX_OSAL_BACKWARD_ASSERT_H
+
+#define IX_ENSURE(c, str)	IX_OSAL_ENSURE(c, str)
+#define IX_ASSERT(c)		IX_OSAL_ASSERT(c)
+
+#endif /* IX_OSAL_BACKWARD_ASSERT_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalBackwardBufferMgt.h b/marvell/uboot/drivers/net/npe/include/IxOsalBackwardBufferMgt.h
new file mode 100644
index 0000000..46df29d
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalBackwardBufferMgt.h
@@ -0,0 +1,135 @@
+/** 
+ * This file is intended to provide backward 
+ * compatibility for main osService/OSSL 
+ * APIs. 
+ *
+ * It shall be phased out gradually and users
+ * are strongly recommended to use IX_OSAL API.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_BACKWARD_BUFFER_MGT_H
+#define IX_OSAL_BACKWARD_BUFFER_MGT_H
+
+typedef IX_OSAL_MBUF IX_MBUF;
+
+typedef IX_OSAL_MBUF_POOL IX_MBUF_POOL;
+
+
+#define IX_MBUF_NEXT_BUFFER_IN_PKT_PTR(m_blk_ptr)  \
+		IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m_blk_ptr)
+
+
+#define IX_MBUF_NEXT_PKT_IN_CHAIN_PTR(m_blk_ptr)  \
+		IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m_blk_ptr)
+
+
+#define IX_MBUF_MDATA(m_blk_ptr)  \
+		IX_OSAL_MBUF_MDATA(m_blk_ptr)
+
+
+#define IX_MBUF_MLEN(m_blk_ptr) \
+		IX_OSAL_MBUF_MLEN(m_blk_ptr)
+
+
+#define IX_MBUF_TYPE(m_blk_ptr) \
+		IX_OSAL_MBUF_MTYPE(m_blk_ptr)
+
+/* Same as IX_MBUF_TYPE */
+#define IX_MBUF_MTYPE(m_blk_ptr) \
+                IX_OSAL_MBUF_MTYPE(m_blk_ptr)
+
+#define IX_MBUF_FLAGS(m_blk_ptr)	\
+		IX_OSAL_MBUF_FLAGS(m_blk_ptr)
+
+
+#define IX_MBUF_NET_POOL(m_blk_ptr)	\
+		IX_OSAL_MBUF_NET_POOL(m_blk_ptr)
+
+
+#define IX_MBUF_PKT_LEN(m_blk_ptr)	\
+		IX_OSAL_MBUF_PKT_LEN(m_blk_ptr)
+
+
+#define IX_MBUF_PRIV(m_blk_ptr)		\
+		IX_OSAL_MBUF_PRIV(m_blk_ptr)
+
+
+#define IX_MBUF_ALLOCATED_BUFF_LEN(m_blk_ptr)  \
+		IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(m_blk_ptr)
+
+
+#define IX_MBUF_ALLOCATED_BUFF_DATA(m_blk_ptr)  \
+		IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(m_blk_ptr)
+
+
+#define IX_MBUF_POOL_SIZE_ALIGN(size)   \
+		IX_OSAL_MBUF_POOL_SIZE_ALIGN(size)
+
+
+#define IX_MBUF_POOL_MBUF_AREA_SIZE_ALIGNED(count)	\
+		IX_OSAL_MBUF_POOL_MBUF_AREA_SIZE_ALIGNED(count)
+
+
+#define IX_MBUF_POOL_DATA_AREA_SIZE_ALIGNED(count, size) \
+		IX_OSAL_MBUF_POOL_DATA_AREA_SIZE_ALIGNED(count, size)
+
+
+#define IX_MBUF_POOL_MBUF_AREA_ALLOC(count, memAreaSize) \
+		IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC(count, memAreaSize)
+
+
+#define IX_MBUF_POOL_DATA_AREA_ALLOC(count, size, memAreaSize) \
+		IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC(count, size, memAreaSize)
+
+IX_STATUS
+ixOsalOsIxp400BackwardPoolInit (IX_OSAL_MBUF_POOL ** poolPtrPtr,
+				UINT32 count, UINT32 size, const char *name);
+
+
+/* This one needs extra steps*/
+#define IX_MBUF_POOL_INIT(poolPtr, count, size, name) \
+		ixOsalOsIxp400BackwardPoolInit( poolPtr, count,  size, name)
+
+
+#define IX_MBUF_POOL_INIT_NO_ALLOC(poolPtrPtr, bufPtr, dataPtr, count, size, name) \
+		(*poolPtrPtr = IX_OSAL_MBUF_NO_ALLOC_POOL_INIT(bufPtr, dataPtr, count, size, name))
+
+
+IX_STATUS
+ixOsalOsIxp400BackwardMbufPoolGet (IX_OSAL_MBUF_POOL * poolPtr,
+				   IX_OSAL_MBUF ** newBufPtrPtr);
+
+#define IX_MBUF_POOL_GET(poolPtr, bufPtrPtr) \
+		ixOsalOsIxp400BackwardMbufPoolGet(poolPtr, bufPtrPtr)
+
+
+#define IX_MBUF_POOL_PUT(bufPtr) \
+		IX_OSAL_MBUF_POOL_PUT(bufPtr)
+
+
+#define IX_MBUF_POOL_PUT_CHAIN(bufPtr) \
+		IX_OSAL_MBUF_POOL_PUT_CHAIN(bufPtr)
+
+
+#define IX_MBUF_POOL_SHOW(poolPtr) \
+		IX_OSAL_MBUF_POOL_SHOW(poolPtr)
+
+
+#define IX_MBUF_POOL_MDATA_RESET(bufPtr) \
+		IX_OSAL_MBUF_POOL_MDATA_RESET(bufPtr)
+
+#endif /* IX_OSAL_BACKWARD_BUFFER_MGT_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalBackwardCacheMMU.h b/marvell/uboot/drivers/net/npe/include/IxOsalBackwardCacheMMU.h
new file mode 100644
index 0000000..d9e20c0
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalBackwardCacheMMU.h
@@ -0,0 +1,45 @@
+/** 
+ * This file is intended to provide backward 
+ * compatibility for main osService/OSSL 
+ * APIs. 
+ *
+ * It shall be phased out gradually and users
+ * are strongly recommended to use IX_OSAL API.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_BACKWARD_CACHE_MMU_H
+#define IX_OSAL_BACKWARD_CACHE_MMU_H
+
+#ifdef IX_OSAL_CACHED
+#define IX_ACC_CACHE_ENABLED
+#endif
+
+#define IX_XSCALE_CACHE_LINE_SIZE IX_OSAL_CACHE_LINE_SIZE
+
+#define IX_ACC_DRV_DMA_MALLOC(size) IX_OSAL_CACHE_DMA_MALLOC(size)
+
+#define IX_ACC_DRV_DMA_FREE(ptr,size) IX_OSAL_CACHE_DMA_FREE(ptr)
+
+#define IX_MMU_VIRTUAL_TO_PHYSICAL_TRANSLATION(addr) IX_OSAL_MMU_VIRT_TO_PHYS(addr)
+
+#define IX_MMU_PHYSICAL_TO_VIRTUAL_TRANSLATION(addr) IX_OSAL_MMU_PHYS_TO_VIRT(addr)
+
+#define IX_ACC_DATA_CACHE_INVALIDATE(addr,size) IX_OSAL_CACHE_INVALIDATE(addr, size)
+
+#define IX_ACC_DATA_CACHE_FLUSH(addr,size) IX_OSAL_CACHE_FLUSH(addr,size)
+
+#endif /* IX_OSAL_BACKWARD_CACHE_MMU_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalBackwardMemMap.h b/marvell/uboot/drivers/net/npe/include/IxOsalBackwardMemMap.h
new file mode 100644
index 0000000..9b6cc72
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalBackwardMemMap.h
@@ -0,0 +1,117 @@
+/** 
+ * This file is intended to provide backward 
+ * compatibility for main osService/OSSL 
+ * APIs. 
+ *
+ * It shall be phased out gradually and users
+ * are strongly recommended to use IX_OSAL API.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#ifndef IX_OSAL_BACKWARD_MEM_MAP_H
+#define IX_OSAL_BACKWARD_MEM_MAP_H
+
+#include "IxOsal.h"
+
+#define IX_OSSERV_SWAP_LONG(wData) IX_OSAL_SWAP_LONG(wData)
+#define IX_OSSERV_SWAP_SHORT(sData) IX_OSAL_SWAP_SHORT(sData)
+
+#define IX_OSSERV_SWAP_SHORT_ADDRESS(sAddr) IX_OSAL_SWAP_SHORT_ADDRESS(sAddr)
+#define IX_OSSERV_SWAP_BYTE_ADDRESS(bAddr) IX_OSAL_SWAP_BYTE_ADDRESS(bAddr)
+
+#define IX_OSSERV_BE_XSTOBUSL(wData)  IX_OSAL_BE_XSTOBUSL(wData)
+#define IX_OSSERV_BE_XSTOBUSS(sData)  IX_OSAL_BE_XSTOBUSS(sData)
+#define IX_OSSERV_BE_XSTOBUSB(bData)  IX_OSAL_BE_XSTOBUSB(bData)
+#define IX_OSSERV_BE_BUSTOXSL(wData)  IX_OSAL_BE_BUSTOXSL(wData)
+#define IX_OSSERV_BE_BUSTOXSS(sData)  IX_OSAL_BE_BUSTOXSS(sData)
+#define IX_OSSERV_BE_BUSTOXSB(bData)  IX_OSAL_BE_BUSTOXSB(bData)
+
+#define IX_OSSERV_LE_AC_XSTOBUSL(wAddr) IX_OSAL_LE_AC_XSTOBUSL(wAddr)
+#define IX_OSSERV_LE_AC_XSTOBUSS(sAddr) IX_OSAL_LE_AC_XSTOBUSS(sAddr)
+#define IX_OSSERV_LE_AC_XSTOBUSB(bAddr) IX_OSAL_LE_AC_XSTOBUSB(bAddr)
+#define IX_OSSERV_LE_AC_BUSTOXSL(wAddr) IX_OSAL_LE_AC_BUSTOXSL(wAddr)
+#define IX_OSSERV_LE_AC_BUSTOXSS(sAddr) IX_OSAL_LE_AC_BUSTOXSS(sAddr)
+#define IX_OSSERV_LE_AC_BUSTOXSB(bAddr) IX_OSAL_LE_AC_BUSTOXSB(bAddr)
+
+#define IX_OSSERV_LE_DC_XSTOBUSL(wData) IX_OSAL_LE_DC_XSTOBUSL(wData)
+#define IX_OSSERV_LE_DC_XSTOBUSS(sData) IX_OSAL_LE_DC_XSTOBUSS(sData)
+#define IX_OSSERV_LE_DC_XSTOBUSB(bData) IX_OSAL_LE_DC_XSTOBUSB(bData)
+#define IX_OSSERV_LE_DC_BUSTOXSL(wData) IX_OSAL_LE_DC_BUSTOXSL(wData)
+#define IX_OSSERV_LE_DC_BUSTOXSS(sData) IX_OSAL_LE_DC_BUSTOXSS(sData)
+#define IX_OSSERV_LE_DC_BUSTOXSB(bData) IX_OSAL_LE_DC_BUSTOXSB(bData)
+
+#define IX_OSSERV_READ_LONG(wAddr)          IX_OSAL_READ_LONG(wAddr)
+#define IX_OSSERV_READ_SHORT(sAddr)         IX_OSAL_READ_SHORT(sAddr)
+#define IX_OSSERV_READ_BYTE(bAddr)          IX_OSAL_READ_BYTE(bAddr)
+#define IX_OSSERV_WRITE_LONG(wAddr, wData)  IX_OSAL_WRITE_LONG(wAddr, wData)
+#define IX_OSSERV_WRITE_SHORT(sAddr, sData) IX_OSAL_WRITE_SHORT(sAddr, sData)
+#define IX_OSSERV_WRITE_BYTE(bAddr, bData)  IX_OSAL_WRITE_BYTE(bAddr, bData)
+
+
+#define IX_OSSERV_READ_NPE_SHARED_LONG(wAddr)            IX_OSAL_READ_BE_SHARED_LONG(wAddr)
+#define IX_OSSERV_READ_NPE_SHARED_SHORT(sAddr)           IX_OSAL_READ_BE_SHARED_SHORT(sAddr)
+#define IX_OSSERV_WRITE_NPE_SHARED_LONG(wAddr, wData)    IX_OSAL_WRITE_BE_SHARED_LONG(wAddr, wData)
+#define IX_OSSERV_WRITE_NPE_SHARED_SHORT(sAddr, sData)   IX_OSAL_WRITE_BE_SHARED_SHORT(sAddr, sData)
+
+#define IX_OSSERV_SWAP_NPE_SHARED_LONG(wData)            IX_OSAL_SWAP_BE_SHARED_LONG(wData)
+#define IX_OSSERV_SWAP_NPE_SHARED_SHORT(sData)           IX_OSAL_SWAP_BE_SHARED_SHORT(sData)
+
+
+/* Map osServ address/size */
+#define IX_OSSERV_QMGR_MAP_SIZE			IX_OSAL_IXP400_QMGR_MAP_SIZE
+#define IX_OSSERV_EXP_REG_MAP_SIZE		IX_OSAL_IXP400_EXP_REG_MAP_SIZE
+#define IX_OSSERV_UART1_MAP_SIZE		IX_OSAL_IXP400_UART1_MAP_SIZE
+#define IX_OSSERV_UART2_MAP_SIZE		IX_OSAL_IXP400_UART2_MAP_SIZE
+#define IX_OSSERV_PMU_MAP_SIZE			IX_OSAL_IXP400_PMU_MAP_SIZE
+#define IX_OSSERV_OSTS_MAP_SIZE			IX_OSAL_IXP400_OSTS_MAP_SIZE
+#define IX_OSSERV_NPEA_MAP_SIZE			IX_OSAL_IXP400_NPEA_MAP_SIZE
+#define IX_OSSERV_NPEB_MAP_SIZE			IX_OSAL_IXP400_NPEB_MAP_SIZE
+#define IX_OSSERV_NPEC_MAP_SIZE			IX_OSAL_IXP400_NPEC_MAP_SIZE
+#define IX_OSSERV_ETHA_MAP_SIZE			IX_OSAL_IXP400_ETHA_MAP_SIZE
+#define IX_OSSERV_ETHB_MAP_SIZE			IX_OSAL_IXP400_ETHB_MAP_SIZE
+#define IX_OSSERV_USB_MAP_SIZE			IX_OSAL_IXP400_USB_MAP_SIZE
+#define IX_OSSERV_GPIO_MAP_SIZE			IX_OSAL_IXP400_GPIO_MAP_SIZE
+#define IX_OSSERV_EXP_BUS_MAP_SIZE		IX_OSAL_IXP400_EXP_BUS_MAP_SIZE
+#define IX_OSSERV_EXP_BUS_CS0_MAP_SIZE	IX_OSAL_IXP400_EXP_BUS_CS0_MAP_SIZE
+#define IX_OSSERV_EXP_BUS_CS1_MAP_SIZE	IX_OSAL_IXP400_EXP_BUS_CS1_MAP_SIZE
+#define IX_OSSERV_EXP_BUS_CS4_MAP_SIZE	IX_OSAL_IXP400_EXP_BUS_CS4_MAP_SIZE
+
+
+#define IX_OSSERV_GPIO_PHYS_BASE			IX_OSAL_IXP400_GPIO_PHYS_BASE
+#define IX_OSSERV_UART1_PHYS_BASE			IX_OSAL_IXP400_UART1_PHYS_BASE
+#define IX_OSSERV_UART2_PHYS_BASE			IX_OSAL_IXP400_UART2_PHYS_BASE
+#define IX_OSSERV_ETHA_PHYS_BASE			IX_OSAL_IXP400_ETHA_PHYS_BASE
+#define IX_OSSERV_ETHB_PHYS_BASE			IX_OSAL_IXP400_ETHB_PHYS_BASE
+#define IX_OSSERV_NPEA_PHYS_BASE			IX_OSAL_IXP400_NPEA_PHYS_BASE
+#define IX_OSSERV_NPEB_PHYS_BASE			IX_OSAL_IXP400_NPEB_PHYS_BASE
+#define IX_OSSERV_NPEC_PHYS_BASE			IX_OSAL_IXP400_NPEC_PHYS_BASE
+#define IX_OSSERV_PERIPHERAL_PHYS_BASE		IX_OSAL_IXP400_PERIPHERAL_PHYS_BASE
+#define IX_OSSERV_QMGR_PHYS_BASE			IX_OSAL_IXP400_QMGR_PHYS_BASE
+#define IX_OSSERV_OSTS_PHYS_BASE			IX_OSAL_IXP400_OSTS_PHYS_BASE
+#define IX_OSSERV_USB_PHYS_BASE				IX_OSAL_IXP400_USB_PHYS_BASE
+#define IX_OSSERV_EXP_BUS_PHYS_BASE			IX_OSAL_IXP400_EXP_BUS_PHYS_BASE
+#define IX_OSSERV_EXP_BUS_BOOT_PHYS_BASE	IX_OSAL_IXP400_EXP_BUS_BOOT_PHYS_BASE
+#define IX_OSSERV_EXP_BUS_CS0_PHYS_BASE		IX_OSAL_IXP400_EXP_BUS_CS0_PHYS_BASE
+#define IX_OSSERV_EXP_BUS_CS1_PHYS_BASE		IX_OSAL_IXP400_EXP_BUS_CS1_PHYS_BASE
+#define IX_OSSERV_EXP_BUS_CS4_PHYS_BASE		IX_OSAL_IXP400_EXP_BUS_CS4_PHYS_BASE
+#define IX_OSSERV_EXP_BUS_REGS_PHYS_BASE	IX_OSAL_IXP400_EXP_BUS_REGS_PHYS_BASE
+
+#define IX_OSSERV_MEM_MAP(physAddr, size)		IX_OSAL_MEM_MAP(physAddr, size)
+
+#define IX_OSSERV_MEM_UNMAP(virtAddr)			IX_OSAL_MEM_UNMAP(virtAddr)
+
+#endif /* IX_OSAL_BACKWARD_MEM_MAP_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalBackwardOsServices.h b/marvell/uboot/drivers/net/npe/include/IxOsalBackwardOsServices.h
new file mode 100644
index 0000000..761779d
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalBackwardOsServices.h
@@ -0,0 +1,101 @@
+/** 
+ * This file is intended to provide backward 
+ * compatibility for main osService/OSSL 
+ * APIs. 
+ *
+ * It shall be phased out gradually and users
+ * are strongly recommended to use IX_OSAL API.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_BACKWARD_OSSERVICES_H
+#define IX_OSAL_BACKWARD_OSSERVICES_H
+
+#ifndef __vxworks
+typedef UINT32 IX_IRQ_STATUS;
+#else
+typedef int IX_IRQ_STATUS;
+#endif
+
+typedef IxOsalMutex IxMutex;
+
+typedef IxOsalFastMutex IxFastMutex;
+
+typedef IxOsalVoidFnVoidPtr IxVoidFnVoidPtr;
+
+typedef IxOsalVoidFnPtr IxVoidFnPtr;
+
+
+#define LOG_NONE 	IX_OSAL_LOG_LVL_NONE
+#define LOG_USER 	IX_OSAL_LOG_LVL_USER
+#define LOG_FATAL 	IX_OSAL_LOG_LVL_FATAL
+#define LOG_ERROR  	IX_OSAL_LOG_LVL_ERROR
+#define LOG_WARNING	IX_OSAL_LOG_LVL_WARNING
+#define LOG_MESSAGE	IX_OSAL_LOG_LVL_MESSAGE
+#define LOG_DEBUG1  IX_OSAL_LOG_LVL_DEBUG1
+#define LOG_DEBUG2	IX_OSAL_LOG_LVL_DEBUG2
+#define LOG_DEBUG3 	IX_OSAL_LOG_LVL_DEBUG3
+#ifndef __vxworks
+#define LOG_ALL 	IX_OSAL_LOG_LVL_ALL
+#endif
+
+PUBLIC IX_STATUS
+ixOsServIntBind (int level, void (*routine) (void *), void *parameter);
+
+PUBLIC IX_STATUS ixOsServIntUnbind (int level);
+
+
+PUBLIC int ixOsServIntLock (void);
+
+PUBLIC void ixOsServIntUnlock (int lockKey);
+
+
+PUBLIC int ixOsServIntLevelSet (int level);
+
+PUBLIC IX_STATUS ixOsServMutexInit (IxMutex * mutex);
+
+PUBLIC IX_STATUS ixOsServMutexLock (IxMutex * mutex);
+
+PUBLIC IX_STATUS ixOsServMutexUnlock (IxMutex * mutex);
+
+PUBLIC IX_STATUS ixOsServMutexDestroy (IxMutex * mutex);
+
+PUBLIC IX_STATUS ixOsServFastMutexInit (IxFastMutex * mutex);
+
+PUBLIC IX_STATUS ixOsServFastMutexTryLock (IxFastMutex * mutex);
+
+PUBLIC IX_STATUS ixOsServFastMutexUnlock (IxFastMutex * mutex);
+
+PUBLIC int
+ixOsServLog (int level, char *format, int arg1, int arg2, int arg3, int arg4,
+	     int arg5, int arg6);
+
+
+PUBLIC int ixOsServLogLevelSet (int level);
+
+PUBLIC void ixOsServSleep (int microseconds);
+
+PUBLIC void ixOsServTaskSleep (int milliseconds);
+
+PUBLIC unsigned int ixOsServTimestampGet (void);
+
+
+PUBLIC void ixOsServUnload (void);
+
+PUBLIC void ixOsServYield (void);
+
+#endif
+/* IX_OSAL_BACKWARD_OSSERVICES_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalBackwardOssl.h b/marvell/uboot/drivers/net/npe/include/IxOsalBackwardOssl.h
new file mode 100644
index 0000000..c9deb54
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalBackwardOssl.h
@@ -0,0 +1,248 @@
+/** 
+ * This file is intended to provide backward 
+ * compatibility for main osService/OSSL 
+ * APIs. 
+ *
+ * It shall be phased out gradually and users
+ * are strongly recommended to use IX_OSAL API.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_BACKWARD_OSSL_H
+#define IX_OSAL_BACKWARD_OSSL_H
+
+
+typedef IxOsalThread ix_ossl_thread_t;
+
+typedef IxOsalSemaphore ix_ossl_sem_t;
+
+typedef IxOsalMutex ix_ossl_mutex_t;
+
+typedef IxOsalTimeval ix_ossl_time_t;
+
+
+/* Map sub-fields for ix_ossl_time_t */
+#define tv_sec secs
+#define tv_nec nsecs
+
+
+typedef IX_STATUS ix_error;
+
+typedef UINT32 ix_ossl_thread_priority;
+
+typedef UINT32 ix_uint32;
+
+
+#define IX_OSSL_ERROR_SUCCESS IX_SUCCESS
+
+#define IX_ERROR_SUCCESS IX_SUCCESS
+
+
+typedef enum
+{
+    IX_OSSL_SEM_UNAVAILABLE = 0,
+    IX_OSSL_SEM_AVAILABLE
+} ix_ossl_sem_state;
+
+
+typedef enum
+{
+    IX_OSSL_MUTEX_UNLOCK = 0,
+    IX_OSSL_MUTEX_LOCK
+} ix_ossl_mutex_state;
+
+
+typedef IxOsalVoidFnVoidPtr ix_ossl_thread_entry_point_t;
+
+
+#define	IX_OSSL_THREAD_PRI_HIGH 	90
+#define IX_OSSL_THREAD_PRI_MEDIUM 	160
+#define IX_OSSL_THREAD_PRI_LOW 		240
+
+
+#define IX_OSSL_WAIT_FOREVER    IX_OSAL_WAIT_FOREVER
+
+#define IX_OSSL_WAIT_NONE       IX_OSAL_WAIT_NONE
+
+#define BILLION  IX_OSAL_BILLION
+
+#define IX_OSSL_TIME_EQ(a,b)  IX_OSAL_TIME_EQ(a,b)
+
+#define IX_OSSL_TIME_GT(a,b)  IX_OSAL_TIME_GT(a,b)
+
+#define IX_OSSL_TIME_LT(a,b)  IX_OSAL_TIME_LT(a,b)
+
+#define IX_OSSL_TIME_ADD(a,b)  IX_OSAL_TIME_ADD(a,b)
+
+#define IX_OSSL_TIME_SUB(a,b)  IX_OSAL_TIME_SUB(a,b)
+
+
+/* a is tick, b is timeval */
+#define IX_OSSL_TIME_CONVERT_TO_TICK(a,b)  \
+		 (a) = IX_OSAL_TIMEVAL_TO_TICKS(b)
+
+
+
+
+PUBLIC IX_STATUS
+ixOsalOsIxp400BackwardOsslThreadCreate (IxOsalVoidFnVoidPtr entryPoint,
+					void *arg, IxOsalThread * ptrThread);
+
+#define ix_ossl_thread_create(entryPoint, arg, ptrTid) \
+		ixOsalOsIxp400BackwardOsslThreadCreate(entryPoint, arg, ptrTid)
+
+
+/* void ix_ossl_thread_exit(ix_error retError, void* retObj) */
+#define ix_ossl_thread_exit(retError, retObj)   \
+		ixOsalThreadExit()
+
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardOsslThreadKill (IxOsalThread tid);
+
+/* ix_error ix_ossl_thread_kill(tid) */
+#define ix_ossl_thread_kill(tid) \
+		ixOsalOsIxp400BackwardOsslThreadKill(tid)
+
+
+PUBLIC IX_STATUS
+ixOsalOsIxp400BackwardOsslThreadSetPriority (IxOsalThread tid,
+					     UINT32 priority);
+
+
+/* 
+ * ix_error ix_ossl_thread_set_priority(ix_ossl_thread_t tid,
+ *                             ix_ossl_thread_priority priority
+ *                             ); 
+ */
+
+#define ix_ossl_thread_set_priority(tid, priority) \
+		ixOsalOsIxp400BackwardOsslThreadSetPriority(tid, priority)
+
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardOsslTickGet (int *pticks);
+
+#define ix_ossl_tick_get(pticks) \
+		ixOsalOsIxp400BackwardOsslTickGet(pticks)
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardOsslThreadDelay (int ticks);
+
+#define ix_ossl_thread_delay(ticks) ixOsalOsIxp400BackwardOsslThreadDelay(ticks)
+
+
+
+/* ix_error ix_ossl_sem_init(int start_value, ix_ossl_sem_t* sid); */
+/* Note sid is a pointer to semaphore */
+#define ix_ossl_sem_init(value, sid) \
+		ixOsalSemaphoreInit(sid, value)
+
+
+PUBLIC IX_STATUS
+ixOsalOsIxp400BackwardOsslSemaphoreWait (IxOsalSemaphore semaphore,
+					 INT32 timeout);
+
+
+/*
+ix_error ix_ossl_sem_take(
+                          ix_ossl_sem_t sid,
+                          ix_uint32 timeout
+                         );
+*/
+
+#define ix_ossl_sem_take( sid, timeout) \
+		ixOsalOsIxp400BackwardOsslSemaphoreWait(sid, timeout)
+
+
+
+PUBLIC IX_STATUS
+ixOsalOsIxp400BackwardOsslSemaphorePost (IxOsalSemaphore sid);
+
+/*ix_error ix_ossl_sem_give(ix_ossl_sem_t sid); */
+#define ix_ossl_sem_give(sid) \
+		ixOsalOsIxp400BackwardOsslSemaphorePost(sid);
+
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardSemaphoreDestroy (IxOsalSemaphore sid);
+
+#define ix_ossl_sem_fini(sid) \
+		ixOsalOsIxp400BackwardSemaphoreDestroy(sid)
+
+
+PUBLIC IX_STATUS
+ixOsalOsIxp400BackwardOsslMutexInit (ix_ossl_mutex_state start_state,
+				     IxOsalMutex * pMutex);
+
+
+/* ix_error ix_ossl_mutex_init(ix_ossl_mutex_state start_state, ix_ossl_mutex_t* mid); */
+#define ix_ossl_mutex_init(start_state, pMutex) \
+		ixOsalOsIxp400BackwardOsslMutexInit(start_state, pMutex)
+
+
+PUBLIC IX_STATUS
+ixOsalOsIxp400BackwardOsslMutexLock (IxOsalMutex mid, INT32 timeout);
+
+/*
+ix_error ix_ossl_mutex_lock(
+                            ix_ossl_mutex_t mid, 
+                            ix_uint32 timeout
+                           );
+*/
+#define ix_ossl_mutex_lock(mid, timeout) \
+		ixOsalOsIxp400BackwardOsslMutexLock(mid, timout)
+
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardOsslMutexUnlock (IxOsalMutex mid);
+
+/* ix_error ix_ossl_mutex_unlock(ix_ossl_mutex_t mid); */
+#define ix_ossl_mutex_unlock(mid) \
+		ixOsalOsIxp400BackwardOsslMutexUnlock(mid)
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardOsslMutexDestroy (IxOsalMutex mid);
+
+#define ix_ossl_mutex_fini(mid) \
+		ixOsalOsIxp400BackwardOsslMutexDestroy(mid);
+
+#define ix_ossl_sleep(sleeptime_ms) \
+		ixOsalSleep(sleeptime_ms)
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardOsslSleepTick (UINT32 ticks);
+
+#define ix_ossl_sleep_tick(sleeptime_ticks) \
+		ixOsalOsIxp400BackwardOsslSleepTick(sleeptime_ticks)
+
+
+PUBLIC IX_STATUS ixOsalOsIxp400BackwardOsslTimeGet (IxOsalTimeval * pTv);
+
+#define ix_ossl_time_get(pTv)    \
+		ixOsalOsIxp400BackwardOsslTimeGet(pTv)
+
+
+typedef UINT32 ix_ossl_size_t;
+
+#define ix_ossl_malloc(arg_size) \
+		ixOsalMemAlloc(arg_size)
+
+#define ix_ossl_free(arg_pMemory) \
+		ixOsalMemFree(arg_pMemory)
+
+
+#define ix_ossl_memcpy(arg_pDest, arg_pSrc,arg_Count) \
+		ixOsalMemCopy(arg_pDest, arg_pSrc,arg_Count)
+
+#define ix_ossl_memset(arg_pDest, arg_pChar, arg_Count) \
+		ixOsalMemSet(arg_pDest, arg_pChar, arg_Count)
+
+
+#endif /* IX_OSAL_BACKWARD_OSSL_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalBufferMgt.h b/marvell/uboot/drivers/net/npe/include/IxOsalBufferMgt.h
new file mode 100644
index 0000000..1f9e373
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalBufferMgt.h
@@ -0,0 +1,570 @@
+/**
+ * @file IxOsalBufferMgt.h
+ *
+ * @brief OSAL Buffer pool management and buffer management definitions.
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+/* @par
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 
+ *      The Regents of the University of California. All rights reserved.
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsalBufferMgt_H
+#define IxOsalBufferMgt_H
+
+#include "IxOsal.h"
+/**
+ * @defgroup IxOsalBufferMgt OSAL Buffer Management Module.
+ *
+ * @brief Buffer management module for IxOsal
+ *
+ * @{ 
+ */
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_MAX_POOLS
+ *
+ * @brief The maximum number of pools that can be allocated, must be 
+ *        a multiple of 32 as required by implementation logic.
+ * @note  This can safely be increased if more pools are required.
+ */
+#define IX_OSAL_MBUF_MAX_POOLS      32
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_NAME_LEN
+ *
+ * @brief The maximum string length of the pool name
+ */
+#define IX_OSAL_MBUF_POOL_NAME_LEN  64
+
+
+
+/**
+ *  Define IX_OSAL_MBUF
+ */
+
+
+/* forward declaration of internal structure */
+struct __IXP_BUF;
+
+/* 
+ * OS can define it in IxOsalOs.h to skip the following
+ * definition.
+ */
+#ifndef IX_OSAL_ATTRIBUTE_ALIGN32
+#define IX_OSAL_ATTRIBUTE_ALIGN32 __attribute__ ((aligned(32)))
+#endif
+
+/* release v1.4 backward compatible definitions */
+struct __IX_MBUF
+{
+    struct __IXP_BUF *ix_next IX_OSAL_ATTRIBUTE_ALIGN32;
+    struct __IXP_BUF *ix_nextPacket;
+    UINT8 *ix_data;
+    UINT32 ix_len;  
+    unsigned char ix_type;
+    unsigned char ix_flags;
+    unsigned short ix_reserved;
+    UINT32 ix_rsvd;
+    UINT32 ix_PktLen; 
+    void *ix_priv;     
+};
+
+struct __IX_CTRL
+{
+    UINT32 ix_reserved[2];        /**< Reserved field */
+    UINT32 ix_signature;          /**< Field to indicate if buffers are allocated by the system */    
+    UINT32 ix_allocated_len;      /**< Allocated buffer length */  
+    UINT32 ix_allocated_data;     /**< Allocated buffer data pointer */  
+    void *ix_pool;                /**< pointer to the buffer pool */
+    struct __IXP_BUF *ix_chain;   /**< chaining */ 
+    void *ix_osbuf_ptr;           /**< Storage for OS-specific buffer pointer */
+};
+
+struct __IX_NE_SHARED
+{
+    UINT32 reserved[8] IX_OSAL_ATTRIBUTE_ALIGN32;   /**< Reserved area for NPE Service-specific usage */
+};
+
+
+/* 
+ * IXP buffer structure 
+ */
+typedef struct __IXP_BUF
+{
+    struct __IX_MBUF ix_mbuf IX_OSAL_ATTRIBUTE_ALIGN32; /**< buffer header */
+    struct __IX_CTRL ix_ctrl;                           /**< buffer management */
+    struct __IX_NE_SHARED ix_ne;                        /**< Reserved area for NPE Service-specific usage*/
+} IXP_BUF;
+
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def typedef IX_OSAL_MBUF
+ *
+ * @brief Generic IXP mbuf format.
+ */
+typedef IXP_BUF IX_OSAL_MBUF;
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_IXP_NEXT_BUFFER_IN_PKT_PTR(m_blk_ptr)
+ *
+ * @brief Return pointer to the next mbuf in a single packet
+ */
+#define IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m_blk_ptr)  \
+        (m_blk_ptr)->ix_mbuf.ix_next
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m_blk_ptr)
+ *
+ * @brief Return pointer to the next packet in the chain
+ */
+#define IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m_blk_ptr)  \
+        (m_blk_ptr)->ix_mbuf.ix_nextPacket
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_MDATA(m_blk_ptr)
+ *
+ * @brief Return pointer to the data in the mbuf
+ */
+#define IX_OSAL_MBUF_MDATA(m_blk_ptr)       (m_blk_ptr)->ix_mbuf.ix_data
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_MLEN(m_blk_ptr)
+ *
+ * @brief Return the data length
+ */
+#define IX_OSAL_MBUF_MLEN(m_blk_ptr) \
+    (m_blk_ptr)->ix_mbuf.ix_len
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_MTYPE(m_blk_ptr)
+ *
+ * @brief Return the data type in the mbuf
+ */
+#define IX_OSAL_MBUF_MTYPE(m_blk_ptr) \
+    (m_blk_ptr)->ix_mbuf.ix_type
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_FLAGS(m_blk_ptr)
+ *
+ * @brief Return the buffer flags
+ */
+#define IX_OSAL_MBUF_FLAGS(m_blk_ptr)       \
+        (m_blk_ptr)->ix_mbuf.ix_flags
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_NET_POOL(m_blk_ptr)
+ *
+ * @brief Return pointer to a network pool
+ */
+#define IX_OSAL_MBUF_NET_POOL(m_blk_ptr)	\
+        (m_blk_ptr)->ix_ctrl.ix_pool
+
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_PKT_LEN(m_blk_ptr)
+ *
+ * @brief Return the total length of all the data in
+ * the mbuf chain for this packet
+ */
+#define IX_OSAL_MBUF_PKT_LEN(m_blk_ptr) \
+        (m_blk_ptr)->ix_mbuf.ix_PktLen
+
+
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_PRIV(m_blk_ptr)
+ *
+ * @brief Return the private field
+ */
+#define IX_OSAL_MBUF_PRIV(m_blk_ptr)        \
+        (m_blk_ptr)->ix_mbuf.ix_priv
+
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_SIGNATURE(m_blk_ptr)
+ *
+ * @brief Return the signature field of IX_OSAL_MBUF
+ */
+#define IX_OSAL_MBUF_SIGNATURE(m_blk_ptr)  \
+        (m_blk_ptr)->ix_ctrl.ix_signature
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_OSBUF_PTR(m_blk_ptr)
+ *
+ * @brief Return ix_osbuf_ptr field of IX_OSAL_MBUF, which is used to store OS-specific buffer pointer during a buffer conversion.
+ */
+#define IX_OSAL_MBUF_OSBUF_PTR(m_blk_ptr)  \
+        (m_blk_ptr)->ix_ctrl.ix_osbuf_ptr
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(m_blk_ptr)
+ *
+ * @brief Return the allocated buffer size
+ */
+#define IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(m_blk_ptr)  \
+        (m_blk_ptr)->ix_ctrl.ix_allocated_len
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(m_blk_ptr)
+ *
+ * @brief Return the allocated buffer pointer
+ */
+#define IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(m_blk_ptr)  \
+        (m_blk_ptr)->ix_ctrl.ix_allocated_data
+
+
+
+/* Name length */
+#define IX_OSAL_MBUF_POOL_NAME_LEN  64
+
+
+/****************************************************
+ * Macros for buffer pool management
+ ****************************************************/
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_FREE_COUNT(m_pool_ptr
+ *
+ * @brief Return the total number of freed buffers left in the pool.
+ */
+#define IX_OSAL_MBUF_POOL_FREE_COUNT(m_pool_ptr) \
+                    ixOsalBuffPoolFreeCountGet(m_pool_ptr)
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_SIZE_ALIGN
+ *
+ * @brief This macro takes an integer as an argument and
+ * rounds it up to be a multiple of the memory cache-line 
+ * size.
+ *
+ * @param int [in] size - the size integer to be rounded up
+ *
+ * @return int - the size, rounded up to a multiple of
+ *               the cache-line size
+ */
+#define IX_OSAL_MBUF_POOL_SIZE_ALIGN(size)                 \
+    ((((size) + (IX_OSAL_CACHE_LINE_SIZE - 1)) /      \
+        IX_OSAL_CACHE_LINE_SIZE) *                  \
+            IX_OSAL_CACHE_LINE_SIZE)
+
+/* Don't use this directly, use macro */
+PUBLIC UINT32 ixOsalBuffPoolMbufAreaSizeGet (int count);
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_MBUF_AREA_SIZE_ALIGNED
+ *
+ * @brief This macro calculates, from the number of mbufs required, the 
+ * size of the memory area required to contain the mbuf headers for the
+ * buffers in the pool.  The size to be used for each mbuf header is 
+ * rounded up to a multiple of the cache-line size, to ensure
+ * each mbuf header aligns on a cache-line boundary.
+ * This macro is used by IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC()
+ *
+ * @param int [in] count - the number of buffers the pool will contain
+ *
+ * @return int - the total size required for the pool mbuf area (aligned)
+ */
+#define IX_OSAL_MBUF_POOL_MBUF_AREA_SIZE_ALIGNED(count) \
+        ixOsalBuffPoolMbufAreaSizeGet(count)
+
+
+/* Don't use this directly, use macro */
+PUBLIC UINT32 ixOsalBuffPoolDataAreaSizeGet (int count, int size);
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_DATA_AREA_SIZE_ALIGNED
+ *
+ * @brief This macro calculates, from the number of mbufs required and the
+ * size of the data portion for each mbuf, the size of the data memory area
+ * required. The size is adjusted to ensure alignment on cache line boundaries.
+ * This macro is used by IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC()
+ *
+ *
+ * @param int [in] count - The number of mbufs in the pool.
+ * @param int [in] size  - The desired size for each mbuf data portion.
+ *                         This size will be rounded up to a multiple of the
+ *                         cache-line size to ensure alignment on cache-line
+ *                         boundaries for each data block.
+ *
+ * @return int - the total size required for the pool data area (aligned)
+ */
+#define IX_OSAL_MBUF_POOL_DATA_AREA_SIZE_ALIGNED(count, size) \
+        ixOsalBuffPoolDataAreaSizeGet((count), (size))
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC
+ *
+ * @brief Allocates the memory area needed for the number of mbuf headers
+ * specified by <i>count</i>.
+ * This macro ensures the mbuf headers align on cache line boundaries.
+ * This macro evaluates to a pointer to the memory allocated.
+ *
+ * @param int [in] count - the number of mbufs the pool will contain
+ * @param int [out] memAreaSize - the total amount of memory allocated
+ *
+ * @return void * - a pointer to the allocated memory area
+ */
+#define IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC(count, memAreaSize) \
+    IX_OSAL_CACHE_DMA_MALLOC((memAreaSize =                 \
+        IX_OSAL_MBUF_POOL_MBUF_AREA_SIZE_ALIGNED(count)))
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC
+ *
+ * @brief Allocates the memory pool for the data portion of the pool mbufs.
+ * The number of mbufs is specified by <i>count</i>.  The size of the data
+ * portion of each mbuf is specified by <i>size</i>.
+ * This macro ensures the mbufs are aligned on cache line boundaries
+ * This macro evaluates to a pointer to the memory allocated.
+ *
+ * @param int [in] count - the number of mbufs the pool will contain
+ * @param int [in] size - the desired size (in bytes) required for the data
+ *                        portion of each mbuf.  Note that this size may be
+ *                        rounded up to ensure alignment on cache-line
+ *                        boundaries.
+ * @param int [out] memAreaSize - the total amount of memory allocated
+ *
+ * @return void * - a pointer to the allocated memory area
+ */
+#define IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC(count, size, memAreaSize) \
+    IX_OSAL_CACHE_DMA_MALLOC((memAreaSize =                     \
+        IX_OSAL_MBUF_POOL_DATA_AREA_SIZE_ALIGNED(count,size)))
+
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_INIT
+ *
+ * @brief Wrapper macro for ixOsalPoolInit() 
+ * See function description below for details.
+ */
+#define IX_OSAL_MBUF_POOL_INIT(count, size, name) \
+    ixOsalPoolInit((count), (size), (name))
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_NO_ALLOC_POOL_INIT
+ *
+ * @return Pointer to the new pool or NULL if the initialization failed.
+ *
+ * @brief Wrapper macro for ixOsalNoAllocPoolInit() 
+ * See function description below for details.
+ * 
+ */
+#define IX_OSAL_MBUF_NO_ALLOC_POOL_INIT(bufPtr, dataPtr, count, size, name) \
+    ixOsalNoAllocPoolInit( (bufPtr), (dataPtr), (count), (size), (name))
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_GET
+ *
+ * @brief Wrapper macro for ixOsalMbufAlloc() 
+ * See function description below for details.
+ */
+#define IX_OSAL_MBUF_POOL_GET(poolPtr) \
+        ixOsalMbufAlloc(poolPtr)
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_PUT
+ *
+ * @brief Wrapper macro for ixOsalMbufFree() 
+ * See function description below for details.
+ */
+#define IX_OSAL_MBUF_POOL_PUT(bufPtr) \
+    ixOsalMbufFree(bufPtr)
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_PUT_CHAIN
+ *
+ * @brief Wrapper macro for ixOsalMbufChainFree() 
+ * See function description below for details.
+ */
+#define IX_OSAL_MBUF_POOL_PUT_CHAIN(bufPtr) \
+    ixOsalMbufChainFree(bufPtr)
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_SHOW
+ *
+ * @brief Wrapper macro for ixOsalMbufPoolShow() 
+ * See function description below for details.
+ */
+#define IX_OSAL_MBUF_POOL_SHOW(poolPtr) \
+    ixOsalMbufPoolShow(poolPtr)
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_MDATA_RESET
+ *
+ * @brief Wrapper macro for ixOsalMbufDataPtrReset() 
+ * See function description below for details.
+ */
+#define IX_OSAL_MBUF_POOL_MDATA_RESET(bufPtr) \
+    ixOsalMbufDataPtrReset(bufPtr)
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_MBUF_POOL_UNINIT
+ *
+ * @brief Wrapper macro for ixOsalBuffPoolUninit() 
+ * See function description below for details.
+ */
+#define IX_OSAL_MBUF_POOL_UNINIT(m_pool_ptr)  \
+        ixOsalBuffPoolUninit(m_pool_ptr)
+
+/* 
+ * Include OS-specific bufferMgt definitions 
+ */
+#include "IxOsalOsBufferMgt.h"
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_CONVERT_OSBUF_TO_IXPBUF( osBufPtr, ixpBufPtr)
+ *
+ * @brief Convert pre-allocated os-specific buffer format to OSAL IXP_BUF (IX_OSAL_MBUF) format. 
+ * It is users' responsibility to provide pre-allocated and valid buffer pointers.
+ * @param osBufPtr (in) - a pre-allocated os-specific buffer pointer.
+ * @param ixpBufPtr (in)- a pre-allocated OSAL IXP_BUF pointer
+ * @return None
+ */
+#define IX_OSAL_CONVERT_OSBUF_TO_IXPBUF( osBufPtr, ixpBufPtr) \
+        IX_OSAL_OS_CONVERT_OSBUF_TO_IXPBUF( osBufPtr, ixpBufPtr)        
+
+
+/**
+ * @ingroup IxOsalBufferMgt
+ *
+ * @def IX_OSAL_CONVERT_IXPBUF_TO_OSBUF( ixpBufPtr, osBufPtr)
+ *
+ * @brief Convert pre-allocated OSAL IXP_BUF (IX_OSAL_MBUF) format to os-specific buffer pointers.
+ * @param ixpBufPtr (in) - OSAL IXP_BUF pointer
+ * @param osBufPtr (out) - os-specific buffer pointer.
+ * @return None
+ */
+
+#define IX_OSAL_CONVERT_IXPBUF_TO_OSBUF( ixpBufPtr, osBufPtr)  \
+        IX_OSAL_OS_CONVERT_IXPBUF_TO_OSBUF( ixpBufPtr, osBufPtr)
+
+
+PUBLIC IX_OSAL_MBUF_POOL *ixOsalPoolInit (UINT32 count,
+                      UINT32 size, const char *name);
+
+PUBLIC IX_OSAL_MBUF_POOL *ixOsalNoAllocPoolInit (void *poolBufPtr,
+                         void *poolDataPtr,
+						 UINT32 count,
+						 UINT32 size,
+						 const char *name);
+
+PUBLIC IX_OSAL_MBUF *ixOsalMbufAlloc (IX_OSAL_MBUF_POOL * pool);
+
+PUBLIC IX_OSAL_MBUF *ixOsalMbufFree (IX_OSAL_MBUF * mbuf);
+
+PUBLIC void ixOsalMbufChainFree (IX_OSAL_MBUF * mbuf);
+
+PUBLIC void ixOsalMbufDataPtrReset (IX_OSAL_MBUF * mbuf);
+
+PUBLIC void ixOsalMbufPoolShow (IX_OSAL_MBUF_POOL * pool);
+
+PUBLIC IX_STATUS ixOsalBuffPoolUninit (IX_OSAL_MBUF_POOL * pool);
+
+PUBLIC UINT32 ixOsalBuffPoolFreeCountGet(IX_OSAL_MBUF_POOL * pool);
+
+
+/**
+ * @} IxOsalBufferMgt
+ */
+
+
+#endif /* IxOsalBufferMgt_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalBufferMgtDefault.h b/marvell/uboot/drivers/net/npe/include/IxOsalBufferMgtDefault.h
new file mode 100644
index 0000000..376c498
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalBufferMgtDefault.h
@@ -0,0 +1,64 @@
+/**
+ * @file IxOsalBufferMgtDefault.h
+ *
+ * @brief Default buffer pool management and buffer management
+ *        definitions.
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IX_OSAL_BUFFER_MGT_DEFAULT_H
+#define IX_OSAL_BUFFER_MGT_DEFAULT_H
+
+/**
+ * @enum IxMbufPoolAllocationType
+ * @brief Used to indicate how the pool memory was allocated
+ */
+
+typedef enum
+{
+    IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC = 0, /**< mbuf pool allocated by the system */
+    IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC	 /**< mbuf pool allocated by the user */
+} IxOsalMbufPoolAllocationType;
+
+
+/**
+ * @brief Implementation of buffer pool structure for use with non-VxWorks OS
+ */
+
+typedef struct
+{
+    IX_OSAL_MBUF *nextFreeBuf;	/**< Pointer to the next free mbuf              */
+    void *mbufMemPtr;	   /**< Pointer to the mbuf memory area            */
+    void *dataMemPtr;	   /**< Pointer to the data memory area            */
+    int bufDataSize;	   /**< The size of the data portion of each mbuf  */
+    int totalBufsInPool;   /**< Total number of mbufs in the pool          */
+    int freeBufsInPool;	   /**< Number of free mbufs currently in the pool */
+    int mbufMemSize;	   /**< The size of the pool mbuf memory area      */
+    int dataMemSize;	   /**< The size of the pool data memory area      */
+    char name[IX_OSAL_MBUF_POOL_NAME_LEN + 1];	 /**< Descriptive name for pool */
+    IxOsalMbufPoolAllocationType poolAllocType;
+    unsigned int poolIdx;  /**< Pool Index */ 
+} IxOsalMbufPool;
+
+typedef IxOsalMbufPool IX_OSAL_MBUF_POOL;
+
+
+PUBLIC IX_STATUS ixOsalBuffPoolUninit (IX_OSAL_MBUF_POOL * pool);
+
+
+#endif /* IX_OSAL_BUFFER_MGT_DEFAULT_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalConfig.h b/marvell/uboot/drivers/net/npe/include/IxOsalConfig.h
new file mode 100644
index 0000000..81449f1
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalConfig.h
@@ -0,0 +1,52 @@
+/**
+ * @file  IxOsalConfig.h
+ *
+ * @brief OSAL Configuration header file
+ * 
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/* 
+ * This file contains user-editable fields for modules inclusion.
+ */
+#ifndef IxOsalConfig_H
+#define IxOsalConfig_H
+
+
+/*
+ * Note: in the future these config options may
+ * become build time decision. 
+ */
+
+/* Choose cache */
+#define IX_OSAL_CACHED
+/* #define IX_OSAL_UNCACHED */
+
+
+/*
+ * Select the module headers to include
+ */
+#include "IxOsalIoMem.h"	/* I/O Memory Management module API */
+#include "IxOsalBufferMgt.h"	/* Buffer Management module API */
+
+/*
+ * Select main platform header file to use
+ */
+#include "IxOsalOem.h"
+
+
+
+#endif /* IxOsalConfig_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalEndianess.h b/marvell/uboot/drivers/net/npe/include/IxOsalEndianess.h
new file mode 100644
index 0000000..01de2c5
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalEndianess.h
@@ -0,0 +1,110 @@
+/** 
+ * @file IxOsalEndianess.h (Obsolete file) 
+ * 
+ * @brief Header file for determining system endianess and OS
+ * 
+ * @par
+ * @version $Revision: 1.1
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#ifndef IxOsalEndianess_H
+#define IxOsalEndianess_H
+
+#if defined (__vxworks) || defined (__linux)
+
+/* get ntohl/ntohs/htohl/htons macros and CPU definitions for VxWorks */
+/* #include <netinet/in.h>  */
+
+#elif defined (__wince)
+
+/* get ntohl/ntohs/htohl/htons macros definitions for WinCE */
+#include <Winsock2.h>
+
+#else
+
+#error Unknown OS, please add a section with the include file for htonl/htons/ntohl/ntohs
+
+#endif /* vxworks or linux or wince */
+
+/* Compiler specific endianness selector - WARNING this works only with arm gcc, use appropriate defines with diab */
+
+#ifndef __wince
+
+#if defined (__ARMEL__)
+
+#ifndef __LITTLE_ENDIAN
+
+#define __LITTLE_ENDIAN
+
+#endif /* _LITTLE_ENDIAN */
+
+#elif defined (__ARMEB__) || CPU == SIMSPARCSOLARIS
+
+#ifndef __BIG_ENDIAN
+
+#define __BIG_ENDIAN
+
+#endif /* __BIG_ENDIAN */
+
+#else
+
+#error Error, could not identify target endianness
+
+#endif /* endianness selector no WinCE OSes */
+
+#else /* ndef __wince */
+
+#define __LITTLE_ENDIAN
+
+#endif /* def __wince */
+
+
+/* OS mode selector */
+#if defined (__vxworks) && defined (__LITTLE_ENDIAN)
+
+#define IX_OSAL_VXWORKS_LE
+
+#elif defined (__vxworks) && defined (__BIG_ENDIAN)
+
+#define IX_OSAL_VXWORKS_BE
+
+#elif defined (__linux) && defined (__BIG_ENDIAN)
+
+#define IX_OSAL_LINUX_BE
+
+#elif defined (__linux) && defined (__LITTLE_ENDIAN)
+
+#define IX_OSAL_LINUX_LE
+
+#elif defined (BOOTLOADER_BLD) && defined (__LITTLE_ENDIAN)
+
+#define IX_OSAL_EBOOT_LE
+
+#elif defined (__wince) && defined (__LITTLE_ENDIAN)
+
+#define IX_OSAL_WINCE_LE
+
+#else
+
+#error Unknown OS/Endianess combination - only vxWorks BE LE, Linux BE LE, WinCE BE LE are supported
+
+#endif /* mode selector */
+
+
+
+#endif /* IxOsalEndianess_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalIoMem.h b/marvell/uboot/drivers/net/npe/include/IxOsalIoMem.h
new file mode 100644
index 0000000..7cb9c18
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalIoMem.h
@@ -0,0 +1,298 @@
+/*
+ * @file        IxOsalIoMem.h
+ * @author	Intel Corporation
+ * @date        25-08-2004
+ *
+ * @brief       description goes here
+ */
+
+/**
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsalIoMem_H
+#define IxOsalIoMem_H
+
+
+/*
+ * Decide OS and Endianess, such as IX_OSAL_VXWORKS_LE.
+ */
+#include "IxOsalEndianess.h"
+
+/**
+ * @defgroup IxOsalIoMem Osal IoMem module
+ *
+ * @brief I/O memory and endianess support.
+ *
+ * @{ 
+ */
+
+/* Low-level conversion macros - DO NOT USE UNLESS ABSOLUTELY NEEDED */
+#ifndef __wince
+
+
+/* 
+ * Private function to swap word
+ */
+#ifdef __XSCALE__
+static __inline__ UINT32
+ixOsalCoreWordSwap (UINT32 wordIn)
+{
+    /*
+     * Storage for the swapped word 
+     */
+    UINT32 wordOut;
+
+    /*
+     * wordIn = A, B, C, D 
+     */
+    __asm__ (" eor r1, %1, %1, ror #16;"	/* R1 =      A^C, B^D, C^A, D^B */
+	     " bic r1, r1, #0x00ff0000;"	/* R1 =      A^C, 0  , C^A, D^B */
+	     " mov %0, %1, ror #8;"	/* wordOut = D,   A,   B,   C   */
+	     " eor %0, %0, r1, lsr #8;"	/* wordOut = D,   C,   B,   A   */
+  : "=r" (wordOut): "r" (wordIn):"r1");
+
+    return wordOut;
+}
+
+#define IX_OSAL_SWAP_LONG(wData)          (ixOsalCoreWordSwap(wData))
+#else
+#define IX_OSAL_SWAP_LONG(wData)          ((wData >> 24) | (((wData >> 16) & 0xFF) << 8) | (((wData >> 8) & 0xFF) << 16) | ((wData & 0xFF) << 24))
+#endif
+
+#else /* ndef __wince */
+#define IX_OSAL_SWAP_LONG(wData)        ((((UINT32)wData << 24) | ((UINT32)wData >> 24)) | (((wData << 8) & 0xff0000) | ((wData >> 8) & 0xff00)))
+#endif /* ndef __wince */
+
+#define IX_OSAL_SWAP_SHORT(sData)         ((sData >> 8) | ((sData & 0xFF) << 8))
+#define IX_OSAL_SWAP_SHORT_ADDRESS(sAddr) ((sAddr) ^ 0x2)
+#define IX_OSAL_SWAP_BYTE_ADDRESS(bAddr)  ((bAddr) ^ 0x3)
+
+#define IX_OSAL_BE_XSTOBUSL(wData)  (wData)
+#define IX_OSAL_BE_XSTOBUSS(sData)  (sData)
+#define IX_OSAL_BE_XSTOBUSB(bData)  (bData)
+#define IX_OSAL_BE_BUSTOXSL(wData)  (wData)
+#define IX_OSAL_BE_BUSTOXSS(sData)  (sData)
+#define IX_OSAL_BE_BUSTOXSB(bData)  (bData)
+
+#define IX_OSAL_LE_AC_XSTOBUSL(wAddr) (wAddr)
+#define IX_OSAL_LE_AC_XSTOBUSS(sAddr) IX_OSAL_SWAP_SHORT_ADDRESS(sAddr)
+#define IX_OSAL_LE_AC_XSTOBUSB(bAddr) IX_OSAL_SWAP_BYTE_ADDRESS(bAddr)
+#define IX_OSAL_LE_AC_BUSTOXSL(wAddr) (wAddr)
+#define IX_OSAL_LE_AC_BUSTOXSS(sAddr) IX_OSAL_SWAP_SHORT_ADDRESS(sAddr)
+#define IX_OSAL_LE_AC_BUSTOXSB(bAddr) IX_OSAL_SWAP_BYTE_ADDRESS(bAddr)
+
+#define IX_OSAL_LE_DC_XSTOBUSL(wData) IX_OSAL_SWAP_LONG(wData)
+#define IX_OSAL_LE_DC_XSTOBUSS(sData) IX_OSAL_SWAP_SHORT(sData)
+#define IX_OSAL_LE_DC_XSTOBUSB(bData) (bData)
+#define IX_OSAL_LE_DC_BUSTOXSL(wData) IX_OSAL_SWAP_LONG(wData)
+#define IX_OSAL_LE_DC_BUSTOXSS(sData) IX_OSAL_SWAP_SHORT(sData)
+#define IX_OSAL_LE_DC_BUSTOXSB(bData) (bData)
+
+
+/*
+ * Decide SDRAM mapping, then implement read/write
+ */
+#include "IxOsalMemAccess.h"
+
+
+/**
+ * @ingroup IxOsalIoMem
+ * @enum IxOsalMapEntryType
+ * @brief This is an emum for OSAL I/O mem map type. 
+ */
+typedef enum
+{
+    IX_OSAL_STATIC_MAP = 0,	 /**<Set map entry type to static map */
+    IX_OSAL_DYNAMIC_MAP	     /**<Set map entry type to dynamic map */
+} IxOsalMapEntryType;
+
+
+/**
+ * @ingroup IxOsalIoMem
+ * @enum IxOsalMapEndianessType
+ * @brief This is an emum for OSAL I/O mem Endianess and Coherency mode.
+ */
+typedef enum
+{
+    IX_OSAL_BE = 0x1,      /**<Set map endian mode to Big Endian */
+    IX_OSAL_LE_AC = 0x2,   /**<Set map endian mode to Little Endian, Address Coherent */
+    IX_OSAL_LE_DC = 0x4,   /**<Set map endian mode to Little Endian, Data Coherent */
+    IX_OSAL_LE = 0x8       /**<Set map endian mode to Little Endian without specifying coherency mode */
+} IxOsalMapEndianessType;
+
+
+/**
+ * @struct IxOsalMemoryMap 
+ * @brief IxOsalMemoryMap structure
+ */
+typedef struct _IxOsalMemoryMap
+{
+    IxOsalMapEntryType type;   /**< map type - IX_OSAL_STATIC_MAP or IX_OSAL_DYNAMIC_MAP */
+
+    UINT32 physicalAddress;    /**< physical address of the memory mapped I/O zone */
+
+    UINT32 size;               /**< size of the map */
+
+    UINT32 virtualAddress;     /**< virtual address of the zone; must be predefined
+                                    in the global memory map for static maps and has
+                                    to be NULL for dynamic maps (populated on allocation)
+								*/
+    /*
+     * pointer to a map function called to map a dynamic map; 
+     * will populate the virtualAddress field 
+     */
+    void (*mapFunction) (struct _IxOsalMemoryMap * map);   /**< pointer to a map function called to map a dynamic map */
+
+    /*
+     * pointer to a map function called to unmap a dynamic map; 
+     * will reset the virtualAddress field to NULL 
+     */
+    void (*unmapFunction) (struct _IxOsalMemoryMap * map); /**< pointer to a map function called to unmap a dynamic map */
+
+    /*
+     * reference count describing how many components share this map; 
+     * actual allocation/deallocation for dynamic maps is done only 
+     * between 0 <=> 1 transitions of the counter 
+     */
+    UINT32 refCount;   /**< reference count describing how many components share this map */
+
+    /*
+     * memory endian type for the map; can be a combination of IX_OSAL_BE (Big 
+     * Endian) and IX_OSAL_LE or IX_OSAL_LE_AC or IX_OSAL_LE_DC
+     * (Little Endian, Address Coherent or Data Coherent). Any combination is
+     * allowed provided it contains at most one LE flag - e.g.
+     * (IX_OSAL_BE), (IX_OSAL_LE_AC), (IX_OSAL_BE | IX_OSAL_LE_DC) are valid
+     * combinations while (IX_OSAL_BE | IX_OSAL_LE_DC | IX_OSAL_LE_AC) is not. 
+     */
+    IxOsalMapEndianessType mapEndianType; /**< memory endian type for the map */
+
+    char *name;      /**< user-friendly name */
+} IxOsalMemoryMap;
+
+
+
+
+/* Internal function to map a memory zone
+ * NOTE - This should not be called by the user.
+ * Use the macro IX_OSAL_MEM_MAP instead
+ */
+PUBLIC void *ixOsalIoMemMap (UINT32 requestedAddress,
+			     UINT32 size,
+			     IxOsalMapEndianessType requestedCoherency);
+
+
+/* Internal function to unmap a memory zone mapped with ixOsalIoMemMap
+ * NOTE - This should not be called by the user.
+ * Use the macro IX_OSAL_MEM_UNMAP instead
+ */
+PUBLIC void ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 coherency);
+
+
+/* Internal function to convert virtual address to physical address 
+ * NOTE - This should not be called by the user.
+ * Use the macro IX_OSAL_MMAP_VIRT_TO_PHYS */
+PUBLIC UINT32 ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 coherency);
+
+
+/* Internal function to convert physical address to virtual address 
+ * NOTE - This should not be called by the user.
+ * Use the macro IX_OSAL_MMAP_PHYS_TO_VIRT */
+PUBLIC UINT32
+ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 coherency);
+
+/**
+ * @ingroup IxOsalIoMem
+ *
+ * @def IX_OSAL_MEM_MAP(physAddr, size)
+ *
+ * @brief Map an I/O mapped physical memory zone to virtual zone and return virtual
+ *        pointer.
+ * @param  physAddr - the physical address
+ * @param  size     - the size
+ * @return start address of the virtual memory zone.
+ *
+ * @note  This function maps an I/O mapped physical memory zone of the given size
+ * into a virtual memory zone accessible by the caller and returns a cookie - 
+ * the start address of the virtual memory zone. 
+ * IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned 
+ * virtual address.
+ * The memory zone is to be unmapped using IX_OSAL_MEM_UNMAP once the caller has
+ * finished using this zone (e.g. on driver unload) using the cookie as 
+ * parameter.
+ * The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write 
+ * the mapped memory, adding the necessary offsets to the address cookie.
+ */
+#define IX_OSAL_MEM_MAP(physAddr, size) \
+    ixOsalIoMemMap((physAddr), (size), IX_OSAL_COMPONENT_MAPPING)
+
+
+/**
+ * @ingroup IxOsalIoMem
+ *
+ * @def IX_OSAL_MEM_UNMAP(virtAddr)
+ *
+ * @brief Unmap a previously mapped I/O memory zone using virtual pointer obtained
+ *        during the mapping operation.
+ *        pointer.
+ * @param  virtAddr - the virtual pointer to the zone to be unmapped.
+ * @return none
+ *
+ * @note  This function unmaps a previously mapped I/O memory zone using
+ * the cookie obtained in the mapping operation. The memory zone in question
+ * becomes unavailable to the caller once unmapped and the cookie should be
+ * discarded.
+ *
+ * This function cannot fail if the given parameter is correct and does not
+ * return a value.
+ */
+#define IX_OSAL_MEM_UNMAP(virtAddr) \
+    ixOsalIoMemUnmap ((virtAddr), IX_OSAL_COMPONENT_MAPPING)
+
+/**
+ * @ingroup IxOsalIoMem
+ *
+ * @def IX_OSAL_MMAP_VIRT_TO_PHYS(virtAddr)
+ *
+ * @brief This function Converts a virtual address into a physical 
+ * address, including the dynamically mapped memory.
+ *
+ * @param  virtAddr - virtual address to convert
+ * Return value: corresponding physical address, or NULL
+ */
+#define IX_OSAL_MMAP_VIRT_TO_PHYS(virtAddr) \
+    ixOsalIoMemVirtToPhys(virtAddr, IX_OSAL_COMPONENT_MAPPING)
+
+
+/**
+ * @ingroup IxOsalIoMem
+ *
+ * @def IX_OSAL_MMAP_PHYS_TO_VIRT(physAddr)
+ *
+ * @brief  This function Converts a virtual address into a physical 
+ * address, including the dynamically mapped memory.
+ *
+ * @param  physAddr - physical address to convert
+ * Return value: corresponding virtual address, or NULL
+ *
+ */
+#define IX_OSAL_MMAP_PHYS_TO_VIRT(physAddr) \
+    ixOsalIoMemPhysToVirt(physAddr, IX_OSAL_COMPONENT_MAPPING)
+
+/**
+ * @} IxOsalIoMem
+ */
+
+#endif /* IxOsalIoMem_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalMemAccess.h b/marvell/uboot/drivers/net/npe/include/IxOsalMemAccess.h
new file mode 100644
index 0000000..be7472a
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalMemAccess.h
@@ -0,0 +1,470 @@
+/** 
+ * @file IxOsalMemAccess.h
+ * 
+ * @brief Header file for memory access
+ * 
+ * @par
+ * @version $Revision: 1.0 $
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsalMemAccess_H
+#define IxOsalMemAccess_H
+
+
+/* Global BE switch
+ * 
+ *  Should be set only in BE mode and only if the component uses I/O memory.
+ */
+
+#if defined (__BIG_ENDIAN)
+
+#define IX_OSAL_BE_MAPPING
+
+#endif /* Global switch */
+
+
+/* By default only static memory maps in use;
+   define IX_OSAL_DYNAMIC_MEMORY_MAP per component if dynamic maps are
+   used instead in that component */
+#define IX_OSAL_STATIC_MEMORY_MAP
+
+
+/* 
+ * SDRAM coherency mode
+ * Must be defined to BE, LE_DATA_COHERENT or LE_ADDRESS_COHERENT.
+ * The mode changes depending on OS 
+ */
+#if defined (IX_OSAL_LINUX_BE) || defined (IX_OSAL_VXWORKS_BE)
+
+#define IX_SDRAM_BE
+
+#elif defined (IX_OSAL_VXWORKS_LE)
+
+#define IX_SDRAM_LE_DATA_COHERENT
+
+#elif defined (IX_OSAL_LINUX_LE)
+
+#define IX_SDRAM_LE_DATA_COHERENT
+
+#elif defined (IX_OSAL_WINCE_LE)
+
+#define IX_SDRAM_LE_DATA_COHERENT
+
+#elif defined (IX_OSAL_EBOOT_LE)
+
+#define IX_SDRAM_LE_ADDRESS_COHERENT
+
+#endif
+
+
+
+
+/**************************************
+ * Retrieve current component mapping *
+ **************************************/
+
+/*
+ * Only use customized mapping for LE. 
+ * 
+ */
+#if defined (IX_OSAL_VXWORKS_LE) || defined (IX_OSAL_LINUX_LE) || defined (IX_OSAL_WINCE_LE) || defined (IX_OSAL_EBOOT_LE)
+
+#include "IxOsalOsIxp400CustomizedMapping.h"
+
+#endif
+
+
+/*******************************************************************
+ * Turn off IX_STATIC_MEMORY map for components using dynamic maps *
+ *******************************************************************/
+#ifdef IX_OSAL_DYNAMIC_MEMORY_MAP
+
+#undef IX_OSAL_STATIC_MEMORY_MAP
+
+#endif
+
+
+/************************************************************
+ * Turn off BE access for components using LE or no mapping *
+ ************************************************************/
+
+#if ( defined (IX_OSAL_LE_AC_MAPPING) || defined (IX_OSAL_LE_DC_MAPPING) || defined (IX_OSAL_NO_MAPPING) )
+
+#undef IX_OSAL_BE_MAPPING
+
+#endif
+
+
+/*****************
+ * Safety checks *
+ *****************/
+
+/* Default to no_mapping */
+#if !defined (IX_OSAL_BE_MAPPING) && !defined (IX_OSAL_LE_AC_MAPPING) && !defined (IX_OSAL_LE_DC_MAPPING) && !defined (IX_OSAL_NO_MAPPING)
+
+#define IX_OSAL_NO_MAPPING
+
+#endif /* check at least one mapping */
+
+/* No more than one mapping can be defined for a component */
+#if   (defined (IX_OSAL_BE_MAPPING)    && defined (IX_OSAL_LE_AC_MAPPING))  \
+    ||(defined (IX_OSAL_BE_MAPPING)    && defined (IX_OSAL_LE_DC_MAPPING))  \
+    ||(defined (IX_OSAL_BE_MAPPING)    && defined (IX_OSAL_NO_MAPPING))     \
+    ||(defined (IX_OSAL_LE_DC_MAPPING) && defined (IX_OSAL_NO_MAPPING))     \
+    ||(defined (IX_OSAL_LE_DC_MAPPING) && defined (IX_OSAL_LE_AC_MAPPING))	\
+    ||(defined (IX_OSAL_LE_AC_MAPPING) && defined (IX_OSAL_NO_MAPPING))
+
+
+#ifdef IX_OSAL_BE_MAPPING
+#warning IX_OSAL_BE_MAPPING is defined
+#endif
+
+#ifdef IX_OSAL_LE_AC_MAPPING
+#warning IX_OSAL_LE_AC_MAPPING is defined
+#endif
+
+#ifdef IX_OSAL_LE_DC_MAPPING
+#warning IX_OSAL_LE_DC_MAPPING is defined
+#endif
+
+#ifdef IX_OSAL_NO_MAPPING
+#warning IX_OSAL_NO_MAPPING is defined
+#endif
+
+#error More than one I/O mapping is defined, please check your component mapping
+
+#endif /* check at most one mapping */
+
+
+/* Now set IX_OSAL_COMPONENT_MAPPING */
+
+#ifdef IX_OSAL_BE_MAPPING
+#define IX_OSAL_COMPONENT_MAPPING IX_OSAL_BE
+#endif
+
+#ifdef IX_OSAL_LE_AC_MAPPING
+#define IX_OSAL_COMPONENT_MAPPING IX_OSAL_LE_AC
+#endif
+
+#ifdef IX_OSAL_LE_DC_MAPPING
+#define IX_OSAL_COMPONENT_MAPPING IX_OSAL_LE_DC
+#endif
+
+#ifdef IX_OSAL_NO_MAPPING
+#define IX_OSAL_COMPONENT_MAPPING IX_OSAL_LE
+#endif
+
+
+/* SDRAM coherency should be defined */
+#if !defined (IX_SDRAM_BE) && !defined (IX_SDRAM_LE_DATA_COHERENT) && !defined (IX_SDRAM_LE_ADDRESS_COHERENT)
+
+#error SDRAM coherency must be defined
+
+#endif /* SDRAM coherency must be defined */
+
+/* SDRAM coherency cannot be defined in several ways */
+#if (defined (IX_SDRAM_BE) && (defined (IX_SDRAM_LE_DATA_COHERENT) || defined (IX_SDRAM_LE_ADDRESS_COHERENT))) \
+    || (defined (IX_SDRAM_LE_DATA_COHERENT) && (defined (IX_SDRAM_BE) || defined (IX_SDRAM_LE_ADDRESS_COHERENT))) \
+    || (defined (IX_SDRAM_LE_ADDRESS_COHERENT) && (defined (IX_SDRAM_BE) || defined (IX_SDRAM_LE_DATA_COHERENT)))
+
+#error SDRAM coherency cannot be defined in more than one way
+
+#endif /* SDRAM coherency must be defined exactly once */
+
+
+/*********************
+ * Read/write macros *
+ *********************/
+
+/* WARNING - except for addition of special cookie read/write macros (see below)
+             these macros are NOT user serviceable. Please do not modify */
+
+#define IX_OSAL_READ_LONG_RAW(wAddr)          (*(wAddr))
+#define IX_OSAL_READ_SHORT_RAW(sAddr)         (*(sAddr))
+#define IX_OSAL_READ_BYTE_RAW(bAddr)          (*(bAddr))
+#define IX_OSAL_WRITE_LONG_RAW(wAddr, wData)  (*(wAddr) = (wData))
+#define IX_OSAL_WRITE_SHORT_RAW(sAddr,sData)  (*(sAddr) = (sData))
+#define IX_OSAL_WRITE_BYTE_RAW(bAddr, bData)  (*(bAddr) = (bData))
+
+#ifdef __linux
+
+/* Linux - specific cookie reads/writes. 
+  Redefine per OS if dynamic memory maps are used
+  and I/O memory is accessed via functions instead of raw pointer access. */
+
+#define IX_OSAL_READ_LONG_COOKIE(wCookie)           (readl((UINT32) (wCookie) ))
+#define IX_OSAL_READ_SHORT_COOKIE(sCookie)          (readw((UINT32) (sCookie) ))
+#define IX_OSAL_READ_BYTE_COOKIE(bCookie)           (readb((UINT32) (bCookie) ))
+#define IX_OSAL_WRITE_LONG_COOKIE(wCookie, wData)   (writel(wData, (UINT32) (wCookie) ))
+#define IX_OSAL_WRITE_SHORT_COOKIE(sCookie, sData)  (writew(sData, (UINT32) (sCookie) ))
+#define IX_OSAL_WRITE_BYTE_COOKIE(bCookie, bData)   (writeb(bData, (UINT32) (bCookie) ))
+
+#endif /* linux */
+
+#ifdef __wince
+
+/* WinCE - specific cookie reads/writes. */
+
+static __inline__ UINT32
+ixOsalWinCEReadLCookie (volatile UINT32 * lCookie)
+{
+    return *lCookie;
+}
+
+static __inline__ UINT16
+ixOsalWinCEReadWCookie (volatile UINT16 * wCookie)
+{
+#if 0
+    UINT32 auxVal = *((volatile UINT32 *) wCookie);
+    if ((unsigned) wCookie & 3)
+	return (UINT16) (auxVal >> 16);
+    else
+	return (UINT16) (auxVal & 0xffff);
+#else
+    return *wCookie;
+#endif
+}
+
+static __inline__ UINT8
+ixOsalWinCEReadBCookie (volatile UINT8 * bCookie)
+{
+#if 0
+    UINT32 auxVal = *((volatile UINT32 *) bCookie);
+    return (UINT8) ((auxVal >> (3 - (((unsigned) bCookie & 3) << 3)) & 0xff));
+#else
+    return *bCookie;
+#endif
+}
+
+static __inline__ void
+ixOsalWinCEWriteLCookie (volatile UINT32 * lCookie, UINT32 lVal)
+{
+    *lCookie = lVal;
+}
+
+static __inline__ void
+ixOsalWinCEWriteWCookie (volatile UINT16 * wCookie, UINT16 wVal)
+{
+#if 0
+    volatile UINT32 *auxCookie =
+	(volatile UINT32 *) ((unsigned) wCookie & ~3);
+    if ((unsigned) wCookie & 3)
+    {
+	*auxCookie &= 0xffff;
+	*auxCookie |= (UINT32) wVal << 16;
+    }
+    else
+    {
+	*auxCookie &= ~0xffff;
+	*auxCookie |= (UINT32) wVal & 0xffff;
+    }
+#else
+    *wCookie = wVal;
+#endif
+}
+
+static __inline__ void
+ixOsalWinCEWriteBCookie (volatile UINT8 * bCookie, UINT8 bVal)
+{
+#if 0
+    volatile UINT32 *auxCookie =
+	(volatile UINT32 *) ((unsigned) bCookie & ~3);
+    *auxCookie &= 0xff << (3 - (((unsigned) bCookie & 3) << 3));
+    *auxCookie |= (UINT32) bVal << (3 - (((unsigned) bCookie & 3) << 3));
+#else
+    *bCookie = bVal;
+#endif
+}
+
+
+#define IX_OSAL_READ_LONG_COOKIE(wCookie)           (ixOsalWinCEReadLCookie(wCookie))
+#define IX_OSAL_READ_SHORT_COOKIE(sCookie)          (ixOsalWinCEReadWCookie(sCookie))
+#define IX_OSAL_READ_BYTE_COOKIE(bCookie)           (ixOsalWinCEReadBCookie(bCookie))
+#define IX_OSAL_WRITE_LONG_COOKIE(wCookie, wData)   (ixOsalWinCEWriteLCookie(wCookie, wData))
+#define IX_OSAL_WRITE_SHORT_COOKIE(sCookie, sData)  (ixOsalWinCEWriteWCookie(sCookie, sData))
+#define IX_OSAL_WRITE_BYTE_COOKIE(bCookie, bData)   (ixOsalWinCEWriteBCookie(bCookie, bData))
+
+#endif /* wince */
+
+#if defined (__vxworks) || (defined (__linux) && defined (IX_OSAL_STATIC_MEMORY_MAP)) || \
+                           (defined (__wince) && defined (IX_OSAL_STATIC_MEMORY_MAP))
+
+#define IX_OSAL_READ_LONG_IO(wAddr)            IX_OSAL_READ_LONG_RAW(wAddr)
+#define IX_OSAL_READ_SHORT_IO(sAddr)           IX_OSAL_READ_SHORT_RAW(sAddr)
+#define IX_OSAL_READ_BYTE_IO(bAddr)            IX_OSAL_READ_BYTE_RAW(bAddr)
+#define IX_OSAL_WRITE_LONG_IO(wAddr, wData)    IX_OSAL_WRITE_LONG_RAW(wAddr, wData)
+#define IX_OSAL_WRITE_SHORT_IO(sAddr, sData)   IX_OSAL_WRITE_SHORT_RAW(sAddr, sData)
+#define IX_OSAL_WRITE_BYTE_IO(bAddr, bData)    IX_OSAL_WRITE_BYTE_RAW(bAddr, bData)
+
+#elif (defined (__linux) && !defined (IX_OSAL_STATIC_MEMORY_MAP)) || \
+      (defined (__wince) && !defined (IX_OSAL_STATIC_MEMORY_MAP))
+
+#ifndef __wince
+#include <asm/io.h>
+#endif /* ndef __wince */
+
+#define IX_OSAL_READ_LONG_IO(wAddr)            IX_OSAL_READ_LONG_COOKIE(wAddr)
+#define IX_OSAL_READ_SHORT_IO(sAddr)           IX_OSAL_READ_SHORT_COOKIE(sAddr)
+#define IX_OSAL_READ_BYTE_IO(bAddr)            IX_OSAL_READ_BYTE_COOKIE(bAddr)
+#define IX_OSAL_WRITE_LONG_IO(wAddr, wData)    IX_OSAL_WRITE_LONG_COOKIE(wAddr, wData)
+#define IX_OSAL_WRITE_SHORT_IO(sAddr, sData)   IX_OSAL_WRITE_SHORT_COOKIE(sAddr, sData)
+#define IX_OSAL_WRITE_BYTE_IO(bAddr, bData)    IX_OSAL_WRITE_BYTE_COOKIE(bAddr, bData)
+
+#endif
+
+/* Define BE macros */
+#define IX_OSAL_READ_LONG_BE(wAddr)          IX_OSAL_BE_BUSTOXSL(IX_OSAL_READ_LONG_IO((volatile UINT32 *) (wAddr) ))
+#define IX_OSAL_READ_SHORT_BE(sAddr)         IX_OSAL_BE_BUSTOXSS(IX_OSAL_READ_SHORT_IO((volatile UINT16 *) (sAddr) ))
+#define IX_OSAL_READ_BYTE_BE(bAddr)          IX_OSAL_BE_BUSTOXSB(IX_OSAL_READ_BYTE_IO((volatile UINT8 *) (bAddr) ))
+#define IX_OSAL_WRITE_LONG_BE(wAddr, wData)  IX_OSAL_WRITE_LONG_IO((volatile UINT32 *) (wAddr), IX_OSAL_BE_XSTOBUSL((UINT32) (wData) ))
+#define IX_OSAL_WRITE_SHORT_BE(sAddr, sData) IX_OSAL_WRITE_SHORT_IO((volatile UINT16 *) (sAddr), IX_OSAL_BE_XSTOBUSS((UINT16) (sData) ))
+#define IX_OSAL_WRITE_BYTE_BE(bAddr, bData)  IX_OSAL_WRITE_BYTE_IO((volatile UINT8 *) (bAddr), IX_OSAL_BE_XSTOBUSB((UINT8) (bData) ))
+
+/* Define LE AC macros */
+#define IX_OSAL_READ_LONG_LE_AC(wAddr)          IX_OSAL_READ_LONG_IO((volatile UINT32 *) IX_OSAL_LE_AC_BUSTOXSL((UINT32) (wAddr) ))
+#define IX_OSAL_READ_SHORT_LE_AC(sAddr)         IX_OSAL_READ_SHORT_IO((volatile UINT16 *) IX_OSAL_LE_AC_BUSTOXSS((UINT32) (sAddr) ))
+#define IX_OSAL_READ_BYTE_LE_AC(bAddr)          IX_OSAL_READ_BYTE_IO((volatile UINT8 *) IX_OSAL_LE_AC_BUSTOXSB((UINT32) (bAddr) ))
+#define IX_OSAL_WRITE_LONG_LE_AC(wAddr, wData)  IX_OSAL_WRITE_LONG_IO((volatile UINT32 *) IX_OSAL_LE_AC_XSTOBUSL((UINT32) (wAddr) ), (UINT32) (wData))
+#define IX_OSAL_WRITE_SHORT_LE_AC(sAddr, sData) IX_OSAL_WRITE_SHORT_IO((volatile UINT16 *) IX_OSAL_LE_AC_XSTOBUSS((UINT32) (sAddr) ), (UINT16) (sData))
+#define IX_OSAL_WRITE_BYTE_LE_AC(bAddr, bData)  IX_OSAL_WRITE_BYTE_IO((volatile UINT8 *) IX_OSAL_LE_AC_XSTOBUSB((UINT32) (bAddr) ), (UINT8) (bData))
+
+
+/* Inline functions are required here to avoid reading the same I/O location 2 or 4 times for the byte swap */
+static __inline__ UINT32
+ixOsalDataCoherentLongReadSwap (volatile UINT32 * wAddr)
+{
+    UINT32 wData = IX_OSAL_READ_LONG_IO (wAddr);
+    return IX_OSAL_LE_DC_BUSTOXSL (wData);
+}
+
+static __inline__ UINT16
+ixOsalDataCoherentShortReadSwap (volatile UINT16 * sAddr)
+{
+    UINT16 sData = IX_OSAL_READ_SHORT_IO (sAddr);
+    return IX_OSAL_LE_DC_BUSTOXSS (sData);
+}
+
+static __inline__ void
+ixOsalDataCoherentLongWriteSwap (volatile UINT32 * wAddr, UINT32 wData)
+{
+    wData = IX_OSAL_LE_DC_XSTOBUSL (wData);
+    IX_OSAL_WRITE_LONG_IO (wAddr, wData);
+}
+
+static __inline__ void
+ixOsalDataCoherentShortWriteSwap (volatile UINT16 * sAddr, UINT16 sData)
+{
+    sData = IX_OSAL_LE_DC_XSTOBUSS (sData);
+    IX_OSAL_WRITE_SHORT_IO (sAddr, sData);
+}
+
+/* Define LE DC macros */
+
+#define IX_OSAL_READ_LONG_LE_DC(wAddr)          ixOsalDataCoherentLongReadSwap((volatile UINT32 *) (wAddr) )
+#define IX_OSAL_READ_SHORT_LE_DC(sAddr)         ixOsalDataCoherentShortReadSwap((volatile UINT16 *) (sAddr) )
+#define IX_OSAL_READ_BYTE_LE_DC(bAddr)          IX_OSAL_LE_DC_BUSTOXSB(IX_OSAL_READ_BYTE_IO((volatile UINT8 *) (bAddr) ))
+#define IX_OSAL_WRITE_LONG_LE_DC(wAddr, wData)  ixOsalDataCoherentLongWriteSwap((volatile UINT32 *) (wAddr), (UINT32) (wData))
+#define IX_OSAL_WRITE_SHORT_LE_DC(sAddr, sData) ixOsalDataCoherentShortWriteSwap((volatile UINT16 *) (sAddr), (UINT16) (sData))
+#define IX_OSAL_WRITE_BYTE_LE_DC(bAddr, bData)  IX_OSAL_WRITE_BYTE_IO((volatile UINT8 *) (bAddr), IX_OSAL_LE_DC_XSTOBUSB((UINT8) (bData)))
+
+#if defined (IX_OSAL_BE_MAPPING)
+
+#define IX_OSAL_READ_LONG(wAddr)            IX_OSAL_READ_LONG_BE(wAddr) 
+#define IX_OSAL_READ_SHORT(sAddr)	        IX_OSAL_READ_SHORT_BE(sAddr) 
+#define IX_OSAL_READ_BYTE(bAddr)	        IX_OSAL_READ_BYTE_BE(bAddr) 
+#define IX_OSAL_WRITE_LONG(wAddr, wData)	IX_OSAL_WRITE_LONG_BE(wAddr, wData)
+#define IX_OSAL_WRITE_SHORT(sAddr, sData)	IX_OSAL_WRITE_SHORT_BE(sAddr, sData)
+#define IX_OSAL_WRITE_BYTE(bAddr, bData)	IX_OSAL_WRITE_BYTE_BE(bAddr, bData)
+
+#elif defined (IX_OSAL_LE_AC_MAPPING)
+
+#define IX_OSAL_READ_LONG(wAddr)            IX_OSAL_READ_LONG_LE_AC(wAddr) 
+#define IX_OSAL_READ_SHORT(sAddr)	        IX_OSAL_READ_SHORT_LE_AC(sAddr) 
+#define IX_OSAL_READ_BYTE(bAddr)	        IX_OSAL_READ_BYTE_LE_AC(bAddr) 
+#define IX_OSAL_WRITE_LONG(wAddr, wData)	IX_OSAL_WRITE_LONG_LE_AC(wAddr, wData)
+#define IX_OSAL_WRITE_SHORT(sAddr, sData)	IX_OSAL_WRITE_SHORT_LE_AC(sAddr, sData)
+#define IX_OSAL_WRITE_BYTE(bAddr, bData)	IX_OSAL_WRITE_BYTE_LE_AC(bAddr, bData)
+
+#elif defined (IX_OSAL_LE_DC_MAPPING)
+
+#define IX_OSAL_READ_LONG(wAddr)            IX_OSAL_READ_LONG_LE_DC(wAddr) 
+#define IX_OSAL_READ_SHORT(sAddr)	        IX_OSAL_READ_SHORT_LE_DC(sAddr) 
+#define IX_OSAL_READ_BYTE(bAddr)	        IX_OSAL_READ_BYTE_LE_DC(bAddr) 
+#define IX_OSAL_WRITE_LONG(wAddr, wData)	IX_OSAL_WRITE_LONG_LE_DC(wAddr, wData)
+#define IX_OSAL_WRITE_SHORT(sAddr, sData)	IX_OSAL_WRITE_SHORT_LE_DC(sAddr, sData)
+#define IX_OSAL_WRITE_BYTE(bAddr, bData)	IX_OSAL_WRITE_BYTE_LE_DC(bAddr, bData)
+
+#endif   /* End of BE and LE coherency mode switch */
+
+
+/* Reads/writes to and from memory shared with NPEs - depends on the SDRAM coherency */
+
+#if defined (IX_SDRAM_BE)
+
+#define IX_OSAL_READ_BE_SHARED_LONG(wAddr)            IX_OSAL_READ_LONG_RAW(wAddr)
+#define IX_OSAL_READ_BE_SHARED_SHORT(sAddr)           IX_OSAL_READ_SHORT_RAW(sAddr)
+#define IX_OSAL_READ_BE_SHARED_BYTE(bAddr)            IX_OSAL_READ_BYTE_RAW(bAddr)
+
+#define IX_OSAL_WRITE_BE_SHARED_LONG(wAddr, wData)    IX_OSAL_WRITE_LONG_RAW(wAddr, wData)
+#define IX_OSAL_WRITE_BE_SHARED_SHORT(sAddr, sData)   IX_OSAL_WRITE_SHORT_RAW(sAddr, sData)
+#define IX_OSAL_WRITE_BE_SHARED_BYTE(bAddr, bData)    IX_OSAL_WRITE_BYTE_RAW(bAddr, bData)
+
+#define IX_OSAL_SWAP_BE_SHARED_LONG(wData)            (wData)
+#define IX_OSAL_SWAP_BE_SHARED_SHORT(sData)           (sData)
+#define IX_OSAL_SWAP_BE_SHARED_BYTE(bData)            (bData)
+
+#elif defined (IX_SDRAM_LE_ADDRESS_COHERENT)
+
+#define IX_OSAL_READ_BE_SHARED_LONG(wAddr)            IX_OSAL_READ_LONG_RAW(wAddr)
+#define IX_OSAL_READ_BE_SHARED_SHORT(sAddr)           IX_OSAL_READ_SHORT_RAW(IX_OSAL_SWAP_SHORT_ADDRESS(sAddr))
+#define IX_OSAL_READ_BE_SHARED_BYTE(bAddr)            IX_OSAL_READ_BYTE_RAW(IX_OSAL_SWAP_BYTE_ADDRESS(bAddr))
+
+#define IX_OSAL_WRITE_BE_SHARED_LONG(wAddr, wData)    IX_OSAL_WRITE_LONG_RAW(wAddr, wData)
+#define IX_OSAL_WRITE_BE_SHARED_SHORT(sAddr, sData)   IX_OSAL_WRITE_SHORT_RAW(IX_OSAL_SWAP_SHORT_ADDRESS(sAddr), sData)
+#define IX_OSAL_WRITE_BE_SHARED_BYTE(bAddr, bData)    IX_OSAL_WRITE_BYTE_RAW(IX_OSAL_SWAP_BYTE_ADDRESS(bAddr), bData)
+
+#define IX_OSAL_SWAP_BE_SHARED_LONG(wData)            (wData)
+#define IX_OSAL_SWAP_BE_SHARED_SHORT(sData)           (sData)
+#define IX_OSAL_SWAP_BE_SHARED_BYTE(bData)            (bData)
+
+#elif defined (IX_SDRAM_LE_DATA_COHERENT)
+
+#define IX_OSAL_READ_BE_SHARED_LONG(wAddr)            IX_OSAL_SWAP_LONG(IX_OSAL_READ_LONG_RAW(wAddr))
+#define IX_OSAL_READ_BE_SHARED_SHORT(sAddr)           IX_OSAL_SWAP_SHORT(IX_OSAL_READ_SHORT_RAW(sAddr))
+#define IX_OSAL_READ_BE_SHARED_BYTE(bAddr)            IX_OSAL_READ_BYTE_RAW(bAddr)
+
+#define IX_OSAL_WRITE_BE_SHARED_LONG(wAddr, wData)    IX_OSAL_WRITE_LONG_RAW(wAddr, IX_OSAL_SWAP_LONG(wData))
+#define IX_OSAL_WRITE_BE_SHARED_SHORT(sAddr, sData)   IX_OSAL_WRITE_SHORT_RAW(sAddr, IX_OSAL_SWAP_SHORT(sData))
+#define IX_OSAL_WRITE_BE_SHARED_BYTE(bAddr, bData)    IX_OSAL_WRITE_BYTE_RAW(bAddr, bData)
+
+#define IX_OSAL_SWAP_BE_SHARED_LONG(wData)            IX_OSAL_SWAP_LONG(wData)
+#define IX_OSAL_SWAP_BE_SHARED_SHORT(sData)           IX_OSAL_SWAP_SHORT(sData)
+
+#endif
+
+
+#define IX_OSAL_COPY_BE_SHARED_LONG_ARRAY(wDestAddr, wSrcAddr, wCount) \
+  { \
+    UINT32 i; \
+    \
+    for ( i = 0 ; i < wCount ; i++ ) \
+    { \
+      * (((UINT32 *) wDestAddr) + i) = IX_OSAL_READ_BE_SHARED_LONG(((UINT32 *) wSrcAddr) + i); \
+    }; \
+  };
+
+#endif /* IxOsalMemAccess_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalOem.h b/marvell/uboot/drivers/net/npe/include/IxOsalOem.h
new file mode 100644
index 0000000..a1f4d21
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalOem.h
@@ -0,0 +1,73 @@
+/**
+ * @file IxOsalIxpOem.h
+ *
+ * @brief this file contains platform-specific defines.
+ * 
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsalOem_H
+#define IxOsalOem_H
+
+#include "IxOsalTypes.h"
+
+/* OS-specific header for Platform package */
+#include "IxOsalOsIxp400.h"
+
+/*
+ * Platform Name
+ */
+#define IX_OSAL_PLATFORM_NAME ixp400
+
+/*
+ * Cache line size
+ */
+#define IX_OSAL_CACHE_LINE_SIZE (32)
+
+
+/* Platform-specific fastmutex implementation */
+PUBLIC IX_STATUS ixOsalOemFastMutexTryLock (IxOsalFastMutex * mutex);
+
+/* Platform-specific init (MemMap) */
+PUBLIC IX_STATUS
+ixOsalOemInit (void);
+
+/* Platform-specific unload (MemMap) */
+PUBLIC void
+ixOsalOemUnload (void);
+
+/* Default implementations */
+
+PUBLIC UINT32
+ixOsalIxp400SharedTimestampGet (void);
+
+
+UINT32
+ixOsalIxp400SharedTimestampRateGet (void);
+
+UINT32
+ixOsalIxp400SharedSysClockRateGet (void);
+
+void
+ixOsalIxp400SharedTimeGet (IxOsalTimeval * tv);
+
+
+INT32
+ixOsalIxp400SharedLog (UINT32 level, UINT32 device, char *format, 
+                       int arg1, int arg2, int arg3, int arg4, 
+                       int arg5, int arg6);
+
+#endif /* IxOsal_Oem_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalOs.h b/marvell/uboot/drivers/net/npe/include/IxOsalOs.h
new file mode 100644
index 0000000..6c66613
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalOs.h
@@ -0,0 +1,30 @@
+#ifndef IxOsalOs_H
+#define IxOsalOs_H
+
+#ifndef IX_OSAL_CACHED
+#error "Uncached memory not supported in linux environment"
+#endif
+
+static inline unsigned long __v2p(unsigned long v)
+{
+	if (v < 0x40000000)
+		return (v & 0xfffffff);
+	else
+		return v;
+}
+
+#define IX_OSAL_OS_MMU_VIRT_TO_PHYS(addr)        __v2p((u32)addr)
+#define IX_OSAL_OS_MMU_PHYS_TO_VIRT(addr)        (addr)
+
+/*
+ * Data cache not enabled (hopefully)
+ */
+#define IX_OSAL_OS_CACHE_INVALIDATE(addr, size)
+#define IX_OSAL_OS_CACHE_FLUSH(addr, size)
+#define HAL_DCACHE_INVALIDATE(addr, size)
+#define HAL_DCACHE_FLUSH(addr, size)
+
+#define __ixp42X			/* sr: U-Boot needs this define */
+
+#endif /* IxOsalOs_H */
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalOsAssert.h b/marvell/uboot/drivers/net/npe/include/IxOsalOsAssert.h
new file mode 100644
index 0000000..e4c3e1f
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalOsAssert.h
@@ -0,0 +1,10 @@
+#ifndef IxOsalOsAssert_H
+#define IxOsalOsAssert_H
+
+#define IX_OSAL_OS_ASSERT(c)    if(!(c)) \
+                                { \
+                                    ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "Assertion failure \n", 0, 0, 0, 0, 0, 0);\
+                                    while(1); \
+                                }
+
+#endif /* IxOsalOsAssert_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalOsBufferMgt.h b/marvell/uboot/drivers/net/npe/include/IxOsalOsBufferMgt.h
new file mode 100644
index 0000000..53b9616
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalOsBufferMgt.h
@@ -0,0 +1,72 @@
+/**
+ * @file IxOsalOsBufferMgt.h
+ *
+ * @brief vxworks-specific buffer management module definitions.
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#ifndef IX_OSAL_OS_BUFFER_MGT_H
+#define IX_OSAL_OS_BUFFER_MGT_H
+
+/*
+ * use the defaul bufferMgt provided by OSAL framework.
+ */
+#define IX_OSAL_USE_DEFAULT_BUFFER_MGT
+
+#include "IxOsalBufferMgtDefault.h"
+
+#if 0  /* FIXME */
+/* Define os-specific buffer macros for subfields */
+#define IX_OSAL_OSBUF_MDATA(osBufPtr) IX_OSAL_MBUF_MDATA(osBufPtr)
+             ( ((M_BLK *) osBufPtr)->m_data )
+
+#define IX_OSAL_OSBUF_MLEN(osBufPtr) \
+             ( ((M_BLK *) osBufPtr)->m_len )
+
+#define IX_OSAL_OSBUF_PKT_LEN(osBufPtr) \
+             ( ((M_BLK *) osBufPtr)->m_pkthdr.len )
+
+#define IX_OSAL_OS_CONVERT_OSBUF_TO_IXPBUF( osBufPtr, ixpBufPtr) \
+        { \
+            IX_OSAL_MBUF_OSBUF_PTR( (IX_OSAL_MBUF *) ixpBufPtr) = (void *) osBufPtr; \
+            IX_OSAL_MBUF_MDATA((IX_OSAL_MBUF *) ixpBufPtr) =  IX_OSAL_OSBUF_MDATA(osBufPtr); \
+            IX_OSAL_MBUF_PKT_LEN((IX_OSAL_MBUF *) ixpBufPtr) = IX_OSAL_OSBUF_PKT_LEN(osBufPtr); \
+            IX_OSAL_MBUF_MLEN((IX_OSAL_MBUF *) ixpBufPtr) = IX_OSAL_OSBUF_MLEN(osBufPtr); \
+        }
+
+#define IX_OSAL_OS_CONVERT_IXPBUF_TO_OSBUF( ixpBufPtr, osBufPtr) \
+        { \
+            if (ixpBufPtr == NULL) \
+            { /* Do nothing */ } \
+            else \
+            { \
+                (M_BLK *) osBufPtr = (M_BLK *) IX_OSAL_MBUF_OSBUF_PTR((IX_OSAL_MBUF *) ixpBufPtr); \
+                if (osBufPtr == NULL) \
+                { /* Do nothing */ } \
+                else \
+                { \
+                    IX_OSAL_OSBUF_MLEN(osBufPtr) =IX_OSAL_MBUF_MLEN((IX_OSAL_MBUF *) ixpBufPtr); \
+                    IX_OSAL_OSBUF_PKT_LEN(osBufPtr) =IX_OSAL_MBUF_PKT_LEN((IX_OSAL_MBUF *) ixpBufPtr); \
+                } \
+            } \
+        }
+
+#endif /* FIXME */
+
+#endif /* #define IX_OSAL_OS_BUFFER_MGT_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalOsIxp400.h b/marvell/uboot/drivers/net/npe/include/IxOsalOsIxp400.h
new file mode 100644
index 0000000..104c733
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalOsIxp400.h
@@ -0,0 +1,292 @@
+/**
+ * @file IxOsalOsIxp400.h
+ *
+ * @brief OS and platform specific definitions
+ *
+ * Design Notes:
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsalOsIxp400_H
+#define IxOsalOsIxp400_H
+
+#define BIT(x) (1<<(x))
+
+#define IXP425_EthA_BASE	0xc8009000
+#define IXP425_EthB_BASE	0xc800a000
+
+#define IXP425_PSMA_BASE	0xc8006000
+#define IXP425_PSMB_BASE	0xc8007000
+#define IXP425_PSMC_BASE	0xc8008000
+
+#define IXP425_PERIPHERAL_BASE	0xc8000000
+
+#define IXP425_QMGR_BASE	0x60000000
+#define IXP425_OSTS		0xC8005000
+
+#define IXP425_INT_LVL_NPEA	0
+#define IXP425_INT_LVL_NPEB	1
+#define IXP425_INT_LVL_NPEC	2
+
+#define IXP425_INT_LVL_QM1	3
+#define IXP425_INT_LVL_QM2	4
+
+#define IXP425_EXPANSION_BUS_BASE1	0x50000000
+#define IXP425_EXPANSION_BUS_BASE2	0x50000000
+#define IXP425_EXPANSION_BUS_CS1_BASE	0x51000000
+
+#define IXP425_EXP_CONFIG_BASE		0xC4000000
+
+/* physical addresses to be used when requesting memory with IX_OSAL_MEM_MAP */
+#define IX_OSAL_IXP400_INTC_PHYS_BASE          IXP425_INTC_BASE
+#define IX_OSAL_IXP400_GPIO_PHYS_BASE          IXP425_GPIO_BASE
+#define IX_OSAL_IXP400_UART1_PHYS_BASE         IXP425_UART1_BASE
+#define IX_OSAL_IXP400_UART2_PHYS_BASE         IXP425_UART2_BASE
+#define IX_OSAL_IXP400_ETHA_PHYS_BASE          IXP425_EthA_BASE
+#define IX_OSAL_IXP400_ETHB_PHYS_BASE          IXP425_EthB_BASE
+#define IX_OSAL_IXP400_NPEA_PHYS_BASE          IXP425_NPEA_BASE
+#define IX_OSAL_IXP400_NPEB_PHYS_BASE          IXP425_NPEB_BASE
+#define IX_OSAL_IXP400_NPEC_PHYS_BASE          IXP425_NPEC_BASE
+#define IX_OSAL_IXP400_PERIPHERAL_PHYS_BASE    IXP425_PERIPHERAL_BASE
+#define IX_OSAL_IXP400_QMGR_PHYS_BASE          IXP425_QMGR_BASE
+#define IX_OSAL_IXP400_OSTS_PHYS_BASE          IXP425_TIMER_BASE
+#define IX_OSAL_IXP400_USB_PHYS_BASE           IXP425_USB_BASE
+#define IX_OSAL_IXP400_EXP_CFG_PHYS_BASE       IXP425_EXP_CFG_BASE
+#define IX_OSAL_IXP400_EXP_BUS_PHYS_BASE       IXP425_EXP_BUS_BASE2
+#define IX_OSAL_IXP400_EXP_BUS_BOOT_PHYS_BASE  IXP425_EXP_BUS_BASE1
+#define IX_OSAL_IXP400_EXP_BUS_CS0_PHYS_BASE   IXP425_EXP_BUS_CS0_BASE
+#define IX_OSAL_IXP400_EXP_BUS_CS1_PHYS_BASE   IXP425_EXP_BUS_CS1_BASE
+#define IX_OSAL_IXP400_EXP_BUS_CS4_PHYS_BASE   IXP425_EXP_BUS_CS4_BASE
+#define IX_OSAL_IXP400_EXP_BUS_REGS_PHYS_BASE  IXP425_EXP_CFG_BASE
+#define IX_OSAL_IXP400_PCI_CFG_PHYS_BASE       IXP425_PCI_CFG_BASE
+
+/* map sizes to be used when requesting memory with IX_OSAL_MEM_MAP */
+#define IX_OSAL_IXP400_QMGR_MAP_SIZE        (0x4000)	 /**< Queue Manager map size */
+#define IX_OSAL_IXP400_PERIPHERAL_MAP_SIZE  (0xC000)	 /**< Peripheral space map size */
+#define IX_OSAL_IXP400_UART1_MAP_SIZE       (0x1000)	 /**< UART1 map size */
+#define IX_OSAL_IXP400_UART2_MAP_SIZE       (0x1000)	 /**< UART2 map size */
+#define IX_OSAL_IXP400_PMU_MAP_SIZE         (0x1000)	 /**< PMU map size */
+#define IX_OSAL_IXP400_OSTS_MAP_SIZE        (0x1000)	 /**< OS Timers map size */
+#define IX_OSAL_IXP400_NPEA_MAP_SIZE        (0x1000)	 /**< NPE A map size */
+#define IX_OSAL_IXP400_NPEB_MAP_SIZE        (0x1000)	 /**< NPE B map size */
+#define IX_OSAL_IXP400_NPEC_MAP_SIZE        (0x1000)	 /**< NPE C map size */
+#define IX_OSAL_IXP400_ETHA_MAP_SIZE        (0x1000)	 /**< Eth A map size */
+#define IX_OSAL_IXP400_ETHB_MAP_SIZE        (0x1000)	 /**< Eth B map size */
+#define IX_OSAL_IXP400_USB_MAP_SIZE         (0x1000)	 /**< USB map size */
+#define IX_OSAL_IXP400_GPIO_MAP_SIZE        (0x1000)	 /**< GPIO map size */
+#define IX_OSAL_IXP400_EXP_REG_MAP_SIZE     (0x1000)	 /**< Exp Bus Config Registers map size */
+#define IX_OSAL_IXP400_EXP_BUS_MAP_SIZE     (0x08000000) /**< Expansion bus map size */
+#define IX_OSAL_IXP400_EXP_BUS_CS0_MAP_SIZE (0x01000000) /**< CS0 map size */
+#define IX_OSAL_IXP400_EXP_BUS_CS1_MAP_SIZE (0x01000000) /**< CS1 map size */
+#define IX_OSAL_IXP400_EXP_BUS_CS4_MAP_SIZE (0x01000000) /**< CS4 map size */
+#define IX_OSAL_IXP400_PCI_CFG_MAP_SIZE     (0x1000)	 /**< PCI Bus Config Registers map size */
+
+#define IX_OSAL_IXP400_EXP_FUSE             (IXP425_EXP_CONFIG_BASE + 0x28)
+#define IX_OSAL_IXP400_ETH_NPEA_PHYS_BASE   0xC800C000
+#define IX_OSAL_IXP400_ETH_NPEA_MAP_SIZE    0x1000
+
+/*
+ * Interrupt Levels
+ */
+#define IX_OSAL_IXP400_NPEA_IRQ_LVL		(0)
+#define IX_OSAL_IXP400_NPEB_IRQ_LVL		(1)
+#define IX_OSAL_IXP400_NPEC_IRQ_LVL		(2)
+#define IX_OSAL_IXP400_QM1_IRQ_LVL		(3)
+#define IX_OSAL_IXP400_QM2_IRQ_LVL		(4)
+#define IX_OSAL_IXP400_TIMER1_IRQ_LVL		(5)
+#define IX_OSAL_IXP400_GPIO0_IRQ_LVL		(6)
+#define IX_OSAL_IXP400_GPIO1_IRQ_LVL		(7)
+#define IX_OSAL_IXP400_PCI_INT_IRQ_LVL		(8)
+#define IX_OSAL_IXP400_PCI_DMA1_IRQ_LVL		(9)
+#define IX_OSAL_IXP400_PCI_DMA2_IRQ_LVL		(10)
+#define IX_OSAL_IXP400_TIMER2_IRQ_LVL		(11)
+#define IX_OSAL_IXP400_USB_IRQ_LVL		(12)
+#define IX_OSAL_IXP400_UART2_IRQ_LVL		(13)
+#define IX_OSAL_IXP400_TIMESTAMP_IRQ_LVL	(14)
+#define IX_OSAL_IXP400_UART1_IRQ_LVL		(15)
+#define IX_OSAL_IXP400_WDOG_IRQ_LVL		(16)
+#define IX_OSAL_IXP400_AHB_PMU_IRQ_LVL		(17)
+#define IX_OSAL_IXP400_XSCALE_PMU_IRQ_LVL	(18)
+#define IX_OSAL_IXP400_GPIO2_IRQ_LVL		(19)
+#define IX_OSAL_IXP400_GPIO3_IRQ_LVL		(20)
+#define IX_OSAL_IXP400_GPIO4_IRQ_LVL		(21)
+#define IX_OSAL_IXP400_GPIO5_IRQ_LVL		(22)
+#define IX_OSAL_IXP400_GPIO6_IRQ_LVL		(23)
+#define IX_OSAL_IXP400_GPIO7_IRQ_LVL		(24)
+#define IX_OSAL_IXP400_GPIO8_IRQ_LVL		(25)
+#define IX_OSAL_IXP400_GPIO9_IRQ_LVL		(26)
+#define IX_OSAL_IXP400_GPIO10_IRQ_LVL		(27)
+#define IX_OSAL_IXP400_GPIO11_IRQ_LVL		(28)
+#define IX_OSAL_IXP400_GPIO12_IRQ_LVL		(29)
+#define IX_OSAL_IXP400_SW_INT1_IRQ_LVL		(30)
+#define IX_OSAL_IXP400_SW_INT2_IRQ_LVL		(31)
+
+/* USB interrupt level mask */
+#define IX_OSAL_IXP400_INT_LVL_USB             IRQ_IXP425_USB
+
+/* USB IRQ */
+#define IX_OSAL_IXP400_USB_IRQ                 IRQ_IXP425_USB
+
+/*
+ * OS name retrieval
+ */
+#define IX_OSAL_OEM_OS_NAME_GET(name, limit) \
+ixOsalOsIxp400NameGet((INT8*)(name), (INT32) (limit))
+
+/*
+ * OS version retrieval
+ */
+#define IX_OSAL_OEM_OS_VERSION_GET(version, limit) \
+ixOsalOsIxp400VersionGet((INT8*)(version), (INT32) (limit))
+
+/*
+ * Function to retrieve the OS name
+ */
+PUBLIC IX_STATUS ixOsalOsIxp400NameGet(INT8* osName, INT32 maxSize);
+
+/*
+ * Function to retrieve the OS version
+ */
+PUBLIC IX_STATUS ixOsalOsIxp400VersionGet(INT8* osVersion, INT32 maxSize);
+
+/*
+ * TimestampGet
+ */
+PUBLIC UINT32 ixOsalOsIxp400TimestampGet (void);
+
+/*
+ * Timestamp
+ */
+#define IX_OSAL_OEM_TIMESTAMP_GET ixOsalOsIxp400TimestampGet
+
+
+/*
+ * Timestamp resolution
+ */
+PUBLIC UINT32 ixOsalOsIxp400TimestampResolutionGet (void);
+
+#define IX_OSAL_OEM_TIMESTAMP_RESOLUTION_GET ixOsalOsIxp400TimestampResolutionGet
+
+/*
+ * Retrieves the system clock rate
+ */
+PUBLIC UINT32 ixOsalOsIxp400SysClockRateGet (void);
+
+#define IX_OSAL_OEM_SYS_CLOCK_RATE_GET ixOsalOsIxp400SysClockRateGet
+
+/*
+ * required by FS but is not really platform-specific.
+ */
+#define IX_OSAL_OEM_TIME_GET(pTv) ixOsalTimeGet(pTv)
+
+
+
+/* linux map/unmap functions */
+PUBLIC void ixOsalLinuxMemMap (IxOsalMemoryMap * map);
+
+PUBLIC void ixOsalLinuxMemUnmap (IxOsalMemoryMap * map);
+
+
+/*********************
+ *	Memory map
+ ********************/
+
+/* Global memmap only visible to IO MEM module */
+
+#ifdef IxOsalIoMem_C
+
+IxOsalMemoryMap ixOsalGlobalMemoryMap[] = {
+     {
+     /* Global BE and LE_AC map */
+     IX_OSAL_STATIC_MAP,	/* type            */
+     0x00000000,		/* physicalAddress */
+     0x30000000,		/* size            */
+     0x00000000,		/* virtualAddress  */
+     NULL,			/* mapFunction     */
+     NULL,			/* unmapFunction   */
+     0,				/* refCount        */
+     IX_OSAL_BE | IX_OSAL_LE_AC,/* endianType      */
+     "global_low"		/* name            */
+     },
+
+    /* SDRAM LE_DC alias */
+    {
+     IX_OSAL_STATIC_MAP,	/* type            */
+     0x00000000,		/* physicalAddress */
+     0x10000000,		/* size            */
+     0x30000000,		/* virtualAddress  */
+     NULL,			/* mapFunction     */
+     NULL,			/* unmapFunction   */
+     0,				/* refCount        */
+     IX_OSAL_LE_DC,		/* endianType      */
+     "sdram_dc"			/* name            */
+     },
+
+    /* QMGR LE_DC alias */
+    {
+     IX_OSAL_STATIC_MAP,	/* type            */
+     0x60000000,		/* physicalAddress */
+     0x00100000,		/* size            */
+     0x60000000,		/* virtualAddress  */
+     NULL,			/* mapFunction     */
+     NULL,			/* unmapFunction   */
+     0,				/* refCount        */
+     IX_OSAL_LE_DC,		/* endianType      */
+     "qmgr_dc"			/* name            */
+     },
+
+    /* QMGR BE alias */
+    {
+     IX_OSAL_STATIC_MAP,	/* type            */
+     0x60000000,		/* physicalAddress */
+     0x00100000,		/* size            */
+     0x60000000,		/* virtualAddress  */
+     NULL,			/* mapFunction     */
+     NULL,			/* unmapFunction   */
+     0,				/* refCount        */
+     IX_OSAL_BE | IX_OSAL_LE_AC,/* endianType      */
+     "qmgr_be"			/* name            */
+     },
+
+    /* Global BE and LE_AC map */
+    {
+     IX_OSAL_STATIC_MAP,	/* type            */
+     0x40000000,		/* physicalAddress */
+     0x20000000,		/* size            */
+     0x40000000,		/* virtualAddress  */
+     NULL,			/* mapFunction     */
+     NULL,			/* unmapFunction   */
+     0,				/* refCount        */
+     IX_OSAL_BE | IX_OSAL_LE_AC,/* endianType      */
+     "Misc Cfg"			/* name            */
+     },
+
+    /* Global BE and LE_AC map */
+    {
+     IX_OSAL_STATIC_MAP,	/* type            */
+     0x70000000,		/* physicalAddress */
+     0x8FFFFFFF,		/* size            */
+     0x70000000,		/* virtualAddress  */
+     NULL,			/* mapFunction     */
+     NULL,			/* unmapFunction   */
+     0,				/* refCount        */
+     IX_OSAL_BE | IX_OSAL_LE_AC,/* endianType      */
+     "Exp Cfg"			/* name            */
+     },
+};
+
+#endif /* IxOsalIoMem_C */
+#endif /* #define IxOsalOsIxp400_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalOsIxp400CustomizedMapping.h b/marvell/uboot/drivers/net/npe/include/IxOsalOsIxp400CustomizedMapping.h
new file mode 100644
index 0000000..e037823
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalOsIxp400CustomizedMapping.h
@@ -0,0 +1,380 @@
+/**
+ * @file IxOsalOsIxp400CustomizedMapping.h 
+ *
+ * @brief Set LE coherency modes for components. 
+ *        The default setting is IX_OSAL_NO_MAPPING for LE.
+ * 
+ *
+ *		  By default IX_OSAL_STATIC_MEMORY_MAP is defined for all the components.
+ *		  If any component uses a dynamic memory map it must define
+ *		  IX_OSAL_DYNAMIC_MEMORY_MAP in its corresponding section.
+ *        
+ *
+ * @par
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsalOsIxp400CustomizedMapping_H
+#define IxOsalOsIxp400CustomizedMapping_H
+
+/*
+ * only include this file in Little Endian
+ */
+
+#if defined (IX_OSAL_LINUX_BE)
+#error Only include IxOsalOsIxp400CustomizedMapping.h in Little Endian
+#endif
+
+ /*
+  * Components don't have to be in this list if
+  * the default mapping is OK.
+  */
+#define ix_osal                1
+#define ix_dmaAcc              2
+#define ix_atmdAcc             3
+
+#define ix_atmsch              5
+#define ix_ethAcc              6
+#define ix_npeMh               7
+#define ix_qmgr                8
+#define ix_npeDl               9
+#define ix_atmm                10
+#define ix_hssAcc              11
+#define ix_ethDB               12
+#define ix_ethMii              13
+#define ix_timerCtrl           14
+#define ix_adsl                15
+#define ix_usb                 16
+#define ix_uartAcc             17
+#define ix_featureCtrl         18
+#define ix_cryptoAcc           19
+#define ix_unloadAcc           33
+#define ix_perfProfAcc         34
+#define ix_parityENAcc                 49
+#define ix_sspAcc                      51
+#define ix_timeSyncAcc                 52
+#define ix_i2c                         53
+
+#define ix_codelets_uartAcc    21
+#define ix_codelets_timers     22
+#define ix_codelets_atm        23
+#define ix_codelets_ethAal5App 24
+#define ix_codelets_demoUtils  26
+#define ix_codelets_usb        27
+#define ix_codelets_hssAcc     28
+#define ix_codelets_dmaAcc         40
+#define ix_codelets_cryptoAcc	   41
+#define ix_codelets_perfProfAcc    42
+#define ix_codelets_ethAcc         43
+#define ix_codelets_parityENAcc        54
+#define ix_codelets_timeSyncAcc        55
+
+
+#endif /* IxOsalOsIxp400CustomizedMapping_H */
+
+
+/***************************
+ * osal
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_osal)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* osal */
+
+/***************************
+ * dmaAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_dmaAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* dmaAcc */
+
+/***************************
+ * atmdAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_atmdAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* atmdAcc */
+
+/***************************
+ * atmsch
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_atmsch)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* atmsch */
+
+/***************************
+ * ethAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_ethAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* ethAcc */
+
+/***************************
+ * npeMh
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_npeMh)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* npeMh */
+
+/***************************
+ * qmgr
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_qmgr)
+
+#define IX_OSAL_LE_DC_MAPPING
+
+#endif /* qmgr */
+
+/***************************
+ * npeDl
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_npeDl)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* npeDl */
+
+/***************************
+ * atmm
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_atmm)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* atmm */
+
+/***************************
+ * ethMii
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_ethMii)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* ethMii */
+
+
+/***************************
+ * adsl
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_adsl)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* adsl */
+
+/***************************
+ * usb
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_usb)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* usb */
+
+/***************************
+ * uartAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_uartAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* uartAcc */
+
+/***************************
+ * featureCtrl
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_featureCtrl)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* featureCtrl */
+
+/***************************
+ * cryptoAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_cryptoAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* cryptoAcc */
+
+/***************************
+ * codelets_usb
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_usb)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_usb */
+
+
+/***************************
+ * codelets_uartAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_uartAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_uartAcc */
+
+
+
+/***************************
+ * codelets_timers
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_timers)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_timers */
+
+/***************************
+ * codelets_atm
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_atm)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_atm */
+
+/***************************
+ * codelets_ethAal5App
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_ethAal5App)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_ethAal5App */
+
+/***************************
+ * codelets_ethAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_ethAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_ethAcc */
+
+
+/***************************
+ * codelets_demoUtils
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_demoUtils)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_demoUtils */
+
+
+
+/***************************
+ * perfProfAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_perfProfAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* perfProfAcc */
+
+
+/***************************
+ * unloadAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_unloadAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* unloadAcc */
+
+
+
+
+
+/***************************
+ * parityENAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_parityENAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* parityENAcc */
+
+/***************************
+ * codelets_parityENAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_parityENAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_parityENAcc */
+
+
+
+
+/***************************
+ * timeSyncAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_timeSyncAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* timeSyncAcc */
+
+
+/***************************
+ * codelets_timeSyncAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_codelets_timeSyncAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* codelets_timeSyncAcc */
+
+
+
+
+/***************************
+ * i2c
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_i2c)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* i2c */
+
+
+
+/***************************
+ * sspAcc
+ ***************************/
+#if (IX_COMPONENT_NAME == ix_sspAcc)
+
+#define IX_OSAL_LE_AC_MAPPING
+
+#endif /* sspAcc */
+
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalOsTypes.h b/marvell/uboot/drivers/net/npe/include/IxOsalOsTypes.h
new file mode 100644
index 0000000..272eef1
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalOsTypes.h
@@ -0,0 +1,60 @@
+#ifndef IxOsalOsTypes_H
+#define IxOsalOsTypes_H
+
+#include <asm/types.h>
+
+typedef s64 INT64;
+typedef u64 UINT64;
+typedef s32 INT32;
+typedef u32 UINT32;
+typedef s16 INT16;
+typedef u16 UINT16;
+typedef s8 INT8;
+typedef u8 UINT8;
+
+typedef u32 ULONG;
+typedef u16 USHORT;
+typedef u8 UCHAR;
+typedef u32 BOOL;
+
+#if 0 /* FIXME */
+
+/* Default stack limit is 10 KB */
+#define IX_OSAL_OS_THREAD_DEFAULT_STACK_SIZE  (10240)
+
+/* Maximum stack limit is 32 MB */
+#define IX_OSAL_OS_THREAD_MAX_STACK_SIZE      (33554432)  /* 32 MBytes */
+
+/* Default thread priority */
+#define IX_OSAL_OS_DEFAULT_THREAD_PRIORITY    (90)
+
+/* Thread maximum priority (0 - 255). 0 - highest priority */
+#define IX_OSAL_OS_MAX_THREAD_PRIORITY	      (255)
+
+#endif /* FIXME */
+
+#define IX_OSAL_OS_WAIT_FOREVER (-1L)
+#define IX_OSAL_OS_WAIT_NONE	0
+
+
+/* Thread handle is eventually an int type */
+typedef int IxOsalOsThread;
+
+/* Semaphore handle FIXME */
+typedef int IxOsalOsSemaphore;
+
+/* Mutex handle */
+typedef int IxOsalOsMutex;
+
+/*
+ * Fast mutex handle - fast mutex operations are implemented in
+ * native assembler code using atomic test-and-set instructions
+ */
+typedef int IxOsalOsFastMutex;
+
+typedef struct
+{
+} IxOsalOsMessageQueue;
+
+
+#endif /* IxOsalOsTypes_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalOsUtilitySymbols.h b/marvell/uboot/drivers/net/npe/include/IxOsalOsUtilitySymbols.h
new file mode 100644
index 0000000..beb45a0
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalOsUtilitySymbols.h
@@ -0,0 +1,4 @@
+#ifndef IxOsalOsUtilitySymbols_H
+#define IxOsalOsUtilitySymbols_H
+
+#endif /* IxOsalOsUtilitySymbols_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalTypes.h b/marvell/uboot/drivers/net/npe/include/IxOsalTypes.h
new file mode 100644
index 0000000..aefa70f
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalTypes.h
@@ -0,0 +1,355 @@
+/**
+ * @file IxOsalTypes.h
+ *
+ * @brief Define OSAL basic data types.
+ *
+ * This file contains fundamental data types used by OSAL.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ *
+ * -- Copyright Notice --
+ *
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ *
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+
+#ifndef IxOsalTypes_H
+#define IxOsalTypes_H
+
+#include <config.h>
+#include <common.h>
+
+#define __ixp42X			/* sr: U-Boot needs this define */
+#define IXP425_EXP_CFG_BASE	0xC4000000
+#define diag_printf		debug
+
+#undef SIMSPARCSOLARIS
+#define SIMSPARCSOLARIS		0xaffe	/* sr: U-Boot gets confused with this solaris define */
+
+/*
+ * Include the OS-specific type definitions
+ */
+#include "IxOsalOsTypes.h"
+/**
+ * @defgroup IxOsalTypes Osal basic data types.
+ *
+ * @brief Basic data types for Osal
+ *
+ * @{
+ */
+
+/**
+ * @brief OSAL status
+ *
+ * @note Possible OSAL return status include IX_SUCCESS and IX_FAIL.
+ */
+typedef UINT32 IX_STATUS;
+
+/**
+ * @brief VUINT32
+ *
+ * @note volatile UINT32
+ */
+typedef volatile UINT32 VUINT32;
+
+/**
+ * @brief VINT32
+ *
+ * @note volatile INT32
+ */
+typedef volatile INT32 VINT32;
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_BILLION
+ *
+ * @brief  Alias for 1,000,000,000
+ *
+ */
+#define IX_OSAL_BILLION (1000000000)
+
+#ifndef NULL
+#define NULL       0L
+#endif
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_SUCCESS
+ *
+ * @brief Success status
+ *
+ */
+#ifndef IX_SUCCESS
+#define IX_SUCCESS 0L /**< #defined as 0L */
+#endif
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_FAIL
+ *
+ * @brief Failure status
+ *
+ */
+#ifndef IX_FAIL
+#define IX_FAIL    1L /**< #defined as 1L */
+#endif
+
+
+#ifndef PRIVATE
+#ifdef IX_PRIVATE_OFF
+#define PRIVATE			/* nothing */
+#else
+#define PRIVATE static	/**< #defined as static, except for debug builds */
+#endif /* IX_PRIVATE_OFF */
+#endif /* PRIVATE */
+
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_INLINE
+ *
+ * @brief Alias for __inline
+ *
+ */
+#ifndef IX_OSAL_INLINE
+#define IX_OSAL_INLINE __inline
+#endif /* IX_OSAL_INLINE */
+
+
+#ifndef __inline__
+#define __inline__	IX_OSAL_INLINE
+#endif
+
+
+/* Each OS can define its own PUBLIC, otherwise it will be empty. */
+#ifndef PUBLIC
+#define PUBLIC
+#endif /* PUBLIC */
+
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_INLINE_EXTERN
+ *
+ * @brief Alias for __inline extern
+ *
+ */
+#ifndef IX_OSAL_INLINE_EXTERN
+#define IX_OSAL_INLINE_EXTERN IX_OSAL_INLINE extern
+#endif
+
+/**
+ * @ingroup IxOsalTypes
+ * @enum IxOsalLogDevice
+ * @brief This is an emum for OSAL log devices.
+ */
+typedef enum
+{
+    IX_OSAL_LOG_DEV_STDOUT = 0,	       /**< standard output (implemented by default) */
+    IX_OSAL_LOG_DEV_STDERR = 1,	       /**< standard error (implemented */
+    IX_OSAL_LOG_DEV_HEX_DISPLAY = 2,   /**< hexadecimal display (not implemented) */
+    IX_OSAL_LOG_DEV_ASCII_DISPLAY = 3  /**< ASCII-capable display (not implemented) */
+} IxOsalLogDevice;
+
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_LOG_ERROR
+ *
+ * @brief Alias for -1, used as log function error status
+ *
+ */
+#define IX_OSAL_LOG_ERROR (-1)
+
+/**
+ * @ingroup IxOsalTypes
+ * @enum IxOsalLogLevel
+ * @brief This is an emum for OSAL log trace level.
+ */
+typedef enum
+{
+    IX_OSAL_LOG_LVL_NONE = 0,	 /**<No trace level */
+    IX_OSAL_LOG_LVL_USER = 1,	 /**<Set trace level to user */
+    IX_OSAL_LOG_LVL_FATAL = 2,	 /**<Set trace level to fatal */
+    IX_OSAL_LOG_LVL_ERROR = 3,	 /**<Set trace level to error */
+    IX_OSAL_LOG_LVL_WARNING = 4, /**<Set trace level to warning */
+    IX_OSAL_LOG_LVL_MESSAGE = 5, /**<Set trace level to message */
+    IX_OSAL_LOG_LVL_DEBUG1 = 6,	 /**<Set trace level to debug1 */
+    IX_OSAL_LOG_LVL_DEBUG2 = 7,	 /**<Set trace level to debug2 */
+    IX_OSAL_LOG_LVL_DEBUG3 = 8,	 /**<Set trace level to debug3 */
+    IX_OSAL_LOG_LVL_ALL	/**<Set trace level to all */
+} IxOsalLogLevel;
+
+
+/**
+ * @ingroup IxOsalTypes
+ * @brief Void function pointer prototype
+ *
+ * @note accepts a void pointer parameter
+ * and does not return a value.
+ */
+typedef void (*IxOsalVoidFnVoidPtr) (void *);
+
+typedef void (*IxOsalVoidFnPtr) (void);
+
+
+/**
+ * @brief Timeval structure
+ *
+ * @note Contain subfields of seconds and nanoseconds..
+ */
+typedef struct
+{
+    UINT32 secs;		/**< seconds */
+    UINT32 nsecs;		/**< nanoseconds */
+} IxOsalTimeval;
+
+
+/**
+ * @ingroup IxOsalTypes
+ * @brief IxOsalTimer
+ *
+ * @note OSAL timer handle
+ *
+ */
+typedef UINT32 IxOsalTimer;
+
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_WAIT_FOREVER
+ *
+ * @brief Definition for timeout forever, OS-specific.
+ *
+ */
+#define IX_OSAL_WAIT_FOREVER IX_OSAL_OS_WAIT_FOREVER
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_WAIT_NONE
+ *
+ * @brief Definition for timeout 0, OS-specific.
+ *
+ */
+#define IX_OSAL_WAIT_NONE    IX_OSAL_OS_WAIT_NONE
+
+
+/**
+ * @ingroup IxOsalTypes
+ * @brief IxOsalMutex
+ *
+ * @note Mutex handle, OS-specific
+ *
+ */
+typedef IxOsalOsMutex IxOsalMutex;
+
+/**
+ * @ingroup IxOsalTypes
+ * @brief IxOsalFastMutex
+ *
+ * @note FastMutex handle, OS-specific
+ *
+ */
+typedef IxOsalOsFastMutex IxOsalFastMutex;
+
+/**
+ * @ingroup IxOsalTypes
+ * @brief IxOsalThread
+ *
+ * @note Thread handle, OS-specific
+ *
+ */
+typedef IxOsalOsThread IxOsalThread;
+
+/**
+ * @ingroup IxOsalTypes
+ * @brief IxOsalSemaphore
+ *
+ * @note Semaphore handle, OS-specific
+ *
+ */
+typedef IxOsalOsSemaphore IxOsalSemaphore;
+
+/**
+ * @ingroup IxOsalTypes
+ * @brief IxOsalMessageQueue
+ *
+ * @note Message Queue handle, OS-specific
+ *
+ */
+typedef IxOsalOsMessageQueue IxOsalMessageQueue;
+
+
+/**
+ * @brief Thread Attribute
+ * @note Default thread attribute
+ */
+typedef struct
+{
+    char *name;        /**< name */
+    UINT32 stackSize;  /**< stack size */
+    UINT32 priority;   /**< priority */
+} IxOsalThreadAttr;
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_THREAD_DEFAULT_STACK_SIZE
+ *
+ * @brief Default thread stack size, OS-specific.
+ *
+ */
+#define IX_OSAL_THREAD_DEFAULT_STACK_SIZE (IX_OSAL_OS_THREAD_DEFAULT_STACK_SIZE)
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_THREAD_MAX_STACK_SIZE
+ *
+ * @brief Max stack size, OS-specific.
+ *
+ */
+#define IX_OSAL_THREAD_MAX_STACK_SIZE (IX_OSAL_OS_THREAD_MAX_STACK_SIZE)
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_DEFAULT_THREAD_PRIORITY
+ *
+ * @brief Default thread priority, OS-specific.
+ *
+ */
+#define IX_OSAL_DEFAULT_THREAD_PRIORITY (IX_OSAL_OS_DEFAULT_THREAD_PRIORITY)
+
+/**
+ * @ingroup IxOsalTypes
+ *
+ * @def IX_OSAL_MAX_THREAD_PRIORITY
+ *
+ * @brief Max thread priority, OS-specific.
+ *
+ */
+#define IX_OSAL_MAX_THREAD_PRIORITY (IX_OSAL_OS_MAX_THREAD_PRIORITY)
+
+/**
+ * @} IxOsalTypes
+ */
+
+
+#endif /* IxOsalTypes_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxOsalUtilitySymbols.h b/marvell/uboot/drivers/net/npe/include/IxOsalUtilitySymbols.h
new file mode 100644
index 0000000..ec34df6
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxOsalUtilitySymbols.h
@@ -0,0 +1,27 @@
+/**
+ * @file
+ *
+ * @brief OSAL Configuration header file
+ * 
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxOsalUtilitySymbols_H
+#define IxOsalUtilitySymbols_H
+
+#include "IxOsalOsUtilitySymbols.h"	/* OS-specific utility symbol definitions */
+
+#endif /* IxOsalUtilitySymbols_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxParityENAcc.h b/marvell/uboot/drivers/net/npe/include/IxParityENAcc.h
new file mode 100644
index 0000000..4d44838
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxParityENAcc.h
@@ -0,0 +1,761 @@
+/**
+ * @file IxParityENAcc.h
+ *
+ * @author Intel Corporation
+ * @date 24 Mar 2004
+ *
+ * @brief This file contains the public API for the IXP400 Parity Error 
+ * Notifier access component.
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxParityENAcc IXP400 Parity Error Notifier (IxParityENAcc) API
+ *
+ * @brief The public API for the Parity Error Notifier 
+ * 
+ * @{
+ */
+
+#ifndef IXPARITYENACC_H
+#define IXPARITYENACC_H
+
+#ifdef __ixp46X
+
+#include "IxOsal.h"
+
+/*
+ * #defines for function return types, etc.
+ */
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccStatus
+ *
+ * @brief The status as returend from the API
+ */
+typedef enum /**< IxParityENAccStatus */
+{
+  IX_PARITYENACC_SUCCESS = IX_SUCCESS, /**< The request is successful */
+  IX_PARITYENACC_INVALID_PARAMETERS,   /**< Invalid or NULL parameters passed */
+  IX_PARITYENACC_NOT_INITIALISED,      /**< Access layer has not been initialised before accessing the APIs */
+  IX_PARITYENACC_ALREADY_INITIALISED,  /**< Access layer has already been initialised */ 
+  IX_PARITYENACC_OPERATION_FAILED,     /**< Operation did not succeed due to hardware failure */
+  IX_PARITYENACC_NO_PARITY             /**< No parity condition exits or has already been cleared */
+} IxParityENAccStatus;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccParityType
+ * 
+ * @brief Odd or Even Parity Type
+ */
+typedef enum  /**< IxParityENAccParityType */
+{
+  IX_PARITYENACC_EVEN_PARITY,    /**< Even Parity */
+  IX_PARITYENACC_ODD_PARITY      /**< Odd Parity */
+} IxParityENAccParityType;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccConfigOption
+ *
+ * @brief The parity error enable/disable configuration option
+ */
+typedef enum /**< IxParityENAccConfigOption */
+{
+  IX_PARITYENACC_DISABLE,       /**< Disable parity error detection */
+  IX_PARITYENACC_ENABLE         /**< Enable parity error detection */
+} IxParityENAccConfigOption;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccNpeConfig
+ *
+ * @brief NPE parity detection is to be enabled/disabled
+ */
+typedef struct /**< IxParityENAccNpeConfig */
+{
+  IxParityENAccConfigOption ideEnabled; /**< NPE IMem, DMem and External */
+  IxParityENAccParityType parityOddEven; /**< Parity - Odd or Even */
+} IxParityENAccNpeConfig ;
+
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccMcuConfig
+ *
+ * @brief MCU pairty detection is to be enabled/disabled
+ */
+typedef struct /**< IxParityENAccMcuConfig */ 
+{
+  IxParityENAccConfigOption singlebitDetectEnabled;      /**< Single-bit parity error detection */
+  IxParityENAccConfigOption singlebitCorrectionEnabled;  /**< Single-bit parity error correction */
+  IxParityENAccConfigOption multibitDetectionEnabled;    /**< Multi-bit  parity error detection */
+} IxParityENAccMcuConfig ;
+
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccEbcConfig
+ *
+ * @brief Expansion Bus Controller parity detection is to be enabled or disabled 
+ *
+ * Note: All the Chip Select(s) and External Masters will have the same parity
+ */
+typedef struct /**< IxParityENAccEbcConfig */
+{
+  IxParityENAccConfigOption ebcCs0Enabled;    /**< Expansion Bus Controller - Chip Select 0 */
+  IxParityENAccConfigOption ebcCs1Enabled;    /**< Expansion Bus Controller - Chip Select 1 */
+  IxParityENAccConfigOption ebcCs2Enabled;    /**< Expansion Bus Controller - Chip Select 2 */
+  IxParityENAccConfigOption ebcCs3Enabled;    /**< Expansion Bus Controller - Chip Select 3 */
+  IxParityENAccConfigOption ebcCs4Enabled;    /**< Expansion Bus Controller - Chip Select 4 */
+  IxParityENAccConfigOption ebcCs5Enabled;    /**< Expansion Bus Controller - Chip Select 5 */
+  IxParityENAccConfigOption ebcCs6Enabled;    /**< Expansion Bus Controller - Chip Select 6 */
+  IxParityENAccConfigOption ebcCs7Enabled;    /**< Expansion Bus Controller - Chip Select 7 */
+  IxParityENAccConfigOption ebcExtMstEnabled; /**< External Master on Expansion bus */
+  IxParityENAccParityType parityOddEven;      /**< Parity - Odd or Even */
+} IxParityENAccEbcConfig ;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccHWParityConfig
+ *
+ * @brief Parity error configuration of the Hardware Blocks
+ */
+typedef struct /**< IxParityENAccHWParityConfig */
+{ 
+  IxParityENAccNpeConfig npeAConfig;     /**< NPE A parity detection is to be enabled/disabled */
+  IxParityENAccNpeConfig npeBConfig;     /**< NPE B parity detection is to be enabled/disabled */
+  IxParityENAccNpeConfig npeCConfig;     /**< NPE C parity detection is to be enabled/disabled */
+  IxParityENAccMcuConfig mcuConfig;      /**< MCU pairty detection is to be enabled/disabled */
+  IxParityENAccConfigOption swcpEnabled; /**< SWCP parity detection is to be enabled */
+  IxParityENAccConfigOption aqmEnabled;  /**< AQM parity detection is to be enabled */
+  IxParityENAccEbcConfig ebcConfig;      /**< Expansion Bus Controller parity detection is to be enabled/disabled */
+} IxParityENAccHWParityConfig;
+
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccNpeParityErrorStats
+ *
+ * @brief NPE parity error statistics
+ */
+typedef struct  /* IxParityENAccNpeParityErrorStats */
+{
+  UINT32 parityErrorsIMem;         /**< Parity errors in Instruction Memory */
+  UINT32 parityErrorsDMem;         /**< Parity errors in Data Memory */
+  UINT32 parityErrorsExternal;     /**< Parity errors in NPE External Entities */
+} IxParityENAccNpeParityErrorStats;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccMcuParityErrorStats
+ *
+ * @brief DDR Memory Control Unit parity error statistics
+ * 
+ * Note: There could be two outstanding parity errors at any given time whose address
+ * details captured. If there is no room for the new interrupt then it would be treated
+ * as overflow parity condition.
+ */
+typedef struct  /* IxParityENAccMcuParityErrorStats */
+{
+  UINT32 parityErrorsSingleBit;    /**< Parity errors of the type Single-Bit */
+  UINT32 parityErrorsMultiBit;     /**< Parity errors of the type Multi-Bit */
+  UINT32 parityErrorsOverflow;     /**< Parity errors when more than two parity errors occured */
+} IxParityENAccMcuParityErrorStats;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccEbcParityErrorStats
+ *
+ * @brief Expansion Bus Controller parity error statistics
+ */
+typedef struct  /* IxParityENAccEbcParityErrorStats */
+{
+  UINT32 parityErrorsInbound;      /**< Odd bit parity errors on inbound transfers */
+  UINT32 parityErrorsOutbound;     /**< Odd bit parity errors on outbound transfers */
+} IxParityENAccEbcParityErrorStats;
+
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccParityErrorStats
+ *
+ * @brief Parity Error Statistics for the all the hardware blocks
+ */
+typedef struct  /**< IxParityENAccParityErrorStats */
+{
+  IxParityENAccNpeParityErrorStats  npeStats;  /**< NPE parity error statistics */
+  IxParityENAccMcuParityErrorStats  mcuStats;  /**< MCU parity error statistics */
+  IxParityENAccEbcParityErrorStats  ebcStats;  /**< EBC parity error statistics */
+  UINT32                            swcpStats; /**< SWCP parity error statistics */
+  UINT32                            aqmStats;  /**< AQM parity error statistics */
+} IxParityENAccParityErrorStats;
+
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccParityErrorSource
+ *
+ * @brief The source of the parity error notification 
+ */
+typedef enum  /**< IxParityENAccParityErrorSource  */
+{
+  IX_PARITYENACC_NPE_A_IMEM,     /**< NPE A - Instruction memory */
+  IX_PARITYENACC_NPE_A_DMEM,     /**< NPE A - Data memory */
+  IX_PARITYENACC_NPE_A_EXT,      /**< NPE A - External Entity*/
+  IX_PARITYENACC_NPE_B_IMEM,     /**< NPE B - Instruction memory */
+  IX_PARITYENACC_NPE_B_DMEM,     /**< NPE B - Data memory */
+  IX_PARITYENACC_NPE_B_EXT,      /**< NPE B - External Entity*/
+  IX_PARITYENACC_NPE_C_IMEM,     /**< NPE C - Instruction memory */
+  IX_PARITYENACC_NPE_C_DMEM,     /**< NPE C - Data memory */
+  IX_PARITYENACC_NPE_C_EXT,      /**< NPE C - External Entity*/
+  IX_PARITYENACC_SWCP,           /**< SWCP */
+  IX_PARITYENACC_AQM,            /**< AQM */
+  IX_PARITYENACC_MCU_SBIT,       /**< DDR Memory Controller Unit - Single bit parity */
+  IX_PARITYENACC_MCU_MBIT,       /**< DDR Memory Controller Unit - Multi bit parity */
+  IX_PARITYENACC_MCU_OVERFLOW,   /**< DDR Memory Controller Unit - Parity errors in excess of two */
+  IX_PARITYENACC_EBC_CS,         /**< Expansion Bus Controller - Chip Select */
+  IX_PARITYENACC_EBC_EXTMST      /**< Expansion Bus Controller - External Master */
+} IxParityENAccParityErrorSource;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccParityErrorAccess
+ *
+ * @brief The type of access resulting in parity error
+ */
+typedef enum  /**< IxParityENAccParityErrorAccess  */
+{
+  IX_PARITYENACC_READ,   /**< Read Access  */
+  IX_PARITYENACC_WRITE   /**< Write Access */
+} IxParityENAccParityErrorAccess;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @typedef IxParityENAccParityErrorAddress
+ *
+ * @brief The memory location which has parity error
+ */
+typedef UINT32 IxParityENAccParityErrorAddress;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @typedef IxParityENAccParityErrorData
+ *
+ * @brief The data read from the memory location which has parity error
+ */
+typedef UINT32 IxParityENAccParityErrorData;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccParityErrorRequester
+ *
+ * @brief The requester interface through which the SDRAM memory access 
+ * resulted in the parity error.
+ */
+typedef enum  /**< IxParityENAccParityErrorRequester  */
+{
+  IX_PARITYENACC_MPI,     /**< Direct Memory Port Interface  */
+  IX_PARITYENACC_AHB_BUS  /**< South or North AHB Bus */
+} IxParityENAccParityErrorRequester;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccAHBErrorMaster
+ *
+ * @brief The Master on the AHB bus interface whose transaction might have 
+ * resulted in the parity error notification to XScale.
+ */
+typedef enum  /**< IxParityENAccAHBErrorMaster */
+{
+  IX_PARITYENACC_AHBN_MST_NPE_A,       /**< NPE - A */
+  IX_PARITYENACC_AHBN_MST_NPE_B,       /**< NPE - B */
+  IX_PARITYENACC_AHBN_MST_NPE_C,       /**< NPE - C */
+  IX_PARITYENACC_AHBS_MST_XSCALE,      /**< XScale Bus Interface Unit */
+  IX_PARITYENACC_AHBS_MST_PBC,         /**< PCI Bus Controller */
+  IX_PARITYENACC_AHBS_MST_EBC,         /**< Expansion Bus Controller */
+  IX_PARITYENACC_AHBS_MST_AHB_BRIDGE,  /**< AHB Bridge */
+  IX_PARITYENACC_AHBS_MST_USBH         /**< USB Host Controller */
+} IxParityENAccAHBErrorMaster;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @enum IxParityENAccAHBErrorSlave
+ *
+ * @brief The Slave on the AHB bus interface whose transaction might have 
+ * resulted in the parity error notification to XScale.
+ */
+typedef enum  /**< IxParityENAccAHBErrorSlave */
+{
+  IX_PARITYENACC_AHBN_SLV_MCU,         /**< Memory Control Unit */
+  IX_PARITYENACC_AHBN_SLV_AHB_BRIDGE,  /**< AHB Bridge */
+  IX_PARITYENACC_AHBS_SLV_MCU,         /**< XScale Bus Interface Unit */
+  IX_PARITYENACC_AHBS_SLV_APB_BRIDGE,  /**< APB Bridge */
+  IX_PARITYENACC_AHBS_SLV_AQM,         /**< AQM */
+  IX_PARITYENACC_AHBS_SLV_RSA,         /**< RSA (Crypto Bus) */
+  IX_PARITYENACC_AHBS_SLV_PBC,         /**< PCI Bus Controller */
+  IX_PARITYENACC_AHBS_SLV_EBC,         /**< Expansion Bus Controller */
+  IX_PARITYENACC_AHBS_SLV_USBH         /**< USB Host Controller */
+} IxParityENAccAHBErrorSlave;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccAHBErrorTransaction
+ *
+ * @brief The Master and Slave on the AHB bus interface whose transaction might
+ * have resulted in the parity error notification to XScale.
+ *
+ * NOTE: This information may be used in the data abort exception handler
+ * to differentiate between the XScale and non-XScale access to the SDRAM
+ * memory.
+ */
+typedef struct  /**< IxParityENAccAHBErrorTransaction  */
+{
+  IxParityENAccAHBErrorMaster  ahbErrorMaster; /**< Master on AHB bus */
+  IxParityENAccAHBErrorSlave   ahbErrorSlave;  /**< Slave  on AHB bus */
+} IxParityENAccAHBErrorTransaction;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @struct IxParityENAccParityErrorContextMessage
+ *
+ * @brief Parity Error Context Message
+ */
+typedef struct /**< IxParityENAccParityErrorContextMessage */
+{
+  IxParityENAccParityErrorSource     pecParitySource; /**< Source info of parity error */
+  IxParityENAccParityErrorAccess     pecAccessType;   /**< Read or Write Access
+                                                           Read  - NPE, SWCP, AQM, DDR MCU,
+                                                                   Exp Bus Ctrlr (Outbound)
+                                                           Write - DDR MCU,
+                                                                   Exp Bus Ctrlr (Inbound 
+                                                                   i.e., External Master) */
+  IxParityENAccParityErrorAddress    pecAddress;      /**< Address faulty location
+                                                           Valid only for AQM, DDR MCU, 
+                                                           Exp Bus Ctrlr */
+  IxParityENAccParityErrorData       pecData;         /**< Data read from the faulty location
+                                                           Valid only for AQM and DDR MCU
+                                                           For DDR MCU it is the bit location
+                                                           of the Single-bit parity */
+  IxParityENAccParityErrorRequester  pecRequester;    /**< Requester of SDRAM memory access
+                                                           Valid only for the DDR MCU */
+  IxParityENAccAHBErrorTransaction   ahbErrorTran;    /**< Master and Slave information on the
+                                                           last AHB Error Transaction */
+} IxParityENAccParityErrorContextMessage;
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @typedef IxParityENAccCallback
+ *
+ * @brief This prototype shows the format of a callback function.
+ *
+ * The callback will be used to notify the parity error to the client application.
+ * The callback will be registered  by @ref ixParityENAccCallbackRegister.
+ *
+ * It will be called from an ISR when a parity error is detected and thus
+ * needs to follow the interrupt callable function conventions.
+ *
+ */
+typedef void (*IxParityENAccCallback) (void);
+
+
+/*
+ * Prototypes for interface functions.
+ */
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccInit(void)
+ *
+ * @brief This function will initialise the IxParityENAcc component.
+ *
+ * This function will initialise the IxParityENAcc component. It should only be
+ * called once, prior to using the IxParityENAcc component.
+ *
+ * <OL><LI>It initialises the internal data structures, registers the ISR that 
+ * will be triggered when a parity error occurs in IXP4xx silicon.</LI></OL>
+ *
+ * @li Re-entrant   : No
+ * @li ISR Callable : No
+ * 
+ * @return @li IX_PARITYENACC_SUCCESS - Initialization is successful
+ *         @li IX_PARITYENACC_ALREADY_INITIALISED - The access layer has already 
+ *             been initialized
+ *         @li IX_PARITYENACC_OPERATION_FAILED - The request failed because the 
+ *             operation didn't succeed on the hardware. Refer to error trace/log
+ *             for details.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccInit(void);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccCallbackRegister (
+           IxParityENAccCallback parityErrNfyCallBack)
+ *
+ * @brief This function will register a new callback with IxParityENAcc component. 
+ * It can also reregister a new callback replacing the old callback.
+ *
+ * @param parityErrNfyCallBack [in] - This parameter will specify the call-back
+ * function supplied by the client application.
+ *
+ * This interface registers the user application supplied call-back handler with
+ * the parity error handling access component after the init.
+ *
+ * The callback function will be called from an ISR that will be triggered by the 
+ * parity error in the IXP400 silicon.
+ *
+ * The following actions will be performed by this function:
+ * <OL><LI>Check for the prior initialisation of the module before registering or
+ * re-registering of the callback.
+ * Check for parity error detection disabled before re-registration of the callback.
+ * </LI></OL>
+ *
+ * @li   Re-entrant   : No
+ * @li   ISR Callable : No
+ *
+ * @return @li IX_PARITYENACC_SUCCESS - The parameters check passed and the 
+ *             registration is successful.
+ *         @li IX_PARITYENACC_INVALID_PARAMETERS - Request failed due to NULL 
+ *             parameter passed.
+ *         @li IX_PARITYENACC_OPERATION_FAILED - The request failed because the 
+ *             parity error detection not yet disabled.
+ *         @li IX_PARITYENACC_NOT_INITIALISED - The operation requested prior to
+ *             the initialisation of the access layer.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccCallbackRegister (
+           IxParityENAccCallback parityErrNfyCallBack);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccParityDetectionConfigure (
+           const IxParityENAccHWParityConfig *hwParityConfig)
+ *
+ * @brief This interface allows the client application to enable the parity 
+ * error detection on the underlying hardware block.
+ *
+ * @param hwParityConfig [in] - Hardware blocks for which the parity error 
+ * detection is to be enabled or disabled.
+ *
+ * The client application allocates and provides the reference to the buffer.
+ *
+ * It will also verify whether the specific hardware block is functional or not.
+ *
+ * NOTE: Failure in enabling or disabling of one or more components result in
+ * trace message but still returns IX_PARITYENACC_SUCCESS. Refer to the function 
+ * @ref ixParityENAccParityDetectionQuery on how to verify the failures while 
+ * enabling/disabling paritys error detection.
+ *
+ * It shall be invoked after the Init and CallbackRegister functions but before
+ * any other function of the IxParityENAcc layer.
+ *
+ * @li   Re-entrant   : No
+ * @li   ISR Callable : No
+ *
+ * @return @li IX_PARITYENACC_SUCCESS - The parameters check passed and the 
+ *             request to enable/disable is successful.
+ *         @li IX_PARITYENACC_INVALID_PARAMETERS-The request failed due to  
+ *             NULL parameter supplied.
+ *         @li IX_PARITYENACC_OPERATION_FAILED - The request failed because the 
+ *             operation didn't succeed on the hardware.
+ *         @li IX_PARITYENACC_NOT_INITIALISED - The operation requested prior to
+ *             the initialisation of the access layer.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccParityDetectionConfigure (
+           const IxParityENAccHWParityConfig *hwParityConfig);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccParityDetectionQuery (
+           IxParityENAccHWParityConfig * const hwParityConfig)
+ *
+ * @brief This interface allows the client application to determine the 
+ * status of the parity error detection on the specified hardware blocks
+ *
+ * @param hwParityConfig [out] - Hardware blocks whose parity error detection 
+ * has been enabled or disabled.
+ *
+ * The client application allocates and provides the reference to the buffer.
+ *
+ * This interface can be used immediately after the interface @ref
+ * ixParityENAccParityDetectionConfigure to see on which of the hardware blocks
+ * the parity error detection has either been enabled or disabled based on the
+ * client application request.
+ *
+ * @li   Re-entrant   : No
+ * @li   ISR Callable : No
+ *
+ * @return @li IX_PARITYENACC_SUCCESS - The parameters check passed and the 
+ *             request to query on whether the hardware parity error detection
+ *             is enabled or disabled is successful.
+ *         @li IX_PARITYENACC_INVALID_PARAMETERS-The request failed due to  
+ *             NULL parameter or invalid values supplied.
+ *         @li IX_PARITYENACC_NOT_INITIALISED - The operation requested prior 
+ *             to the initialisation of the access layer.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccParityDetectionQuery(
+           IxParityENAccHWParityConfig * const hwParityConfig);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccParityErrorContextGet( 
+           IxParityENAccParityErrorContextMessage * const pecMessage)
+ *
+ * @brief This interface allows the client application to determine the 
+ * status of the parity error context on hardware block for which the
+ * current parity error interrupt triggered.
+ *
+ * @param pecMessage [out] - The parity error context information of the
+ * parity interrupt currently being process.
+ *
+ * The client application allocates and provides the reference to the buffer.
+ *
+ * Refer to the data structure @ref IxParityENAccParityErrorContextMessage
+ * for details.
+ *
+ * The routine will will fetch the parity error context in the following
+ * priority, if multiple parity errors observed.
+ * 
+ * <pre>
+ * 0 - MCU (Multi-bit and single-bit in that order)
+ * 1 - NPE-A
+ * 2 - NPE-B
+ * 3 - NPE-C
+ * 4 - SWCP
+ * 5 - QM
+ * 6 - EXP
+ *
+ * NOTE: The information provided in the @ref IxParityENAccAHBErrorTransaction
+ * may be of help for the client application to decide on the course of action 
+ * to take. This info is taken from the Performance Monitoring Unit register
+ * which records most recent error observed on the AHB bus. This information
+ * might have been overwritten by some other error by the time it is retrieved.
+ * </pre>
+ *
+ * @li   Re-entrant   : No
+ * @li   ISR Callable : Yes
+ *
+ * @return @li IX_PARITYENACC_SUCCESS-The parameters check passed and the 
+ *             request to get the parity error context information is successful.
+ *         @li IX_PARITYENACC_INVALID_PARAMETERS-The request failed due to  
+ *             NULL parameter is passed
+ *         @li IX_PARITYENACC_OPERATION_FAILED - The request failed because 
+ *             the operation didn't succeed on the hardware.
+ *         @li IX_PARITYENACC_NOT_INITIALISED - The operation requested prior
+ *             to the initialisation of the access layer.
+ *         @li IX_PARITYENACC_NO_PARITY - No parity condition exits or has 
+ *             already been cleared
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccParityErrorContextGet( 
+           IxParityENAccParityErrorContextMessage * const pecMessage);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccParityErrorInterruptClear (
+          const IxParityENAccParityErrorContextMessage *pecMessage)
+ *
+ * @brief This interface helps the client application to clear off the
+ * interrupt condition on the hardware block identified in the parity
+ * error context message.  Please refer to the table below as the operation
+ * varies depending on the interrupt source.
+ * 
+ * @param pecMessage [in] - The parity error context information of the
+ * hardware block whose parity error interrupt condition is to disabled.
+ *
+ * The client application allocates and provides the reference to the buffer.
+ *
+ * <pre>
+ * ****************************************************************************
+ * Following actions will be taken during the interrupt clear for respective
+ * hardware blocks.
+ * 
+ *  Parity Source     Actions taken during Interrupt clear 
+ *  -------------     -------------------------------------------------------
+ *  NPE-A             Interrupt will be masked off at the interrupt controller 
+ *                    so that it will not trigger continuously.
+ *                      Client application has to take appropriate action and 
+ *                      re-configure the parity error detection subsequently. 
+ *                      The client application will not be notified of further 
+ *                      interrupts, until the re-configuration is done using
+ *                      @ref ixParityENAccParityDetectionConfigure.
+ *
+ *  NPE-B             Interrupt will be masked off at the interrupt controller 
+ *                    so that it will not trigger continuously.
+ *                      Client application has to take appropriate action and 
+ *                      re-configure the parity error detection subsequently. 
+ *                      The client application will not be notified of further
+ *                      interrupts, until the re-configuration is done using
+ *                      @ref ixParityENAccParityDetectionConfigure.
+ *
+ *  NPE-C             Interrupt will be masked off at the interrupt controller 
+ *                      Client application has to take appropriate action and 
+ *                      re-configure the parity error detection subsequently. 
+ *                      The client application will not be notified of further
+ *                      interrupts, until the re-configuration is done using
+ *                      @ref ixParityENAccParityDetectionConfigure.
+ *
+ *  SWCP              Interrupt will be masked off at the interrupt controller.
+ *                      Client application has to take appropriate action and 
+ *                      re-configure the parity error detection subsequently. 
+ *                      The client application will not be notified of further
+ *                      interrupts, until the re-configuration is done using
+ *                      @ref ixParityENAccParityDetectionConfigure.
+ *
+ *  AQM               Interrupt will be masked off at the interrupt controller.
+ *                         Client application has to take appropriate action and 
+ *                         re-configure the parity error detection subsequently. 
+ *                         The client application will not be notified of further
+ *                         interrupts, until the re-configuration is done using
+ *                         @ref ixParityENAccParityDetectionConfigure.
+ *
+ *  MCU               Parity interrupt condition is cleared at the SDRAM MCU for 
+ *                    the following:
+ *                    1. Single-bit
+ *                    2. Multi-bit
+ *                    3. Overflow condition i.e., more than two parity conditions 
+ *                       occurred
+ *                    Note that single-parity errors do not result in data abort
+ *                    and not all data aborts caused by multi-bit parity error.
+ *
+ *  EXP               Parity interrupt condition is cleared at the expansion bus 
+ *                    controller for the following:
+ *                    1. External master initiated Inbound write
+ *                    2. Internal master (IXP400) initiated Outbound read
+ * ****************************************************************************
+ * </pre>
+ * @li   Re-entrant   : No
+ * @li   ISR Callable : No
+ *
+ * @return @li IX_PARITYENACC_SUCCESS-The parameters check passed and the request
+ *             to clear the parity error interrupt condition is successful.
+ *         @li IX_PARITYENACC_INVALID_PARAMETERS-The request failed due to 
+ *             NULL parameters have been passed or contents have been
+ *             supplied with invalid values.
+ *         @li IX_PARITYENACC_OPERATION_FAILED - The request failed because 
+ *             the operation didn't succeed on the hardware.
+ *         @li IX_PARITYENACC_NOT_INITIALISED - The operation requested prior
+ *             to the initialisation of the access layer.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccParityErrorInterruptClear (
+          const IxParityENAccParityErrorContextMessage *pecMessage);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccStatsGet (
+            IxParityENAccParityErrorStats * const ixParityErrorStats)
+ *
+ * @brief This interface allows the client application to retrieve parity 
+ * error statistics for all the hardware blocks 
+ *
+ * @param ixParityErrorStats - [out] The statistics for all the hardware blocks.
+ *
+ * The client application allocates and provides the reference to the buffer.
+ *
+ * @li   Re-entrant   : No
+ * @li   ISR Callable : Yes
+ *
+ * @return @li IX_PARITYENACC_SUCCESS-The parameters check passed and the 
+ *             request to retrieve parity error statistics for the hardware
+ *             block is successful.
+ *         @li IX_PARITYENACC_INVALID_PARAMETERS-The request failed due to a
+ *             NULL parameter passed.
+ *         @li IX_PARITYENACC_NOT_INITIALISED - The operation requested prior
+ *             to the initialisation of the access layer.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccStatsGet (
+            IxParityENAccParityErrorStats * const ixParityErrorStats);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccStatsShow (void)
+ *
+ * @brief This interface allows the client application to print all the
+ * parity error statistics.
+ *
+ * @li   Re-entrant   : No
+ * @li   ISR Callable : No
+ *
+ * @return @li IX_PARITYENACC_SUCCESS - The request to show the pairty 
+ *             error statistics is successful.
+ *         @li IX_PARITYENACC_NOT_INITIALISED - The operation requested
+ *             prior to the initialisation of the access layer.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccStatsShow (void);
+
+/**
+ * @ingroup IxParityENAcc
+ *
+ * @fn IxParityENAccStatus ixParityENAccStatsReset (void)
+ *
+ * @brief This interface allows the client application to reset all the 
+ * parity error statistics.
+ *
+ * @li   Re-entrant   : No
+ * @li   ISR Callable : No
+ *
+ * @return @li IX_PARITYENACC_SUCCESS - The request to reset the parity 
+ *             error statistics is successful.
+ *         @li IX_PARITYENACC_NOT_INITIALISED - The operation requested 
+ *             prior to the initialisation of the access layer.
+ */
+
+PUBLIC IxParityENAccStatus ixParityENAccStatsReset (void);
+
+#endif /* IXPARITYENACC_H */
+#endif /* __ixp46X */
+
+/**
+ * @} defgroup IxParityENAcc
+ */
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxPerfProfAcc.h b/marvell/uboot/drivers/net/npe/include/IxPerfProfAcc.h
new file mode 100644
index 0000000..2781ec8
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxPerfProfAcc.h
@@ -0,0 +1,1334 @@
+/**
+ * @file IxPerfProfAcc.h
+ *
+ * @brief  Header file for the IXP400 Perf Prof component (IxPerfProfAcc)
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxPerfProfAcc IXP400 Performance Profiling (IxPerfProfAcc) API 
+ *
+ * @brief IXP400 Performance Profiling Utility component Public API. 
+ * @li NOTE: Xcycle measurement is not supported in Linux.
+ *
+ *
+ * @{
+ */
+#ifndef IXPERFPROFACC_H
+#define IXPERFPROFACC_H
+
+#include "IxOsal.h"
+
+#ifdef __linux
+#include <linux/proc_fs.h>
+#endif
+
+/*
+ * Section for #define
+ */
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @def IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES
+ *
+ * @brief This is the maximum number of profiling samples allowed, which can be
+ * modified according to the user's discretion
+ */
+#define IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES	0xFFFF
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @def IX_PERFPROF_ACC_BUS_PMU_MAX_PECS      
+ *
+ * @brief This is the maximum number of Programmable Event Counters available. 
+ *        This is a hardware specific and fixed value. Do not change.
+ *        
+ */
+#define IX_PERFPROF_ACC_BUS_PMU_MAX_PECS        7
+
+/**  
+ * @ingroup IxPerfProfAcc
+ *
+ * @def IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS
+ *
+ * @brief Max number of measurement allowed. This constant is used when 
+ *        creating storage array for Xcycle. When run in continuous mode,  
+ *        Xcycle will wrap around and re-use buffer. 
+ */
+#define IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS 600
+
+#ifdef __linux
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @def IX_PERFPROF_ACC_XSCALE_PMU_SYMBOL_ACCURACY
+ *
+ * @brief Level of accuracy required for matching the PC Address to
+ *        symbol address. This is used when the XScale PMU time/event
+ *        sampling functions get the PC address and search for the 
+ *        corresponding symbol address.
+ */
+#define IX_PERFPROF_ACC_XSCALE_PMU_SYMBOL_ACCURACY 0xffff
+
+#endif /*__linux*/
+
+/**  
+ * @ingroup IxPerfProfAcc
+ *
+ * @def IX_PERFPROF_ACC_LOG
+ *
+ * @brief Mechanism for logging a formatted message for the PerfProfAcc component
+ *
+ * @param level UINT32 [in] - trace level
+ * @param device UINT32 [in] - output device
+ * @param str char* [in] - format string, similar to printf().
+ * @param a UINT32 [in] - first argument to display
+ * @param b UINT32 [in] - second argument to display
+ * @param c UINT32 [in] - third argument to display
+ * @param d UINT32 [in] - fourth argument to display
+ * @param e UINT32 [in] - fifth argument to display
+ * @param f UINT32 [in] - sixth argument to display
+ *
+ * @return none
+ */
+#ifndef NDEBUG
+#define IX_PERFPROF_ACC_LOG(level, device, str, a, b, c, d, e, f)\
+             (ixOsalLog (level, device, str, a, b, c, d, e, f))
+#else /*do nothing*/
+#define IX_PERFPROF_ACC_LOG(level, device, str, a, b, c, d, e, f) 
+#endif /*ifdef NDEBUG */
+
+/*
+ * Section for struct
+ */
+
+/**
+ * @brief contains summary of samples taken 
+ * 
+ * Structure contains all details of each program counter value - frequency 
+ * that PC occurs 
+ */
+typedef struct
+{
+	UINT32 programCounter;  /**<the program counter value of the sample*/
+	UINT32 freq;		/**<the frequency of the occurence of the sample*/
+} IxPerfProfAccXscalePmuSamplePcProfile;
+
+/**
+ * @brief contains results of a counter
+ *
+ * Structure contains the results of a counter, which are split into the lower 
+ * and upper 32 bits of the final count
+ */
+typedef struct
+{
+    UINT32 lower32BitsEventCount; /**<lower 32bits value of the event counter*/        
+    UINT32 upper32BitsEventCount; /**<upper 32bits value of the event counter*/
+}   IxPerfProfAccXscalePmuEvtCnt;
+
+/**
+ * @brief contains results of counters and their overflow 
+ * 
+ * Structure contains all values of counters and associated overflows.  The 
+ * specific event and clock counters are determined by the user
+ */
+typedef struct
+{
+    UINT32 clk_value;           /**<current value of clock counter*/                 
+    UINT32 clk_samples;        /**<number of clock counter overflows*/
+    UINT32 event1_value;        /**<current value of event 1 counter*/    
+    UINT32 event1_samples;     /**<number of event 1 counter overflows*/
+    UINT32 event2_value;        /**<current value of event 2 counter*/
+    UINT32 event2_samples;     /**<number of event 2 counter overflows*/
+    UINT32 event3_value;        /**<current value of event 3 counter*/
+    UINT32 event3_samples;     /**<number of event 3 counter overflows*/
+    UINT32 event4_value;        /**<current value of event 4 counter*/
+    UINT32 event4_samples;     /**<number of event 4 counter overflows*/
+} IxPerfProfAccXscalePmuResults;
+
+/** 
+ * 
+ * @brief Results obtained from Xcycle run 
+ */ 
+typedef struct 
+{
+    float maxIdlePercentage; 		/**<maximum percentage of Idle cycles*/
+    float minIdlePercentage; 		/**<minimum percentage of Idle cycles*/
+    float aveIdlePercentage;		/**<average percentage of Idle cycles*/
+    UINT32 totalMeasurements;		/**<total number of measurement made */
+} IxPerfProfAccXcycleResults; 
+
+/**
+ *
+ * @brief Results obtained from running the Bus Pmu component. The results
+ *        are obtained when the get functions is called.
+ *        
+ */
+typedef struct
+{
+    UINT32 statsToGetLower27Bit[IX_PERFPROF_ACC_BUS_PMU_MAX_PECS]; /**<Lower 27 Bit of counter value */
+    UINT32 statsToGetUpper32Bit[IX_PERFPROF_ACC_BUS_PMU_MAX_PECS]; /**<Upper 32 Bit of counter value */
+} IxPerfProfAccBusPmuResults;
+
+/*
+ * Section for enum
+ */
+
+/**
+ * @ingroup IxPerfProfAcc
+ * 
+ * @enum IxPerfProfAccBusPmuEventCounters1
+ *
+ * @brief Type of bus pmu events supported on PEC 1.
+ *
+ * Lists all bus pmu events.  
+ */
+typedef enum
+{
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_NORTH_NPEA_GRANT_SELECT = 1, /**< Select North NPEA grant on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_NORTH_NPEB_GRANT_SELECT, /**< Select North NPEB grant on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_NORTH_NPEC_GRANT_SELECT, /**< Select North NPEC grant on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_NORTH_BUS_IDLE_SELECT, /**< Select North bus idle on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_NORTH_NPEA_REQ_SELECT, /**< Select North NPEA req on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_NORTH_NPEB_REQ_SELECT, /**< Select North NPEB req on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_NORTH_NPEC_REQ_SELECT, /**< Select North NPEC req on PEC1*/
+
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_GSKT_GRANT_SELECT, /**< Select south gasket grant on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_ABB_GRANT_SELECT, /**< Select south abb grant on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_PCI_GRANT_SELECT, /**< Select south pci grant on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_APB_GRANT_SELECT, /**< Select south apb grant on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_GSKT_REQ_SELECT, /**< Select south gasket request on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_ABB_REQ_SELECT, /**< Select south abb request on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_PCI_REQ_SELECT, /**< Select south pci request on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SOUTH_APB_REQ_SELECT, /**< Select south apb request on PEC1*/
+
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_0_HIT_SELECT, /**< Select sdram0 hit on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_1_HIT_SELECT, /**< Select sdram1 hit on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_2_HIT_SELECT, /**< Select sdram2 hit on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_3_HIT_SELECT, /**< Select sdram3 hit on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_4_MISS_SELECT, /**< Select sdram4 miss on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_5_MISS_SELECT, /**< Select sdram5 miss on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_6_MISS_SELECT, /**< Select sdram6 miss on PEC1*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC1_SDR_7_MISS_SELECT /**< Select sdram7 miss on PEC1*/
+} IxPerfProfAccBusPmuEventCounters1;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccBusPmuEventCounters2
+ *
+ * @brief Type of bus pmu events supported on PEC 2.
+ *
+ * Lists all bus pmu events.
+ */
+typedef enum
+{
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_NORTH_NPEA_XFER_SELECT = 24, /**< Select North NPEA transfer on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_NORTH_NPEB_XFER_SELECT, /**< Select North NPEB transfer on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_NORTH_NPEC_XFER_SELECT, /**< Select North NPEC transfer on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_NORTH_BUS_WRITE_SELECT, /**< Select North bus write on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_NORTH_NPEA_OWN_SELECT, /**< Select North NPEA own on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_NORTH_NPEB_OWN_SELECT, /**< Select North NPEB own on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_NORTH_NPEC_OWN_SELECT, /**< Select North NPEC own on PEC2*/
+
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_GSKT_XFER_SELECT, /**< Select South gasket transfer on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_ABB_XFER_SELECT, /**< Select South abb transfer on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_PCI_XFER_SELECT, /**< Select South pci transfer on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_APB_XFER_SELECT, /**< Select South apb transfer on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_GSKT_OWN_SELECT, /**< Select South gasket own on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_ABB_OWN_SELECT, /**< Select South abb own on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_PCI_OWN_SELECT, /**< Select South pci own on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SOUTH_APB_OWN_SELECT, /**< Select South apb own transfer on PEC2*/
+
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_1_HIT_SELECT, /**< Select sdram1 hit on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_2_HIT_SELECT, /**< Select sdram2 hit on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_3_HIT_SELECT, /**< Select sdram3 hit on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_4_HIT_SELECT, /**< Select sdram4 hit on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_5_MISS_SELECT, /**< Select sdram5 miss on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_6_MISS_SELECT, /**< Select sdram6 miss on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_7_MISS_SELECT, /**< Select sdram7 miss on PEC2*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC2_SDR_0_MISS_SELECT /**< Select sdram0 miss on PEC2*/
+} IxPerfProfAccBusPmuEventCounters2;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccBusPmuEventCounters3
+ *
+ * @brief Type of bus pmu events supported on PEC 3.
+ *
+ * Lists all bus pmu events.
+ */
+typedef enum
+{
+	IX_PERFPROF_ACC_BUS_PMU_PEC3_NORTH_NPEA_RETRY_SELECT = 47, /**< Select north NPEA retry on PEC3*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC3_NORTH_NPEB_RETRY_SELECT, /**< Select north NPEB retry on PEC3*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC3_NORTH_NPEC_RETRY_SELECT, /**< Select north NPEC retry on PEC3*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC3_NORTH_BUS_READ_SELECT, /**< Select north bus read on PEC3*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC3_NORTH_NPEA_WRITE_SELECT, /**< Select north NPEA write on PEC3*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC3_NORTH_NPEB_WRITE_SELECT, /**< Select north NPEB write on PEC3*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC3_NORTH_NPEC_WRITE_SELECT, /**< Select north NPEC wirte on PEC3*/
+
+	IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_GSKT_RETRY_SELECT, /**< Select south gasket retry on PEC3*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_ABB_RETRY_SELECT, /**< Select south abb retry on PEC3*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_PCI_RETRY_SELECT, /**< Select south pci retry on PEC3*/
+	IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_APB_RETRY_SELECT, /**< Select south apb retry on PEC3*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_GSKT_WRITE_SELECT, /**< Select south gasket write on PEC3*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_ABB_WRITE_SELECT, /**< Select south abb write on PEC3*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_PCI_WRITE_SELECT, /**< Select south pci write on PEC3*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC3_SOUTH_APB_WRITE_SELECT, /**< Select south apb write on PEC3*/
+
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_2_HIT_SELECT, /**< Select sdram2 hit on PEC3*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_3_HIT_SELECT, /**< Select sdram3 hit on PEC3*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_4_HIT_SELECT, /**< Select sdram4 hit on PEC3*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_5_HIT_SELECT, /**< Select sdram5 hit on PEC3*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_6_MISS_SELECT, /**< Select sdram6 miss on PEC3*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_7_MISS_SELECT, /**< Select sdram7 miss on PEC3*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_0_MISS_SELECT, /**< Select sdram0 miss on PEC3*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC3_SDR_1_MISS_SELECT /**< Select sdram1 miss on PEC3*/
+} IxPerfProfAccBusPmuEventCounters3;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccBusPmuEventCounters4
+ *
+ * @brief Type of bus pmu events supported on PEC 4.
+ *
+ * Lists all bus pmu events.
+ */
+typedef enum
+{
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_PCI_SPLIT_SELECT = 70, /**< Select south pci split on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_EXP_SPLIT_SELECT, /**< Select south expansion split on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_APB_GRANT_SELECT, /**< Select south apb grant on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_APB_XFER_SELECT, /**< Select south apb transfer on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_GSKT_READ_SELECT, /**< Select south gasket read on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_ABB_READ_SELECT, /**< Select south abb read on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_PCI_READ_SELECT, /**< Select south pci read on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SOUTH_APB_READ_SELECT, /**< Select south apb read on PEC4*/
+
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_NORTH_ABB_SPLIT_SELECT, /**< Select north abb split on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_NORTH_NPEA_REQ_SELECT, /**< Select north NPEA req on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_NORTH_NPEA_READ_SELECT, /**< Select north NPEA read on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_NORTH_NPEB_READ_SELECT, /**< Select north NPEB read on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_NORTH_NPEC_READ_SELECT, /**< Select north NPEC read on PEC4*/
+
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_3_HIT_SELECT, /**< Select sdram3 hit on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_4_HIT_SELECT, /**< Select sdram4 hit on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_5_HIT_SELECT, /**< Select sdram5 hit on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_6_HIT_SELECT, /**< Select sdram6 hit on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_7_MISS_SELECT, /**< Select sdram7 miss on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_0_MISS_SELECT, /**< Select sdram0 miss on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_1_MISS_SELECT, /**< Select sdram1 miss on PEC4*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC4_SDR_2_MISS_SELECT /**< Select sdram2 miss on PEC4*/
+} IxPerfProfAccBusPmuEventCounters4;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccBusPmuEventCounters5
+ *
+ * @brief Type of bus pmu events supported on PEC 5.
+ *
+ * Lists all bus pmu events.
+ */
+typedef enum
+{
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SOUTH_ABB_GRANT_SELECT = 91, /**< Select south abb grant on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SOUTH_ABB_XFER_SELECT, /**< Select south abb transfer on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SOUTH_ABB_RETRY_SELECT, /**< Select south abb retry on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SOUTH_EXP_SPLIT_SELECT, /**< Select south expansion split on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SOUTH_ABB_REQ_SELECT, /**< Select south abb request on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SOUTH_ABB_OWN_SELECT, /**< Select south abb own on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SOUTH_BUS_IDLE_SELECT, /**< Select south bus idle on PEC5*/
+
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_NORTH_NPEB_GRANT_SELECT, /**< Select north NPEB grant on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_NORTH_NPEB_XFER_SELECT, /**< Select north NPEB transfer on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_NORTH_NPEB_RETRY_SELECT, /**< Select north NPEB retry on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_NORTH_NPEB_REQ_SELECT, /**< Select north NPEB request on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_NORTH_NPEB_OWN_SELECT, /**< Select north NPEB own on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_NORTH_NPEB_WRITE_SELECT, /**< Select north NPEB write on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_NORTH_NPEB_READ_SELECT, /**< Select north NPEB read on PEC5*/
+
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_4_HIT_SELECT, /**< Select north sdram4 hit on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_5_HIT_SELECT, /**< Select north sdram5 hit on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_6_HIT_SELECT, /**< Select north sdram6 hit on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_7_HIT_SELECT, /**< Select north sdram7 hit on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_0_MISS_SELECT, /**< Select north sdram0 miss on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_1_MISS_SELECT, /**< Select north sdram1 miss on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_2_MISS_SELECT, /**< Select north sdram2 miss on PEC5*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC5_SDR_3_MISS_SELECT /**< Select north sdram3 miss on PEC5*/
+} IxPerfProfAccBusPmuEventCounters5;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccBusPmuEventCounters6
+ *
+ * @brief Type of bus pmu events supported on PEC 6.
+ *
+ * Lists all bus pmu events.
+ */
+typedef enum
+{
+	IX_PERFPROF_ACC_BUS_PMU_PEC6_SOUTH_PCI_GRANT_SELECT = 113, /**< Select south pci grant on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_SOUTH_PCI_XFER_SELECT, /**< Select south pci transfer on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_SOUTH_PCI_RETRY_SELECT, /**< Select south pci retry on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_SOUTH_PCI_SPLIT_SELECT, /**< Select south pci split on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_SOUTH_PCI_REQ_SELECT, /**< Select south pci request on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_SOUTH_PCI_OWN_SELECT, /**< Select south pci own on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_SOUTH_BUS_WRITE_SELECT, /**< Select south pci write on PEC6*/
+
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_NORTH_NPEC_GRANT_SELECT, /**< Select north NPEC grant on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_NORTH_NPEC_XFER_SELECT, /**< Select north NPEC transfer on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_NORTH_NPEC_RETRY_SELECT, /**< Select north NPEC retry on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_NORTH_NPEC_REQ_SELECT, /**< Select north NPEC request on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_NORTH_NPEC_OWN_SELECT, /**< Select north NPEC own on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_NORTH_NPEB_WRITE_SELECT, /**< Select north NPEB write on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_NORTH_NPEC_READ_SELECT, /**< Select north NPEC read on PEC6*/
+
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_5_HIT_SELECT, /**< Select sdram5 hit on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_6_HIT_SELECT, /**< Select sdram6 hit on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_7_HIT_SELECT, /**< Select sdram7 hit on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_0_HIT_SELECT, /**< Select sdram0 hit on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_1_MISS_SELECT, /**< Select sdram1 miss on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_2_MISS_SELECT, /**< Select sdram2 miss on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_3_MISS_SELECT, /**< Select sdram3 miss on PEC6*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC6_SDR_4_MISS_SELECT /**< Select sdram4 miss on PEC6*/
+} IxPerfProfAccBusPmuEventCounters6;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccBusPmuEventCounters7
+ *
+ * @brief Type of bus pmu events supported on PEC 7.
+ *
+ * Lists all bus pmu events.
+ */
+typedef enum
+{
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC7_SOUTH_APB_RETRY_SELECT = 135, /**< Select south apb retry on PEC7*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC7_SOUTH_APB_REQ_SELECT, /**< Select south apb request on PEC7*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC7_SOUTH_APB_OWN_SELECT, /**< Select south apb own on PEC7*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC7_SOUTH_BUS_READ_SELECT, /**< Select south bus read on PEC7*/
+ 	IX_PERFPROF_ACC_BUS_PMU_PEC7_CYCLE_COUNT_SELECT /**< Select cycle count on PEC7*/
+} IxPerfProfAccBusPmuEventCounters7;
+
+/** 
+ * @ingroup IxPerfProfAcc 
+ * 
+ * @enum IxPerfProfAccXscalePmuEvent 
+ * 
+ * @brief Type of xscale pmu events supported 
+ * 
+ * Lists all xscale pmu events.  The maximum is a default value that the user 
+ * should not exceed. 
+ */ 
+typedef enum 
+{
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_CACHE_MISS=0,      /**< cache miss*/ 
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_CACHE_INSTRUCTION,/**< cache instruction*/ 
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_STALL,     /**< event stall*/ 
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_INST_TLB_MISS, /**< instruction tlb miss*/ 
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_DATA_TLB_MISS, /**< data tlb miss*/ 
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_BRANCH_EXEC,   /**< branch executed*/ 
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_BRANCH_MISPREDICT, /**<branch mispredict*/ 
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_INST_EXEC, /**< instruction executed*/ 
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_FULL_EVERYCYCLE,   /**< 
+                                                         *Stall - data cache 
+                                                         *buffers are full. 
+							 							 *This event occurs 
+							 							 *every cycle where 
+							 							 *condition present 
+							 							 */ 
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_ONCE,    /**< 
+                                               *Stall - data cache buffers are 
+					       					   *full.This event occurs once 
+					       					   *for each contiguous sequence 
+					       					   */ 
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_DATA_CACHE_ACCESS, /**< data cache access*/ 
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_DATA_CACHE_MISS,   /**< data cache miss*/ 
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_DATA_CACHE_WRITEBACK,  /**<data cache 
+                                                             *writeback 
+						             						 */ 
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_SW_CHANGE_PC,  /**< sw change pc*/ 
+    IX_PERFPROF_ACC_XSCALE_PMU_EVENT_MAX    /**< max value*/ 
+} IxPerfProfAccXscalePmuEvent;
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @enum IxPerfProfAccStatus
+ *
+ * @brief Invalid Status Definitions  
+ *
+ * These status will be used by the APIs to return to the user.
+ */
+typedef enum
+{
+	IX_PERFPROF_ACC_STATUS_SUCCESS = IX_SUCCESS,    /**< success*/
+	IX_PERFPROF_ACC_STATUS_FAIL = IX_FAIL,          /**< fail*/
+	IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS,/**<another utility in 
+													 *progress
+													 */ 
+	IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_IN_PROGRESS, /**<measurement in
+															*progress
+															*/
+	IX_PERFPROF_ACC_STATUS_XCYCLE_NO_BASELINE, /**<no baseline yet*/	 
+	IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_REQUEST_OUT_OF_RANGE, /**< 
+															* Measurement chosen 
+															* is out of range
+															*/
+	IX_PERFPROF_ACC_STATUS_XCYCLE_PRIORITY_SET_FAIL,  /**<
+	                                                     * Cannot set 
+														 * task priority
+	                                                     */
+	IX_PERFPROF_ACC_STATUS_XCYCLE_THREAD_CREATE_FAIL, /**< 
+	                                                     * Fail create thread
+	                                                     */
+	IX_PERFPROF_ACC_STATUS_XCYCLE_PRIORITY_RESTORE_FAIL,  /**<
+	                                                         *cannot restore
+	                                                         *priority
+	                                                         */
+	IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_NOT_RUNNING, /**< xcycle not running*/
+   	IX_PERFPROF_ACC_STATUS_XSCALE_PMU_NUM_INVALID, /**< invalid number 
+   	                                                *entered
+   	                                                */
+	IX_PERFPROF_ACC_STATUS_XSCALE_PMU_EVENT_INVALID, /**< invalid pmu event*/
+	IX_PERFPROF_ACC_STATUS_XSCALE_PMU_START_NOT_CALLED, /**<a start process
+							     						 *was not called 
+							     						 *before attempting
+							     						 *a stop or results
+							     						 *get
+							     						 */
+	IX_PERFPROF_ACC_STATUS_BUS_PMU_MODE_ERROR,  /**< invalid mode*/
+	IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC1_ERROR,	/**< invalid pec1 entered*/
+	IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC2_ERROR,	/**< invalid pec2 entered*/
+	IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC3_ERROR,	/**< invalid pec3 entered*/
+	IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC4_ERROR,	/**< invalid pec4 entered*/
+	IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC5_ERROR,	/**< invalid pec5 entered*/
+	IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC6_ERROR,	/**< invalid pec6 entered*/
+	IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC7_ERROR,	/**< invalid pec7 entered*/
+	IX_PERFPROF_ACC_STATUS_BUS_PMU_START_NOT_CALLED, /**<a start process
+							     					 *was not called 
+							     					 *before attempting
+							     					 *a stop 
+													 */
+        IX_PERFPROF_ACC_STATUS_COMPONENT_NOT_SUPPORTED /**<Device or OS does not support component*/
+} IxPerfProfAccStatus;
+
+/**
+ * @ingroup IxPerfProfAcc 
+ * 
+ * @enum IxPerfProfAccBusPmuMode
+ *
+ * @brief State selection of counters.
+ *
+ * These states will be used to determine the counters whose values are to be
+ * read.
+ */
+typedef enum
+{
+        IX_PERFPROF_ACC_BUS_PMU_MODE_HALT=0,   /**< halt state*/
+        IX_PERFPROF_ACC_BUS_PMU_MODE_SOUTH,    /**< south state*/
+        IX_PERFPROF_ACC_BUS_PMU_MODE_NORTH,    /**< north state*/
+        IX_PERFPROF_ACC_BUS_PMU_MODE_SDRAM    /**< SDRAM state*/
+} IxPerfProfAccBusPmuMode;
+
+/*
+ * Section for prototypes interface functions
+ */
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuEventCountStart(
+   		BOOL clkCntDiv,
+   		UINT32 numEvents,
+  	 	IxPerfProfAccXscalePmuEvent pmuEvent1,
+   		IxPerfProfAccXscalePmuEvent pmuEvent2,
+   		IxPerfProfAccXscalePmuEvent pmuEvent3,
+   		IxPerfProfAccXscalePmuEvent pmuEvent4 )
+ *
+ * @brief This API will start the clock and event counting
+ *
+ * @param	clkCntDiv BOOL [in] - enables/disables the clock divider. When 
+ *			true, the divider is enabled and the clock count will be incremented
+ *          by one at each 64th processor clock cycle.  When false, the divider
+ *			is disabled and the clock count will be incremented at every 
+ *			processor clock cycle.
+ * @param 	numEvents UINT32 [in] - the number of PMU events that are to be 
+ *	  		monitored as specified by the user. For clock counting only, this
+ *	  	 	is set to zero.
+ * @param 	pmuEvent1 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU 
+ *    		event to be monitored by counter 1
+ * @param 	pmuEvent2 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU 
+ *    		event to be monitored by counter 2 
+ * @param	pmuEvent3 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU 
+ *    		event to be monitored by counter 3
+ * @param 	pmuEvent4 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU 
+ *    		event to be monitored by counter 4
+ *
+ * This API will start the clock and xscale PMU event counting.  Up to 
+ * 4 events can be monitored simultaneously. This API has to be called before
+ * ixPerfProfAccXscalePmuEventCountStop can be called.
+ *
+ * @return 
+ *	- IX_PERFPROF_ACC_STATUS_SUCCESS if clock and events counting are 
+ *        started successfully
+ *	- IX_PERFPROF_ACC_STATUS_FAIL if unable to start the counting
+ *	- IX_PERFPROF_ACC_STATUS_XSCALE_PMU_NUM_INVALID if the number of events 
+ *        specified is out of the valid range
+ *	- IX_PERFPROF_ACC_STATUS_XSCALE_PMU_EVENT_INVALID if the value of the PMU 
+ * 	  event specified does not exist
+ * 	- IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS - another utility is 
+ * 	  running 
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXscalePmuEventCountStart(
+	BOOL clkCntDiv,
+	UINT32 numEvents,
+	IxPerfProfAccXscalePmuEvent pmuEvent1,
+	IxPerfProfAccXscalePmuEvent pmuEvent2,
+	IxPerfProfAccXscalePmuEvent pmuEvent3,
+	IxPerfProfAccXscalePmuEvent pmuEvent4 );
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuEventCountStop (
+   IxPerfProfAccXscalePmuResults *eventCountStopResults) 
+ *
+ * @brief This API will stop the clock and event counting
+ *
+ * @param *eventCountStopResults @ref IxPerfProfAccXscalePmuResults [out] - pointer 
+ *		  to struct containing results of counters and their overflow. It is the 
+ * 		  users's responsibility to allocate the memory for this pointer. 
+ *
+ * This API will stop the clock and xscale PMU events that are being counted.
+ * The results of the clock and events count will be stored in the pointer 
+ * allocated by the user. It can only be called once 
+ * IxPerfProfAccEventCountStart has been called. 
+ *
+ * @return 
+ *      - IX_PERFPROF_ACC_STATUS_SUCCESS if clock and events counting are 
+ *        stopped successfully
+ *      - IX_PERFPROF_ACC_STATUS_XSCALE_PMU_START_NOT_CALLED if
+ *        ixPerfProfAccXscalePmuEventCountStart is not called first.
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+
+PUBLIC IxPerfProfAccStatus 
+ixPerfProfAccXscalePmuEventCountStop(
+   IxPerfProfAccXscalePmuResults *eventCountStopResults); 
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuTimeSampStart(
+   UINT32 samplingRate,
+   BOOL clkCntDiv) 
+ *
+ * @brief Starts the time based sampling
+ *
+ * @param	samplingRate UINT32 [in] - sampling rate is the number of
+ *       	clock counts before a counter overflow interrupt is generated,
+ *        	at which, a sample is taken; the rate specified cannot be greater
+ *          than the counter size of 32bits or set to zero.
+ * @param 	clkCntDiv BOOL [in] - enables/disables the clock divider. When 
+ *		true, the divider is enabled and the clock count will be incremented
+ *          by one at each 64th processor clock cycle.  When false, the divider
+ *			is disabled and the clock count will be incremented at every 
+ *			processor clock cycle. 
+ *
+ * This API starts the time based sampling to determine the frequency with 
+ * which lines of code are being executed.  Sampling is done at the rate 
+ * specified by the user.  At each sample,the value of the program counter
+ * is determined.  Each of these occurrences are recorded to determine the 
+ * frequency with which the Xscale code is being executed. This API has to be 
+ * called before ixPerfProfAccXscalePmuTimeSampStop can be called.
+ *
+ * @return
+ *	- IX_PERFPROF_ACC_STATUS_SUCCESS if time based sampling is started 
+ *        successfully
+ *	- IX_PERFPROF_ACC_STATUS_FAIL if unable to start the sampling
+ * 	- IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS - another utility is 
+ *	  running 
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus 
+ixPerfProfAccXscalePmuTimeSampStart(
+	UINT32 samplingRate, 
+	BOOL clkCntDiv);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuTimeSampStop(
+   IxPerfProfAccXscalePmuEvtCnt *clkCount,
+   IxPerfProfAccXscalePmuSamplePcProfile *timeProfile)
+ *
+ * @brief Stops the time based sampling
+ *
+ * @param	*clkCount @ref IxPerfProfAccXscalePmuEvtCnt [out]  - pointer to the 
+ *			struct containing the final clock count and its overflow.  It is the
+ *			user's responsibility to allocate the memory for this pointer.
+ * @param 	*timeProfile @ref IxPerfProfAccXscalePmuSamplePcProfile [out] -
+ *          pointer to the array of profiles for each program counter value;
+ *          the user should set the size of the array to 
+ *			IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES.  It is the user's 
+ * 			responsibility to allocate the memory for this pointer.
+ *
+ * This API stops the time based sampling.  The results are stored in the 
+ * pointers allocated by the user.  It can only be called once
+ * ixPerfProfAccXscalePmuTimeSampStart has been called.
+ *
+ * @return
+ *	- IX_PERFPROF_ACC_STATUS_SUCCESS if time based sampling is stopped 
+ *        successfully
+ *	- IX_PERFPROF_ACC_STATUS_XSCALE_PMU_START_NOT_CALLED if
+ *	  ixPerfProfAccXscalePmuTimeSampStart not called first
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXscalePmuTimeSampStop(
+	IxPerfProfAccXscalePmuEvtCnt *clkCount,
+	IxPerfProfAccXscalePmuSamplePcProfile *timeProfile);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuEventSampStart(
+   UINT32 numEvents,
+   IxPerfProfAccXscalePmuEvent pmuEvent1,
+   UINT32 eventRate1,
+   IxPerfProfAccXscalePmuEvent pmuEvent2,
+   UINT32 eventRate2,
+   IxPerfProfAccXscalePmuEvent pmuEvent3,
+   UINT32 eventRate3,
+   IxPerfProfAccXscalePmuEvent pmuEvent4,
+   UINT32 eventRate4)
+ *
+ * @brief Starts the event based sampling
+ *
+ * @param	numEvents UINT32 [in] - the number of PMU events that are 
+ *	  		to be monitored as specified by the user. The value should be
+ *          between 1-4 events at a time.
+ * @param 	pmuEvent1 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU 
+ *    		event to be monitored by counter 1
+ * @param 	eventRate1 UINT32 [in] - sampling rate of counter 1. The rate is 
+ *			the number of events before a sample taken.  If 0 is specified, the
+ *			the full counter value (0xFFFFFFFF) is used. The rate must not be 
+ *			greater than the full counter value.
+ * @param 	pmuEvent2 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU 
+ *    		event to be monitored by counter 2 
+ * @param 	eventRate2 UINT32 [in] -  sampling rate of counter 2. The rate is 
+ *			the number of events before a sample taken. If 0 is specified, the 
+ *			full counter value (0xFFFFFFFF) is used. The rate must not be 
+ *          greater than the full counter value.
+ * @param 	pmuEvent3 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU 
+ *    		event to be monitored by counter 3
+ * @param 	eventRate3 UINT32 [in] -  sampling rate of counter 3. The rate is 
+ *			the number of events before a sample taken.  If 0 is specified, the 
+ *			full counter value (0xFFFFFFFF) is used.  The rate must not be 
+ *          greater than the full counter value.
+ * @param 	pmuEvent4 @ref IxPerfProfAccXscalePmuEvent [in] - the specific PMU 
+ *    		event to be monitored by counter 4
+ * @param 	eventRate4 UINT32 [in] -  sampling rate of counter 4. The rate is 
+ *			the number of events before a sample taken.  If 0 is specified, the 
+ *			full counter value (0xFFFFFFFF) is used. The rate must not be 
+ *          greater than the full counter value.
+ *
+ * Starts the event based sampling to determine the frequency with 
+ * which events are being executed.  The sampling rate is the number of events,
+ * as specified by the user,  before a counter overflow interrupt is 
+ * generated.  A sample is taken at each counter overflow interrupt.  At each
+ * sample,the value of the program counter determines the corresponding 
+ * location in the code.  Each of these occurrences are recorded to determine 
+ * the frequency with which the Xscale code in each event is executed. This API
+ * has to be called before ixPerfProfAccXscalePmuEventSampStop can be called.
+ *
+ * @return
+ *	- IX_PERFPROF_ACC_STATUS_SUCCESS if event based sampling is started 
+ *	  successfully
+ *	- IX_PERFPROF_ACC_STATUS_FAIL if unable to start the sampling
+ *	- IX_PERFPROF_ACC_STATUS_XSCALE_PMU_NUM_INVALID if the number of events 
+ *        specified is out of the valid range
+ *	- IX_PERFPROF_ACC_STATUS_XSCALE_PMU_EVENT_INVALID if the value of the
+ *        PMU event specified does not exist
+ *      - IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS - another utility is
+ *        running 
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXscalePmuEventSampStart(
+	UINT32 numEvents,
+	IxPerfProfAccXscalePmuEvent pmuEvent1,
+	UINT32 eventRate1,
+    IxPerfProfAccXscalePmuEvent pmuEvent2,
+    UINT32 eventRate2,
+    IxPerfProfAccXscalePmuEvent pmuEvent3,
+    UINT32 eventRate3,
+    IxPerfProfAccXscalePmuEvent pmuEvent4,
+    UINT32 eventRate4);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuEventSampStop(
+   IxPerfProfAccXscalePmuSamplePcProfile *eventProfile1,
+   IxPerfProfAccXscalePmuSamplePcProfile *eventProfile2,
+   IxPerfProfAccXscalePmuSamplePcProfile *eventProfile3,
+   IxPerfProfAccXscalePmuSamplePcProfile *eventProfile4)
+ *
+ * @brief Stops the event based sampling
+ *
+ * @param       *eventProfile1 @ref IxPerfProfAccXscalePmuSamplePcProfile [out] - 
+ *              pointer to the array of profiles for each program counter value;
+ *              the user should set the size of the array to 
+ *				IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES. It is the 
+ *				users's responsibility to allocate memory for this pointer.
+ * @param       *eventProfile2 @ref IxPerfProfAccXscalePmuSamplePcProfile [out] - 
+ *              pointer to the array of profiles for each program counter value;
+ *              the user should set the size of the array to 
+ *				IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES.  It is the 
+ *				users's responsibility to allocate memory for this pointer.
+ * @param       *eventProfile3 @ref IxPerfProfAccXscalePmuSamplePcProfile [out] - 
+ *              pointer to the array of profiles for each program counter value;
+ *              the user should set the size of the array to 
+ *				IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES.  It is the 
+ *				users's responsibility to allocate memory for this pointer.
+ * @param       *eventProfile4 @ref IxPerfProfAccXscalePmuSamplePcProfile [out] - 
+ *              pointer to the array of profiles for each program counter value;
+ *              the user should set the size of the array to 
+ *				IX_PERFPROF_ACC_XSCALE_PMU_MAX_PROFILE_SAMPLES.  It is the 
+ *				users's responsibility to allocate memory for this pointer.
+ *
+ * This API stops the event based sampling.  The results are stored in the 
+ * pointers allocated by the user.  It can only be called once 
+ * ixPerfProfAccEventSampStart has been called.
+ *
+ * @return 
+ *      - IX_PERFPROF_ACC_STATUS_SUCCESS if event based sampling is stopped 
+ *         successfully
+ *      - IX_PERFPROF_ACC_STATUS_XSCALE_PMU_START_NOT_CALLED if
+ *          ixPerfProfAccEventSampStart not called first.
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus 
+ixPerfProfAccXscalePmuEventSampStop(
+    IxPerfProfAccXscalePmuSamplePcProfile *eventProfile1,
+    IxPerfProfAccXscalePmuSamplePcProfile *eventProfile2,
+    IxPerfProfAccXscalePmuSamplePcProfile *eventProfile3,
+    IxPerfProfAccXscalePmuSamplePcProfile *eventProfile4);
+
+/**                                                                             
+ * @ingroup IxPerfProfAcc                                                      
+ *                                                                              
+ * @fn ixPerfProfAccXscalePmuResultsGet(IxPerfProfAccXscalePmuResults *results)     
+ *                                                                              
+ * @brief Reads the current value of the counters and their overflow                                        
+ *                                                                              
+ * @param *results @ref IxPerfProfAccXscalePmuResults [out] - pointer to the 
+          results struct.  It is the user's responsibility to allocate memory
+          for this pointer
+ *                                                                              
+ * This API reads the value of all four event counters and the clock counter, 
+ * and the associated overflows.  It does not give results associated with 
+ * sampling, i.e. PC and their frequencies.  This API can be called at any time
+ * once a process has been started. If it is called before a process has started
+ * the user should be aware that the values it contains are default values and 
+ * might be meaningless.  The values of the counters are stored in the pointer 
+ * allocated by the client.
+ *                                                                    
+ * @return - none
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */                                                                             
+PUBLIC void                                                     
+ixPerfProfAccXscalePmuResultsGet(IxPerfProfAccXscalePmuResults *results);    
+
+/**
+ * @ingroup IxPerfProfAcc
+ * 
+ * @fn ixPerfProfAccBusPmuStart(
+        IxPerfProfAccBusPmuMode mode, 
+        IxPerfProfAccBusPmuEventCounters1 pecEvent1,
+        IxPerfProfAccBusPmuEventCounters2 pecEvent2, 
+        IxPerfProfAccBusPmuEventCounters3 pecEvent3, 
+        IxPerfProfAccBusPmuEventCounters4 pecEvent4,
+        IxPerfProfAccBusPmuEventCounters5 pecEvent5, 
+        IxPerfProfAccBusPmuEventCounters6 pecEvent6, 
+        IxPerfProfAccBusPmuEventCounters7 pecEvent7)
+ * @brief Initializes all the counters and selects events to be monitored.
+ *
+ * Function initializes all the counters and assigns the events associated 
+ * with the counters. Users send in the mode and events they want to count.
+ * This API verifies if the combination chosen is appropriate 
+ * and sets all the registers accordingly. Selecting HALT mode will result
+ * in an error. User should use ixPerfProfAccBusPmuStop() to HALT. 
+ * 
+ * 
+ * @param mode @ref IxPerfProfAccStateBusPmuMode [in] - Mode selection.
+ * @param pecEvent1 @ref IxPerfProfAccBusPmuEventCounters1 [in] - Event for PEC1.
+ * @param pecEvent2 @ref IxPerfProfAccBusPmuEventCounters2 [in] - Event for PEC2.
+ * @param pecEvent3 @ref IxPerfProfAccBusPmuEventCounters3 [in] - Event for PEC3.
+ * @param pecEvent4 @ref IxPerfProfAccBusPmuEventCounters4 [in] - Event for PEC4.
+ * @param pecEvent5 @ref IxPerfProfAccBusPmuEventCounters5 [in] - Event for PEC5.
+ * @param pecEvent6 @ref IxPerfProfAccBusPmuEventCounters6 [in] - Event for PEC6.
+ * @param pecEvent7 @ref IxPerfProfAccBusPmuEventCounters7 [in] - Event for PEC7.
+ *
+ * @return 
+ *      - IX_PERFPROF_ACC_STATUS_SUCCESS - Initialization executed 
+ *        successfully.  
+ *      - IX_PERFPROF_ACC_STATUS_BUS_PMU_MODE_ERROR - Error in selection of 
+ * 		  mode. Only NORTH, SOUTH and SDRAM modes are allowed. 
+ *      - IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC1_ERROR - Error in selection of 
+ *        event for PEC1
+ *      - IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC2_ERROR - Error in selection of 
+ *        event for PEC2 
+ *      - IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC3_ERROR - Error in selection of 
+ *        event for PEC3
+ *      - IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC4_ERROR - Error in selection of 
+ *        event for PEC4
+ *      - IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC5_ERROR - Error in selection of 
+ *        event for PEC5
+ *      - IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC6_ERROR - Error in selection of 
+ *        event for PEC6
+ *      - IX_PERFPROF_ACC_STATUS_BUS_PMU_PEC7_ERROR - Error in selection of 
+ *        event for PEC7
+ * 		- IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS - another utility 
+ * 		  is running
+ * 		- IX_PERFPROF_ACC_STATUS_FAIL - Failed to start because interrupt 
+ * 		  service routine fails to bind.  
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ **/
+PUBLIC 
+IxPerfProfAccStatus ixPerfProfAccBusPmuStart (
+        IxPerfProfAccBusPmuMode mode, 
+        IxPerfProfAccBusPmuEventCounters1 pecEvent1,
+        IxPerfProfAccBusPmuEventCounters2 pecEvent2, 
+        IxPerfProfAccBusPmuEventCounters3 pecEvent3, 
+        IxPerfProfAccBusPmuEventCounters4 pecEvent4,
+        IxPerfProfAccBusPmuEventCounters5 pecEvent5, 
+        IxPerfProfAccBusPmuEventCounters6 pecEvent6, 
+        IxPerfProfAccBusPmuEventCounters7 pecEvent7);
+
+/**
+ * @ingroup IxPerfProfAcc
+ * 
+ * @fn ixPerfProfAccBusPmuStop(void)
+ * @brief Stops all counters. 
+ * 
+ * This function stops all the PECs by setting the halt bit in the ESR.
+ *
+ *
+ * @return 
+ *      - IX_PERFPROF_ACC_STATUS_SUCCESS - Counters successfully halted.
+ *      - IX_PERFPROF_ACC_STATUS_FAIL - Counters could'nt be halted. 
+ *		- IX_PERFPROF_ACC_STATUS_BUS_PMU_START_NOT_CALLED - the 
+ * 		  ixPerfProfAccBusPmuStart() function is not called.
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ **/
+PUBLIC IxPerfProfAccStatus 
+ixPerfProfAccBusPmuStop (void);
+
+/**
+ * @ingroup IxPerfProfAcc
+ * 
+ * @fn ixPerfProfAccBusPmuResultsGet (
+		IxPerfProfAccBusPmuResults *busPmuResults)
+ * @brief Gets values of all counters 
+ * 
+ * This function is responsible for getting all the counter values from the 
+ * lower API and putting it into an array for the user.
+ *
+ * @param *busPmuResults @ref IxPerfProfAccBusPmuResults [out]
+ *           - Pointer to a structure of arrays to store all counter values.
+ *
+ * @return  none
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ **/
+PUBLIC void
+ixPerfProfAccBusPmuResultsGet (IxPerfProfAccBusPmuResults *BusPmuResults);
+
+/**
+ * @ingroup IxPerfProfAcc
+ * 
+ * @fn ixPerfProfAccBusPmuPMSRGet (
+	UINT32 *pmsrValue)
+ * @brief Get values of PMSR  
+ *
+ * This API gets the Previous Master Slave Register
+ * value and returns it to the calling function. This value indicates
+ * which master or slave accessed the north, south bus or sdram last.
+ * The value returned by this function is a 32 bit value and is read
+ * from location of an offset 0x0024 of the base value.
+ *
+ * The PMSR value returned indicate the following:
+ * <pre>
+ *
+ * *************************************************************************************
+ * *  Bit    *  Name  *       Description                                              *
+ * *                                                                                   * 
+ * *************************************************************************************
+ * * [31:18]  *Reserved*                                                               *
+ * *************************************************************************************
+ * * [17:12] *  PSS   * Indicates which of the slaves on                               *
+ * *         *        *  ARBS was previously                                           *
+ * *         *        * accessed by the AHBS.                                          * 
+ * *         *        * [000001] Expansion Bus                                         *
+ * *         *        * [000010] SDRAM Controller                                      *
+ * *         *        * [000100] PCI                                                   *
+ * *         *        * [001000] Queue Manager                                         * 
+ * *         *        * [010000] AHB-APB Bridge                                        * 
+ * *         *        * [100000] Reserved                                              *
+ * *************************************************************************************
+ * * [11:8]  *  PSN   * Indicates which of the Slaves on                               *
+ * *         *        * ARBN was previously                                            *
+ * *         *        * accessed the AHBN.                                             *
+ * *         *        * [0001] SDRAM Controller                                        *
+ * *         *        * [0010] AHB-AHB Bridge                                          *
+ * *         *        * [0100] Reserved                                                *
+ * *         *        * [1000] Reserved                                                *
+ * *************************************************************************************
+ * *  [7:4]  *  PMS   * Indicates which of the Masters on                              *
+ * *         *        * ARBS was previously                                            *
+ * *         *        * accessing the AHBS.                                            *
+ * *         *        * [0001] Gasket                                                  *
+ * *         *        * [0010] AHB-AHB Bridge                                          *
+ * *         *        * [0100] PCI                                                     *
+ * *         *        * [1000] APB                                                     *
+ * *************************************************************************************
+ * *  [3:0]  *  PMN   * Indicates which of the Masters on                              *
+ * *         *        * ARBN was previously                                            *
+ * *         *        * accessing the AHBN.                                            *
+ * *         *        * [0001] NPEA                                                    *
+ * *         *        * [0010] NPEB                                                    *
+ * *         *        * [0100] NPEC                                                    *
+ * *         *        * [1000] Reserved                                                *
+ * *************************************************************************************
+ * </pre>
+ *
+ * @param *pmsrValue UINT32 [out] - Pointer to return PMSR value. Users need to
+ * 							  allocate storage for psmrValue.   
+ *
+ * @return none 
+ *
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ **/
+PUBLIC void
+ixPerfProfAccBusPmuPMSRGet (
+UINT32 *pmsrValue);
+
+
+/** 
+ * The APIs below are specifically used for Xcycle module. 
+ **/
+
+/**
+ * @ingroup IxPerfProfAcc
+ * 
+ * @fn ixPerfProfAccXcycleBaselineRun (
+		UINT32 *numBaselineCycle) 
+ *
+ * @brief Perform baseline for Xcycle 
+ *
+ * @param *numBaselineCycle UINT32 [out] - pointer to baseline value after
+ * 					calibration. Calling function are responsible for 
+ *					allocating memory space for this pointer. 
+ *
+ * Global Data  : 
+ *                        - None.
+ *                        
+ * This function MUST be run before the Xcycle tool can be used. This 
+ * function must be run immediately when the OS boots up with no other 
+ * addition programs running. 
+ * Addition note :     This API will measure the time needed to perform
+ * a fix amount of CPU instructions (~ 1 second worth of loops) as a 
+ * highest priority task and with interrupt disabled. The time measured
+ * is known as the baseline - interpreted as the shortest time 
+ * needed to complete the amount of CPU instructions. The baseline is 
+ * returned as unit of time in 66Mhz clock tick.  
+ *
+ * @return 
+ *      - IX_PERFPROF_ACC_STATUS_SUCCESS - successful run, result is returned
+ *      - IX_PERFPROF_ACC_STATUS_XCYCLE_PRIORITY_SET_FAIL - failed to change
+ *         task priority
+ *      - IX_PERFPROF_ACC_STATUS_XCYCLE_PRIORITY_RESTORE_FAIL - failed to
+ *         restore task priority
+ *      - IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS - another utility 
+ *         is running 
+ *      - IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_IN_PROGRESS  - Xcycle 
+ *	  tool has already started
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXcycleBaselineRun(
+	UINT32 *numBaselineCycle); 
+
+/**
+ * @ingroup IxPerfProfAcc
+ * 
+ * @fn ixPerfProfAccXcycleStart(
+		UINT32 numMeasurementsRequested);
+ *
+ * @brief Start the measurement
+ *
+ * @param  numMeasurementsRequested UINT32 [in] - number of measurements 
+ *							to perform. Value can be 0 to  
+ *							IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS. 
+ *							0 indicate continuous measurement. 
+ *
+ * Global Data  : 
+ *                        - None.
+ *                        
+ * 
+ * Start the measurements immediately. 
+ * numMeasurementsRequested specifies number of measurements to run. 
+ * If numMeasurementsRequested is set to 0, the measurement will
+ * be performed continuously until IxPerfProfAccXcycleStop()
+ * is called.  
+ * It is estimated that 1 measurement takes approximately 1 second during 
+ * low CPU utilization, therefore 128 measurement takes approximately 128 sec.
+ * When CPU utilization is high, the measurement will take longer.
+ * This function spawn a task the perform the measurement and returns. 
+ * The measurement may continue even if this function returns. 
+ *
+ * IMPORTANT: Under heavy CPU utilization, the task spawn by this 
+ * function may starve and fail to respond to stop command. User 
+ * may need to kill the task manually in this case.  
+ *
+ * There are only IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS 
+ * storage available so storing is wrapped around if measurements are  
+ * more than IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS.
+ *
+ *
+ * @return 
+ *      - IX_PERFPROF_ACC_STATUS_SUCCESS - successful start, a thread is created 
+ *	   in the background to perform measurement. 
+ *      - IX_PERFPROF_ACC_STATUS_XCYCLE_PRIORITY_SET_FAIL - failed to set
+ *         task priority
+ *      - IX_PERFPROF_ACC_STATUS_XCYCLE_THREAD_CREATE_FAIL - failed to create
+ *	   thread to perform measurement.
+ *      - IX_PERFPROF_ACC_STATUS_XCYCLE_NO_BASELINE - baseline is not available 
+ *      - IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_REQUEST_OUT_OF_RANGE -
+ *	   value is larger than IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS
+ *      - IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_IN_PROGRESS	- Xcycle tool 
+ *	   has already started
+ *      - IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS - another utility is 
+ *         running
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXcycleStart (
+	UINT32 numMeasurementsRequested);  
+
+/**
+ * @ingroup IxPerfProfAcc
+ * 
+ * @fn ixPerfProfAccXcycleStop(void); 
+ *
+ * @brief Stop the Xcycle measurement
+ *
+ * @param None
+ *
+ * Global Data  : 
+ *                        - None.
+ *                        
+ * Stop Xcycle measurements immediately. If the measurements have stopped 
+ * or not started, return IX_PERFPROF_STATUS_XCYCLE_MEASUREMENT_NOT_RUNNING. 
+ * Note: This function does not stop measurement cold. The measurement thread 
+ * may need a few seconds to complete the last measurement. User needs to use
+ * ixPerfProfAccXcycleInProgress() to determine if measurement is indeed
+ * completed. 
+ *
+ * @return 
+ *      - IX_PERFPROF_ACC_STATUS_SUCCESS - successful measurement is stopped
+ *      - IX_PERFPROF_STATUS_XCYCLE_MEASUREMENT_NOT_RUNNING - no measurement running
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXcycleStop(void); 
+
+/**
+ * @ingroup IxPerfProfAcc
+ * 
+ * @fn ixPerfProfAccXcycleResultsGet(
+	IxPerfProfAccXcycleResults *xcycleResult ) 
+ *
+ * @brief Get the results of Xcycle measurement
+ *
+ * @param *xcycleResult @ref IxPerfProfAccXcycleResults [out] - Pointer to 
+ * 				results of last measurements. Calling function are 
+ *				responsible for allocating memory space for this pointer.
+ *
+ * Global Data  : 
+ *                        - None.
+ *                        
+ * Retrieve the results of last measurement. User should use 
+ * ixPerfProfAccXcycleInProgress() to check if measurement is completed 
+ * before getting the results.
+ *
+ * @return 
+ *      - IX_PERFPROF_ACC_STATUS_SUCCESS - successful 
+ *      - IX_PERFPROF_ACC_STATUS_FAIL - result is not complete. 
+ *      - IX_PERFPROF_ACC_STATUS_XCYCLE_NO_BASELINE - baseline is performed
+ *      - IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_IN_PROGRESS  - Xcycle 
+ *         tool is still running
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC IxPerfProfAccStatus
+ixPerfProfAccXcycleResultsGet (
+    IxPerfProfAccXcycleResults *xcycleResult);  
+
+/**
+ * @ingroup IxPerfProfAcc
+ * 
+ * @fn ixPerfProfAccXcycleInProgress (void)
+ *
+ * @brief Check if Xcycle is running
+ *
+ * @param None
+ * Global Data  : 
+ *                        - None.
+ *                        
+ * Check if Xcycle measuring task is running. 
+ *
+ * @return 
+ *      - true - Xcycle is running
+ *      - false - Xcycle is not running
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+PUBLIC BOOL
+ixPerfProfAccXcycleInProgress(void); 
+
+#ifdef __linux
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuTimeSampCreateProcFile 
+ *
+ * @brief Enables proc file to call module function
+ *
+ * @param None
+ *
+ * Global Data  :
+ *                        - None.
+ *
+ * This function is declared globally to enable /proc directory system to call
+ * and execute the function when the registered file is called. This function is not meant to 
+ * be called by the user.
+ *
+ * @return
+ *      - Length of data written to file.
+ *
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+int
+ixPerfProfAccXscalePmuTimeSampCreateProcFile (char *buf, char **start, off_t offset,
+                                      int count, int *eof, void *data);
+
+/**
+ * @ingroup IxPerfProfAcc
+ *
+ * @fn ixPerfProfAccXscalePmuEventSampCreateProcFile 
+ *
+ * @brief Enables proc file to call module function 
+ *
+ * @param None
+ *
+ * Global Data  :
+ *                        - None.
+ *
+ * This function is declared globally to enable /proc directory system to call
+ * and execute the function when the registered file is called. This function is not meant to 
+ * be called by the user.
+ *
+ * @return
+ *      - Length of data written to file.
+ *
+ * @li   Reentrant    : no
+ * @li   ISR Callable : no
+ *
+ */
+int
+ixPerfProfAccXscalePmuEventSampCreateProcFile (char *buf, char **start, off_t offset,
+                                      int count, int *eof, void *data);
+
+
+#endif /* ifdef __linux */
+
+#endif /* ndef IXPERFPROFACC_H */
+
+/**
+ *@} defgroup IxPerfProfAcc 
+ */
+
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxQMgr.h b/marvell/uboot/drivers/net/npe/include/IxQMgr.h
new file mode 100644
index 0000000..23a4541
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxQMgr.h
@@ -0,0 +1,2186 @@
+/**
+ * @file    IxQMgr.h
+ *
+ * @date    30-Oct-2001
+ *
+ * @brief This file contains the public API of IxQMgr component.
+ *
+ * Some functions contained in this module are inline to achieve better
+ * data-path performance. For this to work, the function definitions are
+ * contained in this header file. The "normal" use of inline functions
+ * is to use the inline functions in the module in which they are
+ * defined. In this case these inline functions are used in external
+ * modules and therefore the use of "inline extern". What this means
+ * is as follows: if a function foo is declared as "inline extern" this
+ * definition is only used for inlining, in no case is the function
+ * compiled on its own. If the compiler cannot inline the function it
+ * becomes an external reference. Therefore in IxQMgrQAccess.c all
+ * inline functions are defined without the "inline extern" specifier
+ * and so define the external references. In all other source files
+ * including this header file, these funtions are defined as "inline
+ * extern".
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/* ------------------------------------------------------
+   Doxygen group definitions
+   ------------------------------------------------------ */
+/**
+ * @defgroup IxQMgrAPI IXP400 Queue Manager (IxQMgr) API
+ *
+ * @brief The public API for the IXP400 QMgr component.
+ *
+ * IxQMgr is a low level interface to the AHB Queue Manager
+ *
+ * @{
+ */
+
+#ifndef IXQMGR_H
+#define IXQMGR_H
+
+/*
+ * User defined include files
+ */
+
+#include "IxOsal.h"
+
+/* 
+ * Define QMgr's IoMem macros, in DC mode if in LE 
+ * regular if in BE. (Note: For Linux LSP gold release
+ * may need to adjust mode.
+ */
+#if defined (__BIG_ENDIAN)
+
+#define IX_QMGR_INLINE_READ_LONG IX_OSAL_READ_LONG_BE
+#define IX_QMGR_INLINE_WRITE_LONG IX_OSAL_WRITE_LONG_BE
+
+#else
+
+#define IX_QMGR_INLINE_READ_LONG IX_OSAL_READ_LONG_LE_DC
+#define IX_QMGR_INLINE_WRITE_LONG IX_OSAL_WRITE_LONG_LE_DC
+
+#endif
+
+/*
+ * #defines and macros
+ */
+
+/**
+*
+* @ingroup IxQMgrAPI
+*
+* @def IX_QMGR_INLINE
+*
+* @brief Inline definition, for inlining of Queue Access functions on API
+*
+* Please read the header information in this file for more details on the
+* use of function inlining in this component.
+*
+*/
+
+#ifndef __wince
+
+#ifdef IXQMGRQACCESS_C
+/* If IXQMGRQACCESS_C is set then the IxQmgrQAccess.c is including this file
+   and must instantiate a concrete definition for each inlineable API function
+   whether or not that function actually gets inlined. */
+#    ifdef NO_INLINE_APIS
+#        undef NO_INLINE_APIS
+#    endif
+#    define IX_QMGR_INLINE  /* Empty Define */
+#else
+#    ifndef NO_INLINE_APIS
+#       define IX_QMGR_INLINE IX_OSAL_INLINE_EXTERN
+#    else
+#       define IX_QMGR_INLINE /* Empty Define */
+#    endif
+#endif
+
+#else /* ndef __wince */
+
+#    ifndef NO_INLINE_APIS
+#       define NO_INLINE_APIS
+#    endif
+#    define IX_QMGR_INLINE
+
+#endif
+
+
+/**
+*
+* @ingroup IxQMgrAPI
+*
+* @def IX_QMGR_MAX_NUM_QUEUES
+*
+* @brief Number of queues supported by the AQM.
+*
+* This constant is used to indicate the number of AQM queues
+*
+*/
+#define IX_QMGR_MAX_NUM_QUEUES  64
+
+/**
+*
+* @ingroup IxQMgrAPI
+*
+* @def IX_QMGR_MIN_QID
+*
+* @brief Minimum queue identifier.
+*
+* This constant is used to indicate the smallest queue identifier
+*
+*/
+#define IX_QMGR_MIN_QID IX_QMGR_QUEUE_0
+
+/**
+*
+* @ingroup IxQMgrAPI
+*
+* @def IX_QMGR_MAX_QID
+*
+* @brief Maximum queue identifier.
+*
+* This constant is used to indicate the largest queue identifier
+*
+*/
+#define IX_QMGR_MAX_QID IX_QMGR_QUEUE_63
+
+/**
+*
+* @ingroup IxQMgrAPI
+*
+* @def IX_QMGR_MIN_QUEUPP_QID
+*
+* @brief Minimum queue identifier for reduced functionality queues.
+*
+* This constant is used to indicate Minimum queue identifier for reduced
+* functionality queues
+*
+*/
+#define IX_QMGR_MIN_QUEUPP_QID 32
+
+/**
+*
+* @ingroup IxQMgrAPI
+*
+* @def IX_QMGR_MAX_QNAME_LEN
+*
+* @brief Maximum queue name length.
+*
+* This constant is used to indicate the maximum null terminated string length
+* (excluding '\0') for a queue name
+*
+*/
+#define IX_QMGR_MAX_QNAME_LEN 16
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_WARNING
+ *
+ * @brief Warning return code.
+ *
+ * Execution complete, but there is a special case to handle
+ *
+ */
+#define IX_QMGR_WARNING 2
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_PARAMETER_ERROR
+ *
+ * @brief Parameter error return code (NULL pointer etc..).
+ *
+ * parameter error out of range/invalid
+ *
+ */
+#define IX_QMGR_PARAMETER_ERROR 3
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_INVALID_Q_ENTRY_SIZE
+ *
+ * @brief Invalid entry size return code.
+ *
+ * Invalid queue entry size for a queue read/write
+ *
+ */
+#define IX_QMGR_INVALID_Q_ENTRY_SIZE 4
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_INVALID_Q_ID
+ *
+ * @brief Invalid queue identifier return code.
+ *
+ * Invalid queue id, not in range 0-63
+ *
+ */
+#define IX_QMGR_INVALID_Q_ID 5
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_INVALID_CB_ID
+ *
+ * @brief Invalid callback identifier return code.
+ *
+ * Invalid callback id
+ */
+#define IX_QMGR_INVALID_CB_ID 6
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_CB_ALREADY_SET
+ *
+ * @brief Callback set error return code.
+ *
+ * The specified callback has already been for this queue
+ *
+ */
+#define IX_QMGR_CB_ALREADY_SET 7
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_NO_AVAILABLE_SRAM
+ *
+ * @brief Sram consumed return code.
+ *
+ * All AQM Sram is consumed by queue configuration
+ *
+ */
+#define IX_QMGR_NO_AVAILABLE_SRAM 8
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_INVALID_INT_SOURCE_ID
+ *
+ * @brief Invalid queue interrupt source identifier return code.
+ *
+ * Invalid queue interrupt source given for notification enable
+ */
+#define IX_QMGR_INVALID_INT_SOURCE_ID 9
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_INVALID_QSIZE
+ *
+ * @brief Invalid queue size error code.
+ *
+ * Invalid queue size not one of 16,32, 64, 128
+ *
+ *
+ */
+#define IX_QMGR_INVALID_QSIZE 10
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_INVALID_Q_WM
+ *
+ * @brief Invalid queue watermark return code.
+ *
+ * Invalid queue watermark given for watermark set
+ */
+#define IX_QMGR_INVALID_Q_WM 11
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_Q_NOT_CONFIGURED
+ *
+ * @brief Queue not configured return code.
+ *
+ * Returned to the client when a function has been called on an unconfigured
+ * queue
+ *
+ */
+#define IX_QMGR_Q_NOT_CONFIGURED 12
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_Q_ALREADY_CONFIGURED
+ *
+ * @brief Queue already configured return code.
+ *
+ * Returned to client to indicate that a queue has already been configured
+ */
+#define IX_QMGR_Q_ALREADY_CONFIGURED 13
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_Q_UNDERFLOW
+ *
+ * @brief Underflow return code.
+ *
+ * Underflow on a queue read has occurred
+ *
+ */
+#define IX_QMGR_Q_UNDERFLOW 14
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_Q_OVERFLOW
+ *
+ * @brief Overflow return code.
+ *
+ * Overflow on a queue write has occurred
+ *
+ */
+#define IX_QMGR_Q_OVERFLOW 15
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_Q_INVALID_PRIORITY
+ *
+ * @brief Invalid priority return code.
+ *
+ * Invalid priority, not one of 0,1,2
+ */
+#define IX_QMGR_Q_INVALID_PRIORITY 16
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS
+ *
+ * @brief  Entry index out of bounds return code.
+ *
+ * Entry index is greater than number of entries in queue.
+ */
+#define IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS 17
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def ixQMgrDispatcherLoopRun
+ *
+ * @brief  Map old function name ixQMgrDispatcherLoopRun () 
+ *         to @ref ixQMgrDispatcherLoopRunA0 ().
+ *
+ */
+#define ixQMgrDispatcherLoopRun ixQMgrDispatcherLoopRunA0
+
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @def IX_QMGR_QUEUE
+ *
+ * @brief  Definition of AQM queue numbers
+ *
+ */
+#define IX_QMGR_QUEUE_0 (0)      /**< Queue Number 0 */
+#define IX_QMGR_QUEUE_1 (1)      /**< Queue Number 1 */
+#define IX_QMGR_QUEUE_2 (2)      /**< Queue Number 2 */
+#define IX_QMGR_QUEUE_3 (3)      /**< Queue Number 3 */
+#define IX_QMGR_QUEUE_4 (4)      /**< Queue Number 4 */
+#define IX_QMGR_QUEUE_5 (5)      /**< Queue Number 5 */
+#define IX_QMGR_QUEUE_6 (6)      /**< Queue Number 6 */
+#define IX_QMGR_QUEUE_7 (7)      /**< Queue Number 7 */
+#define IX_QMGR_QUEUE_8 (8)      /**< Queue Number 8 */
+#define IX_QMGR_QUEUE_9 (9)      /**< Queue Number 9 */
+#define IX_QMGR_QUEUE_10 (10)    /**< Queue Number 10 */
+#define IX_QMGR_QUEUE_11 (11)    /**< Queue Number 11 */
+#define IX_QMGR_QUEUE_12 (12)    /**< Queue Number 12 */
+#define IX_QMGR_QUEUE_13 (13)    /**< Queue Number 13 */
+#define IX_QMGR_QUEUE_14 (14)    /**< Queue Number 14 */
+#define IX_QMGR_QUEUE_15 (15)    /**< Queue Number 15 */
+#define IX_QMGR_QUEUE_16 (16)    /**< Queue Number 16 */
+#define IX_QMGR_QUEUE_17 (17)    /**< Queue Number 17 */
+#define IX_QMGR_QUEUE_18 (18)    /**< Queue Number 18 */
+#define IX_QMGR_QUEUE_19 (19)    /**< Queue Number 19 */
+#define IX_QMGR_QUEUE_20 (20)    /**< Queue Number 20 */
+#define IX_QMGR_QUEUE_21 (21)    /**< Queue Number 21 */
+#define IX_QMGR_QUEUE_22 (22)    /**< Queue Number 22 */
+#define IX_QMGR_QUEUE_23 (23)    /**< Queue Number 23 */
+#define IX_QMGR_QUEUE_24 (24)    /**< Queue Number 24 */
+#define IX_QMGR_QUEUE_25 (25)    /**< Queue Number 25 */
+#define IX_QMGR_QUEUE_26 (26)    /**< Queue Number 26 */
+#define IX_QMGR_QUEUE_27 (27)    /**< Queue Number 27 */
+#define IX_QMGR_QUEUE_28 (28)    /**< Queue Number 28 */
+#define IX_QMGR_QUEUE_29 (29)    /**< Queue Number 29 */
+#define IX_QMGR_QUEUE_30 (30)    /**< Queue Number 30 */
+#define IX_QMGR_QUEUE_31 (31)    /**< Queue Number 31 */
+#define IX_QMGR_QUEUE_32 (32)    /**< Queue Number 32 */
+#define IX_QMGR_QUEUE_33 (33)    /**< Queue Number 33 */
+#define IX_QMGR_QUEUE_34 (34)    /**< Queue Number 34 */
+#define IX_QMGR_QUEUE_35 (35)    /**< Queue Number 35 */
+#define IX_QMGR_QUEUE_36 (36)    /**< Queue Number 36 */
+#define IX_QMGR_QUEUE_37 (37)    /**< Queue Number 37 */
+#define IX_QMGR_QUEUE_38 (38)    /**< Queue Number 38 */
+#define IX_QMGR_QUEUE_39 (39)    /**< Queue Number 39 */
+#define IX_QMGR_QUEUE_40 (40)    /**< Queue Number 40 */
+#define IX_QMGR_QUEUE_41 (41)    /**< Queue Number 41 */
+#define IX_QMGR_QUEUE_42 (42)    /**< Queue Number 42 */
+#define IX_QMGR_QUEUE_43 (43)    /**< Queue Number 43 */
+#define IX_QMGR_QUEUE_44 (44)    /**< Queue Number 44 */
+#define IX_QMGR_QUEUE_45 (45)    /**< Queue Number 45 */
+#define IX_QMGR_QUEUE_46 (46)    /**< Queue Number 46 */
+#define IX_QMGR_QUEUE_47 (47)    /**< Queue Number 47 */
+#define IX_QMGR_QUEUE_48 (48)    /**< Queue Number 48 */
+#define IX_QMGR_QUEUE_49 (49)    /**< Queue Number 49 */
+#define IX_QMGR_QUEUE_50 (50)    /**< Queue Number 50 */
+#define IX_QMGR_QUEUE_51 (51)    /**< Queue Number 51 */
+#define IX_QMGR_QUEUE_52 (52)    /**< Queue Number 52 */
+#define IX_QMGR_QUEUE_53 (53)    /**< Queue Number 53 */
+#define IX_QMGR_QUEUE_54 (54)    /**< Queue Number 54 */
+#define IX_QMGR_QUEUE_55 (55)    /**< Queue Number 55 */
+#define IX_QMGR_QUEUE_56 (56)    /**< Queue Number 56 */
+#define IX_QMGR_QUEUE_57 (57)    /**< Queue Number 57 */
+#define IX_QMGR_QUEUE_58 (58)    /**< Queue Number 58 */
+#define IX_QMGR_QUEUE_59 (59)    /**< Queue Number 59 */
+#define IX_QMGR_QUEUE_60 (60)    /**< Queue Number 60 */
+#define IX_QMGR_QUEUE_61 (61)    /**< Queue Number 61 */
+#define IX_QMGR_QUEUE_62 (62)    /**< Queue Number 62 */
+#define IX_QMGR_QUEUE_63 (63)    /**< Queue Number 63 */
+#define IX_QMGR_QUEUE_INVALID (64)     /**< AQM Queue Number Delimiter */
+
+
+/*
+ * Typedefs
+ */
+
+/**
+ * @typedef IxQMgrQId
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @brief Used in the API to identify the AQM queues.
+ *
+ */
+typedef int IxQMgrQId;
+
+/**
+ * @typedef IxQMgrQStatus
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @brief Queue status.
+ *
+ * A queues status is defined by its relative fullness or relative emptiness.
+ * Each of the queues 0-31 have Nearly Empty, Nearly Full, Empty, Full,
+ * Underflow and Overflow status flags. Queues 32-63 have just Nearly Empty and
+ * Full status flags.
+ * The flags bit positions are outlined below:
+ *        
+ *        OF - bit-5<br> 
+ *        UF - bit-4<br> 
+ *         F - bit-3<br> 
+ *        NF - bit-2<br> 
+ *        NE - bit-1<br>
+ *         E - bit-0<br> 
+ *
+ */
+typedef UINT32 IxQMgrQStatus;
+
+/**
+ * @enum IxQMgrQStatusMask
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @brief Queue status mask.
+ *
+ * Masks for extracting the individual status flags from the IxQMgrStatus
+ * word.
+ *
+ */
+typedef enum
+{
+    IX_QMGR_Q_STATUS_E_BIT_MASK  = 0x1,
+    IX_QMGR_Q_STATUS_NE_BIT_MASK = 0x2,
+    IX_QMGR_Q_STATUS_NF_BIT_MASK = 0x4,
+    IX_QMGR_Q_STATUS_F_BIT_MASK  = 0x8,
+    IX_QMGR_Q_STATUS_UF_BIT_MASK = 0x10,
+    IX_QMGR_Q_STATUS_OF_BIT_MASK = 0x20
+} IxQMgrQStatusMask;
+
+/**
+ * @enum IxQMgrSourceId
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @brief Queue interrupt source select.
+ *
+ * This enum defines the different source conditions on a queue that result in
+ * an interrupt being fired by the AQM. Interrupt source is configurable for
+ * queues 0-31 only. The interrupt source for queues 32-63 is hardwired to the
+ * NE(Nearly Empty) status flag.
+ *
+ */
+typedef enum
+{
+    IX_QMGR_Q_SOURCE_ID_E = 0,  /**< Queue Empty due to last read             */
+    IX_QMGR_Q_SOURCE_ID_NE,     /**< Queue Nearly Empty due to last read      */
+    IX_QMGR_Q_SOURCE_ID_NF,     /**< Queue Nearly Full due to last write      */
+    IX_QMGR_Q_SOURCE_ID_F,      /**< Queue Full due to last write             */
+    IX_QMGR_Q_SOURCE_ID_NOT_E,  /**< Queue Not Empty due to last write        */
+    IX_QMGR_Q_SOURCE_ID_NOT_NE, /**< Queue Not Nearly Empty due to last write */
+    IX_QMGR_Q_SOURCE_ID_NOT_NF, /**< Queue Not Nearly Full due to last read   */
+    IX_QMGR_Q_SOURCE_ID_NOT_F   /**< Queue Not Full due to last read          */
+} IxQMgrSourceId;
+
+/**
+ * @enum IxQMgrQEntrySizeInWords
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @brief QMgr queue entry sizes.
+ *
+ * The entry size of a queue specifies the size of a queues entry in words.
+ *
+ */
+typedef enum
+{
+    IX_QMGR_Q_ENTRY_SIZE1 = 1,   /**< 1 word entry       */
+    IX_QMGR_Q_ENTRY_SIZE2 = 2,   /**< 2 word entry       */
+    IX_QMGR_Q_ENTRY_SIZE4 = 4    /**< 4 word entry       */
+} IxQMgrQEntrySizeInWords;
+
+/**
+ * @enum IxQMgrQSizeInWords
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @brief QMgr queue sizes.
+ *
+ * These values define the allowed queue sizes for AQM queue. The sizes are
+ * specified in words.
+ *
+ */
+typedef enum
+{
+    IX_QMGR_Q_SIZE16 = 16,   /**< 16 word buffer     */
+    IX_QMGR_Q_SIZE32 = 32,   /**< 32 word buffer     */
+    IX_QMGR_Q_SIZE64 = 64,   /**< 64 word buffer     */
+    IX_QMGR_Q_SIZE128 = 128, /**< 128 word buffer    */
+    IX_QMGR_Q_SIZE_INVALID = 129  /**< Insure that this is greater than largest
+				    * queue size supported by the hardware
+				    */
+} IxQMgrQSizeInWords;
+
+/**
+ * @enum IxQMgrWMLevel
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @brief QMgr watermark levels.
+ *
+ * These values define the valid watermark levels(in ENTRIES) for queues. Each
+ * queue 0-63 have configurable Nearly full and Nearly empty watermarks. For
+ * queues 32-63 the Nearly full watermark has NO EFFECT.
+ * If the Nearly full watermark is set to IX_QMGR_Q_WM_LEVEL16 this means that
+ * the nearly full flag will be set by the hardware when there are >= 16 empty
+ * entries in the specified queue.
+ * If the Nearly empty watermark is set to IX_QMGR_Q_WM_LEVEL16 this means that
+ * the Nearly empty flag will be set by the hardware when there are <= 16 full
+ * entries in the specified queue.
+ */
+typedef enum
+{
+    IX_QMGR_Q_WM_LEVEL0 = 0,    /**< 0 entry watermark  */
+    IX_QMGR_Q_WM_LEVEL1 = 1,    /**< 1 entry watermark  */
+    IX_QMGR_Q_WM_LEVEL2 = 2,    /**< 2 entry watermark  */
+    IX_QMGR_Q_WM_LEVEL4 = 4,    /**< 4 entry watermark  */
+    IX_QMGR_Q_WM_LEVEL8 = 8,    /**< 8 entry watermark  */
+    IX_QMGR_Q_WM_LEVEL16 = 16,  /**< 16 entry watermark */
+    IX_QMGR_Q_WM_LEVEL32 = 32,  /**< 32 entry watermark */
+    IX_QMGR_Q_WM_LEVEL64 = 64   /**< 64 entry watermark */
+} IxQMgrWMLevel;
+
+/**
+ * @ingroup IxQMgrAPI
+ * 
+ * @enum IxQMgrDispatchGroup
+ *
+ * @brief QMgr dispatch group select identifiers.
+ *
+ * This enum defines the groups over which the  dispatcher will process when
+ * called. One of the enum values must be used as a input to
+ * @a ixQMgrDispatcherLoopRunA0, @a ixQMgrDispatcherLoopRunB0 
+ * or @a ixQMgrDispatcherLoopRunB0LLP.
+ *
+ */
+typedef enum
+{
+    IX_QMGR_QUELOW_GROUP = 0, /**< Queues 0-31  */
+    IX_QMGR_QUEUPP_GROUP      /**< Queues 32-63 */
+} IxQMgrDispatchGroup;
+
+/**
+ * @ingroup IxQMgrAPI
+ * 
+ * @enum IxQMgrPriority
+ *
+ * @brief Dispatcher priority levels.
+ *
+ * This enum defines the different queue dispatch priority levels.
+ * The lowest priority number (0) is the highest priority level.
+ *
+ */
+typedef enum
+{
+  IX_QMGR_Q_PRIORITY_0 = 0,  /**< Priority level 0 */
+  IX_QMGR_Q_PRIORITY_1,      /**< Priority level 1 */
+  IX_QMGR_Q_PRIORITY_2,      /**< Priority level 2 */
+  IX_QMGR_Q_PRIORITY_INVALID /**< Invalid Priority level */
+} IxQMgrPriority;
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @enum IxQMgrType
+ *
+ * @brief Callback types as used with livelock prevention
+ *
+ * This enum defines the different callback types. 
+ * These types are only used when Livelock prevention is enabled.
+ * The default is IX_QMGR_TYPE_REALTIME_OTHER. 
+ *
+ */
+
+typedef enum
+{
+  IX_QMGR_TYPE_REALTIME_OTHER = 0, /**< Real time callbacks-always allowed run*/
+  IX_QMGR_TYPE_REALTIME_PERIODIC,  /**< Periodic callbacks-always allowed run */
+  IX_QMGR_TYPE_REALTIME_SPORADIC   /**< Sporadic callbacks-only run if no
+                                        periodic callbacks are in progress    */
+} IxQMgrType;
+
+
+/**
+ * @ingroup IxQMgrAPI
+ * 
+ * @typedef IxQMgrCallbackId
+ *
+ * @brief Uniquely identifies a callback function.
+ *
+ * A unique callback identifier associated with each callback
+ * registered by clients.
+ *
+ */
+typedef unsigned IxQMgrCallbackId;
+
+/**
+ * @typedef IxQMgrCallback
+ *
+ * @brief QMgr notification callback type.
+ *
+ * This defines the interface to all client callback functions.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier
+ * @param cbId @ref IxQMgrCallbackId [in] - the callback identifier
+ */
+typedef void (*IxQMgrCallback)(IxQMgrQId qId,
+                               IxQMgrCallbackId cbId);
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @typedef IxQMgrDispatcherFuncPtr
+ *
+ * @brief QMgr Dispatcher Loop function pointer.
+ *
+ * This defines the interface for QMgr Dispather functions.
+ *
+ * @param group @ref IxQMgrDispatchGroup [in] - the group of the 
+ *                  queue of which the dispatcher will run   
+ */
+typedef void (*IxQMgrDispatcherFuncPtr)(IxQMgrDispatchGroup group);
+
+/*
+ * Function Prototypes
+ */
+
+/* ------------------------------------------------------------
+   Initialisation related functions
+   ---------------------------------------------------------- */
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrInit (void)
+ *
+ * @brief Initialise the QMgr.
+ *
+ * This function must be called before and other QMgr function. It
+ * sets up internal data structures.
+ *
+ * @return @li IX_SUCCESS, the IxQMgr successfully initialised
+ * @return @li IX_FAIL, failed to initialize the Qmgr
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrInit (void);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrUnload (void)
+ *
+ * @brief Uninitialise the QMgr.
+ *
+ * This function will perform the tasks required to unload the QMgr component
+ * cleanly.  This includes unmapping kernel memory.
+ * This should be called before a soft reboot or unloading of a kernel module.
+ *
+ * @pre It should only be called if @ref ixQMgrInit has already been called.
+ *
+ * @post No QMgr functions should be called until ixQMgrInit is called again.
+ *
+ * @return @li IX_SUCCESS, the IxQMgr successfully uninitialised
+ * @return @li IX_FAIL, failed to uninitialize the Qmgr
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrUnload (void);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrShow (void)
+ *
+ * @brief Describe queue configuration and statistics for active queues.
+ *
+ * This function shows active queues, their configurations and statistics.
+ *
+ * @return @li void
+ *
+ */
+PUBLIC void
+ixQMgrShow (void);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQShow (IxQMgrQId qId)
+ *
+ * @brief Display aqueue configuration and statistics for a queue.
+ *
+ * This function shows queue configuration and statistics for a queue.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ *
+ * @return @li IX_SUCCESS, success
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQShow (IxQMgrQId qId);
+
+
+/* ------------------------------------------------------------
+   Configuration related functions
+   ---------------------------------------------------------- */
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrQConfig (char *qName,
+	       IxQMgrQId qId,
+	       IxQMgrQSizeInWords qSizeInWords,
+	       IxQMgrQEntrySizeInWords qEntrySizeInWords)
+ *
+ * @brief Configure an AQM queue.
+ *
+ * This function is called by a client to setup a queue. The size and entrySize
+ * qId and qName(NULL pointer) are checked for valid values. This function must
+ * be called for each queue, before any queue accesses are made and after
+ * ixQMgrInit() has been called. qName is assumed to be a '\0' terminated array
+ * of 16 charachters or less.
+ *
+ * @param *qName char [in] - is the name provided by the client and is associated
+ *                          with a QId by the QMgr.
+ * @param qId @ref IxQMgrQId [in]  - the qId of this queue
+ * @param qSizeInWords @ref IxQMgrQSize [in] - the size of the queue can be one of 16,32
+ *                                       64, 128 words.
+ * @param qEntrySizeInWords @ref IxQMgrQEntrySizeInWords [in] - the size of a queue entry
+ *                                                        can be one of 1,2,4 words.
+ *
+ * @return @li IX_SUCCESS, a specified queue has been successfully configured.
+ * @return @li IX_FAIL, IxQMgr has not been initialised.
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid parameter(s).
+ * @return @li IX_QMGR_INVALID_QSIZE, invalid queue size
+ * @return @li IX_QMGR_INVALID_Q_ID, invalid queue id
+ * @return @li IX_QMGR_INVALID_Q_ENTRY_SIZE, invalid queue entry size
+ * @return @li IX_QMGR_Q_ALREADY_CONFIGURED, queue already configured
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQConfig (char *qName,
+	       IxQMgrQId qId,
+	       IxQMgrQSizeInWords qSizeInWords,
+	       IxQMgrQEntrySizeInWords qEntrySizeInWords);
+
+/**
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrQSizeInEntriesGet (IxQMgrQId qId,
+			 unsigned *qSizeInEntries)
+ *
+ * @brief Return the size of a queue in entries.
+ *
+ * This function returns the the size of the queue in entriese.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier
+ * @param *qSizeInEntries @ref IxQMgrQSize [out] - queue size in entries
+ *
+ * @return @li IX_SUCCESS, successfully retrieved the number of full entrie
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid parameter(s).
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQSizeInEntriesGet (IxQMgrQId qId,
+			 unsigned *qSizeInEntries);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrWatermarkSet (IxQMgrQId qId,
+		    IxQMgrWMLevel ne,
+		    IxQMgrWMLevel nf)
+ *
+ * @brief Set the Nearly Empty and Nearly Full Watermarks fo a queue.
+ *
+ * This function is called by a client to set the watermarks NE and NF for the
+ * queue specified by qId.
+ * The queue must be empty at the time this function is called, it is the clients
+ * responsibility to ensure that the queue is empty.
+ * This function will read the status of the queue before the watermarks are set
+ * and again after the watermarks are set. If the status register has changed,
+ * due to a queue access by an NPE for example, a warning is returned.
+ * Queues 32-63 only support the NE flag, therefore the value of nf will be ignored
+ * for these queues.
+ *
+ * @param qId @ref IxQMgrQId [in] -  the QId of the queue.
+ * @param ne @ref IxQMgrWMLevel [in]  - the NE(Nearly Empty) watermark for this
+ *                                 queue. Valid values are 0,1,2,4,8,16,32 and
+ *                                 64 entries.
+ * @param nf @ref IxQMgrWMLevel [in] - the NF(Nearly Full) watermark for this queue.
+ *                                 Valid values are 0,1,2,4,8,16,32 and 64
+ *                                 entries.
+ *
+ * @return @li IX_SUCCESS, watermarks have been set for the queu
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId
+ * @return @li IX_QMGR_INVALID_Q_WM, invalid watermark
+ * @return @li IX_QMGR_WARNING, the status register may not be constistent
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrWatermarkSet (IxQMgrQId qId,
+		    IxQMgrWMLevel ne,
+		    IxQMgrWMLevel nf);
+
+/**
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrAvailableSramAddressGet (UINT32 *address,
+			       unsigned *sizeOfFreeSram)
+ *
+ * @brief Return the address of available AQM SRAM.
+ *
+ * This function returns the starting address in AQM SRAM not used by the
+ * current queue configuration and should only be called after all queues
+ * have been configured.
+ * Calling this function before all queues have been configured will will return
+ * the currently available SRAM. A call to configure another queue will use some
+ * of the available SRAM.
+ * The amount of SRAM available is specified in sizeOfFreeSram. The address is the
+ * address of the bottom of available SRAM. Available SRAM extends from address
+ * from address to address + sizeOfFreeSram.
+ *
+ * @param **address UINT32 [out] - the address of the available SRAM, NULL if
+ *                                none available.
+ * @param *sizeOfFreeSram unsigned [out]- the size in words of available SRAM
+ *
+ * @return @li IX_SUCCESS, there is available SRAM and is pointed to by address
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid parameter(s)
+ * @return @li IX_QMGR_NO_AVAILABLE_SRAM, all AQM SRAM is consumed by the queue
+ *             configuration.
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrAvailableSramAddressGet (UINT32 *address,
+			       unsigned *sizeOfFreeSram);
+
+
+/* ------------------------------------------------------------
+   Queue access related functions
+   ---------------------------------------------------------- */
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrQReadWithChecks (IxQMgrQId qId,
+                       UINT32 *entry)
+ *
+ * @brief Read an entry from a queue.
+ *
+ * This function reads an entire entry from a queue returning it in entry. The
+ * queue configuration word is read to determine what entry size this queue is
+ * configured for and then the number of words specified by the entry size is
+ * read.  entry must be a pointer to a previously allocated array of sufficient
+ * size to hold an entry.
+ *
+ * @note - IX_QMGR_Q_UNDERFLOW is only returned for queues 0-31 as queues 32-63
+ * do not have an underflow status maintained.
+ *
+ * @param  qId @ref IxQMgrQId [in]   - the queue identifier.
+ * @param  *entry UINT32 [out]  - pointer to the entry word(s).
+ *
+ * @return @li IX_SUCCESS, entry was successfully read.
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid paramter(s).
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId
+ * @return @li IX_QMGR_Q_UNDERFLOW, attempt to read from an empty queue
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQReadWithChecks (IxQMgrQId qId,
+                       UINT32 *entry);
+
+
+
+/** 
+ * @brief Internal structure to facilitate inlining functions in IxQMgr.h
+ */
+typedef struct
+{
+    /* fields related to write functions */
+    UINT32 qOflowStatBitMask;         /**< overflow status mask */
+    UINT32 qWriteCount;               /**< queue write count */
+
+    /* fields related to read and write functions */
+    volatile UINT32 *qAccRegAddr;     /**< access register */
+    volatile UINT32 *qUOStatRegAddr;  /**< status register */
+    volatile UINT32 *qConfigRegAddr;  /**< config register */
+    UINT32 qEntrySizeInWords;         /**< queue entry size in words */
+    UINT32 qSizeInEntries;            /**< queue size in entries */
+
+    /* fields related to read functions */
+    UINT32 qUflowStatBitMask;         /**< underflow status mask */
+    UINT32 qReadCount;                /**< queue read count */
+} IxQMgrQInlinedReadWriteInfo;
+
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQReadMWordsMinus1 (IxQMgrQId qId,
+			        UINT32 *entry)
+ *
+ * @brief This function reads the remaining of the q entry
+ *        for queues configured with many words.
+ *        (the first word of the entry is already read 
+ *        in the inlined function and the entry pointer already
+ *        incremented
+ *
+ * @param  qId @ref IxQMgrQId [in]  - the queue identifier.
+ * @param  *entry UINT32 [out] - pointer to the entry word(s).
+ *
+ * @return @li IX_SUCCESS, entry was successfully read.
+ * @return @li IX_QMGR_Q_UNDERFLOW, attempt to read from an empty queue
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQReadMWordsMinus1 (IxQMgrQId qId,
+			 UINT32 *entry);
+
+
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrQRead (IxQMgrQId qId,
+	     UINT32 *entry)
+ *
+ * @brief Fast read of an entry from a queue.
+ *
+ * This function is a heavily streamlined version of ixQMgrQReadWithChecks(),
+ * but performs essentially the same task.  It reads an entire entry from a
+ * queue, returning it in entry which must be a pointer to a previously
+ * allocated array of sufficient size to hold an entry.
+ *
+ * @note - This function is inlined, to reduce unnecessary function call
+ * overhead.  It does not perform any parameter checks, or update any statistics.
+ * Also, it does not check that the queue specified by qId has been configured.
+ * or is in range. It simply reads an entry from the queue, and checks for
+ * underflow.
+ *
+ * @note - IX_QMGR_Q_UNDERFLOW is only returned for queues 0-31 as queues 32-63
+ * do not have an underflow status maintained.
+ *
+ * @param  qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param  *entry UINT32 [out] - pointer to the entry word(s).
+ *
+ * @return @li IX_SUCCESS, entry was successfully read.
+ * @return @li IX_QMGR_Q_UNDERFLOW, attempt to read from an empty queue
+ *
+ */
+#ifdef NO_INLINE_APIS
+PUBLIC IX_STATUS
+ixQMgrQRead (IxQMgrQId qId,
+             UINT32 *entryPtr);
+#else 
+extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
+extern IX_STATUS ixQMgrQReadMWordsMinus1 (IxQMgrQId qId, UINT32 *entryPtr);
+
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQRead (IxQMgrQId qId,
+             UINT32 *entryPtr);
+#endif
+
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQRead (IxQMgrQId qId,
+	     UINT32 *entryPtr)
+#ifdef NO_INLINE_APIS
+    ;
+#else
+{
+    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+    UINT32 entry, entrySize;
+
+    /* get a new entry */
+    entrySize = infoPtr->qEntrySizeInWords;
+    entry = IX_QMGR_INLINE_READ_LONG(infoPtr->qAccRegAddr);
+
+    if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
+    {	
+	*entryPtr = entry;
+	/* process the remaining part of the entry */
+	return ixQMgrQReadMWordsMinus1(qId, entryPtr);
+    }
+
+    /* underflow is available for lower queues only */
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {
+	/* the counter of queue entries is decremented. In happy 
+	 * day scenario there are many entries in the queue
+	 * and the counter does not reach zero.
+	 */
+	if (infoPtr->qReadCount-- == 0)
+	{
+	    /* There is maybe no entry in the queue
+	     * qReadCount is now negative, but will be corrected before
+	     * the function returns.
+	     */
+	    UINT32 qPtrs; /* queue internal pointers */
+
+	    /* when a queue is empty, the hw guarantees to return 
+	     * a null value. If the value is not null, the queue is
+	     * not empty.
+	     */
+	    if (entry == 0)
+	    {
+		/* get the queue status */
+		UINT32 status = IX_QMGR_INLINE_READ_LONG(infoPtr->qUOStatRegAddr);
+	
+		/* check the underflow status */
+		if (status & infoPtr->qUflowStatBitMask)
+		{
+		    /* the queue is empty 
+		    *  clear the underflow status bit if it was set 
+		    */
+		    IX_QMGR_INLINE_WRITE_LONG(infoPtr->qUOStatRegAddr,
+					 status & ~infoPtr->qUflowStatBitMask);
+		    *entryPtr = 0;
+		    infoPtr->qReadCount = 0;
+		    return IX_QMGR_Q_UNDERFLOW;
+		}
+	    }
+	    /* store the result */
+	    *entryPtr = entry;
+
+	    /* No underflow occured : someone is filling the queue
+	     * or the queue contains null entries.
+	     * The current counter needs to be
+	     * updated from the current number of entries in the queue
+	     */
+
+	    /* get snapshot of queue pointers */
+	    qPtrs = IX_QMGR_INLINE_READ_LONG(infoPtr->qConfigRegAddr);
+
+	    /* Mod subtraction of pointers to get number of words in Q. */
+	    qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f; 
+  
+	    if (qPtrs == 0)
+	    {
+		/* no entry in the queue */
+		infoPtr->qReadCount = 0;
+	    }
+	    else
+	    {
+		/* convert the number of words inside the queue
+		 * to a number of entries 
+		 */
+		infoPtr->qReadCount = qPtrs & (infoPtr->qSizeInEntries - 1);
+	    }
+	    return IX_SUCCESS;
+	}
+    }
+    *entryPtr = entry;
+    return IX_SUCCESS;
+}
+#endif
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrQBurstRead (IxQMgrQId qId,
+		  UINT32 numEntries,
+		  UINT32 *entries)
+ *
+ * @brief Read a number of entries from an AQM queue.
+ *
+ * This function will burst read a number of entries from the specified queue.
+ * The entry size of queue is auto-detected. The function will attempt to
+ * read as many entries as specified by the numEntries parameter and will
+ * return an UNDERFLOW if any one of the individual entry reads fail.
+ *
+ * @warning
+ * IX_QMGR_Q_UNDERFLOW is only returned for queues 0-31 as queues 32-63
+ * do not have an underflow status maintained, hence there is a potential for
+ * silent failure here. This function must be used with caution.
+ *
+ * @note
+ * This function is intended for fast draining of queues, so to make it
+ * as efficient as possible, it has the following features:
+ * - This function is inlined, to reduce unnecessary function call overhead.
+ * - It does not perform any parameter checks, or update any statistics.
+ * - It does not check that the queue specified by qId has been configured.
+ * - It does not check that the queue has the number of full entries that
+ * have been specified to be read. It will read until it finds a NULL entry or
+ * until the number of specified entries have been read.  It always checks for
+ * underflow after all the reads have been performed.
+ * Therefore, the client should ensure before calling this function that there
+ * are enough entries in the queue to read.  ixQMgrQNumEntriesGet() will
+ * provide the number of full entries in a queue.
+ * ixQMgrQRead() or ixQMgrQReadWithChecks(), which only reads
+ * a single queue entry per call, should be used instead if the user requires
+ * checks for UNDERFLOW after each entry read.
+ *
+ * @param qId @ref IxQMgrQId [in]   - the queue identifier.
+ * @param numEntries unsigned [in] - the number of entries to read. 
+ *                     This number should be greater than 0
+ * @param *entries UINT32 [out] - the word(s) read.
+ *
+ * @return @li IX_SUCCESS, entries were successfully read.
+ * @return @li IX_QMGR_Q_UNDERFLOW, attempt to read from an empty queue 
+ *
+ */
+#ifdef NO_INLINE_APIS  
+PUBLIC IX_STATUS
+ixQMgrQBurstRead (IxQMgrQId qId,
+                  UINT32 numEntries,
+                  UINT32 *entries);
+#else
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQBurstRead (IxQMgrQId qId,
+                  UINT32 numEntries,
+                  UINT32 *entries);
+#endif  /* endif NO_INLINE_APIS */
+
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQBurstRead (IxQMgrQId qId,
+		  UINT32 numEntries,
+		  UINT32 *entries)
+#ifdef NO_INLINE_APIS
+;
+#else
+{
+    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+    UINT32 nullCheckEntry;
+
+    if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
+    {
+	volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
+
+	/* the code is optimized to take care of data dependencies:
+	 * Durig a read, there are a few cycles needed to get the 
+	 * read complete. During these cycles, it is poossible to
+	 * do some CPU, e.g. increment pointers and decrement 
+	 * counters.
+	 */
+
+	/* fetch a queue entry */
+	nullCheckEntry = IX_QMGR_INLINE_READ_LONG(infoPtr->qAccRegAddr);
+
+	/* iterate the specified number of queue entries */ 
+	while (--numEntries)
+	{
+	    /* check the result of the previous read */
+	    if (nullCheckEntry == 0)
+	    {
+		/* if we read a NULL entry, stop. We have underflowed */
+		break;
+	    }
+	    else
+	    {
+		/* write the entry */
+		*entries = nullCheckEntry;
+		/* fetch next entry */
+		nullCheckEntry = IX_QMGR_INLINE_READ_LONG(qAccRegAddr);
+		/* increment the write address */
+		entries++;
+	    }
+	}
+	/* write the pre-fetched entry */
+	*entries = nullCheckEntry;
+    }
+    else
+    {
+	IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
+	/* read the specified number of queue entries */
+	nullCheckEntry = 0;
+	while (numEntries--)
+	{
+	    UINT32 i;
+
+	    for (i = 0; i < (UINT32)entrySizeInWords; i++)
+	    {
+		*entries = IX_QMGR_INLINE_READ_LONG(infoPtr->qAccRegAddr + i);
+		nullCheckEntry |= *entries++;
+	    }
+
+	    /* if we read a NULL entry, stop. We have underflowed */
+	    if (nullCheckEntry == 0)
+	    {
+		break;
+	    }
+	    nullCheckEntry = 0;
+	}
+    }
+
+    /* reset the current read count : next access to the read function 
+     * will force a underflow status check 
+     */
+    infoPtr->qReadCount = 0;
+
+    /* Check if underflow occurred on the read */
+    if (nullCheckEntry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID)
+    {
+	/* get the queue status */
+	UINT32 status = IX_QMGR_INLINE_READ_LONG(infoPtr->qUOStatRegAddr);
+
+	if (status & infoPtr->qUflowStatBitMask)
+	{
+	    /* clear the underflow status bit if it was set */
+	    IX_QMGR_INLINE_WRITE_LONG(infoPtr->qUOStatRegAddr,
+				 status & ~infoPtr->qUflowStatBitMask);
+	    return IX_QMGR_Q_UNDERFLOW;
+	}
+    }
+
+    return IX_SUCCESS;
+}
+#endif
+
+/**
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrQPeek (IxQMgrQId qId,
+	     unsigned int entryIndex,
+	     UINT32 *entry)
+ *
+ * @brief Read an entry from a queue without moving the read pointer.
+ *
+ * This function inspects an entry in a queue. The entry is inspected directly
+ * in AQM SRAM and is not read from queue access registers. The entry is NOT removed
+ * from the queue and the read/write pointers are unchanged.
+ * N.B: The queue should not be accessed when this function is called.
+ *
+ * @param  qId @ref IxQMgrQId [in]   - the queue identifier.
+ * @param  entryIndex unsigned int [in] - index of entry in queue in the range
+ *                          [0].......[current number of entries in queue].
+ * @param  *entry UINT32 [out] - pointer to the entry word(s).
+ *
+ * @return @li IX_SUCCESS, entry was successfully inspected.
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid paramter(s).
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId.
+ * @return @li IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS, an entry does not exist at
+ *             specified index.
+ * @return @li IX_FAIL, failed to inpected the queue entry.
+ */
+PUBLIC IX_STATUS
+ixQMgrQPeek (IxQMgrQId qId,
+	     unsigned int entryIndex,
+	     UINT32 *entry);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrQWriteWithChecks (IxQMgrQId qId,
+                        UINT32 *entry)
+ *
+ * @brief Write an entry to an AQM queue.
+ *
+ * This function will write the entry size number of words pointed to by entry to
+ * the queue specified by qId. The queue configuration word is read to
+ * determine the entry size of queue and the corresponding number of words is
+ * then written to the queue.
+ *
+ * @note - IX_QMGR_Q_OVERFLOW is only returned for queues 0-31 as queues 32-63
+ * do not have an overflow status maintained.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param *entry UINT32 [in] - the word(s) to write.
+ *
+ * @return @li IX_SUCCESS, value was successfully written.
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid paramter(s).
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId
+ * @return @li IX_QMGR_Q_OVERFLOW, attempt to write to a full queue
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQWriteWithChecks (IxQMgrQId qId,
+                        UINT32 *entry);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrQWrite (IxQMgrQId qId,
+	      UINT32 *entry)
+ *
+ * @brief Fast write of an entry to a queue.
+ *
+ * This function is a heavily streamlined version of ixQMgrQWriteWithChecks(),
+ * but performs essentially the same task.  It will write the entry size number
+ * of words pointed to by entry to the queue specified by qId.
+ *
+ * @note - This function is inlined, to reduce unnecessary function call
+ * overhead.  It does not perform any parameter checks, or update any
+ * statistics. Also, it does not check that the queue specified by qId has
+ * been configured. It simply writes an entry to the queue, and checks for
+ * overflow.
+ *
+ * @note - IX_QMGR_Q_OVERFLOW is only returned for queues 0-31 as queues 32-63
+ * do not have an overflow status maintained.
+ *
+ * @param  qId @ref IxQMgrQId [in]   - the queue identifier.
+ * @param  *entry UINT32 [in] - pointer to the entry word(s).
+ *
+ * @return @li IX_SUCCESS, entry was successfully read.
+ * @return @li IX_QMGR_Q_OVERFLOW, attempt to write to a full queue
+ *
+ */
+#ifdef NO_INLINE_APIS
+PUBLIC IX_STATUS
+ixQMgrQWrite (IxQMgrQId qId,
+	      UINT32 *entry);
+#else
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQWrite (IxQMgrQId qId,
+	      UINT32 *entry);
+#endif /* NO_INLINE_APIS */
+
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQWrite (IxQMgrQId qId,
+	      UINT32 *entry)
+#ifdef NO_INLINE_APIS
+    ;
+#else
+{
+    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+    UINT32 entrySize;
+
+    /* write the entry */
+    IX_QMGR_INLINE_WRITE_LONG(infoPtr->qAccRegAddr, *entry);
+    entrySize = infoPtr->qEntrySizeInWords;
+
+    if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
+    {	
+	/* process the remaining part of the entry */
+	volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
+	while (--entrySize)
+	{
+	    ++entry;
+	    IX_QMGR_INLINE_WRITE_LONG(++qAccRegAddr, *entry);
+	}
+	entrySize = infoPtr->qEntrySizeInWords;
+    }
+
+    /* overflow is available for lower queues only */
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {   
+	UINT32 qSize = infoPtr->qSizeInEntries;
+	/* increment the current number of entries in the queue
+	 * and check for overflow 
+	 */
+	if (infoPtr->qWriteCount++ == qSize)
+	{
+	    /* the queue may have overflow */
+	    UINT32 qPtrs; /* queue internal pointers */
+  
+	    /* get the queue status */
+	    UINT32 status = IX_QMGR_INLINE_READ_LONG(infoPtr->qUOStatRegAddr);
+
+	    /* read the status twice because the status may 
+	     * not be immediately ready after the write operation
+	     */
+	    if ((status & infoPtr->qOflowStatBitMask) ||
+		((status = IX_QMGR_INLINE_READ_LONG(infoPtr->qUOStatRegAddr))
+		 & infoPtr->qOflowStatBitMask))
+	    {
+		/* the queue is full, clear the overflow status
+		 *  bit if it was set 
+		 */
+		IX_QMGR_INLINE_WRITE_LONG(infoPtr->qUOStatRegAddr,
+				     status & ~infoPtr->qOflowStatBitMask);
+		infoPtr->qWriteCount = infoPtr->qSizeInEntries;
+		return IX_QMGR_Q_OVERFLOW;
+	    }
+	    /* No overflow occured : someone is draining the queue
+	     * and the current counter needs to be
+	     * updated from the current number of entries in the queue
+	     */
+
+	    /* get q pointer snapshot */
+	    qPtrs = IX_QMGR_INLINE_READ_LONG(infoPtr->qConfigRegAddr);
+
+	    /* Mod subtraction of pointers to get number of words in Q. */
+	    qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f; 
+
+	    if (qPtrs == 0)
+	    {
+		/* the queue may be full at the time of the 
+		 * snapshot. Next access will check 
+		 * the overflow status again.
+		 */
+		infoPtr->qWriteCount = qSize;
+	    }
+	    else 
+	    {
+		/* convert the number of words to a number of entries */
+		if (entrySize == IX_QMGR_Q_ENTRY_SIZE1)
+		{
+		    infoPtr->qWriteCount = qPtrs & (qSize - 1);
+		}
+		else
+		{
+		    infoPtr->qWriteCount = (qPtrs / entrySize) & (qSize - 1);
+		}
+	    }
+	}
+    }
+    return IX_SUCCESS;
+}
+#endif
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrQBurstWrite (IxQMgrQId qId,
+		   unsigned numEntries,
+		   UINT32 *entries)
+ *
+ * @brief Write a number of entries to an AQM queue.
+ *
+ * This function will burst write a number of entries to the specified queue.
+ * The entry size of queue is auto-detected. The function will attempt to
+ * write as many entries as specified by the numEntries parameter and will
+ * return an OVERFLOW if any one of the individual entry writes fail.
+ *
+ * @warning
+ * IX_QMGR_Q_OVERFLOW is only returned for queues 0-31 as queues 32-63
+ * do not have an overflow status maintained, hence there is a potential for
+ * silent failure here. This function must be used with caution.
+ *
+ * @note
+ * This function is intended for fast population of queues, so to make it
+ * as efficient as possible, it has the following features:
+ * - This function is inlined, to reduce unnecessary function call overhead.
+ * - It does not perform any parameter checks, or update any statistics.
+ * - It does not check that the queue specified by qId has been configured.
+ * - It does not check that the queue has enough free space to hold the entries
+ * before writing, and only checks for overflow after all writes have been
+ * performed.  Therefore, the client should ensure before calling this function
+ * that there is enough free space in the queue to hold the number of entries
+ * to be written.  ixQMgrQWrite() or ixQMgrQWriteWithChecks(), which only writes
+ * a single queue entry per call, should be used instead if the user requires
+ * checks for OVERFLOW after each entry written.
+ *
+ * @param qId @ref IxQMgrQId [in]   - the queue identifier.
+ * @param numEntries unsigned [in] - the number of entries to write.
+ * @param *entries UINT32 [in]  - the word(s) to write.
+ *
+ * @return @li IX_SUCCESS, value was successfully written.
+ * @return @li IX_QMGR_Q_OVERFLOW, attempt to write to a full queue
+ *
+ */
+#ifdef NO_INLINE_APIS
+PUBLIC IX_STATUS
+ixQMgrQBurstWrite (IxQMgrQId qId,
+		   unsigned numEntries,
+		   UINT32 *entries);
+#else
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQBurstWrite (IxQMgrQId qId,
+		   unsigned numEntries,
+		   UINT32 *entries);
+#endif /* NO_INLINE_APIS */
+
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQBurstWrite (IxQMgrQId qId,
+		   unsigned numEntries,
+		   UINT32 *entries)
+#ifdef NO_INLINE_APIS
+;
+#else
+{
+    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
+    UINT32 status;
+
+    /* update the current write count */
+    infoPtr->qWriteCount += numEntries;
+
+    if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
+    {
+	volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
+	while (numEntries--)
+	{
+	    IX_QMGR_INLINE_WRITE_LONG(qAccRegAddr, *entries);
+	    entries++;
+	}
+    }
+    else
+    {
+	IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
+	UINT32 i;
+
+	/* write each queue entry */
+	while (numEntries--)
+	{
+	    /* write the queueEntrySize number of words for each entry */
+	    for (i = 0; i < (UINT32)entrySizeInWords; i++)
+	    {
+		IX_QMGR_INLINE_WRITE_LONG((infoPtr->qAccRegAddr + i), *entries);
+		entries++;
+	    }
+	}
+    }
+
+    /* check if the write count overflows */
+    if (infoPtr->qWriteCount > infoPtr->qSizeInEntries)
+    {
+	/* reset the current write count */
+	infoPtr->qWriteCount = infoPtr->qSizeInEntries;
+    }
+
+    /* Check if overflow occurred on the write operation */
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {
+	/* get the queue status */
+	status = IX_QMGR_INLINE_READ_LONG(infoPtr->qUOStatRegAddr);
+
+	/* read the status twice because the status may 
+	 * not be ready at the time of the write
+	 */
+	if ((status & infoPtr->qOflowStatBitMask) ||
+	    ((status = IX_QMGR_INLINE_READ_LONG(infoPtr->qUOStatRegAddr))
+	     & infoPtr->qOflowStatBitMask))
+	{
+	    /* clear the underflow status bit if it was set */
+	    IX_QMGR_INLINE_WRITE_LONG(infoPtr->qUOStatRegAddr,
+				 status & ~infoPtr->qOflowStatBitMask);
+	    return IX_QMGR_Q_OVERFLOW;
+	}
+    }
+
+    return IX_SUCCESS;
+}
+#endif
+
+/**
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrQPoke (IxQMgrQId qId,
+	     unsigned int entryIndex,
+	     UINT32 *entry)
+ *
+ * @brief Write an entry to a queue without moving the write pointer.
+ *
+ * This function modifies an entry in a queue. The entry is modified directly
+ * in AQM SRAM and not using the queue access registers. The entry is NOT added to the
+ * queue and the read/write pointers are unchanged.
+ * N.B: The queue should not be accessed when this function is called.
+ *
+ * @param qId @ref IxQMgrQId [in]  - the queue identifier.
+ * @param  entryIndex unsigned int [in] - index of entry in queue in the range
+ *                          [0].......[current number of entries in queue].
+ * @param  *entry UINT32 [in] - pointer to the entry word(s).
+ *
+ * @return @li IX_SUCCESS, entry was successfully modified.
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid paramter(s).
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId.
+ * @return @li IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS, an entry does not exist at
+ *             specified index.
+ * @return @li IX_FAIL, failed to modify the queue entry.
+ */
+PUBLIC IX_STATUS
+ixQMgrQPoke (IxQMgrQId qId,
+	     unsigned int entryIndex,
+	     UINT32 *entry);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrQNumEntriesGet (IxQMgrQId qId,
+		      unsigned *numEntries)
+ *
+ * @brief Get a snapshot of the number of entries in a queue.
+ *
+ * This function gets the number of entries in a queue.
+ *
+ * @param qId @ref IxQMgrQId [in] qId - the queue idenfifier
+ * @param *numEntries unsigned [out] - the number of entries in a queue
+ *
+ * @return @li IX_SUCCESS, got the number of entries for the queue
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid paramter(s).
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, the specified qId has not been configured
+ * @return @li IX_QMGR_WARNING, could not determine num entries at this time
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQNumEntriesGet (IxQMgrQId qId,
+		      unsigned *numEntries);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrQStatusGetWithChecks (IxQMgrQId qId,
+                            IxQMgrQStatus *qStatus)
+ *
+ * @brief Get a queues status.
+ *
+ * This function reads the specified queues status. A queues status is defined
+ * by its status flags. For queues 0-31 these flags are E,NE,NF,F. For
+ * queues 32-63 these flags are NE and F.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param &qStatus @ref IxQMgrQStatus [out] - the status of the specified queue.
+ *
+ * @return @li IX_SUCCESS, queue status was successfully read.
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, the specified qId has not been configured
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid paramter.
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrQStatusGetWithChecks (IxQMgrQId qId,
+                            IxQMgrQStatus *qStatus);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrQStatusGet (IxQMgrQId qId,
+		  IxQMgrQStatus *qStatus)
+ *
+ * @brief Fast get of a queue's status.
+ *
+ * This function is a streamlined version of ixQMgrQStatusGetWithChecks(), but
+ * performs essentially the same task.  It reads the specified queue's status.
+ * A queues status is defined by its status flags. For queues 0-31 these flags
+ * are E,NE,NF,F. For queues 32-63 these flags are NE and F.
+ *
+ * @note - This function is inlined, to reduce unnecessary function call
+ * overhead.  It does not perform any parameter checks, or update any
+ * statistics.  Also, it does not check that the queue specified by qId has
+ * been configured.  It simply reads the specified queue's status.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier.
+ * @param *qStatus @ref IxQMgrQStatus [out] - the status of the specified queue.
+ *
+ * @return @li void.
+ *
+ */
+
+#ifdef NO_INLINE_APIS
+PUBLIC IX_STATUS
+ixQMgrQStatusGet (IxQMgrQId qId,
+		  IxQMgrQStatus *qStatus);
+#else  
+extern UINT32 ixQMgrAqmIfQueLowStatRegAddr[];
+extern UINT32 ixQMgrAqmIfQueLowStatBitsOffset[];
+extern UINT32 ixQMgrAqmIfQueLowStatBitsMask;
+extern UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
+extern UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
+extern UINT32 ixQMgrAqmIfQueUppStat0BitMask[];
+extern UINT32 ixQMgrAqmIfQueUppStat1BitMask[];
+
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQStatusGet (IxQMgrQId qId,
+		  IxQMgrQStatus *qStatus);
+#endif  /* endif NO_INLINE_APIS */
+
+IX_QMGR_INLINE PUBLIC IX_STATUS
+ixQMgrQStatusGet (IxQMgrQId qId,
+		  IxQMgrQStatus *qStatus)
+#ifdef NO_INLINE_APIS
+    ;
+#else
+{
+    /* read the status of a queue in the range 0-31 */
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {
+	volatile UINT32 *lowStatRegAddr = (UINT32*)ixQMgrAqmIfQueLowStatRegAddr[qId];
+
+	UINT32 lowStatBitsOffset = ixQMgrAqmIfQueLowStatBitsOffset[qId];
+	UINT32 lowStatBitsMask   = ixQMgrAqmIfQueLowStatBitsMask;
+
+	/* read the status register for this queue */
+	*qStatus = IX_QMGR_INLINE_READ_LONG(lowStatRegAddr);
+
+	/* mask out the status bits relevant only to this queue */
+	*qStatus = (*qStatus >> lowStatBitsOffset) & lowStatBitsMask;
+
+    }
+    else /* read status of a queue in the range 32-63 */
+    {
+
+	volatile UINT32 *qNearEmptyStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat0RegAddr;
+	volatile UINT32 *qFullStatRegAddr      = (UINT32*)ixQMgrAqmIfQueUppStat1RegAddr;
+	int maskIndex = qId - IX_QMGR_MIN_QUEUPP_QID;
+	UINT32 qNearEmptyStatBitMask = ixQMgrAqmIfQueUppStat0BitMask[maskIndex];
+	UINT32 qFullStatBitMask      = ixQMgrAqmIfQueUppStat1BitMask[maskIndex];
+
+	/* Reset the status bits */
+	*qStatus = 0;
+
+	/* Check if the queue is nearly empty */
+	if (IX_QMGR_INLINE_READ_LONG(qNearEmptyStatRegAddr) & qNearEmptyStatBitMask)
+	{
+	    *qStatus |= IX_QMGR_Q_STATUS_NE_BIT_MASK;
+	}
+
+	/* Check if the queue is full */
+	if (IX_QMGR_INLINE_READ_LONG(qFullStatRegAddr) & qFullStatBitMask)
+	{
+	    *qStatus |= IX_QMGR_Q_STATUS_F_BIT_MASK;
+	}
+    }
+    return IX_SUCCESS;
+}
+#endif
+
+/* ------------------------------------------------------------
+   Queue dispatch related functions
+   ---------------------------------------------------------- */
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrDispatcherPrioritySet (IxQMgrQId qId,
+			     IxQMgrPriority priority)
+ *
+ * @brief Set the dispatch priority of a queue.
+ *
+ * This function is called to set the dispatch priority of queue. The effect of
+ * this function is to add a priority change request to a queue. This queue is
+ * serviced by @a ixQMgrDispatcherLoopRunA0, @a ixQMgrDispatcherLoopRunB0 or 
+ * @a ixQMgrDispatcherLoopRunB0LLP.
+ *
+ * This function is re-entrant. and can be used from an interrupt context
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier
+ * @param priority @ref IxQMgrPriority [in] - the new queue dispatch priority
+ *
+ * @return @li IX_SUCCESS, priority change request is queued
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, the specified qId has not been configured
+ * @return @li IX_QMGR_Q_INVALID_PRIORITY, specified priority is invalid
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrDispatcherPrioritySet (IxQMgrQId qId,
+			     IxQMgrPriority priority);
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrNotificationEnable (IxQMgrQId qId,
+			  IxQMgrSourceId sourceId)
+ *
+ * @brief Enable notification on a queue for a specified queue source flag.
+ *
+ * This function is called by a client of the QMgr to enable notifications on a
+ * specified condition.
+ * If the condition for the notification is set after the client has called this
+ * function but before the function has enabled the interrupt source, then the
+ * notification will not occur.
+ * For queues 32-63 the notification source is fixed to the NE(Nearly Empty) flag
+ * and cannot be changed so the sourceId parameter is ignored for these queues.
+ * The status register is read before the notofication is enabled and is read again
+ * after the notification has been enabled, if they differ then the warning status
+ * is returned.
+ *
+ * This function is re-entrant. and can be used from an interrupt context
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier
+ * @param sourceId @ref IxQMgrSourceId [in] - the interrupt src condition identifier
+ *
+ * @return @li IX_SUCCESS, the interrupt has been enabled for the specified source
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, the specified qId has not been configured
+ * @return @li IX_QMGR_INVALID_INT_SOURCE_ID, interrupt source invalid for this queue
+ * @return @li IX_QMGR_WARNING, the status register may not be constistent
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrNotificationEnable (IxQMgrQId qId,
+			  IxQMgrSourceId sourceId);
+
+/**
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrNotificationDisable (IxQMgrQId qId)
+ *
+ * @brief Disable notifications on a queue.
+ *
+ * This function is called to disable notifications on a specified queue.
+ *
+ * This function is re-entrant. and can be used from an interrupt context
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier
+ *
+ * @return @li IX_SUCCESS, the interrupt has been disabled
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, the specified qId has not been configured
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrNotificationDisable (IxQMgrQId qId);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrDispatcherLoopRunA0 (IxQMgrDispatchGroup group)
+ *
+ * @brief Run the callback dispatcher.
+ *
+ * This function runs the dispatcher for a group of queues.
+ * Callbacks are made for interrupts that have occurred on queues within
+ * the group that have registered callbacks. The order in which queues are
+ * serviced depends on the queue priorities set by the client.
+ * This function may be called from interrupt or task context.
+ * For optimisations that were introduced in IXP42X B0 and supported IXP46X
+ * the @a ixQMgrDispatcherLoopRunB0, or @a ixQMgrDispatcherLoopRunB0LLP 
+ * should be used.
+ *
+ * This function is not re-entrant.
+ *
+ * @param group @ref IxQMgrDispatchGroup [in] - the group of queues over which the
+ *                                        dispatcher will run
+ *
+ * @return @li void
+ *
+ * @note This function may be called from interrupt or task context.
+ * However, for optimal performance the choice of context depends also on the
+ * operating system used.
+ *
+ */
+PUBLIC void
+ixQMgrDispatcherLoopRunA0 (IxQMgrDispatchGroup group);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrDispatcherLoopRunB0 (IxQMgrDispatchGroup group)
+ *
+ * @brief Run the callback dispatcher.
+ *
+ * The enhanced version of @a ixQMgrDispatcherLoopRunA0 that is optimised for
+ * features introduced in IXP42X B0 silicon and supported on IXP46X. 
+ * This is the default dispatcher for IXP42X B0 and IXP46X silicon. 
+ * The function runs the dispatcher for a group of queues.
+ * Callbacks are made for interrupts that have occurred on queues within
+ * the group that have registered callbacks. The order in which queues are
+ * serviced depends on the queue priorities set by the client.
+ * This  function may be called from interrupt or task context.
+ *
+ * This function is not re-entrant.
+ *
+ * @param group @ref IxQMgrDispatchGroup [in] - the group of queues over which the
+ *                                        dispatcher will run
+ *
+ * @return @li void
+ *
+ *
+ * @note This function may be called from interrupt or task context.
+ * However, for optimal performance the choice of context depends also on the
+ * operating system used.
+ *
+ */
+PUBLIC void
+ixQMgrDispatcherLoopRunB0 (IxQMgrDispatchGroup group);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrDispatcherLoopRunB0LLP (IxQMgrDispatchGroup group)
+ *
+ * @brief Run the callback dispatcher.
+ *
+ * This is a version of the optimised dispatcher for IXP42X B0 and IXP46X, 
+ * @a ixQMgrDispatcherLoopRunB0, with added support for livelock prevention. 
+ * This dispatcher will only be used for the IXP42X B0 or IXP46X silicon if 
+ * feature control indicates that IX_FEATURECTRL_ORIGB0_DISPATCHER is set to   
+ * IX_FEATURE_CTRL_SWCONFIG_DISABLED. Otherwise the @a ixQMgrDispatcherLoopRunB0 
+ * dispatcher will be used (Default). 
+ *
+ * When this dispatcher notifies for a queue that is type
+ * IX_QMGR_TYPE_REALTIME_PERIODIC, notifications for queues that are set
+ * as type IX_QMGR_REALTIME_SPORADIC are not processed and disabled.
+ * This helps prevent any tasks resulting from the notification of the 
+ * IX_QMGR_TYPE_REALTIME_PERIODIC type queue to being subject to livelock.
+ * The function runs the dispatcher for a group of queues.
+ * Callbacks are made for interrupts that have occurred on queues within
+ * the group that have registered callbacks. The order in which queues are
+ * serviced depends on their type along with the  queue priorities set by the 
+ * client. This function may be called from interrupt or task context.
+ *
+ * This function is not re-entrant.
+ *
+ * @param group @ref IxQMgrDispatchGroup [in] - the group of queues over which 
+ *                                        the dispatcher will run
+ *
+ * @return @li void
+ *
+ * @note This function may be called from interrupt or task context.
+ * However, for optimal performance the choice of context depends also on the
+ * operating system used.
+ *
+ */
+PUBLIC void
+ixQMgrDispatcherLoopRunB0LLP (IxQMgrDispatchGroup group);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ * 
+ * @fn ixQMgrNotificationCallbackSet (IxQMgrQId qId,
+			       IxQMgrCallback callback,
+			       IxQMgrCallbackId callbackId)
+ *
+ * @brief Set the notification callback for a queue.
+ *
+ * This function sets the callback for the specified queue. This callback will
+ * be called by the dispatcher, and may be called in the context of a interrupt
+ * If callback has a value of NULL the previously registered callback, if one
+ * exists will be unregistered.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue idenfifier
+ * @param callback @ref IxQMgrCallback  [in] - the callback registered for this queue
+ * @param callbackId @ref IxQMgrCallbackId [in] - the callback identifier
+ *
+ * @return @li IX_SUCCESS, the callback for the specified queue has been set
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, the specified qId has not been configured
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrNotificationCallbackSet (IxQMgrQId qId,
+			       IxQMgrCallback callback,
+			       IxQMgrCallbackId callbackId);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrDispatcherLoopGet (IxQMgrDispatcherFuncPtr *qDispatcherFuncPtr)
+ *
+ * @brief Get QMgr DispatcherLoopRun for respective silicon device
+ *
+ * This function gets a function pointer to ixQMgrDispatcherLoopRunA0() for IXP42X A0
+ * Silicon. If the IXP42X B0 or 46X Silicon, the default is the ixQMgrDispatcherLoopRunB0()
+ * function, however if live lock prevention is enabled a function pointer to
+ * ixQMgrDispatcherLoopRunB0LLP() is given.
+ *
+ * @param *qDispatchFuncPtr @ref IxQMgrDispatcherFuncPtr [out]  - 
+ *              the function pointer of QMgr Dispatcher
+ *
+ */
+PUBLIC void
+ixQMgrDispatcherLoopGet (IxQMgrDispatcherFuncPtr *qDispatcherFuncPtr);
+
+/**
+ *
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrStickyInterruptRegEnable(void)
+ *
+ * @brief Enable AQM's sticky interrupt register behaviour only available
+ *        on B0 Silicon. 
+ * 
+ * When AQM's sticky interrupt register is enabled, interrupt register bit will
+ * only be cleared when a '1' is written to interrupt register bit and the
+ * interrupting condition is satisfied, i.e.queue condition does not exist.
+ * 
+ * @note This function must be called before any queue is enabled.
+ *       Calling this function after queue is enabled will cause
+ *       undefined results. 
+ *
+ * @return none
+ *
+ */
+PUBLIC void
+ixQMgrStickyInterruptRegEnable(void);
+
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrCallbackTypeSet(IxQMgrQId qId,
+                             IxQMgrType type)
+ *
+ * @brief Set the Callback Type of a queue.
+ *
+ * This function is only used for live lock prevention.
+ * This function allows the callback type of a queue to be set. The default for
+ * all queues is IX_QMGR_TYPE_REALTIME_OTHER. Setting the type to
+ * IX_QMGR_TYPE_REALTIME_SPORADIC means that this queue will have it's 
+ * notifications disabled while there is a task associated with a 
+ * queue of type IX_QMGR_TYPE_REALTIME_PERIODIC running. As live lock
+ * prevention operates on lower queues, this function should
+ * be called for lower queues only.
+ * This function is not re-entrant.  
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier
+ * @param type @ref IxQMgrType [in] - the type of callback
+ *
+ * @return @li IX_SUCCESS, successfully set callback type for the queue entry
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid parameter(s).
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrCallbackTypeSet(IxQMgrQId qId,
+                      IxQMgrType type);
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrCallbackTypeGet(IxQMgrQId qId,
+                             IxQMgrType *type)
+ *
+ * @brief Get the Callback Type of a queue.
+ *
+ * This function allows the callback type of a queue to be got. As live lock
+ * prevention operates on lower queues, this function should
+ * be called for lower queues only.
+ * This function is re-entrant.
+ *
+ * @param qId @ref IxQMgrQId [in] - the queue identifier
+ * @param *type @ref IxQMgrType [out] - the type of callback
+ *
+ * @return @li IX_SUCCESS, successfully set callback type for the queue entry
+ * @return @li IX_QMGR_Q_NOT_CONFIGURED, queue not configured for this QId
+ * @return @li IX_QMGR_PARAMETER_ERROR, invalid parameter(s)
+ *
+ */
+PUBLIC IX_STATUS
+ixQMgrCallbackTypeGet(IxQMgrQId qId,
+                      IxQMgrType *type);
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrPeriodicDone(void)
+ *
+ * @brief Indicate that the Periodic task is completed for LLP
+ *
+ * This function is used as part of live lock prevention. 
+ * A periodic task is a task that results from a queue that 
+ * is set as type IX_QMGR_TYPE_REALTIME_PERIODIC. This function 
+ * should be called to indicate to the dispatcher that the
+ * the periodic task is completed. This ensures that the notifications
+ * for queues set as type sporadic queues are re-enabled.
+ * This function is re-entrant.
+ *
+ */
+PUBLIC void
+ixQMgrPeriodicDone(void);
+
+
+/**
+ * @ingroup IxQMgrAPI
+ *
+ * @fn ixQMgrLLPShow(int resetStats)
+ *
+ * @brief Print out the live lock prevention statistics when in debug mode.
+ *
+ * This function prints out statistics related to the livelock. These
+ * statistics are only collected in debug mode.
+ * This function is not re-entrant.
+ *
+ * @param resetStats @ref int [in] - if set the the stats are reset.
+ *
+ */
+PUBLIC void
+ixQMgrLLPShow(int resetStats);
+
+
+#endif /* IXQMGR_H */
+
+/**
+ * @} defgroup IxQMgrAPI
+ */
+
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxQMgrAqmIf_p.h b/marvell/uboot/drivers/net/npe/include/IxQMgrAqmIf_p.h
new file mode 100644
index 0000000..1b9cfd2
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxQMgrAqmIf_p.h
@@ -0,0 +1,903 @@
+/**
+ * @file    IxQMgrAqmIf_p.h
+ *
+ * @author Intel Corporation
+ * @date    30-Oct-2001
+ *
+ * @brief   The IxQMgrAqmIf sub-component provides a number of inline
+ * functions for performing I/O on the AQM. 
+ *
+ * Because  some functions contained in this module are inline and are
+ * used in other modules (within the QMgr component) the definitions are
+ * contained in this header file. The "normal" use of inline functions
+ * is to use the inline functions in the module in which they are
+ * defined. In this case these inline functions are used in external
+ * modules and therefore the use of "inline extern". What this means
+ * is as follows: if a function foo is declared as "inline extern"this
+ * definition is only used for inlining, in no case is the function
+ * compiled on its own. If the compiler cannot inline the function it
+ * becomes an external reference. Therefore in IxQMgrAqmIf.c all
+ * inline functions are defined without the "inline extern" specifier
+ * and so define the external references. In all other modules these
+ * funtions are defined as "inline extern".
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+#ifndef IXQMGRAQMIF_P_H
+#define IXQMGRAQMIF_P_H
+
+#include "IxOsalTypes.h"
+
+/*
+ * inline definition
+ */
+ 
+#ifdef IX_OSAL_INLINE_ALL
+/* If IX_OSAL_INLINE_ALL is set then each inlineable API functions will be defined as
+   inline functions */
+#define IX_QMGR_AQMIF_INLINE IX_OSAL_INLINE_EXTERN
+#else   
+#ifdef IXQMGRAQMIF_C
+#ifndef IX_QMGR_AQMIF_INLINE
+#define IX_QMGR_AQMIF_INLINE
+#endif
+#else  
+#ifndef IX_QMGR_AQMIF_INLINE
+#define IX_QMGR_AQMIF_INLINE IX_OSAL_INLINE_EXTERN
+#endif
+#endif /* IXQMGRAQMIF_C */
+#endif /* IX_OSAL_INLINE */
+
+
+/*
+ * User defined include files.
+ */
+#include "IxQMgr.h"
+#include "IxQMgrLog_p.h"
+#include "IxQMgrQCfg_p.h"
+
+/* Because this file contains inline functions which will be compiled into
+ * other components, we need to ensure that the IX_COMPONENT_NAME define
+ * is set to ix_qmgr while this code is being compiled.  This will ensure
+ * that the correct implementation is provided for the memory access macros
+ * IX_OSAL_READ_LONG and IX_OSAL_WRITE_LONG which are used in this file.
+ * This must be done before including "IxOsalMemAccess.h"
+ */
+#define IX_QMGR_AQMIF_SAVED_COMPONENT_NAME IX_COMPONENT_NAME
+#undef  IX_COMPONENT_NAME
+#define IX_COMPONENT_NAME ix_qmgr
+#include "IxOsal.h" 
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/* Number of bytes per word */
+#define IX_QMGR_NUM_BYTES_PER_WORD 4
+
+/* Underflow bit mask  */
+#define IX_QMGR_UNDERFLOW_BIT_OFFSET    0x0
+
+/* Overflow bit mask */
+#define IX_QMGR_OVERFLOW_BIT_OFFSET     0x1
+
+/* Queue access register, queue 0 */
+#define IX_QMGR_QUEACC0_OFFSET      0x0000
+
+/* Size of queue access register in words */
+#define IX_QMGR_QUEACC_SIZE         0x4/*words*/
+
+/* Queue status register, queues 0-7 */
+#define IX_QMGR_QUELOWSTAT0_OFFSET  (IX_QMGR_QUEACC0_OFFSET +\
+(IX_QMGR_MAX_NUM_QUEUES * IX_QMGR_QUEACC_SIZE * IX_QMGR_NUM_BYTES_PER_WORD))
+
+/* Queue status register, queues 8-15 */
+#define IX_QMGR_QUELOWSTAT1_OFFSET  (IX_QMGR_QUELOWSTAT0_OFFSET +\
+                                     IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue status register, queues 16-23 */
+#define IX_QMGR_QUELOWSTAT2_OFFSET  (IX_QMGR_QUELOWSTAT1_OFFSET +\
+                                     IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue status register, queues 24-31 */
+#define IX_QMGR_QUELOWSTAT3_OFFSET  (IX_QMGR_QUELOWSTAT2_OFFSET +\
+                                     IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue status register Q status bits mask */
+#define IX_QMGR_QUELOWSTAT_QUE_STS_BITS_MASK 0xF
+
+/* Size of queue 0-31 status register */
+#define IX_QMGR_QUELOWSTAT_SIZE     0x4 /*words*/
+
+/* The number of queues' status specified per word */
+#define IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD 0x8
+
+/* Queue UF/OF status register queues 0-15  */
+#define IX_QMGR_QUEUOSTAT0_OFFSET   (IX_QMGR_QUELOWSTAT3_OFFSET +\
+                                     IX_QMGR_NUM_BYTES_PER_WORD)
+/* Queue UF/OF status register queues 16-31 */
+#define IX_QMGR_QUEUOSTAT1_OFFSET   (IX_QMGR_QUEUOSTAT0_OFFSET +\
+                                     IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* The number of queues' underflow/overflow status specified per word */
+#define IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD 0x10
+
+/* Queue NE status register, queues 32-63   */
+#define IX_QMGR_QUEUPPSTAT0_OFFSET  (IX_QMGR_QUEUOSTAT1_OFFSET +\
+                                     IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue F status register, queues 32-63    */
+#define IX_QMGR_QUEUPPSTAT1_OFFSET  (IX_QMGR_QUEUPPSTAT0_OFFSET +\
+                                     IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Size of queue 32-63 status register */
+#define IX_QMGR_QUEUPPSTAT_SIZE     0x2 /*words*/
+
+/* The number of queues' status specified per word */
+#define IX_QMGR_QUEUPPSTAT_NUM_QUE_PER_WORD 0x20
+
+/* Queue INT source select register, queues 0-7   */
+#define IX_QMGR_INT0SRCSELREG0_OFFSET (IX_QMGR_QUEUPPSTAT1_OFFSET   +\
+                                       IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue INT source select register, queues 8-15  */
+#define IX_QMGR_INT0SRCSELREG1_OFFSET (IX_QMGR_INT0SRCSELREG0_OFFSET+\
+                                       IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue INT source select register, queues 16-23 */
+#define IX_QMGR_INT0SRCSELREG2_OFFSET (IX_QMGR_INT0SRCSELREG1_OFFSET+\
+                                       IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue INT source select register, queues 24-31 */
+#define IX_QMGR_INT0SRCSELREG3_OFFSET (IX_QMGR_INT0SRCSELREG2_OFFSET+\
+                                       IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Size of interrupt source select reegister */
+#define IX_QMGR_INT0SRCSELREG_SIZE  0x4 /*words*/
+
+/* The number of queues' interrupt source select specified per word*/
+#define IX_QMGR_INTSRC_NUM_QUE_PER_WORD 0x8
+
+/* Queue INT enable register, queues 0-31  */
+#define IX_QMGR_QUEIEREG0_OFFSET    (IX_QMGR_INT0SRCSELREG3_OFFSET +\
+                                     IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue INT enable register, queues 32-63 */
+#define IX_QMGR_QUEIEREG1_OFFSET    (IX_QMGR_QUEIEREG0_OFFSET      +\
+                                     IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue INT register, queues 0-31  */
+#define IX_QMGR_QINTREG0_OFFSET     (IX_QMGR_QUEIEREG1_OFFSET +\
+                                     IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Queue INT register, queues 32-63 */
+#define IX_QMGR_QINTREG1_OFFSET     (IX_QMGR_QINTREG0_OFFSET  +\
+                                     IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Size of interrupt register */
+#define IX_QMGR_QINTREG_SIZE        0x2 /*words*/
+
+/* Number of queues' status specified per word */
+#define IX_QMGR_QINTREG_NUM_QUE_PER_WORD 0x20
+
+/* Number of bits per queue interrupt status */
+#define IX_QMGR_QINTREG_BITS_PER_QUEUE 0x1
+#define IX_QMGR_QINTREG_BIT_OFFSET 0x1
+
+/* Size of address space not used by AQM */
+#define IX_QMGR_AQM_UNUSED_ADDRESS_SPACE_SIZE_IN_BYTES  0x1bC0
+
+/* Queue config register, queue 0 */
+#define IX_QMGR_QUECONFIG_BASE_OFFSET (IX_QMGR_QINTREG1_OFFSET +\
+                             IX_QMGR_NUM_BYTES_PER_WORD +\
+                             IX_QMGR_AQM_UNUSED_ADDRESS_SPACE_SIZE_IN_BYTES)
+
+/* Total size of configuration words */
+#define IX_QMGR_QUECONFIG_SIZE      0x100
+
+/* Start of SRAM queue buffer space */
+#define IX_QMGR_QUEBUFFER_SPACE_OFFSET (IX_QMGR_QUECONFIG_BASE_OFFSET +\
+                                 IX_QMGR_MAX_NUM_QUEUES * IX_QMGR_NUM_BYTES_PER_WORD)
+
+/* Total bits in a word */
+#define BITS_PER_WORD 32
+
+/* Size of queue buffer space */
+#define IX_QMGR_QUE_BUFFER_SPACE_SIZE 0x1F00
+
+/*
+ * This macro will return the address of the access register for the
+ * queue  specified by qId
+ */
+#define IX_QMGR_Q_ACCESS_ADDR_GET(qId)\
+        (((qId) * (IX_QMGR_QUEACC_SIZE * IX_QMGR_NUM_BYTES_PER_WORD))\
+	 + IX_QMGR_QUEACC0_OFFSET)
+
+/* 
+ * Bit location of bit-3 of INT0SRCSELREG0 register to enabled
+ * sticky interrupt register.
+ */
+#define IX_QMGR_INT0SRCSELREG0_BIT3 3
+
+/*
+ * Variable declerations global to this file. Externs are followed by
+ * statics.
+ */
+extern UINT32 aqmBaseAddress;
+
+/*
+ * Function declarations.
+ */
+void
+ixQMgrAqmIfInit (void);
+
+void
+ixQMgrAqmIfUninit (void);
+
+unsigned
+ixQMgrAqmIfLog2 (unsigned number);
+
+void
+ixQMgrAqmIfQRegisterBitsWrite (IxQMgrQId qId, 
+			       UINT32 registerBaseAddrOffset,
+			       unsigned queuesPerRegWord,
+			       UINT32 value);
+
+void
+ixQMgrAqmIfQStatusCheckValsCalc (IxQMgrQId qId,
+				 IxQMgrSourceId srcSel,
+				 unsigned int *statusWordOffset,
+				 UINT32 *checkValue,
+				 UINT32 *mask);
+/*
+ * The Xscale software allways deals with logical addresses and so the
+ * base address of the AQM memory space is not a hardcoded value. This
+ * function must be called before any other function in this component.
+ * NO CHECKING is performed to ensure that the base address has been
+ * set.
+ */
+void
+ixQMgrAqmIfBaseAddressSet (UINT32 address);
+
+/*
+ * Get the base address of the AQM memory space.
+ */
+void
+ixQMgrAqmIfBaseAddressGet (UINT32 *address);
+
+/*
+ * Get the sram base address
+ */
+void
+ixQMgrAqmIfSramBaseAddressGet (UINT32 *address);
+
+/*
+ * Read a queue status
+ */
+void
+ixQMgrAqmIfQueStatRead (IxQMgrQId qId,
+			IxQMgrQStatus* status);
+
+
+/*
+ *   Set INT0SRCSELREG0 Bit3 
+ */ 
+void ixQMgrAqmIfIntSrcSelReg0Bit3Set (void);
+
+
+/*
+ * Set the interrupt source
+ */
+void
+ixQMgrAqmIfIntSrcSelWrite (IxQMgrQId qId,
+			   IxQMgrSourceId sourceId);
+
+/*
+ * Enable interruptson a queue
+ */
+void
+ixQMgrAqmIfQInterruptEnable (IxQMgrQId qId);
+
+/*
+ * Disable interrupt on a quee
+ */
+void
+ixQMgrAqmIfQInterruptDisable (IxQMgrQId qId);
+
+/*
+ * Write the config register of the specified queue
+ */
+void
+ixQMgrAqmIfQueCfgWrite (IxQMgrQId qId,
+			IxQMgrQSizeInWords qSizeInWords,
+			IxQMgrQEntrySizeInWords entrySizeInWords,
+			UINT32 freeSRAMAddress);
+
+/*
+ * read fields from the config of the specified queue.
+ */
+void
+ixQMgrAqmIfQueCfgRead (IxQMgrQId qId,
+		       unsigned int numEntries,
+		       UINT32 *baseAddress,
+		       unsigned int *ne,
+		       unsigned int *nf,
+		       UINT32 *readPtr,
+		       UINT32 *writePtr);
+
+/*
+ * Set the ne and nf watermark level on a queue.
+ */
+void
+ixQMgrAqmIfWatermarkSet (IxQMgrQId qId,
+			 unsigned ne,
+			 unsigned nf);
+
+/* Inspect an entry without moving the read pointer */
+IX_STATUS
+ixQMgrAqmIfQPeek (IxQMgrQId qId,
+		  unsigned int entryIndex,
+		  unsigned int *entry);
+
+/* Modify an entry without moving the write pointer */
+IX_STATUS
+ixQMgrAqmIfQPoke (IxQMgrQId qId,
+		  unsigned int entryIndex,
+		  unsigned int *entry);
+
+/*
+ * Function prototype for inline functions. For description refers to 
+ * the functions defintion below.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfWordWrite (VUINT32 *address,
+		      UINT32 word);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfWordRead (VUINT32 *address,
+		     UINT32 *word);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQPop (IxQMgrQId qId,
+		 IxQMgrQEntrySizeInWords numWords,
+		 UINT32 *entry);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQPush (IxQMgrQId qId,
+		  IxQMgrQEntrySizeInWords numWords,
+		  UINT32 *entry);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQStatusRegsRead (IxQMgrDispatchGroup group, 
+			    UINT32 *qStatusWords);
+
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfQStatusCheck (UINT32 *oldQStatusWords,
+			 UINT32 *newQStatusWords,
+			 unsigned int statusWordOffset,			 
+			 UINT32 checkValue,
+			 UINT32 mask);
+
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfRegisterBitCheck (IxQMgrQId qId, 
+			     UINT32 registerBaseAddrOffset,
+			     unsigned queuesPerRegWord,
+			     unsigned relativeBitOffset,
+			     BOOL reset);
+
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfUnderflowCheck (IxQMgrQId qId);
+
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfOverflowCheck (IxQMgrQId qId);
+
+IX_QMGR_AQMIF_INLINE UINT32
+ixQMgrAqmIfQRegisterBitsRead (IxQMgrQId qId, 
+			      UINT32 registerBaseAddrOffset,
+			      unsigned queuesPerRegWord);
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQInterruptRegWrite (IxQMgrDispatchGroup group, 
+			       UINT32 reg);
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQInterruptRegRead (IxQMgrDispatchGroup group, 
+			      UINT32 *regVal);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQueLowStatRead (IxQMgrQId qId,
+			   IxQMgrQStatus *status);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQueUppStatRead (IxQMgrQId qId,
+			   IxQMgrQStatus *status);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQueStatRead (IxQMgrQId qId, 
+			IxQMgrQStatus *qStatus);
+
+IX_QMGR_AQMIF_INLINE unsigned
+ixQMgrAqmIfPow2NumDivide (unsigned numerator, 
+			  unsigned denominator);
+
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQInterruptEnableRegRead (IxQMgrDispatchGroup group, 
+			            UINT32 *regVal);
+/*
+ * Inline functions
+ */
+
+/*
+ * This inline function is used by other QMgr components to write one
+ * word to the specified address.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfWordWrite (VUINT32 *address,
+		      UINT32 word)
+{
+    IX_OSAL_WRITE_LONG(address, word);
+}
+
+/*
+ * This inline function is used by other QMgr components to read a
+ * word from the specified address.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfWordRead (VUINT32 *address,
+		     UINT32 *word)
+{
+    *word = IX_OSAL_READ_LONG(address);
+}
+
+
+/*
+ * This inline function is used by other QMgr components to pop an
+ * entry off the specified queue.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQPop (IxQMgrQId qId,
+		 IxQMgrQEntrySizeInWords numWords,
+		 UINT32 *entry)
+{
+    volatile UINT32 *accRegAddr;
+
+    accRegAddr = (UINT32*)(aqmBaseAddress +
+			   IX_QMGR_Q_ACCESS_ADDR_GET(qId));
+
+    switch (numWords)
+    {
+	case IX_QMGR_Q_ENTRY_SIZE1:
+	    ixQMgrAqmIfWordRead (accRegAddr, entry);
+	    break;
+	case IX_QMGR_Q_ENTRY_SIZE2:
+	    ixQMgrAqmIfWordRead (accRegAddr++, entry++);
+	    ixQMgrAqmIfWordRead (accRegAddr, entry);
+	    break;
+	case IX_QMGR_Q_ENTRY_SIZE4:
+	    ixQMgrAqmIfWordRead (accRegAddr++, entry++);
+	    ixQMgrAqmIfWordRead (accRegAddr++, entry++);
+	    ixQMgrAqmIfWordRead (accRegAddr++, entry++);
+	    ixQMgrAqmIfWordRead (accRegAddr, entry);
+	    break;
+	default:
+	    IX_QMGR_LOG_ERROR0("Invalid Q Entry size passed to ixQMgrAqmIfQPop");
+	    break;
+    }
+}
+
+/*
+ * This inline function is used by other QMgr components to push an
+ * entry to the specified queue.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQPush (IxQMgrQId qId,
+		  IxQMgrQEntrySizeInWords numWords,
+		  UINT32 *entry)
+{
+    volatile UINT32 *accRegAddr;
+
+    accRegAddr = (UINT32*)(aqmBaseAddress +
+			   IX_QMGR_Q_ACCESS_ADDR_GET(qId));
+    
+    switch (numWords)
+    {
+	case IX_QMGR_Q_ENTRY_SIZE1:
+	    ixQMgrAqmIfWordWrite (accRegAddr, *entry);
+	    break;
+	case IX_QMGR_Q_ENTRY_SIZE2:
+	    ixQMgrAqmIfWordWrite (accRegAddr++, *entry++);
+	    ixQMgrAqmIfWordWrite (accRegAddr, *entry);
+	    break;
+	case IX_QMGR_Q_ENTRY_SIZE4:
+	    ixQMgrAqmIfWordWrite (accRegAddr++, *entry++);
+	    ixQMgrAqmIfWordWrite (accRegAddr++, *entry++);
+	    ixQMgrAqmIfWordWrite (accRegAddr++, *entry++);
+	    ixQMgrAqmIfWordWrite (accRegAddr, *entry);
+	    break;
+	default:
+	    IX_QMGR_LOG_ERROR0("Invalid Q Entry size passed to ixQMgrAqmIfQPush");
+	    break;
+    }
+}
+
+/*
+ * The AQM interrupt registers contains a bit for each AQM queue
+ * specifying the queue (s) that cause an interrupt to fire. This
+ * function is called by IxQMGrDispatcher component.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQStatusRegsRead (IxQMgrDispatchGroup group, 
+			    UINT32 *qStatusWords)
+{
+    volatile UINT32 *regAddress = NULL;
+
+    if (group == IX_QMGR_QUELOW_GROUP)
+    {
+	regAddress = (UINT32*)(aqmBaseAddress +
+			       IX_QMGR_QUELOWSTAT0_OFFSET);
+
+	ixQMgrAqmIfWordRead (regAddress++, qStatusWords++);
+	ixQMgrAqmIfWordRead (regAddress++, qStatusWords++);
+	ixQMgrAqmIfWordRead (regAddress++, qStatusWords++);
+	ixQMgrAqmIfWordRead (regAddress, qStatusWords);
+    }
+    else /* We have the upper queues */
+    {
+       /* Only need to read the Nearly Empty status register for
+	* queues 32-63 as for therse queues the interrtupt source
+	* condition is fixed to Nearly Empty
+	*/
+	regAddress = (UINT32*)(aqmBaseAddress +
+			       IX_QMGR_QUEUPPSTAT0_OFFSET);
+	ixQMgrAqmIfWordRead (regAddress, qStatusWords);
+    }
+}
+
+
+/*
+ * This function check if the status for a queue has changed between
+ * 2 snapshots and if it has, that the status matches a particular
+ * value after masking.
+ */
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfQStatusCheck (UINT32 *oldQStatusWords,
+			 UINT32 *newQStatusWords,
+			 unsigned int statusWordOffset,			 
+			 UINT32 checkValue,
+			 UINT32 mask)
+{
+    if (((oldQStatusWords[statusWordOffset] & mask) != 
+	 (newQStatusWords[statusWordOffset] & mask)) &&
+	((newQStatusWords[statusWordOffset] & mask) == checkValue))
+    {
+	return true;
+    }
+
+    return false;
+}
+
+/*
+ * The AQM interrupt register contains a bit for each AQM queue
+ * specifying the queue (s) that cause an interrupt to fire. This
+ * function is called by IxQMgrDispatcher component.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQInterruptRegRead (IxQMgrDispatchGroup group, 
+			      UINT32 *regVal)
+{
+    volatile UINT32 *regAddress;
+
+    if (group == IX_QMGR_QUELOW_GROUP)
+    {
+	regAddress = (UINT32*)(aqmBaseAddress +
+			       IX_QMGR_QINTREG0_OFFSET);
+    }
+    else
+    {
+	regAddress = (UINT32*)(aqmBaseAddress +
+			       IX_QMGR_QINTREG1_OFFSET);
+    }
+
+    ixQMgrAqmIfWordRead (regAddress, regVal);
+}
+
+/*
+ * The AQM interrupt enable register contains a bit for each AQM queue.
+ * This function reads the interrupt enable register. This
+ * function is called by IxQMgrDispatcher component.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQInterruptEnableRegRead (IxQMgrDispatchGroup group, 
+			            UINT32 *regVal)
+{
+    volatile UINT32 *regAddress;
+
+    if (group == IX_QMGR_QUELOW_GROUP)
+    {
+	regAddress = (UINT32*)(aqmBaseAddress +
+			       IX_QMGR_QUEIEREG0_OFFSET);
+    }
+    else
+    {
+	regAddress = (UINT32*)(aqmBaseAddress +
+			       IX_QMGR_QUEIEREG1_OFFSET);
+    }
+
+    ixQMgrAqmIfWordRead (regAddress, regVal);
+}
+
+
+/*
+ * This inline function will read the status bit of a queue
+ * specified by qId. If reset is true the bit is cleared.
+ */
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfRegisterBitCheck (IxQMgrQId qId, 
+			     UINT32 registerBaseAddrOffset,
+			     unsigned queuesPerRegWord,
+			     unsigned relativeBitOffset,
+			     BOOL reset)
+{
+    UINT32 actualBitOffset;
+    volatile UINT32 *registerAddress;
+    UINT32 registerWord;
+
+    /*
+     * Calculate the registerAddress
+     * multiple queues split accross registers
+     */
+    registerAddress = (UINT32*)(aqmBaseAddress +
+				registerBaseAddrOffset +
+				((qId / queuesPerRegWord) *
+				 IX_QMGR_NUM_BYTES_PER_WORD));
+
+    /*
+     * Get the status word
+     */
+    ixQMgrAqmIfWordRead (registerAddress, &registerWord);
+    
+    /*
+     * Calculate the actualBitOffset
+     * status for multiple queues stored in one register
+     */
+    actualBitOffset = (relativeBitOffset + 1) <<
+	((qId & (queuesPerRegWord - 1)) * (BITS_PER_WORD / queuesPerRegWord));
+
+    /* Check if the status bit is set */
+    if (registerWord & actualBitOffset)
+    {
+	/* Clear the bit if reset */
+	if (reset)
+	{
+	    ixQMgrAqmIfWordWrite (registerAddress, registerWord & (~actualBitOffset));
+	}
+	return true;
+    }
+
+    /* Bit not set */
+    return false;
+}
+
+
+/*
+ * @ingroup IxQmgrAqmIfAPI
+ *
+ * @brief Read the underflow status of a queue 
+ *
+ * This inline function will read the underflow status of a queue
+ * specified by qId.
+ * 
+ */
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfUnderflowCheck (IxQMgrQId qId)
+{
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {
+	return (ixQMgrAqmIfRegisterBitCheck (qId,
+					     IX_QMGR_QUEUOSTAT0_OFFSET,
+					     IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD,
+					     IX_QMGR_UNDERFLOW_BIT_OFFSET,
+					     true/*reset*/));
+    }
+    else
+    {
+	/* Qs 32-63 have no underflow status */
+	return false;
+    }
+}
+
+/*
+ * This inline function will read the overflow status of a queue
+ * specified by qId.
+ */
+IX_QMGR_AQMIF_INLINE BOOL
+ixQMgrAqmIfOverflowCheck (IxQMgrQId qId)
+{
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {
+	return (ixQMgrAqmIfRegisterBitCheck (qId,
+					     IX_QMGR_QUEUOSTAT0_OFFSET,
+					     IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD,
+					     IX_QMGR_OVERFLOW_BIT_OFFSET,
+					     true/*reset*/));
+    }
+    else
+    {
+	/* Qs 32-63 have no overflow status */
+	return false;
+    }
+}
+
+/*
+ * This inline function will read the status bits of a queue
+ * specified by qId.
+ */
+IX_QMGR_AQMIF_INLINE UINT32
+ixQMgrAqmIfQRegisterBitsRead (IxQMgrQId qId, 
+			      UINT32 registerBaseAddrOffset,
+			      unsigned queuesPerRegWord)
+{
+    volatile UINT32 *registerAddress;
+    UINT32 registerWord;
+    UINT32 statusBitsMask;
+    UINT32 bitsPerQueue;
+
+    bitsPerQueue = BITS_PER_WORD / queuesPerRegWord;
+
+    /*
+     * Calculate the registerAddress
+     * multiple queues split accross registers
+     */
+    registerAddress = (UINT32*)(aqmBaseAddress +
+				registerBaseAddrOffset +
+				((qId / queuesPerRegWord) *
+				 IX_QMGR_NUM_BYTES_PER_WORD));
+    /*
+     * Read the status word
+     */
+    ixQMgrAqmIfWordRead (registerAddress, &registerWord);
+    
+
+    /*
+     * Calculate the mask for the status bits for this queue.
+     */
+    statusBitsMask = ((1 << bitsPerQueue) - 1);
+
+    /*
+     * Shift the status word so it is right justified
+     */    
+    registerWord >>= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue);
+
+    /*
+     * Mask out all bar the status bits for this queue
+     */
+    return (registerWord &= statusBitsMask);
+}
+
+/*
+ * This function is called by IxQMgrDispatcher to set the contents of
+ * the AQM interrupt register.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQInterruptRegWrite (IxQMgrDispatchGroup group, 
+			       UINT32 reg)
+{
+    volatile UINT32 *address;
+
+    if (group == IX_QMGR_QUELOW_GROUP)
+    {
+	address = (UINT32*)(aqmBaseAddress +
+			    IX_QMGR_QINTREG0_OFFSET);
+    }
+    else
+    {
+	address = (UINT32*)(aqmBaseAddress +
+			    IX_QMGR_QINTREG1_OFFSET);
+    }
+
+    ixQMgrAqmIfWordWrite (address, reg);
+}
+
+/*
+ * Read the status of a queue in the range 0-31.
+ *
+ * This function is used by other QMgr components to read the
+ * status of the queue specified by qId.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQueLowStatRead (IxQMgrQId qId,
+			   IxQMgrQStatus *status)
+{
+    /* Read the general status bits */
+    *status = ixQMgrAqmIfQRegisterBitsRead (qId,
+					    IX_QMGR_QUELOWSTAT0_OFFSET,
+					    IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD);
+}
+
+/*
+ * This function will read the status of the queue specified
+ * by qId.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQueUppStatRead (IxQMgrQId qId,
+			   IxQMgrQStatus *status)
+{
+    /* Reset the status bits */
+    *status = 0;
+
+    /* 
+     * Check if the queue is nearly empty,
+     * N.b. QUPP stat register contains status for regs 32-63 at each
+     *      bit position so subtract 32 to get bit offset
+     */
+    if (ixQMgrAqmIfRegisterBitCheck ((qId - IX_QMGR_MIN_QUEUPP_QID),
+				     IX_QMGR_QUEUPPSTAT0_OFFSET,
+				     IX_QMGR_QUEUPPSTAT_NUM_QUE_PER_WORD,
+				     0/*relativeBitOffset*/,
+				     false/*!reset*/))
+    {
+	*status |= IX_QMGR_Q_STATUS_NE_BIT_MASK;
+    }
+
+    /* 
+     * Check if the queue is full,
+     * N.b. QUPP stat register contains status for regs 32-63 at each
+     *      bit position so subtract 32 to get bit offset
+     */
+    if (ixQMgrAqmIfRegisterBitCheck ((qId - IX_QMGR_MIN_QUEUPP_QID),
+				     IX_QMGR_QUEUPPSTAT1_OFFSET,
+				     IX_QMGR_QUEUPPSTAT_NUM_QUE_PER_WORD,
+				     0/*relativeBitOffset*/,
+				     false/*!reset*/))
+    {
+	*status |= IX_QMGR_Q_STATUS_F_BIT_MASK;
+    }
+}
+
+/*
+ * This function is used by other QMgr components to read the
+ * status of the queue specified by qId.
+ */
+IX_QMGR_AQMIF_INLINE void
+ixQMgrAqmIfQueStatRead (IxQMgrQId qId, 
+			IxQMgrQStatus *qStatus)
+{
+    if (qId < IX_QMGR_MIN_QUEUPP_QID)
+    {
+	ixQMgrAqmIfQueLowStatRead (qId, qStatus);
+    }
+    else
+    {
+	ixQMgrAqmIfQueUppStatRead (qId, qStatus);
+    }
+}
+
+
+/*
+ * This function performs a mod division
+ */
+IX_QMGR_AQMIF_INLINE unsigned
+ixQMgrAqmIfPow2NumDivide (unsigned numerator, 
+			  unsigned denominator)
+{
+    /* Number is evenly divisable by 2 */
+    return (numerator >> ixQMgrAqmIfLog2 (denominator));
+}
+
+/* Restore IX_COMPONENT_NAME */
+#undef IX_COMPONENT_NAME
+#define IX_COMPONENT_NAME IX_QMGR_AQMIF_SAVED_COMPONENT_NAME
+
+#endif/*IXQMGRAQMIF_P_H*/
diff --git a/marvell/uboot/drivers/net/npe/include/IxQMgrDefines_p.h b/marvell/uboot/drivers/net/npe/include/IxQMgrDefines_p.h
new file mode 100644
index 0000000..1c5d674
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxQMgrDefines_p.h
@@ -0,0 +1,31 @@
+/**
+ * @file    IxQMgrDefines_p.h
+ *
+ * @author Intel Corporation
+ * @date    19-Jul-2002
+ *
+ * @brief   IxQMgr Defines and tuneable constants
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+#ifndef IXQMGRDEFINES_P_H
+#define IXQMGRDEFINES_P_H
+
+#define IX_QMGR_PARM_CHECKS_ENABLED   1
+#define IX_QMGR_STATS_UPDATE_ENABLED  1
+
+#endif /* IXQMGRDEFINES_P_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxQMgrDispatcher_p.h b/marvell/uboot/drivers/net/npe/include/IxQMgrDispatcher_p.h
new file mode 100644
index 0000000..b68a3f1
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxQMgrDispatcher_p.h
@@ -0,0 +1,82 @@
+/**
+ * @file    IxQMgrDispatcher_p.h
+ *
+ * @author Intel Corporation
+ * @date    07-Feb-2002
+ *
+ * @brief   This file contains the internal functions for dispatcher
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+#ifndef IXQMGRDISPATCHER_P_H
+#define IXQMGRDISPATCHER_P_H
+
+/*
+ * User defined include files
+ */
+#include "IxQMgr.h"
+
+/*
+ * This structure defines the statistic data for a queue
+ */
+typedef struct
+{
+    unsigned callbackCnt;       /* Call count of callback                    */
+    unsigned priorityChangeCnt; /* Priority change count                     */
+    unsigned intNoCallbackCnt;  /* Interrupt fired but no callback set count */
+    unsigned intLostCallbackCnt;  /* Interrupt lost and detected ;  SCR541   */
+    BOOL notificationEnabled;    /* Interrupt enabled for this queue         */
+    IxQMgrSourceId srcSel;       /* interrupt source                         */
+    unsigned enableCount;        /* num times notif enabled by LLP           */
+    unsigned disableCount;       /* num of times notif disabled by LLP       */
+} IxQMgrDispatcherQStats;
+
+/*
+ * This structure defines statistic data for the disatcher
+ */
+typedef struct
+ {
+    unsigned loopRunCnt;       /* ixQMgrDispatcherLoopRun count */
+
+    IxQMgrDispatcherQStats queueStats[IX_QMGR_MAX_NUM_QUEUES];
+
+} IxQMgrDispatcherStats;
+
+/*
+ * Initialise the dispatcher component
+ */
+void
+ixQMgrDispatcherInit (void);
+
+/*
+ * Get the dispatcher statistics
+ */
+IxQMgrDispatcherStats*
+ixQMgrDispatcherStatsGet (void);
+
+/**
+ * Retrieve the number of leading zero bits starting from the MSB 
+ * This function is implemented as an (extremely fast) asm routine 
+ * for XSCALE processor (see clz instruction) and as a (slower) C 
+ * function for other systems.
+ */
+unsigned int
+ixQMgrCountLeadingZeros(unsigned int value);
+
+#endif/*IXQMGRDISPATCHER_P_H*/
+
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxQMgrLog_p.h b/marvell/uboot/drivers/net/npe/include/IxQMgrLog_p.h
new file mode 100644
index 0000000..941236a
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxQMgrLog_p.h
@@ -0,0 +1,100 @@
+/**
+ * @file    IxQMgrLog_p.h
+ *
+ * @author Intel Corporation
+ * @date    07-Feb-2002
+ *
+ * @brief   This file contains the internal functions for config
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+#ifndef IXQMGRLOG_P_H
+#define IXQMGRLOG_P_H
+
+/*
+ * User defined header files
+ */
+#include "IxOsal.h"
+
+/*
+ * Macros
+ */
+
+#define IX_QMGR_LOG0(string) do\
+{\
+    ixOsalLog(IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, string, 0, 0, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG1(string, arg1) do\
+{\
+    ixOsalLog(IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, string, (int)arg1, 0, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG2(string, arg1, arg2) do\
+{\
+    ixOsalLog(IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, string, (int)arg1, (int)arg2, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG3(string, arg1, arg2, arg3) do\
+{\
+    ixOsalLog(IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, string, (int)arg1, (int)arg2, (int)arg3, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG6(string, arg1, arg2, arg3, arg4, arg5, arg6) do\
+{\
+    ixOsalLog(IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, string, (int)arg1, (int)arg2, (int)arg3, (int)arg4, (int)arg5, (int)arg6); \
+}while(0);
+
+#define IX_QMGR_LOG_WARNING0(string) do\
+{\
+    ixOsalLog(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, string, 0, 0, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG_WARNING1(string, arg1) do\
+{\
+    ixOsalLog(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, string, (int)arg1, 0, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG_WARNING2(string, arg1, arg2) do\
+{\
+    ixOsalLog(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, string, (int)arg1, (int)arg2, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG_ERROR0(string) do\
+{\
+    ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, string, 0, 0, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG_ERROR1(string, arg1) do\
+{\
+    ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, string, (int)arg1, 0, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG_ERROR2(string, arg1, arg2) do\
+{\
+    ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, string, (int)arg1, (int)arg2, 0, 0, 0, 0);\
+}while(0);
+
+#define IX_QMGR_LOG_ERROR3(string, arg1, arg2, arg3) do\
+{\
+    ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, string, (int)arg1, (int)arg2, (int)arg3, 0, 0, 0);\
+}while(0);
+#endif /* IX_QMGRLOG_P_H */
+
+
+
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxQMgrQAccess_p.h b/marvell/uboot/drivers/net/npe/include/IxQMgrQAccess_p.h
new file mode 100644
index 0000000..363622f
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxQMgrQAccess_p.h
@@ -0,0 +1,72 @@
+/**
+ * @file    IxQMgrQAccess_p.h
+ *
+ * @author Intel Corporation
+ * @date    30-Oct-2001
+ *
+ * @brief   QAccess private header file
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+#ifndef IXQMGRQACCESS_P_H
+#define IXQMGRQACCESS_P_H
+
+/*
+ * User defined header files
+ */
+#include "IxQMgr.h"
+
+/* 
+ * Global variables declarations.
+ */
+extern volatile UINT32 * ixQMgrAqmIfQueAccRegAddr[]; 
+
+/* 
+ * Initialise the Queue Access component
+ */
+void
+ixQMgrQAccessInit (void);
+
+/*
+ * read the remainder of a multi-word queue entry 
+ * (the first word is already read)
+ */
+IX_STATUS
+ixQMgrQReadMWordsMinus1 (IxQMgrQId qId,
+                         UINT32 *entry);
+
+/*
+ * Fast access : pop a q entry from a single word queue
+ */
+extern __inline__ UINT32 ixQMgrQAccessPop(IxQMgrQId qId);
+
+extern __inline__ UINT32 ixQMgrQAccessPop(IxQMgrQId qId)
+{
+  return *(ixQMgrAqmIfQueAccRegAddr[qId]);
+}
+
+/*
+ * Fast access : push a q entry in a single word queue
+ */
+extern __inline__ void ixQMgrQAccessPush(IxQMgrQId qId, UINT32 entry);
+
+extern __inline__ void ixQMgrQAccessPush(IxQMgrQId qId, UINT32 entry)
+{
+  *(ixQMgrAqmIfQueAccRegAddr[qId]) = entry;
+}
+
+#endif/*IXQMGRQACCESS_P_H*/
diff --git a/marvell/uboot/drivers/net/npe/include/IxQMgrQCfg_p.h b/marvell/uboot/drivers/net/npe/include/IxQMgrQCfg_p.h
new file mode 100644
index 0000000..5480214
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxQMgrQCfg_p.h
@@ -0,0 +1,98 @@
+/**
+ * @file    IxQMgrQCfg_p.h
+ *
+ * @author Intel Corporation
+ * @date    07-Feb-2002
+ *
+ * @brief   This file contains the internal functions for config
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+#ifndef IXQMGRQCFG_P_H
+#define IXQMGRQCFG_P_H
+
+/*
+ * User defined header files
+ */
+#include "IxQMgr.h"
+
+/*
+ * Typedefs
+ */
+typedef struct
+{
+    unsigned wmSetCnt;    
+
+    struct
+    {
+	char *qName;
+	BOOL isConfigured;	
+	unsigned int qSizeInWords;
+	unsigned int qEntrySizeInWords;
+	unsigned int ne;
+	unsigned int nf;
+	unsigned int numEntries;
+	UINT32 baseAddress;
+	UINT32 readPtr;
+	UINT32 writePtr;
+    } qStats[IX_QMGR_MAX_NUM_QUEUES];
+
+} IxQMgrQCfgStats;
+
+/*
+ * Initialize the QCfg subcomponent
+ */ 
+void
+ixQMgrQCfgInit (void);
+
+/*
+ * Uninitialize the QCfg subcomponent
+ */ 
+void
+ixQMgrQCfgUninit (void);
+
+/*
+ * Get the Q size in words
+ */ 
+IxQMgrQSizeInWords
+ixQMgrQSizeInWordsGet (IxQMgrQId qId);
+
+/*
+ * Get the Q entry size in words
+ */ 
+IxQMgrQEntrySizeInWords
+ixQMgrQEntrySizeInWordsGet (IxQMgrQId qId);
+
+/*
+ * Get the generic cfg stats
+ */
+IxQMgrQCfgStats*
+ixQMgrQCfgStatsGet (void);
+
+/*
+ * Get queue specific stats
+ */
+IxQMgrQCfgStats*
+ixQMgrQCfgQStatsGet (IxQMgrQId qId);
+
+/*
+ * Check is the queue configured
+ */
+BOOL
+ixQMgrQIsConfigured(IxQMgrQId qId);
+ 
+#endif /* IX_QMGRQCFG_P_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxQueueAssignments.h b/marvell/uboot/drivers/net/npe/include/IxQueueAssignments.h
new file mode 100644
index 0000000..28b9247
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxQueueAssignments.h
@@ -0,0 +1,492 @@
+/**
+ * @file IxQueueAssignments.h
+ *
+ * @author Intel Corporation
+ * @date 29-Oct-2004
+ *
+ * @brief Central definition for queue assignments
+ *
+ * Design Notes:
+ * This file contains queue assignments used by Ethernet (EthAcc),
+ * HSS (HssAcc), ATM (atmdAcc) and DMA (dmaAcc) access libraries.
+ *
+ * Note: Ethernet QoS traffic class definitions are managed separately
+ * by EthDB in IxEthDBQoS.h.
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+#ifndef IxQueueAssignments_H
+#define IxQueueAssignments_H
+
+#include "IxQMgr.h"
+
+/***************************************************************************
+ *  Queue assignments for ATM
+ ***************************************************************************/
+
+/** 
+ * @brief Global compiler switch to select between 3 possible NPE Modes
+ * Define this macro to enable MPHY mode
+ *
+ * Default(No Switch) = MultiPHY Utopia2
+ * IX_UTOPIAMODE = 1 for single Phy Utopia1
+ * IX_MPHYSINGLEPORT = 1 for single Phy Utopia2 
+ */
+#define IX_NPE_MPHYMULTIPORT 1
+#if IX_UTOPIAMODE == 1
+#undef  IX_NPE_MPHYMULTIPORT
+#endif
+#if IX_MPHYSINGLEPORT == 1
+#undef  IX_NPE_MPHYMULTIPORT
+#endif
+
+/**
+ * @def IX_NPE_A_TXDONE_QUEUE_HIGHWATERMARK
+ *
+ * @brief The NPE reserves the High Watermark for its operation. But it must be set by the Xscale
+ */
+#define IX_NPE_A_TXDONE_QUEUE_HIGHWATERMARK  2
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_TX_DONE
+ *
+ * @brief Queue ID for ATM Transmit Done queue
+ */
+#define IX_NPE_A_QMQ_ATM_TX_DONE       IX_QMGR_QUEUE_1
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_TX0
+ *
+ * @brief Queue ID for ATM transmit Queue in a single phy configuration
+ */
+#define IX_NPE_A_QMQ_ATM_TX0           IX_QMGR_QUEUE_2
+
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_TXID_MIN
+ *
+ * @brief Queue Manager Queue ID for ATM transmit Queue with minimum number of queue
+ *
+ */
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_TXID_MAX
+ *
+ * @brief Queue Manager Queue ID for ATM transmit Queue with maximum number of queue
+ *
+ */
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_RX_HI
+ *
+ * @brief Queue Manager Queue ID for ATM Receive high Queue
+ *
+ */
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_RX_LO
+ *
+ * @brief Queue Manager Queue ID for ATM Receive low Queue
+ */
+
+#ifdef IX_NPE_MPHYMULTIPORT
+/**
+ * @def IX_NPE_A_QMQ_ATM_TX1
+ *
+ * @brief Queue ID for ATM transmit Queue Multiphy from 1 to 11
+ */
+#define IX_NPE_A_QMQ_ATM_TX1           IX_NPE_A_QMQ_ATM_TX0+1
+#define IX_NPE_A_QMQ_ATM_TX2           IX_NPE_A_QMQ_ATM_TX1+1
+#define IX_NPE_A_QMQ_ATM_TX3           IX_NPE_A_QMQ_ATM_TX2+1
+#define IX_NPE_A_QMQ_ATM_TX4           IX_NPE_A_QMQ_ATM_TX3+1
+#define IX_NPE_A_QMQ_ATM_TX5           IX_NPE_A_QMQ_ATM_TX4+1
+#define IX_NPE_A_QMQ_ATM_TX6           IX_NPE_A_QMQ_ATM_TX5+1
+#define IX_NPE_A_QMQ_ATM_TX7           IX_NPE_A_QMQ_ATM_TX6+1
+#define IX_NPE_A_QMQ_ATM_TX8           IX_NPE_A_QMQ_ATM_TX7+1
+#define IX_NPE_A_QMQ_ATM_TX9           IX_NPE_A_QMQ_ATM_TX8+1
+#define IX_NPE_A_QMQ_ATM_TX10          IX_NPE_A_QMQ_ATM_TX9+1
+#define IX_NPE_A_QMQ_ATM_TX11          IX_NPE_A_QMQ_ATM_TX10+1
+#define IX_NPE_A_QMQ_ATM_TXID_MIN      IX_NPE_A_QMQ_ATM_TX0
+#define IX_NPE_A_QMQ_ATM_TXID_MAX      IX_NPE_A_QMQ_ATM_TX11
+#define IX_NPE_A_QMQ_ATM_RX_HI         IX_QMGR_QUEUE_21
+#define IX_NPE_A_QMQ_ATM_RX_LO         IX_QMGR_QUEUE_22
+#else
+#define IX_NPE_A_QMQ_ATM_TXID_MIN      IX_NPE_A_QMQ_ATM_TX0
+#define IX_NPE_A_QMQ_ATM_TXID_MAX      IX_NPE_A_QMQ_ATM_TX0
+#define IX_NPE_A_QMQ_ATM_RX_HI         IX_QMGR_QUEUE_10
+#define IX_NPE_A_QMQ_ATM_RX_LO         IX_QMGR_QUEUE_11
+#endif /* MPHY */
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_FREE_VC0
+ *
+ * @brief Hardware QMgr Queue ID for ATM Free VC Queue.
+ *
+ * There are 32 Hardware QMgr Queue ID; from IX_NPE_A_QMQ_ATM_FREE_VC1 to
+ * IX_NPE_A_QMQ_ATM_FREE_VC30
+ */
+#define IX_NPE_A_QMQ_ATM_FREE_VC0      IX_QMGR_QUEUE_32
+#define IX_NPE_A_QMQ_ATM_FREE_VC1      IX_NPE_A_QMQ_ATM_FREE_VC0+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC2      IX_NPE_A_QMQ_ATM_FREE_VC1+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC3      IX_NPE_A_QMQ_ATM_FREE_VC2+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC4      IX_NPE_A_QMQ_ATM_FREE_VC3+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC5      IX_NPE_A_QMQ_ATM_FREE_VC4+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC6      IX_NPE_A_QMQ_ATM_FREE_VC5+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC7      IX_NPE_A_QMQ_ATM_FREE_VC6+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC8      IX_NPE_A_QMQ_ATM_FREE_VC7+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC9      IX_NPE_A_QMQ_ATM_FREE_VC8+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC10     IX_NPE_A_QMQ_ATM_FREE_VC9+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC11     IX_NPE_A_QMQ_ATM_FREE_VC10+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC12     IX_NPE_A_QMQ_ATM_FREE_VC11+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC13     IX_NPE_A_QMQ_ATM_FREE_VC12+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC14     IX_NPE_A_QMQ_ATM_FREE_VC13+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC15     IX_NPE_A_QMQ_ATM_FREE_VC14+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC16     IX_NPE_A_QMQ_ATM_FREE_VC15+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC17     IX_NPE_A_QMQ_ATM_FREE_VC16+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC18     IX_NPE_A_QMQ_ATM_FREE_VC17+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC19     IX_NPE_A_QMQ_ATM_FREE_VC18+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC20     IX_NPE_A_QMQ_ATM_FREE_VC19+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC21     IX_NPE_A_QMQ_ATM_FREE_VC20+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC22     IX_NPE_A_QMQ_ATM_FREE_VC21+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC23     IX_NPE_A_QMQ_ATM_FREE_VC22+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC24     IX_NPE_A_QMQ_ATM_FREE_VC23+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC25     IX_NPE_A_QMQ_ATM_FREE_VC24+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC26     IX_NPE_A_QMQ_ATM_FREE_VC25+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC27     IX_NPE_A_QMQ_ATM_FREE_VC26+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC28     IX_NPE_A_QMQ_ATM_FREE_VC27+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC29     IX_NPE_A_QMQ_ATM_FREE_VC28+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC30     IX_NPE_A_QMQ_ATM_FREE_VC29+1
+#define IX_NPE_A_QMQ_ATM_FREE_VC31     IX_NPE_A_QMQ_ATM_FREE_VC30+1
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_RXFREE_MIN
+ *
+ * @brief The minimum queue ID for FreeVC queue
+ */
+#define IX_NPE_A_QMQ_ATM_RXFREE_MIN  IX_NPE_A_QMQ_ATM_FREE_VC0
+
+/**
+ * @def IX_NPE_A_QMQ_ATM_RXFREE_MAX
+ *
+ * @brief The maximum queue ID for FreeVC queue
+ */
+#define IX_NPE_A_QMQ_ATM_RXFREE_MAX  IX_NPE_A_QMQ_ATM_FREE_VC31
+
+/**
+ * @def IX_NPE_A_QMQ_OAM_FREE_VC
+ * @brief OAM Rx Free queue ID
+ */
+#ifdef IX_NPE_MPHYMULTIPORT
+#define IX_NPE_A_QMQ_OAM_FREE_VC       IX_QMGR_QUEUE_14
+#else
+#define IX_NPE_A_QMQ_OAM_FREE_VC       IX_QMGR_QUEUE_3
+#endif /* MPHY */
+
+/****************************************************************************
+ * Queue assignments for HSS
+ ****************************************************************************/
+
+/****  HSS Port 0 ****/
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_CHL_RX_TRIG
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Channelized Receive trigger
+ */
+#define IX_NPE_A_QMQ_HSS0_CHL_RX_TRIG   IX_QMGR_QUEUE_12
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_RX
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Receive
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_RX        IX_QMGR_QUEUE_13
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_TX0
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Transmit queue 0
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_TX0       IX_QMGR_QUEUE_14
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_TX1
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Transmit queue 1
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_TX1       IX_QMGR_QUEUE_15
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_TX2
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Transmit queue 2
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_TX2       IX_QMGR_QUEUE_16
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_TX3
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Transmit queue 3
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_TX3       IX_QMGR_QUEUE_17
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_RX_FREE0
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Receive Free queue 0
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_RX_FREE0  IX_QMGR_QUEUE_18
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_RX_FREE1
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Receive Free queue 1
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_RX_FREE1  IX_QMGR_QUEUE_19
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_RX_FREE2
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Receive Free queue 2
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_RX_FREE2  IX_QMGR_QUEUE_20
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_RX_FREE3
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Receive Free queue 3
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_RX_FREE3  IX_QMGR_QUEUE_21
+
+/**
+ * @def IX_NPE_A_QMQ_HSS0_PKT_TX_DONE
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 0 Packetized Transmit Done queue
+ */
+#define IX_NPE_A_QMQ_HSS0_PKT_TX_DONE   IX_QMGR_QUEUE_22
+
+/****  HSS Port 1 ****/
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_CHL_RX_TRIG
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Channelized Receive trigger
+ */
+#define IX_NPE_A_QMQ_HSS1_CHL_RX_TRIG   IX_QMGR_QUEUE_10
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_RX
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Receive
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_RX        IX_QMGR_QUEUE_0
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_TX0
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Transmit queue 0
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_TX0       IX_QMGR_QUEUE_5
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_TX1
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Transmit queue 1
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_TX1       IX_QMGR_QUEUE_6
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_TX2
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Transmit queue 2
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_TX2       IX_QMGR_QUEUE_7
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_TX3
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Transmit queue 3
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_TX3       IX_QMGR_QUEUE_8
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_RX_FREE0
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Receive Free queue 0
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_RX_FREE0  IX_QMGR_QUEUE_1
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_RX_FREE1
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Receive Free queue 1
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_RX_FREE1  IX_QMGR_QUEUE_2
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_RX_FREE2
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Receive Free queue 2
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_RX_FREE2  IX_QMGR_QUEUE_3
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_RX_FREE3
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Receive Free queue 3
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_RX_FREE3  IX_QMGR_QUEUE_4
+
+/**
+ * @def IX_NPE_A_QMQ_HSS1_PKT_TX_DONE
+ *
+ * @brief Hardware QMgr Queue ID for HSS Port 1 Packetized Transmit Done queue
+ */
+#define IX_NPE_A_QMQ_HSS1_PKT_TX_DONE   IX_QMGR_QUEUE_9
+
+/*****************************************************************************************
+ * Queue assignments for DMA
+ *****************************************************************************************/
+
+#define IX_DMA_NPE_A_REQUEST_QID IX_QMGR_QUEUE_19   /**< Queue Id for NPE A DMA Request */
+#define IX_DMA_NPE_A_DONE_QID    IX_QMGR_QUEUE_20   /**< Queue Id for NPE A DMA Done    */
+#define IX_DMA_NPE_B_REQUEST_QID IX_QMGR_QUEUE_24   /**< Queue Id for NPE B DMA Request */
+#define IX_DMA_NPE_B_DONE_QID    IX_QMGR_QUEUE_26   /**< Queue Id for NPE B DMA Done    */
+#define IX_DMA_NPE_C_REQUEST_QID IX_QMGR_QUEUE_25   /**< Queue Id for NPE C DMA Request */
+#define IX_DMA_NPE_C_DONE_QID    IX_QMGR_QUEUE_27   /**< Queue Id for NPE C DMA Done    */
+
+
+/*****************************************************************************************
+ * Queue assignments for Ethernet
+ *
+ * Note: Rx queue definitions, which include QoS traffic class definitions
+ * are managed by EthDB and declared in IxEthDBQoS.h
+ *****************************************************************************************/
+
+/**
+*
+* @def IX_ETH_ACC_RX_FRAME_ETH_Q 
+*
+* @brief  Eth0/Eth1 NPE Frame Receive Q.
+*
+* @note THIS IS NOT USED - the Rx queues are read from EthDB QoS configuration
+* 
+*/
+#define IX_ETH_ACC_RX_FRAME_ETH_Q	(IX_QMGR_QUEUE_4)
+
+/**
+*
+* @def IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q
+*
+* @brief Supply Rx Buffers Ethernet Q for NPEB - Eth 0 - Port 1
+*
+*/
+#define IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q    (IX_QMGR_QUEUE_27)
+
+/**
+*
+* @def IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q
+*
+* @brief Supply Rx Buffers Ethernet Q for NPEC - Eth 1 - Port 2
+*
+*/
+#define IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q    (IX_QMGR_QUEUE_28)
+
+/**
+*
+* @def IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q
+*
+* @brief Supply Rx Buffers Ethernet Q for NPEA - Eth 2 - Port 3
+*
+*/
+#define IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q    (IX_QMGR_QUEUE_26)
+
+
+/**
+*
+* @def IX_ETH_ACC_TX_FRAME_ENET0_Q
+*
+* @brief Submit frame Q for NPEB Eth 0 - Port 1
+*
+*/
+#define IX_ETH_ACC_TX_FRAME_ENET0_Q    (IX_QMGR_QUEUE_24)
+
+
+/**
+*
+* @def IX_ETH_ACC_TX_FRAME_ENET1_Q
+*
+* @brief Submit frame Q for NPEC Eth 1 - Port 2
+*
+*/
+#define IX_ETH_ACC_TX_FRAME_ENET1_Q    (IX_QMGR_QUEUE_25)
+
+/**
+*
+* @def IX_ETH_ACC_TX_FRAME_ENET2_Q
+*
+* @brief Submit frame Q for NPEA Eth 2 - Port 3
+*
+*/
+#define IX_ETH_ACC_TX_FRAME_ENET2_Q    (IX_QMGR_QUEUE_23)
+
+/**
+*
+* @def IX_ETH_ACC_TX_FRAME_DONE_ETH_Q
+*
+* @brief Transmit complete Q for NPE Eth 0/1, Port 1&2
+*
+*/
+#define IX_ETH_ACC_TX_FRAME_DONE_ETH_Q    (IX_QMGR_QUEUE_31)
+
+/*****************************************************************************************
+ * Queue assignments for Crypto
+ *****************************************************************************************/
+
+/** Crypto Service Request Queue */
+#define IX_CRYPTO_ACC_CRYPTO_REQ_Q  (IX_QMGR_QUEUE_29)
+
+/** Crypto Service Done Queue */
+#define IX_CRYPTO_ACC_CRYPTO_DONE_Q (IX_QMGR_QUEUE_30)
+
+/** Crypto Req Q CB tag */
+#define IX_CRYPTO_ACC_CRYPTO_REQ_Q_CB_TAG   (0)
+
+/** Crypto Done Q CB tag */
+#define IX_CRYPTO_ACC_CRYPTO_DONE_Q_CB_TAG  (1)
+
+/** WEP Service Request Queue */
+#define IX_CRYPTO_ACC_WEP_REQ_Q  (IX_QMGR_QUEUE_21)
+
+/** WEP Service Done Queue */
+#define IX_CRYPTO_ACC_WEP_DONE_Q (IX_QMGR_QUEUE_22)
+
+/** WEP Req Q CB tag */
+#define IX_CRYPTO_ACC_WEP_REQ_Q_CB_TAG      (2)
+
+/** WEP Done Q CB tag */
+#define IX_CRYPTO_ACC_WEP_DONE_Q_CB_TAG     (3)
+
+/** Number of queues allocate to crypto hardware accelerator services */
+#define IX_CRYPTO_ACC_NUM_OF_CRYPTO_Q       (2)
+
+/** Number of queues allocate to WEP NPE services */
+#define IX_CRYPTO_ACC_NUM_OF_WEP_NPE_Q      (2)
+                                                      
+/** Number of queues allocate to CryptoAcc component */
+#define IX_CRYPTO_ACC_NUM_OF_Q (IX_CRYPTO_ACC_NUM_OF_CRYPTO_Q + IX_CRYPTO_ACC_NUM_OF_WEP_NPE_Q)   
+
+#endif /* IxQueueAssignments_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxSspAcc.h b/marvell/uboot/drivers/net/npe/include/IxSspAcc.h
new file mode 100644
index 0000000..b4a9def
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxSspAcc.h
@@ -0,0 +1,1247 @@
+/**
+ * @file IxSspAcc.h
+ *
+ * @brief  Header file for the IXP400 SSP Serial Port Access (IxSspAcc)
+ *
+ * @version $Revision: 0.1 $
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxSspAcc IXP400 SSP Serial Port Access (IxSspAcc) API 
+ *
+ * @brief IXP400 SSP Serial Port Access Public API
+ *
+ * @{
+ */
+#ifndef IXSSPACC_H
+#define IXSSPACC_H
+
+#ifdef __ixp46X
+
+#include "IxOsal.h"
+
+/*
+ * Section for enum
+ */
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @enum IxSspAccDataSize
+ *
+ * @brief The data sizes in bits that are supported by the protocol
+ */
+typedef enum
+{
+	DATA_SIZE_TOO_SMALL = 0x2,
+	DATA_SIZE_4 = 0x3,
+	DATA_SIZE_5,
+	DATA_SIZE_6,
+	DATA_SIZE_7,
+	DATA_SIZE_8,
+	DATA_SIZE_9,
+	DATA_SIZE_10,
+	DATA_SIZE_11,
+	DATA_SIZE_12,
+	DATA_SIZE_13,
+	DATA_SIZE_14,
+	DATA_SIZE_15,
+	DATA_SIZE_16,
+	DATA_SIZE_TOO_BIG
+} IxSspAccDataSize;
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @enum IxSspAccPortStatus
+ *
+ * @brief The status of the SSP port to be set to enable/disable
+ */
+typedef enum
+{
+	SSP_PORT_DISABLE = 0x0,
+	SSP_PORT_ENABLE,
+	INVALID_SSP_PORT_STATUS
+} IxSspAccPortStatus;
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @enum IxSspAccFrameFormat
+ *
+ * @brief The frame format that is to be used - SPI, SSP, or Microwire
+ */
+typedef enum
+{
+	SPI_FORMAT = 0x0,
+	SSP_FORMAT,
+	MICROWIRE_FORMAT,
+	INVALID_FORMAT
+} IxSspAccFrameFormat;
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @enum IxSspAccClkSource
+ *
+ * @brief The source to produce the SSP serial clock
+ */
+typedef enum
+{
+	ON_CHIP_CLK = 0x0,
+	EXTERNAL_CLK,
+	INVALID_CLK_SOURCE
+} IxSspAccClkSource;
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @enum IxSspAccSpiSclkPhase
+ *
+ * @brief The SPI SCLK Phase: 
+ * 0 - SCLK is inactive one cycle at the start of a frame and 1/2 cycle at the
+ *		end of a frame.
+ * 1 - SCLK is inactive 1/2 cycle at the start of a frame and one cycle at the
+ *		end of a frame.
+ */
+typedef enum
+{
+	START_ONE_END_HALF = 0x0,
+	START_HALF_END_ONE,
+	INVALID_SPI_PHASE
+} IxSspAccSpiSclkPhase;
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @enum IxSspAccSpiSclkPolarity
+ *
+ * @brief The SPI SCLK Polarity can be set to either low or high.
+ */
+typedef enum
+{
+	SPI_POLARITY_LOW = 0x0,
+	SPI_POLARITY_HIGH,
+	INVALID_SPI_POLARITY
+} IxSspAccSpiSclkPolarity;
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @enum IxSspAccMicrowireCtlWord
+ *
+ * @brief The Microwire control word can be either 8 or 16 bit.
+ */
+typedef enum
+{
+	MICROWIRE_8_BIT = 0x0,
+	MICROWIRE_16_BIT,
+	INVALID_MICROWIRE_CTL_WORD
+} IxSspAccMicrowireCtlWord;
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @enum IxSspAccFifoThreshold
+ *
+ * @brief The threshold in frames (each frame is defined by IxSspAccDataSize)
+ *			that can be set for the FIFO to trigger a threshold exceed when
+ *			checking with the ExceedThresholdCheck functions or an interrupt
+ *			when it is enabled.
+ */
+typedef enum
+{
+	FIFO_TSHLD_1 =	0x0,
+	FIFO_TSHLD_2,
+	FIFO_TSHLD_3,
+	FIFO_TSHLD_4,
+	FIFO_TSHLD_5,
+	FIFO_TSHLD_6,
+	FIFO_TSHLD_7,
+	FIFO_TSHLD_8,
+	FIFO_TSHLD_9,
+	FIFO_TSHLD_10,
+	FIFO_TSHLD_11,
+	FIFO_TSHLD_12,
+	FIFO_TSHLD_13,
+	FIFO_TSHLD_14,
+	FIFO_TSHLD_15,
+	FIFO_TSHLD_16,
+	INVALID_FIFO_TSHLD
+} IxSspAccFifoThreshold;
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @enum IX_SSP_STATUS
+ *
+ * @brief The statuses that can be returned in a SSP Serial Port Access
+ */
+typedef enum
+{
+	IX_SSP_SUCCESS = IX_SUCCESS, /**< Success status */
+	IX_SSP_FAIL, /**< Fail status */
+	IX_SSP_RX_FIFO_OVERRUN_HANDLER_MISSING, /**<
+						Rx FIFO Overrun handler is NULL. */
+	IX_SSP_RX_FIFO_HANDLER_MISSING, /**<
+					Rx FIFO threshold hit or above handler is NULL
+					*/
+	IX_SSP_TX_FIFO_HANDLER_MISSING, /**<
+					Tx FIFO threshold hit or below handler is NULL
+					*/
+	IX_SSP_FIFO_NOT_EMPTY_FOR_SETTING_CTL_CMD, /**<
+					Tx FIFO not empty and therefore microwire
+					control command size setting is not allowed.	*/
+	IX_SSP_INVALID_FRAME_FORMAT_ENUM_VALUE, /**<
+					frame format selected is invalid. */
+	IX_SSP_INVALID_DATA_SIZE_ENUM_VALUE, /**<
+					data size selected is invalid. */
+	IX_SSP_INVALID_CLOCK_SOURCE_ENUM_VALUE, /**<
+					source clock selected is invalid. */
+	IX_SSP_INVALID_TX_FIFO_THRESHOLD_ENUM_VALUE, /**<
+					Tx FIFO threshold selected is invalid. */
+	IX_SSP_INVALID_RX_FIFO_THRESHOLD_ENUM_VALUE, /**<
+					Rx FIFO threshold selected is invalid. */
+	IX_SSP_INVALID_SPI_PHASE_ENUM_VALUE, /**<
+					SPI phase selected is invalid. */
+	IX_SSP_INVALID_SPI_POLARITY_ENUM_VALUE, /**<
+					SPI polarity selected is invalid. */
+	IX_SSP_INVALID_MICROWIRE_CTL_CMD_ENUM_VALUE, /**<
+					Microwire control command selected is invalid
+					*/
+	IX_SSP_INT_UNBIND_FAIL, /**< Interrupt unbind fail to unbind SSP
+	                interrupt */
+	IX_SSP_INT_BIND_FAIL, /**< Interrupt bind fail during init */
+	IX_SSP_RX_FIFO_NOT_EMPTY, /**<
+					Rx FIFO not empty while trying to change data
+					size. */
+	IX_SSP_TX_FIFO_NOT_EMPTY, /**<
+					Rx FIFO not empty while trying to change data
+					size or microwire control command size.	*/
+	IX_SSP_POLL_MODE_BLOCKING, /**<
+					poll mode selected blocks interrupt mode from
+					being selected.	*/
+	IX_SSP_TX_FIFO_HIT_BELOW_THRESHOLD, /**<
+					Tx FIFO level hit or below threshold. */
+	IX_SSP_TX_FIFO_EXCEED_THRESHOLD, /**<
+					Tx FIFO level exceeded threshold. */
+	IX_SSP_RX_FIFO_HIT_ABOVE_THRESHOLD, /**<
+					Rx FIFO level hit or exceeded threshold. */
+	IX_SSP_RX_FIFO_BELOW_THRESHOLD, /**<
+					Rx FIFO level below threshold. */
+	IX_SSP_BUSY, /**< SSP is busy. */
+	IX_SSP_IDLE, /**< SSP is idle. */
+	IX_SSP_OVERRUN_OCCURRED, /**<
+					SSP has experienced an overrun. */
+	IX_SSP_NO_OVERRUN, /**<
+					SSP did not experience an overrun. */
+	IX_SSP_NOT_SUPORTED, /**< hardware does not support SSP */
+	IX_SSP_NOT_INIT, /**< SSP Access not intialized */
+	IX_SSP_NULL_POINTER /**< parameter passed in is NULL */
+} IX_SSP_STATUS;
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @brief SSP Rx FIFO Overrun handler
+ *
+ * This function is called for the client to handle Rx FIFO Overrun that occurs
+ * in the SSP hardware
+ */
+typedef void (*RxFIFOOverrunHandler)(void);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @brief SSP Rx FIFO Threshold hit or above handler
+ *
+ * This function is called for the client to handle Rx FIFO threshold hit or
+ * or above that occurs in the SSP hardware
+ */
+typedef void (*RxFIFOThresholdHandler)(void);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @brief SSP Tx FIFO Threshold hit or below handler
+ *
+ * This function is called for the client to handle Tx FIFO threshold hit or
+ * or below that occurs in the SSP hardware
+ */
+typedef void (*TxFIFOThresholdHandler)(void);
+
+
+/*
+ * Section for struct
+ */
+/**
+ * @ingroup IxSspAcc
+ *
+ * @brief contains all the variables required to initialize the SSP serial port
+ *		hardware.
+ * 
+ * Structure to be filled and used for calling initialization
+ */
+typedef struct
+{
+	IxSspAccFrameFormat FrameFormatSelected;/**<Select between SPI, SSP and
+												Microwire. */
+	IxSspAccDataSize DataSizeSelected;		/**<Select between 4 and 16. */
+	IxSspAccClkSource ClkSourceSelected;	/**<Select clock source to be
+												on-chip or external. */
+	IxSspAccFifoThreshold TxFIFOThresholdSelected;
+											/**<Select Tx FIFO threshold
+												between 1 to 16. */
+	IxSspAccFifoThreshold RxFIFOThresholdSelected;
+											/**<Select Rx FIFO threshold
+												between 1 to 16. */
+	BOOL RxFIFOIntrEnable;					/**<Enable/disable Rx FIFO
+												threshold interrupt. Disabling
+												this interrupt will require
+												the use of the polling function
+												RxFIFOExceedThresholdCheck. */
+	BOOL TxFIFOIntrEnable;					/**<Enable/disable Tx FIFO
+												threshold interrupt. Disabling
+												this interrupt will require
+												the use of the polling function
+												TxFIFOExceedThresholdCheck. */
+	RxFIFOThresholdHandler RxFIFOThsldHdlr;	/**<Pointer to function to handle
+												a Rx FIFO interrupt. */
+	TxFIFOThresholdHandler TxFIFOThsldHdlr;	/**<Pointer to function to handle
+												a Tx FIFO interrupt. */
+	RxFIFOOverrunHandler RxFIFOOverrunHdlr;	/**<Pointer to function to handle
+												a Rx FIFO overrun interrupt. */
+	BOOL LoopbackEnable;					/**<Select operation mode to be
+												normal or loopback mode. */
+	IxSspAccSpiSclkPhase SpiSclkPhaseSelected;
+											/**<Select SPI SCLK phase to start
+												with one inactive cycle and end
+												with 1/2 inactive cycle or
+												start with 1/2 inactive cycle
+												and end with one inactive
+												cycle. (Only used in
+												SPI format). */
+	IxSspAccSpiSclkPolarity SpiSclkPolaritySelected;
+											/**<Select SPI SCLK idle state
+												to be low or high. (Only used in
+												SPI format). */
+	IxSspAccMicrowireCtlWord MicrowireCtlWordSelected;
+											/**<Select Microwire control
+												format to be 8 or 16-bit. (Only
+												used in Microwire format). */
+	UINT8 SerialClkRateSelected;			/**<Select between 0 (1.8432Mbps)
+												and 255 (7.2Kbps). The
+												formula used is	Bit rate = 
+												3.6864x10^6 / 
+												(2 x (SerialClkRateSelect + 1))
+												*/
+} IxSspInitVars;
+
+/**
+ * @ingroup IxSspAcc
+ *
+ * @brief contains counters of the SSP statistics
+ * 
+ * Structure contains all values of counters and associated overflows.
+ */
+typedef struct
+{
+	UINT32 ixSspRcvCounter;		/**<Total frames received. */
+	UINT32 ixSspXmitCounter;	/**<Total frames transmitted. */
+	UINT32 ixSspOverflowCounter;/**<Total occurrences of overflow. */
+} IxSspAccStatsCounters;
+
+
+/*
+ * Section for prototypes interface functions
+ */
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccInit (
+	IxSspInitVars *initVarsSelected);
+ *
+ * @brief Initializes the SSP Access module.
+ *
+ * @param "IxSspAccInitVars [in] *initVarsSelected" - struct containing required
+ *			variables for initialization 
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will initialize the SSP Serial Port hardware to the user specified
+ * configuration. Then it will enable the SSP Serial Port.
+ * *NOTE*: Once interrupt or polling mode is selected, the mode cannot be
+ * changed via the interrupt enable/disable function but the init needs to be
+ * called again to change it.
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - Successfully initialize and enable the SSP
+ *									serial port.
+ *		- IX_SSP_RX_FIFO_HANDLER_MISSING - interrupt mode is selected but RX FIFO
+ *									handler pointer is NULL
+ *		- IX_SSP_TX_FIFO_HANDLER_MISSING - interrupt mode is selected but TX FIFO
+ *									handler pointer is NULL
+ *		- IX_SSP_RX_FIFO_OVERRUN_HANDLER_MISSING - interrupt mode is selected but
+ *									RX FIFO Overrun handler pointer is NULL
+ *		- IX_SSP_RX_FIFO_NOT_EMPTY - Rx FIFO not empty, data size change is not
+ *			                        allowed.
+ *		- IX_SSP_TX_FIFO_NOT_EMPTY - Tx FIFO not empty, data size change is not
+ *			                        allowed.
+ *		- IX_SSP_INVALID_FRAME_FORMAT_ENUM_VALUE - frame format selected is invalid
+ *		- IX_SSP_INVALID_DATA_SIZE_ENUM_VALUE - data size selected is invalid
+ *		- IX_SSP_INVALID_CLOCK_SOURCE_ENUM_VALUE - clock source selected is invalid
+ *		- IX_SSP_INVALID_TX_FIFO_THRESHOLD_ENUM_VALUE - Tx FIFO threshold level
+ *									selected is invalid
+ *		- IX_SSP_INVALID_RX_FIFO_THRESHOLD_ENUM_VALUE - Rx FIFO threshold level
+ *									selected is invalid
+ *		- IX_SSP_INVALID_SPI_PHASE_ENUM_VALUE - SPI phase selected is invalid
+ *		- IX_SSP_INVALID_SPI_POLARITY_ENUM_VALUE - SPI polarity selected is invalid
+ *		- IX_SSP_INVALID_MICROWIRE_CTL_CMD_ENUM_VALUE - microwire control command
+ *									size is invalid
+ *      - IX_SSP_INT_UNBIND_FAIL - interrupt handler failed to unbind SSP interrupt
+ *		- IX_SSP_INT_BIND_FAIL - interrupt handler failed to bind to SSP interrupt
+ *									hardware trigger
+ *      - IX_SSP_NOT_SUPORTED - hardware does not support SSP
+ *      - IX_SSP_NULL_POINTER - parameter passed in is NULL
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccInit (IxSspInitVars *initVarsSelected);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccUninit (
+	void)
+ *
+ * @brief Un-initializes the SSP Serial Port Access component
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will disable the SSP Serial Port hardware. The client can call the
+ * init function again if they wish to enable the SSP.
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - successfully uninit SSP component
+ *      - IX_SSP_INT_UNBIND_FAIL - interrupt handler failed to unbind SSP interrupt
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccUninit (void);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccFIFODataSubmit (
+	UINT16 *data,
+	UINT32 amtOfData)
+ *
+ * @brief Inserts data into the SSP Serial Port's FIFO
+ *
+ * @param	"UINT16 [in] *data" - pointer to the location to transmit the data
+ *				from
+ *			"UINT32 [in] amtOfData" - number of data to be transmitted.
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will insert the amount of data specified by "amtOfData" from buffer
+ * pointed to by "data" into the FIFO to be transmitted by the hardware.
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - Data inserted successfully into FIFO
+ *		- IX_SSP_FAIL - FIFO insufficient space
+ *		- IX_SSP_NULL_POINTER - data pointer passed by client is NULL
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccFIFODataSubmit (
+	UINT16* data,
+	UINT32 amtOfData);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccFIFODataReceive (
+	UINT16 *data,
+	UINT32 amtOfData)
+ *
+ * @brief Extract data from the SSP Serial Port's FIFO
+ *
+ * @param	"UINT16 [in] *data" - pointer to the location to receive the data into
+ *			"UINT32 [in] amtOfData" - number of data to be received.
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will extract the amount of data specified by "amtOfData" from the
+ * FIFO already received by the hardware into the buffer pointed to by "data".
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - Data extracted successfully from FIFO
+ *		- IX_SSP_FAIL - FIFO has no data
+ *		- IX_SSP_NULL_POINTER - data pointer passed by client is NULL
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccFIFODataReceive (
+	UINT16* data,
+	UINT32 amtOfData);
+
+
+/**
+ * Polling Functions
+ */
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccTxFIFOHitOrBelowThresholdCheck (
+		void)
+ *
+ * @brief Check if the Tx FIFO threshold has been hit or fallen below.
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will return whether the Tx FIFO threshold has been exceeded or not
+ *
+ * @return 
+ *      - IX_SSP_TX_FIFO_HIT_BELOW_THRESHOLD - Tx FIFO level hit or below threshold .
+ *		- IX_SSP_TX_FIFO_EXCEED_THRESHOLD - Tx FIFO level exceeded threshold.
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccTxFIFOHitOrBelowThresholdCheck (
+	void);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccRxFIFOHitOrAboveThresholdCheck (
+		void)
+ *
+ * @brief Check if the Rx FIFO threshold has been hit or exceeded.
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will return whether the Rx FIFO level is below threshold or not
+ *
+ * @return 
+ *      - IX_SSP_RX_FIFO_HIT_ABOVE_THRESHOLD - Rx FIFO level hit or exceeded threshold
+ *		- IX_SSP_RX_FIFO_BELOW_THRESHOLD - Rx FIFO level below threshold
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccRxFIFOHitOrAboveThresholdCheck (
+	void);
+
+
+/**
+ * Configuration functions
+ *
+ * NOTE: These configurations are not required to be called once init is called
+ * unless configurations need to be changed on the fly.
+ */
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccSSPPortStatusSet (
+	IxSspAccPortStatus portStatusSelected)
+ *
+ * @brief Enables/disables the SSP Serial Port hardware.
+ *
+ * @param "IxSspAccPortStatus [in] portStatusSelected" - Set the SSP port to
+ *			enable or disable
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will enable/disable the SSP Serial Port hardware.
+ * NOTE: This function is called by init to enable the SSP after setting up the
+ * configurations and by uninit to disable the SSP.
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - Port status set with valid enum value
+ *		- IX_SSP_FAIL - invalid enum value
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccSSPPortStatusSet (
+	IxSspAccPortStatus portStatusSelected);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccFrameFormatSelect (
+	IxSspAccFrameFormat frameFormatSelected)
+ *
+ * @brief Sets the frame format for the SSP Serial Port hardware
+ *
+ * @param "IxSspAccFrameFormat [in] frameFormatSelected" - The frame format of
+ *			SPI, SSP or Microwire can be selected as the format
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will set the format for the transfers via user input.
+ * *NOTE*: The SSP hardware will be disabled to clear the FIFOs. Then its
+ * previous state (enabled/disabled) restored after changing the format.
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - frame format set with valid enum value
+ *		- IX_SSP_INVALID_FRAME_FORMAT_ENUM_VALUE - invalid frame format value
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccFrameFormatSelect (
+	IxSspAccFrameFormat frameFormatSelected);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccDataSizeSelect (
+	IxSspAccDataSize dataSizeSelected)
+ *
+ * @brief Sets the data size for transfers
+ *
+ * @param "IxSspAccDataSize [in] dataSizeSelected" - The data size between 4
+ *			and 16 that can be selected for data transfers
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will set the data size for the transfers via user input. It will
+ * disallow the change of the data size if either of the Rx/Tx FIFO is not
+ * empty to prevent data loss.
+ * *NOTE*: The SSP port will be disabled if the FIFOs are found to be empty and
+ *			if between the check and disabling of the SSP (which clears the
+ *			FIFOs) data is received into the FIFO, it might be lost.
+ * *NOTE*: The FIFOs can be cleared by disabling the SSP Port if necessary to
+ *			force the data size change.
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - data size set with valid enum value
+ *		- IX_SSP_RX_FIFO_NOT_EMPTY - Rx FIFO not empty, data size change is not
+ *							allowed.
+ *		- IX_SSP_TX_FIFO_NOT_EMPTY - Tx FIFO not empty, data size change is not
+ *							allowed.
+ *		- IX_SSP_INVALID_DATA_SIZE_ENUM_VALUE - invalid enum value
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccDataSizeSelect (
+	IxSspAccDataSize dataSizeSelected);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccClockSourceSelect(
+	IxSspAccClkSource clkSourceSelected)
+ *
+ * @brief Sets the clock source of the SSP Serial Port hardware
+ *
+ * @param "IxSspAccClkSource [in] clkSourceSelected" - The clock source from
+ *			either external source on on-chip can be selected as the source
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will set the clock source for the transfers via user input.
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - clock source set with valid enum value
+ *		- IX_SSP_INVALID_CLOCK_SOURCE_ENUM_VALUE - invalid enum value
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccClockSourceSelect (
+	IxSspAccClkSource clkSourceSelected);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccSerialClockRateConfigure (
+	UINT8 serialClockRateSelected)
+ *
+ * @brief Sets the on-chip Serial Clock Rate of the SSP Serial Port hardware.
+ *
+ * @param "UINT8 [in] serialClockRateSelected" - The serial clock rate that can
+ *			be set is between 7.2Kbps and 1.8432Mbps. The formula used is
+ *			Bit rate = 3.6864x10^6 / (2 x (SerialClockRateSelected + 1))
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will set the serial clock rate for the transfers via user input.
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - Serial clock rate configured successfully
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccSerialClockRateConfigure (
+	UINT8 serialClockRateSelected);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccRxFIFOIntEnable (
+	RxFIFOThresholdHandler rxFIFOIntrHandler)
+ *
+ * @brief Enables service request interrupt whenever the Rx FIFO hits its
+ *		threshold
+ *
+ * @param "void [in] *rxFIFOIntrHandler(UINT32)" - function pointer to the
+ *				interrupt handler for the Rx FIFO exceeded.
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will enable the service request interrupt for the Rx FIFO
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - Rx FIFO level interrupt enabled successfully
+ *		- IX_SSP_RX_FIFO_HANDLER_MISSING - missing handler for Rx FIFO level interrupt
+ *		- IX_SSP_POLL_MODE_BLOCKING - poll mode is selected at init, interrupt not
+ *				allowed to be enabled. Use init to enable interrupt mode.
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccRxFIFOIntEnable (
+	RxFIFOThresholdHandler rxFIFOIntrHandler);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccRxFIFOIntDisable (
+	void)
+ *
+ * @brief Disables service request interrupt of the Rx FIFO.
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will disable the service request interrupt of the Rx FIFO.
+ *
+ * @return 
+ *		- IX_SSP_SUCCESS - Rx FIFO Interrupt disabled successfully
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccRxFIFOIntDisable (
+	void);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccTxFIFOIntEnable (
+	TxFIFOThresholdHandler txFIFOIntrHandler)
+ *
+ * @brief Enables service request interrupt of the Tx FIFO.
+ *
+ * @param "void [in] *txFIFOIntrHandler(UINT32)" - function pointer to the
+ *				interrupt handler for the Tx FIFO exceeded.
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will enable the service request interrupt of the Tx FIFO.
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - Tx FIFO level interrupt enabled successfully
+ *		- IX_SSP_TX_FIFO_HANDLER_MISSING - missing handler for Tx FIFO level interrupt
+ *		- IX_SSP_POLL_MODE_BLOCKING - poll mode is selected at init, interrupt not
+ *				allowed to be enabled. Use init to enable interrupt mode.
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccTxFIFOIntEnable (
+	TxFIFOThresholdHandler txFIFOIntrHandler);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccTxFIFOIntDisable (
+	void)
+ *
+ * @brief Disables service request interrupt of the Tx FIFO
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will disable the service request interrupt of the Tx FIFO
+ *
+ * @return 
+ *		- IX_SSP_SUCCESS - Tx FIFO Interrupt disabled successfuly.
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccTxFIFOIntDisable (
+	void);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccLoopbackEnable (
+	BOOL loopbackEnable)
+ *
+ * @brief Enables/disables the loopback mode
+ *
+ * @param "BOOL [in] loopbackEnable" - true to enable and false to disable.
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will set the mode of operation to either loopback or normal mode
+ * according to the user input.
+ *
+ * @return 
+ *		- IX_SSP_SUCCESS - Loopback enabled successfully
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccLoopbackEnable (
+	BOOL loopbackEnable);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccSpiSclkPolaritySet (
+	IxSspAccSpiSclkPolarity spiSclkPolaritySelected)
+ *
+ * @brief Sets the SPI SCLK Polarity to Low or High
+ *
+ * @param - "IxSspAccSpiSclkPolarity [in] spiSclkPolaritySelected" - SPI SCLK
+ *				polarity that can be selected to either high or low
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API is only used for the SPI frame format and will set the SPI SCLK polarity
+ * to either low or high
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - SPI Sclk polarity set with valid enum value
+ *		- IX_SSP_INVALID_SPI_POLARITY_ENUM_VALUE - invalid SPI polarity value
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccSpiSclkPolaritySet (
+	IxSspAccSpiSclkPolarity spiSclkPolaritySelected);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccSpiSclkPhaseSet (
+	IxSspAccSpiSclkPhase spiSclkPhaseSelected)
+ *
+ * @brief Sets the SPI SCLK Phase
+ *
+ * @param "IxSspAccSpiSclkPhase [in] spiSclkPhaseSelected" - Phase of either
+ *			the SCLK is inactive one cycle at the start of a frame and 1/2
+ *			cycle at the end of a frame, OR
+ *			the SCLK is inactive 1/2 cycle at the start of a frame and one
+ *			cycle at the end of a frame.
+ *
+ * Global Data	:
+ *		- IX_SSP_SUCCESS - SPI Sclk phase set with valid enum value
+ *		- IX_SSP_INVALID_SPI_PHASE_ENUM_VALUE - invalid SPI phase value
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *                        
+ * This API is only used for the SPI frame format and will set the SPI SCLK
+ * phase according to user input.
+ *
+ * @return 
+ *      - None
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccSpiSclkPhaseSet (
+	IxSspAccSpiSclkPhase spiSclkPhaseSelected);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccMicrowireControlWordSet (
+	IxSspAccMicrowireCtlWord microwireCtlWordSelected)
+ *
+ * @brief Sets the Microwire control word to 8 or 16 bit format
+ *
+ * @param "IxSspAccMicrowireCtlWord [in] microwireCtlWordSelected" - Microwire
+ *			control word format can be either 8 or 16 bit format
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API is only used for the Microwire frame format and will set the
+ * control word to 8 or 16 bit format
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - Microwire Control Word set with valid enum value
+ *		- IX_SSP_TX_FIFO_NOT_EMPTY - Tx FIFO not empty, data size change is not
+ *							allowed.
+ *		- IX_SSP_INVALID_MICROWIRE_CTL_CMD_ENUM_VALUE - invalid enum value
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccMicrowireControlWordSet (
+	IxSspAccMicrowireCtlWord microwireCtlWordSelected);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccTxFIFOThresholdSet (
+	IxSspAccFifoThreshold txFIFOThresholdSelected)
+ *
+ * @brief Sets the Tx FIFO Threshold.
+ *
+ * @param "IxSspAccFifoThreshold [in] txFIFOThresholdSelected" - Threshold that
+ *		is set for a Tx FIFO service request to be triggered
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will set the threshold for a Tx FIFO threshold to be triggered
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - Tx FIFO Threshold set with valid enum value
+ *		- IX_SSP_INVALID_TX_FIFO_THRESHOLD_ENUM_VALUE - invalid enum value
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccTxFIFOThresholdSet (
+	IxSspAccFifoThreshold txFIFOThresholdSelected);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccRxFIFOThresholdSet (
+	IxSspAccFifoThreshold rxFIFOThresholdSelected)
+ *
+ * @brief Sets the Rx FIFO Threshold.
+ *
+ * @param "IxSspAccFifoThreshold [in] rxFIFOThresholdSelected" - Threshold that
+ *		is set for a Tx FIFO service request to be triggered
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will will set the threshold for a Rx FIFO threshold to be triggered
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - Rx FIFO Threshold set with valid enum value
+ *		- IX_SSP_INVALID_RX_FIFO_THRESHOLD_ENUM_VALUE - invalid enum value
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccRxFIFOThresholdSet (
+	IxSspAccFifoThreshold rxFIFOThresholdSelected);
+
+
+/**
+ * Debug functions
+ */
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccStatsGet (
+	IxSspAccStatsCounters *sspStats)
+ *
+ * @brief Returns the SSP Statistics through the pointer passed in
+ *
+ * @param "IxSspAccStatsCounters [in] *sspStats" - SSP statistics counter will
+ *			be read and written to the location pointed by this pointer.
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will return the statistics counters of the SSP transfers.
+ *
+ * @return 
+ *      - IX_SSP_SUCCESS - Stats obtained into the pointer provided successfully
+ *		- IX_SSP_FAIL - client provided pointer is NULL
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccStatsGet (
+	IxSspAccStatsCounters *sspStats);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccStatsReset (
+	void)
+ *
+ * @brief Resets the SSP Statistics
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will reset the SSP statistics counters.
+ *
+ * @return 
+ *      - None
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC void
+ixSspAccStatsReset (
+	void);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccShow (
+		void)
+ *
+ * @brief Display SSP status registers and statistics counters.
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will display the status registers of the SSP and the statistics
+ * counters.
+ *
+ * @return 
+ *		- IX_SSP_SUCCESS - SSP show called successfully.
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccShow (
+	void);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccSSPBusyCheck (
+		void)
+ *
+ * @brief Determine the state of the SSP serial port hardware.
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will return the state of the SSP serial port hardware - busy or
+ * idle
+ *
+ * @return 
+ *      - IX_SSP_BUSY - SSP is busy
+ *		- IX_SSP_IDLE - SSP is idle.
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccSSPBusyCheck (
+	void);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccTxFIFOLevelGet (
+		void)
+ *
+ * @brief Obtain the Tx FIFO's level
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will return the level of the Tx FIFO
+ *
+ * @return 
+ *      - 0..16; 0 can also mean SSP not initialized and will need to be init.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC UINT8
+ixSspAccTxFIFOLevelGet (
+	void);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccRxFIFOLevelGet (
+		void)
+ *
+ * @brief Obtain the Rx FIFO's level
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will return the level of the Rx FIFO
+ *
+ * @return 
+ *      - 0..16; 0 can also mean SSP not initialized and will need to be init.
+ *              
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC UINT8
+ixSspAccRxFIFOLevelGet (
+	void);
+
+/**
+ * @ingroup IxSspAcc
+ * 
+ * @fn ixSspAccRxFIFOOverrunCheck (
+		void)
+ *
+ * @brief Check if the Rx FIFO has overrun its FIFOs
+ *
+ * @param - None
+ *
+ * Global Data	:
+ *		- None.
+ *                        
+ * This API will return whether the Rx FIFO has overrun its 16 FIFOs
+ *
+ * @return 
+ *      - IX_SSP_OVERRUN_OCCURRED - Rx FIFO overrun occurred
+ *		- IX_SSP_NO_OVERRUN - Rx FIFO did not overrun
+ *		- IX_SSP_NOT_INIT - SSP not initialized. SSP init needs to be called.
+ *
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : yes
+ *
+ */
+PUBLIC IX_SSP_STATUS
+ixSspAccRxFIFOOverrunCheck (
+	void);
+
+#endif /* __ixp46X */
+#endif /* IXSSPACC_H */
diff --git a/marvell/uboot/drivers/net/npe/include/IxTimeSyncAcc.h b/marvell/uboot/drivers/net/npe/include/IxTimeSyncAcc.h
new file mode 100644
index 0000000..f8bcffe
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxTimeSyncAcc.h
@@ -0,0 +1,759 @@
+/**
+ * @file IxTimeSyncAcc.h
+ *
+ * @author Intel Corporation
+ * @date 07 May 2004
+ *
+ * @brief  Header file for IXP400 Access Layer to IEEE 1588(TM) Precision
+ * Clock Synchronisation Protocol Hardware Assist
+ *
+ * @version 1
+ *
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxTimeSyncAcc IXP400 Time Sync Access Component API 
+ *
+ * @brief Public API for IxTimeSyncAcc
+ *
+ * @{
+ */
+#ifndef IXTIMESYNCACC_H
+#define IXTIMESYNCACC_H
+
+#ifdef  __ixp46X
+
+#include "IxOsal.h"
+
+/**
+ * Section for enum
+ */
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @enum IxTimeSyncAccStatus
+ *
+ * @brief The status as returned from the API
+ */
+typedef enum /**< IxTimeSyncAccStatus */
+{
+    IX_TIMESYNCACC_SUCCESS = IX_SUCCESS,    /**< Requested operation successful */
+    IX_TIMESYNCACC_INVALIDPARAM,            /**< An invalid parameter was passed */
+    IX_TIMESYNCACC_NOTIMESTAMP,             /**< While polling no time stamp available */
+    IX_TIMESYNCACC_INTERRUPTMODEINUSE,      /**< Polling not allowed while operating in interrupt mode */
+    IX_TIMESYNCACC_FAILED                   /**< Internal error occurred */
+}IxTimeSyncAccStatus;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @enum IxTimeSyncAccAuxMode
+ *
+ * @brief Master or Slave Auxiliary Time Stamp (Snap Shot)
+ */
+typedef enum /**< IxTimeSyncAccAuxMode */
+{
+    IX_TIMESYNCACC_AUXMODE_MASTER,          /**< Auxiliary Master Mode */
+    IX_TIMESYNCACC_AUXMODE_SLAVE,           /**< Auxiliary Slave Mode */
+    IX_TIMESYNCACC_AUXMODE_INVALID          /**< Invalid Auxiliary Mode */
+}IxTimeSyncAccAuxMode;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @enum IxTimeSyncAcc1588PTPPort
+ *
+ * @brief IEEE 1588 PTP Communication Port(Channel)
+ */
+typedef enum /**< IxTimeSyncAcc1588PTPPort */
+{
+    IX_TIMESYNCACC_NPE_A_1588PTP_PORT,      /**< PTP Communication Port on NPE-A */
+    IX_TIMESYNCACC_NPE_B_1588PTP_PORT,      /**< PTP Communication Port on NPE-B */
+    IX_TIMESYNCACC_NPE_C_1588PTP_PORT,      /**< PTP Communication Port on NPE-C */
+    IX_TIMESYNCACC_NPE_1588PORT_INVALID     /**< Invalid PTP Communication Port */
+} IxTimeSyncAcc1588PTPPort;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @enum IxTimeSyncAcc1588PTPPortMode
+ *
+ * @brief Master or Slave mode for IEEE 1588 PTP Communication Port
+ */
+typedef enum  /**< IxTimeSyncAcc1588PTPPortMode */
+{
+    IX_TIMESYNCACC_1588PTP_PORT_MASTER,       /**< PTP Communication Port in Master Mode */
+    IX_TIMESYNCACC_1588PTP_PORT_SLAVE,        /**< PTP Communication Port in Slave Mode */
+    IX_TIMESYNCACC_1588PTP_PORT_ANYMODE,      /**< PTP Communication Port in ANY Mode
+                                                  allows time stamping of all messages
+                                                  including non-1588 PTP */
+    IX_TIMESYNCACC_1588PTP_PORT_MODE_INVALID  /**< Invalid PTP Port Mode */
+}IxTimeSyncAcc1588PTPPortMode;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @enum IxTimeSyncAcc1588PTPMsgType
+ *
+ * @brief 1588 PTP Messages types that can be detected on communication port
+ *
+ * Note that client code can determine this based on master/slave mode in which
+ * it is already operating in and this information is made available for the sake
+ * of convenience only.
+ */
+typedef enum  /**< IxTimeSyncAcc1588PTPMsgType */
+{
+    IX_TIMESYNCACC_1588PTP_MSGTYPE_SYNC,     /**< PTP Sync message sent by Master or received by Slave */
+    IX_TIMESYNCACC_1588PTP_MSGTYPE_DELAYREQ, /**< PTP Delay_Req message sent by Slave or received by Master */
+    IX_TIMESYNCACC_1588PTP_MSGTYPE_UNKNOWN   /**< Other PTP and non-PTP message sent or received by both
+                                                Master and/or Slave */
+} IxTimeSyncAcc1588PTPMsgType;
+
+/**
+ * Section for struct
+ */
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @struct IxTimeSyncAccTimeValue
+ *
+ * @brief Struct to hold 64 bit SystemTime and TimeStamp values
+ */
+typedef struct  /**< IxTimeSyncAccTimeValue */
+{
+    UINT32 timeValueLowWord;               /**< Lower 32 bits of the time value */
+    UINT32 timeValueHighWord;              /**< Upper 32 bits of the time value */  
+} IxTimeSyncAccTimeValue;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @struct IxTimeSyncAccUuid
+ *
+ * @brief Struct to hold 48 bit UUID values captured in Sync or Delay_Req messages
+ */
+typedef struct  /**< IxTimeSyncAccUuid */
+{
+    UINT32 uuidValueLowWord;               /**<The lower 32 bits of the UUID */
+    UINT16 uuidValueHighHalfword;          /**<The upper 16 bits of the UUID */  
+} IxTimeSyncAccUuid;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @struct IxTimeSyncAccPtpMsgData
+ *
+ * @brief Struct for data from the PTP message returned when TimeStamp available
+ */
+typedef struct  /**< IxTimeSyncAccPtpMsgData */
+{
+    IxTimeSyncAcc1588PTPMsgType ptpMsgType; /**< PTP Messages type */
+    IxTimeSyncAccTimeValue ptpTimeStamp;    /**< 64 bit TimeStamp value from PTP Message */
+    IxTimeSyncAccUuid ptpUuid;              /**< 48 bit UUID value from the PTP Message */
+    UINT16 ptpSequenceNumber;               /**< 16 bit Sequence Number from PTP Message */
+} IxTimeSyncAccPtpMsgData;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @struct IxTimeSyncAccStats
+ *
+ * @brief Statistics for the PTP messages
+ */
+typedef struct  /**< IxTimeSyncAccStats */
+{
+    UINT32 rxMsgs; /**< Count of timestamps for received PTP Messages */
+    UINT32 txMsgs; /**< Count of timestamps for transmitted PTP Messages */
+} IxTimeSyncAccStats;
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @typedef IxTimeSyncAccTargetTimeCallback
+ *
+ * @brief Callback for use by target time stamp interrupt
+ */
+typedef void (*IxTimeSyncAccTargetTimeCallback)(IxTimeSyncAccTimeValue targetTime);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @typedef IxTimeSyncAccAuxTimeCallback
+ *
+ * @brief Callback for use by auxiliary time interrupts
+ */
+typedef void (*IxTimeSyncAccAuxTimeCallback)(IxTimeSyncAccAuxMode auxMode,
+             IxTimeSyncAccTimeValue auxTime);
+
+/*
+ * Section for prototypes interface functions
+ */
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccPTPPortConfigSet(
+                               IxTimeSyncAcc1588PTPPort ptpPort,
+                               IxTimeSyncAcc1588PTPPortMode ptpPortMode)
+ *
+ * @brief Configures the IEEE 1588 message detect on particular PTP port.
+ *
+ * @param ptpPort [in] - PTP port to config
+ * @param ptpPortMode [in]- Port to operate in Master or Slave mode
+ *
+ * This API will enable the time stamping on a particular PTP port.
+ *          
+ * @li Re-entrant   : No
+ * @li ISR Callable : No
+ * 
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccPTPPortConfigSet(IxTimeSyncAcc1588PTPPort ptpPort,
+       IxTimeSyncAcc1588PTPPortMode ptpPortMode);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccPTPPortConfigGet(
+                               IxTimeSyncAcc1588PTPPort ptpPort,
+                               IxTimeSyncAcc1588PTPPortMode *ptpPortMode)
+ *
+ * @brief Retrieves IEEE 1588 PTP operation mode on particular PTP port.
+ *
+ * @param ptpPort [in] - PTP port
+ * @param ptpPortMode [in]- Mode of operation of PTP port (Master or Slave)
+ *
+ * This API will identify the time stamping capability of a PTP port by means
+ * of obtaining its mode of operation.
+ *          
+ * @li Re-entrant   : No
+ * @li ISR Callable : No
+ * 
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccPTPPortConfigGet(IxTimeSyncAcc1588PTPPort ptpPort,
+    IxTimeSyncAcc1588PTPPortMode *ptpPortMode);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccPTPRxPoll(
+                               IxTimeSyncAcc1588PTPPort ptpPort,
+                               IxTimeSyncAccPtpMsgData  *ptpMsgData)
+ *
+ * @brief Polls the IEEE 1588 message/time stamp detect status on a particular 
+ * PTP Port on the Receive side.
+ *
+ * @param ptpPort [in] - PTP port to poll
+ * @param ptpMsgData [out] - Current TimeStamp and other Data
+ *
+ * This API will poll for the availability of a time stamp on the received Sync 
+ * (Slave) or Delay_Req (Master) messages.
+ * The client application will provide the buffer.
+ *              
+ * @li Re-entrant   : No
+ * @li ISR Callable : No
+ * 
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed
+ *         @li IX_TIMESYNCACC_NOTIMESTAMP - No time stamp available
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccPTPRxPoll(IxTimeSyncAcc1588PTPPort ptpPort,
+    IxTimeSyncAccPtpMsgData  *ptpMsgData);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccPTPTxPoll(
+                               IxTimeSyncAcc1588PTPPort ptpPort,
+                               IxTimeSyncAccPtpMsgData  *ptpMsgData)
+ *
+ *
+ * @brief Polls the IEEE 1588 message/time stamp detect status on a particular 
+ * PTP Port on the Transmit side.
+ *
+ * @param ptpPort [in] - PTP port to poll
+ * @param ptpMsgData [out] - Current TimeStamp and other Data
+ *                        
+ * This API will poll for the availability of a time stamp on the transmitted
+ * Sync (Master) or Delay_Req (Slave) messages.
+ * The client application will provide the buffer.
+ *              
+ * @li Re-entrant   : No
+ * @li ISR Callable : No
+ * 
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed
+ *         @li IX_TIMESYNCACC_NOTIMESTAMP - No time stamp available
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccPTPTxPoll(IxTimeSyncAcc1588PTPPort ptpPort,
+    IxTimeSyncAccPtpMsgData  *ptpMsgData);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccSystemTimeSet(
+                               IxTimeSyncAccTimeValue systemTime)
+ *
+ * @brief Sets the System Time in the IEEE 1588 hardware assist block
+ *
+ * @param systemTime [in] - Value to set System Time
+ *                        
+ * This API will set the SystemTime to given value.
+ *              
+ * @li Re-entrant   : yes
+ * @li ISR Callable : no
+ * 
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccSystemTimeSet(IxTimeSyncAccTimeValue systemTime);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccSystemTimeGet(
+                               IxTimeSyncAccTimeValue *systemTime)
+ *
+ * @brief Gets the System Time from the IEEE 1588 hardware assist block
+ *
+ * @param systemTime [out] - Copy the current System Time into the client 
+ * application provided buffer
+ *
+ * This API will get the SystemTime from IEEE1588 block and return to client
+ *      
+ * @li Re-entrant   : no
+ * @li ISR Callable : no
+ * 
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccSystemTimeGet(IxTimeSyncAccTimeValue *systemTime);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccTickRateSet(
+                               UINT32 tickRate)
+ *
+ * @brief Sets the Tick Rate (Frequency Scaling Value) in the IEEE 1588
+ * hardware assist block
+ *
+ * @param tickRate [in] - Value to set Tick Rate
+ *                        
+ * This API will set the Tick Rate (Frequency Scaling Value) in the IEEE
+ * 1588 block to the given value. The Accumulator register (not client 
+ * visible) is incremented by this TickRate value every clock cycle. When 
+ * the Accumulator overflows, the SystemTime is incremented by one. This
+ * TickValue can therefore be used to adjust the system timer.
+ *           
+ * @li Re-entrant   : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccTickRateSet(UINT32 tickRate);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccTickRateGet(
+                               UINT32 *tickRate)
+ *
+ * @brief Gets the Tick Rate (Frequency Scaling Value) from the IEEE 1588
+ * hardware assist block
+ *
+ * @param tickRate [out] - Current Tick Rate value in the IEEE 1588 block
+ *
+ * This API will get the TickRate on IEE15588 block. Refer to @ref 
+ * ixTimeSyncAccTickRateSet for notes on usage of this value.
+ *         
+ * @li   Reentrant    : yes
+ * @li   ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccTickRateGet(UINT32 *tickRate);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccTargetTimeInterruptEnable(
+                               IxTimeSyncAccTargetTimeCallback targetTimeCallback)
+ *
+ * @brief Enables the interrupt to verify the condition where the System Time 
+ * greater or equal to the Target Time in the IEEE 1588 hardware assist block. 
+ * If the condition is true an interrupt will be sent to XScale.
+ *
+ * @param targetTimeCallback [in] - Callback to be invoked when interrupt fires
+ *
+ * This API will enable the Target Time reached/hit condition interrupt.
+ *
+ * NOTE: The client application needs to ensure that the APIs 
+ * @ref ixTimeSyncAccTargetTimeInterruptEnable, @ref ixTimeSyncAccTargetTimeSet and
+ * @ref ixTimeSyncAccTargetTimeInterruptDisable are accessed in mutual exclusive 
+ * manner with respect to each other.
+ *
+ * @li Re-entrant   : no
+ * @li ISR Callable : yes
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed for callback
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccTargetTimeInterruptEnable(IxTimeSyncAccTargetTimeCallback targetTimeCallback);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccTargetTimeInterruptDisable(
+                               void)
+ *
+ * @brief Disables the interrupt for the condition explained in the function
+ * description of @ref ixTimeSyncAccTargetTimeInterruptEnable.
+ *
+ * This API will disable the Target Time interrupt.
+ *
+ * NOTE: The client application needs to ensure that the APIs 
+ * @ref ixTimeSyncAccTargetTimeInterruptEnable, @ref ixTimeSyncAccTargetTimeSet and
+ * @ref ixTimeSyncAccTargetTimeInterruptDisable are accessed in mutual exclusive 
+ * manner with respect to each other.
+ *              
+ * @li Re-entrant   : no
+ * @li ISR Callable : yes
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccTargetTimeInterruptDisable(void);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccTargetTimePoll(
+                               BOOL *ttmPollFlag,
+                               IxTimeSyncAccTimeValue *targetTime)
+ *
+ * @brief Poll to verify the condition where the System Time greater or equal to
+ * the Target Time in the IEEE 1588 hardware assist block. If the condition is
+ * true an event flag is set in the hardware.
+ *
+ * @param ttmPollFlag [out] - true  if the target time reached/hit condition event set
+ *                            false if the target time reached/hit condition event is
+                                    not set
+ * @param targetTime [out] - Capture current targetTime into client provided buffer
+ *
+ * Poll the target time reached/hit condition status. Return true and the current
+ * target time value, if the condition is true else return false.
+ *
+ * NOTE: The client application will need to clear the event flag that will be set
+ * as long as the condition that the System Time greater or equal to the Target Time is
+ * valid, in one of the following ways:
+ *     1) Invoke the API to change the target time
+ *     2) Change the system timer value 
+ *              
+ * @li Re-entrant   : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ *         @li IX_TIMESYNCACC_INTERRUPTMODEINUSE - Interrupt mode in use
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccTargetTimePoll(BOOL *ttmPollFlag,
+    IxTimeSyncAccTimeValue *targetTime);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccTargetTimeSet(
+                               IxTimeSyncAccTimeValue targetTime)
+ *
+ * @brief Sets the Target Time in the IEEE 1588 hardware assist block
+ *
+ * @param targetTime [in] - Value to set Target Time
+ *                        
+ * This API will set the Target Time to a given value.
+ *
+ * NOTE: The client application needs to ensure that the APIs 
+ * @ref ixTimeSyncAccTargetTimeInterruptEnable, @ref ixTimeSyncAccTargetTimeSet and
+ * @ref ixTimeSyncAccTargetTimeInterruptDisable are accessed in mutual exclusive 
+ * manner with respect to each other.
+ *              
+ * @li   Reentrant    : no
+ * @li   ISR Callable : yes
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccTargetTimeSet(IxTimeSyncAccTimeValue targetTime);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccTargetTimeGet(
+                               IxTimeSyncAccTimeValue *targetTime)
+ *
+ * @brief Gets the Target Time in the IEEE 1588 hardware assist block
+ *
+ * @param targetTime [out] - Copy current time to client provided buffer
+ *                                                 
+ * This API will get the Target Time from IEEE 1588 block and return to the 
+ * client application
+ *            
+ * @li Re-entrant   : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccTargetTimeGet(IxTimeSyncAccTimeValue *targetTime);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccAuxTimeInterruptEnable(
+                               IxTimeSyncAccAuxMode auxMode, 
+                               IxTimeSyncAccAuxTimeCallback auxTimeCallback)
+ *
+ * @brief Enables the interrupt notification for the given mode of Auxiliary Time 
+ * Stamp in the IEEE 1588 hardware assist block
+ * 
+ * @param auxMode [in] - Auxiliary time stamp register (slave or master) to use
+ * @param auxTimeCallback [in] - Callback to be invoked when interrupt fires 
+ *                                                              
+ * This API will enable the Auxiliary Master/Slave Time stamp Interrupt.
+ *
+ * <pre>
+ * NOTE: 1) An individual callback is to be registered for each Slave and Master 
+ * Auxiliary Time Stamp registers. Thus to register for both Master and Slave time
+ * stamp interrupts either the same callback or two separate callbacks the API has
+ * to be invoked twice.
+ *       2) On the IXDP465 Development Platform, the Auxiliary Timestamp signal for 
+ * slave mode is tied to GPIO 8 pin. This signal is software routed by default to 
+ * PCI for backwards compatibility with the IXDP425 Development Platform. This
+ * routing must be disabled for the auxiliary slave time stamp register to work 
+ * properly. The following commands may be used to accomplish this. However, refer
+ * to the IXDP465 Development Platform Users Guide or the BSP/LSP documentation for
+ * more specific information.
+ *
+ * For Linux (at the Redboot prompt i.e., before loading zImage):
+ *     mfill -b 0x54100000 -1 -l 1 -p 8
+ *     mfill -b 0x54100001 -1 -l 1 -p 0x7f
+ * For vxWorks, at the prompt:
+ *     intDisable(25)
+ *     ixdp400FpgaIODetach(8)
+ * </pre>
+ *              
+ * @li Re-entrant   : no
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed for callback or
+                                            invalid auxiliary snapshot mode
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccAuxTimeInterruptEnable(IxTimeSyncAccAuxMode auxMode,
+    IxTimeSyncAccAuxTimeCallback auxTimeCallback);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccAuxTimeInterruptDisable(
+                               IxTimeSyncAccAuxMode auxMode)
+ *
+ * @brief Disables the interrupt for the indicated mode of Auxiliary Time Stamp
+ * in the IEEE 1588 hardware assist block
+ *
+ * @param auxMode [in] - Auxiliary time stamp mode (slave or master) using which
+ * the interrupt will be disabled.
+ *                        
+ * This API will disable the Auxiliary Time Stamp Interrupt (Master or Slave)
+ *              
+ * @li Re-entrant   : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccAuxTimeInterruptDisable(IxTimeSyncAccAuxMode auxMode);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ * 
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccAuxTimePoll(
+                               IxTimeSyncAccAuxMode auxMode,
+                               BOOL *auxPollFlag,
+                               IxTimeSyncAccTimeValue *auxTime)
+ *
+ * @brief Poll for the Auxiliary Time Stamp captured for the mode indicated 
+ * (Master or Slave)
+ *
+ * @param auxMode [in] - Auxiliary Snapshot Register (Slave or Master) to be checked
+ * @param auxPollFlag [out] - true if the time stamp captured in auxiliary
+                                   snapshot register
+ *                            false if the time stamp not captured in
+                                   auxiliary snapshot register
+ * @param auxTime [out] - Copy the current Auxiliary Snapshot Register value into the
+ * client provided buffer
+ *
+ * Polls for the Time stamp in the appropriate Auxiliary Snapshot Registers based 
+ * on the mode specified. Return true and the contents of the Auxiliary snapshot,
+ * if it is available else return false.
+ * 
+ * Please refer to the note #2 of the API @ref ixTimeSyncAccAuxTimeInterruptEnable
+ * for more information for Auxiliary Slave mode.
+ *
+ * @li Re-entrant   : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed for auxPollFlag,
+                   callback or invalid auxiliary snapshot mode
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ *         @li IX_TIMESYNCACC_INTERRUPTMODEINUSE - Interrupt mode in use
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccAuxTimePoll(IxTimeSyncAccAuxMode auxMode,
+    BOOL *auxPollFlag,
+    IxTimeSyncAccTimeValue *auxTime);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccReset(void)
+ *
+ * @brief Resets the IEEE 1588 hardware assist block
+ *
+ * Sets the reset bit in the IEEE1588 silicon which fully resets the silicon block
+ *            
+ * @li Reentrant    : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_FAILED  - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccReset(void);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccStatsGet(IxTimeSyncAccStats
+                               *timeSyncStats)
+ *
+ * @brief Returns the IxTimeSyncAcc Statistics in the client supplied buffer
+ *
+ * @param timeSyncStats [out] - TimeSync statistics counter values
+ *
+ * This API will return the statistics of the received or transmitted messages.
+ * 
+ * NOTE: 1) These counters are updated only when the client polls for the time 
+ * stamps or interrupt are enabled. This is because the IxTimeSyncAcc module 
+ * does not either transmit or receive messages and does only run the code 
+ * when explicit requests received by client application.
+ *
+ *       2) These statistics reflect the number of valid PTP messages exchanged
+ * in Master and Slave modes but includes all the messages (including valid 
+ * non-PTP messages) while operating in the Any mode.
+ *              
+ * @li Reentrant    : no
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_INVALIDPARAM - NULL parameter passed
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccStatsGet(IxTimeSyncAccStats *timeSyncStats);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn void ixTimeSyncAccStatsReset(void)
+ *
+ * @brief Reset Time Sync statistics
+ *
+ * This API will reset the statistics counters of the TimeSync access layer.
+ *             
+ * @li Reentrant    : yes
+ * @li ISR Callable:  no
+ *
+ * @return @li None
+ */
+PUBLIC void
+ixTimeSyncAccStatsReset(void);
+
+/**
+ * @ingroup IxTimeSyncAcc
+ *
+ * @fn IxTimeSyncAccStatus ixTimeSyncAccShow(void)
+ *
+ * @brief Displays the Time Sync current status
+ *
+ * This API will display status on the current configuration of the IEEE
+ * 1588 hardware assist block, contents of the various time stamp registers,
+ * outstanding interrupts and/or events.
+ *
+ * Note that this is intended for debug only, and in contrast to the other
+ * functions, it does not clear the any of the status bits associated with
+ * active timestamps and so is passive in its nature.
+ *            
+ * @li Reentrant    : yes
+ * @li ISR Callable : no
+ *
+ * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful
+ *         @li IX_TIMESYNCACC_FAILED - Internal error occurred
+ */
+PUBLIC IxTimeSyncAccStatus
+ixTimeSyncAccShow(void);
+
+#endif /* __ixp46X */
+#endif /* IXTIMESYNCACC_H */
+
+/**
+ * @} defgroup IxTimeSyncAcc
+ */
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxTimerCtrl.h b/marvell/uboot/drivers/net/npe/include/IxTimerCtrl.h
new file mode 100644
index 0000000..a865b93
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxTimerCtrl.h
@@ -0,0 +1,239 @@
+/** 
+ * @file IxTimerCtrl.h
+ * @brief 
+ *    This is the header file for the Timer Control component.
+ *
+ *    The timer callback control component provides a mechanism by which different 
+ *    client components can start a timer and have a supplied callback function
+ *    invoked when the timer expires.
+ *    The callbacks are all dispatched from one thread inside this component. 
+ *    Any component that needs to be called periodically should use this facility 
+ *    rather than create its own task with a sleep loop. 
+ *
+ * @par
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxTimerCtrl IXP400 Timer Control (IxTimerCtrl) API
+ *
+ * @brief The public API for the IXP400 Timer Control Component.
+ *
+ * @{
+ */
+
+#ifndef IxTimerCtrl_H
+#define IxTimerCtrl_H
+
+
+#include "IxTypes.h"
+/* #include "Ossl.h" */
+
+/*
+ * #defines and macros used in this file.
+ */
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @def IX_TIMERCTRL_NO_FREE_TIMERS
+ *
+ * @brief Timer schedule return code.
+ *
+ * Indicates that the request to start a timer failed because
+ * all available timer resources are used. 
+ */
+#define IX_TIMERCTRL_NO_FREE_TIMERS 2
+
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @def IX_TIMERCTRL_PARAM_ERROR
+ *
+ * @brief Timer schedule return code.
+ *
+ * Indicates that the request to start a timer failed because
+ * the client has supplied invalid parameters.
+ */
+#define IX_TIMERCTRL_PARAM_ERROR 3
+
+ 
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @brief A typedef for a pointer to a timer callback function. 
+ * @para void * - This parameter is supplied by the client when the
+ * timer is started and passed back to the client in the callback.
+ * @note in general timer callback functions should not block or 
+ * take longer than 100ms. This constraint is required to ensure that
+ * higher priority callbacks are not held up. 
+ * All callbacks are called from the same thread. 
+ * This thread is a shared resource. 
+ * The parameter passed is provided when the timer is scheduled.
+ */
+typedef void (*IxTimerCtrlTimerCallback)(void *userParam);
+
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @brief List used to identify the users of timers.
+ * @note The order in this list indicates priority.  Components appearing 
+ * higher in the list will be given priority over components lower in the
+ * list.  When adding components, please insert at an appropriate position
+ * for priority ( i.e values should be less than IxTimerCtrlMaxPurpose ) .
+ */
+typedef enum 
+{
+    IxTimerCtrlAdslPurpose,
+   /* Insert new purposes above this line only
+    */
+   IxTimerCtrlMaxPurpose
+}
+IxTimerCtrlPurpose;
+
+
+/*
+ * Function definition
+ */
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @fn ixTimerCtrlSchedule(IxTimerCtrlTimerCallback func, 
+                       void *userParam, 
+                       IxTimerCtrlPurpose purpose,
+	               UINT32 relativeTime,
+                       unsigned *timerId )
+ * 
+ * @brief Schedules a callback function to be called after a period of "time".
+ * The callback function should not block or run for more than 100ms.
+ * This function 
+ *
+ * @param func @ref IxTimerCtrlTimerCallback [in] - the callback function to be called.
+ * @param userParam void [in] - a parameter to send to the callback function, can be NULL.
+ * @param purpose @ref IxTimerCtrlPurpose [in] - the purpose of the callback, internally this component will 
+ * decide the priority of callbacks with different purpose.
+ * @param relativeTime UINT32 [in] - time relative to now in milliseconds after which the callback 
+ * will be called. The time must be greater than the duration of one OS tick.
+ * @param *timerId unsigned [out] -  An id for the callback scheduled. 
+ * This id can be used to cancel the callback.
+ * @return 
+ * @li IX_SUCCESS - The timer was started successfully.
+ * @li IX_TIMERCTRL_NO_FREE_TIMERS - The timer was not started because the maximum number
+ * of running timers has been exceeded.
+ * @li IX_TIMERCTRL_PARAM_ERROR - The timer was not started because the client has supplied 
+ * a NULL callback func, or the requested timeout is less than one OS tick.
+ * @note  This function is re-entrant. The function accesses a list of running timers
+ * and may suspend the calling thread if this list is being accesed by another thread.
+ */
+PUBLIC IX_STATUS 
+ixTimerCtrlSchedule(IxTimerCtrlTimerCallback func, 
+                       void *userParam, 
+                       IxTimerCtrlPurpose purpose,
+	               UINT32 relativeTime,
+                       unsigned *timerId );
+
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @fn ixTimerCtrlScheduleRepeating(IxTimerCtrlTimerCallback func, 
+                                void *param, 
+                                IxTimerCtrlPurpose purpose,
+			        UINT32 interval,
+                                unsigned *timerId )
+ * 
+ * @brief Schedules a callback function to be called after a period of "time".
+ * The callback function should not block or run for more than 100ms.
+ *
+ * @param func @ref IxTimerCtrlTimerCallback [in] - the callback function to be called.
+ * @param userParam void [in] - a parameter to send to the callback function, can be NULL.
+ * @param purpose @ref IxTimerCtrlPurpose [in] - the purpose of the callback, internally this component will 
+ * decide the priority of callbacks with different purpose.
+ * @param interval UINT32 [in] - the interval in milliseconds between calls to func. 
+ * @param timerId unsigned [out] - An id for the callback scheduled. 
+ * This id can be used to cancel the callback.
+ * @return 
+ * @li IX_SUCCESS - The timer was started successfully.
+ * @li IX_TIMERCTRL_NO_FREE_TIMERS - The timer was not started because the maximum number
+ * of running timers has been exceeded.
+ * @li IX_TIMERCTRL_PARAM_ERROR - The timer was not started because the client has supplied 
+ * a NULL callback func, or the requested timeout is less than one OS tick.
+ * @note  This function is re-entrant. The function accesses a list of running timers
+ * and may suspend the calling thread if this list is being accesed by another thread.
+ */
+PUBLIC IX_STATUS 
+ixTimerCtrlScheduleRepeating(IxTimerCtrlTimerCallback func, 
+                                void *param, 
+                                IxTimerCtrlPurpose purpose,
+			        UINT32 interval,
+                                unsigned *timerId );
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @fn ixTimerCtrlCancel (unsigned id)
+ *
+ * @brief Cancels a scheduled callback.
+ *
+ * @param id unsigned [in] - the id of the callback to be cancelled.
+ * @return
+ * @li IX_SUCCESS - The timer was successfully stopped.
+ * @li IX_FAIL - The id parameter did not corrrespond to any running timer..
+ * @note This function is re-entrant. The function accesses a list of running timers
+ * and may suspend the calling thread if this list is being accesed by another thread.
+ */
+PUBLIC IX_STATUS
+ixTimerCtrlCancel (unsigned id);
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @fn ixTimerCtrlInit(void)
+ *
+ * @brief Initialise the Timer Control Component.
+ * @return 
+ * @li IX_SUCCESS - The timer control component initialized successfully.
+ * @li IX_FAIL - The timer control component initialization failed,
+ * or the component was already initialized.
+ * @note This must be done before any other API function is called.
+ * This function should be called once only and is not re-entrant.
+ */
+PUBLIC IX_STATUS
+ixTimerCtrlInit(void);
+
+
+/**
+ * @ingroup IxTimerCtrl
+ *
+ * @fn ixTimerCtrlShow( void )
+ *
+ * @brief Display the status of the Timer Control Component. 
+ * @return void
+ * @note Displays a list of running timers.
+ * This function is not re-entrant. This function does not suspend the calling thread.
+ */
+PUBLIC void
+ixTimerCtrlShow( void );
+
+#endif  /* IXTIMERCTRL_H */
+
diff --git a/marvell/uboot/drivers/net/npe/include/IxTypes.h b/marvell/uboot/drivers/net/npe/include/IxTypes.h
new file mode 100644
index 0000000..f936a50
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxTypes.h
@@ -0,0 +1,62 @@
+/**
+ * @file IxTypes.h (Replaced by OSAL)
+ *
+ * @date 28-NOV-2001
+
+ * @brief This file contains basic types used by the IXP400 software
+ *
+ * Design Notes:
+ *    This file shall only include fundamental types and definitions to be
+ *    shared by all the IXP400 components.
+ *    Please DO NOT add component-specific types here.
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxTypes IXP400 Types (IxTypes) 
+ *
+ * @brief Basic data types used by the IXP400 project
+ *
+ * @{
+ */
+
+#ifndef IxTypes_H
+
+#ifndef __doxygen_HIDE
+
+#define IxTypes_H
+
+#endif /* __doxygen_HIDE */
+
+
+/* WR51880: Undefined data types workaround for backward compatibility */
+#ifdef __linux
+#ifndef __INCvxTypesOldh
+typedef int (*FUNCPTR)(void);
+typedef int STATUS;
+#define OK (0)
+#define ERROR (-1)
+#endif
+#endif
+
+#include "IxOsalBackward.h"
+
+#endif /* IxTypes_H */
+
+/**
+ * @} addtogroup IxTypes
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxUART.h b/marvell/uboot/drivers/net/npe/include/IxUART.h
new file mode 100644
index 0000000..ff23b22
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxUART.h
@@ -0,0 +1,434 @@
+/** 
+ * @file IxUART.h
+ *
+ * @date 12-OCT-01
+ *
+ * @brief Public header for the Intel IXP400 internal UART, generic driver.
+ * 
+ * Design Notes:
+ * This driver allows you to perform the following functions: 
+ *	Device Initialization,
+ *	send/receive characters.
+ *
+ * Perform Uart IOCTL for the following:
+ *	Set/Get the current baud rate,
+ *	set parity,
+ *	set the number of Stop bits,
+ *	set the character Length (5,6,7,8),
+ *	enable/disable Hardware flow control.
+ *
+ * Only Polled mode is supported for now.
+ *    
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+*/
+
+/**
+ * @defgroup IxUARTAccAPI IXP400 UART Access (IxUARTAcc) API
+ *
+ * @brief IXP400 UARTAcc Driver Public API
+ * 
+ * @{
+ */
+
+
+/* Defaults */
+
+/**
+ * @defgroup DefaultDefines Defines for Default Values
+ *
+ * @brief Default values which can be used for UART configuration
+ *
+ * @sa ixUARTDev
+ */
+
+/**
+ * @def IX_UART_DEF_OPTS
+ *
+ * @brief The default hardware options to set the UART to -
+ * no flow control, 8 bit word, 1 stop bit, no parity 
+ *
+ * @ingroup DefaultDefines
+ */
+#define IX_UART_DEF_OPTS (CLOCAL | CS8)
+
+/**
+ * @def IX_UART_DEF_XMIT
+ *
+ * @brief The default UART FIFO size - must be no bigger than 64
+ *
+ * @ingroup DefaultDefines
+ */
+#define IX_UART_DEF_XMIT 64
+
+/**
+ * @def IX_UART_DEF_BAUD
+ *
+ * @brief The default UART baud rate - 9600
+ *
+ * @ingroup DefaultDefines
+ */
+#define IX_UART_DEF_BAUD 9600
+
+/**
+ * @def IX_UART_MIN_BAUD
+ *
+ * @brief The minimum UART baud rate - 9600
+ *
+ * @ingroup DefaultDefines
+ */
+#define IX_UART_MIN_BAUD 9600
+
+/**
+ * @def IX_UART_MAX_BAUD
+ *
+ * @brief The maximum UART baud rate - 926100
+ *
+ * @ingroup DefaultDefines
+ */
+#define IX_UART_MAX_BAUD 926100
+
+/**
+ * @def IX_UART_XTAL
+ *
+ * @brief The UART clock speed
+ *
+ * @ingroup DefaultDefines
+ */
+#define IX_UART_XTAL 14745600
+
+
+
+/* IOCTL commands (Request codes) */
+
+/**
+ * @defgroup IoctlCommandDefines Defines for IOCTL Commands
+ *
+ * @brief IOCTL Commands (Request codes) which can be used
+ *        with @ref ixUARTIoctl
+ */
+
+
+/**
+ * @ingroup IoctlCommandDefines
+ *
+ * @def IX_BAUD_SET
+ *
+ * @brief Set the baud rate
+ */
+#define IX_BAUD_SET	0
+
+/**
+ * @ingroup IoctlCommandDefines
+ *
+ * @def IX_BAUD_GET
+ *
+ * @brief Get the baud rate
+ */
+#define IX_BAUD_GET	1
+
+/**
+ * @ingroup IoctlCommandDefines
+ * @def IX_MODE_SET
+ * @brief Set the UART mode of operation
+ */
+#define IX_MODE_SET	2
+
+/**
+ * @ingroup IoctlCommandDefines
+ *
+ * @def IX_MODE_GET
+ *
+ * @brief Get the current UART mode of operation
+ */
+#define IX_MODE_GET	3
+
+/**
+ * @ingroup IoctlCommandDefines
+ *
+ * @def IX_OPTS_SET
+ *
+ * @brief Set the UART device options
+ */
+#define IX_OPTS_SET	4
+
+/**
+ * @ingroup IoctlCommandDefines
+ *
+ * @def IX_OPTS_GET
+ *
+ * @brief Get the UART device options
+ */
+#define IX_OPTS_GET	5
+
+/**
+ * @ingroup IoctlCommandDefines
+ *
+ * @def IX_STATS_GET
+ *
+ * @brief Get the UART statistics
+ */
+#define IX_STATS_GET	6
+
+
+/* POSIX style ioctl arguments */
+
+/**
+ * @defgroup IoctlArgDefines Defines for IOCTL Arguments
+ *
+ * @brief POSIX style IOCTL arguments which can be used
+ *        with @ref ixUARTIoctl
+ *
+ * @sa ixUARTMode
+ */
+
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def CLOCAL
+ *
+ * @brief Software flow control
+ */
+#ifdef CLOCAL
+#undef CLOCAL
+#endif
+#define CLOCAL		0x1
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def CREAD
+ *
+ * @brief Enable interrupt receiver
+ */
+#ifdef CREAD
+#undef CREAD
+#endif
+#define CREAD		0x2
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def CSIZE
+ *
+ * @brief Characters size
+ */
+#ifdef CSIZE
+#undef CSIZE
+#endif
+#define CSIZE		0xc
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def CS5
+ *
+ * @brief 5 bits
+ */
+#ifdef CS5
+#undef CS5
+#endif
+#define CS5		0x0
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def CS6
+ *
+ * @brief 6 bits
+ */
+#ifdef CS6
+#undef CS6
+#endif
+#define CS6		0x4
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def CS7
+ *
+ * @brief 7 bits
+ */
+#ifdef CS7
+#undef CS7
+#endif
+#define CS7		0x8
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def CS8
+ *
+ * @brief 8 bits
+ */
+#ifdef CS8
+#undef CS8
+#endif
+#define CS8		0xc
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def STOPB
+ *
+ * @brief Send two stop bits (else one)
+ */
+#define STOPB		0x20
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def PARENB
+ *
+ * @brief Parity detection enabled (else disabled)
+ */
+#ifdef PARENB
+#undef PARENB
+#endif
+#define PARENB		0x40
+
+/**
+ * @ingroup IoctlArgDefines
+ *
+ * @def PARODD
+ *
+ * @brief Odd parity  (else even)
+ */
+#ifdef PARODD
+#undef PARODD
+#endif
+#define PARODD		0x80
+
+/**
+ * @enum ixUARTMode
+ * @brief The mode to set to UART to.
+ */
+typedef enum
+{
+    INTERRUPT=0,	/**< Interrupt mode */
+    POLLED,		/**< Polled mode */
+    LOOPBACK		/**< Loopback mode */
+} ixUARTMode;
+
+/**
+ * @struct ixUARTStats
+ * @brief Statistics for the UART.
+ */
+typedef struct
+{
+    UINT32  rxCount;
+    UINT32  txCount;	
+    UINT32  overrunErr;
+    UINT32  parityErr;
+    UINT32  framingErr;
+    UINT32  breakErr;
+} ixUARTStats;
+
+/**
+ * @struct ixUARTDev
+ * @brief Device descriptor for the UART.
+ */
+typedef struct
+{
+    UINT8 *addr;	/**< device base address */
+    ixUARTMode mode;	/**< interrupt, polled or loopback */
+    int baudRate;	/**< baud rate */
+    int freq;		/**< UART clock frequency */     
+    int options;	/**< hardware options */
+    int fifoSize;	/**< FIFO xmit size */
+
+    ixUARTStats   stats;	/**< device statistics */
+} ixUARTDev;
+
+/**
+ * @ingroup IxUARTAccAPI
+ *
+ * @fn IX_STATUS ixUARTInit(ixUARTDev* pUART)
+ * 
+ * @param pUART	@ref ixUARTDev [in] - pointer to UART structure describing our device.
+ * 
+ * @brief Initialise the UART. This puts the chip in a quiescent state.
+ * 
+ * @pre The base address for the UART must contain a valid value.
+ *      Also the baud rate and hardware options must contain sensible values
+ *      otherwise the defaults will be used as defined in ixUART.h
+ *
+ * @post UART is initialized and ready to send and receive data.
+ *
+ * @note This function should only be called once per device.
+ *
+ * @retval IX_SUCCESS - UART device successfully initialised.
+ * @retval IX_FAIL - Critical error, device not initialised.
+ ***************************************************************************/
+PUBLIC IX_STATUS ixUARTInit(ixUARTDev* pUART);
+
+/**
+ * @ingroup IxUARTAccAPI
+ *
+ * @fn IX_STATUS ixUARTPollOutput(ixUARTDev* pUART, int outChar)
+ *
+ * @param pUART @ref ixUARTDev [out] - pointer to UART structure describing our device.
+ * @param outChar int [out] - character to transmit.
+ *
+ * @brief Transmit a character in polled mode.
+ *
+ * @pre UART device must be initialised.
+ *
+ * @retval IX_SUCCESS - character was successfully transmitted.
+ * @retval IX_FAIL - output buffer is full (try again).
+ ***************************************************************************/
+PUBLIC IX_STATUS ixUARTPollOutput(ixUARTDev* pUART, int outChar);
+
+/**
+ * @ingroup IxUARTAccAPI
+ *
+ * @fn IX_STATUS ixUARTPollInput(ixUARTDev* pUART, char *inChar)
+ *
+ * @param pUART	@ref ixUARTDev [in] - pointer to UART structure describing our device.
+ * @param *inChar char [in] - character read from the device.
+ *
+ * @brief Receive a character in polled mode.
+ *
+ * @pre UART device must be initialised.
+ *
+ * @retval IX_SUCCESS - character was successfully read.
+ * @retval IX_FAIL - input buffer empty (try again).
+ ***************************************************************************/
+PUBLIC IX_STATUS ixUARTPollInput(ixUARTDev* pUART, char *inChar);
+
+/**
+ * @ingroup IxUARTAccAPI
+ *
+ * @fn IX_STATUS ixUARTIoctl(ixUARTDev* pUART, int cmd, void* arg)
+ *
+ * @param pUART	@ref ixUARTDev [in] - pointer to UART structure describing our device.
+ * @param cmd int [in] - an ioctl request code.
+ * @param arg void* [in] - optional argument used to set the device mode,
+ *	 baud rate, and hardware options.
+ *
+ * @brief Perform I/O control routines on the device.
+ *
+ * @retval IX_SUCCESS - requested feature was set/read successfully.
+ * @retval IX_FAIL - error setting/reading the requested feature.
+ *
+ * @sa IoctlCommandDefines
+ * @sa IoctlArgDefines
+ ***************************************************************************/    
+PUBLIC IX_STATUS ixUARTIoctl(ixUARTDev* pUART, int cmd, void* arg);
+
+/**
+ * @} defgroup IxUARTAcc
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/IxVersionId.h b/marvell/uboot/drivers/net/npe/include/IxVersionId.h
new file mode 100644
index 0000000..1769dcd
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/IxVersionId.h
@@ -0,0 +1,131 @@
+/**
+ * @file IxVersionId.h
+ *
+ * @date 22-Aug-2002
+ *
+ * @brief This file contains the IXP400 Software version identifier
+ *
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/**
+ * @defgroup IxVersionId IXP400 Version ID (IxVersionId)
+ *
+ * @brief Version Identifiers
+ *
+ * @{
+ */
+
+#ifndef IXVERSIONID_H
+#define IXVERSIONID_H
+
+/**
+ * @brief Version Identifier String
+ *
+ * This string will be updated with each customer release of the IXP400
+ * Software.
+ */
+#define IX_VERSION_ID "2_0"
+
+/**
+ * This string will be updated with each customer release of the IXP400
+ * ADSL driver package.
+ */
+#define IX_VERSION_ADSL_ID "1_12"
+
+
+/**
+ * This string will be updated with each customer release of the IXP400
+ * USB Client driver package.
+ */
+#define IX_VERSION_USBRNDIS_ID "1_9"
+
+/**
+ * This string will be updated with each customer release of the IXP400
+ * I2C Linux driver package.
+ */
+#define IX_VERSION_I2C_LINUX_ID "1_0"
+
+/**
+ * @brief Linux Ethernet Driver Patch Version Identifier String
+ *
+ * This string will be updated with each release of Linux Ethernet Patch
+ */
+#define LINUX_ETHERNET_DRIVER_PATCH_ID "1_4"
+
+/**
+ * @brief Linux Integration Patch Version Identifier String
+ *
+ * This String will be updated with each release of Linux Integration Patch
+ */
+#define LINUX_INTEGRATION_PATCH_ID "1_3"
+
+/**
+ * @brief Linux Ethernet Readme version Identifier String
+ *
+ * This string will be updated with each release of Linux Ethernet Readme
+ */
+#define LINUX_ETHERNET_README_ID "1_3"
+
+/**
+ * @brief Linux Integration Readme version Identifier String
+ *
+ * This string will be updated with each release of Linux Integration Readme
+ */
+
+#define LINUX_INTEGRATION_README_ID "1_3"
+
+/**
+ * @brief Linux I2C driver Readme version Identifier String
+ *
+ * This string will be updated with each release of Linux I2C Driver Readme
+ */
+#define LINUX_I2C_DRIVER_README_ID "1_0"
+
+/**
+ * @brief ixp425_eth_update_nf_bridge.patch version Identifier String
+ *
+ * This string will be updated with each release of ixp425_eth_update_nf_bridge.
+patch
+ *
+ */
+
+#define IXP425_ETH_UPDATE_NF_BRIDGE_ID "1_3"
+
+/**
+ * @brief Internal Release Identifier String
+ *
+ * This string will be updated with each internal release (SQA drop)
+ * of the IXP400 Software.
+ */
+#define IX_VERSION_INTERNAL_ID "SQA3_5"
+
+/**
+ * @brief Compatible Tornado Version Identifier
+ */
+#define IX_VERSION_COMPATIBLE_TORNADO "Tornado2_2_1-PNE2_0"
+
+/**
+ * @brief Compatible Linux Version Identifier
+ */
+#define IX_VERSION_COMPATIBLE_LINUX "MVL3_1"
+
+
+#endif /* IXVERSIONID_H */
+
+/**
+ * @} addtogroup IxVersionId
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/ix_error.h b/marvell/uboot/drivers/net/npe/include/ix_error.h
new file mode 100644
index 0000000..4c59999
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/ix_error.h
@@ -0,0 +1,42 @@
+/**
+ * ============================================================================
+ * = COPYRIGHT
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ * = PRODUCT
+ *      Intel(r) IXP425 Software Release
+ *
+ * = FILENAME
+ *      ix_error.h (Replaced by OSAL)
+ *
+ * = DESCRIPTION
+ *      This file will describe the basic error type and support functions that
+ *      will be used by the IXA SDK Framework API.
+ *
+ * = AUTHOR
+ *      Intel Corporation
+ *
+ * = CHANGE HISTORY
+ *      4/22/2002 4:19:03 PM - creation time 
+ * ============================================================================
+ */
+
+#if !defined(__IX_ERROR_H__)
+#define __IX_ERROR_H__
+
+#include "IxOsalBackward.h"
+
+#endif /* end !defined(__IX_ERROR_H__) */
+
diff --git a/marvell/uboot/drivers/net/npe/include/ix_macros.h b/marvell/uboot/drivers/net/npe/include/ix_macros.h
new file mode 100644
index 0000000..b4cf760
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/ix_macros.h
@@ -0,0 +1,242 @@
+/**
+ * ============================================================================
+ * = COPYRIGHT
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ * = PRODUCT
+ *      Intel(r) IXP425 Software Release
+ *
+ * = FILENAME
+ *      ix_macros.h
+ *
+ * = DESCRIPTION
+ *      This file will define the basic preprocessor macros that are going to be used
+ *      the IXA SDK Framework API.
+ *
+ * = AUTHOR
+ *      Intel Corporation
+ *
+ * = CHANGE HISTORY
+ *      4/22/2002 4:41:05 PM - creation time 
+ * ============================================================================
+ */
+
+#if !defined(__IX_MACROS_H__)
+#define __IX_MACROS_H__
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif /* end defined(__cplusplus) */
+
+
+/**
+ * MACRO NAME: IX_BIT_FIELD_MASK16
+ *
+ * DESCRIPTION: Builds the mask required to extract the bit field from a 16 bit unsigned integer value.
+ *
+ * @Param:  - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ *          bit of the bit field.
+ * @Param:  - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ *          bit of the bit field.
+ *
+ * @Return: Returns a 16 bit mask that will extract the bit field from a 16 bit unsigned integer value.
+ */
+#define IX_BIT_FIELD_MASK16( \
+                             arg_FieldLSBBit, \
+                             arg_FieldMSBBit \
+                            ) \
+                            ((ix_bit_mask16)((((ix_uint16)1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - \
+                            (ix_uint16)1) << arg_FieldLSBBit))
+
+
+
+/**
+ * MACRO NAME: IX_GET_BIT_FIELD16
+ *
+ * DESCRIPTION: Extracts a bit field from 16 bit unsigned integer. The returned value is normalized in
+ *          in the sense that will be right aligned.
+ *
+ * @Param:  - IN arg_PackedData16 a 16 bit unsigned integer that contains the bit field of interest.
+ * @Param:  - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ *          bit of the bit field.
+ * @Param:  - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ *          bit of the bit field.
+ *
+ * @Return: Returns the value of the bit field. The value can be from 0 to (1 << (arg_FieldMSBBit + 1 -
+ *          arg_FieldLSBBit)) - 1.
+ */
+#define IX_GET_BIT_FIELD16( \
+                            arg_PackedData16, \
+                            arg_FieldLSBBit, \
+                            arg_FieldMSBBit \
+                          ) \
+                          (((ix_uint16)(arg_PackedData16) & IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit)) >> \
+                             arg_FieldLSBBit)
+
+
+/**
+ * MACRO NAME: IX_MAKE_BIT_FIELD16
+ *
+ * DESCRIPTION: This macro will create a temporary 16 bit value with the bit field
+ *          desired set to the desired value.
+ *
+ * @Param:  - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to 
+ *          (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1.
+ * @Param:  - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ *          bit of the bit field.
+ * @Param:  - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ *          bit of the bit field.
+ * 
+ * @Return: Returns a temporary ix_uint16 value that has the bit field set to the appropriate value.
+ */
+#define IX_MAKE_BIT_FIELD16( \
+                             arg_BitFieldValue, \
+                             arg_FieldLSBBit, \
+                             arg_FieldMSBBit \
+                           ) \
+                           (((ix_uint16)(arg_BitFieldValue) << arg_FieldLSBBit) & \
+                           IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit))
+                                 
+/**
+ * MACRO NAME: IX_SET_BIT_FIELD16
+ *
+ * DESCRIPTION: Sets a new value for a bit field from a 16 bit unsigned integer.
+ *
+ * @Param:  - IN arg_PackedData16 a 16 bit unsigned integer that contains the bit field of interest.
+ * @Param:  - IN arg_BitFieldValue is the new vale of the bit field. The value can be from 0 to 
+ *          (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1.
+ * @Param:  - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ *          bit of the bit field.
+ * @Param:  - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ *          bit of the bit field.
+ *
+ * @Return: Returns the updated value of arg_PackedData16.
+ */
+#define IX_SET_BIT_FIELD16( \
+                            arg_PackedData16, \
+                            arg_BitFieldValue, \
+                            arg_FieldLSBBit, \
+                            arg_FieldMSBBit \
+                          ) \
+                          (arg_PackedData16 = (((ix_uint16)(arg_PackedData16) & \
+                          ~(IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit))) | \
+                          IX_MAKE_BIT_FIELD16(arg_BitFieldValue, arg_FieldLSBBit, arg_FieldMSBBit))) 
+
+
+/**
+ * MACRO NAME: IX_BIT_FIELD_MASK32
+ *
+ * DESCRIPTION: Builds the mask required to extract the bit field from a 32 bit unsigned integer value.
+ *
+ * @Param:  - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ *          bit of the bit field.
+ * @Param:  - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ *          bit of the bit field.
+ *
+ * @Return: Returns a 32 bit mask that will extract the bit field from a 32 bit unsigned integer value.
+ */
+#define IX_BIT_FIELD_MASK32( \
+                             arg_FieldLSBBit, \
+                             arg_FieldMSBBit \
+                           ) \
+                           ((ix_bit_mask32)((((ix_uint32)1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - \
+                           (ix_uint32)1) << arg_FieldLSBBit))
+
+
+
+/**
+ * MACRO NAME: IX_GET_BIT_FIELD32
+ *
+ * DESCRIPTION: Extracts a bit field from 32 bit unsigned integer. The returned value is normalized in
+ *          in the sense that will be right aligned.
+ *
+ * @Param:  - IN arg_PackedData32 a 32 bit unsigned integer that contains the bit field of interest.
+ * @Param:  - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ *          bit of the bit field.
+ * @Param:  - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ *          bit of the bit field.
+ *
+ * @Return: Returns the value of the bit field. The value can be from 0 to (1 << (arg_FieldMSBBit + 1 -
+ *          arg_FieldLSBBit)) - 1.
+ */
+#define IX_GET_BIT_FIELD32( \
+                            arg_PackedData32, \
+                            arg_FieldLSBBit, \
+                            arg_FieldMSBBit \
+                          ) \
+                          (((ix_uint32)(arg_PackedData32) & IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit)) >> \
+                             arg_FieldLSBBit)
+
+
+
+
+/**
+ * MACRO NAME: IX_MAKE_BIT_FIELD32
+ *
+ * DESCRIPTION: This macro will create a temporary 32 bit value with the bit field
+ *          desired set to the desired value.
+ *
+ * @Param:  - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to 
+ *          (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1.
+ * @Param:  - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ *          bit of the bit field.
+ * @Param:  - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ *          bit of the bit field.
+ * 
+ * @Return: Returns a temporary ix_uint32 value that has the bit field set to the appropriate value.
+ */
+#define IX_MAKE_BIT_FIELD32( \
+                             arg_BitFieldValue, \
+                             arg_FieldLSBBit, \
+                             arg_FieldMSBBit \
+                           ) \
+                           (((ix_uint32)(arg_BitFieldValue) << arg_FieldLSBBit) & \
+                           IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit))
+                            
+                                
+/**
+ * MACRO NAME: IX_SET_BIT_FIELD32
+ *
+ * DESCRIPTION: Sets a new value for a bit field from a 32 bit unsigned integer.
+ *
+ * @Param:  - IN arg_PackedData32 a 32 bit unsigned integer that contains the bit field of interest.
+ * @Param:  - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to 
+ *          (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1.
+ * @Param:  - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant
+ *          bit of the bit field.
+ * @Param:  - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant
+ *          bit of the bit field.
+ *
+ * @Return: Returns the updated value of arg_PackedData32.
+ */
+#define IX_SET_BIT_FIELD32( \
+                            arg_PackedData32, \
+                            arg_BitFieldValue, \
+                            arg_FieldLSBBit, \
+                            arg_FieldMSBBit \
+                          ) \
+                          (arg_PackedData32 = (((ix_uint32)(arg_PackedData32) & \
+                          ~(IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit))) | \
+                          IX_MAKE_BIT_FIELD32(arg_BitFieldValue, arg_FieldLSBBit, arg_FieldMSBBit))) 
+
+
+
+#if defined(__cplusplus)
+}
+#endif /* end defined(__cplusplus) */
+
+#endif /* end !defined(__IX_MACROS_H__) */
diff --git a/marvell/uboot/drivers/net/npe/include/ix_os_type.h b/marvell/uboot/drivers/net/npe/include/ix_os_type.h
new file mode 100644
index 0000000..e14d561
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/ix_os_type.h
@@ -0,0 +1,41 @@
+/**
+ * ============================================================================
+ * = COPYRIGHT
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ * = PRODUCT
+ *      Intel(r) IXP425 Software Release
+ *
+ * = FILENAME
+ *      ix_os_type.h (Replaced by OSAL)
+ *
+ * = DESCRIPTION
+ *      This file provides protable symbol definitions for the current OS type.
+ *
+ * = AUTHOR
+ *      Intel Corporation
+ *
+ * = CHANGE HISTORY
+ *      4/22/2002 4:43:30 PM - creation time 
+ * ============================================================================
+ */
+
+#if !defined(__IX_OS_TYPE_H__)
+#define __IX_OS_TYPE_H__
+
+#include "IxOsalBackward.h"
+
+#endif /* end !defined(__IX_OS_TYPE_H__) */
+
diff --git a/marvell/uboot/drivers/net/npe/include/ix_ossl.h b/marvell/uboot/drivers/net/npe/include/ix_ossl.h
new file mode 100644
index 0000000..eaa2629
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/ix_ossl.h
@@ -0,0 +1,136 @@
+/**
+ * ============================================================================
+ * = COPYRIGHT
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ * = PRODUCT
+ *      Intel(r) IXP425 Software Release
+ *
+ * = LIBRARY
+ *      OSSL - Operating System Services  Library
+ *
+ * = MODULE
+ *      OSSL  Abstraction layer header file
+ *
+ * = FILENAME
+ *       ix_ossl.h (Replaced by OSAL)
+ *
+ * = DESCRIPTION
+ *   This file contains the prototypes of OS-independent wrapper
+ *   functions which allow the programmer not to be tied to a specific
+ *   operating system. The OSSL functions can be divided into three classes:
+ *
+ *   1) synchronization-related wrapper functions around thread system calls
+ *   2) thread-related wrapper functions around thread calls
+ *   3) transactor/workbench osapi calls -- defined in osApi.h
+ *
+ *   Both 1 and 2 classes of functions provide Thread Management, Thread 
+ *   Synchronization, Mutual Exclusion and  Timer primitives. Namely, 
+ *   creation and deletion functions as well as the standard "wait" and
+ *   "exit". Additionally, a couple of utility functions which enable to 
+ *   pause the execution of a thread are also provided.
+ *
+ *   The 3rd class provides a  slew of other OSAPI functions to handle
+ *   Transactor/WorkBench OS calls.
+ *
+ *
+ *   OSSL Thread APIs:
+ *             The OSSL thread functions that allow for thread creation,
+ *             get thread id, thread deletion and set thread priroity.
+ *
+ *             ix_ossl_thread_create
+ *             ix_ossl_thread_get_id
+ *             ix_ossl_thread_exit
+ *             ix_ossl_thread_kill
+ *             ix_ossl_thread_set_priority
+ *             ix_ossl_thread__delay
+ * 
+ *   OSSL Semaphore APIs:
+ *             The OSSL semaphore functions that allow for initialization,
+ *             posting, waiting and deletion of semaphores.
+ *
+ *             ix_ossl_sem_init
+ *             ix_ossl_sem_fini
+ *             ix_ossl_sem_take
+ *             ix_ossl_sem_give
+ *             ix_ossl_sem_flush
+ *
+ *   OSSL Mutex APIs:
+ *             The OSSL wrapper functions that allow for initialization,
+ *             posting, waiting and deletion of mutexes.
+ *
+ *             ix_ossl_mutex_init
+ *             ix_ossl_mutex_fini
+ *             ix_ossl_mutex_lock
+ *             ix_ossl_mutex_unlock
+ *
+ *   OSSL Timer APIs:
+ *     	       The timer APIs provide sleep and get time functions.
+ *
+ *             ix_ossl_sleep
+ *             ix_ossl_sleep_tick
+ *             ix_ossl_time_get
+ * 
+ *   OSAPIs for Transactor/WorkBench:
+ *             These OSAPI functions are used for transator OS calls. 
+ *             They are defined in osApi.h. 
+ *
+ *             Sem_Init 			
+ *             Sem_Destroy 		
+ *             Sem_Wait 			
+ *             Sem_Wait			
+ *             Thread_Create		
+ *             Thread_Cancel 		
+ *             Thread_SetPriority 		
+ *             delayMs 			
+ *             delayTick			
+ *             
+ *
+ *
+ **********************************************************************
+ *      
+ *
+ * = AUTHOR
+ *      Intel Corporation
+ *
+ * = ACKNOWLEDGEMENTS
+ *      
+ *
+ * = CREATION TIME
+ *      1/8/2002 1:53:42 PM
+ *
+ * = CHANGE HISTORY
+ *   02/22/2002 : Renamed osapi.h os_api.h
+ *                Moved OS header file includes from OSSL.h to os_api.h
+ *                Moved OS specific datatypes to os_api.h 
+ *                Modified data types, macros and functions as per
+ *                'C' coding guidelines.
+ *
+ *
+ * ============================================================================
+ */
+
+#ifndef _IX_OSSL_H
+#ifndef __doxygen_hide
+#define _IX_OSSL_H
+#endif /* __doxygen_hide */
+
+#include "IxOsalBackward.h"
+ 
+#endif /* _IX_OSSL_H */
+
+/**
+ * @} defgroup IxOSSL
+ */
diff --git a/marvell/uboot/drivers/net/npe/include/ix_symbols.h b/marvell/uboot/drivers/net/npe/include/ix_symbols.h
new file mode 100644
index 0000000..0006b22
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/ix_symbols.h
@@ -0,0 +1,82 @@
+/**
+ * ============================================================================
+ * = COPYRIGHT
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ * = PRODUCT
+ *      Intel(r) IXP425 Software Release
+ *
+ * = FILENAME
+ *      ix_symbols.h
+ *
+ * = DESCRIPTION
+ *      This file declares all the global preprocessor symbols required by 
+ *      the IXA SDK Framework API.
+ *
+ * = AUTHOR
+ *      Intel Corporation
+ *
+ * = CHANGE HISTORY
+ *      4/23/2002 10:41:13 AM - creation time 
+ * ============================================================================
+ */
+
+#if !defined(__IX_SYMBOLS_H__)
+#define __IX_SYMBOLS_H__
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif /* end defined(__cplusplus) */
+
+/**
+ * The IX_EXPORT_FUNCTION symbol will be used for compilation on different platforms.
+ * We are planning to provide a simulation version of the library that should work
+ * with the Transactor rather than the hardware. This implementation will be done on
+ * WIN32 in the form of a DLL that will need to export functions and symbols.
+ */
+#if (_IX_OS_TYPE_ == _IX_OS_WIN32_)
+#    if defined(_IX_LIB_INTERFACE_IMPLEMENTATION_)
+#        define IX_EXPORT_FUNCTION __declspec( dllexport )
+#    elif defined(_IX_LIB_INTERFACE_IMPORT_DLL_)
+#        define IX_EXPORT_FUNCTION __declspec( dllimport )
+#    else
+#        define IX_EXPORT_FUNCTION extern 
+#    endif
+#elif (_IX_OS_TYPE_ == _IX_OS_WINCE_)
+#    define IX_EXPORT_FUNCTION __declspec(dllexport)
+#else
+#    define IX_EXPORT_FUNCTION  extern
+#endif
+
+
+/**
+ * This symbols should be defined when we want to build for a multithreaded environment
+ */
+#define _IX_MULTI_THREADED_     1
+    
+
+/**
+ * This symbol should be defined in the case we to buils for a multithreaded environment
+ * but we want that our modules to work as if they are used in a single threaded environment.
+ */
+/* #define _IX_RM_EXPLICIT_SINGLE_THREADED_    1  */
+
+#if defined(__cplusplus)
+}
+#endif /* end defined(__cplusplus) */
+
+#endif /* end !defined(__IX_SYMBOLS_H__) */
diff --git a/marvell/uboot/drivers/net/npe/include/ix_types.h b/marvell/uboot/drivers/net/npe/include/ix_types.h
new file mode 100644
index 0000000..6945506
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/ix_types.h
@@ -0,0 +1,184 @@
+/**
+ * ============================================================================
+ * = COPYRIGHT
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ * = PRODUCT
+ *      Intel(r) IXP425 Software Release
+ *
+ * = FILENAME
+ *      ix_types.h
+ *
+ * = DESCRIPTION
+ *      This file will define generic types that will guarantee the protability
+ *      between different architectures and compilers. It should be used the entire
+ *      IXA SDK Framework API.
+ *
+ * = AUTHOR
+ *      Intel Corporation
+ *
+ * = CHANGE HISTORY
+ *      4/22/2002 4:44:17 PM - creation time 
+ * ============================================================================
+ */
+
+#if !defined(__IX_TYPES_H__)
+#define __IX_TYPES_H__
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif /* end defined(__cplusplus) */
+
+
+/**
+ * Define generic integral data types that will guarantee the size.
+ */
+
+/**
+ * TYPENAME: ix_int8
+ * 
+ * DESCRIPTION: This type defines an 8 bit signed integer value.
+ *
+ */
+typedef signed char ix_int8;
+
+
+/**
+ * TYPENAME: ix_uint8
+ * 
+ * DESCRIPTION: This type defines an 8 bit unsigned integer value.
+ *
+ */
+typedef unsigned char ix_uint8;
+
+
+/**
+ * TYPENAME: ix_int16
+ * 
+ * DESCRIPTION: This type defines an 16 bit signed integer value.
+ *
+ */
+typedef signed short int ix_int16;
+
+
+/**
+ * TYPENAME: ix_uint16
+ * 
+ * DESCRIPTION: This type defines an 16 bit unsigned integer value.
+ *
+ */
+typedef unsigned short int ix_uint16;
+
+
+/**
+ * TYPENAME: ix_int32
+ * 
+ * DESCRIPTION: This type defines an 32 bit signed integer value.
+ *
+ */
+typedef signed int ix_int32;
+
+
+/**
+ * TYPENAME: ix_uint32
+ * 
+ * DESCRIPTION: This type defines an 32 bit unsigned integer value.
+ *
+ */
+#ifndef __wince
+typedef unsigned int ix_uint32;
+#else
+typedef unsigned long ix_uint32;
+#endif
+
+/**
+ * TYPENAME: ix_int64
+ * 
+ * DESCRIPTION: This type defines an 64 bit signed integer value.
+ *
+ */
+#ifndef __wince
+__extension__ typedef signed long long int ix_int64;
+#endif
+
+/**
+ * TYPENAME: ix_uint64
+ * 
+ * DESCRIPTION: This type defines an 64 bit unsigned integer value.
+ *
+ */
+#ifndef __wince
+__extension__ typedef unsigned long long int ix_uint64;
+#endif
+
+
+/**
+ * TYPENAME: ix_bit_mask8
+ * 
+ * DESCRIPTION: This is a generic type for a 8 bit mask. 
+ */
+typedef ix_uint8 ix_bit_mask8;
+
+
+/**
+ * TYPENAME: ix_bit_mask16
+ * 
+ * DESCRIPTION: This is a generic type for a 16 bit mask. 
+ */
+typedef ix_uint16 ix_bit_mask16;
+
+
+/**
+ * TYPENAME: ix_bit_mask32
+ * 
+ * DESCRIPTION: This is a generic type for a 32 bit mask. 
+ */
+typedef ix_uint32 ix_bit_mask32;
+
+
+/**
+ * TYPENAME: ix_bit_mask64
+ * 
+ * DESCRIPTION: This is a generic type for a 64 bit mask. 
+ */
+#ifndef __wince
+typedef ix_uint64 ix_bit_mask64;
+#endif
+
+
+/**
+ * TYPENAME: ix_handle
+ * 
+ * DESCRIPTION: This type defines a generic handle.
+ *
+ */
+typedef ix_uint32 ix_handle;
+
+
+
+/**
+ * DESCRIPTION: This symbol defines a NULL handle
+ *
+ */
+#define IX_NULL_HANDLE   ((ix_handle)0) 
+
+
+#if defined(__cplusplus)
+}
+#endif /* end defined(__cplusplus) */
+
+#endif /* end !defined(__IX_TYPES_H__) */
diff --git a/marvell/uboot/drivers/net/npe/include/npe.h b/marvell/uboot/drivers/net/npe/include/npe.h
new file mode 100644
index 0000000..1c6ae26
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/npe.h
@@ -0,0 +1,74 @@
+/*
+ * (C) Copyright 2005
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef NPE_H
+#define NPE_H
+
+/*
+ * defines...
+ */
+#define CONFIG_SYS_NPE_NUMS		1
+#ifdef CONFIG_HAS_ETH1
+#undef CONFIG_SYS_NPE_NUMS
+#define CONFIG_SYS_NPE_NUMS		2
+#endif
+
+#define NPE_NUM_PORTS		3
+#define ACTIVE_PORTS		1
+
+#define NPE_PKT_SIZE		1600
+
+#define CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS	64
+#define CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS	2
+
+#define NPE_MBUF_POOL_SIZE					\
+	((CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS +	\
+	  CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS) *	\
+	 sizeof(IX_OSAL_MBUF) * ACTIVE_PORTS)
+
+#define NPE_PKT_POOL_SIZE					\
+	((CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS +	\
+	  CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS) *	\
+	 NPE_PKT_SIZE * ACTIVE_PORTS)
+
+#define NPE_MEM_POOL_SIZE (NPE_MBUF_POOL_SIZE + NPE_PKT_POOL_SIZE)
+
+#define PHY_AUTONEGOTIATE_TIMEOUT 4000	/* 4000 ms autonegotiate timeout */
+
+/*
+ * structs...
+ */
+struct npe {
+	u8			active;           /* NPE active				*/
+	u8			eth_id;           /* IX_ETH_PORT_1 or IX_ETH_PORT_2	*/
+	u8			phy_no;           /* which PHY (0 - 31)			*/
+	u8			mac_address[6];
+
+	IX_OSAL_MBUF		*rxQHead;
+	IX_OSAL_MBUF		*txQHead;
+
+	u8			*tx_pkts;
+	u8			*rx_pkts;
+	IX_OSAL_MBUF		*rx_mbufs;
+	IX_OSAL_MBUF		*tx_mbufs;
+
+	int			print_speed;
+
+	int			rx_read;
+	int			rx_write;
+	int			rx_len[PKTBUFSRX];
+};
+
+/*
+ * prototypes...
+ */
+extern int npe_miiphy_read (const char *devname, unsigned char addr,
+			    unsigned char reg, unsigned short *value);
+extern int npe_miiphy_write (const char *devname, unsigned char addr,
+			     unsigned char reg, unsigned short value);
+
+#endif /* ifndef NPE_H */
diff --git a/marvell/uboot/drivers/net/npe/include/os_datatypes.h b/marvell/uboot/drivers/net/npe/include/os_datatypes.h
new file mode 100644
index 0000000..def891b
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/include/os_datatypes.h
@@ -0,0 +1,58 @@
+/**
+ * ============================================================================
+ * = COPYRIGHT
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * @par
+ * -- End of Copyright Notice --
+ * = PRODUCT
+ *      Intel(r) IXP425 Software Release
+ *
+ * = LIBRARY
+ *      OSSL - Operating System Services  Library
+ *
+ * = MODULE
+ *      OS Specific Data Types header file
+ *
+ * = FILENAME
+ *       OSSL.h (Replaced by OSAL)
+ *
+ * = DESCRIPTION
+ *   This file  contains definitions and encapsulations for OS specific data types. These
+ *   encapsulated  data types are  used by OSSL header files and OS API functions.
+ *
+ *
+ **********************************************************************
+ *      
+ *
+ * = AUTHOR
+ *      Intel Corporation
+ *
+ * = AKNOWLEDGEMENTS
+ *      
+ *
+ * = CREATION TIME
+ *      1/8/2002 1:53:42 PM
+ *
+ * = CHANGE HISTORY
+ 
+ * ============================================================================
+ */
+
+#ifndef _OS_DATATYPES_H
+#define _OS_DATATYPES_H
+
+#include "IxOsalBackward.h"
+
+#endif /* _OS_DATATYPES_H */
+
diff --git a/marvell/uboot/drivers/net/npe/miiphy.c b/marvell/uboot/drivers/net/npe/miiphy.c
new file mode 100644
index 0000000..002fb81
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/miiphy.c
@@ -0,0 +1,101 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0	IBM-pibs
+ */
+/*-----------------------------------------------------------------------------+
+  |
+  |  File Name:	 miiphy.c
+  |
+  |  Function:	 This module has utilities for accessing the MII PHY through
+  |	       the EMAC3 macro.
+  |
+  |  Author:	 Mark Wisner
+  |
+  |  Change Activity-
+  |
+  |  Date	 Description of Change					     BY
+  |  ---------	 ---------------------					     ---
+  |  05-May-99	 Created						     MKW
+  |  01-Jul-99	 Changed clock setting of sta_reg from 66MHz to 50MHz to
+  |		 better match OPB speed. Also modified delay times.	     JWB
+  |  29-Jul-99	 Added Full duplex support				     MKW
+  |  24-Aug-99	 Removed printf from dp83843_duplex()			     JWB
+  |  19-Jul-00	 Ported to esd cpci405					     sr
+  |  23-Dec-03	 Ported from miiphy.c to 440GX Travis Sawyer		     TBS
+  |		 <travis.sawyer@sandburst.com>
+  |
+  +-----------------------------------------------------------------------------*/
+
+#include <common.h>
+#include <miiphy.h>
+#include "IxOsal.h"
+#include "IxEthAcc.h"
+#include "IxEthAcc_p.h"
+#include "IxEthAccMac_p.h"
+#include "IxEthAccMii_p.h"
+
+/***********************************************************/
+/* Dump out to the screen PHY regs			   */
+/***********************************************************/
+
+void miiphy_dump (char *devname, unsigned char addr)
+{
+	unsigned long i;
+	unsigned short data;
+
+
+	for (i = 0; i < 0x1A; i++) {
+		if (miiphy_read (devname, addr, i, &data)) {
+			printf ("read error for reg %lx\n", i);
+			return;
+		}
+		printf ("Phy reg %lx ==> %4x\n", i, data);
+
+		/* jump to the next set of regs */
+		if (i == 0x07)
+			i = 0x0f;
+
+	}			/* end for loop */
+}				/* end dump */
+
+
+/***********************************************************/
+/* (Re)start autonegotiation				   */
+/***********************************************************/
+int phy_setup_aneg (char *devname, unsigned char addr)
+{
+	unsigned short ctl, adv;
+
+	/* Setup standard advertise */
+	miiphy_read (devname, addr, MII_ADVERTISE, &adv);
+	adv |= (LPA_LPACK | LPA_RFAULT | LPA_100BASE4 |
+		LPA_100FULL | LPA_100HALF | LPA_10FULL |
+		LPA_10HALF);
+	miiphy_write (devname, addr, MII_ADVERTISE, adv);
+
+	/* Start/Restart aneg */
+	miiphy_read (devname, addr, MII_BMCR, &ctl);
+	ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
+	miiphy_write (devname, addr, MII_BMCR, ctl);
+
+	return 0;
+}
+
+
+int npe_miiphy_read (const char *devname, unsigned char addr,
+		     unsigned char reg, unsigned short *value)
+{
+	u16 val;
+
+	ixEthAccMiiReadRtn(addr, reg, &val);
+	*value = val;
+
+	return 0;
+}				/* phy_read */
+
+
+int npe_miiphy_write (const char *devname, unsigned char addr,
+		      unsigned char reg, unsigned short value)
+{
+	ixEthAccMiiWriteRtn(addr, reg, value);
+	return 0;
+}				/* phy_write */
diff --git a/marvell/uboot/drivers/net/npe/npe.c b/marvell/uboot/drivers/net/npe/npe.c
new file mode 100644
index 0000000..00b381e
--- /dev/null
+++ b/marvell/uboot/drivers/net/npe/npe.c
@@ -0,0 +1,680 @@
+/*
+ * (C) Copyright 2005-2006
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#if 0
+#define DEBUG		/* define for debug output */
+#endif
+
+#include <config.h>
+#include <common.h>
+#include <net.h>
+#include <miiphy.h>
+#include <malloc.h>
+#include <asm/processor.h>
+#include <asm/arch-ixp/ixp425.h>
+
+#include <IxOsal.h>
+#include <IxEthAcc.h>
+#include <IxEthDB.h>
+#include <IxNpeDl.h>
+#include <IxQMgr.h>
+#include <IxNpeMh.h>
+#include <ix_ossl.h>
+#include <IxFeatureCtrl.h>
+
+#include <npe.h>
+
+static IxQMgrDispatcherFuncPtr qDispatcherFunc = NULL;
+static int npe_exists[NPE_NUM_PORTS];
+static int npe_used[NPE_NUM_PORTS];
+
+/* A little extra so we can align to cacheline. */
+static u8 npe_alloc_pool[NPE_MEM_POOL_SIZE + CONFIG_SYS_CACHELINE_SIZE - 1];
+static u8 *npe_alloc_end;
+static u8 *npe_alloc_free;
+
+static void *npe_alloc(int size)
+{
+	static int count = 0;
+	void *p = NULL;
+
+	size = (size + (CONFIG_SYS_CACHELINE_SIZE-1)) & ~(CONFIG_SYS_CACHELINE_SIZE-1);
+	count++;
+
+	if ((npe_alloc_free + size) < npe_alloc_end) {
+		p = npe_alloc_free;
+		npe_alloc_free += size;
+	} else {
+		printf("npe_alloc: failed (count=%d, size=%d)!\n", count, size);
+	}
+	return p;
+}
+
+/* Not interrupt safe! */
+static void mbuf_enqueue(IX_OSAL_MBUF **q, IX_OSAL_MBUF *new)
+{
+	IX_OSAL_MBUF *m = *q;
+
+	IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(new) = NULL;
+
+	if (m) {
+		while(IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m))
+			m = IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m);
+		IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m) = new;
+	} else
+		*q = new;
+}
+
+/* Not interrupt safe! */
+static IX_OSAL_MBUF *mbuf_dequeue(IX_OSAL_MBUF **q)
+{
+	IX_OSAL_MBUF *m = *q;
+	if (m)
+		*q = IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m);
+	return m;
+}
+
+static void reset_tx_mbufs(struct npe* p_npe)
+{
+	IX_OSAL_MBUF *m;
+	int i;
+
+	p_npe->txQHead = NULL;
+
+	for (i = 0; i < CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS; i++) {
+		m = &p_npe->tx_mbufs[i];
+
+		memset(m, 0, sizeof(*m));
+
+		IX_OSAL_MBUF_MDATA(m) = (void *)&p_npe->tx_pkts[i * NPE_PKT_SIZE];
+		IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE;
+		mbuf_enqueue(&p_npe->txQHead, m);
+	}
+}
+
+static void reset_rx_mbufs(struct npe* p_npe)
+{
+	IX_OSAL_MBUF *m;
+	int i;
+
+	p_npe->rxQHead = NULL;
+
+	HAL_DCACHE_INVALIDATE(p_npe->rx_pkts, NPE_PKT_SIZE *
+			      CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS);
+
+	for (i = 0; i < CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS; i++) {
+		m = &p_npe->rx_mbufs[i];
+
+		memset(m, 0, sizeof(*m));
+
+		IX_OSAL_MBUF_MDATA(m) = (void *)&p_npe->rx_pkts[i * NPE_PKT_SIZE];
+		IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE;
+
+		if(ixEthAccPortRxFreeReplenish(p_npe->eth_id, m) != IX_SUCCESS) {
+			printf("ixEthAccPortRxFreeReplenish failed for port %d\n", p_npe->eth_id);
+			break;
+		}
+	}
+}
+
+static void init_rx_mbufs(struct npe* p_npe)
+{
+	p_npe->rxQHead = NULL;
+
+	p_npe->rx_pkts = npe_alloc(NPE_PKT_SIZE *
+				   CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS);
+	if (p_npe->rx_pkts == NULL) {
+		printf("alloc of packets failed.\n");
+		return;
+	}
+
+	p_npe->rx_mbufs = (IX_OSAL_MBUF *)
+		npe_alloc(sizeof(IX_OSAL_MBUF) *
+			  CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS);
+	if (p_npe->rx_mbufs == NULL) {
+		printf("alloc of mbufs failed.\n");
+		return;
+	}
+
+	reset_rx_mbufs(p_npe);
+}
+
+static void init_tx_mbufs(struct npe* p_npe)
+{
+	p_npe->tx_pkts = npe_alloc(NPE_PKT_SIZE *
+				   CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS);
+	if (p_npe->tx_pkts == NULL) {
+		printf("alloc of packets failed.\n");
+		return;
+	}
+
+	p_npe->tx_mbufs = (IX_OSAL_MBUF *)
+		npe_alloc(sizeof(IX_OSAL_MBUF) *
+			  CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS);
+	if (p_npe->tx_mbufs == NULL) {
+		printf("alloc of mbufs failed.\n");
+		return;
+	}
+
+	reset_tx_mbufs(p_npe);
+}
+
+/* Convert IX_ETH_PORT_n to IX_NPEMH_NPEID_NPEx */
+static int __eth_to_npe(int eth_id)
+{
+	switch(eth_id) {
+	case IX_ETH_PORT_1:
+		return IX_NPEMH_NPEID_NPEB;
+
+	case IX_ETH_PORT_2:
+		return IX_NPEMH_NPEID_NPEC;
+
+	case IX_ETH_PORT_3:
+		return IX_NPEMH_NPEID_NPEA;
+	}
+	return 0;
+}
+
+/* Poll the CSR machinery. */
+static void npe_poll(int eth_id)
+{
+	if (qDispatcherFunc != NULL) {
+		ixNpeMhMessagesReceive(__eth_to_npe(eth_id));
+		(*qDispatcherFunc)(IX_QMGR_QUELOW_GROUP);
+	}
+}
+
+/* ethAcc RX callback */
+static void npe_rx_callback(u32 cbTag, IX_OSAL_MBUF *m, IxEthAccPortId portid)
+{
+	struct npe* p_npe = (struct npe *)cbTag;
+
+	if (IX_OSAL_MBUF_MLEN(m) > 0) {
+		mbuf_enqueue(&p_npe->rxQHead, m);
+
+		if (p_npe->rx_write == ((p_npe->rx_read-1) & (PKTBUFSRX-1))) {
+			debug("Rx overflow: rx_write=%d rx_read=%d\n",
+			      p_npe->rx_write, p_npe->rx_read);
+		} else {
+			debug("Received message #%d (len=%d)\n", p_npe->rx_write,
+			      IX_OSAL_MBUF_MLEN(m));
+			memcpy((void *)NetRxPackets[p_npe->rx_write], IX_OSAL_MBUF_MDATA(m),
+			       IX_OSAL_MBUF_MLEN(m));
+			p_npe->rx_len[p_npe->rx_write] = IX_OSAL_MBUF_MLEN(m);
+			p_npe->rx_write++;
+			if (p_npe->rx_write == PKTBUFSRX)
+				p_npe->rx_write = 0;
+
+#ifdef CONFIG_PRINT_RX_FRAMES
+			{
+				u8 *ptr = IX_OSAL_MBUF_MDATA(m);
+				int i;
+
+				for (i=0; i<60; i++) {
+					debug("%02x ", *ptr++);
+				}
+				debug("\n");
+			}
+#endif
+		}
+
+		m = mbuf_dequeue(&p_npe->rxQHead);
+	} else {
+		debug("Received frame with length 0!!!\n");
+		m = mbuf_dequeue(&p_npe->rxQHead);
+	}
+
+	/* Now return mbuf to NPE */
+	IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE;
+	IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m) = NULL;
+	IX_OSAL_MBUF_FLAGS(m) = 0;
+
+	if(ixEthAccPortRxFreeReplenish(p_npe->eth_id, m) != IX_SUCCESS) {
+		debug("npe_rx_callback: Error returning mbuf.\n");
+	}
+}
+
+/* ethAcc TX callback */
+static void npe_tx_callback(u32 cbTag, IX_OSAL_MBUF *m)
+{
+	struct npe* p_npe = (struct npe *)cbTag;
+
+	debug("%s\n", __FUNCTION__);
+
+	IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE;
+	IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m) = NULL;
+	IX_OSAL_MBUF_FLAGS(m) = 0;
+
+	mbuf_enqueue(&p_npe->txQHead, m);
+}
+
+
+static int npe_set_mac_address(struct eth_device *dev)
+{
+	struct npe *p_npe = (struct npe *)dev->priv;
+	IxEthAccMacAddr npeMac;
+
+	debug("%s\n", __FUNCTION__);
+
+	/* Set MAC address */
+	memcpy(npeMac.macAddress, dev->enetaddr, 6);
+
+	if (ixEthAccPortUnicastMacAddressSet(p_npe->eth_id, &npeMac) != IX_ETH_ACC_SUCCESS) {
+		printf("Error setting unicast address! %02x:%02x:%02x:%02x:%02x:%02x\n",
+		       npeMac.macAddress[0], npeMac.macAddress[1],
+		       npeMac.macAddress[2], npeMac.macAddress[3],
+		       npeMac.macAddress[4], npeMac.macAddress[5]);
+		return 0;
+	}
+
+	return 1;
+}
+
+/* Boot-time CSR library initialization. */
+static int npe_csr_load(void)
+{
+	int i;
+
+	if (ixQMgrInit() != IX_SUCCESS) {
+		debug("Error initialising queue manager!\n");
+		return 0;
+	}
+
+	ixQMgrDispatcherLoopGet(&qDispatcherFunc);
+
+	if(ixNpeMhInitialize(IX_NPEMH_NPEINTERRUPTS_YES) != IX_SUCCESS) {
+		printf("Error initialising NPE Message handler!\n");
+		return 0;
+	}
+
+	if (npe_used[IX_ETH_PORT_1] && npe_exists[IX_ETH_PORT_1] &&
+	    ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS)
+	    != IX_SUCCESS) {
+		printf("Error downloading firmware to NPE-B!\n");
+		return 0;
+	}
+
+	if (npe_used[IX_ETH_PORT_2] && npe_exists[IX_ETH_PORT_2] &&
+	    ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS)
+	    != IX_SUCCESS) {
+		printf("Error downloading firmware to NPE-C!\n");
+		return 0;
+	}
+
+	/* don't need this for U-Boot */
+	ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, false);
+
+	if (ixEthAccInit() != IX_ETH_ACC_SUCCESS) {
+		printf("Error initialising Ethernet access driver!\n");
+		return 0;
+	}
+
+	for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++) {
+		if (!npe_used[i] || !npe_exists[i])
+			continue;
+		if (ixEthAccPortInit(i) != IX_ETH_ACC_SUCCESS) {
+			printf("Error initialising Ethernet port%d!\n", i);
+		}
+		if (ixEthAccTxSchedulingDisciplineSet(i, FIFO_NO_PRIORITY) != IX_ETH_ACC_SUCCESS) {
+			printf("Error setting scheduling discipline for port %d.\n", i);
+		}
+		if (ixEthAccPortRxFrameAppendFCSDisable(i) != IX_ETH_ACC_SUCCESS) {
+			printf("Error disabling RX FCS for port %d.\n", i);
+		}
+		if (ixEthAccPortTxFrameAppendFCSEnable(i) != IX_ETH_ACC_SUCCESS) {
+			printf("Error enabling TX FCS for port %d.\n", i);
+		}
+	}
+
+	return 1;
+}
+
+static int npe_init(struct eth_device *dev, bd_t * bis)
+{
+	struct npe *p_npe = (struct npe *)dev->priv;
+	int i;
+	u16 reg_short;
+	int speed;
+	int duplex;
+
+	debug("%s: 1\n", __FUNCTION__);
+
+#ifdef CONFIG_MII_NPE0_FIXEDLINK
+	if (0 == p_npe->eth_id) {
+		speed = CONFIG_MII_NPE0_SPEED;
+		duplex = CONFIG_MII_NPE0_FULLDUPLEX ? FULL : HALF;
+	} else
+#endif
+#ifdef CONFIG_MII_NPE1_FIXEDLINK
+	if (1 == p_npe->eth_id) {
+		speed = CONFIG_MII_NPE1_SPEED;
+		duplex = CONFIG_MII_NPE1_FULLDUPLEX ? FULL : HALF;
+	} else
+#endif
+	{
+		miiphy_read(dev->name, p_npe->phy_no, MII_BMSR, &reg_short);
+
+		/*
+		 * Wait if PHY is capable of autonegotiation and
+		 * autonegotiation is not complete
+		 */
+		if ((reg_short & BMSR_ANEGCAPABLE) &&
+		    !(reg_short & BMSR_ANEGCOMPLETE)) {
+			puts("Waiting for PHY auto negotiation to complete");
+			i = 0;
+			while (!(reg_short & BMSR_ANEGCOMPLETE)) {
+				/*
+				 * Timeout reached ?
+				 */
+				if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
+					puts(" TIMEOUT !\n");
+					break;
+				}
+
+				if ((i++ % 1000) == 0) {
+					putc('.');
+					miiphy_read(dev->name, p_npe->phy_no,
+						     MII_BMSR, &reg_short);
+				}
+				udelay(1000);	/* 1 ms */
+			}
+			puts(" done\n");
+			/* another 500 ms (results in faster booting) */
+			udelay(500000);
+		}
+		speed = miiphy_speed(dev->name, p_npe->phy_no);
+		duplex = miiphy_duplex(dev->name, p_npe->phy_no);
+	}
+
+	if (p_npe->print_speed) {
+		p_npe->print_speed = 0;
+		printf ("ENET Speed is %d Mbps - %s duplex connection\n",
+			(int) speed, (duplex == HALF) ? "HALF" : "FULL");
+	}
+
+	npe_alloc_end = npe_alloc_pool + sizeof(npe_alloc_pool);
+	npe_alloc_free = (u8 *)(((unsigned)npe_alloc_pool +
+				 CONFIG_SYS_CACHELINE_SIZE - 1) & ~(CONFIG_SYS_CACHELINE_SIZE - 1));
+
+	/* initialize mbuf pool */
+	init_rx_mbufs(p_npe);
+	init_tx_mbufs(p_npe);
+
+	if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_callback,
+					   (u32)p_npe) != IX_ETH_ACC_SUCCESS) {
+		printf("can't register RX callback!\n");
+		return -1;
+	}
+
+	if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_callback,
+					       (u32)p_npe) != IX_ETH_ACC_SUCCESS) {
+		printf("can't register TX callback!\n");
+		return -1;
+	}
+
+	npe_set_mac_address(dev);
+
+	if (ixEthAccPortEnable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) {
+		printf("can't enable port!\n");
+		return -1;
+	}
+
+	p_npe->active = 1;
+
+	return 0;
+}
+
+#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */
+/* Uninitialize CSR library. */
+static void npe_csr_unload(void)
+{
+	ixEthAccUnload();
+	ixEthDBUnload();
+	ixNpeMhUnload();
+	ixQMgrUnload();
+}
+
+/* callback which is used by ethAcc to recover RX buffers when stopping */
+static void npe_rx_stop_callback(u32 cbTag, IX_OSAL_MBUF *m, IxEthAccPortId portid)
+{
+	debug("%s\n", __FUNCTION__);
+}
+
+/* callback which is used by ethAcc to recover TX buffers when stopping */
+static void npe_tx_stop_callback(u32 cbTag, IX_OSAL_MBUF *m)
+{
+	debug("%s\n", __FUNCTION__);
+}
+#endif
+
+static void npe_halt(struct eth_device *dev)
+{
+	struct npe *p_npe = (struct npe *)dev->priv;
+	int i;
+
+	debug("%s\n", __FUNCTION__);
+
+	/* Delay to give time for recovery of mbufs */
+	for (i = 0; i < 100; i++) {
+		npe_poll(p_npe->eth_id);
+		udelay(100);
+	}
+
+#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */
+	if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_stop_callback,
+					   (u32)p_npe) != IX_ETH_ACC_SUCCESS) {
+		debug("Error registering rx callback!\n");
+	}
+
+	if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_stop_callback,
+					       (u32)p_npe) != IX_ETH_ACC_SUCCESS) {
+		debug("Error registering tx callback!\n");
+	}
+
+	if (ixEthAccPortDisable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) {
+		debug("npe_stop: Error disabling NPEB!\n");
+	}
+
+	/* Delay to give time for recovery of mbufs */
+	for (i = 0; i < 100; i++) {
+		npe_poll(p_npe->eth_id);
+		udelay(10000);
+	}
+
+	/*
+	 * For U-Boot only, we are probably launching Linux or other OS that
+	 * needs a clean slate for its NPE library.
+	 */
+#if 0 /* test-only */
+	for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++) {
+		if (npe_used[i] && npe_exists[i])
+			if (ixNpeDlNpeStopAndReset(__eth_to_npe(i)) != IX_SUCCESS)
+				printf("Failed to stop and reset NPE B.\n");
+	}
+#endif
+
+#endif
+	p_npe->active = 0;
+}
+
+
+static int npe_send(struct eth_device *dev, void *packet, int len)
+{
+	struct npe *p_npe = (struct npe *)dev->priv;
+	u8 *dest;
+	int err;
+	IX_OSAL_MBUF *m;
+
+	debug("%s\n", __FUNCTION__);
+	m = mbuf_dequeue(&p_npe->txQHead);
+	dest = IX_OSAL_MBUF_MDATA(m);
+	IX_OSAL_MBUF_PKT_LEN(m) = IX_OSAL_MBUF_MLEN(m) = len;
+	IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m) = NULL;
+
+	memcpy(dest, (char *)packet, len);
+
+	if ((err = ixEthAccPortTxFrameSubmit(p_npe->eth_id, m, IX_ETH_ACC_TX_DEFAULT_PRIORITY))
+	    != IX_ETH_ACC_SUCCESS) {
+		printf("npe_send: Can't submit frame. err[%d]\n", err);
+		mbuf_enqueue(&p_npe->txQHead, m);
+		return 0;
+	}
+
+#ifdef DEBUG_PRINT_TX_FRAMES
+	{
+		u8 *ptr = IX_OSAL_MBUF_MDATA(m);
+		int i;
+
+		for (i=0; i<IX_OSAL_MBUF_MLEN(m); i++) {
+			printf("%02x ", *ptr++);
+		}
+		printf(" (tx-len=%d)\n", IX_OSAL_MBUF_MLEN(m));
+	}
+#endif
+
+	npe_poll(p_npe->eth_id);
+
+	return len;
+}
+
+static int npe_rx(struct eth_device *dev)
+{
+	struct npe *p_npe = (struct npe *)dev->priv;
+
+	debug("%s\n", __FUNCTION__);
+	npe_poll(p_npe->eth_id);
+
+	debug("%s: rx_write=%d rx_read=%d\n", __FUNCTION__, p_npe->rx_write, p_npe->rx_read);
+	while (p_npe->rx_write != p_npe->rx_read) {
+		debug("Reading message #%d\n", p_npe->rx_read);
+		NetReceive(NetRxPackets[p_npe->rx_read], p_npe->rx_len[p_npe->rx_read]);
+		p_npe->rx_read++;
+		if (p_npe->rx_read == PKTBUFSRX)
+			p_npe->rx_read = 0;
+	}
+
+	return 0;
+}
+
+int npe_initialize(bd_t * bis)
+{
+	static int virgin = 0;
+	struct eth_device *dev;
+	int eth_num = 0;
+	struct npe *p_npe = NULL;
+	uchar enetaddr[6];
+
+	for (eth_num = 0; eth_num < CONFIG_SYS_NPE_NUMS; eth_num++) {
+
+		/* See if we can actually bring up the interface, otherwise, skip it */
+#ifdef CONFIG_HAS_ETH1
+		if (eth_num == 1) {
+			if (!eth_getenv_enetaddr("eth1addr", enetaddr))
+				continue;
+		} else
+#endif
+			if (!eth_getenv_enetaddr("ethaddr", enetaddr))
+				continue;
+
+		/* Allocate device structure */
+		dev = (struct eth_device *)malloc(sizeof(*dev));
+		if (dev == NULL) {
+			printf ("%s: Cannot allocate eth_device %d\n", __FUNCTION__, eth_num);
+			return -1;
+		}
+		memset(dev, 0, sizeof(*dev));
+
+		/* Allocate our private use data */
+		p_npe = (struct npe *)malloc(sizeof(struct npe));
+		if (p_npe == NULL) {
+			printf("%s: Cannot allocate private hw data for eth_device %d",
+			       __FUNCTION__, eth_num);
+			free(dev);
+			return -1;
+		}
+		memset(p_npe, 0, sizeof(struct npe));
+
+		p_npe->eth_id = eth_num;
+		memcpy(dev->enetaddr, enetaddr, 6);
+#ifdef CONFIG_HAS_ETH1
+		if (eth_num == 1)
+			p_npe->phy_no = CONFIG_PHY1_ADDR;
+		else
+#endif
+			p_npe->phy_no = CONFIG_PHY_ADDR;
+
+		sprintf(dev->name, "NPE%d", eth_num);
+		dev->priv = (void *)p_npe;
+		dev->init = npe_init;
+		dev->halt = npe_halt;
+		dev->send = npe_send;
+		dev->recv = npe_rx;
+
+		p_npe->print_speed = 1;
+
+		if (0 == virgin) {
+			virgin = 1;
+
+			if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X) {
+				switch (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) {
+				case IX_FEATURE_CTRL_SILICON_TYPE_B0:
+				default: /* newer than B0 */
+					/*
+					 * If it is B0 or newer Silicon, we
+					 * only enable port when its
+					 * corresponding Eth Coprocessor is
+					 * available.
+					 */
+					if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
+					    IX_FEATURE_CTRL_COMPONENT_ENABLED)
+						npe_exists[IX_ETH_PORT_1] = true;
+
+					if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
+					    IX_FEATURE_CTRL_COMPONENT_ENABLED)
+						npe_exists[IX_ETH_PORT_2] = true;
+					break;
+				case IX_FEATURE_CTRL_SILICON_TYPE_A0:
+					/*
+					 * If it is A0 Silicon, we enable both as both Eth Coprocessors
+					 * are available.
+					 */
+					npe_exists[IX_ETH_PORT_1] = true;
+					npe_exists[IX_ETH_PORT_2] = true;
+					break;
+				}
+			} else if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X) {
+				if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
+				    IX_FEATURE_CTRL_COMPONENT_ENABLED)
+					npe_exists[IX_ETH_PORT_1] = true;
+
+				if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
+				    IX_FEATURE_CTRL_COMPONENT_ENABLED)
+					npe_exists[IX_ETH_PORT_2] = true;
+			}
+
+			npe_used[IX_ETH_PORT_1] = 1;
+			npe_used[IX_ETH_PORT_2] = 1;
+
+			npe_alloc_end = npe_alloc_pool + sizeof(npe_alloc_pool);
+			npe_alloc_free = (u8 *)(((unsigned)npe_alloc_pool +
+						 CONFIG_SYS_CACHELINE_SIZE - 1)
+						& ~(CONFIG_SYS_CACHELINE_SIZE - 1));
+
+			if (!npe_csr_load())
+				return 0;
+		}
+
+		eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+		miiphy_register(dev->name, npe_miiphy_read, npe_miiphy_write);
+#endif
+
+	}			/* end for each supported device */
+
+	return 1;
+}
diff --git a/marvell/uboot/drivers/net/ns8382x.c b/marvell/uboot/drivers/net/ns8382x.c
new file mode 100644
index 0000000..cfe1f34
--- /dev/null
+++ b/marvell/uboot/drivers/net/ns8382x.c
@@ -0,0 +1,851 @@
+/*
+   ns8382x.c: A U-Boot driver for the NatSemi DP8382[01].
+   ported by: Mark A. Rakes (mark_rakes@vivato.net)
+
+   Adapted from:
+   1. an Etherboot driver for DP8381[56] written by:
+	   Copyright (C) 2001 Entity Cyber, Inc.
+
+	   This development of this Etherboot driver was funded by
+		  Sicom Systems: http://www.sicompos.com/
+
+	   Author: Marty Connor (mdc@thinguin.org)
+	   Adapted from a Linux driver which was written by Donald Becker
+
+	   This software may be used and distributed according to the terms
+	   of the GNU Public License (GPL), incorporated herein by reference.
+
+   2. A Linux driver by Donald Becker, ns820.c:
+		Written/copyright 1999-2002 by Donald Becker.
+
+		This software may be used and distributed according to the terms of
+		the GNU General Public License (GPL), incorporated herein by reference.
+		Drivers based on or derived from this code fall under the GPL and must
+		retain the authorship, copyright and license notice.  This file is not
+		a complete program and may only be used when the entire operating
+		system is licensed under the GPL.  License for under other terms may be
+		available.  Contact the original author for details.
+
+		The original author may be reached as becker@scyld.com, or at
+		Scyld Computing Corporation
+		410 Severn Ave., Suite 210
+		Annapolis MD 21403
+
+		Support information and updates available at
+		http://www.scyld.com/network/netsemi.html
+
+   Datasheets available from:
+   http://www.national.com/pf/DP/DP83820.html
+   http://www.national.com/pf/DP/DP83821.html
+*/
+
+/* Revision History
+ * October 2002 mar	1.0
+ *   Initial U-Boot Release.
+ *	Tested with Netgear GA622T (83820)
+ *	and SMC9452TX (83821)
+ *	NOTE: custom boards with these chips may (likely) require
+ *	a programmed EEPROM device (if present) in order to work
+ *	correctly.
+*/
+
+/* Includes */
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <pci.h>
+
+/* defines */
+#define DSIZE     0x00000FFF
+#define ETH_ALEN		6
+#define CRC_SIZE  4
+#define TOUT_LOOP   500000
+#define TX_BUF_SIZE    1536
+#define RX_BUF_SIZE    1536
+#define NUM_RX_DESC    4	/* Number of Rx descriptor registers. */
+
+enum register_offsets {
+	ChipCmd = 0x00,
+	ChipConfig = 0x04,
+	EECtrl = 0x08,
+	IntrMask = 0x14,
+	IntrEnable = 0x18,
+	TxRingPtr = 0x20,
+	TxRingPtrHi = 0x24,
+	TxConfig = 0x28,
+	RxRingPtr = 0x30,
+	RxRingPtrHi = 0x34,
+	RxConfig = 0x38,
+	PriQueue = 0x3C,
+	RxFilterAddr = 0x48,
+	RxFilterData = 0x4C,
+	ClkRun = 0xCC,
+	PCIPM = 0x44,
+};
+
+enum ChipCmdBits {
+	ChipReset = 0x100,
+	RxReset = 0x20,
+	TxReset = 0x10,
+	RxOff = 0x08,
+	RxOn = 0x04,
+	TxOff = 0x02,
+	TxOn = 0x01
+};
+
+enum ChipConfigBits {
+	LinkSts = 0x80000000,
+	GigSpeed = 0x40000000,
+	HundSpeed = 0x20000000,
+	FullDuplex = 0x10000000,
+	TBIEn = 0x01000000,
+	Mode1000 = 0x00400000,
+	T64En = 0x00004000,
+	D64En = 0x00001000,
+	M64En = 0x00000800,
+	PhyRst = 0x00000400,
+	PhyDis = 0x00000200,
+	ExtStEn = 0x00000100,
+	BEMode = 0x00000001,
+};
+#define SpeedStatus_Polarity ( GigSpeed | HundSpeed | FullDuplex)
+
+enum TxConfig_bits {
+	TxDrthMask	= 0x000000ff,
+	TxFlthMask	= 0x0000ff00,
+	TxMxdmaMask	= 0x00700000,
+	TxMxdma_8	= 0x00100000,
+	TxMxdma_16	= 0x00200000,
+	TxMxdma_32	= 0x00300000,
+	TxMxdma_64	= 0x00400000,
+	TxMxdma_128	= 0x00500000,
+	TxMxdma_256	= 0x00600000,
+	TxMxdma_512	= 0x00700000,
+	TxMxdma_1024	= 0x00000000,
+	TxCollRetry	= 0x00800000,
+	TxAutoPad	= 0x10000000,
+	TxMacLoop	= 0x20000000,
+	TxHeartIgn	= 0x40000000,
+	TxCarrierIgn	= 0x80000000
+};
+
+enum RxConfig_bits {
+	RxDrthMask	= 0x0000003e,
+	RxMxdmaMask	= 0x00700000,
+	RxMxdma_8	= 0x00100000,
+	RxMxdma_16	= 0x00200000,
+	RxMxdma_32	= 0x00300000,
+	RxMxdma_64	= 0x00400000,
+	RxMxdma_128	= 0x00500000,
+	RxMxdma_256	= 0x00600000,
+	RxMxdma_512	= 0x00700000,
+	RxMxdma_1024	= 0x00000000,
+	RxAcceptLenErr	= 0x04000000,
+	RxAcceptLong	= 0x08000000,
+	RxAcceptTx	= 0x10000000,
+	RxStripCRC	= 0x20000000,
+	RxAcceptRunt	= 0x40000000,
+	RxAcceptErr	= 0x80000000,
+};
+
+/* Bits in the RxMode register. */
+enum rx_mode_bits {
+	RxFilterEnable		= 0x80000000,
+	AcceptAllBroadcast	= 0x40000000,
+	AcceptAllMulticast	= 0x20000000,
+	AcceptAllUnicast	= 0x10000000,
+	AcceptPerfectMatch	= 0x08000000,
+};
+
+typedef struct _BufferDesc {
+	u32 link;
+	u32 bufptr;
+	vu_long cmdsts;
+	u32 extsts;		/*not used here */
+} BufferDesc;
+
+/* Bits in network_desc.status */
+enum desc_status_bits {
+	DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000,
+	DescNoCRC = 0x10000000, DescPktOK = 0x08000000,
+	DescSizeMask = 0xfff,
+
+	DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000,
+	DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000,
+	DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000,
+	DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000,
+
+	DescRxAbort = 0x04000000, DescRxOver = 0x02000000,
+	DescRxDest = 0x01800000, DescRxLong = 0x00400000,
+	DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000,
+	DescRxCRC = 0x00080000, DescRxAlign = 0x00040000,
+	DescRxLoop = 0x00020000, DesRxColl = 0x00010000,
+};
+
+/* Bits in MEAR */
+enum mii_reg_bits {
+	MDIO_ShiftClk = 0x0040,
+	MDIO_EnbOutput = 0x0020,
+	MDIO_Data = 0x0010,
+};
+
+/* PHY Register offsets.  */
+enum phy_reg_offsets {
+	BMCR = 0x00,
+	BMSR = 0x01,
+	PHYIDR1 = 0x02,
+	PHYIDR2 = 0x03,
+	ANAR = 0x04,
+	KTCR = 0x09,
+};
+
+/* basic mode control register bits */
+enum bmcr_bits {
+	Bmcr_Reset = 0x8000,
+	Bmcr_Loop = 0x4000,
+	Bmcr_Speed0 = 0x2000,
+	Bmcr_AutoNegEn = 0x1000,	/*if set ignores Duplex, Speed[01] */
+	Bmcr_RstAutoNeg = 0x0200,
+	Bmcr_Duplex = 0x0100,
+	Bmcr_Speed1 = 0x0040,
+	Bmcr_Force10H = 0x0000,
+	Bmcr_Force10F = 0x0100,
+	Bmcr_Force100H = 0x2000,
+	Bmcr_Force100F = 0x2100,
+	Bmcr_Force1000H = 0x0040,
+	Bmcr_Force1000F = 0x0140,
+};
+
+/* auto negotiation advertisement register */
+enum anar_bits {
+	anar_adv_100F = 0x0100,
+	anar_adv_100H = 0x0080,
+	anar_adv_10F = 0x0040,
+	anar_adv_10H = 0x0020,
+	anar_ieee_8023 = 0x0001,
+};
+
+/* 1K-base T control register */
+enum ktcr_bits {
+	ktcr_adv_1000H = 0x0100,
+	ktcr_adv_1000F = 0x0200,
+};
+
+/* Globals */
+static u32 SavedClkRun;
+static unsigned int cur_rx;
+static unsigned int rx_config;
+static unsigned int tx_config;
+
+/* Note: transmit and receive buffers and descriptors must be
+   long long word aligned */
+static BufferDesc txd __attribute__ ((aligned(8)));
+static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(8)));
+static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(8)));
+static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]
+    __attribute__ ((aligned(8)));
+
+/* Function Prototypes */
+static int mdio_read(struct eth_device *dev, int phy_id, int addr);
+static void mdio_write(struct eth_device *dev, int phy_id, int addr, int value);
+static void mdio_sync(struct eth_device *dev, u32 offset);
+static int ns8382x_init(struct eth_device *dev, bd_t * bis);
+static void ns8382x_reset(struct eth_device *dev);
+static void ns8382x_init_rxfilter(struct eth_device *dev);
+static void ns8382x_init_txd(struct eth_device *dev);
+static void ns8382x_init_rxd(struct eth_device *dev);
+static void ns8382x_set_rx_mode(struct eth_device *dev);
+static void ns8382x_check_duplex(struct eth_device *dev);
+static int ns8382x_send(struct eth_device *dev, void *packet, int length);
+static int ns8382x_poll(struct eth_device *dev);
+static void ns8382x_disable(struct eth_device *dev);
+
+static struct pci_device_id supported[] = {
+	{PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83820},
+	{}
+};
+
+#define bus_to_phys(a)	pci_mem_to_phys((pci_dev_t)dev->priv, a)
+#define phys_to_bus(a)	pci_phys_to_mem((pci_dev_t)dev->priv, a)
+
+static inline int
+INW(struct eth_device *dev, u_long addr)
+{
+	return le16_to_cpu(*(vu_short *) (addr + dev->iobase));
+}
+
+static int
+INL(struct eth_device *dev, u_long addr)
+{
+	return le32_to_cpu(*(vu_long *) (addr + dev->iobase));
+}
+
+static inline void
+OUTW(struct eth_device *dev, int command, u_long addr)
+{
+	*(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command);
+}
+
+static inline void
+OUTL(struct eth_device *dev, int command, u_long addr)
+{
+	*(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command);
+}
+
+/* Function: ns8382x_initialize
+ * Description: Retrieves the MAC address of the card, and sets up some
+ *  globals required by other routines, and initializes the NIC, making it
+ *  ready to send and receive packets.
+ * Side effects: initializes ns8382xs, ready to receive packets.
+ * Returns:   int:          number of cards found
+ */
+
+int
+ns8382x_initialize(bd_t * bis)
+{
+	pci_dev_t devno;
+	int card_number = 0;
+	struct eth_device *dev;
+	u32 iobase, status;
+	int i, idx = 0;
+	u32 phyAddress;
+	u32 tmp;
+	u32 chip_config;
+
+	while (1) {		/* Find PCI device(s) */
+		if ((devno = pci_find_devices(supported, idx++)) < 0)
+			break;
+
+		pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
+		iobase &= ~0x3;	/* 1: unused and 0:I/O Space Indicator */
+
+		debug("ns8382x: NatSemi dp8382x @ 0x%x\n", iobase);
+
+		pci_write_config_dword(devno, PCI_COMMAND,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+		/* Check if I/O accesses and Bus Mastering are enabled. */
+		pci_read_config_dword(devno, PCI_COMMAND, &status);
+		if (!(status & PCI_COMMAND_MEMORY)) {
+			printf("Error: Can not enable MEM access.\n");
+			continue;
+		} else if (!(status & PCI_COMMAND_MASTER)) {
+			printf("Error: Can not enable Bus Mastering.\n");
+			continue;
+		}
+
+		dev = (struct eth_device *) malloc(sizeof *dev);
+		if (!dev) {
+			printf("ns8382x: Can not allocate memory\n");
+			break;
+		}
+		memset(dev, 0, sizeof(*dev));
+
+		sprintf(dev->name, "dp8382x#%d", card_number);
+		dev->iobase = bus_to_phys(iobase);
+		dev->priv = (void *) devno;
+		dev->init = ns8382x_init;
+		dev->halt = ns8382x_disable;
+		dev->send = ns8382x_send;
+		dev->recv = ns8382x_poll;
+
+		/* ns8382x has a non-standard PM control register
+		 * in PCI config space.  Some boards apparently need
+		 * to be brought to D0 in this manner.  */
+		pci_read_config_dword(devno, PCIPM, &tmp);
+		if (tmp & (0x03 | 0x100)) {	/* D0 state, disable PME assertion */
+			u32 newtmp = tmp & ~(0x03 | 0x100);
+			pci_write_config_dword(devno, PCIPM, newtmp);
+		}
+
+		/* get MAC address */
+		for (i = 0; i < 3; i++) {
+			u32 data;
+			char *mac = (char *)&dev->enetaddr[i * 2];
+
+			OUTL(dev, i * 2, RxFilterAddr);
+			data = INL(dev, RxFilterData);
+			*mac++ = data;
+			*mac++ = data >> 8;
+		}
+		/* get PHY address, can't be zero */
+		for (phyAddress = 1; phyAddress < 32; phyAddress++) {
+			u32 rev, phy1;
+
+			phy1 = mdio_read(dev, phyAddress, PHYIDR1);
+			if (phy1 == 0x2000) {	/*check for 83861/91 */
+				rev = mdio_read(dev, phyAddress, PHYIDR2);
+				if ((rev & ~(0x000f)) == 0x00005c50 ||
+				    (rev & ~(0x000f)) == 0x00005c60) {
+					debug("phy rev is %x\n", rev);
+					debug("phy address is %x\n",
+					       phyAddress);
+					break;
+				}
+			}
+		}
+
+		/* set phy to autonegotiate && advertise everything */
+		mdio_write(dev, phyAddress, KTCR,
+			   (ktcr_adv_1000H | ktcr_adv_1000F));
+		mdio_write(dev, phyAddress, ANAR,
+			   (anar_adv_100F | anar_adv_100H | anar_adv_10H |
+			    anar_adv_10F | anar_ieee_8023));
+		mdio_write(dev, phyAddress, BMCR, 0x0);	/*restore */
+		mdio_write(dev, phyAddress, BMCR,
+			   (Bmcr_AutoNegEn | Bmcr_RstAutoNeg));
+		/* Reset the chip to erase any previous misconfiguration. */
+		OUTL(dev, (ChipReset), ChipCmd);
+
+		chip_config = INL(dev, ChipConfig);
+		/* reset the phy */
+		OUTL(dev, (chip_config | PhyRst), ChipConfig);
+		/* power up and initialize transceiver */
+		OUTL(dev, (chip_config & ~(PhyDis)), ChipConfig);
+
+		mdio_sync(dev, EECtrl);
+
+		{
+			u32 chpcfg =
+			    INL(dev, ChipConfig) ^ SpeedStatus_Polarity;
+
+			debug("%s: Transceiver 10%s %s duplex.\n", dev->name,
+			       (chpcfg & GigSpeed) ? "00" : (chpcfg & HundSpeed)
+			       ? "0" : "",
+			       chpcfg & FullDuplex ? "full" : "half");
+			debug("%s: %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
+			       dev->enetaddr[0], dev->enetaddr[1],
+			       dev->enetaddr[2], dev->enetaddr[3],
+			       dev->enetaddr[4], dev->enetaddr[5]);
+		}
+
+		/* Disable PME:
+		 * The PME bit is initialized from the EEPROM contents.
+		 * PCI cards probably have PME disabled, but motherboard
+		 * implementations may have PME set to enable WakeOnLan.
+		 * With PME set the chip will scan incoming packets but
+		 * nothing will be written to memory. */
+		SavedClkRun = INL(dev, ClkRun);
+		OUTL(dev, SavedClkRun & ~0x100, ClkRun);
+
+		eth_register(dev);
+
+		card_number++;
+
+		pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x60);
+
+		udelay(10 * 1000);
+	}
+	return card_number;
+}
+
+/*  MII transceiver control section.
+	Read and write MII registers using software-generated serial MDIO
+	protocol.  See the MII specifications or DP83840A data sheet for details.
+
+	The maximum data clock rate is 2.5 MHz.  To meet minimum timing we
+	must flush writes to the PCI bus with a PCI read. */
+#define mdio_delay(mdio_addr) INL(dev, mdio_addr)
+
+#define MDIO_EnbIn  (0)
+#define MDIO_WRITE0 (MDIO_EnbOutput)
+#define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput)
+
+/* Generate the preamble required for initial synchronization and
+   a few older transceivers. */
+static void
+mdio_sync(struct eth_device *dev, u32 offset)
+{
+	int bits = 32;
+
+	/* Establish sync by sending at least 32 logic ones. */
+	while (--bits >= 0) {
+		OUTL(dev, MDIO_WRITE1, offset);
+		mdio_delay(offset);
+		OUTL(dev, MDIO_WRITE1 | MDIO_ShiftClk, offset);
+		mdio_delay(offset);
+	}
+}
+
+static int
+mdio_read(struct eth_device *dev, int phy_id, int addr)
+{
+	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | addr;
+	int i, retval = 0;
+
+	/* Shift the read command bits out. */
+	for (i = 15; i >= 0; i--) {
+		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
+
+		OUTL(dev, dataval, EECtrl);
+		mdio_delay(EECtrl);
+		OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);
+		mdio_delay(EECtrl);
+	}
+	/* Read the two transition, 16 data, and wire-idle bits. */
+	for (i = 19; i > 0; i--) {
+		OUTL(dev, MDIO_EnbIn, EECtrl);
+		mdio_delay(EECtrl);
+		retval =
+		    (retval << 1) | ((INL(dev, EECtrl) & MDIO_Data) ? 1 : 0);
+		OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);
+		mdio_delay(EECtrl);
+	}
+	return (retval >> 1) & 0xffff;
+}
+
+static void
+mdio_write(struct eth_device *dev, int phy_id, int addr, int value)
+{
+	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (addr << 18) | value;
+	int i;
+
+	/* Shift the command bits out. */
+	for (i = 31; i >= 0; i--) {
+		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
+
+		OUTL(dev, dataval, EECtrl);
+		mdio_delay(EECtrl);
+		OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);
+		mdio_delay(EECtrl);
+	}
+	/* Clear out extra bits. */
+	for (i = 2; i > 0; i--) {
+		OUTL(dev, MDIO_EnbIn, EECtrl);
+		mdio_delay(EECtrl);
+		OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);
+		mdio_delay(EECtrl);
+	}
+	return;
+}
+
+/* Function: ns8382x_init
+ * Description: resets the ethernet controller chip and configures
+ *    registers and data structures required for sending and receiving packets.
+ * Arguments: struct eth_device *dev:       NIC data structure
+ * returns:	int.
+ */
+
+static int
+ns8382x_init(struct eth_device *dev, bd_t * bis)
+{
+	u32 config;
+
+	ns8382x_reset(dev);
+
+	/* Disable PME:
+	 * The PME bit is initialized from the EEPROM contents.
+	 * PCI cards probably have PME disabled, but motherboard
+	 * implementations may have PME set to enable WakeOnLan.
+	 * With PME set the chip will scan incoming packets but
+	 * nothing will be written to memory. */
+	OUTL(dev, SavedClkRun & ~0x100, ClkRun);
+
+	ns8382x_init_rxfilter(dev);
+	ns8382x_init_txd(dev);
+	ns8382x_init_rxd(dev);
+
+	/*set up ChipConfig */
+	config = INL(dev, ChipConfig);
+	/*turn off 64 bit ops && Ten-bit interface
+	 * && big-endian mode && extended status */
+	config &= ~(TBIEn | Mode1000 | T64En | D64En | M64En | BEMode | PhyDis | ExtStEn);
+	OUTL(dev, config, ChipConfig);
+
+	/* Configure the PCI bus bursts and FIFO thresholds. */
+	tx_config = TxCarrierIgn | TxHeartIgn | TxAutoPad
+	    | TxCollRetry | TxMxdma_1024 | (0x1002);
+	rx_config = RxMxdma_1024 | 0x20;
+
+	debug("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config);
+	debug("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config);
+
+	OUTL(dev, tx_config, TxConfig);
+	OUTL(dev, rx_config, RxConfig);
+
+	/*turn off priority queueing */
+	OUTL(dev, 0x0, PriQueue);
+
+	ns8382x_check_duplex(dev);
+	ns8382x_set_rx_mode(dev);
+
+	OUTL(dev, (RxOn | TxOn), ChipCmd);
+	return 1;
+}
+
+/* Function: ns8382x_reset
+ * Description: soft resets the controller chip
+ * Arguments: struct eth_device *dev:          NIC data structure
+ * Returns:   void.
+ */
+static void
+ns8382x_reset(struct eth_device *dev)
+{
+	OUTL(dev, ChipReset, ChipCmd);
+	while (INL(dev, ChipCmd))
+		/*wait until done */ ;
+	OUTL(dev, 0, IntrMask);
+	OUTL(dev, 0, IntrEnable);
+}
+
+/* Function: ns8382x_init_rxfilter
+ * Description: sets receive filter address to our MAC address
+ * Arguments: struct eth_device *dev:          NIC data structure
+ * returns:   void.
+ */
+
+static void
+ns8382x_init_rxfilter(struct eth_device *dev)
+{
+	int i;
+
+	for (i = 0; i < ETH_ALEN; i += 2) {
+		OUTL(dev, i, RxFilterAddr);
+		OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8),
+		     RxFilterData);
+	}
+}
+
+/* Function: ns8382x_init_txd
+ * Description: initializes the Tx descriptor
+ * Arguments: struct eth_device *dev:          NIC data structure
+ * returns:   void.
+ */
+
+static void
+ns8382x_init_txd(struct eth_device *dev)
+{
+	txd.link = (u32) 0;
+	txd.bufptr = cpu_to_le32((u32) & txb[0]);
+	txd.cmdsts = (u32) 0;
+	txd.extsts = (u32) 0;
+
+	OUTL(dev, 0x0, TxRingPtrHi);
+	OUTL(dev, phys_to_bus((u32)&txd), TxRingPtr);
+
+	debug("ns8382x_init_txd: TX descriptor register loaded with: %#08X (&txd: %p)\n",
+	       INL(dev, TxRingPtr), &txd);
+}
+
+/* Function: ns8382x_init_rxd
+ * Description: initializes the Rx descriptor ring
+ * Arguments: struct eth_device *dev:          NIC data structure
+ * Returns:   void.
+ */
+
+static void
+ns8382x_init_rxd(struct eth_device *dev)
+{
+	int i;
+
+	OUTL(dev, 0x0, RxRingPtrHi);
+
+	cur_rx = 0;
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		rxd[i].link =
+		    cpu_to_le32((i + 1 <
+				 NUM_RX_DESC) ? (u32) & rxd[i +
+							    1] : (u32) &
+				rxd[0]);
+		rxd[i].extsts = cpu_to_le32((u32) 0x0);
+		rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE);
+		rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]);
+
+		debug
+		    ("ns8382x_init_rxd: rxd[%d]=%p link=%X cmdsts=%X bufptr=%X\n",
+		     i, &rxd[i], le32_to_cpu(rxd[i].link),
+		     le32_to_cpu(rxd[i].cmdsts), le32_to_cpu(rxd[i].bufptr));
+	}
+	OUTL(dev, phys_to_bus((u32) & rxd), RxRingPtr);
+
+	debug("ns8382x_init_rxd: RX descriptor register loaded with: %X\n",
+	       INL(dev, RxRingPtr));
+}
+
+/* Function: ns8382x_set_rx_mode
+ * Description:
+ *    sets the receive mode to accept all broadcast packets and packets
+ *    with our MAC address, and reject all multicast packets.
+ * Arguments: struct eth_device *dev:          NIC data structure
+ * Returns:   void.
+ */
+
+static void
+ns8382x_set_rx_mode(struct eth_device *dev)
+{
+	u32 rx_mode = 0x0;
+	/*spec says RxFilterEnable has to be 0 for rest of
+	 * this stuff to be properly configured. Linux driver
+	 * seems to support this*/
+/*	OUTL(dev, rx_mode, RxFilterAddr);*/
+	rx_mode = (RxFilterEnable | AcceptAllBroadcast | AcceptPerfectMatch);
+	OUTL(dev, rx_mode, RxFilterAddr);
+	printf("ns8382x_set_rx_mode: set to %X\n", rx_mode);
+	/*now we turn RxFilterEnable back on */
+	/*rx_mode |= RxFilterEnable;
+	OUTL(dev, rx_mode, RxFilterAddr);*/
+}
+
+static void
+ns8382x_check_duplex(struct eth_device *dev)
+{
+	int gig = 0;
+	int hun = 0;
+	int duplex = 0;
+	int config = (INL(dev, ChipConfig) ^ SpeedStatus_Polarity);
+
+	duplex = (config & FullDuplex) ? 1 : 0;
+	gig = (config & GigSpeed) ? 1 : 0;
+	hun = (config & HundSpeed) ? 1 : 0;
+
+	debug("%s: Setting 10%s %s-duplex based on negotiated link"
+	       " capability.\n", dev->name, (gig) ? "00" : (hun) ? "0" : "",
+	       duplex ? "full" : "half");
+
+	if (duplex) {
+		rx_config |= RxAcceptTx;
+		tx_config |= (TxCarrierIgn | TxHeartIgn);
+	} else {
+		rx_config &= ~RxAcceptTx;
+		tx_config &= ~(TxCarrierIgn | TxHeartIgn);
+	}
+
+	debug("%s: Resetting TxConfig Register %#08X\n", dev->name, tx_config);
+	debug("%s: Resetting RxConfig Register %#08X\n", dev->name, rx_config);
+
+	OUTL(dev, tx_config, TxConfig);
+	OUTL(dev, rx_config, RxConfig);
+
+	/*if speed is 10 or 100, remove MODE1000,
+	 * if it's 1000, then set it */
+	config = INL(dev, ChipConfig);
+	if (gig)
+		config |= Mode1000;
+	else
+		config &= ~Mode1000;
+
+	debug("%s: %setting Mode1000\n", dev->name, (gig) ? "S" : "Uns");
+
+	OUTL(dev, config, ChipConfig);
+}
+
+/* Function: ns8382x_send
+ * Description: transmits a packet and waits for completion or timeout.
+ * Returns:   void.  */
+static int ns8382x_send(struct eth_device *dev, void *packet, int length)
+{
+	u32 i, status = 0;
+	vu_long tx_stat = 0;
+
+	/* Stop the transmitter */
+	OUTL(dev, TxOff, ChipCmd);
+
+	debug("ns8382x_send: sending %d bytes\n", (int)length);
+
+	/* set the transmit buffer descriptor and enable Transmit State Machine */
+	txd.link = cpu_to_le32(0x0);
+	txd.bufptr = cpu_to_le32(phys_to_bus((u32)packet));
+	txd.extsts = cpu_to_le32(0x0);
+	txd.cmdsts = cpu_to_le32(DescOwn | length);
+
+	/* load Transmit Descriptor Register */
+	OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr);
+
+	debug("ns8382x_send: TX descriptor register loaded with: %#08X\n",
+	       INL(dev, TxRingPtr));
+	debug("\ttxd.link:%X\tbufp:%X\texsts:%X\tcmdsts:%X\n",
+	       le32_to_cpu(txd.link), le32_to_cpu(txd.bufptr),
+	       le32_to_cpu(txd.extsts), le32_to_cpu(txd.cmdsts));
+
+	/* restart the transmitter */
+	OUTL(dev, TxOn, ChipCmd);
+
+	for (i = 0; (tx_stat = le32_to_cpu(txd.cmdsts)) & DescOwn; i++) {
+		if (i >= TOUT_LOOP) {
+			printf ("%s: tx error buffer not ready: txd.cmdsts %#lX\n",
+			     dev->name, tx_stat);
+			goto Done;
+		}
+	}
+
+	if (!(tx_stat & DescPktOK)) {
+		printf("ns8382x_send: Transmit error, Tx status %lX.\n", tx_stat);
+		goto Done;
+	}
+
+	debug("ns8382x_send: tx_stat: %#08lX\n", tx_stat);
+
+	status = 1;
+Done:
+	return status;
+}
+
+/* Function: ns8382x_poll
+ * Description: checks for a received packet and returns it if found.
+ * Arguments: struct eth_device *dev:          NIC data structure
+ * Returns:   1 if    packet was received.
+ *            0 if no packet was received.
+ * Side effects:
+ *            Returns (copies) the packet to the array dev->packet.
+ *            Returns the length of the packet.
+ */
+
+static int
+ns8382x_poll(struct eth_device *dev)
+{
+	int retstat = 0;
+	int length = 0;
+	vu_long rx_status = le32_to_cpu(rxd[cur_rx].cmdsts);
+
+	if (!(rx_status & (u32) DescOwn))
+		return retstat;
+
+	debug("ns8382x_poll: got a packet: cur_rx:%u, status:%lx\n",
+	       cur_rx, rx_status);
+
+	length = (rx_status & DSIZE) - CRC_SIZE;
+
+	if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {
+		/* corrupted packet received */
+		printf("ns8382x_poll: Corrupted packet, status:%lx\n", rx_status);
+		retstat = 0;
+	} else {
+		/* give packet to higher level routine */
+		NetReceive((rxb + cur_rx * RX_BUF_SIZE), length);
+		retstat = 1;
+	}
+
+	/* return the descriptor and buffer to receive ring */
+	rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE);
+	rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]);
+
+	if (++cur_rx == NUM_RX_DESC)
+		cur_rx = 0;
+
+	/* re-enable the potentially idle receive state machine */
+	OUTL(dev, RxOn, ChipCmd);
+
+	return retstat;
+}
+
+/* Function: ns8382x_disable
+ * Description: Turns off interrupts and stops Tx and Rx engines
+ * Arguments: struct eth_device *dev:          NIC data structure
+ * Returns:   void.
+ */
+
+static void
+ns8382x_disable(struct eth_device *dev)
+{
+	/* Disable interrupts using the mask. */
+	OUTL(dev, 0, IntrMask);
+	OUTL(dev, 0, IntrEnable);
+
+	/* Stop the chip's Tx and Rx processes. */
+	OUTL(dev, (RxOff | TxOff), ChipCmd);
+
+	/* Restore PME enable bit */
+	OUTL(dev, SavedClkRun, ClkRun);
+}
diff --git a/marvell/uboot/drivers/net/pcnet.c b/marvell/uboot/drivers/net/pcnet.c
new file mode 100644
index 0000000..71a3110
--- /dev/null
+++ b/marvell/uboot/drivers/net/pcnet.c
@@ -0,0 +1,534 @@
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger, wg@denx.de.
+ *
+ * This driver for AMD PCnet network controllers is derived from the
+ * Linux driver pcnet32.c written 1996-1999 by Thomas Bogendoerfer.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#define	PCNET_DEBUG_LEVEL	0	/* 0=off, 1=init, 2=rx/tx */
+
+#define PCNET_DEBUG1(fmt,args...)	\
+	debug_cond(PCNET_DEBUG_LEVEL > 0, fmt ,##args)
+#define PCNET_DEBUG2(fmt,args...)	\
+	debug_cond(PCNET_DEBUG_LEVEL > 1, fmt ,##args)
+
+#if !defined(CONF_PCNET_79C973) && defined(CONF_PCNET_79C975)
+#error "Macro for PCnet chip version is not defined!"
+#endif
+
+/*
+ * Set the number of Tx and Rx buffers, using Log_2(# buffers).
+ * Reasonable default values are 4 Tx buffers, and 16 Rx buffers.
+ * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
+ */
+#define PCNET_LOG_TX_BUFFERS	0
+#define PCNET_LOG_RX_BUFFERS	2
+
+#define TX_RING_SIZE		(1 << (PCNET_LOG_TX_BUFFERS))
+#define TX_RING_LEN_BITS	((PCNET_LOG_TX_BUFFERS) << 12)
+
+#define RX_RING_SIZE		(1 << (PCNET_LOG_RX_BUFFERS))
+#define RX_RING_LEN_BITS	((PCNET_LOG_RX_BUFFERS) << 4)
+
+#define PKT_BUF_SZ		1544
+
+/* The PCNET Rx and Tx ring descriptors. */
+struct pcnet_rx_head {
+	u32 base;
+	s16 buf_length;
+	s16 status;
+	u32 msg_length;
+	u32 reserved;
+};
+
+struct pcnet_tx_head {
+	u32 base;
+	s16 length;
+	s16 status;
+	u32 misc;
+	u32 reserved;
+};
+
+/* The PCNET 32-Bit initialization block, described in databook. */
+struct pcnet_init_block {
+	u16 mode;
+	u16 tlen_rlen;
+	u8 phys_addr[6];
+	u16 reserved;
+	u32 filter[2];
+	/* Receive and transmit ring base, along with extra bits. */
+	u32 rx_ring;
+	u32 tx_ring;
+	u32 reserved2;
+};
+
+typedef struct pcnet_priv {
+	struct pcnet_rx_head rx_ring[RX_RING_SIZE];
+	struct pcnet_tx_head tx_ring[TX_RING_SIZE];
+	struct pcnet_init_block init_block;
+	/* Receive Buffer space */
+	unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4];
+	int cur_rx;
+	int cur_tx;
+} pcnet_priv_t;
+
+static pcnet_priv_t *lp;
+
+/* Offsets from base I/O address for WIO mode */
+#define PCNET_RDP		0x10
+#define PCNET_RAP		0x12
+#define PCNET_RESET		0x14
+#define PCNET_BDP		0x16
+
+static u16 pcnet_read_csr(struct eth_device *dev, int index)
+{
+	outw(index, dev->iobase + PCNET_RAP);
+	return inw(dev->iobase + PCNET_RDP);
+}
+
+static void pcnet_write_csr(struct eth_device *dev, int index, u16 val)
+{
+	outw(index, dev->iobase + PCNET_RAP);
+	outw(val, dev->iobase + PCNET_RDP);
+}
+
+static u16 pcnet_read_bcr(struct eth_device *dev, int index)
+{
+	outw(index, dev->iobase + PCNET_RAP);
+	return inw(dev->iobase + PCNET_BDP);
+}
+
+static void pcnet_write_bcr(struct eth_device *dev, int index, u16 val)
+{
+	outw(index, dev->iobase + PCNET_RAP);
+	outw(val, dev->iobase + PCNET_BDP);
+}
+
+static void pcnet_reset(struct eth_device *dev)
+{
+	inw(dev->iobase + PCNET_RESET);
+}
+
+static int pcnet_check(struct eth_device *dev)
+{
+	outw(88, dev->iobase + PCNET_RAP);
+	return inw(dev->iobase + PCNET_RAP) == 88;
+}
+
+static int pcnet_init (struct eth_device *dev, bd_t * bis);
+static int pcnet_send(struct eth_device *dev, void *packet, int length);
+static int pcnet_recv (struct eth_device *dev);
+static void pcnet_halt (struct eth_device *dev);
+static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_num);
+
+#define PCI_TO_MEM(d, a) pci_virt_to_mem((pci_dev_t)d->priv, (a))
+#define PCI_TO_MEM_LE(d,a) (u32)(cpu_to_le32(PCI_TO_MEM(d,a)))
+
+static struct pci_device_id supported[] = {
+	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE},
+	{}
+};
+
+
+int pcnet_initialize(bd_t *bis)
+{
+	pci_dev_t devbusfn;
+	struct eth_device *dev;
+	u16 command, status;
+	int dev_nr = 0;
+
+	PCNET_DEBUG1("\npcnet_initialize...\n");
+
+	for (dev_nr = 0;; dev_nr++) {
+
+		/*
+		 * Find the PCnet PCI device(s).
+		 */
+		devbusfn = pci_find_devices(supported, dev_nr);
+		if (devbusfn < 0)
+			break;
+
+		/*
+		 * Allocate and pre-fill the device structure.
+		 */
+		dev = (struct eth_device *)malloc(sizeof(*dev));
+		if (!dev) {
+			printf("pcnet: Can not allocate memory\n");
+			break;
+		}
+		memset(dev, 0, sizeof(*dev));
+		dev->priv = (void *)devbusfn;
+		sprintf(dev->name, "pcnet#%d", dev_nr);
+
+		/*
+		 * Setup the PCI device.
+		 */
+		pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0,
+				      (unsigned int *)&dev->iobase);
+		dev->iobase = pci_io_to_phys(devbusfn, dev->iobase);
+		dev->iobase &= ~0xf;
+
+		PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%x: ",
+			     dev->name, devbusfn, dev->iobase);
+
+		command = PCI_COMMAND_IO | PCI_COMMAND_MASTER;
+		pci_write_config_word(devbusfn, PCI_COMMAND, command);
+		pci_read_config_word(devbusfn, PCI_COMMAND, &status);
+		if ((status & command) != command) {
+			printf("%s: Couldn't enable IO access or Bus Mastering\n",
+			       dev->name);
+			free(dev);
+			continue;
+		}
+
+		pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40);
+
+		/*
+		 * Probe the PCnet chip.
+		 */
+		if (pcnet_probe(dev, bis, dev_nr) < 0) {
+			free(dev);
+			continue;
+		}
+
+		/*
+		 * Setup device structure and register the driver.
+		 */
+		dev->init = pcnet_init;
+		dev->halt = pcnet_halt;
+		dev->send = pcnet_send;
+		dev->recv = pcnet_recv;
+
+		eth_register(dev);
+	}
+
+	udelay(10 * 1000);
+
+	return dev_nr;
+}
+
+static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr)
+{
+	int chip_version;
+	char *chipname;
+
+#ifdef PCNET_HAS_PROM
+	int i;
+#endif
+
+	/* Reset the PCnet controller */
+	pcnet_reset(dev);
+
+	/* Check if register access is working */
+	if (pcnet_read_csr(dev, 0) != 4 || !pcnet_check(dev)) {
+		printf("%s: CSR register access check failed\n", dev->name);
+		return -1;
+	}
+
+	/* Identify the chip */
+	chip_version =
+		pcnet_read_csr(dev, 88) | (pcnet_read_csr(dev, 89) << 16);
+	if ((chip_version & 0xfff) != 0x003)
+		return -1;
+	chip_version = (chip_version >> 12) & 0xffff;
+	switch (chip_version) {
+	case 0x2621:
+		chipname = "PCnet/PCI II 79C970A";	/* PCI */
+		break;
+#ifdef CONFIG_PCNET_79C973
+	case 0x2625:
+		chipname = "PCnet/FAST III 79C973";	/* PCI */
+		break;
+#endif
+#ifdef CONFIG_PCNET_79C975
+	case 0x2627:
+		chipname = "PCnet/FAST III 79C975";	/* PCI */
+		break;
+#endif
+	default:
+		printf("%s: PCnet version %#x not supported\n",
+		       dev->name, chip_version);
+		return -1;
+	}
+
+	PCNET_DEBUG1("AMD %s\n", chipname);
+
+#ifdef PCNET_HAS_PROM
+	/*
+	 * In most chips, after a chip reset, the ethernet address is read from
+	 * the station address PROM at the base address and programmed into the
+	 * "Physical Address Registers" CSR12-14.
+	 */
+	for (i = 0; i < 3; i++) {
+		unsigned int val;
+
+		val = pcnet_read_csr(dev, i + 12) & 0x0ffff;
+		/* There may be endianness issues here. */
+		dev->enetaddr[2 * i] = val & 0x0ff;
+		dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff;
+	}
+#endif /* PCNET_HAS_PROM */
+
+	return 0;
+}
+
+static int pcnet_init(struct eth_device *dev, bd_t *bis)
+{
+	int i, val;
+	u32 addr;
+
+	PCNET_DEBUG1("%s: pcnet_init...\n", dev->name);
+
+	/* Switch pcnet to 32bit mode */
+	pcnet_write_bcr(dev, 20, 2);
+
+	/* Set/reset autoselect bit */
+	val = pcnet_read_bcr(dev, 2) & ~2;
+	val |= 2;
+	pcnet_write_bcr(dev, 2, val);
+
+	/* Enable auto negotiate, setup, disable fd */
+	val = pcnet_read_bcr(dev, 32) & ~0x98;
+	val |= 0x20;
+	pcnet_write_bcr(dev, 32, val);
+
+	/*
+	 * Enable NOUFLO on supported controllers, with the transmit
+	 * start point set to the full packet. This will cause entire
+	 * packets to be buffered by the ethernet controller before
+	 * transmission, eliminating underflows which are common on
+	 * slower devices. Controllers which do not support NOUFLO will
+	 * simply be left with a larger transmit FIFO threshold.
+	 */
+	val = pcnet_read_bcr(dev, 18);
+	val |= 1 << 11;
+	pcnet_write_bcr(dev, 18, val);
+	val = pcnet_read_csr(dev, 80);
+	val |= 0x3 << 10;
+	pcnet_write_csr(dev, 80, val);
+
+	/*
+	 * We only maintain one structure because the drivers will never
+	 * be used concurrently. In 32bit mode the RX and TX ring entries
+	 * must be aligned on 16-byte boundaries.
+	 */
+	if (lp == NULL) {
+		addr = (u32)malloc(sizeof(pcnet_priv_t) + 0x10);
+		addr = (addr + 0xf) & ~0xf;
+		lp = (pcnet_priv_t *)addr;
+	}
+
+	lp->init_block.mode = cpu_to_le16(0x0000);
+	lp->init_block.filter[0] = 0x00000000;
+	lp->init_block.filter[1] = 0x00000000;
+
+	/*
+	 * Initialize the Rx ring.
+	 */
+	lp->cur_rx = 0;
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		lp->rx_ring[i].base = PCI_TO_MEM_LE(dev, lp->rx_buf[i]);
+		lp->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ);
+		lp->rx_ring[i].status = cpu_to_le16(0x8000);
+		PCNET_DEBUG1
+			("Rx%d: base=0x%x buf_length=0x%hx status=0x%hx\n", i,
+			 lp->rx_ring[i].base, lp->rx_ring[i].buf_length,
+			 lp->rx_ring[i].status);
+	}
+
+	/*
+	 * Initialize the Tx ring. The Tx buffer address is filled in as
+	 * needed, but we do need to clear the upper ownership bit.
+	 */
+	lp->cur_tx = 0;
+	for (i = 0; i < TX_RING_SIZE; i++) {
+		lp->tx_ring[i].base = 0;
+		lp->tx_ring[i].status = 0;
+	}
+
+	/*
+	 * Setup Init Block.
+	 */
+	PCNET_DEBUG1("Init block at 0x%p: MAC", &lp->init_block);
+
+	for (i = 0; i < 6; i++) {
+		lp->init_block.phys_addr[i] = dev->enetaddr[i];
+		PCNET_DEBUG1(" %02x", lp->init_block.phys_addr[i]);
+	}
+
+	lp->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS |
+					       RX_RING_LEN_BITS);
+	lp->init_block.rx_ring = PCI_TO_MEM_LE(dev, lp->rx_ring);
+	lp->init_block.tx_ring = PCI_TO_MEM_LE(dev, lp->tx_ring);
+	flush_dcache_range((unsigned long)lp, (unsigned long)&lp->rx_buf);
+
+	PCNET_DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n",
+		     lp->init_block.tlen_rlen,
+		     lp->init_block.rx_ring, lp->init_block.tx_ring);
+
+	/*
+	 * Tell the controller where the Init Block is located.
+	 */
+	addr = PCI_TO_MEM(dev, &lp->init_block);
+	pcnet_write_csr(dev, 1, addr & 0xffff);
+	pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff);
+
+	pcnet_write_csr(dev, 4, 0x0915);
+	pcnet_write_csr(dev, 0, 0x0001);	/* start */
+
+	/* Wait for Init Done bit */
+	for (i = 10000; i > 0; i--) {
+		if (pcnet_read_csr(dev, 0) & 0x0100)
+			break;
+		udelay(10);
+	}
+	if (i <= 0) {
+		printf("%s: TIMEOUT: controller init failed\n", dev->name);
+		pcnet_reset(dev);
+		return -1;
+	}
+
+	/*
+	 * Finally start network controller operation.
+	 */
+	pcnet_write_csr(dev, 0, 0x0002);
+
+	return 0;
+}
+
+static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len)
+{
+	int i, status;
+	struct pcnet_tx_head *entry = &lp->tx_ring[lp->cur_tx];
+
+	PCNET_DEBUG2("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len,
+		     packet);
+
+	flush_dcache_range((unsigned long)packet,
+			   (unsigned long)packet + pkt_len);
+
+	/* Wait for completion by testing the OWN bit */
+	for (i = 1000; i > 0; i--) {
+		invalidate_dcache_range((unsigned long)entry,
+					(unsigned long)entry + sizeof(*entry));
+		status = le16_to_cpu(entry->status);
+		if ((status & 0x8000) == 0)
+			break;
+		udelay(100);
+		PCNET_DEBUG2(".");
+	}
+	if (i <= 0) {
+		printf("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n",
+		       dev->name, lp->cur_tx, status);
+		pkt_len = 0;
+		goto failure;
+	}
+
+	/*
+	 * Setup Tx ring. Caution: the write order is important here,
+	 * set the status with the "ownership" bits last.
+	 */
+	status = 0x8300;
+	entry->length = cpu_to_le16(-pkt_len);
+	entry->misc = 0x00000000;
+	entry->base = PCI_TO_MEM_LE(dev, packet);
+	entry->status = cpu_to_le16(status);
+	flush_dcache_range((unsigned long)entry,
+			   (unsigned long)entry + sizeof(*entry));
+
+	/* Trigger an immediate send poll. */
+	pcnet_write_csr(dev, 0, 0x0008);
+
+      failure:
+	if (++lp->cur_tx >= TX_RING_SIZE)
+		lp->cur_tx = 0;
+
+	PCNET_DEBUG2("done\n");
+	return pkt_len;
+}
+
+static int pcnet_recv (struct eth_device *dev)
+{
+	struct pcnet_rx_head *entry;
+	int pkt_len = 0;
+	u16 status;
+
+	while (1) {
+		entry = &lp->rx_ring[lp->cur_rx];
+		invalidate_dcache_range((unsigned long)entry,
+					(unsigned long)entry + sizeof(*entry));
+		/*
+		 * If we own the next entry, it's a new packet. Send it up.
+		 */
+		status = le16_to_cpu(entry->status);
+		if ((status & 0x8000) != 0)
+			break;
+		status >>= 8;
+
+		if (status != 0x03) {	/* There was an error. */
+			printf("%s: Rx%d", dev->name, lp->cur_rx);
+			PCNET_DEBUG1(" (status=0x%x)", status);
+			if (status & 0x20)
+				printf(" Frame");
+			if (status & 0x10)
+				printf(" Overflow");
+			if (status & 0x08)
+				printf(" CRC");
+			if (status & 0x04)
+				printf(" Fifo");
+			printf(" Error\n");
+			entry->status &= le16_to_cpu(0x03ff);
+
+		} else {
+			pkt_len = (le32_to_cpu(entry->msg_length) & 0xfff) - 4;
+			if (pkt_len < 60) {
+				printf("%s: Rx%d: invalid packet length %d\n",
+				       dev->name, lp->cur_rx, pkt_len);
+			} else {
+				invalidate_dcache_range(
+					(unsigned long)lp->rx_buf[lp->cur_rx],
+					(unsigned long)lp->rx_buf[lp->cur_rx] +
+					pkt_len);
+				NetReceive(lp->rx_buf[lp->cur_rx], pkt_len);
+				PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n",
+					     lp->cur_rx, pkt_len,
+					     lp->rx_buf[lp->cur_rx]);
+			}
+		}
+		entry->status |= cpu_to_le16(0x8000);
+		flush_dcache_range((unsigned long)entry,
+				   (unsigned long)entry + sizeof(*entry));
+
+		if (++lp->cur_rx >= RX_RING_SIZE)
+			lp->cur_rx = 0;
+	}
+	return pkt_len;
+}
+
+static void pcnet_halt(struct eth_device *dev)
+{
+	int i;
+
+	PCNET_DEBUG1("%s: pcnet_halt...\n", dev->name);
+
+	/* Reset the PCnet controller */
+	pcnet_reset(dev);
+
+	/* Wait for Stop bit */
+	for (i = 1000; i > 0; i--) {
+		if (pcnet_read_csr(dev, 0) & 0x4)
+			break;
+		udelay(10);
+	}
+	if (i <= 0)
+		printf("%s: TIMEOUT: controller reset failed\n", dev->name);
+}
diff --git a/marvell/uboot/drivers/net/phy/Makefile b/marvell/uboot/drivers/net/phy/Makefile
new file mode 100644
index 0000000..dbf7bf7
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/Makefile
@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2008
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_BITBANGMII) += miiphybb.o
+obj-$(CONFIG_MV88E61XX_SWITCH) += mv88e61xx.o
+obj-$(CONFIG_MV88E6352_SWITCH) += mv88e6352.o
+
+obj-$(CONFIG_PHYLIB) += phy.o
+obj-$(CONFIG_PHYLIB_10G) += generic_10g.o
+obj-$(CONFIG_PHY_ATHEROS) += atheros.o
+obj-$(CONFIG_PHY_BROADCOM) += broadcom.o
+obj-$(CONFIG_PHY_DAVICOM) += davicom.o
+obj-$(CONFIG_PHY_ET1011C) += et1011c.o
+obj-$(CONFIG_PHY_ICPLUS) += icplus.o
+obj-$(CONFIG_PHY_LXT) += lxt.o
+obj-$(CONFIG_PHY_MARVELL) += marvell.o
+obj-$(CONFIG_PHY_MICREL) += micrel.o
+obj-$(CONFIG_PHY_NATSEMI) += natsemi.o
+obj-$(CONFIG_PHY_REALTEK) += realtek.o
+obj-$(CONFIG_PHY_SMSC) += smsc.o
+obj-$(CONFIG_PHY_TERANETICS) += teranetics.o
+obj-$(CONFIG_PHY_VITESSE) += vitesse.o
diff --git a/marvell/uboot/drivers/net/phy/atheros.c b/marvell/uboot/drivers/net/phy/atheros.c
new file mode 100644
index 0000000..32c2ab9
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/atheros.c
@@ -0,0 +1,77 @@
+/*
+ * Atheros PHY drivers
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Copyright 2011, 2013 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ */
+#include <phy.h>
+
+static int ar8021_config(struct phy_device *phydev)
+{
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x3D47);
+
+	return 0;
+}
+
+static int ar8035_config(struct phy_device *phydev)
+{
+	int regval;
+
+	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x0007);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
+	regval = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, (regval|0x0018));
+
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
+	regval = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, (regval|0x0100));
+
+	genphy_config_aneg(phydev);
+
+	phy_reset(phydev);
+
+	return 0;
+}
+
+static struct phy_driver AR8021_driver =  {
+	.name = "AR8021",
+	.uid = 0x4dd040,
+	.mask = 0x4fffff,
+	.features = PHY_GBIT_FEATURES,
+	.config = ar8021_config,
+	.startup = genphy_startup,
+	.shutdown = genphy_shutdown,
+};
+
+static struct phy_driver AR8031_driver =  {
+	.name = "AR8031/AR8033",
+	.uid = 0x4dd074,
+	.mask = 0xffffffef,
+	.features = PHY_GBIT_FEATURES,
+	.config = ar8021_config,
+	.startup = genphy_startup,
+	.shutdown = genphy_shutdown,
+};
+
+static struct phy_driver AR8035_driver =  {
+	.name = "AR8035",
+	.uid = 0x4dd072,
+	.mask = 0xffffffef,
+	.features = PHY_GBIT_FEATURES,
+	.config = ar8035_config,
+	.startup = genphy_startup,
+	.shutdown = genphy_shutdown,
+};
+
+int phy_atheros_init(void)
+{
+	phy_register(&AR8021_driver);
+	phy_register(&AR8031_driver);
+	phy_register(&AR8035_driver);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/phy/broadcom.c b/marvell/uboot/drivers/net/phy/broadcom.c
new file mode 100644
index 0000000..4512763
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/broadcom.c
@@ -0,0 +1,274 @@
+/*
+ * Broadcom PHY drivers
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Copyright 2010-2011 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ */
+#include <config.h>
+#include <common.h>
+#include <phy.h>
+
+/* Broadcom BCM54xx -- taken from linux sungem_phy */
+#define MIIM_BCM54xx_AUXCNTL			0x18
+#define MIIM_BCM54xx_AUXCNTL_ENCODE(val) (((val & 0x7) << 12)|(val & 0x7))
+#define MIIM_BCM54xx_AUXSTATUS			0x19
+#define MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK	0x0700
+#define MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT	8
+
+#define MIIM_BCM54XX_SHD			0x1c
+#define MIIM_BCM54XX_SHD_WRITE			0x8000
+#define MIIM_BCM54XX_SHD_VAL(x)			((x & 0x1f) << 10)
+#define MIIM_BCM54XX_SHD_DATA(x)		((x & 0x3ff) << 0)
+#define MIIM_BCM54XX_SHD_WR_ENCODE(val, data)	\
+	(MIIM_BCM54XX_SHD_WRITE | MIIM_BCM54XX_SHD_VAL(val) | \
+	 MIIM_BCM54XX_SHD_DATA(data))
+
+#define MIIM_BCM54XX_EXP_DATA		0x15	/* Expansion register data */
+#define MIIM_BCM54XX_EXP_SEL		0x17	/* Expansion register select */
+#define MIIM_BCM54XX_EXP_SEL_SSD	0x0e00	/* Secondary SerDes select */
+#define MIIM_BCM54XX_EXP_SEL_ER		0x0f00	/* Expansion register select */
+
+/* Broadcom BCM5461S */
+static int bcm5461_config(struct phy_device *phydev)
+{
+	genphy_config_aneg(phydev);
+
+	phy_reset(phydev);
+
+	return 0;
+}
+
+static int bcm54xx_parse_status(struct phy_device *phydev)
+{
+	unsigned int mii_reg;
+
+	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXSTATUS);
+
+	switch ((mii_reg & MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK) >>
+			MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT) {
+	case 1:
+		phydev->duplex = DUPLEX_HALF;
+		phydev->speed = SPEED_10;
+		break;
+	case 2:
+		phydev->duplex = DUPLEX_FULL;
+		phydev->speed = SPEED_10;
+		break;
+	case 3:
+		phydev->duplex = DUPLEX_HALF;
+		phydev->speed = SPEED_100;
+		break;
+	case 5:
+		phydev->duplex = DUPLEX_FULL;
+		phydev->speed = SPEED_100;
+		break;
+	case 6:
+		phydev->duplex = DUPLEX_HALF;
+		phydev->speed = SPEED_1000;
+		break;
+	case 7:
+		phydev->duplex = DUPLEX_FULL;
+		phydev->speed = SPEED_1000;
+		break;
+	default:
+		printf("Auto-neg error, defaulting to 10BT/HD\n");
+		phydev->duplex = DUPLEX_HALF;
+		phydev->speed = SPEED_10;
+		break;
+	}
+
+	return 0;
+}
+
+static int bcm54xx_startup(struct phy_device *phydev)
+{
+	/* Read the Status (2x to make sure link is right) */
+	genphy_update_link(phydev);
+	bcm54xx_parse_status(phydev);
+
+	return 0;
+}
+
+/* Broadcom BCM5482S */
+/*
+ * "Ethernet@Wirespeed" needs to be enabled to achieve link in certain
+ * circumstances.  eg a gigabit TSEC connected to a gigabit switch with
+ * a 4-wire ethernet cable.  Both ends advertise gigabit, but can't
+ * link.  "Ethernet@Wirespeed" reduces advertised speed until link
+ * can be achieved.
+ */
+static u32 bcm5482_read_wirespeed(struct phy_device *phydev, u32 reg)
+{
+	return (phy_read(phydev, MDIO_DEVAD_NONE, reg) & 0x8FFF) | 0x8010;
+}
+
+static int bcm5482_config(struct phy_device *phydev)
+{
+	unsigned int reg;
+
+	/* reset the PHY */
+	reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+	reg |= BMCR_RESET;
+	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, reg);
+
+	/* Setup read from auxilary control shadow register 7 */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL,
+			MIIM_BCM54xx_AUXCNTL_ENCODE(7));
+	/* Read Misc Control register and or in Ethernet@Wirespeed */
+	reg = bcm5482_read_wirespeed(phydev, MIIM_BCM54xx_AUXCNTL);
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL, reg);
+
+	/* Initial config/enable of secondary SerDes interface */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_SHD,
+			MIIM_BCM54XX_SHD_WR_ENCODE(0x14, 0xf));
+	/* Write intial value to secondary SerDes Contol */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_SEL,
+			MIIM_BCM54XX_EXP_SEL_SSD | 0);
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_DATA,
+			BMCR_ANRESTART);
+	/* Enable copper/fiber auto-detect */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_SHD,
+			MIIM_BCM54XX_SHD_WR_ENCODE(0x1e, 0x201));
+
+	genphy_config_aneg(phydev);
+
+	return 0;
+}
+
+/*
+ * Find out if PHY is in copper or serdes mode by looking at Expansion Reg
+ * 0x42 - "Operating Mode Status Register"
+ */
+static int bcm5482_is_serdes(struct phy_device *phydev)
+{
+	u16 val;
+	int serdes = 0;
+
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_SEL,
+			MIIM_BCM54XX_EXP_SEL_ER | 0x42);
+	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_DATA);
+
+	switch (val & 0x1f) {
+	case 0x0d:	/* RGMII-to-100Base-FX */
+	case 0x0e:	/* RGMII-to-SGMII */
+	case 0x0f:	/* RGMII-to-SerDes */
+	case 0x12:	/* SGMII-to-SerDes */
+	case 0x13:	/* SGMII-to-100Base-FX */
+	case 0x16:	/* SerDes-to-Serdes */
+		serdes = 1;
+		break;
+	case 0x6:	/* RGMII-to-Copper */
+	case 0x14:	/* SGMII-to-Copper */
+	case 0x17:	/* SerDes-to-Copper */
+		break;
+	default:
+		printf("ERROR, invalid PHY mode (0x%x\n)", val);
+		break;
+	}
+
+	return serdes;
+}
+
+/*
+ * Determine SerDes link speed and duplex from Expansion reg 0x42 "Operating
+ * Mode Status Register"
+ */
+static u32 bcm5482_parse_serdes_sr(struct phy_device *phydev)
+{
+	u16 val;
+	int i = 0;
+
+	/* Wait 1s for link - Clause 37 autonegotiation happens very fast */
+	while (1) {
+		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_SEL,
+				MIIM_BCM54XX_EXP_SEL_ER | 0x42);
+		val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_DATA);
+
+		if (val & 0x8000)
+			break;
+
+		if (i++ > 1000) {
+			phydev->link = 0;
+			return 1;
+		}
+
+		udelay(1000);	/* 1 ms */
+	}
+
+	phydev->link = 1;
+	switch ((val >> 13) & 0x3) {
+	case (0x00):
+		phydev->speed = 10;
+		break;
+	case (0x01):
+		phydev->speed = 100;
+		break;
+	case (0x02):
+		phydev->speed = 1000;
+		break;
+	}
+
+	phydev->duplex = (val & 0x1000) == 0x1000;
+
+	return 0;
+}
+
+/*
+ * Figure out if BCM5482 is in serdes or copper mode and determine link
+ * configuration accordingly
+ */
+static int bcm5482_startup(struct phy_device *phydev)
+{
+	if (bcm5482_is_serdes(phydev)) {
+		bcm5482_parse_serdes_sr(phydev);
+		phydev->port = PORT_FIBRE;
+	} else {
+		/* Wait for auto-negotiation to complete or fail */
+		genphy_update_link(phydev);
+		/* Parse BCM54xx copper aux status register */
+		bcm54xx_parse_status(phydev);
+	}
+
+	return 0;
+}
+
+static struct phy_driver BCM5461S_driver = {
+	.name = "Broadcom BCM5461S",
+	.uid = 0x2060c0,
+	.mask = 0xfffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &bcm5461_config,
+	.startup = &bcm54xx_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver BCM5464S_driver = {
+	.name = "Broadcom BCM5464S",
+	.uid = 0x2060b0,
+	.mask = 0xfffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &bcm5461_config,
+	.startup = &bcm54xx_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver BCM5482S_driver = {
+	.name = "Broadcom BCM5482S",
+	.uid = 0x143bcb0,
+	.mask = 0xffffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &bcm5482_config,
+	.startup = &bcm5482_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+int phy_broadcom_init(void)
+{
+	phy_register(&BCM5482S_driver);
+	phy_register(&BCM5464S_driver);
+	phy_register(&BCM5461S_driver);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/phy/davicom.c b/marvell/uboot/drivers/net/phy/davicom.c
new file mode 100644
index 0000000..0c039fe
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/davicom.c
@@ -0,0 +1,84 @@
+/*
+ * Davicom PHY drivers
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Copyright 2010-2011 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ */
+#include <phy.h>
+
+#define MIIM_DM9161_SCR                0x10
+#define MIIM_DM9161_SCR_INIT   0x0610
+
+/* DM9161 Specified Configuration and Status Register */
+#define MIIM_DM9161_SCSR       0x11
+#define MIIM_DM9161_SCSR_100F  0x8000
+#define MIIM_DM9161_SCSR_100H  0x4000
+#define MIIM_DM9161_SCSR_10F   0x2000
+#define MIIM_DM9161_SCSR_10H   0x1000
+
+/* DM9161 10BT Configuration/Status */
+#define MIIM_DM9161_10BTCSR    0x12
+#define MIIM_DM9161_10BTCSR_INIT       0x7800
+
+
+/* Davicom DM9161E */
+static int dm9161_config(struct phy_device *phydev)
+{
+	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_ISOLATE);
+	/* Do not bypass the scrambler/descrambler */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_SCR,
+			MIIM_DM9161_SCR_INIT);
+	/* Clear 10BTCSR to default */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_10BTCSR,
+			MIIM_DM9161_10BTCSR_INIT);
+
+	genphy_config_aneg(phydev);
+
+	return 0;
+}
+
+static int dm9161_parse_status(struct phy_device *phydev)
+{
+	int mii_reg;
+
+	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_SCSR);
+
+	if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H))
+		phydev->speed = SPEED_100;
+	else
+		phydev->speed = SPEED_10;
+
+	if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_10F))
+		phydev->duplex = DUPLEX_FULL;
+	else
+		phydev->duplex = DUPLEX_HALF;
+
+	return 0;
+}
+
+static int dm9161_startup(struct phy_device *phydev)
+{
+	genphy_update_link(phydev);
+	dm9161_parse_status(phydev);
+
+	return 0;
+}
+
+static struct phy_driver DM9161_driver = {
+	.name = "Davicom DM9161E",
+	.uid = 0x181b880,
+	.mask = 0xffffff0,
+	.features = PHY_BASIC_FEATURES,
+	.config = &dm9161_config,
+	.startup = &dm9161_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+int phy_davicom_init(void)
+{
+	phy_register(&DM9161_driver);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/phy/et1011c.c b/marvell/uboot/drivers/net/phy/et1011c.c
new file mode 100644
index 0000000..70c15e2
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/et1011c.c
@@ -0,0 +1,101 @@
+/*
+ * ET1011C PHY driver
+ *
+ * Derived from Linux kernel driver by Chaithrika U S
+ * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <config.h>
+#include <phy.h>
+
+#define ET1011C_CONFIG_REG		(0x16)
+#define ET1011C_TX_FIFO_MASK		(0x3 << 12)
+#define ET1011C_TX_FIFO_DEPTH_8		(0x0 << 12)
+#define ET1011C_TX_FIFO_DEPTH_16	(0x1 << 12)
+#define ET1011C_INTERFACE_MASK		(0x7 << 0)
+#define ET1011C_GMII_INTERFACE		(0x2 << 0)
+#define ET1011C_SYS_CLK_EN		(0x1 << 4)
+#define ET1011C_TX_CLK_EN		(0x1 << 5)
+
+#define ET1011C_STATUS_REG		(0x1A)
+#define ET1011C_DUPLEX_STATUS		(0x1 << 7)
+#define ET1011C_SPEED_MASK		(0x3 << 8)
+#define ET1011C_SPEED_1000		(0x2 << 8)
+#define ET1011C_SPEED_100		(0x1 << 8)
+#define ET1011C_SPEED_10		(0x0 << 8)
+
+static int et1011c_config(struct phy_device *phydev)
+{
+	int ctl = 0;
+	ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+	if (ctl < 0)
+		return ctl;
+	ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 |
+		 BMCR_ANENABLE);
+	/* First clear the PHY */
+	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl | BMCR_RESET);
+
+	return genphy_config_aneg(phydev);
+}
+
+static int et1011c_parse_status(struct phy_device *phydev)
+{
+	int mii_reg;
+	int speed;
+
+	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, ET1011C_STATUS_REG);
+
+	if (mii_reg & ET1011C_DUPLEX_STATUS)
+		phydev->duplex = DUPLEX_FULL;
+	else
+		phydev->duplex = DUPLEX_HALF;
+
+	speed = mii_reg & ET1011C_SPEED_MASK;
+	switch (speed) {
+	case ET1011C_SPEED_1000:
+		phydev->speed = SPEED_1000;
+		mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, ET1011C_CONFIG_REG);
+		mii_reg &= ~ET1011C_TX_FIFO_MASK;
+		phy_write(phydev, MDIO_DEVAD_NONE, ET1011C_CONFIG_REG,
+			  mii_reg |
+			  ET1011C_GMII_INTERFACE |
+			  ET1011C_SYS_CLK_EN |
+#ifdef CONFIG_PHY_ET1011C_TX_CLK_FIX
+			  ET1011C_TX_CLK_EN |
+#endif
+			  ET1011C_TX_FIFO_DEPTH_16);
+		break;
+	case ET1011C_SPEED_100:
+		phydev->speed = SPEED_100;
+		break;
+	case ET1011C_SPEED_10:
+		phydev->speed = SPEED_10;
+		break;
+	}
+
+	return 0;
+}
+
+static int et1011c_startup(struct phy_device *phydev)
+{
+	genphy_update_link(phydev);
+	et1011c_parse_status(phydev);
+	return 0;
+}
+
+static struct phy_driver et1011c_driver = {
+	.name		= "ET1011C",
+	.uid		= 0x0282f014,
+	.mask		= 0xfffffff0,
+	.features	= PHY_GBIT_FEATURES,
+	.config		= &et1011c_config,
+	.startup	= &et1011c_startup,
+};
+
+int phy_et1011c_init(void)
+{
+	phy_register(&et1011c_driver);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/phy/generic_10g.c b/marvell/uboot/drivers/net/phy/generic_10g.c
new file mode 100644
index 0000000..ed3dcd9
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/generic_10g.c
@@ -0,0 +1,94 @@
+/*
+ * Generic PHY Management code
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ *
+ * Based loosely off of Linux's PHY Lib
+ */
+
+#include <config.h>
+#include <common.h>
+#include <miiphy.h>
+#include <phy.h>
+
+int gen10g_shutdown(struct phy_device *phydev)
+{
+	return 0;
+}
+
+int gen10g_startup(struct phy_device *phydev)
+{
+	int devad, reg;
+	u32 mmd_mask = phydev->mmds & MDIO_DEVS_LINK;
+
+	phydev->link = 1;
+
+	/* For now just lie and say it's 10G all the time */
+	phydev->speed = SPEED_10000;
+	phydev->duplex = DUPLEX_FULL;
+
+	/*
+	 * Go through all the link-reporting devices, and make sure
+	 * they're all up and happy
+	 */
+	for (devad = 0; mmd_mask; devad++, mmd_mask = mmd_mask >> 1) {
+		if (!(mmd_mask & 1))
+			continue;
+
+		/* Read twice because link state is latched and a
+		 * read moves the current state into the register */
+		phy_read(phydev, devad, MDIO_STAT1);
+		reg = phy_read(phydev, devad, MDIO_STAT1);
+		if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS))
+			phydev->link = 0;
+	}
+
+	return 0;
+}
+
+int gen10g_discover_mmds(struct phy_device *phydev)
+{
+	int mmd, stat2, devs1, devs2;
+
+	/* Assume PHY must have at least one of PMA/PMD, WIS, PCS, PHY
+	 * XS or DTE XS; give up if none is present. */
+	for (mmd = 1; mmd <= 5; mmd++) {
+		/* Is this MMD present? */
+		stat2 = phy_read(phydev, mmd, MDIO_STAT2);
+		if (stat2 < 0 ||
+			(stat2 & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL)
+			continue;
+
+		/* It should tell us about all the other MMDs */
+		devs1 = phy_read(phydev, mmd, MDIO_DEVS1);
+		devs2 = phy_read(phydev, mmd, MDIO_DEVS2);
+		if (devs1 < 0 || devs2 < 0)
+			continue;
+
+		phydev->mmds = devs1 | (devs2 << 16);
+		return 0;
+	}
+
+	return 0;
+}
+
+int gen10g_config(struct phy_device *phydev)
+{
+	/* For now, assume 10000baseT. Fill in later */
+	phydev->supported = phydev->advertising = SUPPORTED_10000baseT_Full;
+
+	return gen10g_discover_mmds(phydev);
+}
+
+struct phy_driver gen10g_driver = {
+	.uid		= 0xffffffff,
+	.mask		= 0xffffffff,
+	.name		= "Generic 10G PHY",
+	.features	= 0,
+	.config		= gen10g_config,
+	.startup	= gen10g_startup,
+	.shutdown	= gen10g_shutdown,
+};
diff --git a/marvell/uboot/drivers/net/phy/icplus.c b/marvell/uboot/drivers/net/phy/icplus.c
new file mode 100644
index 0000000..5971955
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/icplus.c
@@ -0,0 +1,80 @@
+/*
+ * ICPlus PHY drivers
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ */
+#include <phy.h>
+
+/* IP101A/G - IP1001 */
+#define IP10XX_SPEC_CTRL_STATUS         16      /* Spec. Control Register */
+#define IP1001_SPEC_CTRL_STATUS_2       20      /* IP1001 Spec. Control Reg 2 */
+#define IP1001_PHASE_SEL_MASK           3       /* IP1001 RX/TXPHASE_SEL */
+#define IP1001_APS_ON                   11      /* IP1001 APS Mode  bit */
+#define IP101A_G_APS_ON                 2       /* IP101A/G APS Mode bit */
+#define IP101A_G_IRQ_CONF_STATUS        0x11    /* Conf Info IRQ & Status Reg */
+#define IP101A_G_IRQ_PIN_USED           (1<<15) /* INTR pin used */
+#define IP101A_G_IRQ_DEFAULT            IP101A_G_IRQ_PIN_USED
+
+static int ip1001_config(struct phy_device *phydev)
+{
+	int c;
+
+	/* Enable Auto Power Saving mode */
+	c = phy_read(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2);
+	if (c < 0)
+		return c;
+	c |= IP1001_APS_ON;
+	c = phy_write(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2, c);
+	if (c < 0)
+		return c;
+
+	/* INTR pin used: speed/link/duplex will cause an interrupt */
+	c = phy_write(phydev, MDIO_DEVAD_NONE, IP101A_G_IRQ_CONF_STATUS,
+		      IP101A_G_IRQ_DEFAULT);
+	if (c < 0)
+		return c;
+
+	if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
+		/*
+		 * Additional delay (2ns) used to adjust RX clock phase
+		 * at RGMII interface
+		 */
+		c = phy_read(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS);
+		if (c < 0)
+			return c;
+
+		c |= IP1001_PHASE_SEL_MASK;
+		c = phy_write(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS,
+			      c);
+		if (c < 0)
+			return c;
+	}
+
+	return 0;
+}
+
+static int ip1001_startup(struct phy_device *phydev)
+{
+	genphy_update_link(phydev);
+	genphy_parse_link(phydev);
+
+	return 0;
+}
+static struct phy_driver IP1001_driver = {
+	.name = "ICPlus IP1001",
+	.uid = 0x02430d90,
+	.mask = 0x0ffffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &ip1001_config,
+	.startup = &ip1001_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+int phy_icplus_init(void)
+{
+	phy_register(&IP1001_driver);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/phy/lxt.c b/marvell/uboot/drivers/net/phy/lxt.c
new file mode 100644
index 0000000..91838ce
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/lxt.c
@@ -0,0 +1,73 @@
+/*
+ * LXT PHY drivers
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Copyright 2010-2011 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ */
+#include <phy.h>
+
+/* LXT971 Status 2 registers */
+#define MIIM_LXT971_SR2                     0x11  /* Status Register 2  */
+#define MIIM_LXT971_SR2_SPEED_MASK 0x4200
+#define MIIM_LXT971_SR2_10HDX     0x0000  /*  10 Mbit half duplex selected */
+#define MIIM_LXT971_SR2_10FDX     0x0200  /*  10 Mbit full duplex selected */
+#define MIIM_LXT971_SR2_100HDX    0x4000  /* 100 Mbit half duplex selected */
+#define MIIM_LXT971_SR2_100FDX    0x4200  /* 100 Mbit full duplex selected */
+
+
+/* LXT971 */
+static int lxt971_parse_status(struct phy_device *phydev)
+{
+	int mii_reg;
+	int speed;
+
+	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_LXT971_SR2);
+	speed = mii_reg & MIIM_LXT971_SR2_SPEED_MASK;
+
+	switch (speed) {
+	case MIIM_LXT971_SR2_10HDX:
+		phydev->speed = SPEED_10;
+		phydev->duplex = DUPLEX_HALF;
+		break;
+	case MIIM_LXT971_SR2_10FDX:
+		phydev->speed = SPEED_10;
+		phydev->duplex = DUPLEX_FULL;
+		break;
+	case MIIM_LXT971_SR2_100HDX:
+		phydev->speed = SPEED_100;
+		phydev->duplex = DUPLEX_HALF;
+		break;
+	default:
+		phydev->speed = SPEED_100;
+		phydev->duplex = DUPLEX_FULL;
+	}
+
+	return 0;
+}
+
+static int lxt971_startup(struct phy_device *phydev)
+{
+	genphy_update_link(phydev);
+	lxt971_parse_status(phydev);
+
+	return 0;
+}
+
+static struct phy_driver LXT971_driver = {
+	.name = "LXT971",
+	.uid = 0x1378e0,
+	.mask = 0xfffff0,
+	.features = PHY_BASIC_FEATURES,
+	.config = &genphy_config_aneg,
+	.startup = &lxt971_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+int phy_lxt_init(void)
+{
+	phy_register(&LXT971_driver);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/phy/marvell.c b/marvell/uboot/drivers/net/phy/marvell.c
new file mode 100644
index 0000000..d2ecadc
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/marvell.c
@@ -0,0 +1,524 @@
+/*
+ * Marvell PHY drivers
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Copyright 2010-2011 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ */
+#include <config.h>
+#include <common.h>
+#include <phy.h>
+
+#define PHY_AUTONEGOTIATE_TIMEOUT 5000
+
+/* 88E1011 PHY Status Register */
+#define MIIM_88E1xxx_PHY_STATUS		0x11
+#define MIIM_88E1xxx_PHYSTAT_SPEED	0xc000
+#define MIIM_88E1xxx_PHYSTAT_GBIT	0x8000
+#define MIIM_88E1xxx_PHYSTAT_100	0x4000
+#define MIIM_88E1xxx_PHYSTAT_DUPLEX	0x2000
+#define MIIM_88E1xxx_PHYSTAT_SPDDONE	0x0800
+#define MIIM_88E1xxx_PHYSTAT_LINK	0x0400
+
+#define MIIM_88E1xxx_PHY_SCR		0x10
+#define MIIM_88E1xxx_PHY_MDI_X_AUTO	0x0060
+
+/* 88E1111 PHY LED Control Register */
+#define MIIM_88E1111_PHY_LED_CONTROL	24
+#define MIIM_88E1111_PHY_LED_DIRECT	0x4100
+#define MIIM_88E1111_PHY_LED_COMBINE	0x411C
+
+/* 88E1111 Extended PHY Specific Control Register */
+#define MIIM_88E1111_PHY_EXT_CR		0x14
+#define MIIM_88E1111_RX_DELAY		0x80
+#define MIIM_88E1111_TX_DELAY		0x2
+
+/* 88E1111 Extended PHY Specific Status Register */
+#define MIIM_88E1111_PHY_EXT_SR		0x1b
+#define MIIM_88E1111_HWCFG_MODE_MASK		0xf
+#define MIIM_88E1111_HWCFG_MODE_COPPER_RGMII	0xb
+#define MIIM_88E1111_HWCFG_MODE_FIBER_RGMII	0x3
+#define MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK	0x4
+#define MIIM_88E1111_HWCFG_MODE_COPPER_RTBI	0x9
+#define MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO	0x8000
+#define MIIM_88E1111_HWCFG_FIBER_COPPER_RES	0x2000
+
+#define MIIM_88E1111_COPPER		0
+#define MIIM_88E1111_FIBER		1
+
+/* 88E1118 PHY defines */
+#define MIIM_88E1118_PHY_PAGE		22
+#define MIIM_88E1118_PHY_LED_PAGE	3
+
+/* 88E1121 PHY LED Control Register */
+#define MIIM_88E1121_PHY_LED_CTRL	16
+#define MIIM_88E1121_PHY_LED_PAGE	3
+#define MIIM_88E1121_PHY_LED_DEF	0x0030
+
+/* 88E1121 PHY IRQ Enable/Status Register */
+#define MIIM_88E1121_PHY_IRQ_EN		18
+#define MIIM_88E1121_PHY_IRQ_STATUS	19
+
+#define MIIM_88E1121_PHY_PAGE		22
+
+/* 88E1145 Extended PHY Specific Control Register */
+#define MIIM_88E1145_PHY_EXT_CR 20
+#define MIIM_M88E1145_RGMII_RX_DELAY	0x0080
+#define MIIM_M88E1145_RGMII_TX_DELAY	0x0002
+
+#define MIIM_88E1145_PHY_LED_CONTROL	24
+#define MIIM_88E1145_PHY_LED_DIRECT	0x4100
+
+#define MIIM_88E1145_PHY_PAGE	29
+#define MIIM_88E1145_PHY_CAL_OV 30
+
+#define MIIM_88E1149_PHY_PAGE	29
+
+/* 88E1310 PHY defines */
+#define MIIM_88E1310_PHY_LED_CTRL	16
+#define MIIM_88E1310_PHY_IRQ_EN		18
+#define MIIM_88E1310_PHY_RGMII_CTRL	21
+#define MIIM_88E1310_PHY_PAGE		22
+
+/* Marvell 88E1011S */
+static int m88e1011s_config(struct phy_device *phydev)
+{
+	/* Reset and configure the PHY */
+	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
+
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x200c);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
+
+	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
+
+	genphy_config_aneg(phydev);
+
+	return 0;
+}
+
+/* Parse the 88E1011's status register for speed and duplex
+ * information
+ */
+static uint m88e1xxx_parse_status(struct phy_device *phydev)
+{
+	unsigned int speed;
+	unsigned int mii_reg;
+
+	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1xxx_PHY_STATUS);
+
+	if ((mii_reg & MIIM_88E1xxx_PHYSTAT_LINK) &&
+		!(mii_reg & MIIM_88E1xxx_PHYSTAT_SPDDONE)) {
+		int i = 0;
+
+		puts("Waiting for PHY realtime link");
+		while (!(mii_reg & MIIM_88E1xxx_PHYSTAT_SPDDONE)) {
+			/* Timeout reached ? */
+			if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
+				puts(" TIMEOUT !\n");
+				phydev->link = 0;
+				break;
+			}
+
+			if ((i++ % 1000) == 0)
+				putc('.');
+			udelay(1000);
+			mii_reg = phy_read(phydev, MDIO_DEVAD_NONE,
+					MIIM_88E1xxx_PHY_STATUS);
+		}
+		puts(" done\n");
+		udelay(500000);	/* another 500 ms (results in faster booting) */
+	} else {
+		if (mii_reg & MIIM_88E1xxx_PHYSTAT_LINK)
+			phydev->link = 1;
+		else
+			phydev->link = 0;
+	}
+
+	if (mii_reg & MIIM_88E1xxx_PHYSTAT_DUPLEX)
+		phydev->duplex = DUPLEX_FULL;
+	else
+		phydev->duplex = DUPLEX_HALF;
+
+	speed = mii_reg & MIIM_88E1xxx_PHYSTAT_SPEED;
+
+	switch (speed) {
+	case MIIM_88E1xxx_PHYSTAT_GBIT:
+		phydev->speed = SPEED_1000;
+		break;
+	case MIIM_88E1xxx_PHYSTAT_100:
+		phydev->speed = SPEED_100;
+		break;
+	default:
+		phydev->speed = SPEED_10;
+		break;
+	}
+
+	return 0;
+}
+
+static int m88e1011s_startup(struct phy_device *phydev)
+{
+	genphy_update_link(phydev);
+	m88e1xxx_parse_status(phydev);
+
+	return 0;
+}
+
+/* Marvell 88E1111S */
+static int m88e1111s_config(struct phy_device *phydev)
+{
+	int reg;
+	int timeout;
+
+	if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
+			(phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
+			(phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
+			(phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
+		reg = phy_read(phydev,
+			MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR);
+		if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
+			(phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)) {
+			reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY);
+		} else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
+			reg &= ~MIIM_88E1111_TX_DELAY;
+			reg |= MIIM_88E1111_RX_DELAY;
+		} else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
+			reg &= ~MIIM_88E1111_RX_DELAY;
+			reg |= MIIM_88E1111_TX_DELAY;
+		}
+
+		phy_write(phydev,
+			MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg);
+
+		reg = phy_read(phydev,
+			MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR);
+
+		reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK);
+
+		if (reg & MIIM_88E1111_HWCFG_FIBER_COPPER_RES)
+			reg |= MIIM_88E1111_HWCFG_MODE_FIBER_RGMII;
+		else
+			reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RGMII;
+
+		phy_write(phydev,
+			MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR, reg);
+	}
+
+	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
+		reg = phy_read(phydev,
+			MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR);
+
+		reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK);
+		reg |= MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK;
+		reg |= MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO;
+
+		phy_write(phydev, MDIO_DEVAD_NONE,
+			MIIM_88E1111_PHY_EXT_SR, reg);
+	}
+
+	if (phydev->interface == PHY_INTERFACE_MODE_RTBI) {
+		reg = phy_read(phydev,
+			MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR);
+		reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY);
+		phy_write(phydev,
+			MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg);
+
+		reg = phy_read(phydev, MDIO_DEVAD_NONE,
+			MIIM_88E1111_PHY_EXT_SR);
+		reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK |
+			MIIM_88E1111_HWCFG_FIBER_COPPER_RES);
+		reg |= 0x7 | MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO;
+		phy_write(phydev, MDIO_DEVAD_NONE,
+			MIIM_88E1111_PHY_EXT_SR, reg);
+
+		/* soft reset */
+		timeout = 1000;
+		phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
+		udelay(1000);
+		reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+		while ((reg & BMCR_RESET) && --timeout) {
+			udelay(1000);
+			reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+		}
+		if (!timeout)
+			printf("%s: phy soft reset timeout\n", __func__);
+
+		reg = phy_read(phydev, MDIO_DEVAD_NONE,
+			MIIM_88E1111_PHY_EXT_SR);
+		reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK |
+			MIIM_88E1111_HWCFG_FIBER_COPPER_RES);
+		reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RTBI |
+			MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO;
+		phy_write(phydev, MDIO_DEVAD_NONE,
+			MIIM_88E1111_PHY_EXT_SR, reg);
+	}
+
+	/* soft reset */
+	timeout = 1000;
+	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
+	udelay(1000);
+	reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+	while ((reg & BMCR_RESET) && --timeout) {
+		udelay(1000);
+		reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+	}
+	if (!timeout)
+		printf("%s: phy soft reset timeout\n", __func__);
+
+	genphy_config_aneg(phydev);
+
+	phy_reset(phydev);
+
+	return 0;
+}
+
+/* Marvell 88E1118 */
+static int m88e1118_config(struct phy_device *phydev)
+{
+	/* Change Page Number */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0002);
+	/* Delay RGMII TX and RX */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x1070);
+	/* Change Page Number */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0003);
+	/* Adjust LED control */
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x021e);
+	/* Change Page Number */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000);
+
+	genphy_config_aneg(phydev);
+
+	phy_reset(phydev);
+
+	return 0;
+}
+
+static int m88e1118_startup(struct phy_device *phydev)
+{
+	/* Change Page Number */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000);
+
+	genphy_update_link(phydev);
+	m88e1xxx_parse_status(phydev);
+
+	return 0;
+}
+
+/* Marvell 88E1121R */
+static int m88e1121_config(struct phy_device *phydev)
+{
+	int pg;
+
+	/* Configure the PHY */
+	genphy_config_aneg(phydev);
+
+	/* Switch the page to access the led register */
+	pg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE);
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE,
+			MIIM_88E1121_PHY_LED_PAGE);
+	/* Configure leds */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_LED_CTRL,
+			MIIM_88E1121_PHY_LED_DEF);
+	/* Restore the page pointer */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE, pg);
+
+	/* Disable IRQs and de-assert interrupt */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_IRQ_EN, 0);
+	phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_IRQ_STATUS);
+
+	return 0;
+}
+
+/* Marvell 88E1145 */
+static int m88e1145_config(struct phy_device *phydev)
+{
+	int reg;
+
+	/* Errata E0, E1 */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_PAGE, 0x001b);
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_CAL_OV, 0x418f);
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_PAGE, 0x0016);
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_CAL_OV, 0xa2da);
+
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1xxx_PHY_SCR,
+			MIIM_88E1xxx_PHY_MDI_X_AUTO);
+
+	reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_EXT_CR);
+	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+		reg |= MIIM_M88E1145_RGMII_RX_DELAY |
+			MIIM_M88E1145_RGMII_TX_DELAY;
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_EXT_CR, reg);
+
+	genphy_config_aneg(phydev);
+
+	phy_reset(phydev);
+
+	return 0;
+}
+
+static int m88e1145_startup(struct phy_device *phydev)
+{
+	genphy_update_link(phydev);
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_LED_CONTROL,
+			MIIM_88E1145_PHY_LED_DIRECT);
+	m88e1xxx_parse_status(phydev);
+
+	return 0;
+}
+
+/* Marvell 88E1149S */
+static int m88e1149_config(struct phy_device *phydev)
+{
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1149_PHY_PAGE, 0x1f);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x200c);
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1149_PHY_PAGE, 0x5);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x0);
+	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
+
+	genphy_config_aneg(phydev);
+
+	phy_reset(phydev);
+
+	return 0;
+}
+
+/* Marvell 88E1310 */
+static int m88e1310_config(struct phy_device *phydev)
+{
+	u16 reg;
+
+	/* LED link and activity */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0003);
+	reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_LED_CTRL);
+	reg = (reg & ~0xf) | 0x1;
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_LED_CTRL, reg);
+
+	/* Set LED2/INT to INT mode, low active */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0003);
+	reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_IRQ_EN);
+	reg = (reg & 0x77ff) | 0x0880;
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_IRQ_EN, reg);
+
+	/* Set RGMII delay */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0002);
+	reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_RGMII_CTRL);
+	reg |= 0x0030;
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_RGMII_CTRL, reg);
+
+	/* Ensure to return to page 0 */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0000);
+
+	genphy_config_aneg(phydev);
+	phy_reset(phydev);
+
+	return 0;
+}
+
+static struct phy_driver M88E1011S_driver = {
+	.name = "Marvell 88E1011S",
+	.uid = 0x1410c60,
+	.mask = 0xffffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &m88e1011s_config,
+	.startup = &m88e1011s_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver M88E1111S_driver = {
+	.name = "Marvell 88E1111S",
+	.uid = 0x1410cc0,
+	.mask = 0xffffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &m88e1111s_config,
+	.startup = &m88e1011s_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver M88E1118_driver = {
+	.name = "Marvell 88E1118",
+	.uid = 0x1410e10,
+	.mask = 0xffffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &m88e1118_config,
+	.startup = &m88e1118_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver M88E1118R_driver = {
+	.name = "Marvell 88E1118R",
+	.uid = 0x1410e40,
+	.mask = 0xffffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &m88e1118_config,
+	.startup = &m88e1118_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver M88E1121R_driver = {
+	.name = "Marvell 88E1121R",
+	.uid = 0x1410cb0,
+	.mask = 0xffffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &m88e1121_config,
+	.startup = &genphy_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver M88E1145_driver = {
+	.name = "Marvell 88E1145",
+	.uid = 0x1410cd0,
+	.mask = 0xffffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &m88e1145_config,
+	.startup = &m88e1145_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver M88E1149S_driver = {
+	.name = "Marvell 88E1149S",
+	.uid = 0x1410ca0,
+	.mask = 0xffffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &m88e1149_config,
+	.startup = &m88e1011s_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver M88E1518_driver = {
+	.name = "Marvell 88E1518",
+	.uid = 0x1410dd1,
+	.mask = 0xffffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &m88e1111s_config,
+	.startup = &m88e1011s_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver M88E1310_driver = {
+	.name = "Marvell 88E1310",
+	.uid = 0x01410e90,
+	.mask = 0xffffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &m88e1310_config,
+	.startup = &m88e1011s_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+int phy_marvell_init(void)
+{
+	phy_register(&M88E1310_driver);
+	phy_register(&M88E1149S_driver);
+	phy_register(&M88E1145_driver);
+	phy_register(&M88E1121R_driver);
+	phy_register(&M88E1118_driver);
+	phy_register(&M88E1118R_driver);
+	phy_register(&M88E1111S_driver);
+	phy_register(&M88E1011S_driver);
+	phy_register(&M88E1518_driver);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/phy/micrel.c b/marvell/uboot/drivers/net/phy/micrel.c
new file mode 100644
index 0000000..5d7e3be
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/micrel.c
@@ -0,0 +1,226 @@
+/*
+ * Micrel PHY drivers
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Copyright 2010-2011 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ * (C) 2012 NetModule AG, David Andrey, added KSZ9031
+ */
+#include <config.h>
+#include <common.h>
+#include <micrel.h>
+#include <phy.h>
+
+static struct phy_driver KSZ804_driver = {
+	.name = "Micrel KSZ804",
+	.uid = 0x221510,
+	.mask = 0xfffff0,
+	.features = PHY_BASIC_FEATURES,
+	.config = &genphy_config,
+	.startup = &genphy_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+#ifndef CONFIG_PHY_MICREL_KSZ9021
+/*
+ * I can't believe Micrel used the exact same part number
+ * for the KSZ9021
+ * Shame Micrel, Shame!!!!!
+ */
+static struct phy_driver KS8721_driver = {
+	.name = "Micrel KS8721BL",
+	.uid = 0x221610,
+	.mask = 0xfffff0,
+	.features = PHY_BASIC_FEATURES,
+	.config = &genphy_config,
+	.startup = &genphy_startup,
+	.shutdown = &genphy_shutdown,
+};
+#endif
+
+
+/**
+ * KSZ9021 - KSZ9031 common
+ */
+
+#define MII_KSZ90xx_PHY_CTL		0x1f
+#define MIIM_KSZ90xx_PHYCTL_1000	(1 << 6)
+#define MIIM_KSZ90xx_PHYCTL_100		(1 << 5)
+#define MIIM_KSZ90xx_PHYCTL_10		(1 << 4)
+#define MIIM_KSZ90xx_PHYCTL_DUPLEX	(1 << 3)
+
+static int ksz90xx_startup(struct phy_device *phydev)
+{
+	unsigned phy_ctl;
+	genphy_update_link(phydev);
+	phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ90xx_PHY_CTL);
+
+	if (phy_ctl & MIIM_KSZ90xx_PHYCTL_DUPLEX)
+		phydev->duplex = DUPLEX_FULL;
+	else
+		phydev->duplex = DUPLEX_HALF;
+
+	if (phy_ctl & MIIM_KSZ90xx_PHYCTL_1000)
+		phydev->speed = SPEED_1000;
+	else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_100)
+		phydev->speed = SPEED_100;
+	else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_10)
+		phydev->speed = SPEED_10;
+	return 0;
+}
+#ifdef CONFIG_PHY_MICREL_KSZ9021
+
+/*
+ * KSZ9021
+ */
+
+/* PHY Registers */
+#define MII_KSZ9021_EXTENDED_CTRL	0x0b
+#define MII_KSZ9021_EXTENDED_DATAW	0x0c
+#define MII_KSZ9021_EXTENDED_DATAR	0x0d
+
+#define CTRL1000_PREFER_MASTER		(1 << 10)
+#define CTRL1000_CONFIG_MASTER		(1 << 11)
+#define CTRL1000_MANUAL_CONFIG		(1 << 12)
+
+int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val)
+{
+	/* extended registers */
+	phy_write(phydev, MDIO_DEVAD_NONE,
+		MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000);
+	return phy_write(phydev, MDIO_DEVAD_NONE,
+		MII_KSZ9021_EXTENDED_DATAW, val);
+}
+
+int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum)
+{
+	/* extended registers */
+	phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum);
+	return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR);
+}
+
+
+static int ksz9021_phy_extread(struct phy_device *phydev, int addr, int devaddr,
+			      int regnum)
+{
+	return ksz9021_phy_extended_read(phydev, regnum);
+}
+
+static int ksz9021_phy_extwrite(struct phy_device *phydev, int addr,
+			       int devaddr, int regnum, u16 val)
+{
+	return ksz9021_phy_extended_write(phydev, regnum, val);
+}
+
+/* Micrel ksz9021 */
+static int ksz9021_config(struct phy_device *phydev)
+{
+	unsigned ctrl1000 = 0;
+	const unsigned master = CTRL1000_PREFER_MASTER |
+			CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
+	unsigned features = phydev->drv->features;
+
+	if (getenv("disable_giga"))
+		features &= ~(SUPPORTED_1000baseT_Half |
+				SUPPORTED_1000baseT_Full);
+	/* force master mode for 1000BaseT due to chip errata */
+	if (features & SUPPORTED_1000baseT_Half)
+		ctrl1000 |= ADVERTISE_1000HALF | master;
+	if (features & SUPPORTED_1000baseT_Full)
+		ctrl1000 |= ADVERTISE_1000FULL | master;
+	phydev->advertising = phydev->supported = features;
+	phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000);
+	genphy_config_aneg(phydev);
+	genphy_restart_aneg(phydev);
+	return 0;
+}
+
+static struct phy_driver ksz9021_driver = {
+	.name = "Micrel ksz9021",
+	.uid  = 0x221610,
+	.mask = 0xfffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &ksz9021_config,
+	.startup = &ksz90xx_startup,
+	.shutdown = &genphy_shutdown,
+	.writeext = &ksz9021_phy_extwrite,
+	.readext = &ksz9021_phy_extread,
+};
+#endif
+
+/**
+ * KSZ9031
+ */
+/* PHY Registers */
+#define MII_KSZ9031_MMD_ACCES_CTRL	0x0d
+#define MII_KSZ9031_MMD_REG_DATA	0x0e
+
+/* Accessors to extended registers*/
+int ksz9031_phy_extended_write(struct phy_device *phydev,
+			       int devaddr, int regnum, u16 mode, u16 val)
+{
+	/*select register addr for mmd*/
+	phy_write(phydev, MDIO_DEVAD_NONE,
+		  MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
+	/*select register for mmd*/
+	phy_write(phydev, MDIO_DEVAD_NONE,
+		  MII_KSZ9031_MMD_REG_DATA, regnum);
+	/*setup mode*/
+	phy_write(phydev, MDIO_DEVAD_NONE,
+		  MII_KSZ9031_MMD_ACCES_CTRL, (mode | devaddr));
+	/*write the value*/
+	return	phy_write(phydev, MDIO_DEVAD_NONE,
+		MII_KSZ9031_MMD_REG_DATA, val);
+}
+
+int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr,
+			      int regnum, u16 mode)
+{
+	phy_write(phydev, MDIO_DEVAD_NONE,
+		  MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
+	phy_write(phydev, MDIO_DEVAD_NONE,
+		  MII_KSZ9031_MMD_REG_DATA, regnum);
+	phy_write(phydev, MDIO_DEVAD_NONE,
+		  MII_KSZ9031_MMD_ACCES_CTRL, (devaddr | mode));
+	return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9031_MMD_REG_DATA);
+}
+
+static int ksz9031_phy_extread(struct phy_device *phydev, int addr, int devaddr,
+			       int regnum)
+{
+	return ksz9031_phy_extended_read(phydev, devaddr, regnum,
+					 MII_KSZ9031_MOD_DATA_NO_POST_INC);
+};
+
+static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr,
+				int devaddr, int regnum, u16 val)
+{
+	return ksz9031_phy_extended_write(phydev, devaddr, regnum,
+					 MII_KSZ9031_MOD_DATA_POST_INC_RW, val);
+};
+
+
+static struct phy_driver ksz9031_driver = {
+	.name = "Micrel ksz9031",
+	.uid  = 0x221620,
+	.mask = 0xfffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config   = &genphy_config,
+	.startup  = &ksz90xx_startup,
+	.shutdown = &genphy_shutdown,
+	.writeext = &ksz9031_phy_extwrite,
+	.readext = &ksz9031_phy_extread,
+};
+
+int phy_micrel_init(void)
+{
+	phy_register(&KSZ804_driver);
+#ifdef CONFIG_PHY_MICREL_KSZ9021
+	phy_register(&ksz9021_driver);
+#else
+	phy_register(&KS8721_driver);
+#endif
+	phy_register(&ksz9031_driver);
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/phy/miiphybb.c b/marvell/uboot/drivers/net/phy/miiphybb.c
new file mode 100644
index 0000000..5cda0b8
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/miiphybb.c
@@ -0,0 +1,364 @@
+/*
+ * (C) Copyright 2009 Industrie Dial Face S.p.A.
+ * Luigi 'Comio' Mantellini <luigi.mantellini@idf-hit.com>
+ *
+ * (C) Copyright 2001
+ * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * This provides a bit-banged interface to the ethernet MII management
+ * channel.
+ */
+
+#include <common.h>
+#include <ioports.h>
+#include <ppc_asm.tmpl>
+#include <miiphy.h>
+
+#define BB_MII_RELOCATE(v,off) (v += (v?off:0))
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_BITBANGMII_MULTI
+
+/*
+ * If CONFIG_BITBANGMII_MULTI is not defined we use a
+ * compatibility layer with the previous miiphybb implementation
+ * based on macros usage.
+ *
+ */
+static int bb_mii_init_wrap(struct bb_miiphy_bus *bus)
+{
+#ifdef MII_INIT
+	MII_INIT;
+#endif
+	return 0;
+}
+
+static int bb_mdio_active_wrap(struct bb_miiphy_bus *bus)
+{
+#ifdef MDIO_DECLARE
+	MDIO_DECLARE;
+#endif
+	MDIO_ACTIVE;
+	return 0;
+}
+
+static int bb_mdio_tristate_wrap(struct bb_miiphy_bus *bus)
+{
+#ifdef MDIO_DECLARE
+	MDIO_DECLARE;
+#endif
+	MDIO_TRISTATE;
+	return 0;
+}
+
+static int bb_set_mdio_wrap(struct bb_miiphy_bus *bus, int v)
+{
+#ifdef MDIO_DECLARE
+	MDIO_DECLARE;
+#endif
+	MDIO(v);
+	return 0;
+}
+
+static int bb_get_mdio_wrap(struct bb_miiphy_bus *bus, int *v)
+{
+#ifdef MDIO_DECLARE
+	MDIO_DECLARE;
+#endif
+	*v = MDIO_READ;
+	return 0;
+}
+
+static int bb_set_mdc_wrap(struct bb_miiphy_bus *bus, int v)
+{
+#ifdef MDC_DECLARE
+	MDC_DECLARE;
+#endif
+	MDC(v);
+	return 0;
+}
+
+static int bb_delay_wrap(struct bb_miiphy_bus *bus)
+{
+	MIIDELAY;
+	return 0;
+}
+
+struct bb_miiphy_bus bb_miiphy_buses[] = {
+	{
+		.name = BB_MII_DEVNAME,
+		.init = bb_mii_init_wrap,
+		.mdio_active = bb_mdio_active_wrap,
+		.mdio_tristate = bb_mdio_tristate_wrap,
+		.set_mdio = bb_set_mdio_wrap,
+		.get_mdio = bb_get_mdio_wrap,
+		.set_mdc = bb_set_mdc_wrap,
+		.delay = bb_delay_wrap,
+	}
+};
+
+int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
+			  sizeof(bb_miiphy_buses[0]);
+#endif
+
+void bb_miiphy_init(void)
+{
+	int i;
+
+	for (i = 0; i < bb_miiphy_buses_num; i++) {
+#if defined(CONFIG_NEEDS_MANUAL_RELOC)
+		/* Relocate the hook pointers*/
+		BB_MII_RELOCATE(bb_miiphy_buses[i].init, gd->reloc_off);
+		BB_MII_RELOCATE(bb_miiphy_buses[i].mdio_active, gd->reloc_off);
+		BB_MII_RELOCATE(bb_miiphy_buses[i].mdio_tristate, gd->reloc_off);
+		BB_MII_RELOCATE(bb_miiphy_buses[i].set_mdio, gd->reloc_off);
+		BB_MII_RELOCATE(bb_miiphy_buses[i].get_mdio, gd->reloc_off);
+		BB_MII_RELOCATE(bb_miiphy_buses[i].set_mdc, gd->reloc_off);
+		BB_MII_RELOCATE(bb_miiphy_buses[i].delay, gd->reloc_off);
+#endif
+		if (bb_miiphy_buses[i].init != NULL) {
+			bb_miiphy_buses[i].init(&bb_miiphy_buses[i]);
+		}
+	}
+}
+
+static inline struct bb_miiphy_bus *bb_miiphy_getbus(const char *devname)
+{
+#ifdef CONFIG_BITBANGMII_MULTI
+	int i;
+
+	/* Search the correct bus */
+	for (i = 0; i < bb_miiphy_buses_num; i++) {
+		if (!strcmp(bb_miiphy_buses[i].name, devname)) {
+			return &bb_miiphy_buses[i];
+		}
+	}
+	return NULL;
+#else
+	/* We have just one bitbanging bus */
+	return &bb_miiphy_buses[0];
+#endif
+}
+
+/*****************************************************************************
+ *
+ * Utility to send the preamble, address, and register (common to read
+ * and write).
+ */
+static void miiphy_pre(struct bb_miiphy_bus *bus, char read,
+		       unsigned char addr, unsigned char reg)
+{
+	int j;
+
+	/*
+	 * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
+	 * The IEEE spec says this is a PHY optional requirement.  The AMD
+	 * 79C874 requires one after power up and one after a MII communications
+	 * error.  This means that we are doing more preambles than we need,
+	 * but it is safer and will be much more robust.
+	 */
+
+	bus->mdio_active(bus);
+	bus->set_mdio(bus, 1);
+	for (j = 0; j < 32; j++) {
+		bus->set_mdc(bus, 0);
+		bus->delay(bus);
+		bus->set_mdc(bus, 1);
+		bus->delay(bus);
+	}
+
+	/* send the start bit (01) and the read opcode (10) or write (10) */
+	bus->set_mdc(bus, 0);
+	bus->set_mdio(bus, 0);
+	bus->delay(bus);
+	bus->set_mdc(bus, 1);
+	bus->delay(bus);
+	bus->set_mdc(bus, 0);
+	bus->set_mdio(bus, 1);
+	bus->delay(bus);
+	bus->set_mdc(bus, 1);
+	bus->delay(bus);
+	bus->set_mdc(bus, 0);
+	bus->set_mdio(bus, read);
+	bus->delay(bus);
+	bus->set_mdc(bus, 1);
+	bus->delay(bus);
+	bus->set_mdc(bus, 0);
+	bus->set_mdio(bus, !read);
+	bus->delay(bus);
+	bus->set_mdc(bus, 1);
+	bus->delay(bus);
+
+	/* send the PHY address */
+	for (j = 0; j < 5; j++) {
+		bus->set_mdc(bus, 0);
+		if ((addr & 0x10) == 0) {
+			bus->set_mdio(bus, 0);
+		} else {
+			bus->set_mdio(bus, 1);
+		}
+		bus->delay(bus);
+		bus->set_mdc(bus, 1);
+		bus->delay(bus);
+		addr <<= 1;
+	}
+
+	/* send the register address */
+	for (j = 0; j < 5; j++) {
+		bus->set_mdc(bus, 0);
+		if ((reg & 0x10) == 0) {
+			bus->set_mdio(bus, 0);
+		} else {
+			bus->set_mdio(bus, 1);
+		}
+		bus->delay(bus);
+		bus->set_mdc(bus, 1);
+		bus->delay(bus);
+		reg <<= 1;
+	}
+}
+
+/*****************************************************************************
+ *
+ * Read a MII PHY register.
+ *
+ * Returns:
+ *   0 on success
+ */
+int bb_miiphy_read(const char *devname, unsigned char addr,
+		   unsigned char reg, unsigned short *value)
+{
+	short rdreg; /* register working value */
+	int v;
+	int j; /* counter */
+	struct bb_miiphy_bus *bus;
+
+	bus = bb_miiphy_getbus(devname);
+	if (bus == NULL) {
+		return -1;
+	}
+
+	if (value == NULL) {
+		puts("NULL value pointer\n");
+		return -1;
+	}
+
+	miiphy_pre (bus, 1, addr, reg);
+
+	/* tri-state our MDIO I/O pin so we can read */
+	bus->set_mdc(bus, 0);
+	bus->mdio_tristate(bus);
+	bus->delay(bus);
+	bus->set_mdc(bus, 1);
+	bus->delay(bus);
+
+	/* check the turnaround bit: the PHY should be driving it to zero */
+	bus->get_mdio(bus, &v);
+	if (v != 0) {
+		/* puts ("PHY didn't drive TA low\n"); */
+		for (j = 0; j < 32; j++) {
+			bus->set_mdc(bus, 0);
+			bus->delay(bus);
+			bus->set_mdc(bus, 1);
+			bus->delay(bus);
+		}
+		/* There is no PHY, set value to 0xFFFF and return */
+		*value = 0xFFFF;
+		return -1;
+	}
+
+	bus->set_mdc(bus, 0);
+	bus->delay(bus);
+
+	/* read 16 bits of register data, MSB first */
+	rdreg = 0;
+	for (j = 0; j < 16; j++) {
+		bus->set_mdc(bus, 1);
+		bus->delay(bus);
+		rdreg <<= 1;
+		bus->get_mdio(bus, &v);
+		rdreg |= (v & 0x1);
+		bus->set_mdc(bus, 0);
+		bus->delay(bus);
+	}
+
+	bus->set_mdc(bus, 1);
+	bus->delay(bus);
+	bus->set_mdc(bus, 0);
+	bus->delay(bus);
+	bus->set_mdc(bus, 1);
+	bus->delay(bus);
+
+	*value = rdreg;
+
+#ifdef DEBUG
+	printf ("miiphy_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, *value);
+#endif
+
+	return 0;
+}
+
+
+/*****************************************************************************
+ *
+ * Write a MII PHY register.
+ *
+ * Returns:
+ *   0 on success
+ */
+int bb_miiphy_write (const char *devname, unsigned char addr,
+		     unsigned char reg, unsigned short value)
+{
+	struct bb_miiphy_bus *bus;
+	int j;			/* counter */
+
+	bus = bb_miiphy_getbus(devname);
+	if (bus == NULL) {
+		/* Bus not found! */
+		return -1;
+	}
+
+	miiphy_pre (bus, 0, addr, reg);
+
+	/* send the turnaround (10) */
+	bus->set_mdc(bus, 0);
+	bus->set_mdio(bus, 1);
+	bus->delay(bus);
+	bus->set_mdc(bus, 1);
+	bus->delay(bus);
+	bus->set_mdc(bus, 0);
+	bus->set_mdio(bus, 0);
+	bus->delay(bus);
+	bus->set_mdc(bus, 1);
+	bus->delay(bus);
+
+	/* write 16 bits of register data, MSB first */
+	for (j = 0; j < 16; j++) {
+		bus->set_mdc(bus, 0);
+		if ((value & 0x00008000) == 0) {
+			bus->set_mdio(bus, 0);
+		} else {
+			bus->set_mdio(bus, 1);
+		}
+		bus->delay(bus);
+		bus->set_mdc(bus, 1);
+		bus->delay(bus);
+		value <<= 1;
+	}
+
+	/*
+	 * Tri-state the MDIO line.
+	 */
+	bus->mdio_tristate(bus);
+	bus->set_mdc(bus, 0);
+	bus->delay(bus);
+	bus->set_mdc(bus, 1);
+	bus->delay(bus);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/phy/mv88e61xx.c b/marvell/uboot/drivers/net/phy/mv88e61xx.c
new file mode 100644
index 0000000..302abe8
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/mv88e61xx.c
@@ -0,0 +1,537 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <netdev.h>
+#include "mv88e61xx.h"
+
+/*
+ * Uncomment either of the following line for local debug control;
+ * otherwise global debug control will apply.
+ */
+
+/* #undef DEBUG */
+/* #define DEBUG */
+
+#ifdef CONFIG_MV88E61XX_MULTICHIP_ADRMODE
+/* Chip Address mode
+ * The Switch support two modes of operation
+ * 1. single chip mode and
+ * 2. Multi-chip mode
+ * Refer section 9.2 &9.3 in chip datasheet-02 for more details
+ *
+ * By default single chip mode is configured
+ * multichip mode operation can be configured in board header
+ */
+static int mv88e61xx_busychk_multic(char *name, u32 devaddr)
+{
+	u16 reg = 0;
+	u32 timeout = MV88E61XX_PHY_TIMEOUT;
+
+	/* Poll till SMIBusy bit is clear */
+	do {
+		miiphy_read(name, devaddr, 0x0, &reg);
+		if (timeout-- == 0) {
+			printf("SMI busy timeout\n");
+			return -1;
+		}
+	} while (reg & (1 << 15));
+	return 0;
+}
+
+static void mv88e61xx_switch_write(char *name, u32 phy_adr,
+	u32 reg_ofs, u16 data)
+{
+	u16 mii_dev_addr;
+
+	/* command to read PHY dev address */
+	if (miiphy_read(name, 0xEE, 0xEE, &mii_dev_addr)) {
+		printf("Error..could not read PHY dev address\n");
+		return;
+	}
+	mv88e61xx_busychk_multic(name, mii_dev_addr);
+	/* Write data to Switch indirect data register */
+	miiphy_write(name, mii_dev_addr, 0x1, data);
+	/* Write command to Switch indirect command register (write) */
+	miiphy_write(name, mii_dev_addr, 0x0,
+		     reg_ofs | (phy_adr << 5) | (1 << 10) | (1 << 12) | (1 <<
+									 15));
+}
+
+static void mv88e61xx_switch_read(char *name, u32 phy_adr,
+	u32 reg_ofs, u16 *data)
+{
+	u16 mii_dev_addr;
+
+	/* command to read PHY dev address */
+	if (miiphy_read(name, 0xEE, 0xEE, &mii_dev_addr)) {
+		printf("Error..could not read PHY dev address\n");
+		return;
+	}
+	mv88e61xx_busychk_multic(name, mii_dev_addr);
+	/* Write command to Switch indirect command register (read) */
+	miiphy_write(name, mii_dev_addr, 0x0,
+		     reg_ofs | (phy_adr << 5) | (1 << 11) | (1 << 12) | (1 <<
+									 15));
+	mv88e61xx_busychk_multic(name, mii_dev_addr);
+	/* Read data from Switch indirect data register */
+	miiphy_read(name, mii_dev_addr, 0x1, data);
+}
+#endif /* CONFIG_MV88E61XX_MULTICHIP_ADRMODE */
+
+/*
+ * Convenience macros for switch device/port reads/writes
+ * These macros output valid 'mv88e61xx' U_BOOT_CMDs
+ */
+
+#ifndef DEBUG
+#define WR_SWITCH_REG wr_switch_reg
+#define RD_SWITCH_REG rd_switch_reg
+#define WR_SWITCH_PORT_REG(n, p, r, d) \
+	WR_SWITCH_REG(n, (MV88E61XX_PRT_OFST+p), r, d)
+#define RD_SWITCH_PORT_REG(n, p, r, d) \
+	RD_SWITCH_REG(n, (MV88E61XX_PRT_OFST+p), r, d)
+#else
+static void WR_SWITCH_REG(char *name, u32 dev_adr, u32 reg_ofs, u16 data)
+{
+	printf("mv88e61xx %s dev %02x reg %02x write %04x\n",
+		name, dev_adr, reg_ofs, data);
+	wr_switch_reg(name, dev_adr, reg_ofs, data);
+}
+static void RD_SWITCH_REG(char *name, u32 dev_adr, u32 reg_ofs, u16 *data)
+{
+	rd_switch_reg(name, dev_adr, reg_ofs, data);
+	printf("mv88e61xx %s dev %02x reg %02x read %04x\n",
+		name, dev_adr, reg_ofs, *data);
+}
+static void WR_SWITCH_PORT_REG(char *name, u32 prt_adr, u32 reg_ofs,
+	u16 data)
+{
+	printf("mv88e61xx %s port %02x reg %02x write %04x\n",
+		name, prt_adr, reg_ofs, data);
+	wr_switch_reg(name, (MV88E61XX_PRT_OFST+prt_adr), reg_ofs, data);
+}
+static void RD_SWITCH_PORT_REG(char *name, u32 prt_adr, u32 reg_ofs,
+	u16 *data)
+{
+	rd_switch_reg(name, (MV88E61XX_PRT_OFST+prt_adr), reg_ofs, data);
+	printf("mv88e61xx %s port %02x reg %02x read %04x\n",
+		name, prt_adr, reg_ofs, *data);
+}
+#endif
+
+/*
+ * Local functions to read/write registers on the switch PHYs.
+ * NOTE! This goes through switch, not direct miiphy, writes and reads!
+ */
+
+/*
+ * Make sure SMIBusy bit cleared before another
+ * SMI operation can take place
+ */
+static int mv88e61xx_busychk(char *name)
+{
+	u16 reg = 0;
+	u32 timeout = MV88E61XX_PHY_TIMEOUT;
+	do {
+		rd_switch_reg(name, MV88E61XX_GLB2REG_DEVADR,
+		       MV88E61XX_PHY_CMD, &reg);
+		if (timeout-- == 0) {
+			printf("SMI busy timeout\n");
+			return -1;
+		}
+	} while (reg & 1 << 15);	/* busy mask */
+	return 0;
+}
+
+static inline int mv88e61xx_switch_miiphy_write(char *name, u32 phy,
+	u32 reg, u16 data)
+{
+	/* write switch data reg then cmd reg then check completion */
+	wr_switch_reg(name, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA,
+		data);
+	wr_switch_reg(name, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_CMD,
+		(MV88E61XX_PHY_WRITE_CMD | (phy << 5)  | reg));
+	return mv88e61xx_busychk(name);
+}
+
+static inline int mv88e61xx_switch_miiphy_read(char *name, u32 phy,
+	u32 reg, u16 *data)
+{
+	/* write switch cmd reg, check for completion */
+	wr_switch_reg(name, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_CMD,
+		(MV88E61XX_PHY_READ_CMD | (phy << 5)  | reg));
+	if (mv88e61xx_busychk(name))
+		return -1;
+	/* read switch data reg and return success */
+	rd_switch_reg(name, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, data);
+	return 0;
+}
+
+/*
+ * Convenience macros for switch PHY reads/writes
+ */
+
+#ifndef DEBUG
+#define WR_SWITCH_PHY_REG mv88e61xx_switch_miiphy_write
+#define RD_SWITCH_PHY_REG mv88e61xx_switch_miiphy_read
+#else
+static inline int WR_SWITCH_PHY_REG(char *name, u32 phy_adr,
+	u32 reg_ofs, u16 data)
+{
+	int r = mv88e61xx_switch_miiphy_write(name, phy_adr, reg_ofs, data);
+	if (r)
+		printf("** ERROR writing mv88e61xx %s phy %02x reg %02x\n",
+			name, phy_adr, reg_ofs);
+	else
+		printf("mv88e61xx %s phy %02x reg %02x write %04x\n",
+			name, phy_adr, reg_ofs, data);
+	return r;
+}
+static inline int RD_SWITCH_PHY_REG(char *name, u32 phy_adr,
+	u32 reg_ofs, u16 *data)
+{
+	int r = mv88e61xx_switch_miiphy_read(name, phy_adr, reg_ofs, data);
+	if (r)
+		printf("** ERROR reading mv88e61xx %s phy %02x reg %02x\n",
+			name, phy_adr, reg_ofs);
+	else
+		printf("mv88e61xx %s phy %02x reg %02x read %04x\n",
+			name, phy_adr, reg_ofs, *data);
+	return r;
+}
+#endif
+
+static void mv88e61xx_port_vlan_config(struct mv88e61xx_config *swconfig)
+{
+	u32 prt;
+	u16 reg;
+	char *name = swconfig->name;
+	u32 port_mask = swconfig->ports_enabled;
+
+	/* apply internal vlan config */
+	for (prt = 0; prt < MV88E61XX_MAX_PORTS_NUM; prt++) {
+		/* only for enabled ports */
+		if ((1 << prt) & port_mask) {
+			/* take vlan map from swconfig */
+			u8 vlanmap = swconfig->vlancfg[prt];
+			/* remove disabled ports from vlan map */
+			vlanmap &= swconfig->ports_enabled;
+			/* apply vlan map to port */
+			RD_SWITCH_PORT_REG(name, prt,
+				MV88E61XX_PRT_VMAP_REG, &reg);
+			reg &= ~((1 << MV88E61XX_MAX_PORTS_NUM) - 1);
+			reg |= vlanmap;
+			WR_SWITCH_PORT_REG(name, prt,
+				MV88E61XX_PRT_VMAP_REG, reg);
+		}
+	}
+}
+
+/*
+ * Power up the specified port and reset PHY
+ */
+static int mv88361xx_powerup(struct mv88e61xx_config *swconfig, u32 phy)
+{
+	char *name = swconfig->name;
+
+	/* Write Copper Specific control reg1 (0x10) for-
+	 * Enable Phy power up
+	 * Energy Detect on (sense&Xmit NLP Periodically
+	 * reset other settings default
+	 */
+	if (WR_SWITCH_PHY_REG(name, phy, 0x10, 0x3360))
+		return -1;
+
+	/* Write PHY ctrl reg (0x0) to apply
+	 * Phy reset (set bit 15 low)
+	 * reset other default values
+	 */
+	if (WR_SWITCH_PHY_REG(name, phy, 0x00, 0x9140))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Default Setup for LED[0]_Control (ref: Table 46 Datasheet-3)
+ * is set to "On-1000Mb/s Link, Off Else"
+ * This function sets it to "On-Link, Blink-Activity, Off-NoLink"
+ *
+ * This is optional settings may be needed on some boards
+ * to setup PHY LEDs default configuration to detect 10/100/1000Mb/s
+ * Link status
+ */
+static int mv88361xx_led_init(struct mv88e61xx_config *swconfig, u32 phy)
+{
+	char *name = swconfig->name;
+
+	if (swconfig->led_init != MV88E61XX_LED_INIT_EN)
+		return 0;
+
+	/* set page address to 3 */
+	if (WR_SWITCH_PHY_REG(name, phy, 0x16, 0x0003))
+		return -1;
+
+	/*
+	 * set LED Func Ctrl reg
+	 * value 0x0001 = LED[0] On-Link, Blink-Activity, Off-NoLink
+	 */
+	if (WR_SWITCH_PHY_REG(name, phy, 0x10, 0x0001))
+		return -1;
+
+	/* set page address to 0 */
+	if (WR_SWITCH_PHY_REG(name, phy, 0x16, 0x0000))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Reverse Transmit polarity for Media Dependent Interface
+ * Pins (MDIP) bits in Copper Specific Control Register 3
+ * (Page 0, Reg 20 for each phy (except cpu port)
+ * Reference: Section 1.1 Switch datasheet-3
+ *
+ * This is optional settings may be needed on some boards
+ * for PHY<->magnetics h/w tuning
+ */
+static int mv88361xx_reverse_mdipn(struct mv88e61xx_config *swconfig, u32 phy)
+{
+	char *name = swconfig->name;
+
+	if (swconfig->mdip != MV88E61XX_MDIP_REVERSE)
+		return 0;
+
+	/*Reverse MDIP/N[3:0] bits */
+	if (WR_SWITCH_PHY_REG(name, phy, 0x14, 0x000f))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Marvell 88E61XX Switch initialization
+ */
+int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig)
+{
+	u32 prt;
+	u16 reg;
+	char *idstr;
+	char *name = swconfig->name;
+	int time;
+
+	if (miiphy_set_current_dev(name)) {
+		printf("%s failed\n", __FUNCTION__);
+		return -1;
+	}
+
+	if (!(swconfig->cpuport & ((1 << 4) | (1 << 5)))) {
+		swconfig->cpuport = (1 << 5);
+		printf("Invalid cpu port config, using default port5\n");
+	}
+
+	RD_SWITCH_PORT_REG(name, 0, MII_PHYSID2, &reg);
+	switch (reg &= 0xfff0) {
+	case 0x1610:
+		idstr = "88E6161";
+		break;
+	case 0x1650:
+		idstr = "88E6165";
+		break;
+	case 0x1210:
+		idstr = "88E6123";
+		/* ports 2,3,4 not available */
+		swconfig->ports_enabled &= 0x023;
+		break;
+	default:
+		/* Could not detect switch id */
+		idstr = "88E61??";
+		break;
+	}
+
+	/* be sure all ports are disabled */
+	for (prt = 0; prt < MV88E61XX_MAX_PORTS_NUM; prt++) {
+		RD_SWITCH_PORT_REG(name, prt, MV88E61XX_PRT_CTRL_REG, &reg);
+		reg &= ~0x3;
+		WR_SWITCH_PORT_REG(name, prt, MV88E61XX_PRT_CTRL_REG, reg);
+	}
+
+	/* wait 2 ms for queues to drain */
+	udelay(2000);
+
+	/* reset switch */
+	RD_SWITCH_REG(name, MV88E61XX_GLBREG_DEVADR, MV88E61XX_SGCR, &reg);
+	reg |= 0x8000;
+	WR_SWITCH_REG(name, MV88E61XX_GLBREG_DEVADR, MV88E61XX_SGCR, reg);
+
+	/* wait up to 1 second for switch reset complete */
+	for (time = 1000; time; time--) {
+		RD_SWITCH_REG(name, MV88E61XX_GLBREG_DEVADR, MV88E61XX_SGSR,
+			&reg);
+		if ((reg & 0xc800) == 0xc800)
+			break;
+		udelay(1000);
+	}
+	if (!time)
+		return -1;
+
+	/* Port based VLANs configuration */
+	mv88e61xx_port_vlan_config(swconfig);
+
+	if (swconfig->rgmii_delay == MV88E61XX_RGMII_DELAY_EN) {
+		/*
+		 * Enable RGMII delay on Tx and Rx for CPU port
+		 * Ref: sec 9.5 of chip datasheet-02
+		 */
+		/*Force port link down */
+		WR_SWITCH_PORT_REG(name, 5, MV88E61XX_PCS_CTRL_REG, 0x10);
+		/* configure port RGMII delay */
+		WR_SWITCH_PORT_REG(name, 4,
+			MV88E61XX_RGMII_TIMECTRL_REG, 0x81e7);
+		RD_SWITCH_PORT_REG(name, 5,
+			MV88E61XX_RGMII_TIMECTRL_REG, &reg);
+		WR_SWITCH_PORT_REG(name, 5,
+			MV88E61XX_RGMII_TIMECTRL_REG, reg | 0x18);
+		WR_SWITCH_PORT_REG(name, 4,
+			MV88E61XX_RGMII_TIMECTRL_REG, 0xc1e7);
+		/* Force port to RGMII FDX 1000Base then up */
+		WR_SWITCH_PORT_REG(name, 5, MV88E61XX_PCS_CTRL_REG, 0x1e);
+		WR_SWITCH_PORT_REG(name, 5, MV88E61XX_PCS_CTRL_REG, 0x3e);
+	}
+
+	for (prt = 0; prt < MV88E61XX_MAX_PORTS_NUM; prt++) {
+
+		/* configure port's PHY */
+		if (!((1 << prt) & swconfig->cpuport)) {
+			/* port 4 has phy 6, not 4 */
+			int phy = (prt == 4) ? 6 : prt;
+			if (mv88361xx_powerup(swconfig, phy))
+				return -1;
+			if (mv88361xx_reverse_mdipn(swconfig, phy))
+				return -1;
+			if (mv88361xx_led_init(swconfig, phy))
+				return -1;
+		}
+
+		/* set port VID to port+1 except for cpu port */
+		if (!((1 << prt) & swconfig->cpuport)) {
+			RD_SWITCH_PORT_REG(name, prt,
+				MV88E61XX_PRT_VID_REG, &reg);
+			WR_SWITCH_PORT_REG(name, prt,
+				MV88E61XX_PRT_VID_REG,
+				(reg & ~1023) | (prt+1));
+		}
+
+		/*Program port state */
+		RD_SWITCH_PORT_REG(name, prt,
+			MV88E61XX_PRT_CTRL_REG, &reg);
+		WR_SWITCH_PORT_REG(name, prt,
+			MV88E61XX_PRT_CTRL_REG,
+			reg | (swconfig->portstate & 0x03));
+
+	}
+
+	printf("%s Initialized on %s\n", idstr, name);
+	return 0;
+}
+
+#ifdef CONFIG_MV88E61XX_CMD
+static int
+do_switch(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	char *name, *endp;
+	int write = 0;
+	enum { dev, prt, phy } target = dev;
+	u32 addrlo, addrhi, addr;
+	u32 reglo, reghi, reg;
+	u16 data, rdata;
+
+	if (argc < 7)
+		return -1;
+
+	name = argv[1];
+
+	if (strcmp(argv[2], "phy") == 0)
+		target = phy;
+	else if (strcmp(argv[2], "port") == 0)
+		target = prt;
+	else if (strcmp(argv[2], "dev") != 0)
+		return 1;
+
+	addrlo = simple_strtoul(argv[3], &endp, 16);
+
+	if (!*endp) {
+		addrhi = addrlo;
+	} else {
+		while (*endp < '0' || *endp > '9')
+			endp++;
+		addrhi = simple_strtoul(endp, NULL, 16);
+	}
+
+	reglo = simple_strtoul(argv[5], &endp, 16);
+	if (!*endp) {
+		reghi = reglo;
+	} else {
+		while (*endp < '0' || *endp > '9')
+			endp++;
+		reghi = simple_strtoul(endp, NULL, 16);
+	}
+
+	if (strcmp(argv[6], "write") == 0)
+		write = 1;
+	else if (strcmp(argv[6], "read") != 0)
+		return 1;
+
+	data = simple_strtoul(argv[7], NULL, 16);
+
+	for (addr = addrlo; addr <= addrhi; addr++) {
+		for (reg = reglo; reg <= reghi; reg++) {
+			if (write) {
+				if (target == phy)
+					mv88e61xx_switch_miiphy_write(
+						name, addr, reg, data);
+				else if (target == prt)
+					wr_switch_reg(name,
+						addr+MV88E61XX_PRT_OFST,
+						reg, data);
+				else
+					wr_switch_reg(name, addr, reg, data);
+			} else {
+				if (target == phy)
+					mv88e61xx_switch_miiphy_read(
+						name, addr, reg, &rdata);
+				else if (target == prt)
+					rd_switch_reg(name,
+						addr+MV88E61XX_PRT_OFST,
+						reg, &rdata);
+				else
+					rd_switch_reg(name, addr, reg, &rdata);
+				printf("%s %s %s %02x %s %02x %s %04x\n",
+					argv[0], argv[1], argv[2], addr,
+					argv[4], reg, argv[6], rdata);
+				if (write && argc == 7 && rdata != data)
+					return 1;
+			}
+		}
+	}
+	return 0;
+}
+
+U_BOOT_CMD(mv88e61xx, 8, 0, do_switch,
+	"Read or write mv88e61xx switch registers",
+	"<ethdevice> dev|port|phy <addr> reg <reg> write <data>\n"
+	"<ethdevice> dev|port|phy <addr> reg <reg> read [<data>]\n"
+	"    - read/write switch device, port or phy at (addr,reg)\n"
+	"      addr=0..0x1C for dev, 0..5 for port or phy.\n"
+	"      reg=0..0x1F.\n"
+	"      data=0..0xFFFF (tested if present against actual read).\n"
+	"      All numeric parameters are assumed to be hex.\n"
+	"      <addr> and <<reg> arguments can be ranges (x..y)"
+);
+#endif /* CONFIG_MV88E61XX_CMD */
diff --git a/marvell/uboot/drivers/net/phy/mv88e61xx.h b/marvell/uboot/drivers/net/phy/mv88e61xx.h
new file mode 100644
index 0000000..9c62e4a
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/mv88e61xx.h
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _MV88E61XX_H
+#define _MV88E61XX_H
+
+#include <miiphy.h>
+
+#define MV88E61XX_CPU_PORT		0x5
+
+#define MV88E61XX_PHY_TIMEOUT		100000
+
+/* port dev-addr (= port + 0x10) */
+#define MV88E61XX_PRT_OFST		0x10
+/* port registers */
+#define MV88E61XX_PCS_CTRL_REG		0x1
+#define MV88E61XX_PRT_CTRL_REG		0x4
+#define MV88E61XX_PRT_VMAP_REG		0x6
+#define MV88E61XX_PRT_VID_REG		0x7
+#define MV88E61XX_RGMII_TIMECTRL_REG	0x1A
+
+/* global registers dev-addr */
+#define MV88E61XX_GLBREG_DEVADR	0x1B
+/* global registers */
+#define MV88E61XX_SGSR			0x00
+#define MV88E61XX_SGCR			0x04
+
+/* global 2 registers dev-addr */
+#define MV88E61XX_GLB2REG_DEVADR	0x1C
+/* global 2 registers */
+#define MV88E61XX_PHY_CMD		0x18
+#define MV88E61XX_PHY_DATA		0x19
+/* global 2 phy commands */
+#define MV88E61XX_PHY_WRITE_CMD		0x9400
+#define MV88E61XX_PHY_READ_CMD		0x9800
+
+#define MV88E61XX_BUSY_OFST		15
+#define MV88E61XX_MODE_OFST		12
+#define MV88E61XX_OP_OFST		10
+#define MV88E61XX_ADDR_OFST		5
+
+#ifdef CONFIG_MV88E61XX_MULTICHIP_ADRMODE
+static int mv88e61xx_busychk_multic(char *name, u32 devaddr);
+static void mv88e61xx_switch_write(char *name, u32 phy_adr,
+	u32 reg_ofs, u16 data);
+static void mv88e61xx_switch_read(char *name, u32 phy_adr,
+	u32 reg_ofs, u16 *data);
+#define wr_switch_reg mv88e61xx_switch_write
+#define rd_switch_reg mv88e61xx_switch_read
+#else
+/* switch appears a s simple PHY and can thus use miiphy */
+#define wr_switch_reg miiphy_write
+#define rd_switch_reg miiphy_read
+#endif /* CONFIG_MV88E61XX_MULTICHIP_ADRMODE */
+
+#endif /* _MV88E61XX_H */
diff --git a/marvell/uboot/drivers/net/phy/mv88e6352.c b/marvell/uboot/drivers/net/phy/mv88e6352.c
new file mode 100644
index 0000000..f639a42
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/mv88e6352.c
@@ -0,0 +1,302 @@
+/*
+ * (C) Copyright 2012
+ * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <miiphy.h>
+#include <asm/errno.h>
+#include <mv88e6352.h>
+
+#define SMI_HDR		((0x8 | 0x1) << 12)
+#define SMI_BUSY_MASK	(0x8000)
+#define SMIRD_OP	(0x2 << 10)
+#define SMIWR_OP	(0x1 << 10)
+#define SMI_MASK	0x1f
+#define PORT_SHIFT	5
+
+#define COMMAND_REG	0
+#define DATA_REG	1
+
+/* global registers */
+#define GLOBAL		0x1b
+
+#define GLOBAL_STATUS	0x00
+#define PPU_STATE	0x8000
+
+#define GLOBAL_CTRL	0x04
+#define SW_RESET	0x8000
+#define PPU_ENABLE	0x4000
+
+static int sw_wait_rdy(const char *devname, u8 phy_addr)
+{
+	u16 command;
+	u32 timeout = 100;
+	int ret;
+
+	/* wait till the SMI is not busy */
+	do {
+		/* read command register */
+		ret = miiphy_read(devname, phy_addr, COMMAND_REG, &command);
+		if (ret < 0) {
+			printf("%s: Error reading command register\n",
+				__func__);
+			return ret;
+		}
+		if (timeout-- == 0) {
+			printf("Err..(%s) SMI busy timeout\n", __func__);
+			return -EFAULT;
+		}
+	} while (command & SMI_BUSY_MASK);
+
+	return 0;
+}
+
+static int sw_reg_read(const char *devname, u8 phy_addr, u8 port,
+	u8 reg, u16 *data)
+{
+	int ret;
+	u16 command;
+
+	ret = sw_wait_rdy(devname, phy_addr);
+	if (ret)
+		return ret;
+
+	command = SMI_HDR | SMIRD_OP | ((port&SMI_MASK) << PORT_SHIFT) |
+			(reg & SMI_MASK);
+	debug("%s: write to command: %#x\n", __func__, command);
+	ret = miiphy_write(devname, phy_addr, COMMAND_REG, command);
+	if (ret)
+		return ret;
+
+	ret = sw_wait_rdy(devname, phy_addr);
+	if (ret)
+		return ret;
+
+	ret = miiphy_read(devname, phy_addr, DATA_REG, data);
+
+	return ret;
+}
+
+static int sw_reg_write(const char *devname, u8 phy_addr, u8 port,
+	u8 reg, u16 data)
+{
+	int ret;
+	u16 value;
+
+	ret = sw_wait_rdy(devname, phy_addr);
+	if (ret)
+		return ret;
+
+	debug("%s: write to data: %#x\n", __func__, data);
+	ret = miiphy_write(devname, phy_addr, DATA_REG, data);
+	if (ret)
+		return ret;
+
+	value = SMI_HDR | SMIWR_OP | ((port & SMI_MASK) << PORT_SHIFT) |
+			(reg & SMI_MASK);
+	debug("%s: write to command: %#x\n", __func__, value);
+	ret = miiphy_write(devname, phy_addr, COMMAND_REG, value);
+	if (ret)
+		return ret;
+
+	ret = sw_wait_rdy(devname, phy_addr);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int ppu_enable(const char *devname, u8 phy_addr)
+{
+	int i, ret = 0;
+	u16 reg;
+
+	ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, &reg);
+	if (ret) {
+		printf("%s: Error reading global ctrl reg\n", __func__);
+		return ret;
+	}
+
+	reg |= PPU_ENABLE;
+
+	ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg);
+	if (ret) {
+		printf("%s: Error writing global ctrl reg\n", __func__);
+		return ret;
+	}
+
+	for (i = 0; i < 1000; i++) {
+		sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS,
+			&reg);
+		if ((reg & 0xc000) == 0xc000)
+			return 0;
+		udelay(1000);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int ppu_disable(const char *devname, u8 phy_addr)
+{
+	int i, ret = 0;
+	u16 reg;
+
+	ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, &reg);
+	if (ret) {
+		printf("%s: Error reading global ctrl reg\n", __func__);
+		return ret;
+	}
+
+	reg &= ~PPU_ENABLE;
+
+	ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg);
+	if (ret) {
+		printf("%s: Error writing global ctrl reg\n", __func__);
+		return ret;
+	}
+
+	for (i = 0; i < 1000; i++) {
+		sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS,
+			&reg);
+		if ((reg & 0xc000) != 0xc000)
+			return 0;
+		udelay(1000);
+	}
+
+	return -ETIMEDOUT;
+}
+
+int mv88e_sw_program(const char *devname, u8 phy_addr,
+	struct mv88e_sw_reg *regs, int regs_nb)
+{
+	int i, ret = 0;
+
+	/* first we need to disable the PPU */
+	ret = ppu_disable(devname, phy_addr);
+	if (ret) {
+		printf("%s: Error disabling PPU\n", __func__);
+		return ret;
+	}
+
+	for (i = 0; i < regs_nb; i++) {
+		ret = sw_reg_write(devname, phy_addr, regs[i].port,
+			regs[i].reg, regs[i].value);
+		if (ret) {
+			printf("%s: Error configuring switch\n", __func__);
+			ppu_enable(devname, phy_addr);
+			return ret;
+		}
+	}
+
+	/* re-enable the PPU */
+	ret = ppu_enable(devname, phy_addr);
+	if (ret) {
+		printf("%s: Error enabling PPU\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+
+int mv88e_sw_reset(const char *devname, u8 phy_addr)
+{
+	int i, ret = 0;
+	u16 reg;
+
+	ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, &reg);
+	if (ret) {
+		printf("%s: Error reading global ctrl reg\n", __func__);
+		return ret;
+	}
+
+	reg = SW_RESET | PPU_ENABLE | 0x0400;
+
+	ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg);
+	if (ret) {
+		printf("%s: Error writing global ctrl reg\n", __func__);
+		return ret;
+	}
+
+	for (i = 0; i < 1000; i++) {
+		sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS,
+			&reg);
+		if ((reg & 0xc800) != 0xc800)
+			return 0;
+		udelay(1000);
+	}
+
+	return -ETIMEDOUT;
+}
+
+int do_mvsw_reg_read(const char *name, int argc, char * const argv[])
+{
+	u16 value = 0, phyaddr, reg, port;
+	int ret;
+
+	phyaddr = simple_strtoul(argv[1], NULL, 10);
+	port = simple_strtoul(argv[2], NULL, 10);
+	reg = simple_strtoul(argv[3], NULL, 10);
+
+	ret = sw_reg_read(name, phyaddr, port, reg, &value);
+	printf("%#x\n", value);
+
+	return ret;
+}
+
+int do_mvsw_reg_write(const char *name, int argc, char * const argv[])
+{
+	u16 value = 0, phyaddr, reg, port;
+	int ret;
+
+	phyaddr = simple_strtoul(argv[1], NULL, 10);
+	port = simple_strtoul(argv[2], NULL, 10);
+	reg = simple_strtoul(argv[3], NULL, 10);
+	value = simple_strtoul(argv[4], NULL, 16);
+
+	ret = sw_reg_write(name, phyaddr, port, reg, value);
+
+	return ret;
+}
+
+
+int do_mvsw_reg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int ret;
+	const char *cmd, *ethname;
+
+	if (argc < 2)
+		return cmd_usage(cmdtp);
+
+	cmd = argv[1];
+	--argc;
+	++argv;
+
+	if (strcmp(cmd, "read") == 0) {
+		if (argc < 5)
+			return cmd_usage(cmdtp);
+		ethname = argv[1];
+		--argc;
+		++argv;
+		ret = do_mvsw_reg_read(ethname, argc, argv);
+	} else if (strcmp(cmd, "write") == 0) {
+		if (argc < 6)
+			return cmd_usage(cmdtp);
+		ethname = argv[1];
+		--argc;
+		++argv;
+		ret = do_mvsw_reg_write(ethname, argc, argv);
+	} else
+		return cmd_usage(cmdtp);
+
+	return ret;
+}
+
+U_BOOT_CMD(
+	mvsw_reg,	7,	1,	do_mvsw_reg,
+	"marvell 88e6352 switch register access",
+	"write ethname phyaddr port reg value\n"
+	"mvsw_reg read  ethname phyaddr port reg\n"
+	);
diff --git a/marvell/uboot/drivers/net/phy/natsemi.c b/marvell/uboot/drivers/net/phy/natsemi.c
new file mode 100644
index 0000000..ea9fe83
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/natsemi.c
@@ -0,0 +1,119 @@
+/*
+ * National Semiconductor PHY drivers
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Copyright 2010-2011 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ */
+#include <phy.h>
+
+/* NatSemi DP83630 */
+
+#define DP83630_PHY_PAGESEL_REG		0x13
+#define DP83630_PHY_PTP_COC_REG		0x14
+#define DP83630_PHY_PTP_CLKOUT_EN	(1<<15)
+#define DP83630_PHY_RBR_REG		0x17
+
+static int dp83630_config(struct phy_device *phydev)
+{
+	int ptp_coc_reg;
+
+	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
+	phy_write(phydev, MDIO_DEVAD_NONE, DP83630_PHY_PAGESEL_REG, 0x6);
+	ptp_coc_reg = phy_read(phydev, MDIO_DEVAD_NONE,
+			       DP83630_PHY_PTP_COC_REG);
+	ptp_coc_reg &= ~DP83630_PHY_PTP_CLKOUT_EN;
+	phy_write(phydev, MDIO_DEVAD_NONE, DP83630_PHY_PTP_COC_REG,
+		  ptp_coc_reg);
+	phy_write(phydev, MDIO_DEVAD_NONE, DP83630_PHY_PAGESEL_REG, 0);
+
+	genphy_config_aneg(phydev);
+
+	return 0;
+}
+
+static struct phy_driver DP83630_driver = {
+	.name = "NatSemi DP83630",
+	.uid = 0x20005ce1,
+	.mask = 0xfffffff0,
+	.features = PHY_BASIC_FEATURES,
+	.config = &dp83630_config,
+	.startup = &genphy_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+
+/* DP83865 Link and Auto-Neg Status Register */
+#define MIIM_DP83865_LANR      0x11
+#define MIIM_DP83865_SPD_MASK  0x0018
+#define MIIM_DP83865_SPD_1000  0x0010
+#define MIIM_DP83865_SPD_100   0x0008
+#define MIIM_DP83865_DPX_FULL  0x0002
+
+
+/* NatSemi DP83865 */
+static int dp83865_config(struct phy_device *phydev)
+{
+	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
+	genphy_config_aneg(phydev);
+
+	return 0;
+}
+
+static int dp83865_parse_status(struct phy_device *phydev)
+{
+	int mii_reg;
+
+	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_DP83865_LANR);
+
+	switch (mii_reg & MIIM_DP83865_SPD_MASK) {
+
+	case MIIM_DP83865_SPD_1000:
+		phydev->speed = SPEED_1000;
+		break;
+
+	case MIIM_DP83865_SPD_100:
+		phydev->speed = SPEED_100;
+		break;
+
+	default:
+		phydev->speed = SPEED_10;
+		break;
+
+	}
+
+	if (mii_reg & MIIM_DP83865_DPX_FULL)
+		phydev->duplex = DUPLEX_FULL;
+	else
+		phydev->duplex = DUPLEX_HALF;
+
+	return 0;
+}
+
+static int dp83865_startup(struct phy_device *phydev)
+{
+	genphy_update_link(phydev);
+	dp83865_parse_status(phydev);
+
+	return 0;
+}
+
+
+static struct phy_driver DP83865_driver = {
+	.name = "NatSemi DP83865",
+	.uid = 0x20005c70,
+	.mask = 0xfffffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &dp83865_config,
+	.startup = &dp83865_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+int phy_natsemi_init(void)
+{
+	phy_register(&DP83630_driver);
+	phy_register(&DP83865_driver);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/phy/phy.c b/marvell/uboot/drivers/net/phy/phy.c
new file mode 100644
index 0000000..c691fbb
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/phy.c
@@ -0,0 +1,816 @@
+/*
+ * Generic PHY Management code
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ *
+ * Based loosely off of Linux's PHY Lib
+ */
+
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <command.h>
+#include <miiphy.h>
+#include <phy.h>
+#include <errno.h>
+#include <linux/err.h>
+
+/* Generic PHY support and helper functions */
+
+/**
+ * genphy_config_advert - sanitize and advertise auto-negotation parameters
+ * @phydev: target phy_device struct
+ *
+ * Description: Writes MII_ADVERTISE with the appropriate values,
+ *   after sanitizing the values to make sure we only advertise
+ *   what is supported.  Returns < 0 on error, 0 if the PHY's advertisement
+ *   hasn't changed, and > 0 if it has changed.
+ */
+static int genphy_config_advert(struct phy_device *phydev)
+{
+	u32 advertise;
+	int oldadv, adv;
+	int err, changed = 0;
+
+	/* Only allow advertising what
+	 * this PHY supports */
+	phydev->advertising &= phydev->supported;
+	advertise = phydev->advertising;
+
+	/* Setup standard advertisement */
+	oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
+
+	if (adv < 0)
+		return adv;
+
+	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
+		 ADVERTISE_PAUSE_ASYM);
+	if (advertise & ADVERTISED_10baseT_Half)
+		adv |= ADVERTISE_10HALF;
+	if (advertise & ADVERTISED_10baseT_Full)
+		adv |= ADVERTISE_10FULL;
+	if (advertise & ADVERTISED_100baseT_Half)
+		adv |= ADVERTISE_100HALF;
+	if (advertise & ADVERTISED_100baseT_Full)
+		adv |= ADVERTISE_100FULL;
+	if (advertise & ADVERTISED_Pause)
+		adv |= ADVERTISE_PAUSE_CAP;
+	if (advertise & ADVERTISED_Asym_Pause)
+		adv |= ADVERTISE_PAUSE_ASYM;
+	if (advertise & ADVERTISED_1000baseX_Half)
+		adv |= ADVERTISE_1000XHALF;
+	if (advertise & ADVERTISED_1000baseX_Full)
+		adv |= ADVERTISE_1000XFULL;
+
+	if (adv != oldadv) {
+		err = phy_write(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE, adv);
+
+		if (err < 0)
+			return err;
+		changed = 1;
+	}
+
+	/* Configure gigabit if it's supported */
+	if (phydev->supported & (SUPPORTED_1000baseT_Half |
+				SUPPORTED_1000baseT_Full)) {
+		oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
+
+		if (adv < 0)
+			return adv;
+
+		adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
+		if (advertise & SUPPORTED_1000baseT_Half)
+			adv |= ADVERTISE_1000HALF;
+		if (advertise & SUPPORTED_1000baseT_Full)
+			adv |= ADVERTISE_1000FULL;
+
+		if (adv != oldadv) {
+			err = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000,
+					adv);
+
+			if (err < 0)
+				return err;
+			changed = 1;
+		}
+	}
+
+	return changed;
+}
+
+
+/**
+ * genphy_setup_forced - configures/forces speed/duplex from @phydev
+ * @phydev: target phy_device struct
+ *
+ * Description: Configures MII_BMCR to force speed/duplex
+ *   to the values in phydev. Assumes that the values are valid.
+ */
+static int genphy_setup_forced(struct phy_device *phydev)
+{
+	int err;
+	int ctl = 0;
+
+	phydev->pause = phydev->asym_pause = 0;
+
+	if (SPEED_1000 == phydev->speed)
+		ctl |= BMCR_SPEED1000;
+	else if (SPEED_100 == phydev->speed)
+		ctl |= BMCR_SPEED100;
+
+	if (DUPLEX_FULL == phydev->duplex)
+		ctl |= BMCR_FULLDPLX;
+
+	err = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
+
+	return err;
+}
+
+
+/**
+ * genphy_restart_aneg - Enable and Restart Autonegotiation
+ * @phydev: target phy_device struct
+ */
+int genphy_restart_aneg(struct phy_device *phydev)
+{
+	int ctl;
+
+	ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+
+	if (ctl < 0)
+		return ctl;
+
+	ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
+
+	/* Don't isolate the PHY if we're negotiating */
+	ctl &= ~(BMCR_ISOLATE);
+
+	ctl = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
+
+	return ctl;
+}
+
+
+/**
+ * genphy_config_aneg - restart auto-negotiation or write BMCR
+ * @phydev: target phy_device struct
+ *
+ * Description: If auto-negotiation is enabled, we configure the
+ *   advertising, and then restart auto-negotiation.  If it is not
+ *   enabled, then we write the BMCR.
+ */
+int genphy_config_aneg(struct phy_device *phydev)
+{
+	int result;
+
+	if (AUTONEG_ENABLE != phydev->autoneg)
+		return genphy_setup_forced(phydev);
+
+	result = genphy_config_advert(phydev);
+
+	if (result < 0) /* error */
+		return result;
+
+	if (result == 0) {
+		/* Advertisment hasn't changed, but maybe aneg was never on to
+		 * begin with?  Or maybe phy was isolated? */
+		int ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+
+		if (ctl < 0)
+			return ctl;
+
+		if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
+			result = 1; /* do restart aneg */
+	}
+
+	/* Only restart aneg if we are advertising something different
+	 * than we were before.	 */
+	if (result > 0)
+		result = genphy_restart_aneg(phydev);
+
+	return result;
+}
+
+/**
+ * genphy_update_link - update link status in @phydev
+ * @phydev: target phy_device struct
+ *
+ * Description: Update the value in phydev->link to reflect the
+ *   current link value.  In order to do this, we need to read
+ *   the status register twice, keeping the second value.
+ */
+int genphy_update_link(struct phy_device *phydev)
+{
+	unsigned int mii_reg;
+
+	/*
+	 * Wait if the link is up, and autonegotiation is in progress
+	 * (ie - we're capable and it's not done)
+	 */
+	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+
+	/*
+	 * If we already saw the link up, and it hasn't gone down, then
+	 * we don't need to wait for autoneg again
+	 */
+	if (phydev->link && mii_reg & BMSR_LSTATUS)
+		return 0;
+
+	if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
+		int i = 0;
+
+		printf("%s Waiting for PHY auto negotiation to complete",
+			phydev->dev->name);
+		while (!(mii_reg & BMSR_ANEGCOMPLETE)) {
+			/*
+			 * Timeout reached ?
+			 */
+			if (i > PHY_ANEG_TIMEOUT) {
+				printf(" TIMEOUT !\n");
+				phydev->link = 0;
+				return 0;
+			}
+
+			if (ctrlc()) {
+				puts("user interrupt!\n");
+				phydev->link = 0;
+				return -EINTR;
+			}
+
+			if ((i++ % 500) == 0)
+				printf(".");
+
+			udelay(1000);	/* 1 ms */
+			mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+		}
+		printf(" done\n");
+		phydev->link = 1;
+	} else {
+		/* Read the link a second time to clear the latched state */
+		mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+
+		if (mii_reg & BMSR_LSTATUS)
+			phydev->link = 1;
+		else
+			phydev->link = 0;
+	}
+
+	return 0;
+}
+
+/*
+ * Generic function which updates the speed and duplex.  If
+ * autonegotiation is enabled, it uses the AND of the link
+ * partner's advertised capabilities and our advertised
+ * capabilities.  If autonegotiation is disabled, we use the
+ * appropriate bits in the control register.
+ *
+ * Stolen from Linux's mii.c and phy_device.c
+ */
+int genphy_parse_link(struct phy_device *phydev)
+{
+	int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+
+	/* We're using autonegotiation */
+	if (phydev->supported & SUPPORTED_Autoneg) {
+		u32 lpa = 0;
+		int gblpa = 0;
+		u32 estatus = 0;
+
+		/* Check for gigabit capability */
+		if (phydev->supported & (SUPPORTED_1000baseT_Full |
+					SUPPORTED_1000baseT_Half)) {
+			/* We want a list of states supported by
+			 * both PHYs in the link
+			 */
+			gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
+			if (gblpa < 0) {
+				debug("Could not read MII_STAT1000. Ignoring gigabit capability\n");
+				gblpa = 0;
+			}
+			gblpa &= phy_read(phydev,
+					MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
+		}
+
+		/* Set the baseline so we only have to set them
+		 * if they're different
+		 */
+		phydev->speed = SPEED_10;
+		phydev->duplex = DUPLEX_HALF;
+
+		/* Check the gigabit fields */
+		if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
+			phydev->speed = SPEED_1000;
+
+			if (gblpa & PHY_1000BTSR_1000FD)
+				phydev->duplex = DUPLEX_FULL;
+
+			/* We're done! */
+			return 0;
+		}
+
+		lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
+		lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
+
+		if (lpa & (LPA_100FULL | LPA_100HALF)) {
+			phydev->speed = SPEED_100;
+
+			if (lpa & LPA_100FULL)
+				phydev->duplex = DUPLEX_FULL;
+
+		} else if (lpa & LPA_10FULL)
+			phydev->duplex = DUPLEX_FULL;
+
+		/*
+		 * Extended status may indicate that the PHY supports
+		 * 1000BASE-T/X even though the 1000BASE-T registers
+		 * are missing. In this case we can't tell whether the
+		 * peer also supports it, so we only check extended
+		 * status if the 1000BASE-T registers are actually
+		 * missing.
+		 */
+		if ((mii_reg & BMSR_ESTATEN) && !(mii_reg & BMSR_ERCAP))
+			estatus = phy_read(phydev, MDIO_DEVAD_NONE,
+					   MII_ESTATUS);
+
+		if (estatus & (ESTATUS_1000_XFULL | ESTATUS_1000_XHALF |
+				ESTATUS_1000_TFULL | ESTATUS_1000_THALF)) {
+			phydev->speed = SPEED_1000;
+			if (estatus & (ESTATUS_1000_XFULL | ESTATUS_1000_TFULL))
+				phydev->duplex = DUPLEX_FULL;
+		}
+
+	} else {
+		u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+
+		phydev->speed = SPEED_10;
+		phydev->duplex = DUPLEX_HALF;
+
+		if (bmcr & BMCR_FULLDPLX)
+			phydev->duplex = DUPLEX_FULL;
+
+		if (bmcr & BMCR_SPEED1000)
+			phydev->speed = SPEED_1000;
+		else if (bmcr & BMCR_SPEED100)
+			phydev->speed = SPEED_100;
+	}
+
+	return 0;
+}
+
+int genphy_config(struct phy_device *phydev)
+{
+	int val;
+	u32 features;
+
+	/* For now, I'll claim that the generic driver supports
+	 * all possible port types */
+	features = (SUPPORTED_TP | SUPPORTED_MII
+			| SUPPORTED_AUI | SUPPORTED_FIBRE |
+			SUPPORTED_BNC);
+
+	/* Do we support autonegotiation? */
+	val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+
+	if (val < 0)
+		return val;
+
+	if (val & BMSR_ANEGCAPABLE)
+		features |= SUPPORTED_Autoneg;
+
+	if (val & BMSR_100FULL)
+		features |= SUPPORTED_100baseT_Full;
+	if (val & BMSR_100HALF)
+		features |= SUPPORTED_100baseT_Half;
+	if (val & BMSR_10FULL)
+		features |= SUPPORTED_10baseT_Full;
+	if (val & BMSR_10HALF)
+		features |= SUPPORTED_10baseT_Half;
+
+	if (val & BMSR_ESTATEN) {
+		val = phy_read(phydev, MDIO_DEVAD_NONE, MII_ESTATUS);
+
+		if (val < 0)
+			return val;
+
+		if (val & ESTATUS_1000_TFULL)
+			features |= SUPPORTED_1000baseT_Full;
+		if (val & ESTATUS_1000_THALF)
+			features |= SUPPORTED_1000baseT_Half;
+		if (val & ESTATUS_1000_XFULL)
+			features |= SUPPORTED_1000baseX_Full;
+		if (val & ESTATUS_1000_XHALF)
+			features |= SUPPORTED_1000baseX_Half;
+	}
+
+	phydev->supported = features;
+	phydev->advertising = features;
+
+	genphy_config_aneg(phydev);
+
+	return 0;
+}
+
+int genphy_startup(struct phy_device *phydev)
+{
+	genphy_update_link(phydev);
+	genphy_parse_link(phydev);
+
+	return 0;
+}
+
+int genphy_shutdown(struct phy_device *phydev)
+{
+	return 0;
+}
+
+static struct phy_driver genphy_driver = {
+	.uid		= 0xffffffff,
+	.mask		= 0xffffffff,
+	.name		= "Generic PHY",
+	.features	= 0,
+	.config		= genphy_config,
+	.startup	= genphy_startup,
+	.shutdown	= genphy_shutdown,
+};
+
+static LIST_HEAD(phy_drivers);
+
+int phy_init(void)
+{
+#ifdef CONFIG_PHY_ATHEROS
+	phy_atheros_init();
+#endif
+#ifdef CONFIG_PHY_BROADCOM
+	phy_broadcom_init();
+#endif
+#ifdef CONFIG_PHY_DAVICOM
+	phy_davicom_init();
+#endif
+#ifdef CONFIG_PHY_ET1011C
+	phy_et1011c_init();
+#endif
+#ifdef CONFIG_PHY_ICPLUS
+	phy_icplus_init();
+#endif
+#ifdef CONFIG_PHY_LXT
+	phy_lxt_init();
+#endif
+#ifdef CONFIG_PHY_MARVELL
+	phy_marvell_init();
+#endif
+#ifdef CONFIG_PHY_MICREL
+	phy_micrel_init();
+#endif
+#ifdef CONFIG_PHY_NATSEMI
+	phy_natsemi_init();
+#endif
+#ifdef CONFIG_PHY_REALTEK
+	phy_realtek_init();
+#endif
+#ifdef CONFIG_PHY_SMSC
+	phy_smsc_init();
+#endif
+#ifdef CONFIG_PHY_TERANETICS
+	phy_teranetics_init();
+#endif
+#ifdef CONFIG_PHY_VITESSE
+	phy_vitesse_init();
+#endif
+
+	return 0;
+}
+
+int phy_register(struct phy_driver *drv)
+{
+	INIT_LIST_HEAD(&drv->list);
+	list_add_tail(&drv->list, &phy_drivers);
+
+	return 0;
+}
+
+static int phy_probe(struct phy_device *phydev)
+{
+	int err = 0;
+
+	phydev->advertising = phydev->supported = phydev->drv->features;
+	phydev->mmds = phydev->drv->mmds;
+
+	if (phydev->drv->probe)
+		err = phydev->drv->probe(phydev);
+
+	return err;
+}
+
+static struct phy_driver *generic_for_interface(phy_interface_t interface)
+{
+#ifdef CONFIG_PHYLIB_10G
+	if (is_10g_interface(interface))
+		return &gen10g_driver;
+#endif
+
+	return &genphy_driver;
+}
+
+static struct phy_driver *get_phy_driver(struct phy_device *phydev,
+				phy_interface_t interface)
+{
+	struct list_head *entry;
+	int phy_id = phydev->phy_id;
+	struct phy_driver *drv = NULL;
+
+	list_for_each(entry, &phy_drivers) {
+		drv = list_entry(entry, struct phy_driver, list);
+		if ((drv->uid & drv->mask) == (phy_id & drv->mask))
+			return drv;
+	}
+
+	/* If we made it here, there's no driver for this PHY */
+	return generic_for_interface(interface);
+}
+
+static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
+					    int phy_id,
+					    phy_interface_t interface)
+{
+	struct phy_device *dev;
+
+	/* We allocate the device, and initialize the
+	 * default values */
+	dev = malloc(sizeof(*dev));
+	if (!dev) {
+		printf("Failed to allocate PHY device for %s:%d\n",
+			bus->name, addr);
+		return NULL;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+
+	dev->duplex = -1;
+	dev->link = 1;
+	dev->interface = interface;
+
+	dev->autoneg = AUTONEG_ENABLE;
+
+	dev->addr = addr;
+	dev->phy_id = phy_id;
+	dev->bus = bus;
+
+	dev->drv = get_phy_driver(dev, interface);
+
+	phy_probe(dev);
+
+	bus->phymap[addr] = dev;
+
+	return dev;
+}
+
+/**
+ * get_phy_id - reads the specified addr for its ID.
+ * @bus: the target MII bus
+ * @addr: PHY address on the MII bus
+ * @phy_id: where to store the ID retrieved.
+ *
+ * Description: Reads the ID registers of the PHY at @addr on the
+ *   @bus, stores it in @phy_id and returns zero on success.
+ */
+static int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
+{
+	int phy_reg;
+
+	/* Grab the bits from PHYIR1, and put them
+	 * in the upper half */
+	phy_reg = bus->read(bus, addr, devad, MII_PHYSID1);
+
+	if (phy_reg < 0)
+		return -EIO;
+
+	*phy_id = (phy_reg & 0xffff) << 16;
+
+	/* Grab the bits from PHYIR2, and put them in the lower half */
+	phy_reg = bus->read(bus, addr, devad, MII_PHYSID2);
+
+	if (phy_reg < 0)
+		return -EIO;
+
+	*phy_id |= (phy_reg & 0xffff);
+
+	return 0;
+}
+
+static struct phy_device *create_phy_by_mask(struct mii_dev *bus,
+		unsigned phy_mask, int devad, phy_interface_t interface)
+{
+	u32 phy_id = 0xffffffff;
+	while (phy_mask) {
+		int addr = ffs(phy_mask) - 1;
+		int r = get_phy_id(bus, addr, devad, &phy_id);
+		if (r < 0)
+			return ERR_PTR(r);
+		/* If the PHY ID is mostly f's, we didn't find anything */
+		if ((phy_id & 0x1fffffff) != 0x1fffffff)
+			return phy_device_create(bus, addr, phy_id, interface);
+		phy_mask &= ~(1 << addr);
+	}
+	return NULL;
+}
+
+static struct phy_device *search_for_existing_phy(struct mii_dev *bus,
+		unsigned phy_mask, phy_interface_t interface)
+{
+	/* If we have one, return the existing device, with new interface */
+	while (phy_mask) {
+		int addr = ffs(phy_mask) - 1;
+		if (bus->phymap[addr]) {
+			bus->phymap[addr]->interface = interface;
+			return bus->phymap[addr];
+		}
+		phy_mask &= ~(1 << addr);
+	}
+	return NULL;
+}
+
+static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
+		unsigned phy_mask, phy_interface_t interface)
+{
+	int i;
+	struct phy_device *phydev;
+
+	phydev = search_for_existing_phy(bus, phy_mask, interface);
+	if (phydev)
+		return phydev;
+	/* Try Standard (ie Clause 22) access */
+	/* Otherwise we have to try Clause 45 */
+	for (i = 0; i < 5; i++) {
+		phydev = create_phy_by_mask(bus, phy_mask,
+				i ? i : MDIO_DEVAD_NONE, interface);
+		if (IS_ERR(phydev))
+			return NULL;
+		if (phydev)
+			return phydev;
+	}
+	printf("Phy not found\n");
+	return phy_device_create(bus, ffs(phy_mask) - 1, 0xffffffff, interface);
+}
+
+/**
+ * get_phy_device - reads the specified PHY device and returns its @phy_device struct
+ * @bus: the target MII bus
+ * @addr: PHY address on the MII bus
+ *
+ * Description: Reads the ID registers of the PHY at @addr on the
+ *   @bus, then allocates and returns the phy_device to represent it.
+ */
+static struct phy_device *get_phy_device(struct mii_dev *bus, int addr,
+					 phy_interface_t interface)
+{
+	return get_phy_device_by_mask(bus, 1 << addr, interface);
+}
+
+int phy_reset(struct phy_device *phydev)
+{
+	int reg;
+	int timeout = 500;
+	int devad = MDIO_DEVAD_NONE;
+
+#ifdef CONFIG_PHYLIB_10G
+	/* If it's 10G, we need to issue reset through one of the MMDs */
+	if (is_10g_interface(phydev->interface)) {
+		if (!phydev->mmds)
+			gen10g_discover_mmds(phydev);
+
+		devad = ffs(phydev->mmds) - 1;
+	}
+#endif
+
+	reg = phy_read(phydev, devad, MII_BMCR);
+	if (reg < 0) {
+		debug("PHY status read failed\n");
+		return -1;
+	}
+
+	reg |= BMCR_RESET;
+
+	if (phy_write(phydev, devad, MII_BMCR, reg) < 0) {
+		debug("PHY reset failed\n");
+		return -1;
+	}
+
+#ifdef CONFIG_PHY_RESET_DELAY
+	udelay(CONFIG_PHY_RESET_DELAY);	/* Intel LXT971A needs this */
+#endif
+	/*
+	 * Poll the control register for the reset bit to go to 0 (it is
+	 * auto-clearing).  This should happen within 0.5 seconds per the
+	 * IEEE spec.
+	 */
+	while ((reg & BMCR_RESET) && timeout--) {
+		reg = phy_read(phydev, devad, MII_BMCR);
+
+		if (reg < 0) {
+			debug("PHY status read failed\n");
+			return -1;
+		}
+		udelay(1000);
+	}
+
+	if (reg & BMCR_RESET) {
+		puts("PHY reset timed out\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+int miiphy_reset(const char *devname, unsigned char addr)
+{
+	struct mii_dev *bus = miiphy_get_dev_by_name(devname);
+	struct phy_device *phydev;
+
+	/*
+	 * miiphy_reset was only used on standard PHYs, so we'll fake it here.
+	 * If later code tries to connect with the right interface, this will
+	 * be corrected by get_phy_device in phy_connect()
+	 */
+	phydev = get_phy_device(bus, addr, PHY_INTERFACE_MODE_MII);
+
+	return phy_reset(phydev);
+}
+
+struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
+		phy_interface_t interface)
+{
+	/* Reset the bus */
+	if (bus->reset)
+		bus->reset(bus);
+
+	/* Wait 15ms to make sure the PHY has come out of hard reset */
+	udelay(15000);
+	return get_phy_device_by_mask(bus, phy_mask, interface);
+}
+
+void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev)
+{
+	/* Soft Reset the PHY */
+	phy_reset(phydev);
+	if (phydev->dev) {
+		printf("%s:%d is connected to %s.  Reconnecting to %s\n",
+				phydev->bus->name, phydev->addr,
+				phydev->dev->name, dev->name);
+	}
+	phydev->dev = dev;
+	debug("%s connected to %s\n", dev->name, phydev->drv->name);
+}
+
+struct phy_device *phy_connect(struct mii_dev *bus, int addr,
+		struct eth_device *dev, phy_interface_t interface)
+{
+	struct phy_device *phydev;
+
+	phydev = phy_find_by_mask(bus, 1 << addr, interface);
+	if (phydev)
+		phy_connect_dev(phydev, dev);
+	else
+		printf("Could not get PHY for %s: addr %d\n", bus->name, addr);
+	return phydev;
+}
+
+/*
+ * Start the PHY.  Returns 0 on success, or a negative error code.
+ */
+int phy_startup(struct phy_device *phydev)
+{
+	if (phydev->drv->startup)
+		return phydev->drv->startup(phydev);
+
+	return 0;
+}
+
+static int __board_phy_config(struct phy_device *phydev)
+{
+	if (phydev->drv->config)
+		return phydev->drv->config(phydev);
+	return 0;
+}
+
+int board_phy_config(struct phy_device *phydev)
+	__attribute__((weak, alias("__board_phy_config")));
+
+int phy_config(struct phy_device *phydev)
+{
+	/* Invoke an optional board-specific helper */
+	board_phy_config(phydev);
+
+	return 0;
+}
+
+int phy_shutdown(struct phy_device *phydev)
+{
+	if (phydev->drv->shutdown)
+		phydev->drv->shutdown(phydev);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/phy/realtek.c b/marvell/uboot/drivers/net/phy/realtek.c
new file mode 100644
index 0000000..a3ace68
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/realtek.c
@@ -0,0 +1,141 @@
+/*
+ * RealTek PHY drivers
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Copyright 2010-2011 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ */
+#include <config.h>
+#include <common.h>
+#include <phy.h>
+
+#define PHY_AUTONEGOTIATE_TIMEOUT 5000
+
+/* RTL8211x PHY Status Register */
+#define MIIM_RTL8211x_PHY_STATUS       0x11
+#define MIIM_RTL8211x_PHYSTAT_SPEED    0xc000
+#define MIIM_RTL8211x_PHYSTAT_GBIT     0x8000
+#define MIIM_RTL8211x_PHYSTAT_100      0x4000
+#define MIIM_RTL8211x_PHYSTAT_DUPLEX   0x2000
+#define MIIM_RTL8211x_PHYSTAT_SPDDONE  0x0800
+#define MIIM_RTL8211x_PHYSTAT_LINK     0x0400
+
+
+/* RealTek RTL8211x */
+static int rtl8211x_config(struct phy_device *phydev)
+{
+	phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
+
+	genphy_config_aneg(phydev);
+
+	return 0;
+}
+
+static int rtl8211x_parse_status(struct phy_device *phydev)
+{
+	unsigned int speed;
+	unsigned int mii_reg;
+
+	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_STATUS);
+
+	if (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) {
+		int i = 0;
+
+		/* in case of timeout ->link is cleared */
+		phydev->link = 1;
+		puts("Waiting for PHY realtime link");
+		while (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) {
+			/* Timeout reached ? */
+			if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
+				puts(" TIMEOUT !\n");
+				phydev->link = 0;
+				break;
+			}
+
+			if ((i++ % 1000) == 0)
+				putc('.');
+			udelay(1000);	/* 1 ms */
+			mii_reg = phy_read(phydev, MDIO_DEVAD_NONE,
+					MIIM_RTL8211x_PHY_STATUS);
+		}
+		puts(" done\n");
+		udelay(500000);	/* another 500 ms (results in faster booting) */
+	} else {
+		if (mii_reg & MIIM_RTL8211x_PHYSTAT_LINK)
+			phydev->link = 1;
+		else
+			phydev->link = 0;
+	}
+
+	if (mii_reg & MIIM_RTL8211x_PHYSTAT_DUPLEX)
+		phydev->duplex = DUPLEX_FULL;
+	else
+		phydev->duplex = DUPLEX_HALF;
+
+	speed = (mii_reg & MIIM_RTL8211x_PHYSTAT_SPEED);
+
+	switch (speed) {
+	case MIIM_RTL8211x_PHYSTAT_GBIT:
+		phydev->speed = SPEED_1000;
+		break;
+	case MIIM_RTL8211x_PHYSTAT_100:
+		phydev->speed = SPEED_100;
+		break;
+	default:
+		phydev->speed = SPEED_10;
+	}
+
+	return 0;
+}
+
+static int rtl8211x_startup(struct phy_device *phydev)
+{
+	/* Read the Status (2x to make sure link is right) */
+	genphy_update_link(phydev);
+	rtl8211x_parse_status(phydev);
+
+	return 0;
+}
+
+/* Support for RTL8211B PHY */
+static struct phy_driver RTL8211B_driver = {
+	.name = "RealTek RTL8211B",
+	.uid = 0x1cc910,
+	.mask = 0xffffff,
+	.features = PHY_GBIT_FEATURES,
+	.config = &rtl8211x_config,
+	.startup = &rtl8211x_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+/* Support for RTL8211E-VB-CG, RTL8211E-VL-CG and RTL8211EG-VB-CG PHYs */
+static struct phy_driver RTL8211E_driver = {
+	.name = "RealTek RTL8211E",
+	.uid = 0x1cc915,
+	.mask = 0xffffff,
+	.features = PHY_GBIT_FEATURES,
+	.config = &rtl8211x_config,
+	.startup = &rtl8211x_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+/* Support for RTL8211DN PHY */
+static struct phy_driver RTL8211DN_driver = {
+	.name = "RealTek RTL8211DN",
+	.uid = 0x1cc914,
+	.mask = 0xffffff,
+	.features = PHY_GBIT_FEATURES,
+	.config = &rtl8211x_config,
+	.startup = &rtl8211x_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+int phy_realtek_init(void)
+{
+	phy_register(&RTL8211B_driver);
+	phy_register(&RTL8211E_driver);
+	phy_register(&RTL8211DN_driver);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/phy/smsc.c b/marvell/uboot/drivers/net/phy/smsc.c
new file mode 100644
index 0000000..bfd9815
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/smsc.c
@@ -0,0 +1,79 @@
+/*
+ * SMSC PHY drivers
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Base code from drivers/net/phy/davicom.c
+ *   Copyright 2010-2011 Freescale Semiconductor, Inc.
+ *   author Andy Fleming
+ *
+ * Some code copied from linux kernel
+ * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org>
+ */
+#include <miiphy.h>
+
+/* This code does not check the partner abilities. */
+static int smsc_parse_status(struct phy_device *phydev)
+{
+	int mii_reg;
+
+	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+
+	if (mii_reg & (BMSR_100FULL | BMSR_100HALF))
+		phydev->speed = SPEED_100;
+	else
+		phydev->speed = SPEED_10;
+
+	if (mii_reg & (BMSR_10FULL | BMSR_100FULL))
+		phydev->duplex = DUPLEX_FULL;
+	else
+		phydev->duplex = DUPLEX_HALF;
+
+	return 0;
+}
+
+static int smsc_startup(struct phy_device *phydev)
+{
+	genphy_update_link(phydev);
+	smsc_parse_status(phydev);
+	return 0;
+}
+
+static struct phy_driver lan8700_driver = {
+	.name = "SMSC LAN8700",
+	.uid = 0x0007c0c0,
+	.mask = 0xffff0,
+	.features = PHY_BASIC_FEATURES,
+	.config = &genphy_config_aneg,
+	.startup = &smsc_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver lan911x_driver = {
+	.name = "SMSC LAN911x Internal PHY",
+	.uid = 0x0007c0d0,
+	.mask = 0xffff0,
+	.features = PHY_BASIC_FEATURES,
+	.config = &genphy_config_aneg,
+	.startup = &smsc_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver lan8710_driver = {
+	.name = "SMSC LAN8710/LAN8720",
+	.uid = 0x0007c0f0,
+	.mask = 0xffff0,
+	.features = PHY_BASIC_FEATURES,
+	.config = &genphy_config_aneg,
+	.startup = &genphy_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+int phy_smsc_init(void)
+{
+	phy_register(&lan8710_driver);
+	phy_register(&lan911x_driver);
+	phy_register(&lan8700_driver);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/phy/teranetics.c b/marvell/uboot/drivers/net/phy/teranetics.c
new file mode 100644
index 0000000..93d5ac3
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/teranetics.c
@@ -0,0 +1,112 @@
+/*
+ * Teranetics PHY drivers
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Copyright 2010-2011 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ */
+#include <config.h>
+#include <common.h>
+#include <phy.h>
+
+#ifndef CONFIG_PHYLIB_10G
+#error The Teranetics PHY needs 10G support
+#endif
+
+int tn2020_config(struct phy_device *phydev)
+{
+	if (phydev->port == PORT_FIBRE) {
+		unsigned short restart_an = (MDIO_AN_CTRL1_RESTART |
+						MDIO_AN_CTRL1_ENABLE |
+						MDIO_AN_CTRL1_XNP);
+		u8 phy_hwversion;
+
+		/*
+		 * bit 15:12 of register 30.32 indicates PHY hardware
+		 * version. It can be used to distinguish TN80xx from
+		 * TN2020. TN2020 needs write 0x2 to 30.93, but TN80xx
+		 * needs 0x1.
+		 */
+		phy_hwversion = (phy_read(phydev, 30, 32) >> 12) & 0xf;
+		if (phy_hwversion <= 3) {
+			phy_write(phydev, 30, 93, 2);
+			phy_write(phydev, MDIO_MMD_AN, MDIO_CTRL1, restart_an);
+		} else {
+			phy_write(phydev, 30, 93, 1);
+		}
+	}
+
+	return 0;
+}
+
+int tn2020_startup(struct phy_device *phydev)
+{
+	unsigned int timeout = 5 * 1000; /* 5 second timeout */
+
+#define MDIO_PHYXS_LANE_READY (MDIO_PHYXS_LNSTAT_SYNC0 | \
+			       MDIO_PHYXS_LNSTAT_SYNC1 | \
+			       MDIO_PHYXS_LNSTAT_SYNC2 | \
+			       MDIO_PHYXS_LNSTAT_SYNC3 | \
+			       MDIO_PHYXS_LNSTAT_ALIGN)
+
+	/*
+	 * Wait for the XAUI-SERDES lanes to align first.  Under normal
+	 * circumstances, this can take up to three seconds.
+	 */
+	while (--timeout) {
+		int reg = phy_read(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_LNSTAT);
+		if (reg < 0) {
+			printf("TN2020: Error reading from PHY at "
+			       "address %u\n", phydev->addr);
+			break;
+		}
+		if ((reg & MDIO_PHYXS_LANE_READY) == MDIO_PHYXS_LANE_READY)
+			break;
+		udelay(1000);
+	}
+	if (!timeout) {
+		/*
+		 * A timeout is bad, but it may not be fatal, so don't
+		 * return an error.  Display a warning instead.
+		 */
+		printf("TN2020: Timeout waiting for PHY at address %u to "
+		       "align.\n", phydev->addr);
+	}
+
+	if (phydev->port != PORT_FIBRE)
+		return gen10g_startup(phydev);
+
+	/*
+	 * The TN2020 only pretends to support fiber.
+	 * It works, but it doesn't look like it works,
+	 * so the link status reports no link.
+	 */
+	phydev->link = 1;
+
+	/* For now just lie and say it's 10G all the time */
+	phydev->speed = SPEED_10000;
+	phydev->duplex = DUPLEX_FULL;
+
+	return 0;
+}
+
+struct phy_driver tn2020_driver = {
+	.name = "Teranetics TN2020",
+	.uid = PHY_UID_TN2020,
+	.mask = 0xfffffff0,
+	.features = PHY_10G_FEATURES,
+	.mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
+			MDIO_DEVS_PHYXS | MDIO_DEVS_AN |
+			MDIO_DEVS_VEND1 | MDIO_DEVS_VEND2),
+	.config = &tn2020_config,
+	.startup = &tn2020_startup,
+	.shutdown = &gen10g_shutdown,
+};
+
+int phy_teranetics_init(void)
+{
+	phy_register(&tn2020_driver);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/phy/vitesse.c b/marvell/uboot/drivers/net/phy/vitesse.c
new file mode 100644
index 0000000..c555979
--- /dev/null
+++ b/marvell/uboot/drivers/net/phy/vitesse.c
@@ -0,0 +1,373 @@
+/*
+ * Vitesse PHY drivers
+ *
+ * Copyright 2010-2012 Freescale Semiconductor, Inc.
+ * Author: Andy Fleming
+ * Add vsc8662 phy support - Priyanka Jain
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <miiphy.h>
+
+/* Cicada Auxiliary Control/Status Register */
+#define MIIM_CIS82xx_AUX_CONSTAT	0x1c
+#define MIIM_CIS82xx_AUXCONSTAT_INIT	0x0004
+#define MIIM_CIS82xx_AUXCONSTAT_DUPLEX	0x0020
+#define MIIM_CIS82xx_AUXCONSTAT_SPEED	0x0018
+#define MIIM_CIS82xx_AUXCONSTAT_GBIT	0x0010
+#define MIIM_CIS82xx_AUXCONSTAT_100	0x0008
+
+/* Cicada Extended Control Register 1 */
+#define MIIM_CIS82xx_EXT_CON1		0x17
+#define MIIM_CIS8201_EXTCON1_INIT	0x0000
+
+/* Cicada 8204 Extended PHY Control Register 1 */
+#define MIIM_CIS8204_EPHY_CON		0x17
+#define MIIM_CIS8204_EPHYCON_INIT	0x0006
+#define MIIM_CIS8204_EPHYCON_RGMII	0x1100
+
+/* Cicada 8204 Serial LED Control Register */
+#define MIIM_CIS8204_SLED_CON		0x1b
+#define MIIM_CIS8204_SLEDCON_INIT	0x1115
+
+/* Vitesse VSC8601 Extended PHY Control Register 1 */
+#define MIIM_VSC8601_EPHY_CON		0x17
+#define MIIM_VSC8601_EPHY_CON_INIT_SKEW	0x1120
+#define MIIM_VSC8601_SKEW_CTRL		0x1c
+
+#define PHY_EXT_PAGE_ACCESS    0x1f
+#define PHY_EXT_PAGE_ACCESS_GENERAL	0x10
+#define PHY_EXT_PAGE_ACCESS_EXTENDED3	0x3
+
+/* Vitesse VSC8574 control register */
+#define MIIM_VSC8574_MAC_SERDES_CON	0x10
+#define MIIM_VSC8574_MAC_SERDES_ANEG	0x80
+#define MIIM_VSC8574_GENERAL18		0x12
+#define MIIM_VSC8574_GENERAL19		0x13
+
+/* Vitesse VSC8574 gerenal purpose register 18 */
+#define MIIM_VSC8574_18G_SGMII		0x80f0
+#define MIIM_VSC8574_18G_QSGMII		0x80e0
+#define MIIM_VSC8574_18G_CMDSTAT	0x8000
+
+/* Vitesse VSC8514 control register */
+#define MIIM_VSC8514_GENERAL18		0x12
+#define MIIM_VSC8514_GENERAL19		0x13
+#define MIIM_VSC8514_GENERAL23		0x17
+
+/* Vitesse VSC8514 gerenal purpose register 18 */
+#define MIIM_VSC8514_18G_QSGMII		0x80e0
+#define MIIM_VSC8514_18G_CMDSTAT	0x8000
+
+/* CIS8201 */
+static int vitesse_config(struct phy_device *phydev)
+{
+	/* Override PHY config settings */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT,
+			MIIM_CIS82xx_AUXCONSTAT_INIT);
+	/* Set up the interface mode */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_EXT_CON1,
+			MIIM_CIS8201_EXTCON1_INIT);
+
+	genphy_config_aneg(phydev);
+
+	return 0;
+}
+
+static int vitesse_parse_status(struct phy_device *phydev)
+{
+	int speed;
+	int mii_reg;
+
+	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT);
+
+	if (mii_reg & MIIM_CIS82xx_AUXCONSTAT_DUPLEX)
+		phydev->duplex = DUPLEX_FULL;
+	else
+		phydev->duplex = DUPLEX_HALF;
+
+	speed = mii_reg & MIIM_CIS82xx_AUXCONSTAT_SPEED;
+	switch (speed) {
+	case MIIM_CIS82xx_AUXCONSTAT_GBIT:
+		phydev->speed = SPEED_1000;
+		break;
+	case MIIM_CIS82xx_AUXCONSTAT_100:
+		phydev->speed = SPEED_100;
+		break;
+	default:
+		phydev->speed = SPEED_10;
+		break;
+	}
+
+	return 0;
+}
+
+static int vitesse_startup(struct phy_device *phydev)
+{
+	genphy_update_link(phydev);
+	vitesse_parse_status(phydev);
+
+	return 0;
+}
+
+static int cis8204_config(struct phy_device *phydev)
+{
+	/* Override PHY config settings */
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT,
+			MIIM_CIS82xx_AUXCONSTAT_INIT);
+
+	genphy_config_aneg(phydev);
+
+	if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
+			(phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
+			(phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
+			(phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID))
+		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS8204_EPHY_CON,
+				MIIM_CIS8204_EPHYCON_INIT |
+				MIIM_CIS8204_EPHYCON_RGMII);
+	else
+		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS8204_EPHY_CON,
+				MIIM_CIS8204_EPHYCON_INIT);
+
+	return 0;
+}
+
+/* Vitesse VSC8601 */
+static int vsc8601_config(struct phy_device *phydev)
+{
+	/* Configure some basic stuff */
+#ifdef CONFIG_SYS_VSC8601_SKEWFIX
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8601_EPHY_CON,
+			MIIM_VSC8601_EPHY_CON_INIT_SKEW);
+#if defined(CONFIG_SYS_VSC8601_SKEW_TX) && defined(CONFIG_SYS_VSC8601_SKEW_RX)
+	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 1);
+#define VSC8101_SKEW \
+	((CONFIG_SYS_VSC8601_SKEW_TX << 14) \
+	| (CONFIG_SYS_VSC8601_SKEW_RX << 12))
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8601_SKEW_CTRL,
+			VSC8101_SKEW);
+	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
+#endif
+#endif
+
+	genphy_config_aneg(phydev);
+
+	return 0;
+}
+
+static int vsc8574_config(struct phy_device *phydev)
+{
+	u32 val;
+	/* configure register 19G for MAC */
+	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
+		  PHY_EXT_PAGE_ACCESS_GENERAL);
+
+	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL19);
+	if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
+		/* set bit 15:14 to '01' for QSGMII mode */
+		val = (val & 0x3fff) | (1 << 14);
+		phy_write(phydev, MDIO_DEVAD_NONE,
+			  MIIM_VSC8574_GENERAL19, val);
+		/* Enable 4 ports MAC QSGMII */
+		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18,
+			  MIIM_VSC8574_18G_QSGMII);
+	} else {
+		/* set bit 15:14 to '00' for SGMII mode */
+		val = val & 0x3fff;
+		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL19, val);
+		/* Enable 4 ports MAC SGMII */
+		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18,
+			  MIIM_VSC8574_18G_SGMII);
+	}
+	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18);
+	/* When bit 15 is cleared the command has completed */
+	while (val & MIIM_VSC8574_18G_CMDSTAT)
+		val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18);
+
+	/* Enable Serdes Auto-negotiation */
+	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
+		  PHY_EXT_PAGE_ACCESS_EXTENDED3);
+	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_MAC_SERDES_CON);
+	val = val | MIIM_VSC8574_MAC_SERDES_ANEG;
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_MAC_SERDES_CON, val);
+
+	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
+
+	genphy_config_aneg(phydev);
+
+	return 0;
+}
+
+static int vsc8514_config(struct phy_device *phydev)
+{
+	u32 val;
+	int timeout = 1000000;
+
+	/* configure register to access 19G */
+	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
+		  PHY_EXT_PAGE_ACCESS_GENERAL);
+
+	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL19);
+	if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
+		/* set bit 15:14 to '01' for QSGMII mode */
+		val = (val & 0x3fff) | (1 << 14);
+		phy_write(phydev, MDIO_DEVAD_NONE,
+			  MIIM_VSC8514_GENERAL19, val);
+		/* Enable 4 ports MAC QSGMII */
+		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18,
+			  MIIM_VSC8514_18G_QSGMII);
+	} else {
+		/*TODO Add SGMII functionality once spec sheet
+		 * for VSC8514 defines complete functionality
+		 */
+	}
+
+	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18);
+	/* When bit 15 is cleared the command has completed */
+	while ((val & MIIM_VSC8514_18G_CMDSTAT) && timeout--)
+		val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18);
+
+	if (0 == timeout) {
+		printf("PHY 8514 config failed\n");
+		return -1;
+	}
+
+	phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
+
+	/* configure register to access 23 */
+	val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL23);
+	/* set bits 10:8 to '000' */
+	val = (val & 0xf8ff);
+	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL23, val);
+
+	genphy_config_aneg(phydev);
+
+	return 0;
+}
+
+static struct phy_driver VSC8211_driver = {
+	.name	= "Vitesse VSC8211",
+	.uid	= 0xfc4b0,
+	.mask	= 0xffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &vitesse_config,
+	.startup = &vitesse_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver VSC8221_driver = {
+	.name = "Vitesse VSC8221",
+	.uid = 0xfc550,
+	.mask = 0xffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &genphy_config_aneg,
+	.startup = &vitesse_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver VSC8244_driver = {
+	.name = "Vitesse VSC8244",
+	.uid = 0xfc6c0,
+	.mask = 0xffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &genphy_config_aneg,
+	.startup = &vitesse_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver VSC8234_driver = {
+	.name = "Vitesse VSC8234",
+	.uid = 0xfc620,
+	.mask = 0xffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &genphy_config_aneg,
+	.startup = &vitesse_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver VSC8574_driver = {
+	.name = "Vitesse VSC8574",
+	.uid = 0x704a0,
+	.mask = 0xffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &vsc8574_config,
+	.startup = &vitesse_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver VSC8514_driver = {
+	.name = "Vitesse VSC8514",
+	.uid = 0x70570,
+	.mask = 0xffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &vsc8514_config,
+	.startup = &vitesse_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver VSC8601_driver = {
+	.name = "Vitesse VSC8601",
+	.uid = 0x70420,
+	.mask = 0xffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &vsc8601_config,
+	.startup = &vitesse_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver VSC8641_driver = {
+	.name = "Vitesse VSC8641",
+	.uid = 0x70430,
+	.mask = 0xffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &genphy_config_aneg,
+	.startup = &vitesse_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver VSC8662_driver = {
+	.name = "Vitesse VSC8662",
+	.uid = 0x70660,
+	.mask = 0xffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &genphy_config_aneg,
+	.startup = &vitesse_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+/* Vitesse bought Cicada, so we'll put these here */
+static struct phy_driver cis8201_driver = {
+	.name = "CIS8201",
+	.uid = 0xfc410,
+	.mask = 0xffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &vitesse_config,
+	.startup = &vitesse_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+static struct phy_driver cis8204_driver = {
+	.name = "Cicada Cis8204",
+	.uid = 0xfc440,
+	.mask = 0xffff0,
+	.features = PHY_GBIT_FEATURES,
+	.config = &cis8204_config,
+	.startup = &vitesse_startup,
+	.shutdown = &genphy_shutdown,
+};
+
+int phy_vitesse_init(void)
+{
+	phy_register(&VSC8641_driver);
+	phy_register(&VSC8601_driver);
+	phy_register(&VSC8234_driver);
+	phy_register(&VSC8244_driver);
+	phy_register(&VSC8211_driver);
+	phy_register(&VSC8221_driver);
+	phy_register(&VSC8574_driver);
+	phy_register(&VSC8514_driver);
+	phy_register(&VSC8662_driver);
+	phy_register(&cis8201_driver);
+	phy_register(&cis8204_driver);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/plb2800_eth.c b/marvell/uboot/drivers/net/plb2800_eth.c
new file mode 100644
index 0000000..f869514
--- /dev/null
+++ b/marvell/uboot/drivers/net/plb2800_eth.c
@@ -0,0 +1,373 @@
+/*
+ * PLB2800 internal switch ethernet driver.
+ *
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/addrspace.h>
+
+
+#define NUM_RX_DESC	PKTBUFSRX
+#define TOUT_LOOP	1000000
+
+#define LONG_REF(addr) (*((volatile unsigned long*)addr))
+
+#define CMAC_CRX_CTRL	LONG_REF(0xb800c870)
+#define CMAC_CTX_CTRL	LONG_REF(0xb800c874)
+#define SYS_MAC_ADDR_0	LONG_REF(0xb800c878)
+#define SYS_MAC_ADDR_1	LONG_REF(0xb800c87c)
+#define MIPS_H_MASK	LONG_REF(0xB800C810)
+
+#define MA_LEARN	LONG_REF(0xb8008004)
+#define DA_LOOKUP	LONG_REF(0xb8008008)
+
+#define CMAC_CRX_CTRL_PD	0x00000001
+#define CMAC_CRX_CTRL_CG	0x00000002
+#define CMAC_CRX_CTRL_PL_SHIFT	2
+#define CMAC_CRIT		0x0
+#define CMAC_NON_CRIT		0x1
+#define MBOX_STAT_ID_SHF	28
+#define MBOX_STAT_CP		0x80000000
+#define MBOX_STAT_MB		0x00000001
+#define EN_MA_LEARN		0x02000000
+#define EN_DA_LKUP		0x01000000
+#define MA_DEST_SHF		11
+#define DA_DEST_SHF		11
+#define DA_STATE_SHF		19
+#define TSTAMP_MS		0x00000000
+#define SW_H_MBOX4_MASK		0x08000000
+#define SW_H_MBOX3_MASK		0x04000000
+#define SW_H_MBOX2_MASK		0x02000000
+#define SW_H_MBOX1_MASK		0x01000000
+
+typedef volatile struct {
+  unsigned int stat;
+  unsigned int cmd;
+  unsigned int cnt;
+  unsigned int adr;
+} mailbox_t;
+
+#define MBOX_REG(mb) ((mailbox_t*)(0xb800c830+(mb<<4)))
+
+typedef volatile struct {
+  unsigned int word0;
+  unsigned int word1;
+  unsigned int word2;
+} mbhdr_t;
+
+#define MBOX_MEM(mb) ((void*)(0xb800a000+((3-mb)<<11)))
+
+
+static int plb2800_eth_init(struct eth_device *dev, bd_t * bis);
+static int plb2800_eth_send(struct eth_device *dev, void *packet, int length);
+static int plb2800_eth_recv(struct eth_device *dev);
+static void plb2800_eth_halt(struct eth_device *dev);
+
+static void plb2800_set_mac_addr(struct eth_device *dev, unsigned char * addr);
+static unsigned char * plb2800_get_mac_addr(void);
+
+static int rx_new;
+static int mac_addr_set = 0;
+
+
+int plb2800_eth_initialize(bd_t * bis)
+{
+	struct eth_device *dev;
+	ulong temp;
+
+#ifdef DEBUG
+	printf("Entered plb2800_eth_initialize()\n");
+#endif
+
+	if (!(dev = (struct eth_device *) malloc (sizeof *dev)))
+	{
+		printf("Failed to allocate memory\n");
+		return -1;
+	}
+	memset(dev, 0, sizeof(*dev));
+
+	sprintf(dev->name, "PLB2800 Switch");
+	dev->init = plb2800_eth_init;
+	dev->halt = plb2800_eth_halt;
+	dev->send = plb2800_eth_send;
+	dev->recv = plb2800_eth_recv;
+
+	eth_register(dev);
+
+	/* bug fix */
+	*(ulong *)0xb800e800 = 0x838;
+
+	/* Set MBOX ownership */
+	temp = CMAC_CRIT << MBOX_STAT_ID_SHF;
+	MBOX_REG(0)->stat = temp;
+	MBOX_REG(1)->stat = temp;
+
+	temp = CMAC_NON_CRIT << MBOX_STAT_ID_SHF;
+	MBOX_REG(2)->stat = temp;
+	MBOX_REG(3)->stat = temp;
+
+	plb2800_set_mac_addr(dev, plb2800_get_mac_addr());
+
+	/* Disable all Mbox interrupt */
+	temp = MIPS_H_MASK;
+	temp &= ~ (SW_H_MBOX1_MASK | SW_H_MBOX2_MASK | SW_H_MBOX3_MASK | SW_H_MBOX4_MASK) ;
+	MIPS_H_MASK = temp;
+
+#ifdef DEBUG
+	printf("Leaving plb2800_eth_initialize()\n");
+#endif
+
+	return 0;
+}
+
+static int plb2800_eth_init(struct eth_device *dev, bd_t * bis)
+{
+#ifdef DEBUG
+	printf("Entering plb2800_eth_init()\n");
+#endif
+
+	plb2800_set_mac_addr(dev, dev->enetaddr);
+
+	rx_new = 0;
+
+#ifdef DEBUG
+	printf("Leaving plb2800_eth_init()\n");
+#endif
+
+	return 0;
+}
+
+
+static int plb2800_eth_send(struct eth_device *dev, void *packet, int length)
+{
+	int                    i;
+	int                    res         = -1;
+	u32                    temp;
+	mailbox_t *            mb          = MBOX_REG(0);
+	char      *            mem         = MBOX_MEM(0);
+
+#ifdef DEBUG
+	printf("Entered plb2800_eth_send()\n");
+#endif
+
+	if (length <= 0)
+	{
+		printf ("%s: bad packet size: %d\n", dev->name, length);
+		goto Done;
+	}
+
+	if (length < 64)
+	{
+		length = 64;
+	}
+
+	temp = CMAC_CRX_CTRL_CG | ((length + 4) << CMAC_CRX_CTRL_PL_SHIFT);
+
+#ifdef DEBUG
+	printf("0 mb->stat = 0x%x\n",  mb->stat);
+#endif
+
+	for(i = 0; mb->stat & (MBOX_STAT_CP | MBOX_STAT_MB); i++)
+	{
+		if (i >= TOUT_LOOP)
+		{
+			printf("%s: tx buffer not ready\n", dev->name);
+			printf("1 mb->stat = 0x%x\n",  mb->stat);
+			goto Done;
+		}
+	}
+
+		/* For some strange reason, memcpy doesn't work, here!
+		 */
+	do
+	{
+		int words = (length >> 2) + 1;
+		unsigned int* dst = (unsigned int*)(mem);
+		unsigned int* src = (unsigned int*)(packet);
+		for (i = 0; i < words; i++)
+		{
+			*dst = *src;
+			dst++;
+			src++;
+		};
+	} while(0);
+
+	CMAC_CRX_CTRL = temp;
+	mb->cmd = MBOX_STAT_CP;
+
+#ifdef DEBUG
+	printf("2 mb->stat = 0x%x\n",  mb->stat);
+#endif
+
+	res = length;
+Done:
+
+#ifdef DEBUG
+	printf("Leaving plb2800_eth_send()\n");
+#endif
+
+	return res;
+}
+
+
+static int plb2800_eth_recv(struct eth_device *dev)
+{
+	int                    length  = 0;
+	mailbox_t            * mbox    = MBOX_REG(3);
+	unsigned char        * hdr     = MBOX_MEM(3);
+	unsigned int           stat;
+
+#ifdef DEBUG
+	printf("Entered plb2800_eth_recv()\n");
+#endif
+
+	for (;;)
+	{
+		stat = mbox->stat;
+
+		if (!(stat & MBOX_STAT_CP))
+		{
+			break;
+		}
+
+		length = ((*(hdr + 6) & 0x3f) << 8) + *(hdr + 7);
+		memcpy((void *)NetRxPackets[rx_new], hdr + 12, length);
+
+		stat &= ~MBOX_STAT_CP;
+		mbox->stat = stat;
+#ifdef DEBUG
+		{
+			int i;
+			for (i=0;i<length - 4;i++)
+			{
+				if (i % 16 == 0) printf("\n%04x: ", i);
+				printf("%02X ", NetRxPackets[rx_new][i]);
+			}
+			printf("\n");
+		}
+#endif
+
+		if (length)
+		{
+#ifdef DEBUG
+			printf("Received %d bytes\n", length);
+#endif
+			NetReceive((void*)(NetRxPackets[rx_new]),
+				    length - 4);
+		}
+		else
+		{
+#if 1
+			printf("Zero length!!!\n");
+#endif
+		}
+
+		rx_new = (rx_new + 1) % NUM_RX_DESC;
+	}
+
+#ifdef DEBUG
+	printf("Leaving plb2800_eth_recv()\n");
+#endif
+
+	return length;
+}
+
+
+static void plb2800_eth_halt(struct eth_device *dev)
+{
+#ifdef DEBUG
+	printf("Entered plb2800_eth_halt()\n");
+#endif
+
+#ifdef DEBUG
+	printf("Leaving plb2800_eth_halt()\n");
+#endif
+}
+
+static void plb2800_set_mac_addr(struct eth_device *dev, unsigned char * addr)
+{
+	char packet[60];
+	ulong temp;
+	int ix;
+
+	if (mac_addr_set ||
+	    NULL == addr || memcmp(addr, "\0\0\0\0\0\0", 6) == 0)
+	{
+		return;
+	}
+
+	/* send one packet through CPU port
+	 * in order to learn system MAC address
+	 */
+
+	/* Set DA_LOOKUP register */
+	temp = EN_MA_LEARN | (0 << DA_STATE_SHF) | (63 << DA_DEST_SHF);
+	DA_LOOKUP = temp;
+
+	/* Set MA_LEARN register */
+	temp = 50 << MA_DEST_SHF;	/* static entry */
+	MA_LEARN = temp;
+
+	/* set destination address */
+	for (ix=0;ix<6;ix++)
+		packet[ix] = 0xff;
+
+	/* set source address = system MAC address */
+	for (ix=0;ix<6;ix++)
+		packet[6+ix] = addr[ix];
+
+	/* set type field */
+	packet[12]=0xaa;
+	packet[13]=0x55;
+
+	/* set data field */
+	for(ix=14;ix<60;ix++)
+		packet[ix] = 0x00;
+
+#ifdef DEBUG
+	for (ix=0;ix<6;ix++)
+		printf("mac_addr[%d]=%02X\n", ix, (unsigned char)packet[6+ix]);
+#endif
+
+	/* set one packet */
+	plb2800_eth_send(dev, packet, sizeof(packet));
+
+	/* delay for a while */
+	for(ix=0;ix<65535;ix++)
+		temp = ~temp;
+
+	/* Set CMAC_CTX_CTRL register */
+	temp = TSTAMP_MS;	/* no autocast */
+	CMAC_CTX_CTRL = temp;
+
+	/* Set DA_LOOKUP register */
+	temp = EN_DA_LKUP;
+	DA_LOOKUP = temp;
+
+	mac_addr_set = 1;
+}
+
+static unsigned char * plb2800_get_mac_addr(void)
+{
+	static unsigned char addr[6];
+	char *tmp, *end;
+	int i;
+
+	tmp = getenv ("ethaddr");
+	if (NULL == tmp) return NULL;
+
+	for (i=0; i<6; i++) {
+		addr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
+		if (tmp)
+			tmp = (*end) ? end+1 : end;
+	}
+
+	return addr;
+}
diff --git a/marvell/uboot/drivers/net/rtl8139.c b/marvell/uboot/drivers/net/rtl8139.c
new file mode 100644
index 0000000..208ce5c
--- /dev/null
+++ b/marvell/uboot/drivers/net/rtl8139.c
@@ -0,0 +1,539 @@
+/*
+ * rtl8139.c : U-Boot driver for the RealTek RTL8139
+ *
+ * Masami Komiya (mkomiya@sonare.it)
+ *
+ * Most part is taken from rtl8139.c of etherboot
+ *
+ */
+
+/* rtl8139.c - etherboot driver for the Realtek 8139 chipset
+
+  ported from the linux driver written by Donald Becker
+  by Rainer Bawidamann (Rainer.Bawidamann@informatik.uni-ulm.de) 1999
+
+  This software may be used and distributed according to the terms
+  of the GNU Public License, incorporated herein by reference.
+
+  changes to the original driver:
+  - removed support for interrupts, switching to polling mode (yuck!)
+  - removed support for the 8129 chip (external MII)
+
+*/
+
+/*********************************************************************/
+/* Revision History						     */
+/*********************************************************************/
+
+/*
+  28 Dec 2002	ken_yap@users.sourceforge.net (Ken Yap)
+     Put in virt_to_bus calls to allow Etherboot relocation.
+
+  06 Apr 2001	ken_yap@users.sourceforge.net (Ken Yap)
+     Following email from Hyun-Joon Cha, added a disable routine, otherwise
+     NIC remains live and can crash the kernel later.
+
+  4 Feb 2000	espenlaub@informatik.uni-ulm.de (Klaus Espenlaub)
+     Shuffled things around, removed the leftovers from the 8129 support
+     that was in the Linux driver and added a bit more 8139 definitions.
+     Moved the 8K receive buffer to a fixed, available address outside the
+     0x98000-0x9ffff range.  This is a bit of a hack, but currently the only
+     way to make room for the Etherboot features that need substantial amounts
+     of code like the ANSI console support.  Currently the buffer is just below
+     0x10000, so this even conforms to the tagged boot image specification,
+     which reserves the ranges 0x00000-0x10000 and 0x98000-0xA0000.  My
+     interpretation of this "reserved" is that Etherboot may do whatever it
+     likes, as long as its environment is kept intact (like the BIOS
+     variables).  Hopefully fixed rtl_poll() once and for all.	The symptoms
+     were that if Etherboot was left at the boot menu for several minutes, the
+     first eth_poll failed.  Seems like I am the only person who does this.
+     First of all I fixed the debugging code and then set out for a long bug
+     hunting session.  It took me about a week full time work - poking around
+     various places in the driver, reading Don Becker's and Jeff Garzik's Linux
+     driver and even the FreeBSD driver (what a piece of crap!) - and
+     eventually spotted the nasty thing: the transmit routine was acknowledging
+     each and every interrupt pending, including the RxOverrun and RxFIFIOver
+     interrupts.  This confused the RTL8139 thoroughly.	 It destroyed the
+     Rx ring contents by dumping the 2K FIFO contents right where we wanted to
+     get the next packet.  Oh well, what fun.
+
+  18 Jan 2000	mdc@thinguin.org (Marty Connor)
+     Drastically simplified error handling.  Basically, if any error
+     in transmission or reception occurs, the card is reset.
+     Also, pointed all transmit descriptors to the same buffer to
+     save buffer space.	 This should decrease driver size and avoid
+     corruption because of exceeding 32K during runtime.
+
+  28 Jul 1999	(Matthias Meixner - meixner@rbg.informatik.tu-darmstadt.de)
+     rtl_poll was quite broken: it used the RxOK interrupt flag instead
+     of the RxBufferEmpty flag which often resulted in very bad
+     transmission performace - below 1kBytes/s.
+
+*/
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#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. */
+#define RX_FIFO_THRESH	4	/* Rx buffer level before first PCI xfer.  */
+#define RX_DMA_BURST	4	/* Maximum PCI burst, '4' is 256 bytes */
+#define TX_DMA_BURST	4	/* Calculate as 16<<val. */
+#define NUM_TX_DESC	4	/* Number of Tx descriptor registers. */
+#define TX_BUF_SIZE	ETH_FRAME_LEN	/* FCS is added by the chip */
+#define RX_BUF_LEN_IDX 0	/* 0, 1, 2 is allowed - 8,16,32K rx buffer */
+#define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
+
+#define DEBUG_TX	0	/* set to 1 to enable debug code */
+#define DEBUG_RX	0	/* set to 1 to enable debug code */
+
+#define bus_to_phys(a)	pci_mem_to_phys((pci_dev_t)dev->priv, a)
+#define phys_to_bus(a)	pci_phys_to_mem((pci_dev_t)dev->priv, a)
+
+/* Symbolic offsets to registers. */
+enum RTL8139_registers {
+	MAC0=0,			/* Ethernet hardware address. */
+	MAR0=8,			/* Multicast filter. */
+	TxStatus0=0x10,		/* Transmit status (four 32bit registers). */
+	TxAddr0=0x20,		/* Tx descriptors (also four 32bit). */
+	RxBuf=0x30, RxEarlyCnt=0x34, RxEarlyStatus=0x36,
+	ChipCmd=0x37, RxBufPtr=0x38, RxBufAddr=0x3A,
+	IntrMask=0x3C, IntrStatus=0x3E,
+	TxConfig=0x40, RxConfig=0x44,
+	Timer=0x48,		/* general-purpose counter. */
+	RxMissed=0x4C,		/* 24 bits valid, write clears. */
+	Cfg9346=0x50, Config0=0x51, Config1=0x52,
+	TimerIntrReg=0x54,	/* intr if gp counter reaches this value */
+	MediaStatus=0x58,
+	Config3=0x59,
+	MultiIntr=0x5C,
+	RevisionID=0x5E,	/* revision of the RTL8139 chip */
+	TxSummary=0x60,
+	MII_BMCR=0x62, MII_BMSR=0x64, NWayAdvert=0x66, NWayLPAR=0x68,
+	NWayExpansion=0x6A,
+	DisconnectCnt=0x6C, FalseCarrierCnt=0x6E,
+	NWayTestReg=0x70,
+	RxCnt=0x72,		/* packet received counter */
+	CSCR=0x74,		/* chip status and configuration register */
+	PhyParm1=0x78,TwisterParm=0x7c,PhyParm2=0x80,	/* undocumented */
+	/* from 0x84 onwards are a number of power management/wakeup frame
+	 * definitions we will probably never need to know about.  */
+};
+
+enum ChipCmdBits {
+	CmdReset=0x10, CmdRxEnb=0x08, CmdTxEnb=0x04, RxBufEmpty=0x01, };
+
+/* Interrupt register bits, using my own meaningful names. */
+enum IntrStatusBits {
+	PCIErr=0x8000, PCSTimeout=0x4000, CableLenChange= 0x2000,
+	RxFIFOOver=0x40, RxUnderrun=0x20, RxOverflow=0x10,
+	TxErr=0x08, TxOK=0x04, RxErr=0x02, RxOK=0x01,
+};
+enum TxStatusBits {
+	TxHostOwns=0x2000, TxUnderrun=0x4000, TxStatOK=0x8000,
+	TxOutOfWindow=0x20000000, TxAborted=0x40000000,
+	TxCarrierLost=0x80000000,
+};
+enum RxStatusBits {
+	RxMulticast=0x8000, RxPhysical=0x4000, RxBroadcast=0x2000,
+	RxBadSymbol=0x0020, RxRunt=0x0010, RxTooLong=0x0008, RxCRCErr=0x0004,
+	RxBadAlign=0x0002, RxStatusOK=0x0001,
+};
+
+enum MediaStatusBits {
+	MSRTxFlowEnable=0x80, MSRRxFlowEnable=0x40, MSRSpeed10=0x08,
+	MSRLinkFail=0x04, MSRRxPauseFlag=0x02, MSRTxPauseFlag=0x01,
+};
+
+enum MIIBMCRBits {
+	BMCRReset=0x8000, BMCRSpeed100=0x2000, BMCRNWayEnable=0x1000,
+	BMCRRestartNWay=0x0200, BMCRDuplex=0x0100,
+};
+
+enum CSCRBits {
+	CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800,
+	CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0,
+	CSCR_LinkDownCmd=0x0f3c0,
+};
+
+/* Bits in RxConfig. */
+enum rx_mode_bits {
+	RxCfgWrap=0x80,
+	AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0x08,
+	AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
+};
+
+static int ioaddr;
+static unsigned int cur_rx,cur_tx;
+
+/* The RTL8139 can only transmit from a contiguous, aligned memory block.  */
+static unsigned char tx_buffer[TX_BUF_SIZE] __attribute__((aligned(4)));
+static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4)));
+
+static int rtl8139_probe(struct eth_device *dev, bd_t *bis);
+static int read_eeprom(int location, int addr_len);
+static void rtl_reset(struct eth_device *dev);
+static int rtl_transmit(struct eth_device *dev, void *packet, int length);
+static int rtl_poll(struct eth_device *dev);
+static void rtl_disable(struct eth_device *dev);
+#ifdef CONFIG_MCAST_TFTP/*  This driver already accepts all b/mcast */
+static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, u8 set)
+{
+	return (0);
+}
+#endif
+
+static struct pci_device_id supported[] = {
+       {PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139},
+       {PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139},
+       {}
+};
+
+int rtl8139_initialize(bd_t *bis)
+{
+	pci_dev_t devno;
+	int card_number = 0;
+	struct eth_device *dev;
+	u32 iobase;
+	int idx=0;
+
+	while(1){
+		/* Find RTL8139 */
+		if ((devno = pci_find_devices(supported, idx++)) < 0)
+			break;
+
+		pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
+		iobase &= ~0xf;
+
+		debug ("rtl8139: REALTEK RTL8139 @0x%x\n", iobase);
+
+		dev = (struct eth_device *)malloc(sizeof *dev);
+		if (!dev) {
+			printf("Can not allocate memory of rtl8139\n");
+			break;
+		}
+		memset(dev, 0, sizeof(*dev));
+
+		sprintf (dev->name, "RTL8139#%d", card_number);
+
+		dev->priv = (void *) devno;
+		dev->iobase = (int)bus_to_phys(iobase);
+		dev->init = rtl8139_probe;
+		dev->halt = rtl_disable;
+		dev->send = rtl_transmit;
+		dev->recv = rtl_poll;
+#ifdef CONFIG_MCAST_TFTP
+		dev->mcast = rtl_bcast_addr;
+#endif
+
+		eth_register (dev);
+
+		card_number++;
+
+		pci_write_config_byte (devno, PCI_LATENCY_TIMER, 0x20);
+
+		udelay (10 * 1000);
+	}
+
+	return card_number;
+}
+
+static int rtl8139_probe(struct eth_device *dev, bd_t *bis)
+{
+	int i;
+	int addr_len;
+	unsigned short *ap = (unsigned short *)dev->enetaddr;
+
+	ioaddr = dev->iobase;
+
+	/* Bring the chip out of low-power mode. */
+	outb(0x00, ioaddr + Config1);
+
+	addr_len = read_eeprom(0,8) == 0x8129 ? 8 : 6;
+	for (i = 0; i < 3; i++)
+		*ap++ = le16_to_cpu (read_eeprom(i + 7, addr_len));
+
+	rtl_reset(dev);
+
+	if (inb(ioaddr + MediaStatus) & MSRLinkFail) {
+		printf("Cable not connected or other link failure\n");
+		return -1 ;
+	}
+
+	return 0;
+}
+
+/* Serial EEPROM section. */
+
+/*  EEPROM_Ctrl bits. */
+#define EE_SHIFT_CLK	0x04	/* EEPROM shift clock. */
+#define EE_CS		0x08	/* EEPROM chip select. */
+#define EE_DATA_WRITE	0x02	/* EEPROM chip data in. */
+#define EE_WRITE_0	0x00
+#define EE_WRITE_1	0x02
+#define EE_DATA_READ	0x01	/* EEPROM chip data out. */
+#define EE_ENB		(0x80 | EE_CS)
+
+/*
+	Delay between EEPROM clock transitions.
+	No extra delay is needed with 33MHz PCI, but 66MHz may change this.
+*/
+
+#define eeprom_delay()	inl(ee_addr)
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define EE_WRITE_CMD	(5)
+#define EE_READ_CMD	(6)
+#define EE_ERASE_CMD	(7)
+
+static int read_eeprom(int location, int addr_len)
+{
+	int i;
+	unsigned int retval = 0;
+	long ee_addr = ioaddr + Cfg9346;
+	int read_cmd = location | (EE_READ_CMD << addr_len);
+
+	outb(EE_ENB & ~EE_CS, ee_addr);
+	outb(EE_ENB, ee_addr);
+	eeprom_delay();
+
+	/* Shift the read command bits out. */
+	for (i = 4 + addr_len; i >= 0; i--) {
+		int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+		outb(EE_ENB | dataval, ee_addr);
+		eeprom_delay();
+		outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay();
+	}
+	outb(EE_ENB, ee_addr);
+	eeprom_delay();
+
+	for (i = 16; i > 0; i--) {
+		outb(EE_ENB | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay();
+		retval = (retval << 1) | ((inb(ee_addr) & EE_DATA_READ) ? 1 : 0);
+		outb(EE_ENB, ee_addr);
+		eeprom_delay();
+	}
+
+	/* Terminate the EEPROM access. */
+	outb(~EE_CS, ee_addr);
+	eeprom_delay();
+	return retval;
+}
+
+static const unsigned int rtl8139_rx_config =
+	(RX_BUF_LEN_IDX << 11) |
+	(RX_FIFO_THRESH << 13) |
+	(RX_DMA_BURST << 8);
+
+static void set_rx_mode(struct eth_device *dev) {
+	unsigned int mc_filter[2];
+	int rx_mode;
+	/* !IFF_PROMISC */
+	rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+	mc_filter[1] = mc_filter[0] = 0xffffffff;
+
+	outl(rtl8139_rx_config | rx_mode, ioaddr + RxConfig);
+
+	outl(mc_filter[0], ioaddr + MAR0 + 0);
+	outl(mc_filter[1], ioaddr + MAR0 + 4);
+}
+
+static void rtl_reset(struct eth_device *dev)
+{
+	int i;
+
+	outb(CmdReset, ioaddr + ChipCmd);
+
+	cur_rx = 0;
+	cur_tx = 0;
+
+	/* Give the chip 10ms to finish the reset. */
+	for (i=0; i<100; ++i){
+		if ((inb(ioaddr + ChipCmd) & CmdReset) == 0) break;
+		udelay (100); /* wait 100us */
+	}
+
+
+	for (i = 0; i < ETH_ALEN; i++)
+		outb(dev->enetaddr[i], ioaddr + MAC0 + i);
+
+	/* Must enable Tx/Rx before setting transfer thresholds! */
+	outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
+	outl((RX_FIFO_THRESH<<13) | (RX_BUF_LEN_IDX<<11) | (RX_DMA_BURST<<8),
+		ioaddr + RxConfig);		/* accept no frames yet!  */
+	outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + TxConfig);
+
+	/* The Linux driver changes Config1 here to use a different LED pattern
+	 * for half duplex or full/autodetect duplex (for full/autodetect, the
+	 * outputs are TX/RX, Link10/100, FULL, while for half duplex it uses
+	 * TX/RX, Link100, Link10).  This is messy, because it doesn't match
+	 * the inscription on the mounting bracket.  It should not be changed
+	 * from the configuration EEPROM default, because the card manufacturer
+	 * should have set that to match the card.  */
+
+	debug_cond(DEBUG_RX,
+		"rx ring address is %lX\n",(unsigned long)rx_ring);
+	flush_cache((unsigned long)rx_ring, RX_BUF_LEN);
+	outl(phys_to_bus((int)rx_ring), ioaddr + RxBuf);
+
+	/* If we add multicast support, the MAR0 register would have to be
+	 * initialized to 0xffffffffffffffff (two 32 bit accesses).  Etherboot
+	 * only needs broadcast (for ARP/RARP/BOOTP/DHCP) and unicast.	*/
+
+	outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
+
+	outl(rtl8139_rx_config, ioaddr + RxConfig);
+
+	/* Start the chip's Tx and Rx process. */
+	outl(0, ioaddr + RxMissed);
+
+	/* set_rx_mode */
+	set_rx_mode(dev);
+
+	/* Disable all known interrupts by setting the interrupt mask. */
+	outw(0, ioaddr + IntrMask);
+}
+
+static int rtl_transmit(struct eth_device *dev, void *packet, int length)
+{
+	unsigned int status;
+	unsigned long txstatus;
+	unsigned int len = length;
+	int i = 0;
+
+	ioaddr = dev->iobase;
+
+	memcpy((char *)tx_buffer, (char *)packet, (int)length);
+
+	debug_cond(DEBUG_TX, "sending %d bytes\n", len);
+
+	/* Note: RTL8139 doesn't auto-pad, send minimum payload (another 4
+	 * bytes are sent automatically for the FCS, totalling to 64 bytes). */
+	while (len < ETH_ZLEN) {
+		tx_buffer[len++] = '\0';
+	}
+
+	flush_cache((unsigned long)tx_buffer, length);
+	outl(phys_to_bus((int)tx_buffer), ioaddr + TxAddr0 + cur_tx*4);
+	outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len,
+		ioaddr + TxStatus0 + cur_tx*4);
+
+	do {
+		status = inw(ioaddr + IntrStatus);
+		/* Only acknlowledge interrupt sources we can properly handle
+		 * here - the RxOverflow/RxFIFOOver MUST be handled in the
+		 * rtl_poll() function.	 */
+		outw(status & (TxOK | TxErr | PCIErr), ioaddr + IntrStatus);
+		if ((status & (TxOK | TxErr | PCIErr)) != 0) break;
+		udelay(10);
+	} while (i++ < RTL_TIMEOUT);
+
+	txstatus = inl(ioaddr + TxStatus0 + cur_tx*4);
+
+	if (status & TxOK) {
+		cur_tx = (cur_tx + 1) % NUM_TX_DESC;
+
+		debug_cond(DEBUG_TX,
+			"tx done, status %hX txstatus %lX\n",
+			status, txstatus);
+
+		return length;
+	} else {
+
+		debug_cond(DEBUG_TX,
+			"tx timeout/error (%d usecs), status %hX txstatus %lX\n",
+			10*i, status, txstatus);
+
+		rtl_reset(dev);
+
+		return 0;
+	}
+}
+
+static int rtl_poll(struct eth_device *dev)
+{
+	unsigned int status;
+	unsigned int ring_offs;
+	unsigned int rx_size, rx_status;
+	int length=0;
+
+	ioaddr = dev->iobase;
+
+	if (inb(ioaddr + ChipCmd) & RxBufEmpty) {
+		return 0;
+	}
+
+	status = inw(ioaddr + IntrStatus);
+	/* See below for the rest of the interrupt acknowledges.  */
+	outw(status & ~(RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
+
+	debug_cond(DEBUG_RX, "rtl_poll: int %hX ", status);
+
+	ring_offs = cur_rx % RX_BUF_LEN;
+	/* ring_offs is guaranteed being 4-byte aligned */
+	rx_status = le32_to_cpu(*(unsigned int *)(rx_ring + ring_offs));
+	rx_size = rx_status >> 16;
+	rx_status &= 0xffff;
+
+	if ((rx_status & (RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign)) ||
+	    (rx_size < ETH_ZLEN) || (rx_size > ETH_FRAME_LEN + 4)) {
+		printf("rx error %hX\n", rx_status);
+		rtl_reset(dev); /* this clears all interrupts still pending */
+		return 0;
+	}
+
+	/* Received a good packet */
+	length = rx_size - 4;	/* no one cares about the FCS */
+	if (ring_offs+4+rx_size-4 > RX_BUF_LEN) {
+		int semi_count = RX_BUF_LEN - ring_offs - 4;
+		unsigned char rxdata[RX_BUF_LEN];
+
+		memcpy(rxdata, rx_ring + ring_offs + 4, semi_count);
+		memcpy(&(rxdata[semi_count]), rx_ring, rx_size-4-semi_count);
+
+		NetReceive(rxdata, length);
+		debug_cond(DEBUG_RX, "rx packet %d+%d bytes",
+			semi_count, rx_size-4-semi_count);
+	} else {
+		NetReceive(rx_ring + ring_offs + 4, length);
+		debug_cond(DEBUG_RX, "rx packet %d bytes", rx_size-4);
+	}
+	flush_cache((unsigned long)rx_ring, RX_BUF_LEN);
+
+	cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
+	outw(cur_rx - 16, ioaddr + RxBufPtr);
+	/* See RTL8139 Programming Guide V0.1 for the official handling of
+	 * Rx overflow situations.  The document itself contains basically no
+	 * usable information, except for a few exception handling rules.  */
+	outw(status & (RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
+	return length;
+}
+
+static void rtl_disable(struct eth_device *dev)
+{
+	int i;
+
+	ioaddr = dev->iobase;
+
+	/* reset the chip */
+	outb(CmdReset, ioaddr + ChipCmd);
+
+	/* Give the chip 10ms to finish the reset. */
+	for (i=0; i<100; ++i){
+		if ((inb(ioaddr + ChipCmd) & CmdReset) == 0) break;
+		udelay (100); /* wait 100us */
+	}
+}
diff --git a/marvell/uboot/drivers/net/rtl8169.c b/marvell/uboot/drivers/net/rtl8169.c
new file mode 100644
index 0000000..d040ab1
--- /dev/null
+++ b/marvell/uboot/drivers/net/rtl8169.c
@@ -0,0 +1,967 @@
+/*
+ * rtl8169.c : U-Boot driver for the RealTek RTL8169
+ *
+ * Masami Komiya (mkomiya@sonare.it)
+ *
+ * Most part is taken from r8169.c of etherboot
+ *
+ */
+
+/**************************************************************************
+*    r8169.c: Etherboot device driver for the RealTek RTL-8169 Gigabit
+*    Written 2003 by Timothy Legge <tlegge@rogers.com>
+*
+ * SPDX-License-Identifier:	GPL-2.0+
+*
+*    Portions of this code based on:
+*	r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver
+*		for Linux kernel 2.4.x.
+*
+*    Written 2002 ShuChen <shuchen@realtek.com.tw>
+*	  See Linux Driver for full information
+*
+*    Linux Driver Version 1.27a, 10.02.2002
+*
+*    Thanks to:
+*	Jean Chen of RealTek Semiconductor Corp. for
+*	providing the evaluation NIC used to develop
+*	this driver.  RealTek's support for Etherboot
+*	is appreciated.
+*
+*    REVISION HISTORY:
+*    ================
+*
+*    v1.0	11-26-2003	timlegge	Initial port of Linux driver
+*    v1.5	01-17-2004	timlegge	Initial driver output cleanup
+*
+*    Indent Options: indent -kr -i8
+***************************************************************************/
+/*
+ * 26 August 2006 Mihai Georgian <u-boot@linuxnotincluded.org.uk>
+ * Modified to use le32_to_cpu and cpu_to_le32 properly
+ */
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#undef DEBUG_RTL8169
+#undef DEBUG_RTL8169_TX
+#undef DEBUG_RTL8169_RX
+
+#define drv_version "v1.5"
+#define drv_date "01-17-2004"
+
+static u32 ioaddr;
+
+/* Condensed operations for readability. */
+#define currticks()	get_timer(0)
+
+/* media options */
+#define MAX_UNITS 8
+static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
+
+/* MAC address length*/
+#define MAC_ADDR_LEN	6
+
+/* max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4).*/
+#define MAX_ETH_FRAME_SIZE	1536
+
+#define TX_FIFO_THRESH 256	/* In bytes */
+
+#define RX_FIFO_THRESH	7	/* 7 means NO threshold, Rx buffer level before first PCI xfer.	 */
+#define RX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
+#define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
+#define EarlyTxThld	0x3F	/* 0x3F means NO early transmit */
+#define RxPacketMaxSize 0x0800	/* Maximum size supported is 16K-1 */
+#define InterFrameGap	0x03	/* 3 means InterFrameGap = the shortest one */
+
+#define NUM_TX_DESC	1	/* Number of Tx descriptor registers */
+#define NUM_RX_DESC	4	/* Number of Rx descriptor registers */
+#define RX_BUF_SIZE	1536	/* Rx Buffer size */
+#define RX_BUF_LEN	8192
+
+#define RTL_MIN_IO_SIZE 0x80
+#define TX_TIMEOUT  (6*HZ)
+
+/* write/read MMIO register. Notice: {read,write}[wl] do the necessary swapping */
+#define RTL_W8(reg, val8)	writeb ((val8), ioaddr + (reg))
+#define RTL_W16(reg, val16)	writew ((val16), ioaddr + (reg))
+#define RTL_W32(reg, val32)	writel ((val32), ioaddr + (reg))
+#define RTL_R8(reg)		readb (ioaddr + (reg))
+#define RTL_R16(reg)		readw (ioaddr + (reg))
+#define RTL_R32(reg)		((unsigned long) 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)dev->priv, (pci_addr_t)a)
+#define phys_to_bus(a)	pci_phys_to_mem((pci_dev_t)dev->priv, (phys_addr_t)a)
+
+enum RTL8169_registers {
+	MAC0 = 0,		/* Ethernet hardware address. */
+	MAR0 = 8,		/* Multicast filter. */
+	TxDescStartAddrLow = 0x20,
+	TxDescStartAddrHigh = 0x24,
+	TxHDescStartAddrLow = 0x28,
+	TxHDescStartAddrHigh = 0x2c,
+	FLASH = 0x30,
+	ERSR = 0x36,
+	ChipCmd = 0x37,
+	TxPoll = 0x38,
+	IntrMask = 0x3C,
+	IntrStatus = 0x3E,
+	TxConfig = 0x40,
+	RxConfig = 0x44,
+	RxMissed = 0x4C,
+	Cfg9346 = 0x50,
+	Config0 = 0x51,
+	Config1 = 0x52,
+	Config2 = 0x53,
+	Config3 = 0x54,
+	Config4 = 0x55,
+	Config5 = 0x56,
+	MultiIntr = 0x5C,
+	PHYAR = 0x60,
+	TBICSR = 0x64,
+	TBI_ANAR = 0x68,
+	TBI_LPAR = 0x6A,
+	PHYstatus = 0x6C,
+	RxMaxSize = 0xDA,
+	CPlusCmd = 0xE0,
+	RxDescStartAddrLow = 0xE4,
+	RxDescStartAddrHigh = 0xE8,
+	EarlyTxThres = 0xEC,
+	FuncEvent = 0xF0,
+	FuncEventMask = 0xF4,
+	FuncPresetState = 0xF8,
+	FuncForceEvent = 0xFC,
+};
+
+enum RTL8169_register_content {
+	/*InterruptStatusBits */
+	SYSErr = 0x8000,
+	PCSTimeout = 0x4000,
+	SWInt = 0x0100,
+	TxDescUnavail = 0x80,
+	RxFIFOOver = 0x40,
+	RxUnderrun = 0x20,
+	RxOverflow = 0x10,
+	TxErr = 0x08,
+	TxOK = 0x04,
+	RxErr = 0x02,
+	RxOK = 0x01,
+
+	/*RxStatusDesc */
+	RxRES = 0x00200000,
+	RxCRC = 0x00080000,
+	RxRUNT = 0x00100000,
+	RxRWT = 0x00400000,
+
+	/*ChipCmdBits */
+	CmdReset = 0x10,
+	CmdRxEnb = 0x08,
+	CmdTxEnb = 0x04,
+	RxBufEmpty = 0x01,
+
+	/*Cfg9346Bits */
+	Cfg9346_Lock = 0x00,
+	Cfg9346_Unlock = 0xC0,
+
+	/*rx_mode_bits */
+	AcceptErr = 0x20,
+	AcceptRunt = 0x10,
+	AcceptBroadcast = 0x08,
+	AcceptMulticast = 0x04,
+	AcceptMyPhys = 0x02,
+	AcceptAllPhys = 0x01,
+
+	/*RxConfigBits */
+	RxCfgFIFOShift = 13,
+	RxCfgDMAShift = 8,
+
+	/*TxConfigBits */
+	TxInterFrameGapShift = 24,
+	TxDMAShift = 8,		/* DMA burst value (0-7) is shift this many bits */
+
+	/*rtl8169_PHYstatus */
+	TBI_Enable = 0x80,
+	TxFlowCtrl = 0x40,
+	RxFlowCtrl = 0x20,
+	_1000bpsF = 0x10,
+	_100bps = 0x08,
+	_10bps = 0x04,
+	LinkStatus = 0x02,
+	FullDup = 0x01,
+
+	/*GIGABIT_PHY_registers */
+	PHY_CTRL_REG = 0,
+	PHY_STAT_REG = 1,
+	PHY_AUTO_NEGO_REG = 4,
+	PHY_1000_CTRL_REG = 9,
+
+	/*GIGABIT_PHY_REG_BIT */
+	PHY_Restart_Auto_Nego = 0x0200,
+	PHY_Enable_Auto_Nego = 0x1000,
+
+	/* PHY_STAT_REG = 1; */
+	PHY_Auto_Nego_Comp = 0x0020,
+
+	/* PHY_AUTO_NEGO_REG = 4; */
+	PHY_Cap_10_Half = 0x0020,
+	PHY_Cap_10_Full = 0x0040,
+	PHY_Cap_100_Half = 0x0080,
+	PHY_Cap_100_Full = 0x0100,
+
+	/* PHY_1000_CTRL_REG = 9; */
+	PHY_Cap_1000_Full = 0x0200,
+
+	PHY_Cap_Null = 0x0,
+
+	/*_MediaType*/
+	_10_Half = 0x01,
+	_10_Full = 0x02,
+	_100_Half = 0x04,
+	_100_Full = 0x08,
+	_1000_Full = 0x10,
+
+	/*_TBICSRBit*/
+	TBILinkOK = 0x02000000,
+};
+
+static struct {
+	const char *name;
+	u8 version;		/* depend on RTL8169 docs */
+	u32 RxConfigMask;	/* should clear the bits supported by this chip */
+} rtl_chip_info[] = {
+	{"RTL-8169", 0x00, 0xff7e1880,},
+	{"RTL-8169", 0x04, 0xff7e1880,},
+	{"RTL-8169", 0x00, 0xff7e1880,},
+	{"RTL-8169s/8110s",	0x02, 0xff7e1880,},
+	{"RTL-8169s/8110s",	0x04, 0xff7e1880,},
+	{"RTL-8169sb/8110sb",	0x10, 0xff7e1880,},
+	{"RTL-8169sc/8110sc",	0x18, 0xff7e1880,},
+	{"RTL-8168b/8111sb",	0x30, 0xff7e1880,},
+	{"RTL-8168b/8111sb",	0x38, 0xff7e1880,},
+	{"RTL-8168d/8111d",	0x28, 0xff7e1880,},
+	{"RTL-8168evl/8111evl",	0x2e, 0xff7e1880,},
+	{"RTL-8101e",		0x34, 0xff7e1880,},
+	{"RTL-8100e",		0x32, 0xff7e1880,},
+};
+
+enum _DescStatusBit {
+	OWNbit = 0x80000000,
+	EORbit = 0x40000000,
+	FSbit = 0x20000000,
+	LSbit = 0x10000000,
+};
+
+struct TxDesc {
+	u32 status;
+	u32 vlan_tag;
+	u32 buf_addr;
+	u32 buf_Haddr;
+};
+
+struct RxDesc {
+	u32 status;
+	u32 vlan_tag;
+	u32 buf_addr;
+	u32 buf_Haddr;
+};
+
+/* Define the TX Descriptor */
+static u8 tx_ring[NUM_TX_DESC * sizeof(struct TxDesc) + 256];
+/*	__attribute__ ((aligned(256))); */
+
+/* Create a static buffer of size RX_BUF_SZ for each
+TX Descriptor.	All descriptors point to a
+part of this buffer */
+static unsigned char txb[NUM_TX_DESC * RX_BUF_SIZE];
+
+/* Define the RX Descriptor */
+static u8 rx_ring[NUM_RX_DESC * sizeof(struct TxDesc) + 256];
+  /*  __attribute__ ((aligned(256))); */
+
+/* Create a static buffer of size RX_BUF_SZ for each
+RX Descriptor	All descriptors point to a
+part of this buffer */
+static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE];
+
+struct rtl8169_private {
+	void *mmio_addr;	/* memory map physical address */
+	int chipset;
+	unsigned long cur_rx;	/* Index into the Rx descriptor buffer of next Rx pkt. */
+	unsigned long cur_tx;	/* Index into the Tx descriptor buffer of next Rx pkt. */
+	unsigned long dirty_tx;
+	unsigned char *TxDescArrays;	/* Index of Tx Descriptor buffer */
+	unsigned char *RxDescArrays;	/* Index of Rx Descriptor buffer */
+	struct TxDesc *TxDescArray;	/* Index of 256-alignment Tx Descriptor buffer */
+	struct RxDesc *RxDescArray;	/* Index of 256-alignment Rx Descriptor buffer */
+	unsigned char *RxBufferRings;	/* Index of Rx Buffer  */
+	unsigned char *RxBufferRing[NUM_RX_DESC];	/* Index of Rx Buffer array */
+	unsigned char *Tx_skbuff[NUM_TX_DESC];
+} tpx;
+
+static struct rtl8169_private *tpc;
+
+static const u16 rtl8169_intr_mask =
+    SYSErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr |
+    TxOK | RxErr | RxOK;
+static const unsigned int rtl8169_rx_config =
+    (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
+
+static struct pci_device_id supported[] = {
+	{PCI_VENDOR_ID_REALTEK, 0x8167},
+	{PCI_VENDOR_ID_REALTEK, 0x8168},
+	{PCI_VENDOR_ID_REALTEK, 0x8169},
+	{}
+};
+
+void mdio_write(int RegAddr, int value)
+{
+	int i;
+
+	RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
+	udelay(1000);
+
+	for (i = 2000; i > 0; i--) {
+		/* Check if the RTL8169 has completed writing to the specified MII register */
+		if (!(RTL_R32(PHYAR) & 0x80000000)) {
+			break;
+		} else {
+			udelay(100);
+		}
+	}
+}
+
+int mdio_read(int RegAddr)
+{
+	int i, value = -1;
+
+	RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
+	udelay(1000);
+
+	for (i = 2000; i > 0; i--) {
+		/* Check if the RTL8169 has completed retrieving data from the specified MII register */
+		if (RTL_R32(PHYAR) & 0x80000000) {
+			value = (int) (RTL_R32(PHYAR) & 0xFFFF);
+			break;
+		} else {
+			udelay(100);
+		}
+	}
+	return value;
+}
+
+static int rtl8169_init_board(struct eth_device *dev)
+{
+	int i;
+	u32 tmp;
+
+#ifdef DEBUG_RTL8169
+	printf ("%s\n", __FUNCTION__);
+#endif
+	ioaddr = dev->iobase;
+
+	/* Soft reset the chip. */
+	RTL_W8(ChipCmd, CmdReset);
+
+	/* Check that the chip has finished the reset. */
+	for (i = 1000; i > 0; i--)
+		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
+			break;
+		else
+			udelay(10);
+
+	/* identify chip attached to board */
+	tmp = RTL_R32(TxConfig);
+	tmp = ((tmp & 0x7c000000) + ((tmp & 0x00800000) << 2)) >> 24;
+
+	for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--){
+		if (tmp == rtl_chip_info[i].version) {
+			tpc->chipset = i;
+			goto match;
+		}
+	}
+
+	/* if unknown chip, assume array element #0, original RTL-8169 in this case */
+	printf("PCI device %s: unknown chip version, assuming RTL-8169\n", dev->name);
+	printf("PCI device: TxConfig = 0x%lX\n", (unsigned long) RTL_R32(TxConfig));
+	tpc->chipset = 0;
+
+match:
+	return 0;
+}
+
+/*
+ * Cache maintenance functions. These are simple wrappers around the more
+ * general purpose flush_cache() and invalidate_dcache_range() functions.
+ */
+
+static void rtl_inval_rx_desc(struct RxDesc *desc)
+{
+	unsigned long start = (unsigned long)desc & ~(ARCH_DMA_MINALIGN - 1);
+	unsigned long end = ALIGN(start + sizeof(*desc), ARCH_DMA_MINALIGN);
+
+	invalidate_dcache_range(start, end);
+}
+
+static void rtl_flush_rx_desc(struct RxDesc *desc)
+{
+	flush_cache((unsigned long)desc, sizeof(*desc));
+}
+
+static void rtl_inval_tx_desc(struct TxDesc *desc)
+{
+	unsigned long start = (unsigned long)desc & ~(ARCH_DMA_MINALIGN - 1);
+	unsigned long end = ALIGN(start + sizeof(*desc), ARCH_DMA_MINALIGN);
+
+	invalidate_dcache_range(start, end);
+}
+
+static void rtl_flush_tx_desc(struct TxDesc *desc)
+{
+	flush_cache((unsigned long)desc, sizeof(*desc));
+}
+
+static void rtl_inval_buffer(void *buf, size_t size)
+{
+	unsigned long start = (unsigned long)buf & ~(ARCH_DMA_MINALIGN - 1);
+	unsigned long end = ALIGN(start + size, ARCH_DMA_MINALIGN);
+
+	invalidate_dcache_range(start, end);
+}
+
+static void rtl_flush_buffer(void *buf, size_t size)
+{
+	flush_cache((unsigned long)buf, size);
+}
+
+/**************************************************************************
+RECV - Receive a frame
+***************************************************************************/
+static int rtl_recv(struct eth_device *dev)
+{
+	/* return true if there's an ethernet packet ready to read */
+	/* nic->packet should contain data on return */
+	/* nic->packetlen should contain length of data */
+	int cur_rx;
+	int length = 0;
+
+#ifdef DEBUG_RTL8169_RX
+	printf ("%s\n", __FUNCTION__);
+#endif
+	ioaddr = dev->iobase;
+
+	cur_rx = tpc->cur_rx;
+
+	rtl_inval_rx_desc(&tpc->RxDescArray[cur_rx]);
+
+	if ((le32_to_cpu(tpc->RxDescArray[cur_rx].status) & OWNbit) == 0) {
+		if (!(le32_to_cpu(tpc->RxDescArray[cur_rx].status) & RxRES)) {
+			unsigned char rxdata[RX_BUF_LEN];
+			length = (int) (le32_to_cpu(tpc->RxDescArray[cur_rx].
+						status) & 0x00001FFF) - 4;
+
+			rtl_inval_buffer(tpc->RxBufferRing[cur_rx], length);
+			memcpy(rxdata, tpc->RxBufferRing[cur_rx], length);
+			NetReceive(rxdata, length);
+
+			if (cur_rx == NUM_RX_DESC - 1)
+				tpc->RxDescArray[cur_rx].status =
+					cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE);
+			else
+				tpc->RxDescArray[cur_rx].status =
+					cpu_to_le32(OWNbit + RX_BUF_SIZE);
+			tpc->RxDescArray[cur_rx].buf_addr =
+				cpu_to_le32(bus_to_phys(tpc->RxBufferRing[cur_rx]));
+			rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]);
+		} else {
+			puts("Error Rx");
+		}
+		cur_rx = (cur_rx + 1) % NUM_RX_DESC;
+		tpc->cur_rx = cur_rx;
+		return 1;
+
+	} else {
+		ushort sts = RTL_R8(IntrStatus);
+		RTL_W8(IntrStatus, sts & ~(TxErr | RxErr | SYSErr));
+		udelay(100);	/* wait */
+	}
+	tpc->cur_rx = cur_rx;
+	return (0);		/* initially as this is called to flush the input */
+}
+
+#define HZ 1000
+/**************************************************************************
+SEND - Transmit a frame
+***************************************************************************/
+static int rtl_send(struct eth_device *dev, void *packet, int length)
+{
+	/* send the packet to destination */
+
+	u32 to;
+	u8 *ptxb;
+	int entry = tpc->cur_tx % NUM_TX_DESC;
+	u32 len = length;
+	int ret;
+
+#ifdef DEBUG_RTL8169_TX
+	int stime = currticks();
+	printf ("%s\n", __FUNCTION__);
+	printf("sending %d bytes\n", len);
+#endif
+
+	ioaddr = dev->iobase;
+
+	/* point to the current txb incase multiple tx_rings are used */
+	ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE];
+	memcpy(ptxb, (char *)packet, (int)length);
+	rtl_flush_buffer(ptxb, length);
+
+	while (len < ETH_ZLEN)
+		ptxb[len++] = '\0';
+
+	tpc->TxDescArray[entry].buf_Haddr = 0;
+	tpc->TxDescArray[entry].buf_addr = cpu_to_le32(bus_to_phys(ptxb));
+	if (entry != (NUM_TX_DESC - 1)) {
+		tpc->TxDescArray[entry].status =
+			cpu_to_le32((OWNbit | FSbit | LSbit) |
+				    ((len > ETH_ZLEN) ? len : ETH_ZLEN));
+	} else {
+		tpc->TxDescArray[entry].status =
+			cpu_to_le32((OWNbit | EORbit | FSbit | LSbit) |
+				    ((len > ETH_ZLEN) ? len : ETH_ZLEN));
+	}
+	rtl_flush_tx_desc(&tpc->TxDescArray[entry]);
+	RTL_W8(TxPoll, 0x40);	/* set polling bit */
+
+	tpc->cur_tx++;
+	to = currticks() + TX_TIMEOUT;
+	do {
+		rtl_inval_tx_desc(&tpc->TxDescArray[entry]);
+	} while ((le32_to_cpu(tpc->TxDescArray[entry].status) & OWNbit)
+				&& (currticks() < to));	/* wait */
+
+	if (currticks() >= to) {
+#ifdef DEBUG_RTL8169_TX
+		puts("tx timeout/error\n");
+		printf("%s elapsed time : %lu\n", __func__, currticks()-stime);
+#endif
+		ret = 0;
+	} else {
+#ifdef DEBUG_RTL8169_TX
+		puts("tx done\n");
+#endif
+		ret = length;
+	}
+	/* Delay to make net console (nc) work properly */
+	udelay(20);
+	return ret;
+}
+
+static void rtl8169_set_rx_mode(struct eth_device *dev)
+{
+	u32 mc_filter[2];	/* Multicast hash filter */
+	int rx_mode;
+	u32 tmp = 0;
+
+#ifdef DEBUG_RTL8169
+	printf ("%s\n", __FUNCTION__);
+#endif
+
+	/* IFF_ALLMULTI */
+	/* Too many to filter perfectly -- accept all multicasts. */
+	rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+	mc_filter[1] = mc_filter[0] = 0xffffffff;
+
+	tmp = rtl8169_rx_config | rx_mode | (RTL_R32(RxConfig) &
+				   rtl_chip_info[tpc->chipset].RxConfigMask);
+
+	RTL_W32(RxConfig, tmp);
+	RTL_W32(MAR0 + 0, mc_filter[0]);
+	RTL_W32(MAR0 + 4, mc_filter[1]);
+}
+
+static void rtl8169_hw_start(struct eth_device *dev)
+{
+	u32 i;
+
+#ifdef DEBUG_RTL8169
+	int stime = currticks();
+	printf ("%s\n", __FUNCTION__);
+#endif
+
+#if 0
+	/* Soft reset the chip. */
+	RTL_W8(ChipCmd, CmdReset);
+
+	/* Check that the chip has finished the reset. */
+	for (i = 1000; i > 0; i--) {
+		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
+			break;
+		else
+			udelay(10);
+	}
+#endif
+
+	RTL_W8(Cfg9346, Cfg9346_Unlock);
+
+	/* RTL-8169sb/8110sb or previous version */
+	if (tpc->chipset <= 5)
+		RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+
+	RTL_W8(EarlyTxThres, EarlyTxThld);
+
+	/* For gigabit rtl8169 */
+	RTL_W16(RxMaxSize, RxPacketMaxSize);
+
+	/* Set Rx Config register */
+	i = rtl8169_rx_config | (RTL_R32(RxConfig) &
+				 rtl_chip_info[tpc->chipset].RxConfigMask);
+	RTL_W32(RxConfig, i);
+
+	/* Set DMA burst size and Interframe Gap Time */
+	RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
+				(InterFrameGap << TxInterFrameGapShift));
+
+
+	tpc->cur_rx = 0;
+
+	RTL_W32(TxDescStartAddrLow, bus_to_phys(tpc->TxDescArray));
+	RTL_W32(TxDescStartAddrHigh, (unsigned long)0);
+	RTL_W32(RxDescStartAddrLow, bus_to_phys(tpc->RxDescArray));
+	RTL_W32(RxDescStartAddrHigh, (unsigned long)0);
+
+	/* RTL-8169sc/8110sc or later version */
+	if (tpc->chipset > 5)
+		RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
+
+	RTL_W8(Cfg9346, Cfg9346_Lock);
+	udelay(10);
+
+	RTL_W32(RxMissed, 0);
+
+	rtl8169_set_rx_mode(dev);
+
+	/* no early-rx interrupts */
+	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
+
+#ifdef DEBUG_RTL8169
+	printf("%s elapsed time : %lu\n", __func__, currticks()-stime);
+#endif
+}
+
+static void rtl8169_init_ring(struct eth_device *dev)
+{
+	int i;
+
+#ifdef DEBUG_RTL8169
+	int stime = currticks();
+	printf ("%s\n", __FUNCTION__);
+#endif
+
+	tpc->cur_rx = 0;
+	tpc->cur_tx = 0;
+	tpc->dirty_tx = 0;
+	memset(tpc->TxDescArray, 0x0, NUM_TX_DESC * sizeof(struct TxDesc));
+	memset(tpc->RxDescArray, 0x0, NUM_RX_DESC * sizeof(struct RxDesc));
+
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		tpc->Tx_skbuff[i] = &txb[i];
+	}
+
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		if (i == (NUM_RX_DESC - 1))
+			tpc->RxDescArray[i].status =
+				cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE);
+		else
+			tpc->RxDescArray[i].status =
+				cpu_to_le32(OWNbit + RX_BUF_SIZE);
+
+		tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
+		tpc->RxDescArray[i].buf_addr =
+			cpu_to_le32(bus_to_phys(tpc->RxBufferRing[i]));
+		rtl_flush_rx_desc(&tpc->RxDescArray[i]);
+	}
+
+#ifdef DEBUG_RTL8169
+	printf("%s elapsed time : %lu\n", __func__, currticks()-stime);
+#endif
+}
+
+/**************************************************************************
+RESET - Finish setting up the ethernet interface
+***************************************************************************/
+static int rtl_reset(struct eth_device *dev, bd_t *bis)
+{
+	int i;
+
+#ifdef DEBUG_RTL8169
+	int stime = currticks();
+	printf ("%s\n", __FUNCTION__);
+#endif
+
+	tpc->TxDescArrays = tx_ring;
+	/* Tx Desscriptor needs 256 bytes alignment; */
+	tpc->TxDescArray = (struct TxDesc *) ((unsigned long)(tpc->TxDescArrays +
+							      255) & ~255);
+
+	tpc->RxDescArrays = rx_ring;
+	/* Rx Desscriptor needs 256 bytes alignment; */
+	tpc->RxDescArray = (struct RxDesc *) ((unsigned long)(tpc->RxDescArrays +
+							      255) & ~255);
+
+	rtl8169_init_ring(dev);
+	rtl8169_hw_start(dev);
+	/* Construct a perfect filter frame with the mac address as first match
+	 * and broadcast for all others */
+	for (i = 0; i < 192; i++)
+		txb[i] = 0xFF;
+
+	txb[0] = dev->enetaddr[0];
+	txb[1] = dev->enetaddr[1];
+	txb[2] = dev->enetaddr[2];
+	txb[3] = dev->enetaddr[3];
+	txb[4] = dev->enetaddr[4];
+	txb[5] = dev->enetaddr[5];
+
+#ifdef DEBUG_RTL8169
+	printf("%s elapsed time : %lu\n", __func__, currticks()-stime);
+#endif
+	return 0;
+}
+
+/**************************************************************************
+HALT - Turn off ethernet interface
+***************************************************************************/
+static void rtl_halt(struct eth_device *dev)
+{
+	int i;
+
+#ifdef DEBUG_RTL8169
+	printf ("%s\n", __FUNCTION__);
+#endif
+
+	ioaddr = dev->iobase;
+
+	/* Stop the chip's Tx and Rx DMA processes. */
+	RTL_W8(ChipCmd, 0x00);
+
+	/* Disable interrupts by clearing the interrupt mask. */
+	RTL_W16(IntrMask, 0x0000);
+
+	RTL_W32(RxMissed, 0);
+
+	tpc->TxDescArrays = NULL;
+	tpc->RxDescArrays = NULL;
+	tpc->TxDescArray = NULL;
+	tpc->RxDescArray = NULL;
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		tpc->RxBufferRing[i] = NULL;
+	}
+}
+
+/**************************************************************************
+INIT - Look for an adapter, this routine's visible to the outside
+***************************************************************************/
+
+#define board_found 1
+#define valid_link 0
+static int rtl_init(struct eth_device *dev, bd_t *bis)
+{
+	static int board_idx = -1;
+	int i, rc;
+	int option = -1, Cap10_100 = 0, Cap1000 = 0;
+
+#ifdef DEBUG_RTL8169
+	printf ("%s\n", __FUNCTION__);
+#endif
+
+	ioaddr = dev->iobase;
+
+	board_idx++;
+
+	/* point to private storage */
+	tpc = &tpx;
+
+	rc = rtl8169_init_board(dev);
+	if (rc)
+		return rc;
+
+	/* Get MAC address.  FIXME: read EEPROM */
+	for (i = 0; i < MAC_ADDR_LEN; i++)
+		dev->enetaddr[i] = RTL_R8(MAC0 + i);
+
+#ifdef DEBUG_RTL8169
+	printf("chipset = %d\n", tpc->chipset);
+	printf("MAC Address");
+	for (i = 0; i < MAC_ADDR_LEN; i++)
+		printf(":%02x", dev->enetaddr[i]);
+	putc('\n');
+#endif
+
+#ifdef DEBUG_RTL8169
+	/* Print out some hardware info */
+	printf("%s: at ioaddr 0x%x\n", dev->name, ioaddr);
+#endif
+
+	/* if TBI is not endbled */
+	if (!(RTL_R8(PHYstatus) & TBI_Enable)) {
+		int val = mdio_read(PHY_AUTO_NEGO_REG);
+
+		option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
+		/* Force RTL8169 in 10/100/1000 Full/Half mode. */
+		if (option > 0) {
+#ifdef DEBUG_RTL8169
+			printf("%s: Force-mode Enabled.\n", dev->name);
+#endif
+			Cap10_100 = 0, Cap1000 = 0;
+			switch (option) {
+			case _10_Half:
+				Cap10_100 = PHY_Cap_10_Half;
+				Cap1000 = PHY_Cap_Null;
+				break;
+			case _10_Full:
+				Cap10_100 = PHY_Cap_10_Full;
+				Cap1000 = PHY_Cap_Null;
+				break;
+			case _100_Half:
+				Cap10_100 = PHY_Cap_100_Half;
+				Cap1000 = PHY_Cap_Null;
+				break;
+			case _100_Full:
+				Cap10_100 = PHY_Cap_100_Full;
+				Cap1000 = PHY_Cap_Null;
+				break;
+			case _1000_Full:
+				Cap10_100 = PHY_Cap_Null;
+				Cap1000 = PHY_Cap_1000_Full;
+				break;
+			default:
+				break;
+			}
+			mdio_write(PHY_AUTO_NEGO_REG, Cap10_100 | (val & 0x1F));	/* leave PHY_AUTO_NEGO_REG bit4:0 unchanged */
+			mdio_write(PHY_1000_CTRL_REG, Cap1000);
+		} else {
+#ifdef DEBUG_RTL8169
+			printf("%s: Auto-negotiation Enabled.\n",
+			       dev->name);
+#endif
+			/* enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged */
+			mdio_write(PHY_AUTO_NEGO_REG,
+				   PHY_Cap_10_Half | PHY_Cap_10_Full |
+				   PHY_Cap_100_Half | PHY_Cap_100_Full |
+				   (val & 0x1F));
+
+			/* enable 1000 Full Mode */
+			mdio_write(PHY_1000_CTRL_REG, PHY_Cap_1000_Full);
+
+		}
+
+		/* Enable auto-negotiation and restart auto-nigotiation */
+		mdio_write(PHY_CTRL_REG,
+			   PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego);
+		udelay(100);
+
+		/* wait for auto-negotiation process */
+		for (i = 10000; i > 0; i--) {
+			/* check if auto-negotiation complete */
+			if (mdio_read(PHY_STAT_REG) & PHY_Auto_Nego_Comp) {
+				udelay(100);
+				option = RTL_R8(PHYstatus);
+				if (option & _1000bpsF) {
+#ifdef DEBUG_RTL8169
+					printf("%s: 1000Mbps Full-duplex operation.\n",
+					     dev->name);
+#endif
+				} else {
+#ifdef DEBUG_RTL8169
+					printf("%s: %sMbps %s-duplex operation.\n",
+					       dev->name,
+					       (option & _100bps) ? "100" :
+					       "10",
+					       (option & FullDup) ? "Full" :
+					       "Half");
+#endif
+				}
+				break;
+			} else {
+				udelay(100);
+			}
+		}		/* end for-loop to wait for auto-negotiation process */
+
+	} else {
+		udelay(100);
+#ifdef DEBUG_RTL8169
+		printf
+		    ("%s: 1000Mbps Full-duplex operation, TBI Link %s!\n",
+		     dev->name,
+		     (RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed");
+#endif
+	}
+
+	return 1;
+}
+
+int rtl8169_initialize(bd_t *bis)
+{
+	pci_dev_t devno;
+	int card_number = 0;
+	struct eth_device *dev;
+	u32 iobase;
+	int idx=0;
+
+	while(1){
+		unsigned int region;
+		u16 device;
+
+		/* Find RTL8169 */
+		if ((devno = pci_find_devices(supported, idx++)) < 0)
+			break;
+
+		pci_read_config_word(devno, PCI_DEVICE_ID, &device);
+		switch (device) {
+		case 0x8168:
+			region = 2;
+			break;
+
+		default:
+			region = 1;
+			break;
+		}
+
+		pci_read_config_dword(devno, PCI_BASE_ADDRESS_0 + (region * 4), &iobase);
+		iobase &= ~0xf;
+
+		debug ("rtl8169: REALTEK RTL8169 @0x%x\n", iobase);
+
+		dev = (struct eth_device *)malloc(sizeof *dev);
+		if (!dev) {
+			printf("Can not allocate memory of rtl8169\n");
+			break;
+		}
+
+		memset(dev, 0, sizeof(*dev));
+		sprintf (dev->name, "RTL8169#%d", card_number);
+
+		dev->priv = (void *) devno;
+		dev->iobase = (int)pci_mem_to_phys(devno, iobase);
+
+		dev->init = rtl_reset;
+		dev->halt = rtl_halt;
+		dev->send = rtl_send;
+		dev->recv = rtl_recv;
+
+		eth_register (dev);
+
+		rtl_init(dev, bis);
+
+		card_number++;
+	}
+	return card_number;
+}
diff --git a/marvell/uboot/drivers/net/sh_eth.c b/marvell/uboot/drivers/net/sh_eth.c
new file mode 100644
index 0000000..5e132f2
--- /dev/null
+++ b/marvell/uboot/drivers/net/sh_eth.c
@@ -0,0 +1,655 @@
+/*
+ * sh_eth.c - Driver for Renesas ethernet controler.
+ *
+ * Copyright (C) 2008, 2011 Renesas Solutions Corp.
+ * Copyright (c) 2008, 2011 Nobuhiro Iwamatsu
+ * Copyright (c) 2007 Carlos Munoz <carlos@kenati.com>
+ * Copyright (C) 2013  Renesas Electronics Corporation
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <miiphy.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+
+#include "sh_eth.h"
+
+#ifndef CONFIG_SH_ETHER_USE_PORT
+# error "Please define CONFIG_SH_ETHER_USE_PORT"
+#endif
+#ifndef CONFIG_SH_ETHER_PHY_ADDR
+# error "Please define CONFIG_SH_ETHER_PHY_ADDR"
+#endif
+
+#if defined(CONFIG_SH_ETHER_CACHE_WRITEBACK) && !defined(CONFIG_SYS_DCACHE_OFF)
+#define flush_cache_wback(addr, len)    \
+		flush_dcache_range((u32)addr, (u32)(addr + len - 1))
+#else
+#define flush_cache_wback(...)
+#endif
+
+#if defined(CONFIG_SH_ETHER_CACHE_INVALIDATE) && defined(CONFIG_ARM)
+#define invalidate_cache(addr, len)		\
+	{	\
+		u32 line_size = CONFIG_SH_ETHER_ALIGNE_SIZE;	\
+		u32 start, end;	\
+		\
+		start = (u32)addr;	\
+		end = start + len;	\
+		start &= ~(line_size - 1);	\
+		end = ((end + line_size - 1) & ~(line_size - 1));	\
+		\
+		invalidate_dcache_range(start, end);	\
+	}
+#else
+#define invalidate_cache(...)
+#endif
+
+#define TIMEOUT_CNT 1000
+
+int sh_eth_send(struct eth_device *dev, void *packet, int len)
+{
+	struct sh_eth_dev *eth = dev->priv;
+	int port = eth->port, ret = 0, timeout;
+	struct sh_eth_info *port_info = &eth->port_info[port];
+
+	if (!packet || len > 0xffff) {
+		printf(SHETHER_NAME ": %s: Invalid argument\n", __func__);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	/* packet must be a 4 byte boundary */
+	if ((int)packet & 3) {
+		printf(SHETHER_NAME ": %s: packet not 4 byte alligned\n", __func__);
+		ret = -EFAULT;
+		goto err;
+	}
+
+	/* Update tx descriptor */
+	flush_cache_wback(packet, len);
+	port_info->tx_desc_cur->td2 = ADDR_TO_PHY(packet);
+	port_info->tx_desc_cur->td1 = len << 16;
+	/* Must preserve the end of descriptor list indication */
+	if (port_info->tx_desc_cur->td0 & TD_TDLE)
+		port_info->tx_desc_cur->td0 = TD_TACT | TD_TFP | TD_TDLE;
+	else
+		port_info->tx_desc_cur->td0 = TD_TACT | TD_TFP;
+
+	/* Restart the transmitter if disabled */
+	if (!(sh_eth_read(eth, EDTRR) & EDTRR_TRNS))
+		sh_eth_write(eth, EDTRR_TRNS, EDTRR);
+
+	/* Wait until packet is transmitted */
+	timeout = TIMEOUT_CNT;
+	do {
+		invalidate_cache(port_info->tx_desc_cur,
+				 sizeof(struct tx_desc_s));
+		udelay(100);
+	} while (port_info->tx_desc_cur->td0 & TD_TACT && timeout--);
+
+	if (timeout < 0) {
+		printf(SHETHER_NAME ": transmit timeout\n");
+		ret = -ETIMEDOUT;
+		goto err;
+	}
+
+	port_info->tx_desc_cur++;
+	if (port_info->tx_desc_cur >= port_info->tx_desc_base + NUM_TX_DESC)
+		port_info->tx_desc_cur = port_info->tx_desc_base;
+
+err:
+	return ret;
+}
+
+int sh_eth_recv(struct eth_device *dev)
+{
+	struct sh_eth_dev *eth = dev->priv;
+	int port = eth->port, len = 0;
+	struct sh_eth_info *port_info = &eth->port_info[port];
+	uchar *packet;
+
+	/* Check if the rx descriptor is ready */
+	invalidate_cache(port_info->rx_desc_cur, sizeof(struct rx_desc_s));
+	if (!(port_info->rx_desc_cur->rd0 & RD_RACT)) {
+		/* Check for errors */
+		if (!(port_info->rx_desc_cur->rd0 & RD_RFE)) {
+			len = port_info->rx_desc_cur->rd1 & 0xffff;
+			packet = (uchar *)
+				ADDR_TO_P2(port_info->rx_desc_cur->rd2);
+			invalidate_cache(packet, len);
+			NetReceive(packet, len);
+		}
+
+		/* Make current descriptor available again */
+		if (port_info->rx_desc_cur->rd0 & RD_RDLE)
+			port_info->rx_desc_cur->rd0 = RD_RACT | RD_RDLE;
+		else
+			port_info->rx_desc_cur->rd0 = RD_RACT;
+		/* Point to the next descriptor */
+		port_info->rx_desc_cur++;
+		if (port_info->rx_desc_cur >=
+		    port_info->rx_desc_base + NUM_RX_DESC)
+			port_info->rx_desc_cur = port_info->rx_desc_base;
+	}
+
+	/* Restart the receiver if disabled */
+	if (!(sh_eth_read(eth, EDRRR) & EDRRR_R))
+		sh_eth_write(eth, EDRRR_R, EDRRR);
+
+	return len;
+}
+
+static int sh_eth_reset(struct sh_eth_dev *eth)
+{
+#if defined(SH_ETH_TYPE_GETHER)
+	int ret = 0, i;
+
+	/* Start e-dmac transmitter and receiver */
+	sh_eth_write(eth, EDSR_ENALL, EDSR);
+
+	/* Perform a software reset and wait for it to complete */
+	sh_eth_write(eth, EDMR_SRST, EDMR);
+	for (i = 0; i < TIMEOUT_CNT ; i++) {
+		if (!(sh_eth_read(eth, EDMR) & EDMR_SRST))
+			break;
+		udelay(1000);
+	}
+
+	if (i == TIMEOUT_CNT) {
+		printf(SHETHER_NAME  ": Software reset timeout\n");
+		ret = -EIO;
+	}
+
+	return ret;
+#else
+	sh_eth_write(eth, sh_eth_read(eth, EDMR) | EDMR_SRST, EDMR);
+	udelay(3000);
+	sh_eth_write(eth, sh_eth_read(eth, EDMR) & ~EDMR_SRST, EDMR);
+
+	return 0;
+#endif
+}
+
+static int sh_eth_tx_desc_init(struct sh_eth_dev *eth)
+{
+	int port = eth->port, i, ret = 0;
+	u32 tmp_addr;
+	struct sh_eth_info *port_info = &eth->port_info[port];
+	struct tx_desc_s *cur_tx_desc;
+
+	/*
+	 * Allocate tx descriptors. They must be TX_DESC_SIZE bytes aligned
+	 */
+	port_info->tx_desc_malloc = malloc(NUM_TX_DESC *
+						 sizeof(struct tx_desc_s) +
+						 TX_DESC_SIZE - 1);
+	if (!port_info->tx_desc_malloc) {
+		printf(SHETHER_NAME ": malloc failed\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	tmp_addr = (u32) (((int)port_info->tx_desc_malloc + TX_DESC_SIZE - 1) &
+			  ~(TX_DESC_SIZE - 1));
+	flush_cache_wback(tmp_addr, NUM_TX_DESC * sizeof(struct tx_desc_s));
+	/* Make sure we use a P2 address (non-cacheable) */
+	port_info->tx_desc_base = (struct tx_desc_s *)ADDR_TO_P2(tmp_addr);
+	port_info->tx_desc_cur = port_info->tx_desc_base;
+
+	/* Initialize all descriptors */
+	for (cur_tx_desc = port_info->tx_desc_base, i = 0; i < NUM_TX_DESC;
+	     cur_tx_desc++, i++) {
+		cur_tx_desc->td0 = 0x00;
+		cur_tx_desc->td1 = 0x00;
+		cur_tx_desc->td2 = 0x00;
+	}
+
+	/* Mark the end of the descriptors */
+	cur_tx_desc--;
+	cur_tx_desc->td0 |= TD_TDLE;
+
+	/* Point the controller to the tx descriptor list. Must use physical
+	   addresses */
+	sh_eth_write(eth, ADDR_TO_PHY(port_info->tx_desc_base), TDLAR);
+#if defined(SH_ETH_TYPE_GETHER)
+	sh_eth_write(eth, ADDR_TO_PHY(port_info->tx_desc_base), TDFAR);
+	sh_eth_write(eth, ADDR_TO_PHY(cur_tx_desc), TDFXR);
+	sh_eth_write(eth, 0x01, TDFFR);/* Last discriptor bit */
+#endif
+
+err:
+	return ret;
+}
+
+static int sh_eth_rx_desc_init(struct sh_eth_dev *eth)
+{
+	int port = eth->port, i , ret = 0;
+	struct sh_eth_info *port_info = &eth->port_info[port];
+	struct rx_desc_s *cur_rx_desc;
+	u32 tmp_addr;
+	u8 *rx_buf;
+
+	/*
+	 * Allocate rx descriptors. They must be RX_DESC_SIZE bytes aligned
+	 */
+	port_info->rx_desc_malloc = malloc(NUM_RX_DESC *
+						 sizeof(struct rx_desc_s) +
+						 RX_DESC_SIZE - 1);
+	if (!port_info->rx_desc_malloc) {
+		printf(SHETHER_NAME ": malloc failed\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	tmp_addr = (u32) (((int)port_info->rx_desc_malloc + RX_DESC_SIZE - 1) &
+			  ~(RX_DESC_SIZE - 1));
+	flush_cache_wback(tmp_addr, NUM_RX_DESC * sizeof(struct rx_desc_s));
+	/* Make sure we use a P2 address (non-cacheable) */
+	port_info->rx_desc_base = (struct rx_desc_s *)ADDR_TO_P2(tmp_addr);
+
+	port_info->rx_desc_cur = port_info->rx_desc_base;
+
+	/*
+	 * Allocate rx data buffers. They must be 32 bytes aligned  and in
+	 * P2 area
+	 */
+	port_info->rx_buf_malloc = malloc(
+		NUM_RX_DESC * MAX_BUF_SIZE + RX_BUF_ALIGNE_SIZE - 1);
+	if (!port_info->rx_buf_malloc) {
+		printf(SHETHER_NAME ": malloc failed\n");
+		ret = -ENOMEM;
+		goto err_buf_malloc;
+	}
+
+	tmp_addr = (u32)(((int)port_info->rx_buf_malloc
+			  + (RX_BUF_ALIGNE_SIZE - 1)) &
+			  ~(RX_BUF_ALIGNE_SIZE - 1));
+	port_info->rx_buf_base = (u8 *)ADDR_TO_P2(tmp_addr);
+
+	/* Initialize all descriptors */
+	for (cur_rx_desc = port_info->rx_desc_base,
+	     rx_buf = port_info->rx_buf_base, i = 0;
+	     i < NUM_RX_DESC; cur_rx_desc++, rx_buf += MAX_BUF_SIZE, i++) {
+		cur_rx_desc->rd0 = RD_RACT;
+		cur_rx_desc->rd1 = MAX_BUF_SIZE << 16;
+		cur_rx_desc->rd2 = (u32) ADDR_TO_PHY(rx_buf);
+	}
+
+	/* Mark the end of the descriptors */
+	cur_rx_desc--;
+	cur_rx_desc->rd0 |= RD_RDLE;
+
+	/* Point the controller to the rx descriptor list */
+	sh_eth_write(eth, ADDR_TO_PHY(port_info->rx_desc_base), RDLAR);
+#if defined(SH_ETH_TYPE_GETHER)
+	sh_eth_write(eth, ADDR_TO_PHY(port_info->rx_desc_base), RDFAR);
+	sh_eth_write(eth, ADDR_TO_PHY(cur_rx_desc), RDFXR);
+	sh_eth_write(eth, RDFFR_RDLF, RDFFR);
+#endif
+
+	return ret;
+
+err_buf_malloc:
+	free(port_info->rx_desc_malloc);
+	port_info->rx_desc_malloc = NULL;
+
+err:
+	return ret;
+}
+
+static void sh_eth_tx_desc_free(struct sh_eth_dev *eth)
+{
+	int port = eth->port;
+	struct sh_eth_info *port_info = &eth->port_info[port];
+
+	if (port_info->tx_desc_malloc) {
+		free(port_info->tx_desc_malloc);
+		port_info->tx_desc_malloc = NULL;
+	}
+}
+
+static void sh_eth_rx_desc_free(struct sh_eth_dev *eth)
+{
+	int port = eth->port;
+	struct sh_eth_info *port_info = &eth->port_info[port];
+
+	if (port_info->rx_desc_malloc) {
+		free(port_info->rx_desc_malloc);
+		port_info->rx_desc_malloc = NULL;
+	}
+
+	if (port_info->rx_buf_malloc) {
+		free(port_info->rx_buf_malloc);
+		port_info->rx_buf_malloc = NULL;
+	}
+}
+
+static int sh_eth_desc_init(struct sh_eth_dev *eth)
+{
+	int ret = 0;
+
+	ret = sh_eth_tx_desc_init(eth);
+	if (ret)
+		goto err_tx_init;
+
+	ret = sh_eth_rx_desc_init(eth);
+	if (ret)
+		goto err_rx_init;
+
+	return ret;
+err_rx_init:
+	sh_eth_tx_desc_free(eth);
+
+err_tx_init:
+	return ret;
+}
+
+static int sh_eth_phy_config(struct sh_eth_dev *eth)
+{
+	int port = eth->port, ret = 0;
+	struct sh_eth_info *port_info = &eth->port_info[port];
+	struct eth_device *dev = port_info->dev;
+	struct phy_device *phydev;
+
+	phydev = phy_connect(
+			miiphy_get_dev_by_name(dev->name),
+			port_info->phy_addr, dev, CONFIG_SH_ETHER_PHY_MODE);
+	port_info->phydev = phydev;
+	phy_config(phydev);
+
+	return ret;
+}
+
+static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd)
+{
+	int port = eth->port, ret = 0;
+	u32 val;
+	struct sh_eth_info *port_info = &eth->port_info[port];
+	struct eth_device *dev = port_info->dev;
+	struct phy_device *phy;
+
+	/* Configure e-dmac registers */
+	sh_eth_write(eth, (sh_eth_read(eth, EDMR) & ~EMDR_DESC_R) |
+			(EMDR_DESC | EDMR_EL), EDMR);
+
+	sh_eth_write(eth, 0, EESIPR);
+	sh_eth_write(eth, 0, TRSCER);
+	sh_eth_write(eth, 0, TFTR);
+	sh_eth_write(eth, (FIFO_SIZE_T | FIFO_SIZE_R), FDR);
+	sh_eth_write(eth, RMCR_RST, RMCR);
+#if defined(SH_ETH_TYPE_GETHER)
+	sh_eth_write(eth, 0, RPADIR);
+#endif
+	sh_eth_write(eth, (FIFO_F_D_RFF | FIFO_F_D_RFD), FCFTR);
+
+	/* Configure e-mac registers */
+	sh_eth_write(eth, 0, ECSIPR);
+
+	/* Set Mac address */
+	val = dev->enetaddr[0] << 24 | dev->enetaddr[1] << 16 |
+	    dev->enetaddr[2] << 8 | dev->enetaddr[3];
+	sh_eth_write(eth, val, MAHR);
+
+	val = dev->enetaddr[4] << 8 | dev->enetaddr[5];
+	sh_eth_write(eth, val, MALR);
+
+	sh_eth_write(eth, RFLR_RFL_MIN, RFLR);
+#if defined(SH_ETH_TYPE_GETHER)
+	sh_eth_write(eth, 0, PIPR);
+	sh_eth_write(eth, APR_AP, APR);
+	sh_eth_write(eth, MPR_MP, MPR);
+	sh_eth_write(eth, TPAUSER_TPAUSE, TPAUSER);
+#endif
+
+#if defined(CONFIG_CPU_SH7734) || defined(CONFIG_R8A7740)
+	sh_eth_write(eth, CONFIG_SH_ETHER_SH7734_MII, RMII_MII);
+#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791)
+	sh_eth_write(eth, sh_eth_read(eth, RMIIMR) | 0x1, RMIIMR);
+#endif
+	/* Configure phy */
+	ret = sh_eth_phy_config(eth);
+	if (ret) {
+		printf(SHETHER_NAME ": phy config timeout\n");
+		goto err_phy_cfg;
+	}
+	phy = port_info->phydev;
+	ret = phy_startup(phy);
+	if (ret) {
+		printf(SHETHER_NAME ": phy startup failure\n");
+		return ret;
+	}
+
+	val = 0;
+
+	/* Set the transfer speed */
+	if (phy->speed == 100) {
+		printf(SHETHER_NAME ": 100Base/");
+#if defined(SH_ETH_TYPE_GETHER)
+		sh_eth_write(eth, GECMR_100B, GECMR);
+#elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752)
+		sh_eth_write(eth, 1, RTRATE);
+#elif defined(CONFIG_CPU_SH7724) || defined(CONFIG_R8A7790) || \
+		defined(CONFIG_R8A7791)
+		val = ECMR_RTM;
+#endif
+	} else if (phy->speed == 10) {
+		printf(SHETHER_NAME ": 10Base/");
+#if defined(SH_ETH_TYPE_GETHER)
+		sh_eth_write(eth, GECMR_10B, GECMR);
+#elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752)
+		sh_eth_write(eth, 0, RTRATE);
+#endif
+	}
+#if defined(SH_ETH_TYPE_GETHER)
+	else if (phy->speed == 1000) {
+		printf(SHETHER_NAME ": 1000Base/");
+		sh_eth_write(eth, GECMR_1000B, GECMR);
+	}
+#endif
+
+	/* Check if full duplex mode is supported by the phy */
+	if (phy->duplex) {
+		printf("Full\n");
+		sh_eth_write(eth, val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE|ECMR_DM),
+			     ECMR);
+	} else {
+		printf("Half\n");
+		sh_eth_write(eth, val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE), ECMR);
+	}
+
+	return ret;
+
+err_phy_cfg:
+	return ret;
+}
+
+static void sh_eth_start(struct sh_eth_dev *eth)
+{
+	/*
+	 * Enable the e-dmac receiver only. The transmitter will be enabled when
+	 * we have something to transmit
+	 */
+	sh_eth_write(eth, EDRRR_R, EDRRR);
+}
+
+static void sh_eth_stop(struct sh_eth_dev *eth)
+{
+	sh_eth_write(eth, ~EDRRR_R, EDRRR);
+}
+
+int sh_eth_init(struct eth_device *dev, bd_t *bd)
+{
+	int ret = 0;
+	struct sh_eth_dev *eth = dev->priv;
+
+	ret = sh_eth_reset(eth);
+	if (ret)
+		goto err;
+
+	ret = sh_eth_desc_init(eth);
+	if (ret)
+		goto err;
+
+	ret = sh_eth_config(eth, bd);
+	if (ret)
+		goto err_config;
+
+	sh_eth_start(eth);
+
+	return ret;
+
+err_config:
+	sh_eth_tx_desc_free(eth);
+	sh_eth_rx_desc_free(eth);
+
+err:
+	return ret;
+}
+
+void sh_eth_halt(struct eth_device *dev)
+{
+	struct sh_eth_dev *eth = dev->priv;
+	sh_eth_stop(eth);
+}
+
+int sh_eth_initialize(bd_t *bd)
+{
+    int ret = 0;
+	struct sh_eth_dev *eth = NULL;
+    struct eth_device *dev = NULL;
+
+    eth = (struct sh_eth_dev *)malloc(sizeof(struct sh_eth_dev));
+	if (!eth) {
+		printf(SHETHER_NAME ": %s: malloc failed\n", __func__);
+		ret = -ENOMEM;
+		goto err;
+	}
+
+    dev = (struct eth_device *)malloc(sizeof(struct eth_device));
+	if (!dev) {
+		printf(SHETHER_NAME ": %s: malloc failed\n", __func__);
+		ret = -ENOMEM;
+		goto err;
+	}
+    memset(dev, 0, sizeof(struct eth_device));
+    memset(eth, 0, sizeof(struct sh_eth_dev));
+
+	eth->port = CONFIG_SH_ETHER_USE_PORT;
+	eth->port_info[eth->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR;
+
+    dev->priv = (void *)eth;
+    dev->iobase = 0;
+    dev->init = sh_eth_init;
+    dev->halt = sh_eth_halt;
+    dev->send = sh_eth_send;
+    dev->recv = sh_eth_recv;
+    eth->port_info[eth->port].dev = dev;
+
+	sprintf(dev->name, SHETHER_NAME);
+
+    /* Register Device to EtherNet subsystem  */
+    eth_register(dev);
+
+	bb_miiphy_buses[0].priv = eth;
+	miiphy_register(dev->name, bb_miiphy_read, bb_miiphy_write);
+
+	if (!eth_getenv_enetaddr("ethaddr", dev->enetaddr))
+		puts("Please set MAC address\n");
+
+	return ret;
+
+err:
+	if (dev)
+		free(dev);
+
+	if (eth)
+		free(eth);
+
+	printf(SHETHER_NAME ": Failed\n");
+	return ret;
+}
+
+/******* for bb_miiphy *******/
+static int sh_eth_bb_init(struct bb_miiphy_bus *bus)
+{
+	return 0;
+}
+
+static int sh_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
+{
+	struct sh_eth_dev *eth = bus->priv;
+
+	sh_eth_write(eth, sh_eth_read(eth, PIR) | PIR_MMD, PIR);
+
+	return 0;
+}
+
+static int sh_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus)
+{
+	struct sh_eth_dev *eth = bus->priv;
+
+	sh_eth_write(eth, sh_eth_read(eth, PIR) & ~PIR_MMD, PIR);
+
+	return 0;
+}
+
+static int sh_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
+{
+	struct sh_eth_dev *eth = bus->priv;
+
+	if (v)
+		sh_eth_write(eth, sh_eth_read(eth, PIR) | PIR_MDO, PIR);
+	else
+		sh_eth_write(eth, sh_eth_read(eth, PIR) & ~PIR_MDO, PIR);
+
+	return 0;
+}
+
+static int sh_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
+{
+	struct sh_eth_dev *eth = bus->priv;
+
+	*v = (sh_eth_read(eth, PIR) & PIR_MDI) >> 3;
+
+	return 0;
+}
+
+static int sh_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
+{
+	struct sh_eth_dev *eth = bus->priv;
+
+	if (v)
+		sh_eth_write(eth, sh_eth_read(eth, PIR) | PIR_MDC, PIR);
+	else
+		sh_eth_write(eth, sh_eth_read(eth, PIR) & ~PIR_MDC, PIR);
+
+	return 0;
+}
+
+static int sh_eth_bb_delay(struct bb_miiphy_bus *bus)
+{
+	udelay(10);
+
+	return 0;
+}
+
+struct bb_miiphy_bus bb_miiphy_buses[] = {
+	{
+		.name		= "sh_eth",
+		.init		= sh_eth_bb_init,
+		.mdio_active	= sh_eth_bb_mdio_active,
+		.mdio_tristate	= sh_eth_bb_mdio_tristate,
+		.set_mdio	= sh_eth_bb_set_mdio,
+		.get_mdio	= sh_eth_bb_get_mdio,
+		.set_mdc	= sh_eth_bb_set_mdc,
+		.delay		= sh_eth_bb_delay,
+	}
+};
+int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);
diff --git a/marvell/uboot/drivers/net/sh_eth.h b/marvell/uboot/drivers/net/sh_eth.h
new file mode 100644
index 0000000..331c07c
--- /dev/null
+++ b/marvell/uboot/drivers/net/sh_eth.h
@@ -0,0 +1,624 @@
+/*
+ * sh_eth.h - Driver for Renesas SuperH ethernet controler.
+ *
+ * Copyright (C) 2008 - 2012 Renesas Solutions Corp.
+ * Copyright (c) 2008 - 2012 Nobuhiro Iwamatsu
+ * Copyright (c) 2007 Carlos Munoz <carlos@kenati.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <netdev.h>
+#include <asm/types.h>
+
+#define SHETHER_NAME "sh_eth"
+
+#if defined(CONFIG_SH)
+/* Malloc returns addresses in the P1 area (cacheable). However we need to
+   use area P2 (non-cacheable) */
+#define ADDR_TO_P2(addr)	((((int)(addr) & ~0xe0000000) | 0xa0000000))
+
+/* The ethernet controller needs to use physical addresses */
+#if defined(CONFIG_SH_32BIT)
+#define ADDR_TO_PHY(addr)	((((int)(addr) & ~0xe0000000) | 0x40000000))
+#else
+#define ADDR_TO_PHY(addr)	((int)(addr) & ~0xe0000000)
+#endif
+#elif defined(CONFIG_ARM)
+#define inl		readl
+#define outl	writel
+#define ADDR_TO_PHY(addr)	((int)(addr))
+#define ADDR_TO_P2(addr)	(addr)
+#endif /* defined(CONFIG_SH) */
+
+/* base padding size is 16 */
+#ifndef CONFIG_SH_ETHER_ALIGNE_SIZE
+#define CONFIG_SH_ETHER_ALIGNE_SIZE 16
+#endif
+
+/* Number of supported ports */
+#define MAX_PORT_NUM	2
+
+/* Buffers must be big enough to hold the largest ethernet frame. Also, rx
+   buffers must be a multiple of 32 bytes */
+#define MAX_BUF_SIZE	(48 * 32)
+
+/* The number of tx descriptors must be large enough to point to 5 or more
+   frames. If each frame uses 2 descriptors, at least 10 descriptors are needed.
+   We use one descriptor per frame */
+#define NUM_TX_DESC		8
+
+/* The size of the tx descriptor is determined by how much padding is used.
+   4, 20, or 52 bytes of padding can be used */
+#define TX_DESC_PADDING	(CONFIG_SH_ETHER_ALIGNE_SIZE - 12)
+/* same as CONFIG_SH_ETHER_ALIGNE_SIZE */
+#define TX_DESC_SIZE	(12 + TX_DESC_PADDING)
+
+/* Tx descriptor. We always use 3 bytes of padding */
+struct tx_desc_s {
+	volatile u32 td0;
+	u32 td1;
+	u32 td2;		/* Buffer start */
+	u8 padding[TX_DESC_PADDING];	/* aligned cache line size */
+};
+
+/* There is no limitation in the number of rx descriptors */
+#define NUM_RX_DESC	8
+
+/* The size of the rx descriptor is determined by how much padding is used.
+   4, 20, or 52 bytes of padding can be used */
+#define RX_DESC_PADDING	(CONFIG_SH_ETHER_ALIGNE_SIZE - 12)
+/* same as CONFIG_SH_ETHER_ALIGNE_SIZE */
+#define RX_DESC_SIZE		(12 + RX_DESC_PADDING)
+/* aligned cache line size */
+#define RX_BUF_ALIGNE_SIZE	(CONFIG_SH_ETHER_ALIGNE_SIZE > 32 ? 64 : 32)
+
+/* Rx descriptor. We always use 4 bytes of padding */
+struct rx_desc_s {
+	volatile u32 rd0;
+	volatile u32 rd1;
+	u32 rd2;		/* Buffer start */
+	u8 padding[TX_DESC_PADDING];	/* aligned cache line size */
+};
+
+struct sh_eth_info {
+	struct tx_desc_s *tx_desc_malloc;
+	struct tx_desc_s *tx_desc_base;
+	struct tx_desc_s *tx_desc_cur;
+	struct rx_desc_s *rx_desc_malloc;
+	struct rx_desc_s *rx_desc_base;
+	struct rx_desc_s *rx_desc_cur;
+	u8 *rx_buf_malloc;
+	u8 *rx_buf_base;
+	u8 mac_addr[6];
+	u8 phy_addr;
+	struct eth_device *dev;
+	struct phy_device *phydev;
+};
+
+struct sh_eth_dev {
+	int port;
+	struct sh_eth_info port_info[MAX_PORT_NUM];
+};
+
+/* from linux/drivers/net/ethernet/renesas/sh_eth.h */
+enum {
+	/* E-DMAC registers */
+	EDSR = 0,
+	EDMR,
+	EDTRR,
+	EDRRR,
+	EESR,
+	EESIPR,
+	TDLAR,
+	TDFAR,
+	TDFXR,
+	TDFFR,
+	RDLAR,
+	RDFAR,
+	RDFXR,
+	RDFFR,
+	TRSCER,
+	RMFCR,
+	TFTR,
+	FDR,
+	RMCR,
+	EDOCR,
+	TFUCR,
+	RFOCR,
+	FCFTR,
+	RPADIR,
+	TRIMD,
+	RBWAR,
+	TBRAR,
+
+	/* Ether registers */
+	ECMR,
+	ECSR,
+	ECSIPR,
+	PIR,
+	PSR,
+	RDMLR,
+	PIPR,
+	RFLR,
+	IPGR,
+	APR,
+	MPR,
+	PFTCR,
+	PFRCR,
+	RFCR,
+	RFCF,
+	TPAUSER,
+	TPAUSECR,
+	BCFR,
+	BCFRR,
+	GECMR,
+	BCULR,
+	MAHR,
+	MALR,
+	TROCR,
+	CDCR,
+	LCCR,
+	CNDCR,
+	CEFCR,
+	FRECR,
+	TSFRCR,
+	TLFRCR,
+	CERCR,
+	CEECR,
+	RMIIMR, /* R8A7790 */
+	MAFCR,
+	RTRATE,
+	CSMR,
+	RMII_MII,
+
+	/* This value must be written at last. */
+	SH_ETH_MAX_REGISTER_OFFSET,
+};
+
+static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
+	[EDSR]	= 0x0000,
+	[EDMR]	= 0x0400,
+	[EDTRR]	= 0x0408,
+	[EDRRR]	= 0x0410,
+	[EESR]	= 0x0428,
+	[EESIPR]	= 0x0430,
+	[TDLAR]	= 0x0010,
+	[TDFAR]	= 0x0014,
+	[TDFXR]	= 0x0018,
+	[TDFFR]	= 0x001c,
+	[RDLAR]	= 0x0030,
+	[RDFAR]	= 0x0034,
+	[RDFXR]	= 0x0038,
+	[RDFFR]	= 0x003c,
+	[TRSCER]	= 0x0438,
+	[RMFCR]	= 0x0440,
+	[TFTR]	= 0x0448,
+	[FDR]	= 0x0450,
+	[RMCR]	= 0x0458,
+	[RPADIR]	= 0x0460,
+	[FCFTR]	= 0x0468,
+	[CSMR] = 0x04E4,
+
+	[ECMR]	= 0x0500,
+	[ECSR]	= 0x0510,
+	[ECSIPR]	= 0x0518,
+	[PIR]	= 0x0520,
+	[PSR]	= 0x0528,
+	[PIPR]	= 0x052c,
+	[RFLR]	= 0x0508,
+	[APR]	= 0x0554,
+	[MPR]	= 0x0558,
+	[PFTCR]	= 0x055c,
+	[PFRCR]	= 0x0560,
+	[TPAUSER]	= 0x0564,
+	[GECMR]	= 0x05b0,
+	[BCULR]	= 0x05b4,
+	[MAHR]	= 0x05c0,
+	[MALR]	= 0x05c8,
+	[TROCR]	= 0x0700,
+	[CDCR]	= 0x0708,
+	[LCCR]	= 0x0710,
+	[CEFCR]	= 0x0740,
+	[FRECR]	= 0x0748,
+	[TSFRCR]	= 0x0750,
+	[TLFRCR]	= 0x0758,
+	[RFCR]	= 0x0760,
+	[CERCR]	= 0x0768,
+	[CEECR]	= 0x0770,
+	[MAFCR]	= 0x0778,
+	[RMII_MII] =  0x0790,
+};
+
+static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
+	[ECMR]	= 0x0100,
+	[RFLR]	= 0x0108,
+	[ECSR]	= 0x0110,
+	[ECSIPR]	= 0x0118,
+	[PIR]	= 0x0120,
+	[PSR]	= 0x0128,
+	[RDMLR]	= 0x0140,
+	[IPGR]	= 0x0150,
+	[APR]	= 0x0154,
+	[MPR]	= 0x0158,
+	[TPAUSER]	= 0x0164,
+	[RFCF]	= 0x0160,
+	[TPAUSECR]	= 0x0168,
+	[BCFRR]	= 0x016c,
+	[MAHR]	= 0x01c0,
+	[MALR]	= 0x01c8,
+	[TROCR]	= 0x01d0,
+	[CDCR]	= 0x01d4,
+	[LCCR]	= 0x01d8,
+	[CNDCR]	= 0x01dc,
+	[CEFCR]	= 0x01e4,
+	[FRECR]	= 0x01e8,
+	[TSFRCR]	= 0x01ec,
+	[TLFRCR]	= 0x01f0,
+	[RFCR]	= 0x01f4,
+	[MAFCR]	= 0x01f8,
+	[RTRATE]	= 0x01fc,
+
+	[EDMR]	= 0x0000,
+	[EDTRR]	= 0x0008,
+	[EDRRR]	= 0x0010,
+	[TDLAR]	= 0x0018,
+	[RDLAR]	= 0x0020,
+	[EESR]	= 0x0028,
+	[EESIPR]	= 0x0030,
+	[TRSCER]	= 0x0038,
+	[RMFCR]	= 0x0040,
+	[TFTR]	= 0x0048,
+	[FDR]	= 0x0050,
+	[RMCR]	= 0x0058,
+	[TFUCR]	= 0x0064,
+	[RFOCR]	= 0x0068,
+	[RMIIMR] = 0x006C,
+	[FCFTR]	= 0x0070,
+	[RPADIR]	= 0x0078,
+	[TRIMD]	= 0x007c,
+	[RBWAR]	= 0x00c8,
+	[RDFAR]	= 0x00cc,
+	[TBRAR]	= 0x00d4,
+	[TDFAR]	= 0x00d8,
+};
+
+/* Register Address */
+#if defined(CONFIG_CPU_SH7763) || defined(CONFIG_CPU_SH7734)
+#define SH_ETH_TYPE_GETHER
+#define BASE_IO_ADDR	0xfee00000
+#elif defined(CONFIG_CPU_SH7757) || \
+	defined(CONFIG_CPU_SH7752) || \
+	defined(CONFIG_CPU_SH7753)
+#if defined(CONFIG_SH_ETHER_USE_GETHER)
+#define SH_ETH_TYPE_GETHER
+#define BASE_IO_ADDR	0xfee00000
+#else
+#define SH_ETH_TYPE_ETHER
+#define BASE_IO_ADDR	0xfef00000
+#endif
+#elif defined(CONFIG_CPU_SH7724)
+#define SH_ETH_TYPE_ETHER
+#define BASE_IO_ADDR	0xA4600000
+#elif defined(CONFIG_R8A7740)
+#define SH_ETH_TYPE_GETHER
+#define BASE_IO_ADDR	0xE9A00000
+#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791)
+#define SH_ETH_TYPE_ETHER
+#define BASE_IO_ADDR	0xEE700200
+#endif
+
+/*
+ * Register's bits
+ * Copy from Linux driver source code
+ */
+#if defined(SH_ETH_TYPE_GETHER)
+/* EDSR */
+enum EDSR_BIT {
+	EDSR_ENT = 0x01, EDSR_ENR = 0x02,
+};
+#define EDSR_ENALL (EDSR_ENT|EDSR_ENR)
+#endif
+
+/* EDMR */
+enum DMAC_M_BIT {
+	EDMR_DL1 = 0x20, EDMR_DL0 = 0x10,
+#if defined(SH_ETH_TYPE_GETHER)
+	EDMR_SRST	= 0x03, /* Receive/Send reset */
+	EMDR_DESC_R	= 0x30, /* Descriptor reserve size */
+	EDMR_EL		= 0x40, /* Litte endian */
+#elif defined(SH_ETH_TYPE_ETHER)
+	EDMR_SRST	= 0x01,
+	EMDR_DESC_R	= 0x30, /* Descriptor reserve size */
+	EDMR_EL		= 0x40, /* Litte endian */
+#else
+	EDMR_SRST = 0x01,
+#endif
+};
+
+#if CONFIG_SH_ETHER_ALIGNE_SIZE == 64
+# define EMDR_DESC EDMR_DL1
+#elif CONFIG_SH_ETHER_ALIGNE_SIZE == 32
+# define EMDR_DESC EDMR_DL0
+#elif CONFIG_SH_ETHER_ALIGNE_SIZE == 16 /* Default */
+# define EMDR_DESC 0
+#endif
+
+/* RFLR */
+#define RFLR_RFL_MIN	0x05EE	/* Recv Frame length 1518 byte */
+
+/* EDTRR */
+enum DMAC_T_BIT {
+#if defined(SH_ETH_TYPE_GETHER)
+	EDTRR_TRNS = 0x03,
+#else
+	EDTRR_TRNS = 0x01,
+#endif
+};
+
+/* GECMR */
+enum GECMR_BIT {
+#if defined(CONFIG_CPU_SH7757) || \
+	defined(CONFIG_CPU_SH7752) || \
+	defined(CONFIG_CPU_SH7753)
+	GECMR_1000B = 0x20, GECMR_100B = 0x01, GECMR_10B = 0x00,
+#else
+	GECMR_1000B = 0x01, GECMR_100B = 0x04, GECMR_10B = 0x00,
+#endif
+};
+
+/* EDRRR*/
+enum EDRRR_R_BIT {
+	EDRRR_R = 0x01,
+};
+
+/* TPAUSER */
+enum TPAUSER_BIT {
+	TPAUSER_TPAUSE = 0x0000ffff,
+	TPAUSER_UNLIMITED = 0,
+};
+
+/* BCFR */
+enum BCFR_BIT {
+	BCFR_RPAUSE = 0x0000ffff,
+	BCFR_UNLIMITED = 0,
+};
+
+/* PIR */
+enum PIR_BIT {
+	PIR_MDI = 0x08, PIR_MDO = 0x04, PIR_MMD = 0x02, PIR_MDC = 0x01,
+};
+
+/* PSR */
+enum PHY_STATUS_BIT { PHY_ST_LINK = 0x01, };
+
+/* EESR */
+enum EESR_BIT {
+
+#if defined(SH_ETH_TYPE_ETHER)
+	EESR_TWB  = 0x40000000,
+#else
+	EESR_TWB  = 0xC0000000,
+	EESR_TC1  = 0x20000000,
+	EESR_TUC  = 0x10000000,
+	EESR_ROC  = 0x80000000,
+#endif
+	EESR_TABT = 0x04000000,
+	EESR_RABT = 0x02000000, EESR_RFRMER = 0x01000000,
+#if defined(SH_ETH_TYPE_ETHER)
+	EESR_ADE  = 0x00800000,
+#endif
+	EESR_ECI  = 0x00400000,
+	EESR_FTC  = 0x00200000, EESR_TDE  = 0x00100000,
+	EESR_TFE  = 0x00080000, EESR_FRC  = 0x00040000,
+	EESR_RDE  = 0x00020000, EESR_RFE  = 0x00010000,
+#if defined(SH_ETH_TYPE_ETHER)
+	EESR_CND  = 0x00000800,
+#endif
+	EESR_DLC  = 0x00000400,
+	EESR_CD   = 0x00000200, EESR_RTO  = 0x00000100,
+	EESR_RMAF = 0x00000080, EESR_CEEF = 0x00000040,
+	EESR_CELF = 0x00000020, EESR_RRF  = 0x00000010,
+	rESR_RTLF = 0x00000008, EESR_RTSF = 0x00000004,
+	EESR_PRE  = 0x00000002, EESR_CERF = 0x00000001,
+};
+
+
+#if defined(SH_ETH_TYPE_GETHER)
+# define TX_CHECK (EESR_TC1 | EESR_FTC)
+# define EESR_ERR_CHECK	(EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
+		| EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI)
+# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE)
+
+#else
+# define TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO)
+# define EESR_ERR_CHECK	(EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
+		| EESR_RFRMER | EESR_ADE | EESR_TFE | EESR_TDE | EESR_ECI)
+# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE)
+#endif
+
+/* EESIPR */
+enum DMAC_IM_BIT {
+	DMAC_M_TWB = 0x40000000, DMAC_M_TABT = 0x04000000,
+	DMAC_M_RABT = 0x02000000,
+	DMAC_M_RFRMER = 0x01000000, DMAC_M_ADF = 0x00800000,
+	DMAC_M_ECI = 0x00400000, DMAC_M_FTC = 0x00200000,
+	DMAC_M_TDE = 0x00100000, DMAC_M_TFE = 0x00080000,
+	DMAC_M_FRC = 0x00040000, DMAC_M_RDE = 0x00020000,
+	DMAC_M_RFE = 0x00010000, DMAC_M_TINT4 = 0x00000800,
+	DMAC_M_TINT3 = 0x00000400, DMAC_M_TINT2 = 0x00000200,
+	DMAC_M_TINT1 = 0x00000100, DMAC_M_RINT8 = 0x00000080,
+	DMAC_M_RINT5 = 0x00000010, DMAC_M_RINT4 = 0x00000008,
+	DMAC_M_RINT3 = 0x00000004, DMAC_M_RINT2 = 0x00000002,
+	DMAC_M_RINT1 = 0x00000001,
+};
+
+/* Receive descriptor bit */
+enum RD_STS_BIT {
+	RD_RACT = 0x80000000, RD_RDLE = 0x40000000,
+	RD_RFP1 = 0x20000000, RD_RFP0 = 0x10000000,
+	RD_RFE = 0x08000000, RD_RFS10 = 0x00000200,
+	RD_RFS9 = 0x00000100, RD_RFS8 = 0x00000080,
+	RD_RFS7 = 0x00000040, RD_RFS6 = 0x00000020,
+	RD_RFS5 = 0x00000010, RD_RFS4 = 0x00000008,
+	RD_RFS3 = 0x00000004, RD_RFS2 = 0x00000002,
+	RD_RFS1 = 0x00000001,
+};
+#define RDF1ST	RD_RFP1
+#define RDFEND	RD_RFP0
+#define RD_RFP	(RD_RFP1|RD_RFP0)
+
+/* RDFFR*/
+enum RDFFR_BIT {
+	RDFFR_RDLF = 0x01,
+};
+
+/* FCFTR */
+enum FCFTR_BIT {
+	FCFTR_RFF2 = 0x00040000, FCFTR_RFF1 = 0x00020000,
+	FCFTR_RFF0 = 0x00010000, FCFTR_RFD2 = 0x00000004,
+	FCFTR_RFD1 = 0x00000002, FCFTR_RFD0 = 0x00000001,
+};
+#define FIFO_F_D_RFF	(FCFTR_RFF2|FCFTR_RFF1|FCFTR_RFF0)
+#define FIFO_F_D_RFD	(FCFTR_RFD2|FCFTR_RFD1|FCFTR_RFD0)
+
+/* Transfer descriptor bit */
+enum TD_STS_BIT {
+#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_ETHER)
+	TD_TACT = 0x80000000,
+#else
+	TD_TACT = 0x7fffffff,
+#endif
+	TD_TDLE = 0x40000000, TD_TFP1 = 0x20000000,
+	TD_TFP0 = 0x10000000,
+};
+#define TDF1ST	TD_TFP1
+#define TDFEND	TD_TFP0
+#define TD_TFP	(TD_TFP1|TD_TFP0)
+
+/* RMCR */
+enum RECV_RST_BIT { RMCR_RST = 0x01, };
+/* ECMR */
+enum FELIC_MODE_BIT {
+#if defined(SH_ETH_TYPE_GETHER)
+	ECMR_TRCCM=0x04000000, ECMR_RCSC= 0x00800000, ECMR_DPAD= 0x00200000,
+	ECMR_RZPF = 0x00100000,
+#endif
+	ECMR_ZPF = 0x00080000, ECMR_PFR = 0x00040000, ECMR_RXF = 0x00020000,
+	ECMR_TXF = 0x00010000, ECMR_MCT = 0x00002000, ECMR_PRCEF = 0x00001000,
+	ECMR_PMDE = 0x00000200, ECMR_RE = 0x00000040, ECMR_TE = 0x00000020,
+	ECMR_ILB = 0x00000008, ECMR_ELB = 0x00000004, ECMR_DM = 0x00000002,
+	ECMR_PRM = 0x00000001,
+#ifdef CONFIG_CPU_SH7724
+	ECMR_RTM = 0x00000010,
+#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791)
+	ECMR_RTM = 0x00000004,
+#endif
+
+};
+
+#if defined(SH_ETH_TYPE_GETHER)
+#define ECMR_CHG_DM	(ECMR_TRCCM | ECMR_RZPF | ECMR_ZPF | ECMR_PFR | ECMR_RXF | \
+						ECMR_TXF | ECMR_MCT)
+#elif defined(SH_ETH_TYPE_ETHER)
+#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF)
+#else
+#define ECMR_CHG_DM	(ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT)
+#endif
+
+/* ECSR */
+enum ECSR_STATUS_BIT {
+#if defined(SH_ETH_TYPE_ETHER)
+	ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10,
+#endif
+	ECSR_LCHNG = 0x04,
+	ECSR_MPD = 0x02, ECSR_ICD = 0x01,
+};
+
+#if defined(SH_ETH_TYPE_GETHER)
+# define ECSR_INIT (ECSR_ICD | ECSIPR_MPDIP)
+#else
+# define ECSR_INIT (ECSR_BRCRX | ECSR_PSRTO | \
+			ECSR_LCHNG | ECSR_ICD | ECSIPR_MPDIP)
+#endif
+
+/* ECSIPR */
+enum ECSIPR_STATUS_MASK_BIT {
+#if defined(SH_ETH_TYPE_ETHER)
+	ECSIPR_BRCRXIP = 0x20,
+	ECSIPR_PSRTOIP = 0x10,
+#elif defined(SH_ETY_TYPE_GETHER)
+	ECSIPR_PSRTOIP = 0x10,
+	ECSIPR_PHYIP = 0x08,
+#endif
+	ECSIPR_LCHNGIP = 0x04,
+	ECSIPR_MPDIP = 0x02,
+	ECSIPR_ICDIP = 0x01,
+};
+
+#if defined(SH_ETH_TYPE_GETHER)
+# define ECSIPR_INIT (ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP)
+#else
+# define ECSIPR_INIT (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | \
+				ECSIPR_ICDIP | ECSIPR_MPDIP)
+#endif
+
+/* APR */
+enum APR_BIT {
+	APR_AP = 0x00000004,
+};
+
+/* MPR */
+enum MPR_BIT {
+	MPR_MP = 0x00000006,
+};
+
+/* TRSCER */
+enum DESC_I_BIT {
+	DESC_I_TINT4 = 0x0800, DESC_I_TINT3 = 0x0400, DESC_I_TINT2 = 0x0200,
+	DESC_I_TINT1 = 0x0100, DESC_I_RINT8 = 0x0080, DESC_I_RINT5 = 0x0010,
+	DESC_I_RINT4 = 0x0008, DESC_I_RINT3 = 0x0004, DESC_I_RINT2 = 0x0002,
+	DESC_I_RINT1 = 0x0001,
+};
+
+/* RPADIR */
+enum RPADIR_BIT {
+	RPADIR_PADS1 = 0x20000, RPADIR_PADS0 = 0x10000,
+	RPADIR_PADR = 0x0003f,
+};
+
+#if defined(SH_ETH_TYPE_GETHER)
+# define RPADIR_INIT (0x00)
+#else
+# define RPADIR_INIT (RPADIR_PADS1)
+#endif
+
+/* FDR */
+enum FIFO_SIZE_BIT {
+	FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007,
+};
+
+static inline unsigned long sh_eth_reg_addr(struct sh_eth_dev *eth,
+					    int enum_index)
+{
+#if defined(SH_ETH_TYPE_GETHER)
+	const u16 *reg_offset = sh_eth_offset_gigabit;
+#elif defined(SH_ETH_TYPE_ETHER)
+	const u16 *reg_offset = sh_eth_offset_fast_sh4;
+#else
+#error
+#endif
+	return BASE_IO_ADDR + reg_offset[enum_index] + 0x800 * eth->port;
+}
+
+static inline void sh_eth_write(struct sh_eth_dev *eth, unsigned long data,
+				int enum_index)
+{
+	outl(data, sh_eth_reg_addr(eth, enum_index));
+}
+
+static inline unsigned long sh_eth_read(struct sh_eth_dev *eth,
+					int enum_index)
+{
+	return inl(sh_eth_reg_addr(eth, enum_index));
+}
diff --git a/marvell/uboot/drivers/net/smc91111.c b/marvell/uboot/drivers/net/smc91111.c
new file mode 100644
index 0000000..57c667a
--- /dev/null
+++ b/marvell/uboot/drivers/net/smc91111.c
@@ -0,0 +1,1355 @@
+/*------------------------------------------------------------------------
+ . smc91111.c
+ . This is a driver for SMSC's 91C111 single-chip Ethernet device.
+ .
+ . (C) Copyright 2002
+ . Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ . Rolf Offermanns <rof@sysgo.de>
+ .
+ . Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
+ .	 Developed by Simple Network Magic Corporation (SNMC)
+ . Copyright (C) 1996 by Erik Stahlman (ES)
+ .
+ * SPDX-License-Identifier:	GPL-2.0+
+ .
+ . Information contained in this file was obtained from the LAN91C111
+ . manual from SMC.  To get a copy, if you really want one, you can find
+ . information under www.smsc.com.
+ .
+ .
+ . "Features" of the SMC chip:
+ .   Integrated PHY/MAC for 10/100BaseT Operation
+ .   Supports internal and external MII
+ .   Integrated 8K packet memory
+ .   EEPROM interface for configuration
+ .
+ . Arguments:
+ .	io	= for the base address
+ .	irq	= for the IRQ
+ .
+ . author:
+ .	Erik Stahlman				( erik@vt.edu )
+ .	Daris A Nevil				( dnevil@snmc.com )
+ .
+ .
+ . Hardware multicast code from Peter Cammaert ( pc@denkart.be )
+ .
+ . Sources:
+ .    o	  SMSC LAN91C111 databook (www.smsc.com)
+ .    o	  smc9194.c by Erik Stahlman
+ .    o	  skeleton.c by Donald Becker ( becker@cesdis.gsfc.nasa.gov )
+ .
+ . History:
+ .	06/19/03  Richard Woodruff Made u-boot environment aware and added mac addr checks.
+ .	10/17/01  Marco Hasewinkel Modify for DNP/1110
+ .	07/25/01  Woojung Huh	   Modify for ADS Bitsy
+ .	04/25/01  Daris A Nevil	   Initial public release through SMSC
+ .	03/16/01  Daris A Nevil	   Modified smc9194.c for use with LAN91C111
+ ----------------------------------------------------------------------------*/
+
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <malloc.h>
+#include "smc91111.h"
+#include <net.h>
+
+/* Use power-down feature of the chip */
+#define POWER_DOWN	0
+
+#define NO_AUTOPROBE
+
+#define SMC_DEBUG 0
+
+#if SMC_DEBUG > 1
+static const char version[] =
+	"smc91111.c:v1.0 04/25/01 by Daris A Nevil (dnevil@snmc.com)\n";
+#endif
+
+/* Autonegotiation timeout in seconds */
+#ifndef CONFIG_SMC_AUTONEG_TIMEOUT
+#define CONFIG_SMC_AUTONEG_TIMEOUT 10
+#endif
+
+/*------------------------------------------------------------------------
+ .
+ . Configuration options, for the experienced user to change.
+ .
+ -------------------------------------------------------------------------*/
+
+/*
+ . Wait time for memory to be free.  This probably shouldn't be
+ . tuned that much, as waiting for this means nothing else happens
+ . in the system
+*/
+#define MEMORY_WAIT_TIME 16
+
+
+#if (SMC_DEBUG > 2 )
+#define PRINTK3(args...) printf(args)
+#else
+#define PRINTK3(args...)
+#endif
+
+#if SMC_DEBUG > 1
+#define PRINTK2(args...) printf(args)
+#else
+#define PRINTK2(args...)
+#endif
+
+#ifdef SMC_DEBUG
+#define PRINTK(args...) printf(args)
+#else
+#define PRINTK(args...)
+#endif
+
+
+/*------------------------------------------------------------------------
+ .
+ . The internal workings of the driver.	 If you are changing anything
+ . here with the SMC stuff, you should have the datasheet and know
+ . what you are doing.
+ .
+ -------------------------------------------------------------------------*/
+
+/* Memory sizing constant */
+#define LAN91C111_MEMORY_MULTIPLIER	(1024*2)
+
+#ifndef CONFIG_SMC91111_BASE
+#error "SMC91111 Base address must be passed to initialization funciton"
+/* #define CONFIG_SMC91111_BASE 0x20000300 */
+#endif
+
+#define SMC_DEV_NAME "SMC91111"
+#define SMC_PHY_ADDR 0x0000
+#define SMC_ALLOC_MAX_TRY 5
+#define SMC_TX_TIMEOUT 30
+
+#define SMC_PHY_CLOCK_DELAY 1000
+
+#define ETH_ZLEN 60
+
+#ifdef	CONFIG_SMC_USE_32_BIT
+#define USE_32_BIT  1
+#else
+#undef USE_32_BIT
+#endif
+
+#ifdef SHARED_RESOURCES
+extern void swap_to(int device_id);
+#else
+# define swap_to(x)
+#endif
+
+#ifndef CONFIG_SMC91111_EXT_PHY
+static void smc_phy_configure(struct eth_device *dev);
+#endif /* !CONFIG_SMC91111_EXT_PHY */
+
+/*
+ ------------------------------------------------------------
+ .
+ . Internal routines
+ .
+ ------------------------------------------------------------
+*/
+
+#ifdef CONFIG_SMC_USE_IOFUNCS
+/*
+ * input and output functions
+ *
+ * Implemented due to inx,outx macros accessing the device improperly
+ * and putting the device into an unkown state.
+ *
+ * For instance, on Sharp LPD7A400 SDK, affects were chip memory
+ * could not be free'd (hence the alloc failures), duplicate packets,
+ * packets being corrupt (shifted) on the wire, etc.  Switching to the
+ * inx,outx functions fixed this problem.
+ */
+
+static inline word SMC_inw(struct eth_device *dev, dword offset)
+{
+	word v;
+	v = *((volatile word*)(dev->iobase + offset));
+	barrier(); *(volatile u32*)(0xc0000000);
+	return v;
+}
+
+static inline void SMC_outw(struct eth_device *dev, word value, dword offset)
+{
+	*((volatile word*)(dev->iobase + offset)) = value;
+	barrier(); *(volatile u32*)(0xc0000000);
+}
+
+static inline byte SMC_inb(struct eth_device *dev, dword offset)
+{
+	word  _w;
+
+	_w = SMC_inw(dev, offset & ~((dword)1));
+	return (offset & 1) ? (byte)(_w >> 8) : (byte)(_w);
+}
+
+static inline void SMC_outb(struct eth_device *dev, byte value, dword offset)
+{
+	word  _w;
+
+	_w = SMC_inw(dev, offset & ~((dword)1));
+	if (offset & 1)
+		*((volatile word*)(dev->iobase + (offset & ~((dword)1)))) =
+			(value<<8) | (_w & 0x00ff);
+	else
+		*((volatile word*)(dev->iobase + offset)) =
+			value | (_w & 0xff00);
+}
+
+static inline void SMC_insw(struct eth_device *dev, dword offset,
+	volatile uchar* buf, dword len)
+{
+	volatile word *p = (volatile word *)buf;
+
+	while (len-- > 0) {
+		*p++ = SMC_inw(dev, offset);
+		barrier();
+		*((volatile u32*)(0xc0000000));
+	}
+}
+
+static inline void SMC_outsw(struct eth_device *dev, dword offset,
+	uchar* buf, dword len)
+{
+	volatile word *p = (volatile word *)buf;
+
+	while (len-- > 0) {
+		SMC_outw(dev, *p++, offset);
+		barrier();
+		*(volatile u32*)(0xc0000000);
+	}
+}
+#endif  /* CONFIG_SMC_USE_IOFUNCS */
+
+/*
+ . A rather simple routine to print out a packet for debugging purposes.
+*/
+#if SMC_DEBUG > 2
+static void print_packet( byte *, int );
+#endif
+
+#define tx_done(dev) 1
+
+static int poll4int (struct eth_device *dev, byte mask, int timeout)
+{
+	int tmo = get_timer (0) + timeout * CONFIG_SYS_HZ;
+	int is_timeout = 0;
+	word old_bank = SMC_inw (dev, BSR_REG);
+
+	PRINTK2 ("Polling...\n");
+	SMC_SELECT_BANK (dev, 2);
+	while ((SMC_inw (dev, SMC91111_INT_REG) & mask) == 0) {
+		if (get_timer (0) >= tmo) {
+			is_timeout = 1;
+			break;
+		}
+	}
+
+	/* restore old bank selection */
+	SMC_SELECT_BANK (dev, old_bank);
+
+	if (is_timeout)
+		return 1;
+	else
+		return 0;
+}
+
+/* Only one release command at a time, please */
+static inline void smc_wait_mmu_release_complete (struct eth_device *dev)
+{
+	int count = 0;
+
+	/* assume bank 2 selected */
+	while (SMC_inw (dev, MMU_CMD_REG) & MC_BUSY) {
+		udelay (1);	/* Wait until not busy */
+		if (++count > 200)
+			break;
+	}
+}
+
+/*
+ . Function: smc_reset( void )
+ . Purpose:
+ .	This sets the SMC91111 chip to its normal state, hopefully from whatever
+ .	mess that any other DOS driver has put it in.
+ .
+ . Maybe I should reset more registers to defaults in here?  SOFTRST  should
+ . do that for me.
+ .
+ . Method:
+ .	1.  send a SOFT RESET
+ .	2.  wait for it to finish
+ .	3.  enable autorelease mode
+ .	4.  reset the memory management unit
+ .	5.  clear all interrupts
+ .
+*/
+static void smc_reset (struct eth_device *dev)
+{
+	PRINTK2 ("%s: smc_reset\n", SMC_DEV_NAME);
+
+	/* This resets the registers mostly to defaults, but doesn't
+	   affect EEPROM.  That seems unnecessary */
+	SMC_SELECT_BANK (dev, 0);
+	SMC_outw (dev, RCR_SOFTRST, RCR_REG);
+
+	/* Setup the Configuration Register */
+	/* This is necessary because the CONFIG_REG is not affected */
+	/* by a soft reset */
+
+	SMC_SELECT_BANK (dev, 1);
+#if defined(CONFIG_SMC91111_EXT_PHY)
+	SMC_outw (dev, CONFIG_DEFAULT | CONFIG_EXT_PHY, CONFIG_REG);
+#else
+	SMC_outw (dev, CONFIG_DEFAULT, CONFIG_REG);
+#endif
+
+
+	/* Release from possible power-down state */
+	/* Configuration register is not affected by Soft Reset */
+	SMC_outw (dev, SMC_inw (dev, CONFIG_REG) | CONFIG_EPH_POWER_EN,
+		CONFIG_REG);
+
+	SMC_SELECT_BANK (dev, 0);
+
+	/* this should pause enough for the chip to be happy */
+	udelay (10);
+
+	/* Disable transmit and receive functionality */
+	SMC_outw (dev, RCR_CLEAR, RCR_REG);
+	SMC_outw (dev, TCR_CLEAR, TCR_REG);
+
+	/* set the control register */
+	SMC_SELECT_BANK (dev, 1);
+	SMC_outw (dev, CTL_DEFAULT, CTL_REG);
+
+	/* Reset the MMU */
+	SMC_SELECT_BANK (dev, 2);
+	smc_wait_mmu_release_complete (dev);
+	SMC_outw (dev, MC_RESET, MMU_CMD_REG);
+	while (SMC_inw (dev, MMU_CMD_REG) & MC_BUSY)
+		udelay (1);	/* Wait until not busy */
+
+	/* Note:  It doesn't seem that waiting for the MMU busy is needed here,
+	   but this is a place where future chipsets _COULD_ break.  Be wary
+	   of issuing another MMU command right after this */
+
+	/* Disable all interrupts */
+	SMC_outb (dev, 0, IM_REG);
+}
+
+/*
+ . Function: smc_enable
+ . Purpose: let the chip talk to the outside work
+ . Method:
+ .	1.  Enable the transmitter
+ .	2.  Enable the receiver
+ .	3.  Enable interrupts
+*/
+static void smc_enable(struct eth_device *dev)
+{
+	PRINTK2("%s: smc_enable\n", SMC_DEV_NAME);
+	SMC_SELECT_BANK( dev, 0 );
+	/* see the header file for options in TCR/RCR DEFAULT*/
+	SMC_outw( dev, TCR_DEFAULT, TCR_REG );
+	SMC_outw( dev, RCR_DEFAULT, RCR_REG );
+
+	/* clear MII_DIS */
+/*	smc_write_phy_register(PHY_CNTL_REG, 0x0000); */
+}
+
+/*
+ . Function: smc_halt
+ . Purpose:  closes down the SMC91xxx chip.
+ . Method:
+ .	1. zero the interrupt mask
+ .	2. clear the enable receive flag
+ .	3. clear the enable xmit flags
+ .
+ . TODO:
+ .   (1) maybe utilize power down mode.
+ .	Why not yet?  Because while the chip will go into power down mode,
+ .	the manual says that it will wake up in response to any I/O requests
+ .	in the register space.	 Empirical results do not show this working.
+*/
+static void smc_halt(struct eth_device *dev)
+{
+	PRINTK2("%s: smc_halt\n", SMC_DEV_NAME);
+
+	/* no more interrupts for me */
+	SMC_SELECT_BANK( dev, 2 );
+	SMC_outb( dev, 0, IM_REG );
+
+	/* and tell the card to stay away from that nasty outside world */
+	SMC_SELECT_BANK( dev, 0 );
+	SMC_outb( dev, RCR_CLEAR, RCR_REG );
+	SMC_outb( dev, TCR_CLEAR, TCR_REG );
+
+	swap_to(FLASH);
+}
+
+
+/*
+ . Function:  smc_send(struct net_device * )
+ . Purpose:
+ .	This sends the actual packet to the SMC9xxx chip.
+ .
+ . Algorithm:
+ .	First, see if a saved_skb is available.
+ .		( this should NOT be called if there is no 'saved_skb'
+ .	Now, find the packet number that the chip allocated
+ .	Point the data pointers at it in memory
+ .	Set the length word in the chip's memory
+ .	Dump the packet to chip memory
+ .	Check if a last byte is needed ( odd length packet )
+ .		if so, set the control flag right
+ .	Tell the card to send it
+ .	Enable the transmit interrupt, so I know if it failed
+ .	Free the kernel data if I actually sent it.
+*/
+static int smc_send(struct eth_device *dev, void *packet, int packet_length)
+{
+	byte packet_no;
+	byte *buf;
+	int length;
+	int numPages;
+	int try = 0;
+	int time_out;
+	byte status;
+	byte saved_pnr;
+	word saved_ptr;
+
+	/* save PTR and PNR registers before manipulation */
+	SMC_SELECT_BANK (dev, 2);
+	saved_pnr = SMC_inb( dev, PN_REG );
+	saved_ptr = SMC_inw( dev, PTR_REG );
+
+	PRINTK3 ("%s: smc_hardware_send_packet\n", SMC_DEV_NAME);
+
+	length = ETH_ZLEN < packet_length ? packet_length : ETH_ZLEN;
+
+	/* allocate memory
+	 ** The MMU wants the number of pages to be the number of 256 bytes
+	 ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
+	 **
+	 ** The 91C111 ignores the size bits, but the code is left intact
+	 ** for backwards and future compatibility.
+	 **
+	 ** Pkt size for allocating is data length +6 (for additional status
+	 ** words, length and ctl!)
+	 **
+	 ** If odd size then last byte is included in this header.
+	 */
+	numPages = ((length & 0xfffe) + 6);
+	numPages >>= 8;		/* Divide by 256 */
+
+	if (numPages > 7) {
+		printf ("%s: Far too big packet error. \n", SMC_DEV_NAME);
+		return 0;
+	}
+
+	/* now, try to allocate the memory */
+	SMC_SELECT_BANK (dev, 2);
+	SMC_outw (dev, MC_ALLOC | numPages, MMU_CMD_REG);
+
+	/* FIXME: the ALLOC_INT bit never gets set *
+	 * so the following will always give a	   *
+	 * memory allocation error.		   *
+	 * same code works in armboot though	   *
+	 * -ro
+	 */
+
+again:
+	try++;
+	time_out = MEMORY_WAIT_TIME;
+	do {
+		status = SMC_inb (dev, SMC91111_INT_REG);
+		if (status & IM_ALLOC_INT) {
+			/* acknowledge the interrupt */
+			SMC_outb (dev, IM_ALLOC_INT, SMC91111_INT_REG);
+			break;
+		}
+	} while (--time_out);
+
+	if (!time_out) {
+		PRINTK2 ("%s: memory allocation, try %d failed ...\n",
+			 SMC_DEV_NAME, try);
+		if (try < SMC_ALLOC_MAX_TRY)
+			goto again;
+		else
+			return 0;
+	}
+
+	PRINTK2 ("%s: memory allocation, try %d succeeded ...\n",
+		 SMC_DEV_NAME, try);
+
+	buf = (byte *) packet;
+
+	/* If I get here, I _know_ there is a packet slot waiting for me */
+	packet_no = SMC_inb (dev, AR_REG);
+	if (packet_no & AR_FAILED) {
+		/* or isn't there?  BAD CHIP! */
+		printf ("%s: Memory allocation failed. \n", SMC_DEV_NAME);
+		return 0;
+	}
+
+	/* we have a packet address, so tell the card to use it */
+#ifndef CONFIG_XAENIAX
+	SMC_outb (dev, packet_no, PN_REG);
+#else
+	/* On Xaeniax board, we can't use SMC_outb here because that way
+	 * the Allocate MMU command will end up written to the command register
+	 * as well, which will lead to a problem.
+	 */
+	SMC_outl (dev, packet_no << 16, 0);
+#endif
+	/* do not write new ptr value if Write data fifo not empty */
+	while ( saved_ptr & PTR_NOTEMPTY )
+		printf ("Write data fifo not empty!\n");
+
+	/* point to the beginning of the packet */
+	SMC_outw (dev, PTR_AUTOINC, PTR_REG);
+
+	PRINTK3 ("%s: Trying to xmit packet of length %x\n",
+		 SMC_DEV_NAME, length);
+
+#if SMC_DEBUG > 2
+	printf ("Transmitting Packet\n");
+	print_packet (buf, length);
+#endif
+
+	/* send the packet length ( +6 for status, length and ctl byte )
+	   and the status word ( set to zeros ) */
+#ifdef USE_32_BIT
+	SMC_outl (dev, (length + 6) << 16, SMC91111_DATA_REG);
+#else
+	SMC_outw (dev, 0, SMC91111_DATA_REG);
+	/* send the packet length ( +6 for status words, length, and ctl */
+	SMC_outw (dev, (length + 6), SMC91111_DATA_REG);
+#endif
+
+	/* send the actual data
+	   . I _think_ it's faster to send the longs first, and then
+	   . mop up by sending the last word.  It depends heavily
+	   . on alignment, at least on the 486.	 Maybe it would be
+	   . a good idea to check which is optimal?  But that could take
+	   . almost as much time as is saved?
+	 */
+#ifdef USE_32_BIT
+	SMC_outsl (dev, SMC91111_DATA_REG, buf, length >> 2);
+#ifndef CONFIG_XAENIAX
+	if (length & 0x2)
+		SMC_outw (dev, *((word *) (buf + (length & 0xFFFFFFFC))),
+			  SMC91111_DATA_REG);
+#else
+	/* On XANEIAX, we can only use 32-bit writes, so we need to handle
+	 * unaligned tail part specially. The standard code doesn't work.
+	 */
+	if ((length & 3) == 3) {
+		u16 * ptr = (u16*) &buf[length-3];
+		SMC_outl(dev, (*ptr) | ((0x2000 | buf[length-1]) << 16),
+				SMC91111_DATA_REG);
+	} else if ((length & 2) == 2) {
+		u16 * ptr = (u16*) &buf[length-2];
+		SMC_outl(dev, *ptr, SMC91111_DATA_REG);
+	} else if (length & 1) {
+		SMC_outl(dev, (0x2000 | buf[length-1]), SMC91111_DATA_REG);
+	} else {
+		SMC_outl(dev, 0, SMC91111_DATA_REG);
+	}
+#endif
+#else
+	SMC_outsw (dev, SMC91111_DATA_REG, buf, (length) >> 1);
+#endif /* USE_32_BIT */
+
+#ifndef CONFIG_XAENIAX
+	/* Send the last byte, if there is one.	  */
+	if ((length & 1) == 0) {
+		SMC_outw (dev, 0, SMC91111_DATA_REG);
+	} else {
+		SMC_outw (dev, buf[length - 1] | 0x2000, SMC91111_DATA_REG);
+	}
+#endif
+
+	/* and let the chipset deal with it */
+	SMC_outw (dev, MC_ENQUEUE, MMU_CMD_REG);
+
+	/* poll for TX INT */
+	/* if (poll4int (dev, IM_TX_INT, SMC_TX_TIMEOUT)) { */
+	/* poll for TX_EMPTY INT - autorelease enabled */
+	if (poll4int(dev, IM_TX_EMPTY_INT, SMC_TX_TIMEOUT)) {
+		/* sending failed */
+		PRINTK2 ("%s: TX timeout, sending failed...\n", SMC_DEV_NAME);
+
+		/* release packet */
+		/* no need to release, MMU does that now */
+#ifdef CONFIG_XAENIAX
+		 SMC_outw (dev, MC_FREEPKT, MMU_CMD_REG);
+#endif
+
+		/* wait for MMU getting ready (low) */
+		while (SMC_inw (dev, MMU_CMD_REG) & MC_BUSY) {
+			udelay (10);
+		}
+
+		PRINTK2 ("MMU ready\n");
+
+
+		return 0;
+	} else {
+		/* ack. int */
+		SMC_outb (dev, IM_TX_EMPTY_INT, SMC91111_INT_REG);
+		/* SMC_outb (IM_TX_INT, SMC91111_INT_REG); */
+		PRINTK2 ("%s: Sent packet of length %d \n", SMC_DEV_NAME,
+			 length);
+
+		/* release packet */
+		/* no need to release, MMU does that now */
+#ifdef CONFIG_XAENIAX
+		SMC_outw (dev, MC_FREEPKT, MMU_CMD_REG);
+#endif
+
+		/* wait for MMU getting ready (low) */
+		while (SMC_inw (dev, MMU_CMD_REG) & MC_BUSY) {
+			udelay (10);
+		}
+
+		PRINTK2 ("MMU ready\n");
+
+
+	}
+
+	/* restore previously saved registers */
+#ifndef CONFIG_XAENIAX
+	SMC_outb( dev, saved_pnr, PN_REG );
+#else
+	/* On Xaeniax board, we can't use SMC_outb here because that way
+	 * the Allocate MMU command will end up written to the command register
+	 * as well, which will lead to a problem.
+	 */
+	SMC_outl(dev, saved_pnr << 16, 0);
+#endif
+	SMC_outw( dev, saved_ptr, PTR_REG );
+
+	return length;
+}
+
+static int smc_write_hwaddr(struct eth_device *dev)
+{
+	int i;
+
+	swap_to(ETHERNET);
+	SMC_SELECT_BANK (dev, 1);
+#ifdef USE_32_BIT
+	for (i = 0; i < 6; i += 2) {
+		word address;
+
+		address = dev->enetaddr[i + 1] << 8;
+		address |= dev->enetaddr[i];
+		SMC_outw(dev, address, (ADDR0_REG + i));
+	}
+#else
+	for (i = 0; i < 6; i++)
+		SMC_outb(dev, dev->enetaddr[i], (ADDR0_REG + i));
+#endif
+	swap_to(FLASH);
+	return 0;
+}
+
+/*
+ * Open and Initialize the board
+ *
+ * Set up everything, reset the card, etc ..
+ *
+ */
+static int smc_init(struct eth_device *dev, bd_t *bd)
+{
+	swap_to(ETHERNET);
+
+	PRINTK2 ("%s: smc_init\n", SMC_DEV_NAME);
+
+	/* reset the hardware */
+	smc_reset (dev);
+	smc_enable (dev);
+
+	/* Configure the PHY */
+#ifndef CONFIG_SMC91111_EXT_PHY
+	smc_phy_configure (dev);
+#endif
+
+	/* conservative setting (10Mbps, HalfDuplex, no AutoNeg.) */
+/*	SMC_SELECT_BANK(dev, 0); */
+/*	SMC_outw(dev, 0, RPC_REG); */
+
+	printf(SMC_DEV_NAME ": MAC %pM\n", dev->enetaddr);
+
+	return 0;
+}
+
+/*-------------------------------------------------------------
+ .
+ . smc_rcv -  receive a packet from the card
+ .
+ . There is ( at least ) a packet waiting to be read from
+ . chip-memory.
+ .
+ . o Read the status
+ . o If an error, record it
+ . o otherwise, read in the packet
+ --------------------------------------------------------------
+*/
+static int smc_rcv(struct eth_device *dev)
+{
+	int	packet_number;
+	word	status;
+	word	packet_length;
+	int	is_error = 0;
+#ifdef USE_32_BIT
+	dword stat_len;
+#endif
+	byte saved_pnr;
+	word saved_ptr;
+
+	SMC_SELECT_BANK(dev, 2);
+	/* save PTR and PTR registers */
+	saved_pnr = SMC_inb( dev, PN_REG );
+	saved_ptr = SMC_inw( dev, PTR_REG );
+
+	packet_number = SMC_inw( dev, RXFIFO_REG );
+
+	if ( packet_number & RXFIFO_REMPTY ) {
+
+		return 0;
+	}
+
+	PRINTK3("%s: smc_rcv\n", SMC_DEV_NAME);
+	/*  start reading from the start of the packet */
+	SMC_outw( dev, PTR_READ | PTR_RCV | PTR_AUTOINC, PTR_REG );
+
+	/* First two words are status and packet_length */
+#ifdef USE_32_BIT
+	stat_len = SMC_inl(dev, SMC91111_DATA_REG);
+	status = stat_len & 0xffff;
+	packet_length = stat_len >> 16;
+#else
+	status		= SMC_inw( dev, SMC91111_DATA_REG );
+	packet_length	= SMC_inw( dev, SMC91111_DATA_REG );
+#endif
+
+	packet_length &= 0x07ff;  /* mask off top bits */
+
+	PRINTK2("RCV: STATUS %4x LENGTH %4x\n", status, packet_length );
+
+	if ( !(status & RS_ERRORS ) ){
+		/* Adjust for having already read the first two words */
+		packet_length -= 4; /*4; */
+
+
+		/* set odd length for bug in LAN91C111, */
+		/* which never sets RS_ODDFRAME */
+		/* TODO ? */
+
+
+#ifdef USE_32_BIT
+		PRINTK3(" Reading %d dwords (and %d bytes) \n",
+			packet_length >> 2, packet_length & 3 );
+		/* QUESTION:  Like in the TX routine, do I want
+		   to send the DWORDs or the bytes first, or some
+		   mixture.  A mixture might improve already slow PIO
+		   performance	*/
+		SMC_insl( dev, SMC91111_DATA_REG, NetRxPackets[0],
+			packet_length >> 2 );
+		/* read the left over bytes */
+		if (packet_length & 3) {
+			int i;
+
+			byte *tail = (byte *)(NetRxPackets[0] +
+				(packet_length & ~3));
+			dword leftover = SMC_inl(dev, SMC91111_DATA_REG);
+			for (i=0; i<(packet_length & 3); i++)
+				*tail++ = (byte) (leftover >> (8*i)) & 0xff;
+		}
+#else
+		PRINTK3(" Reading %d words and %d byte(s) \n",
+			(packet_length >> 1 ), packet_length & 1 );
+		SMC_insw(dev, SMC91111_DATA_REG , NetRxPackets[0],
+			packet_length >> 1);
+
+#endif /* USE_32_BIT */
+
+#if	SMC_DEBUG > 2
+		printf("Receiving Packet\n");
+		print_packet( NetRxPackets[0], packet_length );
+#endif
+	} else {
+		/* error ... */
+		/* TODO ? */
+		is_error = 1;
+	}
+
+	while ( SMC_inw( dev, MMU_CMD_REG ) & MC_BUSY )
+		udelay(1); /* Wait until not busy */
+
+	/*  error or good, tell the card to get rid of this packet */
+	SMC_outw( dev, MC_RELEASE, MMU_CMD_REG );
+
+	while ( SMC_inw( dev, MMU_CMD_REG ) & MC_BUSY )
+		udelay(1); /* Wait until not busy */
+
+	/* restore saved registers */
+#ifndef CONFIG_XAENIAX
+	SMC_outb( dev, saved_pnr, PN_REG );
+#else
+	/* On Xaeniax board, we can't use SMC_outb here because that way
+	 * the Allocate MMU command will end up written to the command register
+	 * as well, which will lead to a problem.
+	 */
+	SMC_outl( dev, saved_pnr << 16, 0);
+#endif
+	SMC_outw( dev, saved_ptr, PTR_REG );
+
+	if (!is_error) {
+		/* Pass the packet up to the protocol layers. */
+		NetReceive(NetRxPackets[0], packet_length);
+		return packet_length;
+	} else {
+		return 0;
+	}
+
+}
+
+
+#if 0
+/*------------------------------------------------------------
+ . Modify a bit in the LAN91C111 register set
+ .-------------------------------------------------------------*/
+static word smc_modify_regbit(struct eth_device *dev, int bank, int ioaddr, int reg,
+	unsigned int bit, int val)
+{
+	word regval;
+
+	SMC_SELECT_BANK( dev, bank );
+
+	regval = SMC_inw( dev, reg );
+	if (val)
+		regval |= bit;
+	else
+		regval &= ~bit;
+
+	SMC_outw( dev, regval, 0 );
+	return(regval);
+}
+
+
+/*------------------------------------------------------------
+ . Retrieve a bit in the LAN91C111 register set
+ .-------------------------------------------------------------*/
+static int smc_get_regbit(struct eth_device *dev, int bank, int ioaddr, int reg, unsigned int bit)
+{
+	SMC_SELECT_BANK( dev, bank );
+	if ( SMC_inw( dev, reg ) & bit)
+		return(1);
+	else
+		return(0);
+}
+
+
+/*------------------------------------------------------------
+ . Modify a LAN91C111 register (word access only)
+ .-------------------------------------------------------------*/
+static void smc_modify_reg(struct eth_device *dev, int bank, int ioaddr, int reg, word val)
+{
+	SMC_SELECT_BANK( dev, bank );
+	SMC_outw( dev, val, reg );
+}
+
+
+/*------------------------------------------------------------
+ . Retrieve a LAN91C111 register (word access only)
+ .-------------------------------------------------------------*/
+static int smc_get_reg(struct eth_device *dev, int bank, int ioaddr, int reg)
+{
+	SMC_SELECT_BANK( dev, bank );
+	return(SMC_inw( dev, reg ));
+}
+
+#endif /* 0 */
+
+/*---PHY CONTROL AND CONFIGURATION----------------------------------------- */
+
+#if (SMC_DEBUG > 2 )
+
+/*------------------------------------------------------------
+ . Debugging function for viewing MII Management serial bitstream
+ .-------------------------------------------------------------*/
+static void smc_dump_mii_stream (byte * bits, int size)
+{
+	int i;
+
+	printf ("BIT#:");
+	for (i = 0; i < size; ++i) {
+		printf ("%d", i % 10);
+	}
+
+	printf ("\nMDOE:");
+	for (i = 0; i < size; ++i) {
+		if (bits[i] & MII_MDOE)
+			printf ("1");
+		else
+			printf ("0");
+	}
+
+	printf ("\nMDO :");
+	for (i = 0; i < size; ++i) {
+		if (bits[i] & MII_MDO)
+			printf ("1");
+		else
+			printf ("0");
+	}
+
+	printf ("\nMDI :");
+	for (i = 0; i < size; ++i) {
+		if (bits[i] & MII_MDI)
+			printf ("1");
+		else
+			printf ("0");
+	}
+
+	printf ("\n");
+}
+#endif
+
+/*------------------------------------------------------------
+ . Reads a register from the MII Management serial interface
+ .-------------------------------------------------------------*/
+#ifndef CONFIG_SMC91111_EXT_PHY
+static word smc_read_phy_register (struct eth_device *dev, byte phyreg)
+{
+	int oldBank;
+	int i;
+	byte mask;
+	word mii_reg;
+	byte bits[64];
+	int clk_idx = 0;
+	int input_idx;
+	word phydata;
+	byte phyaddr = SMC_PHY_ADDR;
+
+	/* 32 consecutive ones on MDO to establish sync */
+	for (i = 0; i < 32; ++i)
+		bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+	/* Start code <01> */
+	bits[clk_idx++] = MII_MDOE;
+	bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+	/* Read command <10> */
+	bits[clk_idx++] = MII_MDOE | MII_MDO;
+	bits[clk_idx++] = MII_MDOE;
+
+	/* Output the PHY address, msb first */
+	mask = (byte) 0x10;
+	for (i = 0; i < 5; ++i) {
+		if (phyaddr & mask)
+			bits[clk_idx++] = MII_MDOE | MII_MDO;
+		else
+			bits[clk_idx++] = MII_MDOE;
+
+		/* Shift to next lowest bit */
+		mask >>= 1;
+	}
+
+	/* Output the phy register number, msb first */
+	mask = (byte) 0x10;
+	for (i = 0; i < 5; ++i) {
+		if (phyreg & mask)
+			bits[clk_idx++] = MII_MDOE | MII_MDO;
+		else
+			bits[clk_idx++] = MII_MDOE;
+
+		/* Shift to next lowest bit */
+		mask >>= 1;
+	}
+
+	/* Tristate and turnaround (2 bit times) */
+	bits[clk_idx++] = 0;
+	/*bits[clk_idx++] = 0; */
+
+	/* Input starts at this bit time */
+	input_idx = clk_idx;
+
+	/* Will input 16 bits */
+	for (i = 0; i < 16; ++i)
+		bits[clk_idx++] = 0;
+
+	/* Final clock bit */
+	bits[clk_idx++] = 0;
+
+	/* Save the current bank */
+	oldBank = SMC_inw (dev, BANK_SELECT);
+
+	/* Select bank 3 */
+	SMC_SELECT_BANK (dev, 3);
+
+	/* Get the current MII register value */
+	mii_reg = SMC_inw (dev, MII_REG);
+
+	/* Turn off all MII Interface bits */
+	mii_reg &= ~(MII_MDOE | MII_MCLK | MII_MDI | MII_MDO);
+
+	/* Clock all 64 cycles */
+	for (i = 0; i < sizeof bits; ++i) {
+		/* Clock Low - output data */
+		SMC_outw (dev, mii_reg | bits[i], MII_REG);
+		udelay (SMC_PHY_CLOCK_DELAY);
+
+
+		/* Clock Hi - input data */
+		SMC_outw (dev, mii_reg | bits[i] | MII_MCLK, MII_REG);
+		udelay (SMC_PHY_CLOCK_DELAY);
+		bits[i] |= SMC_inw (dev, MII_REG) & MII_MDI;
+	}
+
+	/* Return to idle state */
+	/* Set clock to low, data to low, and output tristated */
+	SMC_outw (dev, mii_reg, MII_REG);
+	udelay (SMC_PHY_CLOCK_DELAY);
+
+	/* Restore original bank select */
+	SMC_SELECT_BANK (dev, oldBank);
+
+	/* Recover input data */
+	phydata = 0;
+	for (i = 0; i < 16; ++i) {
+		phydata <<= 1;
+
+		if (bits[input_idx++] & MII_MDI)
+			phydata |= 0x0001;
+	}
+
+#if (SMC_DEBUG > 2 )
+	printf ("smc_read_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
+		phyaddr, phyreg, phydata);
+	smc_dump_mii_stream (bits, sizeof bits);
+#endif
+
+	return (phydata);
+}
+
+
+/*------------------------------------------------------------
+ . Writes a register to the MII Management serial interface
+ .-------------------------------------------------------------*/
+static void smc_write_phy_register (struct eth_device *dev, byte phyreg,
+	word phydata)
+{
+	int oldBank;
+	int i;
+	word mask;
+	word mii_reg;
+	byte bits[65];
+	int clk_idx = 0;
+	byte phyaddr = SMC_PHY_ADDR;
+
+	/* 32 consecutive ones on MDO to establish sync */
+	for (i = 0; i < 32; ++i)
+		bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+	/* Start code <01> */
+	bits[clk_idx++] = MII_MDOE;
+	bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+	/* Write command <01> */
+	bits[clk_idx++] = MII_MDOE;
+	bits[clk_idx++] = MII_MDOE | MII_MDO;
+
+	/* Output the PHY address, msb first */
+	mask = (byte) 0x10;
+	for (i = 0; i < 5; ++i) {
+		if (phyaddr & mask)
+			bits[clk_idx++] = MII_MDOE | MII_MDO;
+		else
+			bits[clk_idx++] = MII_MDOE;
+
+		/* Shift to next lowest bit */
+		mask >>= 1;
+	}
+
+	/* Output the phy register number, msb first */
+	mask = (byte) 0x10;
+	for (i = 0; i < 5; ++i) {
+		if (phyreg & mask)
+			bits[clk_idx++] = MII_MDOE | MII_MDO;
+		else
+			bits[clk_idx++] = MII_MDOE;
+
+		/* Shift to next lowest bit */
+		mask >>= 1;
+	}
+
+	/* Tristate and turnaround (2 bit times) */
+	bits[clk_idx++] = 0;
+	bits[clk_idx++] = 0;
+
+	/* Write out 16 bits of data, msb first */
+	mask = 0x8000;
+	for (i = 0; i < 16; ++i) {
+		if (phydata & mask)
+			bits[clk_idx++] = MII_MDOE | MII_MDO;
+		else
+			bits[clk_idx++] = MII_MDOE;
+
+		/* Shift to next lowest bit */
+		mask >>= 1;
+	}
+
+	/* Final clock bit (tristate) */
+	bits[clk_idx++] = 0;
+
+	/* Save the current bank */
+	oldBank = SMC_inw (dev, BANK_SELECT);
+
+	/* Select bank 3 */
+	SMC_SELECT_BANK (dev, 3);
+
+	/* Get the current MII register value */
+	mii_reg = SMC_inw (dev, MII_REG);
+
+	/* Turn off all MII Interface bits */
+	mii_reg &= ~(MII_MDOE | MII_MCLK | MII_MDI | MII_MDO);
+
+	/* Clock all cycles */
+	for (i = 0; i < sizeof bits; ++i) {
+		/* Clock Low - output data */
+		SMC_outw (dev, mii_reg | bits[i], MII_REG);
+		udelay (SMC_PHY_CLOCK_DELAY);
+
+
+		/* Clock Hi - input data */
+		SMC_outw (dev, mii_reg | bits[i] | MII_MCLK, MII_REG);
+		udelay (SMC_PHY_CLOCK_DELAY);
+		bits[i] |= SMC_inw (dev, MII_REG) & MII_MDI;
+	}
+
+	/* Return to idle state */
+	/* Set clock to low, data to low, and output tristated */
+	SMC_outw (dev, mii_reg, MII_REG);
+	udelay (SMC_PHY_CLOCK_DELAY);
+
+	/* Restore original bank select */
+	SMC_SELECT_BANK (dev, oldBank);
+
+#if (SMC_DEBUG > 2 )
+	printf ("smc_write_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
+		phyaddr, phyreg, phydata);
+	smc_dump_mii_stream (bits, sizeof bits);
+#endif
+}
+#endif /* !CONFIG_SMC91111_EXT_PHY */
+
+
+/*------------------------------------------------------------
+ . Configures the specified PHY using Autonegotiation. Calls
+ . smc_phy_fixed() if the user has requested a certain config.
+ .-------------------------------------------------------------*/
+#ifndef CONFIG_SMC91111_EXT_PHY
+static void smc_phy_configure (struct eth_device *dev)
+{
+	int timeout;
+	word my_phy_caps;	/* My PHY capabilities */
+	word my_ad_caps;	/* My Advertised capabilities */
+	word status = 0;	/*;my status = 0 */
+
+	PRINTK3 ("%s: smc_program_phy()\n", SMC_DEV_NAME);
+
+	/* Reset the PHY, setting all other bits to zero */
+	smc_write_phy_register (dev, PHY_CNTL_REG, PHY_CNTL_RST);
+
+	/* Wait for the reset to complete, or time out */
+	timeout = 6;		/* Wait up to 3 seconds */
+	while (timeout--) {
+		if (!(smc_read_phy_register (dev, PHY_CNTL_REG)
+		      & PHY_CNTL_RST)) {
+			/* reset complete */
+			break;
+		}
+
+		mdelay(500);	/* wait 500 millisecs */
+	}
+
+	if (timeout < 1) {
+		printf ("%s:PHY reset timed out\n", SMC_DEV_NAME);
+		goto smc_phy_configure_exit;
+	}
+
+	/* Read PHY Register 18, Status Output */
+	/* lp->lastPhy18 = smc_read_phy_register(PHY_INT_REG); */
+
+	/* Enable PHY Interrupts (for register 18) */
+	/* Interrupts listed here are disabled */
+	smc_write_phy_register (dev, PHY_MASK_REG, 0xffff);
+
+	/* Configure the Receive/Phy Control register */
+	SMC_SELECT_BANK (dev, 0);
+	SMC_outw (dev, RPC_DEFAULT, RPC_REG);
+
+	/* Copy our capabilities from PHY_STAT_REG to PHY_AD_REG */
+	my_phy_caps = smc_read_phy_register (dev, PHY_STAT_REG);
+	my_ad_caps = PHY_AD_CSMA;	/* I am CSMA capable */
+
+	if (my_phy_caps & PHY_STAT_CAP_T4)
+		my_ad_caps |= PHY_AD_T4;
+
+	if (my_phy_caps & PHY_STAT_CAP_TXF)
+		my_ad_caps |= PHY_AD_TX_FDX;
+
+	if (my_phy_caps & PHY_STAT_CAP_TXH)
+		my_ad_caps |= PHY_AD_TX_HDX;
+
+	if (my_phy_caps & PHY_STAT_CAP_TF)
+		my_ad_caps |= PHY_AD_10_FDX;
+
+	if (my_phy_caps & PHY_STAT_CAP_TH)
+		my_ad_caps |= PHY_AD_10_HDX;
+
+	/* Update our Auto-Neg Advertisement Register */
+	smc_write_phy_register (dev, PHY_AD_REG, my_ad_caps);
+
+	/* Read the register back.  Without this, it appears that when */
+	/* auto-negotiation is restarted, sometimes it isn't ready and */
+	/* the link does not come up. */
+	smc_read_phy_register(dev, PHY_AD_REG);
+
+	PRINTK2 ("%s: phy caps=%x\n", SMC_DEV_NAME, my_phy_caps);
+	PRINTK2 ("%s: phy advertised caps=%x\n", SMC_DEV_NAME, my_ad_caps);
+
+	/* Restart auto-negotiation process in order to advertise my caps */
+	smc_write_phy_register (dev, PHY_CNTL_REG,
+				PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST);
+
+	/* Wait for the auto-negotiation to complete.  This may take from */
+	/* 2 to 3 seconds. */
+	/* Wait for the reset to complete, or time out */
+	timeout = CONFIG_SMC_AUTONEG_TIMEOUT * 2;
+	while (timeout--) {
+
+		status = smc_read_phy_register (dev, PHY_STAT_REG);
+		if (status & PHY_STAT_ANEG_ACK) {
+			/* auto-negotiate complete */
+			break;
+		}
+
+		mdelay(500);	/* wait 500 millisecs */
+
+		/* Restart auto-negotiation if remote fault */
+		if (status & PHY_STAT_REM_FLT) {
+			printf ("%s: PHY remote fault detected\n",
+				SMC_DEV_NAME);
+
+			/* Restart auto-negotiation */
+			printf ("%s: PHY restarting auto-negotiation\n",
+				SMC_DEV_NAME);
+			smc_write_phy_register (dev, PHY_CNTL_REG,
+						PHY_CNTL_ANEG_EN |
+						PHY_CNTL_ANEG_RST |
+						PHY_CNTL_SPEED |
+						PHY_CNTL_DPLX);
+		}
+	}
+
+	if (timeout < 1) {
+		printf ("%s: PHY auto-negotiate timed out\n", SMC_DEV_NAME);
+	}
+
+	/* Fail if we detected an auto-negotiate remote fault */
+	if (status & PHY_STAT_REM_FLT) {
+		printf ("%s: PHY remote fault detected\n", SMC_DEV_NAME);
+	}
+
+	/* Re-Configure the Receive/Phy Control register */
+	SMC_outw (dev, RPC_DEFAULT, RPC_REG);
+
+smc_phy_configure_exit:	;
+
+}
+#endif /* !CONFIG_SMC91111_EXT_PHY */
+
+
+#if SMC_DEBUG > 2
+static void print_packet( byte * buf, int length )
+{
+	int i;
+	int remainder;
+	int lines;
+
+	printf("Packet of length %d \n", length );
+
+#if SMC_DEBUG > 3
+	lines = length / 16;
+	remainder = length % 16;
+
+	for ( i = 0; i < lines ; i ++ ) {
+		int cur;
+
+		for ( cur = 0; cur < 8; cur ++ ) {
+			byte a, b;
+
+			a = *(buf ++ );
+			b = *(buf ++ );
+			printf("%02x%02x ", a, b );
+		}
+		printf("\n");
+	}
+	for ( i = 0; i < remainder/2 ; i++ ) {
+		byte a, b;
+
+		a = *(buf ++ );
+		b = *(buf ++ );
+		printf("%02x%02x ", a, b );
+	}
+	printf("\n");
+#endif
+}
+#endif
+
+int smc91111_initialize(u8 dev_num, int base_addr)
+{
+	struct smc91111_priv *priv;
+	struct eth_device *dev;
+	int i;
+
+	priv = malloc(sizeof(*priv));
+	if (!priv)
+		return 0;
+	dev = malloc(sizeof(*dev));
+	if (!dev) {
+		free(priv);
+		return 0;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	priv->dev_num = dev_num;
+	dev->priv = priv;
+	dev->iobase = base_addr;
+
+	swap_to(ETHERNET);
+	SMC_SELECT_BANK(dev, 1);
+	for (i = 0; i < 6; ++i)
+		dev->enetaddr[i] = SMC_inb(dev, (ADDR0_REG + i));
+	swap_to(FLASH);
+
+	dev->init = smc_init;
+	dev->halt = smc_halt;
+	dev->send = smc_send;
+	dev->recv = smc_rcv;
+	dev->write_hwaddr = smc_write_hwaddr;
+	sprintf(dev->name, "%s-%hu", SMC_DEV_NAME, dev_num);
+
+	eth_register(dev);
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/smc91111.h b/marvell/uboot/drivers/net/smc91111.h
new file mode 100644
index 0000000..9deee9b
--- /dev/null
+++ b/marvell/uboot/drivers/net/smc91111.h
@@ -0,0 +1,780 @@
+/*------------------------------------------------------------------------
+ . smc91111.h - macros for the LAN91C111 Ethernet Driver
+ .
+ . (C) Copyright 2002
+ . Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ . Rolf Offermanns <rof@sysgo.de>
+ . Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
+ .       Developed by Simple Network Magic Corporation (SNMC)
+ . Copyright (C) 1996 by Erik Stahlman (ES)
+ .
+  * SPDX-License-Identifier:	GPL-2.0+
+ .
+ . This file contains register information and access macros for
+ . the LAN91C111 single chip ethernet controller.  It is a modified
+ . version of the smc9194.h file.
+ .
+ . Information contained in this file was obtained from the LAN91C111
+ . manual from SMC.  To get a copy, if you really want one, you can find
+ . information under www.smsc.com.
+ .
+ . Authors
+ .	Erik Stahlman				( erik@vt.edu )
+ .	Daris A Nevil				( dnevil@snmc.com )
+ .
+ . History
+ . 03/16/01		Daris A Nevil	Modified for use with LAN91C111 device
+ .
+ ---------------------------------------------------------------------------*/
+#ifndef _SMC91111_H_
+#define _SMC91111_H_
+
+#include <asm/types.h>
+#include <config.h>
+
+/*
+ * This function may be called by the board specific initialisation code
+ * in order to override the default mac address.
+ */
+
+void smc_set_mac_addr (const unsigned char *addr);
+
+
+/* I want some simple types */
+
+typedef unsigned char			byte;
+typedef unsigned short			word;
+typedef unsigned long int		dword;
+
+struct smc91111_priv{
+	u8 dev_num;
+};
+
+/*
+ . DEBUGGING LEVELS
+ .
+ . 0 for normal operation
+ . 1 for slightly more details
+ . >2 for various levels of increasingly useless information
+ .    2 for interrupt tracking, status flags
+ .    3 for packet info
+ .    4 for complete packet dumps
+*/
+/*#define SMC_DEBUG 0 */
+
+/* Because of bank switching, the LAN91xxx uses only 16 I/O ports */
+
+#define	SMC_IO_EXTENT	16
+
+#ifdef CONFIG_CPU_PXA25X
+
+#ifdef CONFIG_XSENGINE
+#define	SMC_inl(a,r)	(*((volatile dword *)((a)->iobase+((r)<<1))))
+#define	SMC_inw(a,r)	(*((volatile word *)((a)->iobase+((r)<<1))))
+#define SMC_inb(a,p)  ({ \
+	unsigned int __p = (unsigned int)((a)->iobase + ((p)<<1)); \
+	unsigned int __v = *(volatile unsigned short *)((__p) & ~2); \
+	if (__p & 2) __v >>= 8; \
+	else __v &= 0xff; \
+	__v; })
+#elif defined(CONFIG_XAENIAX)
+#define SMC_inl(a,r)	(*((volatile dword *)((a)->iobase+(r))))
+#define SMC_inw(a,z)	({ \
+	unsigned int __p = (unsigned int)((a)->iobase + (z)); \
+	unsigned int __v = *(volatile unsigned int *)((__p) & ~3); \
+	if (__p & 3) __v >>= 16; \
+	else __v &= 0xffff; \
+	__v; })
+#define SMC_inb(a,p)	({ \
+	unsigned int ___v = SMC_inw((a),(p) & ~1); \
+	if ((p) & 1) ___v >>= 8; \
+	else ___v &= 0xff; \
+	___v; })
+#else
+#define	SMC_inl(a,r)	(*((volatile dword *)((a)->iobase+(r))))
+#define	SMC_inw(a,r)	(*((volatile word *)((a)->iobase+(r))))
+#define SMC_inb(a,p)	({ \
+	unsigned int __p = (unsigned int)((a)->iobase + (p)); \
+	unsigned int __v = *(volatile unsigned short *)((__p) & ~1); \
+	if (__p & 1) __v >>= 8; \
+	else __v &= 0xff; \
+	__v; })
+#endif
+
+#ifdef CONFIG_XSENGINE
+#define	SMC_outl(a,d,r)	(*((volatile dword *)((a)->iobase+(r<<1))) = d)
+#define	SMC_outw(a,d,r)	(*((volatile word *)((a)->iobase+(r<<1))) = d)
+#elif defined (CONFIG_XAENIAX)
+#define SMC_outl(a,d,r)	(*((volatile dword *)((a)->iobase+(r))) = d)
+#define SMC_outw(a,d,p)	({ \
+	dword __dwo = SMC_inl((a),(p) & ~3); \
+	dword __dwn = (word)(d); \
+	__dwo &= ((p) & 3) ? 0x0000ffff : 0xffff0000; \
+	__dwo |= ((p) & 3) ? __dwn << 16 : __dwn; \
+	SMC_outl((a), __dwo, (p) & ~3); \
+})
+#else
+#define	SMC_outl(a,d,r)	(*((volatile dword *)((a)->iobase+(r))) = d)
+#define	SMC_outw(a,d,r)	(*((volatile word *)((a)->iobase+(r))) = d)
+#endif
+
+#define	SMC_outb(a,d,r)	({	word __d = (byte)(d);  \
+				word __w = SMC_inw((a),(r)&~1);  \
+				__w &= ((r)&1) ? 0x00FF : 0xFF00;  \
+				__w |= ((r)&1) ? __d<<8 : __d;  \
+				SMC_outw((a),__w,(r)&~1);  \
+			})
+
+#define SMC_outsl(a,r,b,l)	({	int __i; \
+					dword *__b2; \
+					__b2 = (dword *) b; \
+					for (__i = 0; __i < l; __i++) { \
+					    SMC_outl((a), *(__b2 + __i), r); \
+					} \
+				})
+
+#define SMC_outsw(a,r,b,l)	({	int __i; \
+					word *__b2; \
+					__b2 = (word *) b; \
+					for (__i = 0; __i < l; __i++) { \
+					    SMC_outw((a), *(__b2 + __i), r); \
+					} \
+				})
+
+#define SMC_insl(a,r,b,l)	({	int __i ;  \
+					dword *__b2;  \
+					__b2 = (dword *) b;  \
+					for (__i = 0; __i < l; __i++) {  \
+					  *(__b2 + __i) = SMC_inl((a),(r));  \
+					  SMC_inl((a),0);  \
+					};  \
+				})
+
+#define SMC_insw(a,r,b,l)		({	int __i ;  \
+					word *__b2;  \
+					__b2 = (word *) b;  \
+					for (__i = 0; __i < l; __i++) {  \
+					  *(__b2 + __i) = SMC_inw((a),(r));  \
+					  SMC_inw((a),0);  \
+					};  \
+				})
+
+#define SMC_insb(a,r,b,l)	({	int __i ;  \
+					byte *__b2;  \
+					__b2 = (byte *) b;  \
+					for (__i = 0; __i < l; __i++) {  \
+					  *(__b2 + __i) = SMC_inb((a),(r));  \
+					  SMC_inb((a),0);  \
+					};  \
+				})
+
+#elif defined(CONFIG_LEON)	/* if not CONFIG_CPU_PXA25X */
+
+#define SMC_LEON_SWAP16(_x_) ({ word _x = (_x_); ((_x << 8) | (_x >> 8)); })
+
+#define SMC_LEON_SWAP32(_x_)			\
+    ({ dword _x = (_x_);			\
+       ((_x << 24) |				\
+       ((0x0000FF00UL & _x) <<  8) |		\
+       ((0x00FF0000UL & _x) >>  8) |		\
+       (_x  >> 24)); })
+
+#define	SMC_inl(a,r)	(SMC_LEON_SWAP32((*(volatile dword *)((a)->iobase+((r)<<0)))))
+#define	SMC_inl_nosw(a,r)	((*(volatile dword *)((a)->iobase+((r)<<0))))
+#define	SMC_inw(a,r)	(SMC_LEON_SWAP16((*(volatile word *)((a)->iobase+((r)<<0)))))
+#define	SMC_inw_nosw(a,r)	((*(volatile word *)((a)->iobase+((r)<<0))))
+#define SMC_inb(a,p)	({ \
+	word ___v = SMC_inw((a),(p) & ~1); \
+	if ((p) & 1) ___v >>= 8; \
+	else ___v &= 0xff; \
+	___v; })
+
+#define	SMC_outl(a,d,r)	(*(volatile dword *)((a)->iobase+((r)<<0))=SMC_LEON_SWAP32(d))
+#define	SMC_outl_nosw(a,d,r)	(*(volatile dword *)((a)->iobase+((r)<<0))=(d))
+#define	SMC_outw(a,d,r)	(*(volatile word *)((a)->iobase+((r)<<0))=SMC_LEON_SWAP16(d))
+#define	SMC_outw_nosw(a,d,r)	(*(volatile word *)((a)->iobase+((r)<<0))=(d))
+#define	SMC_outb(a,d,r)	do{	word __d = (byte)(d);  \
+				word __w = SMC_inw((a),(r)&~1);  \
+				__w &= ((r)&1) ? 0x00FF : 0xFF00;  \
+				__w |= ((r)&1) ? __d<<8 : __d;  \
+				SMC_outw((a),__w,(r)&~1);  \
+			}while(0)
+#define SMC_outsl(a,r,b,l)	do{	int __i; \
+					dword *__b2; \
+					__b2 = (dword *) b; \
+					for (__i = 0; __i < l; __i++) { \
+					    SMC_outl_nosw((a), *(__b2 + __i), r); \
+					} \
+				}while(0)
+#define SMC_outsw(a,r,b,l)	do{	int __i; \
+					word *__b2; \
+					__b2 = (word *) b; \
+					for (__i = 0; __i < l; __i++) { \
+					    SMC_outw_nosw((a), *(__b2 + __i), r); \
+					} \
+				}while(0)
+#define SMC_insl(a,r,b,l)	do{	int __i ;  \
+					dword *__b2;  \
+					__b2 = (dword *) b;  \
+					for (__i = 0; __i < l; __i++) {  \
+					  *(__b2 + __i) = SMC_inl_nosw((a),(r));  \
+					};  \
+				}while(0)
+
+#define SMC_insw(a,r,b,l)		do{	int __i ;  \
+					word *__b2;  \
+					__b2 = (word *) b;  \
+					for (__i = 0; __i < l; __i++) {  \
+					  *(__b2 + __i) = SMC_inw_nosw((a),(r));  \
+					};  \
+				}while(0)
+
+#define SMC_insb(a,r,b,l)		do{	int __i ;  \
+					byte *__b2;  \
+					__b2 = (byte *) b;  \
+					for (__i = 0; __i < l; __i++) {  \
+					  *(__b2 + __i) = SMC_inb((a),(r));  \
+					};  \
+				}while(0)
+
+#else			/* if not CONFIG_CPU_PXA25X and not CONFIG_LEON */
+
+#ifndef CONFIG_SMC_USE_IOFUNCS /* these macros don't work on some boards */
+/*
+ * We have only 16 Bit PCMCIA access on Socket 0
+ */
+
+#ifdef CONFIG_ADNPESC1
+#define	SMC_inw(a,r)	(*((volatile word *)((a)->iobase+((r)<<1))))
+#elif CONFIG_BLACKFIN
+#define	SMC_inw(a,r)	({ word __v = (*((volatile word *)((a)->iobase+(r)))); SSYNC(); __v;})
+#else
+#define	SMC_inw(a,r)	(*((volatile word *)((a)->iobase+(r))))
+#endif
+#define  SMC_inb(a,r)	(((r)&1) ? SMC_inw((a),(r)&~1)>>8 : SMC_inw((a),(r)&0xFF))
+
+#ifdef CONFIG_ADNPESC1
+#define	SMC_outw(a,d,r)	(*((volatile word *)((a)->iobase+((r)<<1))) = d)
+#elif CONFIG_BLACKFIN
+#define	SMC_outw(a,d,r)	{(*((volatile word *)((a)->iobase+(r))) = d); SSYNC();}
+#else
+#define	SMC_outw(a,d,r)	(*((volatile word *)((a)->iobase+(r))) = d)
+#endif
+#define	SMC_outb(a,d,r)	({	word __d = (byte)(d);  \
+				word __w = SMC_inw((a),(r)&~1);  \
+				__w &= ((r)&1) ? 0x00FF : 0xFF00;  \
+				__w |= ((r)&1) ? __d<<8 : __d;  \
+				SMC_outw((a),__w,(r)&~1);  \
+			})
+#if 0
+#define	SMC_outsw(a,r,b,l)	outsw((a)->iobase+(r), (b), (l))
+#else
+#define SMC_outsw(a,r,b,l)	({	int __i; \
+					word *__b2; \
+					__b2 = (word *) b; \
+					for (__i = 0; __i < l; __i++) { \
+					    SMC_outw((a), *(__b2 + __i), r); \
+					} \
+				})
+#endif
+
+#if 0
+#define	SMC_insw(a,r,b,l)	insw((a)->iobase+(r), (b), (l))
+#else
+#define SMC_insw(a,r,b,l)	({	int __i ;  \
+					word *__b2;  \
+					__b2 = (word *) b;  \
+					for (__i = 0; __i < l; __i++) {  \
+					  *(__b2 + __i) = SMC_inw((a),(r));  \
+					  SMC_inw((a),0);  \
+					};  \
+				})
+#endif
+
+#endif  /* CONFIG_SMC_USE_IOFUNCS */
+
+#if defined(CONFIG_SMC_USE_32_BIT)
+
+#ifdef CONFIG_XSENGINE
+#define	SMC_inl(a,r)	(*((volatile dword *)((a)->iobase+(r<<1))))
+#else
+#define	SMC_inl(a,r)	(*((volatile dword *)((a)->iobase+(r))))
+#endif
+
+#define SMC_insl(a,r,b,l)	({	int __i ;  \
+					dword *__b2;  \
+					__b2 = (dword *) b;  \
+					for (__i = 0; __i < l; __i++) {  \
+					  *(__b2 + __i) = SMC_inl((a),(r));  \
+					  SMC_inl((a),0);  \
+					};  \
+				})
+
+#ifdef CONFIG_XSENGINE
+#define	SMC_outl(a,d,r)	(*((volatile dword *)((a)->iobase+(r<<1))) = d)
+#else
+#define	SMC_outl(a,d,r)	(*((volatile dword *)((a)->iobase+(r))) = d)
+#endif
+#define SMC_outsl(a,r,b,l)	({	int __i; \
+					dword *__b2; \
+					__b2 = (dword *) b; \
+					for (__i = 0; __i < l; __i++) { \
+					    SMC_outl((a), *(__b2 + __i), r); \
+					} \
+				})
+
+#endif /* CONFIG_SMC_USE_32_BIT */
+
+#endif
+
+/*---------------------------------------------------------------
+ .
+ . A description of the SMSC registers is probably in order here,
+ . although for details, the SMC datasheet is invaluable.
+ .
+ . Basically, the chip has 4 banks of registers ( 0 to 3 ), which
+ . are accessed by writing a number into the BANK_SELECT register
+ . ( I also use a SMC_SELECT_BANK macro for this ).
+ .
+ . The banks are configured so that for most purposes, bank 2 is all
+ . that is needed for simple run time tasks.
+ -----------------------------------------------------------------------*/
+
+/*
+ . Bank Select Register:
+ .
+ .		yyyy yyyy 0000 00xx
+ .		xx		= bank number
+ .		yyyy yyyy	= 0x33, for identification purposes.
+*/
+#define	BANK_SELECT		14
+
+/* Transmit Control Register */
+/* BANK 0  */
+#define	TCR_REG		0x0000	/* transmit control register */
+#define TCR_ENABLE	0x0001	/* When 1 we can transmit */
+#define TCR_LOOP	0x0002	/* Controls output pin LBK */
+#define TCR_FORCOL	0x0004	/* When 1 will force a collision */
+#define TCR_PAD_EN	0x0080	/* When 1 will pad tx frames < 64 bytes w/0 */
+#define TCR_NOCRC	0x0100	/* When 1 will not append CRC to tx frames */
+#define TCR_MON_CSN	0x0400	/* When 1 tx monitors carrier */
+#define TCR_FDUPLX	0x0800  /* When 1 enables full duplex operation */
+#define TCR_STP_SQET	0x1000	/* When 1 stops tx if Signal Quality Error */
+#define	TCR_EPH_LOOP	0x2000	/* When 1 enables EPH block loopback */
+#define	TCR_SWFDUP	0x8000	/* When 1 enables Switched Full Duplex mode */
+
+#define	TCR_CLEAR	0	/* do NOTHING */
+/* the default settings for the TCR register : */
+/* QUESTION: do I want to enable padding of short packets ? */
+#define	TCR_DEFAULT	TCR_ENABLE
+
+
+/* EPH Status Register */
+/* BANK 0  */
+#define EPH_STATUS_REG	0x0002
+#define ES_TX_SUC	0x0001	/* Last TX was successful */
+#define ES_SNGL_COL	0x0002	/* Single collision detected for last tx */
+#define ES_MUL_COL	0x0004	/* Multiple collisions detected for last tx */
+#define ES_LTX_MULT	0x0008	/* Last tx was a multicast */
+#define ES_16COL	0x0010	/* 16 Collisions Reached */
+#define ES_SQET		0x0020	/* Signal Quality Error Test */
+#define ES_LTXBRD	0x0040	/* Last tx was a broadcast */
+#define ES_TXDEFR	0x0080	/* Transmit Deferred */
+#define ES_LATCOL	0x0200	/* Late collision detected on last tx */
+#define ES_LOSTCARR	0x0400	/* Lost Carrier Sense */
+#define ES_EXC_DEF	0x0800	/* Excessive Deferral */
+#define ES_CTR_ROL	0x1000	/* Counter Roll Over indication */
+#define ES_LINK_OK	0x4000	/* Driven by inverted value of nLNK pin */
+#define ES_TXUNRN	0x8000	/* Tx Underrun */
+
+
+/* Receive Control Register */
+/* BANK 0  */
+#define	RCR_REG		0x0004
+#define	RCR_RX_ABORT	0x0001	/* Set if a rx frame was aborted */
+#define	RCR_PRMS	0x0002	/* Enable promiscuous mode */
+#define	RCR_ALMUL	0x0004	/* When set accepts all multicast frames */
+#define RCR_RXEN	0x0100	/* IFF this is set, we can receive packets */
+#define	RCR_STRIP_CRC	0x0200	/* When set strips CRC from rx packets */
+#define	RCR_ABORT_ENB	0x0200	/* When set will abort rx on collision */
+#define	RCR_FILT_CAR	0x0400	/* When set filters leading 12 bit s of carrier */
+#define RCR_SOFTRST	0x8000	/* resets the chip */
+
+/* the normal settings for the RCR register : */
+#define	RCR_DEFAULT	(RCR_STRIP_CRC | RCR_RXEN)
+#define RCR_CLEAR	0x0	/* set it to a base state */
+
+/* Counter Register */
+/* BANK 0  */
+#define	COUNTER_REG	0x0006
+
+/* Memory Information Register */
+/* BANK 0  */
+#define	MIR_REG		0x0008
+
+/* Receive/Phy Control Register */
+/* BANK 0  */
+#define	RPC_REG		0x000A
+#define	RPC_SPEED	0x2000	/* When 1 PHY is in 100Mbps mode. */
+#define	RPC_DPLX	0x1000	/* When 1 PHY is in Full-Duplex Mode */
+#define	RPC_ANEG	0x0800	/* When 1 PHY is in Auto-Negotiate Mode */
+#define	RPC_LSXA_SHFT	5	/* Bits to shift LS2A,LS1A,LS0A to lsb */
+#define	RPC_LSXB_SHFT	2	/* Bits to get LS2B,LS1B,LS0B to lsb */
+#define RPC_LED_100_10	(0x00)	/* LED = 100Mbps OR's with 10Mbps link detect */
+#define RPC_LED_RES	(0x01)	/* LED = Reserved */
+#define RPC_LED_10	(0x02)	/* LED = 10Mbps link detect */
+#define RPC_LED_FD	(0x03)	/* LED = Full Duplex Mode */
+#define RPC_LED_TX_RX	(0x04)	/* LED = TX or RX packet occurred */
+#define RPC_LED_100	(0x05)	/* LED = 100Mbps link dectect */
+#define RPC_LED_TX	(0x06)	/* LED = TX packet occurred */
+#define RPC_LED_RX	(0x07)	/* LED = RX packet occurred */
+#if defined(CONFIG_DK1C20) || defined(CONFIG_DK1S10)
+/* buggy schematic: LEDa -> yellow, LEDb --> green */
+#define RPC_DEFAULT	( RPC_SPEED | RPC_DPLX | RPC_ANEG	\
+			| (RPC_LED_TX_RX << RPC_LSXA_SHFT)	\
+			| (RPC_LED_100_10 << RPC_LSXB_SHFT)	)
+#elif defined(CONFIG_ADNPESC1)
+/* SSV ADNP/ESC1 has only one LED: LEDa -> Rx/Tx indicator */
+#define RPC_DEFAULT	( RPC_SPEED | RPC_DPLX | RPC_ANEG	\
+			| (RPC_LED_TX_RX << RPC_LSXA_SHFT)	\
+			| (RPC_LED_100_10 << RPC_LSXB_SHFT)	)
+#else
+/* SMSC reference design: LEDa --> green, LEDb --> yellow */
+#define RPC_DEFAULT	( RPC_SPEED | RPC_DPLX | RPC_ANEG	\
+			| (RPC_LED_100_10 << RPC_LSXA_SHFT)	\
+			| (RPC_LED_TX_RX << RPC_LSXB_SHFT)	)
+#endif
+
+/* Bank 0 0x000C is reserved */
+
+/* Bank Select Register */
+/* All Banks */
+#define BSR_REG	0x000E
+
+
+/* Configuration Reg */
+/* BANK 1 */
+#define CONFIG_REG	0x0000
+#define CONFIG_EXT_PHY	0x0200	/* 1=external MII, 0=internal Phy */
+#define CONFIG_GPCNTRL	0x0400	/* Inverse value drives pin nCNTRL */
+#define CONFIG_NO_WAIT	0x1000	/* When 1 no extra wait states on ISA bus */
+#define CONFIG_EPH_POWER_EN 0x8000 /* When 0 EPH is placed into low power mode. */
+
+/* Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low */
+#define CONFIG_DEFAULT	(CONFIG_EPH_POWER_EN)
+
+
+/* Base Address Register */
+/* BANK 1 */
+#define	BASE_REG	0x0002
+
+
+/* Individual Address Registers */
+/* BANK 1 */
+#define	ADDR0_REG	0x0004
+#define	ADDR1_REG	0x0006
+#define	ADDR2_REG	0x0008
+
+
+/* General Purpose Register */
+/* BANK 1 */
+#define	GP_REG		0x000A
+
+
+/* Control Register */
+/* BANK 1 */
+#define	CTL_REG		0x000C
+#define CTL_RCV_BAD	0x4000 /* When 1 bad CRC packets are received */
+#define CTL_AUTO_RELEASE 0x0800 /* When 1 tx pages are released automatically */
+#define	CTL_LE_ENABLE	0x0080 /* When 1 enables Link Error interrupt */
+#define	CTL_CR_ENABLE	0x0040 /* When 1 enables Counter Rollover interrupt */
+#define	CTL_TE_ENABLE	0x0020 /* When 1 enables Transmit Error interrupt */
+#define	CTL_EEPROM_SELECT 0x0004 /* Controls EEPROM reload & store */
+#define	CTL_RELOAD	0x0002 /* When set reads EEPROM into registers */
+#define	CTL_STORE	0x0001 /* When set stores registers into EEPROM */
+#define CTL_DEFAULT     (0x1A10) /* Autorelease enabled*/
+
+/* MMU Command Register */
+/* BANK 2 */
+#define MMU_CMD_REG	0x0000
+#define MC_BUSY		1	/* When 1 the last release has not completed */
+#define MC_NOP		(0<<5)	/* No Op */
+#define	MC_ALLOC	(1<<5)	/* OR with number of 256 byte packets */
+#define	MC_RESET	(2<<5)	/* Reset MMU to initial state */
+#define	MC_REMOVE	(3<<5)	/* Remove the current rx packet */
+#define MC_RELEASE	(4<<5)	/* Remove and release the current rx packet */
+#define MC_FREEPKT	(5<<5)	/* Release packet in PNR register */
+#define MC_ENQUEUE	(6<<5)	/* Enqueue the packet for transmit */
+#define MC_RSTTXFIFO	(7<<5)	/* Reset the TX FIFOs */
+
+
+/* Packet Number Register */
+/* BANK 2 */
+#define	PN_REG		0x0002
+
+
+/* Allocation Result Register */
+/* BANK 2 */
+#define	AR_REG		0x0003
+#define AR_FAILED	0x80	/* Alocation Failed */
+
+
+/* RX FIFO Ports Register */
+/* BANK 2 */
+#define RXFIFO_REG	0x0004	/* Must be read as a word */
+#define RXFIFO_REMPTY	0x8000	/* RX FIFO Empty */
+
+
+/* TX FIFO Ports Register */
+/* BANK 2 */
+#define TXFIFO_REG	RXFIFO_REG	/* Must be read as a word */
+#define TXFIFO_TEMPTY	0x80	/* TX FIFO Empty */
+
+
+/* Pointer Register */
+/* BANK 2 */
+#define PTR_REG		0x0006
+#define	PTR_RCV		0x8000 /* 1=Receive area, 0=Transmit area */
+#define	PTR_AUTOINC	0x4000 /* Auto increment the pointer on each access */
+#define PTR_READ	0x2000 /* When 1 the operation is a read */
+#define PTR_NOTEMPTY	0x0800 /* When 1 _do not_ write fifo DATA REG */
+
+
+/* Data Register */
+/* BANK 2 */
+#define	SMC91111_DATA_REG	0x0008
+
+
+/* Interrupt Status/Acknowledge Register */
+/* BANK 2 */
+#define	SMC91111_INT_REG	0x000C
+
+
+/* Interrupt Mask Register */
+/* BANK 2 */
+#define IM_REG		0x000D
+#define	IM_MDINT	0x80 /* PHY MI Register 18 Interrupt */
+#define	IM_ERCV_INT	0x40 /* Early Receive Interrupt */
+#define	IM_EPH_INT	0x20 /* Set by Etheret Protocol Handler section */
+#define	IM_RX_OVRN_INT	0x10 /* Set by Receiver Overruns */
+#define	IM_ALLOC_INT	0x08 /* Set when allocation request is completed */
+#define	IM_TX_EMPTY_INT	0x04 /* Set if the TX FIFO goes empty */
+#define	IM_TX_INT	0x02 /* Transmit Interrrupt */
+#define IM_RCV_INT	0x01 /* Receive Interrupt */
+
+
+/* Multicast Table Registers */
+/* BANK 3 */
+#define	MCAST_REG1	0x0000
+#define	MCAST_REG2	0x0002
+#define	MCAST_REG3	0x0004
+#define	MCAST_REG4	0x0006
+
+
+/* Management Interface Register (MII) */
+/* BANK 3 */
+#define	MII_REG		0x0008
+#define MII_MSK_CRS100	0x4000 /* Disables CRS100 detection during tx half dup */
+#define MII_MDOE	0x0008 /* MII Output Enable */
+#define MII_MCLK	0x0004 /* MII Clock, pin MDCLK */
+#define MII_MDI		0x0002 /* MII Input, pin MDI */
+#define MII_MDO		0x0001 /* MII Output, pin MDO */
+
+
+/* Revision Register */
+/* BANK 3 */
+#define	REV_REG		0x000A /* ( hi: chip id   low: rev # ) */
+
+
+/* Early RCV Register */
+/* BANK 3 */
+/* this is NOT on SMC9192 */
+#define	ERCV_REG	0x000C
+#define ERCV_RCV_DISCRD	0x0080 /* When 1 discards a packet being received */
+#define ERCV_THRESHOLD	0x001F /* ERCV Threshold Mask */
+
+/* External Register */
+/* BANK 7 */
+#define	EXT_REG		0x0000
+
+
+#define CHIP_9192	3
+#define CHIP_9194	4
+#define CHIP_9195	5
+#define CHIP_9196	6
+#define CHIP_91100	7
+#define CHIP_91100FD	8
+#define CHIP_91111FD	9
+
+#if 0
+static const char * chip_ids[ 15 ] =  {
+	NULL, NULL, NULL,
+	/* 3 */ "SMC91C90/91C92",
+	/* 4 */ "SMC91C94",
+	/* 5 */ "SMC91C95",
+	/* 6 */ "SMC91C96",
+	/* 7 */ "SMC91C100",
+	/* 8 */ "SMC91C100FD",
+	/* 9 */ "SMC91C111",
+	NULL, NULL,
+	NULL, NULL, NULL};
+#endif
+
+/*
+ . Transmit status bits
+*/
+#define TS_SUCCESS 0x0001
+#define TS_LOSTCAR 0x0400
+#define TS_LATCOL  0x0200
+#define TS_16COL   0x0010
+
+/*
+ . Receive status bits
+*/
+#define RS_ALGNERR	0x8000
+#define RS_BRODCAST	0x4000
+#define RS_BADCRC	0x2000
+#define RS_ODDFRAME	0x1000	/* bug: the LAN91C111 never sets this on receive */
+#define RS_TOOLONG	0x0800
+#define RS_TOOSHORT	0x0400
+#define RS_MULTICAST	0x0001
+#define RS_ERRORS	(RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
+
+
+/* PHY Types */
+enum {
+	PHY_LAN83C183 = 1,	/* LAN91C111 Internal PHY */
+	PHY_LAN83C180
+};
+
+
+/* PHY Register Addresses (LAN91C111 Internal PHY) */
+
+/* PHY Control Register */
+#define PHY_CNTL_REG		0x00
+#define PHY_CNTL_RST		0x8000	/* 1=PHY Reset */
+#define PHY_CNTL_LPBK		0x4000	/* 1=PHY Loopback */
+#define PHY_CNTL_SPEED		0x2000	/* 1=100Mbps, 0=10Mpbs */
+#define PHY_CNTL_ANEG_EN	0x1000 /* 1=Enable Auto negotiation */
+#define PHY_CNTL_PDN		0x0800	/* 1=PHY Power Down mode */
+#define PHY_CNTL_MII_DIS	0x0400	/* 1=MII 4 bit interface disabled */
+#define PHY_CNTL_ANEG_RST	0x0200 /* 1=Reset Auto negotiate */
+#define PHY_CNTL_DPLX		0x0100	/* 1=Full Duplex, 0=Half Duplex */
+#define PHY_CNTL_COLTST		0x0080	/* 1= MII Colision Test */
+
+/* PHY Status Register */
+#define PHY_STAT_REG		0x01
+#define PHY_STAT_CAP_T4		0x8000	/* 1=100Base-T4 capable */
+#define PHY_STAT_CAP_TXF	0x4000	/* 1=100Base-X full duplex capable */
+#define PHY_STAT_CAP_TXH	0x2000	/* 1=100Base-X half duplex capable */
+#define PHY_STAT_CAP_TF		0x1000	/* 1=10Mbps full duplex capable */
+#define PHY_STAT_CAP_TH		0x0800	/* 1=10Mbps half duplex capable */
+#define PHY_STAT_CAP_SUPR	0x0040	/* 1=recv mgmt frames with not preamble */
+#define PHY_STAT_ANEG_ACK	0x0020	/* 1=ANEG has completed */
+#define PHY_STAT_REM_FLT	0x0010	/* 1=Remote Fault detected */
+#define PHY_STAT_CAP_ANEG	0x0008	/* 1=Auto negotiate capable */
+#define PHY_STAT_LINK		0x0004	/* 1=valid link */
+#define PHY_STAT_JAB		0x0002	/* 1=10Mbps jabber condition */
+#define PHY_STAT_EXREG		0x0001	/* 1=extended registers implemented */
+
+/* PHY Identifier Registers */
+#define PHY_ID1_REG		0x02	/* PHY Identifier 1 */
+#define PHY_ID2_REG		0x03	/* PHY Identifier 2 */
+
+/* PHY Auto-Negotiation Advertisement Register */
+#define PHY_AD_REG		0x04
+#define PHY_AD_NP		0x8000	/* 1=PHY requests exchange of Next Page */
+#define PHY_AD_ACK		0x4000	/* 1=got link code word from remote */
+#define PHY_AD_RF		0x2000	/* 1=advertise remote fault */
+#define PHY_AD_T4		0x0200	/* 1=PHY is capable of 100Base-T4 */
+#define PHY_AD_TX_FDX		0x0100	/* 1=PHY is capable of 100Base-TX FDPLX */
+#define PHY_AD_TX_HDX		0x0080	/* 1=PHY is capable of 100Base-TX HDPLX */
+#define PHY_AD_10_FDX		0x0040	/* 1=PHY is capable of 10Base-T FDPLX */
+#define PHY_AD_10_HDX		0x0020	/* 1=PHY is capable of 10Base-T HDPLX */
+#define PHY_AD_CSMA		0x0001	/* 1=PHY is capable of 802.3 CMSA */
+
+/* PHY Auto-negotiation Remote End Capability Register */
+#define PHY_RMT_REG		0x05
+/* Uses same bit definitions as PHY_AD_REG */
+
+/* PHY Configuration Register 1 */
+#define PHY_CFG1_REG		0x10
+#define PHY_CFG1_LNKDIS		0x8000	/* 1=Rx Link Detect Function disabled */
+#define PHY_CFG1_XMTDIS		0x4000	/* 1=TP Transmitter Disabled */
+#define PHY_CFG1_XMTPDN		0x2000	/* 1=TP Transmitter Powered Down */
+#define PHY_CFG1_BYPSCR		0x0400	/* 1=Bypass scrambler/descrambler */
+#define PHY_CFG1_UNSCDS		0x0200	/* 1=Unscramble Idle Reception Disable */
+#define PHY_CFG1_EQLZR		0x0100	/* 1=Rx Equalizer Disabled */
+#define PHY_CFG1_CABLE		0x0080	/* 1=STP(150ohm), 0=UTP(100ohm) */
+#define PHY_CFG1_RLVL0		0x0040	/* 1=Rx Squelch level reduced by 4.5db */
+#define PHY_CFG1_TLVL_SHIFT	2	/* Transmit Output Level Adjust */
+#define PHY_CFG1_TLVL_MASK	0x003C
+#define PHY_CFG1_TRF_MASK	0x0003	/* Transmitter Rise/Fall time */
+
+
+/* PHY Configuration Register 2 */
+#define PHY_CFG2_REG		0x11
+#define PHY_CFG2_APOLDIS	0x0020	/* 1=Auto Polarity Correction disabled */
+#define PHY_CFG2_JABDIS		0x0010	/* 1=Jabber disabled */
+#define PHY_CFG2_MREG		0x0008	/* 1=Multiple register access (MII mgt) */
+#define PHY_CFG2_INTMDIO	0x0004	/* 1=Interrupt signaled with MDIO pulseo */
+
+/* PHY Status Output (and Interrupt status) Register */
+#define PHY_INT_REG		0x12	/* Status Output (Interrupt Status) */
+#define PHY_INT_INT		0x8000	/* 1=bits have changed since last read */
+#define	PHY_INT_LNKFAIL		0x4000	/* 1=Link Not detected */
+#define PHY_INT_LOSSSYNC	0x2000	/* 1=Descrambler has lost sync */
+#define PHY_INT_CWRD		0x1000	/* 1=Invalid 4B5B code detected on rx */
+#define PHY_INT_SSD		0x0800	/* 1=No Start Of Stream detected on rx */
+#define PHY_INT_ESD		0x0400	/* 1=No End Of Stream detected on rx */
+#define PHY_INT_RPOL		0x0200	/* 1=Reverse Polarity detected */
+#define PHY_INT_JAB		0x0100	/* 1=Jabber detected */
+#define PHY_INT_SPDDET		0x0080	/* 1=100Base-TX mode, 0=10Base-T mode */
+#define PHY_INT_DPLXDET		0x0040	/* 1=Device in Full Duplex */
+
+/* PHY Interrupt/Status Mask Register */
+#define PHY_MASK_REG		0x13	/* Interrupt Mask */
+/* Uses the same bit definitions as PHY_INT_REG */
+
+
+/*-------------------------------------------------------------------------
+ .  I define some macros to make it easier to do somewhat common
+ . or slightly complicated, repeated tasks.
+ --------------------------------------------------------------------------*/
+
+/* select a register bank, 0 to 3  */
+
+#define SMC_SELECT_BANK(a,x)  { SMC_outw((a), (x), BANK_SELECT ); }
+
+/* this enables an interrupt in the interrupt mask register */
+#define SMC_ENABLE_INT(a,x) {\
+		unsigned char mask;\
+		SMC_SELECT_BANK((a),2);\
+		mask = SMC_inb((a), IM_REG );\
+		mask |= (x);\
+		SMC_outb( (a), mask, IM_REG ); \
+}
+
+/* this disables an interrupt from the interrupt mask register */
+
+#define SMC_DISABLE_INT(a,x) {\
+		unsigned char mask;\
+		SMC_SELECT_BANK(2);\
+		mask = SMC_inb( (a), IM_REG );\
+		mask &= ~(x);\
+		SMC_outb( (a), mask, IM_REG ); \
+}
+
+/*----------------------------------------------------------------------
+ . Define the interrupts that I want to receive from the card
+ .
+ . I want:
+ .  IM_EPH_INT, for nasty errors
+ .  IM_RCV_INT, for happy received packets
+ .  IM_RX_OVRN_INT, because I have to kick the receiver
+ .  IM_MDINT, for PHY Register 18 Status Changes
+ --------------------------------------------------------------------------*/
+#define SMC_INTERRUPT_MASK   (IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | \
+	IM_MDINT)
+
+#endif  /* _SMC_91111_H_ */
diff --git a/marvell/uboot/drivers/net/smc911x.c b/marvell/uboot/drivers/net/smc911x.c
new file mode 100644
index 0000000..b097c1a
--- /dev/null
+++ b/marvell/uboot/drivers/net/smc911x.c
@@ -0,0 +1,282 @@
+/*
+ * SMSC LAN9[12]1[567] Network driver
+ *
+ * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <net.h>
+#include <miiphy.h>
+
+#include "smc911x.h"
+
+u32 pkt_data_pull(struct eth_device *dev, u32 addr) \
+	__attribute__ ((weak, alias ("smc911x_reg_read")));
+void pkt_data_push(struct eth_device *dev, u32 addr, u32 val) \
+	__attribute__ ((weak, alias ("smc911x_reg_write")));
+
+static void smc911x_handle_mac_address(struct eth_device *dev)
+{
+	unsigned long addrh, addrl;
+	uchar *m = dev->enetaddr;
+
+	addrl = m[0] | (m[1] << 8) | (m[2] << 16) | (m[3] << 24);
+	addrh = m[4] | (m[5] << 8);
+	smc911x_set_mac_csr(dev, ADDRL, addrl);
+	smc911x_set_mac_csr(dev, ADDRH, addrh);
+
+	printf(DRIVERNAME ": MAC %pM\n", m);
+}
+
+static int smc911x_eth_phy_read(struct eth_device *dev,
+				u8 phy, u8 reg, u16 *val)
+{
+	while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY)
+		;
+
+	smc911x_set_mac_csr(dev, MII_ACC, phy << 11 | reg << 6 |
+				MII_ACC_MII_BUSY);
+
+	while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY)
+		;
+
+	*val = smc911x_get_mac_csr(dev, MII_DATA);
+
+	return 0;
+}
+
+static int smc911x_eth_phy_write(struct eth_device *dev,
+				u8 phy, u8 reg, u16  val)
+{
+	while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY)
+		;
+
+	smc911x_set_mac_csr(dev, MII_DATA, val);
+	smc911x_set_mac_csr(dev, MII_ACC,
+		phy << 11 | reg << 6 | MII_ACC_MII_BUSY | MII_ACC_MII_WRITE);
+
+	while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY)
+		;
+	return 0;
+}
+
+static int smc911x_phy_reset(struct eth_device *dev)
+{
+	u32 reg;
+
+	reg = smc911x_reg_read(dev, PMT_CTRL);
+	reg &= ~0xfffff030;
+	reg |= PMT_CTRL_PHY_RST;
+	smc911x_reg_write(dev, PMT_CTRL, reg);
+
+	mdelay(100);
+
+	return 0;
+}
+
+static void smc911x_phy_configure(struct eth_device *dev)
+{
+	int timeout;
+	u16 status;
+
+	smc911x_phy_reset(dev);
+
+	smc911x_eth_phy_write(dev, 1, MII_BMCR, BMCR_RESET);
+	mdelay(1);
+	smc911x_eth_phy_write(dev, 1, MII_ADVERTISE, 0x01e1);
+	smc911x_eth_phy_write(dev, 1, MII_BMCR, BMCR_ANENABLE |
+				BMCR_ANRESTART);
+
+	timeout = 5000;
+	do {
+		mdelay(1);
+		if ((timeout--) == 0)
+			goto err_out;
+
+		if (smc911x_eth_phy_read(dev, 1, MII_BMSR, &status) != 0)
+			goto err_out;
+	} while (!(status & BMSR_LSTATUS));
+
+	printf(DRIVERNAME ": phy initialized\n");
+
+	return;
+
+err_out:
+	printf(DRIVERNAME ": autonegotiation timed out\n");
+}
+
+static void smc911x_enable(struct eth_device *dev)
+{
+	/* Enable TX */
+	smc911x_reg_write(dev, HW_CFG, 8 << 16 | HW_CFG_SF);
+
+	smc911x_reg_write(dev, GPT_CFG, GPT_CFG_TIMER_EN | 10000);
+
+	smc911x_reg_write(dev, TX_CFG, TX_CFG_TX_ON);
+
+	/* no padding to start of packets */
+	smc911x_reg_write(dev, RX_CFG, 0);
+
+	smc911x_set_mac_csr(dev, MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN |
+				MAC_CR_HBDIS);
+
+}
+
+static int smc911x_init(struct eth_device *dev, bd_t * bd)
+{
+	struct chip_id *id = dev->priv;
+
+	printf(DRIVERNAME ": detected %s controller\n", id->name);
+
+	smc911x_reset(dev);
+
+	/* Configure the PHY, initialize the link state */
+	smc911x_phy_configure(dev);
+
+	smc911x_handle_mac_address(dev);
+
+	/* Turn on Tx + Rx */
+	smc911x_enable(dev);
+
+	return 0;
+}
+
+static int smc911x_send(struct eth_device *dev, void *packet, int length)
+{
+	u32 *data = (u32*)packet;
+	u32 tmplen;
+	u32 status;
+
+	smc911x_reg_write(dev, TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG |
+				TX_CMD_A_INT_LAST_SEG | length);
+	smc911x_reg_write(dev, TX_DATA_FIFO, length);
+
+	tmplen = (length + 3) / 4;
+
+	while (tmplen--)
+		pkt_data_push(dev, TX_DATA_FIFO, *data++);
+
+	/* wait for transmission */
+	while (!((smc911x_reg_read(dev, TX_FIFO_INF) &
+					TX_FIFO_INF_TSUSED) >> 16));
+
+	/* get status. Ignore 'no carrier' error, it has no meaning for
+	 * full duplex operation
+	 */
+	status = smc911x_reg_read(dev, TX_STATUS_FIFO) &
+			(TX_STS_LOC | TX_STS_LATE_COLL | TX_STS_MANY_COLL |
+			TX_STS_MANY_DEFER | TX_STS_UNDERRUN);
+
+	if (!status)
+		return 0;
+
+	printf(DRIVERNAME ": failed to send packet: %s%s%s%s%s\n",
+		status & TX_STS_LOC ? "TX_STS_LOC " : "",
+		status & TX_STS_LATE_COLL ? "TX_STS_LATE_COLL " : "",
+		status & TX_STS_MANY_COLL ? "TX_STS_MANY_COLL " : "",
+		status & TX_STS_MANY_DEFER ? "TX_STS_MANY_DEFER " : "",
+		status & TX_STS_UNDERRUN ? "TX_STS_UNDERRUN" : "");
+
+	return -1;
+}
+
+static void smc911x_halt(struct eth_device *dev)
+{
+	smc911x_reset(dev);
+}
+
+static int smc911x_rx(struct eth_device *dev)
+{
+	u32 *data = (u32 *)NetRxPackets[0];
+	u32 pktlen, tmplen;
+	u32 status;
+
+	if ((smc911x_reg_read(dev, RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) {
+		status = smc911x_reg_read(dev, RX_STATUS_FIFO);
+		pktlen = (status & RX_STS_PKT_LEN) >> 16;
+
+		smc911x_reg_write(dev, RX_CFG, 0);
+
+		tmplen = (pktlen + 3) / 4;
+		while (tmplen--)
+			*data++ = pkt_data_pull(dev, RX_DATA_FIFO);
+
+		if (status & RX_STS_ES)
+			printf(DRIVERNAME
+				": dropped bad packet. Status: 0x%08x\n",
+				status);
+		else
+			NetReceive(NetRxPackets[0], pktlen);
+	}
+
+	return 0;
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+/* wrapper for smc911x_eth_phy_read */
+static int smc911x_miiphy_read(const char *devname, u8 phy, u8 reg, u16 *val)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	if (dev)
+		return smc911x_eth_phy_read(dev, phy, reg, val);
+	return -1;
+}
+/* wrapper for smc911x_eth_phy_write */
+static int smc911x_miiphy_write(const char *devname, u8 phy, u8 reg, u16 val)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	if (dev)
+		return smc911x_eth_phy_write(dev, phy, reg, val);
+	return -1;
+}
+#endif
+
+int smc911x_initialize(u8 dev_num, int base_addr)
+{
+	unsigned long addrl, addrh;
+	struct eth_device *dev;
+
+	dev = malloc(sizeof(*dev));
+	if (!dev) {
+		return -1;
+	}
+	memset(dev, 0, sizeof(*dev));
+
+	dev->iobase = base_addr;
+
+	/* Try to detect chip. Will fail if not present. */
+	if (smc911x_detect_chip(dev)) {
+		free(dev);
+		return 0;
+	}
+
+	addrh = smc911x_get_mac_csr(dev, ADDRH);
+	addrl = smc911x_get_mac_csr(dev, ADDRL);
+	if (!(addrl == 0xffffffff && addrh == 0x0000ffff)) {
+		/* address is obtained from optional eeprom */
+		dev->enetaddr[0] = addrl;
+		dev->enetaddr[1] = addrl >>  8;
+		dev->enetaddr[2] = addrl >> 16;
+		dev->enetaddr[3] = addrl >> 24;
+		dev->enetaddr[4] = addrh;
+		dev->enetaddr[5] = addrh >> 8;
+	}
+
+	dev->init = smc911x_init;
+	dev->halt = smc911x_halt;
+	dev->send = smc911x_send;
+	dev->recv = smc911x_rx;
+	sprintf(dev->name, "%s-%hu", DRIVERNAME, dev_num);
+
+	eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	miiphy_register(dev->name, smc911x_miiphy_read, smc911x_miiphy_write);
+#endif
+
+	return 1;
+}
diff --git a/marvell/uboot/drivers/net/smc911x.h b/marvell/uboot/drivers/net/smc911x.h
new file mode 100644
index 0000000..acae0cf
--- /dev/null
+++ b/marvell/uboot/drivers/net/smc911x.h
@@ -0,0 +1,500 @@
+/*
+ * SMSC LAN9[12]1[567] Network driver
+ *
+ * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _SMC911X_H_
+#define _SMC911X_H_
+
+#include <linux/types.h>
+
+#define DRIVERNAME "smc911x"
+
+#if defined (CONFIG_SMC911X_32_BIT) && \
+	defined (CONFIG_SMC911X_16_BIT)
+#error "SMC911X: Only one of CONFIG_SMC911X_32_BIT and \
+	CONFIG_SMC911X_16_BIT shall be set"
+#endif
+
+#if defined (CONFIG_SMC911X_32_BIT)
+static inline u32 __smc911x_reg_read(struct eth_device *dev, u32 offset)
+{
+	return *(volatile u32*)(dev->iobase + offset);
+}
+u32 smc911x_reg_read(struct eth_device *dev, u32 offset)
+	__attribute__((weak, alias("__smc911x_reg_read")));
+
+static inline void __smc911x_reg_write(struct eth_device *dev,
+					u32 offset, u32 val)
+{
+	*(volatile u32*)(dev->iobase + offset) = val;
+}
+void smc911x_reg_write(struct eth_device *dev, u32 offset, u32 val)
+	__attribute__((weak, alias("__smc911x_reg_write")));
+#elif defined (CONFIG_SMC911X_16_BIT)
+static inline u32 smc911x_reg_read(struct eth_device *dev, u32 offset)
+{
+	volatile u16 *addr_16 = (u16 *)(dev->iobase + offset);
+	return ((*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16));
+}
+static inline void smc911x_reg_write(struct eth_device *dev,
+					u32 offset, u32 val)
+{
+	*(volatile u16 *)(dev->iobase + offset) = (u16)val;
+	*(volatile u16 *)(dev->iobase + offset + 2) = (u16)(val >> 16);
+}
+#else
+#error "SMC911X: undefined bus width"
+#endif /* CONFIG_SMC911X_16_BIT */
+
+/* Below are the register offsets and bit definitions
+ * of the Lan911x memory space
+ */
+#define RX_DATA_FIFO		 		0x00
+
+#define TX_DATA_FIFO		 		0x20
+#define	TX_CMD_A_INT_ON_COMP			0x80000000
+#define	TX_CMD_A_INT_BUF_END_ALGN		0x03000000
+#define	TX_CMD_A_INT_4_BYTE_ALGN		0x00000000
+#define	TX_CMD_A_INT_16_BYTE_ALGN		0x01000000
+#define	TX_CMD_A_INT_32_BYTE_ALGN		0x02000000
+#define	TX_CMD_A_INT_DATA_OFFSET		0x001F0000
+#define	TX_CMD_A_INT_FIRST_SEG			0x00002000
+#define	TX_CMD_A_INT_LAST_SEG			0x00001000
+#define	TX_CMD_A_BUF_SIZE			0x000007FF
+#define	TX_CMD_B_PKT_TAG			0xFFFF0000
+#define	TX_CMD_B_ADD_CRC_DISABLE		0x00002000
+#define	TX_CMD_B_DISABLE_PADDING		0x00001000
+#define	TX_CMD_B_PKT_BYTE_LENGTH		0x000007FF
+
+#define RX_STATUS_FIFO				0x40
+#define	RX_STS_PKT_LEN				0x3FFF0000
+#define	RX_STS_ES				0x00008000
+#define	RX_STS_BCST				0x00002000
+#define	RX_STS_LEN_ERR				0x00001000
+#define	RX_STS_RUNT_ERR				0x00000800
+#define	RX_STS_MCAST				0x00000400
+#define	RX_STS_TOO_LONG				0x00000080
+#define	RX_STS_COLL				0x00000040
+#define	RX_STS_ETH_TYPE				0x00000020
+#define	RX_STS_WDOG_TMT				0x00000010
+#define	RX_STS_MII_ERR				0x00000008
+#define	RX_STS_DRIBBLING			0x00000004
+#define	RX_STS_CRC_ERR				0x00000002
+#define RX_STATUS_FIFO_PEEK			0x44
+#define TX_STATUS_FIFO				0x48
+#define	TX_STS_TAG				0xFFFF0000
+#define	TX_STS_ES				0x00008000
+#define	TX_STS_LOC				0x00000800
+#define	TX_STS_NO_CARR				0x00000400
+#define	TX_STS_LATE_COLL			0x00000200
+#define	TX_STS_MANY_COLL			0x00000100
+#define	TX_STS_COLL_CNT				0x00000078
+#define	TX_STS_MANY_DEFER			0x00000004
+#define	TX_STS_UNDERRUN				0x00000002
+#define	TX_STS_DEFERRED				0x00000001
+#define TX_STATUS_FIFO_PEEK			0x4C
+#define ID_REV					0x50
+#define	ID_REV_CHIP_ID				0xFFFF0000  /* RO */
+#define	ID_REV_REV_ID				0x0000FFFF  /* RO */
+
+#define INT_CFG					0x54
+#define	INT_CFG_INT_DEAS			0xFF000000  /* R/W */
+#define	INT_CFG_INT_DEAS_CLR			0x00004000
+#define	INT_CFG_INT_DEAS_STS			0x00002000
+#define	INT_CFG_IRQ_INT				0x00001000  /* RO */
+#define	INT_CFG_IRQ_EN				0x00000100  /* R/W */
+					/* R/W Not Affected by SW Reset */
+#define	INT_CFG_IRQ_POL				0x00000010
+					/* R/W Not Affected by SW Reset */
+#define	INT_CFG_IRQ_TYPE			0x00000001
+
+#define INT_STS					0x58
+#define	INT_STS_SW_INT				0x80000000  /* R/WC */
+#define	INT_STS_TXSTOP_INT			0x02000000  /* R/WC */
+#define	INT_STS_RXSTOP_INT			0x01000000  /* R/WC */
+#define	INT_STS_RXDFH_INT			0x00800000  /* R/WC */
+#define	INT_STS_RXDF_INT			0x00400000  /* R/WC */
+#define	INT_STS_TX_IOC				0x00200000  /* R/WC */
+#define	INT_STS_RXD_INT				0x00100000  /* R/WC */
+#define	INT_STS_GPT_INT				0x00080000  /* R/WC */
+#define	INT_STS_PHY_INT				0x00040000  /* RO */
+#define	INT_STS_PME_INT				0x00020000  /* R/WC */
+#define	INT_STS_TXSO				0x00010000  /* R/WC */
+#define	INT_STS_RWT				0x00008000  /* R/WC */
+#define	INT_STS_RXE				0x00004000  /* R/WC */
+#define	INT_STS_TXE				0x00002000  /* R/WC */
+/*#define	INT_STS_ERX		0x00001000*/  /* R/WC */
+#define	INT_STS_TDFU				0x00000800  /* R/WC */
+#define	INT_STS_TDFO				0x00000400  /* R/WC */
+#define	INT_STS_TDFA				0x00000200  /* R/WC */
+#define	INT_STS_TSFF				0x00000100  /* R/WC */
+#define	INT_STS_TSFL				0x00000080  /* R/WC */
+/*#define	INT_STS_RXDF		0x00000040*/  /* R/WC */
+#define	INT_STS_RDFO				0x00000040  /* R/WC */
+#define	INT_STS_RDFL				0x00000020  /* R/WC */
+#define	INT_STS_RSFF				0x00000010  /* R/WC */
+#define	INT_STS_RSFL				0x00000008  /* R/WC */
+#define	INT_STS_GPIO2_INT			0x00000004  /* R/WC */
+#define	INT_STS_GPIO1_INT			0x00000002  /* R/WC */
+#define	INT_STS_GPIO0_INT			0x00000001  /* R/WC */
+#define INT_EN					0x5C
+#define	INT_EN_SW_INT_EN			0x80000000  /* R/W */
+#define	INT_EN_TXSTOP_INT_EN			0x02000000  /* R/W */
+#define	INT_EN_RXSTOP_INT_EN			0x01000000  /* R/W */
+#define	INT_EN_RXDFH_INT_EN			0x00800000  /* R/W */
+/*#define	INT_EN_RXDF_INT_EN		0x00400000*/  /* R/W */
+#define	INT_EN_TIOC_INT_EN			0x00200000  /* R/W */
+#define	INT_EN_RXD_INT_EN			0x00100000  /* R/W */
+#define	INT_EN_GPT_INT_EN			0x00080000  /* R/W */
+#define	INT_EN_PHY_INT_EN			0x00040000  /* R/W */
+#define	INT_EN_PME_INT_EN			0x00020000  /* R/W */
+#define	INT_EN_TXSO_EN				0x00010000  /* R/W */
+#define	INT_EN_RWT_EN				0x00008000  /* R/W */
+#define	INT_EN_RXE_EN				0x00004000  /* R/W */
+#define	INT_EN_TXE_EN				0x00002000  /* R/W */
+/*#define	INT_EN_ERX_EN			0x00001000*/  /* R/W */
+#define	INT_EN_TDFU_EN				0x00000800  /* R/W */
+#define	INT_EN_TDFO_EN				0x00000400  /* R/W */
+#define	INT_EN_TDFA_EN				0x00000200  /* R/W */
+#define	INT_EN_TSFF_EN				0x00000100  /* R/W */
+#define	INT_EN_TSFL_EN				0x00000080  /* R/W */
+/*#define	INT_EN_RXDF_EN			0x00000040*/  /* R/W */
+#define	INT_EN_RDFO_EN				0x00000040  /* R/W */
+#define	INT_EN_RDFL_EN				0x00000020  /* R/W */
+#define	INT_EN_RSFF_EN				0x00000010  /* R/W */
+#define	INT_EN_RSFL_EN				0x00000008  /* R/W */
+#define	INT_EN_GPIO2_INT			0x00000004  /* R/W */
+#define	INT_EN_GPIO1_INT			0x00000002  /* R/W */
+#define	INT_EN_GPIO0_INT			0x00000001  /* R/W */
+
+#define BYTE_TEST				0x64
+#define FIFO_INT				0x68
+#define	FIFO_INT_TX_AVAIL_LEVEL			0xFF000000  /* R/W */
+#define	FIFO_INT_TX_STS_LEVEL			0x00FF0000  /* R/W */
+#define	FIFO_INT_RX_AVAIL_LEVEL			0x0000FF00  /* R/W */
+#define	FIFO_INT_RX_STS_LEVEL			0x000000FF  /* R/W */
+
+#define RX_CFG					0x6C
+#define	RX_CFG_RX_END_ALGN			0xC0000000  /* R/W */
+#define		RX_CFG_RX_END_ALGN4		0x00000000  /* R/W */
+#define		RX_CFG_RX_END_ALGN16		0x40000000  /* R/W */
+#define		RX_CFG_RX_END_ALGN32		0x80000000  /* R/W */
+#define	RX_CFG_RX_DMA_CNT			0x0FFF0000  /* R/W */
+#define	RX_CFG_RX_DUMP				0x00008000  /* R/W */
+#define	RX_CFG_RXDOFF				0x00001F00  /* R/W */
+/*#define	RX_CFG_RXBAD			0x00000001*/  /* R/W */
+
+#define TX_CFG					0x70
+/*#define	TX_CFG_TX_DMA_LVL		0xE0000000*/	 /* R/W */
+						 /* R/W Self Clearing */
+/*#define	TX_CFG_TX_DMA_CNT		0x0FFF0000*/
+#define	TX_CFG_TXS_DUMP				0x00008000  /* Self Clearing */
+#define	TX_CFG_TXD_DUMP				0x00004000  /* Self Clearing */
+#define	TX_CFG_TXSAO				0x00000004  /* R/W */
+#define	TX_CFG_TX_ON				0x00000002  /* R/W */
+#define	TX_CFG_STOP_TX				0x00000001  /* Self Clearing */
+
+#define HW_CFG					0x74
+#define	HW_CFG_TTM				0x00200000  /* R/W */
+#define	HW_CFG_SF				0x00100000  /* R/W */
+#define	HW_CFG_TX_FIF_SZ			0x000F0000  /* R/W */
+#define	HW_CFG_TR				0x00003000  /* R/W */
+#define	HW_CFG_PHY_CLK_SEL			0x00000060  /* R/W */
+#define	HW_CFG_PHY_CLK_SEL_INT_PHY		0x00000000 /* R/W */
+#define	HW_CFG_PHY_CLK_SEL_EXT_PHY		0x00000020 /* R/W */
+#define	HW_CFG_PHY_CLK_SEL_CLK_DIS		0x00000040 /* R/W */
+#define	HW_CFG_SMI_SEL				0x00000010  /* R/W */
+#define	HW_CFG_EXT_PHY_DET			0x00000008  /* RO */
+#define	HW_CFG_EXT_PHY_EN			0x00000004  /* R/W */
+#define	HW_CFG_32_16_BIT_MODE			0x00000004  /* RO */
+#define	HW_CFG_SRST_TO				0x00000002  /* RO */
+#define	HW_CFG_SRST				0x00000001  /* Self Clearing */
+
+#define RX_DP_CTRL				0x78
+#define	RX_DP_CTRL_RX_FFWD			0x80000000  /* R/W */
+#define	RX_DP_CTRL_FFWD_BUSY			0x80000000  /* RO */
+
+#define RX_FIFO_INF				0x7C
+#define	 RX_FIFO_INF_RXSUSED			0x00FF0000  /* RO */
+#define	 RX_FIFO_INF_RXDUSED			0x0000FFFF  /* RO */
+
+#define TX_FIFO_INF				0x80
+#define	TX_FIFO_INF_TSUSED			0x00FF0000  /* RO */
+#define	TX_FIFO_INF_TDFREE			0x0000FFFF  /* RO */
+
+#define PMT_CTRL				0x84
+#define	PMT_CTRL_PM_MODE			0x00003000  /* Self Clearing */
+#define	PMT_CTRL_PHY_RST			0x00000400  /* Self Clearing */
+#define	PMT_CTRL_WOL_EN				0x00000200  /* R/W */
+#define	PMT_CTRL_ED_EN				0x00000100  /* R/W */
+					/* R/W Not Affected by SW Reset */
+#define	PMT_CTRL_PME_TYPE			0x00000040
+#define	PMT_CTRL_WUPS				0x00000030  /* R/WC */
+#define	PMT_CTRL_WUPS_NOWAKE			0x00000000  /* R/WC */
+#define	PMT_CTRL_WUPS_ED			0x00000010  /* R/WC */
+#define	PMT_CTRL_WUPS_WOL			0x00000020  /* R/WC */
+#define	PMT_CTRL_WUPS_MULTI			0x00000030  /* R/WC */
+#define	PMT_CTRL_PME_IND			0x00000008  /* R/W */
+#define	PMT_CTRL_PME_POL			0x00000004  /* R/W */
+					/* R/W Not Affected by SW Reset */
+#define	PMT_CTRL_PME_EN				0x00000002
+#define	PMT_CTRL_READY				0x00000001  /* RO */
+
+#define GPIO_CFG				0x88
+#define	GPIO_CFG_LED3_EN			0x40000000  /* R/W */
+#define	GPIO_CFG_LED2_EN			0x20000000  /* R/W */
+#define	GPIO_CFG_LED1_EN			0x10000000  /* R/W */
+#define	GPIO_CFG_GPIO2_INT_POL			0x04000000  /* R/W */
+#define	GPIO_CFG_GPIO1_INT_POL			0x02000000  /* R/W */
+#define	GPIO_CFG_GPIO0_INT_POL			0x01000000  /* R/W */
+#define	GPIO_CFG_EEPR_EN			0x00700000  /* R/W */
+#define	GPIO_CFG_GPIOBUF2			0x00040000  /* R/W */
+#define	GPIO_CFG_GPIOBUF1			0x00020000  /* R/W */
+#define	GPIO_CFG_GPIOBUF0			0x00010000  /* R/W */
+#define	GPIO_CFG_GPIODIR2			0x00000400  /* R/W */
+#define	GPIO_CFG_GPIODIR1			0x00000200  /* R/W */
+#define	GPIO_CFG_GPIODIR0			0x00000100  /* R/W */
+#define	GPIO_CFG_GPIOD4				0x00000010  /* R/W */
+#define	GPIO_CFG_GPIOD3				0x00000008  /* R/W */
+#define	GPIO_CFG_GPIOD2				0x00000004  /* R/W */
+#define	GPIO_CFG_GPIOD1				0x00000002  /* R/W */
+#define	GPIO_CFG_GPIOD0				0x00000001  /* R/W */
+
+#define GPT_CFG					0x8C
+#define	GPT_CFG_TIMER_EN			0x20000000  /* R/W */
+#define	GPT_CFG_GPT_LOAD			0x0000FFFF  /* R/W */
+
+#define GPT_CNT					0x90
+#define	GPT_CNT_GPT_CNT				0x0000FFFF  /* RO */
+
+#define ENDIAN					0x98
+#define FREE_RUN				0x9C
+#define RX_DROP					0xA0
+#define MAC_CSR_CMD				0xA4
+#define	 MAC_CSR_CMD_CSR_BUSY			0x80000000  /* Self Clearing */
+#define	 MAC_CSR_CMD_R_NOT_W			0x40000000  /* R/W */
+#define	 MAC_CSR_CMD_CSR_ADDR			0x000000FF  /* R/W */
+
+#define MAC_CSR_DATA				0xA8
+#define AFC_CFG					0xAC
+#define		AFC_CFG_AFC_HI			0x00FF0000  /* R/W */
+#define		AFC_CFG_AFC_LO			0x0000FF00  /* R/W */
+#define		AFC_CFG_BACK_DUR		0x000000F0  /* R/W */
+#define		AFC_CFG_FCMULT			0x00000008  /* R/W */
+#define		AFC_CFG_FCBRD			0x00000004  /* R/W */
+#define		AFC_CFG_FCADD			0x00000002  /* R/W */
+#define		AFC_CFG_FCANY			0x00000001  /* R/W */
+
+#define E2P_CMD					0xB0
+#define		E2P_CMD_EPC_BUSY		0x80000000  /* Self Clearing */
+#define		E2P_CMD_EPC_CMD			0x70000000  /* R/W */
+#define		E2P_CMD_EPC_CMD_READ		0x00000000  /* R/W */
+#define		E2P_CMD_EPC_CMD_EWDS		0x10000000  /* R/W */
+#define		E2P_CMD_EPC_CMD_EWEN		0x20000000  /* R/W */
+#define		E2P_CMD_EPC_CMD_WRITE		0x30000000  /* R/W */
+#define		E2P_CMD_EPC_CMD_WRAL		0x40000000  /* R/W */
+#define		E2P_CMD_EPC_CMD_ERASE		0x50000000  /* R/W */
+#define		E2P_CMD_EPC_CMD_ERAL		0x60000000  /* R/W */
+#define		E2P_CMD_EPC_CMD_RELOAD		0x70000000  /* R/W */
+#define		E2P_CMD_EPC_TIMEOUT		0x00000200  /* RO */
+#define		E2P_CMD_MAC_ADDR_LOADED		0x00000100  /* RO */
+#define		E2P_CMD_EPC_ADDR		0x000000FF  /* R/W */
+
+#define E2P_DATA				0xB4
+#define	E2P_DATA_EEPROM_DATA			0x000000FF  /* R/W */
+/* end of LAN register offsets and bit definitions */
+
+/* MAC Control and Status registers */
+#define MAC_CR			0x01  /* R/W */
+
+/* MAC_CR - MAC Control Register */
+#define MAC_CR_RXALL			0x80000000
+/* TODO: delete this bit? It is not described in the data sheet. */
+#define MAC_CR_HBDIS			0x10000000
+#define MAC_CR_RCVOWN			0x00800000
+#define MAC_CR_LOOPBK			0x00200000
+#define MAC_CR_FDPX			0x00100000
+#define MAC_CR_MCPAS			0x00080000
+#define MAC_CR_PRMS			0x00040000
+#define MAC_CR_INVFILT			0x00020000
+#define MAC_CR_PASSBAD			0x00010000
+#define MAC_CR_HFILT			0x00008000
+#define MAC_CR_HPFILT			0x00002000
+#define MAC_CR_LCOLL			0x00001000
+#define MAC_CR_BCAST			0x00000800
+#define MAC_CR_DISRTY			0x00000400
+#define MAC_CR_PADSTR			0x00000100
+#define MAC_CR_BOLMT_MASK		0x000000C0
+#define MAC_CR_DFCHK			0x00000020
+#define MAC_CR_TXEN			0x00000008
+#define MAC_CR_RXEN			0x00000004
+
+#define ADDRH			0x02	  /* R/W mask 0x0000FFFFUL */
+#define ADDRL			0x03	  /* R/W mask 0xFFFFFFFFUL */
+#define HASHH			0x04	  /* R/W */
+#define HASHL			0x05	  /* R/W */
+
+#define MII_ACC			0x06	  /* R/W */
+#define MII_ACC_PHY_ADDR		0x0000F800
+#define MII_ACC_MIIRINDA		0x000007C0
+#define MII_ACC_MII_WRITE		0x00000002
+#define MII_ACC_MII_BUSY		0x00000001
+
+#define MII_DATA		0x07	  /* R/W mask 0x0000FFFFUL */
+
+#define FLOW			0x08	  /* R/W */
+#define FLOW_FCPT			0xFFFF0000
+#define FLOW_FCPASS			0x00000004
+#define FLOW_FCEN			0x00000002
+#define FLOW_FCBSY			0x00000001
+
+#define VLAN1			0x09	  /* R/W mask 0x0000FFFFUL */
+#define VLAN1_VTI1			0x0000ffff
+
+#define VLAN2			0x0A	  /* R/W mask 0x0000FFFFUL */
+#define VLAN2_VTI2			0x0000ffff
+
+#define WUFF			0x0B	  /* WO */
+
+#define WUCSR			0x0C	  /* R/W */
+#define WUCSR_GUE			0x00000200
+#define WUCSR_WUFR			0x00000040
+#define WUCSR_MPR			0x00000020
+#define WUCSR_WAKE_EN			0x00000004
+#define WUCSR_MPEN			0x00000002
+
+/* Chip ID values */
+#define CHIP_89218	0x218a
+#define CHIP_9115	0x115
+#define CHIP_9116	0x116
+#define CHIP_9117	0x117
+#define CHIP_9118	0x118
+#define CHIP_9211	0x9211
+#define CHIP_9215	0x115a
+#define CHIP_9216	0x116a
+#define CHIP_9217	0x117a
+#define CHIP_9218	0x118a
+#define CHIP_9220	0x9220
+#define CHIP_9221	0x9221
+
+struct chip_id {
+	u16 id;
+	char *name;
+};
+
+static const struct chip_id chip_ids[] =  {
+	{ CHIP_89218, "LAN89218" },
+	{ CHIP_9115, "LAN9115" },
+	{ CHIP_9116, "LAN9116" },
+	{ CHIP_9117, "LAN9117" },
+	{ CHIP_9118, "LAN9118" },
+	{ CHIP_9211, "LAN9211" },
+	{ CHIP_9215, "LAN9215" },
+	{ CHIP_9216, "LAN9216" },
+	{ CHIP_9217, "LAN9217" },
+	{ CHIP_9218, "LAN9218" },
+	{ CHIP_9220, "LAN9220" },
+	{ CHIP_9221, "LAN9221" },
+	{ 0, NULL },
+};
+
+static u32 smc911x_get_mac_csr(struct eth_device *dev, u8 reg)
+{
+	while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
+		;
+	smc911x_reg_write(dev, MAC_CSR_CMD,
+			MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg);
+	while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
+		;
+
+	return smc911x_reg_read(dev, MAC_CSR_DATA);
+}
+
+static void smc911x_set_mac_csr(struct eth_device *dev, u8 reg, u32 data)
+{
+	while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
+		;
+	smc911x_reg_write(dev, MAC_CSR_DATA, data);
+	smc911x_reg_write(dev, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg);
+	while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
+		;
+}
+
+static int smc911x_detect_chip(struct eth_device *dev)
+{
+	unsigned long val, i;
+
+	val = smc911x_reg_read(dev, BYTE_TEST);
+	if (val == 0xffffffff) {
+		/* Special case -- no chip present */
+		return -1;
+	} else if (val != 0x87654321) {
+		printf(DRIVERNAME ": Invalid chip endian 0x%08lx\n", val);
+		return -1;
+	}
+
+	val = smc911x_reg_read(dev, ID_REV) >> 16;
+	for (i = 0; chip_ids[i].id != 0; i++) {
+		if (chip_ids[i].id == val) break;
+	}
+	if (!chip_ids[i].id) {
+		printf(DRIVERNAME ": Unknown chip ID %04lx\n", val);
+		return -1;
+	}
+
+	dev->priv = (void *)&chip_ids[i];
+
+	return 0;
+}
+
+static void smc911x_reset(struct eth_device *dev)
+{
+	int timeout;
+
+	/*
+	 *  Take out of PM setting first
+	 *  Device is already wake up if PMT_CTRL_READY bit is set
+	 */
+	if ((smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY) == 0) {
+		/* Write to the bytetest will take out of powerdown */
+		smc911x_reg_write(dev, BYTE_TEST, 0x0);
+
+		timeout = 10;
+
+		while (timeout-- &&
+			!(smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY))
+			udelay(10);
+		if (timeout < 0) {
+			printf(DRIVERNAME
+				": timeout waiting for PM restore\n");
+			return;
+		}
+	}
+
+	/* Disable interrupts */
+	smc911x_reg_write(dev, INT_EN, 0);
+
+	smc911x_reg_write(dev, HW_CFG, HW_CFG_SRST);
+
+	timeout = 1000;
+	while (timeout-- && smc911x_reg_read(dev, E2P_CMD) & E2P_CMD_EPC_BUSY)
+		udelay(10);
+
+	if (timeout < 0) {
+		printf(DRIVERNAME ": reset timeout\n");
+		return;
+	}
+
+	/* Reset the FIFO level and flow control settings */
+	smc911x_set_mac_csr(dev, FLOW, FLOW_FCPT | FLOW_FCEN);
+	smc911x_reg_write(dev, AFC_CFG, 0x0050287F);
+
+	/* Set to LED outputs */
+	smc911x_reg_write(dev, GPIO_CFG, 0x70070000);
+}
+
+#endif
diff --git a/marvell/uboot/drivers/net/sunxi_wemac.c b/marvell/uboot/drivers/net/sunxi_wemac.c
new file mode 100644
index 0000000..699a381
--- /dev/null
+++ b/marvell/uboot/drivers/net/sunxi_wemac.c
@@ -0,0 +1,525 @@
+/*
+ * sunxi_wemac.c -- Allwinner A10 ethernet driver
+ *
+ * (C) Copyright 2012, Stefan Roese <sr@denx.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <miiphy.h>
+#include <linux/err.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+
+/* EMAC register  */
+struct wemac_regs {
+	u32 ctl;	/* 0x00 */
+	u32 tx_mode;	/* 0x04 */
+	u32 tx_flow;	/* 0x08 */
+	u32 tx_ctl0;	/* 0x0c */
+	u32 tx_ctl1;	/* 0x10 */
+	u32 tx_ins;	/* 0x14 */
+	u32 tx_pl0;	/* 0x18 */
+	u32 tx_pl1;	/* 0x1c */
+	u32 tx_sta;	/* 0x20 */
+	u32 tx_io_data;	/* 0x24 */
+	u32 tx_io_data1; /* 0x28 */
+	u32 tx_tsvl0;	/* 0x2c */
+	u32 tx_tsvh0;	/* 0x30 */
+	u32 tx_tsvl1;	/* 0x34 */
+	u32 tx_tsvh1;	/* 0x38 */
+	u32 rx_ctl;	/* 0x3c */
+	u32 rx_hash0;	/* 0x40 */
+	u32 rx_hash1;	/* 0x44 */
+	u32 rx_sta;	/* 0x48 */
+	u32 rx_io_data;	/* 0x4c */
+	u32 rx_fbc;	/* 0x50 */
+	u32 int_ctl;	/* 0x54 */
+	u32 int_sta;	/* 0x58 */
+	u32 mac_ctl0;	/* 0x5c */
+	u32 mac_ctl1;	/* 0x60 */
+	u32 mac_ipgt;	/* 0x64 */
+	u32 mac_ipgr;	/* 0x68 */
+	u32 mac_clrt;	/* 0x6c */
+	u32 mac_maxf;	/* 0x70 */
+	u32 mac_supp;	/* 0x74 */
+	u32 mac_test;	/* 0x78 */
+	u32 mac_mcfg;	/* 0x7c */
+	u32 mac_mcmd;	/* 0x80 */
+	u32 mac_madr;	/* 0x84 */
+	u32 mac_mwtd;	/* 0x88 */
+	u32 mac_mrdd;	/* 0x8c */
+	u32 mac_mind;	/* 0x90 */
+	u32 mac_ssrr;	/* 0x94 */
+	u32 mac_a0;	/* 0x98 */
+	u32 mac_a1;	/* 0x9c */
+};
+
+/* SRAMC register  */
+struct sunxi_sramc_regs {
+	u32 ctrl0;
+	u32 ctrl1;
+};
+
+/* 0: Disable       1: Aborted frame enable(default) */
+#define EMAC_TX_AB_M		(0x1 << 0)
+/* 0: CPU           1: DMA(default) */
+#define EMAC_TX_TM		(0x1 << 1)
+
+#define EMAC_TX_SETUP		(0)
+
+/* 0: DRQ asserted  1: DRQ automatically(default) */
+#define EMAC_RX_DRQ_MODE	(0x1 << 1)
+/* 0: CPU           1: DMA(default) */
+#define EMAC_RX_TM		(0x1 << 2)
+/* 0: Normal(default)        1: Pass all Frames */
+#define EMAC_RX_PA		(0x1 << 4)
+/* 0: Normal(default)        1: Pass Control Frames */
+#define EMAC_RX_PCF		(0x1 << 5)
+/* 0: Normal(default)        1: Pass Frames with CRC Error */
+#define EMAC_RX_PCRCE		(0x1 << 6)
+/* 0: Normal(default)        1: Pass Frames with Length Error */
+#define EMAC_RX_PLE		(0x1 << 7)
+/* 0: Normal                 1: Pass Frames length out of range(default) */
+#define EMAC_RX_POR		(0x1 << 8)
+/* 0: Not accept             1: Accept unicast Packets(default) */
+#define EMAC_RX_UCAD		(0x1 << 16)
+/* 0: Normal(default)        1: DA Filtering */
+#define EMAC_RX_DAF		(0x1 << 17)
+/* 0: Not accept             1: Accept multicast Packets(default) */
+#define EMAC_RX_MCO		(0x1 << 20)
+/* 0: Disable(default)       1: Enable Hash filter */
+#define EMAC_RX_MHF		(0x1 << 21)
+/* 0: Not accept             1: Accept Broadcast Packets(default) */
+#define EMAC_RX_BCO		(0x1 << 22)
+/* 0: Disable(default)       1: Enable SA Filtering */
+#define EMAC_RX_SAF		(0x1 << 24)
+/* 0: Normal(default)        1: Inverse Filtering */
+#define EMAC_RX_SAIF		(0x1 << 25)
+
+#define EMAC_RX_SETUP		(EMAC_RX_POR | EMAC_RX_UCAD | EMAC_RX_DAF | \
+				 EMAC_RX_MCO | EMAC_RX_BCO)
+
+/* 0: Disable                1: Enable Receive Flow Control(default) */
+#define EMAC_MAC_CTL0_RFC	(0x1 << 2)
+/* 0: Disable                1: Enable Transmit Flow Control(default) */
+#define EMAC_MAC_CTL0_TFC	(0x1 << 3)
+
+#define EMAC_MAC_CTL0_SETUP	(EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC)
+
+/* 0: Disable                1: Enable MAC Frame Length Checking(default) */
+#define EMAC_MAC_CTL1_FLC	(0x1 << 1)
+/* 0: Disable(default)       1: Enable Huge Frame */
+#define EMAC_MAC_CTL1_HF	(0x1 << 2)
+/* 0: Disable(default)       1: Enable MAC Delayed CRC */
+#define EMAC_MAC_CTL1_DCRC	(0x1 << 3)
+/* 0: Disable                1: Enable MAC CRC(default) */
+#define EMAC_MAC_CTL1_CRC	(0x1 << 4)
+/* 0: Disable                1: Enable MAC PAD Short frames(default) */
+#define EMAC_MAC_CTL1_PC	(0x1 << 5)
+/* 0: Disable(default)       1: Enable MAC PAD Short frames and append CRC */
+#define EMAC_MAC_CTL1_VC	(0x1 << 6)
+/* 0: Disable(default)       1: Enable MAC auto detect Short frames */
+#define EMAC_MAC_CTL1_ADP	(0x1 << 7)
+/* 0: Disable(default)       1: Enable */
+#define EMAC_MAC_CTL1_PRE	(0x1 << 8)
+/* 0: Disable(default)       1: Enable */
+#define EMAC_MAC_CTL1_LPE	(0x1 << 9)
+/* 0: Disable(default)       1: Enable no back off */
+#define EMAC_MAC_CTL1_NB	(0x1 << 12)
+/* 0: Disable(default)       1: Enable */
+#define EMAC_MAC_CTL1_BNB	(0x1 << 13)
+/* 0: Disable(default)       1: Enable */
+#define EMAC_MAC_CTL1_ED	(0x1 << 14)
+
+#define EMAC_MAC_CTL1_SETUP	(EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \
+				 EMAC_MAC_CTL1_PC)
+
+#define EMAC_MAC_IPGT		0x15
+
+#define EMAC_MAC_NBTB_IPG1	0xC
+#define EMAC_MAC_NBTB_IPG2	0x12
+
+#define EMAC_MAC_CW		0x37
+#define EMAC_MAC_RM		0xF
+
+#define EMAC_MAC_MFL		0x0600
+
+/* Receive status */
+#define EMAC_CRCERR		(1 << 4)
+#define EMAC_LENERR		(3 << 5)
+
+#define DMA_CPU_TRRESHOLD	2000
+
+struct wemac_eth_dev {
+	u32 speed;
+	u32 duplex;
+	u32 phy_configured;
+	int link_printed;
+};
+
+struct wemac_rxhdr {
+	s16 rx_len;
+	u16 rx_status;
+};
+
+static void wemac_inblk_32bit(void *reg, void *data, int count)
+{
+	int cnt = (count + 3) >> 2;
+
+	if (cnt) {
+		u32 *buf = data;
+
+		do {
+			u32 x = readl(reg);
+			*buf++ = x;
+		} while (--cnt);
+	}
+}
+
+static void wemac_outblk_32bit(void *reg, void *data, int count)
+{
+	int cnt = (count + 3) >> 2;
+
+	if (cnt) {
+		const u32 *buf = data;
+
+		do {
+			writel(*buf++, reg);
+		} while (--cnt);
+	}
+}
+
+/*
+ * Read a word from phyxcer
+ */
+static int wemac_phy_read(const char *devname, unsigned char addr,
+			  unsigned char reg, unsigned short *value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
+
+	/* issue the phy address and reg */
+	writel(addr << 8 | reg, &regs->mac_madr);
+
+	/* pull up the phy io line */
+	writel(0x1, &regs->mac_mcmd);
+
+	/* Wait read complete */
+	mdelay(1);
+
+	/* push down the phy io line */
+	writel(0x0, &regs->mac_mcmd);
+
+	/* and write data */
+	*value = readl(&regs->mac_mrdd);
+
+	return 0;
+}
+
+/*
+ * Write a word to phyxcer
+ */
+static int wemac_phy_write(const char *devname, unsigned char addr,
+			   unsigned char reg, unsigned short value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
+
+	/* issue the phy address and reg */
+	writel(addr << 8 | reg, &regs->mac_madr);
+
+	/* pull up the phy io line */
+	writel(0x1, &regs->mac_mcmd);
+
+	/* Wait write complete */
+	mdelay(1);
+
+	/* push down the phy io line */
+	writel(0x0, &regs->mac_mcmd);
+
+	/* and write data */
+	writel(value, &regs->mac_mwtd);
+
+	return 0;
+}
+
+static void emac_setup(struct eth_device *dev)
+{
+	struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
+	u32 reg_val;
+	u16 phy_val;
+	u32 duplex_flag;
+
+	/* Set up TX */
+	writel(EMAC_TX_SETUP, &regs->tx_mode);
+
+	/* Set up RX */
+	writel(EMAC_RX_SETUP, &regs->rx_ctl);
+
+	/* Set MAC */
+	/* Set MAC CTL0 */
+	writel(EMAC_MAC_CTL0_SETUP, &regs->mac_ctl0);
+
+	/* Set MAC CTL1 */
+	wemac_phy_read(dev->name, 1, 0, &phy_val);
+	debug("PHY SETUP, reg 0 value: %x\n", phy_val);
+	duplex_flag = !!(phy_val & (1 << 8));
+
+	reg_val = 0;
+	if (duplex_flag)
+		reg_val = (0x1 << 0);
+	writel(EMAC_MAC_CTL1_SETUP | reg_val, &regs->mac_ctl1);
+
+	/* Set up IPGT */
+	writel(EMAC_MAC_IPGT, &regs->mac_ipgt);
+
+	/* Set up IPGR */
+	writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), &regs->mac_ipgr);
+
+	/* Set up Collison window */
+	writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), &regs->mac_clrt);
+
+	/* Set up Max Frame Length */
+	writel(EMAC_MAC_MFL, &regs->mac_maxf);
+}
+
+static void wemac_reset(struct eth_device *dev)
+{
+	struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
+
+	debug("resetting device\n");
+
+	/* RESET device */
+	writel(0, &regs->ctl);
+	udelay(200);
+
+	writel(1, &regs->ctl);
+	udelay(200);
+}
+
+static int sunxi_wemac_eth_init(struct eth_device *dev, bd_t *bd)
+{
+	struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
+	struct wemac_eth_dev *priv = dev->priv;
+	u16 phy_reg;
+
+	/* Init EMAC */
+
+	/* Flush RX FIFO */
+	setbits_le32(&regs->rx_ctl, 0x8);
+	udelay(1);
+
+	/* Init MAC */
+
+	/* Soft reset MAC */
+	clrbits_le32(&regs->mac_ctl0, 1 << 15);
+
+	/* Set MII clock */
+	clrsetbits_le32(&regs->mac_mcfg, 0xf << 2, 0xd << 2);
+
+	/* Clear RX counter */
+	writel(0x0, &regs->rx_fbc);
+	udelay(1);
+
+	/* Set up EMAC */
+	emac_setup(dev);
+
+	writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 |
+	       dev->enetaddr[2], &regs->mac_a1);
+	writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 |
+	       dev->enetaddr[5], &regs->mac_a0);
+
+	mdelay(1);
+
+	wemac_reset(dev);
+
+	/* PHY POWER UP */
+	wemac_phy_read(dev->name, 1, 0, &phy_reg);
+	wemac_phy_write(dev->name, 1, 0, phy_reg & (~(1 << 11)));
+	mdelay(1);
+
+	wemac_phy_read(dev->name, 1, 0, &phy_reg);
+
+	priv->speed = miiphy_speed(dev->name, 0);
+	priv->duplex = miiphy_duplex(dev->name, 0);
+
+	/* Print link status only once */
+	if (!priv->link_printed) {
+		printf("ENET Speed is %d Mbps - %s duplex connection\n",
+		       priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL");
+		priv->link_printed = 1;
+	}
+
+	/* Set EMAC SPEED depend on PHY */
+	clrsetbits_le32(&regs->mac_supp, 1 << 8,
+			((phy_reg & (1 << 13)) >> 13) << 8);
+
+	/* Set duplex depend on phy */
+	clrsetbits_le32(&regs->mac_ctl1, 1 << 0,
+			((phy_reg & (1 << 8)) >> 8) << 0);
+
+	/* Enable RX/TX */
+	setbits_le32(&regs->ctl, 0x7);
+
+	return 0;
+}
+
+static void sunxi_wemac_eth_halt(struct eth_device *dev)
+{
+	/* Nothing to do here */
+}
+
+static int sunxi_wemac_eth_recv(struct eth_device *dev)
+{
+	struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
+	struct wemac_rxhdr rxhdr;
+	u32 rxcount;
+	u32 reg_val;
+	int rx_len;
+	int rx_status;
+	int good_packet;
+
+	/* Check packet ready or not */
+
+	/*
+	 * Race warning: The first packet might arrive with
+	 * the interrupts disabled, but the second will fix
+	 */
+	rxcount = readl(&regs->rx_fbc);
+	if (!rxcount) {
+		/* Had one stuck? */
+		rxcount = readl(&regs->rx_fbc);
+		if (!rxcount)
+			return 0;
+	}
+
+	reg_val = readl(&regs->rx_io_data);
+	if (reg_val != 0x0143414d) {
+		/* Disable RX */
+		clrbits_le32(&regs->ctl, 1 << 2);
+
+		/* Flush RX FIFO */
+		setbits_le32(&regs->rx_ctl, 1 << 3);
+		while (readl(&regs->rx_ctl) & (1 << 3))
+			;
+
+		/* Enable RX */
+		setbits_le32(&regs->ctl, 1 << 2);
+
+		return 0;
+	}
+
+	/*
+	 * A packet ready now
+	 * Get status/length
+	 */
+	good_packet = 1;
+
+	wemac_inblk_32bit(&regs->rx_io_data, &rxhdr, sizeof(rxhdr));
+
+	rx_len = rxhdr.rx_len;
+	rx_status = rxhdr.rx_status;
+
+	/* Packet Status check */
+	if (rx_len < 0x40) {
+		good_packet = 0;
+		debug("RX: Bad Packet (runt)\n");
+	}
+
+	/* rx_status is identical to RSR register. */
+	if (0 & rx_status & (EMAC_CRCERR | EMAC_LENERR)) {
+		good_packet = 0;
+		if (rx_status & EMAC_CRCERR)
+			printf("crc error\n");
+		if (rx_status & EMAC_LENERR)
+			printf("length error\n");
+	}
+
+	/* Move data from WEMAC */
+	if (good_packet) {
+		if (rx_len > DMA_CPU_TRRESHOLD) {
+			printf("Received packet is too big (len=%d)\n", rx_len);
+		} else {
+			wemac_inblk_32bit((void *)&regs->rx_io_data,
+					  NetRxPackets[0], rx_len);
+
+			/* Pass to upper layer */
+			NetReceive(NetRxPackets[0], rx_len);
+			return rx_len;
+		}
+	}
+
+	return 0;
+}
+
+static int sunxi_wemac_eth_send(struct eth_device *dev, void *packet, int len)
+{
+	struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
+
+	/* Select channel 0 */
+	writel(0, &regs->tx_ins);
+
+	/* Write packet */
+	wemac_outblk_32bit((void *)&regs->tx_io_data, packet, len);
+
+	/* Set TX len */
+	writel(len, &regs->tx_pl0);
+
+	/* Start translate from fifo to phy */
+	setbits_le32(&regs->tx_ctl0, 1);
+
+	return 0;
+}
+
+int sunxi_wemac_initialize(void)
+{
+	struct sunxi_ccm_reg *const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	struct sunxi_sramc_regs *sram =
+		(struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE;
+	struct eth_device *dev;
+	struct wemac_eth_dev *priv;
+	int pin;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL)
+		return -ENOMEM;
+
+	priv = (struct wemac_eth_dev *)malloc(sizeof(struct wemac_eth_dev));
+	if (!priv) {
+		free(dev);
+		return -ENOMEM;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	memset(priv, 0, sizeof(struct wemac_eth_dev));
+
+	/* Map SRAM to EMAC */
+	setbits_le32(&sram->ctrl1, 0x5 << 2);
+
+	/* Configure pin mux settings for MII Ethernet */
+	for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++)
+		sunxi_gpio_set_cfgpin(pin, 2);
+
+	/* Set up clock gating */
+	setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_EMAC);
+
+	dev->iobase = SUNXI_EMAC_BASE;
+	dev->priv = priv;
+	dev->init = sunxi_wemac_eth_init;
+	dev->halt = sunxi_wemac_eth_halt;
+	dev->send = sunxi_wemac_eth_send;
+	dev->recv = sunxi_wemac_eth_recv;
+	strcpy(dev->name, "wemac");
+
+	eth_register(dev);
+
+	miiphy_register(dev->name, wemac_phy_read, wemac_phy_write);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/tsec.c b/marvell/uboot/drivers/net/tsec.c
new file mode 100644
index 0000000..e9138f0
--- /dev/null
+++ b/marvell/uboot/drivers/net/tsec.c
@@ -0,0 +1,688 @@
+/*
+ * Freescale Three Speed Ethernet Controller driver
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ * Copyright 2004-2011, 2013 Freescale Semiconductor, Inc.
+ * (C) Copyright 2003, Motorola, Inc.
+ * author Andy Fleming
+ *
+ */
+
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <command.h>
+#include <tsec.h>
+#include <fsl_mdio.h>
+#include <asm/errno.h>
+#include <asm/processor.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TX_BUF_CNT		2
+
+static uint rx_idx;		/* index of the current RX buffer */
+static uint tx_idx;		/* index of the current TX buffer */
+
+#ifdef __GNUC__
+static struct txbd8 __iomem txbd[TX_BUF_CNT] __aligned(8);
+static struct rxbd8 __iomem rxbd[PKTBUFSRX] __aligned(8);
+
+#else
+#error "rtx must be 64-bit aligned"
+#endif
+
+static int tsec_send(struct eth_device *dev, void *packet, int length);
+
+/* Default initializations for TSEC controllers. */
+
+static struct tsec_info_struct tsec_info[] = {
+#ifdef CONFIG_TSEC1
+	STD_TSEC_INFO(1),	/* TSEC1 */
+#endif
+#ifdef CONFIG_TSEC2
+	STD_TSEC_INFO(2),	/* TSEC2 */
+#endif
+#ifdef CONFIG_MPC85XX_FEC
+	{
+		.regs = TSEC_GET_REGS(2, 0x2000),
+		.devname = CONFIG_MPC85XX_FEC_NAME,
+		.phyaddr = FEC_PHY_ADDR,
+		.flags = FEC_FLAGS,
+		.mii_devname = DEFAULT_MII_NAME
+	},			/* FEC */
+#endif
+#ifdef CONFIG_TSEC3
+	STD_TSEC_INFO(3),	/* TSEC3 */
+#endif
+#ifdef CONFIG_TSEC4
+	STD_TSEC_INFO(4),	/* TSEC4 */
+#endif
+};
+
+#define TBIANA_SETTINGS ( \
+		TBIANA_ASYMMETRIC_PAUSE \
+		| TBIANA_SYMMETRIC_PAUSE \
+		| TBIANA_FULL_DUPLEX \
+		)
+
+/* By default force the TBI PHY into 1000Mbps full duplex when in SGMII mode */
+#ifndef CONFIG_TSEC_TBICR_SETTINGS
+#define CONFIG_TSEC_TBICR_SETTINGS ( \
+		TBICR_PHY_RESET \
+		| TBICR_ANEG_ENABLE \
+		| TBICR_FULL_DUPLEX \
+		| TBICR_SPEED1_SET \
+		)
+#endif /* CONFIG_TSEC_TBICR_SETTINGS */
+
+/* Configure the TBI for SGMII operation */
+static void tsec_configure_serdes(struct tsec_private *priv)
+{
+	/* Access TBI PHY registers at given TSEC register offset as opposed
+	 * to the register offset used for external PHY accesses */
+	tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa),
+			0, TBI_ANA, TBIANA_SETTINGS);
+	tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa),
+			0, TBI_TBICON, TBICON_CLK_SELECT);
+	tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa),
+			0, TBI_CR, CONFIG_TSEC_TBICR_SETTINGS);
+}
+
+#ifdef CONFIG_MCAST_TFTP
+
+/* CREDITS: linux gianfar driver, slightly adjusted... thanx. */
+
+/* Set the appropriate hash bit for the given addr */
+
+/* The algorithm works like so:
+ * 1) Take the Destination Address (ie the multicast address), and
+ * do a CRC on it (little endian), and reverse the bits of the
+ * result.
+ * 2) Use the 8 most significant bits as a hash into a 256-entry
+ * table.  The table is controlled through 8 32-bit registers:
+ * gaddr0-7.  gaddr0's MSB is entry 0, and gaddr7's LSB is entry
+ * 255.  This means that the 3 most significant bits in the
+ * hash index which gaddr register to use, and the 5 other bits
+ * indicate which bit (assuming an IBM numbering scheme, which
+ * for PowerPC (tm) is usually the case) in the register holds
+ * the entry. */
+static int
+tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set)
+{
+	struct tsec_private *priv = (struct tsec_private *)dev->priv;
+	struct tsec __iomem *regs = priv->regs;
+	u32 result, value;
+	u8 whichbit, whichreg;
+
+	result = ether_crc(MAC_ADDR_LEN, mcast_mac);
+	whichbit = (result >> 24) & 0x1f; /* the 5 LSB = which bit to set */
+	whichreg = result >> 29; /* the 3 MSB = which reg to set it in */
+
+	value = 1 << (31-whichbit);
+
+	if (set)
+		setbits_be32(&regs->hash.gaddr0 + whichreg, value);
+	else
+		clrbits_be32(&regs->hash.gaddr0 + whichreg, value);
+
+	return 0;
+}
+#endif /* Multicast TFTP ? */
+
+/* Initialized required registers to appropriate values, zeroing
+ * those we don't care about (unless zero is bad, in which case,
+ * choose a more appropriate value)
+ */
+static void init_registers(struct tsec __iomem *regs)
+{
+	/* Clear IEVENT */
+	out_be32(&regs->ievent, IEVENT_INIT_CLEAR);
+
+	out_be32(&regs->imask, IMASK_INIT_CLEAR);
+
+	out_be32(&regs->hash.iaddr0, 0);
+	out_be32(&regs->hash.iaddr1, 0);
+	out_be32(&regs->hash.iaddr2, 0);
+	out_be32(&regs->hash.iaddr3, 0);
+	out_be32(&regs->hash.iaddr4, 0);
+	out_be32(&regs->hash.iaddr5, 0);
+	out_be32(&regs->hash.iaddr6, 0);
+	out_be32(&regs->hash.iaddr7, 0);
+
+	out_be32(&regs->hash.gaddr0, 0);
+	out_be32(&regs->hash.gaddr1, 0);
+	out_be32(&regs->hash.gaddr2, 0);
+	out_be32(&regs->hash.gaddr3, 0);
+	out_be32(&regs->hash.gaddr4, 0);
+	out_be32(&regs->hash.gaddr5, 0);
+	out_be32(&regs->hash.gaddr6, 0);
+	out_be32(&regs->hash.gaddr7, 0);
+
+	out_be32(&regs->rctrl, 0x00000000);
+
+	/* Init RMON mib registers */
+	memset((void *)&regs->rmon, 0, sizeof(regs->rmon));
+
+	out_be32(&regs->rmon.cam1, 0xffffffff);
+	out_be32(&regs->rmon.cam2, 0xffffffff);
+
+	out_be32(&regs->mrblr, MRBLR_INIT_SETTINGS);
+
+	out_be32(&regs->minflr, MINFLR_INIT_SETTINGS);
+
+	out_be32(&regs->attr, ATTR_INIT_SETTINGS);
+	out_be32(&regs->attreli, ATTRELI_INIT_SETTINGS);
+
+}
+
+/* Configure maccfg2 based on negotiated speed and duplex
+ * reported by PHY handling code
+ */
+static void adjust_link(struct tsec_private *priv, struct phy_device *phydev)
+{
+	struct tsec __iomem *regs = priv->regs;
+	u32 ecntrl, maccfg2;
+
+	if (!phydev->link) {
+		printf("%s: No link.\n", phydev->dev->name);
+		return;
+	}
+
+	/* clear all bits relative with interface mode */
+	ecntrl = in_be32(&regs->ecntrl);
+	ecntrl &= ~ECNTRL_R100;
+
+	maccfg2 = in_be32(&regs->maccfg2);
+	maccfg2 &= ~(MACCFG2_IF | MACCFG2_FULL_DUPLEX);
+
+	if (phydev->duplex)
+		maccfg2 |= MACCFG2_FULL_DUPLEX;
+
+	switch (phydev->speed) {
+	case 1000:
+		maccfg2 |= MACCFG2_GMII;
+		break;
+	case 100:
+	case 10:
+		maccfg2 |= MACCFG2_MII;
+
+		/* Set R100 bit in all modes although
+		 * it is only used in RGMII mode
+		 */
+		if (phydev->speed == 100)
+			ecntrl |= ECNTRL_R100;
+		break;
+	default:
+		printf("%s: Speed was bad\n", phydev->dev->name);
+		break;
+	}
+
+	out_be32(&regs->ecntrl, ecntrl);
+	out_be32(&regs->maccfg2, maccfg2);
+
+	printf("Speed: %d, %s duplex%s\n", phydev->speed,
+			(phydev->duplex) ? "full" : "half",
+			(phydev->port == PORT_FIBRE) ? ", fiber mode" : "");
+}
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129
+/*
+ * When MACCFG1[Rx_EN] is enabled during system boot as part
+ * of the eTSEC port initialization sequence,
+ * the eTSEC Rx logic may not be properly initialized.
+ */
+void redundant_init(struct eth_device *dev)
+{
+	struct tsec_private *priv = dev->priv;
+	struct tsec __iomem *regs = priv->regs;
+	uint t, count = 0;
+	int fail = 1;
+	static const u8 pkt[] = {
+		0x00, 0x1e, 0x4f, 0x12, 0xcb, 0x2c, 0x00, 0x25,
+		0x64, 0xbb, 0xd1, 0xab, 0x08, 0x00, 0x45, 0x00,
+		0x00, 0x5c, 0xdd, 0x22, 0x00, 0x00, 0x80, 0x01,
+		0x1f, 0x71, 0x0a, 0xc1, 0x14, 0x22, 0x0a, 0xc1,
+		0x14, 0x6a, 0x08, 0x00, 0xef, 0x7e, 0x02, 0x00,
+		0x94, 0x05, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+		0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
+		0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
+		0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+		0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+		0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+		0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+		0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+		0x71, 0x72};
+
+	/* Enable promiscuous mode */
+	setbits_be32(&regs->rctrl, 0x8);
+	/* Enable loopback mode */
+	setbits_be32(&regs->maccfg1, MACCFG1_LOOPBACK);
+	/* Enable transmit and receive */
+	setbits_be32(&regs->maccfg1, MACCFG1_RX_EN | MACCFG1_TX_EN);
+
+	/* Tell the DMA it is clear to go */
+	setbits_be32(&regs->dmactrl, DMACTRL_INIT_SETTINGS);
+	out_be32(&regs->tstat, TSTAT_CLEAR_THALT);
+	out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
+	clrbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
+
+	do {
+		uint16_t status;
+		tsec_send(dev, (void *)pkt, sizeof(pkt));
+
+		/* Wait for buffer to be received */
+		for (t = 0; in_be16(&rxbd[rx_idx].status) & RXBD_EMPTY; t++) {
+			if (t >= 10 * TOUT_LOOP) {
+				printf("%s: tsec: rx error\n", dev->name);
+				break;
+			}
+		}
+
+		if (!memcmp(pkt, (void *)NetRxPackets[rx_idx], sizeof(pkt)))
+			fail = 0;
+
+		out_be16(&rxbd[rx_idx].length, 0);
+		status = RXBD_EMPTY;
+		if ((rx_idx + 1) == PKTBUFSRX)
+			status |= RXBD_WRAP;
+		out_be16(&rxbd[rx_idx].status, status);
+		rx_idx = (rx_idx + 1) % PKTBUFSRX;
+
+		if (in_be32(&regs->ievent) & IEVENT_BSY) {
+			out_be32(&regs->ievent, IEVENT_BSY);
+			out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
+		}
+		if (fail) {
+			printf("loopback recv packet error!\n");
+			clrbits_be32(&regs->maccfg1, MACCFG1_RX_EN);
+			udelay(1000);
+			setbits_be32(&regs->maccfg1, MACCFG1_RX_EN);
+		}
+	} while ((count++ < 4) && (fail == 1));
+
+	if (fail)
+		panic("eTSEC init fail!\n");
+	/* Disable promiscuous mode */
+	clrbits_be32(&regs->rctrl, 0x8);
+	/* Disable loopback mode */
+	clrbits_be32(&regs->maccfg1, MACCFG1_LOOPBACK);
+}
+#endif
+
+/* Set up the buffers and their descriptors, and bring up the
+ * interface
+ */
+static void startup_tsec(struct eth_device *dev)
+{
+	struct tsec_private *priv = (struct tsec_private *)dev->priv;
+	struct tsec __iomem *regs = priv->regs;
+	uint16_t status;
+	int i;
+
+	/* reset the indices to zero */
+	rx_idx = 0;
+	tx_idx = 0;
+#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129
+	uint svr;
+#endif
+
+	/* Point to the buffer descriptors */
+	out_be32(&regs->tbase, (u32)&txbd[0]);
+	out_be32(&regs->rbase, (u32)&rxbd[0]);
+
+	/* Initialize the Rx Buffer descriptors */
+	for (i = 0; i < PKTBUFSRX; i++) {
+		out_be16(&rxbd[i].status, RXBD_EMPTY);
+		out_be16(&rxbd[i].length, 0);
+		out_be32(&rxbd[i].bufptr, (u32)NetRxPackets[i]);
+	}
+	status = in_be16(&rxbd[PKTBUFSRX - 1].status);
+	out_be16(&rxbd[PKTBUFSRX - 1].status, status | RXBD_WRAP);
+
+	/* Initialize the TX Buffer Descriptors */
+	for (i = 0; i < TX_BUF_CNT; i++) {
+		out_be16(&txbd[i].status, 0);
+		out_be16(&txbd[i].length, 0);
+		out_be32(&txbd[i].bufptr, 0);
+	}
+	status = in_be16(&txbd[TX_BUF_CNT - 1].status);
+	out_be16(&txbd[TX_BUF_CNT - 1].status, status | TXBD_WRAP);
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129
+	svr = get_svr();
+	if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0))
+		redundant_init(dev);
+#endif
+	/* Enable Transmit and Receive */
+	setbits_be32(&regs->maccfg1, MACCFG1_RX_EN | MACCFG1_TX_EN);
+
+	/* Tell the DMA it is clear to go */
+	setbits_be32(&regs->dmactrl, DMACTRL_INIT_SETTINGS);
+	out_be32(&regs->tstat, TSTAT_CLEAR_THALT);
+	out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
+	clrbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
+}
+
+/* This returns the status bits of the device.	The return value
+ * is never checked, and this is what the 8260 driver did, so we
+ * do the same.	 Presumably, this would be zero if there were no
+ * errors
+ */
+static int tsec_send(struct eth_device *dev, void *packet, int length)
+{
+	struct tsec_private *priv = (struct tsec_private *)dev->priv;
+	struct tsec __iomem *regs = priv->regs;
+	uint16_t status;
+	int result = 0;
+	int i;
+
+	/* Find an empty buffer descriptor */
+	for (i = 0; in_be16(&txbd[tx_idx].status) & TXBD_READY; i++) {
+		if (i >= TOUT_LOOP) {
+			debug("%s: tsec: tx buffers full\n", dev->name);
+			return result;
+		}
+	}
+
+	out_be32(&txbd[tx_idx].bufptr, (u32)packet);
+	out_be16(&txbd[tx_idx].length, length);
+	status = in_be16(&txbd[tx_idx].status);
+	out_be16(&txbd[tx_idx].status, status |
+		(TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT));
+
+	/* Tell the DMA to go */
+	out_be32(&regs->tstat, TSTAT_CLEAR_THALT);
+
+	/* Wait for buffer to be transmitted */
+	for (i = 0; in_be16(&txbd[tx_idx].status) & TXBD_READY; i++) {
+		if (i >= TOUT_LOOP) {
+			debug("%s: tsec: tx error\n", dev->name);
+			return result;
+		}
+	}
+
+	tx_idx = (tx_idx + 1) % TX_BUF_CNT;
+	result = in_be16(&txbd[tx_idx].status) & TXBD_STATS;
+
+	return result;
+}
+
+static int tsec_recv(struct eth_device *dev)
+{
+	struct tsec_private *priv = (struct tsec_private *)dev->priv;
+	struct tsec __iomem *regs = priv->regs;
+
+	while (!(in_be16(&rxbd[rx_idx].status) & RXBD_EMPTY)) {
+		int length = in_be16(&rxbd[rx_idx].length);
+		uint16_t status = in_be16(&rxbd[rx_idx].status);
+
+		/* Send the packet up if there were no errors */
+		if (!(status & RXBD_STATS))
+			NetReceive(NetRxPackets[rx_idx], length - 4);
+		else
+			printf("Got error %x\n", (status & RXBD_STATS));
+
+		out_be16(&rxbd[rx_idx].length, 0);
+
+		status = RXBD_EMPTY;
+		/* Set the wrap bit if this is the last element in the list */
+		if ((rx_idx + 1) == PKTBUFSRX)
+			status |= RXBD_WRAP;
+		out_be16(&rxbd[rx_idx].status, status);
+
+		rx_idx = (rx_idx + 1) % PKTBUFSRX;
+	}
+
+	if (in_be32(&regs->ievent) & IEVENT_BSY) {
+		out_be32(&regs->ievent, IEVENT_BSY);
+		out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
+	}
+
+	return -1;
+
+}
+
+/* Stop the interface */
+static void tsec_halt(struct eth_device *dev)
+{
+	struct tsec_private *priv = (struct tsec_private *)dev->priv;
+	struct tsec __iomem *regs = priv->regs;
+
+	clrbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
+	setbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
+
+	while ((in_be32(&regs->ievent) & (IEVENT_GRSC | IEVENT_GTSC))
+			!= (IEVENT_GRSC | IEVENT_GTSC))
+		;
+
+	clrbits_be32(&regs->maccfg1, MACCFG1_TX_EN | MACCFG1_RX_EN);
+
+	/* Shut down the PHY, as needed */
+	phy_shutdown(priv->phydev);
+}
+
+/* Initializes data structures and registers for the controller,
+ * and brings the interface up.	 Returns the link status, meaning
+ * that it returns success if the link is up, failure otherwise.
+ * This allows u-boot to find the first active controller.
+ */
+static int tsec_init(struct eth_device *dev, bd_t * bd)
+{
+	struct tsec_private *priv = (struct tsec_private *)dev->priv;
+	struct tsec __iomem *regs = priv->regs;
+	u32 tempval;
+	int ret;
+
+	/* Make sure the controller is stopped */
+	tsec_halt(dev);
+
+	/* Init MACCFG2.  Defaults to GMII */
+	out_be32(&regs->maccfg2, MACCFG2_INIT_SETTINGS);
+
+	/* Init ECNTRL */
+	out_be32(&regs->ecntrl, ECNTRL_INIT_SETTINGS);
+
+	/* Copy the station address into the address registers.
+	 * For a station address of 0x12345678ABCD in transmission
+	 * order (BE), MACnADDR1 is set to 0xCDAB7856 and
+	 * MACnADDR2 is set to 0x34120000.
+	 */
+	tempval = (dev->enetaddr[5] << 24) | (dev->enetaddr[4] << 16) |
+		  (dev->enetaddr[3] << 8)  |  dev->enetaddr[2];
+
+	out_be32(&regs->macstnaddr1, tempval);
+
+	tempval = (dev->enetaddr[1] << 24) | (dev->enetaddr[0] << 16);
+
+	out_be32(&regs->macstnaddr2, tempval);
+
+	/* Clear out (for the most part) the other registers */
+	init_registers(regs);
+
+	/* Ready the device for tx/rx */
+	startup_tsec(dev);
+
+	/* Start up the PHY */
+	ret = phy_startup(priv->phydev);
+	if (ret) {
+		printf("Could not initialize PHY %s\n",
+		       priv->phydev->dev->name);
+		return ret;
+	}
+
+	adjust_link(priv, priv->phydev);
+
+	/* If there's no link, fail */
+	return priv->phydev->link ? 0 : -1;
+}
+
+static phy_interface_t tsec_get_interface(struct tsec_private *priv)
+{
+	struct tsec __iomem *regs = priv->regs;
+	u32 ecntrl;
+
+	ecntrl = in_be32(&regs->ecntrl);
+
+	if (ecntrl & ECNTRL_SGMII_MODE)
+		return PHY_INTERFACE_MODE_SGMII;
+
+	if (ecntrl & ECNTRL_TBI_MODE) {
+		if (ecntrl & ECNTRL_REDUCED_MODE)
+			return PHY_INTERFACE_MODE_RTBI;
+		else
+			return PHY_INTERFACE_MODE_TBI;
+	}
+
+	if (ecntrl & ECNTRL_REDUCED_MODE) {
+		if (ecntrl & ECNTRL_REDUCED_MII_MODE)
+			return PHY_INTERFACE_MODE_RMII;
+		else {
+			phy_interface_t interface = priv->interface;
+
+			/*
+			 * This isn't autodetected, so it must
+			 * be set by the platform code.
+			 */
+			if ((interface == PHY_INTERFACE_MODE_RGMII_ID) ||
+				 (interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
+				 (interface == PHY_INTERFACE_MODE_RGMII_RXID))
+				return interface;
+
+			return PHY_INTERFACE_MODE_RGMII;
+		}
+	}
+
+	if (priv->flags & TSEC_GIGABIT)
+		return PHY_INTERFACE_MODE_GMII;
+
+	return PHY_INTERFACE_MODE_MII;
+}
+
+
+/* Discover which PHY is attached to the device, and configure it
+ * properly.  If the PHY is not recognized, then return 0
+ * (failure).  Otherwise, return 1
+ */
+static int init_phy(struct eth_device *dev)
+{
+	struct tsec_private *priv = (struct tsec_private *)dev->priv;
+	struct phy_device *phydev;
+	struct tsec __iomem *regs = priv->regs;
+	u32 supported = (SUPPORTED_10baseT_Half |
+			SUPPORTED_10baseT_Full |
+			SUPPORTED_100baseT_Half |
+			SUPPORTED_100baseT_Full);
+
+	if (priv->flags & TSEC_GIGABIT)
+		supported |= SUPPORTED_1000baseT_Full;
+
+	/* Assign a Physical address to the TBI */
+	out_be32(&regs->tbipa, CONFIG_SYS_TBIPA_VALUE);
+
+	priv->interface = tsec_get_interface(priv);
+
+	if (priv->interface == PHY_INTERFACE_MODE_SGMII)
+		tsec_configure_serdes(priv);
+
+	phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface);
+
+	phydev->supported &= supported;
+	phydev->advertising = phydev->supported;
+
+	priv->phydev = phydev;
+
+	phy_config(phydev);
+
+	return 1;
+}
+
+/* Initialize device structure. Returns success if PHY
+ * initialization succeeded (i.e. if it recognizes the PHY)
+ */
+static int tsec_initialize(bd_t *bis, struct tsec_info_struct *tsec_info)
+{
+	struct eth_device *dev;
+	int i;
+	struct tsec_private *priv;
+
+	dev = (struct eth_device *)malloc(sizeof *dev);
+
+	if (NULL == dev)
+		return 0;
+
+	memset(dev, 0, sizeof *dev);
+
+	priv = (struct tsec_private *)malloc(sizeof(*priv));
+
+	if (NULL == priv)
+		return 0;
+
+	priv->regs = tsec_info->regs;
+	priv->phyregs_sgmii = tsec_info->miiregs_sgmii;
+
+	priv->phyaddr = tsec_info->phyaddr;
+	priv->flags = tsec_info->flags;
+
+	sprintf(dev->name, tsec_info->devname);
+	priv->interface = tsec_info->interface;
+	priv->bus = miiphy_get_dev_by_name(tsec_info->mii_devname);
+	dev->iobase = 0;
+	dev->priv = priv;
+	dev->init = tsec_init;
+	dev->halt = tsec_halt;
+	dev->send = tsec_send;
+	dev->recv = tsec_recv;
+#ifdef CONFIG_MCAST_TFTP
+	dev->mcast = tsec_mcast_addr;
+#endif
+
+	/* Tell u-boot to get the addr from the env */
+	for (i = 0; i < 6; i++)
+		dev->enetaddr[i] = 0;
+
+	eth_register(dev);
+
+	/* Reset the MAC */
+	setbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
+	udelay(2);  /* Soft Reset must be asserted for 3 TX clocks */
+	clrbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
+
+	/* Try to initialize PHY here, and return */
+	return init_phy(dev);
+}
+
+/*
+ * Initialize all the TSEC devices
+ *
+ * Returns the number of TSEC devices that were initialized
+ */
+int tsec_eth_init(bd_t *bis, struct tsec_info_struct *tsecs, int num)
+{
+	int i;
+	int ret, count = 0;
+
+	for (i = 0; i < num; i++) {
+		ret = tsec_initialize(bis, &tsecs[i]);
+		if (ret > 0)
+			count += ret;
+	}
+
+	return count;
+}
+
+int tsec_standard_init(bd_t *bis)
+{
+	struct fsl_pq_mdio_info info;
+
+	info.regs = TSEC_GET_MDIO_REGS_BASE(1);
+	info.name = DEFAULT_MII_NAME;
+
+	fsl_pq_mdio_init(bis, &info);
+
+	return tsec_eth_init(bis, tsec_info, ARRAY_SIZE(tsec_info));
+}
diff --git a/marvell/uboot/drivers/net/tsi108_eth.c b/marvell/uboot/drivers/net/tsi108_eth.c
new file mode 100644
index 0000000..72b8159
--- /dev/null
+++ b/marvell/uboot/drivers/net/tsi108_eth.c
@@ -0,0 +1,1016 @@
+/***********************************************************************
+ *
+ * Copyright (c) 2005 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Description:
+ *   Ethernet interface for Tundra TSI108 bridge chip
+ *
+ ***********************************************************************/
+
+#include <config.h>
+
+#if !defined(CONFIG_TSI108_ETH_NUM_PORTS) || (CONFIG_TSI108_ETH_NUM_PORTS > 2)
+#error "CONFIG_TSI108_ETH_NUM_PORTS must be defined as 1 or 2"
+#endif
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/cache.h>
+
+#ifdef DEBUG
+#define TSI108_ETH_DEBUG 7
+#else
+#define TSI108_ETH_DEBUG 0
+#endif
+
+#if TSI108_ETH_DEBUG > 0
+#define debug_lev(lev, fmt, args...) \
+if (lev <= TSI108_ETH_DEBUG) \
+printf ("%s %d: " fmt, __FUNCTION__, __LINE__, ##args)
+#else
+#define debug_lev(lev, fmt, args...) do{}while(0)
+#endif
+
+#define RX_PRINT_ERRORS
+#define TX_PRINT_ERRORS
+
+#define ETH_BASE	(CONFIG_SYS_TSI108_CSR_BASE + 0x6000)
+
+#define ETH_PORT_OFFSET	0x400
+
+#define __REG32(base, offset) (*((volatile u32 *)((char *)(base) + (offset))))
+
+#define reg_MAC_CONFIG_1(base)		__REG32(base, 0x00000000)
+#define MAC_CONFIG_1_TX_ENABLE		(0x00000001)
+#define MAC_CONFIG_1_SYNC_TX_ENABLE	(0x00000002)
+#define MAC_CONFIG_1_RX_ENABLE		(0x00000004)
+#define MAC_CONFIG_1_SYNC_RX_ENABLE	(0x00000008)
+#define MAC_CONFIG_1_TX_FLOW_CONTROL	(0x00000010)
+#define MAC_CONFIG_1_RX_FLOW_CONTROL	(0x00000020)
+#define MAC_CONFIG_1_LOOP_BACK		(0x00000100)
+#define MAC_CONFIG_1_RESET_TX_FUNCTION	(0x00010000)
+#define MAC_CONFIG_1_RESET_RX_FUNCTION	(0x00020000)
+#define MAC_CONFIG_1_RESET_TX_MAC	(0x00040000)
+#define MAC_CONFIG_1_RESET_RX_MAC	(0x00080000)
+#define MAC_CONFIG_1_SIM_RESET		(0x40000000)
+#define MAC_CONFIG_1_SOFT_RESET		(0x80000000)
+
+#define reg_MAC_CONFIG_2(base)		__REG32(base, 0x00000004)
+#define MAC_CONFIG_2_FULL_DUPLEX	(0x00000001)
+#define MAC_CONFIG_2_CRC_ENABLE		(0x00000002)
+#define MAC_CONFIG_2_PAD_CRC		(0x00000004)
+#define MAC_CONFIG_2_LENGTH_CHECK	(0x00000010)
+#define MAC_CONFIG_2_HUGE_FRAME		(0x00000020)
+#define MAC_CONFIG_2_INTERFACE_MODE(val)	(((val) & 0x3) << 8)
+#define MAC_CONFIG_2_PREAMBLE_LENGTH(val)	(((val) & 0xf) << 12)
+#define INTERFACE_MODE_NIBBLE		1	/* 10/100 Mb/s MII) */
+#define INTERFACE_MODE_BYTE		2	/* 1000 Mb/s GMII/TBI */
+
+#define reg_MAXIMUM_FRAME_LENGTH(base)		__REG32(base, 0x00000010)
+
+#define reg_MII_MGMT_CONFIG(base)		__REG32(base, 0x00000020)
+#define MII_MGMT_CONFIG_MGMT_CLOCK_SELECT(val)	((val) & 0x7)
+#define MII_MGMT_CONFIG_NO_PREAMBLE		(0x00000010)
+#define MII_MGMT_CONFIG_SCAN_INCREMENT		(0x00000020)
+#define MII_MGMT_CONFIG_RESET_MGMT		(0x80000000)
+
+#define reg_MII_MGMT_COMMAND(base)		__REG32(base, 0x00000024)
+#define MII_MGMT_COMMAND_READ_CYCLE		(0x00000001)
+#define MII_MGMT_COMMAND_SCAN_CYCLE		(0x00000002)
+
+#define reg_MII_MGMT_ADDRESS(base)		__REG32(base, 0x00000028)
+#define reg_MII_MGMT_CONTROL(base)		__REG32(base, 0x0000002c)
+#define reg_MII_MGMT_STATUS(base)		__REG32(base, 0x00000030)
+
+#define reg_MII_MGMT_INDICATORS(base)		__REG32(base, 0x00000034)
+#define MII_MGMT_INDICATORS_BUSY		(0x00000001)
+#define MII_MGMT_INDICATORS_SCAN		(0x00000002)
+#define MII_MGMT_INDICATORS_NOT_VALID		(0x00000004)
+
+#define reg_INTERFACE_STATUS(base)		__REG32(base, 0x0000003c)
+#define INTERFACE_STATUS_LINK_FAIL		(0x00000008)
+#define INTERFACE_STATUS_EXCESS_DEFER		(0x00000200)
+
+#define reg_STATION_ADDRESS_1(base)		__REG32(base, 0x00000040)
+#define reg_STATION_ADDRESS_2(base)		__REG32(base, 0x00000044)
+
+#define reg_PORT_CONTROL(base)			__REG32(base, 0x00000200)
+#define PORT_CONTROL_PRI		(0x00000001)
+#define PORT_CONTROL_BPT		(0x00010000)
+#define PORT_CONTROL_SPD		(0x00040000)
+#define PORT_CONTROL_RBC		(0x00080000)
+#define PORT_CONTROL_PRB		(0x00200000)
+#define PORT_CONTROL_DIS		(0x00400000)
+#define PORT_CONTROL_TBI		(0x00800000)
+#define PORT_CONTROL_STE		(0x10000000)
+#define PORT_CONTROL_ZOR		(0x20000000)
+#define PORT_CONTROL_CLR		(0x40000000)
+#define PORT_CONTROL_SRT		(0x80000000)
+
+#define reg_TX_CONFIG(base)		__REG32(base, 0x00000220)
+#define TX_CONFIG_START_Q		(0x00000003)
+#define TX_CONFIG_EHP			(0x00400000)
+#define TX_CONFIG_CHP			(0x00800000)
+#define TX_CONFIG_RST			(0x80000000)
+
+#define reg_TX_CONTROL(base)		__REG32(base, 0x00000224)
+#define TX_CONTROL_GO			(0x00008000)
+#define TX_CONTROL_MP			(0x01000000)
+#define TX_CONTROL_EAI			(0x20000000)
+#define TX_CONTROL_ABT			(0x40000000)
+#define TX_CONTROL_EII			(0x80000000)
+
+#define reg_TX_STATUS(base)		__REG32(base, 0x00000228)
+#define TX_STATUS_QUEUE_USABLE		(0x0000000f)
+#define TX_STATUS_CURR_Q		(0x00000300)
+#define TX_STATUS_ACT			(0x00008000)
+#define TX_STATUS_QUEUE_IDLE		(0x000f0000)
+#define TX_STATUS_EOQ_PENDING		(0x0f000000)
+
+#define reg_TX_EXTENDED_STATUS(base)		__REG32(base, 0x0000022c)
+#define TX_EXTENDED_STATUS_END_OF_QUEUE_CONDITION		(0x0000000f)
+#define TX_EXTENDED_STATUS_END_OF_FRAME_CONDITION		(0x00000f00)
+#define TX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION	(0x000f0000)
+#define TX_EXTENDED_STATUS_ERROR_FLAG				(0x0f000000)
+
+#define reg_TX_THRESHOLDS(base)			__REG32(base, 0x00000230)
+
+#define reg_TX_DIAGNOSTIC_ADDR(base)           __REG32(base, 0x00000270)
+#define TX_DIAGNOSTIC_ADDR_INDEX		(0x0000007f)
+#define TX_DIAGNOSTIC_ADDR_DFR			(0x40000000)
+#define TX_DIAGNOSTIC_ADDR_AI			(0x80000000)
+
+#define reg_TX_DIAGNOSTIC_DATA(base)		__REG32(base, 0x00000274)
+
+#define reg_TX_ERROR_STATUS(base)		__REG32(base, 0x00000278)
+#define TX_ERROR_STATUS				(0x00000278)
+#define TX_ERROR_STATUS_QUEUE_0_ERROR_RESPONSE	(0x0000000f)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_0		(0x00000010)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_0		(0x00000020)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_0		(0x00000040)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_0		(0x00000080)
+#define TX_ERROR_STATUS_QUEUE_1_ERROR_RESPONSE	(0x00000f00)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_1		(0x00001000)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_1		(0x00002000)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_1		(0x00004000)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_1		(0x00008000)
+#define TX_ERROR_STATUS_QUEUE_2_ERROR_RESPONSE	(0x000f0000)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_2		(0x00100000)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_2		(0x00200000)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_2		(0x00400000)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_2		(0x00800000)
+#define TX_ERROR_STATUS_QUEUE_3_ERROR_RESPONSE	(0x0f000000)
+#define TX_ERROR_STATUS_TEA_ON_QUEUE_3		(0x10000000)
+#define TX_ERROR_STATUS_RER_ON_QUEUE_3		(0x20000000)
+#define TX_ERROR_STATUS_TER_ON_QUEUE_3		(0x40000000)
+#define TX_ERROR_STATUS_DER_ON_QUEUE_3		(0x80000000)
+
+#define reg_TX_QUEUE_0_CONFIG(base)		__REG32(base, 0x00000280)
+#define TX_QUEUE_0_CONFIG_OCN_PORT		(0x0000003f)
+#define TX_QUEUE_0_CONFIG_BSWP			(0x00000400)
+#define TX_QUEUE_0_CONFIG_WSWP			(0x00000800)
+#define TX_QUEUE_0_CONFIG_AM			(0x00004000)
+#define TX_QUEUE_0_CONFIG_GVI			(0x00008000)
+#define TX_QUEUE_0_CONFIG_EEI			(0x00010000)
+#define TX_QUEUE_0_CONFIG_ELI			(0x00020000)
+#define TX_QUEUE_0_CONFIG_ENI			(0x00040000)
+#define TX_QUEUE_0_CONFIG_ESI			(0x00080000)
+#define TX_QUEUE_0_CONFIG_EDI			(0x00100000)
+
+#define reg_TX_QUEUE_0_BUF_CONFIG(base)		__REG32(base, 0x00000284)
+#define TX_QUEUE_0_BUF_CONFIG_OCN_PORT		(0x0000003f)
+#define TX_QUEUE_0_BUF_CONFIG_BURST		(0x00000300)
+#define TX_QUEUE_0_BUF_CONFIG_BSWP		(0x00000400)
+#define TX_QUEUE_0_BUF_CONFIG_WSWP		(0x00000800)
+
+#define OCN_PORT_HLP			0	/* HLP Interface */
+#define OCN_PORT_PCI_X			1	/* PCI-X Interface */
+#define OCN_PORT_PROCESSOR_MASTER	2	/* Processor Interface (master) */
+#define OCN_PORT_PROCESSOR_SLAVE	3	/* Processor Interface (slave) */
+#define OCN_PORT_MEMORY			4	/* Memory Controller */
+#define OCN_PORT_DMA			5	/* DMA Controller */
+#define OCN_PORT_ETHERNET		6	/* Ethernet Controller */
+#define OCN_PORT_PRINT			7	/* Print Engine Interface */
+
+#define reg_TX_QUEUE_0_PTR_LOW(base)		__REG32(base, 0x00000288)
+
+#define reg_TX_QUEUE_0_PTR_HIGH(base)		__REG32(base, 0x0000028c)
+#define TX_QUEUE_0_PTR_HIGH_VALID		(0x80000000)
+
+#define reg_RX_CONFIG(base)			__REG32(base, 0x00000320)
+#define RX_CONFIG_DEF_Q				(0x00000003)
+#define RX_CONFIG_EMF				(0x00000100)
+#define RX_CONFIG_EUF				(0x00000200)
+#define RX_CONFIG_BFE				(0x00000400)
+#define RX_CONFIG_MFE				(0x00000800)
+#define RX_CONFIG_UFE				(0x00001000)
+#define RX_CONFIG_SE				(0x00002000)
+#define RX_CONFIG_ABF				(0x00200000)
+#define RX_CONFIG_APE				(0x00400000)
+#define RX_CONFIG_CHP				(0x00800000)
+#define RX_CONFIG_RST				(0x80000000)
+
+#define reg_RX_CONTROL(base)			__REG32(base, 0x00000324)
+#define GE_E0_RX_CONTROL_QUEUE_ENABLES		(0x0000000f)
+#define GE_E0_RX_CONTROL_GO			(0x00008000)
+#define GE_E0_RX_CONTROL_EAI			(0x20000000)
+#define GE_E0_RX_CONTROL_ABT			(0x40000000)
+#define GE_E0_RX_CONTROL_EII			(0x80000000)
+
+#define reg_RX_EXTENDED_STATUS(base)		__REG32(base, 0x0000032c)
+#define RX_EXTENDED_STATUS			(0x0000032c)
+#define RX_EXTENDED_STATUS_EOQ			(0x0000000f)
+#define RX_EXTENDED_STATUS_EOQ_0		(0x00000001)
+#define RX_EXTENDED_STATUS_EOF			(0x00000f00)
+#define RX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION	(0x000f0000)
+#define RX_EXTENDED_STATUS_ERROR_FLAG				(0x0f000000)
+
+#define reg_RX_THRESHOLDS(base)			__REG32(base, 0x00000330)
+
+#define reg_RX_DIAGNOSTIC_ADDR(base)		__REG32(base, 0x00000370)
+#define RX_DIAGNOSTIC_ADDR_INDEX		(0x0000007f)
+#define RX_DIAGNOSTIC_ADDR_DFR			(0x40000000)
+#define RX_DIAGNOSTIC_ADDR_AI			(0x80000000)
+
+#define reg_RX_DIAGNOSTIC_DATA(base)		__REG32(base, 0x00000374)
+
+#define reg_RX_QUEUE_0_CONFIG(base)		__REG32(base, 0x00000380)
+#define RX_QUEUE_0_CONFIG_OCN_PORT		(0x0000003f)
+#define RX_QUEUE_0_CONFIG_BSWP			(0x00000400)
+#define RX_QUEUE_0_CONFIG_WSWP			(0x00000800)
+#define RX_QUEUE_0_CONFIG_AM			(0x00004000)
+#define RX_QUEUE_0_CONFIG_EEI			(0x00010000)
+#define RX_QUEUE_0_CONFIG_ELI			(0x00020000)
+#define RX_QUEUE_0_CONFIG_ENI			(0x00040000)
+#define RX_QUEUE_0_CONFIG_ESI			(0x00080000)
+#define RX_QUEUE_0_CONFIG_EDI			(0x00100000)
+
+#define reg_RX_QUEUE_0_BUF_CONFIG(base)		__REG32(base, 0x00000384)
+#define RX_QUEUE_0_BUF_CONFIG_OCN_PORT		(0x0000003f)
+#define RX_QUEUE_0_BUF_CONFIG_BURST		(0x00000300)
+#define RX_QUEUE_0_BUF_CONFIG_BSWP		(0x00000400)
+#define RX_QUEUE_0_BUF_CONFIG_WSWP		(0x00000800)
+
+#define reg_RX_QUEUE_0_PTR_LOW(base)		__REG32(base, 0x00000388)
+
+#define reg_RX_QUEUE_0_PTR_HIGH(base)		__REG32(base, 0x0000038c)
+#define RX_QUEUE_0_PTR_HIGH_VALID		(0x80000000)
+
+/*
+ *  PHY register definitions
+ */
+/* the first 15 PHY registers are standard. */
+#define PHY_CTRL_REG		0	/* Control Register */
+#define PHY_STATUS_REG		1	/* Status Regiser */
+#define PHY_ID1_REG		2	/* Phy Id Reg (word 1) */
+#define PHY_ID2_REG		3	/* Phy Id Reg (word 2) */
+#define PHY_AN_ADV_REG		4	/* Autoneg Advertisement */
+#define PHY_LP_ABILITY_REG	5	/* Link Partner Ability (Base Page) */
+#define PHY_AUTONEG_EXP_REG	6	/* Autoneg Expansion Reg */
+#define PHY_NEXT_PAGE_TX_REG	7	/* Next Page TX */
+#define PHY_LP_NEXT_PAGE_REG	8	/* Link Partner Next Page */
+#define PHY_1000T_CTRL_REG	9	/* 1000Base-T Control Reg */
+#define PHY_1000T_STATUS_REG	10	/* 1000Base-T Status Reg */
+#define PHY_EXT_STATUS_REG	11	/* Extended Status Reg */
+
+/*
+ * PHY Register bit masks.
+ */
+#define PHY_CTRL_RESET		(1 << 15)
+#define PHY_CTRL_LOOPBACK	(1 << 14)
+#define PHY_CTRL_SPEED0		(1 << 13)
+#define PHY_CTRL_AN_EN		(1 << 12)
+#define PHY_CTRL_PWR_DN		(1 << 11)
+#define PHY_CTRL_ISOLATE	(1 << 10)
+#define PHY_CTRL_RESTART_AN	(1 << 9)
+#define PHY_CTRL_FULL_DUPLEX	(1 << 8)
+#define PHY_CTRL_CT_EN		(1 << 7)
+#define PHY_CTRL_SPEED1		(1 << 6)
+
+#define PHY_STAT_100BASE_T4	(1 << 15)
+#define PHY_STAT_100BASE_X_FD	(1 << 14)
+#define PHY_STAT_100BASE_X_HD	(1 << 13)
+#define PHY_STAT_10BASE_T_FD	(1 << 12)
+#define PHY_STAT_10BASE_T_HD	(1 << 11)
+#define PHY_STAT_100BASE_T2_FD	(1 << 10)
+#define PHY_STAT_100BASE_T2_HD	(1 << 9)
+#define PHY_STAT_EXT_STAT	(1 << 8)
+#define PHY_STAT_RESERVED	(1 << 7)
+#define PHY_STAT_MFPS		(1 << 6)	/* Management Frames Preamble Suppression */
+#define PHY_STAT_AN_COMPLETE	(1 << 5)
+#define PHY_STAT_REM_FAULT	(1 << 4)
+#define PHY_STAT_AN_CAP		(1 << 3)
+#define PHY_STAT_LINK_UP	(1 << 2)
+#define PHY_STAT_JABBER		(1 << 1)
+#define PHY_STAT_EXT_CAP	(1 << 0)
+
+#define TBI_CONTROL_2					0x11
+#define TBI_CONTROL_2_ENABLE_COMMA_DETECT		0x0001
+#define TBI_CONTROL_2_ENABLE_WRAP			0x0002
+#define TBI_CONTROL_2_G_MII_MODE			0x0010
+#define TBI_CONTROL_2_RECEIVE_CLOCK_SELECT		0x0020
+#define TBI_CONTROL_2_AUTO_NEGOTIATION_SENSE		0x0100
+#define TBI_CONTROL_2_DISABLE_TRANSMIT_RUNNING_DISPARITY	0x1000
+#define TBI_CONTROL_2_DISABLE_RECEIVE_RUNNING_DISPARITY		0x2000
+#define TBI_CONTROL_2_SHORTCUT_LINK_TIMER			0x4000
+#define TBI_CONTROL_2_SOFT_RESET				0x8000
+
+/* marvel specific */
+#define MV1111_EXT_CTRL1_REG	16	/* PHY Specific Control Reg */
+#define MV1111_SPEC_STAT_REG	17	/* PHY Specific Status Reg */
+#define MV1111_EXT_CTRL2_REG	20	/* Extended PHY Specific Control Reg */
+
+/*
+ * MARVELL 88E1111 PHY register bit masks
+ */
+/* PHY Specific Status Register (MV1111_EXT_CTRL1_REG) */
+
+#define SPEC_STAT_SPEED_MASK	(3 << 14)
+#define SPEC_STAT_FULL_DUP	(1 << 13)
+#define SPEC_STAT_PAGE_RCVD	(1 << 12)
+#define SPEC_STAT_RESOLVED	(1 << 11)	/* Speed and Duplex Resolved */
+#define SPEC_STAT_LINK_UP	(1 << 10)
+#define SPEC_STAT_CABLE_LEN_MASK	(7 << 7)/* Cable Length (100/1000 modes only) */
+#define SPEC_STAT_MDIX		(1 << 6)
+#define SPEC_STAT_POLARITY	(1 << 1)
+#define SPEC_STAT_JABBER	(1 << 0)
+
+#define SPEED_1000		(2 << 14)
+#define SPEED_100		(1 << 14)
+#define SPEED_10		(0 << 14)
+
+#define TBI_ADDR	0x1E	/* Ten Bit Interface address */
+
+/* negotiated link parameters */
+#define LINK_SPEED_UNKNOWN	0
+#define LINK_SPEED_10		1
+#define LINK_SPEED_100		2
+#define LINK_SPEED_1000		3
+
+#define LINK_DUPLEX_UNKNOWN	0
+#define LINK_DUPLEX_HALF	1
+#define LINK_DUPLEX_FULL	2
+
+static unsigned int phy_address[] = { 8, 9 };
+
+#define vuint32 volatile u32
+
+/* TX/RX buffer descriptors. MUST be cache line aligned in memory. (32 byte)
+ * This structure is accessed by the ethernet DMA engine which means it
+ * MUST be in LITTLE ENDIAN format */
+struct dma_descriptor {
+	vuint32 start_addr0;	/* buffer address, least significant bytes. */
+	vuint32 start_addr1;	/* buffer address, most significant bytes. */
+	vuint32 next_descr_addr0;/* next descriptor address, least significant bytes.  Must be 64-bit aligned. */
+	vuint32 next_descr_addr1;/* next descriptor address, most significant bytes. */
+	vuint32 vlan_byte_count;/* VLAN tag(top 2 bytes) and byte countt (bottom 2 bytes). */
+	vuint32 config_status;	/* Configuration/Status. */
+	vuint32 reserved1;	/* reserved to make the descriptor cache line aligned. */
+	vuint32 reserved2;	/* reserved to make the descriptor cache line aligned. */
+};
+
+/* last next descriptor address flag */
+#define DMA_DESCR_LAST		(1 << 31)
+
+/* TX DMA descriptor config status bits */
+#define DMA_DESCR_TX_EOF	(1 <<  0)	/* end of frame */
+#define DMA_DESCR_TX_SOF	(1 <<  1)	/* start of frame */
+#define DMA_DESCR_TX_PFVLAN	(1 <<  2)
+#define DMA_DESCR_TX_HUGE	(1 <<  3)
+#define DMA_DESCR_TX_PAD	(1 <<  4)
+#define DMA_DESCR_TX_CRC	(1 <<  5)
+#define DMA_DESCR_TX_DESCR_INT	(1 << 14)
+#define DMA_DESCR_TX_RETRY_COUNT	0x000F0000
+#define DMA_DESCR_TX_ONE_COLLISION	(1 << 20)
+#define DMA_DESCR_TX_LATE_COLLISION	(1 << 24)
+#define DMA_DESCR_TX_UNDERRUN		(1 << 25)
+#define DMA_DESCR_TX_RETRY_LIMIT	(1 << 26)
+#define DMA_DESCR_TX_OK			(1 << 30)
+#define DMA_DESCR_TX_OWNER		(1 << 31)
+
+/* RX DMA descriptor status bits */
+#define DMA_DESCR_RX_EOF		(1 <<  0)
+#define DMA_DESCR_RX_SOF		(1 <<  1)
+#define DMA_DESCR_RX_VTF		(1 <<  2)
+#define DMA_DESCR_RX_FRAME_IS_TYPE	(1 <<  3)
+#define DMA_DESCR_RX_SHORT_FRAME	(1 <<  4)
+#define DMA_DESCR_RX_HASH_MATCH		(1 <<  7)
+#define DMA_DESCR_RX_BAD_FRAME		(1 <<  8)
+#define DMA_DESCR_RX_OVERRUN		(1 <<  9)
+#define DMA_DESCR_RX_MAX_FRAME_LEN	(1 << 11)
+#define DMA_DESCR_RX_CRC_ERROR		(1 << 12)
+#define DMA_DESCR_RX_DESCR_INT		(1 << 13)
+#define DMA_DESCR_RX_OWNER		(1 << 15)
+
+#define RX_BUFFER_SIZE	PKTSIZE
+#define NUM_RX_DESC	PKTBUFSRX
+
+static struct dma_descriptor tx_descriptor __attribute__ ((aligned(32)));
+
+static struct dma_descriptor rx_descr_array[NUM_RX_DESC]
+	__attribute__ ((aligned(32)));
+
+static struct dma_descriptor *rx_descr_current;
+
+static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis);
+static int tsi108_eth_send(struct eth_device *dev, void *packet, int length);
+static int tsi108_eth_recv (struct eth_device *dev);
+static void tsi108_eth_halt (struct eth_device *dev);
+static unsigned int read_phy (unsigned int base,
+			     unsigned int phy_addr, unsigned int phy_reg);
+static void write_phy (unsigned int base,
+		      unsigned int phy_addr,
+		      unsigned int phy_reg, unsigned int phy_data);
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print phy debug infomation
+ */
+static void dump_phy_regs (unsigned int phy_addr)
+{
+	int i;
+
+	printf ("PHY %d registers\n", phy_addr);
+	for (i = 0; i <= 30; i++) {
+		printf ("%2d  0x%04x\n", i, read_phy (ETH_BASE, phy_addr, i));
+	}
+	printf ("\n");
+
+}
+#else
+#define dump_phy_regs(base) do{}while(0)
+#endif
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print debug infomation
+ */
+static void tx_diag_regs (unsigned int base)
+{
+	int i;
+	unsigned long dummy;
+
+	printf ("TX diagnostics registers\n");
+	reg_TX_DIAGNOSTIC_ADDR(base) = 0x00 | TX_DIAGNOSTIC_ADDR_AI;
+	udelay (1000);
+	dummy = reg_TX_DIAGNOSTIC_DATA(base);
+	for (i = 0x00; i <= 0x05; i++) {
+		udelay (1000);
+		printf ("0x%02x  0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base));
+	}
+	reg_TX_DIAGNOSTIC_ADDR(base) = 0x40 | TX_DIAGNOSTIC_ADDR_AI;
+	udelay (1000);
+	dummy = reg_TX_DIAGNOSTIC_DATA(base);
+	for (i = 0x40; i <= 0x47; i++) {
+		udelay (1000);
+		printf ("0x%02x  0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base));
+	}
+	printf ("\n");
+
+}
+#else
+#define tx_diag_regs(base) do{}while(0)
+#endif
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print debug infomation
+ */
+static void rx_diag_regs (unsigned int base)
+{
+	int i;
+	unsigned long dummy;
+
+	printf ("RX diagnostics registers\n");
+	reg_RX_DIAGNOSTIC_ADDR(base) = 0x00 | RX_DIAGNOSTIC_ADDR_AI;
+	udelay (1000);
+	dummy = reg_RX_DIAGNOSTIC_DATA(base);
+	for (i = 0x00; i <= 0x05; i++) {
+		udelay (1000);
+		printf ("0x%02x  0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base));
+	}
+	reg_RX_DIAGNOSTIC_ADDR(base) = 0x40 | RX_DIAGNOSTIC_ADDR_AI;
+	udelay (1000);
+	dummy = reg_RX_DIAGNOSTIC_DATA(base);
+	for (i = 0x08; i <= 0x0a; i++) {
+		udelay (1000);
+		printf ("0x%02x  0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base));
+	}
+	printf ("\n");
+
+}
+#else
+#define rx_diag_regs(base) do{}while(0)
+#endif
+
+#if TSI108_ETH_DEBUG > 100
+/*
+ * print debug infomation
+ */
+static void debug_mii_regs (unsigned int base)
+{
+	printf ("MII_MGMT_CONFIG     0x%08x\n", reg_MII_MGMT_CONFIG(base));
+	printf ("MII_MGMT_COMMAND    0x%08x\n", reg_MII_MGMT_COMMAND(base));
+	printf ("MII_MGMT_ADDRESS    0x%08x\n", reg_MII_MGMT_ADDRESS(base));
+	printf ("MII_MGMT_CONTROL    0x%08x\n", reg_MII_MGMT_CONTROL(base));
+	printf ("MII_MGMT_STATUS     0x%08x\n", reg_MII_MGMT_STATUS(base));
+	printf ("MII_MGMT_INDICATORS 0x%08x\n", reg_MII_MGMT_INDICATORS(base));
+	printf ("\n");
+
+}
+#else
+#define debug_mii_regs(base) do{}while(0)
+#endif
+
+/*
+ * Wait until the phy bus is non-busy
+ */
+static void phy_wait (unsigned int base, unsigned int condition)
+{
+	int timeout;
+
+	timeout = 0;
+	while (reg_MII_MGMT_INDICATORS(base) & condition) {
+		udelay (10);
+		if (++timeout > 10000) {
+			printf ("ERROR: timeout waiting for phy bus (%d)\n",
+			       condition);
+			break;
+		}
+	}
+}
+
+/*
+ * read phy register
+ */
+static unsigned int read_phy (unsigned int base,
+			     unsigned int phy_addr, unsigned int phy_reg)
+{
+	unsigned int value;
+
+	phy_wait (base, MII_MGMT_INDICATORS_BUSY);
+
+	reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg;
+
+	/* Ensure that the Read Cycle bit is cleared prior to next read cycle */
+	reg_MII_MGMT_COMMAND(base) = 0;
+
+	/* start the read */
+	reg_MII_MGMT_COMMAND(base) = MII_MGMT_COMMAND_READ_CYCLE;
+
+	/* wait for the read to complete */
+	phy_wait (base,
+		 MII_MGMT_INDICATORS_NOT_VALID | MII_MGMT_INDICATORS_BUSY);
+
+	value = reg_MII_MGMT_STATUS(base);
+
+	reg_MII_MGMT_COMMAND(base) = 0;
+
+	return value;
+}
+
+/*
+ * write phy register
+ */
+static void write_phy (unsigned int base,
+		      unsigned int phy_addr,
+		      unsigned int phy_reg, unsigned int phy_data)
+{
+	phy_wait (base, MII_MGMT_INDICATORS_BUSY);
+
+	reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg;
+
+	/* Ensure that the Read Cycle bit is cleared prior to next cycle */
+	reg_MII_MGMT_COMMAND(base) = 0;
+
+	/* start the write */
+	reg_MII_MGMT_CONTROL(base) = phy_data;
+}
+
+/*
+ * configure the marvell 88e1111 phy
+ */
+static int marvell_88e_phy_config (struct eth_device *dev, int *speed,
+				  int *duplex)
+{
+	unsigned long base;
+	unsigned long phy_addr;
+	unsigned int phy_status;
+	unsigned int phy_spec_status;
+	int timeout;
+	int phy_speed;
+	int phy_duplex;
+	unsigned int value;
+
+	phy_speed = LINK_SPEED_UNKNOWN;
+	phy_duplex = LINK_DUPLEX_UNKNOWN;
+
+	base = dev->iobase;
+	phy_addr = (unsigned long)dev->priv;
+
+	/* Take the PHY out of reset. */
+	write_phy (ETH_BASE, phy_addr, PHY_CTRL_REG, PHY_CTRL_RESET);
+
+	/* Wait for the reset process to complete. */
+	udelay (10);
+	timeout = 0;
+	while ((phy_status =
+		read_phy (ETH_BASE, phy_addr, PHY_CTRL_REG)) & PHY_CTRL_RESET) {
+		udelay (10);
+		if (++timeout > 10000) {
+			printf ("ERROR: timeout waiting for phy reset\n");
+			break;
+		}
+	}
+
+	/* TBI Configuration. */
+	write_phy (base, TBI_ADDR, TBI_CONTROL_2, TBI_CONTROL_2_G_MII_MODE |
+		  TBI_CONTROL_2_RECEIVE_CLOCK_SELECT);
+	/* Wait for the link to be established. */
+	timeout = 0;
+	do {
+		udelay (20000);
+		phy_status = read_phy (ETH_BASE, phy_addr, PHY_STATUS_REG);
+		if (++timeout > 100) {
+			debug_lev(1, "ERROR: unable to establish link!!!\n");
+			break;
+		}
+	} while ((phy_status & PHY_STAT_LINK_UP) == 0);
+
+	if ((phy_status & PHY_STAT_LINK_UP) == 0)
+		return 0;
+
+	value = 0;
+	phy_spec_status = read_phy (ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG);
+	if (phy_spec_status & SPEC_STAT_RESOLVED) {
+		switch (phy_spec_status & SPEC_STAT_SPEED_MASK) {
+		case SPEED_1000:
+			phy_speed = LINK_SPEED_1000;
+			value |= PHY_CTRL_SPEED1;
+			break;
+		case SPEED_100:
+			phy_speed = LINK_SPEED_100;
+			value |= PHY_CTRL_SPEED0;
+			break;
+		case SPEED_10:
+			phy_speed = LINK_SPEED_10;
+			break;
+		}
+		if (phy_spec_status & SPEC_STAT_FULL_DUP) {
+			phy_duplex = LINK_DUPLEX_FULL;
+			value |= PHY_CTRL_FULL_DUPLEX;
+		} else
+			phy_duplex = LINK_DUPLEX_HALF;
+	}
+	/* set TBI speed */
+	write_phy (base, TBI_ADDR, PHY_CTRL_REG, value);
+	write_phy (base, TBI_ADDR, PHY_AN_ADV_REG, 0x0060);
+
+#if TSI108_ETH_DEBUG > 0
+	printf ("%s link is up", dev->name);
+	phy_spec_status = read_phy (ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG);
+	if (phy_spec_status & SPEC_STAT_RESOLVED) {
+		switch (phy_speed) {
+		case LINK_SPEED_1000:
+			printf (", 1000 Mbps");
+			break;
+		case LINK_SPEED_100:
+			printf (", 100 Mbps");
+			break;
+		case LINK_SPEED_10:
+			printf (", 10 Mbps");
+			break;
+		}
+		if (phy_duplex == LINK_DUPLEX_FULL)
+			printf (", Full duplex");
+		else
+			printf (", Half duplex");
+	}
+	printf ("\n");
+#endif
+
+	dump_phy_regs (TBI_ADDR);
+	if (speed)
+		*speed = phy_speed;
+	if (duplex)
+		*duplex = phy_duplex;
+
+	return 1;
+}
+
+/*
+ * External interface
+ *
+ * register the tsi108 ethernet controllers with the multi-ethernet system
+ */
+int tsi108_eth_initialize (bd_t * bis)
+{
+	struct eth_device *dev;
+	int index;
+
+	for (index = 0; index < CONFIG_TSI108_ETH_NUM_PORTS; index++) {
+		dev = (struct eth_device *)malloc(sizeof(struct eth_device));
+		if (!dev) {
+			printf("tsi108: Can not allocate memory\n");
+			break;
+		}
+		memset(dev, 0, sizeof(*dev));
+		sprintf (dev->name, "TSI108_eth%d", index);
+
+		dev->iobase = ETH_BASE + (index * ETH_PORT_OFFSET);
+		dev->priv = (void *)(phy_address[index]);
+		dev->init = tsi108_eth_probe;
+		dev->halt = tsi108_eth_halt;
+		dev->send = tsi108_eth_send;
+		dev->recv = tsi108_eth_recv;
+
+		eth_register(dev);
+	}
+	return index;
+}
+
+/*
+ * probe for and initialize a single ethernet interface
+ */
+static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis)
+{
+	unsigned long base;
+	unsigned long value;
+	int index;
+	struct dma_descriptor *tx_descr;
+	struct dma_descriptor *rx_descr;
+	int speed;
+	int duplex;
+
+	base = dev->iobase;
+
+	reg_PORT_CONTROL(base) = PORT_CONTROL_STE | PORT_CONTROL_BPT;
+
+	/* Bring DMA/FIFO out of reset. */
+	reg_TX_CONFIG(base) = 0x00000000;
+	reg_RX_CONFIG(base) = 0x00000000;
+
+	reg_TX_THRESHOLDS(base) = (192 << 16) | 192;
+	reg_RX_THRESHOLDS(base) = (192 << 16) | 112;
+
+	/* Bring MAC out of reset. */
+	reg_MAC_CONFIG_1(base) = 0x00000000;
+
+	/* DMA MAC configuration. */
+	reg_MAC_CONFIG_1(base) =
+	    MAC_CONFIG_1_RX_ENABLE | MAC_CONFIG_1_TX_ENABLE;
+
+	reg_MII_MGMT_CONFIG(base) = MII_MGMT_CONFIG_NO_PREAMBLE;
+	reg_MAXIMUM_FRAME_LENGTH(base) = RX_BUFFER_SIZE;
+
+	/* Note: Early tsi108 manual did not have correct byte order
+	 * for the station address.*/
+	reg_STATION_ADDRESS_1(base) = (dev->enetaddr[5] << 24) |
+	    (dev->enetaddr[4] << 16) |
+	    (dev->enetaddr[3] << 8) | (dev->enetaddr[2] << 0);
+
+	reg_STATION_ADDRESS_2(base) = (dev->enetaddr[1] << 24) |
+	    (dev->enetaddr[0] << 16);
+
+	if (marvell_88e_phy_config(dev, &speed, &duplex) == 0)
+		return -1;
+
+	value =
+	    MAC_CONFIG_2_PREAMBLE_LENGTH(7) | MAC_CONFIG_2_PAD_CRC |
+	    MAC_CONFIG_2_CRC_ENABLE;
+	if (speed == LINK_SPEED_1000)
+		value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_BYTE);
+	else {
+		value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_NIBBLE);
+		reg_PORT_CONTROL(base) |= PORT_CONTROL_SPD;
+	}
+	if (duplex == LINK_DUPLEX_FULL) {
+		value |= MAC_CONFIG_2_FULL_DUPLEX;
+		reg_PORT_CONTROL(base) &= ~PORT_CONTROL_BPT;
+	} else
+		reg_PORT_CONTROL(base) |= PORT_CONTROL_BPT;
+	reg_MAC_CONFIG_2(base) = value;
+
+	reg_RX_CONFIG(base) = RX_CONFIG_SE;
+	reg_RX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY;
+	reg_RX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY;
+
+	/* initialize the RX DMA descriptors */
+	rx_descr = &rx_descr_array[0];
+	rx_descr_current = rx_descr;
+	for (index = 0; index < NUM_RX_DESC; index++) {
+		/* make sure the receive buffers are not in cache */
+		invalidate_dcache_range((unsigned long)NetRxPackets[index],
+					(unsigned long)NetRxPackets[index] +
+					RX_BUFFER_SIZE);
+		rx_descr->start_addr0 =
+		    cpu_to_le32((vuint32) NetRxPackets[index]);
+		rx_descr->start_addr1 = 0;
+		rx_descr->next_descr_addr0 =
+		    cpu_to_le32((vuint32) (rx_descr + 1));
+		rx_descr->next_descr_addr1 = 0;
+		rx_descr->vlan_byte_count = 0;
+		rx_descr->config_status = cpu_to_le32((RX_BUFFER_SIZE << 16) |
+						      DMA_DESCR_RX_OWNER);
+		rx_descr++;
+	}
+	rx_descr--;
+	rx_descr->next_descr_addr0 = 0;
+	rx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
+	/* Push the descriptors to RAM so the ethernet DMA can see them */
+	invalidate_dcache_range((unsigned long)rx_descr_array,
+				(unsigned long)rx_descr_array +
+				sizeof(rx_descr_array));
+
+	/* enable RX queue */
+	reg_RX_CONTROL(base) = TX_CONTROL_GO | 0x01;
+	reg_RX_QUEUE_0_PTR_LOW(base) = (u32) rx_descr_current;
+	/* enable receive DMA */
+	reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID;
+
+	reg_TX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY;
+	reg_TX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY;
+
+	/* initialize the TX DMA descriptor */
+	tx_descr = &tx_descriptor;
+
+	tx_descr->start_addr0 = 0;
+	tx_descr->start_addr1 = 0;
+	tx_descr->next_descr_addr0 = 0;
+	tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
+	tx_descr->vlan_byte_count = 0;
+	tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OK |
+					      DMA_DESCR_TX_SOF |
+					      DMA_DESCR_TX_EOF);
+	/* enable TX queue */
+	reg_TX_CONTROL(base) = TX_CONTROL_GO | 0x01;
+
+	return 0;
+}
+
+/*
+ * send a packet
+ */
+static int tsi108_eth_send(struct eth_device *dev, void *packet, int length)
+{
+	unsigned long base;
+	int timeout;
+	struct dma_descriptor *tx_descr;
+	unsigned long status;
+
+	base = dev->iobase;
+	tx_descr = &tx_descriptor;
+
+	/* Wait until the last packet has been transmitted. */
+	timeout = 0;
+	do {
+		/* make sure we see the changes made by the DMA engine */
+		invalidate_dcache_range((unsigned long)tx_descr,
+					(unsigned long)tx_descr +
+					sizeof(struct dma_descriptor));
+
+		if (timeout != 0)
+			udelay (15);
+		if (++timeout > 10000) {
+			tx_diag_regs(base);
+			debug_lev(1,
+				  "ERROR: timeout waiting for last transmit packet to be sent\n");
+			return 0;
+		}
+	} while (tx_descr->config_status & cpu_to_le32(DMA_DESCR_TX_OWNER));
+
+	status = le32_to_cpu(tx_descr->config_status);
+	if ((status & DMA_DESCR_TX_OK) == 0) {
+#ifdef TX_PRINT_ERRORS
+		printf ("TX packet error: 0x%08lx\n    %s%s%s%s\n", status,
+		       status & DMA_DESCR_TX_OK ? "tx error, " : "",
+		       status & DMA_DESCR_TX_RETRY_LIMIT ?
+		       "retry limit reached, " : "",
+		       status & DMA_DESCR_TX_UNDERRUN ? "underrun, " : "",
+		       status & DMA_DESCR_TX_LATE_COLLISION ? "late collision, "
+		       : "");
+#endif
+	}
+
+	debug_lev (9, "sending packet %d\n", length);
+	tx_descr->start_addr0 = cpu_to_le32((vuint32) packet);
+	tx_descr->start_addr1 = 0;
+	tx_descr->next_descr_addr0 = 0;
+	tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);
+	tx_descr->vlan_byte_count = cpu_to_le32(length);
+	tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OWNER |
+					      DMA_DESCR_TX_CRC |
+					      DMA_DESCR_TX_PAD |
+					      DMA_DESCR_TX_SOF |
+					      DMA_DESCR_TX_EOF);
+
+	invalidate_dcache_range((unsigned long)tx_descr,
+				(unsigned long)tx_descr +
+				sizeof(struct dma_descriptor));
+
+	invalidate_dcache_range((unsigned long)packet,
+				(unsigned long)packet + length);
+
+	reg_TX_QUEUE_0_PTR_LOW(base) = (u32) tx_descr;
+	reg_TX_QUEUE_0_PTR_HIGH(base) = TX_QUEUE_0_PTR_HIGH_VALID;
+
+	return length;
+}
+
+/*
+ * Check for received packets and send them up the protocal stack
+ */
+static int tsi108_eth_recv (struct eth_device *dev)
+{
+	struct dma_descriptor *rx_descr;
+	unsigned long base;
+	int length = 0;
+	unsigned long status;
+	uchar *buffer;
+
+	base = dev->iobase;
+
+	/* make sure we see the changes made by the DMA engine */
+	invalidate_dcache_range ((unsigned long)rx_descr_array,
+				(unsigned long)rx_descr_array +
+				sizeof(rx_descr_array));
+
+	/* process all of the received packets */
+	rx_descr = rx_descr_current;
+	while ((rx_descr->config_status & cpu_to_le32(DMA_DESCR_RX_OWNER)) == 0) {
+		/* check for error */
+		status = le32_to_cpu(rx_descr->config_status);
+		if (status & DMA_DESCR_RX_BAD_FRAME) {
+#ifdef RX_PRINT_ERRORS
+			printf ("RX packet error: 0x%08lx\n    %s%s%s%s%s%s\n",
+			       status,
+			       status & DMA_DESCR_RX_FRAME_IS_TYPE ? "too big, "
+			       : "",
+			       status & DMA_DESCR_RX_SHORT_FRAME ? "too short, "
+			       : "",
+			       status & DMA_DESCR_RX_BAD_FRAME ? "bad frame, " :
+			       "",
+			       status & DMA_DESCR_RX_OVERRUN ? "overrun, " : "",
+			       status & DMA_DESCR_RX_MAX_FRAME_LEN ?
+			       "max length, " : "",
+			       status & DMA_DESCR_RX_CRC_ERROR ? "CRC error, " :
+			       "");
+#endif
+		} else {
+			length =
+			    le32_to_cpu(rx_descr->vlan_byte_count) & 0xFFFF;
+
+			/*** process packet ***/
+			buffer = (uchar *)(le32_to_cpu(rx_descr->start_addr0));
+			NetReceive(buffer, length);
+
+			invalidate_dcache_range ((unsigned long)buffer,
+						(unsigned long)buffer +
+						RX_BUFFER_SIZE);
+		}
+		/* Give this buffer back to the DMA engine */
+		rx_descr->vlan_byte_count = 0;
+		rx_descr->config_status = cpu_to_le32 ((RX_BUFFER_SIZE << 16) |
+						      DMA_DESCR_RX_OWNER);
+		/* move descriptor pointer forward */
+		rx_descr =
+		    (struct dma_descriptor
+		     *)(le32_to_cpu (rx_descr->next_descr_addr0));
+		if (rx_descr == 0)
+			rx_descr = &rx_descr_array[0];
+	}
+	/* remember where we are for next time */
+	rx_descr_current = rx_descr;
+
+	/* If the DMA engine has reached the end of the queue
+	 * start over at the begining */
+	if (reg_RX_EXTENDED_STATUS(base) & RX_EXTENDED_STATUS_EOQ_0) {
+
+		reg_RX_EXTENDED_STATUS(base) = RX_EXTENDED_STATUS_EOQ_0;
+		reg_RX_QUEUE_0_PTR_LOW(base) = (u32) & rx_descr_array[0];
+		reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID;
+	}
+
+	return length;
+}
+
+/*
+ * disable an ethernet interface
+ */
+static void tsi108_eth_halt (struct eth_device *dev)
+{
+	unsigned long base;
+
+	base = dev->iobase;
+
+	/* Put DMA/FIFO into reset state. */
+	reg_TX_CONFIG(base) = TX_CONFIG_RST;
+	reg_RX_CONFIG(base) = RX_CONFIG_RST;
+
+	/* Put MAC into reset state. */
+	reg_MAC_CONFIG_1(base) = MAC_CONFIG_1_SOFT_RESET;
+}
diff --git a/marvell/uboot/drivers/net/uli526x.c b/marvell/uboot/drivers/net/uli526x.c
new file mode 100644
index 0000000..538f11e
--- /dev/null
+++ b/marvell/uboot/drivers/net/uli526x.c
@@ -0,0 +1,996 @@
+/*
+ * Copyright 2007, 2010 Freescale Semiconductor, Inc.
+ *
+ * Author: Roy Zang <tie-fei.zang@freescale.com>, Sep, 2007
+ *
+ * Description:
+ * ULI 526x Ethernet port driver.
+ * Based on the Linux driver: drivers/net/tulip/uli526x.c
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <pci.h>
+#include <miiphy.h>
+
+/* some kernel function compatible define */
+
+#undef DEBUG
+
+/* Board/System/Debug information/definition */
+#define ULI_VENDOR_ID		0x10B9
+#define ULI5261_DEVICE_ID	0x5261
+#define ULI5263_DEVICE_ID	0x5263
+/* ULi M5261 ID*/
+#define PCI_ULI5261_ID		(ULI5261_DEVICE_ID << 16 | ULI_VENDOR_ID)
+/* ULi M5263 ID*/
+#define PCI_ULI5263_ID		(ULI5263_DEVICE_ID << 16 | ULI_VENDOR_ID)
+
+#define ULI526X_IO_SIZE	0x100
+#define TX_DESC_CNT	0x10		/* Allocated Tx descriptors */
+#define RX_DESC_CNT	PKTBUFSRX	/* Allocated Rx descriptors */
+#define TX_FREE_DESC_CNT	(TX_DESC_CNT - 2) /* Max TX packet count */
+#define TX_WAKE_DESC_CNT	(TX_DESC_CNT - 3) /* TX wakeup count */
+#define DESC_ALL_CNT		(TX_DESC_CNT + RX_DESC_CNT)
+#define TX_BUF_ALLOC		0x300
+#define RX_ALLOC_SIZE		PKTSIZE
+#define ULI526X_RESET		1
+#define CR0_DEFAULT		0
+#define CR6_DEFAULT		0x22200000
+#define CR7_DEFAULT		0x180c1
+#define CR15_DEFAULT		0x06		/* TxJabber RxWatchdog */
+#define TDES0_ERR_MASK		0x4302		/* TXJT, LC, EC, FUE */
+#define MAX_PACKET_SIZE		1514
+#define ULI5261_MAX_MULTICAST	14
+#define RX_COPY_SIZE		100
+#define MAX_CHECK_PACKET	0x8000
+
+#define ULI526X_10MHF		0
+#define ULI526X_100MHF		1
+#define ULI526X_10MFD		4
+#define ULI526X_100MFD		5
+#define ULI526X_AUTO		8
+
+#define ULI526X_TXTH_72		0x400000	/* TX TH 72 byte */
+#define ULI526X_TXTH_96		0x404000	/* TX TH 96 byte */
+#define ULI526X_TXTH_128	0x0000		/* TX TH 128 byte */
+#define ULI526X_TXTH_256	0x4000		/* TX TH 256 byte */
+#define ULI526X_TXTH_512	0x8000		/* TX TH 512 byte */
+#define ULI526X_TXTH_1K		0xC000		/* TX TH 1K  byte */
+
+/* CR9 definition: SROM/MII */
+#define CR9_SROM_READ		0x4800
+#define CR9_SRCS		0x1
+#define CR9_SRCLK		0x2
+#define CR9_CRDOUT		0x8
+#define SROM_DATA_0		0x0
+#define SROM_DATA_1		0x4
+#define PHY_DATA_1		0x20000
+#define PHY_DATA_0		0x00000
+#define MDCLKH			0x10000
+
+#define PHY_POWER_DOWN	0x800
+
+#define SROM_V41_CODE		0x14
+
+#define SROM_CLK_WRITE(data, ioaddr) do {			\
+	outl(data|CR9_SROM_READ|CR9_SRCS, ioaddr);		\
+	udelay(5);						\
+	outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK, ioaddr);	\
+	udelay(5);						\
+	outl(data|CR9_SROM_READ|CR9_SRCS, ioaddr);		\
+	udelay(5);						\
+	} while (0)
+
+/* Structure/enum declaration */
+
+struct tx_desc {
+	u32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */
+	char *tx_buf_ptr;		/* Data for us */
+	struct tx_desc *next_tx_desc;
+};
+
+struct rx_desc {
+	u32 rdes0, rdes1, rdes2, rdes3;	/* Data for the card */
+	char *rx_buf_ptr;		/* Data for us */
+	struct rx_desc *next_rx_desc;
+};
+
+struct uli526x_board_info {
+	u32 chip_id;	/* Chip vendor/Device ID */
+	pci_dev_t pdev;
+
+	long ioaddr;			/* I/O base address */
+	u32 cr0_data;
+	u32 cr5_data;
+	u32 cr6_data;
+	u32 cr7_data;
+	u32 cr15_data;
+
+	/* pointer for memory physical address */
+	dma_addr_t buf_pool_dma_ptr;	/* Tx buffer pool memory */
+	dma_addr_t buf_pool_dma_start;	/* Tx buffer pool align dword */
+	dma_addr_t desc_pool_dma_ptr;	/* descriptor pool memory */
+	dma_addr_t first_tx_desc_dma;
+	dma_addr_t first_rx_desc_dma;
+
+	/* descriptor pointer */
+	unsigned char *buf_pool_ptr;	/* Tx buffer pool memory */
+	unsigned char *buf_pool_start;	/* Tx buffer pool align dword */
+	unsigned char *desc_pool_ptr;	/* descriptor pool memory */
+	struct tx_desc *first_tx_desc;
+	struct tx_desc *tx_insert_ptr;
+	struct tx_desc *tx_remove_ptr;
+	struct rx_desc *first_rx_desc;
+	struct rx_desc *rx_ready_ptr;	/* packet come pointer */
+	unsigned long tx_packet_cnt;	/* transmitted packet count */
+
+	u16 PHY_reg4;			/* Saved Phyxcer register 4 value */
+
+	u8 media_mode;			/* user specify media mode */
+	u8 op_mode;			/* real work dedia mode */
+	u8 phy_addr;
+
+	/* NIC SROM data */
+	unsigned char srom[128];
+};
+
+enum uli526x_offsets {
+	DCR0 = 0x00, DCR1 = 0x08, DCR2 = 0x10, DCR3 = 0x18, DCR4 = 0x20,
+	DCR5 = 0x28, DCR6 = 0x30, DCR7 = 0x38, DCR8 = 0x40, DCR9 = 0x48,
+	DCR10 = 0x50, DCR11 = 0x58, DCR12 = 0x60, DCR13 = 0x68, DCR14 = 0x70,
+	DCR15 = 0x78
+};
+
+enum uli526x_CR6_bits {
+	CR6_RXSC = 0x2, CR6_PBF = 0x8, CR6_PM = 0x40, CR6_PAM = 0x80,
+	CR6_FDM = 0x200, CR6_TXSC = 0x2000, CR6_STI = 0x100000,
+	CR6_SFT = 0x200000, CR6_RXA = 0x40000000, CR6_NO_PURGE = 0x20000000
+};
+
+/* Global variable declaration -- */
+
+static unsigned char uli526x_media_mode = ULI526X_AUTO;
+
+static struct tx_desc desc_pool_array[DESC_ALL_CNT + 0x20]
+	__attribute__ ((aligned(32)));
+static char buf_pool[TX_BUF_ALLOC * TX_DESC_CNT + 4];
+
+/* For module input parameter */
+static int mode = 8;
+
+/* function declaration -- */
+static int uli526x_start_xmit(struct eth_device *dev, void *packet, int length);
+static const struct ethtool_ops netdev_ethtool_ops;
+static u16 read_srom_word(long, int);
+static void uli526x_descriptor_init(struct uli526x_board_info *, unsigned long);
+static void allocate_rx_buffer(struct uli526x_board_info *);
+static void update_cr6(u32, unsigned long);
+static u16 uli_phy_read(unsigned long, u8, u8, u32);
+static u16 phy_readby_cr10(unsigned long, u8, u8);
+static void uli_phy_write(unsigned long, u8, u8, u16, u32);
+static void phy_writeby_cr10(unsigned long, u8, u8, u16);
+static void phy_write_1bit(unsigned long, u32, u32);
+static u16 phy_read_1bit(unsigned long, u32);
+static int uli526x_rx_packet(struct eth_device *);
+static void uli526x_free_tx_pkt(struct eth_device *,
+		struct uli526x_board_info *);
+static void uli526x_reuse_buf(struct rx_desc *);
+static void uli526x_init(struct eth_device *);
+static void uli526x_set_phyxcer(struct uli526x_board_info *);
+
+
+static int uli526x_init_one(struct eth_device *, bd_t *);
+static void uli526x_disable(struct eth_device *);
+static void set_mac_addr(struct eth_device *);
+
+static struct pci_device_id uli526x_pci_tbl[] = {
+	{ ULI_VENDOR_ID, ULI5261_DEVICE_ID}, /* 5261 device */
+	{ ULI_VENDOR_ID, ULI5263_DEVICE_ID}, /* 5263 device */
+	{}
+};
+
+/* ULI526X network board routine */
+
+/*
+ *	Search ULI526X board, register it
+ */
+
+int uli526x_initialize(bd_t *bis)
+{
+	pci_dev_t devno;
+	int card_number = 0;
+	struct eth_device *dev;
+	struct uli526x_board_info *db;	/* board information structure */
+
+	u32 iobase;
+	int idx = 0;
+
+	while (1) {
+		/* Find PCI device */
+		devno = pci_find_devices(uli526x_pci_tbl, idx++);
+		if (devno < 0)
+			break;
+
+		pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
+		iobase &= ~0xf;
+
+		dev = (struct eth_device *)malloc(sizeof *dev);
+		if (!dev) {
+			printf("uli526x: Can not allocate memory\n");
+			break;
+		}
+		memset(dev, 0, sizeof(*dev));
+		sprintf(dev->name, "uli526x#%d", card_number);
+		db = (struct uli526x_board_info *)
+			malloc(sizeof(struct uli526x_board_info));
+
+		dev->priv = db;
+		db->pdev = devno;
+		dev->iobase = iobase;
+
+		dev->init = uli526x_init_one;
+		dev->halt = uli526x_disable;
+		dev->send = uli526x_start_xmit;
+		dev->recv = uli526x_rx_packet;
+
+		/* init db */
+		db->ioaddr = dev->iobase;
+		/* get chip id */
+
+		pci_read_config_dword(devno, PCI_VENDOR_ID, &db->chip_id);
+#ifdef DEBUG
+		printf("uli526x: uli526x @0x%x\n", iobase);
+		printf("uli526x: chip_id%x\n", db->chip_id);
+#endif
+		eth_register(dev);
+		card_number++;
+		pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20);
+		udelay(10 * 1000);
+	}
+	return card_number;
+}
+
+static int uli526x_init_one(struct eth_device *dev, bd_t *bis)
+{
+
+	struct uli526x_board_info *db = dev->priv;
+	int i;
+
+	switch (mode) {
+	case ULI526X_10MHF:
+	case ULI526X_100MHF:
+	case ULI526X_10MFD:
+	case ULI526X_100MFD:
+		uli526x_media_mode = mode;
+		break;
+	default:
+		uli526x_media_mode = ULI526X_AUTO;
+		break;
+	}
+
+	/* Allocate Tx/Rx descriptor memory */
+	db->desc_pool_ptr = (uchar *)&desc_pool_array[0];
+	db->desc_pool_dma_ptr = (dma_addr_t)&desc_pool_array[0];
+	if (db->desc_pool_ptr == NULL)
+		return -1;
+
+	db->buf_pool_ptr = (uchar *)&buf_pool[0];
+	db->buf_pool_dma_ptr = (dma_addr_t)&buf_pool[0];
+	if (db->buf_pool_ptr == NULL)
+		return -1;
+
+	db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr;
+	db->first_tx_desc_dma = db->desc_pool_dma_ptr;
+
+	db->buf_pool_start = db->buf_pool_ptr;
+	db->buf_pool_dma_start = db->buf_pool_dma_ptr;
+
+#ifdef DEBUG
+	printf("%s(): db->ioaddr= 0x%x\n",
+		__FUNCTION__, db->ioaddr);
+	printf("%s(): media_mode= 0x%x\n",
+		__FUNCTION__, uli526x_media_mode);
+	printf("%s(): db->desc_pool_ptr= 0x%x\n",
+		__FUNCTION__, db->desc_pool_ptr);
+	printf("%s(): db->desc_pool_dma_ptr= 0x%x\n",
+		__FUNCTION__, db->desc_pool_dma_ptr);
+	printf("%s(): db->buf_pool_ptr= 0x%x\n",
+		__FUNCTION__, db->buf_pool_ptr);
+	printf("%s(): db->buf_pool_dma_ptr= 0x%x\n",
+		__FUNCTION__, db->buf_pool_dma_ptr);
+#endif
+
+	/* read 64 word srom data */
+	for (i = 0; i < 64; i++)
+		((u16 *) db->srom)[i] = cpu_to_le16(read_srom_word(db->ioaddr,
+			i));
+
+	/* Set Node address */
+	if (((db->srom[0] == 0xff) && (db->srom[1] == 0xff)) ||
+	    ((db->srom[0] == 0x00) && (db->srom[1] == 0x00)))
+	/* SROM absent, so write MAC address to ID Table */
+		set_mac_addr(dev);
+	else {		/*Exist SROM*/
+		for (i = 0; i < 6; i++)
+			dev->enetaddr[i] = db->srom[20 + i];
+	}
+#ifdef DEBUG
+	for (i = 0; i < 6; i++)
+		printf("%c%02x", i ? ':' : ' ', dev->enetaddr[i]);
+#endif
+	db->PHY_reg4 = 0x1e0;
+
+	/* system variable init */
+	db->cr6_data = CR6_DEFAULT ;
+	db->cr6_data |= ULI526X_TXTH_256;
+	db->cr0_data = CR0_DEFAULT;
+	uli526x_init(dev);
+	return 0;
+}
+
+static void uli526x_disable(struct eth_device *dev)
+{
+#ifdef DEBUG
+	printf("uli526x_disable\n");
+#endif
+	struct uli526x_board_info *db = dev->priv;
+
+	if (!((inl(db->ioaddr + DCR12)) & 0x8)) {
+		/* Reset & stop ULI526X board */
+		outl(ULI526X_RESET, db->ioaddr + DCR0);
+		udelay(5);
+		uli_phy_write(db->ioaddr, db->phy_addr, 0, 0x8000, db->chip_id);
+
+		/* reset the board */
+		db->cr6_data &= ~(CR6_RXSC | CR6_TXSC);	/* Disable Tx/Rx */
+		update_cr6(db->cr6_data, dev->iobase);
+		outl(0, dev->iobase + DCR7);		/* Disable Interrupt */
+		outl(inl(dev->iobase + DCR5), dev->iobase + DCR5);
+	}
+}
+
+/*	Initialize ULI526X board
+ *	Reset ULI526X board
+ *	Initialize TX/Rx descriptor chain structure
+ *	Send the set-up frame
+ *	Enable Tx/Rx machine
+ */
+
+static void uli526x_init(struct eth_device *dev)
+{
+
+	struct uli526x_board_info *db = dev->priv;
+	u8	phy_tmp;
+	u16	phy_value;
+	u16 phy_reg_reset;
+
+	/* Reset M526x MAC controller */
+	outl(ULI526X_RESET, db->ioaddr + DCR0);	/* RESET MAC */
+	udelay(100);
+	outl(db->cr0_data, db->ioaddr + DCR0);
+	udelay(5);
+
+	/* Phy addr : In some boards,M5261/M5263 phy address != 1 */
+	db->phy_addr = 1;
+	db->tx_packet_cnt = 0;
+	for (phy_tmp = 0; phy_tmp < 32; phy_tmp++) {
+		/* peer add */
+		phy_value = uli_phy_read(db->ioaddr, phy_tmp, 3, db->chip_id);
+		if (phy_value != 0xffff && phy_value != 0) {
+			db->phy_addr = phy_tmp;
+			break;
+		}
+	}
+
+#ifdef DEBUG
+	printf("%s(): db->ioaddr= 0x%x\n", __FUNCTION__, db->ioaddr);
+	printf("%s(): db->phy_addr= 0x%x\n", __FUNCTION__, db->phy_addr);
+#endif
+	if (phy_tmp == 32)
+		printf("Can not find the phy address!!!");
+
+	/* Parser SROM and media mode */
+	db->media_mode = uli526x_media_mode;
+
+	if (!(inl(db->ioaddr + DCR12) & 0x8)) {
+		/* Phyxcer capability setting */
+		phy_reg_reset = uli_phy_read(db->ioaddr,
+			db->phy_addr, 0, db->chip_id);
+		phy_reg_reset = (phy_reg_reset | 0x8000);
+		uli_phy_write(db->ioaddr, db->phy_addr, 0,
+			phy_reg_reset, db->chip_id);
+		udelay(500);
+
+		/* Process Phyxcer Media Mode */
+		uli526x_set_phyxcer(db);
+	}
+	/* Media Mode Process */
+	if (!(db->media_mode & ULI526X_AUTO))
+		db->op_mode = db->media_mode;	/* Force Mode */
+
+	/* Initialize Transmit/Receive decriptor and CR3/4 */
+	uli526x_descriptor_init(db, db->ioaddr);
+
+	/* Init CR6 to program M526X operation */
+	update_cr6(db->cr6_data, db->ioaddr);
+
+	/* Init CR7, interrupt active bit */
+	db->cr7_data = CR7_DEFAULT;
+	outl(db->cr7_data, db->ioaddr + DCR7);
+
+	/* Init CR15, Tx jabber and Rx watchdog timer */
+	outl(db->cr15_data, db->ioaddr + DCR15);
+
+	/* Enable ULI526X Tx/Rx function */
+	db->cr6_data |= CR6_RXSC | CR6_TXSC;
+	update_cr6(db->cr6_data, db->ioaddr);
+	while (!(inl(db->ioaddr + DCR12) & 0x8))
+		udelay(10);
+}
+
+/*
+ *	Hardware start transmission.
+ *	Send a packet to media from the upper layer.
+ */
+
+static int uli526x_start_xmit(struct eth_device *dev, void *packet, int length)
+{
+	struct uli526x_board_info *db = dev->priv;
+	struct tx_desc *txptr;
+	unsigned int len = length;
+	/* Too large packet check */
+	if (len > MAX_PACKET_SIZE) {
+		printf(": big packet = %d\n", len);
+		return 0;
+	}
+
+	/* No Tx resource check, it never happen nromally */
+	if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) {
+		printf("No Tx resource %ld\n", db->tx_packet_cnt);
+		return 0;
+	}
+
+	/* Disable NIC interrupt */
+	outl(0, dev->iobase + DCR7);
+
+	/* transmit this packet */
+	txptr = db->tx_insert_ptr;
+	memcpy((char *)txptr->tx_buf_ptr, (char *)packet, (int)length);
+	txptr->tdes1 = cpu_to_le32(0xe1000000 | length);
+
+	/* Point to next transmit free descriptor */
+	db->tx_insert_ptr = txptr->next_tx_desc;
+
+	/* Transmit Packet Process */
+	if ((db->tx_packet_cnt < TX_DESC_CNT)) {
+		txptr->tdes0 = cpu_to_le32(0x80000000);	/* Set owner bit */
+		db->tx_packet_cnt++;			/* Ready to send */
+		outl(0x1, dev->iobase + DCR1);	/* Issue Tx polling */
+	}
+
+	/* Got ULI526X status */
+	db->cr5_data = inl(db->ioaddr + DCR5);
+	outl(db->cr5_data, db->ioaddr + DCR5);
+
+#ifdef TX_DEBUG
+	printf("%s(): length = 0x%x\n", __FUNCTION__, length);
+	printf("%s(): cr5_data=%x\n", __FUNCTION__, db->cr5_data);
+#endif
+
+	outl(db->cr7_data, dev->iobase + DCR7);
+	uli526x_free_tx_pkt(dev, db);
+
+	return length;
+}
+
+/*
+ *	Free TX resource after TX complete
+ */
+
+static void uli526x_free_tx_pkt(struct eth_device *dev,
+	struct uli526x_board_info *db)
+{
+	struct tx_desc *txptr;
+	u32 tdes0;
+
+	txptr = db->tx_remove_ptr;
+	while (db->tx_packet_cnt) {
+		tdes0 = le32_to_cpu(txptr->tdes0);
+		/* printf(DRV_NAME ": tdes0=%x\n", tdes0); */
+		if (tdes0 & 0x80000000)
+			break;
+
+		/* A packet sent completed */
+		db->tx_packet_cnt--;
+
+		if (tdes0 != 0x7fffffff) {
+#ifdef TX_DEBUG
+			printf("%s()tdes0=%x\n", __FUNCTION__, tdes0);
+#endif
+			if (tdes0 & TDES0_ERR_MASK) {
+				if (tdes0 & 0x0002) {	/* UnderRun */
+					if (!(db->cr6_data & CR6_SFT)) {
+						db->cr6_data = db->cr6_data |
+							CR6_SFT;
+						update_cr6(db->cr6_data,
+							db->ioaddr);
+					}
+				}
+			}
+		}
+
+		txptr = txptr->next_tx_desc;
+	}/* End of while */
+
+	/* Update TX remove pointer to next */
+	db->tx_remove_ptr = txptr;
+}
+
+
+/*
+ *	Receive the come packet and pass to upper layer
+ */
+
+static int uli526x_rx_packet(struct eth_device *dev)
+{
+	struct uli526x_board_info *db = dev->priv;
+	struct rx_desc *rxptr;
+	int rxlen = 0;
+	u32 rdes0;
+
+	rxptr = db->rx_ready_ptr;
+
+	rdes0 = le32_to_cpu(rxptr->rdes0);
+#ifdef RX_DEBUG
+	printf("%s(): rxptr->rdes0=%x:%x\n", __FUNCTION__, rxptr->rdes0);
+#endif
+	if (!(rdes0 & 0x80000000)) {	/* packet owner check */
+		if ((rdes0 & 0x300) != 0x300) {
+			/* A packet without First/Last flag */
+			/* reuse this buf */
+			printf("A packet without First/Last flag");
+			uli526x_reuse_buf(rxptr);
+		} else {
+			/* A packet with First/Last flag */
+			rxlen = ((rdes0 >> 16) & 0x3fff) - 4;
+#ifdef RX_DEBUG
+			printf("%s(): rxlen =%x\n", __FUNCTION__, rxlen);
+#endif
+			/* error summary bit check */
+			if (rdes0 & 0x8000) {
+				/* This is a error packet */
+				printf("Error: rdes0: %x\n", rdes0);
+			}
+
+			if (!(rdes0 & 0x8000) ||
+				((db->cr6_data & CR6_PM) && (rxlen > 6))) {
+
+#ifdef RX_DEBUG
+				printf("%s(): rx_skb_ptr =%x\n",
+					__FUNCTION__, rxptr->rx_buf_ptr);
+				printf("%s(): rxlen =%x\n",
+					__FUNCTION__, rxlen);
+
+				printf("%s(): buf addr =%x\n",
+					__FUNCTION__, rxptr->rx_buf_ptr);
+				printf("%s(): rxlen =%x\n",
+					__FUNCTION__, rxlen);
+				int i;
+				for (i = 0; i < 0x20; i++)
+					printf("%s(): data[%x] =%x\n",
+					__FUNCTION__, i, rxptr->rx_buf_ptr[i]);
+#endif
+
+				NetReceive((uchar *)rxptr->rx_buf_ptr, rxlen);
+				uli526x_reuse_buf(rxptr);
+
+			} else {
+				/* Reuse SKB buffer when the packet is error */
+				printf("Reuse buffer, rdes0");
+				uli526x_reuse_buf(rxptr);
+			}
+		}
+
+		rxptr = rxptr->next_rx_desc;
+	}
+
+	db->rx_ready_ptr = rxptr;
+	return rxlen;
+}
+
+/*
+ *	Reuse the RX buffer
+ */
+
+static void uli526x_reuse_buf(struct rx_desc *rxptr)
+{
+
+	if (!(rxptr->rdes0 & cpu_to_le32(0x80000000)))
+		rxptr->rdes0 = cpu_to_le32(0x80000000);
+	else
+		printf("Buffer reuse method error");
+}
+/*
+ *	Initialize transmit/Receive descriptor
+ *	Using Chain structure, and allocate Tx/Rx buffer
+ */
+
+static void uli526x_descriptor_init(struct uli526x_board_info *db,
+	unsigned long ioaddr)
+{
+	struct tx_desc *tmp_tx;
+	struct rx_desc *tmp_rx;
+	unsigned char *tmp_buf;
+	dma_addr_t tmp_tx_dma, tmp_rx_dma;
+	dma_addr_t tmp_buf_dma;
+	int i;
+	/* tx descriptor start pointer */
+	db->tx_insert_ptr = db->first_tx_desc;
+	db->tx_remove_ptr = db->first_tx_desc;
+
+	outl(db->first_tx_desc_dma, ioaddr + DCR4);     /* TX DESC address */
+
+	/* rx descriptor start pointer */
+	db->first_rx_desc = (void *)db->first_tx_desc +
+		sizeof(struct tx_desc) * TX_DESC_CNT;
+	db->first_rx_desc_dma =  db->first_tx_desc_dma +
+		sizeof(struct tx_desc) * TX_DESC_CNT;
+	db->rx_ready_ptr = db->first_rx_desc;
+	outl(db->first_rx_desc_dma, ioaddr + DCR3);	/* RX DESC address */
+#ifdef DEBUG
+	printf("%s(): db->first_tx_desc= 0x%x\n",
+		__FUNCTION__, db->first_tx_desc);
+	printf("%s(): db->first_rx_desc_dma= 0x%x\n",
+		__FUNCTION__, db->first_rx_desc_dma);
+#endif
+	/* Init Transmit chain */
+	tmp_buf = db->buf_pool_start;
+	tmp_buf_dma = db->buf_pool_dma_start;
+	tmp_tx_dma = db->first_tx_desc_dma;
+	for (tmp_tx = db->first_tx_desc, i = 0;
+			i < TX_DESC_CNT; i++, tmp_tx++) {
+		tmp_tx->tx_buf_ptr = (char *)tmp_buf;
+		tmp_tx->tdes0 = cpu_to_le32(0);
+		tmp_tx->tdes1 = cpu_to_le32(0x81000000);	/* IC, chain */
+		tmp_tx->tdes2 = cpu_to_le32(tmp_buf_dma);
+		tmp_tx_dma += sizeof(struct tx_desc);
+		tmp_tx->tdes3 = cpu_to_le32(tmp_tx_dma);
+		tmp_tx->next_tx_desc = tmp_tx + 1;
+		tmp_buf = tmp_buf + TX_BUF_ALLOC;
+		tmp_buf_dma = tmp_buf_dma + TX_BUF_ALLOC;
+	}
+	(--tmp_tx)->tdes3 = cpu_to_le32(db->first_tx_desc_dma);
+	tmp_tx->next_tx_desc = db->first_tx_desc;
+
+	 /* Init Receive descriptor chain */
+	tmp_rx_dma = db->first_rx_desc_dma;
+	for (tmp_rx = db->first_rx_desc, i = 0; i < RX_DESC_CNT;
+			i++, tmp_rx++) {
+		tmp_rx->rdes0 = cpu_to_le32(0);
+		tmp_rx->rdes1 = cpu_to_le32(0x01000600);
+		tmp_rx_dma += sizeof(struct rx_desc);
+		tmp_rx->rdes3 = cpu_to_le32(tmp_rx_dma);
+		tmp_rx->next_rx_desc = tmp_rx + 1;
+	}
+	(--tmp_rx)->rdes3 = cpu_to_le32(db->first_rx_desc_dma);
+	tmp_rx->next_rx_desc = db->first_rx_desc;
+
+	/* pre-allocate Rx buffer */
+	allocate_rx_buffer(db);
+}
+
+/*
+ *	Update CR6 value
+ *	Firstly stop ULI526X, then written value and start
+ */
+
+static void update_cr6(u32 cr6_data, unsigned long ioaddr)
+{
+
+	outl(cr6_data, ioaddr + DCR6);
+	udelay(5);
+}
+
+/*
+ *	Allocate rx buffer,
+ */
+
+static void allocate_rx_buffer(struct uli526x_board_info *db)
+{
+	int index;
+	struct rx_desc *rxptr;
+	rxptr = db->first_rx_desc;
+	u32 addr;
+
+	for (index = 0; index < RX_DESC_CNT; index++) {
+		addr = (u32)NetRxPackets[index];
+		addr += (16 - (addr & 15));
+		rxptr->rx_buf_ptr = (char *) addr;
+		rxptr->rdes2 = cpu_to_le32(addr);
+		rxptr->rdes0 = cpu_to_le32(0x80000000);
+#ifdef DEBUG
+		printf("%s(): Number 0x%x:\n", __FUNCTION__, index);
+		printf("%s(): addr 0x%x:\n", __FUNCTION__, addr);
+		printf("%s(): rxptr address = 0x%x\n", __FUNCTION__, rxptr);
+		printf("%s(): rxptr buf address = 0x%x\n", \
+			__FUNCTION__, rxptr->rx_buf_ptr);
+		printf("%s(): rdes2  = 0x%x\n", __FUNCTION__, rxptr->rdes2);
+#endif
+		rxptr = rxptr->next_rx_desc;
+	}
+}
+
+/*
+ *	Read one word data from the serial ROM
+ */
+
+static u16 read_srom_word(long ioaddr, int offset)
+{
+	int i;
+	u16 srom_data = 0;
+	long cr9_ioaddr = ioaddr + DCR9;
+
+	outl(CR9_SROM_READ, cr9_ioaddr);
+	outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+
+	/* Send the Read Command 110b */
+	SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
+	SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
+	SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr);
+
+	/* Send the offset */
+	for (i = 5; i >= 0; i--) {
+		srom_data = (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0;
+		SROM_CLK_WRITE(srom_data, cr9_ioaddr);
+	}
+
+	outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+
+	for (i = 16; i > 0; i--) {
+		outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr);
+		udelay(5);
+		srom_data = (srom_data << 1) | ((inl(cr9_ioaddr) & CR9_CRDOUT)
+			? 1 : 0);
+		outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+		udelay(5);
+	}
+
+	outl(CR9_SROM_READ, cr9_ioaddr);
+	return srom_data;
+}
+
+/*
+ *	Set 10/100 phyxcer capability
+ *	AUTO mode : phyxcer register4 is NIC capability
+ *	Force mode: phyxcer register4 is the force media
+ */
+
+static void uli526x_set_phyxcer(struct uli526x_board_info *db)
+{
+	u16 phy_reg;
+
+	/* Phyxcer capability setting */
+	phy_reg = uli_phy_read(db->ioaddr,
+			db->phy_addr, 4, db->chip_id) & ~0x01e0;
+
+	if (db->media_mode & ULI526X_AUTO) {
+		/* AUTO Mode */
+		phy_reg |= db->PHY_reg4;
+	} else {
+		/* Force Mode */
+		switch (db->media_mode) {
+		case ULI526X_10MHF: phy_reg |= 0x20; break;
+		case ULI526X_10MFD: phy_reg |= 0x40; break;
+		case ULI526X_100MHF: phy_reg |= 0x80; break;
+		case ULI526X_100MFD: phy_reg |= 0x100; break;
+		}
+
+	}
+
+	/* Write new capability to Phyxcer Reg4 */
+	if (!(phy_reg & 0x01e0)) {
+		phy_reg |= db->PHY_reg4;
+		db->media_mode |= ULI526X_AUTO;
+	}
+	uli_phy_write(db->ioaddr, db->phy_addr, 4, phy_reg, db->chip_id);
+
+	/* Restart Auto-Negotiation */
+	uli_phy_write(db->ioaddr, db->phy_addr, 0, 0x1200, db->chip_id);
+	udelay(50);
+}
+
+/*
+ *	Write a word to Phy register
+ */
+
+static void uli_phy_write(unsigned long iobase, u8 phy_addr, u8 offset,
+	u16 phy_data, u32 chip_id)
+{
+	u16 i;
+	unsigned long ioaddr;
+
+	if (chip_id == PCI_ULI5263_ID) {
+		phy_writeby_cr10(iobase, phy_addr, offset, phy_data);
+		return;
+	}
+	/* M5261/M5263 Chip */
+	ioaddr = iobase + DCR9;
+
+	/* Send 33 synchronization clock to Phy controller */
+	for (i = 0; i < 35; i++)
+		phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+	/* Send start command(01) to Phy */
+	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+	/* Send write command(01) to Phy */
+	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+	/* Send Phy address */
+	for (i = 0x10; i > 0; i = i >> 1)
+		phy_write_1bit(ioaddr, phy_addr & i ?
+			PHY_DATA_1 : PHY_DATA_0, chip_id);
+
+	/* Send register address */
+	for (i = 0x10; i > 0; i = i >> 1)
+		phy_write_1bit(ioaddr, offset & i ?
+			PHY_DATA_1 : PHY_DATA_0, chip_id);
+
+	/* written trasnition */
+	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+
+	/* Write a word data to PHY controller */
+	for (i = 0x8000; i > 0; i >>= 1)
+		phy_write_1bit(ioaddr, phy_data & i ?
+			PHY_DATA_1 : PHY_DATA_0, chip_id);
+}
+
+/*
+ *	Read a word data from phy register
+ */
+
+static u16 uli_phy_read(unsigned long iobase, u8 phy_addr, u8 offset,
+			u32 chip_id)
+{
+	int i;
+	u16 phy_data;
+	unsigned long ioaddr;
+
+	if (chip_id == PCI_ULI5263_ID)
+		return phy_readby_cr10(iobase, phy_addr, offset);
+	/* M5261/M5263 Chip */
+	ioaddr = iobase + DCR9;
+
+	/* Send 33 synchronization clock to Phy controller */
+	for (i = 0; i < 35; i++)
+		phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+	/* Send start command(01) to Phy */
+	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+	/* Send read command(10) to Phy */
+	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+
+	/* Send Phy address */
+	for (i = 0x10; i > 0; i = i >> 1)
+		phy_write_1bit(ioaddr, phy_addr & i ?
+			PHY_DATA_1 : PHY_DATA_0, chip_id);
+
+	/* Send register address */
+	for (i = 0x10; i > 0; i = i >> 1)
+		phy_write_1bit(ioaddr, offset & i ?
+			PHY_DATA_1 : PHY_DATA_0, chip_id);
+
+	/* Skip transition state */
+	phy_read_1bit(ioaddr, chip_id);
+
+	/* read 16bit data */
+	for (phy_data = 0, i = 0; i < 16; i++) {
+		phy_data <<= 1;
+		phy_data |= phy_read_1bit(ioaddr, chip_id);
+	}
+
+	return phy_data;
+}
+
+static u16 phy_readby_cr10(unsigned long iobase, u8 phy_addr, u8 offset)
+{
+	unsigned long ioaddr, cr10_value;
+
+	ioaddr = iobase + DCR10;
+	cr10_value = phy_addr;
+	cr10_value = (cr10_value<<5) + offset;
+	cr10_value = (cr10_value<<16) + 0x08000000;
+	outl(cr10_value, ioaddr);
+	udelay(1);
+	while (1) {
+		cr10_value = inl(ioaddr);
+		if (cr10_value & 0x10000000)
+			break;
+	}
+	return (cr10_value&0x0ffff);
+}
+
+static void phy_writeby_cr10(unsigned long iobase, u8 phy_addr,
+	u8 offset, u16 phy_data)
+{
+	unsigned long ioaddr, cr10_value;
+
+	ioaddr = iobase + DCR10;
+	cr10_value = phy_addr;
+	cr10_value = (cr10_value<<5) + offset;
+	cr10_value = (cr10_value<<16) + 0x04000000 + phy_data;
+	outl(cr10_value, ioaddr);
+	udelay(1);
+}
+/*
+ *	Write one bit data to Phy Controller
+ */
+
+static void phy_write_1bit(unsigned long ioaddr, u32 phy_data, u32 chip_id)
+{
+	outl(phy_data , ioaddr);			/* MII Clock Low */
+	udelay(1);
+	outl(phy_data  | MDCLKH, ioaddr);	/* MII Clock High */
+	udelay(1);
+	outl(phy_data , ioaddr);			/* MII Clock Low */
+	udelay(1);
+}
+
+/*
+ *	Read one bit phy data from PHY controller
+ */
+
+static u16 phy_read_1bit(unsigned long ioaddr, u32 chip_id)
+{
+	u16 phy_data;
+
+	outl(0x50000 , ioaddr);
+	udelay(1);
+	phy_data = (inl(ioaddr) >> 19) & 0x1;
+	outl(0x40000 , ioaddr);
+	udelay(1);
+
+	return phy_data;
+}
+
+/*
+ * Set MAC address to ID Table
+ */
+
+static void set_mac_addr(struct eth_device *dev)
+{
+	int i;
+	u16 addr;
+	struct uli526x_board_info *db = dev->priv;
+	outl(0x10000, db->ioaddr + DCR0);	/* Diagnosis mode */
+	/* Reset dianostic pointer port */
+	outl(0x1c0, db->ioaddr + DCR13);
+	outl(0, db->ioaddr + DCR14);	/* Clear reset port */
+	outl(0x10, db->ioaddr + DCR14);	/* Reset ID Table pointer */
+	outl(0, db->ioaddr + DCR14);	/* Clear reset port */
+	outl(0, db->ioaddr + DCR13);	/* Clear CR13 */
+	/* Select ID Table access port */
+	outl(0x1b0, db->ioaddr + DCR13);
+	/* Read MAC address from CR14 */
+	for (i = 0; i < 3; i++) {
+		addr = dev->enetaddr[2 * i] | (dev->enetaddr[2 * i + 1] << 8);
+		outl(addr, db->ioaddr + DCR14);
+	}
+	/* write end */
+	outl(0, db->ioaddr + DCR13);	/* Clear CR13 */
+	outl(0, db->ioaddr + DCR0);	/* Clear CR0 */
+	udelay(10);
+	return;
+}
diff --git a/marvell/uboot/drivers/net/vsc7385.c b/marvell/uboot/drivers/net/vsc7385.c
new file mode 100644
index 0000000..a5110e5
--- /dev/null
+++ b/marvell/uboot/drivers/net/vsc7385.c
@@ -0,0 +1,97 @@
+/*
+ * Vitesse 7385 Switch Firmware Upload
+ *
+ * Author: Timur Tabi <timur@freescale.com>
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc.  This file is licensed
+ * under the terms of the GNU General Public License version 2.  This
+ * program is licensed "as is" without any warranty of any kind, whether
+ * express or implied.
+ *
+ * This module uploads proprietary firmware for the Vitesse VSC7385 5-port
+ * switch.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include "vsc7385.h"
+
+/*
+ * Upload a Vitesse VSC7385 firmware image to the hardware
+ *
+ * This function takes a pointer to a VSC7385 firmware image and a size, and
+ * uploads that firmware to the VSC7385.
+ *
+ * This firmware is typically located at a board-specific flash address,
+ * and the size is typically 8KB.
+ *
+ * The firmware is Vitesse proprietary.
+ *
+ * Further details on the register information can be obtained from Vitesse.
+ */
+int vsc7385_upload_firmware(void *firmware, unsigned int size)
+{
+	u8 *fw = firmware;
+	unsigned int i;
+
+	u32 *gloreset = (u32 *) (CONFIG_SYS_VSC7385_BASE + 0x1c050);
+	u32 *icpu_ctrl = (u32 *) (CONFIG_SYS_VSC7385_BASE + 0x1c040);
+	u32 *icpu_addr = (u32 *) (CONFIG_SYS_VSC7385_BASE + 0x1c044);
+	u32 *icpu_data = (u32 *) (CONFIG_SYS_VSC7385_BASE + 0x1c048);
+	u32 *icpu_rom_map = (u32 *) (CONFIG_SYS_VSC7385_BASE + 0x1c070);
+#ifdef DEBUG
+	u32 *chipid = (u32 *) (CONFIG_SYS_VSC7385_BASE + 0x1c060);
+#endif
+
+	out_be32(gloreset, 3);
+	udelay(200);
+
+	out_be32(icpu_ctrl, 0x8E);
+	udelay(20);
+
+	out_be32(icpu_rom_map, 1);
+	udelay(20);
+
+	/* Write the firmware to I-RAM */
+	out_be32(icpu_addr, 0);
+	udelay(20);
+
+	for (i = 0; i < size; i++) {
+		out_be32(icpu_data, fw[i]);
+		udelay(20);
+		if (ctrlc())
+			return -EINTR;
+	}
+
+	/* Read back and compare */
+	out_be32(icpu_addr, 0);
+	udelay(20);
+
+	for (i = 0; i < size; i++) {
+		u8 value;
+
+		value = (u8) in_be32(icpu_data);
+		udelay(20);
+		if (value != fw[i]) {
+			debug("VSC7385: Upload mismatch: address 0x%x, "
+			      "read value 0x%x, image value 0x%x\n",
+			      i, value, fw[i]);
+
+			return -EIO;
+		}
+		if (ctrlc())
+			break;
+	}
+
+	out_be32(icpu_ctrl, 0x0B);
+	udelay(20);
+
+#ifdef DEBUG
+	printf("VSC7385: Chip ID is %08x\n", in_be32(chipid));
+	udelay(20);
+#endif
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/xilinx_axi_emac.c b/marvell/uboot/drivers/net/xilinx_axi_emac.c
new file mode 100644
index 0000000..bb5044b
--- /dev/null
+++ b/marvell/uboot/drivers/net/xilinx_axi_emac.c
@@ -0,0 +1,652 @@
+/*
+ * Copyright (C) 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2011 PetaLogix
+ * Copyright (C) 2010 Xilinx, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <net.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <phy.h>
+#include <miiphy.h>
+
+#if !defined(CONFIG_PHYLIB)
+# error AXI_ETHERNET requires PHYLIB
+#endif
+
+/* Link setup */
+#define XAE_EMMC_LINKSPEED_MASK	0xC0000000 /* Link speed */
+#define XAE_EMMC_LINKSPD_10	0x00000000 /* Link Speed mask for 10 Mbit */
+#define XAE_EMMC_LINKSPD_100	0x40000000 /* Link Speed mask for 100 Mbit */
+#define XAE_EMMC_LINKSPD_1000	0x80000000 /* Link Speed mask for 1000 Mbit */
+
+/* Interrupt Status/Enable/Mask Registers bit definitions */
+#define XAE_INT_RXRJECT_MASK	0x00000008 /* Rx frame rejected */
+#define XAE_INT_MGTRDY_MASK	0x00000080 /* MGT clock Lock */
+
+/* Receive Configuration Word 1 (RCW1) Register bit definitions */
+#define XAE_RCW1_RX_MASK	0x10000000 /* Receiver enable */
+
+/* Transmitter Configuration (TC) Register bit definitions */
+#define XAE_TC_TX_MASK		0x10000000 /* Transmitter enable */
+
+#define XAE_UAW1_UNICASTADDR_MASK	0x0000FFFF
+
+/* MDIO Management Configuration (MC) Register bit definitions */
+#define XAE_MDIO_MC_MDIOEN_MASK		0x00000040 /* MII management enable*/
+
+/* MDIO Management Control Register (MCR) Register bit definitions */
+#define XAE_MDIO_MCR_PHYAD_MASK		0x1F000000 /* Phy Address Mask */
+#define XAE_MDIO_MCR_PHYAD_SHIFT	24	   /* Phy Address Shift */
+#define XAE_MDIO_MCR_REGAD_MASK		0x001F0000 /* Reg Address Mask */
+#define XAE_MDIO_MCR_REGAD_SHIFT	16	   /* Reg Address Shift */
+#define XAE_MDIO_MCR_OP_READ_MASK	0x00008000 /* Op Code Read Mask */
+#define XAE_MDIO_MCR_OP_WRITE_MASK	0x00004000 /* Op Code Write Mask */
+#define XAE_MDIO_MCR_INITIATE_MASK	0x00000800 /* Ready Mask */
+#define XAE_MDIO_MCR_READY_MASK		0x00000080 /* Ready Mask */
+
+#define XAE_MDIO_DIV_DFT	29	/* Default MDIO clock divisor */
+
+/* DMA macros */
+/* Bitmasks of XAXIDMA_CR_OFFSET register */
+#define XAXIDMA_CR_RUNSTOP_MASK	0x00000001 /* Start/stop DMA channel */
+#define XAXIDMA_CR_RESET_MASK	0x00000004 /* Reset DMA engine */
+
+/* Bitmasks of XAXIDMA_SR_OFFSET register */
+#define XAXIDMA_HALTED_MASK	0x00000001  /* DMA channel halted */
+
+/* Bitmask for interrupts */
+#define XAXIDMA_IRQ_IOC_MASK	0x00001000 /* Completion intr */
+#define XAXIDMA_IRQ_DELAY_MASK	0x00002000 /* Delay interrupt */
+#define XAXIDMA_IRQ_ALL_MASK	0x00007000 /* All interrupts */
+
+/* Bitmasks of XAXIDMA_BD_CTRL_OFFSET register */
+#define XAXIDMA_BD_CTRL_TXSOF_MASK	0x08000000 /* First tx packet */
+#define XAXIDMA_BD_CTRL_TXEOF_MASK	0x04000000 /* Last tx packet */
+
+#define DMAALIGN	128
+
+static u8 rxframe[PKTSIZE_ALIGN] __attribute((aligned(DMAALIGN)));
+
+/* Reflect dma offsets */
+struct axidma_reg {
+	u32 control; /* DMACR */
+	u32 status; /* DMASR */
+	u32 current; /* CURDESC */
+	u32 reserved;
+	u32 tail; /* TAILDESC */
+};
+
+/* Private driver structures */
+struct axidma_priv {
+	struct axidma_reg *dmatx;
+	struct axidma_reg *dmarx;
+	int phyaddr;
+
+	struct phy_device *phydev;
+	struct mii_dev *bus;
+};
+
+/* BD descriptors */
+struct axidma_bd {
+	u32 next;	/* Next descriptor pointer */
+	u32 reserved1;
+	u32 phys;	/* Buffer address */
+	u32 reserved2;
+	u32 reserved3;
+	u32 reserved4;
+	u32 cntrl;	/* Control */
+	u32 status;	/* Status */
+	u32 app0;
+	u32 app1;	/* TX start << 16 | insert */
+	u32 app2;	/* TX csum seed */
+	u32 app3;
+	u32 app4;
+	u32 sw_id_offset;
+	u32 reserved5;
+	u32 reserved6;
+};
+
+/* Static BDs - driver uses only one BD */
+static struct axidma_bd tx_bd __attribute((aligned(DMAALIGN)));
+static struct axidma_bd rx_bd __attribute((aligned(DMAALIGN)));
+
+struct axi_regs {
+	u32 reserved[3];
+	u32 is; /* 0xC: Interrupt status */
+	u32 reserved2;
+	u32 ie; /* 0x14: Interrupt enable */
+	u32 reserved3[251];
+	u32 rcw1; /* 0x404: Rx Configuration Word 1 */
+	u32 tc; /* 0x408: Tx Configuration */
+	u32 reserved4;
+	u32 emmc; /* 0x410: EMAC mode configuration */
+	u32 reserved5[59];
+	u32 mdio_mc; /* 0x500: MII Management Config */
+	u32 mdio_mcr; /* 0x504: MII Management Control */
+	u32 mdio_mwd; /* 0x508: MII Management Write Data */
+	u32 mdio_mrd; /* 0x50C: MII Management Read Data */
+	u32 reserved6[124];
+	u32 uaw0; /* 0x700: Unicast address word 0 */
+	u32 uaw1; /* 0x704: Unicast address word 1 */
+};
+
+/* Use MII register 1 (MII status register) to detect PHY */
+#define PHY_DETECT_REG  1
+
+/*
+ * Mask used to verify certain PHY features (or register contents)
+ * in the register above:
+ *  0x1000: 10Mbps full duplex support
+ *  0x0800: 10Mbps half duplex support
+ *  0x0008: Auto-negotiation support
+ */
+#define PHY_DETECT_MASK 0x1808
+
+static inline int mdio_wait(struct eth_device *dev)
+{
+	struct axi_regs *regs = (struct axi_regs *)dev->iobase;
+	u32 timeout = 200;
+
+	/* Wait till MDIO interface is ready to accept a new transaction. */
+	while (timeout && (!(in_be32(&regs->mdio_mcr)
+						& XAE_MDIO_MCR_READY_MASK))) {
+		timeout--;
+		udelay(1);
+	}
+	if (!timeout) {
+		printf("%s: Timeout\n", __func__);
+		return 1;
+	}
+	return 0;
+}
+
+static u32 phyread(struct eth_device *dev, u32 phyaddress, u32 registernum,
+								u16 *val)
+{
+	struct axi_regs *regs = (struct axi_regs *)dev->iobase;
+	u32 mdioctrlreg = 0;
+
+	if (mdio_wait(dev))
+		return 1;
+
+	mdioctrlreg = ((phyaddress << XAE_MDIO_MCR_PHYAD_SHIFT) &
+			XAE_MDIO_MCR_PHYAD_MASK) |
+			((registernum << XAE_MDIO_MCR_REGAD_SHIFT)
+			& XAE_MDIO_MCR_REGAD_MASK) |
+			XAE_MDIO_MCR_INITIATE_MASK |
+			XAE_MDIO_MCR_OP_READ_MASK;
+
+	out_be32(&regs->mdio_mcr, mdioctrlreg);
+
+	if (mdio_wait(dev))
+		return 1;
+
+	/* Read data */
+	*val = in_be32(&regs->mdio_mrd);
+	return 0;
+}
+
+static u32 phywrite(struct eth_device *dev, u32 phyaddress, u32 registernum,
+								u32 data)
+{
+	struct axi_regs *regs = (struct axi_regs *)dev->iobase;
+	u32 mdioctrlreg = 0;
+
+	if (mdio_wait(dev))
+		return 1;
+
+	mdioctrlreg = ((phyaddress << XAE_MDIO_MCR_PHYAD_SHIFT) &
+			XAE_MDIO_MCR_PHYAD_MASK) |
+			((registernum << XAE_MDIO_MCR_REGAD_SHIFT)
+			& XAE_MDIO_MCR_REGAD_MASK) |
+			XAE_MDIO_MCR_INITIATE_MASK |
+			XAE_MDIO_MCR_OP_WRITE_MASK;
+
+	/* Write data */
+	out_be32(&regs->mdio_mwd, data);
+
+	out_be32(&regs->mdio_mcr, mdioctrlreg);
+
+	if (mdio_wait(dev))
+		return 1;
+
+	return 0;
+}
+
+/* Setting axi emac and phy to proper setting */
+static int setup_phy(struct eth_device *dev)
+{
+	u16 phyreg;
+	u32 i, speed, emmc_reg, ret;
+	struct axidma_priv *priv = dev->priv;
+	struct axi_regs *regs = (struct axi_regs *)dev->iobase;
+	struct phy_device *phydev;
+
+	u32 supported = SUPPORTED_10baseT_Half |
+			SUPPORTED_10baseT_Full |
+			SUPPORTED_100baseT_Half |
+			SUPPORTED_100baseT_Full |
+			SUPPORTED_1000baseT_Half |
+			SUPPORTED_1000baseT_Full;
+
+	if (priv->phyaddr == -1) {
+		/* Detect the PHY address */
+		for (i = 31; i >= 0; i--) {
+			ret = phyread(dev, i, PHY_DETECT_REG, &phyreg);
+			if (!ret && (phyreg != 0xFFFF) &&
+			((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
+				/* Found a valid PHY address */
+				priv->phyaddr = i;
+				debug("axiemac: Found valid phy address, %x\n",
+									phyreg);
+				break;
+			}
+		}
+	}
+
+	/* Interface - look at tsec */
+	phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0);
+
+	phydev->supported &= supported;
+	phydev->advertising = phydev->supported;
+	priv->phydev = phydev;
+	phy_config(phydev);
+	if (phy_startup(phydev)) {
+		printf("axiemac: could not initialize PHY %s\n",
+		       phydev->dev->name);
+		return 0;
+	}
+
+	switch (phydev->speed) {
+	case 1000:
+		speed = XAE_EMMC_LINKSPD_1000;
+		break;
+	case 100:
+		speed = XAE_EMMC_LINKSPD_100;
+		break;
+	case 10:
+		speed = XAE_EMMC_LINKSPD_10;
+		break;
+	default:
+		return 0;
+	}
+
+	/* Setup the emac for the phy speed */
+	emmc_reg = in_be32(&regs->emmc);
+	emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK;
+	emmc_reg |= speed;
+
+	/* Write new speed setting out to Axi Ethernet */
+	out_be32(&regs->emmc, emmc_reg);
+
+	/*
+	* Setting the operating speed of the MAC needs a delay. There
+	* doesn't seem to be register to poll, so please consider this
+	* during your application design.
+	*/
+	udelay(1);
+
+	return 1;
+}
+
+/* STOP DMA transfers */
+static void axiemac_halt(struct eth_device *dev)
+{
+	struct axidma_priv *priv = dev->priv;
+	u32 temp;
+
+	/* Stop the hardware */
+	temp = in_be32(&priv->dmatx->control);
+	temp &= ~XAXIDMA_CR_RUNSTOP_MASK;
+	out_be32(&priv->dmatx->control, temp);
+
+	temp = in_be32(&priv->dmarx->control);
+	temp &= ~XAXIDMA_CR_RUNSTOP_MASK;
+	out_be32(&priv->dmarx->control, temp);
+
+	debug("axiemac: Halted\n");
+}
+
+static int axi_ethernet_init(struct eth_device *dev)
+{
+	struct axi_regs *regs = (struct axi_regs *)dev->iobase;
+	u32 timeout = 200;
+
+	/*
+	 * Check the status of the MgtRdy bit in the interrupt status
+	 * registers. This must be done to allow the MGT clock to become stable
+	 * for the Sgmii and 1000BaseX PHY interfaces. No other register reads
+	 * will be valid until this bit is valid.
+	 * The bit is always a 1 for all other PHY interfaces.
+	 */
+	while (timeout && (!(in_be32(&regs->is) & XAE_INT_MGTRDY_MASK))) {
+		timeout--;
+		udelay(1);
+	}
+	if (!timeout) {
+		printf("%s: Timeout\n", __func__);
+		return 1;
+	}
+
+	/* Stop the device and reset HW */
+	/* Disable interrupts */
+	out_be32(&regs->ie, 0);
+
+	/* Disable the receiver */
+	out_be32(&regs->rcw1, in_be32(&regs->rcw1) & ~XAE_RCW1_RX_MASK);
+
+	/*
+	 * Stopping the receiver in mid-packet causes a dropped packet
+	 * indication from HW. Clear it.
+	 */
+	/* Set the interrupt status register to clear the interrupt */
+	out_be32(&regs->is, XAE_INT_RXRJECT_MASK);
+
+	/* Setup HW */
+	/* Set default MDIO divisor */
+	out_be32(&regs->mdio_mc, XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK);
+
+	debug("axiemac: InitHw done\n");
+	return 0;
+}
+
+static int axiemac_setup_mac(struct eth_device *dev)
+{
+	struct axi_regs *regs = (struct axi_regs *)dev->iobase;
+
+	/* Set the MAC address */
+	int val = ((dev->enetaddr[3] << 24) | (dev->enetaddr[2] << 16) |
+		(dev->enetaddr[1] << 8) | (dev->enetaddr[0]));
+	out_be32(&regs->uaw0, val);
+
+	val = (dev->enetaddr[5] << 8) | dev->enetaddr[4] ;
+	val |= in_be32(&regs->uaw1) & ~XAE_UAW1_UNICASTADDR_MASK;
+	out_be32(&regs->uaw1, val);
+	return 0;
+}
+
+/* Reset DMA engine */
+static void axi_dma_init(struct eth_device *dev)
+{
+	struct axidma_priv *priv = dev->priv;
+	u32 timeout = 500;
+
+	/* Reset the engine so the hardware starts from a known state */
+	out_be32(&priv->dmatx->control, XAXIDMA_CR_RESET_MASK);
+	out_be32(&priv->dmarx->control, XAXIDMA_CR_RESET_MASK);
+
+	/* At the initialization time, hardware should finish reset quickly */
+	while (timeout--) {
+		/* Check transmit/receive channel */
+		/* Reset is done when the reset bit is low */
+		if (!(in_be32(&priv->dmatx->control) |
+				in_be32(&priv->dmarx->control))
+						& XAXIDMA_CR_RESET_MASK) {
+			break;
+		}
+	}
+	if (!timeout)
+		printf("%s: Timeout\n", __func__);
+}
+
+static int axiemac_init(struct eth_device *dev, bd_t * bis)
+{
+	struct axidma_priv *priv = dev->priv;
+	struct axi_regs *regs = (struct axi_regs *)dev->iobase;
+	u32 temp;
+
+	debug("axiemac: Init started\n");
+	/*
+	 * Initialize AXIDMA engine. AXIDMA engine must be initialized before
+	 * AxiEthernet. During AXIDMA engine initialization, AXIDMA hardware is
+	 * reset, and since AXIDMA reset line is connected to AxiEthernet, this
+	 * would ensure a reset of AxiEthernet.
+	 */
+	axi_dma_init(dev);
+
+	/* Initialize AxiEthernet hardware. */
+	if (axi_ethernet_init(dev))
+		return -1;
+
+	/* Disable all RX interrupts before RxBD space setup */
+	temp = in_be32(&priv->dmarx->control);
+	temp &= ~XAXIDMA_IRQ_ALL_MASK;
+	out_be32(&priv->dmarx->control, temp);
+
+	/* Start DMA RX channel. Now it's ready to receive data.*/
+	out_be32(&priv->dmarx->current, (u32)&rx_bd);
+
+	/* Setup the BD. */
+	memset(&rx_bd, 0, sizeof(rx_bd));
+	rx_bd.next = (u32)&rx_bd;
+	rx_bd.phys = (u32)&rxframe;
+	rx_bd.cntrl = sizeof(rxframe);
+	/* Flush the last BD so DMA core could see the updates */
+	flush_cache((u32)&rx_bd, sizeof(rx_bd));
+
+	/* It is necessary to flush rxframe because if you don't do it
+	 * then cache can contain uninitialized data */
+	flush_cache((u32)&rxframe, sizeof(rxframe));
+
+	/* Start the hardware */
+	temp = in_be32(&priv->dmarx->control);
+	temp |= XAXIDMA_CR_RUNSTOP_MASK;
+	out_be32(&priv->dmarx->control, temp);
+
+	/* Rx BD is ready - start */
+	out_be32(&priv->dmarx->tail, (u32)&rx_bd);
+
+	/* Enable TX */
+	out_be32(&regs->tc, XAE_TC_TX_MASK);
+	/* Enable RX */
+	out_be32(&regs->rcw1, XAE_RCW1_RX_MASK);
+
+	/* PHY setup */
+	if (!setup_phy(dev)) {
+		axiemac_halt(dev);
+		return -1;
+	}
+
+	debug("axiemac: Init complete\n");
+	return 0;
+}
+
+static int axiemac_send(struct eth_device *dev, void *ptr, int len)
+{
+	struct axidma_priv *priv = dev->priv;
+	u32 timeout;
+
+	if (len > PKTSIZE_ALIGN)
+		len = PKTSIZE_ALIGN;
+
+	/* Flush packet to main memory to be trasfered by DMA */
+	flush_cache((u32)ptr, len);
+
+	/* Setup Tx BD */
+	memset(&tx_bd, 0, sizeof(tx_bd));
+	/* At the end of the ring, link the last BD back to the top */
+	tx_bd.next = (u32)&tx_bd;
+	tx_bd.phys = (u32)ptr;
+	/* Save len */
+	tx_bd.cntrl = len | XAXIDMA_BD_CTRL_TXSOF_MASK |
+						XAXIDMA_BD_CTRL_TXEOF_MASK;
+
+	/* Flush the last BD so DMA core could see the updates */
+	flush_cache((u32)&tx_bd, sizeof(tx_bd));
+
+	if (in_be32(&priv->dmatx->status) & XAXIDMA_HALTED_MASK) {
+		u32 temp;
+		out_be32(&priv->dmatx->current, (u32)&tx_bd);
+		/* Start the hardware */
+		temp = in_be32(&priv->dmatx->control);
+		temp |= XAXIDMA_CR_RUNSTOP_MASK;
+		out_be32(&priv->dmatx->control, temp);
+	}
+
+	/* Start transfer */
+	out_be32(&priv->dmatx->tail, (u32)&tx_bd);
+
+	/* Wait for transmission to complete */
+	debug("axiemac: Waiting for tx to be done\n");
+	timeout = 200;
+	while (timeout && (!in_be32(&priv->dmatx->status) &
+			(XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK))) {
+		timeout--;
+		udelay(1);
+	}
+	if (!timeout) {
+		printf("%s: Timeout\n", __func__);
+		return 1;
+	}
+
+	debug("axiemac: Sending complete\n");
+	return 0;
+}
+
+static int isrxready(struct eth_device *dev)
+{
+	u32 status;
+	struct axidma_priv *priv = dev->priv;
+
+	/* Read pending interrupts */
+	status = in_be32(&priv->dmarx->status);
+
+	/* Acknowledge pending interrupts */
+	out_be32(&priv->dmarx->status, status & XAXIDMA_IRQ_ALL_MASK);
+
+	/*
+	 * If Reception done interrupt is asserted, call RX call back function
+	 * to handle the processed BDs and then raise the according flag.
+	 */
+	if ((status & (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK)))
+		return 1;
+
+	return 0;
+}
+
+static int axiemac_recv(struct eth_device *dev)
+{
+	u32 length;
+	struct axidma_priv *priv = dev->priv;
+	u32 temp;
+
+	/* Wait for an incoming packet */
+	if (!isrxready(dev))
+		return 0;
+
+	debug("axiemac: RX data ready\n");
+
+	/* Disable IRQ for a moment till packet is handled */
+	temp = in_be32(&priv->dmarx->control);
+	temp &= ~XAXIDMA_IRQ_ALL_MASK;
+	out_be32(&priv->dmarx->control, temp);
+
+	length = rx_bd.app4 & 0xFFFF; /* max length mask */
+#ifdef DEBUG
+	print_buffer(&rxframe, &rxframe[0], 1, length, 16);
+#endif
+	/* Pass the received frame up for processing */
+	if (length)
+		NetReceive(rxframe, length);
+
+#ifdef DEBUG
+	/* It is useful to clear buffer to be sure that it is consistent */
+	memset(rxframe, 0, sizeof(rxframe));
+#endif
+	/* Setup RxBD */
+	/* Clear the whole buffer and setup it again - all flags are cleared */
+	memset(&rx_bd, 0, sizeof(rx_bd));
+	rx_bd.next = (u32)&rx_bd;
+	rx_bd.phys = (u32)&rxframe;
+	rx_bd.cntrl = sizeof(rxframe);
+
+	/* Write bd to HW */
+	flush_cache((u32)&rx_bd, sizeof(rx_bd));
+
+	/* It is necessary to flush rxframe because if you don't do it
+	 * then cache will contain previous packet */
+	flush_cache((u32)&rxframe, sizeof(rxframe));
+
+	/* Rx BD is ready - start again */
+	out_be32(&priv->dmarx->tail, (u32)&rx_bd);
+
+	debug("axiemac: RX completed, framelength = %d\n", length);
+
+	return length;
+}
+
+static int axiemac_miiphy_read(const char *devname, uchar addr,
+							uchar reg, ushort *val)
+{
+	struct eth_device *dev = eth_get_dev();
+	u32 ret;
+
+	ret = phyread(dev, addr, reg, val);
+	debug("axiemac: Read MII 0x%x, 0x%x, 0x%x\n", addr, reg, *val);
+	return ret;
+}
+
+static int axiemac_miiphy_write(const char *devname, uchar addr,
+							uchar reg, ushort val)
+{
+	struct eth_device *dev = eth_get_dev();
+
+	debug("axiemac: Write MII 0x%x, 0x%x, 0x%x\n", addr, reg, val);
+	return phywrite(dev, addr, reg, val);
+}
+
+static int axiemac_bus_reset(struct mii_dev *bus)
+{
+	debug("axiemac: Bus reset\n");
+	return 0;
+}
+
+int xilinx_axiemac_initialize(bd_t *bis, unsigned long base_addr,
+							unsigned long dma_addr)
+{
+	struct eth_device *dev;
+	struct axidma_priv *priv;
+
+	dev = calloc(1, sizeof(struct eth_device));
+	if (dev == NULL)
+		return -1;
+
+	dev->priv = calloc(1, sizeof(struct axidma_priv));
+	if (dev->priv == NULL) {
+		free(dev);
+		return -1;
+	}
+	priv = dev->priv;
+
+	sprintf(dev->name, "aximac.%lx", base_addr);
+
+	dev->iobase = base_addr;
+	priv->dmatx = (struct axidma_reg *)dma_addr;
+	/* RX channel offset is 0x30 */
+	priv->dmarx = (struct axidma_reg *)(dma_addr + 0x30);
+	dev->init = axiemac_init;
+	dev->halt = axiemac_halt;
+	dev->send = axiemac_send;
+	dev->recv = axiemac_recv;
+	dev->write_hwaddr = axiemac_setup_mac;
+
+#ifdef CONFIG_PHY_ADDR
+	priv->phyaddr = CONFIG_PHY_ADDR;
+#else
+	priv->phyaddr = -1;
+#endif
+
+	eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
+	miiphy_register(dev->name, axiemac_miiphy_read, axiemac_miiphy_write);
+	priv->bus = miiphy_get_dev_by_name(dev->name);
+	priv->bus->reset = axiemac_bus_reset;
+#endif
+	return 1;
+}
diff --git a/marvell/uboot/drivers/net/xilinx_emaclite.c b/marvell/uboot/drivers/net/xilinx_emaclite.c
new file mode 100644
index 0000000..0a5209d
--- /dev/null
+++ b/marvell/uboot/drivers/net/xilinx_emaclite.c
@@ -0,0 +1,391 @@
+/*
+ * (C) Copyright 2007-2009 Michal Simek
+ * (C) Copyright 2003 Xilinx Inc.
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <net.h>
+#include <config.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <fdtdec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#undef DEBUG
+
+#define ENET_ADDR_LENGTH	6
+
+/* EmacLite constants */
+#define XEL_BUFFER_OFFSET	0x0800	/* Next buffer's offset */
+#define XEL_TPLR_OFFSET		0x07F4	/* Tx packet length */
+#define XEL_TSR_OFFSET		0x07FC	/* Tx status */
+#define XEL_RSR_OFFSET		0x17FC	/* Rx status */
+#define XEL_RXBUFF_OFFSET	0x1000	/* Receive Buffer */
+
+/* Xmit complete */
+#define XEL_TSR_XMIT_BUSY_MASK		0x00000001UL
+/* Xmit interrupt enable bit */
+#define XEL_TSR_XMIT_IE_MASK		0x00000008UL
+/* Buffer is active, SW bit only */
+#define XEL_TSR_XMIT_ACTIVE_MASK	0x80000000UL
+/* Program the MAC address */
+#define XEL_TSR_PROGRAM_MASK		0x00000002UL
+/* define for programming the MAC address into the EMAC Lite */
+#define XEL_TSR_PROG_MAC_ADDR	(XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK)
+
+/* Transmit packet length upper byte */
+#define XEL_TPLR_LENGTH_MASK_HI		0x0000FF00UL
+/* Transmit packet length lower byte */
+#define XEL_TPLR_LENGTH_MASK_LO		0x000000FFUL
+
+/* Recv complete */
+#define XEL_RSR_RECV_DONE_MASK		0x00000001UL
+/* Recv interrupt enable bit */
+#define XEL_RSR_RECV_IE_MASK		0x00000008UL
+
+struct xemaclite {
+	u32 nexttxbuffertouse;	/* Next TX buffer to write to */
+	u32 nextrxbuffertouse;	/* Next RX buffer to read from */
+	u32 txpp;		/* TX ping pong buffer */
+	u32 rxpp;		/* RX ping pong buffer */
+};
+
+static u32 etherrxbuff[PKTSIZE_ALIGN/4]; /* Receive buffer */
+
+static void xemaclite_alignedread(u32 *srcptr, void *destptr, u32 bytecount)
+{
+	u32 i;
+	u32 alignbuffer;
+	u32 *to32ptr;
+	u32 *from32ptr;
+	u8 *to8ptr;
+	u8 *from8ptr;
+
+	from32ptr = (u32 *) srcptr;
+
+	/* Word aligned buffer, no correction needed. */
+	to32ptr = (u32 *) destptr;
+	while (bytecount > 3) {
+		*to32ptr++ = *from32ptr++;
+		bytecount -= 4;
+	}
+	to8ptr = (u8 *) to32ptr;
+
+	alignbuffer = *from32ptr++;
+	from8ptr = (u8 *) &alignbuffer;
+
+	for (i = 0; i < bytecount; i++)
+		*to8ptr++ = *from8ptr++;
+}
+
+static void xemaclite_alignedwrite(void *srcptr, u32 destptr, u32 bytecount)
+{
+	u32 i;
+	u32 alignbuffer;
+	u32 *to32ptr = (u32 *) destptr;
+	u32 *from32ptr;
+	u8 *to8ptr;
+	u8 *from8ptr;
+
+	from32ptr = (u32 *) srcptr;
+	while (bytecount > 3) {
+
+		*to32ptr++ = *from32ptr++;
+		bytecount -= 4;
+	}
+
+	alignbuffer = 0;
+	to8ptr = (u8 *) &alignbuffer;
+	from8ptr = (u8 *) from32ptr;
+
+	for (i = 0; i < bytecount; i++)
+		*to8ptr++ = *from8ptr++;
+
+	*to32ptr++ = alignbuffer;
+}
+
+static void emaclite_halt(struct eth_device *dev)
+{
+	debug("eth_halt\n");
+}
+
+static int emaclite_init(struct eth_device *dev, bd_t *bis)
+{
+	struct xemaclite *emaclite = dev->priv;
+	debug("EmacLite Initialization Started\n");
+
+/*
+ * TX - TX_PING & TX_PONG initialization
+ */
+	/* Restart PING TX */
+	out_be32 (dev->iobase + XEL_TSR_OFFSET, 0);
+	/* Copy MAC address */
+	xemaclite_alignedwrite(dev->enetaddr, dev->iobase, ENET_ADDR_LENGTH);
+	/* Set the length */
+	out_be32 (dev->iobase + XEL_TPLR_OFFSET, ENET_ADDR_LENGTH);
+	/* Update the MAC address in the EMAC Lite */
+	out_be32 (dev->iobase + XEL_TSR_OFFSET, XEL_TSR_PROG_MAC_ADDR);
+	/* Wait for EMAC Lite to finish with the MAC address update */
+	while ((in_be32 (dev->iobase + XEL_TSR_OFFSET) &
+		XEL_TSR_PROG_MAC_ADDR) != 0)
+		;
+
+	if (emaclite->txpp) {
+		/* The same operation with PONG TX */
+		out_be32 (dev->iobase + XEL_TSR_OFFSET + XEL_BUFFER_OFFSET, 0);
+		xemaclite_alignedwrite(dev->enetaddr, dev->iobase +
+			XEL_BUFFER_OFFSET, ENET_ADDR_LENGTH);
+		out_be32 (dev->iobase + XEL_TPLR_OFFSET, ENET_ADDR_LENGTH);
+		out_be32 (dev->iobase + XEL_TSR_OFFSET + XEL_BUFFER_OFFSET,
+			XEL_TSR_PROG_MAC_ADDR);
+		while ((in_be32 (dev->iobase + XEL_TSR_OFFSET +
+			XEL_BUFFER_OFFSET) & XEL_TSR_PROG_MAC_ADDR) != 0)
+			;
+	}
+
+/*
+ * RX - RX_PING & RX_PONG initialization
+ */
+	/* Write out the value to flush the RX buffer */
+	out_be32 (dev->iobase + XEL_RSR_OFFSET, XEL_RSR_RECV_IE_MASK);
+
+	if (emaclite->rxpp)
+		out_be32 (dev->iobase + XEL_RSR_OFFSET + XEL_BUFFER_OFFSET,
+			XEL_RSR_RECV_IE_MASK);
+
+	debug("EmacLite Initialization complete\n");
+	return 0;
+}
+
+static int xemaclite_txbufferavailable(struct eth_device *dev)
+{
+	u32 reg;
+	u32 txpingbusy;
+	u32 txpongbusy;
+	struct xemaclite *emaclite = dev->priv;
+
+	/*
+	 * Read the other buffer register
+	 * and determine if the other buffer is available
+	 */
+	reg = in_be32 (dev->iobase +
+			emaclite->nexttxbuffertouse + 0);
+	txpingbusy = ((reg & XEL_TSR_XMIT_BUSY_MASK) ==
+			XEL_TSR_XMIT_BUSY_MASK);
+
+	reg = in_be32 (dev->iobase +
+			(emaclite->nexttxbuffertouse ^ XEL_TSR_OFFSET) + 0);
+	txpongbusy = ((reg & XEL_TSR_XMIT_BUSY_MASK) ==
+			XEL_TSR_XMIT_BUSY_MASK);
+
+	return !(txpingbusy && txpongbusy);
+}
+
+static int emaclite_send(struct eth_device *dev, void *ptr, int len)
+{
+	u32 reg;
+	u32 baseaddress;
+	struct xemaclite *emaclite = dev->priv;
+
+	u32 maxtry = 1000;
+
+	if (len > PKTSIZE)
+		len = PKTSIZE;
+
+	while (!xemaclite_txbufferavailable(dev) && maxtry) {
+		udelay(10);
+		maxtry--;
+	}
+
+	if (!maxtry) {
+		printf("Error: Timeout waiting for ethernet TX buffer\n");
+		/* Restart PING TX */
+		out_be32 (dev->iobase + XEL_TSR_OFFSET, 0);
+		if (emaclite->txpp) {
+			out_be32 (dev->iobase + XEL_TSR_OFFSET +
+				XEL_BUFFER_OFFSET, 0);
+		}
+		return -1;
+	}
+
+	/* Determine the expected TX buffer address */
+	baseaddress = (dev->iobase + emaclite->nexttxbuffertouse);
+
+	/* Determine if the expected buffer address is empty */
+	reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
+	if (((reg & XEL_TSR_XMIT_BUSY_MASK) == 0)
+		&& ((in_be32 ((baseaddress) + XEL_TSR_OFFSET)
+			& XEL_TSR_XMIT_ACTIVE_MASK) == 0)) {
+
+		if (emaclite->txpp)
+			emaclite->nexttxbuffertouse ^= XEL_BUFFER_OFFSET;
+
+		debug("Send packet from 0x%x\n", baseaddress);
+		/* Write the frame to the buffer */
+		xemaclite_alignedwrite(ptr, baseaddress, len);
+		out_be32 (baseaddress + XEL_TPLR_OFFSET,(len &
+			(XEL_TPLR_LENGTH_MASK_HI | XEL_TPLR_LENGTH_MASK_LO)));
+		reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
+		reg |= XEL_TSR_XMIT_BUSY_MASK;
+		if ((reg & XEL_TSR_XMIT_IE_MASK) != 0)
+			reg |= XEL_TSR_XMIT_ACTIVE_MASK;
+		out_be32 (baseaddress + XEL_TSR_OFFSET, reg);
+		return 0;
+	}
+
+	if (emaclite->txpp) {
+		/* Switch to second buffer */
+		baseaddress ^= XEL_BUFFER_OFFSET;
+		/* Determine if the expected buffer address is empty */
+		reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
+		if (((reg & XEL_TSR_XMIT_BUSY_MASK) == 0)
+			&& ((in_be32 ((baseaddress) + XEL_TSR_OFFSET)
+				& XEL_TSR_XMIT_ACTIVE_MASK) == 0)) {
+			debug("Send packet from 0x%x\n", baseaddress);
+			/* Write the frame to the buffer */
+			xemaclite_alignedwrite(ptr, baseaddress, len);
+			out_be32 (baseaddress + XEL_TPLR_OFFSET, (len &
+				(XEL_TPLR_LENGTH_MASK_HI |
+					XEL_TPLR_LENGTH_MASK_LO)));
+			reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
+			reg |= XEL_TSR_XMIT_BUSY_MASK;
+			if ((reg & XEL_TSR_XMIT_IE_MASK) != 0)
+				reg |= XEL_TSR_XMIT_ACTIVE_MASK;
+			out_be32 (baseaddress + XEL_TSR_OFFSET, reg);
+			return 0;
+		}
+	}
+
+	puts("Error while sending frame\n");
+	return -1;
+}
+
+static int emaclite_recv(struct eth_device *dev)
+{
+	u32 length;
+	u32 reg;
+	u32 baseaddress;
+	struct xemaclite *emaclite = dev->priv;
+
+	baseaddress = dev->iobase + emaclite->nextrxbuffertouse;
+	reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
+	debug("Testing data at address 0x%x\n", baseaddress);
+	if ((reg & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
+		if (emaclite->rxpp)
+			emaclite->nextrxbuffertouse ^= XEL_BUFFER_OFFSET;
+	} else {
+
+		if (!emaclite->rxpp) {
+			debug("No data was available - address 0x%x\n",
+								baseaddress);
+			return 0;
+		} else {
+			baseaddress ^= XEL_BUFFER_OFFSET;
+			reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
+			if ((reg & XEL_RSR_RECV_DONE_MASK) !=
+						XEL_RSR_RECV_DONE_MASK) {
+				debug("No data was available - address 0x%x\n",
+						baseaddress);
+				return 0;
+			}
+		}
+	}
+	/* Get the length of the frame that arrived */
+	switch(((ntohl(in_be32 (baseaddress + XEL_RXBUFF_OFFSET + 0xC))) &
+			0xFFFF0000 ) >> 16) {
+		case 0x806:
+			length = 42 + 20; /* FIXME size of ARP */
+			debug("ARP Packet\n");
+			break;
+		case 0x800:
+			length = 14 + 14 +
+			(((ntohl(in_be32 (baseaddress + XEL_RXBUFF_OFFSET +
+						0x10))) & 0xFFFF0000) >> 16);
+			/* FIXME size of IP packet */
+			debug ("IP Packet\n");
+			break;
+		default:
+			debug("Other Packet\n");
+			length = PKTSIZE;
+			break;
+	}
+
+	xemaclite_alignedread((u32 *) (baseaddress + XEL_RXBUFF_OFFSET),
+			etherrxbuff, length);
+
+	/* Acknowledge the frame */
+	reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
+	reg &= ~XEL_RSR_RECV_DONE_MASK;
+	out_be32 (baseaddress + XEL_RSR_OFFSET, reg);
+
+	debug("Packet receive from 0x%x, length %dB\n", baseaddress, length);
+	NetReceive((uchar *) etherrxbuff, length);
+	return length;
+
+}
+
+int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr,
+							int txpp, int rxpp)
+{
+	struct eth_device *dev;
+	struct xemaclite *emaclite;
+
+	dev = calloc(1, sizeof(*dev));
+	if (dev == NULL)
+		return -1;
+
+	emaclite = calloc(1, sizeof(struct xemaclite));
+	if (emaclite == NULL) {
+		free(dev);
+		return -1;
+	}
+
+	dev->priv = emaclite;
+
+	emaclite->txpp = txpp;
+	emaclite->rxpp = rxpp;
+
+	sprintf(dev->name, "Xelite.%lx", base_addr);
+
+	dev->iobase = base_addr;
+	dev->init = emaclite_init;
+	dev->halt = emaclite_halt;
+	dev->send = emaclite_send;
+	dev->recv = emaclite_recv;
+
+	eth_register(dev);
+
+	return 1;
+}
+
+#ifdef CONFIG_OF_CONTROL
+int xilinx_emaclite_init(bd_t *bis)
+{
+	int offset = 0;
+	u32 ret = 0;
+	u32 reg;
+
+	do {
+		offset = fdt_node_offset_by_compatible(gd->fdt_blob, offset,
+					"xlnx,xps-ethernetlite-1.00.a");
+		if (offset != -1) {
+			reg = fdtdec_get_addr(gd->fdt_blob, offset, "reg");
+			if (reg != FDT_ADDR_T_NONE) {
+				u32 rxpp = fdtdec_get_int(gd->fdt_blob, offset,
+							"xlnx,rx-ping-pong", 0);
+				u32 txpp = fdtdec_get_int(gd->fdt_blob, offset,
+							"xlnx,tx-ping-pong", 0);
+				ret |= xilinx_emaclite_initialize(bis, reg,
+								txpp, rxpp);
+			}
+		}
+	} while (offset != -1);
+
+	return ret;
+}
+#endif
diff --git a/marvell/uboot/drivers/net/xilinx_ll_temac.c b/marvell/uboot/drivers/net/xilinx_ll_temac.c
new file mode 100644
index 0000000..dab78d0
--- /dev/null
+++ b/marvell/uboot/drivers/net/xilinx_ll_temac.c
@@ -0,0 +1,402 @@
+/*
+ * Xilinx xps_ll_temac ethernet driver for u-boot
+ *
+ * supports SDMA or FIFO access and MDIO bus communication
+ *
+ * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
+ * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008 - 2011 PetaLogix
+ *
+ * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
+ * Copyright (C) 2008 Nissin Systems Co.,Ltd.
+ * March 2008 created
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * [0]: http://www.xilinx.com/support/documentation
+ *
+ * [S]:	[0]/ip_documentation/xps_ll_temac.pdf
+ * [A]:	[0]/application_notes/xapp1041.pdf
+ */
+
+#include <config.h>
+#include <common.h>
+#include <net.h>
+#include <netdev.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <miiphy.h>
+
+#include "xilinx_ll_temac.h"
+#include "xilinx_ll_temac_fifo.h"
+#include "xilinx_ll_temac_sdma.h"
+#include "xilinx_ll_temac_mdio.h"
+
+#if !defined(CONFIG_MII)
+# error "LL_TEMAC requires MII -- missing CONFIG_MII"
+#endif
+
+#if !defined(CONFIG_PHYLIB)
+# error "LL_TEMAC requires PHYLIB -- missing CONFIG_PHYLIB"
+#endif
+
+struct ll_temac_info {
+	int			flags;
+	unsigned long		base_addr;
+	unsigned long		ctrl_addr;
+	char			*devname;
+	unsigned int		phyaddr;
+	char			*mdio_busname;
+};
+
+/* Ethernet interface ready status */
+int ll_temac_check_status(struct temac_reg *regs, u32 mask)
+{
+	unsigned timeout = 50;	/* 1usec * 50 = 50usec */
+
+	/*
+	 * Quote from LL TEMAC documentation: The bits in the RDY
+	 * register are asserted when there is no access in progress.
+	 * When an access is in progress, a bit corresponding to the
+	 * type of access is automatically de-asserted. The bit is
+	 * automatically re-asserted when the access is complete.
+	 */
+	while (timeout && (!(in_be32(&regs->rdy) & mask))) {
+		timeout--;
+		udelay(1);
+	}
+
+	if (!timeout) {
+		printf("%s: Timeout on 0x%08x @%p\n", __func__,
+				mask, &regs->rdy);
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * Indirect write to ll_temac.
+ *
+ * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf
+ * page 23, second paragraph, The use of CTL0 register or CTL1 register
+ */
+int ll_temac_indirect_set(struct temac_reg *regs, u16 regn, u32 reg_data)
+{
+	out_be32(&regs->lsw, (reg_data & MLSW_MASK));
+	out_be32(&regs->ctl, CTL_WEN | (regn & CTL_ADDR_MASK));
+
+	if (ll_temac_check_status(regs, RSE_CFG_WR))
+		return 0;
+
+	return 1;
+}
+
+/*
+ * Indirect read from ll_temac.
+ *
+ * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf
+ * page 23, second paragraph, The use of CTL0 register or CTL1 register
+ */
+int ll_temac_indirect_get(struct temac_reg *regs, u16 regn, u32* reg_data)
+{
+	out_be32(&regs->ctl, (regn & CTL_ADDR_MASK));
+
+	if (ll_temac_check_status(regs, RSE_CFG_RR))
+		return 0;
+
+	*reg_data = in_be32(&regs->lsw) & MLSW_MASK;
+	return 1;
+}
+
+/* setting sub-controller and ll_temac to proper setting */
+static int ll_temac_setup_ctrl(struct eth_device *dev)
+{
+	struct ll_temac *ll_temac = dev->priv;
+	struct temac_reg *regs = (struct temac_reg *)dev->iobase;
+
+	if (ll_temac->ctrlreset && ll_temac->ctrlreset(dev))
+		return 0;
+
+	if (ll_temac->ctrlinit && ll_temac->ctrlinit(dev))
+		return 0;
+
+	/* Promiscuous mode disable */
+	if (!ll_temac_indirect_set(regs, TEMAC_AFM, 0))
+		return 0;
+
+	/* Enable Receiver - RX bit */
+	if (!ll_temac_indirect_set(regs, TEMAC_RCW1, RCW1_RX))
+		return 0;
+
+	/* Enable Transmitter - TX bit */
+	if (!ll_temac_indirect_set(regs, TEMAC_TC, TC_TX))
+		return 0;
+
+	return 1;
+}
+
+/*
+ * Configure ll_temac based on negotiated speed and duplex
+ * reported by PHY handling code
+ */
+static int ll_temac_adjust_link(struct eth_device *dev)
+{
+	unsigned int speed, emmc_reg;
+	struct temac_reg *regs = (struct temac_reg *)dev->iobase;
+	struct ll_temac *ll_temac = dev->priv;
+	struct phy_device *phydev = ll_temac->phydev;
+
+	if (!phydev->link) {
+		printf("%s: No link.\n", phydev->dev->name);
+		return 0;
+	}
+
+	switch (phydev->speed) {
+	case 1000:
+		speed = EMMC_LSPD_1000;
+		break;
+	case 100:
+		speed = EMMC_LSPD_100;
+		break;
+	case 10:
+		speed = EMMC_LSPD_10;
+		break;
+	default:
+		return 0;
+	}
+
+	if (!ll_temac_indirect_get(regs, TEMAC_EMMC, &emmc_reg))
+		return 0;
+
+	emmc_reg &= ~EMMC_LSPD_MASK;
+	emmc_reg |= speed;
+
+	if (!ll_temac_indirect_set(regs, TEMAC_EMMC, emmc_reg))
+		return 0;
+
+	printf("%s: PHY is %s with %dbase%s, %s%s\n",
+			dev->name, phydev->drv->name,
+			phydev->speed, (phydev->port == PORT_TP) ? "T" : "X",
+			(phydev->duplex) ? "FDX" : "HDX",
+			(phydev->port == PORT_OTHER) ? ", unkown mode" : "");
+
+	return 1;
+}
+
+/* setup mac addr */
+static int ll_temac_setup_mac_addr(struct eth_device *dev)
+{
+	struct temac_reg *regs = (struct temac_reg *)dev->iobase;
+	u32 val;
+
+	/* set up unicast MAC address filter */
+	val = ((dev->enetaddr[3] << 24) | (dev->enetaddr[2] << 16) |
+			(dev->enetaddr[1] << 8) | (dev->enetaddr[0]));
+	val &= UAW0_UADDR_MASK;
+
+	if (!ll_temac_indirect_set(regs, TEMAC_UAW0, val))
+		return 1;
+
+	val = ((dev->enetaddr[5] << 8) | dev->enetaddr[4]);
+	val &= UAW1_UADDR_MASK;
+
+	if (!ll_temac_indirect_set(regs, TEMAC_UAW1, val))
+		return 1;
+
+	return 0;
+}
+
+/* halt device */
+static void ll_temac_halt(struct eth_device *dev)
+{
+	struct ll_temac *ll_temac = dev->priv;
+	struct temac_reg *regs = (struct temac_reg *)dev->iobase;
+
+	/* Disable Receiver */
+	ll_temac_indirect_set(regs, TEMAC_RCW0, 0);
+
+	/* Disable Transmitter */
+	ll_temac_indirect_set(regs, TEMAC_TC, 0);
+
+	if (ll_temac->ctrlhalt)
+		ll_temac->ctrlhalt(dev);
+
+	/* Shut down the PHY, as needed */
+	phy_shutdown(ll_temac->phydev);
+}
+
+static int ll_temac_init(struct eth_device *dev, bd_t *bis)
+{
+	struct ll_temac *ll_temac = dev->priv;
+	int ret;
+
+	printf("%s: Xilinx XPS LocalLink Tri-Mode Ether MAC #%d at 0x%08X.\n",
+		dev->name, dev->index, dev->iobase);
+
+	if (!ll_temac_setup_ctrl(dev))
+		return -1;
+
+	/* Start up the PHY */
+	ret = phy_startup(ll_temac->phydev);
+	if (ret) {
+		printf("%s: Could not initialize PHY %s\n",
+		       dev->name, ll_temac->phydev->dev->name);
+		return ret;
+	}
+
+	if (!ll_temac_adjust_link(dev)) {
+		ll_temac_halt(dev);
+		return -1;
+	}
+
+	/* If there's no link, fail */
+	return ll_temac->phydev->link ? 0 : -1;
+}
+
+/*
+ * Discover which PHY is attached to the device, and configure it
+ * properly.  If the PHY is not recognized, then return 0
+ * (failure).  Otherwise, return 1
+ */
+static int ll_temac_phy_init(struct eth_device *dev)
+{
+	struct ll_temac *ll_temac = dev->priv;
+	struct phy_device *phydev;
+	unsigned int supported = PHY_GBIT_FEATURES;
+
+	/* interface - look at driver/net/tsec.c */
+	phydev = phy_connect(ll_temac->bus, ll_temac->phyaddr,
+			dev, PHY_INTERFACE_MODE_NONE);
+
+	phydev->supported &= supported;
+	phydev->advertising = phydev->supported;
+
+	ll_temac->phydev = phydev;
+
+	phy_config(phydev);
+
+	return 1;
+}
+
+/*
+ * Initialize a single ll_temac devices
+ *
+ * Returns the result of ll_temac phy interface that were initialized
+ */
+int xilinx_ll_temac_initialize(bd_t *bis, struct ll_temac_info *devinf)
+{
+	struct eth_device *dev;
+	struct ll_temac *ll_temac;
+
+	dev = calloc(1, sizeof(*dev));
+	if (dev == NULL)
+		return 0;
+
+	ll_temac = calloc(1, sizeof(struct ll_temac));
+	if (ll_temac == NULL) {
+		free(dev);
+		return 0;
+	}
+
+	/* use given name or generate its own unique name */
+	if (devinf->devname) {
+		strncpy(dev->name, devinf->devname, sizeof(dev->name));
+	} else {
+		snprintf(dev->name, sizeof(dev->name), "lltemac.%lx", devinf->base_addr);
+		devinf->devname = dev->name;
+	}
+
+	dev->iobase = devinf->base_addr;
+
+	dev->priv = ll_temac;
+	dev->init = ll_temac_init;
+	dev->halt = ll_temac_halt;
+	dev->write_hwaddr = ll_temac_setup_mac_addr;
+
+	ll_temac->ctrladdr = devinf->ctrl_addr;
+	if (devinf->flags & XILINX_LL_TEMAC_M_SDMA_PLB) {
+#if defined(CONFIG_XILINX_440) || defined(CONFIG_XILINX_405)
+		if (devinf->flags & XILINX_LL_TEMAC_M_SDMA_DCR) {
+			ll_temac_collect_xldcr_sdma_reg_addr(dev);
+			ll_temac->in32 = ll_temac_xldcr_in32;
+			ll_temac->out32 = ll_temac_xldcr_out32;
+		} else
+#endif
+		{
+			ll_temac_collect_xlplb_sdma_reg_addr(dev);
+			ll_temac->in32 = ll_temac_xlplb_in32;
+			ll_temac->out32 = ll_temac_xlplb_out32;
+		}
+		ll_temac->ctrlinit = ll_temac_init_sdma;
+		ll_temac->ctrlhalt = ll_temac_halt_sdma;
+		ll_temac->ctrlreset = ll_temac_reset_sdma;
+		dev->recv = ll_temac_recv_sdma;
+		dev->send = ll_temac_send_sdma;
+	} else {
+		ll_temac->in32 = NULL;
+		ll_temac->out32 = NULL;
+		ll_temac->ctrlinit = NULL;
+		ll_temac->ctrlhalt = NULL;
+		ll_temac->ctrlreset = ll_temac_reset_fifo;
+		dev->recv = ll_temac_recv_fifo;
+		dev->send = ll_temac_send_fifo;
+	}
+
+	/* Link to specified MDIO bus */
+	strncpy(ll_temac->mdio_busname, devinf->mdio_busname, MDIO_NAME_LEN);
+	ll_temac->bus = miiphy_get_dev_by_name(ll_temac->mdio_busname);
+
+	/* Looking for a valid PHY address if it is not yet set */
+	if (devinf->phyaddr == -1)
+		ll_temac->phyaddr = ll_temac_phy_addr(ll_temac->bus);
+	else
+		ll_temac->phyaddr = devinf->phyaddr;
+
+	eth_register(dev);
+
+	/* Try to initialize PHY here, and return */
+	return ll_temac_phy_init(dev);
+}
+
+/*
+ * Initialize a single ll_temac device with its mdio bus behind ll_temac
+ *
+ * Returns 1 if the ll_temac device and the mdio bus were initialized
+ * otherwise returns 0
+ */
+int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags,
+							unsigned long ctrl_addr)
+{
+	struct ll_temac_info devinf;
+	struct ll_temac_mdio_info mdioinf;
+	int ret;
+
+	/* prepare the internal driver informations */
+	devinf.flags = flags;
+	devinf.base_addr = base_addr;
+	devinf.ctrl_addr = ctrl_addr;
+	devinf.devname = NULL;
+	devinf.phyaddr = -1;
+
+	mdioinf.name = devinf.mdio_busname = NULL;
+	mdioinf.regs = (struct temac_reg *)devinf.base_addr;
+
+	ret = xilinx_ll_temac_mdio_initialize(bis, &mdioinf);
+	if (ret >= 0) {
+
+		/*
+		 * If there was no MDIO bus name then take over the
+		 * new automaticaly generated by the MDIO init code.
+		 */
+		if (mdioinf.name != devinf.mdio_busname)
+			devinf.mdio_busname = mdioinf.name;
+
+		ret = xilinx_ll_temac_initialize(bis, &devinf);
+		if (ret > 0)
+			return 1;
+
+	}
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/xilinx_ll_temac.h b/marvell/uboot/drivers/net/xilinx_ll_temac.h
new file mode 100644
index 0000000..56362ba
--- /dev/null
+++ b/marvell/uboot/drivers/net/xilinx_ll_temac.h
@@ -0,0 +1,307 @@
+/*
+ * Xilinx xps_ll_temac ethernet driver for u-boot
+ *
+ * LL_TEMAC interface
+ *
+ * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
+ * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008 - 2011 PetaLogix
+ *
+ * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
+ * Copyright (C) 2008 Nissin Systems Co.,Ltd.
+ * March 2008 created
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * [0]: http://www.xilinx.com/support/documentation
+ *
+ * [S]:	[0]/ip_documentation/xps_ll_temac.pdf
+ * [A]:	[0]/application_notes/xapp1041.pdf
+ */
+#ifndef _XILINX_LL_TEMAC_
+#define _XILINX_LL_TEMAC_
+
+#include <config.h>
+#include <net.h>
+#include <phy.h>
+#include <miiphy.h>
+
+#include <asm/types.h>
+#include <asm/byteorder.h>
+
+#include "xilinx_ll_temac_sdma.h"
+
+#if !defined(__BIG_ENDIAN)
+# error LL_TEMAC requires big endianess
+#endif
+
+/*
+ * TEMAC Memory and Register Definition
+ *
+ * [1]:	[0]/ip_documentation/xps_ll_temac.pdf
+ *	page 19, Memory and Register Descriptions
+ */
+struct temac_reg {
+	/* direct soft registers (low part) */
+	u32 raf;	/* Reset and Address Filter */
+	u32 tpf;	/* Transmit Pause Frame */
+	u32 ifgp;	/* Transmit Inter Frame Gap Adjustment */
+	u32 is;		/* Interrupt Status */
+	u32 ip;		/* Interrupt Pending */
+	u32 ie;		/* Interrupt Enable */
+	u32 ttag;	/* Transmit VLAN Tag */
+	u32 rtag;	/* Receive VLAN Tag */
+	/* hard TEMAC registers */
+	u32 msw;	/* Most Significant Word Data */
+	u32 lsw;	/* Least Significant Word Data */
+	u32 ctl;	/* Control */
+	u32 rdy;	/* Ready Status */
+	/* direct soft registers (high part) */
+	u32 uawl;	/* Unicast Address Word Lower */
+	u32 uawu;	/* Unicast Address Word Upper */
+	u32 tpid0;	/* VLAN TPID Word 0 */
+	u32 tpid1;	/* VLAN TPID Word 1 */
+};
+
+/* Reset and Address Filter Registers (raf), [1] p25 */
+#define RAF_SR			(1 << 13)
+#define RAF_EMFE		(1 << 12)
+#define RAF_NFE			(1 << 11)
+#define RAF_RVSTM_POS		9
+#define RAF_RVSTM_MASK		(3 << RAF_RVSTM_POS)
+#define RAF_TVSTM_POS		7
+#define RAF_TVSTM_MASK		(3 << RAF_TVSTM_POS)
+#define RAF_RVTM_POS		5
+#define RAF_RVTM_MASK		(3 << RAF_RVTM_POS)
+#define RAF_TVTM_POS		3
+#define RAF_TVTM_MASK		(3 << RAF_TVTM_POS)
+#define RAF_BCREJ		(1 << 2)
+#define RAF_MCREJ		(1 << 1)
+#define RAF_HTRST		(1 << 0)
+
+/* Transmit Pause Frame Registers (tpf), [1] p28 */
+#define TPF_TPFV_POS		0
+#define TPF_TPFV_MASK		(0xFFFF << TPF_TPFV_POS)
+
+/* Transmit Inter Frame Gap Adjustment Registers (ifgp), [1] p28 */
+#define IFGP_POS		0
+#define IFGP_MASK		(0xFF << IFGP_POS)
+
+/* Interrupt Status, Pending, Enable Registers (is, ip, ie), [1] p29-33 */
+#define ISPE_MR			(1 << 7)
+#define ISPE_RDL		(1 << 6)
+#define ISPE_TC			(1 << 5)
+#define ISPE_RFO		(1 << 4)
+#define ISPE_RR			(1 << 3)
+#define ISPE_RC			(1 << 2)
+#define ISPE_AN			(1 << 1)
+#define ISPE_HAC		(1 << 0)
+
+/* Transmit, Receive VLAN Tag Registers (ttag, rtag), [1] p34-35 */
+#define TRTAG_TPID_POS		16
+#define TRTAG_TPID_MASK		(0xFFFF << TRTAG_TPID_POS)
+#define TRTAG_PRIO_POS		13
+#define TRTAG_PRIO_MASK		(7 << TRTAG_PRIO_POS)
+#define TRTAG_CFI		(1 << 12)
+#define TRTAG_VID_POS		0
+#define TRTAG_VID_MASK		(0xFFF << TRTAG_VID_POS)
+
+/* Most, Least Significant Word Data Register (msw, lsw), [1] p46 */
+#define MLSW_POS		0
+#define MLSW_MASK		(~0UL << MLSW_POS)
+
+/* LSW Data Register for PHY addresses (lsw), [1] p66 */
+#define LSW_REGAD_POS		0
+#define LSW_REGAD_MASK		(0x1F << LSW_REGAD_POS)
+#define LSW_PHYAD_POS		5
+#define LSW_PHYAD_MASK		(0x1F << LSW_PHYAD_POS)
+
+/* LSW Data Register for PHY data (lsw), [1] p66 */
+#define LSW_REGDAT_POS		0
+#define LSW_REGDAT_MASK		(0xFFFF << LSW_REGDAT_POS)
+
+/* Control Register (ctl), [1] p47 */
+#define CTL_WEN			(1 << 15)
+#define CTL_ADDR_POS		0
+#define CTL_ADDR_MASK		(0x3FF << CTL_ADDR_POS)
+
+/* Ready Status Register Ethernet (rdy), [1] p48 */
+#define RSE_HACS_RDY		(1 << 14)
+#define RSE_CFG_WR		(1 << 6)
+#define RSE_CFG_RR		(1 << 5)
+#define RSE_AF_WR		(1 << 4)
+#define RSE_AF_RR		(1 << 3)
+#define RSE_MIIM_WR		(1 << 2)
+#define RSE_MIIM_RR		(1 << 1)
+#define RSE_FABR_RR		(1 << 0)
+
+/* Unicast Address Word Lower, Upper Registers (uawl, uawu), [1] p35-36 */
+#define UAWL_UADDR_POS		0
+#define UAWL_UADDR_MASK		(~0UL << UAWL_UADDR_POS)
+#define UAWU_UADDR_POS		0
+#define UAWU_UADDR_MASK		(0xFFFF << UAWU_UADDR_POS)
+
+/* VLAN TPID Word 0, 1 Registers (tpid0, tpid1), [1] p37 */
+#define TPID0_V0_POS		0
+#define TPID0_V0_MASK		(0xFFFF << TPID0_V0_POS)
+#define TPID0_V1_POS		16
+#define TPID0_V1_MASK		(0xFFFF << TPID0_V1_POS)
+#define TPID1_V2_POS		0
+#define TPID1_V2_MASK		(0xFFFF << TPID1_V2_POS)
+#define TPID1_V3_POS		16
+#define TPID1_V3_MASK		(0xFFFF << TPID1_V3_POS)
+
+/*
+ * TEMAC Indirectly Addressable Register Index Enumeration
+ *
+ * [0]: http://www.xilinx.com/support/documentation
+ *
+ * [1]:	[0]/ip_documentation/xps_ll_temac.pdf
+ *	page 23, PLB Indirectly Addressable TEMAC Registers
+ */
+enum temac_ctrl {
+	TEMAC_RCW0	= 0x200,
+	TEMAC_RCW1	= 0x240,
+	TEMAC_TC	= 0x280,
+	TEMAC_FCC	= 0x2C0,
+	TEMAC_EMMC	= 0x300,
+	TEMAC_PHYC	= 0x320,
+	TEMAC_MC	= 0x340,
+	TEMAC_UAW0	= 0x380,
+	TEMAC_UAW1	= 0x384,
+	TEMAC_MAW0	= 0x388,
+	TEMAC_MAW1	= 0x38C,
+	TEMAC_AFM	= 0x390,
+	TEMAC_TIS	= 0x3A0,
+	TEMAC_TIE	= 0x3A4,
+	TEMAC_MIIMWD	= 0x3B0,
+	TEMAC_MIIMAI	= 0x3B4
+};
+
+/* Receive Configuration Word 0, 1 Registers (RCW0, RCW1), [1] p50-51 */
+#define RCW0_PADDR_POS		0
+#define RCW0_PADDR_MASK		(~0UL << RCW_PADDR_POS)
+#define RCW1_RST		(1 << 31)
+#define RCW1_JUM		(1 << 30)
+#define RCW1_FCS		(1 << 29)
+#define RCW1_RX			(1 << 28)
+#define RCW1_VLAN		(1 << 27)
+#define RCW1_HD			(1 << 26)
+#define RCW1_LT_DIS		(1 << 25)
+#define RCW1_PADDR_POS		0
+#define RCW1_PADDR_MASK		(0xFFFF << RCW_PADDR_POS)
+
+/* Transmit Configuration Registers (TC), [1] p52 */
+#define TC_RST			(1 << 31)
+#define TC_JUM			(1 << 30)
+#define TC_FCS			(1 << 29)
+#define TC_TX			(1 << 28)
+#define TC_VLAN			(1 << 27)
+#define TC_HD			(1 << 26)
+#define TC_IFG			(1 << 25)
+
+/* Flow Control Configuration Registers (FCC), [1] p54 */
+#define FCC_FCTX		(1 << 30)
+#define FCC_FCRX		(1 << 29)
+
+/* Ethernet MAC Mode Configuration Registers (EMMC), [1] p54 */
+#define EMMC_LSPD_POS		30
+#define EMMC_LSPD_MASK		(3 << EMMC_LSPD_POS)
+#define EMMC_LSPD_1000		(2 << EMMC_LSPD_POS)
+#define EMMC_LSPD_100		(1 << EMMC_LSPD_POS)
+#define EMMC_LSPD_10		0
+#define EMMC_RGMII		(1 << 29)
+#define EMMC_SGMII		(1 << 28)
+#define EMMC_GPCS		(1 << 27)
+#define EMMC_HOST		(1 << 26)
+#define EMMC_TX16		(1 << 25)
+#define EMMC_RX16		(1 << 24)
+
+/* RGMII/SGMII Configuration Registers (PHYC), [1] p56 */
+#define PHYC_SLSPD_POS		30
+#define PHYC_SLSPD_MASK		(3 << EMMC_SLSPD_POS)
+#define PHYC_SLSPD_1000		(2 << EMMC_SLSPD_POS)
+#define PHYC_SLSPD_100		(1 << EMMC_SLSPD_POS)
+#define PHYC_SLSPD_10		0
+#define PHYC_RLSPD_POS		2
+#define PHYC_RLSPD_MASK		(3 << EMMC_RLSPD_POS)
+#define PHYC_RLSPD_1000		(2 << EMMC_RLSPD_POS)
+#define PHYC_RLSPD_100		(1 << EMMC_RLSPD_POS)
+#define PHYC_RLSPD_10		0
+#define PHYC_RGMII_HD		(1 << 1)
+#define PHYC_RGMII_LINK		(1 << 0)
+
+/* Management Configuration Registers (MC), [1] p57 */
+#define MC_MDIOEN		(1 << 6)
+#define MC_CLKDIV_POS		0
+#define MC_CLKDIV_MASK		(0x3F << MC_CLKDIV_POS)
+
+/*
+ *             fHOSTCLK          fMDC =                  fHOSTCLK
+ * fMDC = -------------------   --------->   MC_CLKDIV = -------- - 1
+ *        (1 + MC_CLKDIV) * 2    2.5 MHz                   5MHz
+ */
+#define MC_CLKDIV(f, m)		((f / (2 * m)) - 1)
+#define MC_CLKDIV_25(f)		MC_CLKDIV(f, 2500000)
+#define MC_CLKDIV_20(f)		MC_CLKDIV(f, 2000000)
+#define MC_CLKDIV_15(f)		MC_CLKDIV(f, 1500000)
+#define MC_CLKDIV_10(f)		MC_CLKDIV(f, 1000000)
+
+/* Unicast Address Word 0, 1 Registers (UAW0, UAW1), [1] p58-59 */
+#define UAW0_UADDR_POS		0
+#define UAW0_UADDR_MASK		(~0UL << UAW0_UADDR_POS)
+#define UAW1_UADDR_POS		0
+#define UAW1_UADDR_MASK		(0xFFFF << UAW1_UADDR_POS)
+
+/* Multicast Address Word 0, 1 Registers (MAW0, MAW1), [1] p60 */
+#define MAW0_MADDR_POS		0
+#define MAW0_MADDR_MASK		(~0UL << MAW0_MADDR_POS)
+#define MAW1_RNW		(1 << 23)
+#define MAW1_MAIDX_POS		16
+#define MAW1_MAIDX_MASK		(3 << MAW1_MAIDX_POS)
+#define MAW1_MADDR_POS		0
+#define MAW1_MADDR_MASK		(0xFFFF << MAW1_MADDR_POS)
+
+/* Address Filter Mode Registers (AFM), [1] p63 */
+#define AFM_PM			(1 << 31)
+
+/* Interrupt Status, Enable Registers (TIS, TIE), [1] p63-65 */
+#define TISE_CFG_W		(1 << 6)
+#define TISE_CFG_R		(1 << 5)
+#define TISE_AF_W		(1 << 4)
+#define TISE_AF_R		(1 << 3)
+#define TISE_MIIM_W		(1 << 2)
+#define TISE_MIIM_R		(1 << 1)
+#define TISE_FABR_R		(1 << 0)
+
+/* MII Management Write Data Registers (MIIMWD), [1] p66 */
+#define MIIMWD_DATA_POS		0
+#define MIIMWD_DATA_MASK	(0xFFFF << MIIMWD_DATA_POS)
+
+/* Ethernet interface ready status */
+int ll_temac_check_status(struct temac_reg *regs, u32 mask);
+
+/* Indirect write to ll_temac. */
+int ll_temac_indirect_set(struct temac_reg *regs, u16 regn, u32 reg_data);
+
+/* Indirect read from ll_temac. */
+int ll_temac_indirect_get(struct temac_reg *regs, u16 regn, u32* reg_data);
+
+struct ll_temac {
+	phys_addr_t		ctrladdr;
+	phys_addr_t		sdma_reg_addr[SDMA_CTRL_REGNUMS];
+
+	unsigned		(*in32)(phys_addr_t);
+	void			(*out32)(phys_addr_t, unsigned);
+
+	int			(*ctrlinit) (struct eth_device *);
+	int			(*ctrlhalt) (struct eth_device *);
+	int			(*ctrlreset) (struct eth_device *);
+
+	int			phyaddr;
+	struct phy_device	*phydev;
+	struct mii_dev		*bus;
+	char			mdio_busname[MDIO_NAME_LEN];
+};
+
+#endif /* _XILINX_LL_TEMAC_ */
diff --git a/marvell/uboot/drivers/net/xilinx_ll_temac_fifo.c b/marvell/uboot/drivers/net/xilinx_ll_temac_fifo.c
new file mode 100644
index 0000000..b8993cd
--- /dev/null
+++ b/marvell/uboot/drivers/net/xilinx_ll_temac_fifo.c
@@ -0,0 +1,139 @@
+/*
+ * Xilinx xps_ll_temac ethernet driver for u-boot
+ *
+ * FIFO sub-controller
+ *
+ * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
+ * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008 - 2011 PetaLogix
+ *
+ * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
+ * Copyright (C) 2008 Nissin Systems Co.,Ltd.
+ * March 2008 created
+ *
+ * CREDITS: tsec driver
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * [0]: http://www.xilinx.com/support/documentation
+ *
+ * [F]:	[0]/ip_documentation/xps_ll_fifo.pdf
+ * [S]:	[0]/ip_documentation/xps_ll_temac.pdf
+ * [A]:	[0]/application_notes/xapp1041.pdf
+ */
+
+#include <config.h>
+#include <common.h>
+#include <net.h>
+
+#include <asm/types.h>
+#include <asm/io.h>
+
+#include "xilinx_ll_temac.h"
+#include "xilinx_ll_temac_fifo.h"
+
+int ll_temac_reset_fifo(struct eth_device *dev)
+{
+	struct ll_temac *ll_temac = dev->priv;
+	struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr;
+
+	out_be32(&fifo_ctrl->tdfr, LL_FIFO_TDFR_KEY);
+	out_be32(&fifo_ctrl->rdfr, LL_FIFO_RDFR_KEY);
+	out_be32(&fifo_ctrl->isr, ~0UL);
+	out_be32(&fifo_ctrl->ier, 0);
+
+	return 0;
+}
+
+int ll_temac_recv_fifo(struct eth_device *dev)
+{
+	int i, length = 0;
+	u32 *buf = (u32 *)NetRxPackets[0];
+	struct ll_temac *ll_temac = dev->priv;
+	struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr;
+
+	if (in_be32(&fifo_ctrl->isr) & LL_FIFO_ISR_RC) {
+
+		/* reset isr */
+		out_be32(&fifo_ctrl->isr, ~0UL);
+
+		/*
+		 * MAYBE here:
+		 *   while (fifo_ctrl->isr);
+		 */
+
+		/*
+		 * The length is written (into RLR) by the XPS LL FIFO
+		 * when the packet is received across the RX LocalLink
+		 * interface and the receive data FIFO had enough
+		 * locations that all of the packet data has been saved.
+		 * The RLR should only be read when a receive packet is
+		 * available for processing (the receive occupancy is
+		 * not zero). Once the RLR is read, the receive packet
+		 * data should be read from the receive data FIFO before
+		 * the RLR is read again.
+		 *
+		 * [F] page 17, Receive Length Register (RLR)
+		 */
+		if (in_be32(&fifo_ctrl->rdfo) & LL_FIFO_RDFO_MASK) {
+			length = in_be32(&fifo_ctrl->rlf) & LL_FIFO_RLF_MASK;
+		} else {
+			printf("%s: Got error, no receive occupancy\n",
+					__func__);
+			return -1;
+		}
+
+		if (length > PKTSIZE_ALIGN) {
+			printf("%s: Got error, receive package too big (%i)\n",
+					__func__, length);
+			ll_temac_reset_fifo(dev);
+			return -1;
+		}
+
+		for (i = 0; i < length; i += 4)
+			*buf++ = in_be32(&fifo_ctrl->rdfd);
+
+		NetReceive(NetRxPackets[0], length);
+	}
+
+	return 0;
+}
+
+int ll_temac_send_fifo(struct eth_device *dev, void *packet, int length)
+{
+	int i;
+	u32 *buf = (u32 *)packet;
+	struct ll_temac *ll_temac = dev->priv;
+	struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr;
+
+	if (length < LL_FIFO_TLF_MIN) {
+		printf("%s: Got error, transmit package too small (%i)\n",
+				__func__, length);
+		return -1;
+	}
+
+	if (length > LL_FIFO_TLF_MAX) {
+		printf("%s: Got error, transmit package too big (%i)\n",
+				__func__, length);
+		return -1;
+	}
+
+	for (i = 0; i < length; i += 4)
+		out_be32(&fifo_ctrl->tdfd, *buf++);
+
+	/*
+	 * Once the packet length is written to the TLR it is
+	 * automatically moved to the transmit data FIFO with
+	 * the packet data freeing up the TLR for another value.
+	 * The packet length must be written to the TLR after
+	 * the packet data is written to the transmit data FIFO.
+	 * It is not valid to write data for multiple packets
+	 * to the transmit data FIFO before writing the packet
+	 * length values.
+	 *
+	 * [F] page 17, Transmit Length Register (TLR)
+	 */
+	out_be32(&fifo_ctrl->tlf, length);
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/xilinx_ll_temac_fifo.h b/marvell/uboot/drivers/net/xilinx_ll_temac_fifo.h
new file mode 100644
index 0000000..c1bf7cc
--- /dev/null
+++ b/marvell/uboot/drivers/net/xilinx_ll_temac_fifo.h
@@ -0,0 +1,118 @@
+/*
+ * Xilinx xps_ll_temac ethernet driver for u-boot
+ *
+ * FIFO sub-controller interface
+ *
+ * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
+ * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008 - 2011 PetaLogix
+ *
+ * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
+ * Copyright (C) 2008 Nissin Systems Co.,Ltd.
+ * March 2008 created
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * [0]: http://www.xilinx.com/support/documentation
+ *
+ * [S]:	[0]/ip_documentation/xps_ll_temac.pdf
+ * [A]:	[0]/application_notes/xapp1041.pdf
+ */
+#ifndef _XILINX_LL_TEMAC_FIFO_
+#define _XILINX_LL_TEMAC_FIFO_
+
+#include <net.h>
+
+#include <asm/types.h>
+#include <asm/byteorder.h>
+
+#if !defined(__BIG_ENDIAN)
+# error LL_TEMAC requires big endianess
+#endif
+
+/*
+ * FIFO Register Definition
+ *
+ * Used for memory mapped access from and to (Rd/Td) the LocalLink (LL)
+ * Tri-Mode Ether MAC (TEMAC) via the 2 kb full duplex FIFO Controller,
+ * one for each.
+ *
+ * [1]: [0]/ip_documentation/xps_ll_fifo.pdf
+ *      page 10, Registers Definition
+ */
+struct fifo_ctrl {
+	u32 isr;	/* Interrupt Status Register (RW) */
+	u32 ier;	/* Interrupt Enable Register (RW) */
+	u32 tdfr;	/* Transmit Data FIFO Reset (WO) */
+	u32 tdfv;	/* Transmit Data FIFO Vacancy (RO) */
+	u32 tdfd;	/* Transmit Data FIFO 32bit wide Data write port (WO) */
+	u32 tlf;	/* Transmit Length FIFO (WO) */
+	u32 rdfr;	/* Receive Data FIFO Reset (WO) */
+	u32 rdfo;	/* Receive Data FIFO Occupancy (RO) */
+	u32 rdfd;	/* Receive Data FIFO 32bit wide Data read port (RO) */
+	u32 rlf;	/* Receive Length FIFO (RO) */
+	u32 llr;	/* LocalLink Reset (WO) */
+};
+
+/* Interrupt Status Register (ISR), [1] p11 */
+#define LL_FIFO_ISR_RPURE	(1 << 31) /* Receive Packet Underrun Read Err */
+#define LL_FIFO_ISR_RPORE	(1 << 30) /* Receive Packet Overrun Read Err */
+#define LL_FIFO_ISR_RPUE	(1 << 29) /* Receive Packet Underrun Error */
+#define LL_FIFO_ISR_TPOE	(1 << 28) /* Transmit Packet Overrun Error */
+#define LL_FIFO_ISR_TC		(1 << 27) /* Transmit Complete */
+#define LL_FIFO_ISR_RC		(1 << 26) /* Receive Complete */
+#define LL_FIFO_ISR_TSE		(1 << 25) /* Transmit Size Error */
+#define LL_FIFO_ISR_TRC		(1 << 24) /* Transmit Reset Complete */
+#define LL_FIFO_ISR_RRC		(1 << 23) /* Receive Reset Complete */
+
+/* Interrupt Enable Register (IER), [1] p12/p13 */
+#define LL_FIFO_IER_RPURE	(1 << 31) /* Receive Packet Underrun Read Err */
+#define LL_FIFO_IER_RPORE	(1 << 30) /* Receive Packet Overrun Read Err */
+#define LL_FIFO_IER_RPUE	(1 << 29) /* Receive Packet Underrun Error */
+#define LL_FIFO_IER_TPOE	(1 << 28) /* Transmit Packet Overrun Error */
+#define LL_FIFO_IER_TC		(1 << 27) /* Transmit Complete */
+#define LL_FIFO_IER_RC		(1 << 26) /* Receive Complete */
+#define LL_FIFO_IER_TSE		(1 << 25) /* Transmit Size Error */
+#define LL_FIFO_IER_TRC		(1 << 24) /* Transmit Reset Complete */
+#define LL_FIFO_IER_RRC		(1 << 23) /* Receive Reset Complete */
+
+/* Transmit Data FIFO Reset (TDFR), [1] p13/p14 */
+#define LL_FIFO_TDFR_KEY	0x000000A5UL
+
+/* Transmit Data FIFO Vacancy (TDFV), [1] p14 */
+#define LL_FIFO_TDFV_POS	0
+#define LL_FIFO_TDFV_MASK	(0x000001FFUL << LL_FIFO_TDFV_POS)
+
+/* Transmit Length FIFO (TLF), [1] p16/p17 */
+#define LL_FIFO_TLF_POS		0
+#define LL_FIFO_TLF_MASK	(0x000007FFUL << LL_FIFO_TLF_POS)
+#define LL_FIFO_TLF_MIN		((4 * sizeof(u32)) & LL_FIFO_TLF_MASK)
+#define LL_FIFO_TLF_MAX		((510 * sizeof(u32)) & LL_FIFO_TLF_MASK)
+
+/* Receive Data FIFO Reset (RDFR), [1] p15 */
+#define LL_FIFO_RDFR_KEY	0x000000A5UL
+
+/* Receive Data FIFO Occupancy (RDFO), [1] p16 */
+#define LL_FIFO_RDFO_POS	0
+#define LL_FIFO_RDFO_MASK	(0x000001FFUL << LL_FIFO_RDFO_POS)
+
+/* Receive Length FIFO (RLF), [1] p17/p18 */
+#define LL_FIFO_RLF_POS		0
+#define LL_FIFO_RLF_MASK	(0x000007FFUL << LL_FIFO_RLF_POS)
+#define LL_FIFO_RLF_MIN		((4 * sizeof(uint32)) & LL_FIFO_RLF_MASK)
+#define LL_FIFO_RLF_MAX		((510 * sizeof(uint32)) & LL_FIFO_RLF_MASK)
+
+/* LocalLink Reset (LLR), [1] p18 */
+#define LL_FIFO_LLR_KEY		0x000000A5UL
+
+
+/* reset FIFO and IRQ, disable interrupts */
+int ll_temac_reset_fifo(struct eth_device *dev);
+
+/* receive buffered data from FIFO (polling ISR) */
+int ll_temac_recv_fifo(struct eth_device *dev);
+
+/* send buffered data to FIFO */
+int ll_temac_send_fifo(struct eth_device *dev, void *packet, int length);
+
+#endif /* _XILINX_LL_TEMAC_FIFO_ */
diff --git a/marvell/uboot/drivers/net/xilinx_ll_temac_mdio.c b/marvell/uboot/drivers/net/xilinx_ll_temac_mdio.c
new file mode 100644
index 0000000..b7bab79
--- /dev/null
+++ b/marvell/uboot/drivers/net/xilinx_ll_temac_mdio.c
@@ -0,0 +1,177 @@
+/*
+ * Xilinx xps_ll_temac ethernet driver for u-boot
+ *
+ * MDIO bus access
+ *
+ * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
+ * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008 - 2011 PetaLogix
+ *
+ * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
+ * Copyright (C) 2008 Nissin Systems Co.,Ltd.
+ * March 2008 created
+ *
+ * CREDITS: tsec driver
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * [0]: http://www.xilinx.com/support/documentation
+ *
+ * [S]:	[0]/ip_documentation/xps_ll_temac.pdf
+ * [A]:	[0]/application_notes/xapp1041.pdf
+ */
+
+#include <config.h>
+#include <common.h>
+#include <miiphy.h>
+#include <phy.h>
+#include <malloc.h>
+#include <asm/io.h>
+
+#include "xilinx_ll_temac.h"
+#include "xilinx_ll_temac_mdio.h"
+
+#if !defined(CONFIG_MII)
+# error "LL_TEMAC requires MII -- missing CONFIG_MII"
+#endif
+
+#if !defined(CONFIG_PHYLIB)
+# error "LL_TEMAC requires PHYLIB -- missing CONFIG_PHYLIB"
+#endif
+
+/*
+ * Prior to PHY access, the MDIO clock must be setup. This driver will set a
+ * safe default that should work with PLB bus speeds of up to 150 MHz and keep
+ * the MDIO clock below 2.5 MHz. If the user wishes faster access to the PHY
+ * then the clock divisor can be set to a different value by setting the
+ * correct bus speed value with CONFIG_XILINX_LL_TEMAC_CLK.
+ */
+#if !defined(CONFIG_XILINX_LL_TEMAC_CLK)
+#define MDIO_CLOCK_DIV		MC_CLKDIV_10(150000000)
+#else
+#define MDIO_CLOCK_DIV		MC_CLKDIV_25(CONFIG_XILINX_LL_TEMAC_CLK)
+#endif
+
+static int ll_temac_mdio_setup(struct mii_dev *bus)
+{
+	struct temac_reg *regs = (struct temac_reg *)bus->priv;
+
+	/* setup MDIO clock */
+	ll_temac_indirect_set(regs, TEMAC_MC,
+			MC_MDIOEN | (MDIO_CLOCK_DIV & MC_CLKDIV_MASK));
+
+	return 0;
+}
+
+/*
+ * Indirect MII PHY read via ll_temac.
+ *
+ * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf
+ * page 67, Using the MII Management to Access PHY Registers
+ */
+int ll_temac_local_mdio_read(struct temac_reg *regs, int addr, int devad,
+				int regnum)
+{
+	out_be32(&regs->lsw,
+		((addr << LSW_PHYAD_POS) & LSW_PHYAD_MASK) |
+		(regnum & LSW_REGAD_MASK));
+	out_be32(&regs->ctl, TEMAC_MIIMAI);
+
+	ll_temac_check_status(regs, RSE_MIIM_RR);
+
+	return in_be32(&regs->lsw) & LSW_REGDAT_MASK;
+}
+
+/*
+ * Indirect MII PHY write via ll_temac.
+ *
+ * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf
+ * page 67, Using the MII Management to Access PHY Registers
+ */
+void ll_temac_local_mdio_write(struct temac_reg *regs, int addr, int devad,
+				int regnum, u16 value)
+{
+	out_be32(&regs->lsw, (value & LSW_REGDAT_MASK));
+	out_be32(&regs->ctl, CTL_WEN | TEMAC_MIIMWD);
+
+	out_be32(&regs->lsw,
+		((addr << LSW_PHYAD_POS) & LSW_PHYAD_MASK) |
+		(regnum & LSW_REGAD_MASK));
+	out_be32(&regs->ctl, CTL_WEN | TEMAC_MIIMAI);
+
+	ll_temac_check_status(regs, RSE_MIIM_WR);
+}
+
+int ll_temac_phy_read(struct mii_dev *bus, int addr, int devad, int regnum)
+{
+	struct temac_reg *regs = (struct temac_reg *)bus->priv;
+
+	return ll_temac_local_mdio_read(regs, addr, devad, regnum);
+}
+
+int ll_temac_phy_write(struct mii_dev *bus, int addr, int devad, int regnum,
+			u16 value)
+{
+	struct temac_reg *regs = (struct temac_reg *)bus->priv;
+
+	ll_temac_local_mdio_write(regs, addr, devad, regnum, value);
+
+	return 0;
+}
+
+/*
+ * Use MII register 1 (MII status register) to detect PHY
+ *
+ * A Mask used to verify certain PHY features (register content)
+ * in the PHY detection register:
+ *  Auto-negotiation support, 10Mbps half/full duplex support
+ */
+#define PHY_DETECT_REG		MII_BMSR
+#define PHY_DETECT_MASK		(BMSR_10FULL | BMSR_10HALF | BMSR_ANEGCAPABLE)
+
+/* Looking for a valid PHY address */
+int ll_temac_phy_addr(struct mii_dev *bus)
+{
+	struct temac_reg *regs = (struct temac_reg *)bus->priv;
+	unsigned short val;
+	unsigned int phy;
+
+	for (phy = PHY_MAX_ADDR; phy >= 0; phy--) {
+		val = ll_temac_local_mdio_read(regs, phy, 0, PHY_DETECT_REG);
+		if ((val != 0xFFFF) &&
+		((val & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
+			/* Found a valid PHY address */
+			return phy;
+		}
+	}
+
+	return -1;
+}
+
+int xilinx_ll_temac_mdio_initialize(bd_t *bis, struct ll_temac_mdio_info *info)
+{
+	struct mii_dev *bus = mdio_alloc();
+
+	if (!bus) {
+		printf("Failed to allocate LL_TEMAC MDIO bus: %s\n",
+				info->name);
+		return -1;
+	}
+
+	bus->read = ll_temac_phy_read;
+	bus->write = ll_temac_phy_write;
+	bus->reset = NULL;
+
+	/* use given name or generate its own unique name */
+	if (info->name) {
+		strncpy(bus->name, info->name, MDIO_NAME_LEN);
+	} else {
+		snprintf(bus->name, MDIO_NAME_LEN, "lltemii.%p", info->regs);
+		info->name = bus->name;
+	}
+
+	bus->priv = info->regs;
+
+	ll_temac_mdio_setup(bus);
+	return mdio_register(bus);
+}
diff --git a/marvell/uboot/drivers/net/xilinx_ll_temac_mdio.h b/marvell/uboot/drivers/net/xilinx_ll_temac_mdio.h
new file mode 100644
index 0000000..0603c64
--- /dev/null
+++ b/marvell/uboot/drivers/net/xilinx_ll_temac_mdio.h
@@ -0,0 +1,50 @@
+/*
+ * Xilinx xps_ll_temac ethernet driver for u-boot
+ *
+ * MDIO bus access interface
+ *
+ * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
+ * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008 - 2011 PetaLogix
+ *
+ * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
+ * Copyright (C) 2008 Nissin Systems Co.,Ltd.
+ * March 2008 created
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * [0]: http://www.xilinx.com/support/documentation
+ *
+ * [S]:	[0]/ip_documentation/xps_ll_temac.pdf
+ * [A]:	[0]/application_notes/xapp1041.pdf
+ */
+#ifndef _XILINX_LL_TEMAC_MDIO_
+#define _XILINX_LL_TEMAC_MDIO_
+
+#include <net.h>
+#include <miiphy.h>
+
+#include <asm/types.h>
+#include <asm/byteorder.h>
+
+#include "xilinx_ll_temac.h"
+
+int ll_temac_local_mdio_read(struct temac_reg *regs, int addr, int devad,
+				int regnum);
+void ll_temac_local_mdio_write(struct temac_reg *regs, int addr, int devad,
+				int regnum, u16 value);
+
+int ll_temac_phy_read(struct mii_dev *bus, int addr, int devad, int regnum);
+int ll_temac_phy_write(struct mii_dev *bus, int addr, int devad, int regnum,
+			u16 value);
+
+int ll_temac_phy_addr(struct mii_dev *bus);
+
+struct ll_temac_mdio_info {
+	struct temac_reg *regs;
+	char *name;
+};
+
+int xilinx_ll_temac_mdio_initialize(bd_t *bis, struct ll_temac_mdio_info *info);
+
+#endif /* _XILINX_LL_TEMAC_MDIO_ */
diff --git a/marvell/uboot/drivers/net/xilinx_ll_temac_sdma.c b/marvell/uboot/drivers/net/xilinx_ll_temac_sdma.c
new file mode 100644
index 0000000..32a822e
--- /dev/null
+++ b/marvell/uboot/drivers/net/xilinx_ll_temac_sdma.c
@@ -0,0 +1,366 @@
+/*
+ * Xilinx xps_ll_temac ethernet driver for u-boot
+ *
+ * SDMA sub-controller
+ *
+ * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
+ * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008 - 2011 PetaLogix
+ *
+ * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
+ * Copyright (C) 2008 Nissin Systems Co.,Ltd.
+ * March 2008 created
+ *
+ * CREDITS: tsec driver
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * [0]: http://www.xilinx.com/support/documentation
+ *
+ * [M]:	[0]/ip_documentation/mpmc.pdf
+ * [S]:	[0]/ip_documentation/xps_ll_temac.pdf
+ * [A]:	[0]/application_notes/xapp1041.pdf
+ */
+
+#include <config.h>
+#include <common.h>
+#include <net.h>
+
+#include <asm/types.h>
+#include <asm/io.h>
+
+#include "xilinx_ll_temac.h"
+#include "xilinx_ll_temac_sdma.h"
+
+#define TX_BUF_CNT		2
+
+static unsigned int rx_idx;	/* index of the current RX buffer */
+static unsigned int tx_idx;	/* index of the current TX buffer */
+
+struct rtx_cdmac_bd {
+	struct cdmac_bd rx[PKTBUFSRX];
+	struct cdmac_bd tx[TX_BUF_CNT];
+};
+
+/*
+ * DMA Buffer Descriptor alignment
+ *
+ * If the address contained in the Next Descriptor Pointer register is not
+ * 8-word aligned or reaches beyond the range of available memory, the SDMA
+ * halts processing and sets the CDMAC_BD_STCTRL_ERROR bit in the respective
+ * status register (tx_chnl_sts or rx_chnl_sts).
+ *
+ * [1]: [0]/ip_documentation/mpmc.pdf
+ *      page 161, Next Descriptor Pointer
+ */
+static struct rtx_cdmac_bd cdmac_bd __aligned(32);
+
+#if defined(CONFIG_XILINX_440) || defined(CONFIG_XILINX_405)
+
+/*
+ * Indirect DCR access operations mi{ft}dcr_xilinx() espacialy
+ * for Xilinx PowerPC implementations on FPGA.
+ *
+ * FIXME: This part should go up to arch/powerpc -- but where?
+ */
+#include <asm/processor.h>
+#define XILINX_INDIRECT_DCR_ADDRESS_REG	0
+#define XILINX_INDIRECT_DCR_ACCESS_REG	1
+inline unsigned mifdcr_xilinx(const unsigned dcrn)
+{
+	mtdcr(XILINX_INDIRECT_DCR_ADDRESS_REG, dcrn);
+	return mfdcr(XILINX_INDIRECT_DCR_ACCESS_REG);
+}
+inline void mitdcr_xilinx(const unsigned dcrn, int val)
+{
+	mtdcr(XILINX_INDIRECT_DCR_ADDRESS_REG, dcrn);
+	mtdcr(XILINX_INDIRECT_DCR_ACCESS_REG, val);
+}
+
+/* Xilinx Device Control Register (DCR) in/out accessors */
+inline unsigned ll_temac_xldcr_in32(phys_addr_t addr)
+{
+	return mifdcr_xilinx((const unsigned)addr);
+}
+inline void ll_temac_xldcr_out32(phys_addr_t addr, unsigned value)
+{
+	mitdcr_xilinx((const unsigned)addr, value);
+}
+
+void ll_temac_collect_xldcr_sdma_reg_addr(struct eth_device *dev)
+{
+	struct ll_temac *ll_temac = dev->priv;
+	phys_addr_t dmac_ctrl = ll_temac->ctrladdr;
+	phys_addr_t *ra = ll_temac->sdma_reg_addr;
+
+	ra[TX_NXTDESC_PTR]   = dmac_ctrl + TX_NXTDESC_PTR;
+	ra[TX_CURBUF_ADDR]   = dmac_ctrl + TX_CURBUF_ADDR;
+	ra[TX_CURBUF_LENGTH] = dmac_ctrl + TX_CURBUF_LENGTH;
+	ra[TX_CURDESC_PTR]   = dmac_ctrl + TX_CURDESC_PTR;
+	ra[TX_TAILDESC_PTR]  = dmac_ctrl + TX_TAILDESC_PTR;
+	ra[TX_CHNL_CTRL]     = dmac_ctrl + TX_CHNL_CTRL;
+	ra[TX_IRQ_REG]       = dmac_ctrl + TX_IRQ_REG;
+	ra[TX_CHNL_STS]      = dmac_ctrl + TX_CHNL_STS;
+	ra[RX_NXTDESC_PTR]   = dmac_ctrl + RX_NXTDESC_PTR;
+	ra[RX_CURBUF_ADDR]   = dmac_ctrl + RX_CURBUF_ADDR;
+	ra[RX_CURBUF_LENGTH] = dmac_ctrl + RX_CURBUF_LENGTH;
+	ra[RX_CURDESC_PTR]   = dmac_ctrl + RX_CURDESC_PTR;
+	ra[RX_TAILDESC_PTR]  = dmac_ctrl + RX_TAILDESC_PTR;
+	ra[RX_CHNL_CTRL]     = dmac_ctrl + RX_CHNL_CTRL;
+	ra[RX_IRQ_REG]       = dmac_ctrl + RX_IRQ_REG;
+	ra[RX_CHNL_STS]      = dmac_ctrl + RX_CHNL_STS;
+	ra[DMA_CONTROL_REG]  = dmac_ctrl + DMA_CONTROL_REG;
+}
+
+#endif /* CONFIG_XILINX_440 || ONFIG_XILINX_405 */
+
+/* Xilinx Processor Local Bus (PLB) in/out accessors */
+inline unsigned ll_temac_xlplb_in32(phys_addr_t addr)
+{
+	return in_be32((void *)addr);
+}
+inline void ll_temac_xlplb_out32(phys_addr_t addr, unsigned value)
+{
+	out_be32((void *)addr, value);
+}
+
+/* collect all register addresses for Xilinx PLB in/out accessors */
+void ll_temac_collect_xlplb_sdma_reg_addr(struct eth_device *dev)
+{
+	struct ll_temac *ll_temac = dev->priv;
+	struct sdma_ctrl *sdma_ctrl = (void *)ll_temac->ctrladdr;
+	phys_addr_t *ra = ll_temac->sdma_reg_addr;
+
+	ra[TX_NXTDESC_PTR]   = (phys_addr_t)&sdma_ctrl->tx_nxtdesc_ptr;
+	ra[TX_CURBUF_ADDR]   = (phys_addr_t)&sdma_ctrl->tx_curbuf_addr;
+	ra[TX_CURBUF_LENGTH] = (phys_addr_t)&sdma_ctrl->tx_curbuf_length;
+	ra[TX_CURDESC_PTR]   = (phys_addr_t)&sdma_ctrl->tx_curdesc_ptr;
+	ra[TX_TAILDESC_PTR]  = (phys_addr_t)&sdma_ctrl->tx_taildesc_ptr;
+	ra[TX_CHNL_CTRL]     = (phys_addr_t)&sdma_ctrl->tx_chnl_ctrl;
+	ra[TX_IRQ_REG]       = (phys_addr_t)&sdma_ctrl->tx_irq_reg;
+	ra[TX_CHNL_STS]      = (phys_addr_t)&sdma_ctrl->tx_chnl_sts;
+	ra[RX_NXTDESC_PTR]   = (phys_addr_t)&sdma_ctrl->rx_nxtdesc_ptr;
+	ra[RX_CURBUF_ADDR]   = (phys_addr_t)&sdma_ctrl->rx_curbuf_addr;
+	ra[RX_CURBUF_LENGTH] = (phys_addr_t)&sdma_ctrl->rx_curbuf_length;
+	ra[RX_CURDESC_PTR]   = (phys_addr_t)&sdma_ctrl->rx_curdesc_ptr;
+	ra[RX_TAILDESC_PTR]  = (phys_addr_t)&sdma_ctrl->rx_taildesc_ptr;
+	ra[RX_CHNL_CTRL]     = (phys_addr_t)&sdma_ctrl->rx_chnl_ctrl;
+	ra[RX_IRQ_REG]       = (phys_addr_t)&sdma_ctrl->rx_irq_reg;
+	ra[RX_CHNL_STS]      = (phys_addr_t)&sdma_ctrl->rx_chnl_sts;
+	ra[DMA_CONTROL_REG]  = (phys_addr_t)&sdma_ctrl->dma_control_reg;
+}
+
+/* Check for TX and RX channel errors. */
+static inline int ll_temac_sdma_error(struct eth_device *dev)
+{
+	int err;
+	struct ll_temac *ll_temac = dev->priv;
+	phys_addr_t *ra = ll_temac->sdma_reg_addr;
+
+	err = ll_temac->in32(ra[TX_CHNL_STS]) & CHNL_STS_ERROR;
+	err |= ll_temac->in32(ra[RX_CHNL_STS]) & CHNL_STS_ERROR;
+
+	return err;
+}
+
+int ll_temac_init_sdma(struct eth_device *dev)
+{
+	struct ll_temac *ll_temac = dev->priv;
+	struct cdmac_bd *rx_dp;
+	struct cdmac_bd *tx_dp;
+	phys_addr_t *ra = ll_temac->sdma_reg_addr;
+	int i;
+
+	printf("%s: SDMA: %d Rx buffers, %d Tx buffers\n",
+			dev->name, PKTBUFSRX, TX_BUF_CNT);
+
+	/* Initialize the Rx Buffer descriptors */
+	for (i = 0; i < PKTBUFSRX; i++) {
+		rx_dp = &cdmac_bd.rx[i];
+		memset(rx_dp, 0, sizeof(*rx_dp));
+		rx_dp->next_p = rx_dp;
+		rx_dp->buf_len = PKTSIZE_ALIGN;
+		rx_dp->phys_buf_p = (u8 *)NetRxPackets[i];
+		flush_cache((u32)rx_dp->phys_buf_p, PKTSIZE_ALIGN);
+	}
+	flush_cache((u32)cdmac_bd.rx, sizeof(cdmac_bd.rx));
+
+	/* Initialize the TX Buffer Descriptors */
+	for (i = 0; i < TX_BUF_CNT; i++) {
+		tx_dp = &cdmac_bd.tx[i];
+		memset(tx_dp, 0, sizeof(*tx_dp));
+		tx_dp->next_p = tx_dp;
+	}
+	flush_cache((u32)cdmac_bd.tx, sizeof(cdmac_bd.tx));
+
+	/* Reset index counter to the Rx and Tx Buffer descriptors */
+	rx_idx = tx_idx = 0;
+
+	/* initial Rx DMA start by writing to respective TAILDESC_PTR */
+	ll_temac->out32(ra[RX_CURDESC_PTR], (int)&cdmac_bd.rx[rx_idx]);
+	ll_temac->out32(ra[RX_TAILDESC_PTR], (int)&cdmac_bd.rx[rx_idx]);
+
+	return 0;
+}
+
+int ll_temac_halt_sdma(struct eth_device *dev)
+{
+	unsigned timeout = 50;	/* 1usec * 50 = 50usec */
+	struct ll_temac *ll_temac = dev->priv;
+	phys_addr_t *ra = ll_temac->sdma_reg_addr;
+
+	/*
+	 * Soft reset the DMA
+	 *
+	 * Quote from MPMC documentation: Writing a 1 to this field
+	 * forces the DMA engine to shutdown and reset itself. After
+	 * setting this bit, software must poll it until the bit is
+	 * cleared by the DMA. This indicates that the reset process
+	 * is done and the pipeline has been flushed.
+	 */
+	ll_temac->out32(ra[DMA_CONTROL_REG], DMA_CONTROL_RESET);
+	while (timeout && (ll_temac->in32(ra[DMA_CONTROL_REG])
+					& DMA_CONTROL_RESET)) {
+		timeout--;
+		udelay(1);
+	}
+
+	if (!timeout) {
+		printf("%s: Timeout\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
+
+int ll_temac_reset_sdma(struct eth_device *dev)
+{
+	u32 r;
+	struct ll_temac *ll_temac = dev->priv;
+	phys_addr_t *ra = ll_temac->sdma_reg_addr;
+
+	/* Soft reset the DMA.  */
+	if (ll_temac_halt_sdma(dev))
+		return -1;
+
+	/* Now clear the interrupts.  */
+	r = ll_temac->in32(ra[TX_CHNL_CTRL]);
+	r &= ~CHNL_CTRL_IRQ_MASK;
+	ll_temac->out32(ra[TX_CHNL_CTRL], r);
+
+	r = ll_temac->in32(ra[RX_CHNL_CTRL]);
+	r &= ~CHNL_CTRL_IRQ_MASK;
+	ll_temac->out32(ra[RX_CHNL_CTRL], r);
+
+	/* Now ACK pending IRQs.  */
+	ll_temac->out32(ra[TX_IRQ_REG], IRQ_REG_IRQ_MASK);
+	ll_temac->out32(ra[RX_IRQ_REG], IRQ_REG_IRQ_MASK);
+
+	/* Set tail-ptr mode, disable errors for both channels.  */
+	ll_temac->out32(ra[DMA_CONTROL_REG],
+			/* Enable use of tail pointer register */
+			DMA_CONTROL_TPE |
+			/* Disable error when 2 or 4 bit coalesce cnt overfl */
+			DMA_CONTROL_RXOCEID |
+			/* Disable error when 2 or 4 bit coalesce cnt overfl */
+			DMA_CONTROL_TXOCEID);
+
+	return 0;
+}
+
+int ll_temac_recv_sdma(struct eth_device *dev)
+{
+	int length, pb_idx;
+	struct cdmac_bd *rx_dp = &cdmac_bd.rx[rx_idx];
+	struct ll_temac *ll_temac = dev->priv;
+	phys_addr_t *ra = ll_temac->sdma_reg_addr;
+
+	if (ll_temac_sdma_error(dev)) {
+
+		if (ll_temac_reset_sdma(dev))
+			return -1;
+
+		ll_temac_init_sdma(dev);
+	}
+
+	flush_cache((u32)rx_dp, sizeof(*rx_dp));
+
+	if (!(rx_dp->sca.stctrl & CDMAC_BD_STCTRL_COMPLETED))
+		return 0;
+
+	if (rx_dp->sca.stctrl & (CDMAC_BD_STCTRL_SOP | CDMAC_BD_STCTRL_EOP)) {
+		pb_idx = rx_idx;
+		length = rx_dp->sca.app[4] & CDMAC_BD_APP4_RXBYTECNT_MASK;
+	} else {
+		pb_idx = -1;
+		length = 0;
+		printf("%s: Got part of package, unsupported (%x)\n",
+				__func__, rx_dp->sca.stctrl);
+	}
+
+	/* flip the buffer */
+	flush_cache((u32)rx_dp->phys_buf_p, length);
+
+	/* reset the current descriptor */
+	rx_dp->sca.stctrl = 0;
+	rx_dp->sca.app[4] = 0;
+	flush_cache((u32)rx_dp, sizeof(*rx_dp));
+
+	/* Find next empty buffer descriptor, preparation for next iteration */
+	rx_idx = (rx_idx + 1) % PKTBUFSRX;
+	rx_dp = &cdmac_bd.rx[rx_idx];
+	flush_cache((u32)rx_dp, sizeof(*rx_dp));
+
+	/* DMA start by writing to respective TAILDESC_PTR */
+	ll_temac->out32(ra[RX_CURDESC_PTR], (int)&cdmac_bd.rx[rx_idx]);
+	ll_temac->out32(ra[RX_TAILDESC_PTR], (int)&cdmac_bd.rx[rx_idx]);
+
+	if (length > 0 && pb_idx != -1)
+		NetReceive(NetRxPackets[pb_idx], length);
+
+	return 0;
+}
+
+int ll_temac_send_sdma(struct eth_device *dev, void *packet, int length)
+{
+	unsigned timeout = 50;	/* 1usec * 50 = 50usec */
+	struct cdmac_bd *tx_dp = &cdmac_bd.tx[tx_idx];
+	struct ll_temac *ll_temac = dev->priv;
+	phys_addr_t *ra = ll_temac->sdma_reg_addr;
+
+	if (ll_temac_sdma_error(dev)) {
+
+		if (ll_temac_reset_sdma(dev))
+			return -1;
+
+		ll_temac_init_sdma(dev);
+	}
+
+	tx_dp->phys_buf_p = (u8 *)packet;
+	tx_dp->buf_len = length;
+	tx_dp->sca.stctrl = CDMAC_BD_STCTRL_SOP | CDMAC_BD_STCTRL_EOP |
+			CDMAC_BD_STCTRL_STOP_ON_END;
+
+	flush_cache((u32)packet, length);
+	flush_cache((u32)tx_dp, sizeof(*tx_dp));
+
+	/* DMA start by writing to respective TAILDESC_PTR */
+	ll_temac->out32(ra[TX_CURDESC_PTR], (int)tx_dp);
+	ll_temac->out32(ra[TX_TAILDESC_PTR], (int)tx_dp);
+
+	/* Find next empty buffer descriptor, preparation for next iteration */
+	tx_idx = (tx_idx + 1) % TX_BUF_CNT;
+	tx_dp = &cdmac_bd.tx[tx_idx];
+
+	do {
+		flush_cache((u32)tx_dp, sizeof(*tx_dp));
+		udelay(1);
+	} while (timeout-- && !(tx_dp->sca.stctrl & CDMAC_BD_STCTRL_COMPLETED));
+
+	if (!timeout) {
+		printf("%s: Timeout\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/marvell/uboot/drivers/net/xilinx_ll_temac_sdma.h b/marvell/uboot/drivers/net/xilinx_ll_temac_sdma.h
new file mode 100644
index 0000000..41659c0
--- /dev/null
+++ b/marvell/uboot/drivers/net/xilinx_ll_temac_sdma.h
@@ -0,0 +1,277 @@
+/*
+ * Xilinx xps_ll_temac ethernet driver for u-boot
+ *
+ * SDMA sub-controller interface
+ *
+ * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
+ * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2008 - 2011 PetaLogix
+ *
+ * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
+ * Copyright (C) 2008 Nissin Systems Co.,Ltd.
+ * March 2008 created
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * [0]: http://www.xilinx.com/support/documentation
+ *
+ * [S]:	[0]/ip_documentation/xps_ll_temac.pdf
+ * [A]:	[0]/application_notes/xapp1041.pdf
+ */
+#ifndef _XILINX_LL_TEMAC_SDMA_
+#define _XILINX_LL_TEMAC_SDMA_
+
+#include <net.h>
+
+#include <asm/types.h>
+#include <asm/byteorder.h>
+
+#include <linux/compiler.h>
+
+#if !defined(__BIG_ENDIAN)
+# error LL_TEMAC requires big endianess
+#endif
+
+/*
+ * DMA Buffer Descriptor for CDMAC
+ *
+ * Used for data connection from and to (Rx/Tx) the LocalLink (LL) TEMAC via
+ * the Communications Direct Memory Access Controller (CDMAC) -- one for each.
+ *
+ * overview:
+ *      ftp://ftp.xilinx.com/pub/documentation/misc/mpmc_getting_started.pdf
+ *
+ * [1]: [0]/ip_documentation/mpmc.pdf
+ *      page 140, DMA Operation Descriptors
+ *
+ * [2]:	[0]/user_guides/ug200.pdf
+ *	page 229, DMA Controller -- Descriptor Format
+ *
+ * [3]:	[0]/ip_documentation/xps_ll_temac.pdf
+ *	page 72, Transmit LocalLink Frame Format
+ *	page 73, Receive LocalLink Frame Format
+ */
+struct cdmac_bd {
+	struct cdmac_bd *next_p;	/* Next Descriptor Pointer */
+	u8 *phys_buf_p;			/* Buffer Address */
+	u32 buf_len;			/* Buffer Length */
+	union {
+		u8 stctrl;		/* Status/Control the DMA transfer */
+		u32 app[5];		/* application specific data */
+	} __packed __aligned(1) sca;
+};
+
+/* CDMAC Descriptor Status and Control (stctrl), [1] p140, [2] p230 */
+#define CDMAC_BD_STCTRL_ERROR		(1 << 7)
+#define CDMAC_BD_STCTRL_IRQ_ON_END	(1 << 6)
+#define CDMAC_BD_STCTRL_STOP_ON_END	(1 << 5)
+#define CDMAC_BD_STCTRL_COMPLETED	(1 << 4)
+#define CDMAC_BD_STCTRL_SOP		(1 << 3)
+#define CDMAC_BD_STCTRL_EOP		(1 << 2)
+#define CDMAC_BD_STCTRL_DMACHBUSY	(1 << 1)
+
+/* CDMAC Descriptor APP0: Transmit LocalLink Footer Word 3, [3] p72 */
+#define CDMAC_BD_APP0_TXCSCNTRL		(1 << 0)
+
+/* CDMAC Descriptor APP1: Transmit LocalLink Footer Word 4, [3] p73 */
+#define CDMAC_BD_APP1_TXCSBEGIN_POS	16
+#define CDMAC_BD_APP1_TXCSBEGIN_MASK	(0xFFFF << CDMAC_BD_APP1_TXCSBEGIN_POS)
+#define CDMAC_BD_APP1_TXCSINSERT_POS	0
+#define CDMAC_BD_APP1_TXCSINSERT_MASK	(0xFFFF << CDMAC_BD_APP1_TXCSINSERT_POS)
+
+/* CDMAC Descriptor APP2: Transmit LocalLink Footer Word 5, [3] p73 */
+#define CDMAC_BD_APP2_TXCSINIT_POS	0
+#define CDMAC_BD_APP2_TXCSINIT_MASK	(0xFFFF << CDMAC_BD_APP2_TXCSINIT_POS)
+
+/* CDMAC Descriptor APP0: Receive LocalLink Footer Word 3, [3] p73 */
+#define CDMAC_BD_APP0_MADDRU_POS	0
+#define CDMAC_BD_APP0_MADDRU_MASK	(0xFFFF << CDMAC_BD_APP0_MADDRU_POS)
+
+/* CDMAC Descriptor APP1: Receive LocalLink Footer Word 4, [3] p74 */
+#define CDMAC_BD_APP1_MADDRL_POS	0
+#define CDMAC_BD_APP1_MADDRL_MASK	(~0UL << CDMAC_BD_APP1_MADDRL_POS)
+
+/* CDMAC Descriptor APP2: Receive LocalLink Footer Word 5, [3] p74 */
+#define CDMAC_BD_APP2_BCAST_FRAME	(1 << 2)
+#define CDMAC_BD_APP2_IPC_MCAST_FRAME	(1 << 1)
+#define CDMAC_BD_APP2_MAC_MCAST_FRAME	(1 << 0)
+
+/* CDMAC Descriptor APP3: Receive LocalLink Footer Word 6, [3] p74 */
+#define CDMAC_BD_APP3_TLTPID_POS	16
+#define CDMAC_BD_APP3_TLTPID_MASK	(0xFFFF << CDMAC_BD_APP3_TLTPID_POS)
+#define CDMAC_BD_APP3_RXCSRAW_POS	0
+#define CDMAC_BD_APP3_RXCSRAW_MASK	(0xFFFF << CDMAC_BD_APP3_RXCSRAW_POS)
+
+/* CDMAC Descriptor APP4: Receive LocalLink Footer Word 7, [3] p74 */
+#define CDMAC_BD_APP4_VLANTAG_POS	16
+#define CDMAC_BD_APP4_VLANTAG_MASK	(0xFFFF << CDMAC_BD_APP4_VLANTAG_POS)
+#define CDMAC_BD_APP4_RXBYTECNT_POS	0
+#define CDMAC_BD_APP4_RXBYTECNT_MASK	(0x3FFF << CDMAC_BD_APP4_RXBYTECNT_POS)
+
+/*
+ * SDMA Register Definition
+ *
+ * [0]: http://www.xilinx.com/support/documentation
+ *
+ * [1]:	[0]/ip_documentation/mpmc.pdf
+ *	page 54, SDMA Register Summary
+ *	page 160, SDMA Registers
+ *
+ * [2]:	[0]/user_guides/ug200.pdf
+ *	page 244, DMA Controller -- Programming Interface and Registers
+ */
+#define SDMA_CTRL_REGTYPE	u32
+#define SDMA_CTRL_REGSIZE	sizeof(SDMA_CTRL_REGTYPE)
+struct sdma_ctrl {
+	/* Transmit Registers */
+	SDMA_CTRL_REGTYPE tx_nxtdesc_ptr;   /* TX Next Description Pointer */
+	SDMA_CTRL_REGTYPE tx_curbuf_addr;   /* TX Current Buffer Address */
+	SDMA_CTRL_REGTYPE tx_curbuf_length; /* TX Current Buffer Length */
+	SDMA_CTRL_REGTYPE tx_curdesc_ptr;   /* TX Current Descriptor Pointer */
+	SDMA_CTRL_REGTYPE tx_taildesc_ptr;  /* TX Tail Descriptor Pointer */
+	SDMA_CTRL_REGTYPE tx_chnl_ctrl;     /* TX Channel Control */
+	SDMA_CTRL_REGTYPE tx_irq_reg;       /* TX Interrupt Register */
+	SDMA_CTRL_REGTYPE tx_chnl_sts;      /* TX Status Register */
+	/* Receive Registers */
+	SDMA_CTRL_REGTYPE rx_nxtdesc_ptr;   /* RX Next Descriptor Pointer */
+	SDMA_CTRL_REGTYPE rx_curbuf_addr;   /* RX Current Buffer Address */
+	SDMA_CTRL_REGTYPE rx_curbuf_length; /* RX Current Buffer Length */
+	SDMA_CTRL_REGTYPE rx_curdesc_ptr;   /* RX Current Descriptor Pointer */
+	SDMA_CTRL_REGTYPE rx_taildesc_ptr;  /* RX Tail Descriptor Pointer */
+	SDMA_CTRL_REGTYPE rx_chnl_ctrl;     /* RX Channel Control */
+	SDMA_CTRL_REGTYPE rx_irq_reg;       /* RX Interrupt Register */
+	SDMA_CTRL_REGTYPE rx_chnl_sts;      /* RX Status Register */
+	/* Control Registers */
+	SDMA_CTRL_REGTYPE dma_control_reg;  /* DMA Control Register */
+};
+
+#define SDMA_CTRL_REGNUMS	sizeof(struct sdma_ctrl)/SDMA_CTRL_REGSIZE
+
+/*
+ * DMAC Register Index Enumeration
+ *
+ * [2]:	http://www.xilinx.com/support/documentation/user_guides/ug200.pdf
+ *	page 244, DMA Controller -- Programming Interface and Registers
+ */
+enum dmac_ctrl {
+	/* Transmit Registers */
+	TX_NXTDESC_PTR = 0,	/* TX Next Description Pointer */
+	TX_CURBUF_ADDR,		/* TX Current Buffer Address */
+	TX_CURBUF_LENGTH,	/* TX Current Buffer Length */
+	TX_CURDESC_PTR,		/* TX Current Descriptor Pointer */
+	TX_TAILDESC_PTR,	/* TX Tail Descriptor Pointer */
+	TX_CHNL_CTRL,		/* TX Channel Control */
+	TX_IRQ_REG,		/* TX Interrupt Register */
+	TX_CHNL_STS,		/* TX Status Register */
+	/* Receive Registers */
+	RX_NXTDESC_PTR,		/* RX Next Descriptor Pointer */
+	RX_CURBUF_ADDR,		/* RX Current Buffer Address */
+	RX_CURBUF_LENGTH,	/* RX Current Buffer Length */
+	RX_CURDESC_PTR,		/* RX Current Descriptor Pointer */
+	RX_TAILDESC_PTR,	/* RX Tail Descriptor Pointer */
+	RX_CHNL_CTRL,		/* RX Channel Control */
+	RX_IRQ_REG,		/* RX Interrupt Register */
+	RX_CHNL_STS,		/* RX Status Register */
+	/* Control Registers */
+	DMA_CONTROL_REG		/* DMA Control Register */
+};
+
+/* Rx/Tx Channel Control Register (*_chnl_ctrl), [1] p163, [2] p246/p252 */
+#define CHNL_CTRL_ITO_POS	24
+#define CHNL_CTRL_ITO_MASK	(0xFF << CHNL_CTRL_ITO_POS)
+#define CHNL_CTRL_IC_POS	16
+#define CHNL_CTRL_IC_MASK	(0xFF << CHNL_CTRL_IC_POS)
+#define CHNL_CTRL_MSBADDR_POS	12
+#define CHNL_CTRL_MSBADDR_MASK	(0xF << CHNL_CTRL_MSBADDR_POS)
+#define CHNL_CTRL_AME		(1 << 11)
+#define CHNL_CTRL_OBWC		(1 << 10)
+#define CHNL_CTRL_IOE		(1 << 9)
+#define CHNL_CTRL_LIC		(1 << 8)
+#define CHNL_CTRL_IE		(1 << 7)
+#define CHNL_CTRL_IEE		(1 << 2)
+#define CHNL_CTRL_IDE		(1 << 1)
+#define CHNL_CTRL_ICE		(1 << 0)
+
+/* All interrupt enable bits */
+#define CHNL_CTRL_IRQ_MASK	(CHNL_CTRL_IE | \
+				 CHNL_CTRL_IEE | \
+				 CHNL_CTRL_IDE | \
+				 CHNL_CTRL_ICE)
+
+/* Rx/Tx Interrupt Status Register (*_irq_reg), [1] p164, [2] p247/p253 */
+#define IRQ_REG_DTV_POS		24
+#define IRQ_REG_DTV_MASK	(0xFF << IRQ_REG_DTV_POS)
+#define IRQ_REG_CCV_POS		16
+#define IRQ_REG_CCV_MASK	(0xFF << IRQ_REG_CCV_POS)
+#define IRQ_REG_WRCQ_EMPTY	(1 << 14)
+#define IRQ_REG_CIC_POS		10
+#define IRQ_REG_CIC_MASK	(0xF << IRQ_REG_CIC_POS)
+#define IRQ_REG_DIC_POS		8
+#define IRQ_REG_DIC_MASK	(3 << 8)
+#define IRQ_REG_PLB_RD_NMI	(1 << 4)
+#define IRQ_REG_PLB_WR_NMI	(1 << 3)
+#define IRQ_REG_EI		(1 << 2)
+#define IRQ_REG_DI		(1 << 1)
+#define IRQ_REG_CI		(1 << 0)
+
+/* All interrupt bits */
+#define IRQ_REG_IRQ_MASK	(IRQ_REG_PLB_RD_NMI | \
+				 IRQ_REG_PLB_WR_NMI | \
+				 IRQ_REG_EI | IRQ_REG_DI | IRQ_REG_CI)
+
+/* Rx/Tx Channel Status Register (*_chnl_sts), [1] p165, [2] p249/p255 */
+#define CHNL_STS_ERROR_TAIL	(1 << 21)
+#define CHNL_STS_ERROR_CMP	(1 << 20)
+#define CHNL_STS_ERROR_ADDR	(1 << 19)
+#define CHNL_STS_ERROR_NXTP	(1 << 18)
+#define CHNL_STS_ERROR_CURP	(1 << 17)
+#define CHNL_STS_ERROR_BSYWR	(1 << 16)
+#define CHNL_STS_ERROR		(1 << 7)
+#define CHNL_STS_IOE		(1 << 6)
+#define CHNL_STS_SOE		(1 << 5)
+#define CHNL_STS_CMPLT		(1 << 4)
+#define CHNL_STS_SOP		(1 << 3)
+#define CHNL_STS_EOP		(1 << 2)
+#define CHNL_STS_EBUSY		(1 << 1)
+
+/* DMA Control Register (dma_control_reg), [1] p166, [2] p256 */
+#define DMA_CONTROL_PLBED	(1 << 5)
+#define DMA_CONTROL_RXOCEID	(1 << 4)
+#define DMA_CONTROL_TXOCEID	(1 << 3)
+#define DMA_CONTROL_TPE		(1 << 2)
+#define DMA_CONTROL_RESET	(1 << 0)
+
+#if defined(CONFIG_XILINX_440) || defined(CONFIG_XILINX_405)
+
+/* Xilinx Device Control Register (DCR) in/out accessors */
+unsigned ll_temac_xldcr_in32(phys_addr_t addr);
+void ll_temac_xldcr_out32(phys_addr_t addr, unsigned value);
+
+/* collect all register addresses for Xilinx DCR in/out accessors */
+void ll_temac_collect_xldcr_sdma_reg_addr(struct eth_device *dev);
+
+#endif /* CONFIG_XILINX_440 || CONFIG_XILINX_405 */
+
+/* Xilinx Processor Local Bus (PLB) in/out accessors */
+unsigned ll_temac_xlplb_in32(phys_addr_t base);
+void ll_temac_xlplb_out32(phys_addr_t base, unsigned value);
+
+/* collect all register addresses for Xilinx PLB in/out accessors */
+void ll_temac_collect_xlplb_sdma_reg_addr(struct eth_device *dev);
+
+/* initialize both Rx/Tx buffer descriptors */
+int ll_temac_init_sdma(struct eth_device *dev);
+
+/* halt both Rx/Tx transfers */
+int ll_temac_halt_sdma(struct eth_device *dev);
+
+/* reset SDMA and IRQ, disable interrupts and errors */
+int ll_temac_reset_sdma(struct eth_device *dev);
+
+/* receive buffered data from SDMA (polling ISR) */
+int ll_temac_recv_sdma(struct eth_device *dev);
+
+/* send buffered data to SDMA */
+int ll_temac_send_sdma(struct eth_device *dev, void *packet, int length);
+
+#endif /* _XILINX_LL_TEMAC_SDMA_ */
diff --git a/marvell/uboot/drivers/net/zynq_gem.c b/marvell/uboot/drivers/net/zynq_gem.c
new file mode 100644
index 0000000..6a017a8
--- /dev/null
+++ b/marvell/uboot/drivers/net/zynq_gem.c
@@ -0,0 +1,529 @@
+/*
+ * (C) Copyright 2011 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * Based on Xilinx gmac driver:
+ * (C) Copyright 2011 Xilinx
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <net.h>
+#include <config.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <phy.h>
+#include <miiphy.h>
+#include <watchdog.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+
+#if !defined(CONFIG_PHYLIB)
+# error XILINX_GEM_ETHERNET requires PHYLIB
+#endif
+
+/* Bit/mask specification */
+#define ZYNQ_GEM_PHYMNTNC_OP_MASK	0x40020000 /* operation mask bits */
+#define ZYNQ_GEM_PHYMNTNC_OP_R_MASK	0x20000000 /* read operation */
+#define ZYNQ_GEM_PHYMNTNC_OP_W_MASK	0x10000000 /* write operation */
+#define ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK	23 /* Shift bits for PHYAD */
+#define ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK	18 /* Shift bits for PHREG */
+
+#define ZYNQ_GEM_RXBUF_EOF_MASK		0x00008000 /* End of frame. */
+#define ZYNQ_GEM_RXBUF_SOF_MASK		0x00004000 /* Start of frame. */
+#define ZYNQ_GEM_RXBUF_LEN_MASK		0x00003FFF /* Mask for length field */
+
+#define ZYNQ_GEM_RXBUF_WRAP_MASK	0x00000002 /* Wrap bit, last BD */
+#define ZYNQ_GEM_RXBUF_NEW_MASK		0x00000001 /* Used bit.. */
+#define ZYNQ_GEM_RXBUF_ADD_MASK		0xFFFFFFFC /* Mask for address */
+
+/* Wrap bit, last descriptor */
+#define ZYNQ_GEM_TXBUF_WRAP_MASK	0x40000000
+#define ZYNQ_GEM_TXBUF_LAST_MASK	0x00008000 /* Last buffer */
+
+#define ZYNQ_GEM_NWCTRL_TXEN_MASK	0x00000008 /* Enable transmit */
+#define ZYNQ_GEM_NWCTRL_RXEN_MASK	0x00000004 /* Enable receive */
+#define ZYNQ_GEM_NWCTRL_MDEN_MASK	0x00000010 /* Enable MDIO port */
+#define ZYNQ_GEM_NWCTRL_STARTTX_MASK	0x00000200 /* Start tx (tx_go) */
+
+#define ZYNQ_GEM_NWCFG_SPEED100		0x000000001 /* 100 Mbps operation */
+#define ZYNQ_GEM_NWCFG_SPEED1000	0x000000400 /* 1Gbps operation */
+#define ZYNQ_GEM_NWCFG_FDEN		0x000000002 /* Full Duplex mode */
+#define ZYNQ_GEM_NWCFG_FSREM		0x000020000 /* FCS removal */
+#define ZYNQ_GEM_NWCFG_MDCCLKDIV	0x000080000 /* Div pclk by 32, 80MHz */
+#define ZYNQ_GEM_NWCFG_MDCCLKDIV2	0x0000c0000 /* Div pclk by 48, 120MHz */
+
+#define ZYNQ_GEM_NWCFG_INIT		(ZYNQ_GEM_NWCFG_FDEN | \
+					ZYNQ_GEM_NWCFG_FSREM | \
+					ZYNQ_GEM_NWCFG_MDCCLKDIV)
+
+#define ZYNQ_GEM_NWSR_MDIOIDLE_MASK	0x00000004 /* PHY management idle */
+
+#define ZYNQ_GEM_DMACR_BLENGTH		0x00000004 /* INCR4 AHB bursts */
+/* Use full configured addressable space (8 Kb) */
+#define ZYNQ_GEM_DMACR_RXSIZE		0x00000300
+/* Use full configured addressable space (4 Kb) */
+#define ZYNQ_GEM_DMACR_TXSIZE		0x00000400
+/* Set with binary 00011000 to use 1536 byte(1*max length frame/buffer) */
+#define ZYNQ_GEM_DMACR_RXBUF		0x00180000
+
+#define ZYNQ_GEM_DMACR_INIT		(ZYNQ_GEM_DMACR_BLENGTH | \
+					ZYNQ_GEM_DMACR_RXSIZE | \
+					ZYNQ_GEM_DMACR_TXSIZE | \
+					ZYNQ_GEM_DMACR_RXBUF)
+
+/* Use MII register 1 (MII status register) to detect PHY */
+#define PHY_DETECT_REG  1
+
+/* Mask used to verify certain PHY features (or register contents)
+ * in the register above:
+ *  0x1000: 10Mbps full duplex support
+ *  0x0800: 10Mbps half duplex support
+ *  0x0008: Auto-negotiation support
+ */
+#define PHY_DETECT_MASK 0x1808
+
+/* TX BD status masks */
+#define ZYNQ_GEM_TXBUF_FRMLEN_MASK	0x000007ff
+#define ZYNQ_GEM_TXBUF_EXHAUSTED	0x08000000
+#define ZYNQ_GEM_TXBUF_UNDERRUN		0x10000000
+
+/* Device registers */
+struct zynq_gem_regs {
+	u32 nwctrl; /* Network Control reg */
+	u32 nwcfg; /* Network Config reg */
+	u32 nwsr; /* Network Status reg */
+	u32 reserved1;
+	u32 dmacr; /* DMA Control reg */
+	u32 txsr; /* TX Status reg */
+	u32 rxqbase; /* RX Q Base address reg */
+	u32 txqbase; /* TX Q Base address reg */
+	u32 rxsr; /* RX Status reg */
+	u32 reserved2[2];
+	u32 idr; /* Interrupt Disable reg */
+	u32 reserved3;
+	u32 phymntnc; /* Phy Maintaince reg */
+	u32 reserved4[18];
+	u32 hashl; /* Hash Low address reg */
+	u32 hashh; /* Hash High address reg */
+#define LADDR_LOW	0
+#define LADDR_HIGH	1
+	u32 laddr[4][LADDR_HIGH + 1]; /* Specific1 addr low/high reg */
+	u32 match[4]; /* Type ID1 Match reg */
+	u32 reserved6[18];
+	u32 stat[44]; /* Octects transmitted Low reg - stat start */
+};
+
+/* BD descriptors */
+struct emac_bd {
+	u32 addr; /* Next descriptor pointer */
+	u32 status;
+};
+
+#define RX_BUF 3
+/* Page table entries are set to 1MB, or multiples of 1MB
+ * (not < 1MB). driver uses less bd's so use 1MB bdspace.
+ */
+#define BD_SPACE	0x100000
+/* BD separation space */
+#define BD_SEPRN_SPACE	64
+
+/* Initialized, rxbd_current, rx_first_buf must be 0 after init */
+struct zynq_gem_priv {
+	struct emac_bd *tx_bd;
+	struct emac_bd *rx_bd;
+	char *rxbuffers;
+	u32 rxbd_current;
+	u32 rx_first_buf;
+	int phyaddr;
+	u32 emio;
+	int init;
+	struct phy_device *phydev;
+	struct mii_dev *bus;
+};
+
+static inline int mdio_wait(struct eth_device *dev)
+{
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+	u32 timeout = 200;
+
+	/* Wait till MDIO interface is ready to accept a new transaction. */
+	while (--timeout) {
+		if (readl(&regs->nwsr) & ZYNQ_GEM_NWSR_MDIOIDLE_MASK)
+			break;
+		WATCHDOG_RESET();
+	}
+
+	if (!timeout) {
+		printf("%s: Timeout\n", __func__);
+		return 1;
+	}
+
+	return 0;
+}
+
+static u32 phy_setup_op(struct eth_device *dev, u32 phy_addr, u32 regnum,
+							u32 op, u16 *data)
+{
+	u32 mgtcr;
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+
+	if (mdio_wait(dev))
+		return 1;
+
+	/* Construct mgtcr mask for the operation */
+	mgtcr = ZYNQ_GEM_PHYMNTNC_OP_MASK | op |
+		(phy_addr << ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK) |
+		(regnum << ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK) | *data;
+
+	/* Write mgtcr and wait for completion */
+	writel(mgtcr, &regs->phymntnc);
+
+	if (mdio_wait(dev))
+		return 1;
+
+	if (op == ZYNQ_GEM_PHYMNTNC_OP_R_MASK)
+		*data = readl(&regs->phymntnc);
+
+	return 0;
+}
+
+static u32 phyread(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 *val)
+{
+	return phy_setup_op(dev, phy_addr, regnum,
+				ZYNQ_GEM_PHYMNTNC_OP_R_MASK, val);
+}
+
+static u32 phywrite(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 data)
+{
+	return phy_setup_op(dev, phy_addr, regnum,
+				ZYNQ_GEM_PHYMNTNC_OP_W_MASK, &data);
+}
+
+static void phy_detection(struct eth_device *dev)
+{
+	int i;
+	u16 phyreg;
+	struct zynq_gem_priv *priv = dev->priv;
+
+	if (priv->phyaddr != -1) {
+		phyread(dev, priv->phyaddr, PHY_DETECT_REG, &phyreg);
+		if ((phyreg != 0xFFFF) &&
+		    ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
+			/* Found a valid PHY address */
+			debug("Default phy address %d is valid\n",
+			      priv->phyaddr);
+			return;
+		} else {
+			debug("PHY address is not setup correctly %d\n",
+			      priv->phyaddr);
+			priv->phyaddr = -1;
+		}
+	}
+
+	debug("detecting phy address\n");
+	if (priv->phyaddr == -1) {
+		/* detect the PHY address */
+		for (i = 31; i >= 0; i--) {
+			phyread(dev, i, PHY_DETECT_REG, &phyreg);
+			if ((phyreg != 0xFFFF) &&
+			    ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
+				/* Found a valid PHY address */
+				priv->phyaddr = i;
+				debug("Found valid phy address, %d\n", i);
+				return;
+			}
+		}
+	}
+	printf("PHY is not detected\n");
+}
+
+static int zynq_gem_setup_mac(struct eth_device *dev)
+{
+	u32 i, macaddrlow, macaddrhigh;
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+
+	/* Set the MAC bits [31:0] in BOT */
+	macaddrlow = dev->enetaddr[0];
+	macaddrlow |= dev->enetaddr[1] << 8;
+	macaddrlow |= dev->enetaddr[2] << 16;
+	macaddrlow |= dev->enetaddr[3] << 24;
+
+	/* Set MAC bits [47:32] in TOP */
+	macaddrhigh = dev->enetaddr[4];
+	macaddrhigh |= dev->enetaddr[5] << 8;
+
+	for (i = 0; i < 4; i++) {
+		writel(0, &regs->laddr[i][LADDR_LOW]);
+		writel(0, &regs->laddr[i][LADDR_HIGH]);
+		/* Do not use MATCHx register */
+		writel(0, &regs->match[i]);
+	}
+
+	writel(macaddrlow, &regs->laddr[0][LADDR_LOW]);
+	writel(macaddrhigh, &regs->laddr[0][LADDR_HIGH]);
+
+	return 0;
+}
+
+static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
+{
+	u32 i, rclk, clk = 0;
+	struct phy_device *phydev;
+	const u32 stat_size = (sizeof(struct zynq_gem_regs) -
+				offsetof(struct zynq_gem_regs, stat)) / 4;
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+	struct zynq_gem_priv *priv = dev->priv;
+	const u32 supported = SUPPORTED_10baseT_Half |
+			SUPPORTED_10baseT_Full |
+			SUPPORTED_100baseT_Half |
+			SUPPORTED_100baseT_Full |
+			SUPPORTED_1000baseT_Half |
+			SUPPORTED_1000baseT_Full;
+
+	if (!priv->init) {
+		/* Disable all interrupts */
+		writel(0xFFFFFFFF, &regs->idr);
+
+		/* Disable the receiver & transmitter */
+		writel(0, &regs->nwctrl);
+		writel(0, &regs->txsr);
+		writel(0, &regs->rxsr);
+		writel(0, &regs->phymntnc);
+
+		/* Clear the Hash registers for the mac address
+		 * pointed by AddressPtr
+		 */
+		writel(0x0, &regs->hashl);
+		/* Write bits [63:32] in TOP */
+		writel(0x0, &regs->hashh);
+
+		/* Clear all counters */
+		for (i = 0; i <= stat_size; i++)
+			readl(&regs->stat[i]);
+
+		/* Setup RxBD space */
+		memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd));
+
+		for (i = 0; i < RX_BUF; i++) {
+			priv->rx_bd[i].status = 0xF0000000;
+			priv->rx_bd[i].addr =
+					((u32)(priv->rxbuffers) +
+							(i * PKTSIZE_ALIGN));
+		}
+		/* WRAP bit to last BD */
+		priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
+		/* Write RxBDs to IP */
+		writel((u32)priv->rx_bd, &regs->rxqbase);
+
+		/* Setup for DMA Configuration register */
+		writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);
+
+		/* Setup for Network Control register, MDIO, Rx and Tx enable */
+		setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK);
+
+		priv->init++;
+	}
+
+	phy_detection(dev);
+
+	/* interface - look at tsec */
+	phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0);
+
+	phydev->supported = supported | ADVERTISED_Pause |
+			    ADVERTISED_Asym_Pause;
+	phydev->advertising = phydev->supported;
+	priv->phydev = phydev;
+	phy_config(phydev);
+	phy_startup(phydev);
+
+	switch (phydev->speed) {
+	case SPEED_1000:
+		writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED1000,
+		       &regs->nwcfg);
+		rclk = (0 << 4) | (1 << 0);
+		clk = (1 << 20) | (8 << 8) | (0 << 4) | (1 << 0);
+		break;
+	case SPEED_100:
+		clrsetbits_le32(&regs->nwcfg, ZYNQ_GEM_NWCFG_SPEED1000,
+				ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100);
+		rclk = 1 << 0;
+		clk = (5 << 20) | (8 << 8) | (0 << 4) | (1 << 0);
+		break;
+	case SPEED_10:
+		rclk = 1 << 0;
+		/* FIXME untested */
+		clk = (5 << 20) | (8 << 8) | (0 << 4) | (1 << 0);
+		break;
+	}
+
+	/* Change the rclk and clk only not using EMIO interface */
+	if (!priv->emio)
+		zynq_slcr_gem_clk_setup(dev->iobase !=
+					ZYNQ_GEM_BASEADDR0, rclk, clk);
+
+	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
+					ZYNQ_GEM_NWCTRL_TXEN_MASK);
+
+	return 0;
+}
+
+static int zynq_gem_send(struct eth_device *dev, void *ptr, int len)
+{
+	u32 addr, size;
+	struct zynq_gem_priv *priv = dev->priv;
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+
+	/* setup BD */
+	writel((u32)priv->tx_bd, &regs->txqbase);
+
+	/* Setup Tx BD */
+	memset(priv->tx_bd, 0, sizeof(struct emac_bd));
+
+	priv->tx_bd->addr = (u32)ptr;
+	priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) |
+				ZYNQ_GEM_TXBUF_LAST_MASK;
+
+	addr = (u32) ptr;
+	addr &= ~(ARCH_DMA_MINALIGN - 1);
+	size = roundup(len, ARCH_DMA_MINALIGN);
+	flush_dcache_range(addr, addr + size);
+	barrier();
+
+	/* Start transmit */
+	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK);
+
+	/* Read TX BD status */
+	if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_UNDERRUN)
+		printf("TX underrun\n");
+	if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_EXHAUSTED)
+		printf("TX buffers exhausted in mid frame\n");
+
+	return 0;
+}
+
+/* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */
+static int zynq_gem_recv(struct eth_device *dev)
+{
+	int frame_len;
+	struct zynq_gem_priv *priv = dev->priv;
+	struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current];
+	struct emac_bd *first_bd;
+
+	if (!(current_bd->addr & ZYNQ_GEM_RXBUF_NEW_MASK))
+		return 0;
+
+	if (!(current_bd->status &
+			(ZYNQ_GEM_RXBUF_SOF_MASK | ZYNQ_GEM_RXBUF_EOF_MASK))) {
+		printf("GEM: SOF or EOF not set for last buffer received!\n");
+		return 0;
+	}
+
+	frame_len = current_bd->status & ZYNQ_GEM_RXBUF_LEN_MASK;
+	if (frame_len) {
+		u32 addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK;
+		addr &= ~(ARCH_DMA_MINALIGN - 1);
+		u32 size = roundup(frame_len, ARCH_DMA_MINALIGN);
+		invalidate_dcache_range(addr, addr + size);
+
+		NetReceive((u8 *)addr, frame_len);
+
+		if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK)
+			priv->rx_first_buf = priv->rxbd_current;
+		else {
+			current_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK;
+			current_bd->status = 0xF0000000; /* FIXME */
+		}
+
+		if (current_bd->status & ZYNQ_GEM_RXBUF_EOF_MASK) {
+			first_bd = &priv->rx_bd[priv->rx_first_buf];
+			first_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK;
+			first_bd->status = 0xF0000000;
+		}
+
+		if ((++priv->rxbd_current) >= RX_BUF)
+			priv->rxbd_current = 0;
+	}
+
+	return frame_len;
+}
+
+static void zynq_gem_halt(struct eth_device *dev)
+{
+	struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
+
+	clrsetbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
+						ZYNQ_GEM_NWCTRL_TXEN_MASK, 0);
+}
+
+static int zynq_gem_miiphyread(const char *devname, uchar addr,
+							uchar reg, ushort *val)
+{
+	struct eth_device *dev = eth_get_dev();
+	int ret;
+
+	ret = phyread(dev, addr, reg, val);
+	debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, *val);
+	return ret;
+}
+
+static int zynq_gem_miiphy_write(const char *devname, uchar addr,
+							uchar reg, ushort val)
+{
+	struct eth_device *dev = eth_get_dev();
+
+	debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, val);
+	return phywrite(dev, addr, reg, val);
+}
+
+int zynq_gem_initialize(bd_t *bis, int base_addr, int phy_addr, u32 emio)
+{
+	struct eth_device *dev;
+	struct zynq_gem_priv *priv;
+	void *bd_space;
+
+	dev = calloc(1, sizeof(*dev));
+	if (dev == NULL)
+		return -1;
+
+	dev->priv = calloc(1, sizeof(struct zynq_gem_priv));
+	if (dev->priv == NULL) {
+		free(dev);
+		return -1;
+	}
+	priv = dev->priv;
+
+	/* Align rxbuffers to ARCH_DMA_MINALIGN */
+	priv->rxbuffers = memalign(ARCH_DMA_MINALIGN, RX_BUF * PKTSIZE_ALIGN);
+	memset(priv->rxbuffers, 0, RX_BUF * PKTSIZE_ALIGN);
+
+	/* Align bd_space to 1MB */
+	bd_space = memalign(1 << MMU_SECTION_SHIFT, BD_SPACE);
+	mmu_set_region_dcache_behaviour((u32)bd_space, BD_SPACE, DCACHE_OFF);
+
+	/* Initialize the bd spaces for tx and rx bd's */
+	priv->tx_bd = (struct emac_bd *)bd_space;
+	priv->rx_bd = (struct emac_bd *)((u32)bd_space + BD_SEPRN_SPACE);
+
+	priv->phyaddr = phy_addr;
+	priv->emio = emio;
+
+	sprintf(dev->name, "Gem.%x", base_addr);
+
+	dev->iobase = base_addr;
+
+	dev->init = zynq_gem_init;
+	dev->halt = zynq_gem_halt;
+	dev->send = zynq_gem_send;
+	dev->recv = zynq_gem_recv;
+	dev->write_hwaddr = zynq_gem_setup_mac;
+
+	eth_register(dev);
+
+	miiphy_register(dev->name, zynq_gem_miiphyread, zynq_gem_miiphy_write);
+	priv->bus = miiphy_get_dev_by_name(dev->name);
+
+	return 1;
+}