diff options
author | kaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2006-12-14 22:50:13 +0000 |
---|---|---|
committer | kaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2006-12-14 22:50:13 +0000 |
commit | 1b4100d26b206eb971d681d2340b1e1107611fef (patch) | |
tree | a6f6c4ca9a38c4e639c666d36a4c354a480b7fda /target/linux/ar531x-2.4/patches | |
parent | 68a471122c10e6db85385d0d4ac6467a72afc8fb (diff) |
remove the ar531x-2.4 target, a 2.6 port will be added soon
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@5796 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/ar531x-2.4/patches')
-rw-r--r-- | target/linux/ar531x-2.4/patches/000-atheros-support.patch | 11411 |
1 files changed, 0 insertions, 11411 deletions
diff --git a/target/linux/ar531x-2.4/patches/000-atheros-support.patch b/target/linux/ar531x-2.4/patches/000-atheros-support.patch deleted file mode 100644 index de7115b46..000000000 --- a/target/linux/ar531x-2.4/patches/000-atheros-support.patch +++ /dev/null @@ -1,11411 +0,0 @@ -diff -urN linux-mips/arch/mips/ar531x/ar531xdbg_io.c mips-linux-2.4.25/arch/mips/ar531x/ar531xdbg_io.c ---- linux-mips/arch/mips/ar531x/ar531xdbg_io.c 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/arch/mips/ar531x/ar531xdbg_io.c 2005-12-30 17:26:30.606883840 +0000 -@@ -0,0 +1,234 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright MontaVista Software Inc -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * Basic support for polled character input/output -+ * using the AR531X's serial port. -+ */ -+ -+#include <linux/config.h> -+#include <linux/init.h> -+#include <linux/delay.h> -+#include <linux/irq.h> -+#include <linux/interrupt.h> -+#include <linux/serial.h> -+#include <linux/types.h> -+#include <linux/string.h> -+ -+#include <asm/reboot.h> -+#include <asm/io.h> -+#include <asm/time.h> -+#include <asm/pgtable.h> -+#include <asm/processor.h> -+#include <asm/reboot.h> -+#include <asm/system.h> -+#include <asm/serial.h> -+#include <asm/gdb-stub.h> -+ -+#include "ar531xlnx.h" -+ -+#if CONFIG_EARLY_PRINTK_HACK || CONFIG_KGDB -+/* base addr of uart and clock timing */ -+#if CONFIG_AR5315 -+#define BASE AR5315_UART0 -+#else -+#define BASE AR531X_UART0 -+#endif -+ -+/* distance in bytes between two serial registers */ -+#define REG_OFFSET 4 -+ -+/* -+ * 0 - we need to do serial init -+ * 1 - skip serial init -+ */ -+static int serialPortInitialized = 0; -+ -+/* -+ * * the default baud rate *if* we do serial init -+ * */ -+#define BAUD_DEFAULT UART16550_BAUD_9600 -+ -+/* === END OF CONFIG === */ -+ -+#define UART16550_BAUD_2400 2400 -+#define UART16550_BAUD_4800 4800 -+#define UART16550_BAUD_9600 9600 -+#define UART16550_BAUD_19200 19200 -+#define UART16550_BAUD_38400 38400 -+#define UART16550_BAUD_57600 57600 -+#define UART16550_BAUD_115200 115200 -+ -+#define UART16550_PARITY_NONE 0 -+#define UART16550_PARITY_ODD 0x08 -+#define UART16550_PARITY_EVEN 0x18 -+#define UART16550_PARITY_MARK 0x28 -+#define UART16550_PARITY_SPACE 0x38 -+ -+#define UART16550_DATA_5BIT 0x0 -+#define UART16550_DATA_6BIT 0x1 -+#define UART16550_DATA_7BIT 0x2 -+#define UART16550_DATA_8BIT 0x3 -+ -+#define UART16550_STOP_1BIT 0x0 -+#define UART16550_STOP_2BIT 0x4 -+ -+/* register offset */ -+#define OFS_RCV_BUFFER (0*REG_OFFSET) -+#define OFS_TRANS_HOLD (0*REG_OFFSET) -+#define OFS_SEND_BUFFER (0*REG_OFFSET) -+#define OFS_INTR_ENABLE (1*REG_OFFSET) -+#define OFS_INTR_ID (2*REG_OFFSET) -+#define OFS_DATA_FORMAT (3*REG_OFFSET) -+#define OFS_LINE_CONTROL (3*REG_OFFSET) -+#define OFS_MODEM_CONTROL (4*REG_OFFSET) -+#define OFS_RS232_OUTPUT (4*REG_OFFSET) -+#define OFS_LINE_STATUS (5*REG_OFFSET) -+#define OFS_MODEM_STATUS (6*REG_OFFSET) -+#define OFS_RS232_INPUT (6*REG_OFFSET) -+#define OFS_SCRATCH_PAD (7*REG_OFFSET) -+ -+#define OFS_DIVISOR_LSB (0*REG_OFFSET) -+#define OFS_DIVISOR_MSB (1*REG_OFFSET) -+ -+ -+/* memory-mapped read/write of the port */ -+#define UART16550_READ(y) (*((volatile u8*)(BASE + y))) -+#define UART16550_WRITE(y, z) ((*((volatile u8*)(BASE + y))) = z) -+ -+void -+debugPortInit(u32 baud, u8 data, u8 parity, u8 stop) -+{ -+ /* Pull UART out of reset */ -+#if CONFIG_AR5315 -+ sysRegWrite(AR5315_RESET, -+ sysRegRead(AR5315_RESET) & ~(RESET_UART0)); -+#else -+ sysRegWrite(AR531X_RESET, -+ sysRegRead(AR531X_RESET) & ~(AR531X_RESET_UART0)); -+#endif -+ -+ /* disable interrupts */ -+ UART16550_WRITE(OFS_LINE_CONTROL, 0x0); -+ UART16550_WRITE(OFS_INTR_ENABLE, 0); -+ -+ /* set up buad rate */ -+ { -+ u32 divisor; -+#if CONFIG_AR5315 -+ u32 uart_clock_rate = ar531x_apb_frequency(); -+#else -+ u32 uart_clock_rate = ar531x_cpu_frequency() / 4; -+#endif -+ u32 base_baud = uart_clock_rate / 16; -+ -+ /* set DIAB bit */ -+ UART16550_WRITE(OFS_LINE_CONTROL, 0x80); -+ -+ /* set divisor */ -+ divisor = base_baud / baud; -+ UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); -+ UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00)>>8); -+ -+ /* clear DIAB bit */ -+ UART16550_WRITE(OFS_LINE_CONTROL, 0x0); -+ } -+ -+ /* set data format */ -+ UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); -+} -+ -+u8 -+getDebugChar(void) -+{ -+ if (!serialPortInitialized) { -+ serialPortInitialized = 1; -+ debugPortInit(BAUD_DEFAULT, -+ UART16550_DATA_8BIT, -+ UART16550_PARITY_NONE, UART16550_STOP_1BIT); -+ } -+ -+ while((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0); -+ return UART16550_READ(OFS_RCV_BUFFER); -+} -+ -+#if CONFIG_KGDB -+/* -+ * Peek at the most recently received character. -+ * Don't wait for a new character to be received. -+ */ -+u8 -+peekDebugChar(void) -+{ -+ return UART16550_READ(OFS_RCV_BUFFER); -+} -+ -+static int kgdbInitialized = 0; -+ -+void -+kgdbInit(void) -+{ -+#if CONFIG_AR5315 -+ sysRegWrite(AR5315_WDC, WDC_IGNORE_EXPIRATION); -+#else -+ sysRegWrite(AR531X_WD_CTRL, AR531X_WD_CTRL_IGNORE_EXPIRATION); -+#endif -+ -+ if (!kgdbInitialized) { -+ printk("Setting debug traps - please connect the remote debugger.\n"); -+ set_debug_traps(); -+ kgdbInitialized = 1; -+ } -+ breakpoint(); -+} -+ -+int -+kgdbEnabled(void) -+{ -+ return kgdbInitialized; -+} -+ -+#define DEBUG_CHAR '\001'; -+ -+int -+kgdbInterrupt(void) -+{ -+ if (!kgdbInitialized) { -+ return 0; -+ } -+ -+ /* -+ * Try to avoid swallowing too much input: Only consume -+ * a character if nothing new has arrived. Yes, there's -+ * still a small hole here, and we may lose an input -+ * character now and then. -+ */ -+ if (UART16550_READ(OFS_LINE_STATUS) & 1) { -+ return 0; -+ } else { -+ return UART16550_READ(OFS_RCV_BUFFER) == DEBUG_CHAR; -+ } -+} -+#endif -+ -+ -+void -+putDebugChar(char byte) -+{ -+ if (!serialPortInitialized) { -+ serialPortInitialized = 1; -+ debugPortInit(BAUD_DEFAULT, -+ UART16550_DATA_8BIT, -+ UART16550_PARITY_NONE, UART16550_STOP_1BIT); -+ } -+ -+ while ((UART16550_READ(OFS_LINE_STATUS) &0x20) == 0); -+ UART16550_WRITE(OFS_SEND_BUFFER, byte); -+ } -+#endif /* CONFIG_EARLY_PRINTK_HACK || CONFIG_KGDB */ -diff -urN linux-mips/arch/mips/ar531x/ar531xgpio.c mips-linux-2.4.25/arch/mips/ar531x/ar531xgpio.c ---- linux-mips/arch/mips/ar531x/ar531xgpio.c 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/arch/mips/ar531x/ar531xgpio.c 2005-12-30 17:26:30.606883840 +0000 -@@ -0,0 +1,147 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * Support for GPIO -- General Purpose Input/Output Pins -+ */ -+ -+#include <linux/config.h> -+#include <linux/kernel.h> -+#include <linux/signal.h> -+#include <linux/interrupt.h> -+#include <linux/irq.h> -+ -+#include "ar531xlnx.h" -+ -+/* GPIO Interrupt Support */ -+ -+/* Turn on the specified AR531X_GPIO_IRQ interrupt */ -+static unsigned int -+ar531x_gpio_intr_startup(unsigned int irq) -+{ -+ ar531x_gpio_intr_enable(irq); -+ return 0; -+} -+ -+/* Turn off the specified AR531X_GPIO_IRQ interrupt */ -+static void -+ar531x_gpio_intr_shutdown(unsigned int irq) -+{ -+ ar531x_gpio_intr_disable(irq); -+} -+ -+u32 gpioIntMask = 0; -+ -+/* Enable the specified AR531X_GPIO_IRQ interrupt */ -+void -+ar531x_gpio_intr_enable(unsigned int irq) -+{ -+ u32 reg; -+ int gpio; -+ -+#ifndef CONFIG_AR5315 -+ gpio = irq - AR531X_GPIO_IRQ_BASE; -+ gpioIntMask |= gpio; -+ -+ reg = sysRegRead(AR531X_GPIO_CR); -+ reg &= ~(GPIO_CR_M(gpio) | GPIO_CR_UART(gpio) | GPIO_CR_INT(gpio)); -+ reg |= GPIO_CR_I(gpio); -+ reg |= GPIO_CR_INT(gpio); -+ -+ sysRegWrite(AR531X_GPIO_CR, reg); -+ (void)sysRegRead(AR531X_GPIO_CR); /* flush to hardware */ -+#endif -+} -+ -+/* Disable the specified AR531X_GPIO_IRQ interrupt */ -+void -+ar531x_gpio_intr_disable(unsigned int irq) -+{ -+ u32 reg; -+ int gpio; -+ -+#ifndef CONFIG_AR5315 -+ gpio = irq - AR531X_GPIO_IRQ_BASE; -+ reg = sysRegRead(AR531X_GPIO_CR); -+ reg &= ~(GPIO_CR_M(gpio) | GPIO_CR_UART(gpio) | GPIO_CR_INT(gpio)); -+ reg |= GPIO_CR_I(gpio); -+ /* No GPIO_CR_INT bit */ -+ -+ sysRegWrite(AR531X_GPIO_CR, reg); -+ (void)sysRegRead(AR531X_GPIO_CR); /* flush to hardware */ -+ -+ gpioIntMask &= ~gpio; -+#endif -+} -+ -+static void -+ar531x_gpio_intr_ack(unsigned int irq) -+{ -+ ar531x_gpio_intr_disable(irq); -+} -+ -+static void -+ar531x_gpio_intr_end(unsigned int irq) -+{ -+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) -+ ar531x_gpio_intr_enable(irq); -+} -+ -+static void -+ar531x_gpio_intr_set_affinity(unsigned int irq, unsigned long mask) -+{ -+ /* Only 1 CPU; ignore affinity request */ -+} -+ -+int ar531x_gpio_irq_base; -+ -+struct hw_interrupt_type ar531x_gpio_intr_controller = { -+ "AR531X GPIO", -+ ar531x_gpio_intr_startup, -+ ar531x_gpio_intr_shutdown, -+ ar531x_gpio_intr_enable, -+ ar531x_gpio_intr_disable, -+ ar531x_gpio_intr_ack, -+ ar531x_gpio_intr_end, -+ ar531x_gpio_intr_set_affinity, -+}; -+ -+void -+ar531x_gpio_intr_init(int irq_base) -+{ -+ int i; -+ -+ for (i = irq_base; i < irq_base + AR531X_GPIO_IRQ_COUNT; i++) { -+ irq_desc[i].status = IRQ_DISABLED; -+ irq_desc[i].action = NULL; -+ irq_desc[i].depth = 1; -+ irq_desc[i].handler = &ar531x_gpio_intr_controller; -+ } -+ -+ ar531x_gpio_irq_base = irq_base; -+} -+ -+/* ARGSUSED */ -+void -+spurious_gpio_handler(int cpl, void *dev_id, struct pt_regs *regs) -+{ -+ u32 gpioDataIn; -+#if CONFIG_AR5315 -+ gpioDataIn = sysRegRead(AR5315_GPIO_DI) & gpioIntMask; -+#else -+ gpioDataIn = sysRegRead(AR531X_GPIO_DI) & gpioIntMask; -+#endif -+ -+ printk("spurious_gpio_handler: 0x%x di=0x%8.8x gpioIntMask=0x%8.8x\n", -+ cpl, gpioDataIn, gpioIntMask); -+} -+ -+struct irqaction spurious_gpio = -+ {spurious_gpio_handler, SA_INTERRUPT, 0, "spurious_gpio", -+ NULL, NULL}; -+ -diff -urN linux-mips/arch/mips/ar531x/ar531x.h mips-linux-2.4.25/arch/mips/ar531x/ar531x.h ---- linux-mips/arch/mips/ar531x/ar531x.h 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/arch/mips/ar531x/ar531x.h 2005-12-30 17:26:30.605883992 +0000 -@@ -0,0 +1,1018 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+#ifndef AR531X_H -+#define AR531X_H 1 -+ -+#ifndef CONFIG_AR5315 -+ -+#include <asm/addrspace.h> -+ -+/* Address Map */ -+#define AR531X_WLAN0 0x18000000 -+#define AR531X_WLAN1 0x18500000 -+#define AR531X_ENET0 0x18100000 -+#define AR531X_ENET1 0x18200000 -+#define AR531X_SDRAMCTL 0x18300000 -+#define AR531X_FLASHCTL 0x18400000 -+#define AR531X_APBBASE 0x1c000000 -+#define AR531X_FLASH 0x1e000000 -+#define AR531X_UART0 0xbc000003 /* UART MMR */ -+ -+/* -+ * AR531X_NUM_ENET_MAC defines the number of ethernet MACs that -+ * should be considered available. The AR5312 supports 2 enet MACS, -+ * even though many reference boards only actually use 1 of them -+ * (i.e. Only MAC 0 is actually connected to an enet PHY or PHY switch. -+ * The AR2312 supports 1 enet MAC. -+ */ -+#define AR531X_NUM_ENET_MAC 2 -+ -+/* -+ * Need these defines to determine true number of ethernet MACs -+ */ -+#define AR5212_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */ -+#define AR5212_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ -+#define AR5212_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */ -+#define AR531X_RADIO_MASK_OFF 0xc8 -+#define AR531X_RADIO0_MASK 0x0003 -+#define AR531X_RADIO1_MASK 0x000c -+#define AR531X_RADIO1_S 2 -+ -+/* -+ * AR531X_NUM_WMAC defines the number of Wireless MACs that\ -+ * should be considered available. -+ */ -+#define AR531X_NUM_WMAC 2 -+ -+/* Reset/Timer Block Address Map */ -+#define AR531X_RESETTMR (AR531X_APBBASE + 0x3000) -+#define AR531X_TIMER (AR531X_RESETTMR + 0x0000) /* countdown timer */ -+#define AR531X_WD_CTRL (AR531X_RESETTMR + 0x0008) /* watchdog cntrl */ -+#define AR531X_WD_TIMER (AR531X_RESETTMR + 0x000c) /* watchdog timer */ -+#define AR531X_ISR (AR531X_RESETTMR + 0x0010) /* Intr Status Reg */ -+#define AR531X_IMR (AR531X_RESETTMR + 0x0014) /* Intr Mask Reg */ -+#define AR531X_RESET (AR531X_RESETTMR + 0x0020) -+#define AR5312_CLOCKCTL1 (AR531X_RESETTMR + 0x0064) -+#define AR5312_SCRATCH (AR531X_RESETTMR + 0x006c) -+#define AR531X_PROCADDR (AR531X_RESETTMR + 0x0070) -+#define AR531X_PROC1 (AR531X_RESETTMR + 0x0074) -+#define AR531X_DMAADDR (AR531X_RESETTMR + 0x0078) -+#define AR531X_DMA1 (AR531X_RESETTMR + 0x007c) -+#define AR531X_ENABLE (AR531X_RESETTMR + 0x0080) /* interface enb */ -+#define AR531X_REV (AR531X_RESETTMR + 0x0090) /* revision */ -+ -+/* AR531X_WD_CTRL register bit field definitions */ -+#define AR531X_WD_CTRL_IGNORE_EXPIRATION 0x0000 -+#define AR531X_WD_CTRL_NMI 0x0001 -+#define AR531X_WD_CTRL_RESET 0x0002 -+ -+/* AR531X_ISR register bit field definitions */ -+#define AR531X_ISR_NONE 0x0000 -+#define AR531X_ISR_TIMER 0x0001 -+#define AR531X_ISR_AHBPROC 0x0002 -+#define AR531X_ISR_AHBDMA 0x0004 -+#define AR531X_ISR_GPIO 0x0008 -+#define AR531X_ISR_UART0 0x0010 -+#define AR531X_ISR_UART0DMA 0x0020 -+#define AR531X_ISR_WD 0x0040 -+#define AR531X_ISR_LOCAL 0x0080 -+ -+/* AR531X_RESET register bit field definitions */ -+#define AR531X_RESET_SYSTEM 0x00000001 /* cold reset full system */ -+#define AR531X_RESET_PROC 0x00000002 /* cold reset MIPS core */ -+#define AR531X_RESET_WLAN0 0x00000004 /* cold reset WLAN MAC and BB */ -+#define AR531X_RESET_EPHY0 0x00000008 /* cold reset ENET0 phy */ -+#define AR531X_RESET_EPHY1 0x00000010 /* cold reset ENET1 phy */ -+#define AR531X_RESET_ENET0 0x00000020 /* cold reset ENET0 mac */ -+#define AR531X_RESET_ENET1 0x00000040 /* cold reset ENET1 mac */ -+#define AR531X_RESET_UART0 0x00000100 /* cold reset UART0 (high speed) */ -+#define AR531X_RESET_WLAN1 0x00000200 /* cold reset WLAN MAC/BB */ -+#define AR531X_RESET_APB 0x00000400 /* cold reset APB (ar5312) */ -+#define AR531X_RESET_WARM_PROC 0x00001000 /* warm reset MIPS core */ -+#define AR531X_RESET_WARM_WLAN0_MAC 0x00002000 /* warm reset WLAN0 MAC */ -+#define AR531X_RESET_WARM_WLAN0_BB 0x00004000 /* warm reset WLAN0 BaseBand */ -+#define AR531X_RESET_NMI 0x00010000 /* send an NMI to the processor */ -+#define AR531X_RESET_WARM_WLAN1_MAC 0x00020000 /* warm reset WLAN1 mac */ -+#define AR531X_RESET_WARM_WLAN1_BB 0x00040000 /* warm reset WLAN1 baseband */ -+#define AR531X_RESET_LOCAL_BUS 0x00080000 /* reset local bus */ -+#define AR531X_RESET_WDOG 0x00100000 /* last reset was a watchdog */ -+ -+#define AR531X_RESET_WMAC0_BITS \ -+ AR531X_RESET_WLAN0 |\ -+ AR531X_RESET_WARM_WLAN0_MAC |\ -+ AR531X_RESET_WARM_WLAN0_BB -+ -+#define AR531X_RESERT_WMAC1_BITS \ -+ AR531X_RESET_WLAN1 |\ -+ AR531X_RESET_WARM_WLAN1_MAC |\ -+ AR531X_RESET_WARM_WLAN1_BB -+ -+/* AR5312_CLOCKCTL1 register bit field definitions */ -+#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030 -+#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4 -+#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00 -+#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8 -+#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000 -+ -+/* Valid for AR5312 and AR2312 */ -+#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030 -+#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4 -+#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00 -+#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8 -+#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000 -+ -+/* Valid for AR2313 */ -+#define AR2313_CLOCKCTL1_PREDIVIDE_MASK 0x00003000 -+#define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT 12 -+#define AR2313_CLOCKCTL1_MULTIPLIER_MASK 0x001f0000 -+#define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT 16 -+#define AR2313_CLOCKCTL1_DOUBLER_MASK 0x00000000 -+ -+ -+/* AR531X_ENABLE register bit field definitions */ -+#define AR531X_ENABLE_WLAN0 0x0001 -+#define AR531X_ENABLE_ENET0 0x0002 -+#define AR531X_ENABLE_ENET1 0x0004 -+#define AR531X_ENABLE_UART_AND_WLAN1_PIO 0x0008 /* UART, and WLAN1 PIOs */ -+#define AR531X_ENABLE_WLAN1_DMA 0x0010 /* WLAN1 DMAs */ -+#define AR531X_ENABLE_WLAN1 \ -+ (AR531X_ENABLE_UART_AND_WLAN1_PIO | AR531X_ENABLE_WLAN1_DMA) -+ -+/* AR531X_REV register bit field definitions */ -+#define AR531X_REV_WMAC_MAJ 0xf000 -+#define AR531X_REV_WMAC_MAJ_S 12 -+#define AR531X_REV_WMAC_MIN 0x0f00 -+#define AR531X_REV_WMAC_MIN_S 8 -+#define AR531X_REV_MAJ 0x00f0 -+#define AR531X_REV_MAJ_S 4 -+#define AR531X_REV_MIN 0x000f -+#define AR531X_REV_MIN_S 0 -+#define AR531X_REV_CHIP (REV_MAJ|REV_MIN) -+ -+/* Major revision numbers, bits 7..4 of Revision ID register */ -+#define AR531X_REV_MAJ_AR5312 0x4 -+#define AR531X_REV_MAJ_AR2313 0x5 -+ -+/* Minor revision numbers, bits 3..0 of Revision ID register */ -+#define AR5312_REV_MIN_DUAL 0x0 /* Dual WLAN version */ -+#define AR5312_REV_MIN_SINGLE 0x1 /* Single WLAN version */ -+ -+/* AR531X_FLASHCTL register bit field definitions */ -+#define FLASHCTL_IDCY 0x0000000f /* Idle cycle turn around time */ -+#define FLASHCTL_IDCY_S 0 -+#define FLASHCTL_WST1 0x000003e0 /* Wait state 1 */ -+#define FLASHCTL_WST1_S 5 -+#define FLASHCTL_RBLE 0x00000400 /* Read byte lane enable */ -+#define FLASHCTL_WST2 0x0000f800 /* Wait state 2 */ -+#define FLASHCTL_WST2_S 11 -+#define FLASHCTL_AC 0x00070000 /* Flash address check (added) */ -+#define FLASHCTL_AC_S 16 -+#define FLASHCTL_AC_128K 0x00000000 -+#define FLASHCTL_AC_256K 0x00010000 -+#define FLASHCTL_AC_512K 0x00020000 -+#define FLASHCTL_AC_1M 0x00030000 -+#define FLASHCTL_AC_2M 0x00040000 -+#define FLASHCTL_AC_4M 0x00050000 -+#define FLASHCTL_AC_8M 0x00060000 -+#define FLASHCTL_AC_RES 0x00070000 /* 16MB is not supported */ -+#define FLASHCTL_E 0x00080000 /* Flash bank enable (added) */ -+#define FLASHCTL_BUSERR 0x01000000 /* Bus transfer error status flag */ -+#define FLASHCTL_WPERR 0x02000000 /* Write protect error status flag */ -+#define FLASHCTL_WP 0x04000000 /* Write protect */ -+#define FLASHCTL_BM 0x08000000 /* Burst mode */ -+#define FLASHCTL_MW 0x30000000 /* Memory width */ -+#define FLASHCTL_MWx8 0x00000000 /* Memory width x8 */ -+#define FLASHCTL_MWx16 0x10000000 /* Memory width x16 */ -+#define FLASHCTL_MWx32 0x20000000 /* Memory width x32 (not supported) */ -+#define FLASHCTL_ATNR 0x00000000 /* Access type == no retry */ -+#define FLASHCTL_ATR 0x80000000 /* Access type == retry every */ -+#define FLASHCTL_ATR4 0xc0000000 /* Access type == retry every 4 */ -+ -+/* ARM Flash Controller -- 3 flash banks with either x8 or x16 devices. */ -+#define AR531X_FLASHCTL0 (AR531X_FLASHCTL + 0x00) -+#define AR531X_FLASHCTL1 (AR531X_FLASHCTL + 0x04) -+#define AR531X_FLASHCTL2 (AR531X_FLASHCTL + 0x08) -+ -+/* ARM SDRAM Controller -- just enough to determine memory size */ -+#define AR531X_MEM_CFG1 (AR531X_SDRAMCTL + 0x04) -+#define MEM_CFG1_AC0 0x00000700 /* bank 0: SDRAM addr check (added) */ -+#define MEM_CFG1_AC0_S 8 -+#define MEM_CFG1_AC1 0x00007000 /* bank 1: SDRAM addr check (added) */ -+#define MEM_CFG1_AC1_S 12 -+ -+/* GPIO Address Map */ -+#define AR531X_GPIO (AR531X_APBBASE + 0x2000) -+#define AR531X_GPIO_DO (AR531X_GPIO + 0x00) /* output register */ -+#define AR531X_GPIO_DI (AR531X_GPIO + 0x04) /* intput register */ -+#define AR531X_GPIO_CR (AR531X_GPIO + 0x08) /* control register */ -+ -+/* GPIO Control Register bit field definitions */ -+#define GPIO_CR_M(x) (1 << (x)) /* mask for i/o */ -+#define GPIO_CR_O(x) (0 << (x)) /* mask for output */ -+#define GPIO_CR_I(x) (1 << (x)) /* mask for input */ -+#define GPIO_CR_INT(x) (1 << ((x)+8)) /* mask for interrupt */ -+#define GPIO_CR_UART(x) (1 << ((x)+16)) /* uart multiplex */ -+ -+ -+typedef unsigned int AR531X_REG; -+ -+#define sysRegRead(phys) \ -+ (*(volatile AR531X_REG *)PHYS_TO_K1(phys)) -+ -+#define sysRegWrite(phys, val) \ -+ ((*(volatile AR531X_REG *)PHYS_TO_K1(phys)) = (val)) -+ -+ -+/* -+ * This is board-specific data that is stored in a "fixed" location in flash. -+ * It is shared across operating systems, so it should not be changed lightly. -+ * The main reason we need it is in order to extract the ethernet MAC -+ * address(es). -+ */ -+struct ar531x_boarddata { -+ u32 magic; /* board data is valid */ -+#define AR531X_BD_MAGIC 0x35333131 /* "5311", for all 531x platforms */ -+ u16 cksum; /* checksum (starting with BD_REV 2) */ -+ u16 rev; /* revision of this struct */ -+#define BD_REV 4 -+ char boardName[64]; /* Name of board */ -+ u16 major; /* Board major number */ -+ u16 minor; /* Board minor number */ -+ u32 config; /* Board configuration */ -+#define BD_ENET0 0x00000001 /* ENET0 is stuffed */ -+#define BD_ENET1 0x00000002 /* ENET1 is stuffed */ -+#define BD_UART1 0x00000004 /* UART1 is stuffed */ -+#define BD_UART0 0x00000008 /* UART0 is stuffed (dma) */ -+#define BD_RSTFACTORY 0x00000010 /* Reset factory defaults stuffed */ -+#define BD_SYSLED 0x00000020 /* System LED stuffed */ -+#define BD_EXTUARTCLK 0x00000040 /* External UART clock */ -+#define BD_CPUFREQ 0x00000080 /* cpu freq is valid in nvram */ -+#define BD_SYSFREQ 0x00000100 /* sys freq is set in nvram */ -+#define BD_WLAN0 0x00000200 /* Enable WLAN0 */ -+#define BD_MEMCAP 0x00000400 /* CAP SDRAM @ memCap for testing */ -+#define BD_DISWATCHDOG 0x00000800 /* disable system watchdog */ -+#define BD_WLAN1 0x00001000 /* Enable WLAN1 (ar5212) */ -+#define BD_ISCASPER 0x00002000 /* FLAG for AR2312 */ -+#define BD_WLAN0_2G_EN 0x00004000 /* FLAG for radio0_2G */ -+#define BD_WLAN0_5G_EN 0x00008000 /* FLAG for radio0_2G */ -+#define BD_WLAN1_2G_EN 0x00020000 /* FLAG for radio0_2G */ -+#define BD_WLAN1_5G_EN 0x00040000 /* FLAG for radio0_2G */ -+ u16 resetConfigGpio; /* Reset factory GPIO pin */ -+ u16 sysLedGpio; /* System LED GPIO pin */ -+ -+ u32 cpuFreq; /* CPU core frequency in Hz */ -+ u32 sysFreq; /* System frequency in Hz */ -+ u32 cntFreq; /* Calculated C0_COUNT frequency */ -+ -+ u8 wlan0Mac[6]; -+ u8 enet0Mac[6]; -+ u8 enet1Mac[6]; -+ -+ u16 pciId; /* Pseudo PCIID for common code */ -+ u16 memCap; /* cap bank1 in MB */ -+ -+ /* version 3 */ -+ u8 wlan1Mac[6]; /* (ar5212) */ -+}; -+ -+#else -+ -+/* -+ * Address map -+ */ -+#define AR5315_SDRAM0 0x00000000 /* DRAM */ -+#define AR5315_SPI_READ 0x08000000 /* SPI FLASH */ -+#define AR5315_WLAN0 0xB0000000 /* Wireless MMR */ -+#define AR5315_PCI 0xB0100000 /* PCI MMR */ -+#define AR5315_SDRAMCTL 0xB0300000 /* SDRAM MMR */ -+#define AR5315_LOCAL 0xB0400000 /* LOCAL BUS MMR */ -+#define AR5315_ENET0 0xB0500000 /* ETHERNET MMR */ -+#define AR5315_DSLBASE 0xB1000000 /* RESET CONTROL MMR */ -+#define AR5315_UART0 0xB1100003 /* UART MMR */ -+#define AR5315_SPI 0xB1300000 /* SPI FLASH MMR */ -+#define AR5315_FLASHBT 0xBfc00000 /* ro boot alias to FLASH */ -+#define AR5315_RAM1 0x40000000 /* ram alias */ -+#define AR5315_PCIEXT 0x80000000 /* pci external */ -+#define AR5315_RAM2 0xc0000000 /* ram alias */ -+#define AR5315_RAM3 0xe0000000 /* ram alias */ -+ -+/* -+ * Reset Register -+ */ -+#define AR5315_COLD_RESET (AR5315_DSLBASE + 0x0000) -+ -+/* Cold Reset */ -+#define RESET_COLD_AHB 0x00000001 -+#define RESET_COLD_APB 0x00000002 -+#define RESET_COLD_CPU 0x00000004 -+#define RESET_COLD_CPUWARM 0x00000008 -+#define RESET_SYSTEM (RESET_COLD_CPU | RESET_COLD_APB | RESET_COLD_AHB) /* full system */ -+ -+/* Warm Reset */ -+ -+#define AR5315_RESET (AR5315_DSLBASE + 0x0004) -+ -+#define RESET_WARM_WLAN0_MAC 0x00000001 /* warm reset WLAN0 MAC */ -+#define RESET_WARM_WLAN0_BB 0x00000002 /* warm reset WLAN0 BaseBand */ -+#define RESET_MPEGTS_RSVD 0x00000004 /* warm reset MPEG-TS */ -+#define RESET_PCIDMA 0x00000008 /* warm reset PCI ahb/dma */ -+#define RESET_MEMCTL 0x00000010 /* warm reset memory controller */ -+#define RESET_LOCAL 0x00000020 /* warm reset local bus */ -+#define RESET_I2C_RSVD 0x00000040 /* warm reset I2C bus */ -+#define RESET_SPI 0x00000080 /* warm reset SPI interface */ -+#define RESET_UART0 0x00000100 /* warm reset UART0 */ -+#define RESET_IR_RSVD 0x00000200 /* warm reset IR interface */ -+#define RESET_EPHY0 0x00000400 /* cold reset ENET0 phy */ -+#define RESET_ENET0 0x00000800 /* cold reset ENET0 mac */ -+ -+/* -+ * AHB master arbitration control -+ */ -+#define AR5315_AHB_ARB_CTL (AR5315_DSLBASE + 0x0008) -+ -+#define ARB_CPU 0x00000001 /* CPU, default */ -+#define ARB_WLAN 0x00000002 /* WLAN */ -+#define ARB_MPEGTS_RSVD 0x00000004 /* MPEG-TS */ -+#define ARB_LOCAL 0x00000008 /* LOCAL */ -+#define ARB_PCI 0x00000010 /* PCI */ -+#define ARB_ETHERNET 0x00000020 /* Ethernet */ -+#define ARB_RETRY 0x00000100 /* retry policy, debug only */ -+ -+/* -+ * Config Register -+ */ -+#define AR5315_ENDIAN_CTL (AR5315_DSLBASE + 0x000c) -+ -+#define CONFIG_AHB 0x00000001 /* EC - AHB bridge endianess */ -+#define CONFIG_WLAN 0x00000002 /* WLAN byteswap */ -+#define CONFIG_MPEGTS_RSVD 0x00000004 /* MPEG-TS byteswap */ -+#define CONFIG_PCI 0x00000008 /* PCI byteswap */ -+#define CONFIG_MEMCTL 0x00000010 /* Memory controller endianess */ -+#define CONFIG_LOCAL 0x00000020 /* Local bus byteswap */ -+#define CONFIG_ETHERNET 0x00000040 /* Ethernet byteswap */ -+ -+#define CONFIG_MERGE 0x00000200 /* CPU write buffer merge */ -+#define CONFIG_CPU 0x00000400 /* CPU big endian */ -+#define CONFIG_PCIAHB 0x00000800 -+#define CONFIG_PCIAHB_BRIDGE 0x00001000 -+#define CONFIG_SPI 0x00008000 /* SPI byteswap */ -+#define CONFIG_CPU_DRAM 0x00010000 -+#define CONFIG_CPU_PCI 0x00020000 -+#define CONFIG_CPU_MMR 0x00040000 -+#define CONFIG_BIG 0x00000400 -+ -+ -+/* -+ * NMI control -+ */ -+#define AR5315_NMI_CTL (AR5315_DSLBASE + 0x0010) -+ -+#define NMI_EN 1 -+ -+/* -+ * Revision Register - Initial value is 0x3010 (WMAC 3.0, AR531X 1.0). -+ */ -+#define AR5315_SREV (AR5315_DSLBASE + 0x0014) -+ -+#define REV_MAJ 0x00f0 -+#define REV_MAJ_S 4 -+#define REV_MIN 0x000f -+#define REV_MIN_S 0 -+#define REV_CHIP (REV_MAJ|REV_MIN) -+ -+/* -+ * Interface Enable -+ */ -+#define AR5315_IF_CTL (AR5315_DSLBASE + 0x0018) -+ -+#define IF_MASK 0x00000007 -+#define IF_DISABLED 0 -+#define IF_PCI 1 -+#define IF_TS_LOCAL 2 -+#define IF_ALL 3 /* only for emulation with separate pins */ -+#define IF_LOCAL_HOST 0x00000008 -+#define IF_PCI_HOST 0x00000010 -+#define IF_PCI_INTR 0x00000020 -+#define IF_PCI_CLK_MASK 0x00030000 -+#define IF_PCI_CLK_INPUT 0 -+#define IF_PCI_CLK_OUTPUT_LOW 1 -+#define IF_PCI_CLK_OUTPUT_CLK 2 -+#define IF_PCI_CLK_OUTPUT_HIGH 3 -+#define IF_PCI_CLK_SHIFT 16 -+ -+ -+/* Major revision numbers, bits 7..4 of Revision ID register */ -+#define REV_MAJ_AR5311 0x01 -+#define REV_MAJ_AR5312 0x04 -+#define REV_MAJ_AR5315 0x0B -+ -+/* -+ * APB Interrupt control -+ */ -+ -+#define AR5315_ISR (AR5315_DSLBASE + 0x0020) -+#define AR5315_IMR (AR5315_DSLBASE + 0x0024) -+#define AR5315_GISR (AR5315_DSLBASE + 0x0028) -+ -+#define ISR_UART0 0x0001 /* high speed UART */ -+#define ISR_I2C_RSVD 0x0002 /* I2C bus */ -+#define ISR_SPI 0x0004 /* SPI bus */ -+#define ISR_AHB 0x0008 /* AHB error */ -+#define ISR_APB 0x0010 /* APB error */ -+#define ISR_TIMER 0x0020 /* timer */ -+#define ISR_GPIO 0x0040 /* GPIO */ -+#define ISR_WD 0x0080 /* watchdog */ -+#define ISR_IR_RSVD 0x0100 /* IR */ -+ -+#define IMR_UART0 ISR_UART0 -+#define IMR_I2C_RSVD ISR_I2C_RSVD -+#define IMR_SPI ISR_SPI -+#define IMR_AHB ISR_AHB -+#define IMR_APB ISR_APB -+#define IMR_TIMER ISR_TIMER -+#define IMR_GPIO ISR_GPIO -+#define IMR_WD ISR_WD -+#define IMR_IR_RSVD ISR_IR_RSVD -+ -+#define GISR_MISC 0x0001 -+#define GISR_WLAN0 0x0002 -+#define GISR_MPEGTS_RSVD 0x0004 -+#define GISR_LOCALPCI 0x0008 -+#define GISR_WMACPOLL 0x0010 -+#define GISR_TIMER 0x0020 -+#define GISR_ETHERNET 0x0040 -+ -+/* -+ * Interrupt routing from IO to the processor IP bits -+ * Define our inter mask and level -+ */ -+#define AR5315_INTR_MISCIO SR_IBIT3 -+#define AR5315_INTR_WLAN0 SR_IBIT4 -+#define AR5315_INTR_ENET0 SR_IBIT5 -+#define AR5315_INTR_LOCALPCI SR_IBIT6 -+#define AR5315_INTR_WMACPOLL SR_IBIT7 -+#define AR5315_INTR_COMPARE SR_IBIT8 -+ -+/* -+ * Timers -+ */ -+#define AR5315_TIMER (AR5315_DSLBASE + 0x0030) -+#define AR5315_RELOAD (AR5315_DSLBASE + 0x0034) -+#define AR5315_WD (AR5315_DSLBASE + 0x0038) -+#define AR5315_WDC (AR5315_DSLBASE + 0x003c) -+ -+#define WDC_RESET 0x00000002 /* reset on watchdog */ -+#define WDC_NMI 0x00000001 /* NMI on watchdog */ -+#define WDC_IGNORE_EXPIRATION 0x00000000 -+ -+/* -+ * Interface Debug -+ */ -+#define AR531X_FLASHDBG (AR531X_RESETTMR + 0x0040) -+#define AR531X_MIIDBG (AR531X_RESETTMR + 0x0044) -+ -+ -+/* -+ * CPU Performance Counters -+ */ -+#define AR5315_PERFCNT0 (AR5315_DSLBASE + 0x0048) -+#define AR5315_PERFCNT1 (AR5315_DSLBASE + 0x004c) -+ -+#define PERF_DATAHIT 0x0001 /* Count Data Cache Hits */ -+#define PERF_DATAMISS 0x0002 /* Count Data Cache Misses */ -+#define PERF_INSTHIT 0x0004 /* Count Instruction Cache Hits */ -+#define PERF_INSTMISS 0x0008 /* Count Instruction Cache Misses */ -+#define PERF_ACTIVE 0x0010 /* Count Active Processor Cycles */ -+#define PERF_WBHIT 0x0020 /* Count CPU Write Buffer Hits */ -+#define PERF_WBMISS 0x0040 /* Count CPU Write Buffer Misses */ -+ -+#define PERF_EB_ARDY 0x0001 /* Count EB_ARdy signal */ -+#define PERF_EB_AVALID 0x0002 /* Count EB_AValid signal */ -+#define PERF_EB_WDRDY 0x0004 /* Count EB_WDRdy signal */ -+#define PERF_EB_RDVAL 0x0008 /* Count EB_RdVal signal */ -+#define PERF_VRADDR 0x0010 /* Count valid read address cycles */ -+#define PERF_VWADDR 0x0020 /* Count valid write address cycles */ -+#define PERF_VWDATA 0x0040 /* Count valid write data cycles */ -+ -+/* -+ * AHB Error Reporting. -+ */ -+#define AR5315_AHB_ERR0 (AR5315_DSLBASE + 0x0050) /* error */ -+#define AR5315_AHB_ERR1 (AR5315_DSLBASE + 0x0054) /* haddr */ -+#define AR5315_AHB_ERR2 (AR5315_DSLBASE + 0x0058) /* hwdata */ -+#define AR5315_AHB_ERR3 (AR5315_DSLBASE + 0x005c) /* hrdata */ -+#define AR5315_AHB_ERR4 (AR5315_DSLBASE + 0x0060) /* status */ -+ -+#define AHB_ERROR_DET 1 /* AHB Error has been detected, */ -+ /* write 1 to clear all bits in ERR0 */ -+#define AHB_ERROR_OVR 2 /* AHB Error overflow has been detected */ -+#define AHB_ERROR_WDT 4 /* AHB Error due to wdt instead of hresp */ -+ -+#define PROCERR_HMAST 0x0000000f -+#define PROCERR_HMAST_DFLT 0 -+#define PROCERR_HMAST_WMAC 1 -+#define PROCERR_HMAST_ENET 2 -+#define PROCERR_HMAST_PCIENDPT 3 -+#define PROCERR_HMAST_LOCAL 4 -+#define PROCERR_HMAST_CPU 5 -+#define PROCERR_HMAST_PCITGT 6 -+ -+#define PROCERR_HMAST_S 0 -+#define PROCERR_HWRITE 0x00000010 -+#define PROCERR_HSIZE 0x00000060 -+#define PROCERR_HSIZE_S 5 -+#define PROCERR_HTRANS 0x00000180 -+#define PROCERR_HTRANS_S 7 -+#define PROCERR_HBURST 0x00000e00 -+#define PROCERR_HBURST_S 9 -+ -+ -+ -+/* -+ * Clock Control -+ */ -+#define AR5315_PLLC_CTL (AR5315_DSLBASE + 0x0064) -+#define AR5315_PLLV_CTL (AR5315_DSLBASE + 0x0068) -+#define AR5315_CPUCLK (AR5315_DSLBASE + 0x006c) -+#define AR5315_AMBACLK (AR5315_DSLBASE + 0x0070) -+#define AR5315_SYNCCLK (AR5315_DSLBASE + 0x0074) -+#define AR5315_DSL_SLEEP_CTL (AR5315_DSLBASE + 0x0080) -+#define AR5315_DSL_SLEEP_DUR (AR5315_DSLBASE + 0x0084) -+ -+/* PLLc Control fields */ -+#define PLLC_REF_DIV_M 0x00000003 -+#define PLLC_REF_DIV_S 0 -+#define PLLC_FDBACK_DIV_M 0x0000007C -+#define PLLC_FDBACK_DIV_S 2 -+#define PLLC_ADD_FDBACK_DIV_M 0x00000080 -+#define PLLC_ADD_FDBACK_DIV_S 7 -+#define PLLC_CLKC_DIV_M 0x0001c000 -+#define PLLC_CLKC_DIV_S 14 -+#define PLLC_CLKM_DIV_M 0x00700000 -+#define PLLC_CLKM_DIV_S 20 -+ -+/* CPU CLK Control fields */ -+#define CPUCLK_CLK_SEL_M 0x00000003 -+#define CPUCLK_CLK_SEL_S 0 -+#define CPUCLK_CLK_DIV_M 0x0000000c -+#define CPUCLK_CLK_DIV_S 2 -+ -+/* AMBA CLK Control fields */ -+#define AMBACLK_CLK_SEL_M 0x00000003 -+#define AMBACLK_CLK_SEL_S 0 -+#define AMBACLK_CLK_DIV_M 0x0000000c -+#define AMBACLK_CLK_DIV_S 2 -+ -+#if defined(COBRA_EMUL) -+#define AR5315_AMBA_CLOCK_RATE 20000000 -+#define AR5315_CPU_CLOCK_RATE 40000000 -+#else -+#if defined(DEFAULT_PLL) -+#define AR5315_AMBA_CLOCK_RATE 40000000 -+#define AR5315_CPU_CLOCK_RATE 40000000 -+#else -+#define AR5315_AMBA_CLOCK_RATE 92000000 -+#define AR5315_CPU_CLOCK_RATE 184000000 -+#endif /* ! DEFAULT_PLL */ -+#endif /* ! COBRA_EMUL */ -+ -+#define AR5315_UART_CLOCK_RATE AR5315_AMBA_CLOCK_RATE -+#define AR5315_SDRAM_CLOCK_RATE AR5315_AMBA_CLOCK_RATE -+ -+/* -+ * The UART computes baud rate as: -+ * baud = clock / (16 * divisor) -+ * where divisor is specified as a High Byte (DLM) and a Low Byte (DLL). -+ */ -+#define DESIRED_BAUD_RATE 38400 -+ -+/* -+ * The WATCHDOG value is computed as -+ * 10 seconds * AR531X_WATCHDOG_CLOCK_RATE -+ */ -+#define DESIRED_WATCHDOG_SECONDS 10 -+#define AR531X_WATCHDOG_TIME \ -+ (DESIRED_WATCHDOG_SECONDS * AR531X_WATCHDOG_CLOCK_RATE) -+ -+ -+#define CLOCKCTL_UART0 0x0010 /* enable UART0 external clock */ -+ -+ -+ /* -+ * Applicable "PCICFG" bits for WLAN(s). Assoc status and LED mode. -+ */ -+#define AR531X_PCICFG (AR531X_RESETTMR + 0x00b0) -+#define ASSOC_STATUS_M 0x00000003 -+#define ASSOC_STATUS_NONE 0 -+#define ASSOC_STATUS_PENDING 1 -+#define ASSOC_STATUS_ASSOCIATED 2 -+#define LED_MODE_M 0x0000001c -+#define LED_BLINK_THRESHOLD_M 0x000000e0 -+#define LED_SLOW_BLINK_MODE 0x00000100 -+ -+/* -+ * GPIO -+ */ -+ -+#define AR5315_GPIO_DI (AR5315_DSLBASE + 0x0088) -+#define AR5315_GPIO_DO (AR5315_DSLBASE + 0x0090) -+#define AR5315_GPIO_CR (AR5315_DSLBASE + 0x0098) -+#define AR5315_GPIO_INT (AR5315_DSLBASE + 0x00a0) -+ -+#define GPIO_CR_M(x) (1 << (x)) /* mask for i/o */ -+#define GPIO_CR_O(x) (1 << (x)) /* output */ -+#define GPIO_CR_I(x) (0 << (x)) /* input */ -+ -+#define GPIO_INT(x,Y) ((x) << (8 * (Y))) /* interrupt enable */ -+#define GPIO_INT_M(Y) ((0x3F) << (8 * (Y))) /* mask for int */ -+#define GPIO_INT_LVL(x,Y) ((x) << (8 * (Y) + 6)) /* interrupt level */ -+#define GPIO_INT_LVL_M(Y) ((0x3) << (8 * (Y) + 6)) /* mask for int level */ -+ -+#define AR5315_RESET_GPIO 5 -+#define AR5315_NUM_GPIO 22 -+ -+ -+/* -+ * PCI Clock Control -+ */ -+ -+#define AR5315_PCICLK (AR5315_DSLBASE + 0x00a4) -+ -+#define PCICLK_INPUT_M 0x3 -+#define PCICLK_INPUT_S 0 -+ -+#define PCICLK_PLLC_CLKM 0 -+#define PCICLK_PLLC_CLKM1 1 -+#define PCICLK_PLLC_CLKC 2 -+#define PCICLK_REF_CLK 3 -+ -+#define PCICLK_DIV_M 0xc -+#define PCICLK_DIV_S 2 -+ -+#define PCICLK_IN_FREQ 0 -+#define PCICLK_IN_FREQ_DIV_6 1 -+#define PCICLK_IN_FREQ_DIV_8 2 -+#define PCICLK_IN_FREQ_DIV_10 3 -+ -+/* -+ * Observation Control Register -+ */ -+#define AR5315_OCR (AR5315_DSLBASE + 0x00b0) -+#define OCR_GPIO0_IRIN 0x0040 -+#define OCR_GPIO1_IROUT 0x0080 -+#define OCR_GPIO3_RXCLR 0x0200 -+ -+/* -+ * General Clock Control -+ */ -+ -+#define AR5315_MISCCLK (AR5315_DSLBASE + 0x00b4) -+#define MISCCLK_PLLBYPASS_EN 0x00000001 -+#define MISCCLK_PROCREFCLK 0x00000002 -+ -+/* -+ * SDRAM Controller -+ * - No read or write buffers are included. -+ */ -+#define AR5315_MEM_CFG (AR5315_SDRAMCTL + 0x00) -+#define AR5315_MEM_CTRL (AR5315_SDRAMCTL + 0x0c) -+#define AR5315_MEM_REF (AR5315_SDRAMCTL + 0x10) -+ -+#define SDRAM_DATA_WIDTH_M 0x00006000 -+#define SDRAM_DATA_WIDTH_S 13 -+ -+#define SDRAM_COL_WIDTH_M 0x00001E00 -+#define SDRAM_COL_WIDTH_S 9 -+ -+#define SDRAM_ROW_WIDTH_M 0x000001E0 -+#define SDRAM_ROW_WIDTH_S 5 -+ -+#define SDRAM_BANKADDR_BITS_M 0x00000018 -+#define SDRAM_BANKADDR_BITS_S 3 -+ -+ -+/* -+ * SDRAM Memory Refresh (MEM_REF) value is computed as: -+ * MEMCTL_SREFR = (Tr * hclk_freq) / R -+ * where Tr is max. time of refresh of any single row -+ * R is number of rows in the DRAM -+ * For most 133MHz SDRAM parts, Tr=64ms, R=4096 or 8192 -+ */ -+#if defined(COBRA_EMUL) -+#define AR5315_SDRAM_MEMORY_REFRESH_VALUE 0x96 -+#else -+#if defined(DEFAULT_PLL) -+#define AR5315_SDRAM_MEMORY_REFRESH_VALUE 0x200 -+#else -+#define AR5315_SDRAM_MEMORY_REFRESH_VALUE 0x61a -+#endif /* ! DEFAULT_PLL */ -+#endif -+ -+#if defined(AR5315) -+ -+#define AR5315_SDRAM_DDR_SDRAM 0 /* Not DDR SDRAM */ -+#define AR5315_SDRAM_DATA_WIDTH 16 /* bits */ -+#define AR5315_SDRAM_COL_WIDTH 8 -+#define AR5315_SDRAM_ROW_WIDTH 12 -+ -+#else -+ -+#define AR5315_SDRAM_DDR_SDRAM 0 /* Not DDR SDRAM */ -+#define AR5315_SDRAM_DATA_WIDTH 16 -+#define AR5315_SDRAM_COL_WIDTH 8 -+#define AR5315_SDRAM_ROW_WIDTH 12 -+ -+#endif /* ! AR5315 */ -+ -+/* -+ * SPI Flash Interface Registers -+ */ -+ -+#define AR5315_SPI_CTL (AR5315_SPI + 0x00) -+#define AR5315_SPI_OPCODE (AR5315_SPI + 0x04) -+#define AR5315_SPI_DATA (AR5315_SPI + 0x08) -+ -+#define SPI_CTL_START 0x00000100 -+#define SPI_CTL_BUSY 0x00010000 -+#define SPI_CTL_TXCNT_MASK 0x0000000f -+#define SPI_CTL_RXCNT_MASK 0x000000f0 -+#define SPI_CTL_TX_RX_CNT_MASK 0x000000ff -+#define SPI_CTL_SIZE_MASK 0x00060000 -+ -+#define SPI_CTL_CLK_SEL_MASK 0x03000000 -+#define SPI_OPCODE_MASK 0x000000ff -+ -+/* -+ * PCI-MAC Configuration registers -+ */ -+#define PCI_MAC_RC (AR5315_PCI + 0x4000) -+#define PCI_MAC_SCR (AR5315_PCI + 0x4004) -+#define PCI_MAC_INTPEND (AR5315_PCI + 0x4008) -+#define PCI_MAC_SFR (AR5315_PCI + 0x400C) -+#define PCI_MAC_PCICFG (AR5315_PCI + 0x4010) -+#define PCI_MAC_SREV (AR5315_PCI + 0x4020) -+ -+#define PCI_MAC_RC_MAC 0x00000001 -+#define PCI_MAC_RC_BB 0x00000002 -+ -+#define PCI_MAC_SCR_SLMODE_M 0x00030000 -+#define PCI_MAC_SCR_SLMODE_S 16 -+#define PCI_MAC_SCR_SLM_FWAKE 0 -+#define PCI_MAC_SCR_SLM_FSLEEP 1 -+#define PCI_MAC_SCR_SLM_NORMAL 2 -+ -+#define PCI_MAC_SFR_SLEEP 0x00000001 -+ -+#define PCI_MAC_PCICFG_SPWR_DN 0x00010000 -+ -+ -+ -+ -+/* -+ * PCI Bus Interface Registers -+ */ -+#define AR5315_PCI_1MS_REG (AR5315_PCI + 0x0008) -+#define AR5315_PCI_1MS_MASK 0x3FFFF /* # of AHB clk cycles in 1ms */ -+ -+#define AR5315_PCI_MISC_CONFIG (AR5315_PCI + 0x000c) -+#define AR5315_PCIMISC_TXD_EN 0x00000001 /* Enable TXD for fragments */ -+#define AR5315_PCIMISC_CFG_SEL 0x00000002 /* mem or config cycles */ -+#define AR5315_PCIMISC_GIG_MASK 0x0000000C /* bits 31-30 for pci req */ -+#define AR5315_PCIMISC_RST_MODE 0x00000030 -+#define AR5315_PCIRST_INPUT 0x00000000 /* 4:5=0 rst is input */ -+#define AR5315_PCIRST_LOW 0x00000010 /* 4:5=1 rst to GND */ -+#define AR5315_PCIRST_HIGH 0x00000020 /* 4:5=2 rst to VDD */ -+#define AR5315_PCIGRANT_EN 0x00000000 /* 6:7=0 early grant en */ -+#define AR5315_PCIGRANT_FRAME 0x00000040 /* 6:7=1 grant waits 4 frame */ -+#define AR5315_PCIGRANT_IDLE 0x00000080 /* 6:7=2 grant waits 4 idle */ -+#define AR5315_PCIGRANT_GAP 0x00000000 /* 6:7=2 grant waits 4 idle */ -+#define AR5315_PCICACHE_DIS 0x00001000 /* PCI external access cache disable */ -+ -+#define AR5315_PCI_OUT_TSTAMP (AR5315_PCI + 0x0010) -+ -+#define AR5315_PCI_UNCACHE_CFG (AR5315_PCI + 0x0014) -+ -+#define AR5315_PCI_IN_EN (AR5315_PCI + 0x0100) -+#define AR5315_PCI_IN_EN0 0x01 /* Enable chain 0 */ -+#define AR5315_PCI_IN_EN1 0x02 /* Enable chain 1 */ -+#define AR5315_PCI_IN_EN2 0x04 /* Enable chain 2 */ -+#define AR5315_PCI_IN_EN3 0x08 /* Enable chain 3 */ -+ -+#define AR5315_PCI_IN_DIS (AR5315_PCI + 0x0104) -+#define AR5315_PCI_IN_DIS0 0x01 /* Disable chain 0 */ -+#define AR5315_PCI_IN_DIS1 0x02 /* Disable chain 1 */ -+#define AR5315_PCI_IN_DIS2 0x04 /* Disable chain 2 */ -+#define AR5315_PCI_IN_DIS3 0x08 /* Disable chain 3 */ -+ -+#define AR5315_PCI_IN_PTR (AR5315_PCI + 0x0200) -+ -+#define AR5315_PCI_OUT_EN (AR5315_PCI + 0x0400) -+#define AR5315_PCI_OUT_EN0 0x01 /* Enable chain 0 */ -+ -+#define AR5315_PCI_OUT_DIS (AR5315_PCI + 0x0404) -+#define AR5315_PCI_OUT_DIS0 0x01 /* Disable chain 0 */ -+ -+#define AR5315_PCI_OUT_PTR (AR5315_PCI + 0x0408) -+ -+#define AR5315_PCI_INT_STATUS (AR5315_PCI + 0x0500) /* write one to clr */ -+#define AR5315_PCI_TXINT 0x00000001 /* Desc In Completed */ -+#define AR5315_PCI_TXOK 0x00000002 /* Desc In OK */ -+#define AR5315_PCI_TXERR 0x00000004 /* Desc In ERR */ -+#define AR5315_PCI_TXEOL 0x00000008 /* Desc In End-of-List */ -+#define AR5315_PCI_RXINT 0x00000010 /* Desc Out Completed */ -+#define AR5315_PCI_RXOK 0x00000020 /* Desc Out OK */ -+#define AR5315_PCI_RXERR 0x00000040 /* Desc Out ERR */ -+#define AR5315_PCI_RXEOL 0x00000080 /* Desc Out EOL */ -+#define AR5315_PCI_TXOOD 0x00000200 /* Desc In Out-of-Desc */ -+#define AR5315_PCI_MASK 0x0000FFFF /* Desc Mask */ -+#define AR5315_PCI_EXT_INT 0x02000000 -+#define AR5315_PCI_ABORT_INT 0x04000000 -+ -+#define AR5315_PCI_INT_MASK (AR5315_PCI + 0x0504) /* same as INT_STATUS */ -+ -+#define AR5315_PCI_INTEN_REG (AR5315_PCI + 0x0508) -+#define AR5315_PCI_INT_DISABLE 0x00 /* disable pci interrupts */ -+#define AR5315_PCI_INT_ENABLE 0x01 /* enable pci interrupts */ -+ -+#define AR5315_PCI_HOST_IN_EN (AR5315_PCI + 0x0800) -+#define AR5315_PCI_HOST_IN_DIS (AR5315_PCI + 0x0804) -+#define AR5315_PCI_HOST_IN_PTR (AR5315_PCI + 0x0810) -+#define AR5315_PCI_HOST_OUT_EN (AR5315_PCI + 0x0900) -+#define AR5315_PCI_HOST_OUT_DIS (AR5315_PCI + 0x0904) -+#define AR5315_PCI_HOST_OUT_PTR (AR5315_PCI + 0x0908) -+ -+ -+/* -+ * Local Bus Interface Registers -+ */ -+#define AR5315_LB_CONFIG (AR5315_LOCAL + 0x0000) -+#define AR5315_LBCONF_OE 0x00000001 /* =1 OE is low-true */ -+#define AR5315_LBCONF_CS0 0x00000002 /* =1 first CS is low-true */ -+#define AR5315_LBCONF_CS1 0x00000004 /* =1 2nd CS is low-true */ -+#define AR5315_LBCONF_RDY 0x00000008 /* =1 RDY is low-true */ -+#define AR5315_LBCONF_WE 0x00000010 /* =1 Write En is low-true */ -+#define AR5315_LBCONF_WAIT 0x00000020 /* =1 WAIT is low-true */ -+#define AR5315_LBCONF_ADS 0x00000040 /* =1 Adr Strobe is low-true */ -+#define AR5315_LBCONF_MOT 0x00000080 /* =0 Intel, =1 Motorola */ -+#define AR5315_LBCONF_8CS 0x00000100 /* =1 8 bits CS, 0= 16bits */ -+#define AR5315_LBCONF_8DS 0x00000200 /* =1 8 bits Data S, 0=16bits */ -+#define AR5315_LBCONF_ADS_EN 0x00000400 /* =1 Enable ADS */ -+#define AR5315_LBCONF_ADR_OE 0x00000800 /* =1 Adr cap on OE, WE or DS */ -+#define AR5315_LBCONF_ADDT_MUX 0x00001000 /* =1 Adr and Data share bus */ -+#define AR5315_LBCONF_DATA_OE 0x00002000 /* =1 Data cap on OE, WE, DS */ -+#define AR5315_LBCONF_16DATA 0x00004000 /* =1 Data is 16 bits wide */ -+#define AR5315_LBCONF_SWAPDT 0x00008000 /* =1 Byte swap data */ -+#define AR5315_LBCONF_SYNC 0x00010000 /* =1 Bus synchronous to clk */ -+#define AR5315_LBCONF_INT 0x00020000 /* =1 Intr is low true */ -+#define AR5315_LBCONF_INT_CTR0 0x00000000 /* GND high-Z, Vdd is high-Z */ -+#define AR5315_LBCONF_INT_CTR1 0x00040000 /* GND drive, Vdd is high-Z */ -+#define AR5315_LBCONF_INT_CTR2 0x00080000 /* GND high-Z, Vdd drive */ -+#define AR5315_LBCONF_INT_CTR3 0x000C0000 /* GND drive, Vdd drive */ -+#define AR5315_LBCONF_RDY_WAIT 0x00100000 /* =1 RDY is negative of WAIT */ -+#define AR5315_LBCONF_INT_PULSE 0x00200000 /* =1 Interrupt is a pulse */ -+#define AR5315_LBCONF_ENABLE 0x00400000 /* =1 Falcon respond to LB */ -+ -+#define AR5315_LB_CLKSEL (AR5315_LOCAL + 0x0004) -+#define AR5315_LBCLK_EXT 0x0001 /* use external clk for lb */ -+ -+#define AR5315_LB_1MS (AR5315_LOCAL + 0x0008) -+#define AR5315_LB1MS_MASK 0x3FFFF /* # of AHB clk cycles in 1ms */ -+ -+#define AR5315_LB_MISCCFG (AR5315_LOCAL + 0x000C) -+#define AR5315_LBM_TXD_EN 0x00000001 /* Enable TXD for fragments */ -+#define AR5315_LBM_RX_INTEN 0x00000002 /* Enable LB ints on RX ready */ -+#define AR5315_LBM_MBOXWR_INTEN 0x00000004 /* Enable LB ints on mbox wr */ -+#define AR5315_LBM_MBOXRD_INTEN 0x00000008 /* Enable LB ints on mbox rd */ -+#define AR5315_LMB_DESCSWAP_EN 0x00000010 /* Byte swap desc enable */ -+#define AR5315_LBM_TIMEOUT_MASK 0x00FFFF80 -+#define AR5315_LBM_TIMEOUT_SHFT 7 -+#define AR5315_LBM_PORTMUX 0x07000000 -+ -+ -+#define AR5315_LB_RXTSOFF (AR5315_LOCAL + 0x0010) -+ -+#define AR5315_LB_TX_CHAIN_EN (AR5315_LOCAL + 0x0100) -+#define AR5315_LB_TXEN_0 0x01 -+#define AR5315_LB_TXEN_1 0x02 -+#define AR5315_LB_TXEN_2 0x04 -+#define AR5315_LB_TXEN_3 0x08 -+ -+#define AR5315_LB_TX_CHAIN_DIS (AR5315_LOCAL + 0x0104) -+#define AR5315_LB_TX_DESC_PTR (AR5315_LOCAL + 0x0200) -+ -+#define AR5315_LB_RX_CHAIN_EN (AR5315_LOCAL + 0x0400) -+#define AR5315_LB_RXEN 0x01 -+ -+#define AR5315_LB_RX_CHAIN_DIS (AR5315_LOCAL + 0x0404) -+#define AR5315_LB_RX_DESC_PTR (AR5315_LOCAL + 0x0408) -+ -+#define AR5315_LB_INT_STATUS (AR5315_LOCAL + 0x0500) -+#define AR5315_INT_TX_DESC 0x0001 -+#define AR5315_INT_TX_OK 0x0002 -+#define AR5315_INT_TX_ERR 0x0004 -+#define AR5315_INT_TX_EOF 0x0008 -+#define AR5315_INT_RX_DESC 0x0010 -+#define AR5315_INT_RX_OK 0x0020 -+#define AR5315_INT_RX_ERR 0x0040 -+#define AR5315_INT_RX_EOF 0x0080 -+#define AR5315_INT_TX_TRUNC 0x0100 -+#define AR5315_INT_TX_STARVE 0x0200 -+#define AR5315_INT_LB_TIMEOUT 0x0400 -+#define AR5315_INT_LB_ERR 0x0800 -+#define AR5315_INT_MBOX_WR 0x1000 -+#define AR5315_INT_MBOX_RD 0x2000 -+ -+/* Bit definitions for INT MASK are the same as INT_STATUS */ -+#define AR5315_LB_INT_MASK (AR5315_LOCAL + 0x0504) -+ -+#define AR5315_LB_INT_EN (AR5315_LOCAL + 0x0508) -+#define AR5315_LB_MBOX (AR5315_LOCAL + 0x0600) -+ -+ -+ -+/* -+ * IR Interface Registers -+ */ -+#define AR5315_IR_PKTDATA (AR5315_IR + 0x0000) -+ -+#define AR5315_IR_PKTLEN (AR5315_IR + 0x07fc) /* 0 - 63 */ -+ -+#define AR5315_IR_CONTROL (AR5315_IR + 0x0800) -+#define AR5315_IRCTL_TX 0x00000000 /* use as tranmitter */ -+#define AR5315_IRCTL_RX 0x00000001 /* use as receiver */ -+#define AR5315_IRCTL_SAMPLECLK_MASK 0x00003ffe /* Sample clk divisor mask */ -+#define AR5315_IRCTL_SAMPLECLK_SHFT 1 -+#define AR5315_IRCTL_OUTPUTCLK_MASK 0x03ffc000 /* Output clk divisor mask */ -+#define AR5315_IRCTL_OUTPUTCLK_SHFT 14 -+ -+#define AR5315_IR_STATUS (AR5315_IR + 0x0804) -+#define AR5315_IRSTS_RX 0x00000001 /* receive in progress */ -+#define AR5315_IRSTS_TX 0x00000002 /* transmit in progress */ -+ -+#define AR5315_IR_CONFIG (AR5315_IR + 0x0808) -+#define AR5315_IRCFG_INVIN 0x00000001 /* invert input polarity */ -+#define AR5315_IRCFG_INVOUT 0x00000002 /* invert output polarity */ -+#define AR5315_IRCFG_SEQ_START_WIN_SEL 0x00000004 /* 1 => 28, 0 => 7 */ -+#define AR5315_IRCFG_SEQ_START_THRESH 0x000000f0 /* */ -+#define AR5315_IRCFG_SEQ_END_UNIT_SEL 0x00000100 /* */ -+#define AR5315_IRCFG_SEQ_END_UNIT_THRESH 0x00007e00 /* */ -+#define AR5315_IRCFG_SEQ_END_WIN_SEL 0x00008000 /* */ -+#define AR5315_IRCFG_SEQ_END_WIN_THRESH 0x001f0000 /* */ -+#define AR5315_IRCFG_NUM_BACKOFF_WORDS 0x01e00000 /* */ -+ -+/* -+ * PCI memory constants: Memory area 1 and 2 are the same size - -+ * (twice the PCI_TLB_PAGE_SIZE). The definition of -+ * CPU_TO_PCI_MEM_SIZE is coupled with the TLB setup routine -+ * sysLib.c/sysTlbInit(), in that it assumes that 2 pages of size -+ * PCI_TLB_PAGE_SIZE are set up in the TLB for each PCI memory space. -+ */ -+ -+#define CPU_TO_PCI_MEM_BASE1 0xE0000000 -+#define CPU_TO_PCI_MEM_SIZE1 (2*PCI_TLB_PAGE_SIZE) -+ -+ -+/* TLB attributes for PCI transactions */ -+ -+#define PCI_MMU_PAGEMASK 0x00003FFF -+#define MMU_PAGE_UNCACHED 0x00000010 -+#define MMU_PAGE_DIRTY 0x00000004 -+#define MMU_PAGE_VALID 0x00000002 -+#define MMU_PAGE_GLOBAL 0x00000001 -+#define PCI_MMU_PAGEATTRIB (MMU_PAGE_UNCACHED|MMU_PAGE_DIRTY|\ -+ MMU_PAGE_VALID|MMU_PAGE_GLOBAL) -+#define PCI_MEMORY_SPACE1_VIRT 0xE0000000 /* Used for non-prefet mem */ -+#define PCI_MEMORY_SPACE1_PHYS 0x80000000 -+#define PCI_TLB_PAGE_SIZE 0x01000000 -+#define TLB_HI_MASK 0xFFFFE000 -+#define TLB_LO_MASK 0x3FFFFFFF -+#define PAGEMASK_SHIFT 11 -+#define TLB_LO_SHIFT 6 -+ -+#define PCI_MAX_LATENCY 0xFFF /* Max PCI latency */ -+ -+#define HOST_PCI_DEV_ID 3 -+#define HOST_PCI_MBAR0 0x10000000 -+#define HOST_PCI_MBAR1 0x20000000 -+#define HOST_PCI_MBAR2 0x30000000 -+ -+#define HOST_PCI_SDRAM_BASEADDR HOST_PCI_MBAR1 -+#define PCI_DEVICE_MEM_SPACE 0x800000 -+ -+ -+typedef unsigned int AR531X_REG; -+ -+#define sysRegRead(phys) \ -+ (*(volatile AR531X_REG *)PHYS_TO_K1(phys)) -+ -+#define sysRegWrite(phys, val) \ -+ ((*(volatile AR531X_REG *)PHYS_TO_K1(phys)) = (val)) -+#endif -+ -+#endif -diff -urN linux-mips/arch/mips/ar531x/ar531xintr.S mips-linux-2.4.25/arch/mips/ar531x/ar531xintr.S ---- linux-mips/arch/mips/ar531x/ar531xintr.S 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/arch/mips/ar531x/ar531xintr.S 2005-12-30 17:26:31.000823952 +0000 -@@ -0,0 +1,30 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+#include <asm/asm.h> -+#include <asm/mipsregs.h> -+#include <asm/regdef.h> -+#include <asm/stackframe.h> -+ -+/* -+ * Glue code to save registers and get us to the interrupt dispatcher -+ */ -+ .text -+ .set noat -+ .align 5 -+NESTED(ar531x_interrupt_receive, PT_SIZE, sp) -+ SAVE_ALL -+ CLI -+ .set at -+ -+ move a0, sp -+ jal ar531x_irq_dispatch -+ -+ j ret_from_irq -+ -+ END(ar531x_interrupt_receive) -diff -urN linux-mips/arch/mips/ar531x/ar531xirq.c mips-linux-2.4.25/arch/mips/ar531x/ar531xirq.c ---- linux-mips/arch/mips/ar531x/ar531xirq.c 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/arch/mips/ar531x/ar531xirq.c 2005-12-30 17:26:31.000823952 +0000 -@@ -0,0 +1,442 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * Interrupt support for AR531X WiSOC. -+ */ -+ -+#include <linux/config.h> -+#include <linux/init.h> -+#include <linux/kernel_stat.h> -+#include <linux/signal.h> -+#include <linux/sched.h> -+#include <linux/interrupt.h> -+#include <linux/slab.h> -+#include <linux/random.h> -+#include <linux/pm.h> -+#include <linux/delay.h> -+#include <linux/reboot.h> -+ -+#include <asm/irq.h> -+#include <asm/mipsregs.h> -+#include <asm/gdb-stub.h> -+ -+#include "ar531xlnx.h" -+#include <asm/irq_cpu.h> -+ -+extern int setup_irq(unsigned int irq, struct irqaction *irqaction); -+ -+static void ar531x_misc_intr_enable(unsigned int irq); -+static void ar531x_misc_intr_disable(unsigned int irq); -+ -+/* Turn on the specified AR531X_MISC_IRQ interrupt */ -+static unsigned int -+ar531x_misc_intr_startup(unsigned int irq) -+{ -+ ar531x_misc_intr_enable(irq); -+ return 0; -+} -+ -+/* Turn off the specified AR531X_MISC_IRQ interrupt */ -+static void -+ar531x_misc_intr_shutdown(unsigned int irq) -+{ -+ ar531x_misc_intr_disable(irq); -+} -+ -+/* Enable the specified AR531X_MISC_IRQ interrupt */ -+static void -+ar531x_misc_intr_enable(unsigned int irq) -+{ -+ unsigned int imr; -+ -+#if CONFIG_AR5315 -+ imr = sysRegRead(AR5315_IMR); -+ switch(irq) -+ { -+ case AR531X_MISC_IRQ_TIMER: -+ imr |= IMR_TIMER; -+ break; -+ -+ case AR531X_MISC_IRQ_AHB_PROC: -+ imr |= IMR_AHB; -+ break; -+ -+ case AR531X_MISC_IRQ_AHB_DMA: -+ imr |= 0/* ?? */; -+ break; -+ /* -+ case AR531X_ISR_GPIO: -+ imr |= IMR_GPIO; -+ break; -+ */ -+ -+ case AR531X_MISC_IRQ_UART0: -+ imr |= IMR_UART0; -+ break; -+ -+ -+ case AR531X_MISC_IRQ_WATCHDOG: -+ imr |= IMR_WD; -+ break; -+ -+ case AR531X_MISC_IRQ_LOCAL: -+ imr |= 0/* ?? */; -+ break; -+ -+ } -+ sysRegWrite(AR5315_IMR, imr); -+ imr=sysRegRead(AR5315_IMR); /* flush write buffer */ -+ //printk("enable Interrupt irq 0x%x imr 0x%x \n",irq,imr); -+ -+#else -+ imr = sysRegRead(AR531X_IMR); -+ imr |= (1 << (irq - AR531X_MISC_IRQ_BASE - 1)); -+ sysRegWrite(AR531X_IMR, imr); -+ sysRegRead(AR531X_IMR); /* flush write buffer */ -+#endif -+} -+ -+/* Disable the specified AR531X_MISC_IRQ interrupt */ -+static void -+ar531x_misc_intr_disable(unsigned int irq) -+{ -+ unsigned int imr; -+ -+#if CONFIG_AR5315 -+ imr = sysRegRead(AR5315_IMR); -+ switch(irq) -+ { -+ case AR531X_MISC_IRQ_TIMER: -+ imr &= (~IMR_TIMER); -+ break; -+ -+ case AR531X_MISC_IRQ_AHB_PROC: -+ imr &= (~IMR_AHB); -+ break; -+ -+ case AR531X_MISC_IRQ_AHB_DMA: -+ imr &= 0/* ?? */; -+ break; -+ /* -+ case AR531X_ISR_GPIO: -+ imr &= ~IMR_GPIO; -+ break; -+ */ -+ -+ case AR531X_MISC_IRQ_UART0: -+ imr &= (~IMR_UART0); -+ break; -+ -+ case AR531X_MISC_IRQ_WATCHDOG: -+ imr &= (~IMR_WD); -+ break; -+ -+ case AR531X_MISC_IRQ_LOCAL: -+ imr &= ~0/* ?? */; -+ break; -+ -+ } -+ sysRegWrite(AR5315_IMR, imr); -+ sysRegRead(AR5315_IMR); /* flush write buffer */ -+#else -+ imr = sysRegRead(AR531X_IMR); -+ imr &= ~(1 << (irq - AR531X_MISC_IRQ_BASE - 1)); -+ sysRegWrite(AR531X_IMR, imr); -+ sysRegRead(AR531X_IMR); /* flush write buffer */ -+#endif -+} -+ -+static void -+ar531x_misc_intr_ack(unsigned int irq) -+{ -+ ar531x_misc_intr_disable(irq); -+} -+ -+static void -+ar531x_misc_intr_end(unsigned int irq) -+{ -+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) -+ ar531x_misc_intr_enable(irq); -+} -+ -+static void -+ar531x_misc_intr_set_affinity(unsigned int irq, unsigned long mask) -+{ -+ /* Only 1 CPU; ignore affinity request */ -+} -+ -+struct hw_interrupt_type ar531x_misc_intr_controller = { -+ "AR531X MISC", -+ ar531x_misc_intr_startup, -+ ar531x_misc_intr_shutdown, -+ ar531x_misc_intr_enable, -+ ar531x_misc_intr_disable, -+ ar531x_misc_intr_ack, -+ ar531x_misc_intr_end, -+ ar531x_misc_intr_set_affinity, -+}; -+ -+int ar531x_misc_irq_base; -+ -+/* -+ * Determine interrupt source among interrupts that use IP6 -+ */ -+void -+ar531x_misc_intr_init(int irq_base) -+{ -+ int i; -+ -+ for (i = irq_base; i < irq_base + AR531X_MISC_IRQ_COUNT; i++) { -+ irq_desc[i].status = IRQ_DISABLED; -+ irq_desc[i].action = NULL; -+ irq_desc[i].depth = 1; -+ irq_desc[i].handler = &ar531x_misc_intr_controller; -+ } -+ -+ ar531x_misc_irq_base = irq_base; -+} -+ -+/* ARGSUSED */ -+void -+spurious_irq_handler(int cpl, void *dev_id, struct pt_regs *regs) -+{ -+ /* -+ printk("spurious_irq_handler: %d cause=0x%8.8x status=0x%8.8x\n", -+ cpl, cause_intrs, status_intrs); -+ */ -+} -+ -+/* ARGSUSED */ -+void -+spurious_misc_handler(int cpl, void *dev_id, struct pt_regs *regs) -+{ -+ /* -+ printk("spurious_misc_handler: 0x%x isr=0x%8.8x imr=0x%8.8x\n", -+ cpl, ar531x_isr, ar531x_imr); -+ */ -+} -+ -+void -+ar531x_timer_handler(int cpl, void *dev_id, struct pt_regs *regs) -+{ -+#if CONFIG_AR5315 -+ (void)sysRegRead(AR5315_TIMER); /* clear interrupt */ -+#else -+ (void)sysRegRead(AR531X_TIMER); /* clear interrupt */ -+#endif -+} -+ -+void -+ar531x_ahb_proc_handler(int cpl, void *dev_id, struct pt_regs *regs) -+{ -+ u32 procAddr; -+ u32 proc1; -+ u32 dmaAddr; -+ u32 dma1; -+#if CONFIG_AR5315 -+ sysRegWrite(AR5315_AHB_ERR0,AHB_ERROR_DET); -+ sysRegRead(AR5315_AHB_ERR1); -+#else -+ proc1 = sysRegRead(AR531X_PROC1); -+ procAddr = sysRegRead(AR531X_PROCADDR); /* clears error state */ -+ dma1 = sysRegRead(AR531X_DMA1); -+ dmaAddr = sysRegRead(AR531X_DMAADDR); /* clears error state */ -+#endif -+ -+ printk("AHB interrupt: PROCADDR=0x%8.8x PROC1=0x%8.8x DMAADDR=0x%8.8x DMA1=0x%8.8x\n", -+ procAddr, proc1, dmaAddr, dma1); -+ -+ machine_restart("AHB error"); /* Catastrophic failure */ -+} -+ -+static struct irqaction cascade = -+ {no_action, SA_INTERRUPT, 0, "cascade", -+ NULL, NULL}; -+ -+static struct irqaction spurious_irq = -+ {spurious_irq_handler, SA_INTERRUPT, 0, "spurious_irq", -+ NULL, NULL}; -+ -+static struct irqaction spurious_misc = -+ {spurious_misc_handler, SA_INTERRUPT, 0, "spurious_misc", -+ NULL, NULL}; -+ -+static struct irqaction ar531x_timer_interrupt = -+ {ar531x_timer_handler, SA_INTERRUPT, 0, "ar531x_timer_interrupt", -+ NULL, NULL}; -+ -+static struct irqaction ar531x_ahb_proc_interrupt = -+ {ar531x_ahb_proc_handler, SA_INTERRUPT, 0, "ar531x_ahb_proc_interrupt", -+ NULL, NULL}; -+ -+extern asmlinkage void ar531x_interrupt_receive(void); -+ -+/* -+ * Called when an interrupt is received, this function -+ * determines exactly which interrupt it was, and it -+ * invokes the appropriate handler. -+ * -+ * Implicitly, we also define interrupt priority by -+ * choosing which to dispatch first. -+ */ -+extern void dump_uart(void *); -+ -+#if CONFIG_AR5315 -+ -+void -+ar531x_irq_dispatch(struct pt_regs *regs) -+{ -+ int cause_intrs = regs->cp0_cause; -+ int status_intrs = regs->cp0_status; -+ int pending = cause_intrs & status_intrs; -+ -+ if (pending & CAUSEF_IP3) { -+ do_IRQ(AR531X_IRQ_WLAN0_INTRS, regs); -+ } -+ else if (pending & CAUSEF_IP4) { -+ do_IRQ(AR531X_IRQ_ENET0_INTRS, regs); -+ } -+ else if (pending & CAUSEF_IP2) { -+ AR531X_REG ar531x_isr = sysRegRead(AR5315_ISR); -+ AR531X_REG ar531x_imr = sysRegRead(AR5315_IMR); -+ unsigned int ar531x_misc_intrs = ar531x_isr & ar531x_imr; -+ -+ if (ar531x_misc_intrs & ISR_TIMER) -+ do_IRQ(AR531X_MISC_IRQ_TIMER, regs); -+ else if (ar531x_misc_intrs & ISR_AHB) -+ do_IRQ(AR531X_MISC_IRQ_AHB_PROC, regs); -+ else if (ar531x_misc_intrs & ISR_GPIO) -+ { -+ int i; -+ u32 gpioIntPending; -+ -+ gpioIntPending = sysRegRead(AR5315_GPIO_DI) & gpioIntMask; -+ for (i=0; i<AR531X_GPIO_IRQ_COUNT; i++) { -+ if (gpioIntPending & (1 << i)) -+ do_IRQ(AR531X_GPIO_IRQ(i), regs); -+ } -+ } -+ else if (ar531x_misc_intrs & ISR_UART0) { -+ do_IRQ(AR531X_MISC_IRQ_UART0, regs); -+#if CONFIG_KGDB -+ if (kgdbInterrupt()) { -+ if (!user_mode(regs)) -+ set_async_breakpoint((unsigned long *)®s->cp0_epc); -+ } -+#endif /* CONFIG_KGDB */ -+ } -+ else if (ar531x_misc_intrs & ISR_WD) -+ do_IRQ(AR531X_MISC_IRQ_WATCHDOG, regs); -+ else -+ do_IRQ(AR531X_MISC_IRQ_NONE, regs); -+ } else if (pending & CAUSEF_IP7) { -+ do_IRQ(AR531X_IRQ_CPU_CLOCK, regs); -+ } -+ else { -+ do_IRQ(AR531X_IRQ_NONE, regs); -+ } -+} -+ -+#else -+ -+void -+ar531x_irq_dispatch(struct pt_regs *regs) -+{ -+ int cause_intrs = regs->cp0_cause; -+ int status_intrs = regs->cp0_status; -+ int pending = cause_intrs & status_intrs; -+ -+ if (pending & CAUSEF_IP2) { -+ do_IRQ(AR531X_IRQ_WLAN0_INTRS, regs); -+ } -+ else if (pending & CAUSEF_IP3) { -+ do_IRQ(AR531X_IRQ_ENET0_INTRS, regs); -+ } -+ else if (pending & CAUSEF_IP4) { -+ do_IRQ(AR531X_IRQ_ENET1_INTRS, regs); -+ } -+ else if (pending & CAUSEF_IP5) { -+ do_IRQ(AR531X_IRQ_WLAN1_INTRS, regs); -+ } -+ else if (pending & CAUSEF_IP6) { -+ AR531X_REG ar531x_isr = sysRegRead(AR531X_ISR); -+ AR531X_REG ar531x_imr = sysRegRead(AR531X_IMR); -+ unsigned int ar531x_misc_intrs = ar531x_isr & ar531x_imr; -+ -+ if (ar531x_misc_intrs & AR531X_ISR_TIMER) -+ do_IRQ(AR531X_MISC_IRQ_TIMER, regs); -+ else if (ar531x_misc_intrs & AR531X_ISR_AHBPROC) -+ do_IRQ(AR531X_MISC_IRQ_AHB_PROC, regs); -+ else if (ar531x_misc_intrs & AR531X_ISR_AHBDMA) -+ do_IRQ(AR531X_MISC_IRQ_AHB_DMA, regs); -+ else if (ar531x_misc_intrs & AR531X_ISR_GPIO) -+ { -+ int i; -+ u32 gpioIntPending; -+ -+ gpioIntPending = sysRegRead(AR531X_GPIO_DI) & gpioIntMask; -+ for (i=0; i<AR531X_GPIO_IRQ_COUNT; i++) { -+ if (gpioIntPending & (1 << i)) -+ do_IRQ(AR531X_GPIO_IRQ(i), regs); -+ } -+ } -+ else if ((ar531x_misc_intrs & AR531X_ISR_UART0) || -+ (ar531x_misc_intrs & AR531X_ISR_UART0DMA)) { -+ do_IRQ(AR531X_MISC_IRQ_UART0, regs); -+#if CONFIG_KGDB -+ if (kgdbInterrupt()) { -+ if (!user_mode(regs)) -+ set_async_breakpoint((unsigned long *)®s->cp0_epc); -+ } -+#endif /* CONFIG_KGDB */ -+ } -+ else if (ar531x_misc_intrs & AR531X_ISR_WD) -+ do_IRQ(AR531X_MISC_IRQ_WATCHDOG, regs); -+ else if (ar531x_misc_intrs & AR531X_ISR_LOCAL) -+ do_IRQ(AR531X_MISC_IRQ_LOCAL, regs); -+ else -+ do_IRQ(AR531X_MISC_IRQ_NONE, regs); -+ } else if (pending & CAUSEF_IP7) { -+ do_IRQ(AR531X_IRQ_CPU_CLOCK, regs); -+ } else -+ do_IRQ(AR531X_IRQ_NONE, regs); -+} -+ -+#endif -+ -+void __init init_IRQ(void) -+{ -+ init_generic_irq(); -+ set_except_vector(0, ar531x_interrupt_receive); -+ -+ /* Initialize interrupt controllers */ -+ mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); -+ ar531x_misc_intr_init(AR531X_MISC_IRQ_BASE); -+ ar531x_gpio_intr_init(AR531X_GPIO_IRQ_BASE); -+ setup_irq(AR531X_IRQ_MISC_INTRS, &cascade); -+ /* -+ * AR531X_IRQ_CPU_CLOCK is setup by ar531x_timer_setup. -+ */ -+ -+ /* Default "spurious interrupt" handlers */ -+ setup_irq(AR531X_IRQ_NONE, &spurious_irq); -+ setup_irq(AR531X_MISC_IRQ_NONE, &spurious_misc); -+ setup_irq(AR531X_GPIO_IRQ_NONE, &spurious_gpio); -+#ifndef CONFIG_AR5315 -+ setup_irq(AR531X_MISC_IRQ_TIMER, &ar531x_timer_interrupt); -+#endif -+ setup_irq(AR531X_MISC_IRQ_AHB_PROC, &ar531x_ahb_proc_interrupt); -+ setup_irq(AR531X_MISC_IRQ_GPIO, &cascade); -+ -+#ifdef CONFIG_KGDB -+#if CONFIG_EARLY_STOP -+ kgdbInit(); -+#endif -+#endif -+} -diff -urN linux-mips/arch/mips/ar531x/ar531xksyms.c mips-linux-2.4.25/arch/mips/ar531x/ar531xksyms.c ---- linux-mips/arch/mips/ar531x/ar531xksyms.c 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/arch/mips/ar531x/ar531xksyms.c 2005-12-30 17:26:31.001823800 +0000 -@@ -0,0 +1,17 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+#include <linux/module.h> -+#include "asm/atheros/ar531xbsp.h" -+ -+#ifdef CONFIG_KGDB -+EXPORT_SYMBOL(kgdbInit); -+EXPORT_SYMBOL(kgdbEnabled); -+#endif -+EXPORT_SYMBOL(ar531x_sys_frequency); -+EXPORT_SYMBOL(get_system_type); -diff -urN linux-mips/arch/mips/ar531x/ar531xlnx.h mips-linux-2.4.25/arch/mips/ar531x/ar531xlnx.h ---- linux-mips/arch/mips/ar531x/ar531xlnx.h 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/arch/mips/ar531x/ar531xlnx.h 2005-12-30 17:26:31.001823800 +0000 -@@ -0,0 +1,135 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * This file contains definitions needed in order to compile -+ * AR531X products for linux. Definitions that are largely -+ * AR531X-specific and independent of operating system belong -+ * in ar531x.h rather than this file. -+ */ -+#include "ar531x.h" -+ -+#define MIPS_CPU_IRQ_BASE 0x00 -+#define AR531X_HIGH_PRIO 0x10 -+#define AR531X_MISC_IRQ_BASE 0x20 -+#define AR531X_GPIO_IRQ_BASE 0x30 -+ -+/* Software's idea of interrupts handled by "CPU Interrupt Controller" */ -+#if CONFIG_AR5315 -+#define AR531X_IRQ_NONE MIPS_CPU_IRQ_BASE+0 -+#define AR531X_IRQ_MISC_INTRS MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */ -+#define AR531X_IRQ_WLAN0_INTRS MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */ -+#define AR531X_IRQ_ENET0_INTRS MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */ -+#define AR531X_IRQ_LCBUS_PCI MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */ -+#define AR531X_IRQ_WLAN0_POLL MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */ -+#define AR531X_IRQ_CPU_CLOCK MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */ -+#else -+#define AR531X_IRQ_NONE MIPS_CPU_IRQ_BASE+0 -+#define AR531X_IRQ_WLAN0_INTRS MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */ -+#define AR531X_IRQ_ENET0_INTRS MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */ -+#define AR531X_IRQ_ENET1_INTRS MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */ -+#define AR531X_IRQ_WLAN1_INTRS MIPS_CPU_IRQ_BASE+5 /* C0_CAUSE: 0x2000 */ -+#define AR531X_IRQ_MISC_INTRS MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */ -+#define AR531X_IRQ_CPU_CLOCK MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */ -+#endif -+/* Miscellaneous interrupts, which share IP6 */ -+#define AR531X_MISC_IRQ_NONE AR531X_MISC_IRQ_BASE+0 -+#define AR531X_MISC_IRQ_TIMER AR531X_MISC_IRQ_BASE+1 -+#define AR531X_MISC_IRQ_AHB_PROC AR531X_MISC_IRQ_BASE+2 -+#define AR531X_MISC_IRQ_AHB_DMA AR531X_MISC_IRQ_BASE+3 -+#define AR531X_MISC_IRQ_GPIO AR531X_MISC_IRQ_BASE+4 -+#define AR531X_MISC_IRQ_UART0 AR531X_MISC_IRQ_BASE+5 -+#define AR531X_MISC_IRQ_UART0_DMA AR531X_MISC_IRQ_BASE+6 -+#define AR531X_MISC_IRQ_WATCHDOG AR531X_MISC_IRQ_BASE+7 -+#define AR531X_MISC_IRQ_LOCAL AR531X_MISC_IRQ_BASE+8 -+#define AR531X_MISC_IRQ_COUNT 9 -+ -+/* GPIO Interrupts [0..7], share AR531X_MISC_IRQ_GPIO */ -+#define AR531X_GPIO_IRQ_NONE AR531X_MISC_IRQ_BASE+0 -+#define AR531X_GPIO_IRQ(n) AR531X_MISC_IRQ_BASE+(n)+1 -+#ifdef CONFIG_AR5315 -+#define AR531X_GPIO_IRQ_COUNT 2 -+#else -+#define AR531X_GPIO_IRQ_COUNT 9 -+#endif -+ -+#define PHYS_TO_K1(physaddr) KSEG1ADDR(physaddr) -+#define PHYS_TO_K0(physaddr) KSEG0ADDR(physaddr) -+#define UNMAPPED_TO_PHYS(vaddr) PHYSADDR(vaddr) -+#define IS_UNMAPPED_VADDR(vaddr) \ -+ ((KSEGX(vaddr) == KSEG0) || (KSEGX(vaddr) == KSEG1)) -+ -+/* IOCTL commands for /proc/ar531x */ -+#define AR531X_CTRL_DO_BREAKPOINT 1 -+#define AR531X_CTRL_DO_MADWIFI 2 -+ -+/* -+ * Definitions for operating system portability. -+ * These are vxWorks-->Linux translations. -+ */ -+#define LOCAL static -+#define BOOL int -+#define TRUE 1 -+#define FALSE 0 -+#define UINT8 u8 -+#define UINT16 u16 -+#define UINT32 u32 -+#define PRINTF printk -+#if /* DEBUG */ 1 -+#define DEBUG_PRINTF printk -+#define INLINE -+#else -+DEBUG_PRINTF while (0) printk -+#define INLINE inline -+#endif -+#define sysUDelay(usecs) udelay(usecs) -+#define sysMsDelay(msecs) mdelay(msecs) -+typedef volatile UINT8 *VIRT_ADDR; -+#define MALLOC(sz) kmalloc(sz, GFP_KERNEL) -+#define MALLOC_NOSLEEP(sz) kmalloc(sz, GFP_ATOMIC) -+#define FREE(ptr) kfree((void *)ptr) -+#define BSP_BUG() do { printk("kernel BSP BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0) -+#define BSP_BUG_ON(condition) do { if (unlikely((condition)!=0)) BSP_BUG(); } while(0) -+#define ASSERT(x) BSP_BUG_ON(!(x)) -+ -+extern struct ar531x_boarddata *ar531x_board_configuration; -+extern char *ar531x_radio_configuration; -+extern char *enet_mac_address_get(int MACUnit); -+ -+extern void kgdbInit(void); -+extern int kgdbEnabled(void); -+extern void breakpoint(void); -+extern int kgdbInterrupt(void); -+extern unsigned int ar531x_cpu_frequency(void); -+extern unsigned int ar531x_sys_frequency(void); -+ -+/* GPIO support */ -+extern struct irqaction spurious_gpio; -+extern unsigned int gpioIntMask; -+extern void ar531x_gpio_intr_init(int irq_base); -+extern void ar531x_gpio_ctrl_output(int gpio); -+extern void ar531x_gpio_ctrl_input(int gpio); -+extern void ar531x_gpio_set(int gpio, int val); -+extern int ar531x_gpio_get(int gpio); -+extern void ar531x_gpio_intr_enable(unsigned int irq); -+extern void ar531x_gpio_intr_disable(unsigned int irq); -+ -+/* Watchdog Timer support */ -+extern int watchdog_start(unsigned int milliseconds); -+extern int watchdog_stop(void); -+extern int watchdog_is_enabled(void); -+extern unsigned int watchdog_min_timer_reached(void); -+extern void watchdog_notify_alive(void); -+ -+#define A_DATA_CACHE_INVAL(start, length) \ -+ dma_cache_inv((UINT32)(start),(length)) -+ -+#define sysWbFlush() mb() -+ -+#define intDisable(x) cli() -+#define intEnable(x) sti() -diff -urN linux-mips/arch/mips/ar531x/ar531xprom.c mips-linux-2.4.25/arch/mips/ar531x/ar531xprom.c ---- linux-mips/arch/mips/ar531x/ar531xprom.c 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/arch/mips/ar531x/ar531xprom.c 2005-12-30 17:26:31.001823800 +0000 -@@ -0,0 +1,88 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright MontaVista Software Inc -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * Prom setup file for ar531x -+ */ -+ -+#include <linux/init.h> -+#include <linux/config.h> -+#include <linux/kernel.h> -+#include <linux/string.h> -+#include <linux/mm.h> -+#include <linux/bootmem.h> -+ -+#include <asm/bootinfo.h> -+#include <asm/addrspace.h> -+ -+#include "ar531xlnx.h" -+ -+#define COMMAND_LINE_SIZE 512 -+ -+char arcs_cmdline[COMMAND_LINE_SIZE]; -+ -+void __init prom_init(int argc, char *argv[]) -+{ -+ int i; -+ unsigned int memcfg1; -+ int bank0AC, bank1AC; -+ int memsz_in_mb; -+ strcpy(arcs_cmdline, "console=ttyS0,9600"); -+ for (i=0; i<argc; i++) { -+ strcat(arcs_cmdline, " "); -+ strcat(arcs_cmdline, argv[i]); -+ } -+ -+ mips_machgroup = MACH_GROUP_AR531X; -+#ifdef CONFIG_APUNUSED -+ mips_machtype = MACH_ATHEROS_UNUSED; -+#endif -+#ifdef CONFIG_AP30 -+ mips_machtype = MACH_ATHEROS_AP30; -+#endif -+#ifdef CONFIG_AP33 -+ mips_machtype = MACH_ATHEROS_AP33; -+#endif -+#ifdef CONFIG_AP38 -+ mips_machtype = MACH_ATHEROS_AP38; -+#endif -+#ifdef CONFIG_AP43 -+ mips_machtype = MACH_ATHEROS_AP43; -+#endif -+#ifdef CONFIG_AP48 -+ mips_machtype = MACH_ATHEROS_AP48; -+#endif -+#ifdef CONFIG_PB32 -+ mips_machtype = MACH_ATHEROS_PB32; -+#endif -+ -+ -+ /* Determine SDRAM size based on Address Checks done at startup */ -+#if CONFIG_AR5315 -+ /* TO-DO : compute the SDRAM size */ -+ memsz_in_mb=8; -+#else -+ memcfg1 = sysRegRead(AR531X_MEM_CFG1); -+ bank0AC = (memcfg1 & MEM_CFG1_AC0) >> MEM_CFG1_AC0_S; -+ bank1AC = (memcfg1 & MEM_CFG1_AC1) >> MEM_CFG1_AC1_S; -+ memsz_in_mb = (bank0AC ? (1 << (bank0AC+1)) : 0) -+ + (bank1AC ? (1 << (bank1AC+1)) : 0); -+#endif -+ -+ /* -+ * By default, use all available memory. You can override this -+ * to use, say, 8MB by specifying "mem=8M" as an argument on the -+ * linux bootup command line. -+ */ -+ add_memory_region(0, memsz_in_mb << 20, BOOT_MEM_RAM); -+} -+ -+void __init prom_free_prom_memory(void) -+{ -+} -diff -urN linux-mips/arch/mips/ar531x/ar531xsetup.c mips-linux-2.4.25/arch/mips/ar531x/ar531xsetup.c ---- linux-mips/arch/mips/ar531x/ar531xsetup.c 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/arch/mips/ar531x/ar531xsetup.c 2005-12-30 17:26:31.002823648 +0000 -@@ -0,0 +1,406 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * Initialization for ar531x SOC. -+ */ -+ -+#include <linux/config.h> -+#include <linux/init.h> -+#include <linux/delay.h> -+#include <linux/irq.h> -+#include <linux/interrupt.h> -+#include <linux/serial.h> -+#include <linux/types.h> -+#include <linux/string.h> -+ -+#include <asm/reboot.h> -+#include <asm/io.h> -+#include <asm/time.h> -+#include <asm/pgtable.h> -+#include <asm/processor.h> -+#include <asm/reboot.h> -+#include <asm/system.h> -+#include <asm/serial.h> -+ -+#include "ar531xlnx.h" -+ -+void -+ar531x_restart(char *command) -+{ -+ for(;;) { -+#if CONFIG_AR5315 -+ /* -+ ** Cold reset does not work,work around is to use the GPIO reset bit. -+ */ -+ unsigned int reg; -+ reg = sysRegRead(AR5315_GPIO_DO); -+ reg &= ~(1 << AR5315_RESET_GPIO); -+ sysRegWrite(AR5315_GPIO_DO, reg); -+ (void)sysRegRead(AR5315_GPIO_DO); /* flush write to hardware */ -+ -+#else -+ sysRegWrite(AR531X_RESET, AR531X_RESET_SYSTEM); -+#endif -+ } -+} -+ -+void -+ar531x_halt(void) -+{ -+ printk(KERN_NOTICE "\n** You can safely turn off the power\n"); -+ while (1); -+} -+ -+void -+ar531x_power_off(void) -+{ -+ ar531x_halt(); -+} -+ -+const char * -+get_system_type(void) -+{ -+#if CONFIG_AR5315 -+ return "Atheros AR5315"; -+#else -+ return "Atheros AR531X"; -+#endif -+} -+ -+/* -+ * This table is indexed by bits 5..4 of the CLOCKCTL1 register -+ * to determine the predevisor value. -+ */ -+static int CLOCKCTL1_PREDIVIDE_TABLE[4] = { -+ 1, -+ 2, -+ 4, -+ 5 -+}; -+ -+#if CONFIG_AR5315 -+static int PLLC_DIVIDE_TABLE[5] = { -+ 2, -+ 3, -+ 4, -+ 6, -+ 3 -+}; -+ -+unsigned int -+ar531x_cpu_frequency(void) -+{ -+ static unsigned int ar531x_calculated_cpu_freq=0; -+ unsigned int clockCtl,pllcCtrl,cpuDiv; -+ unsigned int pllcOut,refdiv,fdiv,divby2; -+ -+ if(ar531x_calculated_cpu_freq) -+ return ar531x_calculated_cpu_freq; -+ -+ -+ pllcCtrl = sysRegRead(AR5315_PLLC_CTL); -+ refdiv = (pllcCtrl & PLLC_REF_DIV_M) >> PLLC_REF_DIV_S; -+ refdiv = CLOCKCTL1_PREDIVIDE_TABLE[refdiv]; -+ fdiv = (pllcCtrl & PLLC_FDBACK_DIV_M) >> PLLC_FDBACK_DIV_S; -+ divby2 = (pllcCtrl & PLLC_ADD_FDBACK_DIV_M) >> PLLC_ADD_FDBACK_DIV_S; -+ divby2 += 1; -+ pllcOut = (40000000/refdiv)*(2*divby2)*fdiv; -+ -+ clockCtl = sysRegRead(AR5315_CPUCLK); -+ -+ /* clkm input selected */ -+ if((clockCtl & CPUCLK_CLK_SEL_M) == 0 || (clockCtl & CPUCLK_CLK_SEL_M) == 1 ) { -+ unsigned int clkMdiv; -+ clkMdiv = (pllcCtrl & PLLC_CLKM_DIV_M) >> PLLC_CLKM_DIV_S; -+ clkMdiv = PLLC_DIVIDE_TABLE[clkMdiv]; -+ -+ cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S; -+ if(cpuDiv) cpuDiv *= 2; -+ else cpuDiv=1; -+ -+ ar531x_calculated_cpu_freq= (pllcOut/(clkMdiv * cpuDiv)) ; -+ -+ return ar531x_calculated_cpu_freq; -+ } -+ -+ /* clkc input selected */ -+ if((clockCtl & CPUCLK_CLK_SEL_M) == 2 ) { -+ unsigned int clkCdiv; -+ clkCdiv = (pllcCtrl & PLLC_CLKC_DIV_M) >> PLLC_CLKC_DIV_S; -+ clkCdiv = PLLC_DIVIDE_TABLE[clkCdiv]; -+ -+ cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S; -+ if(cpuDiv) cpuDiv *= 2; -+ else cpuDiv=1; -+ -+ ar531x_calculated_cpu_freq= (pllcOut/(clkCdiv * cpuDiv)) ; -+ -+ return ar531x_calculated_cpu_freq; -+ } else { /* ref_clk selected */ -+ -+ cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S; -+ if(cpuDiv) cpuDiv *= 2; -+ else cpuDiv=1; -+ -+ ar531x_calculated_cpu_freq= (40000000/(cpuDiv)) ; -+ return ar531x_calculated_cpu_freq; -+ } -+} -+ -+unsigned int -+ar531x_apb_frequency(void) -+{ -+ static unsigned int ar531x_calculated_cpu_freq=0; -+ unsigned int clockCtl,pllcCtrl,cpuDiv; -+ unsigned int pllcOut,refdiv,fdiv,divby2; -+ -+ if(ar531x_calculated_cpu_freq) -+ return ar531x_calculated_cpu_freq; -+ -+ -+ pllcCtrl = sysRegRead(AR5315_PLLC_CTL); -+ refdiv = (pllcCtrl & PLLC_REF_DIV_M) >> PLLC_REF_DIV_S; -+ refdiv = CLOCKCTL1_PREDIVIDE_TABLE[refdiv]; -+ fdiv = (pllcCtrl & PLLC_FDBACK_DIV_M) >> PLLC_FDBACK_DIV_S; -+ divby2 = (pllcCtrl & PLLC_ADD_FDBACK_DIV_M) >> PLLC_ADD_FDBACK_DIV_S; -+ divby2 += 1; -+ pllcOut = (40000000/refdiv)*(2*divby2)*fdiv; -+ -+ clockCtl = sysRegRead(AR5315_AMBACLK); -+ -+ /* clkm input selected */ -+ if((clockCtl & CPUCLK_CLK_SEL_M) == 0 || (clockCtl & CPUCLK_CLK_SEL_M) == 1 ) { -+ unsigned int clkMdiv; -+ clkMdiv = (pllcCtrl & PLLC_CLKM_DIV_M) >> PLLC_CLKM_DIV_S; -+ clkMdiv = PLLC_DIVIDE_TABLE[clkMdiv]; -+ -+ cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S; -+ if(cpuDiv) cpuDiv *= 2; -+ else cpuDiv=1; -+ -+ ar531x_calculated_cpu_freq= (pllcOut/(clkMdiv * cpuDiv)) ; -+ -+ return ar531x_calculated_cpu_freq; -+ } -+ -+ /* clkc input selected */ -+ if((clockCtl & CPUCLK_CLK_SEL_M) == 2 ) { -+ unsigned int clkCdiv; -+ clkCdiv = (pllcCtrl & PLLC_CLKC_DIV_M) >> PLLC_CLKC_DIV_S; -+ clkCdiv = PLLC_DIVIDE_TABLE[clkCdiv]; -+ -+ cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S; -+ if(cpuDiv) cpuDiv *= 2; -+ else cpuDiv=1; -+ -+ ar531x_calculated_cpu_freq= (pllcOut/(clkCdiv * cpuDiv)) ; -+ -+ return ar531x_calculated_cpu_freq; -+ } else { /* ref_clk selected */ -+ -+ cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S; -+ if(cpuDiv) cpuDiv *= 2; -+ else cpuDiv=1; -+ -+ ar531x_calculated_cpu_freq= (40000000/(cpuDiv)) ; -+ return ar531x_calculated_cpu_freq; -+ } -+} -+ -+#else -+unsigned int -+ar531x_cpu_frequency(void) -+{ -+ static unsigned int ar531x_calculated_cpu_freq; -+ unsigned int clockctl1_predivide_mask; -+ unsigned int clockctl1_predivide_shift; -+ unsigned int clockctl1_multiplier_mask; -+ unsigned int clockctl1_multiplier_shift; -+ unsigned int clockctl1_doubler_mask; -+ int wisoc_revision; -+ -+ /* -+ * Trust the bootrom's idea of cpu frequency. -+ */ -+ ar531x_calculated_cpu_freq = sysRegRead(AR5312_SCRATCH); -+ if (ar531x_calculated_cpu_freq) -+ return ar531x_calculated_cpu_freq; -+ -+ wisoc_revision = (sysRegRead(AR531X_REV) & AR531X_REV_MAJ) >> AR531X_REV_MAJ_S; -+ -+ if (wisoc_revision == AR531X_REV_MAJ_AR2313) { -+ clockctl1_predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK; -+ clockctl1_predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT; -+ clockctl1_multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK; -+ clockctl1_multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT; -+ clockctl1_doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK; -+ } else { /* AR5312 and AR2312 */ -+ clockctl1_predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK; -+ clockctl1_predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT; -+ clockctl1_multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK; -+ clockctl1_multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT; -+ clockctl1_doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK; -+ } -+ -+ /* -+ * Clocking is derived from a fixed 40MHz input clock. -+ * cpuFreq = InputClock * MULT (where MULT is PLL multiplier) -+ * -+ * sysFreq = cpuFreq / 4 (used for APB clock, serial, -+ * flash, Timer, Watchdog Timer) -+ * -+ * cntFreq = cpuFreq / 2 (use for CPU count/compare) -+ * -+ * So, for example, with a PLL multiplier of 5, we have -+ * cpuFrez = 200MHz -+ * sysFreq = 50MHz -+ * cntFreq = 100MHz -+ * -+ * We compute the CPU frequency, based on PLL settings. -+ */ -+ if (ar531x_calculated_cpu_freq == 0) { -+ unsigned int clockCtl1 = sysRegRead(AR5312_CLOCKCTL1); -+ -+ int preDivideSelect = (clockCtl1 & clockctl1_predivide_mask) >> -+ clockctl1_predivide_shift; -+ -+ int preDivisor = CLOCKCTL1_PREDIVIDE_TABLE[preDivideSelect]; -+ -+ int multiplier = (clockCtl1 & clockctl1_multiplier_mask) >> -+ clockctl1_multiplier_shift; -+ -+ if (clockCtl1 & clockctl1_doubler_mask) { -+ multiplier = multiplier << 1; -+ } -+ -+ ar531x_calculated_cpu_freq = (40000000 / preDivisor) * multiplier; -+ } -+ -+ return ar531x_calculated_cpu_freq; -+} -+#endif -+ -+unsigned int -+ar531x_sys_frequency(void) -+{ -+ static unsigned int ar531x_calculated_sys_freq = 0; -+ -+ if (ar531x_calculated_sys_freq == 0) { -+ ar531x_calculated_sys_freq = ar531x_cpu_frequency() / 4; -+ } -+ -+ return ar531x_calculated_sys_freq; -+} -+ -+static void __init -+flash_setup(void) -+{ -+ UINT32 flash_ctl; -+#ifndef CONFIG_AR5315 -+ /* Configure flash bank 0 */ -+ flash_ctl = FLASHCTL_E | -+ FLASHCTL_AC_8M | -+ FLASHCTL_RBLE | -+ (0x01 << FLASHCTL_IDCY_S) | -+ (0x07 << FLASHCTL_WST1_S) | -+ (0x07 << FLASHCTL_WST2_S) | -+ (sysRegRead(AR531X_FLASHCTL0) & FLASHCTL_MW); -+ -+ sysRegWrite(AR531X_FLASHCTL0, flash_ctl); -+ -+ /* Disable other flash banks */ -+ sysRegWrite(AR531X_FLASHCTL1, -+ sysRegRead(AR531X_FLASHCTL1) & ~(FLASHCTL_E | FLASHCTL_AC)); -+ -+ sysRegWrite(AR531X_FLASHCTL2, -+ sysRegRead(AR531X_FLASHCTL2) & ~(FLASHCTL_E | FLASHCTL_AC)); -+#endif -+} -+ -+ -+ -+void __init -+serial_setup(void) -+{ -+ struct serial_struct s; -+ -+ memset(&s, 0, sizeof(s)); -+ -+ s.flags = STD_COM_FLAGS; -+ s.io_type = SERIAL_IO_MEM; -+#if CONFIG_AR5315 -+ s.baud_base = ar531x_apb_frequency()/16; -+#else -+ s.baud_base = ar531x_sys_frequency()/16; -+#endif -+ s.irq = AR531X_MISC_IRQ_UART0; -+ s.iomem_reg_shift = 2; -+#if CONFIG_AR5315 -+ s.iomem_base = (u8 *)AR5315_UART0; -+#else -+ s.iomem_base = (u8 *)AR531X_UART0; -+#endif -+ -+ if (early_serial_setup(&s) != 0) -+ printk(KERN_ERR "early_serial_setup failed\n"); -+} -+ -+extern int setup_irq(unsigned int irq, struct irqaction *irqaction); -+static void __init -+ar531x_timer_setup(struct irqaction *irq) -+{ -+ unsigned int count; -+ -+ /* Usually irq is timer_irqaction (timer_interrupt) */ -+ setup_irq(AR531X_IRQ_CPU_CLOCK, irq); -+ -+ /* to generate the first CPU timer interrupt */ -+ count = read_c0_count(); -+ write_c0_compare(count + 1000); -+} -+ -+extern void (*board_time_init)(void); -+ -+static void __init -+ar531x_time_init(void) -+{ -+ mips_hpt_frequency = ar531x_cpu_frequency() / 2; -+} -+ -+void __init -+ar531x_setup(void) -+{ -+ /* Clear any lingering AHB errors */ -+#if CONFIG_AR5315 -+ unsigned int config = read_c0_config(); -+ write_c0_config(config & ~0x3); -+ sysRegWrite(AR5315_AHB_ERR0,AHB_ERROR_DET); -+ sysRegRead(AR5315_AHB_ERR1); -+ sysRegWrite(AR5315_WDC, WDC_IGNORE_EXPIRATION); -+#else -+ sysRegRead(AR531X_PROCADDR); -+ sysRegRead(AR531X_DMAADDR); -+ -+ sysRegWrite(AR531X_WD_CTRL, AR531X_WD_CTRL_IGNORE_EXPIRATION); -+ -+#endif -+ -+ /* Disable data watchpoints */ -+ write_c0_watchlo0(0); -+ -+ board_time_init = ar531x_time_init; -+ board_timer_setup = ar531x_timer_setup; -+ -+ _machine_restart = ar531x_restart; -+ _machine_halt = ar531x_halt; -+ _machine_power_off = ar531x_power_off; -+ -+ flash_setup(); -+ serial_setup(); -+} -diff -urN linux-mips/arch/mips/ar531x/Makefile mips-linux-2.4.25/arch/mips/ar531x/Makefile ---- linux-mips/arch/mips/ar531x/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/arch/mips/ar531x/Makefile 2005-12-30 17:26:29.912989328 +0000 -@@ -0,0 +1,33 @@ -+# -+# This file is subject to the terms and conditions of the GNU General Public -+# License. See the file "COPYING" in the main directory of this archive -+# for more details. -+# -+# Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+# -+ -+# Makefile for Atheros ar531x boards -+# -+# Note! Dependencies are done automagically by 'make dep', which also -+# removes any old dependencies. DON'T put your own dependencies here -+# unless it's something special (ie not a .c file). -+# -+ -+.S.s: -+ $(CPP) $(CFLAGS) $< -o $*.s -+.S.o: -+ $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $*.o -+ -+O_TARGET:= ar531x.o -+ -+export-objs = ar531xksyms.o -+ -+obj-y := ar531xdbg_io.o \ -+ ar531xsetup.o \ -+ ar531xprom.o \ -+ ar531xirq.o \ -+ ar531xintr.o \ -+ ar531xgpio.o \ -+ ar531xksyms.o -+ -+include $(TOPDIR)/Rules.make -diff -urN linux-mips/arch/mips/ar531x/README mips-linux-2.4.25/arch/mips/ar531x/README ---- linux-mips/arch/mips/ar531x/README 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/arch/mips/ar531x/README 2005-12-30 17:26:30.478903296 +0000 -@@ -0,0 +1,68 @@ -+Basic information for the AR531X Board Support Package -+ -+This directory contains the "LBSP" -- Linux Board Support Package -- -+for Linux on the Atheros AR531X Wireless System-On-a-Chip. It is intended -+primarily as a building block for wireless products. At this time, the -+AR531X Linux BSP is experimental code, and is actively UNDER CONSTRUCTION. -+ -+Some components that are supported by this LBSP along with a standard 2.4 -+Linux MIPS kernel include -+ R4Kc CPU -+ instruction and data caches -+ SDRAM -+ flash (Macronix, AMD, STS, etc.) -+ 16550 serial port -+ ethernet MACs -+ ethernet PHY or PHY Switch (RealTek, Kendin, Marvell) -+ General-Purpose I/O pins -+ kernel debugging with kgdb -+ -+This LBSP code does NOT include drivers for the wireless components of the -+chip/boards! Drivers for those components may be distributed separately. -+In particular, the MADWiFi project under SourceForge supports (not yet!) -+wireless functions on the AR531X chipset. See -+ http://www.sourceforge.net/projects/madwifi -+ -+Files included in this BSP: -+ae531xlnx.c - Linux-specific portions of the ethernet driver -+ae531xmac.c - OS-independent AR531X ethernet MAC code -+ae531xmac.h - OS-independent AR531X ethernet MAC software definitions -+ae531xreg.h - OS-independent AR531X ethernet MAC hardware definitions -+ar531x.h - OS-independent AR531X system hardware definitions -+ar531xlnx.h - Linux-specific AR531X system definitions and externs -+defconfig-ar531x - Default Linux configuration file -+intr_recv.S - Linux interrupt "glue" code -+ar531xirq.c - Linux Interrupt Request management -+Makefile - Linux makefile -+mvPhy.c - OS-independent ethernet PHY code for Marvell Switch -+mvPhy.h - OS-independent ethernet PHY definitions for Marvell Switch -+ar531xprom.c - Linux prom "glue" code -+ar531xsetup.c - Linux startup code -+ar531xdbg_io.c - Support for kgdb-based debugging and for EARLY_PRINTK_HACK -+ar531xproc.c - Pseudo-device driver for /proc/ar531x device -+ar531xgpio.c - Support for General Purpose I/O pins -+ar531xwmacsl.c - Wireless MAC Support Layer -+ -+Additional files, distributed with the BSP: -+README - This file -+README.BUILD - Instructions for building a linux kernel from source -+README.EXECUTE - Instructions for testing your linux kernel -+README.RAMDISK - Instructions for building a root ramdisk image -+ -+ramdisk.gz - A binary ramdisk image, suitable for use with AR531X. -+DIFFS - Directory that contains "patch" files (See README.BUILD) -+ -+ -+There are several ways to boot a vmlinux image on an AR531X board: -+ -You can boot in over ethernet from the vxWorks bootrom, which is preloaded -+ on all Atheros boards -+ -You can use an ICE (e.g. VisionICE) to load the vmlinux image. You will -+ need appropriate register initialization (e.g. AP30.ini file) -+ -You can use the eCos RedBoot bootrom loader. This is a full-featured -+ bootrom which as been ported to AR531x. It can boot vmlinux over ethernet -+ or from flash. Source code is available from Atheros. -+ -+Please send comments, corrections, complaints, criticisms, suggestions, -+enhancements, requests, or any other reasonable communications regarding -+this effort, to "linux@atheros.com". Your email will be received by a -+couple of engineers, and redirected as appropriate. -diff -urN linux-mips/arch/mips/ar531x/README.BUILD mips-linux-2.4.25/arch/mips/ar531x/README.BUILD ---- linux-mips/arch/mips/ar531x/README.BUILD 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/arch/mips/ar531x/README.BUILD 2005-12-30 17:26:30.478903296 +0000 -@@ -0,0 +1,47 @@ -+ How to BUILD a linux kernel for an AR531X system -+ -+It is expected that you will build Linux on an existing Linux system, which -+has all of the standard Linux tools. -+ -+01) Obtain a MIPS BigEndian ELF gcc-compatible toolchain. For example, -+ if you're cross-compiling on a x86 Linux system, you could use: -+ ftp://ftp.mips.com/pub/tools/software/sde-for-linux/sdelinux-5.01-4eb.i386.rpm -+ -+02) Obtain the latest working MIPS Linux kernel -+ cvs -d :pserver:cvs@ftp.linux-mips.org:/home/cvs login (password "cvs") -+ cvs -d :pserver:cvs@ftp.linux-mips.org:/home/cvs co -r linux_2_4 linux -+ -+ Now "cd linux". The remainder of these instructions assume -+ that you are in the linux directory. -+ -+03) Place the contents of this directory at arch/mips/ar531x. -+ -+04) Use the patch command to patch generic linux files according -+ to the DIFFS directory -+ for i in arch/mips/ar531x/DIFFS/*.diff -+ do -+ patch -p1 < $i -+ done -+ NOTE: This version of the AR531X Linux BSP was tested with -+ MIPS Linux 2.4.22 as of 11/14/03. If you use a different -+ (e.g. more recent) version of Linux source, you may need to -+ resolve some minor patch and compilation issues. -+ -+05) Set up a RAMDISK image. -+ See the instructions in README.RAMDISK. -+ -+06) Set up a linux configuration using ar531x/defconfig-ar531x. -+ cp arch/mips/ar531x/defconfig-ar531x .config -+ make oldconfig (answer all questions that are asked) -+ NOTE: For development/debug purposes, you may want to -+ enable CONFIG_RUNTIME_DEBUG and CONFIG_KGDB. -+ -+07) Make dependencies. -+ make dep -+ -+08) Build the linux kernel -+ make -+ -+09) The linux image you just built is in vmlinux. -+ See instructions in README.EXECUTE to run your vmlinux -+ image on an AP531X-based board. -diff -urN linux-mips/arch/mips/ar531x/README.EXECUTE mips-linux-2.4.25/arch/mips/ar531x/README.EXECUTE ---- linux-mips/arch/mips/ar531x/README.EXECUTE 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/arch/mips/ar531x/README.EXECUTE 2005-12-30 17:26:30.479903144 +0000 -@@ -0,0 +1,23 @@ -+ How to EXECUTE a linux image on an AR531X system -+ -+There are currently three ways to run you vmlinux image: -+ 1) Load it using the vxWorks bootrom that is supplied with the board. -+ You can load it over ethernet or from the TFFS file system, if you -+ have sufficient flash to store the image. -+ 2) Load it using an ICE (e.g. VisionICE). -+ 3) Use a bootrom loader, such as eCos RedBoot. -+ -+After you have booted linux: -+ By default, the root filesystem on ramdisk is read-only. -+ To make it writable, use "mount -o remount w /". -+ -+ The user-level commands are slightly non-standard, as they -+ are based on "busybox". -+ -+ The "wget" command is included. You can use wget to fetch -+ files from any ftp server. So, for instance, you can fetch -+ a kernel module and then "insmod" it. -+ -+Note that the standard source-level kernel debugger, kgdb, works well -+over the serial line with this port. We use kgdb and the kgdb_demux perl -+script -- available over the www -- for debugging. -diff -urN linux-mips/arch/mips/ar531x/README.VERSION mips-linux-2.4.25/arch/mips/ar531x/README.VERSION ---- linux-mips/arch/mips/ar531x/README.VERSION 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/arch/mips/ar531x/README.VERSION 2005-12-30 17:26:30.479903144 +0000 -@@ -0,0 +1 @@ -+Source release last modified: 12/16/03 -diff -urN linux-mips/arch/mips/config-shared.in mips-linux-2.4.25/arch/mips/config-shared.in ---- linux-mips/arch/mips/config-shared.in 2005-12-24 15:11:15.963885864 +0000 -+++ mips-linux-2.4.25/arch/mips/config-shared.in 2005-12-30 17:26:31.611731080 +0000 -@@ -34,6 +34,7 @@ - dep_bool 'Support for Alchemy PB1550 board' CONFIG_MIPS_PB1550 $CONFIG_MIPS32 - dep_bool 'Support for Alchemy PB1200 board' CONFIG_MIPS_PB1200 $CONFIG_MIPS32 - dep_bool 'Support for Alchemy Hydrogen3 board' CONFIG_MIPS_HYDROGEN3 $CONFIG_MIPS32 -+dep_bool 'Support for Atheros AR5312/AR2312 WiSoC (EXPERIMENTAL)' CONFIG_AR531X $CONFIG_AR531X $CONFIG_EXPERIMENTAL - dep_bool 'Support for MyCable XXS1500 board' CONFIG_MIPS_XXS1500 $CONFIG_MIPS32 - dep_bool 'Support for 4G Systems MTX-1 board' CONFIG_MIPS_MTX1 $CONFIG_MIPS32 - dep_bool 'Support for Cogent CSB250 board' CONFIG_COGENT_CSB250 $CONFIG_MIPS32 -@@ -238,6 +239,63 @@ - define_bool CONFIG_PC_KEYB y - define_bool CONFIG_OLD_TIME_C y - fi -+if [ "$CONFIG_AR531X" = "y" ]; then -+ define_bool CONFIG_IRQ_CPU y -+ define_bool CONFIG_CPU_R4X00 y -+ define_bool CONFIG_SERIAL y -+ define_bool CONFIG_NEW_IRQ y -+ define_bool CONFIG_NEW_TIME_C y -+ define_bool CONFIG_AR5312 -+ define_bool CONFIG_NONCOHERENT_IO y -+ bool 'Enable early printk hack' CONFIG_EARLY_PRINTK_HACK -+ define_bool CONFIG_SCSI n -+ mainmenu_option next_comment -+ comment 'Board selection' -+ choice 'Board type' \ -+ "UNKNOWN CONFIG_APUNKNOWN \ -+ AP30 CONFIG_AP30 \ -+ AP31 CONFIG_AP31 \ -+ AP33 CONFIG_AP33 \ -+ AP38 CONFIG_AP38 \ -+ AP43 CONFIG_AP43 \ -+ AP48 CONFIG_AP48 \ -+ AP51 CONFIG_AP51 \ -+ AP30-ASK CONFIG_AP30ASK" AP30 -+ if [ "$CONFIG_AP30" = "y" -o "$CONFIG_AP30ASK" = "y" ]; then -+ define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 2 -+ fi -+ if [ "$CONFIG_AP33" = "y" ]; then -+ define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1 -+ fi -+ if [ "$CONFIG_AP38" = "y" ]; then -+ define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1 -+ fi -+ if [ "$CONFIG_AP43" = "y" ]; then -+ define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1 -+ fi -+ if [ "$CONFIG_AP48" = "y" ]; then -+ define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1 -+ fi -+ if [ "$CONFIG_AP51" = "y" ]; then -+ define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1 -+ define_bool CONFIG_MTD_REDBOOT_PARTS y -+ define_bool CONFIG_AR5315 y -+ define_bool CONFIG_MTD_SPIFLASH y -+ define_bool CONFIG_MTD_CFI n -+ define_bool CONFIG_MTD_JEDECPROBE n -+ define_bool CONFIG_MTD_CFI_INTELEXT n -+ define_bool CONFIG_MTD_CFI_AMDSTD n -+ define_bool CONFIG_MTD_OBSOLETE_CHIPS n -+ define_bool CONFIG_MTD_AMDSTD n -+ define_bool CONFIG_MTD_JEDEC n -+ define_bool CONFIG_MTD_PHYSMAP n -+ fi -+ mainmenu_option next_comment -+ comment 'Flash Selection' -+ choice 'Flash Size' \ -+ "2MB CONFIG_FLASH_2MB \ -+ 4MB CONFIG_FLASH_4MB" 2MB -+fi - if [ "$CONFIG_CASIO_E55" = "y" ]; then - define_bool CONFIG_IRQ_CPU y - define_bool CONFIG_NEW_TIME_C y - -diff -urN linux-mips/arch/mips/kernel/setup.c mips-linux-2.4.25/arch/mips/kernel/setup.c ---- linux-mips/arch/mips/kernel/setup.c 2005-12-24 15:11:16.188851664 +0000 -+++ mips-linux-2.4.25/arch/mips/kernel/setup.c 2005-12-30 17:26:33.536438480 +0000 -@@ -496,6 +496,7 @@ - void hp_setup(void); - void au1x00_setup(void); - void frame_info_init(void); -+ void ar531x_setup(void); - - frame_info_init(); - #if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) -@@ -693,6 +694,12 @@ - pmc_yosemite_setup(); - break; - #endif -+ -+#ifdef CONFIG_AR531X -+ case MACH_GROUP_AR531X: -+ ar531x_setup(); -+ break; -+#endif - default: - panic("Unsupported architecture"); - } -diff -urN linux-mips/arch/mips/Makefile mips-linux-2.4.25/arch/mips/Makefile ---- linux-mips/arch/mips/Makefile 2005-12-24 15:11:15.903894984 +0000 -+++ mips-linux-2.4.25/arch/mips/Makefile 2005-12-30 17:26:29.911989480 +0000 -@@ -701,6 +701,17 @@ - LOADADDR += 0x80020000 - endif - -+ifdef CONFIG_AR531X -+SUBDIRS += arch/mips/ar531x -+LIBS += arch/mips/ar531x/ar531x.o -+ifdef CONFIG_AP51 -+LOADADDR += 0x80041000 -+else -+LOADADDR += 0x80002000 -+endif -+ -+endif -+ - # - # Choosing incompatible machines durings configuration will result in - # error messages during linking. Select a default linkscript if -diff -urN linux-mips/ath_version.mk mips-linux-2.4.25/ath_version.mk ---- linux-mips/ath_version.mk 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/ath_version.mk 2005-12-30 17:27:00.579327336 +0000 -@@ -0,0 +1 @@ -+EXTRAVERSION=-LSDK-5.0.0-RC5 -diff -urN linux-mips/drivers/char/serial.c mips-linux-2.4.25/drivers/char/serial.c ---- linux-mips/drivers/char/serial.c 2005-12-24 15:11:21.796999096 +0000 -+++ mips-linux-2.4.25/drivers/char/serial.c 2005-12-30 17:27:10.815771160 +0000 -@@ -3441,7 +3441,7 @@ - - static _INLINE_ void show_serial_version(void) - { -- printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name, -+ printk(KERN_INFO "%s version %s%s (%s) with%s\n", serial_name, - serial_version, LOCAL_VERSTRING, serial_revdate, - serial_options); - } -@@ -5567,7 +5567,7 @@ - printk(KERN_INFO"ttyS%02d%s at 0x%p (irq = %d) is a %s\n", - state->line + SERIAL_DEV_OFFSET, - (state->flags & ASYNC_FOURPORT) ? " FourPort" : "", -- state->iomem_base, state->irq, -+ (void *)state->iomem_base, state->irq, - uart_config[state->type].name); - } - else { -diff -urN linux-mips/drivers/mtd/chips/cfi_cmdset_0002.c mips-linux-2.4.25/drivers/mtd/chips/cfi_cmdset_0002.c ---- linux-mips/drivers/mtd/chips/cfi_cmdset_0002.c 2005-12-24 15:11:25.102496584 +0000 -+++ mips-linux-2.4.25/drivers/mtd/chips/cfi_cmdset_0002.c 2005-12-30 17:27:21.333172272 +0000 -@@ -511,7 +511,7 @@ - or tells us why it failed. */ - dq6 = CMD(1<<6); - dq5 = CMD(1<<5); -- timeo = jiffies + (HZ/1000); /* setting timeout to 1ms for now */ -+ timeo = jiffies + (HZ/1000) + 1; /* setting timeout to 1ms for now */ - - oldstatus = cfi_read(map, adr); - status = cfi_read(map, adr); -@@ -536,16 +536,18 @@ - if( (status & dq5) == dq5 ) { - /* When DQ5 raises, we must check once again - if DQ6 is toggling. If not, the erase has been -- completed OK. If not, reset chip. */ -+ completed OK. But if so, reset chip. */ - oldstatus = cfi_read(map, adr); - status = cfi_read(map, adr); - - if ( (oldstatus & 0x00FF) == (status & 0x00FF) ) { -+#if 0 - printk(KERN_WARNING "Warning: DQ5 raised while program operation was in progress, however operation completed OK\n" ); -+#endif - } else { - /* DQ5 is active so we can do a reset and stop the erase */ - cfi_write(map, CMD(0xF0), chip->start); -- printk(KERN_WARNING "Internal flash device timeout occurred or write operation was performed while flash was programming.\n" ); -+ printk(KERN_WARNING "Internal flash device timeout pt A occurred or write operation was performed while flash was programming. timeout=%d\n",chip->word_write_time ); - } - } else { - printk(KERN_WARNING "Waiting for write to complete timed out in do_write_oneword."); -@@ -959,7 +961,7 @@ - { - /* DQ5 is active so we can do a reset and stop the erase */ - cfi_write(map, CMD(0xF0), chip->start); -- printk( KERN_WARNING "Internal flash device timeout occured or write operation was performed while flash was erasing\n" ); -+ printk( KERN_WARNING "Internal flash device timeout pt B occured or write operation was performed while flash was erasing\n" ); - } - } - else -diff -urN linux-mips/drivers/mtd/chips/cfi_probe.c mips-linux-2.4.25/drivers/mtd/chips/cfi_probe.c ---- linux-mips/drivers/mtd/chips/cfi_probe.c 2005-12-24 15:11:25.103496432 +0000 -+++ mips-linux-2.4.25/drivers/mtd/chips/cfi_probe.c 2005-12-30 17:27:21.507145824 +0000 -@@ -51,7 +51,7 @@ - struct flchip *chips, struct cfi_private *cfi) - { - int i; -- -+ - if ((base + 0) >= map->size) { - printk(KERN_NOTICE - "Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n", -@@ -221,12 +221,10 @@ - - static void print_cfi_ident(struct cfi_ident *cfip) - { --#if 0 - if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') { - printk("Invalid CFI ident structure.\n"); - return; - } --#endif - printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID)); - if (cfip->P_ADR) - printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR); -diff -urN linux-mips/drivers/mtd/chips/jedec_probe.c mips-linux-2.4.25/drivers/mtd/chips/jedec_probe.c ---- linux-mips/drivers/mtd/chips/jedec_probe.c 2005-12-24 15:11:25.126492936 +0000 -+++ mips-linux-2.4.25/drivers/mtd/chips/jedec_probe.c 2005-12-30 17:27:21.532142024 +0000 -@@ -104,6 +104,7 @@ - #define SST29LE512 0x003d - #define SST39LF800 0x2781 - #define SST39LF160 0x2782 -+#define SST39LF1601 0x234b - #define SST39LF512 0x00D4 - #define SST39LF010 0x00D5 - #define SST39LF020 0x00D6 -@@ -113,6 +114,8 @@ - #define SST49LF030A 0x001C - #define SST49LF040A 0x0051 - #define SST49LF080A 0x005B -+#define SST39VF3201 0x235B -+#define SST39VF3202 0x235A - - /* Toshiba */ - #define TC58FVT160 0x00C2 -@@ -900,7 +903,43 @@ - NumEraseRegions: 1, - regions: {ERASEINFO(0x01000,256), - } -- } -+ }, { -+ mfr_id: MANUFACTURER_SST, -+ dev_id: SST39LF160, -+ name: "SST 39LF160", -+ DevSize: SIZE_2MiB, -+ CmdSet: P_ID_AMD_STD, -+ NumEraseRegions: 1, -+ regions: {ERASEINFO(0x01000,512), -+ } -+ }, { -+ mfr_id: MANUFACTURER_SST, -+ dev_id: SST39LF1601, -+ name: "SST 39LF1601", -+ DevSize: SIZE_2MiB, -+ CmdSet: P_ID_AMD_STD, -+ NumEraseRegions: 1, -+ regions: {ERASEINFO(0x01000,512), -+ } -+ }, { -+ mfr_id: MANUFACTURER_SST, -+ dev_id: SST39VF3201, -+ name: "SST 39VF3201", -+ DevSize: SIZE_4MiB, -+ CmdSet: P_ID_AMD_STD, -+ NumEraseRegions: 1, -+ regions: {ERASEINFO(0x01000,1024), -+ } -+ }, { -+ mfr_id: MANUFACTURER_SST, -+ dev_id: SST39VF3202, -+ name: "SST 39VF3202", -+ DevSize: SIZE_4MiB, -+ CmdSet: P_ID_AMD_STD, -+ NumEraseRegions: 1, -+ regions: {ERASEINFO(0x01000,1024), -+ } -+ } - }; - - -@@ -967,6 +1006,35 @@ - p_cfi->cfiq->DevSize = jedec_table[index].DevSize; - p_cfi->cfi_mode = CFI_MODE_JEDEC; - -+ /* -+ * Add the following code to set the flash timing parameters. -+ * Maybe this is done in a table somwehere else? I can't find it. -+ */ -+ -+ -+ switch(jedec_table[index].dev_id) { -+ case SST39VF3201: -+ case SST39VF3202: -+ p_cfi->cfiq->WordWriteTimeoutTyp = 3; /* 8 us */ -+ p_cfi->cfiq->WordWriteTimeoutMax = 4; /* 16 us */ -+ p_cfi->cfiq->BlockEraseTimeoutTyp = 15; /* Actually 18ms, max 25 */ -+ p_cfi->cfiq->BlockEraseTimeoutMax = 15; /* Actually 25ms */ -+ p_cfi->cfiq->ChipEraseTimeoutTyp = 16; /* Max is 50ms, typical is 40ms */ -+ p_cfi->cfiq->ChipEraseTimeoutMax = 16; -+ break; -+ case SST39LF160: -+ case SST39LF1601: -+ p_cfi->cfiq->WordWriteTimeoutTyp = 4; /* 14 us */ -+ p_cfi->cfiq->WordWriteTimeoutMax = 5; /* 20 us */ -+ p_cfi->cfiq->BlockEraseTimeoutTyp = 15; /* Actually 18ms, max 25 */ -+ p_cfi->cfiq->BlockEraseTimeoutMax = 15; /* Actually 25ms */ -+ p_cfi->cfiq->ChipEraseTimeoutTyp = 17; /* Max is 70ms, typical is 40ms */ -+ p_cfi->cfiq->ChipEraseTimeoutMax = 17; -+ break; -+ } -+ -+ -+ - for (i=0; i<num_erase_regions; i++){ - p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i]; - } -diff -urN linux-mips/drivers/mtd/Config.in mips-linux-2.4.25/drivers/mtd/Config.in ---- linux-mips/drivers/mtd/Config.in 2005-12-24 15:11:25.091498256 +0000 -+++ mips-linux-2.4.25/drivers/mtd/Config.in 2005-12-30 17:27:21.182195224 +0000 -@@ -14,6 +14,9 @@ - dep_tristate ' MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD - dep_tristate ' MTD concatenating support' CONFIG_MTD_CONCAT $CONFIG_MTD - dep_tristate ' RedBoot partition table parsing' CONFIG_MTD_REDBOOT_PARTS $CONFIG_MTD_PARTITIONS -+ if [ "$CONFIG_MTD_END_RESERVED" != "" ]; then -+ define_int CONFIG_MTD_END_RESERVED $CONFIG_MTD_END_RESERVED -+ fi - dep_tristate ' Command line partition table parsing' CONFIG_MTD_CMDLINE_PARTS $CONFIG_MTD_PARTITIONS - if [ "$CONFIG_ARM" = "y" ]; then - dep_tristate ' ARM Firmware Suite partition parsing' CONFIG_MTD_AFS_PARTS $CONFIG_MTD_PARTITIONS -diff -urN linux-mips/drivers/mtd/devices/Makefile mips-linux-2.4.25/drivers/mtd/devices/Makefile ---- linux-mips/drivers/mtd/devices/Makefile 2005-12-24 15:11:25.128492632 +0000 -+++ mips-linux-2.4.25/drivers/mtd/devices/Makefile 2005-12-30 17:27:21.561137616 +0000 -@@ -22,5 +22,6 @@ - obj-$(CONFIG_MTD_MTDRAM) += mtdram.o - obj-$(CONFIG_MTD_LART) += lart.o - obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o -+obj-$(CONFIG_MTD_SPIFLASH) += spiflash.o - - include $(TOPDIR)/Rules.make -diff -urN linux-mips/drivers/mtd/devices/spiflash.c mips-linux-2.4.25/drivers/mtd/devices/spiflash.c ---- linux-mips/drivers/mtd/devices/spiflash.c 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/drivers/mtd/devices/spiflash.c 2005-12-30 17:27:21.652123784 +0000 -@@ -0,0 +1,506 @@ -+ -+/* -+ * MTD driver for the SPI Flash Memory support. -+ * -+ * $Id: //depot/sw/releases/linuxsrc/src/kernels/mips-linux-2.4.25/drivers/mtd/devices/spiflash.c#3 $ -+ * -+ * -+ * Copyright (c) 2005-2006 Atheros Communications Inc. -+ * -+ * This code 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. -+ * -+ */ -+ -+/*=========================================================================== -+** !!!! VERY IMPORTANT NOTICE !!!! FLASH DATA STORED IN LITTLE ENDIAN FORMAT -+** -+** This module contains the Serial Flash access routines for the Atheros SOC. -+** The Atheros SOC integrates a SPI flash controller that is used to access -+** serial flash parts. The SPI flash controller executes in "Little Endian" -+** mode. THEREFORE, all WRITES and READS from the MIPS CPU must be -+** BYTESWAPPED! The SPI Flash controller hardware by default performs READ -+** ONLY byteswapping when accessed via the SPI Flash Alias memory region -+** (Physical Address 0x0800_0000 - 0x0fff_ffff). The data stored in the -+** flash sectors is stored in "Little Endian" format. -+** -+** The spiflash_write() routine performs byteswapping on all write -+** operations. -+**===========================================================================*/ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/types.h> -+#include <linux/version.h> -+#include <linux/errno.h> -+#include <linux/slab.h> -+#include <linux/mtd/mtd.h> -+#include <linux/mtd/partitions.h> -+#include <asm/delay.h> -+#include <asm/io.h> -+#include "spiflash.h" -+ -+/* debugging */ -+/* #define SPIFLASH_DEBUG */ -+ -+#ifndef __BIG_ENDIAN -+#error This driver currently only works with big endian CPU. -+#endif -+ -+static char module_name[] = "spiflash"; -+ -+#define MIN(a,b) ((a) < (b) ? (a) : (b)) -+#define FALSE 0 -+#define TRUE 1 -+ -+#define ROOTFS_NAME "rootfs" -+ -+static __u32 spiflash_regread32(int reg); -+static void spiflash_regwrite32(int reg, __u32 data); -+static __u32 spiflash_sendcmd (int op); -+ -+int __init spiflash_init (void); -+void __exit spiflash_exit (void); -+static int spiflash_probe (void); -+static int spiflash_erase (struct mtd_info *mtd,struct erase_info *instr); -+static int spiflash_read (struct mtd_info *mtd, loff_t from,size_t len,size_t *retlen,u_char *buf); -+static int spiflash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf); -+ -+/* Flash configuration table */ -+struct flashconfig { -+ __u32 byte_cnt; -+ __u32 sector_cnt; -+ __u32 sector_size; -+ __u32 cs_addrmask; -+} flashconfig_tbl[MAX_FLASH] = -+ { -+ { 0, 0, 0, 0}, -+ { STM_1MB_BYTE_COUNT, STM_1MB_SECTOR_COUNT, STM_1MB_SECTOR_SIZE, 0x0}, -+ { STM_2MB_BYTE_COUNT, STM_2MB_SECTOR_COUNT, STM_2MB_SECTOR_SIZE, 0x0}, -+ { STM_4MB_BYTE_COUNT, STM_4MB_SECTOR_COUNT, STM_4MB_SECTOR_SIZE, 0x0} -+ }; -+ -+/* Mapping of generic opcodes to STM serial flash opcodes */ -+struct opcodes { -+ __u16 code; -+ __s8 tx_cnt; -+ __s8 rx_cnt; -+} stm_opcodes[] = { -+ {STM_OP_WR_ENABLE, 1, 0}, -+ {STM_OP_WR_DISABLE, 1, 0}, -+ {STM_OP_RD_STATUS, 1, 1}, -+ {STM_OP_WR_STATUS, 1, 0}, -+ {STM_OP_RD_DATA, 4, 4}, -+ {STM_OP_FAST_RD_DATA, 1, 0}, -+ {STM_OP_PAGE_PGRM, 8, 0}, -+ {STM_OP_SECTOR_ERASE, 4, 0}, -+ {STM_OP_BULK_ERASE, 1, 0}, -+ {STM_OP_DEEP_PWRDOWN, 1, 0}, -+ {STM_OP_RD_SIG, 4, 1} -+}; -+ -+/* Driver private data structure */ -+struct spiflash_data { -+ struct mtd_info *mtd; -+ struct mtd_partition *parsed_parts; /* parsed partitions */ -+ void *spiflash_readaddr; /* memory mapped data for read */ -+ void *spiflash_mmraddr; /* memory mapped register space */ -+}; -+ -+static struct spiflash_data *spidata; -+ -+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts); -+ -+/***************************************************************************************************/ -+ -+static __u32 -+spiflash_regread32(int reg) -+{ -+ volatile __u32 *data = (__u32 *)(spidata->spiflash_mmraddr + reg); -+ -+ return (*data); -+} -+ -+static void -+spiflash_regwrite32(int reg, __u32 data) -+{ -+ volatile __u32 *addr = (__u32 *)(spidata->spiflash_mmraddr + reg); -+ -+ *addr = data; -+ return; -+} -+ -+static __u32 -+spiflash_sendcmd (int op) -+{ -+ __u32 reg; -+ __u32 mask; -+ struct opcodes *ptr_opcode; -+ -+ ptr_opcode = &stm_opcodes[op]; -+ -+ do { -+ reg = spiflash_regread32(SPI_FLASH_CTL); -+ } while (reg & SPI_CTL_BUSY); -+ -+ spiflash_regwrite32(SPI_FLASH_OPCODE, ptr_opcode->code); -+ -+ reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt | -+ (ptr_opcode->rx_cnt << 4) | SPI_CTL_START; -+ -+ spiflash_regwrite32(SPI_FLASH_CTL, reg); -+ -+ if (ptr_opcode->rx_cnt > 0) { -+ do { -+ reg = spiflash_regread32(SPI_FLASH_CTL); -+ } while (reg & SPI_CTL_BUSY); -+ -+ reg = (__u32) spiflash_regread32(SPI_FLASH_DATA); -+ -+ switch (ptr_opcode->rx_cnt) { -+ case 1: -+ mask = 0x000000ff; -+ break; -+ case 2: -+ mask = 0x0000ffff; -+ break; -+ case 3: -+ mask = 0x00ffffff; -+ break; -+ default: -+ mask = 0xffffffff; -+ break; -+ } -+ -+ reg &= mask; -+ } -+ else { -+ reg = 0; -+ } -+ -+ return reg; -+} -+ -+/* Probe SPI flash device -+ * Function returns 0 for failure. -+ * and flashconfig_tbl array index for success. -+ */ -+static int -+spiflash_probe (void) -+{ -+ __u32 sig; -+ int flash_size; -+ -+ /* Read the signature on the flash device */ -+ sig = spiflash_sendcmd(SPI_RD_SIG); -+ -+ switch (sig) { -+ case STM_8MBIT_SIGNATURE: -+ flash_size = FLASH_1MB; -+ break; -+ case STM_16MBIT_SIGNATURE: -+ flash_size = FLASH_2MB; -+ break; -+ case STM_32MBIT_SIGNATURE: -+ flash_size = FLASH_4MB; -+ break; -+ default: -+ printk (KERN_WARNING "%s: Read of flash device signature failed!\n", module_name); -+ return (0); -+ } -+ -+ return (flash_size); -+} -+ -+ -+static int -+spiflash_erase (struct mtd_info *mtd,struct erase_info *instr) -+{ -+ struct opcodes *ptr_opcode; -+ __u32 temp, reg; -+ int finished = FALSE; -+ -+#ifdef SPIFLASH_DEBUG -+ printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n",__FUNCTION__,instr->addr,instr->len); -+#endif -+ -+ /* sanity checks */ -+ if (instr->addr + instr->len > mtd->size) return (-EINVAL); -+ -+ ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE]; -+ -+ temp = ((__u32)instr->addr << 8) | (__u32)(ptr_opcode->code); -+ spiflash_sendcmd(SPI_WRITE_ENABLE); -+ do { -+ reg = spiflash_regread32(SPI_FLASH_CTL); -+ } while (reg & SPI_CTL_BUSY); -+ -+ spiflash_regwrite32(SPI_FLASH_OPCODE, temp); -+ -+ reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt | SPI_CTL_START; -+ spiflash_regwrite32(SPI_FLASH_CTL, reg); -+ -+ do { -+ reg = spiflash_sendcmd(SPI_RD_STATUS); -+ if (!(reg & SPI_STATUS_WIP)) { -+ finished = TRUE; -+ } -+ } while (!finished); -+ -+ instr->state = MTD_ERASE_DONE; -+ if (instr->callback) instr->callback (instr); -+ -+#ifdef SPIFLASH_DEBUG -+ printk (KERN_DEBUG "%s return\n",__FUNCTION__); -+#endif -+ return (0); -+} -+ -+static int -+spiflash_read (struct mtd_info *mtd, loff_t from,size_t len,size_t *retlen,u_char *buf) -+{ -+ u_char *read_addr; -+ -+#ifdef SPIFLASH_DEBUG -+ printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) from,(int)len); -+#endif -+ -+ /* sanity checks */ -+ if (!len) return (0); -+ if (from + len > mtd->size) return (-EINVAL); -+ -+ -+ /* we always read len bytes */ -+ *retlen = len; -+ -+ read_addr = (u_char *)(spidata->spiflash_readaddr + from); -+ memcpy(buf, read_addr, len); -+ -+ return (0); -+} -+ -+static int -+spiflash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf) -+{ -+ int done = FALSE, page_offset, bytes_left, finished; -+ __u32 xact_len, spi_data = 0, opcode, reg; -+ -+#ifdef SPIFLASH_DEBUG -+ printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) to,len); -+#endif -+ -+ *retlen = 0; -+ -+ /* sanity checks */ -+ if (!len) return (0); -+ if (to + len > mtd->size) return (-EINVAL); -+ -+ opcode = stm_opcodes[SPI_PAGE_PROGRAM].code; -+ bytes_left = len; -+ -+ while (done == FALSE) { -+ xact_len = MIN(bytes_left, sizeof(__u32)); -+ -+ /* 32-bit writes cannot span across a page boundary -+ * (256 bytes). This types of writes require two page -+ * program operations to handle it correctly. The STM part -+ * will write the overflow data to the beginning of the -+ * current page as opposed to the subsequent page. -+ */ -+ page_offset = (to & (STM_PAGE_SIZE - 1)) + xact_len; -+ -+ if (page_offset > STM_PAGE_SIZE) { -+ xact_len -= (page_offset - STM_PAGE_SIZE); -+ } -+ -+ spiflash_sendcmd(SPI_WRITE_ENABLE); -+ -+ do { -+ reg = spiflash_regread32(SPI_FLASH_CTL); -+ } while (reg & SPI_CTL_BUSY); -+ -+ switch (xact_len) { -+ case 1: -+ (__u8)spi_data = *buf; -+ break; -+ case 2: -+ spi_data = (buf[1] << 8) | buf[0]; -+ break; -+ case 3: -+ spi_data = (buf[2] << 16) | (buf[1] << 8) | buf[0]; -+ break; -+ case 4: -+ spi_data = (buf[3] << 24) | (buf[2] << 16) | -+ (buf[1] << 8) | buf[0]; -+ break; -+ default: -+ printk("spiflash_write: default case\n"); -+ break; -+ } -+ -+ spiflash_regwrite32(SPI_FLASH_DATA, spi_data); -+ opcode = (opcode & SPI_OPCODE_MASK) | ((__u32)to << 8); -+ spiflash_regwrite32(SPI_FLASH_OPCODE, opcode); -+ -+ reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | (xact_len + 4) | SPI_CTL_START; -+ spiflash_regwrite32(SPI_FLASH_CTL, reg); -+ finished = FALSE; -+ -+ do { -+ udelay(1); -+ reg = spiflash_sendcmd(SPI_RD_STATUS); -+ if (!(reg & SPI_STATUS_WIP)) { -+ finished = TRUE; -+ } -+ } while (!finished); -+ -+ bytes_left -= xact_len; -+ to += xact_len; -+ buf += xact_len; -+ -+ *retlen += xact_len; -+ -+ if (bytes_left == 0) { -+ done = TRUE; -+ } -+ } -+ -+ return (0); -+} -+ -+ -+int __init -+spiflash_init (void) -+{ -+ int result, i; -+ int index, num_parts; -+ struct mtd_info *mtd; -+ struct mtd_partition *mtd_parts; -+ -+ spidata = kmalloc(sizeof(struct spiflash_data), GFP_KERNEL); -+ if (!spidata) -+ return (-ENXIO); -+ -+ spidata->spiflash_mmraddr = ioremap_nocache(SPI_FLASH_MMR, SPI_FLASH_MMR_SIZE); -+ if (!spidata->spiflash_mmraddr) { -+ printk (KERN_WARNING "%s: Failed to map flash device\n", module_name); -+ kfree(spidata); -+ return (-ENXIO); -+ } -+ -+ mtd = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); -+ if (!mtd) { -+ kfree(spidata); -+ return (-ENXIO); -+ } -+ -+ memset (mtd,0,sizeof (*mtd)); -+ -+ printk ("MTD driver for SPI flash.\n"); -+ printk ("%s: Probing for Serial flash ...\n", module_name); -+ if (!(index = spiflash_probe ())) { -+ printk (KERN_WARNING "%s: Found no serial flash device\n", module_name); -+ kfree(mtd); -+ kfree(spidata); -+ return (-ENXIO); -+ } -+ printk ("%s: Found SPI serial Flash.\n", module_name); -+ printk ("%d: size\n", flashconfig_tbl[index].byte_cnt); -+ -+ spidata->spiflash_readaddr = ioremap_nocache(SPI_FLASH_READ, flashconfig_tbl[index].byte_cnt); -+ if (!spidata->spiflash_readaddr) { -+ printk (KERN_WARNING "%s: Failed to map flash device\n", module_name); -+ kfree(mtd); -+ kfree(spidata); -+ return (-ENXIO); -+ } -+ -+ mtd->name = module_name; -+ mtd->type = MTD_NORFLASH; -+ mtd->flags = (MTD_CAP_NORFLASH|MTD_WRITEABLE); -+ mtd->size = flashconfig_tbl[index].byte_cnt; -+ mtd->erasesize = flashconfig_tbl[index].sector_size; -+ mtd->numeraseregions = 0; -+ mtd->eraseregions = NULL; -+ mtd->module = THIS_MODULE; -+ mtd->erase = spiflash_erase; -+ mtd->read = spiflash_read; -+ mtd->write = spiflash_write; -+ -+#ifdef SPIFLASH_DEBUG -+ printk (KERN_DEBUG -+ "mtd->name = %s\n" -+ "mtd->size = 0x%.8x (%uM)\n" -+ "mtd->erasesize = 0x%.8x (%uK)\n" -+ "mtd->numeraseregions = %d\n", -+ mtd->name, -+ mtd->size, mtd->size / (1024*1024), -+ mtd->erasesize, mtd->erasesize / 1024, -+ mtd->numeraseregions); -+ -+ if (mtd->numeraseregions) { -+ for (result = 0; result < mtd->numeraseregions; result++) { -+ printk (KERN_DEBUG -+ "\n\n" -+ "mtd->eraseregions[%d].offset = 0x%.8x\n" -+ "mtd->eraseregions[%d].erasesize = 0x%.8x (%uK)\n" -+ "mtd->eraseregions[%d].numblocks = %d\n", -+ result,mtd->eraseregions[result].offset, -+ result,mtd->eraseregions[result].erasesize,mtd->eraseregions[result].erasesize / 1024, -+ result,mtd->eraseregions[result].numblocks); -+ } -+ } -+#endif -+ -+#ifndef CONFIG_BLK_DEV_INITRD -+ /* parse redboot partitions */ -+ num_parts = parse_redboot_partitions(mtd, &spidata->parsed_parts); -+ -+#ifdef SPIFLASH_DEBUG -+ printk (KERN_DEBUG "Found %d redboot partitions\n", num_parts); -+#endif -+ -+ if (num_parts) { -+ result = add_mtd_partitions(mtd, spidata->parsed_parts, num_parts); -+ /* Find root partition */ -+ mtd_parts = spidata->parsed_parts; -+ for (i=0; i < num_parts; i++) { -+ if (!strcmp(mtd_parts[i].name, ROOTFS_NAME)) { -+ /* Create root device */ -+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, i); -+ break; -+ } -+ } -+ } else { -+#ifdef SPIFLASH_DEBUG -+ printk (KERN_DEBUG "Did not find any redboot partitions\n"); -+#endif -+ kfree(mtd); -+ kfree(spidata); -+ return (-ENXIO); -+ } -+#endif -+ -+ spidata->mtd = mtd; -+ -+ return (result); -+} -+ -+void __exit -+spiflash_exit (void) -+{ -+ if (spidata && spidata->parsed_parts) { -+ del_mtd_partitions (spidata->mtd); -+ kfree(spidata->mtd); -+ kfree(spidata); -+ } -+} -+ -+module_init (spiflash_init); -+module_exit (spiflash_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Atheros Communications Inc"); -+MODULE_DESCRIPTION("MTD driver for SPI Flash on Atheros SOC"); -+ -diff -urN linux-mips/drivers/mtd/devices/spiflash.h mips-linux-2.4.25/drivers/mtd/devices/spiflash.h ---- linux-mips/drivers/mtd/devices/spiflash.h 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/drivers/mtd/devices/spiflash.h 2005-12-30 17:27:21.652123784 +0000 -@@ -0,0 +1,113 @@ -+/* -+ * SPI Flash Memory support header file. -+ * -+ * $Id: //depot/sw/releases/linuxsrc/src/kernels/mips-linux-2.4.25/drivers/mtd/devices/spiflash.h#3 $ -+ * -+ * -+ * Copyright (c) 2005, Atheros Communications Inc. -+ * -+ * This code 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. -+ * -+ */ -+#define FLASH_1MB 1 -+#define FLASH_2MB 2 -+#define FLASH_4MB 3 -+#define MAX_FLASH 4 -+ -+#define STM_PAGE_SIZE 256 -+ -+#define STM_8MBIT_SIGNATURE 0x13 -+#define STM_M25P80_BYTE_COUNT 1048576 -+#define STM_M25P80_SECTOR_COUNT 16 -+#define STM_M25P80_SECTOR_SIZE 0x10000 -+ -+#define STM_16MBIT_SIGNATURE 0x14 -+#define STM_M25P16_BYTE_COUNT 2097152 -+#define STM_M25P16_SECTOR_COUNT 32 -+#define STM_M25P16_SECTOR_SIZE 0x10000 -+ -+#define STM_32MBIT_SIGNATURE 0x15 -+#define STM_M25P32_BYTE_COUNT 4194304 -+#define STM_M25P32_SECTOR_COUNT 64 -+#define STM_M25P32_SECTOR_SIZE 0x10000 -+ -+#define STM_1MB_BYTE_COUNT STM_M25P80_BYTE_COUNT -+#define STM_1MB_SECTOR_COUNT STM_M25P80_SECTOR_COUNT -+#define STM_1MB_SECTOR_SIZE STM_M25P80_SECTOR_SIZE -+#define STM_2MB_BYTE_COUNT STM_M25P16_BYTE_COUNT -+#define STM_2MB_SECTOR_COUNT STM_M25P16_SECTOR_COUNT -+#define STM_2MB_SECTOR_SIZE STM_M25P16_SECTOR_SIZE -+#define STM_4MB_BYTE_COUNT STM_M25P32_BYTE_COUNT -+#define STM_4MB_SECTOR_COUNT STM_M25P32_SECTOR_COUNT -+#define STM_4MB_SECTOR_SIZE STM_M25P32_SECTOR_SIZE -+ -+#define SPI_WRITE_ENABLE 0 -+#define SPI_WRITE_DISABLE 1 -+#define SPI_RD_STATUS 2 -+#define SPI_WR_STATUS 3 -+#define SPI_RD_DATA 4 -+#define SPI_FAST_RD_DATA 5 -+#define SPI_PAGE_PROGRAM 6 -+#define SPI_SECTOR_ERASE 7 -+#define SPI_BULK_ERASE 8 -+#define SPI_DEEP_PWRDOWN 9 -+#define SPI_RD_SIG 10 -+#define SPI_MAX_OPCODES 11 -+ -+#define SFI_WRITE_BUFFER_SIZE 4 -+#define SFI_FLASH_ADDR_MASK 0x00ffffff -+ -+/* -+ * ST Microelectronics Opcodes for Serial Flash -+ */ -+ -+#define STM_OP_WR_ENABLE 0x06 /* Write Enable */ -+#define STM_OP_WR_DISABLE 0x04 /* Write Disable */ -+#define STM_OP_RD_STATUS 0x05 /* Read Status */ -+#define STM_OP_WR_STATUS 0x01 /* Write Status */ -+#define STM_OP_RD_DATA 0x03 /* Read Data */ -+#define STM_OP_FAST_RD_DATA 0x0b /* Fast Read Data */ -+#define STM_OP_PAGE_PGRM 0x02 /* Page Program */ -+#define STM_OP_SECTOR_ERASE 0xd8 /* Sector Erase */ -+#define STM_OP_BULK_ERASE 0xc7 /* Bulk Erase */ -+#define STM_OP_DEEP_PWRDOWN 0xb9 /* Deep Power-Down Mode */ -+#define STM_OP_RD_SIG 0xab /* Read Electronic Signature */ -+ -+#define STM_STATUS_WIP 0x01 /* Write-In-Progress */ -+#define STM_STATUS_WEL 0x02 /* Write Enable Latch */ -+#define STM_STATUS_BP0 0x04 /* Block Protect 0 */ -+#define STM_STATUS_BP1 0x08 /* Block Protect 1 */ -+#define STM_STATUS_BP2 0x10 /* Block Protect 2 */ -+#define STM_STATUS_SRWD 0x80 /* Status Register Write Disable */ -+ -+/* -+ * SPI Flash Interface Registers -+ */ -+#define AR531XPLUS_SPI_READ 0x1fc00000 -+#define AR531XPLUS_SPI_MMR 0x11300000 -+#define AR531XPLUS_SPI_MMR_SIZE 12 -+ -+#define AR531XPLUS_SPI_CTL 0x00 -+#define AR531XPLUS_SPI_OPCODE 0x04 -+#define AR531XPLUS_SPI_DATA 0x08 -+ -+#define SPI_FLASH_READ AR531XPLUS_SPI_READ -+#define SPI_FLASH_MMR AR531XPLUS_SPI_MMR -+#define SPI_FLASH_MMR_SIZE AR531XPLUS_SPI_MMR_SIZE -+#define SPI_FLASH_CTL AR531XPLUS_SPI_CTL -+#define SPI_FLASH_OPCODE AR531XPLUS_SPI_OPCODE -+#define SPI_FLASH_DATA AR531XPLUS_SPI_DATA -+ -+#define SPI_CTL_START 0x00000100 -+#define SPI_CTL_BUSY 0x00010000 -+#define SPI_CTL_TXCNT_MASK 0x0000000f -+#define SPI_CTL_RXCNT_MASK 0x000000f0 -+#define SPI_CTL_TX_RX_CNT_MASK 0x000000ff -+#define SPI_CTL_SIZE_MASK 0x00060000 -+ -+#define SPI_CTL_CLK_SEL_MASK 0x03000000 -+#define SPI_OPCODE_MASK 0x000000ff -+ -+#define SPI_STATUS_WIP STM_STATUS_WIP -diff -urN linux-mips/drivers/mtd/maps/Config.in mips-linux-2.4.25/drivers/mtd/maps/Config.in ---- linux-mips/drivers/mtd/maps/Config.in 2005-12-24 15:11:25.158488072 +0000 -+++ mips-linux-2.4.25/drivers/mtd/maps/Config.in 2005-12-30 17:27:21.660122568 +0000 -@@ -9,7 +9,14 @@ - dep_tristate ' CFI Flash device in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_GEN_PROBE - if [ "$CONFIG_MTD_PHYSMAP" = "y" -o "$CONFIG_MTD_PHYSMAP" = "m" ]; then - hex ' Physical start address of flash mapping' CONFIG_MTD_PHYSMAP_START 0x8000000 -- hex ' Physical length of flash mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000 -+ if [ "$CONFIG_FLASH_2MB" = "y" ]; then -+ define_hex CONFIG_MTD_PHYSMAP_LEN 200000 -+ fi -+ if [ "$CONFIG_FLASH_4MB" = "y" ]; then -+ define_hex CONFIG_MTD_PHYSMAP_LEN 400000 -+ fi -+ -+# hex ' Physical length of flash mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000 - int ' Bus width in octets' CONFIG_MTD_PHYSMAP_BUSWIDTH 2 - fi - -diff -urN linux-mips/drivers/mtd/maps/physmap.c mips-linux-2.4.25/drivers/mtd/maps/physmap.c ---- linux-mips/drivers/mtd/maps/physmap.c 2005-12-24 15:11:25.217479104 +0000 -+++ mips-linux-2.4.25/drivers/mtd/maps/physmap.c 2005-12-30 17:27:22.044064200 +0000 -@@ -80,12 +80,25 @@ - }; - - #ifdef CONFIG_MTD_PARTITIONS --#ifdef CONFIG_MTD_CMDLINE_PARTS -+#if defined(CONFIG_MTD_CMDLINE_PARTS) || defined(CONFIG_MTD_REDBOOT_PARTS) - static struct mtd_partition *mtd_parts = 0; - static int mtd_parts_nb = 0; - #else - static struct mtd_partition physmap_partitions[] = { - /* Put your own partition definitions here */ -+ { -+ name: "rootfs", -+#ifdef CONFIG_FLASH_2MB -+ size: 0x000e0000, -+ offset: 0x000f0000, -+#endif -+#ifdef CONFIG_FLASH_4MB -+ size: 0x002dd000, -+ offset: 0x00100000, -+#endif -+ -+ /* Allow file system to be mounted for writing */ -+ } - #if 0 - { - name: "bootROM", -@@ -138,6 +151,22 @@ - - add_mtd_device(mymtd); - #ifdef CONFIG_MTD_PARTITIONS -+#ifdef CONFIG_MTD_REDBOOT_PARTS -+ { -+ extern int parse_redboot_partitions(struct mtd_info *master, -+ struct mtd_partition **pparts); -+ -+ struct mtd_partition *rb_parts = 0; -+ int rb_parts_nb = 0; -+ -+ rb_parts_nb = parse_redboot_partitions(mymtd, &rb_parts); -+ if (rb_parts_nb > 0) { -+ printk(KERN_NOTICE -+ "Using redboot flash partitioning"); -+ add_mtd_partitions (mymtd, rb_parts, rb_parts_nb); -+ } -+ } -+#endif - #ifdef CONFIG_MTD_CMDLINE_PARTS - mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, - "phys"); -@@ -147,7 +176,8 @@ - "Using command line partition definition\n"); - add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb); - } --#else -+#endif -+#if !defined(CONFIG_MTD_CMDLINE_PARTS) && !defined(CONFIG_MTD_REDBOOT_PARTS) - if (NUM_PARTITIONS != 0) - { - printk(KERN_NOTICE -diff -urN linux-mips/drivers/mtd/redboot.c mips-linux-2.4.25/drivers/mtd/redboot.c ---- linux-mips/drivers/mtd/redboot.c 2005-12-24 15:11:25.249474240 +0000 -+++ mips-linux-2.4.25/drivers/mtd/redboot.c 2005-12-30 17:27:22.517992152 +0000 -@@ -51,8 +51,14 @@ - return -ENOMEM; - - /* Read the start of the last erase block */ -- ret = master->read(master, master->size - master->erasesize, -+ { -+ u_int32_t part_table_start = master->size - master->erasesize; -+#if defined(CONFIG_MTD_END_RESERVED) -+ part_table_start -= CONFIG_MTD_END_RESERVED; -+#endif -+ ret = master->read(master, part_table_start, - PAGE_SIZE, &retlen, (void *)buf); -+ } - - if (ret) - goto out; -diff -urN linux-mips/drivers/net/Config.in mips-linux-2.4.25/drivers/net/Config.in ---- linux-mips/drivers/net/Config.in 2005-12-24 15:11:25.725401888 +0000 -+++ mips-linux-2.4.25/drivers/net/Config.in 2005-12-30 17:27:22.684966768 +0000 -@@ -24,6 +24,18 @@ - comment 'Ethernet (10 or 100Mbit)' - bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET - if [ "$CONFIG_NET_ETHERNET" = "y" ]; then -+ define_bool CONFIG_VENETDEV n -+ tristate ' BUILT-IN ATHEROS ENET DRIVER' CONFIG_NET_ATHEROS_ETHER -+ if [ "$CONFIG_AP38" = "y" -o "$CONFIG_AP48" = "y" ]; then -+ define_bool CONFIG_KENDIN_ENET_PHY y -+ elif [ "$CONFIG_AP30ASK" = "y" ]; then -+ define_bool CONFIG_KENDIN_KS8995XA_ENET_PHY y -+ bool 'Multiple Ethernet address hack ' CONFIG_ASK_MULT_MAC_HACK -+ elif [ "$CONFIG_AP51" = "y" ]; then -+ define_bool CONFIG_ICPLUS_ENET_PHY y -+ else -+ define_bool CONFIG_MARVELL_ENET_PHY y -+ fi - if [ "$CONFIG_ARM" = "y" ]; then - dep_bool ' ARM EBSA110 AM79C961A support' CONFIG_ARM_AM79C961A $CONFIG_ARCH_EBSA110 - tristate ' Cirrus Logic CS8900A support' CONFIG_ARM_CIRRUS -diff -urN linux-mips/drivers/net/Makefile mips-linux-2.4.25/drivers/net/Makefile ---- linux-mips/drivers/net/Makefile 2005-12-24 15:11:25.726401736 +0000 -+++ mips-linux-2.4.25/drivers/net/Makefile 2005-12-30 17:27:22.709962968 +0000 -@@ -31,6 +31,10 @@ - obj-y += e1000/e1000.o - endif - -+ifeq ($(CONFIG_NET_ATHEROS_ETHER),y) -+ obj-y += ath/ae531x.o -+endif -+ - ifeq ($(CONFIG_BONDING),y) - obj-y += bonding/bonding.o - endif -@@ -53,8 +57,13 @@ - subdir-$(CONFIG_SKFP) += skfp - subdir-$(CONFIG_E100) += e100 - subdir-$(CONFIG_E1000) += e1000 -+subdir-$(CONFIG_NET_ATHEROS_ETHER) += ath - subdir-$(CONFIG_BONDING) += bonding - -+ifeq ($(CONFIG_ATHAP33),y) -+subdir-$(CONFIG_ATHAP33) += athap33 -+endif -+ - # - # link order important here - # -@@ -242,6 +251,10 @@ - obj-$(CONFIG_R8169) += r8169.o - obj-$(CONFIG_AMD8111_ETH) += amd8111e.o mii.o - -+ifeq ($(CONFIG_ATHAP33),y) -+obj-$(CONFIG_ATHAP33) += athap33/ath_ap_mips.o -+endif -+ - # non-drivers/net drivers who want mii lib - obj-$(CONFIG_PCMCIA_SMC91C92) += mii.o - obj-$(CONFIG_USB_USBNET) += mii.o -diff -urN linux-mips/fs/jffs2/nodelist.h mips-linux-2.4.25/fs/jffs2/nodelist.h ---- linux-mips/fs/jffs2/nodelist.h 2005-12-24 15:11:50.407649616 +0000 -+++ mips-linux-2.4.25/fs/jffs2/nodelist.h 2005-12-30 17:27:51.289618200 +0000 -@@ -31,7 +31,7 @@ - * provisions above, a recipient may use your version of this file - * under either the RHEPL or the GPL. - * -- * $Id: nodelist.h,v 1.46.2.5 2003/11/02 13:54:20 dwmw2 Exp $ -+ * $Id: //depot/sw/releases/linuxsrc/src/kernels/mips-linux-2.4.25/fs/jffs2/nodelist.h#3 $ - * - */ - -@@ -222,8 +222,8 @@ - #define ALLOC_DELETION 1 /* Deletion node. Best to allow it */ - #define ALLOC_GC 2 /* Space requested for GC. Give it or die */ - --#define JFFS2_RESERVED_BLOCKS_BASE 3 /* Number of free blocks there must be before we... */ --#define JFFS2_RESERVED_BLOCKS_WRITE (JFFS2_RESERVED_BLOCKS_BASE + 2) /* ... allow a normal filesystem write */ -+#define JFFS2_RESERVED_BLOCKS_BASE 2 /* Number of free blocks there must be before we... */ -+#define JFFS2_RESERVED_BLOCKS_WRITE (JFFS2_RESERVED_BLOCKS_BASE + 1) /* ... allow a normal filesystem write */ - #define JFFS2_RESERVED_BLOCKS_DELETION (JFFS2_RESERVED_BLOCKS_BASE + 1) /* ... allow a normal filesystem deletion */ - #define JFFS2_RESERVED_BLOCKS_GCTRIGGER (JFFS2_RESERVED_BLOCKS_BASE + 3) /* ... wake up the GC thread */ - #define JFFS2_RESERVED_BLOCKS_GCBAD (JFFS2_RESERVED_BLOCKS_BASE + 1) /* ... pick a block from the bad_list to GC */ -diff -urN linux-mips/fs/partitions/Config.in mips-linux-2.4.25/fs/partitions/Config.in ---- linux-mips/fs/partitions/Config.in 2005-12-24 15:11:52.366351848 +0000 -+++ mips-linux-2.4.25/fs/partitions/Config.in 2005-12-30 17:27:52.279467720 +0000 -@@ -39,7 +39,7 @@ - fi - if [ "$CONFIG_AMIGA" != "y" -a "$CONFIG_ATARI" != "y" -a \ - "$CONFIG_MAC" != "y" -a "$CONFIG_SGI_IP22" != "y" -a \ -- "$CONFIG_SGI_IP27" != "y" ]; then -+ "$CONFIG_SGI_IP27" != "y" -a "$CONFIG_AR531X" != "y" ]; then - define_bool CONFIG_MSDOS_PARTITION y - fi - if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_AFFS_FS" = "y" ]; then -diff -urN linux-mips/include/asm-mips/atheros/ar531xbsp.h mips-linux-2.4.25/include/asm-mips/atheros/ar531xbsp.h ---- linux-mips/include/asm-mips/atheros/ar531xbsp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mips-linux-2.4.25/include/asm-mips/atheros/ar531xbsp.h 2005-12-30 17:28:01.523062480 +0000 -@@ -0,0 +1,17 @@ -+#ifndef __ASM_ATHEROS_BSP_SUPPORT_H -+#define __ASM_ATHEROS_BSP_SUPPORT_H -+/* -+ * These are definitions and functions provided by the bsp to support the -+ * AR5312 WiSoC running LSDK. For different BSP implementations, different -+ * BSP functions will be needed. -+ */ -+ -+extern unsigned int ar531x_sys_frequency(void); -+extern const char* get_system_type(void); -+ -+#ifdef CONFIG_KGDB -+extern void kgdbInit(void); -+extern int kgdbEnabled(void); -+#endif -+ -+#endif /* __ASM_ATHEROS_BSP_SUPPORT_H */ -diff -urN linux-mips/include/asm-mips/bootinfo.h mips-linux-2.4.25/include/asm-mips/bootinfo.h ---- linux-mips/include/asm-mips/bootinfo.h 2005-12-24 15:12:00.645093288 +0000 -+++ mips-linux-2.4.25/include/asm-mips/bootinfo.h 2005-12-30 17:28:01.534060808 +0000 -@@ -37,6 +37,7 @@ - #define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */ - #define MACH_GROUP_LASAT 21 - #define MACH_GROUP_TITAN 22 /* PMC-Sierra Titan */ -+#define MACH_GROUP_AR531X 23 /* Atheros AR531X */ - - /* - * Valid machtype values for group unknown (low order halfword of mips_machtype) -@@ -198,6 +199,17 @@ - */ - #define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */ - -+/* -+ * Valid machtype for group MACH_GROUP_AR5312 -+ */ -+#define MACH_ATHEROS_UNUSED 0 -+#define MACH_ATHEROS_AP30 1 /* AP30 */ -+#define MACH_ATHEROS_AP33 2 /* AP33 */ -+#define MACH_ATHEROS_AP38 3 /* AP38 */ -+#define MACH_ATHEROS_AP43 4 /* AP43 */ -+#define MACH_ATHEROS_AP48 5 /* AP48 */ -+#define MACH_ATHEROS_PB32 6 /* PB32 */ -+ - #define CL_SIZE (256) - - const char *get_system_type(void); -diff -urN linux-mips/include/asm-mips/page.h mips-linux-2.4.25/include/asm-mips/page.h ---- linux-mips/include/asm-mips/page.h 2005-12-24 15:12:01.097024584 +0000 -+++ mips-linux-2.4.25/include/asm-mips/page.h 2005-12-30 17:28:01.898005480 +0000 -@@ -13,7 +13,6 @@ - #include <linux/config.h> - #include <asm/break.h> - --#ifdef __KERNEL__ - - /* - * PAGE_SHIFT determines the page size -@@ -30,6 +29,7 @@ - #define PAGE_SIZE (1L << PAGE_SHIFT) - #define PAGE_MASK (~(PAGE_SIZE-1)) - -+#ifdef __KERNEL__ - #ifndef __ASSEMBLY__ - - #include <asm/cacheflush.h> -diff -urN linux-mips/include/asm-mips/serial.h mips-linux-2.4.25/include/asm-mips/serial.h ---- linux-mips/include/asm-mips/serial.h 2005-12-24 15:12:01.130019568 +0000 -+++ mips-linux-2.4.25/include/asm-mips/serial.h 2005-12-30 17:28:02.143968088 +0000 -@@ -410,6 +410,11 @@ - #define DDB5477_SERIAL_PORT_DEFNS - #endif - -+#if defined(CONFIG_AR531X) -+#undef RS_TABLE_SIZE -+#define RS_TABLE_SIZE 1 -+#endif -+ - #define SERIAL_PORT_DFNS \ - ATLAS_SERIAL_PORT_DEFNS \ - AU1000_SERIAL_PORT_DEFNS \ -diff -urN linux-mips/kernel/printk.c mips-linux-2.4.25/kernel/printk.c ---- linux-mips/kernel/printk.c 2005-12-24 15:12:09.361768152 +0000 -+++ mips-linux-2.4.25/kernel/printk.c 2005-12-30 17:28:11.943478336 +0000 -@@ -383,6 +383,18 @@ - _call_console_drivers(start_print, end, msg_level); - } - -+#if CONFIG_EARLY_PRINTK_HACK -+void putDebugChar(char byte); -+static void emit_log_char(char c) -+{ -+ if (c == '\n') { -+ putDebugChar('\r'); -+ putDebugChar('\n'); -+ } else { -+ putDebugChar(c); -+ } -+} -+#else - static void emit_log_char(char c) - { - LOG_BUF(log_end) = c; -@@ -394,6 +406,7 @@ - if (logged_chars < LOG_BUF_LEN) - logged_chars++; - } -+#endif - - /* - * This is printk. It can be called from any context. We want it to work. -@@ -696,3 +709,4 @@ - tty->driver.write(tty, 0, msg, strlen(msg)); - return; - } -+ -diff -urN linux-mips-orig/drivers/net/ath/ae531x.h linux-mips-new/drivers/net/ath/ae531x.h ---- linux-mips-orig/drivers/net/ath/ae531x.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/ae531x.h 2005-12-31 12:33:57.672538976 +0000 -@@ -0,0 +1,43 @@ -+#ifndef __AE531X_H -+#define __AE531X_H -+ -+#include <linux/config.h> -+#include <linux/types.h> -+#include <linux/delay.h> -+#include <linux/netdevice.h> -+#include <linux/etherdevice.h> -+#include <linux/init.h> -+#include <linux/skbuff.h> -+#include <asm/io.h> -+ -+#include "ar531xlnx.h" -+#include "ae531xreg.h" -+#include "ae531xmac.h" -+ -+extern void *ae531x_rxbuf_alloc(ae531x_MAC_t *MACInfo, char **rxBuffp, -+ int *rxBuffSizep); -+extern void ae531x_swptr_free(VIRT_ADDR desc); -+extern BOOL ae531x_twisted_enet(void); -+extern void ae531x_MiiWrite(UINT32 phyBase, UINT32 phyAddr, UINT8 reg, -+ UINT16 data); -+extern UINT16 ae531x_MiiRead(UINT32 phyBase, UINT32 phyAddr, UINT8 reg); -+extern void ae531x_unitLinkGained(int ethUnit); -+extern void ae531x_unitLinkLost(int ethUnit); -+extern void ae531x_WriteDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data); -+extern void ae531x_MACReset(ae531x_MAC_t *MACInfo); -+extern void ae531x_DisableComm(ae531x_MAC_t *MACInfo); -+extern void ae531x_FreeQueues(ae531x_MAC_t *MACInfo); -+extern void ae531x_reset(ae531x_MAC_t *MACInfo); -+extern int ae531x_AllocateQueues(ae531x_MAC_t *MACInfo); -+extern void ae531x_EnableComm(ae531x_MAC_t *MACInfo); -+extern void ae531x_DmaIntEnable(ae531x_MAC_t *MACInfo); -+extern void ae531x_DmaIntDisable(ae531x_MAC_t *MACInfo); -+extern void ae531x_DmaReset(ae531x_MAC_t *MACInfo); -+extern void ae531x_BeginResetMode(ae531x_MAC_t *MACInfo); -+extern void ae531x_AckIntr(ae531x_MAC_t *MACInfo, UINT32 data); -+extern void ae531x_SetDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val); -+extern BOOL ae531x_IsInResetMode(ae531x_MAC_t *MACInfo); -+extern UINT32 ae531x_ReadDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg); -+extern void ae531x_ClearDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val); -+ -+#endif /* __AE531X_H */ -diff -urN linux-mips-orig/drivers/net/ath/ae531xlnx.c linux-mips-new/drivers/net/ath/ae531xlnx.c ---- linux-mips-orig/drivers/net/ath/ae531xlnx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/ae531xlnx.c 2005-12-31 12:33:57.673538824 +0000 -@@ -0,0 +1,1303 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * Ethernet driver for Atheros' ae531x ethernet MAC. -+ * This is a fairly generic driver, but it's intended -+ * for use in typical Atheros products. -+ */ -+ -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/types.h> -+#include <linux/delay.h> -+#include <linux/netdevice.h> -+#include <linux/etherdevice.h> -+#include <linux/init.h> -+#include <linux/skbuff.h> -+#include <asm/io.h> -+ -+#include "ar531xlnx.h" -+#include "ae531xreg.h" -+#include "ae531xmac.h" -+#include "ae531x.h" -+ -+#ifndef EXPORT_SYMTAB -+#define EXPORT_SYMTAB -+#endif -+ -+#ifdef DEBUG -+void my_mvPhyShow(int ethUnit); -+#endif -+ -+static struct ar531x_boarddata *ar531x_boardConfig=NULL; -+ -+static char *radioConfig=NULL; -+ -+#define AE531X_LAN_PORT 0 -+#define AE531X_DEV_PER_MAC 1 -+ -+/* -+ * ae531x_MAC_state contains driver-specific linux-specific per-MAC information. -+ * The OSinfo member of ae531x_MAC_t points to one of these. -+ */ -+typedef struct ae531x_MAC_state { -+ int irq; -+ struct tq_struct restart_task; -+ struct net_device_stats stats; -+ struct ae531x_dev_sw_state *dev_sw_state[AE531X_DEV_PER_MAC]; -+ int primary_dev; -+ ae531x_MAC_t MACInfo; /* hardware state */ -+} ae531x_MAC_state_t; -+ -+/* -+ * ae531x_dev_sw_state contains driver-specific linux-specific per-device -+ * information. The net_device priv member points to one of these, and -+ * this structure contains a pointer to the associated MAC information. -+ */ -+ -+typedef struct ae531x_dev_sw_state { -+ int enetUnit; /* system unit number "eth%d" */ -+ int unit_on_MAC; /* MAC-relative unit number */ -+ struct net_device *dev; -+ ae531x_MAC_state_t *MAC_state; /* underlying MAC hw/sw state */ -+} ae531x_dev_sw_state_t; -+ -+/* -+ * Driver-independent linux-specific per-ethernet device software information. -+ */ -+static struct net_device *ae531x_MAC_dev[AR531X_NUM_ENET_MAC * AE531X_DEV_PER_MAC]; -+ -+/* Driver-dependent per-MAC information */ -+static ae531x_MAC_state_t per_MAC_info[AR531X_NUM_ENET_MAC]; -+ -+/* -+ * Receive buffers need enough room to hold the following: -+ * 1) a max MTU-sized packet. -+ * 2) space for an ethernet header -+ * 3) room at the beginning of the receive buffer in order -+ * to facilitate cooperating drivers that need to PREpend -+ * data. -+ * 4) Depending on configuration, we may need some additional -+ * room at the END of the rx buffer for phy-supplied -+ * trailers (if any). (c.f. CONFIG_VENETDEV) -+ * -+ * The DMA engine insists on 32-bit aligned RX buffers. -+ * TBDXXX: With current code, the IP stack ends up looking -+ * at misaligned headers with word operations. The misaligned -+ * reads are software-emulated via handle_adel_int. We'd -+ * rather align the buffers on a 16-bit boundary, but the -+ * DMA engine doesn't permit it??? -+ */ -+#define ETH_MAX_MTU 1518 -+#define AE531X_RX_BUF_SIZE \ -+ (((RXBUFF_RESERVE + ETH_HLEN + ETH_MAX_MTU + PHY_TRAILER_SIZE) + 3) & ~3) -+ -+/* Forward references to local functions */ -+static void ae531x_TxReap(ae531x_MAC_state_t *MAC_state); -+static int ae531x_phy_poll(void *data); -+static int ae531x_MAC_stop(struct net_device *dev); -+static int ae531x_MAC_open(struct net_device *dev); -+ -+/******************************************************************************* -+* ae531x_MAC_poll checks for received packets, and sends data -+* up the stack. -+*/ -+int -+ae531x_MAC_poll(struct net_device *dev, int *budget) -+{ -+ struct sk_buff *skb; -+ struct sk_buff *newskb; -+ char *rxBufp; -+ int unused_length; -+ VIRT_ADDR rxDesc; -+ int length; -+ ae531x_dev_sw_state_t *dev_sw_state; -+ ae531x_MAC_state_t *MAC_state; -+ ae531x_MAC_t *MACInfo; -+ u32 cmdsts; -+ int rx_limit; -+ int rx_received; -+ int rxDescCount; -+ struct net_device *rxdev; -+ int early_stop; -+ int retval; -+#ifdef DEBUG -+ static int rxDescCountMax = 0; -+#endif -+ -+ ARRIVE(); -+ -+ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; -+ MAC_state = dev_sw_state->MAC_state; -+ MACInfo = &MAC_state->MACInfo; -+ rx_limit = MAC_state->dev_sw_state[MAC_state->primary_dev]->dev->quota; -+ rx_received = 0; -+ -+ rxDescCount = 0; -+ -+ early_stop = 0; -+ do { -+ ae531x_AckIntr(MACInfo, DmaIntRxCompleted); -+ -+ for(;!early_stop;) { -+ rxDesc = MACInfo->rxQueue.curDescAddr; -+ cmdsts = AE531X_DESC_STATUS_GET(KSEG1ADDR(rxDesc)); -+ -+ AE531X_PRINT(AE531X_DEBUG_RX, -+ ("examine rxDesc %p with cmdsts=0x%x\n", -+ (void *)rxDesc, cmdsts)); -+ -+ if (cmdsts & DescOwnByDma) { -+ /* There's nothing left to process in the RX ring */ -+ goto rx_all_done; -+ } -+ -+ rxDescCount++; -+ -+ AE531X_CONSUME_DESC((&MACInfo->rxQueue)); -+ -+ A_DATA_CACHE_INVAL(rxDesc, AE531X_DESC_SIZE); -+ -+ /* Process a packet */ -+ length = AE531X_DESC_STATUS_RX_SIZE(cmdsts) - ETH_CRC_LEN; -+ if ( (cmdsts & (DescRxFirst |DescRxLast | DescRxErrors)) == -+ (DescRxFirst | DescRxLast) ) { -+ /* Descriptor status indicates "NO errors" */ -+ skb = AE531X_DESC_SWPTR_GET(rxDesc); -+ -+ /* -+ * Allocate a replacement skb. -+ * We want to get another buffer ready for Rx ASAP. -+ */ -+ newskb = (struct sk_buff *)ae531x_rxbuf_alloc(MACInfo, &rxBufp, &unused_length); -+ if(newskb == NULL ) { -+ /* -+ * Give this descriptor back to the DMA engine, -+ * and drop the received packet. -+ */ -+ MAC_state->stats.rx_dropped++; -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("Can't allocate new skb\n")); -+ } else { -+ AE531X_DESC_BUFPTR_SET(rxDesc, virt_to_bus(rxBufp)); -+ AE531X_DESC_SWPTR_SET(rxDesc, newskb); -+ } -+ -+ AE531X_DESC_STATUS_SET(rxDesc, DescOwnByDma); -+ rxDesc = NULL; /* sanity -- cannot use rxDesc now */ -+ sysWbFlush(); -+ -+ if (newskb == NULL) { -+ retval = 1; -+ goto rx_no_skbs; -+ } else { -+ /* Sync data cache w.r.t. DMA */ -+ A_DATA_CACHE_INVAL(skb->data, length); -+ -+ rxdev = dev_sw_state->dev; -+ -+ if (rxdev == NULL) { -+ /* -+ * We received a packet for a virtual enet device -+ * that is no longer up. Ignore it. -+ */ -+ kfree_skb(skb); -+ continue; -+ } -+ -+ /* Advance data pointer to show that there's data here */ -+ skb_put(skb, length); -+ skb->protocol = eth_type_trans(skb, rxdev); -+ skb->dev = rxdev; -+ rxdev->last_rx = jiffies; -+ rxdev->quota--; -+ -+ if (rx_limit-- < 0) { -+ early_stop=1; -+ /* We've done enough for now -- more later */ -+ AE531X_PRINT(AE531X_DEBUG_RX_STOP, -+ ("Enet%d RX early stop. Quota=%d rxDescCount=%d budget=%d\n", -+ MACInfo->unit, dev->quota, rxDescCount, *budget)); -+ } -+ rx_received++; -+ -+ /* Send the data up the stack */ -+ AE531X_PRINT(AE531X_DEBUG_RX, -+ ("Send data up stack: skb=%p data=%p length=%d\n", -+ (void *)skb, (void *)skb->data, length)); -+ -+ netif_receive_skb(skb); -+ -+ MAC_state->stats.rx_packets++; -+ MAC_state->stats.rx_bytes += length; -+ } -+ } else { -+ /* Descriptor status indicates ERRORS */ -+ MAC_state->stats.rx_errors++; -+ -+ if (cmdsts & (DescRxRunt | DescRxLateColl)) { -+ MAC_state->stats.collisions++; -+ } -+ -+ if (cmdsts & DescRxLengthError) { -+ MAC_state->stats.rx_length_errors++; -+ } -+ -+ if (cmdsts & DescRxCrc) { -+ MAC_state->stats.rx_crc_errors++; -+ } -+ -+ if (cmdsts & DescRxDribbling) { -+ MAC_state->stats.rx_frame_errors++; -+ } -+ -+ AE531X_DESC_STATUS_SET(rxDesc, DescOwnByDma); -+ -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("Bad receive. rxDesc=%p cmdsts=0x%8.8x\n", -+ (void *)rxDesc, cmdsts)); -+ } -+ } -+ } while ((!early_stop) && -+ ae531x_ReadDmaReg(MACInfo, DmaStatus) & DmaIntRxCompleted); -+ -+rx_all_done: -+ AE531X_PRINT(AE531X_DEBUG_RX, -+ ("rx done (%d)\n", rxDescCount)); -+ *budget -= rxDescCount; -+ -+ if (!early_stop) { -+ netif_rx_complete(dev); -+ -+ ae531x_SetDmaReg(MACInfo, DmaIntrEnb, -+ DmaIeRxCompleted | DmaIeRxNoBuffer); -+ ae531x_WriteDmaReg(MACInfo, DmaRxPollDemand, 0); -+ } -+ -+ retval = early_stop; -+ -+rx_no_skbs: -+ -+ LEAVE(); -+ -+#ifdef DEBUG -+ if (rxDescCount > rxDescCountMax) { -+ printk("max rx %d\n", rxDescCount); -+ rxDescCountMax = rxDescCount; -+ } -+#endif -+ -+ return retval; -+} -+ -+/******************************************************************************* -+* ae531x_restart stops all ethernet devices associated with a physical MAC, -+* then shuts down the MAC. Then it re-opens all devices that were in use. -+* TBDXXX: needs testing! -+*/ -+static void -+ae531x_restart(void *data) -+{ -+ ae531x_MAC_t *MACInfo = (ae531x_MAC_t *)data; -+ ae531x_MAC_state_t *MAC_state = (ae531x_MAC_state_t *)MACInfo->OSinfo; -+ struct net_device *saved_dev[AE531X_DEV_PER_MAC]; -+ int i; -+ -+ for (i=0; i<AE531X_DEV_PER_MAC; i++) { -+ if ((saved_dev[i] = MAC_state->dev_sw_state[i]->dev) != NULL) { -+ ae531x_MAC_stop(saved_dev[i]); -+ } -+ } -+ -+ for (i=0; i<AE531X_DEV_PER_MAC; i++) { -+ if (saved_dev[i]) -+ ae531x_MAC_open(saved_dev[i]); -+ } -+} -+ -+/******************************************************************************* -+* ae531x_MAC_intr handle interrupts from an ethernet MAC. -+* It checks MAC status registers, and dispatches as appropriate. -+*/ -+void -+ae531x_MAC_intr(int cpl, void *dev_id, struct pt_regs *regs) -+{ -+ ae531x_MAC_state_t *MAC_state; -+ ae531x_MAC_t *MACInfo; -+ u32 regIsr; -+ u32 regImr; -+ u32 pendIntrs; -+ -+ ARRIVE(); -+ MACInfo = (ae531x_MAC_t *)dev_id; -+ MAC_state = (ae531x_MAC_state_t *)MACInfo->OSinfo; -+ for(;;) { -+ /* Clear any unhandled intr causes. */ -+ ae531x_WriteDmaReg(MACInfo, DmaStatus, UnhandledIntrMask); -+ -+ regIsr = ae531x_ReadDmaReg(MACInfo, DmaStatus); -+ regImr = ae531x_ReadDmaReg(MACInfo, DmaIntrEnb); -+ pendIntrs = regIsr & regImr; -+ -+ AE531X_PRINT(AE531X_DEBUG_INT, -+ ("ethmac%d: intIsr=0x%8.8x intImr=0x%8.8x pendIntrs=0x%8.8x\n", -+ MACInfo->unit, regIsr, regImr, pendIntrs )); -+ -+ if ((pendIntrs & DmaAllIntCauseMask) == 0) -+ break; -+ -+ if ((pendIntrs & DmaIntRxCompleted) || -+ (pendIntrs & DmaIntRxNoBuffer)) { -+ if (netif_rx_schedule_prep(MAC_state->dev_sw_state[MAC_state->primary_dev]->dev)) { -+ ae531x_ClearDmaReg(MACInfo, -+ DmaIntrEnb, -+ DmaIeRxCompleted | DmaIeRxNoBuffer); -+ ae531x_AckIntr(MACInfo, -+ DmaIntRxCompleted | DmaIntRxNoBuffer); -+ (void)ae531x_ReadDmaReg(MACInfo, DmaIntrEnb); -+ __netif_rx_schedule(MAC_state->dev_sw_state[MAC_state->primary_dev]->dev); -+ } else { -+#if 0 -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("%s: Interrupt (0x%8.8x/0x%8.8x) while in poll. regs@%p, pc=%p, ra=%p\n", -+ __FILE__, -+ regIsr, -+ ae531x_ReadDmaReg(MACInfo, DmaIntrEnb), -+ (void *)regs, -+ (void *)regs->cp0_epc, -+ (void *)regs->regs[31])); -+#endif -+ ae531x_AckIntr(MACInfo, -+ DmaIntRxCompleted | DmaIntRxNoBuffer); -+ } -+ } -+ -+ if (pendIntrs & -+ (DmaIntTxStopped | DmaIntTxJabber | DmaIntTxUnderflow)) { -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("ethmac%d: TX Error Intr (0x%x)\n", -+ MACInfo->unit, pendIntrs)); -+ ae531x_AckIntr(MACInfo, -+ (DmaIntTxStopped | DmaIntTxJabber | DmaIntTxUnderflow)); -+ } -+ -+ if (pendIntrs & DmaIntBusError) { -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("ethmac%d: DMA Bus Error Intr (0x%x)\n", -+ MACInfo->unit, pendIntrs)); -+ ae531x_AckIntr(MACInfo, DmaIntBusError); -+ /* Reset the chip, if it's not already being done */ -+ if (ae531x_IsInResetMode(MACInfo)) { -+ goto intr_done; -+ } -+ ae531x_BeginResetMode(MACInfo); -+ schedule_task(&MAC_state->restart_task); -+ } -+ -+ if (pendIntrs & DmaIntRxStopped) { -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("ethmac%d: RX Stopped Intr (0x%x)\n", -+ MACInfo->unit, pendIntrs)); -+ ae531x_AckIntr(MACInfo, DmaIntRxStopped); -+ } -+ } -+ -+ intr_done: -+ LEAVE(); -+} -+ -+/******************************************************************************* -+* ae531x_MAC_get_stats returns statistics for a specified device -+*/ -+static struct net_device_stats* -+ae531x_MAC_get_stats(struct net_device *dev) -+{ -+ ae531x_dev_sw_state_t *dev_sw_state; -+ ae531x_MAC_state_t *MAC_state; -+ -+ ARRIVE(); -+ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; -+ MAC_state = dev_sw_state->MAC_state; -+ -+ LEAVE(); -+ return &MAC_state->stats; -+} -+ -+#define AE531X_PHY_POLL_SECONDS 2 -+ -+#if CONFIG_AR5315 -+ -+/******************************************************************************* -+* ae531x_getMACInfo returns the MACInfo of the interface given by unit -+*/ -+ae531x_MAC_t *ae531x_getMAcInfo(int ethUnit) -+{ -+ int i,j; -+ for(i=0;i<AR531X_NUM_ENET_MAC;++i) { -+ if(per_MAC_info[i].dev_sw_state) { -+ for(j=0;j<AE531X_DEV_PER_MAC;++j) { -+ if(per_MAC_info[i].dev_sw_state[j] -+ && per_MAC_info[i].dev_sw_state[j]->enetUnit == ethUnit) -+ return (&(per_MAC_info[i].MACInfo)); -+ } -+ } -+ } -+ return NULL; -+} -+ -+ -+#endif -+ -+/******************************************************************************* -+* ae531x_phy_poll periodically checks for changes in phy status -+* (e.g. dropped link). -+*/ -+static int -+ae531x_phy_poll(void *data) -+{ -+ ae531x_dev_sw_state_t *dev_sw_state = (ae531x_dev_sw_state_t *)data; -+ ae531x_MAC_t *MACInfo = &dev_sw_state->MAC_state->MACInfo; -+ int unit = dev_sw_state->enetUnit; -+ -+ while(dev_sw_state->dev!=NULL) { -+ if (MACInfo->port_is_up) { -+ phyCheckStatusChange(unit); -+ } -+ -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ schedule_timeout(AE531X_PHY_POLL_SECONDS * HZ); -+ } -+ -+ return 0; -+} -+ -+ -+static char invalid_enet_MAC_addr[] = {0, 0, 0, 0, 0, 0}; -+ -+/* -+ * Fetch a pointer to an ethernet's MAC address -+ * in the Board Configuration data (in flash). -+ */ -+char * -+ae531x_enet_mac_address_get(int MACUnit) -+{ -+ /* XXX: Hack for poorly configured boards. -+ * Cannot setup bridging properly (brctl) when both enet -+ * interfaces share the same MAC address. -+ * -+ */ -+ -+#ifdef CONFIG_ASK_MULT_MAC_HACK -+ static u8 enet0Mac[6] = {0x00, 0x0d, 0x0b, 0x13, 0x6b, 0x16}; -+ static u8 enet1Mac[6] = {0x00, 0x0d, 0x0b, 0x13, 0x6b, 0x17}; -+#endif -+ -+ if (!ar531x_boardConfig) -+ return invalid_enet_MAC_addr; -+ if (MACUnit == 0) { -+#ifndef CONFIG_ASK_MULT_MAC_HACK -+ return ar531x_boardConfig->enet0Mac; -+#else -+ return enet0Mac; -+#endif -+ } -+ if (MACUnit == 1) { -+#ifndef CONFIG_ASK_MULT_MAC_HACK -+ return ar531x_boardConfig->enet1Mac; -+#else -+ return enet1Mac; -+#endif -+ } -+ printk("Invalid ethernet MAC unit number (%d)!\n", MACUnit); -+ return invalid_enet_MAC_addr; -+} -+ -+ -+ -+/******************************************************************************* -+* ae531x_MAC_open is the standard Linux open function. It puts -+* hardware into a known good state, allocates queues, starts -+* the phy polling task, and arranges for interrupts to be handled. -+*/ -+static int -+ae531x_MAC_open(struct net_device *dev) -+{ -+ ae531x_dev_sw_state_t *dev_sw_state; -+ ae531x_MAC_state_t *MAC_state; -+ ae531x_MAC_t *MACInfo; -+ u8 *MACAddr; -+ int rv; -+ struct tq_struct *restart_task; -+ pid_t phy_poll_pid; -+ ARRIVE(); -+ -+ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; -+ dev_sw_state->dev = dev; -+ MAC_state = dev_sw_state->MAC_state; -+ MACInfo = &MAC_state->MACInfo; -+ -+ restart_task = &MAC_state->restart_task; -+ restart_task->routine = ae531x_restart; -+ restart_task->data = (void *)MACInfo; -+ -+ AE531X_PRINT(AE531X_DEBUG_RESET, -+ ("ae531x_MAC_open eth%d ethmac%d macBase=0x%x dmaBase=0x%x irq=0x%x\n", -+ dev_sw_state->enetUnit, -+ MACInfo->unit, -+ MACInfo->macBase, -+ MACInfo->dmaBase, -+ MAC_state->irq)); -+ -+ /* Default MAC address */ -+ MACAddr = ae531x_enet_mac_address_get(MACInfo->unit); -+ memcpy(dev->dev_addr, MACAddr, dev->addr_len ); -+ -+ if (!MACInfo->port_is_up) { -+ /* Bring MAC and PHY out of reset */ -+ ae531x_reset(MACInfo); -+ -+ /* Attach interrupt handler */ -+ rv = request_irq(MAC_state->irq, ae531x_MAC_intr, SA_INTERRUPT, -+ "ae531x_MAC_intr", (void *)MACInfo); -+ if (rv < 0) { -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("request_irq(0x%x) failed (%d)\n", -+ MAC_state->irq, rv)); -+ goto open_failure; -+ } -+ -+ /* Initialize PHY */ -+ AE531X_PRINT(AE531X_DEBUG_RESET, ("\n --- phyBase: %08x\n", MACInfo->phyBase)); -+ phySetup(MACInfo->unit, MACInfo->phyBase); -+ -+ /* Start thread to poll for phy link status changes */ -+ phy_poll_pid = kernel_thread(ae531x_phy_poll, dev_sw_state, 0); -+ if (phy_poll_pid < 0) { -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("ethmac%d unable to start Phy Poll thread\n", -+ MACInfo->unit)); -+ } -+ -+ /* Allocate RX/TX Queues */ -+ if (ae531x_AllocateQueues(MACInfo) < 0) { -+ AE531X_PRINT(AE531X_DEBUG_RESET, ("Queue allocation failed")); -+ free_irq(MAC_state->irq, (void *)MACInfo); -+ goto open_failure; -+ } -+ -+ /* Initialize DMA and descriptors */ -+ ae531x_DmaReset(MACInfo); -+ -+ /* Initialize MAC */ -+ ae531x_MACReset(MACInfo); -+ -+ /* Enable Receive/Transmit */ -+ ae531x_EnableComm(MACInfo); -+ -+ MAC_state->primary_dev = dev_sw_state->unit_on_MAC; -+ MACInfo->port_is_up = TRUE; -+ } -+ -+ dev->trans_start = jiffies; -+ SET_MODULE_OWNER(dev); -+ -+ LEAVE(); -+ return 0; -+ -+open_failure: -+ LEAVE(); -+ return -1; -+} -+ -+/* -+ * Shut down MAC hardware. -+ */ -+static void -+ae531x_MAC_shutdown(ae531x_MAC_state_t *MAC_state) -+{ -+ ae531x_MAC_t *MACInfo; -+ -+ MACInfo = &MAC_state->MACInfo; -+ MACInfo->port_is_up = FALSE; -+ -+ /* Disable Receive/Transmit */ -+ ae531x_DisableComm(MACInfo); -+ -+ /* Disable Interrupts */ -+ ae531x_DmaIntDisable(MACInfo); -+ sysWbFlush(); -+ free_irq(MAC_state->irq, (void *)MACInfo); -+ -+ /* Free Transmit & Receive skb's/descriptors */ -+ ae531x_TxReap(MAC_state); /* one last time */ -+ ae531x_FreeQueues(MACInfo); -+} -+ -+/******************************************************************************* -+* ae531x_MAC_stop is the standard Linux stop function. It undoes -+* everything set up by ae531x_MAC_open. -+*/ -+static int -+ae531x_MAC_stop(struct net_device *dev) -+{ -+ ae531x_dev_sw_state_t *dev_sw_state; -+ ae531x_MAC_state_t *MAC_state; -+ ae531x_MAC_t *MACInfo; -+ int i; -+ -+ ARRIVE(); -+ -+ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; -+ MAC_state = dev_sw_state->MAC_state; -+ MACInfo = &MAC_state->MACInfo; -+ -+ for (i=0; i<AE531X_DEV_PER_MAC; i++) { -+ if ((MAC_state->dev_sw_state[i]->dev) && -+ (MAC_state->dev_sw_state[i]->dev != dev_sw_state->dev)) { -+ break; -+ } -+ } -+ -+ if (i < AE531X_DEV_PER_MAC) { -+ /* Physical MAC is still in use */ -+ if (MAC_state->primary_dev == dev_sw_state->unit_on_MAC) { -+ /* -+ * If the primary_dev is being stopped -+ * then we need to assign a new one. -+ */ -+ MAC_state->primary_dev = i; -+ } -+ } else { -+ /* Physical MAC is no longer in use */ -+ ae531x_MAC_shutdown(MAC_state); -+ } -+ -+ dev_sw_state->dev = NULL; -+ LEAVE(); -+ return 0; -+} -+ -+/******************************************************************************* -+* ae531x_rxbuf_alloc - Allocate an skb to be associated with an RX descriptor. -+* -+* RETURNS: A pointer to the skb. Also returns a pointer to the underlying -+* buffer and the size of that buffer. -+*/ -+void * -+ae531x_rxbuf_alloc(ae531x_MAC_t *MACInfo, char **rxBuffp, int *rxBuffSizep) -+{ -+ int buf_size; -+ struct sk_buff *skb; -+ char *rxBuff; -+ int rxBuffSize; -+ -+ buf_size = AE531X_RX_BUF_SIZE; -+ -+ skb = dev_alloc_skb(buf_size); -+ if (skb) { -+ /* skb->dev = dev; */ -+ skb_reserve(skb, RXBUFF_RESERVE); -+ -+ rxBuffSize = skb_tailroom(skb); -+ rxBuff = skb->tail; -+ -+ *rxBuffp = rxBuff; -+ *rxBuffSizep = rxBuffSize; -+ } -+ -+ return skb; -+} -+ -+/******************************************************************************* -+* ae531x_swptr_free - Free the skb, if any, associated with a descriptor. -+*/ -+void -+ae531x_swptr_free(VIRT_ADDR desc) -+{ -+ struct sk_buff *skb; -+ -+ skb = (struct sk_buff *)AE531X_DESC_SWPTR_GET(desc); -+ if (skb) { -+ AE531X_DESC_SWPTR_SET(desc, NULL); -+ kfree_skb(skb); -+ } -+} -+ -+/******************************************************************************* -+* -+* ae531x_TxReap - the driver Tx completion routine. -+* -+* This routine reaps sk_buffs which have already been transmitted. -+* -+*/ -+static void -+ae531x_TxReap(ae531x_MAC_state_t *MAC_state) -+{ -+ AE531X_QUEUE *txq; -+ VIRT_ADDR txDesc; -+ UINT32 cmdsts; -+ struct sk_buff *skb; -+ int reaped; -+ ae531x_MAC_t *MACInfo; -+ static int aeUselessReap = 0; -+#ifdef DEBUG -+ static int aeMaxReap = 0; -+#endif -+ ARRIVE(); -+ -+ MACInfo = &MAC_state->MACInfo; -+ txq = &MACInfo->txQueue; -+ reaped = 0; -+ -+ while (1) { -+ -+ txDesc = AE531X_QUEUE_ELE_NEXT_GET(txq, txq->reapDescAddr); -+ if (txDesc == txq->curDescAddr) { -+ break; -+ } -+ -+ cmdsts = AE531X_DESC_STATUS_GET(KSEG1ADDR(txDesc)); -+ if (cmdsts & DescOwnByDma) { -+ break; -+ } -+ -+ /* Release sk_buff associated with completed transmit */ -+ skb = (struct sk_buff *)AE531X_DESC_SWPTR_GET(txDesc); -+ if (skb) { -+ kfree_skb(skb); -+ AE531X_DESC_SWPTR_SET(txDesc, NULL); -+ } -+ -+ /* Update statistics according to completed transmit desc */ -+ if (cmdsts & DescTxErrors) { -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("enetmac%d Tx prior error: 0x%8.8x <0x%8.8x> 0x%8.8x\n", -+ MACInfo->unit, -+ cmdsts, -+ DescTxErrors, -+ (int)txDesc)); -+#ifdef DEBUG -+ //my_mvPhyShow(MACInfo->unit); -+ printk ("ae531xMacControl: 0x%08x\tMacFlowControl: 0x%08x\n", -+ ae531x_ReadMacReg(MACInfo, MacControl), -+ ae531x_ReadMacReg(MACInfo, MacFlowControl)); -+#endif -+ MAC_state->stats.tx_errors++; -+ if (cmdsts & (DescTxLateCollision | DescTxExcCollisions)) { -+ MAC_state->stats.tx_aborted_errors++; -+ } -+ if (cmdsts & (DescTxLostCarrier | DescTxNoCarrier)) { -+ MAC_state->stats.tx_carrier_errors++; -+ } -+ } else { -+ MAC_state->stats.tx_bytes += AE531X_DESC_STATUS_RX_SIZE(cmdsts); -+ MAC_state->stats.tx_packets++; -+ } -+ -+ MAC_state->stats.collisions += -+ ((cmdsts & DescTxCollMask) >> DescTxCollShift); -+ -+ txq->reapDescAddr = txDesc; -+ reaped++; -+ } -+ -+ if (reaped > 0) { -+ int i; -+ -+#ifdef DEBUG -+ if (reaped > aeMaxReap) { -+ aeMaxReap = reaped; -+ printk("max reaped = %d\n", reaped); -+ } -+#endif -+ AE531X_PRINT(AE531X_DEBUG_TX_REAP, -+ ("reaped %d\n", reaped)); -+ -+ /* -+ * Re-start transmit queues for all ethernet devices -+ * associated with this MAC. -+ */ -+ for (i=0; i<AE531X_DEV_PER_MAC; i++) { -+ if (MAC_state->dev_sw_state[i]->dev) -+ netif_start_queue(MAC_state->dev_sw_state[i]->dev); -+ } -+ } else { -+ aeUselessReap++; -+ } -+ -+ LEAVE(); -+} -+ -+ -+/******************************************************************************* -+* ae531x_MAC_start_xmit sends a packet. -+*/ -+static int -+ae531x_MAC_start_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ ae531x_dev_sw_state_t *dev_sw_state; -+ ae531x_MAC_state_t *MAC_state; -+ ae531x_MAC_t *MACInfo; -+ u32 buf; -+ u32 ctrlen; -+ u32 length; -+ int mtu; -+ int max_buf_size; -+ VIRT_ADDR txDesc; -+ -+ ARRIVE(); -+ -+ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; -+ MAC_state = dev_sw_state->MAC_state; -+ MACInfo = &MAC_state->MACInfo; -+ -+ length = skb->len; -+ -+ /* Check if this port is up, else toss packet */ -+ if (!MACInfo->port_is_up) { -+ buf = virt_to_bus(skb->data); -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("eth%d Tx Down, dropping buf=0x%8.8x, length=0x%8.8x, skb=%p\n", -+ dev_sw_state->enetUnit, buf, length, (void *)skb)); -+ -+ MAC_state->stats.tx_dropped++; -+ MAC_state->stats.tx_carrier_errors++; -+ goto dropFrame; -+ } -+ -+ if (ae531x_IsInResetMode(MACInfo)) { -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("eth%d Tx: In Chip reset - drop frame\n", -+ dev_sw_state->enetUnit)); -+ -+ MAC_state->stats.tx_dropped++; -+ MAC_state->stats.tx_aborted_errors++; -+ goto dropFrame; -+ } -+ -+ /* Check if we can transport this packet */ -+ length = max((u32)60, length); /* total length */ -+ mtu = dev->mtu; -+ max_buf_size = mtu + ETH_HLEN; -+ if (length > max_buf_size) { -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("eth%d Tx: length %d too long. mtu=%d, trailer=%d\n", -+ dev_sw_state->enetUnit, length, mtu, PHY_TRAILER_SIZE)); -+ -+ MAC_state->stats.tx_errors++; -+ MAC_state->stats.tx_aborted_errors++; -+ -+ goto dropFrame; -+ } -+ -+ /* Reap any old, completed Tx descriptors */ -+ ae531x_TxReap(MAC_state); -+ -+ txDesc = MACInfo->txQueue.curDescAddr; -+ if (txDesc == MACInfo->txQueue.reapDescAddr) { -+ int i; -+ -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("eth%d Tx: cannot get txDesc\n", -+ dev_sw_state->enetUnit)); -+ -+ MAC_state->stats.tx_dropped++; -+ MAC_state->stats.tx_fifo_errors++; -+ -+ /* -+ * Stop transmit queues for any ethernet devices -+ * associated with this MAC. -+ */ -+#if 0 /* XXX: no way to recover from queue stop until ae531x_MAC_tx_timeout() -+ * is rewritten to avoid calls to shedule(). -+ */ -+ for (i=0; i<AE531X_DEV_PER_MAC; i++) { -+ if (MAC_state->dev_sw_state[i]->dev) -+ netif_stop_queue(MAC_state->dev_sw_state[i]->dev); -+ } -+#endif -+ goto dropFrame; -+ } -+ -+ /* We won't fail now; so consume this descriptor */ -+ AE531X_CONSUME_DESC((&MACInfo->txQueue)); -+ -+ /* Update the descriptor */ -+ buf = virt_to_bus(skb->data); -+ AE531X_DESC_BUFPTR_SET(txDesc, buf); -+ AE531X_DESC_SWPTR_SET(txDesc, skb); -+ ctrlen = AE531X_DESC_CTRLEN_GET(txDesc); -+ ctrlen = (ctrlen & (DescEndOfRing)) | -+ DescTxFirst | -+ DescTxLast | -+ DescTxIntEnable; -+ -+ ctrlen |= ((length << DescSize1Shift) & DescSize1Mask); -+ -+ AE531X_DESC_CTRLEN_SET(txDesc, ctrlen); -+ AE531X_DESC_STATUS_SET(txDesc, DescOwnByDma); -+ -+ /* Alert DMA engine to resume Tx */ -+ ae531x_WriteDmaReg(MACInfo, DmaTxPollDemand, 0); -+ sysWbFlush(); -+ -+ AE531X_PRINT(AE531X_DEBUG_TX, -+ ("eth%d Tx: Desc=0x%8.8x, L=0x%8.8x, D=0x%8.8x, d=0x%8.8x, length=0x%8.8x\n", -+ dev_sw_state->enetUnit, -+ (UINT32)txDesc, -+ AE531X_DESC_CTRLEN_GET(txDesc), -+ buf, -+ AE531X_DESC_LNKBUF_GET(txDesc), -+ length)); -+ -+ /* Tell upper layers to keep it coming */ -+ dev->trans_start = jiffies; -+ -+ LEAVE(); -+ -+ return 0; -+ -+dropFrame: -+ kfree_skb(skb); -+ LEAVE(); -+ return 0; -+} -+ -+ -+/******************************************************************************* -+* ae531x_MAC_tx_timeout handles transmit timeouts -+*/ -+static void -+ae531x_MAC_tx_timeout(struct net_device *dev) -+{ -+ ae531x_dev_sw_state_t *dev_sw_state; -+ ae531x_MAC_state_t *MAC_state; -+ ae531x_MAC_t *MACInfo; -+ -+ ARRIVE(); -+ -+ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; -+ MAC_state = dev_sw_state->MAC_state; -+ MACInfo = &MAC_state->MACInfo; -+ -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("enet%d: Tx timeout\n", dev_sw_state->enetUnit)); -+ -+ ae531x_restart(MACInfo); -+ -+ LEAVE(); -+} -+ -+ -+/******************************************************************************* -+* ae531x_MAC_do_ioctl is a placeholder for future ioctls. -+*/ -+static int -+ae531x_MAC_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -+{ -+ int rv; -+ ae531x_MAC_t *MACInfo; -+ struct ioctl_data { -+ u32 unit; -+ u32 addr; -+ u32 data; -+ } *req; -+ ae531x_dev_sw_state_t *dev_sw_state; -+ ae531x_MAC_state_t *MAC_state; -+ -+ ARRIVE(); -+ -+ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; -+ MAC_state = dev_sw_state->MAC_state; -+ MACInfo = &MAC_state->MACInfo; -+ -+ req = (struct ioctl_data *)ifr->ifr_data; -+ -+ switch( cmd ) { -+ default: -+ AE531X_PRINT(AE531X_DEBUG_ERROR, -+ ("Unsupported ioctl: 0x%x\n", cmd)); -+ rv = -EOPNOTSUPP; -+ } -+ -+ LEAVE(); -+ return rv; -+} -+ -+static void -+ae531x_MAC_setup_fntable(struct net_device *dev) -+{ -+ ARRIVE(); -+ -+ dev->get_stats = ae531x_MAC_get_stats; -+ dev->open = ae531x_MAC_open; -+ dev->stop = ae531x_MAC_stop; -+ dev->hard_start_xmit = ae531x_MAC_start_xmit; -+ dev->do_ioctl = ae531x_MAC_do_ioctl; -+ dev->poll = ae531x_MAC_poll; -+ dev->weight = 16; -+#if 0 /* XXX: currently, ae531x_MAC_tx_timeout() will call functions -+ * that in turn call schedule(). this is BAD, since the -+ * timeout call runs at interrupt time. until ae531x_MAC_tx_timeout -+ * is rewritten to avoid schedule() calls, we do not use it. -+ */ -+ dev->tx_timeout = ae531x_MAC_tx_timeout; -+#else -+ dev->tx_timeout = NULL; -+#endif -+ dev->features = NETIF_F_HW_CSUM |\ -+ NETIF_F_HIGHDMA; -+ -+ LEAVE(); -+} -+ -+static void -+ar5312EepromRead(char *EepromAddr, u_int16_t id, unsigned int off, -+ unsigned int nbytes, char *data) -+{ -+ int i; -+ -+ for (i=0; i<nbytes; i++, off++) { -+ data[i] = EepromAddr[off]; -+ } -+} -+ -+int -+ae531x_get_numMACs(void) -+{ -+ int devid; -+ u16 radioMask; -+ -+ /* Probe to find out the silicon revision and enable the -+ correct number of macs */ -+ devid = ((u_int16_t) ((sysRegRead(AR531X_REV) >>8) & -+ (AR531X_REV_MAJ | AR531X_REV_MIN))); -+ switch (devid) { -+ case AR5212_AR5312_REV2: -+ case AR5212_AR5312_REV7: -+ /* Need to determine if we have a 5312 or a 2312 since they -+ have the same Silicon Rev ID*/ -+ ar5312EepromRead(radioConfig,0,2*AR531X_RADIO_MASK_OFF,2, -+ (char *) &radioMask); -+ if ((radioMask & AR531X_RADIO0_MASK) != 0) { -+ return 2; -+ } -+ return 1; -+ case AR5212_AR2313_REV8: -+ return 1; -+ } -+ -+ /* default to 1 */ -+ return 1; -+} -+ -+BOOL -+ae531x_twisted_enet(void) -+{ -+ int wisoc_revision; -+ -+ wisoc_revision = (sysRegRead(AR531X_REV) & AR531X_REV_MAJ) >> AR531X_REV_MAJ_S; -+ if ( (wisoc_revision == AR531X_REV_MAJ_AR2313) || -+ /* next clause is used to determine AR2312, based on number of MACs. -+ * must do this since revision is same for 5312 and 2312. -+ */ -+ (wisoc_revision == AR531X_REV_MAJ_AR5312 && ae531x_get_numMACs() == 1) ) { -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+ -+int -+ae531x_get_board_config(void) -+{ -+ int dataFound; -+ char *bd_config; -+ -+ /* -+ * Find start of Board Configuration data, using heuristics: -+ * Search back from the (aliased) end of flash by 0x1000 bytes -+ * at a time until we find the string "5311", which marks the -+ * start of Board Configuration. Give up if we've searched -+ * more than 500KB. -+ */ -+ dataFound = 0; -+ for (bd_config = (char *)0xbffff000; -+ bd_config > (char *)0xbff80000; -+ bd_config -= 0x1000) -+ { -+ if ( *(int *)bd_config == AR531X_BD_MAGIC) { -+ dataFound = 1; -+ break; -+ } -+ } -+ -+ if (!dataFound) { -+ printk("Could not find Board Configuration Data\n"); -+ bd_config = NULL; -+ } -+ -+ ar531x_boardConfig = (struct ar531x_boarddata *) bd_config; -+ -+ return(dataFound); -+} -+ -+int -+ae531x_get_radio_config(void) -+{ -+ int dataFound; -+ char *radio_config; -+ -+ /* -+ * Now find the start of Radio Configuration data, using heuristics: -+ * Search forward from Board Configuration data by 0x1000 bytes -+ * at a time until we find non-0xffffffff. -+ */ -+ dataFound = 0; -+ for (radio_config = ((char *) ar531x_boardConfig) + 0x1000; -+ radio_config < (char *)0xbffff000; -+ radio_config += 0x1000) -+ { -+ if (*(int *)radio_config != 0xffffffff) { -+ dataFound = 1; -+ break; -+ } -+ } -+ -+ if (!dataFound) { /* AR2316 relocates radio config to new location */ -+ dataFound = 0; -+ for (radio_config = ((char *) ar531x_boardConfig) + 0xf8; -+ radio_config < (char *)0xbffff0f8; -+ radio_config += 0x1000) -+ { -+ if (*(int *)radio_config != 0xffffffff) { -+ dataFound = 1; -+ break; -+ } -+ } -+ } -+ -+ if (!dataFound) { -+ printk("Could not find Radio Configuration data\n"); -+ radio_config = NULL; -+ } -+ radioConfig = radio_config; -+ return(dataFound); -+} -+ -+static int __init -+ae531x_MAC_setup(void) -+{ -+ int next_dev, i; -+ struct net_device *dev; -+ ae531x_dev_sw_state_t *dev_sw_state; -+ ae531x_MAC_state_t *MAC_state; -+ ae531x_MAC_t *MACInfo; -+ char *addr; -+ -+ ARRIVE(); -+ -+ MOD_INC_USE_COUNT; -+ for (i=0;i<AR531X_NUM_ENET_MAC * AE531X_DEV_PER_MAC; i++) { -+ ae531x_MAC_dev[i] = NULL; -+ } -+ -+ if (!ae531x_get_board_config()) { -+ LEAVE(); -+ return -1; -+ } -+ if (!ae531x_get_radio_config()) { -+ LEAVE(); -+ return(-1); -+ } -+ for(i=0, next_dev = AR531X_NUM_ENET_MAC-1; -+ i<ae531x_get_numMACs() && next_dev>=0; -+ i++, next_dev--){ -+ -+ /* if MAC is bogus in config data, skip */ -+ addr = ae531x_enet_mac_address_get(next_dev); -+ if((*(u32 *)addr == 0xffffffff) && (*(u16 *)(addr+4)==0xffff)){ -+ /* bogus MAC config data */ -+ continue; -+ } -+ -+ dev = ae531x_MAC_dev[next_dev] = -+ init_etherdev(NULL, sizeof(ae531x_dev_sw_state_t)); -+ -+ if (dev == NULL) { -+ LEAVE(); -+ return -1; -+ } -+ -+ ae531x_MAC_setup_fntable(dev); -+ -+ dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv; -+ dev_sw_state->enetUnit = next_dev; -+ dev_sw_state->unit_on_MAC = 0; -+ MAC_state = &per_MAC_info[next_dev]; -+ dev_sw_state->MAC_state = MAC_state; -+ MAC_state->dev_sw_state[AE531X_LAN_PORT] = dev_sw_state; -+ MAC_state->primary_dev = -1; -+ -+ /* Initialize per-MAC information */ -+ MACInfo = &MAC_state->MACInfo; -+ -+ MACInfo->unit = next_dev; -+ -+ if (MACInfo->unit == 0) { -+ MACInfo->macBase = (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_MAC_OFFSET); -+ MACInfo->dmaBase = (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_DMA_OFFSET); -+ MACInfo->phyBase = (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET); -+ MAC_state->irq = AR531X_IRQ_ENET0_INTRS; -+ } else { -+#ifndef CONFIG_AR5315 -+ MACInfo->macBase = (u32) (PHYS_TO_K1(AR531X_ENET1)+AE531X_MAC_OFFSET); -+ MACInfo->dmaBase = (u32) (PHYS_TO_K1(AR531X_ENET1)+AE531X_DMA_OFFSET); -+ if (ae531x_twisted_enet()) { -+ MACInfo->phyBase = (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET); -+ } else { -+ MACInfo->phyBase = (u32)(PHYS_TO_K1(AR531X_ENET1)+AE531X_PHY_OFFSET); -+ } -+ MAC_state->irq = AR531X_IRQ_ENET1_INTRS; -+#endif -+ } -+ -+ MACInfo->OSinfo = (void *)MAC_state; -+ -+ } -+ -+ LEAVE(); -+ return 0; -+} -+module_init(ae531x_MAC_setup); -+ -+/******************************************************************************* -+* ae531x_MAC_unload is the module unload function -+*/ -+static void __exit -+ae531x_MAC_unload(void) -+{ -+ int i; -+ -+ for (i=0;i<AR531X_NUM_ENET_MAC * AE531X_DEV_PER_MAC; i++) { -+ if (ae531x_MAC_dev[i] != NULL) { -+ if( (((ae531x_dev_sw_state_t *)ae531x_MAC_dev[i]->priv)->dev) != NULL) -+ ae531x_MAC_stop(ae531x_MAC_dev[i]); -+ ae531x_MAC_dev[i] = NULL; -+ } -+ } -+ MOD_DEC_USE_COUNT; -+} -+ -+MODULE_AUTHOR("Atheros Communications, Inc."); -+MODULE_DESCRIPTION("Support for Atheros WiSoC Ethernet device"); -+#ifdef MODULE_LICENSE -+MODULE_LICENSE("Atheros"); -+#endif -+module_exit(ae531x_MAC_unload); -diff -urN linux-mips-orig/drivers/net/ath/ae531xmac.c linux-mips-new/drivers/net/ath/ae531xmac.c ---- linux-mips-orig/drivers/net/ath/ae531xmac.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/ae531xmac.c 2005-12-31 12:33:57.673538824 +0000 -@@ -0,0 +1,951 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+ -+/* -+ * Ethernet driver for Atheros' ae531x ethernet MAC. -+ */ -+ -+#if linux -+#include <linux/config.h> -+#include <linux/types.h> -+#include <linux/delay.h> -+#include <linux/netdevice.h> -+#include <linux/etherdevice.h> -+#include <linux/init.h> -+#include <asm/io.h> -+ -+#include "ar531xlnx.h" -+#endif /* linux */ -+ -+#include "ae531xreg.h" -+#include "ae531xmac.h" -+ -+#ifdef DEBUG -+int ae531x_MAC_debug = AE531X_DEBUG_ERROR; -+#else -+int ae531x_MAC_debug = 0; -+#endif -+ -+extern char *ae531x_enet_mac_address_get(int); -+ -+/* Forward references to local functions */ -+static void ae531x_QueueDestroy(AE531X_QUEUE *q); -+ -+ -+/****************************************************************************** -+* -+* ae531x_ReadMacReg - read AE MAC register -+* -+* RETURNS: register value -+*/ -+UINT32 -+ae531x_ReadMacReg(ae531x_MAC_t *MACInfo, UINT32 reg) -+{ -+ UINT32 addr = MACInfo->macBase+reg; -+ UINT32 data; -+ -+ data = RegRead(addr); -+ return data; -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_WriteMacReg - write AE MAC register -+* -+* RETURNS: N/A -+*/ -+void -+ae531x_WriteMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data) -+{ -+ UINT32 addr = MACInfo->macBase+reg; -+ -+ RegWrite(data, addr); -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_SetMacReg - set bits in AE MAC register -+* -+* RETURNS: N/A -+*/ -+void -+ae531x_SetMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val) -+{ -+ UINT32 addr = MACInfo->macBase+reg; -+ UINT32 data = RegRead(addr); -+ -+ data |= val; -+ RegWrite(data, addr); -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_ClearMacReg - clear bits in AE MAC register -+* -+* RETURNS: N/A -+*/ -+void -+ae531x_ClearMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val) -+{ -+ UINT32 addr = MACInfo->macBase+reg; -+ UINT32 data = RegRead(addr); -+ -+ data &= ~val; -+ RegWrite(data, addr); -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_ReadDmaReg - read AE DMA register -+* -+* RETURNS: register value -+*/ -+UINT32 -+ae531x_ReadDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg) -+{ -+ UINT32 addr = MACInfo->dmaBase+reg; -+ UINT32 data = RegRead(addr); -+ -+ return data; -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_WriteDmaReg - write AE DMA register -+* -+* RETURNS: N/A -+*/ -+void -+ae531x_WriteDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data) -+{ -+ UINT32 addr = MACInfo->dmaBase+reg; -+ -+ RegWrite(data, addr); -+} -+ -+ -+/****************************************************************************** -+ * -+ * ae531x_AckIntr - clear interrupt bits in the status register. -+ * Note: Interrupt bits are *cleared* by writing a 1. -+ */ -+void -+ae531x_AckIntr(ae531x_MAC_t *MACInfo, UINT32 data) -+{ -+ ae531x_WriteDmaReg(MACInfo, DmaStatus, data); -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_SetDmaReg - set bits in an AE DMA register -+* -+* RETURNS: N/A -+*/ -+void -+ae531x_SetDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val) -+{ -+ UINT32 addr = MACInfo->dmaBase+reg; -+ UINT32 data = RegRead(addr); -+ -+ data |= val; -+ RegWrite(data, addr); -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_ClearDmaReg - clear bits in an AE DMA register -+* -+* RETURNS: N/A -+*/ -+void -+ae531x_ClearDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val) -+{ -+ UINT32 addr = MACInfo->dmaBase+reg; -+ UINT32 data = RegRead(addr); -+ -+ data &= ~val; -+ RegWrite(data, addr); -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_ReadMiiReg - read PHY registers via AE MAC Mii addr/data registers -+* -+* RETURNS: register value -+*/ -+UINT32 -+ae531x_ReadMiiReg(UINT32 phyBase, UINT32 reg) -+{ -+ UINT32 data; -+ UINT32 addr = phyBase+reg; -+ -+ data = RegRead(addr); -+ return data; -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_WriteMiiReg - write PHY registers via AE MAC Mii addr/data registers -+* -+* RETURNS: N/A -+*/ -+void -+ae531x_WriteMiiReg(UINT32 phyBase, UINT32 reg, UINT32 data) -+{ -+ UINT32 addr = phyBase+reg; -+ -+ RegWrite(data, addr); -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_MiiRead - read AE Mii register -+* -+* RETURNS: register value -+*/ -+UINT16 -+ae531x_MiiRead(UINT32 phyBase, UINT32 phyAddr, UINT8 reg) -+{ -+ UINT32 addr; -+ UINT16 data; -+ -+ addr = ((phyAddr << MiiDevShift) & MiiDevMask) | ((reg << MiiRegShift) & MiiRegMask); -+ -+ ae531x_WriteMiiReg(phyBase, MacMiiAddr, addr ); -+ do { -+ /* nop */ -+ } while ((ae531x_ReadMiiReg(phyBase, MacMiiAddr ) & MiiBusy) == MiiBusy); -+ -+ data = ae531x_ReadMiiReg(phyBase, MacMiiData) & 0xFFFF; -+ -+ return data; -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_MiiWrite - write AE Mii register -+* -+* RETURNS: N/A -+*/ -+void -+ae531x_MiiWrite(UINT32 phyBase, UINT32 phyAddr, UINT8 reg, UINT16 data) -+{ -+ UINT32 addr; -+ -+ ae531x_WriteMiiReg(phyBase, MacMiiData, data ); -+ -+ addr = ((phyAddr << MiiDevShift) & MiiDevMask) | -+ ((reg << MiiRegShift) & MiiRegMask) | MiiWrite; -+ ae531x_WriteMiiReg(phyBase, MacMiiAddr, addr ); -+ -+ do { -+ /* nop */ -+ } while ((ae531x_ReadMiiReg(phyBase, MacMiiAddr ) & MiiBusy) == MiiBusy); -+} -+ -+ -+/******************************************************************************* -+* ae531x_BeginResetMode - enter a special "reset mode" in which -+* -no interrupts are expected from the device -+* -the device will not transmit nor receive -+* -attempts to send or receive will return with an error and -+* -the device will be reset at the next convenient opportunity. -+*/ -+void -+ae531x_BeginResetMode(ae531x_MAC_t *MACInfo) -+{ -+ /* Set the reset flag */ -+ MACInfo->aeProcessRst = 1; -+} -+ -+ -+/******************************************************************************* -+* ae531x_EndResetMode - exit the special "reset mode" entered -+* earlier via a call to ae531x_BeginResetMode. -+*/ -+void -+ae531x_EndResetMode(ae531x_MAC_t *MACInfo) -+{ -+ MACInfo->aeProcessRst = 0; -+} -+ -+ -+/******************************************************************************* -+* ae531x_IsInResetMode - determine whether or not the device is -+* currently in "reset mode" (i.e. that a device reset is pending) -+*/ -+BOOL -+ae531x_IsInResetMode(ae531x_MAC_t *MACInfo) -+{ -+ return MACInfo->aeProcessRst; -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_DmaRxStart - Start Rx -+* -+* RETURNS: N/A -+*/ -+static void -+ae531x_DmaRxStart(ae531x_MAC_t *MACInfo) -+{ -+ ae531x_SetDmaReg(MACInfo, DmaControl, DmaRxStart); -+ sysWbFlush(); -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_DmaRxStop - Stop Rx -+* -+* RETURNS: N/A -+*/ -+void -+ae531x_DmaRxStop(ae531x_MAC_t *MACInfo) -+{ -+ ae531x_ClearDmaReg(MACInfo, DmaControl, DmaRxStart); -+ sysWbFlush(); -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_DmaTxStart - Start Tx -+* -+* RETURNS: N/A -+*/ -+void -+ae531x_DmaTxStart(ae531x_MAC_t *MACInfo) -+{ -+ ae531x_SetDmaReg(MACInfo, DmaControl, DmaTxStart); -+ sysWbFlush(); -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_DmaTxStop - Stop Tx -+* -+* RETURNS: N/A -+*/ -+void -+ae531x_DmaTxStop(ae531x_MAC_t *MACInfo) -+{ -+ ae531x_ClearDmaReg(MACInfo, DmaControl, DmaTxStart); -+ sysWbFlush(); -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_DmaIntEnable - Enable DMA interrupts -+* -+* RETURNS: N/A -+*/ -+void -+ae531x_DmaIntEnable(ae531x_MAC_t *MACInfo) -+{ -+ ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntEnable); -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_DmaIntDisable - Disable DMA interrupts -+* -+* RETURNS: N/A -+*/ -+void -+ae531x_DmaIntDisable(ae531x_MAC_t *MACInfo) -+{ -+ ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntDisable); -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_DmaIntClear - Clear DMA interrupts -+* -+* RETURNS: N/A -+*/ -+static void -+ae531x_DmaIntClear(ae531x_MAC_t *MACInfo) -+{ -+ /* clear all interrupt requests */ -+ ae531x_WriteDmaReg(MACInfo, DmaStatus, -+ ae531x_ReadDmaReg(MACInfo, DmaStatus)); -+} -+ -+ -+/****************************************************************************** -+* Initialize generic queue data -+*/ -+void -+ae531x_QueueInit(AE531X_QUEUE *q, char *pMem, int count) -+{ -+ ARRIVE(); -+ q->firstDescAddr = pMem; -+ q->lastDescAddr = (VIRT_ADDR)((UINT32)q->firstDescAddr + -+ (count - 1) * AE531X_QUEUE_ELE_SIZE); -+ q->curDescAddr = q->firstDescAddr; -+ q->count = count; -+ LEAVE(); -+} -+ -+ -+/****************************************************************************** -+* ae531x_TxQueueCreate - create a circular queue of descriptors for Transmit -+*/ -+static int -+ae531x_TxQueueCreate(ae531x_MAC_t *MACInfo, -+ AE531X_QUEUE *q, -+ char *pMem, -+ int count) -+{ -+ int i; -+ VIRT_ADDR descAddr; -+ -+ ARRIVE(); -+ -+ ae531x_QueueInit(q, pMem, count); -+ q->reapDescAddr = q->lastDescAddr; -+ -+ /* Initialize Tx buffer descriptors. */ -+ for (i=0, descAddr=q->firstDescAddr; -+ i<count; -+ i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE)) -+ { -+ /* Update the size, BUFPTR, and SWPTR fields */ -+ -+ AE531X_DESC_STATUS_SET(descAddr, 0); -+ AE531X_DESC_CTRLEN_SET(descAddr, 0); -+ -+ AE531X_DESC_BUFPTR_SET(descAddr, (UINT32)0); -+ AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0); -+ AE531X_DESC_SWPTR_SET(descAddr, (void *)0); -+ } /* for each desc */ -+ -+ /* Make the queue circular */ -+ AE531X_DESC_CTRLEN_SET(q->lastDescAddr, -+ DescEndOfRing|AE531X_DESC_CTRLEN_GET(q->lastDescAddr)); -+ -+ AE531X_PRINT(AE531X_DEBUG_RESET, -+ ("ethmac%d Txbuf begin = %x, end = %x\n", -+ MACInfo->unit, -+ (UINT32)q->firstDescAddr, -+ (UINT32)q->lastDescAddr)); -+ -+ LEAVE(); -+ return 0; -+} -+ -+ -+/****************************************************************************** -+* ae531x_RxQueueCreate - create a circular queue of Rx descriptors -+*/ -+int -+ae531x_RxQueueCreate(ae531x_MAC_t *MACInfo, -+ AE531X_QUEUE *q, -+ char *pMem, -+ int count) -+{ -+ int i; -+ VIRT_ADDR descAddr; -+ -+ ARRIVE(); -+ -+ ae531x_QueueInit(q, pMem, count); -+ q->reapDescAddr = NULL; -+ -+ -+ /* Initialize Rx buffer descriptors */ -+ for (i=0, descAddr=q->firstDescAddr; -+ i<count; -+ i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE)) -+ { -+ void *swptr; -+ char *rxBuffer; -+ int rxBufferSize; -+ -+ swptr = ae531x_rxbuf_alloc(MACInfo, &rxBuffer, &rxBufferSize); -+ if (swptr == NULL) { -+ AE531X_PRINT(AE531X_DEBUG_RESET, -+ ("ethmac%d RX queue: ae531x_rxbuf_alloc failed\n", -+ MACInfo->unit)); -+ ae531x_QueueDestroy(q); -+ return -1; -+ } -+ AE531X_DESC_SWPTR_SET(descAddr, swptr); -+ -+ AE531X_DESC_STATUS_SET(descAddr, DescOwnByDma); -+ AE531X_DESC_CTRLEN_SET(descAddr, rxBufferSize); -+ AE531X_DESC_BUFPTR_SET(descAddr, virt_to_bus(rxBuffer)); -+ AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0); -+ } /* for each desc */ -+ -+ /* Make the queue circular */ -+ AE531X_DESC_CTRLEN_SET(q->lastDescAddr, -+ DescEndOfRing|AE531X_DESC_CTRLEN_GET(q->lastDescAddr)); -+ -+ AE531X_PRINT(AE531X_DEBUG_RESET, -+ ("ethmac%d Rxbuf begin = %x, end = %x\n", -+ MACInfo->unit, -+ (UINT32)q->firstDescAddr, -+ (UINT32)q->lastDescAddr)); -+ -+ LEAVE(); -+ return 0; -+} -+ -+ -+/****************************************************************************** -+* ae531x_QueueDestroy -- Free all buffers and descriptors associated -+* with a queue. -+*/ -+static void -+ae531x_QueueDestroy(AE531X_QUEUE *q) -+{ -+ int i; -+ int count; -+ VIRT_ADDR descAddr; -+ -+ ARRIVE(); -+ -+ count = q->count; -+ -+ for (i=0, descAddr=q->firstDescAddr; -+ i<count; -+ i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE)) { -+ -+ AE531X_DESC_STATUS_SET(descAddr, 0); -+ AE531X_DESC_CTRLEN_SET(descAddr, 0); -+ AE531X_DESC_BUFPTR_SET(descAddr, (UINT32)0); -+ AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0); -+ -+ ae531x_swptr_free(descAddr); /* Free OS-specific software pointer */ -+ } -+ -+ LEAVE(); -+} -+ -+static void -+ae531x_TxQueueDestroy(ae531x_MAC_t *MACInfo) -+{ -+ ae531x_QueueDestroy(&MACInfo->txQueue); -+} -+ -+static void -+ae531x_RxQueueDestroy(ae531x_MAC_t *MACInfo) -+{ -+ ae531x_QueueDestroy(&MACInfo->rxQueue); -+} -+ -+ -+/****************************************************************************** -+* ae531x_AllocateQueues - Allocate receive and transmit queues -+*/ -+int -+ae531x_AllocateQueues(ae531x_MAC_t *MACInfo) -+{ -+ size_t QMemSize; -+ char *pTxBuf = NULL; -+ char *pRxBuf = NULL; -+ -+ ARRIVE(); -+ -+ MACInfo->txDescCount = AE531X_TX_DESC_COUNT_DEFAULT; -+ QMemSize = AE531X_QUEUE_ELE_SIZE * MACInfo->txDescCount; -+ pTxBuf = MALLOC(QMemSize); -+ if (pTxBuf == NULL) { -+ AE531X_PRINT(AE531X_DEBUG_RESET, -+ ("ethmac%d Failed to allocate TX queue\n", MACInfo->unit)); -+ goto AllocQFail; -+ } -+ -+ if (ae531x_TxQueueCreate(MACInfo, &MACInfo->txQueue, pTxBuf, -+ MACInfo->txDescCount) < 0) -+ { -+ AE531X_PRINT(AE531X_DEBUG_RESET, -+ ("ethmac%d Failed to create TX queue\n", MACInfo->unit)); -+ goto AllocQFail; -+ } -+ -+ MACInfo->rxDescCount = AE531X_RX_DESC_COUNT_DEFAULT; -+ QMemSize = AE531X_QUEUE_ELE_SIZE * MACInfo->rxDescCount; -+ pRxBuf = MALLOC(QMemSize); -+ if (pRxBuf == NULL) { -+ AE531X_PRINT(AE531X_DEBUG_RESET, -+ ("ethmac%d Failed to allocate RX queue\n", MACInfo->unit)); -+ goto AllocQFail; -+ } -+ -+ if (ae531x_RxQueueCreate(MACInfo, &MACInfo->rxQueue, pRxBuf, -+ MACInfo->rxDescCount) < 0) -+ { -+ AE531X_PRINT(AE531X_DEBUG_RESET, -+ ("ethmac%d Failed to create RX queue\n", MACInfo->unit)); -+ goto AllocQFail; -+ } -+ -+ AE531X_PRINT(AE531X_DEBUG_RESET, -+ ("ethmac%d Memory setup complete.\n", MACInfo->unit)); -+ -+ LEAVE(); -+ return 0; -+ -+AllocQFail: -+ MACInfo->txDescCount = 0; /* sanity */ -+ MACInfo->rxDescCount = 0; /* sanity */ -+ -+ if (pTxBuf) { -+ FREE(pTxBuf); -+ } -+ if (pRxBuf) { -+ FREE(pRxBuf); -+ } -+ -+ LEAVE(); -+ return -1; -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_FreeQueues - Free Transmit & Receive queues -+*/ -+void -+ae531x_FreeQueues(ae531x_MAC_t *MACInfo) -+{ -+ ae531x_TxQueueDestroy(MACInfo); -+ FREE(MACInfo->txQueue.firstDescAddr); -+ -+ ae531x_RxQueueDestroy(MACInfo); -+ FREE(MACInfo->rxQueue.firstDescAddr); -+} -+ -+/****************************************************************************** -+* -+* ae531x_DmaReset - Reset DMA and TLI controllers -+* -+* RETURNS: N/A -+*/ -+void -+ae531x_DmaReset(ae531x_MAC_t *MACInfo) -+{ -+ int i; -+ UINT32 descAddr; -+ -+ ARRIVE(); -+ -+ /* Disable device interrupts prior to any errors during stop */ -+ intDisable(MACInfo->ilevel); -+ -+ /* Disable MAC rx and tx */ -+ ae531x_ClearMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable)); -+ -+ udelay(1); -+ -+ /* Reset dma controller */ -+ -+ ae531x_WriteDmaReg(MACInfo, DmaBusMode, DmaResetOn); -+ -+ /* Delay 2 usec */ -+ sysUDelay(2); -+ -+ /* Flush the rx queue */ -+ descAddr = (UINT32)MACInfo->rxQueue.firstDescAddr; -+ MACInfo->rxQueue.curDescAddr = MACInfo->rxQueue.firstDescAddr; -+ for (i=0; -+ i<(MACInfo->rxDescCount); -+ i++, descAddr += AE531X_QUEUE_ELE_SIZE) { -+ AE531X_DESC_STATUS_SET(descAddr, DescOwnByDma); -+ } -+ -+ /* Flush the tx queue */ -+ descAddr = (UINT32)MACInfo->txQueue.firstDescAddr; -+ MACInfo->txQueue.curDescAddr = MACInfo->txQueue.firstDescAddr; -+ MACInfo->txQueue.reapDescAddr = MACInfo->txQueue.lastDescAddr; -+ for (i=0; -+ i<(MACInfo->txDescCount); -+ i++, descAddr += AE531X_QUEUE_ELE_SIZE) { -+ AE531X_DESC_STATUS_SET (descAddr, 0); -+ } -+ -+ /* Set init register values */ -+ ae531x_WriteDmaReg(MACInfo, DmaBusMode, DmaBusModeInit); -+ -+ /* Install the first Tx and Rx queues on the device */ -+ ae531x_WriteDmaReg(MACInfo, DmaRxBaseAddr, -+ virt_to_bus(MACInfo->rxQueue.firstDescAddr)); -+ ae531x_WriteDmaReg(MACInfo, DmaTxBaseAddr, -+ virt_to_bus(MACInfo->txQueue.firstDescAddr)); -+ -+ -+ ae531x_WriteDmaReg(MACInfo, DmaControl, DmaStoreAndForward); -+ -+ ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntDisable); -+ -+ AE531X_PRINT(AE531X_DEBUG_RESET, -+ ("ethmac%d: DMA RESET!\n", MACInfo->unit)); -+ -+ /* Turn on device interrupts -- enable most errors */ -+ ae531x_DmaIntClear(MACInfo); /* clear interrupt requests */ -+ ae531x_DmaIntEnable(MACInfo); /* enable interrupts */ -+ -+ ae531x_EndResetMode(MACInfo); -+ -+ intEnable(MACInfo->ilevel); -+ -+ LEAVE(); -+} -+ -+ -+/****************************************************************************** -+* -+* ae531x_MACAddressSet - Set the ethernet address -+* -+* Sets the ethernet address according to settings in flash. -+* -+* RETURNS: void -+*/ -+static void -+ae531x_MACAddressSet(ae531x_MAC_t *MACInfo) -+{ -+ unsigned int data; -+ UINT8 *macAddr; -+ -+ ARRIVE(); -+ -+ macAddr = ae531x_enet_mac_address_get(MACInfo->unit); -+ -+ /* set our MAC address */ -+ data = (macAddr[5]<<8) | macAddr[4]; -+ ae531x_WriteMacReg(MACInfo, MacAddrHigh, data ); -+ -+ data = (macAddr[3]<<24) | (macAddr[2]<<16) | (macAddr[1]<<8) | macAddr[0]; -+ ae531x_WriteMacReg(MACInfo, MacAddrLow, data ); -+ -+ AE531X_PRINT(AE531X_DEBUG_RESET, -+ ("ethmac%d Verify MAC address %8.8X %8.8X \n", -+ MACInfo->unit, -+ ae531x_ReadMacReg(MACInfo, MacAddrLow), -+ ae531x_ReadMacReg(MACInfo, MacAddrHigh))); -+ -+ AE531X_PRINT(AE531X_DEBUG_RESET, -+ (" sb = %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", -+ 0xff&macAddr[0], -+ 0xff&macAddr[1], -+ 0xff&macAddr[2], -+ 0xff&macAddr[3], -+ 0xff&macAddr[4], -+ 0xff&macAddr[5])); -+ LEAVE(); -+} -+ -+ -+/****************************************************************************** -+* -+* ae_SetMACFromPhy - read Phy settings and update Mac -+* with current duplex and speed. -+* -+* RETURNS: -+*/ -+static void -+ae531x_SetMACFromPhy(ae531x_MAC_t *MACInfo) -+{ -+ UINT32 macCtl; -+ BOOL fullDuplex; -+ UINT32 timeout; -+ -+ ARRIVE(); -+ -+ timeout = jiffies+(HZ/1000)*AE531X_NEGOT_TIMEOUT; -+ -+ /* Get duplex mode from Phy */ -+ while (((fullDuplex = phyIsFullDuplex(MACInfo->unit)) == -1) && -+ (jiffies <= timeout)); -+ -+ /* Flag is set for full duplex mode, else cleared */ -+ macCtl = ae531x_ReadMacReg(MACInfo, MacControl); -+ -+ if (fullDuplex) { -+ /* set values of control registers */ -+ macCtl &= ~MacDisableRxOwn; -+ macCtl |= MacFullDuplex; -+ ae531x_WriteMacReg(MACInfo, MacControl, macCtl); -+ ae531x_WriteMacReg(MACInfo, MacFlowControl, MacFlowControlInitFdx); -+ } else { -+ /* set values of control registers */ -+ ae531x_WriteMacReg(MACInfo, MacFlowControl, MacFlowControlInitHdx); -+ macCtl |= MacDisableRxOwn; -+ macCtl &= ~MacFullDuplex; -+ ae531x_WriteMacReg(MACInfo, MacControl, macCtl); -+ } -+ -+ LEAVE(); -+} -+ -+ -+/****************************************************************************** -+* ae531x_MACReset -- sets MAC address and duplex. -+*/ -+void -+ae531x_MACReset(ae531x_MAC_t *MACInfo) -+{ -+ ae531x_MACAddressSet(MACInfo); -+#ifndef CONFIG_AR5315 -+ ae531x_SetMACFromPhy(MACInfo); -+#endif -+} -+ -+ -+/****************************************************************************** -+* ae531x_EnableComm -- enable Transmit and Receive -+*/ -+void -+ae531x_EnableComm(ae531x_MAC_t *MACInfo) -+{ -+ ae531x_SetMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable)); -+ ae531x_DmaRxStart(MACInfo); /* start receiver */ -+ ae531x_DmaTxStart(MACInfo); /* start transmitter */ -+} -+ -+ -+/****************************************************************************** -+* ae531x_DisableComm -- disable Transmit and Receive -+*/ -+void -+ae531x_DisableComm(ae531x_MAC_t *MACInfo) -+{ -+ ae531x_ClearMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable)); -+} -+ -+ -+/****************************************************************************** -+* ae531x_reset -- Cold reset ethernet interface -+*/ -+void -+ae531x_reset(ae531x_MAC_t *MACInfo) -+{ -+ UINT32 mask = 0; -+ UINT32 regtmp; -+#ifndef CONFIG_AR5315 -+ -+ if (MACInfo->unit == 0) { -+ mask = AR531X_RESET_ENET0 | AR531X_RESET_EPHY0; -+ } else { -+ mask = AR531X_RESET_ENET1 | AR531X_RESET_EPHY1; -+ } -+ -+ /* Put into reset */ -+ regtmp = sysRegRead(AR531X_RESET); -+ sysRegWrite(AR531X_RESET, regtmp | mask); -+ sysMsDelay(15); -+ -+ /* Pull out of reset */ -+ regtmp = sysRegRead(AR531X_RESET); -+ sysRegWrite(AR531X_RESET, regtmp & ~mask); -+ sysUDelay(25); -+ -+ /* Enable */ -+ if (MACInfo->unit == 0) { -+ mask = AR531X_ENABLE_ENET0; -+ } else { -+ mask = AR531X_ENABLE_ENET1; -+ } -+ regtmp = sysRegRead(AR531X_ENABLE); -+ sysRegWrite(AR531X_ENABLE, regtmp | mask); -+#else -+ if (MACInfo->unit == 0) { -+ mask = AR531X_RESET_ENET0 | AR531X_RESET_EPHY0; -+ } -+ /* Enable Arbitration for Ethernet bus */ -+ regtmp = sysRegRead(AR531XPLUS_AHB_ARB_CTL); -+ regtmp |= ARB_ETHERNET; -+ sysRegWrite(AR531XPLUS_AHB_ARB_CTL, regtmp); -+ -+ /* Put into reset */ -+ regtmp = sysRegRead(AR531X_RESET); -+ sysRegWrite(AR531X_RESET, regtmp | mask); -+ sysMsDelay(10); -+ -+ /* Pull out of reset */ -+ regtmp = sysRegRead(AR531X_RESET); -+ sysRegWrite(AR531X_RESET, regtmp & ~mask); -+ sysMsDelay(10); -+ -+ regtmp = sysRegRead(AR531XPLUS_IF_CTL); -+ regtmp |= IF_TS_LOCAL; -+ sysRegWrite(AR531XPLUS_IF_CTL, regtmp); -+#endif -+} -+ -+ -+/****************************************************************************** -+* ae531x_unitLinkLost -- Called from PHY layer to notify the MAC layer -+* that there are no longer any live links associated with a MAC. -+*/ -+void -+ae531x_unitLinkLost(int ethUnit) -+{ -+ AE531X_PRINT(AE531X_DEBUG_LINK_CHANGE, -+ ("enetmac%d link down\n", ethUnit)); -+} -+ -+ -+/****************************************************************************** -+* ae531x_unitLinkGained -- Called from PHY layer to notify the MAC layer -+* that there are 1 or more live links associated with a MAC. -+*/ -+void -+ae531x_unitLinkGained(int ethUnit) -+{ -+#if CONFIG_AR5315 -+#define AE531X_POLL_MILLI_SECONDS 200 -+ ae531x_MAC_t *MACInfo = ae531x_getMAcInfo(ethUnit); -+ while(!MACInfo || !MACInfo->port_is_up) -+ { -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ schedule_timeout((AE531X_POLL_MILLI_SECONDS * HZ)/1000); -+ MACInfo = ae531x_getMAcInfo(ethUnit); -+ } -+ ae531x_SetMACFromPhy(MACInfo); -+#endif -+ AE531X_PRINT(AE531X_DEBUG_LINK_CHANGE, -+ ("enet%d link up\n", ethUnit)); -+} -+ -+/****************************************************************************** -+* ae531x_ethMacDefault -- Called from PHY layer to determine the default -+* ethernet MAC. On some "twisted" platforms, the only usable MAC is 1, -+* while on others the usable MAC is 0. Future boards may allow both MACs -+* to be used; in this case, return -1 to indicate that there IS NO default -+* MAC. -+*/ -+int -+ae531x_ethMacDefault(void) -+{ -+ if (ae531x_twisted_enet()) -+ return 1; -+ -+ return 0; -+ -+} -diff -urN linux-mips-orig/drivers/net/ath/ae531xmac.h linux-mips-new/drivers/net/ath/ae531xmac.h ---- linux-mips-orig/drivers/net/ath/ae531xmac.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/ae531xmac.h 2005-12-31 12:33:57.674538672 +0000 -@@ -0,0 +1,229 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * See README to understand the decomposition of the ethernet driver. -+ * -+ * This file contains OS-independent pure software definitions for -+ * ethernet support on the AR531X platform. -+ */ -+ -+#ifndef _AE531XMAC_H_ -+#define _AE531XMAC_H_ -+ -+#include <linux/config.h> -+#include <linux/module.h> -+ -+/* -+ * DEBUG switches to control verbosity. -+ * Just modify the value of ae531x_MAC_debug. -+ */ -+#define AE531X_DEBUG_ALL 0xffffffff -+#define AE531X_DEBUG_ERROR 0x00000001 /* Unusual conditions and Errors */ -+#define AE531X_DEBUG_ARRIVE 0x00000002 /* Arrive into a function */ -+#define AE531X_DEBUG_LEAVE 0x00000004 /* Leave a function */ -+#define AE531X_DEBUG_RESET 0x00000008 /* Reset */ -+#define AE531X_DEBUG_TX 0x00000010 /* Transmit */ -+#define AE531X_DEBUG_TX_REAP 0x00000020 /* Transmit Descriptor Reaping */ -+#define AE531X_DEBUG_RX 0x00000040 /* Receive */ -+#define AE531X_DEBUG_RX_STOP 0x00000080 /* Receive Early Stop */ -+#define AE531X_DEBUG_INT 0x00000100 /* Interrupts */ -+#define AE531X_DEBUG_LINK_CHANGE 0x00000200 /* PHY Link status changed */ -+ -+#define AE531X_NEGOT_TIMEOUT 500 /* ms to wait for autonegotiation */ -+ -+extern int ae531x_MAC_debug; -+ -+#define AE531X_PRINT(FLG, X) \ -+{ \ -+ if (ae531x_MAC_debug & (FLG)) { \ -+ DEBUG_PRINTF("%s#%d:%s ", \ -+ __FILE__, \ -+ __LINE__, \ -+ __FUNCTION__); \ -+ DEBUG_PRINTF X; \ -+ } \ -+} -+ -+#define ARRIVE() AE531X_PRINT(AE531X_DEBUG_ARRIVE, ("Arrive{\n")) -+#define LEAVE() AE531X_PRINT(AE531X_DEBUG_LEAVE, ("}Leave\n")) -+ -+#define RegRead(addr) \ -+ (*(volatile unsigned int *)(addr)) -+ -+#define RegWrite(val,addr) \ -+ ((*(volatile unsigned int *)(addr)) = (val)) -+ -+/***************************************************************** -+ * Phy code is broken out into a separate layer, so that different -+ * PHY hardware can easily be supported. -+ * -+ * These functions are provided by the PHY layer for use by the MAC layer. -+ * phySetup -- Set phy hardware appropriately for a MAC unit -+ * -+ * phyCheckStatusChange -- Look for dropped/initiated links on any -+ * phy port associated with a MAC unit -+ * -+ * phyIsSpeed100 -- Determines whether or not a PHY is up and -+ * running at 100Mbit -+ * -+ * phyIsFullDuplex -- Determines whether or not a PHY is up and -+ * running in Full Duplex mode -+ * -+ */ -+#if CONFIG_MARVELL_ENET_PHY -+/* -+ * Mapping of generic phy APIs to Marvell Ethernet Switch phy functions. -+ */ -+#include "mvPhy.h" -+#define phySetup(ethUnit, phyBase) mv_phySetup((ethUnit), (phyBase)) -+#define phyCheckStatusChange(ethUnit) mv_phyCheckStatusChange(ethUnit) -+#define phyIsSpeed100(ethUnit) mv_phyIsSpeed100(ethUnit) -+#define phyIsFullDuplex(ethUnit) mv_phyIsFullDuplex(ethUnit) -+ -+#if CONFIG_VENETDEV -+#define PHY_TRAILER_SIZE MV_PHY_TRAILER_SIZE -+extern void mv_phyDetermineSource(char *data, int len, int *pFromLAN); -+extern void mv_phySetDestinationPort(char *data, int len, int fromLAN); -+#define phyDetermineSource(data, len, pFromLAN) mv_phyDetermineSource((data), (len), (pFromLAN)) -+#define phySetDestinationPort(data, len, fromLAN) mv_phySetDestinationPort((data), (len), (fromLAN)) -+#else -+#define PHY_TRAILER_SIZE 0 -+#endif -+#endif /* CONFIG_MARVELL_ENET_PHY */ -+ -+#if CONFIG_KENDIN_ENET_PHY || CONFIG_REALTEK_ENET_PHY || CONFIG_KENDIN_KS8995XA_ENET_PHY -+/* -+ * Mapping of generic phy APIs to Kendin KS8721B and RealTek RTL8201BL phys. -+ */ -+#include "rtPhy.h" -+#define phySetup(ethUnit, phyBase) rt_phySetup((ethUnit), (phyBase)) -+#define phyCheckStatusChange(ethUnit) rt_phyCheckStatusChange(ethUnit) -+#define phyIsSpeed100(ethUnit) rt_phyIsSpeed100(ethUnit) -+#define phyIsFullDuplex(ethUnit) rt_phyIsFullDuplex(ethUnit) -+#endif -+ -+#if CONFIG_ICPLUS_ENET_PHY -+/* -+ * Mapping of generic phy APIs to Icplus phys. -+ */ -+#include "ipPhy.h" -+#define phySetup(ethUnit, phyBase) ip_phySetup((ethUnit), (phyBase)) -+#define phyCheckStatusChange(ethUnit) ip_phyCheckStatusChange(ethUnit) -+#define phyIsSpeed100(ethUnit) ip_phyIsSpeed100(ethUnit) -+#define phyIsFullDuplex(ethUnit) ip_phyIsFullDuplex(ethUnit) -+#endif -+ -+#if !defined(PHY_TRAILER_SIZE) -+#define PHY_TRAILER_SIZE 0 -+#endif -+ -+/***************************************************************** -+ * MAC-independent interface to be used by PHY code -+ * -+ * These functions are provided by the MAC layer for use by the PHY layer. -+ */ -+#define phyRegRead ae531x_MiiRead -+#define phyRegWrite ae531x_MiiWrite -+#define phyLinkLost(ethUnit) ae531x_unitLinkLost(ethUnit) -+#define phyLinkGained(ethUnit) ae531x_unitLinkGained(ethUnit) -+#define phyEthMacDefault() ae531x_ethMacDefault() -+ -+void ae531x_unitLinkLost(int unit); -+void ae531x_unitLinkGained(int unit); -+int ae531x_ethMacDefault(void); -+ -+ -+/* -+ * RXBUFF_RESERVE enables building header on WLAN-side in place -+ * NB: Divisible by 2 but NOT 4. Otherwise handle_adel_int() will -+ * be used by the ip layer for misaligned word accesses and -+ * performance will suffer - a lot. -+ */ -+#define ETH_CRC_LEN 4 -+#define RXBUFF_RESERVE 98 -+// #define RXBUFF_RESERVE 98 -+ -+/***************************************************************** -+ * Descriptor queue -+ */ -+typedef struct ae531x_queue { -+ VIRT_ADDR firstDescAddr; /* descriptor array address */ -+ VIRT_ADDR lastDescAddr; /* last descriptor address */ -+ VIRT_ADDR curDescAddr; /* current descriptor address */ -+ VIRT_ADDR reapDescAddr; /* current tail of tx descriptors reaped */ -+ UINT16 count; /* number of elements */ -+} AE531X_QUEUE; -+ -+/* Given a descriptor, return the next one in a circular list */ -+#define AE531X_QUEUE_ELE_NEXT_GET(q, descAddr) \ -+ ((descAddr) == (q)->lastDescAddr) ? (q)->firstDescAddr : \ -+ (VIRT_ADDR)((UINT32)(descAddr) + AE531X_QUEUE_ELE_SIZE) -+ -+/* Move the "current descriptor" forward to the next one */ -+#define AE531X_CONSUME_DESC(q) \ -+ q->curDescAddr = AE531X_QUEUE_ELE_NEXT_GET(q, q->curDescAddr) -+ -+/***************************************************************** -+ * Per-ethernet-MAC OS-independent information -+ */ -+typedef struct ae531x_MAC_s { -+ u32 unit; /* MAC unit ID */ -+ u32 macBase; /* MAC base address */ -+ u32 dmaBase; /* DMA base address */ -+ u32 phyBase; /* PHY base address */ -+ AE531X_QUEUE txQueue; /* Transmit descriptor queue */ -+ AE531X_QUEUE rxQueue; /* Receive descriptor queue */ -+ UINT16 txDescCount; /* Transmit descriptor count */ -+ UINT16 rxDescCount; /* Receive descriptor count */ -+ BOOL aeProcessRst; /* flag to indicate reset in progress */ -+ BOOL port_is_up; /* flag to indicate port is up */ -+ void *OSinfo; /* OS-dependent data */ -+} ae531x_MAC_t; -+ -+#define AE531X_TX_DESC_COUNT_DEFAULT 128 /* Transmit descriptors */ -+#define AE531X_RX_DESC_COUNT_DEFAULT 128 /* Receive descriptors */ -+ -+ -+/***************************************************************** -+ * Interfaces exported by the OS-independent MAC layer -+ */ -+void ae531x_BeginResetMode(ae531x_MAC_t *MACInfo); -+void ae531x_EndResetMode(ae531x_MAC_t *MACInfo); -+BOOL ae531x_IsInResetMode(ae531x_MAC_t *MACInfo); -+int ae531x_RxQueueCreate(ae531x_MAC_t *MACInfo, AE531X_QUEUE *q, -+ char *pMem, int count); -+int ae531x_QueueDelete(struct ae531x_queue *q); -+void ae531x_DmaReset(ae531x_MAC_t *MACInfo); -+void ae531x_MACReset(ae531x_MAC_t *MACInfo); -+void ae531x_EnableComm(ae531x_MAC_t *MACInfo); -+void ae531x_DisableComm(ae531x_MAC_t *MACInfo); -+void ae531x_reset(ae531x_MAC_t *MACInfo); -+int ae531x_AllocateQueues(ae531x_MAC_t *MACInfo); -+void ae531x_FreeQueues(ae531x_MAC_t *MACInfo); -+void ae531x_QueueInit(AE531X_QUEUE *q, char *pMem, int count); -+UINT32 ae531x_ReadMacReg(ae531x_MAC_t *MACInfo, UINT32 reg); -+void ae531x_WriteMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data); -+void ae531x_SetMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val); -+void ae531x_ClearMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val); -+void ae531x_SetDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val); -+void ae531x_ClearDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val); -+UINT32 ae531x_ReadDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg); -+void ae531x_WriteDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data); -+UINT32 ae531x_ReadMiiReg(UINT32 phyBase, UINT32 reg); -+void ae531x_WriteMiiReg(UINT32 phyBase, UINT32 reg, UINT32 data); -+UINT16 ae531x_MiiRead(UINT32 phyBase, UINT32 phyAddr, UINT8 reg); -+void ae531x_MiiWrite(UINT32 phyBase, UINT32 phyAddr, UINT8 reg, UINT16 data); -+void ae531x_DmaIntEnable(ae531x_MAC_t *MACInfo); -+void ae531x_DmaIntDisable(ae531x_MAC_t *MACInfo); -+void ae531x_AckIntr(ae531x_MAC_t *MACInfo, UINT32 val); -+void *ae531x_rxbuf_alloc(ae531x_MAC_t *MACInfo, char **rxBptr, int *rxBSize); -+void ae531x_swptr_free(VIRT_ADDR txDesc); -+BOOL ae531x_twisted_enet(void); -+ -+#endif /* _AE531XMAC_H_ */ -diff -urN linux-mips-orig/drivers/net/ath/ae531xreg.h linux-mips-new/drivers/net/ath/ae531xreg.h ---- linux-mips-orig/drivers/net/ath/ae531xreg.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/ae531xreg.h 2005-12-31 12:33:57.675538520 +0000 -@@ -0,0 +1,439 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * See README to understand the decomposition of the ethernet driver. -+ * -+ * Register definitions for Atheros AR531X Ethernet MAC. -+ */ -+ -+#ifndef _AE531XREG_H_ -+#define _AE531XREG_H_ -+ -+#define AE531X_MAC_OFFSET 0x0000 -+#define AE531X_PHY_OFFSET 0x0000 /* Same as MAC offset */ -+#define AE531X_DMA_OFFSET 0x1000 -+ -+/***********************************************************/ -+/* MAC110 registers, base address is BAR+AE531X_MAC_OFFSET */ -+/***********************************************************/ -+#define MacControl 0x00 /* control */ -+#define MacAddrHigh 0x04 /* address high */ -+#define MacAddrLow 0x08 /* address low */ -+#define MacMultiHashHigh 0x0C /* multicast hash table high */ -+#define MacMultiHashLow 0x10 /* multicast hash table low */ -+#define MacMiiAddr 0x14 /* MII address */ -+#define MacMiiData 0x18 /* MII data */ -+#define MacFlowControl 0x1C /* Flow control */ -+#define MacVlan1Tag 0x4C /* VLAN1 tag */ -+#define MacVlan2Tag 0x50 /* VLAN2 tag */ -+ -+ -+/***************************************************************/ -+/* DMA engine registers, base address is BAR+AE531X_DMA_OFFSET */ -+/***************************************************************/ -+#define DmaBusMode 0x00 /* CSR0 - Bus Mode */ -+#define DmaTxPollDemand 0x04 /* CSR1 - Transmit Poll Demand */ -+#define DmaRxPollDemand 0x08 /* CSR2 - Receive Poll Demand */ -+#define DmaRxBaseAddr 0x0C /* CSR3 - Receive list base address */ -+#define DmaTxBaseAddr 0x10 /* CSR4 - Transmit list base address */ -+#define DmaStatus 0x14 /* CSR5 - Dma status */ -+#define DmaControl 0x18 /* CSR6 - Dma control */ -+#define DmaIntrEnb 0x1C /* CSR7 - Interrupt enable */ -+#define DmaOverflowCnt 0x20 /* CSR8 - Missed Frame and Buff Overflow counter */ -+#define DmaTxCurrAddr 0x50 /* CSR20 - Current host transmit buffer address */ -+#define DmaRxCurrAddr 0x54 /* CSR21 - Current host receive buffer address */ -+ -+/**********************************************************/ -+/* MAC Control register layout */ -+/**********************************************************/ -+#define MacFilterOff 0x80000000 /* Receive all incoming packets RW */ -+#define MacFilterOn 0 /* Receive filtered packets only 0 */ -+#define MacBigEndian 0x40000000 /* Big endian mode RW */ -+#define MacLittleEndian 0 /* Little endian 0 */ -+#define MacHeartBeatOff 0x10000000 /* Heartbeat signal qual disable RW*/ -+#define MacHeartBeatOn 0 /* Heartbeat signal qual enable 0 */ -+#define MacSelectSrl 0x08000000 /* Select SRL port RW */ -+#define MacSelectMii 0 /* Select MII port 0 */ -+#define MacDisableRxOwn 0x00800000 /* Disable receive own packets RW */ -+#define MacEnableRxOwn 0 /* Enable receive own packets 0 */ -+#define MacLoopbackExt 0x00400000 /* External loopback RW */ -+#define MacLoopbackInt 0x00200000 /* Internal loopback */ -+#define MacLoopbackOff 0 /* Normal mode 00 */ -+#define MacFullDuplex 0x00100000 /* Full duplex mode RW */ -+#define MacHalfDuplex 0 /* Half duplex mode 0 */ -+#define MacMulticastFilterOff 0x00080000 /* Pass all multicast packets RW */ -+#define MacMulticastFilterOn 0 /* Pass filtered mcast packets 0 */ -+#define MacPromiscuousModeOn 0x00040000 /* Receive all valid packets RW 1 */ -+#define MacPromiscuousModeOff 0 /* Receive filtered packets only */ -+#define MacFilterInverse 0x00020000 /* Inverse filtering RW */ -+#define MacFilterNormal 0 /* Normal filtering 0 */ -+#define MacBadFramesEnable 0x00010000 /* Pass bad frames RW */ -+#define MacBadFramesDisable 0 /* Do not pass bad frames 0 */ -+#define MacPerfectFilterOff 0x00008000 /* Hash filtering only RW */ -+#define MacPerfectFilterOn 0 /* Both perfect and hash filtering 0 */ -+#define MacHashFilterOn 0x00002000 /* perform hash filtering RW */ -+#define MacHashFilterOff 0 /* perfect filtering only 0 */ -+#define MacLateCollisionOn 0x00001000 /* Enable late collision control RW */ -+#define MacLateCollisionOff 0 /* Disable late collision control 0 */ -+#define MacBroadcastDisable 0x00000800 /* Disable reception of bcast frames RW */ -+#define MacBroadcastEnable 0 /* Enable broadcast frames 0 */ -+#define MacRetryDisable 0x00000400 /* Disable retransmission RW */ -+#define MacRetryEnable 0 /* Enable retransmission 0 */ -+#define MacPadStripEnable 0x00000100 /* Pad stripping enable RW */ -+#define MacPadStripDisable 0 /* Pad stripping disable 0 */ -+#define MacBackoff 0 /* Backoff Limit RW 00 */ -+#define MacDeferralCheckEnable 0x00000020 /* Deferral check enable RW */ -+#define MacDeferralCheckDisable 0 /* Deferral check disable 0 */ -+#define MacTxEnable 0x00000008 /* Transmitter enable RW */ -+#define MacTxDisable 0 /* Transmitter disable 0 */ -+#define MacRxEnable 0x00000004 /* Receiver enable RW */ -+#define MacRxDisable 0 /* Receiver disable 0 */ -+ -+ -+/**********************************************************/ -+/* MII address register layout */ -+/**********************************************************/ -+#define MiiDevMask 0x0000F800 /* MII device address */ -+#define MiiDevShift 11 -+#define MiiRegMask 0x000007C0 /* MII register */ -+#define MiiRegShift 6 -+#define MiiWrite 0x00000002 /* Write to register */ -+#define MiiRead 0 /* Read from register */ -+#define MiiBusy 0x00000001 /* MII interface is busy */ -+ -+/**********************************************************/ -+/* MII Data register layout */ -+/**********************************************************/ -+#define MiiDataMask 0x0000FFFF /* MII Data */ -+ -+/**********************************************************/ -+/* MAC flow control register layout */ -+/**********************************************************/ -+#define MacPauseTimeMask 0xFFFF0000 /* PAUSE TIME field in ctrl frame */ -+#define MacPauseTimeShift 15 -+#define MacControlFrameEnable 0x00000004 /* Enable pass ctrl frames to host */ -+#define MacControlFrameDisable 0 /* Do not pass ctrl frames to host */ -+#define MacFlowControlEnable 0x00000002 /* Enable flow control */ -+#define MacFlowControlDisable 0 /* Disable flow control */ -+#define MacSendPauseFrame 0x00000001 /* send pause frame */ -+ -+/**********************************************************/ -+/* DMA bus mode register layout */ -+/**********************************************************/ -+#define DmaRxAlign16 0x01000000 /* Force all rx buffers to align on odd hw bndry */ -+#define DmaBigEndianDes 0x00100000 /* Big endian data buffer descriptors RW */ -+#define DmaLittleEndianDesc 0 /* Little endian data descriptors */ -+#define DmaBurstLength32 0x00002000 /* Dma burst length 32 RW */ -+#define DmaBurstLength16 0x00001000 /* Dma burst length 16 */ -+#define DmaBurstLength8 0x00000800 /* Dma burst length 8 */ -+#define DmaBurstLength4 0x00000400 /* Dma burst length 4 */ -+#define DmaBurstLength2 0x00000200 /* Dma burst length 2 */ -+#define DmaBurstLength1 0x00000100 /* Dma burst length 1 */ -+#define DmaBurstLength0 0x00000000 /* Dma burst length 0 */ -+#define DmaBigEndianData 0x00000080 /* Big endian data buffers RW */ -+#define DmaLittleEndianData 0 /* Little endian data buffers 0 */ -+#define DmaDescriptorSkip16 0x00000040 /* number of dwords to skip RW */ -+#define DmaDescriptorSkip8 0x00000020 /* between two unchained descriptors */ -+#define DmaDescriptorSkip4 0x00000010 -+#define DmaDescriptorSkip2 0x00000008 -+#define DmaDescriptorSkip1 0x00000004 -+#define DmaDescriptorSkip0 0 -+#define DmaReceivePriorityOff 0x00000002 /* equal rx and tx priorities RW */ -+#define DmaReceivePriorityOn 0 /* Rx has prioryty over Tx 0 */ -+#define DmaResetOn 0x00000001 /* Reset DMA engine RW */ -+#define DmaResetOff 0 -+ -+/**********************************************************/ -+/* DMA Status register layout */ -+/**********************************************************/ -+#define DmaRxAbort 0x01000000 /* receiver bus abort R 0 */ -+#define DmaTxAbort 0x00800000 /* transmitter bus abort R 0 */ -+#define DmaTxState 0x00700000 /* Transmit process state R 000 */ -+#define DmaTxStopped 0x00000000 /* Stopped */ -+#define DmaTxFetching 0x00100000 /* Running - fetching the descriptor */ -+#define DmaTxWaiting 0x00200000 /* Running - waiting for end of transmission */ -+#define DmaTxReading 0x00300000 /* Running - reading the data from memory */ -+#define DmaTxSuspended 0x00600000 /* Suspended */ -+#define DmaTxClosing 0x00700000 /* Running - closing descriptor */ -+#define DmaRxState 0x000E0000 /* Receive process state 000 */ -+#define DmaRxStopped 0x00000000 /* Stopped */ -+#define DmaRxFetching 0x00020000 /* Running - fetching the descriptor */ -+#define DmaRxChecking 0x00040000 /* Running - checking for end of packet */ -+#define DmaRxWaiting 0x00060000 /* Running - waiting for packet */ -+#define DmaRxSuspended 0x00080000 /* Suspended */ -+#define DmaRxClosing 0x000A0000 /* Running - closing descriptor */ -+#define DmaRxFlushing 0x000C0000 /* Running - flushing the current frame */ -+#define DmaRxQueuing 0x000E0000 /* Running - queuing the recieve frame into host memory */ -+#define DmaIntNormal 0x00010000 /* Normal interrupt summary RW 0 */ -+#define DmaIntAbnormal 0x00008000 /* Abnormal interrupt summary RW 0 */ -+#define DmaIntEarlyRx 0x00004000 /* Early receive interrupt (Normal) RW 0 */ -+#define DmaIntBusError 0x00002000 /* Fatal bus error (Abnormal) RW 0 */ -+#define DmaIntEarlyTx 0x00000400 /* Early transmit interrupt RW 0 */ -+#define DmaIntRxStopped 0x00000100 /* Receive process stopped (Abnormal) RW 0 */ -+#define DmaIntRxNoBuffer 0x00000080 /* Receive buffer unavailable (Abnormal) RW 0*/ -+#define DmaIntRxCompleted 0x00000040 /* Completion of frame reception(Normal) RW 0*/ -+#define DmaIntTxUnderflow 0x00000020 /* Transmit underflow (Abnormal) RW 0 */ -+#define DmaIntTxJabber 0x00000008 /* Transmit Jabber Timeout (Abnormal) RW 0 */ -+#define DmaIntTxNoBuffer 0x00000004 /* Transmit buffer unavailable (Normal) RW 0*/ -+#define DmaIntTxStopped 0x00000002 /* Transmit process stopped (Abnormal) RW 0 */ -+#define DmaIntTxCompleted 0x00000001 /* Transmit completed (Normal) RW 0 */ -+ -+/**********************************************************/ -+/* DMA control register layout */ -+/**********************************************************/ -+#define DmaStoreAndForward 0x00000000 /* Store and forward RW 0 */ -+#define DmaTxThreshCtl256 0x0000c000 /* Non-SF threshold is 256 words */ -+#define DmaTxThreshCtl128 0x00008000 /* Non-SF threshold is 128 words */ -+#define DmaTxThreshCtl064 0x00004000 /* Non-SF threshold is 64 words */ -+#define DmaTxThreshCtl032 0x00000000 /* Non-SF threshold is 32 words */ -+#define DmaTxStart 0x00002000 /* Start/Stop transmission RW 0 */ -+#define DmaTxSecondFrame 0x00000004 /* Operate on second frame RW 0 */ -+#define DmaRxStart 0x00000002 /* Start/Stop reception RW 0 */ -+ -+/**********************************************************/ -+/* DMA interrupt enable register layout */ -+/**********************************************************/ -+#define DmaIeNormal DmaIntNormal /* Normal interrupt enable RW 0 */ -+#define DmaIeAbnormal DmaIntAbnormal /* Abnormal interrupt enable RW 0 */ -+#define DmaIeEarlyRx DmaIntEarlyRx /* Early receive interrupt enable RW 0 */ -+#define DmaIeBusError DmaIntBusError /* Fatal bus error enable RW 0 */ -+#define DmaIeEarlyTx DmaIntEarlyTx /* Early transmit interrupt enable RW 0 */ -+#define DmaIeRxStopped DmaIntRxStopped /* Receive process stopped enable RW 0 */ -+#define DmaIeRxNoBuffer DmaIntRxNoBuffer /* Receive buffer unavailable enable RW 0 */ -+#define DmaIeRxCompleted DmaIntRxCompleted /* Completion of frame reception enable RW 0 */ -+#define DmaIeTxUnderflow DmaIntTxUnderflow /* Transmit underflow enable RW 0 */ -+#define DmaIeTxJabber DmaIntTxJabber /* Transmit jabber timeout RW 0 */ -+#define DmaIeTxNoBuffer DmaIntTxNoBuffer /* Transmit buffer unavailable enable RW 0 */ -+#define DmaIeTxStopped DmaIntTxStopped /* Transmit process stopped enable RW 0 */ -+#define DmaIeTxCompleted DmaIntTxCompleted /* Transmit completed enable RW 0 */ -+ -+/****************************************************************/ -+/* DMA Missed Frame and Buffer Overflow Counter register layout */ -+/****************************************************************/ -+#define DmaRxBufferMissedFrame 0xffff0000 /* cleared on read */ -+#define DmaMissedFrameShift 16 -+#define DmaRxBufferOverflowCnt 0x0000ffff /* cleared on read */ -+#define DmaMissedFrameCountMask 0x0000ffff -+ -+/**********************************************************/ -+/* DMA Engine descriptor layout */ -+/**********************************************************/ -+/* status word of DMA descriptor */ -+#define DescOwnByDma 0x80000000 /* Descriptor is owned by DMA engine */ -+#define DescFrameLengthMask 0x3FFF0000 /* Receive descriptor frame length */ -+#define DescFrameLengthShift 16 -+#define DescError 0x00008000 /* Error summary bit OR of following bits */ -+#define DescRxTruncated 0x00004000 /* Rx - no more descs for receive frame */ -+#define DescRxLengthError 0x00001000 /* Rx - frame size not matching with length field */ -+#define DescRxRunt 0x00000800 /* Rx - runt frame, damaged by a -+ collision or term before 64 bytes */ -+#define DescRxMulticast 0x00000400 /* Rx - received frame is multicast */ -+#define DescRxFirst 0x00000200 /* Rx - first descriptor of the frame */ -+#define DescRxLast 0x00000100 /* Rx - last descriptor of the frame */ -+#define DescRxLongFrame 0x00000080 /* Rx - frame is longer than 1518 bytes */ -+#define DescRxLateColl 0x00000040 /* Rx - frame was damaged by a late collision */ -+#define DescRxFrameEther 0x00000020 /* Rx - Frame type Ethernet 802.3*/ -+#define DescRxMiiError 0x00000008 /* Rx - error reported by MII interface */ -+#define DescRxDribbling 0x00000004 /* Rx - frame contains noninteger multiple of 8 bits */ -+#define DescRxCrc 0x00000002 /* Rx - CRC error */ -+#define DescTxTimeout 0x00004000 /* Tx - Transmit jabber timeout */ -+#define DescTxLostCarrier 0x00000800 /* Tx - carrier lost during tramsmission */ -+#define DescTxNoCarrier 0x00000400 /* Tx - no carrier signal from tranceiver */ -+#define DescTxLateCollision 0x00000200 /* Tx - transmission aborted due to collision */ -+#define DescTxExcCollisions 0x00000100 /* Tx - transmission aborted after 16 collisions */ -+#define DescTxHeartbeatFail 0x00000080 /* Tx - heartbeat collision check failure */ -+#define DescTxCollMask 0x00000078 /* Tx - Collision count */ -+#define DescTxCollShift 3 -+#define DescTxExcDeferral 0x00000004 /* Tx - excessive deferral */ -+#define DescTxUnderflow 0x00000002 /* Tx - late data arrival from memory */ -+#define DescTxDeferred 0x00000001 /* Tx - frame transmision deferred */ -+ -+/* length word of DMA descriptor */ -+#define DescTxIntEnable 0x80000000 /* Tx - interrupt on completion */ -+#define DescTxLast 0x40000000 /* Tx - Last segment of the frame */ -+#define DescTxFirst 0x20000000 /* Tx - First segment of the frame */ -+#define DescTxDisableCrc 0x04000000 /* Tx - Add CRC disabled (first segment only) */ -+#define DescEndOfRing 0x02000000 /* End of descriptors ring */ -+#define DescChain 0x01000000 /* Second buffer address is chain address */ -+#define DescTxDisablePadd 0x00800000 /* disable padding */ -+#define DescSize2Mask 0x003FF800 /* Buffer 2 size */ -+#define DescSize2Shift 11 -+#define DescSize1Mask 0x000007FF /* Buffer 1 size */ -+#define DescSize1Shift 0 -+ -+/**********************************************************/ -+/* Initial register values */ -+/**********************************************************/ -+/* Full-duplex mode with perfect filter on */ -+#define MacControlInitFdx \ -+ ( MacFilterOn \ -+ | MacLittleEndian \ -+ | MacHeartBeatOn \ -+ | MacSelectMii \ -+ | MacEnableRxOwn \ -+ | MacLoopbackOff \ -+ | MacFullDuplex \ -+ | MacMulticastFilterOn \ -+ | MacPromiscuousModeOff \ -+ | MacFilterNormal \ -+ | MacBadFramesDisable \ -+ | MacPerfectFilterOn \ -+ | MacHashFilterOff \ -+ | MacLateCollisionOff \ -+ | MacBroadcastEnable \ -+ | MacRetryEnable \ -+ | MacPadStripDisable \ -+ | MacDeferralCheckDisable \ -+ | MacTxEnable \ -+ | MacRxEnable) -+ -+/* Full-duplex mode */ -+#define MacFlowControlInitFdx \ -+ ( MacControlFrameDisable \ -+ | MacFlowControlEnable) -+ -+/* Half-duplex mode with perfect filter on */ -+#define MacControlInitHdx \ -+ ( MacFilterOn \ -+ | MacLittleEndian \ -+ | MacHeartBeatOn \ -+ | MacSelectMii \ -+ | MacDisableRxOwn \ -+ | MacLoopbackOff \ -+ | MacHalfDuplex \ -+ | MacMulticastFilterOn \ -+ | MacPromiscuousModeOff \ -+ | MacFilterNormal \ -+ | MacBadFramesDisable \ -+ | MacPerfectFilterOn \ -+ | MacHashFilterOff \ -+ | MacLateCollisionOff \ -+ | MacBroadcastEnable \ -+ | MacRetryEnable \ -+ | MacPadStripDisable \ -+ | MacDeferralCheckDisable \ -+ | MacTxEnable \ -+ | MacRxEnable) -+ -+/* Half-duplex mode */ -+#define MacFlowControlInitHdx \ -+ ( MacControlFrameDisable \ -+ | MacFlowControlDisable) -+ -+/* Bus Mode Rx odd half word align */ -+#define DmaBusModeInit \ -+ ( DmaLittleEndianDesc \ -+ | DmaRxAlign16 \ -+ | DmaBurstLength32 \ -+ | DmaBigEndianData \ -+ | DmaDescriptorSkip1 \ -+ | DmaReceivePriorityOn \ -+ | DmaResetOff) -+ -+#define DmaControlInit (DmaStoreAndForward) -+ -+/* Interrupt groups */ -+#define DmaIntEnable \ -+ ( DmaIeNormal \ -+ | DmaIeAbnormal \ -+ | DmaIntBusError \ -+ | DmaIntRxStopped \ -+ | DmaIntRxNoBuffer \ -+ | DmaIntRxCompleted \ -+ | DmaIntTxUnderflow \ -+ | DmaIntTxStopped) -+ -+#define DmaIntDisable 0 -+ -+#define DmaAllIntCauseMask \ -+ ( DmaIeNormal \ -+ | DmaIeAbnormal \ -+ | DmaIntEarlyRx \ -+ | DmaIntBusError \ -+ | DmaIntEarlyTx \ -+ | DmaIntRxStopped \ -+ | DmaIntRxNoBuffer \ -+ | DmaIntRxCompleted \ -+ | DmaIntTxUnderflow \ -+ | DmaIntTxJabber \ -+ | DmaIntTxNoBuffer \ -+ | DmaIntTxStopped \ -+ | DmaIntTxCompleted) -+ -+#define UnhandledIntrMask \ -+ (DmaAllIntCauseMask \ -+ & ~(DmaIntRxNoBuffer \ -+ | DmaIntTxStopped \ -+ | DmaIntTxJabber \ -+ | DmaIntTxUnderflow \ -+ | DmaIntBusError \ -+ | DmaIntRxCompleted )) -+ -+#define DescRxErrors \ -+ (DescRxTruncated \ -+ | DescRxRunt \ -+ | DescRxLateColl \ -+ | DescRxMiiError \ -+ | DescRxCrc) -+ -+#define DescTxErrors \ -+ ( DescTxTimeout \ -+ | DescTxLateCollision \ -+ | DescTxExcCollisions \ -+ | DescTxExcDeferral \ -+ | DescTxUnderflow) -+ -+/**********************************************************/ -+/* Descriptor Layout */ -+/**********************************************************/ -+#define AE531X_DESC_STATUS 0x00 /* Status offset */ -+#define AE531X_DESC_CTRLEN 0x04 /* Control and Length offset */ -+#define AE531X_DESC_BUFPTR 0x08 /* Buffer pointer offset */ -+#define AE531X_DESC_LNKBUF 0x0c /* Link field offset, or ptr to 2nd buf */ -+#define AE531X_DESC_SWPTR 0x10 /* OS-Dependent software pointer */ -+ -+#define AE531X_DESC_SIZE 0x10 /* 4 words, 16 bytes */ -+#define AE531X_QUEUE_ELE_SIZE 0x14 /* with software pointer extension */ -+ -+/* Accessors to the dma descriptor fields */ -+#define AE531X_DESC_STATUS_GET(ptr) \ -+ *(volatile UINT32 *)((UINT32)(ptr) + AE531X_DESC_STATUS) -+ -+#define AE531X_DESC_STATUS_SET(ptr, val) \ -+ AE531X_DESC_STATUS_GET(ptr) = (val) -+ -+#define AE531X_DESC_CTRLEN_GET(ptr) \ -+ *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_CTRLEN) -+ -+#define AE531X_DESC_CTRLEN_SET(ptr, val) \ -+ AE531X_DESC_CTRLEN_GET(ptr) = (val) -+ -+#define AE531X_DESC_BUFPTR_GET(ptr) \ -+ *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_BUFPTR) -+ -+#define AE531X_DESC_BUFPTR_SET(ptr,val) \ -+ AE531X_DESC_BUFPTR_GET(ptr) = (UINT32)(val) -+ -+#define AE531X_DESC_LNKBUF_GET(ptr) \ -+ *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_LNKBUF) -+ -+#define AE531X_DESC_LNKBUF_SET(ptr, val) \ -+ AE531X_DESC_LNKBUF_GET(ptr) = (val) -+ -+#define AE531X_DESC_SWPTR_GET(ptr) \ -+ (void *)(*(volatile UINT32 *) ((UINT32)ptr + AE531X_DESC_SWPTR)) -+ -+#define AE531X_DESC_SWPTR_SET(ptr,val) \ -+ AE531X_DESC_SWPTR_GET(ptr) = (void *)(val) -+ -+/* Get size of Rx data from desc, in bytes */ -+#define AE531X_DESC_STATUS_RX_SIZE(x) \ -+ (((x) & DescFrameLengthMask) >> DescFrameLengthShift) -+ -+#endif /* _AE531XREG_H_ */ -diff -urN linux-mips-orig/drivers/net/ath/ar531x.h linux-mips-new/drivers/net/ath/ar531x.h ---- linux-mips-orig/drivers/net/ath/ar531x.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/ar531x.h 2005-12-31 12:33:57.676538368 +0000 -@@ -0,0 +1,1124 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+#ifndef AR531X_H -+#define AR531X_H 1 -+ -+ -+#ifndef CONFIG_AR5315 -+ -+#include <asm/addrspace.h> -+ -+/* Address Map */ -+#define AR531X_WLAN0 0x18000000 -+#define AR531X_WLAN1 0x18500000 -+#define AR531X_ENET0 0x18100000 -+#define AR531X_ENET1 0x18200000 -+#define AR531X_SDRAMCTL 0x18300000 -+#define AR531X_FLASHCTL 0x18400000 -+#define AR531X_APBBASE 0x1c000000 -+#define AR531X_FLASH 0x1e000000 -+ -+/* -+ * AR531X_NUM_ENET_MAC defines the number of ethernet MACs that -+ * should be considered available. The AR5312 supports 2 enet MACS, -+ * even though many reference boards only actually use 1 of them -+ * (i.e. Only MAC 0 is actually connected to an enet PHY or PHY switch. -+ * The AR2312 supports 1 enet MAC. -+ */ -+#define AR531X_NUM_ENET_MAC 2 -+ -+/* -+ * Need these defines to determine true number of ethernet MACs -+ */ -+#define AR5212_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */ -+#define AR5212_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ -+#define AR5212_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */ -+#define AR531X_RADIO_MASK_OFF 0xc8 -+#define AR531X_RADIO0_MASK 0x0003 -+#define AR531X_RADIO1_MASK 0x000c -+#define AR531X_RADIO1_S 2 -+ -+/* -+ * AR531X_NUM_WMAC defines the number of Wireless MACs that\ -+ * should be considered available. -+ */ -+#define AR531X_NUM_WMAC 2 -+ -+/* Reset/Timer Block Address Map */ -+#define AR531X_RESETTMR (AR531X_APBBASE + 0x3000) -+#define AR531X_TIMER (AR531X_RESETTMR + 0x0000) /* countdown timer */ -+#define AR531X_WD_CTRL (AR531X_RESETTMR + 0x0008) /* watchdog cntrl */ -+#define AR531X_WD_TIMER (AR531X_RESETTMR + 0x000c) /* watchdog timer */ -+#define AR531X_ISR (AR531X_RESETTMR + 0x0010) /* Intr Status Reg */ -+#define AR531X_IMR (AR531X_RESETTMR + 0x0014) /* Intr Mask Reg */ -+#define AR531X_RESET (AR531X_RESETTMR + 0x0020) -+#define AR5312_CLOCKCTL1 (AR531X_RESETTMR + 0x0064) -+#define AR5312_SCRATCH (AR531X_RESETTMR + 0x006c) -+#define AR531X_PROCADDR (AR531X_RESETTMR + 0x0070) -+#define AR531X_PROC1 (AR531X_RESETTMR + 0x0074) -+#define AR531X_DMAADDR (AR531X_RESETTMR + 0x0078) -+#define AR531X_DMA1 (AR531X_RESETTMR + 0x007c) -+#define AR531X_ENABLE (AR531X_RESETTMR + 0x0080) /* interface enb */ -+#define AR531X_REV (AR531X_RESETTMR + 0x0090) /* revision */ -+ -+/* AR531X_WD_CTRL register bit field definitions */ -+#define AR531X_WD_CTRL_IGNORE_EXPIRATION 0x0000 -+#define AR531X_WD_CTRL_NMI 0x0001 -+#define AR531X_WD_CTRL_RESET 0x0002 -+ -+/* AR531X_ISR register bit field definitions */ -+#define AR531X_ISR_NONE 0x0000 -+#define AR531X_ISR_TIMER 0x0001 -+#define AR531X_ISR_AHBPROC 0x0002 -+#define AR531X_ISR_AHBDMA 0x0004 -+#define AR531X_ISR_GPIO 0x0008 -+#define AR531X_ISR_UART0 0x0010 -+#define AR531X_ISR_UART0DMA 0x0020 -+#define AR531X_ISR_WD 0x0040 -+#define AR531X_ISR_LOCAL 0x0080 -+ -+/* AR531X_RESET register bit field definitions */ -+#define AR531X_RESET_SYSTEM 0x00000001 /* cold reset full system */ -+#define AR531X_RESET_PROC 0x00000002 /* cold reset MIPS core */ -+#define AR531X_RESET_WLAN0 0x00000004 /* cold reset WLAN MAC and BB */ -+#define AR531X_RESET_EPHY0 0x00000008 /* cold reset ENET0 phy */ -+#define AR531X_RESET_EPHY1 0x00000010 /* cold reset ENET1 phy */ -+#define AR531X_RESET_ENET0 0x00000020 /* cold reset ENET0 mac */ -+#define AR531X_RESET_ENET1 0x00000040 /* cold reset ENET1 mac */ -+#define AR531X_RESET_UART0 0x00000100 /* cold reset UART0 (high speed) */ -+#define AR531X_RESET_WLAN1 0x00000200 /* cold reset WLAN MAC/BB */ -+#define AR531X_RESET_APB 0x00000400 /* cold reset APB (ar5312) */ -+#define AR531X_RESET_WARM_PROC 0x00001000 /* warm reset MIPS core */ -+#define AR531X_RESET_WARM_WLAN0_MAC 0x00002000 /* warm reset WLAN0 MAC */ -+#define AR531X_RESET_WARM_WLAN0_BB 0x00004000 /* warm reset WLAN0 BaseBand */ -+#define AR531X_RESET_NMI 0x00010000 /* send an NMI to the processor */ -+#define AR531X_RESET_WARM_WLAN1_MAC 0x00020000 /* warm reset WLAN1 mac */ -+#define AR531X_RESET_WARM_WLAN1_BB 0x00040000 /* warm reset WLAN1 baseband */ -+#define AR531X_RESET_LOCAL_BUS 0x00080000 /* reset local bus */ -+#define AR531X_RESET_WDOG 0x00100000 /* last reset was a watchdog */ -+ -+#define AR531X_RESET_WMAC0_BITS \ -+ AR531X_RESET_WLAN0 |\ -+ AR531X_RESET_WARM_WLAN0_MAC |\ -+ AR531X_RESET_WARM_WLAN0_BB -+ -+#define AR531X_RESERT_WMAC1_BITS \ -+ AR531X_RESET_WLAN1 |\ -+ AR531X_RESET_WARM_WLAN1_MAC |\ -+ AR531X_RESET_WARM_WLAN1_BB -+ -+/* AR5312_CLOCKCTL1 register bit field definitions */ -+#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030 -+#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4 -+#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00 -+#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8 -+#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000 -+ -+/* Valid for AR5312 and AR2312 */ -+#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030 -+#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4 -+#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00 -+#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8 -+#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000 -+ -+/* Valid for AR2313 */ -+#define AR2313_CLOCKCTL1_PREDIVIDE_MASK 0x00003000 -+#define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT 12 -+#define AR2313_CLOCKCTL1_MULTIPLIER_MASK 0x001f0000 -+#define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT 16 -+#define AR2313_CLOCKCTL1_DOUBLER_MASK 0x00000000 -+ -+ -+/* AR531X_ENABLE register bit field definitions */ -+#define AR531X_ENABLE_WLAN0 0x0001 -+#define AR531X_ENABLE_ENET0 0x0002 -+#define AR531X_ENABLE_ENET1 0x0004 -+#define AR531X_ENABLE_UART_AND_WLAN1_PIO 0x0008 /* UART, and WLAN1 PIOs */ -+#define AR531X_ENABLE_WLAN1_DMA 0x0010 /* WLAN1 DMAs */ -+#define AR531X_ENABLE_WLAN1 \ -+ (AR531X_ENABLE_UART_AND_WLAN1_PIO | AR531X_ENABLE_WLAN1_DMA) -+ -+/* AR531X_REV register bit field definitions */ -+#define AR531X_REV_WMAC_MAJ 0xf000 -+#define AR531X_REV_WMAC_MAJ_S 12 -+#define AR531X_REV_WMAC_MIN 0x0f00 -+#define AR531X_REV_WMAC_MIN_S 8 -+#define AR531X_REV_MAJ 0x00f0 -+#define AR531X_REV_MAJ_S 4 -+#define AR531X_REV_MIN 0x000f -+#define AR531X_REV_MIN_S 0 -+#define AR531X_REV_CHIP (REV_MAJ|REV_MIN) -+ -+/* Major revision numbers, bits 7..4 of Revision ID register */ -+#define AR531X_REV_MAJ_AR5312 0x4 -+#define AR531X_REV_MAJ_AR2313 0x5 -+ -+/* Minor revision numbers, bits 3..0 of Revision ID register */ -+#define AR5312_REV_MIN_DUAL 0x0 /* Dual WLAN version */ -+#define AR5312_REV_MIN_SINGLE 0x1 /* Single WLAN version */ -+ -+/* AR531X_FLASHCTL register bit field definitions */ -+#define FLASHCTL_IDCY 0x0000000f /* Idle cycle turn around time */ -+#define FLASHCTL_IDCY_S 0 -+#define FLASHCTL_WST1 0x000003e0 /* Wait state 1 */ -+#define FLASHCTL_WST1_S 5 -+#define FLASHCTL_RBLE 0x00000400 /* Read byte lane enable */ -+#define FLASHCTL_WST2 0x0000f800 /* Wait state 2 */ -+#define FLASHCTL_WST2_S 11 -+#define FLASHCTL_AC 0x00070000 /* Flash address check (added) */ -+#define FLASHCTL_AC_S 16 -+#define FLASHCTL_AC_128K 0x00000000 -+#define FLASHCTL_AC_256K 0x00010000 -+#define FLASHCTL_AC_512K 0x00020000 -+#define FLASHCTL_AC_1M 0x00030000 -+#define FLASHCTL_AC_2M 0x00040000 -+#define FLASHCTL_AC_4M 0x00050000 -+#define FLASHCTL_AC_8M 0x00060000 -+#define FLASHCTL_AC_RES 0x00070000 /* 16MB is not supported */ -+#define FLASHCTL_E 0x00080000 /* Flash bank enable (added) */ -+#define FLASHCTL_BUSERR 0x01000000 /* Bus transfer error status flag */ -+#define FLASHCTL_WPERR 0x02000000 /* Write protect error status flag */ -+#define FLASHCTL_WP 0x04000000 /* Write protect */ -+#define FLASHCTL_BM 0x08000000 /* Burst mode */ -+#define FLASHCTL_MW 0x30000000 /* Memory width */ -+#define FLASHCTL_MWx8 0x00000000 /* Memory width x8 */ -+#define FLASHCTL_MWx16 0x10000000 /* Memory width x16 */ -+#define FLASHCTL_MWx32 0x20000000 /* Memory width x32 (not supported) */ -+#define FLASHCTL_ATNR 0x00000000 /* Access type == no retry */ -+#define FLASHCTL_ATR 0x80000000 /* Access type == retry every */ -+#define FLASHCTL_ATR4 0xc0000000 /* Access type == retry every 4 */ -+ -+/* ARM Flash Controller -- 3 flash banks with either x8 or x16 devices. */ -+#define AR531X_FLASHCTL0 (AR531X_FLASHCTL + 0x00) -+#define AR531X_FLASHCTL1 (AR531X_FLASHCTL + 0x04) -+#define AR531X_FLASHCTL2 (AR531X_FLASHCTL + 0x08) -+ -+/* ARM SDRAM Controller -- just enough to determine memory size */ -+#define AR531X_MEM_CFG1 (AR531X_SDRAMCTL + 0x04) -+#define MEM_CFG1_AC0 0x00000700 /* bank 0: SDRAM addr check (added) */ -+#define MEM_CFG1_AC0_S 8 -+#define MEM_CFG1_AC1 0x00007000 /* bank 1: SDRAM addr check (added) */ -+#define MEM_CFG1_AC1_S 12 -+ -+/* GPIO Address Map */ -+#define AR531X_GPIO (AR531X_APBBASE + 0x2000) -+#define AR531X_GPIO_DO (AR531X_GPIO + 0x00) /* output register */ -+#define AR531X_GPIO_DI (AR531X_GPIO + 0x04) /* intput register */ -+#define AR531X_GPIO_CR (AR531X_GPIO + 0x08) /* control register */ -+ -+/* GPIO Control Register bit field definitions */ -+#define GPIO_CR_M(x) (1 << (x)) /* mask for i/o */ -+#define GPIO_CR_O(x) (0 << (x)) /* mask for output */ -+#define GPIO_CR_I(x) (1 << (x)) /* mask for input */ -+#define GPIO_CR_INT(x) (1 << ((x)+8)) /* mask for interrupt */ -+#define GPIO_CR_UART(x) (1 << ((x)+16)) /* uart multiplex */ -+ -+ -+typedef unsigned int AR531X_REG; -+ -+#define sysRegRead(phys) \ -+ (*(volatile AR531X_REG *)PHYS_TO_K1(phys)) -+ -+#define sysRegWrite(phys, val) \ -+ ((*(volatile AR531X_REG *)PHYS_TO_K1(phys)) = (val)) -+ -+ -+/* -+ * This is board-specific data that is stored in a "fixed" location in flash. -+ * It is shared across operating systems, so it should not be changed lightly. -+ * The main reason we need it is in order to extract the ethernet MAC -+ * address(es). -+ */ -+struct ar531x_boarddata { -+ u32 magic; /* board data is valid */ -+#define AR531X_BD_MAGIC 0x35333131 /* "5311", for all 531x platforms */ -+ u16 cksum; /* checksum (starting with BD_REV 2) */ -+ u16 rev; /* revision of this struct */ -+#define BD_REV 4 -+ char boardName[64]; /* Name of board */ -+ u16 major; /* Board major number */ -+ u16 minor; /* Board minor number */ -+ u32 config; /* Board configuration */ -+#define BD_ENET0 0x00000001 /* ENET0 is stuffed */ -+#define BD_ENET1 0x00000002 /* ENET1 is stuffed */ -+#define BD_UART1 0x00000004 /* UART1 is stuffed */ -+#define BD_UART0 0x00000008 /* UART0 is stuffed (dma) */ -+#define BD_RSTFACTORY 0x00000010 /* Reset factory defaults stuffed */ -+#define BD_SYSLED 0x00000020 /* System LED stuffed */ -+#define BD_EXTUARTCLK 0x00000040 /* External UART clock */ -+#define BD_CPUFREQ 0x00000080 /* cpu freq is valid in nvram */ -+#define BD_SYSFREQ 0x00000100 /* sys freq is set in nvram */ -+#define BD_WLAN0 0x00000200 /* Enable WLAN0 */ -+#define BD_MEMCAP 0x00000400 /* CAP SDRAM @ memCap for testing */ -+#define BD_DISWATCHDOG 0x00000800 /* disable system watchdog */ -+#define BD_WLAN1 0x00001000 /* Enable WLAN1 (ar5212) */ -+#define BD_ISCASPER 0x00002000 /* FLAG for AR2312 */ -+#define BD_WLAN0_2G_EN 0x00004000 /* FLAG for radio0_2G */ -+#define BD_WLAN0_5G_EN 0x00008000 /* FLAG for radio0_2G */ -+#define BD_WLAN1_2G_EN 0x00020000 /* FLAG for radio0_2G */ -+#define BD_WLAN1_5G_EN 0x00040000 /* FLAG for radio0_2G */ -+ u16 resetConfigGpio; /* Reset factory GPIO pin */ -+ u16 sysLedGpio; /* System LED GPIO pin */ -+ -+ u32 cpuFreq; /* CPU core frequency in Hz */ -+ u32 sysFreq; /* System frequency in Hz */ -+ u32 cntFreq; /* Calculated C0_COUNT frequency */ -+ -+ u8 wlan0Mac[6]; -+ u8 enet0Mac[6]; -+ u8 enet1Mac[6]; -+ -+ u16 pciId; /* Pseudo PCIID for common code */ -+ u16 memCap; /* cap bank1 in MB */ -+ -+ /* version 3 */ -+ u8 wlan1Mac[6]; /* (ar5212) */ -+}; -+ -+#else -+ -+/* -+ * Add support for Cobra -+ * -+ * AR531XPLUSreg.h Register definitions for Atheros AR5311 and AR5312 chipsets. -+ * - WLAN registers are listed in -+ * hal/ar5211/ar5211Reg.h -+ * hal/ar5212/ar5212Reg.h -+ * - Ethernet registers are listed in ar531xenet.h -+ * - Standard UART is 16550 compatible. -+ */ -+ -+ -+/* -+ * Address map -+ */ -+#define AR531XPLUS_SDRAM0 0x00000000 /* DRAM */ -+#define AR531XPLUS_SPI_READ 0x08000000 /* SPI FLASH */ -+#define AR531XPLUS_WLAN0 0xB0000000 /* Wireless MMR */ -+#define AR531XPLUS_PCI 0xB0100000 /* PCI MMR */ -+#define AR531XPLUS_SDRAMCTL 0xB0300000 /* SDRAM MMR */ -+#define AR531XPLUS_LOCAL 0xB0400000 /* LOCAL BUS MMR */ -+#define AR531XPLUS_ENET0 0xB0500000 /* ETHERNET MMR */ -+#define AR531XPLUS_DSLBASE 0xB1000000 /* RESET CONTROL MMR */ -+#define AR531XPLUS_UART0 0xB1100003 /* UART MMR */ -+#define AR531XPLUS_SPI 0xB1300000 /* SPI FLASH MMR */ -+#define AR531XPLUS_FLASHBT 0xBfc00000 /* ro boot alias to FLASH */ -+#define AR531XPLUS_RAM1 0x40000000 /* ram alias */ -+#define AR531XPLUS_PCIEXT 0x80000000 /* pci external */ -+#define AR531XPLUS_RAM2 0xc0000000 /* ram alias */ -+#define AR531XPLUS_RAM3 0xe0000000 /* ram alias */ -+ -+#define AR531X_ENET0 AR531XPLUS_ENET0 -+#define AR531X_ENET1 0 -+/* -+ * Reset Register -+ */ -+#define AR531XPLUS_COLD_RESET (AR531XPLUS_DSLBASE + 0x0000) -+ -+/* Cold Reset */ -+#define RESET_COLD_AHB 0x00000001 -+#define RESET_COLD_APB 0x00000002 -+#define RESET_COLD_CPU 0x00000004 -+#define RESET_COLD_CPUWARM 0x00000008 -+#define RESET_SYSTEM (RESET_COLD_CPU | RESET_COLD_APB | RESET_COLD_AHB) /* full system */ -+ -+/* Warm Reset */ -+ -+#define AR531XPLUS_RESET (AR531XPLUS_DSLBASE + 0x0004) -+#define AR531X_RESET AR531XPLUS_RESET -+ -+#define RESET_WARM_WLAN0_MAC 0x00000001 /* warm reset WLAN0 MAC */ -+#define RESET_WARM_WLAN0_BB 0x00000002 /* warm reset WLAN0 BaseBand */ -+#define RESET_MPEGTS_RSVD 0x00000004 /* warm reset MPEG-TS */ -+#define RESET_PCIDMA 0x00000008 /* warm reset PCI ahb/dma */ -+#define RESET_MEMCTL 0x00000010 /* warm reset memory controller */ -+#define RESET_LOCAL 0x00000020 /* warm reset local bus */ -+#define RESET_I2C_RSVD 0x00000040 /* warm reset I2C bus */ -+#define RESET_SPI 0x00000080 /* warm reset SPI interface */ -+#define RESET_UART0 0x00000100 /* warm reset UART0 */ -+#define RESET_IR_RSVD 0x00000200 /* warm reset IR interface */ -+#define RESET_EPHY0 0x00000400 /* cold reset ENET0 phy */ -+#define RESET_ENET0 0x00000800 /* cold reset ENET0 mac */ -+ -+#define AR531X_RESET_ENET0 RESET_ENET0 -+#define AR531X_RESET_EPHY0 RESET_EPHY0 -+#define AR531X_RESET_ENET1 0 -+#define AR531X_RESET_EPHY1 0 -+ -+/* -+ * AHB master arbitration control -+ */ -+#define AR531XPLUS_AHB_ARB_CTL (AR531XPLUS_DSLBASE + 0x0008) -+ -+#define ARB_CPU 0x00000001 /* CPU, default */ -+#define ARB_WLAN 0x00000002 /* WLAN */ -+#define ARB_MPEGTS_RSVD 0x00000004 /* MPEG-TS */ -+#define ARB_LOCAL 0x00000008 /* LOCAL */ -+#define ARB_PCI 0x00000010 /* PCI */ -+#define ARB_ETHERNET 0x00000020 /* Ethernet */ -+#define ARB_RETRY 0x00000100 /* retry policy, debug only */ -+ -+/* -+ * Config Register -+ */ -+#define AR531XPLUS_ENDIAN_CTL (AR531XPLUS_DSLBASE + 0x000c) -+ -+#define CONFIG_AHB 0x00000001 /* EC - AHB bridge endianess */ -+#define CONFIG_WLAN 0x00000002 /* WLAN byteswap */ -+#define CONFIG_MPEGTS_RSVD 0x00000004 /* MPEG-TS byteswap */ -+#define CONFIG_PCI 0x00000008 /* PCI byteswap */ -+#define CONFIG_MEMCTL 0x00000010 /* Memory controller endianess */ -+#define CONFIG_LOCAL 0x00000020 /* Local bus byteswap */ -+#define CONFIG_ETHERNET 0x00000040 /* Ethernet byteswap */ -+ -+#define CONFIG_MERGE 0x00000200 /* CPU write buffer merge */ -+#define CONFIG_CPU 0x00000400 /* CPU big endian */ -+#define CONFIG_PCIAHB 0x00000800 -+#define CONFIG_PCIAHB_BRIDGE 0x00001000 -+#define CONFIG_SPI 0x00008000 /* SPI byteswap */ -+#define CONFIG_CPU_DRAM 0x00010000 -+#define CONFIG_CPU_PCI 0x00020000 -+#define CONFIG_CPU_MMR 0x00040000 -+#define CONFIG_BIG 0x00000400 -+ -+ -+/* -+ * NMI control -+ */ -+#define AR531XPLUS_NMI_CTL (AR531XPLUS_DSLBASE + 0x0010) -+ -+#define NMI_EN 1 -+ -+/* -+ * Revision Register - Initial value is 0x3010 (WMAC 3.0, AR531X 1.0). -+ */ -+#define AR531XPLUS_SREV (AR531XPLUS_DSLBASE + 0x0014) -+ -+#define AR531X_REV AR531XPLUS_SREV -+ -+#define REV_MAJ 0x00f0 -+#define REV_MAJ_S 4 -+#define REV_MIN 0x000f -+#define REV_MIN_S 0 -+#define REV_CHIP (REV_MAJ|REV_MIN) -+ -+#define AR531X_REV_MAJ REV_MAJ -+#define AR531X_REV_MAJ_S REV_MAJ_S -+#define AR531X_REV_MIN REV_MIN -+#define AR531X_REV_MIN_S REV_MIN_S -+#define REV_CHIP (REV_MAJ|REV_MIN) -+/* -+ * Need these defines to determine true number of ethernet MACs -+ */ -+#define AR5212_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */ -+#define AR5212_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ -+#define AR5212_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */ -+#define AR531X_RADIO_MASK_OFF 0xc8 -+#define AR531X_RADIO0_MASK 0x0003 -+#define AR531X_RADIO1_MASK 0x000c -+#define AR531X_RADIO1_S 2 -+ -+/* Major revision numbers, bits 7..4 of Revision ID register */ -+#define AR531X_REV_MAJ_AR5312 0x4 -+#define AR531X_REV_MAJ_AR2313 0x5 -+ -+/* -+ * AR531X_NUM_ENET_MAC defines the number of ethernet MACs that -+ * should be considered available. The AR5312 supports 2 enet MACS, -+ * even though many reference boards only actually use 1 of them -+ * (i.e. Only MAC 0 is actually connected to an enet PHY or PHY switch. -+ * The AR2312 supports 1 enet MAC. -+ */ -+#define AR531X_NUM_ENET_MAC 1 -+ -+/* -+ * Interface Enable -+ */ -+#define AR531XPLUS_IF_CTL (AR531XPLUS_DSLBASE + 0x0018) -+ -+#define IF_MASK 0x00000007 -+#define IF_DISABLED 0 -+#define IF_PCI 1 -+#define IF_TS_LOCAL 2 -+#define IF_ALL 3 /* only for emulation with separate pins */ -+#define IF_LOCAL_HOST 0x00000008 -+#define IF_PCI_HOST 0x00000010 -+#define IF_PCI_INTR 0x00000020 -+#define IF_PCI_CLK_MASK 0x00030000 -+#define IF_PCI_CLK_INPUT 0 -+#define IF_PCI_CLK_OUTPUT_LOW 1 -+#define IF_PCI_CLK_OUTPUT_CLK 2 -+#define IF_PCI_CLK_OUTPUT_HIGH 3 -+#define IF_PCI_CLK_SHIFT 16 -+ -+ -+/* Major revision numbers, bits 7..4 of Revision ID register */ -+#define REV_MAJ_AR5311 0x01 -+#define REV_MAJ_AR5312 0x04 -+#define REV_MAJ_AR5315 0x0B -+ -+/* -+ * APB Interrupt control -+ */ -+ -+#define AR531XPLUS_ISR (AR531XPLUS_DSLBASE + 0x0020) -+#define AR531XPLUS_IMR (AR531XPLUS_DSLBASE + 0x0024) -+#define AR531XPLUS_GISR (AR531XPLUS_DSLBASE + 0x0028) -+ -+#define ISR_UART0 0x0001 /* high speed UART */ -+#define ISR_I2C_RSVD 0x0002 /* I2C bus */ -+#define ISR_SPI 0x0004 /* SPI bus */ -+#define ISR_AHB 0x0008 /* AHB error */ -+#define ISR_APB 0x0010 /* APB error */ -+#define ISR_TIMER 0x0020 /* timer */ -+#define ISR_GPIO 0x0040 /* GPIO */ -+#define ISR_WD 0x0080 /* watchdog */ -+#define ISR_IR_RSVD 0x0100 /* IR */ -+ -+#define IMR_UART0 ISR_UART0 -+#define IMR_I2C_RSVD ISR_I2C_RSVD -+#define IMR_SPI ISR_SPI -+#define IMR_AHB ISR_AHB -+#define IMR_APB ISR_APB -+#define IMR_TIMER ISR_TIMER -+#define IMR_GPIO ISR_GPIO -+#define IMR_WD ISR_WD -+#define IMR_IR_RSVD ISR_IR_RSVD -+ -+#define GISR_MISC 0x0001 -+#define GISR_WLAN0 0x0002 -+#define GISR_MPEGTS_RSVD 0x0004 -+#define GISR_LOCALPCI 0x0008 -+#define GISR_WMACPOLL 0x0010 -+#define GISR_TIMER 0x0020 -+#define GISR_ETHERNET 0x0040 -+ -+/* -+ * Interrupt routing from IO to the processor IP bits -+ * Define our inter mask and level -+ */ -+#define AR531XPLUS_INTR_MISCIO SR_IBIT3 -+#define AR531XPLUS_INTR_WLAN0 SR_IBIT4 -+#define AR531XPLUS_INTR_ENET0 SR_IBIT5 -+#define AR531XPLUS_INTR_LOCALPCI SR_IBIT6 -+#define AR531XPLUS_INTR_WMACPOLL SR_IBIT7 -+#define AR531XPLUS_INTR_COMPARE SR_IBIT8 -+ -+/* -+ * Timers -+ */ -+#define AR531XPLUS_TIMER (AR531XPLUS_DSLBASE + 0x0030) -+#define AR531XPLUS_RELOAD (AR531XPLUS_DSLBASE + 0x0034) -+#define AR531XPLUS_WD (AR531XPLUS_DSLBASE + 0x0038) -+#define AR531XPLUS_WDC (AR531XPLUS_DSLBASE + 0x003c) -+ -+#define WDC_RESET 0x00000002 /* reset on watchdog */ -+#define WDC_NMI 0x00000001 /* NMI on watchdog */ -+#define WDC_IGNORE_EXPIRATION 0x00000000 -+ -+/* -+ * Interface Debug -+ */ -+#define AR531X_FLASHDBG (AR531X_RESETTMR + 0x0040) -+#define AR531X_MIIDBG (AR531X_RESETTMR + 0x0044) -+ -+ -+/* -+ * CPU Performance Counters -+ */ -+#define AR531XPLUS_PERFCNT0 (AR531XPLUS_DSLBASE + 0x0048) -+#define AR531XPLUS_PERFCNT1 (AR531XPLUS_DSLBASE + 0x004c) -+ -+#define PERF_DATAHIT 0x0001 /* Count Data Cache Hits */ -+#define PERF_DATAMISS 0x0002 /* Count Data Cache Misses */ -+#define PERF_INSTHIT 0x0004 /* Count Instruction Cache Hits */ -+#define PERF_INSTMISS 0x0008 /* Count Instruction Cache Misses */ -+#define PERF_ACTIVE 0x0010 /* Count Active Processor Cycles */ -+#define PERF_WBHIT 0x0020 /* Count CPU Write Buffer Hits */ -+#define PERF_WBMISS 0x0040 /* Count CPU Write Buffer Misses */ -+ -+#define PERF_EB_ARDY 0x0001 /* Count EB_ARdy signal */ -+#define PERF_EB_AVALID 0x0002 /* Count EB_AValid signal */ -+#define PERF_EB_WDRDY 0x0004 /* Count EB_WDRdy signal */ -+#define PERF_EB_RDVAL 0x0008 /* Count EB_RdVal signal */ -+#define PERF_VRADDR 0x0010 /* Count valid read address cycles */ -+#define PERF_VWADDR 0x0020 /* Count valid write address cycles */ -+#define PERF_VWDATA 0x0040 /* Count valid write data cycles */ -+ -+/* -+ * AHB Error Reporting. -+ */ -+#define AR531XPLUS_AHB_ERR0 (AR531XPLUS_DSLBASE + 0x0050) /* error */ -+#define AR531XPLUS_AHB_ERR1 (AR531XPLUS_DSLBASE + 0x0054) /* haddr */ -+#define AR531XPLUS_AHB_ERR2 (AR531XPLUS_DSLBASE + 0x0058) /* hwdata */ -+#define AR531XPLUS_AHB_ERR3 (AR531XPLUS_DSLBASE + 0x005c) /* hrdata */ -+#define AR531XPLUS_AHB_ERR4 (AR531XPLUS_DSLBASE + 0x0060) /* status */ -+ -+#define AHB_ERROR_DET 1 /* AHB Error has been detected, */ -+ /* write 1 to clear all bits in ERR0 */ -+#define AHB_ERROR_OVR 2 /* AHB Error overflow has been detected */ -+#define AHB_ERROR_WDT 4 /* AHB Error due to wdt instead of hresp */ -+ -+#define PROCERR_HMAST 0x0000000f -+#define PROCERR_HMAST_DFLT 0 -+#define PROCERR_HMAST_WMAC 1 -+#define PROCERR_HMAST_ENET 2 -+#define PROCERR_HMAST_PCIENDPT 3 -+#define PROCERR_HMAST_LOCAL 4 -+#define PROCERR_HMAST_CPU 5 -+#define PROCERR_HMAST_PCITGT 6 -+ -+#define PROCERR_HMAST_S 0 -+#define PROCERR_HWRITE 0x00000010 -+#define PROCERR_HSIZE 0x00000060 -+#define PROCERR_HSIZE_S 5 -+#define PROCERR_HTRANS 0x00000180 -+#define PROCERR_HTRANS_S 7 -+#define PROCERR_HBURST 0x00000e00 -+#define PROCERR_HBURST_S 9 -+ -+ -+ -+/* -+ * Clock Control -+ */ -+#define AR531XPLUS_PLLC_CTL (AR531XPLUS_DSLBASE + 0x0064) -+#define AR531XPLUS_PLLV_CTL (AR531XPLUS_DSLBASE + 0x0068) -+#define AR531XPLUS_CPUCLK (AR531XPLUS_DSLBASE + 0x006c) -+#define AR531XPLUS_AMBACLK (AR531XPLUS_DSLBASE + 0x0070) -+#define AR531XPLUS_SYNCCLK (AR531XPLUS_DSLBASE + 0x0074) -+#define AR531XPLUS_DSL_SLEEP_CTL (AR531XPLUS_DSLBASE + 0x0080) -+#define AR531XPLUS_DSL_SLEEP_DUR (AR531XPLUS_DSLBASE + 0x0084) -+ -+/* PLLc Control fields */ -+#define PLLC_REF_DIV_M 0x00000003 -+#define PLLC_REF_DIV_S 0 -+#define PLLC_FDBACK_DIV_M 0x0000007C -+#define PLLC_FDBACK_DIV_S 2 -+#define PLLC_ADD_FDBACK_DIV_M 0x00000080 -+#define PLLC_ADD_FDBACK_DIV_S 7 -+#define PLLC_CLKC_DIV_M 0x0001c000 -+#define PLLC_CLKC_DIV_S 14 -+#define PLLC_CLKM_DIV_M 0x00700000 -+#define PLLC_CLKM_DIV_S 20 -+ -+/* CPU CLK Control fields */ -+#define CPUCLK_CLK_SEL_M 0x00000003 -+#define CPUCLK_CLK_SEL_S 0 -+#define CPUCLK_CLK_DIV_M 0x0000000c -+#define CPUCLK_CLK_DIV_S 2 -+ -+/* AMBA CLK Control fields */ -+#define AMBACLK_CLK_SEL_M 0x00000003 -+#define AMBACLK_CLK_SEL_S 0 -+#define AMBACLK_CLK_DIV_M 0x0000000c -+#define AMBACLK_CLK_DIV_S 2 -+ -+#if defined(COBRA_EMUL) -+#define AR531XPLUS_AMBA_CLOCK_RATE 20000000 -+#define AR531XPLUS_CPU_CLOCK_RATE 40000000 -+#else -+#if defined(DEFAULT_PLL) -+#define AR531XPLUS_AMBA_CLOCK_RATE 40000000 -+#define AR531XPLUS_CPU_CLOCK_RATE 40000000 -+#else -+#define AR531XPLUS_AMBA_CLOCK_RATE 92000000 -+#define AR531XPLUS_CPU_CLOCK_RATE 184000000 -+#endif /* ! DEFAULT_PLL */ -+#endif /* ! COBRA_EMUL */ -+ -+#define AR531XPLUS_UART_CLOCK_RATE AR531XPLUS_AMBA_CLOCK_RATE -+#define AR531XPLUS_SDRAM_CLOCK_RATE AR531XPLUS_AMBA_CLOCK_RATE -+ -+/* -+ * The UART computes baud rate as: -+ * baud = clock / (16 * divisor) -+ * where divisor is specified as a High Byte (DLM) and a Low Byte (DLL). -+ */ -+#define DESIRED_BAUD_RATE 38400 -+ -+/* -+ * The WATCHDOG value is computed as -+ * 10 seconds * AR531X_WATCHDOG_CLOCK_RATE -+ */ -+#define DESIRED_WATCHDOG_SECONDS 10 -+#define AR531X_WATCHDOG_TIME \ -+ (DESIRED_WATCHDOG_SECONDS * AR531X_WATCHDOG_CLOCK_RATE) -+ -+ -+#define CLOCKCTL_UART0 0x0010 /* enable UART0 external clock */ -+ -+ -+ /* -+ * Applicable "PCICFG" bits for WLAN(s). Assoc status and LED mode. -+ */ -+#define AR531X_PCICFG (AR531X_RESETTMR + 0x00b0) -+#define ASSOC_STATUS_M 0x00000003 -+#define ASSOC_STATUS_NONE 0 -+#define ASSOC_STATUS_PENDING 1 -+#define ASSOC_STATUS_ASSOCIATED 2 -+#define LED_MODE_M 0x0000001c -+#define LED_BLINK_THRESHOLD_M 0x000000e0 -+#define LED_SLOW_BLINK_MODE 0x00000100 -+ -+/* -+ * GPIO -+ */ -+ -+#define AR531XPLUS_GPIO_DI (AR531XPLUS_DSLBASE + 0x0088) -+#define AR531XPLUS_GPIO_DO (AR531XPLUS_DSLBASE + 0x0090) -+#define AR531XPLUS_GPIO_CR (AR531XPLUS_DSLBASE + 0x0098) -+#define AR531XPLUS_GPIO_INT (AR531XPLUS_DSLBASE + 0x00a0) -+ -+#define GPIO_CR_M(x) (1 << (x)) /* mask for i/o */ -+#define GPIO_CR_O(x) (1 << (x)) /* output */ -+#define GPIO_CR_I(x) (0 << (x)) /* input */ -+ -+#define GPIO_INT(x,Y) ((x) << (8 * (Y))) /* interrupt enable */ -+#define GPIO_INT_M(Y) ((0x3F) << (8 * (Y))) /* mask for int */ -+#define GPIO_INT_LVL(x,Y) ((x) << (8 * (Y) + 6)) /* interrupt level */ -+#define GPIO_INT_LVL_M(Y) ((0x3) << (8 * (Y) + 6)) /* mask for int level */ -+ -+#define AR531XPLUS_RESET_GPIO 5 -+#define AR531XPLUS_NUM_GPIO 22 -+ -+ -+/* -+ * PCI Clock Control -+ */ -+ -+#define AR531XPLUS_PCICLK (AR531XPLUS_DSLBASE + 0x00a4) -+ -+#define PCICLK_INPUT_M 0x3 -+#define PCICLK_INPUT_S 0 -+ -+#define PCICLK_PLLC_CLKM 0 -+#define PCICLK_PLLC_CLKM1 1 -+#define PCICLK_PLLC_CLKC 2 -+#define PCICLK_REF_CLK 3 -+ -+#define PCICLK_DIV_M 0xc -+#define PCICLK_DIV_S 2 -+ -+#define PCICLK_IN_FREQ 0 -+#define PCICLK_IN_FREQ_DIV_6 1 -+#define PCICLK_IN_FREQ_DIV_8 2 -+#define PCICLK_IN_FREQ_DIV_10 3 -+ -+/* -+ * Observation Control Register -+ */ -+#define AR531XPLUS_OCR (AR531XPLUS_DSLBASE + 0x00b0) -+#define OCR_GPIO0_IRIN 0x0040 -+#define OCR_GPIO1_IROUT 0x0080 -+#define OCR_GPIO3_RXCLR 0x0200 -+ -+/* -+ * General Clock Control -+ */ -+ -+#define AR531XPLUS_MISCCLK (AR531XPLUS_DSLBASE + 0x00b4) -+#define MISCCLK_PLLBYPASS_EN 0x00000001 -+#define MISCCLK_PROCREFCLK 0x00000002 -+ -+/* -+ * SDRAM Controller -+ * - No read or write buffers are included. -+ */ -+#define AR531XPLUS_MEM_CFG (AR531XPLUS_SDRAMCTL + 0x00) -+#define AR531XPLUS_MEM_CTRL (AR531XPLUS_SDRAMCTL + 0x0c) -+#define AR531XPLUS_MEM_REF (AR531XPLUS_SDRAMCTL + 0x10) -+ -+#define SDRAM_DATA_WIDTH_M 0x00006000 -+#define SDRAM_DATA_WIDTH_S 13 -+ -+#define SDRAM_COL_WIDTH_M 0x00001E00 -+#define SDRAM_COL_WIDTH_S 9 -+ -+#define SDRAM_ROW_WIDTH_M 0x000001E0 -+#define SDRAM_ROW_WIDTH_S 5 -+ -+#define SDRAM_BANKADDR_BITS_M 0x00000018 -+#define SDRAM_BANKADDR_BITS_S 3 -+ -+ -+/* -+ * SDRAM Memory Refresh (MEM_REF) value is computed as: -+ * MEMCTL_SREFR = (Tr * hclk_freq) / R -+ * where Tr is max. time of refresh of any single row -+ * R is number of rows in the DRAM -+ * For most 133MHz SDRAM parts, Tr=64ms, R=4096 or 8192 -+ */ -+#if defined(COBRA_EMUL) -+#define AR531XPLUS_SDRAM_MEMORY_REFRESH_VALUE 0x96 -+#else -+#if defined(DEFAULT_PLL) -+#define AR531XPLUS_SDRAM_MEMORY_REFRESH_VALUE 0x200 -+#else -+#define AR531XPLUS_SDRAM_MEMORY_REFRESH_VALUE 0x61a -+#endif /* ! DEFAULT_PLL */ -+#endif -+ -+#if defined(AR531XPLUS) -+ -+#define AR531XPLUS_SDRAM_DDR_SDRAM 0 /* Not DDR SDRAM */ -+#define AR531XPLUS_SDRAM_DATA_WIDTH 16 /* bits */ -+#define AR531XPLUS_SDRAM_COL_WIDTH 8 -+#define AR531XPLUS_SDRAM_ROW_WIDTH 12 -+ -+#else -+ -+#define AR531XPLUS_SDRAM_DDR_SDRAM 0 /* Not DDR SDRAM */ -+#define AR531XPLUS_SDRAM_DATA_WIDTH 16 -+#define AR531XPLUS_SDRAM_COL_WIDTH 8 -+#define AR531XPLUS_SDRAM_ROW_WIDTH 12 -+ -+#endif /* ! AR531XPLUS */ -+ -+/* -+ * SPI Flash Interface Registers -+ */ -+ -+#define AR531XPLUS_SPI_CTL (AR531XPLUS_SPI + 0x00) -+#define AR531XPLUS_SPI_OPCODE (AR531XPLUS_SPI + 0x04) -+#define AR531XPLUS_SPI_DATA (AR531XPLUS_SPI + 0x08) -+ -+#define SPI_CTL_START 0x00000100 -+#define SPI_CTL_BUSY 0x00010000 -+#define SPI_CTL_TXCNT_MASK 0x0000000f -+#define SPI_CTL_RXCNT_MASK 0x000000f0 -+#define SPI_CTL_TX_RX_CNT_MASK 0x000000ff -+#define SPI_CTL_SIZE_MASK 0x00060000 -+ -+#define SPI_CTL_CLK_SEL_MASK 0x03000000 -+#define SPI_OPCODE_MASK 0x000000ff -+ -+/* -+ * PCI-MAC Configuration registers -+ */ -+#define PCI_MAC_RC (AR531XPLUS_PCI + 0x4000) -+#define PCI_MAC_SCR (AR531XPLUS_PCI + 0x4004) -+#define PCI_MAC_INTPEND (AR531XPLUS_PCI + 0x4008) -+#define PCI_MAC_SFR (AR531XPLUS_PCI + 0x400C) -+#define PCI_MAC_PCICFG (AR531XPLUS_PCI + 0x4010) -+#define PCI_MAC_SREV (AR531XPLUS_PCI + 0x4020) -+ -+#define PCI_MAC_RC_MAC 0x00000001 -+#define PCI_MAC_RC_BB 0x00000002 -+ -+#define PCI_MAC_SCR_SLMODE_M 0x00030000 -+#define PCI_MAC_SCR_SLMODE_S 16 -+#define PCI_MAC_SCR_SLM_FWAKE 0 -+#define PCI_MAC_SCR_SLM_FSLEEP 1 -+#define PCI_MAC_SCR_SLM_NORMAL 2 -+ -+#define PCI_MAC_SFR_SLEEP 0x00000001 -+ -+#define PCI_MAC_PCICFG_SPWR_DN 0x00010000 -+ -+ -+ -+ -+/* -+ * PCI Bus Interface Registers -+ */ -+#define AR531XPLUS_PCI_1MS_REG (AR531XPLUS_PCI + 0x0008) -+#define AR531XPLUS_PCI_1MS_MASK 0x3FFFF /* # of AHB clk cycles in 1ms */ -+ -+#define AR531XPLUS_PCI_MISC_CONFIG (AR531XPLUS_PCI + 0x000c) -+#define AR531XPLUS_PCIMISC_TXD_EN 0x00000001 /* Enable TXD for fragments */ -+#define AR531XPLUS_PCIMISC_CFG_SEL 0x00000002 /* mem or config cycles */ -+#define AR531XPLUS_PCIMISC_GIG_MASK 0x0000000C /* bits 31-30 for pci req */ -+#define AR531XPLUS_PCIMISC_RST_MODE 0x00000030 -+#define AR531XPLUS_PCIRST_INPUT 0x00000000 /* 4:5=0 rst is input */ -+#define AR531XPLUS_PCIRST_LOW 0x00000010 /* 4:5=1 rst to GND */ -+#define AR531XPLUS_PCIRST_HIGH 0x00000020 /* 4:5=2 rst to VDD */ -+#define AR531XPLUS_PCIGRANT_EN 0x00000000 /* 6:7=0 early grant en */ -+#define AR531XPLUS_PCIGRANT_FRAME 0x00000040 /* 6:7=1 grant waits 4 frame */ -+#define AR531XPLUS_PCIGRANT_IDLE 0x00000080 /* 6:7=2 grant waits 4 idle */ -+#define AR531XPLUS_PCIGRANT_GAP 0x00000000 /* 6:7=2 grant waits 4 idle */ -+#define AR531XPLUS_PCICACHE_DIS 0x00001000 /* PCI external access cache disable */ -+ -+#define AR531XPLUS_PCI_OUT_TSTAMP (AR531XPLUS_PCI + 0x0010) -+ -+#define AR531XPLUS_PCI_UNCACHE_CFG (AR531XPLUS_PCI + 0x0014) -+ -+#define AR531XPLUS_PCI_IN_EN (AR531XPLUS_PCI + 0x0100) -+#define AR531XPLUS_PCI_IN_EN0 0x01 /* Enable chain 0 */ -+#define AR531XPLUS_PCI_IN_EN1 0x02 /* Enable chain 1 */ -+#define AR531XPLUS_PCI_IN_EN2 0x04 /* Enable chain 2 */ -+#define AR531XPLUS_PCI_IN_EN3 0x08 /* Enable chain 3 */ -+ -+#define AR531XPLUS_PCI_IN_DIS (AR531XPLUS_PCI + 0x0104) -+#define AR531XPLUS_PCI_IN_DIS0 0x01 /* Disable chain 0 */ -+#define AR531XPLUS_PCI_IN_DIS1 0x02 /* Disable chain 1 */ -+#define AR531XPLUS_PCI_IN_DIS2 0x04 /* Disable chain 2 */ -+#define AR531XPLUS_PCI_IN_DIS3 0x08 /* Disable chain 3 */ -+ -+#define AR531XPLUS_PCI_IN_PTR (AR531XPLUS_PCI + 0x0200) -+ -+#define AR531XPLUS_PCI_OUT_EN (AR531XPLUS_PCI + 0x0400) -+#define AR531XPLUS_PCI_OUT_EN0 0x01 /* Enable chain 0 */ -+ -+#define AR531XPLUS_PCI_OUT_DIS (AR531XPLUS_PCI + 0x0404) -+#define AR531XPLUS_PCI_OUT_DIS0 0x01 /* Disable chain 0 */ -+ -+#define AR531XPLUS_PCI_OUT_PTR (AR531XPLUS_PCI + 0x0408) -+ -+#define AR531XPLUS_PCI_INT_STATUS (AR531XPLUS_PCI + 0x0500) /* write one to clr */ -+#define AR531XPLUS_PCI_TXINT 0x00000001 /* Desc In Completed */ -+#define AR531XPLUS_PCI_TXOK 0x00000002 /* Desc In OK */ -+#define AR531XPLUS_PCI_TXERR 0x00000004 /* Desc In ERR */ -+#define AR531XPLUS_PCI_TXEOL 0x00000008 /* Desc In End-of-List */ -+#define AR531XPLUS_PCI_RXINT 0x00000010 /* Desc Out Completed */ -+#define AR531XPLUS_PCI_RXOK 0x00000020 /* Desc Out OK */ -+#define AR531XPLUS_PCI_RXERR 0x00000040 /* Desc Out ERR */ -+#define AR531XPLUS_PCI_RXEOL 0x00000080 /* Desc Out EOL */ -+#define AR531XPLUS_PCI_TXOOD 0x00000200 /* Desc In Out-of-Desc */ -+#define AR531XPLUS_PCI_MASK 0x0000FFFF /* Desc Mask */ -+#define AR531XPLUS_PCI_EXT_INT 0x02000000 -+#define AR531XPLUS_PCI_ABORT_INT 0x04000000 -+ -+#define AR531XPLUS_PCI_INT_MASK (AR531XPLUS_PCI + 0x0504) /* same as INT_STATUS */ -+ -+#define AR531XPLUS_PCI_INTEN_REG (AR531XPLUS_PCI + 0x0508) -+#define AR531XPLUS_PCI_INT_DISABLE 0x00 /* disable pci interrupts */ -+#define AR531XPLUS_PCI_INT_ENABLE 0x01 /* enable pci interrupts */ -+ -+#define AR531XPLUS_PCI_HOST_IN_EN (AR531XPLUS_PCI + 0x0800) -+#define AR531XPLUS_PCI_HOST_IN_DIS (AR531XPLUS_PCI + 0x0804) -+#define AR531XPLUS_PCI_HOST_IN_PTR (AR531XPLUS_PCI + 0x0810) -+#define AR531XPLUS_PCI_HOST_OUT_EN (AR531XPLUS_PCI + 0x0900) -+#define AR531XPLUS_PCI_HOST_OUT_DIS (AR531XPLUS_PCI + 0x0904) -+#define AR531XPLUS_PCI_HOST_OUT_PTR (AR531XPLUS_PCI + 0x0908) -+ -+ -+/* -+ * Local Bus Interface Registers -+ */ -+#define AR531XPLUS_LB_CONFIG (AR531XPLUS_LOCAL + 0x0000) -+#define AR531XPLUS_LBCONF_OE 0x00000001 /* =1 OE is low-true */ -+#define AR531XPLUS_LBCONF_CS0 0x00000002 /* =1 first CS is low-true */ -+#define AR531XPLUS_LBCONF_CS1 0x00000004 /* =1 2nd CS is low-true */ -+#define AR531XPLUS_LBCONF_RDY 0x00000008 /* =1 RDY is low-true */ -+#define AR531XPLUS_LBCONF_WE 0x00000010 /* =1 Write En is low-true */ -+#define AR531XPLUS_LBCONF_WAIT 0x00000020 /* =1 WAIT is low-true */ -+#define AR531XPLUS_LBCONF_ADS 0x00000040 /* =1 Adr Strobe is low-true */ -+#define AR531XPLUS_LBCONF_MOT 0x00000080 /* =0 Intel, =1 Motorola */ -+#define AR531XPLUS_LBCONF_8CS 0x00000100 /* =1 8 bits CS, 0= 16bits */ -+#define AR531XPLUS_LBCONF_8DS 0x00000200 /* =1 8 bits Data S, 0=16bits */ -+#define AR531XPLUS_LBCONF_ADS_EN 0x00000400 /* =1 Enable ADS */ -+#define AR531XPLUS_LBCONF_ADR_OE 0x00000800 /* =1 Adr cap on OE, WE or DS */ -+#define AR531XPLUS_LBCONF_ADDT_MUX 0x00001000 /* =1 Adr and Data share bus */ -+#define AR531XPLUS_LBCONF_DATA_OE 0x00002000 /* =1 Data cap on OE, WE, DS */ -+#define AR531XPLUS_LBCONF_16DATA 0x00004000 /* =1 Data is 16 bits wide */ -+#define AR531XPLUS_LBCONF_SWAPDT 0x00008000 /* =1 Byte swap data */ -+#define AR531XPLUS_LBCONF_SYNC 0x00010000 /* =1 Bus synchronous to clk */ -+#define AR531XPLUS_LBCONF_INT 0x00020000 /* =1 Intr is low true */ -+#define AR531XPLUS_LBCONF_INT_CTR0 0x00000000 /* GND high-Z, Vdd is high-Z */ -+#define AR531XPLUS_LBCONF_INT_CTR1 0x00040000 /* GND drive, Vdd is high-Z */ -+#define AR531XPLUS_LBCONF_INT_CTR2 0x00080000 /* GND high-Z, Vdd drive */ -+#define AR531XPLUS_LBCONF_INT_CTR3 0x000C0000 /* GND drive, Vdd drive */ -+#define AR531XPLUS_LBCONF_RDY_WAIT 0x00100000 /* =1 RDY is negative of WAIT */ -+#define AR531XPLUS_LBCONF_INT_PULSE 0x00200000 /* =1 Interrupt is a pulse */ -+#define AR531XPLUS_LBCONF_ENABLE 0x00400000 /* =1 Falcon respond to LB */ -+ -+#define AR531XPLUS_LB_CLKSEL (AR531XPLUS_LOCAL + 0x0004) -+#define AR531XPLUS_LBCLK_EXT 0x0001 /* use external clk for lb */ -+ -+#define AR531XPLUS_LB_1MS (AR531XPLUS_LOCAL + 0x0008) -+#define AR531XPLUS_LB1MS_MASK 0x3FFFF /* # of AHB clk cycles in 1ms */ -+ -+#define AR531XPLUS_LB_MISCCFG (AR531XPLUS_LOCAL + 0x000C) -+#define AR531XPLUS_LBM_TXD_EN 0x00000001 /* Enable TXD for fragments */ -+#define AR531XPLUS_LBM_RX_INTEN 0x00000002 /* Enable LB ints on RX ready */ -+#define AR531XPLUS_LBM_MBOXWR_INTEN 0x00000004 /* Enable LB ints on mbox wr */ -+#define AR531XPLUS_LBM_MBOXRD_INTEN 0x00000008 /* Enable LB ints on mbox rd */ -+#define AR531XPLUS_LMB_DESCSWAP_EN 0x00000010 /* Byte swap desc enable */ -+#define AR531XPLUS_LBM_TIMEOUT_MASK 0x00FFFF80 -+#define AR531XPLUS_LBM_TIMEOUT_SHFT 7 -+#define AR531XPLUS_LBM_PORTMUX 0x07000000 -+ -+ -+#define AR531XPLUS_LB_RXTSOFF (AR531XPLUS_LOCAL + 0x0010) -+ -+#define AR531XPLUS_LB_TX_CHAIN_EN (AR531XPLUS_LOCAL + 0x0100) -+#define AR531XPLUS_LB_TXEN_0 0x01 -+#define AR531XPLUS_LB_TXEN_1 0x02 -+#define AR531XPLUS_LB_TXEN_2 0x04 -+#define AR531XPLUS_LB_TXEN_3 0x08 -+ -+#define AR531XPLUS_LB_TX_CHAIN_DIS (AR531XPLUS_LOCAL + 0x0104) -+#define AR531XPLUS_LB_TX_DESC_PTR (AR531XPLUS_LOCAL + 0x0200) -+ -+#define AR531XPLUS_LB_RX_CHAIN_EN (AR531XPLUS_LOCAL + 0x0400) -+#define AR531XPLUS_LB_RXEN 0x01 -+ -+#define AR531XPLUS_LB_RX_CHAIN_DIS (AR531XPLUS_LOCAL + 0x0404) -+#define AR531XPLUS_LB_RX_DESC_PTR (AR531XPLUS_LOCAL + 0x0408) -+ -+#define AR531XPLUS_LB_INT_STATUS (AR531XPLUS_LOCAL + 0x0500) -+#define AR531XPLUS_INT_TX_DESC 0x0001 -+#define AR531XPLUS_INT_TX_OK 0x0002 -+#define AR531XPLUS_INT_TX_ERR 0x0004 -+#define AR531XPLUS_INT_TX_EOF 0x0008 -+#define AR531XPLUS_INT_RX_DESC 0x0010 -+#define AR531XPLUS_INT_RX_OK 0x0020 -+#define AR531XPLUS_INT_RX_ERR 0x0040 -+#define AR531XPLUS_INT_RX_EOF 0x0080 -+#define AR531XPLUS_INT_TX_TRUNC 0x0100 -+#define AR531XPLUS_INT_TX_STARVE 0x0200 -+#define AR531XPLUS_INT_LB_TIMEOUT 0x0400 -+#define AR531XPLUS_INT_LB_ERR 0x0800 -+#define AR531XPLUS_INT_MBOX_WR 0x1000 -+#define AR531XPLUS_INT_MBOX_RD 0x2000 -+ -+/* Bit definitions for INT MASK are the same as INT_STATUS */ -+#define AR531XPLUS_LB_INT_MASK (AR531XPLUS_LOCAL + 0x0504) -+ -+#define AR531XPLUS_LB_INT_EN (AR531XPLUS_LOCAL + 0x0508) -+#define AR531XPLUS_LB_MBOX (AR531XPLUS_LOCAL + 0x0600) -+ -+ -+ -+/* -+ * IR Interface Registers -+ */ -+#define AR531XPLUS_IR_PKTDATA (AR531XPLUS_IR + 0x0000) -+ -+#define AR531XPLUS_IR_PKTLEN (AR531XPLUS_IR + 0x07fc) /* 0 - 63 */ -+ -+#define AR531XPLUS_IR_CONTROL (AR531XPLUS_IR + 0x0800) -+#define AR531XPLUS_IRCTL_TX 0x00000000 /* use as tranmitter */ -+#define AR531XPLUS_IRCTL_RX 0x00000001 /* use as receiver */ -+#define AR531XPLUS_IRCTL_SAMPLECLK_MASK 0x00003ffe /* Sample clk divisor mask */ -+#define AR531XPLUS_IRCTL_SAMPLECLK_SHFT 1 -+#define AR531XPLUS_IRCTL_OUTPUTCLK_MASK 0x03ffc000 /* Output clk divisor mask */ -+#define AR531XPLUS_IRCTL_OUTPUTCLK_SHFT 14 -+ -+#define AR531XPLUS_IR_STATUS (AR531XPLUS_IR + 0x0804) -+#define AR531XPLUS_IRSTS_RX 0x00000001 /* receive in progress */ -+#define AR531XPLUS_IRSTS_TX 0x00000002 /* transmit in progress */ -+ -+#define AR531XPLUS_IR_CONFIG (AR531XPLUS_IR + 0x0808) -+#define AR531XPLUS_IRCFG_INVIN 0x00000001 /* invert input polarity */ -+#define AR531XPLUS_IRCFG_INVOUT 0x00000002 /* invert output polarity */ -+#define AR531XPLUS_IRCFG_SEQ_START_WIN_SEL 0x00000004 /* 1 => 28, 0 => 7 */ -+#define AR531XPLUS_IRCFG_SEQ_START_THRESH 0x000000f0 /* */ -+#define AR531XPLUS_IRCFG_SEQ_END_UNIT_SEL 0x00000100 /* */ -+#define AR531XPLUS_IRCFG_SEQ_END_UNIT_THRESH 0x00007e00 /* */ -+#define AR531XPLUS_IRCFG_SEQ_END_WIN_SEL 0x00008000 /* */ -+#define AR531XPLUS_IRCFG_SEQ_END_WIN_THRESH 0x001f0000 /* */ -+#define AR531XPLUS_IRCFG_NUM_BACKOFF_WORDS 0x01e00000 /* */ -+ -+/* -+ * PCI memory constants: Memory area 1 and 2 are the same size - -+ * (twice the PCI_TLB_PAGE_SIZE). The definition of -+ * CPU_TO_PCI_MEM_SIZE is coupled with the TLB setup routine -+ * sysLib.c/sysTlbInit(), in that it assumes that 2 pages of size -+ * PCI_TLB_PAGE_SIZE are set up in the TLB for each PCI memory space. -+ */ -+ -+#define CPU_TO_PCI_MEM_BASE1 0xE0000000 -+#define CPU_TO_PCI_MEM_SIZE1 (2*PCI_TLB_PAGE_SIZE) -+ -+ -+/* TLB attributes for PCI transactions */ -+ -+#define PCI_MMU_PAGEMASK 0x00003FFF -+#define MMU_PAGE_UNCACHED 0x00000010 -+#define MMU_PAGE_DIRTY 0x00000004 -+#define MMU_PAGE_VALID 0x00000002 -+#define MMU_PAGE_GLOBAL 0x00000001 -+#define PCI_MMU_PAGEATTRIB (MMU_PAGE_UNCACHED|MMU_PAGE_DIRTY|\ -+ MMU_PAGE_VALID|MMU_PAGE_GLOBAL) -+#define PCI_MEMORY_SPACE1_VIRT 0xE0000000 /* Used for non-prefet mem */ -+#define PCI_MEMORY_SPACE1_PHYS 0x80000000 -+#define PCI_TLB_PAGE_SIZE 0x01000000 -+#define TLB_HI_MASK 0xFFFFE000 -+#define TLB_LO_MASK 0x3FFFFFFF -+#define PAGEMASK_SHIFT 11 -+#define TLB_LO_SHIFT 6 -+ -+#define PCI_MAX_LATENCY 0xFFF /* Max PCI latency */ -+ -+#define HOST_PCI_DEV_ID 3 -+#define HOST_PCI_MBAR0 0x10000000 -+#define HOST_PCI_MBAR1 0x20000000 -+#define HOST_PCI_MBAR2 0x30000000 -+ -+#define HOST_PCI_SDRAM_BASEADDR HOST_PCI_MBAR1 -+#define PCI_DEVICE_MEM_SPACE 0x800000 -+ -+ -+typedef unsigned int AR531X_REG; -+ -+#define sysRegRead(phys) \ -+ (*(volatile AR531X_REG *)PHYS_TO_K1(phys)) -+ -+#define sysRegWrite(phys, val) \ -+ ((*(volatile AR531X_REG *)PHYS_TO_K1(phys)) = (val)) -+ -+ -+ -+/* -+ * This is board-specific data that is stored in a "fixed" location in flash. -+ * It is shared across operating systems, so it should not be changed lightly. -+ * The main reason we need it is in order to extract the ethernet MAC -+ * address(es). -+ */ -+struct ar531x_boarddata { -+ u32 magic; /* board data is valid */ -+#define AR531X_BD_MAGIC 0x35333131 /* "5311", for all 531x platforms */ -+ u16 cksum; /* checksum (starting with BD_REV 2) */ -+ u16 rev; /* revision of this struct */ -+#define BD_REV 4 -+ char boardName[64]; /* Name of board */ -+ u16 major; /* Board major number */ -+ u16 minor; /* Board minor number */ -+ u32 config; /* Board configuration */ -+#define BD_ENET0 0x00000001 /* ENET0 is stuffed */ -+#define BD_ENET1 0x00000002 /* ENET1 is stuffed */ -+#define BD_UART1 0x00000004 /* UART1 is stuffed */ -+#define BD_UART0 0x00000008 /* UART0 is stuffed (dma) */ -+#define BD_RSTFACTORY 0x00000010 /* Reset factory defaults stuffed */ -+#define BD_SYSLED 0x00000020 /* System LED stuffed */ -+#define BD_EXTUARTCLK 0x00000040 /* External UART clock */ -+#define BD_CPUFREQ 0x00000080 /* cpu freq is valid in nvram */ -+#define BD_SYSFREQ 0x00000100 /* sys freq is set in nvram */ -+#define BD_WLAN0 0x00000200 /* Enable WLAN0 */ -+#define BD_MEMCAP 0x00000400 /* CAP SDRAM @ memCap for testing */ -+#define BD_DISWATCHDOG 0x00000800 /* disable system watchdog */ -+#define BD_WLAN1 0x00001000 /* Enable WLAN1 (ar5212) */ -+#define BD_ISCASPER 0x00002000 /* FLAG for AR2312 */ -+#define BD_WLAN0_2G_EN 0x00004000 /* FLAG for radio0_2G */ -+#define BD_WLAN0_5G_EN 0x00008000 /* FLAG for radio0_2G */ -+#define BD_WLAN1_2G_EN 0x00020000 /* FLAG for radio0_2G */ -+#define BD_WLAN1_5G_EN 0x00040000 /* FLAG for radio0_2G */ -+ u16 resetConfigGpio; /* Reset factory GPIO pin */ -+ u16 sysLedGpio; /* System LED GPIO pin */ -+ -+ u32 cpuFreq; /* CPU core frequency in Hz */ -+ u32 sysFreq; /* System frequency in Hz */ -+ u32 cntFreq; /* Calculated C0_COUNT frequency */ -+ -+ u8 wlan0Mac[6]; -+ u8 enet0Mac[6]; -+ u8 enet1Mac[6]; -+ -+ u16 pciId; /* Pseudo PCIID for common code */ -+ u16 memCap; /* cap bank1 in MB */ -+ -+ /* version 3 */ -+ u8 wlan1Mac[6]; /* (ar5212) */ -+}; -+ -+#endif -+ -+#endif /* AR531X_H */ -diff -urN linux-mips-orig/drivers/net/ath/ar531xlnx.h linux-mips-new/drivers/net/ath/ar531xlnx.h ---- linux-mips-orig/drivers/net/ath/ar531xlnx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/ar531xlnx.h 2005-12-31 12:33:57.676538368 +0000 -@@ -0,0 +1,137 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * This file contains definitions needed in order to compile -+ * AR531X products for linux. Definitions that are largely -+ * AR531X-specific and independent of operating system belong -+ * in ar531x.h rather than this file. -+ */ -+#ifndef __AR531XLNX_H -+#define __AR531XLNX_H -+#include "ar531x.h" -+ -+#define MIPS_CPU_IRQ_BASE 0x00 -+#define AR531X_HIGH_PRIO 0x10 -+#define AR531X_MISC_IRQ_BASE 0x20 -+#define AR531X_GPIO_IRQ_BASE 0x30 -+ -+/* Software's idea of interrupts handled by "CPU Interrupt Controller" */ -+#if CONFIG_AR5315 -+#define AR531X_IRQ_NONE MIPS_CPU_IRQ_BASE+0 -+#define AR531X_IRQ_MISC_INTRS MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */ -+#define AR531X_IRQ_WLAN0_INTRS MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */ -+#define AR531X_IRQ_ENET0_INTRS MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */ -+#define AR531X_IRQ_LCBUS_PCI MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */ -+#define AR531X_IRQ_WLAN0_POLL MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */ -+#define AR531X_IRQ_CPU_CLOCK MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */ -+#else -+#define AR531X_IRQ_NONE MIPS_CPU_IRQ_BASE+0 -+#define AR531X_IRQ_WLAN0_INTRS MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */ -+#define AR531X_IRQ_ENET0_INTRS MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */ -+#define AR531X_IRQ_ENET1_INTRS MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */ -+#define AR531X_IRQ_WLAN1_INTRS MIPS_CPU_IRQ_BASE+5 /* C0_CAUSE: 0x2000 */ -+#define AR531X_IRQ_MISC_INTRS MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */ -+#define AR531X_IRQ_CPU_CLOCK MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */ -+#endif -+ -+/* Miscellaneous interrupts, which share IP6 or IP2 */ -+#define AR531X_MISC_IRQ_NONE AR531X_MISC_IRQ_BASE+0 -+#define AR531X_MISC_IRQ_TIMER AR531X_MISC_IRQ_BASE+1 -+#define AR531X_MISC_IRQ_AHB_PROC AR531X_MISC_IRQ_BASE+2 -+#define AR531X_MISC_IRQ_AHB_DMA AR531X_MISC_IRQ_BASE+3 -+#define AR531X_MISC_IRQ_GPIO AR531X_MISC_IRQ_BASE+4 -+#define AR531X_MISC_IRQ_UART0 AR531X_MISC_IRQ_BASE+5 -+#define AR531X_MISC_IRQ_UART0_DMA AR531X_MISC_IRQ_BASE+6 -+#define AR531X_MISC_IRQ_WATCHDOG AR531X_MISC_IRQ_BASE+7 -+#define AR531X_MISC_IRQ_LOCAL AR531X_MISC_IRQ_BASE+8 -+#define AR531X_MISC_IRQ_COUNT 9 -+ -+/* GPIO Interrupts [0..7], share AR531X_MISC_IRQ_GPIO */ -+#define AR531X_GPIO_IRQ_NONE AR531X_MISC_IRQ_BASE+0 -+#define AR531X_GPIO_IRQ(n) AR531X_MISC_IRQ_BASE+(n)+1 -+#define AR531X_GPIO_IRQ_COUNT 9 -+ -+#define PHYS_TO_K1(physaddr) KSEG1ADDR(physaddr) -+#define PHYS_TO_K0(physaddr) KSEG0ADDR(physaddr) -+#define UNMAPPED_TO_PHYS(vaddr) PHYSADDR(vaddr) -+#define IS_UNMAPPED_VADDR(vaddr) \ -+ ((KSEGX(vaddr) == KSEG0) || (KSEGX(vaddr) == KSEG1)) -+ -+/* IOCTL commands for /proc/ar531x */ -+#define AR531X_CTRL_DO_BREAKPOINT 1 -+#define AR531X_CTRL_DO_MADWIFI 2 -+ -+/* -+ * Definitions for operating system portability. -+ * These are vxWorks-->Linux translations. -+ */ -+#define LOCAL static -+#define BOOL int -+#define TRUE 1 -+#define FALSE 0 -+#define UINT8 u8 -+#define UINT16 u16 -+#define UINT32 u32 -+#define PRINTF printk -+#if /* DEBUG */ 1 -+#define DEBUG_PRINTF printk -+#define printf printk -+#define INLINE -+#else -+DEBUG_PRINTF while (0) printk -+#define INLINE inline -+#endif -+#define sysUDelay(usecs) udelay(usecs) -+#define sysMsDelay(msecs) mdelay(msecs) -+typedef volatile UINT8 *VIRT_ADDR; -+#define MALLOC(sz) kmalloc(sz, GFP_KERNEL) -+#define MALLOC_NOSLEEP(sz) kmalloc(sz, GFP_ATOMIC) -+#define FREE(ptr) kfree((void *)ptr) -+#define BSP_BUG() do { printk("kernel BSP BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0) -+#define BSP_BUG_ON(condition) do { if (unlikely((condition)!=0)) BSP_BUG(); } while(0) -+#define ASSERT(x) BSP_BUG_ON(!(x)) -+ -+extern struct ar531x_boarddata *ar531x_board_configuration; -+extern char *ar531x_radio_configuration; -+extern char *enet_mac_address_get(int MACUnit); -+ -+extern void kgdbInit(void); -+extern int kgdbEnabled(void); -+extern void breakpoint(void); -+extern int kgdbInterrupt(void); -+extern unsigned int ar531x_cpu_frequency(void); -+extern unsigned int ar531x_sys_frequency(void); -+ -+/* GPIO support */ -+extern struct irqaction spurious_gpio; -+extern unsigned int gpioIntMask; -+extern void ar531x_gpio_intr_init(int irq_base); -+extern void ar531x_gpio_ctrl_output(int gpio); -+extern void ar531x_gpio_ctrl_input(int gpio); -+extern void ar531x_gpio_set(int gpio, int val); -+extern int ar531x_gpio_get(int gpio); -+extern void ar531x_gpio_intr_enable(unsigned int irq); -+extern void ar531x_gpio_intr_disable(unsigned int irq); -+ -+/* Watchdog Timer support */ -+extern int watchdog_start(unsigned int milliseconds); -+extern int watchdog_stop(void); -+extern int watchdog_is_enabled(void); -+extern unsigned int watchdog_min_timer_reached(void); -+extern void watchdog_notify_alive(void); -+ -+#define A_DATA_CACHE_INVAL(start, length) \ -+ dma_cache_inv((UINT32)(start),(length)) -+ -+#define sysWbFlush() mb() -+ -+#define intDisable(x) cli() -+#define intEnable(x) sti() -+ -+#endif /* __AR531XLNX_H */ -diff -urN linux-mips-orig/drivers/net/ath/ipPhy.c linux-mips-new/drivers/net/ath/ipPhy.c ---- linux-mips-orig/drivers/net/ath/ipPhy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/ipPhy.c 2005-12-31 12:33:57.677538216 +0000 -@@ -0,0 +1,833 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * Manage the ICPLUS ethernet PHY. -+ * -+ * All definitions in this file are operating system independent! -+ */ -+ -+#if defined(linux) -+#include <linux/config.h> -+#include <linux/types.h> -+#include <linux/netdevice.h> -+#include <linux/etherdevice.h> -+#include <linux/delay.h> -+ -+#include "ar531xlnx.h" -+#endif -+ -+#include "ae531xmac.h" -+#include "ae531xreg.h" -+#include "ipPhy.h" -+ -+/* PHY selections and access functions */ -+ -+typedef enum { -+ PHY_SRCPORT_INFO, -+ PHY_PORTINFO_SIZE, -+} PHY_CAP_TYPE; -+ -+typedef enum { -+ PHY_SRCPORT_NONE, -+ PHY_SRCPORT_VLANTAG, -+ PHY_SRCPORT_TRAILER, -+} PHY_SRCPORT_TYPE; -+ -+#ifdef DEBUG -+#define DRV_DEBUG 1 -+#endif -+#define DRV_DEBUG 1 -+ -+#if DRV_DEBUG -+#define DRV_DEBUG_PHYERROR 0x00000001 -+#define DRV_DEBUG_PHYCHANGE 0x00000002 -+#define DRV_DEBUG_PHYSETUP 0x00000004 -+ -+int ipPhyDebug = DRV_DEBUG_PHYERROR; -+ -+#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ -+{ \ -+ if (ipPhyDebug & (FLG)) { \ -+ logMsg(X0, X1, X2, X3, X4, X5, X6); \ -+ } \ -+} -+ -+#define DRV_MSG(x,a,b,c,d,e,f) \ -+ logMsg(x,a,b,c,d,e,f) -+ -+#define DRV_PRINT(FLG, X) \ -+{ \ -+ if (ipPhyDebug & (FLG)) { \ -+ printf X; \ -+ } \ -+} -+ -+#else /* !DRV_DEBUG */ -+#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6) -+#define DRV_MSG(x,a,b,c,d,e,f) -+#define DRV_PRINT(DBG_SW,X) -+#endif -+ -+#define IP_LAN_PORT_VLAN 1 -+#define IP_WAN_PORT_VLAN 2 -+ -+#define ENET_UNIT_DEFAULT 0 -+ -+/* -+ * Track per-PHY port information. -+ */ -+typedef struct { -+ BOOL isEnetPort; /* normal enet port */ -+ BOOL isPhyAlive; /* last known state of link */ -+ int ethUnit; /* MAC associated with this phy port */ -+ UINT32 phyBase; -+ UINT32 phyAddr; /* PHY registers associated with this phy port */ -+ UINT32 VLANTableSetting; /* Value to be written to VLAN table */ -+} ipPhyInfo_t; -+ -+/* -+ * Per-PHY information, indexed by PHY unit number. -+ */ -+ipPhyInfo_t ipPhyInfo[] = { -+ /* -+ * On AP30/AR5312, all PHYs are associated with MAC0. -+ * AP30/AR5312's MAC1 isn't used for anything. -+ * CONFIG_VENETDEV==1 (router) configuration: -+ * Ports 0,1,2, and 3 are "LAN ports" -+ * Port 4 is a WAN port -+ * Port 5 connects to MAC0 in the AR5312 -+ * CONFIG_VENETDEV==0 (bridge) configuration: -+ * Ports 0,1,2,3,4 are "LAN ports" -+ * Port 5 connects to the MAC0 in the AR5312 -+ */ -+ {TRUE, /* phy port 0 -- LAN port 0 */ -+ FALSE, -+ ENET_UNIT_DEFAULT, -+ (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET), -+ IP_PHY0_ADDR, -+ IP_LAN_PORT_VLAN -+ }, -+ -+ {TRUE, /* phy port 1 -- LAN port 1 */ -+ FALSE, -+ ENET_UNIT_DEFAULT, -+ (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET), -+ IP_PHY1_ADDR, -+ IP_LAN_PORT_VLAN -+ }, -+ -+ {TRUE, /* phy port 2 -- LAN port 2 */ -+ FALSE, -+ ENET_UNIT_DEFAULT, -+ (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET), -+ IP_PHY2_ADDR, -+ IP_LAN_PORT_VLAN -+ }, -+ -+ {TRUE, /* phy port 3 -- LAN port 3 */ -+ FALSE, -+ ENET_UNIT_DEFAULT, -+ (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET), -+ IP_PHY3_ADDR, -+ IP_LAN_PORT_VLAN -+ }, -+ -+ {TRUE, /* phy port 4 -- WAN port or LAN port 4 */ -+ FALSE, -+ ENET_UNIT_DEFAULT, -+ (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET), -+ IP_PHY4_ADDR, -+ IP_LAN_PORT_VLAN /* Send to all ports */ -+ }, -+ -+ {FALSE, /* phy port 5 -- CPU port (no RJ45 connector) */ -+ TRUE, -+ ENET_UNIT_DEFAULT, -+ (UINT32) (PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET), -+ 0x00, -+ IP_LAN_PORT_VLAN /* Send to all ports */ -+ }, -+}; -+ -+#define IP_GLOBALREGBASE ((UINT32) (PHYS_TO_K1(AR531X_ENET0))) -+ -+#define IP_PHY_MAX (sizeof(ipPhyInfo) / sizeof(ipPhyInfo[0])) -+ -+/* Range of valid PHY IDs is [MIN..MAX] */ -+#define IP_ID_MIN 0 -+#define IP_ID_MAX (IP_PHY_MAX-1) -+ -+/* Convenience macros to access myPhyInfo */ -+#define IP_IS_ENET_PORT(phyUnit) (ipPhyInfo[phyUnit].isEnetPort) -+#define IP_IS_PHY_ALIVE(phyUnit) (ipPhyInfo[phyUnit].isPhyAlive) -+#define IP_ETHUNIT(phyUnit) (ipPhyInfo[phyUnit].ethUnit) -+#define IP_PHYBASE(phyUnit) (ipPhyInfo[phyUnit].phyBase) -+#define IP_PHYADDR(phyUnit) (ipPhyInfo[phyUnit].phyAddr) -+#define IP_VLAN_TABLE_SETTING(phyUnit) (ipPhyInfo[phyUnit].VLANTableSetting) -+ -+ -+#define IP_IS_ETHUNIT(phyUnit, ethUnit) \ -+ (IP_IS_ENET_PORT(phyUnit) && \ -+ IP_ETHUNIT(phyUnit) == (ethUnit)) -+ -+/* Forward references */ -+BOOL ip_phyIsLinkAlive(int phyUnit); -+LOCAL void ip_VLANInit(int ethUnit); -+LOCAL void ip_verifyReady(int ethUnit); -+#if DEBUG -+void ip_phyShow(int phyUnit); -+void ip_phySet(int phyUnit, UINT32 regnum, UINT32 value); -+void ip_globalSet(UINT32 phyAddr, UINT32 regnum, UINT32 value); -+#endif -+ -+/****************************************************************************** -+* -+* ip_phyIsLinkAlive - test to see if the specified link is alive -+* -+* RETURNS: -+* TRUE --> link is alive -+* FALSE --> link is down -+*/ -+BOOL -+ip_phyIsLinkAlive(int phyUnit) -+{ -+ UINT16 phyHwStatus; -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ -+ phyBase = IP_PHYBASE(phyUnit); -+ phyAddr = IP_PHYADDR(phyUnit); -+ -+ phyHwStatus = phyRegRead(phyBase, phyAddr, IP_PHY_STATUS); -+ -+ if (phyHwStatus & IP_STATUS_LINK_PASS) { -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+ -+/****************************************************************************** -+* -+* ip_VLANInit - initialize "port-based VLANs" for the specified enet unit. -+*/ -+LOCAL void -+ip_VLANInit(int ethUnit) -+{ -+ int phyUnit; -+ UINT32 phyBase; -+ UINT32 phyReg; -+ -+ phyBase = IP_GLOBALREGBASE; -+ -+ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { -+ if (IP_ETHUNIT(phyUnit) != ethUnit) { -+ continue; -+ } -+ phyRegWrite(phyBase, IP_GLOBAL_PHY29_ADDR, -+ IP_GLOBAL_PHY29_24_REG + ((phyUnit == 5) ? (phyUnit + 1) : phyUnit), -+ IP_VLAN_TABLE_SETTING(phyUnit)); -+ -+ /* Send all packets to all ports */ -+ phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_1_REG); -+ phyReg = phyReg | ((1 << phyUnit) << IP_VLAN1_OUTPUT_PORT_MASK_S); -+ phyRegWrite(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_1_REG, phyReg); -+ } -+ phyReg = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_9_REG); -+ phyReg = phyReg | TAG_VLAN_ENABLE; -+ phyReg = phyReg & ~VID_INDX_SEL_M; -+ phyRegWrite(phyBase, IP_GLOBAL_PHY30_ADDR, IP_GLOBAL_PHY30_9_REG, phyReg); -+ -+} -+ -+ -+LOCAL void -+ip_verifyReady(int ethUnit) -+{ -+ int phyUnit; -+ UINT32 phyBase = 0; -+ UINT32 phyAddr; -+ UINT16 phyID1; -+ UINT16 phyID2; -+ -+ /* -+ * The first read to the Phy port registers always fails and -+ * returns 0. So get things started with a bogus read. -+ */ -+ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { -+ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ -+ phyBase = IP_PHYBASE(phyUnit); -+ phyAddr = IP_PHYADDR(phyUnit); -+ -+ phyID1 = phyRegRead(phyBase, phyAddr, IP_PHY_ID1); /* returns 0 */ -+ break; -+ } -+ -+ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { -+ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ -+ /*******************/ -+ /* Verify phy port */ -+ /*******************/ -+ phyBase = IP_PHYBASE(phyUnit); -+ phyAddr = IP_PHYADDR(phyUnit); -+ -+ phyID1 = phyRegRead(phyBase, phyAddr, IP_PHY_ID1); -+ if (phyID1 != IP_PHY_ID1_EXPECTATION) { -+ DRV_PRINT(DRV_DEBUG_PHYERROR, -+ ("Invalid PHY ID1 for enet%d port%d. Expected 0x%04x, read 0x%04x\n", -+ ethUnit, -+ phyUnit, -+ IP_PHY_ID1_EXPECTATION, -+ phyID1)); -+ return; -+ } -+ -+ phyID2 = phyRegRead(phyBase, phyAddr, IP_PHY_ID2); -+ if ((phyID2 & IP_OUI_LSB_MASK) != IP_OUI_LSB_EXPECTATION) { -+ DRV_PRINT(DRV_DEBUG_PHYERROR, -+ ("Invalid PHY ID2 for enet%d port %d. Expected 0x%04x, read 0x%04x\n", -+ ethUnit, -+ phyUnit, -+ IP_OUI_LSB_EXPECTATION, -+ phyID2)); -+ return; -+ } -+ -+ DRV_PRINT(DRV_DEBUG_PHYSETUP, -+ ("Found PHY enet%d port%d: model 0x%x revision 0x%x\n", -+ ethUnit, -+ phyUnit, -+ (phyID2 & IP_MODEL_NUM_MASK) >> IP_MODEL_NUM_SHIFT, -+ (phyID2 & IP_REV_NUM_MASK) >> IP_REV_NUM_SHIFT)); -+ -+ } -+} -+ -+ -+/****************************************************************************** -+* -+* ip_phySetup - reset and setup the PHY associated with -+* the specified MAC unit number. -+* -+* Resets the associated PHY port. -+* -+* RETURNS: -+* TRUE --> associated PHY is alive -+* FALSE --> no LINKs on this ethernet unit -+*/ -+ -+BOOL -+ip_phySetup(int ethUnit, UINT32 _phyBase) -+{ -+ int phyUnit; -+ UINT16 phyHwStatus; -+ UINT16 timeout; -+ int liveLinks = 0; -+ UINT32 phyBase = 0; -+ BOOL foundPhy = FALSE; -+ UINT32 phyAddr; -+ -+ /* Reset PHYs*/ -+ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { -+ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ -+ phyBase = IP_PHYBASE(phyUnit); -+ phyAddr = IP_PHYADDR(phyUnit); -+ -+ phyRegWrite(phyBase, phyAddr, IP_PHY_CONTROL, -+ IP_CTRL_SOFTWARE_RESET); -+ } -+ /* -+ * After the phy is reset, it takes a little while before -+ * it can respond properly. -+ */ -+ sysMsDelay(300); -+ /* Verify that the switch is what we think it is, and that it's ready */ -+ ip_verifyReady(ethUnit); -+ -+ /* See if there's any configuration data for this enet */ -+ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { -+ if (IP_ETHUNIT(phyUnit) != ethUnit) { -+ continue; -+ } -+ -+ phyBase = IP_PHYBASE(phyUnit); -+ foundPhy = TRUE; -+ break; -+ } -+ -+ if (!foundPhy) { -+ return FALSE; /* No PHY's configured for this ethUnit */ -+ } -+ -+#ifdef COBRA_TODO -+ /* Initialize global switch settings */ -+ -+ /* Initialize the aging time */ -+ -+ /* Set the learning properties */ -+#endif -+ -+ /* start auto negogiation on each phy */ -+ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { -+ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ -+ phyBase = IP_PHYBASE(phyUnit); -+ phyAddr = IP_PHYADDR(phyUnit); -+ -+ phyRegWrite(phyBase, phyAddr, IP_AUTONEG_ADVERT, -+ IP_ADVERTISE_ALL); -+ phyRegWrite(phyBase, phyAddr, IP_PHY_CONTROL, -+ IP_CTRL_AUTONEGOTIATION_ENABLE | IP_CTRL_START_AUTONEGOTIATION); -+ } -+ -+ /* -+ * Wait up to .75 seconds for ALL associated PHYs to finish -+ * autonegotiation. The only way we get out of here sooner is -+ * if ALL PHYs are connected AND finish autonegotiation. -+ */ -+ timeout=5; -+ for (phyUnit=0; (phyUnit < IP_PHY_MAX) /*&& (timeout > 0) */; phyUnit++) { -+ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ for (;;) { -+ phyBase = IP_PHYBASE(phyUnit); -+ phyAddr = IP_PHYADDR(phyUnit); -+ -+ phyHwStatus = phyRegRead(phyBase, phyAddr, IP_PHY_STATUS); -+ -+ if (IP_AUTONEG_DONE(phyHwStatus)) { -+ DRV_PRINT(DRV_DEBUG_PHYSETUP, -+ ("Port %d, Neg Success\n", phyUnit)); -+ break; -+ } -+ if (timeout == 0) { -+ DRV_PRINT(DRV_DEBUG_PHYSETUP, -+ ("Port %d, Negogiation timeout\n", phyUnit)); -+ break; -+ } -+ if (--timeout == 0) { -+ DRV_PRINT(DRV_DEBUG_PHYSETUP, -+ ("Port %d, Negogiation timeout\n", phyUnit)); -+ break; -+ } -+ -+ sysMsDelay(150); -+ } -+ } -+ -+ /* -+ * All PHYs have had adequate time to autonegotiate. -+ * Now initialize software status. -+ * -+ * It's possible that some ports may take a bit longer -+ * to autonegotiate; but we can't wait forever. They'll -+ * get noticed by mv_phyCheckStatusChange during regular -+ * polling activities. -+ */ -+ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { -+ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ -+ if (ip_phyIsLinkAlive(phyUnit)) { -+ liveLinks++; -+ IP_IS_PHY_ALIVE(phyUnit) = TRUE; -+ } else { -+ IP_IS_PHY_ALIVE(phyUnit) = FALSE; -+ } -+ -+ DRV_PRINT(DRV_DEBUG_PHYSETUP, -+ ("eth%d: Phy Status=%4.4x\n", -+ ethUnit, -+ phyRegRead(IP_PHYBASE(phyUnit), -+ IP_PHYADDR(phyUnit), -+ IP_PHY_STATUS))); -+ } -+#if 0 -+ /* XXX Divy. Disable WAN/LAN seggregation. See bug 17866 */ -+ ip_VLANInit(ethUnit); -+#endif -+ return (liveLinks > 0); -+} -+ -+/****************************************************************************** -+* -+* ip_phyIsDuplexFull - Determines whether the phy ports associated with the -+* specified device are FULL or HALF duplex. -+* -+* RETURNS: -+* 1 --> FULL -+* 0 --> HALF -+*/ -+int -+ip_phyIsFullDuplex(int ethUnit) -+{ -+ int phyUnit; -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ UINT16 phyHwStatus; -+ -+ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { -+ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ -+ if (ip_phyIsLinkAlive(phyUnit)) { -+ -+ phyBase = IP_PHYBASE(phyUnit); -+ phyAddr = IP_PHYADDR(phyUnit); -+ -+ phyHwStatus = phyRegRead(phyBase, phyAddr, IP_LINK_PARTNER_ABILITY); -+ printk("ipPhy.c: phyHwStatus 0x%x\n",phyHwStatus); -+ if ((phyHwStatus & IP_LINK_100BASETX_FULL_DUPLEX) || -+ (phyHwStatus & IP_LINK_10BASETX_FULL_DUPLEX)) { -+ return TRUE; -+ } -+ } -+ return -1; -+ } -+ -+ return FALSE; -+ -+} -+ -+ -+/****************************************************************************** -+* -+* ip_phyIsSpeed100 - Determines the speed of phy ports associated with the -+* specified device. -+* -+* RETURNS: -+* TRUE --> 100Mbit -+* FALSE --> 10Mbit -+*/ -+ -+BOOL -+ip_phyIsSpeed100(int ethUnit) -+{ -+ int phyUnit; -+ UINT16 phyHwStatus; -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ -+ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { -+ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ -+ if (ip_phyIsLinkAlive(phyUnit)) { -+ -+ phyBase = IP_PHYBASE(phyUnit); -+ phyAddr = IP_PHYADDR(phyUnit); -+ -+ phyHwStatus = phyRegRead(phyBase, phyAddr, IP_LINK_PARTNER_ABILITY); -+ -+ if (phyHwStatus & IP_LINK_100BASETX) { -+ return TRUE; -+ } -+ } -+ } -+ -+ return FALSE; -+} -+ -+/***************************************************************************** -+* -+* ip_phyCheckStatusChange -- checks for significant changes in PHY state. -+* -+* A "significant change" is: -+* dropped link (e.g. ethernet cable unplugged) OR -+* autonegotiation completed + link (e.g. ethernet cable plugged in) -+* -+* When a PHY is plugged in, phyLinkGained is called. -+* When a PHY is unplugged, phyLinkLost is called. -+*/ -+ -+void -+ip_phyCheckStatusChange(int ethUnit) -+{ -+ -+ int phyUnit; -+ UINT16 phyHwStatus; -+ ipPhyInfo_t *lastStatus; -+ int linkCount = 0; -+ int lostLinks = 0; -+ int gainedLinks = 0; -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ -+ for (phyUnit=0; phyUnit < IP_PHY_MAX; phyUnit++) { -+ if (!IP_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ -+ phyBase = IP_PHYBASE(phyUnit); -+ phyAddr = IP_PHYADDR(phyUnit); -+ -+ lastStatus = &ipPhyInfo[phyUnit]; -+ phyHwStatus = phyRegRead(phyBase, phyAddr, IP_PHY_STATUS); -+ -+ if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */ -+ /* See if we've lost link */ -+ if (phyHwStatus & IP_STATUS_LINK_PASS) { -+ linkCount++; -+ } else { -+ lostLinks++; -+#ifdef COBRA_TODO -+ mv_flushATUDB(phyUnit); -+#endif -+ DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d down\n", -+ ethUnit, phyUnit)); -+ lastStatus->isPhyAlive = FALSE; -+ } -+ } else { /* last known link status was DEAD */ -+ /* Check for AutoNegotiation complete */ -+ if (IP_AUTONEG_DONE(phyHwStatus)) { -+ gainedLinks++; -+ linkCount++; -+ DRV_PRINT(DRV_DEBUG_PHYCHANGE,("\nenet%d port%d up\n", -+ ethUnit, phyUnit)); -+ lastStatus->isPhyAlive = TRUE; -+ } -+ } -+ } -+ -+ if (linkCount == 0) { -+ if (lostLinks) { -+ /* We just lost the last link for this MAC */ -+ phyLinkLost(ethUnit); -+ } -+ } else { -+ if (gainedLinks == linkCount) { -+ /* We just gained our first link(s) for this MAC */ -+ phyLinkGained(ethUnit); -+ } -+ } -+ -+} -+ -+#if DEBUG -+ -+/* Define the registers of interest for a phyShow command */ -+typedef struct ipRegisterTableEntry_s { -+ UINT32 regNum; -+ char *regIdString; -+} ipRegisterTableEntry_t; -+ -+ipRegisterTableEntry_t ipPhyRegisterTable[] = { -+ {IP_PHY_CONTROL, "PHY Control "}, -+ {IP_PHY_STATUS, "PHY Status "}, -+ {IP_PHY_ID1, "PHY Identifier 1 "}, -+ {IP_PHY_ID2, "PHY Identifier 2 "}, -+ {IP_AUTONEG_ADVERT, "Auto-Negotiation Advertisement "}, -+ {IP_LINK_PARTNER_ABILITY, "Link Partner Ability "}, -+ {IP_AUTONEG_EXPANSION, "Auto-Negotiation Expansion "}, -+}; -+int ipPhyNumRegs = sizeof(ipPhyRegisterTable) / sizeof(ipPhyRegisterTable[0]); -+ -+ -+ipRegisterTableEntry_t ipPhy29GlobalRegisterTable[] = { -+ {IP_GLOBAL_PHY29_18_REG, "29_18_REG "}, -+ {IP_GLOBAL_PHY29_19_REG, "29_19_REG "}, -+ {IP_GLOBAL_PHY29_20_REG, "29_20_REG "}, -+ {IP_GLOBAL_PHY29_21_REG, "29_21_REG "}, -+ {IP_GLOBAL_PHY29_22_REG, "29_22_REG "}, -+ {IP_GLOBAL_PHY29_23_REG, "29_23_REG "}, -+ {IP_GLOBAL_PHY29_24_REG, "29_24_REG "}, -+ {IP_GLOBAL_PHY29_25_REG, "29_25_REG "}, -+ {IP_GLOBAL_PHY29_26_REG, "29_26_REG "}, -+ {IP_GLOBAL_PHY29_27_REG, "29_27_REG "}, -+ {IP_GLOBAL_PHY29_28_REG, "29_28_REG "}, -+ {IP_GLOBAL_PHY29_29_REG, "29_29_REG "}, -+ {IP_GLOBAL_PHY29_30_REG, "29_30_REG "}, -+ {IP_GLOBAL_PHY29_31_REG, "29_31_REG "}, -+}; -+int ipPhy29GlobalNumRegs = -+ sizeof(ipPhy29GlobalRegisterTable) / sizeof(ipPhy29GlobalRegisterTable[0]); -+ -+ -+ipRegisterTableEntry_t ipPhy30GlobalRegisterTable[] = { -+ {IP_GLOBAL_PHY30_0_REG, "30_0_REG "}, -+ {IP_GLOBAL_PHY30_1_REG, "30_1_REG "}, -+ {IP_GLOBAL_PHY30_2_REG, "30_2_REG "}, -+ {IP_GLOBAL_PHY30_3_REG, "30_3_REG "}, -+ {IP_GLOBAL_PHY30_4_REG, "30_4_REG "}, -+ {IP_GLOBAL_PHY30_5_REG, "30_5_REG "}, -+ {IP_GLOBAL_PHY30_6_REG, "30_6_REG "}, -+ {IP_GLOBAL_PHY30_7_REG, "30_7_REG "}, -+ {IP_GLOBAL_PHY30_8_REG, "30_8_REG "}, -+ {IP_GLOBAL_PHY30_9_REG, "30_9_REG "}, -+ {IP_GLOBAL_PHY30_10_REG, "30_10_REG "}, -+ {IP_GLOBAL_PHY30_11_REG, "30_11_REG "}, -+ {IP_GLOBAL_PHY30_12_REG, "30_12_REG "}, -+ {IP_GLOBAL_PHY30_13_REG, "30_13_REG "}, -+ {IP_GLOBAL_PHY30_16_REG, "30_16_REG "}, -+ {IP_GLOBAL_PHY30_17_REG, "30_17_REG "}, -+ {IP_GLOBAL_PHY30_18_REG, "30_18_REG "}, -+ {IP_GLOBAL_PHY30_20_REG, "30_20_REG "}, -+ {IP_GLOBAL_PHY30_21_REG, "30_21_REG "}, -+ {IP_GLOBAL_PHY30_22_REG, "30_22_REG "}, -+ {IP_GLOBAL_PHY30_23_REG, "30_23_REG "}, -+ {IP_GLOBAL_PHY30_24_REG, "30_24_REG "}, -+ {IP_GLOBAL_PHY30_25_REG, "30_25_REG "}, -+ {IP_GLOBAL_PHY30_26_REG, "30_26_REG "}, -+ {IP_GLOBAL_PHY30_27_REG, "30_27_REG "}, -+ {IP_GLOBAL_PHY30_28_REG, "30_28_REG "}, -+ {IP_GLOBAL_PHY30_29_REG, "30_29_REG "}, -+ {IP_GLOBAL_PHY30_30_REG, "30_30_REG "}, -+ {IP_GLOBAL_PHY30_31_REG, "30_31_REG "}, -+}; -+int ipPhy30GlobalNumRegs = -+ sizeof(ipPhy30GlobalRegisterTable) / sizeof(ipPhy30GlobalRegisterTable[0]); -+ -+ipRegisterTableEntry_t ipPhy31GlobalRegisterTable[] = { -+ {IP_GLOBAL_PHY31_0_REG, "31_0_REG "}, -+ {IP_GLOBAL_PHY31_1_REG, "31_1_REG "}, -+ {IP_GLOBAL_PHY31_2_REG, "31_2_REG "}, -+ {IP_GLOBAL_PHY31_3_REG, "31_3_REG "}, -+ {IP_GLOBAL_PHY31_4_REG, "31_4_REG "}, -+ {IP_GLOBAL_PHY31_5_REG, "31_5_REG "}, -+ {IP_GLOBAL_PHY31_6_REG, "31_6_REG "}, -+}; -+ -+int ipPhy31GlobalNumRegs = -+ sizeof(ipPhy31GlobalRegisterTable) / sizeof(ipPhy31GlobalRegisterTable[0]); -+ -+ -+/***************************************************************************** -+* -+* ip_phyShow - Dump the state of a PHY. -+* There are two sets of registers for each phy port: -+* "phy registers" and -+* "switch port registers" -+* We dump 'em all, plus the switch global registers. -+*/ -+void -+ip_phyShow(int phyUnit) -+{ -+ int i; -+ UINT16 value; -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ -+ if (!ip_validPhyId(phyUnit)) { -+ return; -+ } -+ -+ phyBase = IP_PHYBASE(phyUnit); -+ phyAddr = IP_PHYADDR(phyUnit); -+ -+ printf("PHY state for PHY%d (enet%d, phyBase 0x%8x, phyAddr 0x%x)\n", -+ phyUnit, -+ IP_ETHUNIT(phyUnit), -+ IP_PHYBASE(phyUnit), -+ IP_PHYADDR(phyUnit)); -+ -+ printf("PHY Registers:\n"); -+ for (i=0; i < ipPhyNumRegs; i++) { -+ -+ value = phyRegRead(phyBase, phyAddr, ipPhyRegisterTable[i].regNum); -+ -+ printf("Reg %02d (0x%02x) %s = 0x%08x\n", -+ ipPhyRegisterTable[i].regNum, -+ ipPhyRegisterTable[i].regNum, -+ ipPhyRegisterTable[i].regIdString, -+ value); -+ } -+ -+ phyBase = IP_GLOBALREGBASE; -+ -+ printf("Switch Global Registers:\n"); -+ printf("Phy29 Registers:\n"); -+ for (i=0; i < ipPhy29GlobalNumRegs; i++) { -+ -+ value = phyRegRead(phyBase, IP_GLOBAL_PHY29_ADDR, -+ ipPhy29GlobalRegisterTable[i].regNum); -+ -+ printf("Reg %02d (0x%02x) %s = 0x%08x\n", -+ ipPhy29GlobalRegisterTable[i].regNum, -+ ipPhy29GlobalRegisterTable[i].regNum, -+ ipPhy29GlobalRegisterTable[i].regIdString, -+ value); -+ } -+ -+ printf("Phy30 Registers:\n"); -+ for (i=0; i < ipPhy30GlobalNumRegs; i++) { -+ -+ value = phyRegRead(phyBase, IP_GLOBAL_PHY30_ADDR, -+ ipPhy30GlobalRegisterTable[i].regNum); -+ -+ printf("Reg %02d (0x%02x) %s = 0x%08x\n", -+ ipPhy30GlobalRegisterTable[i].regNum, -+ ipPhy30GlobalRegisterTable[i].regNum, -+ ipPhy30GlobalRegisterTable[i].regIdString, -+ value); -+ } -+ printf("Phy31 Registers:\n"); -+ for (i=0; i < ipPhy31GlobalNumRegs; i++) { -+ -+ value = phyRegRead(phyBase, IP_GLOBAL_PHY31_ADDR, -+ ipPhy31GlobalRegisterTable[i].regNum); -+ -+ printf("Reg %02d (0x%02x) %s = 0x%08x\n", -+ ipPhy31GlobalRegisterTable[i].regNum, -+ ipPhy31GlobalRegisterTable[i].regNum, -+ ipPhy31GlobalRegisterTable[i].regIdString, -+ value); -+ } -+} -+ -+/***************************************************************************** -+* -+* ip_phySet - Modify the value of a PHY register (debug only). -+*/ -+void -+ip_phySet(int phyUnit, UINT32 regnum, UINT32 value) -+{ -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ -+ if (ip_validPhyId(phyUnit)) { -+ -+ phyBase = IP_PHYBASE(phyUnit); -+ phyAddr = IP_PHYADDR(phyUnit); -+ -+ phyRegWrite(phyBase, phyAddr, regnum, value); -+ } -+} -+ -+/***************************************************************************** -+* -+* ip_globalSet - Modify the value of a global register -+* (debug only). -+*/ -+void -+ip_globalSet(UINT32 phyAddr, UINT32 regnum, UINT32 value) -+{ -+ UINT32 phyBase; -+ -+ phyBase = IP_GLOBALREGBASE; -+ -+ phyRegWrite(phyBase, phyAddr, regnum, value); -+} -+ -+ -+#endif -diff -urN linux-mips-orig/drivers/net/ath/ipPhy.h linux-mips-new/drivers/net/ath/ipPhy.h ---- linux-mips-orig/drivers/net/ath/ipPhy.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/ipPhy.h 2005-12-31 12:33:57.678538064 +0000 -@@ -0,0 +1,172 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * icPhy.h - definitions for the ethernet PHY. -+ * This code supports a simple 1-port ethernet phy, ICPLUS, -+ * All definitions in this file are operating system independent! -+ */ -+ -+#ifndef IPPHY_H -+#define IPPHY_H -+ -+/*****************/ -+/* PHY Registers */ -+/*****************/ -+#define IP_PHY_CONTROL 0 -+#define IP_PHY_STATUS 1 -+#define IP_PHY_ID1 2 -+#define IP_PHY_ID2 3 -+#define IP_AUTONEG_ADVERT 4 -+#define IP_LINK_PARTNER_ABILITY 5 -+#define IP_AUTONEG_EXPANSION 6 -+ -+ -+/* IP_PHY_CONTROL fields */ -+#define IP_CTRL_SOFTWARE_RESET 0x8000 -+#define IP_CTRL_SPEED_100 0x2000 -+#define IP_CTRL_AUTONEGOTIATION_ENABLE 0x1000 -+#define IP_CTRL_START_AUTONEGOTIATION 0x0200 -+#define IP_CTRL_SPEED_FULL_DUPLEX 0x0100 -+ -+/* Phy status fields */ -+#define IP_STATUS_AUTO_NEG_DONE 0x0020 -+#define IP_STATUS_LINK_PASS 0x0004 -+ -+#define IP_AUTONEG_DONE(ip_phy_status) \ -+ (((ip_phy_status) & \ -+ (IP_STATUS_AUTO_NEG_DONE)) == \ -+ (IP_STATUS_AUTO_NEG_DONE)) -+ -+/* ICPLUS_PHY_ID1 fields */ -+#define IP_PHY_ID1_EXPECTATION 0x0243 /* OUI >> 6 */ -+ -+/* ICPLUS_PHY_ID2 fields */ -+#define IP_OUI_LSB_MASK 0xfc00 -+#define IP_OUI_LSB_EXPECTATION 0x0c00 -+#define IP_OUI_LSB_SHIFT 10 -+#define IP_MODEL_NUM_MASK 0x03f0 -+#define IP_MODEL_NUM_SHIFT 4 -+#define IP_REV_NUM_MASK 0x000f -+#define IP_REV_NUM_SHIFT 0 -+ -+/* Link Partner ability */ -+#define IP_LINK_100BASETX_FULL_DUPLEX 0x0100 -+#define IP_LINK_100BASETX 0x0080 -+#define IP_LINK_10BASETX_FULL_DUPLEX 0x0040 -+#define IP_LINK_10BASETX 0x0020 -+ -+/* Advertisement register. */ -+#define IP_ADVERTISE_100FULL 0x0100 -+#define IP_ADVERTISE_100HALF 0x0080 -+#define IP_ADVERTISE_10FULL 0x0040 -+#define IP_ADVERTISE_10HALF 0x0020 -+ -+#define IP_ADVERTISE_ALL (IP_ADVERTISE_10HALF | IP_ADVERTISE_10FULL | \ -+ IP_ADVERTISE_100HALF | IP_ADVERTISE_100FULL) -+ -+ -+#define IP_VLAN_TAG_VALID 0x81 -+#define IP_VLAN_TAG_SIZE 4 -+#define IP_VLAN_TAG_OFFSET 12 /* After DA & SA */ -+#define IP_SPECIAL_TAG_VALID 0x81 -+ -+/****************************/ -+/* Global Control Registers */ -+/****************************/ -+/* IP Global register doesn't have names based on functionality -+ * hence has to live with this names for now */ -+#define IP_GLOBAL_PHY29_18_REG 18 -+#define IP_GLOBAL_PHY29_19_REG 19 -+#define IP_GLOBAL_PHY29_20_REG 20 -+#define IP_GLOBAL_PHY29_21_REG 21 -+#define IP_GLOBAL_PHY29_22_REG 22 -+#define IP_GLOBAL_PHY29_23_REG 23 -+#define IP_GLOBAL_PHY29_24_REG 24 -+#define IP_GLOBAL_PHY29_25_REG 25 -+#define IP_GLOBAL_PHY29_26_REG 26 -+#define IP_GLOBAL_PHY29_27_REG 27 -+#define IP_GLOBAL_PHY29_28_REG 28 -+#define IP_GLOBAL_PHY29_29_REG 29 -+#define IP_GLOBAL_PHY29_30_REG 30 -+#define IP_GLOBAL_PHY29_31_REG 31 -+ -+ -+#define IP_GLOBAL_PHY30_0_REG 0 -+#define IP_GLOBAL_PHY30_1_REG 1 -+#define IP_GLOBAL_PHY30_2_REG 2 -+#define IP_GLOBAL_PHY30_3_REG 3 -+#define IP_GLOBAL_PHY30_4_REG 4 -+#define IP_GLOBAL_PHY30_5_REG 5 -+#define IP_GLOBAL_PHY30_6_REG 6 -+#define IP_GLOBAL_PHY30_7_REG 7 -+#define IP_GLOBAL_PHY30_8_REG 8 -+#define IP_GLOBAL_PHY30_9_REG 9 -+#define IP_GLOBAL_PHY30_10_REG 10 -+#define IP_GLOBAL_PHY30_11_REG 11 -+#define IP_GLOBAL_PHY30_12_REG 12 -+#define IP_GLOBAL_PHY30_13_REG 13 -+#define IP_GLOBAL_PHY30_16_REG 16 -+#define IP_GLOBAL_PHY30_17_REG 17 -+#define IP_GLOBAL_PHY30_18_REG 18 -+#define IP_GLOBAL_PHY30_20_REG 20 -+#define IP_GLOBAL_PHY30_21_REG 21 -+#define IP_GLOBAL_PHY30_22_REG 22 -+#define IP_GLOBAL_PHY30_23_REG 23 -+#define IP_GLOBAL_PHY30_24_REG 24 -+#define IP_GLOBAL_PHY30_25_REG 25 -+#define IP_GLOBAL_PHY30_26_REG 26 -+#define IP_GLOBAL_PHY30_27_REG 27 -+#define IP_GLOBAL_PHY30_28_REG 28 -+#define IP_GLOBAL_PHY30_29_REG 29 -+#define IP_GLOBAL_PHY30_30_REG 30 -+#define IP_GLOBAL_PHY30_31_REG 31 -+ -+#define IP_GLOBAL_PHY31_0_REG 0 -+#define IP_GLOBAL_PHY31_1_REG 1 -+#define IP_GLOBAL_PHY31_2_REG 2 -+#define IP_GLOBAL_PHY31_3_REG 3 -+#define IP_GLOBAL_PHY31_4_REG 4 -+#define IP_GLOBAL_PHY31_5_REG 5 -+#define IP_GLOBAL_PHY31_6_REG 6 -+ -+#define IP_GLOBAL_PHY29_31_REG 31 -+ -+ -+#define IP_VLAN0_OUTPUT_PORT_MASK_S 0 -+#define IP_VLAN1_OUTPUT_PORT_MASK_S 8 -+#define IP_VLAN2_OUTPUT_PORT_MASK_S 0 -+#define IP_VLAN3_OUTPUT_PORT_MASK_S 8 -+ -+/* Masks and shifts for 29.23 register */ -+#define IP_PORTX_ADD_TAG_S 11 -+#define IP_PORTX_REMOVE_TAG_S 6 -+#define IP_PORT5_ADD_TAG_S 1 -+#define IP_PORT5_REMOVE_TAG_S 0 -+ -+/* -+ * 30.9 Definitions -+ */ -+#define TAG_VLAN_ENABLE 0x0080 -+#define VID_INDX_SEL_M 0x0070 -+#define VID_INDX_SEL_S 4 -+ -+ -+/* PHY Addresses */ -+#define IP_PHY0_ADDR 0 -+#define IP_PHY1_ADDR 1 -+#define IP_PHY2_ADDR 2 -+#define IP_PHY3_ADDR 3 -+#define IP_PHY4_ADDR 4 -+ -+#define IP_GLOBAL_PHY29_ADDR 29 -+#define IP_GLOBAL_PHY30_ADDR 30 -+#define IP_GLOBAL_PHY31_ADDR 31 -+ -+ -+#endif -diff -urN linux-mips-orig/drivers/net/ath/kendSwitchPhy.c linux-mips-new/drivers/net/ath/kendSwitchPhy.c ---- linux-mips-orig/drivers/net/ath/kendSwitchPhy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/kendSwitchPhy.c 2005-12-31 12:33:57.678538064 +0000 -@@ -0,0 +1,286 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * Manage the ethernet PHY. -+ * This code supports a simple 1-port ethernet phy, Realtek RTL8201BL, -+ * and compatible PHYs, such as the Kendin KS8721B. -+ * All definitions in this file are operating system independent! -+ */ -+ -+#if defined(linux) -+#include <linux/config.h> -+#include <linux/types.h> -+#include <linux/netdevice.h> -+#include <linux/etherdevice.h> -+#include <linux/delay.h> -+ -+#include "ar531xlnx.h" -+#endif -+ -+#if defined(__ECOS) -+#include "ae531xecos.h" -+#endif -+ -+ -+#include "ae531xmac.h" -+#include "ae531xreg.h" -+#include "rtPhy.h" -+ -+#define RT_MAX_PORTS 5 /* max addressable ports per MIIM */ -+ -+#if /* DEBUG */ 1 -+#define RT_DEBUG_ERROR 0x00000001 -+#define RT_DEBUG_PHYSETUP 0x00000002 -+#define RT_DEBUG_PHYCHANGE 0x00000004 -+ -+/* XXX: must hardcode this since same MIIM for all ethUnits */ -+const UINT32 phyBase = 0xb8100000; -+ -+int rtPhyDebug = RT_DEBUG_ERROR; -+ -+#define RT_PRINT(FLG, X) \ -+{ \ -+ if (rtPhyDebug & (FLG)) { \ -+ DEBUG_PRINTF X; \ -+ } \ -+} -+#else -+#define RT_PRINT(FLG, X) -+#endif -+ -+/* -+ * Track per-PHY state. -+ */ -+static BOOL rtPhyAlive[RT_MAX_PORTS]; -+ -+ -+/****************************************************************************** -+* -+* rt_phySetup - reset and setup the PHY associated with -+* the specified MAC unit number. -+* -+* Resets the associated PHY port. -+* -+* RETURNS: -+* TRUE --> associated PHY is alive -+* FALSE --> no LINKs on this ethernet unit -+*/ -+ -+BOOL -+rt_phySetup(int ethUnit, UINT32 phyBaseIgnored) -+{ -+ BOOL linkAlive = FALSE; -+ -+ /* Reset phy */ -+ if (ethUnit == 0) { -+ int i; -+ for (i=1; i<5; i++) { -+ phyRegWrite(phyBase, i, GEN_ctl, AUTONEGENA); -+ sysMsDelay(200); -+ if (phyRegRead(phyBase, i, GEN_sts) & (AUTOCMPLT | LINK)) { -+ rtPhyAlive[i] = TRUE; -+ } -+ else { -+ rtPhyAlive[i] = FALSE; -+ } -+ } -+ } -+ else { -+ phyRegWrite(phyBase, 5, GEN_ctl, AUTONEGENA); -+ sysMsDelay(200); -+ if (phyRegRead(phyBase, 5, GEN_sts) & (AUTOCMPLT | LINK)) { -+ rtPhyAlive[5] = TRUE; -+ } -+ else { -+ rtPhyAlive[5] = FALSE; -+ } -+ } -+ -+ return linkAlive; -+} -+ -+/****************************************************************************** -+* -+* rt_phyIsDuplexFull - Determines whether the phy ports associated with the -+* specified device are FULL or HALF duplex. -+* -+* RETURNS: -+* 1 --> FULL -+* 0 --> HALF -+*/ -+int -+rt_phyIsFullDuplex(int ethUnit) -+{ -+ UINT16 phyLpa = 0; -+ -+ if (ethUnit == 0) { -+ int i; -+ /* 4 ports connected. If any are half-duplex report half. */ -+ for (i=1; i<5; i++) { -+ phyLpa = phyRegRead(phyBase, i, AN_lpa); -+ if ( (!(phyLpa & (LPA_TXFD | LPA_10FD))) && -+ (phyLpa & (LPA_TX | LPA_10)) ) { -+ return 0; -+ } -+ } -+ return 1; -+ } -+ else { -+ phyLpa = phyRegRead(phyBase, 5, AN_lpa); -+ if (phyLpa & (LPA_TXFD | LPA_10FD) ) { -+ return 1; -+ } -+ else { -+ return 0; -+ } -+ } -+} -+ -+/****************************************************************************** -+* -+* rt_phyIsSpeed100 - Determines the speed of phy ports associated with the -+* specified device. -+* -+* RETURNS: -+* TRUE --> 100Mbit -+* FALSE --> 10Mbit -+*/ -+BOOL -+rt_phyIsSpeed100(int ethUnit) -+{ -+ UINT16 phyLpa; -+ -+ if (ethUnit == 0) { -+ int i; -+ /* 4 ports connected. If any are not 100 report 10. */ -+ for (i=1; i<5; i++) { -+ phyLpa = phyRegRead(phyBase, i, AN_lpa); -+ if ( (!(phyLpa & (LPA_TXFD | LPA_TX))) && -+ (phyLpa & (LPA_10FD | LPA_10)) ) { -+ printk("10\n"); -+ return FALSE; -+ } -+ } -+ printk("100\n"); -+ return TRUE; -+ } -+ else { -+ phyLpa = phyRegRead(phyBase, 5, AN_lpa); -+ if (phyLpa & (LPA_TXFD | LPA_TX) ) { -+ printk("100\n"); -+ return TRUE; -+ } -+ else { -+ printk("10\n"); -+ return FALSE; -+ } -+ } -+} -+ -+/***************************************************************************** -+* -+* rt_phyCheckStatusChange -- checks for significant changes in PHY state. -+* -+* A "significant change" is: -+* dropped link (e.g. ethernet cable unplugged) OR -+* autonegotiation completed + link (e.g. ethernet cable plugged in) -+* -+* When a PHY is plugged in, phyLinkGained is called. -+* When a PHY is unplugged, phyLinkLost is called. -+*/ -+void -+rt_phyCheckStatusChange(int ethUnit) -+{ -+ UINT16 phyHwStatus; -+ int i, loopLower, loopUpper; -+ -+ if (ethUnit == 0) { -+ loopLower = 1; -+ loopUpper = 4; -+ } -+ else { -+ loopLower = 5; -+ loopUpper = 5; -+ } -+ -+ for (i=loopLower; i<=loopUpper; i++) { -+ phyHwStatus = phyRegRead(phyBase, i, GEN_sts); -+ -+ if (rtPhyAlive[i]) { /* last known status was ALIVE */ -+ /* See if we've lost link */ -+ if (!(phyHwStatus & LINK)) { -+ RT_PRINT(RT_DEBUG_PHYCHANGE,("\nethmac%d link down\n", ethUnit)); -+ rtPhyAlive[i] = FALSE; -+ phyLinkLost(ethUnit); -+ } -+ } else { /* last known status was DEAD */ -+ /* Check for AN complete */ -+ if ((phyHwStatus & (AUTOCMPLT | LINK)) == (AUTOCMPLT | LINK)) { -+ RT_PRINT(RT_DEBUG_PHYCHANGE,("\nethmac%d link up\n", ethUnit)); -+ rtPhyAlive[i] = TRUE; -+ phyLinkGained(ethUnit); -+ } -+ } -+ } -+} -+ -+#if DEBUG -+ -+/* Define the PHY registers of interest for a phyShow command */ -+struct rtRegisterTable_s { -+ UINT32 regNum; -+ char *regIdString; -+} rtRegisterTable[] = -+{ -+ {GEN_ctl, "Basic Mode Control (GEN_ctl) "}, -+ {GEN_sts, "Basic Mode Status (GEN_sts) "}, -+ {GEN_id_hi, "PHY Identifier 1 (GET_id_hi) "}, -+ {GEN_id_lo, "PHY Identifier 2 (GET_id_lo) "}, -+ {AN_adv, "Auto-Neg Advertisement (AN_adv) "}, -+ {AN_lpa, "Auto-Neg Link Partner Ability "}, -+ {AN_exp, "Auto-Neg Expansion "}, -+}; -+ -+int rtNumRegs = sizeof(rtRegisterTable) / sizeof(rtRegisterTable[0]); -+ -+/* -+ * Dump the state of a PHY. -+ */ -+void -+rt_phyShow(int phyUnit) -+{ -+ int i; -+ UINT16 value; -+ int j, loopLower, loopUpper; -+ -+ printf("PHY state for ethphy%d\n", phyUnit); -+ -+ if (phyUnit == 0) { -+ loopLower = 1; -+ loopUpper = 4; -+ } -+ else { -+ loopLower = 5; -+ loopUpper = 5; -+ } -+ -+ for (j=loopLower; j<=loopUpper; j++) { -+ printk("PHY port %d:\n", j); -+ for (i=0; i<rtNumRegs; i++) { -+ -+ value = phyRegRead(phyBase, j, rtRegisterTable[i].regNum); -+ -+ printf("Reg %02d (0x%02x) %s = 0x%08x\n", -+ rtRegisterTable[i].regNum, rtRegisterTable[i].regNum, -+ rtRegisterTable[i].regIdString, value); -+ } -+ } -+} -+ -+#endif -diff -urN linux-mips-orig/drivers/net/ath/Makefile linux-mips-new/drivers/net/ath/Makefile ---- linux-mips-orig/drivers/net/ath/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/Makefile 2005-12-31 12:33:57.678538064 +0000 -@@ -0,0 +1,78 @@ -+################################################################################ -+# -+# This file is subject to the terms and conditions of the GNU General Public -+# License. See the file "COPYING" in the main directory of this archive -+# for more details. -+# -+# Copyright © 2004 Atheros Communications, Inc., All Rights Reserved. -+# -+# Makefile for Atheros ar531x ethernet driver -+# -+# Note! Dependencies are done automagically by 'make dep', which also -+# removes any old dependencies. DON'T put your own dependencies here -+# unless it's something special (ie not a .c file). -+# -+################################################################################ -+ -+# -+# Makefile for the Atheros ar531x ethernet driver -+# -+ -+obj= . -+ -+obj-m += ae531x.o -+ae531x-objs := ae531xlnx.o ae531xmac.o -+export-objs := ae531xlnx.o -+list-multi := ae531x.o -+ -+ifeq ($(CONFIG_KENDIN_ENET_PHY),y) -+ ae531x-objs += rtPhy.o -+endif -+ifeq ($(CONFIG_KENDIN_KS8995XA_ENET_PHY),y) -+ ae531x-objs += kendSwitchPhy.o -+endif -+ifeq ($(CONFIG_MARVELL_ENET_PHY),y) -+ ae531x-objs += mvPhy.o -+endif -+ifeq ($(CONFIG_ICPLUS_ENET_PHY),y) -+ ae531x-objs += ipPhy.o -+endif -+ -+# -+# If building directly into kernel -+# -+ifneq ($(MAKING_MODULES),1) -+obj-$(CONFIG_NET_ATHEROS_ETHER) := ae531x.o $(ae531x-objs) -+O_TARGET := ae531x.o -+endif -+ -+INCS += -I. -+ -+EXTRA_CFLAGS+=$(INCS) ${COPTS} -g -+ifeq ($(DEBUG_BUILD),1) -+EXTRA_CFLAGS+=-DDEBUG -+endif -+ -+# release tag versioning -+-include $(KERNELPATH)/ath_version.mk -+ -+-include $(TOPDIR)/Rules.make -+STRIP= ${TOOLPREFIX}strip -+ -+ifndef MODPATH -+MODPATH = ${KERNELPATH}/arch/mips/ar531x/ROOTDISK/rootdir/lib/modules/${KERNELRELEASE}/ -+endif -+ -+all: -+ $(MAKE) -C ${KERNELPATH} SUBDIRS=$(shell pwd) modules -+ -+install: all -+ $(STRIP) -S ae531x.o -+ cp ae531x.o ${KERNELPATH}/arch/mips/ar531x/ROOTDISK/rootdir/lib/modules/$(strip $(shell head -n 1 $(KERNELPATH)/Makefile | cut -f 2 -d'=')).$(strip $(shell head -n 2 $(KERNELPATH)/Makefile | tail -1 | cut -f 2 -d'=')).$(strip $(shell head -n 3 $(KERNELPATH)/Makefile | tail -1 | cut -f 2 -d'='))${EXTRAVERSION}/net/. -+ -+clean: -+ -rm -f *~ *.o *.ko *.mod.c -+ -rm -f .version .*.o.flags .*.o.d .*.o.cmd .*.ko.cmd -+ -+ae531x.o : $(ae531x-objs) -+ $(LD) -o ae531x.o -r $(ae531x-objs) -diff -urN linux-mips-orig/drivers/net/ath/mvPhy.c linux-mips-new/drivers/net/ath/mvPhy.c ---- linux-mips-orig/drivers/net/ath/mvPhy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/mvPhy.c 2005-12-31 12:33:57.726530768 +0000 -@@ -0,0 +1,1230 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+* Manage the ethernet PHY switch, Marvell 88E6060. -+* -+* This module is intended to be largely OS and platform-independent. -+*/ -+ -+#if defined(linux) -+#include <linux/config.h> -+#include <linux/types.h> -+#include <linux/netdevice.h> -+#include <linux/etherdevice.h> -+#include <linux/delay.h> -+ -+#include "ar531xlnx.h" -+#endif -+ -+#if defined(__ECOS) -+#include "ae531xecos.h" -+#endif -+ -+ -+#include "ae531xmac.h" -+#include "ae531xreg.h" -+#include "mvPhy.h" -+ -+#if /* DEBUG */ 1 -+#define MV_DEBUG_ERROR 0x00000001 -+#define MV_DEBUG_PHYSETUP 0x00000002 -+#define MV_DEBUG_PHYCHANGE 0x00000004 -+ -+int mvPhyDebug = MV_DEBUG_ERROR; -+ -+#define MV_PRINT(FLG, X) \ -+{ \ -+ if (mvPhyDebug & (FLG)) { \ -+ DEBUG_PRINTF X; \ -+ } \ -+} -+#else -+#define MV_PRINT(FLG, X) -+#endif -+ -+#if CONFIG_VENETDEV -+/* -+ * On AR5312 with CONFIG_VENETDEV==1, -+ * ports 0..3 are LAN ports (accessed through ae0) -+ * port 4 is the WAN port. (accessed through ae1) -+ * -+ * The phy switch settings in the mvPhyInfo table are set accordingly. -+ */ -+#define MV_WAN_PORT 4 -+#define MV_IS_LAN_PORT(port) ((port) < MV_WAN_PORT) -+#define MV_IS_WAN_PORT(port) ((port) == MV_WAN_PORT) -+#endif -+ -+/* -+ * Track per-PHY port information. -+ */ -+typedef struct { -+ BOOL isEnetPort; /* normal enet port */ -+ BOOL isPhyAlive; /* last known state of link */ -+ int ethUnit; /* MAC associated with this phy port */ -+ UINT32 phyBase; -+ UINT32 phyAddr; /* PHY registers associated with this phy port */ -+ UINT32 switchPortAddr; /* switch port regs assoc'ed with this phy port */ -+ UINT32 VLANTableSetting; /* Value to be written to VLAN table */ -+} mvPhyInfo_t; -+ -+/****************************************************************************** -+ * Per-PHY information, indexed by PHY unit number. -+ * -+ * This table is board-dependent. It includes information -+ * about which enet MAC controls which PHY port. -+ */ -+mvPhyInfo_t mvPhyInfo[] = { -+ /* -+ * On AP30/AR5312, all PHYs are associated with MAC0. -+ * AP30/AR5312's MAC1 isn't used for anything. -+ * CONFIG_VENETDEV==1 (router) configuration: -+ * Ports 0,1,2, and 3 are "LAN ports" -+ * Port 4 is a WAN port -+ * Port 5 connects to MAC0 in the AR5312 -+ * CONFIG_VENETDEV==0 (bridge) configuration: -+ * Ports 0,1,2,3,4 are "LAN ports" -+ * Port 5 connects to the MAC0 in the AR5312 -+ */ -+ {isEnetPort: TRUE, /* phy port 0 -- LAN port 0 */ -+ isPhyAlive: FALSE, -+ ethUnit: 0, -+ phyBase: 0, -+ phyAddr: 0x10, -+ switchPortAddr: 0x18, -+#if CONFIG_VENETDEV -+ VLANTableSetting: 0x2e -+#else -+ VLANTableSetting: 0x3e -+#endif -+ }, -+ -+ {isEnetPort: TRUE, /* phy port 1 -- LAN port 1 */ -+ isPhyAlive: FALSE, -+ ethUnit: 0, -+ phyBase: 0, -+ phyAddr: 0x11, -+ switchPortAddr: 0x19, -+#if CONFIG_VENETDEV -+ VLANTableSetting: 0x2d -+#else -+ VLANTableSetting: 0x3d -+#endif -+ }, -+ -+ {isEnetPort: TRUE, /* phy port 2 -- LAN port 2 */ -+ isPhyAlive: FALSE, -+ ethUnit: 0, -+ phyBase: 0, -+ phyAddr: 0x12, -+ switchPortAddr: 0x1a, -+#if CONFIG_VENETDEV -+ VLANTableSetting: 0x2b -+#else -+ VLANTableSetting: 0x3b -+#endif -+ }, -+ -+ {isEnetPort: TRUE, /* phy port 3 -- LAN port 3 */ -+ isPhyAlive: FALSE, -+ ethUnit: 0, -+ phyBase: 0, -+ phyAddr: 0x13, -+ switchPortAddr: 0x1b, -+#if CONFIG_VENETDEV -+ VLANTableSetting: 0x27 -+#else -+ VLANTableSetting: 0x37 -+#endif -+ }, -+ -+ {isEnetPort: TRUE, /* phy port 4 -- WAN port or LAN port 4 */ -+ isPhyAlive: FALSE, -+ ethUnit: 0, -+ phyBase: 0, -+ phyAddr: 0x14, -+ switchPortAddr: 0x1c, -+#if CONFIG_VENETDEV -+ VLANTableSetting: 0x1020 /* WAN port */ -+#else -+ VLANTableSetting: 0x2f /* LAN port 4 */ -+#endif -+ }, -+ -+ {isEnetPort: FALSE, /* phy port 5 -- CPU port (no RJ45 connector) */ -+ isPhyAlive: TRUE, -+ ethUnit: 0, -+ phyBase: 0, -+ phyAddr: 0x15, -+ switchPortAddr: 0x1d, -+#if CONFIG_VENETDEV -+ VLANTableSetting: 0x0f /* Send only to LAN ports */ -+#else -+ VLANTableSetting: 0x1f /* Send to all ports */ -+#endif -+ }, -+}; -+ -+#define MV_PHY_MAX (sizeof(mvPhyInfo) / sizeof(mvPhyInfo[0])) -+ -+/* Range of valid PHY IDs is [MIN..MAX] */ -+#define MV_ID_MIN 0 -+#define MV_ID_MAX (MV_PHY_MAX-1) -+ -+/* Convenience macros to access myPhyInfo */ -+#define MV_IS_ENET_PORT(phyUnit) (mvPhyInfo[phyUnit].isEnetPort) -+#define MV_IS_PHY_ALIVE(phyUnit) (mvPhyInfo[phyUnit].isPhyAlive) -+#define MV_ETHUNIT(phyUnit) (mvPhyInfo[phyUnit].ethUnit) -+#define MV_PHYBASE(phyUnit) (mvPhyInfo[phyUnit].phyBase) -+#define MV_PHYADDR(phyUnit) (mvPhyInfo[phyUnit].phyAddr) -+#define MV_SWITCH_PORT_ADDR(phyUnit) (mvPhyInfo[phyUnit].switchPortAddr) -+#define MV_VLAN_TABLE_SETTING(phyUnit) (mvPhyInfo[phyUnit].VLANTableSetting) -+ -+#define MV_IS_ETHUNIT(phyUnit, ethUnit) \ -+ (MV_IS_ENET_PORT(phyUnit) && \ -+ MV_ETHUNIT(phyUnit) == (ethUnit)) -+ -+ -+/* Forward references */ -+BOOL mv_phyIsLinkAlive(int phyUnit); -+LOCAL void mv_VLANInit(int ethUnit); -+LOCAL void mv_enableConfiguredPorts(int ethUnit); -+LOCAL void mv_verifyReady(int ethUnit); -+BOOL mv_phySetup(int ethUnit, UINT32 phyBase); -+int mv_phyIsFullDuplex(int ethUnit); -+BOOL mv_phyIsSpeed100(int phyUnit); -+LOCAL BOOL mv_validPhyId(int phyUnit); -+void mv_flushATUDB(int phyUnit); -+void mv_phyCheckStatusChange(int ethUnit); -+#if DEBUG -+void mv_phyShow(int phyUnit); -+void mv_phySet(int phyUnit, UINT32 regnum, UINT32 value); -+void mv_switchPortSet(int phyUnit, UINT32 regnum, UINT32 value); -+void mv_switchGlobalSet(int phyUnit, UINT32 regnum, UINT32 value); -+void mv_showATUDB(int phyUnit); -+void mv_countGoodFrames(int phyUnit); -+void mv_countBadFrames(int phyUnit); -+void mv_showFrameCounts(int phyUnit); -+#endif -+ -+ -+/****************************************************************************** -+* -+* mv_phyIsLinkAlive - test to see if the specified link is alive -+* -+* RETURNS: -+* TRUE --> link is alive -+* FALSE --> link is down -+*/ -+BOOL -+mv_phyIsLinkAlive(int phyUnit) -+{ -+ UINT16 phyHwStatus; -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ phyAddr = MV_PHYADDR(phyUnit); -+ -+ phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS); -+ -+ if (phyHwStatus & MV_STATUS_REAL_TIME_LINK_UP) { -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+ -+/****************************************************************************** -+* -+* mv_VLANInit - initialize "port-based VLANs" for the specified enet unit. -+*/ -+LOCAL void -+mv_VLANInit(int ethUnit) -+{ -+ int phyUnit; -+ UINT32 phyBase; -+ UINT32 switchPortAddr; -+ -+ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { -+ if (MV_ETHUNIT(phyUnit) != ethUnit) { -+ continue; -+ } -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); -+ -+ phyRegWrite(phyBase, switchPortAddr, MV_PORT_BASED_VLAN_MAP, -+ MV_VLAN_TABLE_SETTING(phyUnit)); -+ } -+} -+ -+#define phyPortConfigured(phyUnit) TRUE /* TBDFREEDOM2 */ -+ -+/****************************************************************************** -+* -+* mv_enableConfiguredPorts - enable whichever PHY ports are supposed -+* to be enabled according to administrative configuration. -+*/ -+LOCAL void -+mv_enableConfiguredPorts(int ethUnit) -+{ -+ int phyUnit; -+ UINT32 phyBase; -+ UINT32 switchPortAddr; -+ UINT16 portControl; -+ UINT16 portAssociationVector; -+ -+ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { -+ if (MV_ETHUNIT(phyUnit) != ethUnit) { -+ continue; -+ } -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); -+ -+ if (phyPortConfigured(phyUnit)) { -+ -+ portControl = MV_PORT_CONTROL_PORT_STATE_FORWARDING; -+#if CONFIG_VENETDEV -+ if (!MV_IS_ENET_PORT(phyUnit)) { /* CPU port */ -+ portControl |= MV_PORT_CONTROL_INGRESS_TRAILER -+ | MV_PORT_CONTROL_EGRESS_MODE; -+ } -+#endif -+ phyRegWrite(phyBase, switchPortAddr, MV_PORT_CONTROL, portControl); -+ -+ portAssociationVector = 1 << phyUnit; -+ -+ phyRegWrite(phyBase, switchPortAddr, -+ MV_PORT_ASSOCIATION_VECTOR, portAssociationVector); -+ } -+ } -+} -+ -+/****************************************************************************** -+* -+* mv_verifyReady - validates that we're dealing with the device -+* we think we're dealing with, and that it's ready. -+*/ -+LOCAL void -+mv_verifyReady(int ethUnit) -+{ -+ int phyUnit; -+ UINT16 globalStatus; -+ UINT32 phyBase = 0; -+ UINT32 phyAddr; -+ UINT32 switchPortAddr; -+ UINT16 phyID1; -+ UINT16 phyID2; -+ UINT16 switchID; -+ -+ /* -+ * The first read to the Phy port registers always fails and -+ * returns 0. So get things started with a bogus read. -+ */ -+ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { -+ if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ phyBase = MV_PHYBASE(phyUnit); -+ phyAddr = MV_PHYADDR(phyUnit); -+ -+ (void)phyRegRead(phyBase, phyAddr, MV_PHY_ID1); /* returns 0 */ -+ break; -+ } -+ -+ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { -+ if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ -+ /*******************/ -+ /* Verify phy port */ -+ /*******************/ -+ phyBase = MV_PHYBASE(phyUnit); -+ phyAddr = MV_PHYADDR(phyUnit); -+ -+ phyID1 = phyRegRead(phyBase, phyAddr, MV_PHY_ID1); -+ if (phyID1 != MV_PHY_ID1_EXPECTATION) { -+ MV_PRINT(MV_DEBUG_PHYSETUP, -+ ("Invalid PHY ID1 for ethmac%d port%d. Expected 0x%04x, read 0x%04x\n", -+ ethUnit, -+ phyUnit, -+ MV_PHY_ID1_EXPECTATION, -+ phyID1)); -+ return; -+ } -+ -+ phyID2 = phyRegRead(phyBase, phyAddr, MV_PHY_ID2); -+ if ((phyID2 & MV_OUI_LSB_MASK) != MV_OUI_LSB_EXPECTATION) { -+ MV_PRINT(MV_DEBUG_PHYSETUP, -+ ("Invalid PHY ID2 for ethmac%d port %d. Expected 0x%04x, read 0x%04x\n", -+ ethUnit, -+ phyUnit, -+ MV_OUI_LSB_EXPECTATION, -+ phyID2)); -+ return; -+ } -+ -+ MV_PRINT(MV_DEBUG_PHYSETUP, -+ ("Found PHY ethmac%d port%d: model 0x%x revision 0x%x\n", -+ ethUnit, -+ phyUnit, -+ (phyID2 & MV_MODEL_NUM_MASK) >> MV_MODEL_NUM_SHIFT, -+ (phyID2 & MV_REV_NUM_MASK) >> MV_REV_NUM_SHIFT)); -+ -+ -+ /**********************/ -+ /* Verify switch port */ -+ /**********************/ -+ switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); -+ -+ switchID = phyRegRead(phyBase, switchPortAddr, MV_SWITCH_ID); -+ if ((switchID & MV_SWITCH_ID_DEV_MASK) != -+ MV_SWITCH_ID_DEV_EXPECTATION) { -+ -+ MV_PRINT(MV_DEBUG_PHYSETUP, -+ ("Invalid switch ID for ethmac%d port %d. Expected 0x%04x, read 0x%04x\n", -+ ethUnit, -+ phyUnit, -+ MV_SWITCH_ID_DEV_EXPECTATION, -+ switchID)); -+ return; -+ } -+ -+ MV_PRINT(MV_DEBUG_PHYSETUP, -+ ("Found PHY switch for enet %d port %d deviceID 0x%x revision 0x%x\n", -+ ethUnit, -+ phyUnit, -+ (switchID & MV_SWITCH_ID_DEV_MASK) >> MV_SWITCH_ID_DEV_SHIFT, -+ (switchID & MV_SWITCH_ID_REV_MASK) >> MV_SWITCH_ID_REV_SHIFT)) -+ } -+ -+ /*******************************/ -+ /* Verify that switch is ready */ -+ /*******************************/ -+ if (phyBase) { -+ globalStatus = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, -+ MV_SWITCH_GLOBAL_STATUS); -+ -+ if (!(globalStatus & MV_SWITCH_STATUS_READY_MASK)) { -+ MV_PRINT(MV_DEBUG_PHYSETUP, -+ ("PHY switch for ethmac%d NOT ready!\n", -+ ethUnit)); -+ } -+ } else { -+ MV_PRINT(MV_DEBUG_PHYSETUP, -+ ("No ports configured for ethmac%d\n", ethUnit)); -+ } -+} -+ -+/****************************************************************************** -+* -+* mv_phySetup - reset and setup the PHY switch. -+* -+* Resets each PHY port. -+* -+* RETURNS: -+* TRUE --> at least 1 PHY with LINK -+* FALSE --> no LINKs on this ethernet unit -+*/ -+BOOL -+mv_phySetup(int ethUnit, UINT32 phyBase) -+{ -+ int phyUnit; -+ int liveLinks = 0; -+ BOOL foundPhy = FALSE; -+ UINT32 phyAddr; -+ UINT16 atuControl; -+ -+ /* -+ * Allow platform-specific code to determine the default Ethernet MAC -+ * at run-time. If phyEthMacDefault returns a negative value, use the -+ * static mvPhyInfo table "as is". But if phyEthMacDefault returns a -+ * non-negative value, use it as the default ethernet unit. -+ */ -+ { -+ int ethMacDefault = phyEthMacDefault(); -+ -+ if (ethMacDefault >= 0) { -+ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { -+ MV_ETHUNIT(phyUnit)=ethMacDefault; -+ } -+ } -+ } -+ -+ /* -+ * See if there's any configuration data for this enet, -+ * and set up phyBase in table. -+ */ -+ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { -+ if (MV_ETHUNIT(phyUnit) != ethUnit) { -+ continue; -+ } -+ -+ MV_PHYBASE(phyUnit) = phyBase; -+ foundPhy = TRUE; -+ } -+ -+ if (!foundPhy) { -+ return FALSE; /* No PHY's configured for this ethUnit */ -+ } -+ -+ /* Verify that the switch is what we think it is, and that it's ready */ -+ mv_verifyReady(ethUnit); -+ -+ /* Initialize global switch settings */ -+ atuControl = MV_ATUCTRL_AGE_TIME_DEFAULT << MV_ATUCTRL_AGE_TIME_SHIFT; -+ atuControl |= MV_ATUCTRL_ATU_SIZE_DEFAULT << MV_ATUCTRL_ATU_SIZE_SHIFT; -+ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_CONTROL, atuControl); -+ -+ /* Reset PHYs and start autonegoation on each. */ -+ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { -+ if (MV_ETHUNIT(phyUnit) != ethUnit) { -+ continue; -+ } -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ phyAddr = MV_PHYADDR(phyUnit); -+ -+ phyRegWrite(phyBase, phyAddr, MV_PHY_CONTROL, -+ MV_CTRL_SOFTWARE_RESET | MV_CTRL_AUTONEGOTIATION_ENABLE); -+ } -+ -+#if 0 /* Don't wait -- we'll detect shortly after the link comes up */ -+{ -+ int timeout; -+ UINT16 phyHwStatus; -+ -+ /* -+ * Wait 5 seconds for ALL associated PHYs to finish autonegotiation. -+ */ -+ timeout=50; -+ for (phyUnit=0; (phyUnit < MV_PHY_MAX) && (timeout > 0); phyUnit++) { -+ if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ for (;;) { -+ phyBase = MV_PHYBASE(phyUnit); -+ phyAddr = MV_PHYADDR(phyUnit); -+ -+ phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS); -+ -+ if (MV_AUTONEG_DONE(phyHwStatus)) { -+ break; -+ } -+ -+ if (--timeout == 0) { -+ break; -+ } -+ -+ sysMsDelay(100); -+ } -+ } -+} -+#endif -+ -+ /* -+ * All PHYs have had adequate time to autonegotiate. -+ * Now initialize software status. -+ * -+ * It's possible that some ports may take a bit longer -+ * to autonegotiate; but we can't wait forever. They'll -+ * get noticed by mv_phyCheckStatusChange during regular -+ * polling activities. -+ */ -+ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { -+ if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ -+ if (mv_phyIsLinkAlive(phyUnit)) { -+ liveLinks++; -+ MV_IS_PHY_ALIVE(phyUnit) = TRUE; -+ } else { -+ MV_IS_PHY_ALIVE(phyUnit) = FALSE; -+ } -+ -+ MV_PRINT(MV_DEBUG_PHYSETUP, -+ ("ethmac%d: Phy Status=%4.4x\n", -+ ethUnit, -+ phyRegRead(MV_PHYBASE(phyUnit), -+ MV_PHYADDR(phyUnit), -+ MV_PHY_SPECIFIC_STATUS))); -+ } -+ -+ mv_VLANInit(ethUnit); -+ -+ mv_enableConfiguredPorts(ethUnit); -+ -+ return (liveLinks > 0); -+} -+ -+ -+/****************************************************************************** -+* -+* mv_phyIsDuplexFull - Determines whether the phy ports associated with the -+* specified device are FULL or HALF duplex. -+* -+* RETURNS: -+* 1 --> at least one associated PHY in FULL DUPLEX -+* 0 --> all half duplex -+* -1 --> No links -+*/ -+int -+mv_phyIsFullDuplex(int ethUnit) -+{ -+ int phyUnit; -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ UINT16 phyHwStatus; -+ int oneIsReady=0; -+ -+ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { -+ if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ -+ if (mv_phyIsLinkAlive(phyUnit)) { -+ oneIsReady = 1; -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ phyAddr = MV_PHYADDR(phyUnit); -+ -+ phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS); -+ -+ if (phyHwStatus & MV_STATUS_RESOLVED_DUPLEX_FULL) { -+ return 1; -+ } -+ } -+ } -+ if (oneIsReady) -+ return 0; -+ else -+ return -1; -+} -+ -+/****************************************************************************** -+* -+* mv_phyIsSpeed100 - Determines the speed of a phy port -+* -+* RETURNS: -+* TRUE --> PHY operating at 100 Mbit -+* FALSE --> link down, or not operating at 100 Mbit -+*/ -+BOOL -+mv_phyIsSpeed100(int phyUnit) -+{ -+ UINT16 phyHwStatus; -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ -+ if (MV_IS_ENET_PORT(phyUnit)) { -+ if (mv_phyIsLinkAlive(phyUnit)) { -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ phyAddr = MV_PHYADDR(phyUnit); -+ -+ phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS); -+ -+ if (phyHwStatus & MV_STATUS_RESOLVED_SPEED_100) { -+ return TRUE; -+ } -+ } -+ } -+ -+ return FALSE; -+} -+ -+#if CONFIG_VENETDEV -+/****************************************************************************** -+* -+* mv_phyDetermineSource - Examine a received frame's Egress Trailer -+* to determine whether it came from a LAN or WAN port. -+* -+* RETURNS: -+* Sets *pFromLAN: 1-->LAN, 0-->WAN -+* Modifies *pLen to remove PHY trailer from frame -+*/ -+void -+mv_phyDetermineSource(char *data, int len, int *pFromLAN) -+{ -+ unsigned char *phyTrailer; -+ unsigned char incomingPort; -+ -+ phyTrailer = &data[len - MV_PHY_TRAILER_SIZE]; -+ ASSERT(phyTrailer[0] == MV_EGRESS_TRAILER_VALID); -+ -+ incomingPort = phyTrailer[1]; -+ if (MV_IS_LAN_PORT(incomingPort)) { -+ *pFromLAN = 1; -+ } else { -+ ASSERT(MV_IS_WAN_PORT(incomingPort)); -+ *pFromLAN = 0; -+ } -+} -+ -+ -+/****************************************************************************** -+* -+* mv_phySetDestinationPort - Set the Ingress Trailer to force the -+* frame to be sent to LAN or WAN, as specified. -+* -+*/ -+void -+mv_phySetDestinationPort(char *data, int len, int fromLAN) -+{ -+ char *phyTrailer; -+ -+ phyTrailer = &data[len]; -+ if (fromLAN) { -+ /* LAN ports: Use default settings, as per mvPhyInfo */ -+ phyTrailer[0] = 0x00; -+ phyTrailer[1] = 0x00; -+ } else { -+ /* WAN port: Direct to WAN port */ -+ phyTrailer[0] = MV_INGRESS_TRAILER_OVERRIDE; -+ phyTrailer[1] = 1 << MV_WAN_PORT; -+ } -+ phyTrailer[2] = 0x00; -+ phyTrailer[3] = 0x00; -+} -+#endif -+ -+ -+/***************************************************************************** -+* -+* Validate that the specified PHY unit number is a valid PHY ID. -+* Print a message if it is invalid. -+* RETURNS -+* TRUE --> valid -+* FALSE --> invalid -+*/ -+LOCAL BOOL -+mv_validPhyId(int phyUnit) -+{ -+ if ((phyUnit >= MV_ID_MIN) && (phyUnit <= MV_ID_MAX)) { -+ return TRUE; -+ } else { -+ PRINTF("PHY unit number must be in the range [%d..%d]\n", -+ MV_ID_MIN, MV_ID_MAX); -+ return FALSE; -+ } -+} -+ -+ -+/***************************************************************************** -+* -+* mv_waitWhileATUBusy - spins until the ATU completes -+* its previous operation. -+*/ -+LOCAL void -+mv_waitWhileATUBusy(UINT32 phyBase) -+{ -+ BOOL isBusy; -+ UINT16 ATUOperation; -+ -+ do { -+ -+ ATUOperation = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, -+ MV_ATU_OPERATION); -+ -+ isBusy = (ATUOperation & MV_ATU_BUSY_MASK) == MV_ATU_IS_BUSY; -+ -+ } while(isBusy); -+} -+ -+/***************************************************************************** -+* -+* mv_flushATUDB - flushes ALL entries in the Address Translation Unit -+* DataBase associated with phyUnit. [Since we use a single DB for -+* all PHYs, this flushes the entire shared DataBase.] -+* -+* The current implementation flushes even more than absolutely needed -- -+* it flushes all entries for all phyUnits on the same ethernet as the -+* specified phyUnit. -+* -+* It is called only when a link failure is detected on a port that was -+* previously working. In other words, when the cable is unplugged. -+*/ -+void -+mv_flushATUDB(int phyUnit) -+{ -+ UINT32 phyBase; -+ -+ if (!mv_validPhyId(phyUnit)) { -+ PRINTF("Invalid port number: %d\n", phyUnit); -+ return; -+ } -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ -+ /* Wait for previous operation (if any) to complete */ -+ mv_waitWhileATUBusy(phyBase); -+ -+ /* Tell hardware to flush all entries */ -+ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_OPERATION, -+ MV_ATU_OP_FLUSH_ALL | MV_ATU_IS_BUSY); -+ -+ mv_waitWhileATUBusy(phyBase); -+} -+ -+/***************************************************************************** -+* -+* mv_phyCheckStatusChange -- checks for significant changes in PHY state. -+* -+* A "significant change" is: -+* dropped link (e.g. ethernet cable unplugged) OR -+* autonegotiation completed + link (e.g. ethernet cable plugged in) -+*/ -+void -+mv_phyCheckStatusChange(int ethUnit) -+{ -+ int phyUnit; -+ UINT16 phyHwStatus; -+ mvPhyInfo_t *lastStatus; -+ int linkCount = 0; -+ int lostLinks = 0; -+ int gainedLinks = 0; -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ -+ for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) { -+ if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ phyAddr = MV_PHYADDR(phyUnit); -+ -+ lastStatus = &mvPhyInfo[phyUnit]; -+ phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS); -+ -+ if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */ -+ /* See if we've lost link */ -+ if (phyHwStatus & MV_STATUS_REAL_TIME_LINK_UP) { -+ linkCount++; -+ } else { -+ lostLinks++; -+ mv_flushATUDB(phyUnit); -+ MV_PRINT(MV_DEBUG_PHYCHANGE,("\nethmac%d port%d down\n", -+ ethUnit, phyUnit)); -+ lastStatus->isPhyAlive = FALSE; -+ } -+ } else { /* last known link status was DEAD */ -+ /* Check for AutoNegotiation complete */ -+ if (MV_AUTONEG_DONE(phyHwStatus)) { -+ gainedLinks++; -+ linkCount++; -+ MV_PRINT(MV_DEBUG_PHYCHANGE,("\nethmac%d port%d up\n", -+ ethUnit, phyUnit)); -+ lastStatus->isPhyAlive = TRUE; -+ } -+ } -+ } -+ -+ if (linkCount == 0) { -+ if (lostLinks) { -+ /* We just lost the last link for this MAC */ -+ phyLinkLost(ethUnit); -+ } -+ } else { -+ if (gainedLinks == linkCount) { -+ /* We just gained our first link(s) for this MAC */ -+ phyLinkGained(ethUnit); -+ } -+ } -+} -+ -+#if DEBUG -+ -+/* Define the registers of interest for a phyShow command */ -+typedef struct mvRegisterTableEntry_s { -+ UINT32 regNum; -+ char *regIdString; -+} mvRegisterTableEntry_t; -+ -+mvRegisterTableEntry_t mvPhyRegisterTable[] = { -+ {MV_PHY_CONTROL, "PHY Control "}, -+ {MV_PHY_STATUS, "PHY Status "}, -+ {MV_PHY_ID1, "PHY Identifier 1 "}, -+ {MV_PHY_ID2, "PHY Identifier 2 "}, -+ {MV_AUTONEG_ADVERT, "Auto-Negotiation Advertisement "}, -+ {MV_LINK_PARTNER_ABILITY, "Link Partner Ability "}, -+ {MV_AUTONEG_EXPANSION, "Auto-Negotiation Expansion "}, -+ {MV_NEXT_PAGE_TRANSMIT, "Next Page Transmit "}, -+ {MV_LINK_PARTNER_NEXT_PAGE, "Link Partner Next Page "}, -+ {MV_PHY_SPECIFIC_CONTROL_1, "PHY-Specific Control Register 1 "}, -+ {MV_PHY_SPECIFIC_STATUS, "PHY-Specific Status "}, -+ {MV_PHY_INTERRUPT_ENABLE, "PHY Interrupt Enable "}, -+ {MV_PHY_INTERRUPT_STATUS, "PHY Interrupt Status "}, -+ {MV_PHY_INTERRUPT_PORT_SUMMARY, "PHY Interrupt Port Summary "}, -+ {MV_RECEIVE_ERROR_COUNTER, "Receive Error Counter "}, -+ {MV_LED_PARALLEL_SELECT, "LED Parallel Select "}, -+ {MV_LED_STREAM_SELECT_LEDS, "LED Stream Select "}, -+ {MV_PHY_LED_CONTROL, "PHY LED Control "}, -+ {MV_PHY_MANUAL_LED_OVERRIDE, "PHY Manual LED Override "}, -+ {MV_VCT_CONTROL, "VCT Control "}, -+ {MV_VCT_STATUS, "VCT Status "}, -+ {MV_PHY_SPECIFIC_CONTROL_2, "PHY-Specific Control Register 2 "}, -+}; -+int mvPhyNumRegs = sizeof(mvPhyRegisterTable) / sizeof(mvPhyRegisterTable[0]); -+ -+ -+mvRegisterTableEntry_t mvSwitchPortRegisterTable[] = { -+ {MV_PORT_STATUS, "Port Status "}, -+ {MV_SWITCH_ID, "Switch ID "}, -+ {MV_PORT_CONTROL, "Port Control "}, -+ {MV_PORT_BASED_VLAN_MAP, "Port-Based VLAN Map "}, -+ {MV_PORT_ASSOCIATION_VECTOR, "Port Association Vector "}, -+ {MV_RX_COUNTER, "RX Counter "}, -+ {MV_TX_COUNTER, "TX Counter "}, -+}; -+int mvSwitchPortNumRegs = -+ sizeof(mvSwitchPortRegisterTable) / sizeof(mvSwitchPortRegisterTable[0]); -+ -+ -+mvRegisterTableEntry_t mvSwitchGlobalRegisterTable[] = { -+ {MV_SWITCH_GLOBAL_STATUS, "Switch Global Status "}, -+ {MV_SWITCH_MAC_ADDR0, "Switch MAC Addr 0 & 1 "}, -+ {MV_SWITCH_MAC_ADDR2, "Switch MAC Addr 2 & 3 "}, -+ {MV_SWITCH_MAC_ADDR4, "Switch MAC Addr 4 & 5 "}, -+ {MV_SWITCH_GLOBAL_CONTROL, "Switch Global Control "}, -+ {MV_ATU_CONTROL, "ATU Control "}, -+ {MV_ATU_OPERATION, "ATU Operation "}, -+ {MV_ATU_DATA, "ATU Data "}, -+ {MV_ATU_MAC_ADDR0, "ATU MAC Addr 0 & 1 "}, -+ {MV_ATU_MAC_ADDR2, "ATU MAC Addr 2 & 3 "}, -+ {MV_ATU_MAC_ADDR4, "ATU MAC Addr 4 & 5 "}, -+}; -+int mvSwitchGlobalNumRegs = -+ sizeof(mvSwitchGlobalRegisterTable) / sizeof(mvSwitchGlobalRegisterTable[0]); -+ -+void my_mvPhyShow(int ethUnit) -+{ -+ int phyUnit; -+ for (phyUnit=0; (phyUnit < MV_PHY_MAX); phyUnit++) { -+ if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) { -+ continue; -+ } -+ mv_phyShow(phyUnit); -+ } -+} -+ -+/***************************************************************************** -+* -+* mv_phyShow - Dump the state of a PHY. -+* There are two sets of registers for each phy port: -+* "phy registers" and -+* "switch port registers" -+* We dump 'em all, plus the switch global registers. -+*/ -+void -+mv_phyShow(int phyUnit) -+{ -+ int i; -+ UINT16 value; -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ UINT32 switchPortAddr; -+ -+ if (!mv_validPhyId(phyUnit)) { -+ return; -+ } -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ phyAddr = MV_PHYADDR(phyUnit); -+ switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); -+ -+ printk("PHY state for PHY%d (ethmac%d, phyBase 0x%8x, phyAddr 0x%x, switchAddr 0x%x)\n", -+ phyUnit, -+ MV_ETHUNIT(phyUnit), -+ MV_PHYBASE(phyUnit), -+ MV_PHYADDR(phyUnit), -+ MV_SWITCH_PORT_ADDR(phyUnit)); -+ -+ printk("PHY Registers:\n"); -+ for (i=0; i < mvPhyNumRegs; i++) { -+ -+ value = phyRegRead(phyBase, phyAddr, mvPhyRegisterTable[i].regNum); -+ -+ printk("Reg %02d (0x%02x) %s = 0x%08x\n", -+ mvPhyRegisterTable[i].regNum, -+ mvPhyRegisterTable[i].regNum, -+ mvPhyRegisterTable[i].regIdString, -+ value); -+ } -+ -+ printk("Switch Port Registers:\n"); -+ for (i=0; i < mvSwitchPortNumRegs; i++) { -+ -+ value = phyRegRead(phyBase, switchPortAddr, -+ mvSwitchPortRegisterTable[i].regNum); -+ -+ printk("Reg %02d (0x%02x) %s = 0x%08x\n", -+ mvSwitchPortRegisterTable[i].regNum, -+ mvSwitchPortRegisterTable[i].regNum, -+ mvSwitchPortRegisterTable[i].regIdString, -+ value); -+ } -+ -+ printk("Switch Global Registers:\n"); -+ for (i=0; i < mvSwitchGlobalNumRegs; i++) { -+ -+ value = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, -+ mvSwitchGlobalRegisterTable[i].regNum); -+ -+ printk("Reg %02d (0x%02x) %s = 0x%08x\n", -+ mvSwitchGlobalRegisterTable[i].regNum, -+ mvSwitchGlobalRegisterTable[i].regNum, -+ mvSwitchGlobalRegisterTable[i].regIdString, -+ value); -+ } -+} -+ -+/***************************************************************************** -+* -+* mv_phySet - Modify the value of a PHY register (debug only). -+*/ -+void -+mv_phySet(int phyUnit, UINT32 regnum, UINT32 value) -+{ -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ -+ if (mv_validPhyId(phyUnit)) { -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ phyAddr = MV_PHYADDR(phyUnit); -+ -+ phyRegWrite(phyBase, phyAddr, regnum, value); -+ } -+} -+ -+ -+/***************************************************************************** -+* -+* mv_switchPortSet - Modify the value of a switch port register (debug only). -+*/ -+void -+mv_switchPortSet(int phyUnit, UINT32 regnum, UINT32 value) -+{ -+ UINT32 phyBase; -+ UINT32 switchPortAddr; -+ -+ if (mv_validPhyId(phyUnit)) { -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); -+ -+ phyRegWrite(phyBase, switchPortAddr, regnum, value); -+ } -+} -+ -+/***************************************************************************** -+* -+* mv_switchGlobalSet - Modify the value of a switch global register -+* (debug only). -+*/ -+void -+mv_switchGlobalSet(int phyUnit, UINT32 regnum, UINT32 value) -+{ -+ UINT32 phyBase; -+ -+ if (mv_validPhyId(phyUnit)) { -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ -+ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, regnum, value); -+ } -+} -+ -+/***************************************************************************** -+* -+* mv_showATUDB - Dump the contents of the Address Translation Unit DataBase -+* for the PHY switch associated with the specified phy. -+*/ -+void -+mv_showATUDB(int phyUnit) -+{ -+ UINT32 phyBase; -+ UINT16 ATUData; -+ UINT16 ATUMac0; -+ UINT16 ATUMac2; -+ UINT16 ATUMac4; -+ int portVec; -+ int entryState; -+ -+ if (!mv_validPhyId(phyUnit)) { -+ printk("Invalid port number: %d\n", phyUnit); -+ return; -+ } -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ -+ /* Wait for previous operation (if any) to complete */ -+ mv_waitWhileATUBusy(phyBase); -+ -+ /* Initialize ATU MAC to all 1's */ -+ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR0, 0xffff); -+ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR2, 0xffff); -+ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR4, 0xffff); -+ -+ printk(" MAC ADDRESS EntryState PortVector\n"); -+ -+ for(;;) { -+ /* Tell hardware to get next MAC info */ -+ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_OPERATION, -+ MV_ATU_OP_GET_NEXT | MV_ATU_IS_BUSY); -+ -+ mv_waitWhileATUBusy(phyBase); -+ -+ ATUData = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_DATA); -+ entryState = (ATUData & MV_ENTRYSTATE_MASK) >> MV_ENTRYSTATE_SHIFT; -+ -+ if (entryState == 0) { -+ /* We've hit the end of the list */ -+ break; -+ } -+ -+ ATUMac0 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR0); -+ ATUMac2 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR2); -+ ATUMac4 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR4); -+ -+ portVec = (ATUData & MV_PORTVEC_MASK) >> MV_PORTVEC_SHIFT; -+ -+ printk("%02x:%02x:%02x:%02x:%02x:%02x 0x%02x 0x%02x\n", -+ ATUMac0 >> 8, /* MAC byte 0 */ -+ ATUMac0 & 0xff, /* MAC byte 1 */ -+ ATUMac2 >> 8, /* MAC byte 2 */ -+ ATUMac2 & 0xff, /* MAC byte 3 */ -+ ATUMac4 >> 8, /* MAC byte 4 */ -+ ATUMac4 & 0xff, /* MAC byte 5 */ -+ entryState, -+ portVec); -+ } -+} -+ -+LOCAL BOOL countingGoodFrames; -+ -+/***************************************************************************** -+* -+* mv_countGoodFrames - starts counting GOOD RX/TX frames per port -+*/ -+void -+mv_countGoodFrames(int phyUnit) -+{ -+ UINT32 phyBase; -+ UINT16 globalControl; -+ -+ if (mv_validPhyId(phyUnit)) { -+ /* -+ * Guarantee that counters are cleared by -+ * forcing CtrMode to toggle and end on GOODFRAMES. -+ */ -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ -+ /* Read current Switch Global Control Register */ -+ globalControl = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, -+ MV_SWITCH_GLOBAL_CONTROL); -+ -+ /* Set CtrMode to count BAD frames */ -+ globalControl = ((globalControl & ~MV_CTRMODE_MASK) | -+ MV_CTRMODE_BADFRAMES); -+ -+ /* Push new value out to hardware */ -+ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, -+ MV_SWITCH_GLOBAL_CONTROL, globalControl); -+ -+ /* Now toggle CtrMode to count GOOD frames */ -+ globalControl = ((globalControl & ~MV_CTRMODE_MASK) | -+ MV_CTRMODE_GOODFRAMES); -+ -+ /* Push new value out to hardware */ -+ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, -+ MV_SWITCH_GLOBAL_CONTROL, globalControl); -+ -+ countingGoodFrames = TRUE; -+ } -+} -+ -+/***************************************************************************** -+* -+* mv_countBadFrames - starts counting BAD RX/TX frames per port -+*/ -+void -+mv_countBadFrames(int phyUnit) -+{ -+ UINT32 phyBase; -+ UINT16 globalControl; -+ -+ if (mv_validPhyId(phyUnit)) { -+ /* -+ * Guarantee that counters are cleared by -+ * forcing CtrMode to toggle and end on BADFRAMES. -+ */ -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ -+ /* Read current Switch Global Control Register */ -+ globalControl = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, -+ MV_SWITCH_GLOBAL_CONTROL); -+ -+ /* Set CtrMode to count GOOD frames */ -+ globalControl = ((globalControl & ~MV_CTRMODE_MASK) | -+ MV_CTRMODE_GOODFRAMES); -+ -+ /* Push new value out to hardware */ -+ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, -+ MV_SWITCH_GLOBAL_CONTROL, globalControl); -+ -+ /* Now toggle CtrMode to count BAD frames */ -+ globalControl = ((globalControl & ~MV_CTRMODE_MASK) | -+ MV_CTRMODE_BADFRAMES); -+ -+ /* Push new value out to hardware */ -+ phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, -+ MV_SWITCH_GLOBAL_CONTROL, globalControl); -+ -+ countingGoodFrames = FALSE; -+ } -+} -+ -+/***************************************************************************** -+* -+* mv_showFrameCounts - shows current GOOD/BAD Frame counts -+*/ -+void -+mv_showFrameCounts(int phyUnit) -+{ -+ UINT16 rxCounter; -+ UINT16 txCounter; -+ UINT32 phyBase; -+ UINT32 switchPortAddr; -+ -+ if (!mv_validPhyId(phyUnit)) { -+ return; -+ } -+ -+ phyBase = MV_PHYBASE(phyUnit); -+ switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit); -+ -+ rxCounter = phyRegRead(phyBase, switchPortAddr, MV_RX_COUNTER); -+ -+ txCounter = phyRegRead(phyBase, switchPortAddr, MV_TX_COUNTER); -+ -+ printk("port%d %s frames: receive: %05d transmit: %05d\n", -+ phyUnit, -+ (countingGoodFrames ? "good" : "error"), -+ rxCounter, -+ txCounter); -+} -+#endif -diff -urN linux-mips-orig/drivers/net/ath/mvPhy.h linux-mips-new/drivers/net/ath/mvPhy.h ---- linux-mips-orig/drivers/net/ath/mvPhy.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/mvPhy.h 2005-12-31 12:33:57.727530616 +0000 -@@ -0,0 +1,162 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * mvPhy.h - definitions for the ethernet PHY -- Marvell 88E6060 -+ * All definitions in this file are operating system independent! -+ */ -+ -+#ifndef MVPHY_H -+#define MVPHY_H -+ -+/*****************/ -+/* PHY Registers */ -+/*****************/ -+#define MV_PHY_CONTROL 0 -+#define MV_PHY_STATUS 1 -+#define MV_PHY_ID1 2 -+#define MV_PHY_ID2 3 -+#define MV_AUTONEG_ADVERT 4 -+#define MV_LINK_PARTNER_ABILITY 5 -+#define MV_AUTONEG_EXPANSION 6 -+#define MV_NEXT_PAGE_TRANSMIT 7 -+#define MV_LINK_PARTNER_NEXT_PAGE 8 -+#define MV_PHY_SPECIFIC_CONTROL_1 16 -+#define MV_PHY_SPECIFIC_STATUS 17 -+#define MV_PHY_INTERRUPT_ENABLE 18 -+#define MV_PHY_INTERRUPT_STATUS 19 -+#define MV_PHY_INTERRUPT_PORT_SUMMARY 20 -+#define MV_RECEIVE_ERROR_COUNTER 21 -+#define MV_LED_PARALLEL_SELECT 22 -+#define MV_LED_STREAM_SELECT_LEDS 23 -+#define MV_PHY_LED_CONTROL 24 -+#define MV_PHY_MANUAL_LED_OVERRIDE 25 -+ -+#define MV_VCT_CONTROL 26 -+#define MV_VCT_STATUS 27 -+#define MV_PHY_SPECIFIC_CONTROL_2 28 -+ -+/* MV_PHY_CONTROL fields */ -+#define MV_CTRL_SOFTWARE_RESET 0x8000 -+#define MV_CTRL_AUTONEGOTIATION_ENABLE 0x1000 -+#define MV_CTRL_FULL_DUPLEX 0x0100 -+#define MV_CTRL_100_MBPS 0x2000 -+ -+/* MV_PHY_ID1 fields */ -+#define MV_PHY_ID1_EXPECTATION 0x0141 /* OUI >> 6 */ -+ -+/* MV_PHY_ID2 fields */ -+#define MV_OUI_LSB_MASK 0xfc00 -+#define MV_OUI_LSB_EXPECTATION 0x0c00 -+#define MV_OUI_LSB_SHIFT 10 -+#define MV_MODEL_NUM_MASK 0x03f0 -+#define MV_MODEL_NUM_SHIFT 4 -+#define MV_REV_NUM_MASK 0x000f -+#define MV_REV_NUM_SHIFT 0 -+ -+/* MV_PHY_SPECIFIC_STATUS fields */ -+#define MV_STATUS_RESOLVED_SPEED_100 0x4000 -+#define MV_STATUS_RESOLVED_DUPLEX_FULL 0x2000 -+#define MV_STATUS_RESOLVED 0x0800 -+#define MV_STATUS_REAL_TIME_LINK_UP 0x0400 -+ -+/* Check if autonegotiation is complete and link is up */ -+#define MV_AUTONEG_DONE(mv_phy_specific_status) \ -+ (((mv_phy_specific_status) & \ -+ (MV_STATUS_RESOLVED | MV_STATUS_REAL_TIME_LINK_UP)) == \ -+ (MV_STATUS_RESOLVED | MV_STATUS_REAL_TIME_LINK_UP)) -+ -+ -+/*************************/ -+/* Switch Port Registers */ -+/*************************/ -+#define MV_PORT_STATUS 0 -+#define MV_SWITCH_ID 3 -+#define MV_PORT_CONTROL 4 -+#define MV_PORT_BASED_VLAN_MAP 6 -+#define MV_PORT_ASSOCIATION_VECTOR 11 -+#define MV_RX_COUNTER 16 -+#define MV_TX_COUNTER 17 -+ -+/* MV_SWITCH_ID fields */ -+#define MV_SWITCH_ID_DEV_MASK 0xfff0 -+#define MV_SWITCH_ID_DEV_EXPECTATION 0x0600 -+#define MV_SWITCH_ID_DEV_SHIFT 4 -+#define MV_SWITCH_ID_REV_MASK 0x000f -+#define MV_SWITCH_ID_REV_SHIFT 0 -+ -+/* MV_PORT_CONTROL fields */ -+#define MV_PORT_CONTROL_PORT_STATE_MASK 0x0003 -+#define MV_PORT_CONTROL_PORT_STATE_DISABLED 0x0000 -+#define MV_PORT_CONTROL_PORT_STATE_FORWARDING 0x0003 -+ -+#define MV_PORT_CONTROL_EGRESS_MODE 0x0100 /* Receive */ -+#define MV_PORT_CONTROL_INGRESS_TRAILER 0x4000 /* Transmit */ -+ -+#define MV_EGRESS_TRAILER_VALID 0x80 -+#define MV_INGRESS_TRAILER_OVERRIDE 0x80 -+ -+#define MV_PHY_TRAILER_SIZE 4 -+ -+ -+/***************************/ -+/* Switch Global Registers */ -+/***************************/ -+#define MV_SWITCH_GLOBAL_STATUS 0 -+#define MV_SWITCH_MAC_ADDR0 1 -+#define MV_SWITCH_MAC_ADDR2 2 -+#define MV_SWITCH_MAC_ADDR4 3 -+#define MV_SWITCH_GLOBAL_CONTROL 4 -+#define MV_ATU_CONTROL 10 -+#define MV_ATU_OPERATION 11 -+#define MV_ATU_DATA 12 -+#define MV_ATU_MAC_ADDR0 13 -+#define MV_ATU_MAC_ADDR2 14 -+#define MV_ATU_MAC_ADDR4 15 -+ -+/* MV_SWITCH_GLOBAL_STATUS fields */ -+#define MV_SWITCH_STATUS_READY_MASK 0x0800 -+ -+/* MV_SWITCH_GLOBAL_CONTROL fields */ -+#define MV_CTRMODE_MASK 0x0100 -+#define MV_CTRMODE_GOODFRAMES 0x0000 -+#define MV_CTRMODE_BADFRAMES 0x0100 -+ -+/* MV_ATU_CONTROL fields */ -+#define MV_ATUCTRL_ATU_SIZE_MASK 0x3000 -+#define MV_ATUCTRL_ATU_SIZE_SHIFT 12 -+#define MV_ATUCTRL_ATU_SIZE_DEFAULT 2 /* 1024 entry database */ -+#define MV_ATUCTRL_AGE_TIME_MASK 0x0ff0 -+#define MV_ATUCTRL_AGE_TIME_SHIFT 4 -+#define MV_ATUCTRL_AGE_TIME_DEFAULT 19 /* 19 * 16 = 304 seconds */ -+ -+/* MV_ATU_OPERATION fields */ -+#define MV_ATU_BUSY_MASK 0x8000 -+#define MV_ATU_IS_BUSY 0x8000 -+#define MV_ATU_IS_FREE 0x0000 -+#define MV_ATU_OP_MASK 0x7000 -+#define MV_ATU_OP_FLUSH_ALL 0x1000 -+#define MV_ATU_OP_GET_NEXT 0x4000 -+ -+/* MV_ATU_DATA fields */ -+#define MV_ENTRYPRI_MASK 0xc000 -+#define MV_ENTRYPRI_SHIFT 14 -+#define MV_PORTVEC_MASK 0x03f0 -+#define MV_PORTVEC_SHIFT 4 -+#define MV_ENTRYSTATE_MASK 0x000f -+#define MV_ENTRYSTATE_SHIFT 0 -+ -+/* PHY Address for the switch itself */ -+#define MV_SWITCH_GLOBAL_ADDR 0x1f -+ -+BOOL mv_phySetup(int ethUnit, UINT32 phyBase); -+void mv_phyCheckStatusChange(int ethUnit); -+BOOL mv_phyIsSpeed100(int ethUnit); -+int mv_phyIsFullDuplex(int ethUnit); -+ -+#endif /* MVPHY_H */ -diff -urN linux-mips-orig/drivers/net/ath/rtPhy.c linux-mips-new/drivers/net/ath/rtPhy.c ---- linux-mips-orig/drivers/net/ath/rtPhy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/rtPhy.c 2005-12-31 12:33:57.727530616 +0000 -@@ -0,0 +1,272 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * Manage the ethernet PHY. -+ * This code supports a simple 1-port ethernet phy, Realtek RTL8201BL, -+ * and compatible PHYs, such as the Kendin KS8721B. -+ * All definitions in this file are operating system independent! -+ */ -+ -+#if defined(linux) -+#include <linux/config.h> -+#include <linux/types.h> -+#include <linux/netdevice.h> -+#include <linux/etherdevice.h> -+#include <linux/delay.h> -+ -+#include "ar531xlnx.h" -+#endif -+ -+#if defined(__ECOS) -+#include "ae531xecos.h" -+#endif -+ -+ -+#include "ae531xmac.h" -+#include "ae531xreg.h" -+#include "rtPhy.h" -+ -+#if /* DEBUG */ 1 -+#define RT_DEBUG_ERROR 0x00000001 -+#define RT_DEBUG_PHYSETUP 0x00000002 -+#define RT_DEBUG_PHYCHANGE 0x00000004 -+ -+int rtPhyDebug = RT_DEBUG_ERROR; -+ -+#define RT_PRINT(FLG, X) \ -+{ \ -+ if (rtPhyDebug & (FLG)) { \ -+ DEBUG_PRINTF X; \ -+ } \ -+} -+#else -+#define RT_PRINT(FLG, X) -+#endif -+ -+/* -+ * Track per-PHY port information. -+ */ -+typedef struct { -+ BOOL phyAlive; /* last known state of link */ -+ UINT32 phyBase; -+ UINT32 phyAddr; -+} rtPhyInfo_t; -+ -+#define ETH_PHY_ADDR 1 -+ -+/* -+ * This table defines the mapping from phy units to -+ * per-PHY information. -+ * -+ * This table is somewhat board-dependent. -+ */ -+rtPhyInfo_t rtPhyInfo[] = { -+ {phyAlive: FALSE, /* PHY 0 */ -+ phyBase: 0, /* filled in by rt_phySetup */ -+ phyAddr: ETH_PHY_ADDR}, -+ -+ {phyAlive: FALSE, /* PHY 1 */ -+ phyBase: 0, /* filled in by rt_phySetup */ -+ phyAddr: ETH_PHY_ADDR} -+}; -+ -+/* Convert from phy unit# to (phyBase, phyAddr) pair */ -+#define RT_PHYBASE(phyUnit) (rtPhyInfo[phyUnit].phyBase) -+#define RT_PHYADDR(phyUnit) (rtPhyInfo[phyUnit].phyAddr) -+ -+ -+/****************************************************************************** -+* -+* rt_phySetup - reset and setup the PHY associated with -+* the specified MAC unit number. -+* -+* Resets the associated PHY port. -+* -+* RETURNS: -+* TRUE --> associated PHY is alive -+* FALSE --> no LINKs on this ethernet unit -+*/ -+ -+BOOL -+rt_phySetup(int ethUnit, UINT32 phyBase) -+{ -+ BOOL linkAlive = FALSE; -+ UINT32 phyAddr; -+ -+ RT_PHYBASE(ethUnit) = phyBase; -+ -+ phyAddr = RT_PHYADDR(ethUnit); -+ -+ /* Reset phy */ -+ phyRegWrite(phyBase, phyAddr, GEN_ctl, PHY_SW_RST | AUTONEGENA); -+ -+ sysMsDelay(1500); -+ -+ return linkAlive; -+} -+ -+/****************************************************************************** -+* -+* rt_phyIsDuplexFull - Determines whether the phy ports associated with the -+* specified device are FULL or HALF duplex. -+* -+* RETURNS: -+* 1 --> FULL -+* 0 --> HALF -+*/ -+int -+rt_phyIsFullDuplex(int ethUnit) -+{ -+ UINT16 phyCtl; -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ -+ phyBase = RT_PHYBASE(ethUnit); -+ phyAddr = RT_PHYADDR(ethUnit); -+ -+ phyCtl = phyRegRead(phyBase, phyAddr, GEN_ctl); -+ -+ if (phyCtl & DUPLEX) { -+ return 1; -+ } else { -+ return 0; -+ } -+} -+ -+/****************************************************************************** -+* -+* rt_phyIsSpeed100 - Determines the speed of phy ports associated with the -+* specified device. -+* -+* RETURNS: -+* TRUE --> 100Mbit -+* FALSE --> 10Mbit -+*/ -+BOOL -+rt_phyIsSpeed100(int phyUnit) -+{ -+ UINT16 phyLpa; -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ -+ phyBase = RT_PHYBASE(phyUnit); -+ phyAddr = RT_PHYADDR(phyUnit); -+ -+ phyLpa = phyRegRead(phyBase, phyAddr, AN_lpa); -+ -+ if (phyLpa & (LPA_TXFD | LPA_TX)) { -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+ -+/***************************************************************************** -+* -+* rt_phyCheckStatusChange -- checks for significant changes in PHY state. -+* -+* A "significant change" is: -+* dropped link (e.g. ethernet cable unplugged) OR -+* autonegotiation completed + link (e.g. ethernet cable plugged in) -+* -+* On AR5311, there is a 1-to-1 mapping of ethernet units to PHYs. -+* When a PHY is plugged in, phyLinkGained is called. -+* When a PHY is unplugged, phyLinkLost is called. -+*/ -+void -+rt_phyCheckStatusChange(int ethUnit) -+{ -+ UINT16 phyHwStatus; -+ rtPhyInfo_t *lastStatus = &rtPhyInfo[ethUnit]; -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ -+ phyBase = RT_PHYBASE(ethUnit); -+ phyAddr = RT_PHYADDR(ethUnit); -+ -+ phyHwStatus = phyRegRead(phyBase, phyAddr, GEN_sts); -+ -+ if (lastStatus->phyAlive) { /* last known status was ALIVE */ -+ /* See if we've lost link */ -+ if (!(phyHwStatus & LINK)) { -+ RT_PRINT(RT_DEBUG_PHYCHANGE,("\nethmac%d link down\n", ethUnit)); -+ lastStatus->phyAlive = FALSE; -+ phyLinkLost(ethUnit); -+ } -+ } else { /* last known status was DEAD */ -+ /* Check for AN complete */ -+ if ((phyHwStatus & (AUTOCMPLT | LINK)) == (AUTOCMPLT | LINK)) { -+ RT_PRINT(RT_DEBUG_PHYCHANGE,("\nethmac%d link up\n", ethUnit)); -+ lastStatus->phyAlive = TRUE; -+ phyLinkGained(ethUnit); -+ } -+ } -+} -+ -+#if DEBUG -+ -+/* Define the PHY registers of interest for a phyShow command */ -+struct rtRegisterTable_s { -+ UINT32 regNum; -+ char *regIdString; -+} rtRegisterTable[] = -+{ -+ {GEN_ctl, "Basic Mode Control (GEN_ctl) "}, -+ {GEN_sts, "Basic Mode Status (GEN_sts) "}, -+ {GEN_id_hi, "PHY Identifier 1 (GET_id_hi) "}, -+ {GEN_id_lo, "PHY Identifier 2 (GET_id_lo) "}, -+ {AN_adv, "Auto-Neg Advertisement (AN_adv) "}, -+ {AN_lpa, "Auto-Neg Link Partner Ability "}, -+ {AN_exp, "Auto-Neg Expansion "}, -+}; -+ -+int rtNumRegs = sizeof(rtRegisterTable) / sizeof(rtRegisterTable[0]); -+ -+/* -+ * Dump the state of a PHY. -+ */ -+void -+rt_phyShow(int phyUnit) -+{ -+ int i; -+ UINT16 value; -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ -+ phyBase = RT_PHYBASE(phyUnit); -+ phyAddr = RT_PHYADDR(phyUnit); -+ -+ printf("PHY state for ethphy%d\n", phyUnit); -+ -+ for (i=0; i<rtNumRegs; i++) { -+ -+ value = phyRegRead(phyBase, phyAddr, rtRegisterTable[i].regNum); -+ -+ printf("Reg %02d (0x%02x) %s = 0x%08x\n", -+ rtRegisterTable[i].regNum, rtRegisterTable[i].regNum, -+ rtRegisterTable[i].regIdString, value); -+ } -+} -+ -+/* -+ * Modify the value of a PHY register. -+ * This makes it a bit easier to modify PHY values during debug. -+ */ -+void -+rt_phySet(int phyUnit, UINT32 regnum, UINT32 value) -+{ -+ UINT32 phyBase; -+ UINT32 phyAddr; -+ -+ phyBase = RT_PHYBASE(phyUnit); -+ phyAddr = RT_PHYADDR(phyUnit); -+ -+ phyRegWrite(phyBase, phyAddr, regnum, value); -+} -+#endif -diff -urN linux-mips-orig/drivers/net/ath/rtPhy.h linux-mips-new/drivers/net/ath/rtPhy.h ---- linux-mips-orig/drivers/net/ath/rtPhy.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-mips-new/drivers/net/ath/rtPhy.h 2005-12-31 12:33:57.727530616 +0000 -@@ -0,0 +1,50 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright © 2003 Atheros Communications, Inc., All Rights Reserved. -+ */ -+ -+/* -+ * rtPhy.h - definitions for the ethernet PHY. -+ * This code supports a simple 1-port ethernet phy, Realtek RTL8201BL, -+ * and compatible PHYs, such as the Kendin KS8721B. -+ * All definitions in this file are operating system independent! -+ */ -+ -+#ifndef RTPHY_H -+#define RTPHY_H -+ -+/* MII Registers */ -+ -+#define GEN_ctl 00 -+#define GEN_sts 01 -+#define GEN_id_hi 02 -+#define GEN_id_lo 03 -+#define AN_adv 04 -+#define AN_lpa 05 -+#define AN_exp 06 -+ -+/* GEN_ctl */ -+#define PHY_SW_RST 0x8000 -+#define LOOPBACK 0x4000 -+#define SPEED 0x2000 /* 100 Mbit/s */ -+#define AUTONEGENA 0x1000 -+#define DUPLEX 0x0100 /* Duplex mode */ -+ -+ -+/* GEN_sts */ -+#define AUTOCMPLT 0x0020 /* Autonegotiation completed */ -+#define LINK 0x0004 /* Link status */ -+ -+/* GEN_ids */ -+#define RT_PHY_ID1_EXPECTATION 0x22 -+ -+/* AN_lpa */ -+#define LPA_TXFD 0x0100 /* Link partner supports 100 TX Full Duplex */ -+#define LPA_TX 0x0080 /* Link partner supports 100 TX Half Duplex */ -+#define LPA_10FD 0x0040 /* Link partner supports 10 BT Full Duplex */ -+#define LPA_10 0x0020 /* Link partner supports 10 BT Half Duplex */ -+ -+#endif /* RTPHY_H */ -diff -urN linux-mips/include/linux/raid/md_p.h mips-linux-2.4.25/include/linux/raid/md_p.h ---- linux-mips/include/linux/raid/md_p.h 2005-12-24 15:12:07.189098448 +0000 -+++ mips-linux-2.4.25/include/linux/raid/md_p.h 2005-12-30 17:28:10.345721232 +0000 -@@ -151,10 +151,12 @@ - */ - mdp_disk_t disks[MD_SB_DISKS]; - -+#if MD_SB_RESERVED_WORDS - /* - * Reserved - */ - __u32 reserved[MD_SB_RESERVED_WORDS]; -+#endif - - /* - * Active descriptor |