[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