diff options
author | Felix Fietkau <nbd@openwrt.org> | 2007-02-04 21:18:10 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2007-02-04 21:18:10 +0000 |
commit | 76c376d82a9bb487024875ad8a9985b078428ca0 (patch) | |
tree | cb1889ac12efd291486fea515200a0715cba6ce7 /target/linux/atheros-2.6/patches | |
parent | b4bd2648998ee5ed8f4a1dc6385462976ad64ff0 (diff) | |
download | upstream-76c376d82a9bb487024875ad8a9985b078428ca0.tar.gz upstream-76c376d82a9bb487024875ad8a9985b078428ca0.tar.bz2 upstream-76c376d82a9bb487024875ad8a9985b078428ca0.zip |
update atheros 2.6 port - add support for the older chip generation
SVN-Revision: 6265
Diffstat (limited to 'target/linux/atheros-2.6/patches')
4 files changed, 32 insertions, 4667 deletions
diff --git a/target/linux/atheros-2.6/patches/100-board.patch b/target/linux/atheros-2.6/patches/100-board.patch index 040a28faf2..a137d15d20 100644 --- a/target/linux/atheros-2.6/patches/100-board.patch +++ b/target/linux/atheros-2.6/patches/100-board.patch @@ -1,1926 +1,63 @@ -diff -urN linux.old/arch/mips/ar531x/ar531x.h linux.dev/arch/mips/ar531x/ar531x.h ---- linux.old/arch/mips/ar531x/ar531x.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/ar531x/ar531x.h 2006-12-16 03:51:47.000000000 +0100 -@@ -0,0 +1,734 @@ -+/* -+ * 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 (C) 2003 Atheros Communications, Inc., All Rights Reserved. -+ * Copyright (C) 2006 FON Technology, SL. -+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> -+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> -+ */ -+ -+#ifndef AR531X_H -+#define AR531X_H 1 -+ -+/* -+ * 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 */ -+ -+#define AR5317_RESET_SYSTEM 0x00000010 -+ -+/* 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 -+ -+#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 -+ -+/* -+ * 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 -+ -+#define sysRegRead(phys) \ -+ (*(volatile u32 *)KSEG1ADDR(phys)) -+ -+#define sysRegWrite(phys, val) \ -+ ((*(volatile u32 *)KSEG1ADDR(phys)) = (val)) -+ -+#endif -diff -urN linux.old/arch/mips/ar531x/ar531xlnx.h linux.dev/arch/mips/ar531x/ar531xlnx.h ---- linux.old/arch/mips/ar531x/ar531xlnx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/ar531x/ar531xlnx.h 2006-12-16 04:49:36.000000000 +0100 -@@ -0,0 +1,74 @@ -+/* -+ * 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 (C) 2003 Atheros Communications, Inc., All Rights Reserved. -+ * Copyright (C) 2006 FON Technology, SL. -+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> -+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> -+ */ -+ -+/* -+ * 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" -+ -+/* -+ * Board support data. The driver is required to locate -+ * and fill-in this information before passing a reference to -+ * this structure as the HAL_BUS_TAG parameter supplied to -+ * ath_hal_attach. -+ */ -+struct ar531x_config { -+ const char *board; /* board config data */ -+ const char *radio; /* radio config data */ -+ int unit; /* unit number [0, 1] */ -+ u32 tag; /* used as devid for now */ -+}; -+ -+#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" */ -+#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 */ -+ -+/* 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 -+#define AR531X_GPIO_IRQ_COUNT 22 -+ -+extern struct ar531x_boarddata *ar531x_board_configuration; -+extern char *ar531x_radio_configuration; -+extern char *enet_mac_address_get(int MACUnit); -+ -+#define A_DATA_CACHE_INVAL(start, length) \ -+ dma_cache_inv((UINT32)(start),(length)) -+ -+#endif /* _AR531XLNX_H */ -diff -urN linux.old/arch/mips/ar531x/devices.c linux.dev/arch/mips/ar531x/devices.c ---- linux.old/arch/mips/ar531x/devices.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/ar531x/devices.c 2006-12-16 04:46:43.000000000 +0100 -@@ -0,0 +1,281 @@ -+/* -+ * 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 (C) 2003 Atheros Communications, Inc., All Rights Reserved. -+ * Copyright (C) 2006 FON Technology, SL. -+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> -+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> -+ */ -+ -+/* -+ * Platform devices for AR531x SoC. -+ */ -+ -+#include <linux/autoconf.h> -+#include <linux/init.h> -+#include <linux/module.h> -+#include <linux/types.h> -+#include <linux/string.h> -+#include <linux/platform_device.h> -+#include <linux/kernel.h> -+#include <asm/io.h> -+#include <ar531x_platform.h> -+ -+#include "ar531xlnx.h" -+ -+static struct resource ar531x_eth_res[] = { -+ { -+ .name = "eth_membase", -+ .flags = IORESOURCE_MEM, -+ .start = 0xb0500000, -+ .end = 0xb0502000, -+ }, -+ { -+ .name = "eth_irq", -+ .flags = IORESOURCE_IRQ, -+ .start = 4, -+ .end = 4, -+ }, -+}; -+ -+static struct ar531x_eth ar531x_eth_data = { -+ .phy = 1, -+ .mac = 0, -+ .reset_base = 0x11000004, -+ .reset_mac = 0x800, -+ .reset_phy = 0x400, -+}; -+ -+static struct platform_device ar531x_eth = { -+ .id = 0, -+ .name = "ar531x-eth", -+ .dev.platform_data = &ar531x_eth_data, -+ .resource = ar531x_eth_res, -+ .num_resources = ARRAY_SIZE(ar531x_eth_res) -+}; -+ -+static struct platform_device ar531x_wmac = { -+ .id = 0, -+ .name = "ar531x-wmac", -+ /* FIXME: add resources */ -+}; -+ -+static struct resource ar531x_spiflash_res[] = { -+ { -+ .name = "flash_base", -+ .flags = IORESOURCE_MEM, -+ .start = 0xa8000000, -+ .end = 0xa8400000, -+ }, -+ { -+ .name = "flash_regs", -+ .flags = IORESOURCE_MEM, -+ .start = 0x11300000, -+ .end = 0x11300012, -+ }, -+}; -+ -+static struct platform_device ar531x_spiflash = { -+ .id = 0, -+ .name = "spiflash", -+ .resource = ar531x_spiflash_res, -+ .num_resources = ARRAY_SIZE(ar531x_spiflash_res) -+}; -+ -+static __initdata struct platform_device *ar531x_devs[] = { -+ &ar531x_eth, -+ &ar531x_wmac, -+ &ar531x_spiflash -+}; -+ -+ -+ -+static void *flash_regs; -+ -+static inline __u32 spiflash_regread32(int reg) -+{ -+ volatile __u32 *data = (__u32 *)(flash_regs + reg); -+ -+ return (*data); -+} -+ -+static inline void spiflash_regwrite32(int reg, __u32 data) -+{ -+ volatile __u32 *addr = (__u32 *)(flash_regs + reg); -+ -+ *addr = data; -+} -+ -+#define SPI_FLASH_CTL 0x00 -+#define SPI_FLASH_OPCODE 0x04 -+#define SPI_FLASH_DATA 0x08 -+ -+static __u8 spiflash_probe(void) -+{ -+ __u32 reg; -+ -+ do { -+ reg = spiflash_regread32(SPI_FLASH_CTL); -+ } while (reg & SPI_CTL_BUSY); -+ -+ spiflash_regwrite32(SPI_FLASH_OPCODE, 0xab); -+ -+ reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | 4 | -+ (1 << 4) | SPI_CTL_START; -+ -+ spiflash_regwrite32(SPI_FLASH_CTL, reg); -+ -+ do { -+ reg = spiflash_regread32(SPI_FLASH_CTL); -+ } while (reg & SPI_CTL_BUSY); -+ -+ reg = (__u32) spiflash_regread32(SPI_FLASH_DATA); -+ reg &= 0xff; -+ -+ return (u8) reg; -+} -+ -+static u8 *find_board_config(void) -+{ -+ char *addr; -+ int found = 0; -+ -+ for (addr = (char *) (ar531x_spiflash_res[0].end - 0x1000); -+ addr >= (char *) (ar531x_spiflash_res[0].end - 0x30000); -+ addr -= 0x1000) { -+ -+ if ( *(int *)addr == 0x35333131) { -+ /* config magic found */ -+ found = 1; -+ break; -+ } -+ } -+ -+ if (!found) { -+ printk("WARNING: No board configuration data found!\n"); -+ addr = NULL; -+ } -+ -+ return addr; -+} -+ -+static void *find_radio_config(char *board_config) -+{ -+ int dataFound; -+ u32 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 = (u32) board_config + 0x1000; -+ (radio_config < (u32) ar531x_spiflash_res[0].end); -+ radio_config += 0x1000) { -+ if (*(int *)radio_config != 0xffffffff) { -+ dataFound = 1; -+ break; -+ } -+ } -+ -+ if (!dataFound) { /* AR2316 relocates radio config to new location */ -+ for (radio_config = (u32) board_config + 0xf8; -+ (radio_config < (u32) ar531x_spiflash_res[0].end - 0x1000 + 0xf8); -+ radio_config += 0x1000) { -+ if (*(int *)radio_config != 0xffffffff) { -+ dataFound = 1; -+ break; -+ } -+ } -+ } -+ -+ if (!dataFound) { -+ printk("Could not find Radio Configuration data\n"); -+ radio_config = 0; -+ } -+ -+ return (u8 *) radio_config; -+} -+ -+ -+#define STM_8MBIT_SIGNATURE 0x13 -+#define STM_16MBIT_SIGNATURE 0x14 -+#define STM_32MBIT_SIGNATURE 0x15 -+#define STM_64MBIT_SIGNATURE 0x16 -+ -+ -+static void __init ar531x_init_flash(void) -+{ -+ u8 sig; -+ u32 flash_size = 0; -+ unsigned int rcfg_size; -+ char *bcfg, *rcfg, *board_config, *radio_config; -+ struct ar531x_config *config; -+ -+ /* probe the flash chip size */ -+ flash_regs = ioremap_nocache(ar531x_spiflash_res[1].start, ar531x_spiflash_res[1].end - ar531x_spiflash_res[1].start); -+ sig = spiflash_probe(); -+ iounmap(flash_regs); -+ -+ switch(sig) { -+ case STM_8MBIT_SIGNATURE: -+ flash_size = 0x00100000; -+ break; -+ case STM_16MBIT_SIGNATURE: -+ flash_size = 0x00200000; -+ break; -+ case STM_32MBIT_SIGNATURE: -+ flash_size = 0x00400000; -+ break; -+ case STM_64MBIT_SIGNATURE: -+ flash_size = 0x00800000; -+ break; -+ } -+ -+ if (!flash_size) -+ return; -+ -+ ar531x_spiflash_res[0].end = ar531x_spiflash_res[0].start + flash_size; -+ -+ /* Copy the board and radio data to RAM, because with the new -+ * spiflash driver, accessing the mapped memory directly is no -+ * longer safe */ -+ -+ bcfg = find_board_config(); -+ if (!bcfg) -+ return; -+ -+ board_config = kmalloc(0x1000, GFP_KERNEL); -+ memcpy(board_config, bcfg, 0x100); -+ ar531x_eth_data.board_config = board_config; -+ -+ /* Radio config starts 0x100 bytes after board config, regardless -+ * of what the physical layout on the flash chip looks like */ -+ -+ rcfg = find_radio_config(bcfg); -+ if (!rcfg) -+ return; -+ printk("Radio config found at offset 0x%x\n", rcfg - bcfg); -+ radio_config = board_config + 0x100 + ((rcfg - bcfg) & 0xfff); -+ rcfg_size = 0x1000 - ((rcfg - bcfg) & 0xfff); -+ memcpy(radio_config, rcfg, rcfg_size); -+ -+ config = (struct ar531x_config *) kzalloc(sizeof(struct ar531x_config), GFP_KERNEL); -+ config->board = board_config; -+ config->radio = radio_config; -+ config->unit = 0; -+ config->tag = (u_int16_t) (sysRegRead(AR5315_SREV) & REV_CHIP); -+ ar531x_wmac.dev.platform_data = config; -+} -+ -+static int __init ar531x_register_devices(void) -+{ -+ ar531x_init_flash(); -+ return platform_add_devices(ar531x_devs, ARRAY_SIZE(ar531x_devs)); -+} -+ -+ -+arch_initcall(ar531x_register_devices); -diff -urN linux.old/arch/mips/ar531x/gpio.c linux.dev/arch/mips/ar531x/gpio.c ---- linux.old/arch/mips/ar531x/gpio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/ar531x/gpio.c 2006-12-16 04:49:20.000000000 +0100 -@@ -0,0 +1,127 @@ -+/* -+ * 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 (C) 2003 Atheros Communications, Inc., All Rights Reserved. -+ * Copyright (C) 2006 FON Technology, SL. -+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> -+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> -+ */ -+ -+/* -+ * Support for GPIO -- General Purpose Input/Output Pins -+ * XXX: should be rewritten -+ */ -+ -+#include <linux/autoconf.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; -+ -+static void ar531x_gpio_intr_set_enabled(unsigned int gpio, int enabled) -+{ -+ u32 reg; -+ int intnum = 0; -+ int intlevel = 2; -+ -+ reg = sysRegRead(AR5315_GPIO_CR); -+ reg &= ~(GPIO_CR_M(gpio)); -+ reg |= GPIO_CR_I(gpio); -+ sysRegWrite(AR5315_GPIO_CR, reg); -+ (void)sysRegRead(AR5315_GPIO_CR); /* flush write to hardware */ -+ -+ reg = sysRegRead(AR5315_GPIO_INT); -+ -+ reg &= ~(GPIO_INT_M(intnum)); -+ reg &= ~(GPIO_INT_LVL_M(intnum)); -+ -+ if (enabled) { -+ reg |= GPIO_INT_LVL(intlevel, intnum); -+ reg |= GPIO_INT(gpio, intnum); -+ } -+ -+ sysRegWrite(AR5315_GPIO_INT, reg); -+ (void)sysRegRead(AR5315_GPIO_INT); /* flush write to hardware */ -+} -+ -+ -+/* Enable the specified AR531X_GPIO_IRQ interrupt */ -+static void -+ar531x_gpio_intr_enable(unsigned int irq) -+{ -+ int gpio = irq - AR531X_GPIO_IRQ_BASE; -+ -+ gpioIntMask |= (1<<gpio); -+ ar531x_gpio_intr_set_enabled(irq, 1); -+} -+ -+/* Disable the specified AR531X_GPIO_IRQ interrupt */ -+static void -+ar531x_gpio_intr_disable(unsigned int irq) -+{ -+ int gpio = irq - AR531X_GPIO_IRQ_BASE; -+ -+ gpioIntMask &= (1<<gpio); -+ ar531x_gpio_intr_set_enabled(irq, 0); -+} -+ -+ -+static void -+ar531x_gpio_intr_end(unsigned int irq) -+{ -+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) -+ ar531x_gpio_intr_enable(irq); -+} -+ -+int ar531x_gpio_irq_base; -+ -+struct hw_interrupt_type ar531x_gpio_intr_controller = { -+ .typename = "AR531X GPIO", -+ .startup = ar531x_gpio_intr_startup, -+ .shutdown = ar531x_gpio_intr_shutdown, -+ .enable = ar531x_gpio_intr_enable, -+ .disable = ar531x_gpio_intr_disable, -+ .ack = ar531x_gpio_intr_disable, -+ .end = ar531x_gpio_intr_end, -+}; -+ -+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].chip = &ar531x_gpio_intr_controller; -+ } -+ -+ ar531x_gpio_irq_base = irq_base; -+} -+ -+ -diff -urN linux.old/arch/mips/ar531x/irq.c linux.dev/arch/mips/ar531x/irq.c ---- linux.old/arch/mips/ar531x/irq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/ar531x/irq.c 2006-12-17 15:09:04.000000000 +0100 -@@ -0,0 +1,312 @@ -+/* -+ * 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 (C) 2003 Atheros Communications, Inc., All Rights Reserved. -+ * Copyright (C) 2006 FON Technology, SL. -+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> -+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> -+ */ -+ -+/* -+ * Interrupt support for AR531X WiSOC. -+ */ -+ -+#include <linux/autoconf.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; -+ -+ 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_MISC_IRQ_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); -+ -+} -+ -+/* Disable the specified AR531X_MISC_IRQ interrupt */ -+static void -+ar531x_misc_intr_disable(unsigned int irq) -+{ -+ unsigned int imr; -+ -+ 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_MISC_IRQ_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 */ -+} -+ -+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); -+} -+ -+struct irq_chip ar531x_misc_intr_controller = { -+ .typename = "AR531X MISC", -+ .startup = ar531x_misc_intr_startup, -+ .shutdown = ar531x_misc_intr_shutdown, -+ .enable = ar531x_misc_intr_enable, -+ .disable = ar531x_misc_intr_disable, -+ .ack = ar531x_misc_intr_ack, -+ .end = ar531x_misc_intr_end, -+}; -+ -+/* -+ * 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].chip = &ar531x_misc_intr_controller; -+ } -+} -+ -+/* ARGSUSED */ -+irqreturn_t -+spurious_irq_handler(int cpl, void *dev_id) -+{ -+ /* -+ printk("spurious_irq_handler: %d cause=0x%8.8x status=0x%8.8x\n", -+ cpl, cause_intrs, status_intrs); -+ */ -+ return IRQ_NONE; -+} -+ -+/* ARGSUSED */ -+irqreturn_t -+spurious_misc_handler(int cpl, void *dev_id) -+{ -+ /* -+ printk("spurious_misc_handler: 0x%x isr=0x%8.8x imr=0x%8.8x\n", -+ cpl, ar531x_isr, ar531x_imr); -+ */ -+ return IRQ_NONE; -+} -+ -+irqreturn_t -+ar531x_ahb_proc_handler(int cpl, void *dev_id) -+{ -+ u32 procAddr = -1; -+ u32 proc1 = -1; -+ u32 dmaAddr = -1; -+ u32 dma1 = -1; -+ sysRegWrite(AR5315_AHB_ERR0,AHB_ERROR_DET); -+ sysRegRead(AR5315_AHB_ERR1); -+ -+ 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 */ -+ return IRQ_HANDLED; -+} -+ -+static struct irqaction cascade = { -+ .handler = no_action, -+ .flags = SA_INTERRUPT, -+ .name = "cascade", -+}; -+ -+static struct irqaction spurious_irq = { -+ .handler = spurious_irq_handler, -+ .flags = SA_INTERRUPT, -+ .name = "spurious_irq", -+}; -+ -+static struct irqaction spurious_misc = { -+ .handler = spurious_misc_handler, -+ .flags = SA_INTERRUPT, -+ .name = "spurious_misc", -+}; -+ -+static struct irqaction ar531x_ahb_proc_interrupt = { -+ .handler = ar531x_ahb_proc_handler, -+ .flags = SA_INTERRUPT, -+ .name = "ar531x_ahb_proc_interrupt", -+}; -+ -+/* -+ * 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. -+ */ -+asmlinkage void plat_irq_dispatch(void) -+{ -+ int pending = read_c0_status() & read_c0_cause(); -+ -+ if (pending & CAUSEF_IP3) -+ do_IRQ(AR531X_IRQ_WLAN0_INTRS); -+ else if (pending & CAUSEF_IP4) -+ do_IRQ(AR531X_IRQ_ENET0_INTRS); -+ else if (pending & CAUSEF_IP2) { -+ unsigned int ar531x_misc_intrs = sysRegRead(AR5315_ISR) & sysRegRead(AR5315_IMR); -+ -+ if (ar531x_misc_intrs & ISR_TIMER) -+ do_IRQ(AR531X_MISC_IRQ_TIMER); -+ else if (ar531x_misc_intrs & ISR_AHB) -+ do_IRQ(AR531X_MISC_IRQ_AHB_PROC); -+ else if (ar531x_misc_intrs & ISR_GPIO) { -+#if 0 -+ 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_BASE+i); -+ } -+#endif -+ sysRegWrite(AR5315_ISR, sysRegRead(AR5315_IMR) | ~ISR_GPIO); -+ } else if (ar531x_misc_intrs & ISR_UART0) -+ do_IRQ(AR531X_MISC_IRQ_UART0); -+ else if (ar531x_misc_intrs & ISR_WD) -+ do_IRQ(AR531X_MISC_IRQ_WATCHDOG); -+ else -+ do_IRQ(AR531X_MISC_IRQ_NONE); -+ } else if (pending & CAUSEF_IP7) -+ do_IRQ(AR531X_IRQ_CPU_CLOCK); -+ else -+ do_IRQ(AR531X_IRQ_NONE); -+} -+ -+void __init arch_init_irq(void) -+{ -+ clear_c0_status(ST0_IM); -+ mips_cpu_irq_init(0); -+ -+ /* Initialize interrupt controllers */ -+ ar531x_misc_intr_init(AR531X_MISC_IRQ_BASE); -+#if 0 -+ ar531x_gpio_intr_init(AR531X_GPIO_IRQ_BASE); -+#endif -+ 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_MISC_IRQ_AHB_PROC, &ar531x_ahb_proc_interrupt); -+ setup_irq(AR531X_MISC_IRQ_GPIO, &cascade); -+} -diff -urN linux.old/arch/mips/ar531x/Makefile linux.dev/arch/mips/ar531x/Makefile ---- linux.old/arch/mips/ar531x/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/ar531x/Makefile 2006-12-16 03:51:47.000000000 +0100 -@@ -0,0 +1,18 @@ -+# -+# 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 (C) 2003 Atheros Communications, Inc., All Rights Reserved. -+# Copyright (C) 2006 FON Technology, SL. -+# Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> -+# Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> -+# -+ -+# 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). -+# -+obj-y := setup.o prom.o irq.o devices.o -diff -urN linux.old/arch/mips/ar531x/prom.c linux.dev/arch/mips/ar531x/prom.c ---- linux.old/arch/mips/ar531x/prom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/ar531x/prom.c 2006-12-16 04:50:30.000000000 +0100 -@@ -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 MontaVista Software Inc -+ * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. -+ * Copyright (C) 2006 FON Technology, SL. -+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> -+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> -+ */ -+ -+/* -+ * Prom setup file for ar531x -+ */ -+ -+#include <linux/init.h> -+#include <linux/autoconf.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" -+ -+void __init prom_init(void) -+{ -+ u32 memsize, memcfg; -+ -+ mips_machgroup = MACH_GROUP_AR531X; -+ mips_machtype = MACH_ATHEROS_AP51; -+ -+ memcfg = sysRegRead(AR5315_MEM_CFG); -+ memsize = 1 + ((memcfg & SDRAM_DATA_WIDTH_M) >> SDRAM_DATA_WIDTH_S); -+ memsize <<= 1 + ((memcfg & SDRAM_COL_WIDTH_M) >> SDRAM_COL_WIDTH_S); -+ memsize <<= 1 + ((memcfg & SDRAM_ROW_WIDTH_M) >> SDRAM_ROW_WIDTH_S); -+ memsize <<= 3; -+ add_memory_region(0, memsize, BOOT_MEM_RAM); -+ -+ strcpy(arcs_cmdline, "console=ttyS0,9600 rootfstype=squashfs,jffs2"); -+} -+ -+void __init prom_free_prom_memory(void) -+{ -+} -+ -+ -diff -urN linux.old/arch/mips/ar531x/setup.c linux.dev/arch/mips/ar531x/setup.c ---- linux.old/arch/mips/ar531x/setup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/ar531x/setup.c 2006-12-16 03:51:47.000000000 +0100 -@@ -0,0 +1,198 @@ -+/* -+ * 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 (C) 2003 Atheros Communications, Inc., All Rights Reserved. -+ * Copyright (C) 2006 FON Technology, SL. -+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> -+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> -+ */ -+ -+/* -+ * Initialization for ar531x SOC. -+ */ -+ -+#include <linux/autoconf.h> -+#include <linux/init.h> -+#include <linux/module.h> -+#include <linux/delay.h> -+#include <linux/irq.h> -+#include <linux/interrupt.h> -+#include <linux/pm.h> -+#include <linux/serial.h> -+#include <linux/serial_core.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(;;) { -+ /* -+ ** Cold reset does not work,work around is to use the GPIO reset bit. -+ */ -+ unsigned int reg; -+ -+ /* AR2317 reset */ -+ sysRegWrite(AR5315_COLD_RESET,AR5317_RESET_SYSTEM); -+ -+ reg = sysRegRead(AR5315_GPIO_DO); -+ reg &= ~(1 << AR5315_RESET_GPIO); -+ sysRegWrite(AR5315_GPIO_DO, reg); -+ (void)sysRegRead(AR5315_GPIO_DO); /* flush write to hardware */ -+ } -+} -+ -+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(); -+} -+ -+char *get_system_type(void) -+{ -+ return "Atheros AR5315"; -+} -+ -+/* -+ * This table is indexed by bits 5..4 of the CLOCKCTL1 register -+ * to determine the predevisor value. -+ */ -+static int __initdata CLOCKCTL1_PREDIVIDE_TABLE[4] = { -+ 1, -+ 2, -+ 4, -+ 5 -+}; -+ -+static int __initdata PLLC_DIVIDE_TABLE[5] = { -+ 2, -+ 3, -+ 4, -+ 6, -+ 3 -+}; -+ -+static unsigned int __init -+ar531x_sys_clk(unsigned int clockCtl) -+{ -+ unsigned int pllcCtrl,cpuDiv; -+ unsigned int pllcOut,refdiv,fdiv,divby2; -+ unsigned int clkDiv; -+ -+ 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; -+ -+ -+ /* clkm input selected */ -+ switch(clockCtl & CPUCLK_CLK_SEL_M) { -+ case 0: -+ case 1: -+ clkDiv = PLLC_DIVIDE_TABLE[(pllcCtrl & PLLC_CLKM_DIV_M) >> PLLC_CLKM_DIV_S]; -+ break; -+ case 2: -+ clkDiv = PLLC_DIVIDE_TABLE[(pllcCtrl & PLLC_CLKC_DIV_M) >> PLLC_CLKC_DIV_S]; -+ break; -+ default: -+ pllcOut = 40000000; -+ clkDiv = 1; -+ break; -+ } -+ cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S; -+ cpuDiv = cpuDiv * 2 ?: 1; -+ return (pllcOut/(clkDiv * cpuDiv)); -+} -+ -+static inline unsigned int ar531x_cpu_frequency(void) -+{ -+ return ar531x_sys_clk(sysRegRead(AR5315_CPUCLK)); -+} -+ -+static inline unsigned int ar531x_apb_frequency(void) -+{ -+ return ar531x_sys_clk(sysRegRead(AR5315_AMBACLK)); -+} -+ -+ -+void __init serial_setup(void) -+{ -+ struct uart_port s; -+ -+ memset(&s, 0, sizeof(s)); -+ -+ s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; -+ s.iotype = UPIO_MEM; -+ s.uartclk = AR5315_UART_CLOCK_RATE; -+ s.irq = AR531X_MISC_IRQ_UART0; -+ s.regshift = 2; -+ s.mapbase = KSEG1ADDR(AR5315_UART0); -+ s.membase = (void __iomem *)s.mapbase; -+ -+ early_serial_setup(&s); -+} -+ -+void __init plat_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); -+} -+ -+static void __init -+ar531x_time_init(void) -+{ -+ mips_hpt_frequency = ar531x_cpu_frequency() / 2; -+} -+ -+void __init plat_mem_setup(void) -+{ -+ unsigned int config = read_c0_config(); -+ -+ /* Clear any lingering AHB errors */ -+ write_c0_config(config & ~0x3); -+ sysRegWrite(AR5315_AHB_ERR0,AHB_ERROR_DET); -+ sysRegRead(AR5315_AHB_ERR1); -+ sysRegWrite(AR5315_WDC, WDC_IGNORE_EXPIRATION); -+ -+ /* Disable data watchpoints */ -+ write_c0_watchlo0(0); -+ -+ board_time_init = ar531x_time_init; -+ -+ _machine_restart = ar531x_restart; -+ _machine_halt = ar531x_halt; -+ pm_power_off = ar531x_power_off; -+ -+ serial_setup(); -+} -+ -+EXPORT_SYMBOL(get_system_type); diff -urN linux.old/arch/mips/Kconfig linux.dev/arch/mips/Kconfig ---- linux.old/arch/mips/Kconfig 2006-11-29 22:57:37.000000000 +0100 -+++ linux.dev/arch/mips/Kconfig 2006-12-16 03:51:47.000000000 +0100 -@@ -145,6 +145,19 @@ +--- linux.old/arch/mips/Kconfig 2007-02-02 23:55:52.912446784 +0100 ++++ linux.dev/arch/mips/Kconfig 2007-02-03 21:50:25.262027104 +0100 +@@ -145,6 +145,16 @@ note that a kernel built with this option selected will not be able to run on normal units. -+config AR531X -+ bool 'Atheros AR531x/AR231x WiSoC (EXPERIMENTAL)' ++config ATHEROS ++ bool "Atheros SoC support (EXPERIMENTAL)" + depends on EXPERIMENTAL + select DMA_NONCOHERENT + select IRQ_CPU + select SYS_HAS_CPU_MIPS32_R1 + select HAVE_STD_PC_SERIAL_PORT -+ select AR531X_COBRA -+ select AR5315 -+ select AP51 + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_32BIT_KERNEL + config MIPS_COBALT bool "Cobalt Server" select DMA_NONCOHERENT -@@ -864,6 +877,18 @@ - config MIPS_DISABLE_OBSOLETE_IDE - bool +@@ -766,6 +776,7 @@ -+config AR531X_COBRA -+ bool -+ -+config AR5315 -+ bool -+ -+config AR5317 -+ bool -+ -+config AP51 -+ bool -+ - # - # Endianess selection. Suffiently obscure so many users don't know what to - # answer,so we try hard to limit the available choices. Also the use of a + endchoice + ++source "arch/mips/atheros/Kconfig" + source "arch/mips/ddb5xxx/Kconfig" + source "arch/mips/gt64120/ev64120/Kconfig" + source "arch/mips/jazz/Kconfig" diff -urN linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile ---- linux.old/arch/mips/Makefile 2006-12-14 23:53:29.000000000 +0100 -+++ linux.dev/arch/mips/Makefile 2006-12-16 04:45:48.000000000 +0100 +--- linux.old/arch/mips/Makefile 2007-02-02 23:55:52.913446632 +0100 ++++ linux.dev/arch/mips/Makefile 2007-02-03 17:40:29.193776000 +0100 @@ -267,6 +267,13 @@ load-$(CONFIG_MIPS_XXS1500) += 0xffffffff80100000 # +# Atheros AR5312/AR2312 WiSoC +# -+core-$(CONFIG_AR531X) += arch/mips/ar531x/ -+cflags-$(CONFIG_AR531X) += -Iinclude/asm-mips/mach-atheros -+load-$(CONFIG_AR531X) += 0xffffffff80041000 ++core-$(CONFIG_ATHEROS) += arch/mips/atheros/ ++cflags-$(CONFIG_ATHEROS) += -Iinclude/asm-mips/mach-atheros ++load-$(CONFIG_ATHEROS) += 0xffffffff80041000 + +# # Cobalt Server # core-$(CONFIG_MIPS_COBALT) += arch/mips/cobalt/ diff -urN linux.old/include/asm-mips/bootinfo.h linux.dev/include/asm-mips/bootinfo.h ---- linux.old/include/asm-mips/bootinfo.h 2006-11-29 22:57:37.000000000 +0100 -+++ linux.dev/include/asm-mips/bootinfo.h 2006-12-16 03:51:47.000000000 +0100 -@@ -212,6 +212,19 @@ +--- linux.old/include/asm-mips/bootinfo.h 2007-02-02 23:55:52.913446632 +0100 ++++ linux.dev/include/asm-mips/bootinfo.h 2007-02-03 17:51:02.531494032 +0100 +@@ -212,6 +212,13 @@ #define MACH_GROUP_NEC_EMMA2RH 25 /* NEC EMMA2RH (was 23) */ #define MACH_NEC_MARKEINS 0 /* NEC EMMA2RH Mark-eins */ +/* -+ * Valid machtype for group AR531X ++ * Valid machtype for group ATHEROS + */ -+#define MACH_GROUP_AR531X 23 -+#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 MACH_ATHEROS_AP51 7 /* AP51 */ ++#define MACH_GROUP_ATHEROS 26 ++#define MACH_ATHEROS_AR5312 0 /* Atheros AR5312, AR2312/3/4 */ ++#define MACH_ATHEROS_AR5315 1 /* Atheros AR2315/6/7/8 */ + #define CL_SIZE COMMAND_LINE_SIZE const char *get_system_type(void); -diff -urN linux.old/include/asm-mips/mach-atheros/ar531x_platform.h linux.dev/include/asm-mips/mach-atheros/ar531x_platform.h ---- linux.old/include/asm-mips/mach-atheros/ar531x_platform.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/include/asm-mips/mach-atheros/ar531x_platform.h 2006-12-16 04:27:21.000000000 +0100 -@@ -0,0 +1,14 @@ -+#ifndef __AR531X_PLATFORM_H -+#define __AR531X_PLATFORM_H -+ -+struct ar531x_eth { -+ int phy; -+ int mac; -+ u32 reset_base; -+ u32 reset_mac; -+ u32 reset_phy; -+ char *board_config; -+}; -+ -+#endif /* __AR531X_PLATFORM_H */ -+ + diff --git a/target/linux/atheros-2.6/patches/110-spiflash.patch b/target/linux/atheros-2.6/patches/110-spiflash.patch index a8fc4af8ed..e6461ff06d 100644 --- a/target/linux/atheros-2.6/patches/110-spiflash.patch +++ b/target/linux/atheros-2.6/patches/110-spiflash.patch @@ -1,750 +1,23 @@ diff -urN linux.old/drivers/mtd/devices/Kconfig linux.dev/drivers/mtd/devices/Kconfig ---- linux.old/drivers/mtd/devices/Kconfig 2006-11-29 22:57:37.000000000 +0100 -+++ linux.dev/drivers/mtd/devices/Kconfig 2006-12-15 00:03:11.000000000 +0100 +--- linux.old/drivers/mtd/devices/Kconfig 2007-02-04 04:30:26.145338240 +0100 ++++ linux.dev/drivers/mtd/devices/Kconfig 2007-02-02 23:48:28.748969000 +0100 @@ -68,6 +68,10 @@ used for program and data storage. Set up your spi devices with the right board-specific platform data. +config MTD_SPIFLASH + tristate "Atheros AR2315/6/7 SPI Flash support" -+ depends on MTD && AR531X_COBRA ++ depends on MTD && ATHEROS_AR5315 + config MTD_SLRAM tristate "Uncached system RAM" depends on MTD diff -urN linux.old/drivers/mtd/devices/Makefile linux.dev/drivers/mtd/devices/Makefile ---- linux.old/drivers/mtd/devices/Makefile 2006-11-29 22:57:37.000000000 +0100 -+++ linux.dev/drivers/mtd/devices/Makefile 2006-12-15 00:03:11.000000000 +0100 +--- linux.old/drivers/mtd/devices/Makefile 2007-02-04 04:30:26.146338088 +0100 ++++ linux.dev/drivers/mtd/devices/Makefile 2007-02-02 23:48:28.749969000 +0100 @@ -17,3 +17,4 @@ obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o obj-$(CONFIG_MTD_M25P80) += m25p80.o +obj-$(CONFIG_MTD_SPIFLASH) += spiflash.o -diff -urN linux.old/drivers/mtd/devices/spiflash.c linux.dev/drivers/mtd/devices/spiflash.c ---- linux.old/drivers/mtd/devices/spiflash.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/mtd/devices/spiflash.c 2006-12-15 08:26:11.000000000 +0100 -@@ -0,0 +1,595 @@ -+ -+/* -+ * MTD driver for the SPI Flash Memory support. -+ * -+ * Copyright (c) 2005-2006 Atheros Communications Inc. -+ * Copyright (C) 2006 FON Technology, SL. -+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> -+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> -+ * -+ * 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 <linux/squashfs_fs.h> -+#include <linux/root_dev.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 -+ -+#define MAX_PARTS 32 -+ -+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); -+ -+static void __init spidata_init(void); -+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}, -+ { STM_8MB_BYTE_COUNT, STM_8MB_SECTOR_COUNT, STM_8MB_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 */ -+ spinlock_t mutex; -+}; -+ -+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; -+ -+ if (!spidata) -+ spidata_init(); -+ -+ if (!spidata) /* init failed */ -+ return 0; -+ -+ /* 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; -+ case STM_64MBIT_SIGNATURE: -+ flash_size = FLASH_8MB; -+ 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); -+ spin_lock(&spidata->mutex); -+ spiflash_sendcmd(SPI_WRITE_ENABLE); -+ do { -+ schedule(); -+ 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 { -+ schedule(); -+ reg = spiflash_sendcmd(SPI_RD_STATUS); -+ if (!(reg & SPI_STATUS_WIP)) { -+ finished = TRUE; -+ } -+ } while (!finished); -+ spin_unlock(&spidata->mutex); -+ -+ 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); -+ spin_lock(&spidata->mutex); -+ memcpy(buf, read_addr, len); -+ spin_unlock(&spidata->mutex); -+ -+ 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); -+ } -+ -+ spin_lock(&spidata->mutex); -+ spiflash_sendcmd(SPI_WRITE_ENABLE); -+ -+ do { -+ schedule(); -+ reg = spiflash_regread32(SPI_FLASH_CTL); -+ } while (reg & SPI_CTL_BUSY); -+ -+ switch (xact_len) { -+ case 1: -+ spi_data = (u32) ((u8) *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 { -+ schedule(); -+ reg = spiflash_sendcmd(SPI_RD_STATUS); -+ if (!(reg & SPI_STATUS_WIP)) { -+ finished = TRUE; -+ } -+ } while (!finished); -+ spin_unlock(&spidata->mutex); -+ -+ bytes_left -= xact_len; -+ to += xact_len; -+ buf += xact_len; -+ -+ *retlen += xact_len; -+ -+ if (bytes_left == 0) { -+ done = TRUE; -+ } -+ } -+ -+ return (0); -+} -+ -+static void __init spidata_init(void) -+{ -+ if (spidata) -+ return; -+ -+ spidata = kmalloc(sizeof(struct spiflash_data), GFP_KERNEL); -+ spin_lock_init(&spidata->mutex); -+ -+ if (!spidata) -+ return; -+ -+ 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); -+ spidata = NULL; -+ } -+} -+ -+#ifdef CONFIG_MTD_PARTITIONS -+static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; -+#endif -+ -+int __init -+spiflash_init (void) -+{ -+ int result = -1, i, j; -+ u32 len; -+ int index, num_parts; -+ struct mtd_info *mtd; -+ struct mtd_partition *mtd_parts; -+ char *buf; -+ struct mtd_partition *part; -+ struct squashfs_super_block *sb; -+ u32 config_start; -+ -+ spidata_init(); -+ -+ if (!spidata) -+ return (-ENXIO); -+ -+ mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); -+ if (!mtd) { -+ kfree(spidata); -+ return (-ENXIO); -+ } -+ -+ 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); -+ -+ 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->writesize = 1; -+ mtd->numeraseregions = 0; -+ mtd->eraseregions = NULL; -+ mtd->erase = spiflash_erase; -+ mtd->read = spiflash_read; -+ mtd->write = spiflash_write; -+ mtd->owner = THIS_MODULE; -+ -+#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 -+ -+ /* parse redboot partitions */ -+ num_parts = parse_mtd_partitions(mtd, part_probe_types, &spidata->parsed_parts, 0); -+ -+ mtd_parts = kzalloc(sizeof(struct mtd_partition) * MAX_PARTS, GFP_KERNEL); -+ buf = kmalloc(mtd->erasesize, GFP_KERNEL); -+ sb = (struct squashfs_super_block *) buf; -+ for (i = j = 0; i < num_parts; i++, j++) { -+ part = &mtd_parts[j]; -+ memcpy(part, &spidata->parsed_parts[i], sizeof(struct mtd_partition)); -+ -+ if (!strcmp(part->name, ROOTFS_NAME)) { -+ /* create the root device */ -+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, i); -+ -+ part->size -= mtd->erasesize; -+ config_start = part->offset + part->size; -+ -+ while ((mtd->read(mtd, part->offset, mtd->erasesize, &len, buf) == 0) && -+ (len == mtd->erasesize) && -+ (*((u32 *) buf) == SQUASHFS_MAGIC) && -+ (sb->bytes_used > 0)) { -+ -+ /* this is squashfs, allocate another partition starting from the end of filesystem data */ -+ memcpy(&mtd_parts[j + 1], part, sizeof(struct mtd_partition)); -+ -+ len = (u32) sb->bytes_used; -+ len += (part->offset & 0x000fffff); -+ len += (mtd->erasesize - 1); -+ len &= ~(mtd->erasesize - 1); -+ len -= (part->offset & 0x000fffff); -+ -+ if (len + mtd->erasesize > part->size) -+ break; -+ -+ part = &mtd_parts[++j]; -+ -+ part->offset += len; -+ part->size -= len; -+ -+ part->name = kmalloc(10, GFP_KERNEL); -+ sprintf(part->name, "rootfs%d", j - i); -+ } -+ } -+ if (!strcmp(part->name, "RedBoot config")) { -+ /* add anoterh partition for the board config data */ -+ memcpy(&mtd_parts[j + 1], part, sizeof(struct mtd_partition)); -+ j++; -+ part = &mtd_parts[j]; -+ part->offset += part->size; -+ part->size = mtd->erasesize; -+ -+ part->name = kmalloc(16, GFP_KERNEL); -+ sprintf(part->name, "board_config"); -+ } -+ } -+ num_parts += j - i; -+ kfree(buf); -+ -+#ifdef SPIFLASH_DEBUG -+ printk (KERN_DEBUG "Found %d redboot partitions\n", num_parts); -+#endif -+ if (num_parts) { -+ result = add_mtd_partitions(mtd, mtd_parts, num_parts); -+ } else { -+#ifdef SPIFLASH_DEBUG -+ printk (KERN_DEBUG "Did not find any redboot partitions\n"); -+#endif -+ kfree(mtd); -+ kfree(spidata); -+ return (-ENXIO); -+ } -+ -+ 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.old/drivers/mtd/devices/spiflash.h linux.dev/drivers/mtd/devices/spiflash.h ---- linux.old/drivers/mtd/devices/spiflash.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/mtd/devices/spiflash.h 2006-12-15 06:59:43.000000000 +0100 -@@ -0,0 +1,124 @@ -+/* -+ * 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. -+ * Copyright (C) 2006 FON Technology, SL. -+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> -+ * -+ * 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 FLASH_8MB 4 -+#define MAX_FLASH 5 -+ -+#define STM_PAGE_SIZE 256 -+ -+#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 -+ -+#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_64MBIT_SIGNATURE 0x16 -+#define STM_M25P64_BYTE_COUNT 8388608 -+#define STM_M25P64_SECTOR_COUNT 128 -+#define STM_M25P64_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 STM_8MB_BYTE_COUNT STM_M25P64_BYTE_COUNT -+#define STM_8MB_SECTOR_COUNT STM_M25P64_SECTOR_COUNT -+#define STM_8MB_SECTOR_SIZE STM_M25P64_SECTOR_SIZE -+ -+/* -+ * 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 0x08000000 -+#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 --git a/target/linux/atheros-2.6/patches/120-enable_wireless_for_ahb.patch b/target/linux/atheros-2.6/patches/120-enable_wireless_for_ahb.patch index 616f394584..a959cba9c3 100644 --- a/target/linux/atheros-2.6/patches/120-enable_wireless_for_ahb.patch +++ b/target/linux/atheros-2.6/patches/120-enable_wireless_for_ahb.patch @@ -6,7 +6,7 @@ diff -urN linux.old/drivers/net/wireless/Kconfig linux.dev/drivers/net/wireless/ config NET_WIRELESS bool - depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA) -+ depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA || AR531X) ++ depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA || ATHEROS) default y endmenu diff --git a/target/linux/atheros-2.6/patches/130-ar2313_ethernet.patch b/target/linux/atheros-2.6/patches/130-ar2313_ethernet.patch index 7040543351..960c736ae9 100644 --- a/target/linux/atheros-2.6/patches/130-ar2313_ethernet.patch +++ b/target/linux/atheros-2.6/patches/130-ar2313_ethernet.patch @@ -1,2048 +1,3 @@ -diff -urN linux.old/drivers/net/ar2313/ar2313.c linux.eth/drivers/net/ar2313/ar2313.c ---- linux.old/drivers/net/ar2313/ar2313.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.eth/drivers/net/ar2313/ar2313.c 2006-12-16 04:30:44.000000000 +0100 -@@ -0,0 +1,1545 @@ -+/* -+ * ar2313.c: Linux driver for the Atheros AR231z Ethernet device. -+ * -+ * Copyright (C) 2004 by Sameer Dekate <sdekate@arubanetworks.com> -+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> -+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> -+ * -+ * Thanks to Atheros for providing hardware and documentation -+ * enabling me to write this driver. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * Additional credits: -+ * This code is taken from John Taylor's Sibyte driver and then -+ * modified for the AR2313. -+ */ -+ -+#include <linux/autoconf.h> -+#include <linux/module.h> -+#include <linux/version.h> -+#include <linux/types.h> -+#include <linux/errno.h> -+#include <linux/ioport.h> -+#include <linux/pci.h> -+#include <linux/netdevice.h> -+#include <linux/etherdevice.h> -+#include <linux/skbuff.h> -+#include <linux/init.h> -+#include <linux/delay.h> -+#include <linux/mm.h> -+#include <linux/highmem.h> -+#include <linux/sockios.h> -+#include <linux/pkt_sched.h> -+#include <linux/compile.h> -+#include <linux/mii.h> -+#include <linux/ethtool.h> -+#include <linux/ctype.h> -+#include <linux/platform_device.h> -+ -+#include <net/sock.h> -+#include <net/ip.h> -+ -+#include <asm/system.h> -+#include <asm/io.h> -+#include <asm/irq.h> -+#include <asm/byteorder.h> -+#include <asm/uaccess.h> -+#include <asm/bootinfo.h> -+ -+#include <ar531x_platform.h> -+ -+#undef INDEX_DEBUG -+#define DEBUG 0 -+#define DEBUG_TX 0 -+#define DEBUG_RX 0 -+#define DEBUG_INT 0 -+#define DEBUG_MC 0 -+#define DEBUG_ERR 1 -+ -+#ifndef min -+#define min(a,b) (((a)<(b))?(a):(b)) -+#endif -+ -+#ifndef SMP_CACHE_BYTES -+#define SMP_CACHE_BYTES L1_CACHE_BYTES -+#endif -+ -+#ifndef SET_MODULE_OWNER -+#define SET_MODULE_OWNER(dev) {do{} while(0);} -+#define AR2313_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -+#define AR2313_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -+#else -+#define AR2313_MOD_INC_USE_COUNT {do{} while(0);} -+#define AR2313_MOD_DEC_USE_COUNT {do{} while(0);} -+#endif -+ -+#define PHYSADDR(a) ((_ACAST32_ (a)) & 0x1fffffff) -+ -+static char ifname[5] = "bond"; -+ -+module_param_string(ifname, ifname, 5, 0); -+ -+#define AR2313_MBOX_SET_BIT 0x8 -+ -+#define BOARD_IDX_STATIC 0 -+#define BOARD_IDX_OVERFLOW -1 -+ -+#include "ar2313_msg.h" -+#include "platform.h" -+#include "dma.h" -+#include "ar2313.h" -+ -+/* -+ * New interrupt handler strategy: -+ * -+ * An old interrupt handler worked using the traditional method of -+ * replacing an skbuff with a new one when a packet arrives. However -+ * the rx rings do not need to contain a static number of buffer -+ * descriptors, thus it makes sense to move the memory allocation out -+ * of the main interrupt handler and do it in a bottom half handler -+ * and only allocate new buffers when the number of buffers in the -+ * ring is below a certain threshold. In order to avoid starving the -+ * NIC under heavy load it is however necessary to force allocation -+ * when hitting a minimum threshold. The strategy for alloction is as -+ * follows: -+ * -+ * RX_LOW_BUF_THRES - allocate buffers in the bottom half -+ * RX_PANIC_LOW_THRES - we are very low on buffers, allocate -+ * the buffers in the interrupt handler -+ * RX_RING_THRES - maximum number of buffers in the rx ring -+ * -+ * One advantagous side effect of this allocation approach is that the -+ * entire rx processing can be done without holding any spin lock -+ * since the rx rings and registers are totally independent of the tx -+ * ring and its registers. This of course includes the kmalloc's of -+ * new skb's. Thus start_xmit can run in parallel with rx processing -+ * and the memory allocation on SMP systems. -+ * -+ * Note that running the skb reallocation in a bottom half opens up -+ * another can of races which needs to be handled properly. In -+ * particular it can happen that the interrupt handler tries to run -+ * the reallocation while the bottom half is either running on another -+ * CPU or was interrupted on the same CPU. To get around this the -+ * driver uses bitops to prevent the reallocation routines from being -+ * reentered. -+ * -+ * TX handling can also be done without holding any spin lock, wheee -+ * this is fun! since tx_csm is only written to by the interrupt -+ * handler. -+ */ -+ -+/* -+ * Threshold values for RX buffer allocation - the low water marks for -+ * when to start refilling the rings are set to 75% of the ring -+ * sizes. It seems to make sense to refill the rings entirely from the -+ * intrrupt handler once it gets below the panic threshold, that way -+ * we don't risk that the refilling is moved to another CPU when the -+ * one running the interrupt handler just got the slab code hot in its -+ * cache. -+ */ -+#define RX_RING_SIZE AR2313_DESCR_ENTRIES -+#define RX_PANIC_THRES (RX_RING_SIZE/4) -+#define RX_LOW_THRES ((3*RX_RING_SIZE)/4) -+#define CRC_LEN 4 -+#define RX_OFFSET 2 -+ -+#define AR2313_BUFSIZE (AR2313_MTU + ETH_HLEN + CRC_LEN + RX_OFFSET) -+ -+#ifdef MODULE -+MODULE_AUTHOR("Sameer Dekate <sdekate@arubanetworks.com>, Imre Kaloz <kaloz@openwrt.org>, Felix Fietkau <nbd@openwrt.org>"); -+MODULE_DESCRIPTION("AR2313 Ethernet driver"); -+#endif -+ -+#if DEBUG -+static char version[] __initdata = -+ "ar2313.c: v0.03 2006/07/12 sdekate@arubanetworks.com\n"; -+#endif /* DEBUG */ -+ -+#define virt_to_phys(x) ((u32)(x) & 0x1fffffff) -+ -+// prototypes -+static short armiiread(short phy, short reg); -+static void armiiwrite(short phy, short reg, short data); -+#ifdef TX_TIMEOUT -+static void ar2313_tx_timeout(struct net_device *dev); -+#endif -+static void ar2313_halt(struct net_device *dev); -+static void rx_tasklet_func(unsigned long data); -+static void ar2313_multicast_list(struct net_device *dev); -+ -+static int probed __initdata = 0; -+static unsigned long ar_eth_base; -+static unsigned long ar_dma_base; -+static unsigned long ar_int_base; -+static unsigned long ar_int_mac_mask; -+static unsigned long ar_int_phy_mask; -+ -+#ifndef ERR -+#define ERR(fmt, args...) printk("%s: " fmt, __func__, ##args) -+#endif -+ -+ -+int __init ar2313_probe(struct platform_device *pdev) -+{ -+ struct net_device *dev; -+ struct ar2313_private *sp; -+ struct ar531x_eth *cfg; -+ struct resource *res; -+ int version_disp; -+ char name[64] ; -+ -+ if (probed) -+ return -ENODEV; -+ probed++; -+ -+ version_disp = 0; -+ sprintf(name, "%s%%d", ifname) ; -+ dev = alloc_etherdev(sizeof(struct ar2313_private)); -+ -+ if (dev == NULL) { -+ printk(KERN_ERR "ar2313: Unable to allocate net_device structure!\n"); -+ return -ENOMEM; -+ } -+ -+ SET_MODULE_OWNER(dev); -+ platform_set_drvdata(pdev, dev); -+ -+ sp = dev->priv; -+ sp->dev = dev; -+ cfg = pdev->dev.platform_data; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "eth_membase"); -+ if (!res) -+ return -ENODEV; -+ -+ sp->link = 0; -+ ar_eth_base = res->start; -+ ar_dma_base = ar_eth_base + 0x1000; -+ ar_int_base = cfg->reset_base; -+ ar_int_mac_mask = cfg->reset_mac; -+ ar_int_phy_mask = cfg->reset_phy; -+ sp->phy = cfg->phy; -+ -+ dev->irq = platform_get_irq_byname(pdev, "eth_irq"); -+ -+ spin_lock_init(&sp->lock); -+ -+ /* initialize func pointers */ -+ dev->open = &ar2313_open; -+ dev->stop = &ar2313_close; -+ dev->hard_start_xmit = &ar2313_start_xmit; -+ -+ dev->get_stats = &ar2313_get_stats; -+ dev->set_multicast_list = &ar2313_multicast_list; -+#ifdef TX_TIMEOUT -+ dev->tx_timeout = ar2313_tx_timeout; -+ dev->watchdog_timeo = AR2313_TX_TIMEOUT; -+#endif -+ dev->do_ioctl = &ar2313_ioctl; -+ -+ // SAMEER: do we need this? -+ dev->features |= NETIF_F_SG | NETIF_F_HIGHDMA; -+ -+ tasklet_init(&sp->rx_tasklet, rx_tasklet_func, (unsigned long) dev); -+ tasklet_disable(&sp->rx_tasklet); -+ -+ /* display version info if adapter is found */ -+ if (!version_disp) { -+ /* set display flag to TRUE so that */ -+ /* we only display this string ONCE */ -+ version_disp = 1; -+#if DEBUG -+ printk(version); -+#endif /* DEBUG */ -+ } -+ -+#if 0 -+ request_region(PHYSADDR(ar_eth_base), ETHERNET_SIZE*ETHERNET_MACS, -+ "AR2313ENET"); -+#endif -+ -+ sp->eth_regs = ioremap_nocache(PHYSADDR(ar_eth_base), sizeof(*sp->eth_regs)); -+ if (!sp->eth_regs) { -+ printk("Can't remap eth registers\n"); -+ return(-ENXIO); -+ } -+ -+ sp->dma_regs = ioremap_nocache(PHYSADDR(ar_eth_base + 0x1000), sizeof(*sp->dma_regs)); -+ dev->base_addr = (unsigned int) sp->dma_regs; -+ if (!sp->dma_regs) { -+ printk("Can't remap DMA registers\n"); -+ return(-ENXIO); -+ } -+ -+ sp->int_regs = ioremap_nocache(PHYSADDR(ar_int_base), 4); -+ if (!sp->int_regs) { -+ printk("Can't remap INTERRUPT registers\n"); -+ return(-ENXIO); -+ } -+ -+ strncpy(sp->name, "Atheros AR2313", sizeof (sp->name) - 1); -+ sp->name [sizeof (sp->name) - 1] = '\0'; -+ -+ { -+ /* XXX: Will have to rewrite this part later */ -+ char *configstart; -+ unsigned char def_mac[6] = {0, 0xaa, 0xbb, 0xcc, 0xdd, 0xee}; -+ -+ configstart = (char *) cfg->board_config; -+ -+ if (!configstart) { -+ printk("no valid mac found, using defaults"); -+ memcpy(dev->dev_addr, def_mac, 6); -+ } else { -+ memcpy(dev->dev_addr, ((u8 *)configstart)+102, 6); -+ } -+ } -+ -+ sp->board_idx = BOARD_IDX_STATIC; -+ -+ if (ar2313_init(dev)) { -+ /* -+ * ar2313_init() calls ar2313_init_cleanup() on error. -+ */ -+ kfree(dev); -+ return -ENODEV; -+ } -+ -+ if (register_netdev(dev)){ -+ printk("%s: register_netdev failed\n", __func__); -+ return -1; -+ } -+ -+ printk("%s: %s: %02x:%02x:%02x:%02x:%02x:%02x, irq %d\n", -+ dev->name, sp->name, -+ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], -+ dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5], -+ dev->irq); -+ -+ /* start link poll timer */ -+ ar2313_setup_timer(dev); -+ -+ return 0; -+} -+ -+#if 0 -+static void ar2313_dump_regs(struct net_device *dev) -+{ -+ unsigned int *ptr, i; -+ struct ar2313_private *sp = (struct ar2313_private *)dev->priv; -+ -+ ptr = (unsigned int *)sp->eth_regs; -+ for(i=0; i< (sizeof(ETHERNET_STRUCT)/ sizeof(unsigned int)); i++, ptr++) { -+ printk("ENET: %08x = %08x\n", (int)ptr, *ptr); -+ } -+ -+ ptr = (unsigned int *)sp->dma_regs; -+ for(i=0; i< (sizeof(DMA)/ sizeof(unsigned int)); i++, ptr++) { -+ printk("DMA: %08x = %08x\n", (int)ptr, *ptr); -+ } -+ -+ ptr = (unsigned int *)sp->int_regs; -+ for(i=0; i< (sizeof(INTERRUPT)/ sizeof(unsigned int)); i++, ptr++){ -+ printk("INT: %08x = %08x\n", (int)ptr, *ptr); -+ } -+ -+ for (i = 0; i < AR2313_DESCR_ENTRIES; i++) { -+ ar2313_descr_t *td = &sp->tx_ring[i]; -+ printk("Tx desc %2d: %08x %08x %08x %08x\n", i, -+ td->status, td->devcs, td->addr, td->descr); -+ } -+} -+#endif -+ -+#ifdef TX_TIMEOUT -+static void -+ar2313_tx_timeout(struct net_device *dev) -+{ -+ struct ar2313_private *sp = (struct ar2313_private *)dev->priv; -+ unsigned long flags; -+ -+#if DEBUG_TX -+ printk("Tx timeout\n"); -+#endif -+ spin_lock_irqsave(&sp->lock, flags); -+ ar2313_restart(dev); -+ spin_unlock_irqrestore(&sp->lock, flags); -+} -+#endif -+ -+#if DEBUG_MC -+static void -+printMcList(struct net_device *dev) -+{ -+ struct dev_mc_list *list = dev->mc_list; -+ int num=0, i; -+ while(list){ -+ printk("%d MC ADDR ", num); -+ for(i=0;i<list->dmi_addrlen;i++) { -+ printk(":%02x", list->dmi_addr[i]); -+ } -+ list = list->next; -+ printk("\n"); -+ } -+} -+#endif -+ -+/* -+ * Set or clear the multicast filter for this adaptor. -+ * THIS IS ABSOLUTE CRAP, disabled -+ */ -+static void -+ar2313_multicast_list(struct net_device *dev) -+{ -+ /* -+ * Always listen to broadcasts and -+ * treat IFF bits independently -+ */ -+ struct ar2313_private *sp = (struct ar2313_private *)dev->priv; -+ unsigned int recognise; -+ -+ recognise = sp->eth_regs->mac_control; -+ -+ if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */ -+ recognise |= MAC_CONTROL_PR; -+ } else { -+ recognise &= ~MAC_CONTROL_PR; -+ } -+ -+ if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15)) { -+#if DEBUG_MC -+ printMcList(dev); -+ printk("%s: all MULTICAST mc_count %d\n", __FUNCTION__, dev->mc_count); -+#endif -+ recognise |= MAC_CONTROL_PM;/* all multicast */ -+ } else if (dev->mc_count > 0) { -+#if DEBUG_MC -+ printMcList(dev); -+ printk("%s: mc_count %d\n", __FUNCTION__, dev->mc_count); -+#endif -+ recognise |= MAC_CONTROL_PM; /* for the time being */ -+ } -+#if DEBUG_MC -+ printk("%s: setting %08x to %08x\n", __FUNCTION__, (int)sp->eth_regs, recognise); -+#endif -+ -+ sp->eth_regs->mac_control = recognise; -+} -+ -+static void rx_tasklet_cleanup(struct net_device *dev) -+{ -+ struct ar2313_private *sp = dev->priv; -+ -+ /* -+ * Tasklet may be scheduled. Need to get it removed from the list -+ * since we're about to free the struct. -+ */ -+ -+ sp->unloading = 1; -+ tasklet_enable(&sp->rx_tasklet); -+ tasklet_kill(&sp->rx_tasklet); -+} -+ -+static int __exit ar2313_remove(struct platform_device *pdev) -+{ -+ struct net_device *dev = platform_get_drvdata(pdev); -+ rx_tasklet_cleanup(dev); -+ ar2313_init_cleanup(dev); -+ unregister_netdev(dev); -+ kfree(dev); -+ return 0; -+} -+ -+ -+/* -+ * Restart the AR2313 ethernet controller. -+ */ -+static int ar2313_restart(struct net_device *dev) -+{ -+ /* disable interrupts */ -+ disable_irq(dev->irq); -+ -+ /* stop mac */ -+ ar2313_halt(dev); -+ -+ /* initialize */ -+ ar2313_init(dev); -+ -+ /* enable interrupts */ -+ enable_irq(dev->irq); -+ -+ return 0; -+} -+ -+static struct platform_driver ar2313_driver = { -+ .driver.name = "ar531x-eth", -+ .probe = ar2313_probe, -+ .remove = ar2313_remove, -+}; -+ -+int __init ar2313_module_init(void) -+{ -+ return platform_driver_register(&ar2313_driver); -+} -+ -+void __exit ar2313_module_cleanup(void) -+{ -+ platform_driver_unregister(&ar2313_driver); -+} -+ -+module_init(ar2313_module_init); -+module_exit(ar2313_module_cleanup); -+ -+ -+static void ar2313_free_descriptors(struct net_device *dev) -+{ -+ struct ar2313_private *sp = dev->priv; -+ if (sp->rx_ring != NULL) { -+ kfree((void*)KSEG0ADDR(sp->rx_ring)); -+ sp->rx_ring = NULL; -+ sp->tx_ring = NULL; -+ } -+} -+ -+ -+static int ar2313_allocate_descriptors(struct net_device *dev) -+{ -+ struct ar2313_private *sp = dev->priv; -+ int size; -+ int j; -+ ar2313_descr_t *space; -+ -+ if(sp->rx_ring != NULL){ -+ printk("%s: already done.\n", __FUNCTION__); -+ return 0; -+ } -+ -+ size = (sizeof(ar2313_descr_t) * (AR2313_DESCR_ENTRIES * AR2313_QUEUES)); -+ space = kmalloc(size, GFP_KERNEL); -+ if (space == NULL) -+ return 1; -+ -+ /* invalidate caches */ -+ dma_cache_inv((unsigned int)space, size); -+ -+ /* now convert pointer to KSEG1 */ -+ space = (ar2313_descr_t *)KSEG1ADDR(space); -+ -+ memset((void *)space, 0, size); -+ -+ sp->rx_ring = space; -+ space += AR2313_DESCR_ENTRIES; -+ -+ sp->tx_ring = space; -+ space += AR2313_DESCR_ENTRIES; -+ -+ /* Initialize the transmit Descriptors */ -+ for (j = 0; j < AR2313_DESCR_ENTRIES; j++) { -+ ar2313_descr_t *td = &sp->tx_ring[j]; -+ td->status = 0; -+ td->devcs = DMA_TX1_CHAINED; -+ td->addr = 0; -+ td->descr = K1_TO_PHYS(&sp->tx_ring[(j+1) & (AR2313_DESCR_ENTRIES-1)]); -+ } -+ -+ return 0; -+} -+ -+ -+/* -+ * Generic cleanup handling data allocated during init. Used when the -+ * module is unloaded or if an error occurs during initialization -+ */ -+static void ar2313_init_cleanup(struct net_device *dev) -+{ -+ struct ar2313_private *sp = dev->priv; -+ struct sk_buff *skb; -+ int j; -+ -+ ar2313_free_descriptors(dev); -+ -+ if (sp->eth_regs) iounmap((void*)sp->eth_regs); -+ if (sp->dma_regs) iounmap((void*)sp->dma_regs); -+ -+ if (sp->rx_skb) { -+ for (j = 0; j < AR2313_DESCR_ENTRIES; j++) { -+ skb = sp->rx_skb[j]; -+ if (skb) { -+ sp->rx_skb[j] = NULL; -+ dev_kfree_skb(skb); -+ } -+ } -+ kfree(sp->rx_skb); -+ sp->rx_skb = NULL; -+ } -+ -+ if (sp->tx_skb) { -+ for (j = 0; j < AR2313_DESCR_ENTRIES; j++) { -+ skb = sp->tx_skb[j]; -+ if (skb) { -+ sp->tx_skb[j] = NULL; -+ dev_kfree_skb(skb); -+ } -+ } -+ kfree(sp->tx_skb); -+ sp->tx_skb = NULL; -+ } -+} -+ -+static int ar2313_setup_timer(struct net_device *dev) -+{ -+ struct ar2313_private *sp = dev->priv; -+ -+ init_timer(&sp->link_timer); -+ -+ sp->link_timer.function = ar2313_link_timer_fn; -+ sp->link_timer.data = (int) dev; -+ sp->link_timer.expires = jiffies + HZ; -+ -+ add_timer(&sp->link_timer); -+ return 0; -+ -+} -+ -+static void ar2313_link_timer_fn(unsigned long data) -+{ -+ struct net_device *dev = (struct net_device *) data; -+ struct ar2313_private *sp = dev->priv; -+ -+ // see if the link status changed -+ // This was needed to make sure we set the PHY to the -+ // autonegotiated value of half or full duplex. -+ ar2313_check_link(dev); -+ -+ // Loop faster when we don't have link. -+ // This was needed to speed up the AP bootstrap time. -+ if(sp->link == 0) { -+ mod_timer(&sp->link_timer, jiffies + HZ/2); -+ } else { -+ mod_timer(&sp->link_timer, jiffies + LINK_TIMER); -+ } -+} -+ -+static void ar2313_check_link(struct net_device *dev) -+{ -+ struct ar2313_private *sp = dev->priv; -+ u16 phyData; -+ -+ phyData = armiiread(sp->phy, MII_BMSR); -+ if (sp->phyData != phyData) { -+ if (phyData & BMSR_LSTATUS) { -+ /* link is present, ready link partner ability to deterine duplexity */ -+ int duplex = 0; -+ u16 reg; -+ -+ sp->link = 1; -+ reg = armiiread(sp->phy, MII_BMCR); -+ if (reg & BMCR_ANENABLE) { -+ /* auto neg enabled */ -+ reg = armiiread(sp->phy, MII_LPA); -+ duplex = (reg & (LPA_100FULL|LPA_10FULL))? 1:0; -+ } else { -+ /* no auto neg, just read duplex config */ -+ duplex = (reg & BMCR_FULLDPLX)? 1:0; -+ } -+ -+ printk(KERN_INFO "%s: Configuring MAC for %s duplex\n", dev->name, -+ (duplex)? "full":"half"); -+ -+ if (duplex) { -+ /* full duplex */ -+ sp->eth_regs->mac_control = ((sp->eth_regs->mac_control | MAC_CONTROL_F) & -+ ~MAC_CONTROL_DRO); -+ } else { -+ /* half duplex */ -+ sp->eth_regs->mac_control = ((sp->eth_regs->mac_control | MAC_CONTROL_DRO) & -+ ~MAC_CONTROL_F); -+ } -+ } else { -+ /* no link */ -+ sp->link = 0; -+ } -+ sp->phyData = phyData; -+ } -+} -+ -+static int -+ar2313_reset_reg(struct net_device *dev) -+{ -+ struct ar2313_private *sp = (struct ar2313_private *)dev->priv; -+ unsigned int ethsal, ethsah; -+ unsigned int flags; -+ -+ *sp->int_regs |= ar_int_mac_mask; -+ mdelay(10); -+ *sp->int_regs &= ~ar_int_mac_mask; -+ mdelay(10); -+ *sp->int_regs |= ar_int_phy_mask; -+ mdelay(10); -+ *sp->int_regs &= ~ar_int_phy_mask; -+ mdelay(10); -+ -+ sp->dma_regs->bus_mode = (DMA_BUS_MODE_SWR); -+ mdelay(10); -+ sp->dma_regs->bus_mode = ((32 << DMA_BUS_MODE_PBL_SHIFT) | DMA_BUS_MODE_BLE); -+ -+ /* enable interrupts */ -+ sp->dma_regs->intr_ena = (DMA_STATUS_AIS | -+ DMA_STATUS_NIS | -+ DMA_STATUS_RI | -+ DMA_STATUS_TI | -+ DMA_STATUS_FBE); -+ sp->dma_regs->xmt_base = K1_TO_PHYS(sp->tx_ring); -+ sp->dma_regs->rcv_base = K1_TO_PHYS(sp->rx_ring); -+ sp->dma_regs->control = (DMA_CONTROL_SR | DMA_CONTROL_ST | DMA_CONTROL_SF); -+ -+ sp->eth_regs->flow_control = (FLOW_CONTROL_FCE); -+ sp->eth_regs->vlan_tag = (0x8100); -+ -+ /* Enable Ethernet Interface */ -+ flags = (MAC_CONTROL_TE | /* transmit enable */ -+ MAC_CONTROL_PM | /* pass mcast */ -+ MAC_CONTROL_F | /* full duplex */ -+ MAC_CONTROL_HBD); /* heart beat disabled */ -+ -+ if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */ -+ flags |= MAC_CONTROL_PR; -+ } -+ sp->eth_regs->mac_control = flags; -+ -+ /* Set all Ethernet station address registers to their initial values */ -+ ethsah = ((((u_int)(dev->dev_addr[5]) << 8) & (u_int)0x0000FF00) | -+ (((u_int)(dev->dev_addr[4]) << 0) & (u_int)0x000000FF)); -+ -+ ethsal = ((((u_int)(dev->dev_addr[3]) << 24) & (u_int)0xFF000000) | -+ (((u_int)(dev->dev_addr[2]) << 16) & (u_int)0x00FF0000) | -+ (((u_int)(dev->dev_addr[1]) << 8) & (u_int)0x0000FF00) | -+ (((u_int)(dev->dev_addr[0]) << 0) & (u_int)0x000000FF) ); -+ -+ sp->eth_regs->mac_addr[0] = ethsah; -+ sp->eth_regs->mac_addr[1] = ethsal; -+ -+ mdelay(10); -+ -+ return(0); -+} -+ -+ -+static int ar2313_init(struct net_device *dev) -+{ -+ struct ar2313_private *sp = dev->priv; -+ int ecode=0; -+ -+ /* -+ * Allocate descriptors -+ */ -+ if (ar2313_allocate_descriptors(dev)) { -+ printk("%s: %s: ar2313_allocate_descriptors failed\n", -+ dev->name, __FUNCTION__); -+ ecode = -EAGAIN; -+ goto init_error; -+ } -+ -+ /* -+ * Get the memory for the skb rings. -+ */ -+ if(sp->rx_skb == NULL) { -+ sp->rx_skb = kmalloc(sizeof(struct sk_buff *) * AR2313_DESCR_ENTRIES, GFP_KERNEL); -+ if (!(sp->rx_skb)) { -+ printk("%s: %s: rx_skb kmalloc failed\n", -+ dev->name, __FUNCTION__); -+ ecode = -EAGAIN; -+ goto init_error; -+ } -+ } -+ memset(sp->rx_skb, 0, sizeof(struct sk_buff *) * AR2313_DESCR_ENTRIES); -+ -+ if(sp->tx_skb == NULL) { -+ sp->tx_skb = kmalloc(sizeof(struct sk_buff *) * AR2313_DESCR_ENTRIES, GFP_KERNEL); -+ if (!(sp->tx_skb)) { -+ printk("%s: %s: tx_skb kmalloc failed\n", -+ dev->name, __FUNCTION__); -+ ecode = -EAGAIN; -+ goto init_error; -+ } -+ } -+ memset(sp->tx_skb, 0, sizeof(struct sk_buff *) * AR2313_DESCR_ENTRIES); -+ -+ /* -+ * Set tx_csm before we start receiving interrupts, otherwise -+ * the interrupt handler might think it is supposed to process -+ * tx ints before we are up and running, which may cause a null -+ * pointer access in the int handler. -+ */ -+ sp->rx_skbprd = 0; -+ sp->cur_rx = 0; -+ sp->tx_prd = 0; -+ sp->tx_csm = 0; -+ -+ /* -+ * Zero the stats before starting the interface -+ */ -+ memset(&sp->stats, 0, sizeof(sp->stats)); -+ -+ /* -+ * We load the ring here as there seem to be no way to tell the -+ * firmware to wipe the ring without re-initializing it. -+ */ -+ ar2313_load_rx_ring(dev, RX_RING_SIZE); -+ -+ /* -+ * Init hardware -+ */ -+ ar2313_reset_reg(dev); -+ -+ /* -+ * Get the IRQ -+ */ -+ ecode = request_irq(dev->irq, &ar2313_interrupt, IRQF_SHARED | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, dev->name, dev); -+ if (ecode) { -+ printk(KERN_WARNING "%s: %s: Requested IRQ %d is busy\n", -+ dev->name, __FUNCTION__, dev->irq); -+ goto init_error; -+ } -+ -+ -+ tasklet_enable(&sp->rx_tasklet); -+ -+ return 0; -+ -+ init_error: -+ ar2313_init_cleanup(dev); -+ return ecode; -+} -+ -+/* -+ * Load the rx ring. -+ * -+ * Loading rings is safe without holding the spin lock since this is -+ * done only before the device is enabled, thus no interrupts are -+ * generated and by the interrupt handler/tasklet handler. -+ */ -+static void ar2313_load_rx_ring(struct net_device *dev, int nr_bufs) -+{ -+ -+ struct ar2313_private *sp = ((struct net_device *)dev)->priv; -+ short i, idx; -+ -+ idx = sp->rx_skbprd; -+ -+ for (i = 0; i < nr_bufs; i++) { -+ struct sk_buff *skb; -+ ar2313_descr_t *rd; -+ -+ if (sp->rx_skb[idx]) { -+#if DEBUG_RX -+ printk(KERN_INFO "ar2313 rx refill full\n"); -+#endif /* DEBUG */ -+ break; -+ } -+ -+ // partha: create additional room for the second GRE fragment -+ skb = alloc_skb(AR2313_BUFSIZE+128, GFP_ATOMIC); -+ if (!skb) { -+ printk("\n\n\n\n %s: No memory in system\n\n\n\n", __FUNCTION__); -+ break; -+ } -+ // partha: create additional room in the front for tx pkt capture -+ skb_reserve(skb, 32); -+ -+ /* -+ * Make sure IP header starts on a fresh cache line. -+ */ -+ skb->dev = dev; -+ skb_reserve(skb, RX_OFFSET); -+ sp->rx_skb[idx] = skb; -+ -+ rd = (ar2313_descr_t *) &sp->rx_ring[idx]; -+ -+ /* initialize dma descriptor */ -+ rd->devcs = ((AR2313_BUFSIZE << DMA_RX1_BSIZE_SHIFT) | -+ DMA_RX1_CHAINED); -+ rd->addr = virt_to_phys(skb->data); -+ rd->descr = virt_to_phys(&sp->rx_ring[(idx+1) & (AR2313_DESCR_ENTRIES-1)]); -+ rd->status = DMA_RX_OWN; -+ -+ idx = DSC_NEXT(idx); -+ } -+ -+ if (!i) { -+#if DEBUG_ERR -+ printk(KERN_INFO "Out of memory when allocating standard receive buffers\n"); -+#endif /* DEBUG */ -+ } else { -+ sp->rx_skbprd = idx; -+ } -+ -+ return; -+} -+ -+#define AR2313_MAX_PKTS_PER_CALL 64 -+ -+static int ar2313_rx_int(struct net_device *dev) -+{ -+ struct ar2313_private *sp = dev->priv; -+ struct sk_buff *skb, *skb_new; -+ ar2313_descr_t *rxdesc; -+ unsigned int status; -+ u32 idx; -+ int pkts = 0; -+ int rval; -+ -+ idx = sp->cur_rx; -+ -+ /* process at most the entire ring and then wait for another interrupt */ -+ while(1) { -+ -+ rxdesc = &sp->rx_ring[idx]; -+ status = rxdesc->status; -+ if (status & DMA_RX_OWN) { -+ /* SiByte owns descriptor or descr not yet filled in */ -+ rval = 0; -+ break; -+ } -+ -+ if (++pkts > AR2313_MAX_PKTS_PER_CALL) { -+ rval = 1; -+ break; -+ } -+ -+#if DEBUG_RX -+ printk("index %d\n", idx); -+ printk("RX status %08x\n", rxdesc->status); -+ printk("RX devcs %08x\n", rxdesc->devcs ); -+ printk("RX addr %08x\n", rxdesc->addr ); -+ printk("RX descr %08x\n", rxdesc->descr ); -+#endif -+ -+ if ((status & (DMA_RX_ERROR|DMA_RX_ERR_LENGTH)) && -+ (!(status & DMA_RX_LONG))){ -+#if DEBUG_RX -+ printk("%s: rx ERROR %08x\n", __FUNCTION__, status); -+#endif -+ sp->stats.rx_errors++; -+ sp->stats.rx_dropped++; -+ -+ /* add statistics counters */ -+ if (status & DMA_RX_ERR_CRC) sp->stats.rx_crc_errors++; -+ if (status & DMA_RX_ERR_COL) sp->stats.rx_over_errors++; -+ if (status & DMA_RX_ERR_LENGTH) -+ sp->stats.rx_length_errors++; -+ if (status & DMA_RX_ERR_RUNT) sp->stats.rx_over_errors++; -+ if (status & DMA_RX_ERR_DESC) sp->stats.rx_over_errors++; -+ -+ } else { -+ /* alloc new buffer. */ -+ skb_new = dev_alloc_skb(AR2313_BUFSIZE + RX_OFFSET + 128); -+ if (skb_new != NULL) { -+ -+ skb = sp->rx_skb[idx]; -+ /* set skb */ -+ skb_put(skb, ((status >> DMA_RX_LEN_SHIFT) & 0x3fff) - CRC_LEN); -+ -+#ifdef CONFIG_MERLOT -+ if ((dev->am_pkt_handler == NULL) || -+ (dev->am_pkt_handler(skb, dev) == 0)) { -+#endif -+ sp->stats.rx_bytes += skb->len; -+ skb->protocol = eth_type_trans(skb, dev); -+ /* pass the packet to upper layers */ -+ -+#ifdef CONFIG_MERLOT -+ if (dev->asap_netif_rx) -+ dev->asap_netif_rx(skb); -+ else -+#endif -+ netif_rx(skb); -+#ifdef CONFIG_MERLOT -+ } -+#endif -+ skb_new->dev = dev; -+ /* 16 bit align */ -+ skb_reserve(skb_new, RX_OFFSET+32); -+ /* reset descriptor's curr_addr */ -+ rxdesc->addr = virt_to_phys(skb_new->data); -+ -+ sp->stats.rx_packets++; -+ sp->rx_skb[idx] = skb_new; -+ -+ } else { -+ sp->stats.rx_dropped++; -+ } -+ } -+ -+ rxdesc->devcs = ((AR2313_BUFSIZE << DMA_RX1_BSIZE_SHIFT) | -+ DMA_RX1_CHAINED); -+ rxdesc->status = DMA_RX_OWN; -+ -+ idx = DSC_NEXT(idx); -+ } -+ -+ sp->cur_rx = idx; -+ -+ return rval; -+} -+ -+ -+static void ar2313_tx_int(struct net_device *dev) -+{ -+ struct ar2313_private *sp = dev->priv; -+ u32 idx; -+ struct sk_buff *skb; -+ ar2313_descr_t *txdesc; -+ unsigned int status=0; -+ -+ idx = sp->tx_csm; -+ -+ while (idx != sp->tx_prd) { -+ -+ txdesc = &sp->tx_ring[idx]; -+ -+#if DEBUG_TX -+ printk("%s: TXINT: csm=%d idx=%d prd=%d status=%x devcs=%x addr=%08x descr=%x\n", -+ dev->name, sp->tx_csm, idx, sp->tx_prd, -+ txdesc->status, txdesc->devcs, txdesc->addr, txdesc->descr); -+#endif /* DEBUG */ -+ -+ if ((status = txdesc->status) & DMA_TX_OWN) { -+ /* ar2313 dma still owns descr */ -+ break; -+ } -+ /* done with this descriptor */ -+ dma_unmap_single(NULL, txdesc->addr, txdesc->devcs & DMA_TX1_BSIZE_MASK, DMA_TO_DEVICE); -+ txdesc->status = 0; -+ -+ if (status & DMA_TX_ERROR){ -+ sp->stats.tx_errors++; -+ sp->stats.tx_dropped++; -+ if(status & DMA_TX_ERR_UNDER) -+ sp->stats.tx_fifo_errors++; -+ if(status & DMA_TX_ERR_HB) -+ sp->stats.tx_heartbeat_errors++; -+ if(status & (DMA_TX_ERR_LOSS | -+ DMA_TX_ERR_LINK)) -+ sp->stats.tx_carrier_errors++; -+ if (status & (DMA_TX_ERR_LATE| -+ DMA_TX_ERR_COL | -+ DMA_TX_ERR_JABBER | -+ DMA_TX_ERR_DEFER)) -+ sp->stats.tx_aborted_errors++; -+ } else { -+ /* transmit OK */ -+ sp->stats.tx_packets++; -+ } -+ -+ skb = sp->tx_skb[idx]; -+ sp->tx_skb[idx] = NULL; -+ idx = DSC_NEXT(idx); -+ sp->stats.tx_bytes += skb->len; -+ dev_kfree_skb_irq(skb); -+ } -+ -+ sp->tx_csm = idx; -+ -+ return; -+} -+ -+ -+static void -+rx_tasklet_func(unsigned long data) -+{ -+ struct net_device *dev = (struct net_device *) data; -+ struct ar2313_private *sp = dev->priv; -+ -+ if (sp->unloading) { -+ return; -+ } -+ -+ if (ar2313_rx_int(dev)) { -+ tasklet_hi_schedule(&sp->rx_tasklet); -+ } -+ else { -+ unsigned long flags; -+ spin_lock_irqsave(&sp->lock, flags); -+ sp->dma_regs->intr_ena |= DMA_STATUS_RI; -+ spin_unlock_irqrestore(&sp->lock, flags); -+ } -+} -+ -+static void -+rx_schedule(struct net_device *dev) -+{ -+ struct ar2313_private *sp = dev->priv; -+ -+ sp->dma_regs->intr_ena &= ~DMA_STATUS_RI; -+ -+ tasklet_hi_schedule(&sp->rx_tasklet); -+} -+ -+static irqreturn_t ar2313_interrupt(int irq, void *dev_id) -+{ -+ struct net_device *dev = (struct net_device *)dev_id; -+ struct ar2313_private *sp = dev->priv; -+ unsigned int status, enabled; -+ -+ /* clear interrupt */ -+ /* -+ * Don't clear RI bit if currently disabled. -+ */ -+ status = sp->dma_regs->status; -+ enabled = sp->dma_regs->intr_ena; -+ sp->dma_regs->status = status & enabled; -+ -+ if (status & DMA_STATUS_NIS) { -+ /* normal status */ -+ /* -+ * Don't schedule rx processing if interrupt -+ * is already disabled. -+ */ -+ if (status & enabled & DMA_STATUS_RI) { -+ /* receive interrupt */ -+ rx_schedule(dev); -+ } -+ if (status & DMA_STATUS_TI) { -+ /* transmit interrupt */ -+ ar2313_tx_int(dev); -+ } -+ } -+ -+ if (status & DMA_STATUS_AIS) { -+#if DEBUG_INT -+ printk("%s: AIS set %08x & %x\n", __FUNCTION__, -+ status, (DMA_STATUS_FBE | DMA_STATUS_TPS)); -+#endif -+ /* abnormal status */ -+ if (status & (DMA_STATUS_FBE | DMA_STATUS_TPS)) { -+ ar2313_restart(dev); -+ } -+ } -+ return IRQ_HANDLED; -+} -+ -+ -+static int ar2313_open(struct net_device *dev) -+{ -+ struct ar2313_private *sp; -+ -+ sp = dev->priv; -+ -+ dev->mtu = 1500; -+ netif_start_queue(dev); -+ -+ sp->eth_regs->mac_control |= MAC_CONTROL_RE; -+ -+ AR2313_MOD_INC_USE_COUNT; -+ -+ return 0; -+} -+ -+static void ar2313_halt(struct net_device *dev) -+{ -+ struct ar2313_private *sp = dev->priv; -+ int j; -+ -+ tasklet_disable(&sp->rx_tasklet); -+ -+ /* kill the MAC */ -+ sp->eth_regs->mac_control &= ~(MAC_CONTROL_RE | /* disable Receives */ -+ MAC_CONTROL_TE); /* disable Transmits */ -+ /* stop dma */ -+ sp->dma_regs->control = 0; -+ sp->dma_regs->bus_mode = DMA_BUS_MODE_SWR; -+ -+ /* place phy and MAC in reset */ -+ *sp->int_regs |= (ar_int_mac_mask | ar_int_phy_mask); -+ -+ /* free buffers on tx ring */ -+ for (j = 0; j < AR2313_DESCR_ENTRIES; j++) { -+ struct sk_buff *skb; -+ ar2313_descr_t *txdesc; -+ -+ txdesc = &sp->tx_ring[j]; -+ txdesc->descr = 0; -+ -+ skb = sp->tx_skb[j]; -+ if (skb) { -+ dev_kfree_skb(skb); -+ sp->tx_skb[j] = NULL; -+ } -+ } -+} -+ -+/* -+ * close should do nothing. Here's why. It's called when -+ * 'ifconfig bond0 down' is run. If it calls free_irq then -+ * the irq is gone forever ! When bond0 is made 'up' again, -+ * the ar2313_open () does not call request_irq (). Worse, -+ * the call to ar2313_halt() generates a WDOG reset due to -+ * the write to 'sp->int_regs' and the box reboots. -+ * Commenting this out is good since it allows the -+ * system to resume when bond0 is made up again. -+ */ -+static int ar2313_close(struct net_device *dev) -+{ -+#if 0 -+ /* -+ * Disable interrupts -+ */ -+ disable_irq(dev->irq); -+ -+ /* -+ * Without (or before) releasing irq and stopping hardware, this -+ * is an absolute non-sense, by the way. It will be reset instantly -+ * by the first irq. -+ */ -+ netif_stop_queue(dev); -+ -+ /* stop the MAC and DMA engines */ -+ ar2313_halt(dev); -+ -+ /* release the interrupt */ -+ free_irq(dev->irq, dev); -+ -+#endif -+ AR2313_MOD_DEC_USE_COUNT; -+ return 0; -+} -+ -+static int ar2313_start_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct ar2313_private *sp = dev->priv; -+ ar2313_descr_t *td; -+ u32 idx; -+ -+ idx = sp->tx_prd; -+ td = &sp->tx_ring[idx]; -+ -+ if (td->status & DMA_TX_OWN) { -+#if DEBUG_TX -+ printk("%s: No space left to Tx\n", __FUNCTION__); -+#endif -+ /* free skbuf and lie to the caller that we sent it out */ -+ sp->stats.tx_dropped++; -+ dev_kfree_skb(skb); -+ -+ /* restart transmitter in case locked */ -+ sp->dma_regs->xmt_poll = 0; -+ return 0; -+ } -+ -+ /* Setup the transmit descriptor. */ -+ td->devcs = ((skb->len << DMA_TX1_BSIZE_SHIFT) | -+ (DMA_TX1_LS|DMA_TX1_IC|DMA_TX1_CHAINED)); -+ td->addr = dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE); -+ td->status = DMA_TX_OWN; -+ -+ /* kick transmitter last */ -+ sp->dma_regs->xmt_poll = 0; -+ -+#if DEBUG_TX -+ printk("index %d\n", idx); -+ printk("TX status %08x\n", td->status); -+ printk("TX devcs %08x\n", td->devcs ); -+ printk("TX addr %08x\n", td->addr ); -+ printk("TX descr %08x\n", td->descr ); -+#endif -+ -+ sp->tx_skb[idx] = skb; -+ idx = DSC_NEXT(idx); -+ sp->tx_prd = idx; -+ -+ //dev->trans_start = jiffies; -+ -+ return 0; -+} -+ -+static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd) -+{ -+ struct ar2313_private *np = dev->priv; -+ u32 tmp; -+ -+ ecmd->supported = -+ (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | -+ SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | -+ SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII); -+ -+ ecmd->port = PORT_TP; -+ /* only supports internal transceiver */ -+ ecmd->transceiver = XCVR_INTERNAL; -+ /* not sure what this is for */ -+ ecmd->phy_address = 1; -+ -+ ecmd->advertising = ADVERTISED_MII; -+ tmp = armiiread(np->phy, MII_ADVERTISE); -+ if (tmp & ADVERTISE_10HALF) -+ ecmd->advertising |= ADVERTISED_10baseT_Half; -+ if (tmp & ADVERTISE_10FULL) -+ ecmd->advertising |= ADVERTISED_10baseT_Full; -+ if (tmp & ADVERTISE_100HALF) -+ ecmd->advertising |= ADVERTISED_100baseT_Half; -+ if (tmp & ADVERTISE_100FULL) -+ ecmd->advertising |= ADVERTISED_100baseT_Full; -+ -+ tmp = armiiread(np->phy, MII_BMCR); -+ if (tmp & BMCR_ANENABLE) { -+ ecmd->advertising |= ADVERTISED_Autoneg; -+ ecmd->autoneg = AUTONEG_ENABLE; -+ } else { -+ ecmd->autoneg = AUTONEG_DISABLE; -+ } -+ -+ if (ecmd->autoneg == AUTONEG_ENABLE) { -+ tmp = armiiread(np->phy, MII_LPA); -+ if (tmp & (LPA_100FULL|LPA_10FULL)) { -+ ecmd->duplex = DUPLEX_FULL; -+ } else { -+ ecmd->duplex = DUPLEX_HALF; -+ } -+ if (tmp & (LPA_100FULL|LPA_100HALF)) { -+ ecmd->speed = SPEED_100; -+ } else { -+ ecmd->speed = SPEED_10; -+ } -+ } else { -+ if (tmp & BMCR_FULLDPLX) { -+ ecmd->duplex = DUPLEX_FULL; -+ } else { -+ ecmd->duplex = DUPLEX_HALF; -+ } -+ if (tmp & BMCR_SPEED100) { -+ ecmd->speed = SPEED_100; -+ } else { -+ ecmd->speed = SPEED_10; -+ } -+ } -+ -+ /* ignore maxtxpkt, maxrxpkt for now */ -+ -+ return 0; -+} -+ -+static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd) -+{ -+ struct ar2313_private *np = dev->priv; -+ u32 tmp; -+ -+ if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100) -+ return -EINVAL; -+ if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL) -+ return -EINVAL; -+ if (ecmd->port != PORT_TP) -+ return -EINVAL; -+ if (ecmd->transceiver != XCVR_INTERNAL) -+ return -EINVAL; -+ if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE) -+ return -EINVAL; -+ /* ignore phy_address, maxtxpkt, maxrxpkt for now */ -+ -+ /* WHEW! now lets bang some bits */ -+ -+ tmp = armiiread(np->phy, MII_BMCR); -+ if (ecmd->autoneg == AUTONEG_ENABLE) { -+ /* turn on autonegotiation */ -+ tmp |= BMCR_ANENABLE; -+ printk("%s: Enabling auto-neg\n", dev->name); -+ } else { -+ /* turn off auto negotiation, set speed and duplexity */ -+ tmp &= ~(BMCR_ANENABLE | BMCR_SPEED100 | BMCR_FULLDPLX); -+ if (ecmd->speed == SPEED_100) -+ tmp |= BMCR_SPEED100; -+ if (ecmd->duplex == DUPLEX_FULL) -+ tmp |= BMCR_FULLDPLX; -+ printk("%s: Hard coding %d/%s\n", dev->name, -+ (ecmd->speed == SPEED_100)? 100:10, -+ (ecmd->duplex == DUPLEX_FULL)? "full":"half"); -+ } -+ armiiwrite(np->phy, MII_BMCR, tmp); -+ np->phyData = 0; -+ return 0; -+} -+ -+static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) -+{ -+ struct ar2313_private *np = dev->priv; -+ u32 cmd; -+ -+ if (get_user(cmd, (u32 *)useraddr)) -+ return -EFAULT; -+ -+ switch (cmd) { -+ /* get settings */ -+ case ETHTOOL_GSET: { -+ struct ethtool_cmd ecmd = { ETHTOOL_GSET }; -+ spin_lock_irq(&np->lock); -+ netdev_get_ecmd(dev, &ecmd); -+ spin_unlock_irq(&np->lock); -+ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) -+ return -EFAULT; -+ return 0; -+ } -+ /* set settings */ -+ case ETHTOOL_SSET: { -+ struct ethtool_cmd ecmd; -+ int r; -+ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) -+ return -EFAULT; -+ spin_lock_irq(&np->lock); -+ r = netdev_set_ecmd(dev, &ecmd); -+ spin_unlock_irq(&np->lock); -+ return r; -+ } -+ /* restart autonegotiation */ -+ case ETHTOOL_NWAY_RST: { -+ int tmp; -+ int r = -EINVAL; -+ /* if autoneg is off, it's an error */ -+ tmp = armiiread(np->phy, MII_BMCR); -+ if (tmp & BMCR_ANENABLE) { -+ tmp |= (BMCR_ANRESTART); -+ armiiwrite(np->phy, MII_BMCR, tmp); -+ r = 0; -+ } -+ return r; -+ } -+ /* get link status */ -+ case ETHTOOL_GLINK: { -+ struct ethtool_value edata = {ETHTOOL_GLINK}; -+ edata.data = (armiiread(np->phy, MII_BMSR)&BMSR_LSTATUS) ? 1:0; -+ if (copy_to_user(useraddr, &edata, sizeof(edata))) -+ return -EFAULT; -+ return 0; -+ } -+ } -+ -+ return -EOPNOTSUPP; -+} -+ -+static int ar2313_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -+{ -+ struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data; -+ -+ switch (cmd) { -+ case SIOCDEVPRIVATE: { -+ struct ar2313_cmd scmd; -+ -+ if (copy_from_user(&scmd, ifr->ifr_data, sizeof(scmd))) -+ return -EFAULT; -+ -+#if DEBUG -+ printk("%s: ioctl devprivate c=%d a=%x l=%d m=%d d=%x,%x\n", -+ dev->name, scmd.cmd, -+ scmd.address, scmd.length, -+ scmd.mailbox, scmd.data[0], scmd.data[1]); -+#endif /* DEBUG */ -+ -+ switch (scmd.cmd) { -+ case AR2313_READ_DATA: -+ if(scmd.length==4){ -+ scmd.data[0] = *((u32*)scmd.address); -+ } else if(scmd.length==2) { -+ scmd.data[0] = *((u16*)scmd.address); -+ } else if (scmd.length==1) { -+ scmd.data[0] = *((u8*)scmd.address); -+ } else { -+ return -EOPNOTSUPP; -+ } -+ if(copy_to_user(ifr->ifr_data, &scmd, sizeof(scmd))) -+ return -EFAULT; -+ break; -+ -+ case AR2313_WRITE_DATA: -+ if(scmd.length==4){ -+ *((u32*)scmd.address) = scmd.data[0]; -+ } else if(scmd.length==2) { -+ *((u16*)scmd.address) = scmd.data[0]; -+ } else if (scmd.length==1) { -+ *((u8*)scmd.address) = scmd.data[0]; -+ } else { -+ return -EOPNOTSUPP; -+ } -+ break; -+ -+ case AR2313_GET_VERSION: -+ // SAMEER: sprintf((char*) &scmd, "%s", ARUBA_VERSION); -+ if(copy_to_user(ifr->ifr_data, &scmd, sizeof(scmd))) -+ return -EFAULT; -+ break; -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+ return 0; -+ } -+ -+ case SIOCETHTOOL: -+ return netdev_ethtool_ioctl(dev, (void *) ifr->ifr_data); -+ -+ case SIOCGMIIPHY: /* Get address of MII PHY in use. */ -+ data->phy_id = 1; -+ /* Fall Through */ -+ -+ case SIOCGMIIREG: /* Read MII PHY register. */ -+ case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ -+ data->val_out = armiiread(data->phy_id & 0x1f, -+ data->reg_num & 0x1f); -+ return 0; -+ case SIOCSMIIREG: /* Write MII PHY register. */ -+ case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ -+ if (!capable(CAP_NET_ADMIN)) -+ return -EPERM; -+ armiiwrite(data->phy_id & 0x1f, -+ data->reg_num & 0x1f, data->val_in); -+ return 0; -+ -+ case SIOCSIFHWADDR: -+ if (copy_from_user(dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr))) -+ return -EFAULT; -+ return 0; -+ -+ case SIOCGIFHWADDR: -+ if (copy_to_user(ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr))) -+ return -EFAULT; -+ return 0; -+ -+ default: -+ break; -+ } -+ -+ return -EOPNOTSUPP; -+} -+ -+static struct net_device_stats *ar2313_get_stats(struct net_device *dev) -+{ -+ struct ar2313_private *sp = dev->priv; -+ return &sp->stats; -+} -+ -+static short -+armiiread(short phy, short reg) -+{ -+ volatile ETHERNET_STRUCT * ethernet; -+ -+ ethernet = (volatile ETHERNET_STRUCT *)KSEG1ADDR(ar_eth_base); /* always MAC 0 */ -+ ethernet->mii_addr = ((reg << MII_ADDR_REG_SHIFT) | -+ (phy << MII_ADDR_PHY_SHIFT)); -+ while (ethernet->mii_addr & MII_ADDR_BUSY); -+ return (ethernet->mii_data >> MII_DATA_SHIFT); -+} -+ -+static void -+armiiwrite(short phy, short reg, short data) -+{ -+ volatile ETHERNET_STRUCT * ethernet; -+ -+ ethernet = (volatile ETHERNET_STRUCT *)KSEG1ADDR(ar_eth_base); /* always MAC 0 */ -+ while (ethernet->mii_addr & MII_ADDR_BUSY); -+ ethernet->mii_data = data << MII_DATA_SHIFT; -+ ethernet->mii_addr = ((reg << MII_ADDR_REG_SHIFT) | -+ (phy << MII_ADDR_PHY_SHIFT) | -+ MII_ADDR_WRITE); -+} -+ -diff -urN linux.old/drivers/net/ar2313/ar2313.h linux.eth/drivers/net/ar2313/ar2313.h ---- linux.old/drivers/net/ar2313/ar2313.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.eth/drivers/net/ar2313/ar2313.h 2006-12-16 04:30:11.000000000 +0100 -@@ -0,0 +1,191 @@ -+#ifndef _AR2313_H_ -+#define _AR2313_H_ -+ -+#include <linux/autoconf.h> -+#include <asm/bootinfo.h> -+#include "platform.h" -+ -+extern unsigned long mips_machtype; -+ -+#undef ETHERNET_BASE -+#define ETHERNET_BASE ar_eth_base -+#define ETHERNET_SIZE 0x00100000 -+#define ETHERNET_MACS 2 -+ -+#undef DMA_BASE -+#define DMA_BASE ar_dma_base -+#define DMA_SIZE 0x00100000 -+ -+ -+/* -+ * probe link timer - 5 secs -+ */ -+#define LINK_TIMER (5*HZ) -+ -+/* -+ * Interrupt register base address -+ */ -+#define INTERRUPT_BASE PHYS_TO_K1(ar_int_base) -+ -+/* -+ * Reset Register -+ */ -+#define AR531X_RESET (AR531X_RESETTMR + 0x0020) -+#define RESET_SYSTEM 0x00000001 /* cold reset full system */ -+#define RESET_PROC 0x00000002 /* cold reset MIPS core */ -+#define RESET_WLAN0 0x00000004 /* cold reset WLAN MAC and BB */ -+#define RESET_EPHY0 0x00000008 /* cold reset ENET0 phy */ -+#define RESET_EPHY1 0x00000010 /* cold reset ENET1 phy */ -+#define RESET_ENET0 0x00000020 /* cold reset ENET0 mac */ -+#define RESET_ENET1 0x00000040 /* cold reset ENET1 mac */ -+ -+#define IS_DMA_TX_INT(X) (((X) & (DMA_STATUS_TI)) != 0) -+#define IS_DMA_RX_INT(X) (((X) & (DMA_STATUS_RI)) != 0) -+#define IS_DRIVER_OWNED(X) (((X) & (DMA_TX_OWN)) == 0) -+ -+#ifndef K1_TO_PHYS -+// hack -+#define K1_TO_PHYS(x) (((unsigned int)(x)) & 0x1FFFFFFF) /* kseg1 to physical */ -+#endif -+ -+#ifndef PHYS_TO_K1 -+// hack -+#define PHYS_TO_K1(x) (((unsigned int)(x)) | 0xA0000000) /* physical to kseg1 */ -+#endif -+ -+#define AR2313_TX_TIMEOUT (HZ/4) -+ -+/* -+ * Rings -+ */ -+#define DSC_RING_ENTRIES_SIZE (AR2313_DESCR_ENTRIES * sizeof(struct desc)) -+#define DSC_NEXT(idx) ((idx + 1) & (AR2313_DESCR_ENTRIES - 1)) -+ -+static inline int tx_space (u32 csm, u32 prd) -+{ -+ return (csm - prd - 1) & (AR2313_DESCR_ENTRIES - 1); -+} -+ -+#if MAX_SKB_FRAGS -+#define TX_RESERVED (MAX_SKB_FRAGS+1) /* +1 for message header */ -+#define tx_ring_full(csm, prd) (tx_space(csm, prd) <= TX_RESERVED) -+#else -+#define tx_ring_full 0 -+#endif -+ -+#define AR2313_MBGET 2 -+#define AR2313_MBSET 3 -+#define AR2313_PCI_RECONFIG 4 -+#define AR2313_PCI_DUMP 5 -+#define AR2313_TEST_PANIC 6 -+#define AR2313_TEST_NULLPTR 7 -+#define AR2313_READ_DATA 8 -+#define AR2313_WRITE_DATA 9 -+#define AR2313_GET_VERSION 10 -+#define AR2313_TEST_HANG 11 -+#define AR2313_SYNC 12 -+ -+ -+struct ar2313_cmd { -+ u32 cmd; -+ u32 address; /* virtual address of image */ -+ u32 length; /* size of image to download */ -+ u32 mailbox; /* mailbox to get/set */ -+ u32 data[2]; /* contents of mailbox to read/write */ -+}; -+ -+ -+/* -+ * Struct private for the Sibyte. -+ * -+ * Elements are grouped so variables used by the tx handling goes -+ * together, and will go into the same cache lines etc. in order to -+ * avoid cache line contention between the rx and tx handling on SMP. -+ * -+ * Frequently accessed variables are put at the beginning of the -+ * struct to help the compiler generate better/shorter code. -+ */ -+struct ar2313_private -+{ -+ struct net_device *dev; -+ int version; -+ u32 mb[2]; -+ -+ volatile ETHERNET_STRUCT *eth_regs; -+ volatile DMA *dma_regs; -+ volatile u32 *int_regs; -+ -+ spinlock_t lock; /* Serialise access to device */ -+ -+ /* -+ * RX and TX descriptors, must be adjacent -+ */ -+ ar2313_descr_t *rx_ring; -+ ar2313_descr_t *tx_ring; -+ -+ -+ struct sk_buff **rx_skb; -+ struct sk_buff **tx_skb; -+ -+ /* -+ * RX elements -+ */ -+ u32 rx_skbprd; -+ u32 cur_rx; -+ -+ /* -+ * TX elements -+ */ -+ u32 tx_prd; -+ u32 tx_csm; -+ -+ /* -+ * Misc elements -+ */ -+ int board_idx; -+ char name[48]; -+ struct net_device_stats stats; -+ struct { -+ u32 address; -+ u32 length; -+ char *mapping; -+ } desc; -+ -+ -+ struct timer_list link_timer; -+ unsigned short phy; /* merlot phy = 1, samsung phy = 0x1f */ -+ unsigned short mac; -+ unsigned short link; /* 0 - link down, 1 - link up */ -+ u16 phyData; -+ -+ struct tasklet_struct rx_tasklet; -+ int unloading; -+}; -+ -+ -+/* -+ * Prototypes -+ */ -+static int ar2313_init(struct net_device *dev); -+#ifdef TX_TIMEOUT -+static void ar2313_tx_timeout(struct net_device *dev); -+#endif -+#if 0 -+static void ar2313_multicast_list(struct net_device *dev); -+#endif -+static int ar2313_restart(struct net_device *dev); -+#if DEBUG -+static void ar2313_dump_regs(struct net_device *dev); -+#endif -+static void ar2313_load_rx_ring(struct net_device *dev, int bufs); -+static irqreturn_t ar2313_interrupt(int irq, void *dev_id); -+static int ar2313_open(struct net_device *dev); -+static int ar2313_start_xmit(struct sk_buff *skb, struct net_device *dev); -+static int ar2313_close(struct net_device *dev); -+static int ar2313_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); -+static void ar2313_init_cleanup(struct net_device *dev); -+static int ar2313_setup_timer(struct net_device *dev); -+static void ar2313_link_timer_fn(unsigned long data); -+static void ar2313_check_link(struct net_device *dev); -+static struct net_device_stats *ar2313_get_stats(struct net_device *dev); -+#endif /* _AR2313_H_ */ -diff -urN linux.old/drivers/net/ar2313/ar2313_msg.h linux.eth/drivers/net/ar2313/ar2313_msg.h ---- linux.old/drivers/net/ar2313/ar2313_msg.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.eth/drivers/net/ar2313/ar2313_msg.h 2006-12-16 04:30:11.000000000 +0100 -@@ -0,0 +1,17 @@ -+#ifndef _AR2313_MSG_H_ -+#define _AR2313_MSG_H_ -+ -+#define AR2313_MTU 1692 -+#define AR2313_PRIOS 1 -+#define AR2313_QUEUES (2*AR2313_PRIOS) -+ -+#define AR2313_DESCR_ENTRIES 64 -+ -+typedef struct { -+ volatile unsigned int status; // OWN, Device control and status. -+ volatile unsigned int devcs; // pkt Control bits + Length -+ volatile unsigned int addr; // Current Address. -+ volatile unsigned int descr; // Next descriptor in chain. -+} ar2313_descr_t; -+ -+#endif /* _AR2313_MSG_H_ */ -diff -urN linux.old/drivers/net/ar2313/dma.h linux.eth/drivers/net/ar2313/dma.h ---- linux.old/drivers/net/ar2313/dma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.eth/drivers/net/ar2313/dma.h 2006-12-16 04:30:11.000000000 +0100 -@@ -0,0 +1,135 @@ -+#ifndef __ARUBA_DMA_H__ -+#define __ARUBA_DMA_H__ -+ -+/******************************************************************************* -+ * -+ * Copyright 2002 Integrated Device Technology, Inc. -+ * All rights reserved. -+ * -+ * DMA register definition. -+ * -+ * File : $Id: dma.h,v 1.3 2002/06/06 18:34:03 astichte Exp $ -+ * -+ * Author : ryan.holmQVist@idt.com -+ * Date : 20011005 -+ * Update : -+ * $Log: dma.h,v $ -+ * Revision 1.3 2002/06/06 18:34:03 astichte -+ * Added XXX_PhysicalAddress and XXX_VirtualAddress -+ * -+ * Revision 1.2 2002/06/05 18:30:46 astichte -+ * Removed IDTField -+ * -+ * Revision 1.1 2002/05/29 17:33:21 sysarch -+ * jba File moved from vcode/include/idt/acacia -+ * -+ * -+ ******************************************************************************/ -+ -+#define AR_BIT(x) (1 << (x)) -+#define DMA_RX_ERR_CRC AR_BIT(1) -+#define DMA_RX_ERR_DRIB AR_BIT(2) -+#define DMA_RX_ERR_MII AR_BIT(3) -+#define DMA_RX_EV2 AR_BIT(5) -+#define DMA_RX_ERR_COL AR_BIT(6) -+#define DMA_RX_LONG AR_BIT(7) -+#define DMA_RX_LS AR_BIT(8) /* last descriptor */ -+#define DMA_RX_FS AR_BIT(9) /* first descriptor */ -+#define DMA_RX_MF AR_BIT(10) /* multicast frame */ -+#define DMA_RX_ERR_RUNT AR_BIT(11) /* runt frame */ -+#define DMA_RX_ERR_LENGTH AR_BIT(12) /* length error */ -+#define DMA_RX_ERR_DESC AR_BIT(14) /* descriptor error */ -+#define DMA_RX_ERROR AR_BIT(15) /* error summary */ -+#define DMA_RX_LEN_MASK 0x3fff0000 -+#define DMA_RX_LEN_SHIFT 16 -+#define DMA_RX_FILT AR_BIT(30) -+#define DMA_RX_OWN AR_BIT(31) /* desc owned by DMA controller */ -+ -+#define DMA_RX1_BSIZE_MASK 0x000007ff -+#define DMA_RX1_BSIZE_SHIFT 0 -+#define DMA_RX1_CHAINED AR_BIT(24) -+#define DMA_RX1_RER AR_BIT(25) -+ -+#define DMA_TX_ERR_UNDER AR_BIT(1) /* underflow error */ -+#define DMA_TX_ERR_DEFER AR_BIT(2) /* excessive deferral */ -+#define DMA_TX_COL_MASK 0x78 -+#define DMA_TX_COL_SHIFT 3 -+#define DMA_TX_ERR_HB AR_BIT(7) /* hearbeat failure */ -+#define DMA_TX_ERR_COL AR_BIT(8) /* excessive collisions */ -+#define DMA_TX_ERR_LATE AR_BIT(9) /* late collision */ -+#define DMA_TX_ERR_LINK AR_BIT(10) /* no carrier */ -+#define DMA_TX_ERR_LOSS AR_BIT(11) /* loss of carrier */ -+#define DMA_TX_ERR_JABBER AR_BIT(14) /* transmit jabber timeout */ -+#define DMA_TX_ERROR AR_BIT(15) /* frame aborted */ -+#define DMA_TX_OWN AR_BIT(31) /* descr owned by DMA controller */ -+ -+#define DMA_TX1_BSIZE_MASK 0x000007ff -+#define DMA_TX1_BSIZE_SHIFT 0 -+#define DMA_TX1_CHAINED AR_BIT(24) /* chained descriptors */ -+#define DMA_TX1_TER AR_BIT(25) /* transmit end of ring */ -+#define DMA_TX1_FS AR_BIT(29) /* first segment */ -+#define DMA_TX1_LS AR_BIT(30) /* last segment */ -+#define DMA_TX1_IC AR_BIT(31) /* interrupt on completion */ -+ -+#define RCVPKT_LENGTH(X) (X >> 16) /* Received pkt Length */ -+ -+#define MAC_CONTROL_RE AR_BIT(2) /* receive enable */ -+#define MAC_CONTROL_TE AR_BIT(3) /* transmit enable */ -+#define MAC_CONTROL_DC AR_BIT(5) /* Deferral check*/ -+#define MAC_CONTROL_ASTP AR_BIT(8) /* Auto pad strip */ -+#define MAC_CONTROL_DRTY AR_BIT(10) /* Disable retry */ -+#define MAC_CONTROL_DBF AR_BIT(11) /* Disable bcast frames */ -+#define MAC_CONTROL_LCC AR_BIT(12) /* late collision ctrl */ -+#define MAC_CONTROL_HP AR_BIT(13) /* Hash Perfect filtering */ -+#define MAC_CONTROL_HASH AR_BIT(14) /* Unicast hash filtering */ -+#define MAC_CONTROL_HO AR_BIT(15) /* Hash only filtering */ -+#define MAC_CONTROL_PB AR_BIT(16) /* Pass Bad frames */ -+#define MAC_CONTROL_IF AR_BIT(17) /* Inverse filtering */ -+#define MAC_CONTROL_PR AR_BIT(18) /* promiscuous mode (valid frames only) */ -+#define MAC_CONTROL_PM AR_BIT(19) /* pass multicast */ -+#define MAC_CONTROL_F AR_BIT(20) /* full-duplex */ -+#define MAC_CONTROL_DRO AR_BIT(23) /* Disable Receive Own */ -+#define MAC_CONTROL_HBD AR_BIT(28) /* heart-beat disabled (MUST BE SET) */ -+#define MAC_CONTROL_BLE AR_BIT(30) /* big endian mode */ -+#define MAC_CONTROL_RA AR_BIT(31) /* receive all (valid and invalid frames) */ -+ -+#define MII_ADDR_BUSY AR_BIT(0) -+#define MII_ADDR_WRITE AR_BIT(1) -+#define MII_ADDR_REG_SHIFT 6 -+#define MII_ADDR_PHY_SHIFT 11 -+#define MII_DATA_SHIFT 0 -+ -+#define FLOW_CONTROL_FCE AR_BIT(1) -+ -+#define DMA_BUS_MODE_SWR AR_BIT(0) /* software reset */ -+#define DMA_BUS_MODE_BLE AR_BIT(7) /* big endian mode */ -+#define DMA_BUS_MODE_PBL_SHIFT 8 /* programmable burst length 32 */ -+#define DMA_BUS_MODE_DBO AR_BIT(20) /* big-endian descriptors */ -+ -+#define DMA_STATUS_TI AR_BIT(0) /* transmit interrupt */ -+#define DMA_STATUS_TPS AR_BIT(1) /* transmit process stopped */ -+#define DMA_STATUS_TU AR_BIT(2) /* transmit buffer unavailable */ -+#define DMA_STATUS_TJT AR_BIT(3) /* transmit buffer timeout */ -+#define DMA_STATUS_UNF AR_BIT(5) /* transmit underflow */ -+#define DMA_STATUS_RI AR_BIT(6) /* receive interrupt */ -+#define DMA_STATUS_RU AR_BIT(7) /* receive buffer unavailable */ -+#define DMA_STATUS_RPS AR_BIT(8) /* receive process stopped */ -+#define DMA_STATUS_ETI AR_BIT(10) /* early transmit interrupt */ -+#define DMA_STATUS_FBE AR_BIT(13) /* fatal bus interrupt */ -+#define DMA_STATUS_ERI AR_BIT(14) /* early receive interrupt */ -+#define DMA_STATUS_AIS AR_BIT(15) /* abnormal interrupt summary */ -+#define DMA_STATUS_NIS AR_BIT(16) /* normal interrupt summary */ -+#define DMA_STATUS_RS_SHIFT 17 /* receive process state */ -+#define DMA_STATUS_TS_SHIFT 20 /* transmit process state */ -+#define DMA_STATUS_EB_SHIFT 23 /* error bits */ -+ -+#define DMA_CONTROL_SR AR_BIT(1) /* start receive */ -+#define DMA_CONTROL_ST AR_BIT(13) /* start transmit */ -+#define DMA_CONTROL_SF AR_BIT(21) /* store and forward */ -+ -+#endif // __ARUBA_DMA_H__ -+ -+ -+ -+ -+ -diff -urN linux.old/drivers/net/ar2313/Makefile linux.eth/drivers/net/ar2313/Makefile ---- linux.old/drivers/net/ar2313/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.eth/drivers/net/ar2313/Makefile 2006-12-16 04:30:11.000000000 +0100 -@@ -0,0 +1,5 @@ -+# -+# Makefile for the AR2313 ethernet driver -+# -+ -+obj-$(CONFIG_AR2313) += ar2313.o -diff -urN linux.old/drivers/net/ar2313/platform.h linux.eth/drivers/net/ar2313/platform.h ---- linux.old/drivers/net/ar2313/platform.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.eth/drivers/net/ar2313/platform.h 2006-12-16 04:30:11.000000000 +0100 -@@ -0,0 +1,128 @@ -+/******************************************************************************** -+ Title: $Source: platform.h,v $ -+ -+ Author: Dan Steinberg -+ Copyright Integrated Device Technology 2001 -+ -+ Purpose: AR2313 Register/Bit Definitions -+ -+ Update: -+ $Log: platform.h,v $ -+ -+ Notes: See Merlot architecture spec for complete details. Note, all -+ addresses are virtual addresses in kseg1 (Uncached, Unmapped). -+ -+********************************************************************************/ -+ -+#ifndef PLATFORM_H -+#define PLATFORM_H -+ -+#define BIT(x) (1 << (x)) -+ -+#define RESET_BASE 0xBC003020 -+#define RESET_VALUE 0x00000001 -+ -+/******************************************************************** -+ * Device controller -+ ********************************************************************/ -+typedef struct { -+ volatile unsigned int flash0; -+} DEVICE; -+ -+#define device (*((volatile DEVICE *) DEV_CTL_BASE)) -+ -+// DDRC register -+#define DEV_WP (1<<26) -+ -+/******************************************************************** -+ * DDR controller -+ ********************************************************************/ -+typedef struct { -+ volatile unsigned int ddrc0; -+ volatile unsigned int ddrc1; -+ volatile unsigned int ddrrefresh; -+} DDR; -+ -+#define ddr (*((volatile DDR *) DDR_BASE)) -+ -+// DDRC register -+#define DDRC_CS(i) ((i&0x3)<<0) -+#define DDRC_WE (1<<2) -+ -+/******************************************************************** -+ * Ethernet interfaces -+ ********************************************************************/ -+#define ETHERNET_BASE 0xB8200000 -+ -+// -+// New Combo structure for Both Eth0 AND eth1 -+// -+typedef struct { -+ volatile unsigned int mac_control; /* 0x00 */ -+ volatile unsigned int mac_addr[2]; /* 0x04 - 0x08*/ -+ volatile unsigned int mcast_table[2]; /* 0x0c - 0x10 */ -+ volatile unsigned int mii_addr; /* 0x14 */ -+ volatile unsigned int mii_data; /* 0x18 */ -+ volatile unsigned int flow_control; /* 0x1c */ -+ volatile unsigned int vlan_tag; /* 0x20 */ -+ volatile unsigned int pad[7]; /* 0x24 - 0x3c */ -+ volatile unsigned int ucast_table[8]; /* 0x40-0x5c */ -+ -+} ETHERNET_STRUCT; -+ -+/******************************************************************** -+ * Interrupt controller -+ ********************************************************************/ -+ -+typedef struct { -+ volatile unsigned int wdog_control; /* 0x08 */ -+ volatile unsigned int wdog_timer; /* 0x0c */ -+ volatile unsigned int misc_status; /* 0x10 */ -+ volatile unsigned int misc_mask; /* 0x14 */ -+ volatile unsigned int global_status; /* 0x18 */ -+ volatile unsigned int reserved; /* 0x1c */ -+ volatile unsigned int reset_control; /* 0x20 */ -+} INTERRUPT; -+ -+#define interrupt (*((volatile INTERRUPT *) INTERRUPT_BASE)) -+ -+#define INTERRUPT_MISC_TIMER BIT(0) -+#define INTERRUPT_MISC_AHBPROC BIT(1) -+#define INTERRUPT_MISC_AHBDMA BIT(2) -+#define INTERRUPT_MISC_GPIO BIT(3) -+#define INTERRUPT_MISC_UART BIT(4) -+#define INTERRUPT_MISC_UARTDMA BIT(5) -+#define INTERRUPT_MISC_WATCHDOG BIT(6) -+#define INTERRUPT_MISC_LOCAL BIT(7) -+ -+#define INTERRUPT_GLOBAL_ETH BIT(2) -+#define INTERRUPT_GLOBAL_WLAN BIT(3) -+#define INTERRUPT_GLOBAL_MISC BIT(4) -+#define INTERRUPT_GLOBAL_ITIMER BIT(5) -+ -+/******************************************************************** -+ * DMA controller -+ ********************************************************************/ -+#define DMA_BASE 0xB8201000 -+ -+typedef struct { -+ volatile unsigned int bus_mode; /* 0x00 (CSR0) */ -+ volatile unsigned int xmt_poll; /* 0x04 (CSR1) */ -+ volatile unsigned int rcv_poll; /* 0x08 (CSR2) */ -+ volatile unsigned int rcv_base; /* 0x0c (CSR3) */ -+ volatile unsigned int xmt_base; /* 0x10 (CSR4) */ -+ volatile unsigned int status; /* 0x14 (CSR5) */ -+ volatile unsigned int control; /* 0x18 (CSR6) */ -+ volatile unsigned int intr_ena; /* 0x1c (CSR7) */ -+ volatile unsigned int rcv_missed; /* 0x20 (CSR8) */ -+ volatile unsigned int reserved[11]; /* 0x24-0x4c (CSR9-19) */ -+ volatile unsigned int cur_tx_buf_addr; /* 0x50 (CSR20) */ -+ volatile unsigned int cur_rx_buf_addr; /* 0x50 (CSR21) */ -+} DMA; -+ -+#define dma (*((volatile DMA *) DMA_BASE)) -+ -+// macro to convert from virtual to physical address -+#define phys_addr(x) (x & 0x1fffffff) -+ -+#endif /* PLATFORM_H */ diff -urN linux.old/drivers/net/Kconfig linux.eth/drivers/net/Kconfig --- linux.old/drivers/net/Kconfig 2006-12-14 23:53:29.000000000 +0100 +++ linux.eth/drivers/net/Kconfig 2006-12-16 04:30:11.000000000 +0100 @@ -2052,7 +7,7 @@ diff -urN linux.old/drivers/net/Kconfig linux.eth/drivers/net/Kconfig +config AR2313 + tristate "AR2313 Ethernet support" -+ depends on NET_ETHERNET && AR531X ++ depends on NET_ETHERNET && ATHEROS + help + Support for the AR231x/531x ethernet controller + |