[U-Boot-Users] [PATCH] AX88180: new gigabit network driver

Mike Frysinger vapier at gentoo.org
Sun Jun 1 06:58:35 CEST 2008


From: Michael Hennerich <michael.hennerich at analog.com>

A new driver for the AXIS AX88180 gigabit ethernet chip.

Signed-off-by: Michael Hennerich <michael.hennerich at analog.com>
Signed-off-by: Mike Frysinger <vapier at gentoo.org>
---
 drivers/net/Makefile  |    1 +
 drivers/net/ax88180.c |  943 +++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/ax88180.h |  348 ++++++++++++++++++
 3 files changed, 1292 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/ax88180.c
 create mode 100644 drivers/net/ax88180.h

diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 5b031c9..26d941a 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk
 LIB	:= $(obj)libnet.a
 
 COBJS-y += 3c589.o
+COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o
 COBJS-y += bcm570x.o bcm570x_autoneg.o 5701rls.o
 COBJS-$(CONFIG_BFIN_MAC) += bfin_mac.o
 COBJS-y += cs8900.o
diff --git a/drivers/net/ax88180.c b/drivers/net/ax88180.c
new file mode 100644
index 0000000..e6ad5d9
--- /dev/null
+++ b/drivers/net/ax88180.c
@@ -0,0 +1,943 @@
+/* ax88180: ASIX AX88180 Non-PCI Gigabit Ethernet u-boot driver
+ * Licensed under the GPL-2.
+ */
+/*
+ * ========================================================================
+ * ASIX AX88180 Non-PCI 16/32-bit Gigabit Ethernet Linux Driver
+ *
+ * The AX88180 Ethernet controller is high performance and highly
+ * integrated local CPU bus Ethernet controllers 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
+ * Purpose     : This file is the main file.
+ * Author      : Allan Chou <allan at asix.com.tw>
+ * Date        : 2006-09-06
+ * Notes       :
+ * History     :
+ * $Log:$
+ * 1.0.0	2006-09-06
+ * New release for AX88180 US2 chip.
+ *
+ * ========================================================================
+ */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+
+#if defined(CONFIG_S3C2440A_SMDK)
+#include <s3c2440.h>
+#endif
+
+#include "ax88180.h"
+
+/*
+ * ===========================================================================
+ * <<<<<<             Local SubProgram Declaration              >>>>>>
+ * ===========================================================================
+ */
+static void ax88180_rx_handler(void);
+static void ax88180_PHY_initial(void);
+static void ax88180_meida_config(void);
+static void get_CicadaPHY_meida_mode(void);
+static void get_MarvellPHY_meida_mode(void);
+
+/*
+ * ===========================================================================
+ * <<<<<<             Declare Macro/Structure Definition        >>>>>>
+ * ===========================================================================
+ */
+
+typedef struct _AX88180_PRIVATE {
+	unsigned long PhyAddr;
+	unsigned long PhyID0;
+	unsigned int MediaMode;
+	unsigned int RealMediaMode;
+	unsigned long RxFilterMode;
+	unsigned long FirstTxDesc;
+	unsigned long NextTxDesc;
+	unsigned long rxbuf_overflow_count;
+} AX88180_PRIVATE;
+
+#define mdelay(n)       udelay((n)*1000)
+
+#define	PRINTK(flag, args...) if (flag & DEBUG_FLAGS) printf(args)
+
+/* Access RXBUFFER_START/TXBUFFER_START to read RX buffer/write TX buffer */
+
+#ifdef CONFIG_DRIVER_AX88180_16BIT
+
+#define MACREG_OFFSET_16BIT	(- 0xDD00)
+#define RXBUF_OFFSET_16BIT	(0x2000)
+#define TXBUF_OFFSET_16BIT	(- 0x7000)
+
+#if defined(__bfin__)
+#include <asm/io.h>
+#define READ_RXBUF(data) data = readw(AX88180_BASE + RXBUFFER_START + RXBUF_OFFSET_16BIT)
+#define WRITE_TXBUF(data) writew(data, AX88180_BASE + TXBUFFER_START + TXBUF_OFFSET_16BIT)
+#define READ_MACREG(regaddr, regdata) regdata = readw(AX88180_BASE + MACREG_OFFSET_16BIT + regaddr)
+#define WRITE_MACREG(regaddr, regdata) writew(regdata, AX88180_BASE + MACREG_OFFSET_16BIT + regaddr);
+#else				/* defined(__bfin__) */
+#define READ_RXBUF(data)	data = *(volatile unsigned short *)(AX88180_BASE + RXBUFFER_START)
+#define WRITE_TXBUF(data)	*(volatile unsigned short *)(AX88180_BASE + TXBUFFER_START) = data
+#define READ_MACREG(regaddr, regdata) regdata = *(volatile unsigned short*)(AX88180_BASE + regaddr)
+#define WRITE_MACREG(regaddr, regdata) *(volatile unsigned short*)(AX88180_BASE + regaddr) = regdata;
+#endif				/* defined(__bfin__) */
+
+#else				/* CONFIG_DRIVER_AX88180_16BIT */
+
+#if defined(__bfin__)
+#include <asm/io.h>
+#define READ_RXBUF(data) data = readl(AX88180_BASE + RXBUFFER_START)
+#define WRITE_TXBUF(data) writel(data, AX88180_BASE + TXBUFFER_START)
+#define READ_MACREG(regaddr, regdata) regdata = readl(AX88180_BASE + regaddr)
+#define WRITE_MACREG(regaddr, regdata) writel(regdata, AX88180_BASE + regaddr);
+#else				/* defined(__bfin__) */
+#define READ_RXBUF(data)	data = *(volatile unsigned long *)(AX88180_BASE + RXBUFFER_START)
+#define WRITE_TXBUF(data)	*(volatile unsigned long *)(AX88180_BASE + TXBUFFER_START) = data
+#define READ_MACREG(regaddr, regdata) regdata = *(volatile unsigned long*)(AX88180_BASE + regaddr)
+#define WRITE_MACREG(regaddr, regdata) *(volatile unsigned long*)(AX88180_BASE + regaddr) = regdata;
+#endif				/* defined(__bfin__) */
+
+#endif				/* CONFIG_DRIVER_AX88180_16BIT */
+
+#define READ_PHYREG(phyaddr, regaddr, regdata) { \
+	unsigned long tmpval1, k1; \
+	WRITE_MACREG(MDIOCTRL, READ_PHY | (regaddr << 8) | phyaddr); \
+	for (k1 = 0; k1 < 10000; k1++) { \
+		READ_MACREG(MDIOCTRL, tmpval1); \
+		if ((tmpval1 & READ_PHY) == 0) { \
+			break; \
+		} \
+		udelay(1); \
+	} \
+	READ_MACREG(MDIODP, regdata); \
+}
+#define WRITE_PHYREG(phyaddr, regaddr, regdata) { \
+	unsigned long tmpval2, k2; \
+	WRITE_MACREG(MDIODP, regdata); \
+	WRITE_MACREG(MDIOCTRL, WRITE_PHY | (regaddr << 8) | phyaddr); \
+	for (k2 = 0; k2 < 10000; k2++) { \
+		READ_MACREG(MDIOCTRL, tmpval2); \
+		if ((tmpval2 & WRITE_PHY) == 0) { \
+			break; \
+		} \
+		udelay(1); \
+	} \
+}
+
+#define RESET_MAC { \
+	unsigned long tmpval3; \
+	WRITE_MACREG(MISC, MISC_RESET_MAC); \
+	READ_MACREG(MISC, tmpval3); \
+	WRITE_MACREG(MISC, MISC_NORMAL); \
+	WRITE_MACREG(RXINDICATOR, DEFAULT_RXINDICATOR); \
+	WRITE_MACREG(TXCMD, DEFAULT_TXCMD); \
+	WRITE_MACREG(TXBS, DEFAULT_TXBS); \
+	WRITE_MACREG(TXDES0, DEFAULT_TXDES0); \
+	WRITE_MACREG(TXDES1, DEFAULT_TXDES1); \
+	WRITE_MACREG(TXDES2, DEFAULT_TXDES2); \
+	WRITE_MACREG(TXDES3, DEFAULT_TXDES3); \
+	WRITE_MACREG(TXCFG, DEFAULT_TXCFG); \
+	WRITE_MACREG(MACCFG2, DEFAULT_MACCFG2); \
+	WRITE_MACREG(MACCFG3, DEFAULT_MACCFG3); \
+	WRITE_MACREG(TXLEN, DEFAULT_TXLEN); \
+	WRITE_MACREG(TXPAUT, DEFAULT_TXPAUT); \
+	WRITE_MACREG(RXBTHD0, DEFAULT_RXBTHD0); \
+	WRITE_MACREG(RXBTHD1, DEFAULT_RXBTHD1); \
+	WRITE_MACREG(RXFULTHD, DEFAULT_RXFULTHD); \
+	WRITE_MACREG(DOGTHD0, DEFAULT_DOGTHD0); \
+	WRITE_MACREG(DOGTHD1, DEFAULT_DOGTHD1); \
+}
+#define RESET_PHY { \
+	unsigned long tmpval3a, k3a; \
+	WRITE_PHYREG(axlocal.PhyAddr, BMCR, PHY_RESET); \
+	for (k3a = 0; k3a < 500; k3a++) { \
+		READ_PHYREG(axlocal.PhyAddr, BMCR, tmpval3a); \
+		if (!(tmpval3a & PHY_RESET)) \
+			break; \
+		mdelay(1); \
+	} \
+}
+
+#define	INIT_TXRX_VARIABLES { \
+	axlocal.FirstTxDesc = TXDP0; \
+	axlocal.NextTxDesc = TXDP0; \
+	axlocal.rxbuf_overflow_count = 0; \
+}
+
+#define	ENABLE_INTERRUPT	WRITE_MACREG(IMR, DEFAULT_IMR)
+#define	DISABLE_INTERRUPT	WRITE_MACREG(IMR, CLEAR_IMR)
+
+#define	START_READ_RXBUFF 	WRITE_MACREG(RXINDICATOR, RX_START_READ)
+#define	STOP_READ_RXBUFF 	WRITE_MACREG(RXINDICATOR, RX_STOP_READ)
+
+/* Display all AX88180 MAC registers onto console screen */
+#define	DISPLAY_ALLMACREG { \
+	unsigned long tmpval4; \
+	int k4; \
+	PRINTK(DEBUG_MSG, "ax88180: AX88180 MAC Registers:\n"); \
+	for (k4 = 0xFC00; k4 <= 0xFCFF; k4 += 4) { \
+		READ_MACREG(k4, tmpval4); \
+		PRINTK(DEBUG_MSG, "0x%04x=0x%08lx ", k4, tmpval4); \
+		if ((k4 & 0xF) == 0xC) \
+			PRINTK(DEBUG_MSG, "\n"); \
+	} \
+	PRINTK(DEBUG_MSG, "\n"); \
+}
+
+/* Display all AX88180 PHY registers onto console screen */
+#define	DISPLAY_ALLPHYREG { \
+	unsigned long tmpval5; \
+	READ_PHYREG(axlocal.PhyAddr, BMCR, tmpval5); \
+	PRINTK(DEBUG_MSG, "BMCR=0x%04x ", (unsigned int)tmpval5); \
+	READ_PHYREG(axlocal.PhyAddr, BMSR, tmpval5); \
+	PRINTK(DEBUG_MSG, "BMSR=0x%04x ", (unsigned int)tmpval5); \
+	READ_PHYREG(axlocal.PhyAddr, PHYIDR0, tmpval5); \
+	PRINTK(DEBUG_MSG, "PHYIDR0=0x%04x ", (unsigned int)tmpval5); \
+	READ_PHYREG(axlocal.PhyAddr, PHYIDR1, tmpval5); \
+	PRINTK(DEBUG_MSG, "PHYIDR1=0x%04x ", (unsigned int)tmpval5); \
+	READ_PHYREG(axlocal.PhyAddr, ANAR, tmpval5); \
+	PRINTK(DEBUG_MSG, "ANAR=0x%04x ", (unsigned int)tmpval5); \
+	READ_PHYREG(axlocal.PhyAddr, ANLPAR, tmpval5); \
+	PRINTK(DEBUG_MSG, "ANLPAR=0x%04x \n", (unsigned int)tmpval5); \
+	READ_PHYREG(axlocal.PhyAddr, ANER, tmpval5); \
+	PRINTK(DEBUG_MSG, "ANER=0x%04x ", (unsigned int)tmpval5); \
+	READ_PHYREG(axlocal.PhyAddr, AUX_1000_CTRL, tmpval5); \
+	PRINTK(DEBUG_MSG, "1G_CTRL=0x%04x ", (unsigned int)tmpval5); \
+	READ_PHYREG(axlocal.PhyAddr, AUX_1000_STATUS, tmpval5); \
+	PRINTK(DEBUG_MSG, "1G_STATUS=0x%04x \n", (unsigned int)tmpval5); \
+	if (axlocal.PhyID0 == MARVELL_88E1111_PHYIDR0) { \
+		READ_PHYREG(axlocal.PhyAddr, M88_SSR, tmpval5); \
+		PRINTK(DEBUG_MSG, "M88_SSR=0x%04x ", (unsigned int)tmpval5); \
+		READ_PHYREG(axlocal.PhyAddr, M88_IER, tmpval5); \
+		PRINTK(DEBUG_MSG, "M88_IER=0x%04x ", (unsigned int)tmpval5); \
+		READ_PHYREG(axlocal.PhyAddr, M88_ISR, tmpval5); \
+		PRINTK(DEBUG_MSG, "M88_ISR=0x%04x ", (unsigned int)tmpval5); \
+		READ_PHYREG(axlocal.PhyAddr, M88_EXT_SCR, tmpval5); \
+		PRINTK(DEBUG_MSG, "M88_EXT_SCR=0x%04x ", (unsigned int)tmpval5); \
+		READ_PHYREG(axlocal.PhyAddr, M88_EXT_SSR, tmpval5); \
+		PRINTK(DEBUG_MSG, "M88_EXT_SSR=0x%04x \n", (unsigned int)tmpval5); \
+	} else if (axlocal.PhyID0 == CICADA_CIS8201_PHYIDR0) { \
+		READ_PHYREG(axlocal.PhyAddr, CIS_IMR, tmpval5); \
+		PRINTK(DEBUG_MSG, "CIS_IMR=0x%04x ", (unsigned int)tmpval5); \
+		READ_PHYREG(axlocal.PhyAddr, CIS_ISR, tmpval5); \
+		PRINTK(DEBUG_MSG, "CIS_ISR=0x%04x ", (unsigned int)tmpval5); \
+		READ_PHYREG(axlocal.PhyAddr, CIS_AUX_CTRL_STATUS, tmpval5); \
+		PRINTK(DEBUG_MSG, "CIS_AUX=0x%04x \n", (unsigned int)tmpval5); \
+	} \
+	READ_MACREG(RXCFG, tmpval5); \
+	PRINTK(DEBUG_MSG, "RXCFG=0x%08lx ", tmpval5); \
+	READ_MACREG(MACCFG0, tmpval5); \
+	PRINTK(DEBUG_MSG, "MACCFG0=0x%08lx ", tmpval5); \
+	READ_MACREG(MACCFG1, tmpval5); \
+	PRINTK(DEBUG_MSG, "MACCFG1=0x%08lx ", tmpval5); \
+	READ_MACREG(MACCFG2, tmpval5); \
+	PRINTK(DEBUG_MSG, "MACCFG2=0x%08lx \n\n", tmpval5); \
+}
+
+/*
+ * ===========================================================================
+ * <<<<<<             Global Variable Definition                >>>>>>
+ * ===========================================================================
+ */
+
+AX88180_PRIVATE axlocal;
+
+/*
+ * ===========================================================================
+ * <<<<<<             Local SubProgram Bodies                   >>>>>>
+ * ===========================================================================
+ */
+
+/*
+ *****************************************************************************
+ * ax88180_rx_handler()
+ *
+ * Handle packets received completion interrupt event.
+ *
+ *****************************************************************************
+ */
+static void ax88180_rx_handler(void)
+{
+	unsigned char *rxdata;
+	unsigned long tmp_data;
+	unsigned long rx_packet_len;
+	unsigned int data_size;
+	unsigned int dword_count, byte_count;
+	unsigned long rxcurt_ptr, rxbound_ptr, next_ptr;
+	int i;
+	int j;
+
+	READ_MACREG(RXCURT, rxcurt_ptr);
+	READ_MACREG(RXBOUND, rxbound_ptr);
+	next_ptr = (rxbound_ptr + 1) & RX_PAGE_NUM_MASK;
+
+	PRINTK(RX_MSG,
+	       "ax88180: RX original RXBOUND=0x%08lx, RXCURT=0x%08lx\n",
+	       rxbound_ptr, rxcurt_ptr);
+
+	while (next_ptr != rxcurt_ptr) {
+		START_READ_RXBUFF;
+		READ_RXBUF(rx_packet_len);
+		if ((rx_packet_len == 0) || (rx_packet_len > MAX_RX_SIZE)) {
+			STOP_READ_RXBUFF;
+			RESET_MAC;
+			PRINTK(ERROR_MSG,
+			       "ax88180: Invalid Rx packet length!! (len=0x%08lx)\n",
+			       rx_packet_len);
+			PRINTK(ERROR_MSG,
+			       "ax88180: RX RXBOUND=0x%08lx, RXCURT=0x%08lx\n",
+			       rxbound_ptr, rxcurt_ptr);
+			PRINTK(RX_MSG,
+			       "ax88180: ax88180_rx_handler fail end ..........\n");
+			return;
+		}
+		data_size = (unsigned int)rx_packet_len;
+		rxbound_ptr += (((data_size + 0xF) & 0xFFF0) >> 4) + 1;
+		rxbound_ptr &= RX_PAGE_NUM_MASK;
+
+		rxdata = (unsigned char *)NetRxPackets[0];
+
+#ifdef CONFIG_DRIVER_AX88180_16BIT
+		dword_count = data_size >> 1;
+		byte_count = data_size & 0x1;
+#else
+		dword_count = data_size >> 2;
+		byte_count = data_size & 0x3;
+#endif
+		for (i = 0; i < dword_count; i++) {
+			READ_RXBUF(tmp_data);
+#ifdef CONFIG_DRIVER_AX88180_16BIT
+			*((unsigned short *)rxdata + i) = tmp_data;
+#else
+			*((unsigned long *)rxdata + i) = tmp_data;
+#endif
+		}
+		if (byte_count != 0) {
+			READ_RXBUF(tmp_data);
+			for (j = 0; j < byte_count; j++) {
+				*(rxdata + (dword_count * 4) + j) =
+				    (unsigned char)(tmp_data >> (j * 8));
+			}
+		}
+
+		STOP_READ_RXBUFF;
+
+		/* Pass the packet up to the protocol layers. */
+		NetReceive(NetRxPackets[0], data_size);
+
+		WRITE_MACREG(RXBOUND, rxbound_ptr);
+
+		READ_MACREG(RXCURT, rxcurt_ptr);
+		READ_MACREG(RXBOUND, rxbound_ptr);
+		next_ptr = (rxbound_ptr + 1) & RX_PAGE_NUM_MASK;
+
+		PRINTK(RX_MSG,
+		       "ax88180: RX updated RXBOUND=0x%08lx, RXCURT=0x%08lx\n",
+		       rxbound_ptr, rxcurt_ptr);
+	}
+
+	if (axlocal.rxbuf_overflow_count > 0)
+		axlocal.rxbuf_overflow_count--;
+
+	return;
+}
+
+/*
+ *****************************************************************************
+ * ax88180_PHY_initial()
+ *
+ * Initialize PHY registers.
+ *
+ *****************************************************************************
+ */
+static void ax88180_PHY_initial(void)
+{
+	unsigned long bmcr_val, anar_val, bmsr_val;
+	unsigned long aux_1000_ctrl;
+	unsigned long tmp_regval;
+	unsigned int i;
+
+	/* Check avaliable PHY chipset  */
+	axlocal.PhyAddr = MARVELL_88E1111_PHYADDR;
+	READ_PHYREG(axlocal.PhyAddr, PHYIDR0, axlocal.PhyID0);
+
+	if (axlocal.PhyID0 == MARVELL_88E1111_PHYIDR0) {
+		PRINTK(DRIVER_MSG,
+		       "ax88180: Found Marvell 88E1111 PHY chipset. (PHY Addr=0x%x)\n",
+		       (unsigned int)axlocal.PhyAddr);
+		READ_PHYREG(axlocal.PhyAddr, M88_EXT_SSR, tmp_regval);
+		if ((tmp_regval & HWCFG_MODE_MASK) == RGMII_COPPER_MODE) {
+			WRITE_PHYREG(axlocal.PhyAddr, M88_EXT_SCR,
+				     DEFAULT_EXT_SCR);
+			RESET_PHY;
+			WRITE_PHYREG(axlocal.PhyAddr, M88_IER, LINK_CHANGE_INT);
+		}
+	} else {
+		axlocal.PhyAddr = CICADA_CIS8201_PHYADDR;
+		READ_PHYREG(axlocal.PhyAddr, PHYIDR0, axlocal.PhyID0);
+		if (axlocal.PhyID0 == CICADA_CIS8201_PHYIDR0) {
+			PRINTK(DRIVER_MSG,
+			       "ax88180: Found CICADA CIS8201 PHY chipset. (PHY Addr=0x%x)\n",
+			       (unsigned int)axlocal.PhyAddr);
+			WRITE_PHYREG(axlocal.PhyAddr, CIS_IMR,
+				     (CIS_INT_ENABLE | LINK_CHANGE_INT));
+
+			/* Set CIS_SMI_PRIORITY bit before force the media mode  */
+			READ_PHYREG(axlocal.PhyAddr, CIS_AUX_CTRL_STATUS,
+				    tmp_regval);
+			tmp_regval &= ~CIS_SMI_PRIORITY;
+			WRITE_PHYREG(axlocal.PhyAddr, CIS_AUX_CTRL_STATUS,
+				     tmp_regval);
+		} else {
+			PRINTK(ERROR_MSG, "ax88180: Unknown PHY chipset!!\n");
+		}
+	}
+
+	/* axlocal.ForceMedia = AUTO_MEDIA; */
+	aux_1000_ctrl = DEFAULT_AUX_1000_CTRL;
+	anar_val =
+	    (ANAR_PAUSE | ANAR_100FULL | ANAR_100HALF | ANAR_10FULL |
+	     ANAR_10HALF | ANAR_8023BIT);
+
+	WRITE_PHYREG(axlocal.PhyAddr, AUX_1000_CTRL, aux_1000_ctrl);
+	WRITE_PHYREG(axlocal.PhyAddr, ANAR, anar_val);
+
+	/* Enable and restart auto-negotiation operation */
+	bmcr_val = (AUTONEG_EN | RESTART_AUTONEG);
+	WRITE_PHYREG(axlocal.PhyAddr, BMCR, bmcr_val);
+
+	/* Waiting 5 secs for PHY link stable */
+	PRINTK(DRIVER_MSG,
+	       "ax88180: Waiting for auto-negotiation completion......\n");
+	for (i = 0; i < 5000; i++) {
+		READ_PHYREG(axlocal.PhyAddr, BMSR, bmsr_val);
+		if (bmsr_val & LINKOK) {
+			break;
+		}
+		mdelay(1);
+	}
+
+	return;
+}
+
+/*
+ *****************************************************************************
+ * ax88180_meida_config()
+ *
+ * Configure MAC registers (RXCFG, MACCFG0, MACCFG1) to match the real PHY media mode.
+ *
+ *****************************************************************************
+ */
+static void ax88180_meida_config(void)
+{
+	unsigned long bmcr_val, bmsr_val;
+	unsigned long rxcfg_val, maccfg0_val, maccfg1_val;
+	int i;
+
+	/* Waiting 200 msecs for PHY link stable */
+	for (i = 0; i < 200; i++) {
+		READ_PHYREG(axlocal.PhyAddr, BMSR, bmsr_val);
+		if (bmsr_val & LINKOK) {
+			break;
+		}
+		mdelay(1);
+	}
+
+	READ_PHYREG(axlocal.PhyAddr, BMSR, bmsr_val);
+	if (bmsr_val & LINKOK) {
+		READ_PHYREG(axlocal.PhyAddr, BMCR, bmcr_val);
+		if (bmcr_val & AUTONEG_EN) {
+			/* Waiting for Auto-negotiation completion */
+			PRINTK(INIT_MSG,
+			       "ax88180: Auto-negotiation is enabled. Waiting for NWay completion.....\n");
+
+			for (i = 0; i < 5000; i++) {
+				if (bmsr_val & AUTONEG_COMPLETE) {
+					break;
+				}
+				mdelay(1);
+				READ_PHYREG(axlocal.PhyAddr, BMSR, bmsr_val);
+			}
+			if (i >= 5000)
+				PRINTK(INIT_MSG,
+				       "ax88180: Auto-negotiation is NOT completed!!\n");
+		} else
+			PRINTK(INIT_MSG,
+			       "ax88180: Auto-negotiation is disabled.\n");
+
+		PRINTK(DEBUG_MSG, "ax88180: BMCR=0x%04x, BMSR=0x%04x\n",
+		       (unsigned int)bmcr_val, (unsigned int)bmsr_val);
+
+		/* Get real media mode here */
+		if (axlocal.PhyID0 == MARVELL_88E1111_PHYIDR0) {
+			get_MarvellPHY_meida_mode();
+		} else if (axlocal.PhyID0 == CICADA_CIS8201_PHYIDR0) {
+			get_CicadaPHY_meida_mode();
+		} else {
+			axlocal.RealMediaMode = MEDIA_1000FULL;
+		}
+
+		switch (axlocal.RealMediaMode) {
+		default:
+		case MEDIA_1000FULL:
+			PRINTK(DRIVER_MSG,
+			       "ax88180: Set to 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:
+			PRINTK(DRIVER_MSG,
+			       "ax88180: Set to 1000Mbps Half-duplex mode.\n");
+			rxcfg_val = DEFAULT_RXCFG;
+			maccfg0_val = DEFAULT_MACCFG0;
+			maccfg1_val = GIGA_MODE_EN | DEFAULT_MACCFG1;
+			break;
+
+		case MEDIA_100FULL:
+			PRINTK(DRIVER_MSG,
+			       "ax88180: Set to 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:
+			PRINTK(DRIVER_MSG,
+			       "ax88180: Set to 100Mbps Half-duplex mode.\n");
+			rxcfg_val = DEFAULT_RXCFG;
+			maccfg0_val = SPEED100 | DEFAULT_MACCFG0;
+			maccfg1_val = DEFAULT_MACCFG1;
+			break;
+
+		case MEDIA_10FULL:
+			PRINTK(DRIVER_MSG,
+			       "ax88180: Set to 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:
+			PRINTK(DRIVER_MSG,
+			       "ax88180: Set to 10Mbps Half-duplex mode.\n");
+			rxcfg_val = DEFAULT_RXCFG;
+			maccfg0_val = DEFAULT_MACCFG0;
+			maccfg1_val = DEFAULT_MACCFG1;
+			break;
+		}
+	} else {
+		PRINTK(INIT_MSG, "ax88180: The cable is disconnected!!\n");
+		/* Set to default media mode (1000FULL) */
+		rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
+		maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0;
+		maccfg1_val =
+		    GIGA_MODE_EN | RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1;
+	}
+
+	WRITE_MACREG(RXCFG, rxcfg_val);
+	WRITE_MACREG(MACCFG0, maccfg0_val);
+	WRITE_MACREG(MACCFG1, maccfg1_val);
+
+	return;
+}
+
+/*
+ *****************************************************************************
+ * get_MarvellPHY_meida_mode()
+ *
+ * Get real media mode of Marvell 88E1111 PHY.
+ *
+ *****************************************************************************
+ */
+static void get_MarvellPHY_meida_mode(void)
+{
+	unsigned long m88_ssr;
+	int i;
+
+	/* Get the real media mode */
+	for (i = 0; i < 200; i++) {
+		READ_PHYREG(axlocal.PhyAddr, M88_SSR, m88_ssr);
+		if (m88_ssr & SSR_MEDIA_RESOLVED_OK) {
+			break;
+		}
+		mdelay(1);
+	}
+
+	READ_PHYREG(axlocal.PhyAddr, M88_SSR, m88_ssr);
+	switch (m88_ssr & SSR_MEDIA_MASK) {
+	default:
+	case SSR_1000FULL:
+		axlocal.RealMediaMode = MEDIA_1000FULL;
+		break;
+
+	case SSR_1000HALF:
+		axlocal.RealMediaMode = MEDIA_1000HALF;
+		break;
+
+	case SSR_100FULL:
+		axlocal.RealMediaMode = MEDIA_100FULL;
+		break;
+
+	case SSR_100HALF:
+		axlocal.RealMediaMode = MEDIA_100HALF;
+		break;
+
+	case SSR_10FULL:
+		axlocal.RealMediaMode = MEDIA_10FULL;
+		break;
+
+	case SSR_10HALF:
+		axlocal.RealMediaMode = MEDIA_10HALF;
+		break;
+	}
+
+	PRINTK(INIT_MSG, "ax88180: get_MarvellPHY_meida_mode end ..........\n");
+	return;
+}
+
+/*
+ *****************************************************************************
+ * get_CicadaPHY_meida_mode()
+ *
+ * Get real media mode of CICADA CIS8201 PHY.
+ *
+ *****************************************************************************
+ */
+static void get_CicadaPHY_meida_mode(void)
+{
+	unsigned long tmp_regval;
+
+	READ_PHYREG(axlocal.PhyAddr, CIS_AUX_CTRL_STATUS, tmp_regval);
+	switch (tmp_regval & CIS_MEDIA_MASK) {
+	default:
+	case CIS_1000FULL:
+		axlocal.RealMediaMode = MEDIA_1000FULL;
+		break;
+
+	case CIS_1000HALF:
+		axlocal.RealMediaMode = MEDIA_1000HALF;
+		break;
+
+	case CIS_100FULL:
+		axlocal.RealMediaMode = MEDIA_100FULL;
+		break;
+
+	case CIS_100HALF:
+		axlocal.RealMediaMode = MEDIA_100HALF;
+		break;
+
+	case CIS_10FULL:
+		axlocal.RealMediaMode = MEDIA_10FULL;
+		break;
+
+	case CIS_10HALF:
+		axlocal.RealMediaMode = MEDIA_10HALF;
+		break;
+	}
+
+	return;
+}
+
+/*
+ * ===========================================================================
+ * <<<<<<             Exported SubProgram Bodies                   >>>>>>
+ * ===========================================================================
+ */
+
+void eth_halt(void)
+{
+	/* Disable AX88180 TX/RX functions */
+	WRITE_MACREG(CMD, WAKEMOD);
+}
+
+void ax88180_get_enetaddr(uchar * addr)
+{
+	unsigned long macid0_val, macid1_val, macid2_val;
+	unsigned long tmp_regval;
+	unsigned char env_enetaddr[6];
+	char *tmp = getenv("ethaddr");
+	char *end;
+	int i;
+
+#if defined(CONFIG_S3C2440A_SMDK)
+	/* 32-bit mode */
+	BWSCON = (BWSCON & ~(0xf << 4)) | (0x02 << 4);
+	BANKCON1 = BANKCON1_14CLKS;
+#endif
+
+	for (i = 0; i < 6; i++) {
+		env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
+		if (tmp)
+			tmp = (*end) ? end + 1 : end;
+	}
+
+	RESET_MAC;
+
+	/* Disable AX88180 interrupt */
+	DISABLE_INTERRUPT;
+
+	/* Disable AX88180 TX/RX functions */
+	WRITE_MACREG(CMD, WAKEMOD);
+
+	/* Reload MAC address from EEPROM */
+	WRITE_MACREG(PROMCTRL, RELOAD_EEPROM);
+	for (i = 0; i < 500; i++) {
+		READ_MACREG(PROMCTRL, tmp_regval);
+		if ((tmp_regval & RELOAD_EEPROM) == 0)
+			break;
+		mdelay(1);
+	}
+
+	/* Get MAC addresses */
+	READ_MACREG(MACID0, macid0_val);
+	READ_MACREG(MACID1, macid1_val);
+	READ_MACREG(MACID2, macid2_val);
+	if ((macid0_val | macid1_val | macid2_val) != 0) {
+		*addr = (unsigned char)macid0_val;
+		*(addr + 1) = (unsigned char)(macid0_val >> 8);
+		*(addr + 2) = (unsigned char)macid1_val;
+		*(addr + 3) = (unsigned char)(macid1_val >> 8);
+		*(addr + 4) = (unsigned char)macid2_val;
+		*(addr + 5) = (unsigned char)(macid2_val >> 8);
+	} else {
+		/* No EEPROM here!! Set MAC address from environment. */
+		for (i = 0; i < 6; i++)
+			addr[i] = env_enetaddr[i];
+	}
+
+	printf("MAC: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
+	       *addr, *(addr + 1), *(addr + 2), *(addr + 3), *(addr + 4),
+	       *(addr + 5));
+	printf("\n");
+
+}
+
+int eth_init(bd_t *bd)
+{
+	unsigned long tmp_regval;
+	unsigned long macid0_val, macid1_val, macid2_val;
+	unsigned short tmp16;
+#if defined(CONFIG_S3C2440A_SMDK)
+	/* 32-bit mode */
+	BWSCON = (BWSCON & ~(0xf << 4)) | (0x02 << 4);
+	BANKCON1 = BANKCON1_14CLKS;
+#endif
+
+#ifdef CONFIG_DRIVER_AX88180_16BIT
+	WRITE_MACREG(0xDD00, 0);
+	WRITE_MACREG(0xDD06, 0x10);
+	WRITE_MACREG(0xDD00, 1);
+#endif
+	memset(&axlocal, 0, sizeof(AX88180_PRIVATE));
+
+	RESET_MAC;
+
+	/* Disable AX88180 interrupt */
+	DISABLE_INTERRUPT;
+
+	/* Disable AX88180 TX/RX functions */
+	WRITE_MACREG(CMD, WAKEMOD);
+
+	tmp16 = bd->bi_enetaddr[1];
+	macid0_val = (tmp16 << 8) | bd->bi_enetaddr[0];
+
+	tmp16 = bd->bi_enetaddr[3];
+	macid1_val = (tmp16 << 8) | bd->bi_enetaddr[2];
+
+	tmp16 = bd->bi_enetaddr[5];
+	macid2_val = (tmp16 << 8) | bd->bi_enetaddr[4];
+
+	WRITE_MACREG(MACID0, macid0_val);
+	WRITE_MACREG(MACID1, macid1_val);
+	WRITE_MACREG(MACID2, macid2_val);
+
+	/* Initial PHY registers */
+	ax88180_PHY_initial();
+
+	/* Configure MAC media mode registers */
+	ax88180_meida_config();
+
+	WRITE_MACREG(RXFILTER, DEFAULT_RXFILTER);
+
+	/* Initial variables here */
+	INIT_TXRX_VARIABLES;
+
+	DISPLAY_ALLMACREG;
+
+	/* Check if there is any invalid interrupt status. If yes, clear it. */
+	READ_MACREG(ISR, tmp_regval);
+	PRINTK(INIT_MSG, "ax88180: The interrupt status = 0x%08lx\n",
+	       tmp_regval);
+	if (tmp_regval)
+		WRITE_MACREG(ISR, tmp_regval);
+
+	/* Start AX88180 TX/RX functions */
+	WRITE_MACREG(CMD, RXEN | TXEN | WAKEMOD);
+
+	return 0;
+}
+
+/* Get a data block via Ethernet */
+extern int eth_rx(void)
+{
+	unsigned long ISR_Status;
+	unsigned long rxcurt_ptr, rxbound_ptr;
+	unsigned long bmsr_val;
+	unsigned long tmp_regval;
+	int i;
+
+	/* Read and check interrupt status here...... */
+	READ_MACREG(ISR, ISR_Status);
+
+	while (ISR_Status) {
+		/* Clear the interrupt status */
+		WRITE_MACREG(ISR, ISR_Status);
+
+		PRINTK(INT_MSG,
+		       "\n\rax88180: The interrupt status = 0x%08lx\n\r",
+		       ISR_Status);
+
+		if (ISR_Status & ISR_PHY) {
+			/* Read ISR register once to clear Marvell PHY interrupt bit */
+			READ_PHYREG(axlocal.PhyAddr, M88_ISR, tmp_regval);
+
+			/* Waiting 200 msecs for PHY link stable */
+			for (i = 0; i < 200; i++) {
+				READ_PHYREG(axlocal.PhyAddr, BMSR, bmsr_val);
+				if (bmsr_val & LINKOK) {
+					break;
+				}
+				mdelay(1);
+			}
+
+			if (bmsr_val & LINKOK) {
+				PRINTK(WARNING_MSG,
+				       "ax88180: The cable is connected.\n");
+				ax88180_meida_config();
+			} else {
+				PRINTK(WARNING_MSG,
+				       "ax88180: The cable is disconnected.\n");
+			}
+			DISPLAY_ALLPHYREG;
+		}
+
+		if (ISR_Status & ISR_RXBUFFOVR) {
+			axlocal.rxbuf_overflow_count++;
+			READ_MACREG(RXCURT, rxcurt_ptr);
+			READ_MACREG(RXBOUND, rxbound_ptr);
+			PRINTK(ERROR_MSG,
+			       "ax88180: RX Buffer overflow!! (count=%d, RXBOUND=0x%08lx, RXCURT=0x%08lx)\n",
+			       (int)axlocal.rxbuf_overflow_count, rxbound_ptr,
+			       rxcurt_ptr);
+			PRINTK(ERROR_MSG,
+			       "ax88180: The interrupt status = 0x%08lx\n",
+			       ISR_Status);
+
+			if (axlocal.rxbuf_overflow_count > 10) {
+				RESET_MAC;
+				INIT_TXRX_VARIABLES;
+			}
+		}
+
+		if (ISR_Status & ISR_RX) {
+			ax88180_rx_handler();
+		}
+
+		/* Read and check interrupt status here...... */
+		READ_MACREG(ISR, ISR_Status);
+	}
+
+	return 0;
+}
+
+/* Send a data block via Ethernet. */
+extern int eth_send(volatile void *packet, int length)
+{
+	volatile unsigned char *txdata;
+	unsigned long TXDES_addr;
+	unsigned long txcmd_txdp, txbs_txdp;
+	/* unsigned long txdes0_val, txdes1_val, txdes2_val, txdes3_val; */
+	unsigned long tmp_data;
+	int i;
+
+	txdata = (volatile unsigned char *)packet;
+
+	axlocal.FirstTxDesc = axlocal.NextTxDesc;
+	txbs_txdp = 1 << axlocal.FirstTxDesc;
+
+	/* allan9 add to make sure TX machine is OK */
+	i = 0;
+	READ_MACREG(TXBS, tmp_data);
+	READ_MACREG(TXBS, tmp_data);
+	PRINTK(TX_MSG, "ax88180: Checking available TXDP (TXBS=0x%08lx)\n",
+	       tmp_data);
+	while (tmp_data & txbs_txdp) {
+		axlocal.NextTxDesc++;
+		axlocal.NextTxDesc &= TXDP_MASK;
+		axlocal.FirstTxDesc = axlocal.NextTxDesc;
+		txbs_txdp = 1 << axlocal.FirstTxDesc;
+		READ_MACREG(TXBS, tmp_data);
+		i++;
+
+		if (i > 1000) {
+			RESET_MAC;
+			axlocal.NextTxDesc = TXDP0;
+			axlocal.FirstTxDesc = axlocal.NextTxDesc;
+			txbs_txdp = 1 << axlocal.FirstTxDesc;
+			READ_MACREG(TXBS, tmp_data);
+			i = 0;
+			PRINTK(ERROR_MSG, "ax88180: No available TXDP!!\n");
+		}
+	}
+
+	PRINTK(TX_MSG, "ax88180: TXDP%d is available, i=%d\n",
+	       (int)axlocal.FirstTxDesc, i);
+	/* allan9 end */
+
+	txcmd_txdp = axlocal.FirstTxDesc << 13;
+	TXDES_addr = TXDES0 + (axlocal.FirstTxDesc << 2);
+
+	WRITE_MACREG(TXCMD, txcmd_txdp | length | TX_START_WRITE);
+
+#ifdef CONFIG_DRIVER_AX88180_16BIT
+	for (i = 0; i < length; i += 2) {
+		tmp_data =
+		    (unsigned short)*(txdata + i) +
+		    (unsigned short)(*(txdata + i + 1) << 8);
+		WRITE_TXBUF(tmp_data);
+	}
+#else
+	for (i = 0; i < length; i += 4) {
+		tmp_data =
+		    (unsigned long)*(txdata + i) +
+		    (unsigned long)(*(txdata + i + 1) << 8) +
+		    (unsigned long)(*(txdata + i + 2) << 16) +
+		    (unsigned long)(*(txdata + i + 3) << 24);
+		WRITE_TXBUF(tmp_data);
+	}
+#endif
+
+	WRITE_MACREG(TXCMD, txcmd_txdp | length);
+	WRITE_MACREG(TXBS, txbs_txdp);
+	WRITE_MACREG(TXDES_addr, TXDPx_ENABLE | length);
+
+	axlocal.NextTxDesc++;
+
+	axlocal.NextTxDesc &= TXDP_MASK;
+
+	return 0;
+}
diff --git a/drivers/net/ax88180.h b/drivers/net/ax88180.h
new file mode 100644
index 0000000..977258f
--- /dev/null
+++ b/drivers/net/ax88180.h
@@ -0,0 +1,348 @@
+/* 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.
+ *
+ */
+
+#include <asm/types.h>
+#include <config.h>
+
+#ifdef CONFIG_DRIVER_AX88180
+
+#define PLATFORM_MEMBASE		0x08000000
+
+#define ENABLE_JUMBO			1
+#define	DISABLE_JUMBO			0
+
+#define	DEFAULT_ETH_MTU			1500
+#define	MAX_JUMBO_MTU			4072	/* Jumbo packet size 4086 bytes included 4 bytes CRC */
+#define	MAX_TX_JUMBO_SIZE		4086	/* Max Tx Jumbo size 4086 bytes included 4 bytes CRC */
+#define	MAX_RX_SIZE			0x3C00	/* Max Rx Jumbo size is 15K Bytes */
+
+#define AX88180_MEMORY_SIZE		0x00010000
+
+#define	MARVELL_88E1111_PHYADDR		0x18
+#define	MARVELL_88E1111_PHYIDR0		0x0141
+
+#define	CICADA_CIS8201_PHYADDR		0x01
+#define	CICADA_CIS8201_PHYIDR0		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	AUTO_MEDIA			0
+#define	FORCE_MEDIA			1
+
+#define	TXDP_MASK			3
+#define	TXDP0				0
+#define	TXDP1				1
+#define	TXDP2				2
+#define	TXDP3				3
+
+/* AX88180 Memory Mapping Definition */
+#define	RXBUFFER_START			0x0000
+#define	RX_PACKET_LEN_OFFSET		0
+#define	RX_PAGE_NUM_MASK		0x7FF	/* RX pages 0~7FFh */
+#define TXBUFFER_START			0x8000
+
+/* AX88180 MAC Register Definition */
+#define	CMD		0xFC00
+#define	WAKEMOD				0x00000001
+#define	TXEN				0x00000100
+#define	RXEN				0x00000200
+#define	DEFAULT_CMD			WAKEMOD
+#define	IMR		0xFC04
+#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_RXBUFFOVR)
+#define	ISR		0xFC08
+#define	ISR_RXBUFFOVR			0x00000001
+#define	ISR_WATCHDOG			0x00000002
+#define	ISR_TX				0x00000008
+#define	ISR_RX				0x00000010
+#define	ISR_PHY				0x00000020
+#define	TXCFG		0xFC10
+#define	AUTOPAD_CRC			0x00000040
+#define	DEFAULT_TXCFG			AUTOPAD_CRC
+#define	TXCMD		0xFC14
+#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		0xFC18
+#define	TXDP0_USED			0x00000001
+#define	TXDP1_USED			0x00000002
+#define	TXDP2_USED			0x00000004
+#define	TXDP3_USED			0x00000008
+#define	DEFAULT_TXBS			0x00000000
+#define	TXDES0		0xFC20
+#define	TXDPx_ENABLE			0x00008000
+#define	TXDPx_LEN_MASK			0x00001FFF
+#define	DEFAULT_TXDES0			0x00000000
+#define	TXDES1		0xFC24
+#define	TXDPx_ENABLE			0x00008000
+#define	TXDPx_LEN_MASK			0x00001FFF
+#define	DEFAULT_TXDES1			0x00000000
+#define	TXDES2		0xFC28
+#define	TXDPx_ENABLE			0x00008000
+#define	TXDPx_LEN_MASK			0x00001FFF
+#define	DEFAULT_TXDES2			0x00000000
+#define	TXDES3		0xFC2C
+#define	TXDPx_ENABLE			0x00008000
+#define	TXDPx_LEN_MASK			0x00001FFF
+#define	DEFAULT_TXDES3			0x00000000
+#define	RXCFG		0xFC30
+#define 	RXBUFF_PROTECT		0x00000001
+#define	RXTCPCRC_CHECK			0x00000010
+#define	RXFLOW_ENABLE			0x00000100
+#define	DEFAULT_RXCFG			RXBUFF_PROTECT
+#define	RXCURT		0xFC34
+#define	DEFAULT_RXCURT			0x00000000
+#define	RXBOUND		0xFC38
+#define	DEFAULT_RXBOUND			0x000007FF
+#define	MACCFG0		0xFC40
+#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		0xFC44
+#define	RGMII_EN			0x00000002
+#define	RXFLOW_EN			0x00000020
+#define	FULLDUPLEX			0x00000040
+#define	MAX_JUMBO_LEN_MASK		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	MACCFG2		0xFC48
+#define	MACCFG2_BIT15_8			0x00000100
+#define	JAM_LIMIT_MASK			0x000000FC
+#define	DEFAULT_JAM_LIMIT		0x00000064
+#define	DEFAULT_MACCFG2			MACCFG2_BIT15_8
+#define	MACCFG3		0xFC4C
+#define	IPGR2_VAL			0x0000000E
+#define	IPGR1_VAL			0x00000600
+#define	NOABORT				0x00008000
+#define	DEFAULT_MACCFG3			(IPGR1_VAL | IPGR2_VAL)
+#define	TXPAUT		0xFC54
+#define	DEFAULT_TXPAUT			0x001FE000
+#define	RXBTHD0		0xFC58
+#define	DEFAULT_RXBTHD0			0x00000300
+#define	RXBTHD1		0xFC5C
+#define	DEFAULT_RXBTHD1			0x00000600
+#define	RXFULTHD	0xFC60
+#define	DEFAULT_RXFULTHD		0x00000100
+#define	MISC		0xFC68
+#define	MISC_NORMAL			0x00000003	/* Normal operation mode */
+#define	MISC_RESET_MAC			0x00000002	/* Clear bit 0 to reset MAC */
+#define	MISC_RESET_PHY			0x00000001	/* Clear bit 1 to reset PHY */
+#define	MISC_RESET_MAC_PHY		0x00000000	/* Clear bit 0 and 1 to reset MAC and PHY */
+#define	DEFAULT_MISC			MISC_NORMAL
+#define	MACID0		0xFC70
+#define	MACID1		0xFC74
+#define	MACID2		0xFC78
+#define	TXLEN		0xFC7C
+#define	DEFAULT_TXLEN			0x000005FC
+#define	RXFILTER	0xFC80
+#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 + RX_MULTICAST)
+#define	MDIOCTRL	0xFC84
+#define	PHY_ADDR_MASK			0x0000001F
+#define	REG_ADDR_MASK			0x00001F00
+#define	READ_PHY			0x00004000
+#define WRITE_PHY			0x00008000
+#define	MDIODP		0xFC88
+#define	GPIOCTRL	0xFC8C
+#define	RXINDICATOR	0xFC90
+#define	RX_START_READ			0x00000001
+#define	RX_STOP_READ			0x00000000
+#define	DEFAULT_RXINDICATOR		RX_STOP_READ
+#define	TXST		0xFC94
+#define	MDCCLKPAT	0xFCA0
+#define	RXIPCRCCNT	0xFCA4
+#define	RXCRCCNT	0xFCA8
+#define	TXFAILCNT	0xFCAC
+#define	PROMDP		0xFCB0
+#define	PROMCTRL	0xFCB4
+#define	RELOAD_EEPROM			0x00000200
+#define	MAXRXLEN	0xFCB8
+#define	HASHTAB0	0xFCC0
+#define	HASHTAB1	0xFCC4
+#define	HASHTAB2	0xFCC8
+#define	HASHTAB3	0xFCCC
+#define	DOGTHD0		0xFCE0
+#define	DEFAULT_DOGTHD0			0x0000FFFF
+#define	DOGTHD1		0xFCE4
+#define	START_WATCHDOG_TIMER		0x00008000
+#define	DEFAULT_DOGTHD1			0x00000FFF
+#define	SOFTRST		0xFCEC
+#define	SOFTRST_NORMAL			0x00000003
+#define	SOFTRST_RESET_MAC		0x00000002
+
+/* External PHY Register Definition */
+#define	BMCR				0x0000
+#define	LINE_SPEED_MSB			0x0040
+#define	DUPLEX_MODE			0x0100
+#define	RESTART_AUTONEG			0x0200
+#define	POWER_DOWN			0x0800
+#define	AUTONEG_EN			0x1000
+#define	LINE_SPEED_LSB			0x2000
+#define PHY_RESET			0x8000
+
+#define	MEDIAMODE_MASK			(LINE_SPEED_MSB | LINE_SPEED_LSB | DUPLEX_MODE)
+#define	BMCR_SPEED_1000			LINE_SPEED_MSB
+#define	BMCR_SPEED_100			LINE_SPEED_LSB
+#define	BMCR_SPEED_10			0x0000
+
+#define	BMCR_1000FULL			(BMCR_SPEED_1000 | DUPLEX_MODE)
+#define	BMCR_100FULL			(BMCR_SPEED_100 | DUPLEX_MODE)
+#define	BMCR_100HALF			BMCR_SPEED_100
+#define	BMCR_10FULL			DUPLEX_MODE
+#define	BMCR_10HALF			0x0000
+#define	BMSR				0x0001
+#define	LINKOK				0x0004
+#define	AUTONEG_ENABLE_STS		0x0008
+#define AUTONEG_COMPLETE		0x0020
+#define	PHYIDR0				0x0002
+#define PHYIDR1				0x0003
+#define	ANAR				0x0004
+#define ANAR_PAUSE			0x0400
+#define ANAR_100FULL			0x0100
+#define ANAR_100HALF			0x0080
+#define ANAR_10FULL			0x0040
+#define ANAR_10HALF			0x0020
+#define	ANAR_8023BIT			0x0001
+#define	ANLPAR				0x0005
+#define	ANER				0x0006
+#define	AUX_1000_CTRL			0x0009
+#define	ENABLE_1000HALF			0x0100
+#define	ENABLE_1000FULL			0x0200
+#define DEFAULT_AUX_1000_CTRL	(ENABLE_1000HALF | ENABLE_1000FULL)
+#define	AUX_1000_STATUS			0x000A
+#define	LP_1000HALF			0x0400
+#define	LP_1000FULL			0x0800
+
+/* 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	M88_EXT_SCR			0x0014
+#define	RGMII_RXCLK_DELAY		0x0080
+#define	RGMII_TXCLK_DELAY		0x0002
+#define	DEFAULT_EXT_SCR			(RGMII_TXCLK_DELAY | RGMII_RXCLK_DELAY)
+#define	M88_EXT_SSR			0x001B
+#define	HWCFG_MODE_MASK			0x000F
+#define	RGMII_COPPER_MODE		0x000B
+
+/* 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
+
+/* SMDK2440 Registers Definition */
+/* SMDK2440 default clocks: FCLK=400MHZ, HCLK=125MHZ, PCLK=62.5MHZ */
+#define	CLKDIVN_125MHZ			0x0000000F	/* Set HCLK=FCLK/3, PCLK=HCLK/2 when CAMDIVN[8]=0 */
+#define	CAMDIVN_125MHZ			0x00000000	/* Set HCLK=FCLK/3, PCLK=HCLK/2 when CAMDIVN[8]=0 */
+#define UBRDIV0_125MHZ			0x00000023	/* Set UART Baud Rate divisor for 125MHZ HCLK */
+#define	CLKDIVN_100MHZ			0x0000000D	/* Set HCLK=FCLK/4, PCLK=HCLK/2 when CAMDIVN[9]=0 */
+#define	CAMDIVN_100MHZ			0x00000000	/* Set HCLK=FCLK/4, PCLK=HCLK/2 when CAMDIVN[9]=0 */
+#define UBRDIV0_100MHZ			0x0000001B	/* Set UART Baud Rate divisor for 100MHZ HCLK */
+#define	CLKDIVN_50MHZ			0x0000000D	/* Set HCLK=FCLK/8, PCLK=HCLK/2 when CAMDIVN[9]=1 */
+#define	CAMDIVN_50MHZ			0x00000200	/* Set HCLK=FCLK/8, PCLK=HCLK/2 when CAMDIVN[9]=1 */
+#define UBRDIV0_50MHZ			0x0000000D	/* Set UART Baud Rate divisor for 50MHZ HCLK */
+#define	BANKCON1_4CLKS			0x00000300	/* Set Bank 1 access timing 4 clocks for AX88180 US1 */
+#define	BANKCON1_6CLKS			0x00000400	/* Set Bank 1 access timing 6 clocks for AX88180 US2 */
+#define	BANKCON1_6CLKS_PAGE		0x0000040F	/* Set Bank 1 access timing 6 clocks with page access for AX88180 US2 */
+#define	BANKCON1_14CLKS			0x00000700	/* Set Bank 1 access timing 14 clocks (SMDK2440 H/W default) */
+
+/* EINTMASK Register Bit Definition */
+#define	EINT11_MASK			0x00000800	/* Clear this bit to enable EINT11 interrupt */
+
+/* EXTINT1 Register Bit Definition */
+#define	FLTEN11				0x00008000	/* Enable EINT11 signal noise filter */
+
+/* Debug Message Display Level Definition */
+#define	DRIVER_MSG			0x0001
+#define	INIT_MSG			0x0002
+#define	TX_MSG				0x0004
+#define	RX_MSG				0x0008
+#define INT_MSG				0x0010
+#define	ERROR_MSG			0x0020
+#define	WARNING_MSG			0x0040
+#define	DEBUG_MSG			0x0080
+#define	OTHERS_MSG			0x0100
+#define	ALL_MSG				0x01FF
+#define	NO_MSG				0x0000
+#define	DEBUG_FLAGS			(ERROR_MSG)
+
+#endif	/*end of CONFIG_DRIVER_AX88180 */
-- 
1.5.5.3





More information about the U-Boot mailing list