diff options
Diffstat (limited to 'target/wag54g/patches')
-rw-r--r-- | target/wag54g/patches/ar7.patch | 1676 |
1 files changed, 222 insertions, 1454 deletions
diff --git a/target/wag54g/patches/ar7.patch b/target/wag54g/patches/ar7.patch index 1398c5e71..adf7c5abd 100644 --- a/target/wag54g/patches/ar7.patch +++ b/target/wag54g/patches/ar7.patch @@ -1,6 +1,65 @@ +diff -Nur linux-2.6.29.1.orig/arch/mips/Kconfig linux-2.6.29.1/arch/mips/Kconfig +--- linux-2.6.29.1.orig/arch/mips/Kconfig 2009-04-02 22:55:27.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/Kconfig 2009-06-05 23:38:22.964942366 +0200 +@@ -19,6 +19,24 @@ + prompt "System type" + default SGI_IP22 + ++config AR7 ++ bool "Texas Instruments AR7" ++ select BOOT_ELF32 ++ select DMA_NONCOHERENT ++ select CEVT_R4K ++ select CSRC_R4K ++ select IRQ_CPU ++ select NO_EXCEPT_FILL ++ select SWAP_IO_SPACE ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_HAS_EARLY_PRINTK ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_SUPPORTS_KGDB ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select GENERIC_GPIO ++ select GENERIC_HARDIRQS_NO__DO_IRQ ++ + config MACH_ALCHEMY + bool "Alchemy processor based machines" + +diff -Nur linux-2.6.29.1.orig/arch/mips/Makefile linux-2.6.29.1/arch/mips/Makefile +--- linux-2.6.29.1.orig/arch/mips/Makefile 2009-04-02 22:55:27.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/Makefile 2009-06-05 23:38:22.972943665 +0200 +@@ -173,6 +173,13 @@ + # + + # ++# Texas Instruments AR7 ++# ++core-$(CONFIG_AR7) += arch/mips/ar7/ ++cflags-$(CONFIG_AR7) += -I$(srctree)/arch/mips/include/asm/mach-ar7 ++load-$(CONFIG_AR7) += 0xffffffff94100000 ++ ++# + # Acer PICA 61, Mips Magnum 4000 and Olivetti M700. + # + core-$(CONFIG_MACH_JAZZ) += arch/mips/jazz/ +diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/Makefile linux-2.6.29.1/arch/mips/ar7/Makefile +--- linux-2.6.29.1.orig/arch/mips/ar7/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.29.1/arch/mips/ar7/Makefile 2009-06-05 23:38:22.900939237 +0200 +@@ -0,0 +1,10 @@ ++ ++obj-y := \ ++ prom.o \ ++ setup.o \ ++ memory.o \ ++ irq.o \ ++ time.o \ ++ platform.o \ ++ gpio.o \ ++ clock.o diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/clock.c linux-2.6.29.1/arch/mips/ar7/clock.c --- linux-2.6.29.1.orig/arch/mips/ar7/clock.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar7/clock.c 2009-05-31 20:19:17.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/ar7/clock.c 2009-06-05 23:38:22.890200159 +0200 @@ -0,0 +1,483 @@ +/* + * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org> @@ -487,7 +546,7 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/clock.c linux-2.6.29.1/arch/mips/ar7 +} diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/gpio.c linux-2.6.29.1/arch/mips/ar7/gpio.c --- linux-2.6.29.1.orig/arch/mips/ar7/gpio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar7/gpio.c 2009-05-31 20:19:27.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/ar7/gpio.c 2009-06-05 23:38:22.896939006 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org> @@ -540,7 +599,7 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/gpio.c linux-2.6.29.1/arch/mips/ar7/ +EXPORT_SYMBOL(gpio_free); diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/irq.c linux-2.6.29.1/arch/mips/ar7/irq.c --- linux-2.6.29.1.orig/arch/mips/ar7/irq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar7/irq.c 2009-05-31 20:19:35.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/ar7/irq.c 2009-06-05 23:38:22.896939006 +0200 @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2006,2007 Felix Fietkau <nbd@openwrt.org> @@ -725,23 +784,9 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/irq.c linux-2.6.29.1/arch/mips/ar7/i + else + spurious_interrupt(); +} -diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/Makefile linux-2.6.29.1/arch/mips/ar7/Makefile ---- linux-2.6.29.1.orig/arch/mips/ar7/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar7/Makefile 2009-05-31 19:50:05.000000000 +0200 -@@ -0,0 +1,10 @@ -+ -+obj-y := \ -+ prom.o \ -+ setup.o \ -+ memory.o \ -+ irq.o \ -+ time.o \ -+ platform.o \ -+ gpio.o \ -+ clock.o diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/memory.c linux-2.6.29.1/arch/mips/ar7/memory.c --- linux-2.6.29.1.orig/arch/mips/ar7/memory.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar7/memory.c 2009-05-31 19:50:05.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/ar7/memory.c 2009-06-05 23:38:22.900939237 +0200 @@ -0,0 +1,74 @@ +/* + * Based on arch/mips/mm/init.c @@ -819,8 +864,8 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/memory.c linux-2.6.29.1/arch/mips/ar +} diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/platform.c linux-2.6.29.1/arch/mips/ar7/platform.c --- linux-2.6.29.1.orig/arch/mips/ar7/platform.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar7/platform.c 2009-06-01 13:34:18.000000000 +0200 -@@ -0,0 +1,535 @@ ++++ linux-2.6.29.1/arch/mips/ar7/platform.c 2009-06-11 11:03:47.318484670 +0200 +@@ -0,0 +1,554 @@ +/* + * Copyright (C) 2006,2007 Felix Fietkau <nbd@openwrt.org> + * Copyright (C) 2006,2007 Eugene Konev <ejka@openwrt.org> @@ -856,6 +901,9 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/platform.c linux-2.6.29.1/arch/mips/ +#include <linux/vlynq.h> +#include <linux/leds.h> +#include <linux/string.h> ++#include <linux/phy.h> ++#include <linux/phy_fixed.h> ++ + +#include <asm/addrspace.h> +#include <asm/mach-ar7/ar7.h> @@ -1028,6 +1076,13 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/platform.c linux-2.6.29.1/arch/mips/ + .width = 2, +}; + ++/* lets assume this is suitable for both high and low cpmacs links */ ++static struct fixed_phy_status fixed_phy_status __initdata = { ++ .link = 1, ++ .speed = 100, ++ .duplex = 1, ++}; ++ +static struct plat_cpmac_data cpmac_low_data = { + .reset_bit = 17, + .power_bit = 20, @@ -1331,6 +1386,10 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/platform.c linux-2.6.29.1/arch/mips/ + } + + if (ar7_has_high_cpmac()) { ++ res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status); ++ if (res && res != -ENODEV) { ++ return res; ++ } + cpmac_get_mac(1, cpmac_high_data.dev_addr); + res = platform_device_register(&cpmac_high); + if (res) @@ -1339,6 +1398,11 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/platform.c linux-2.6.29.1/arch/mips/ + cpmac_low_data.phy_mask = 0xffffffff; + } + ++ res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status); ++ if (res && res != -ENODEV) { ++ return res; ++ } ++ + cpmac_get_mac(0, cpmac_low_data.dev_addr); + res = platform_device_register(&cpmac_low); + if (res) @@ -1358,7 +1422,7 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/platform.c linux-2.6.29.1/arch/mips/ +arch_initcall(ar7_register_devices); diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/prom.c linux-2.6.29.1/arch/mips/ar7/prom.c --- linux-2.6.29.1.orig/arch/mips/ar7/prom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar7/prom.c 2009-05-31 20:18:44.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/ar7/prom.c 2009-06-05 23:38:22.904938908 +0200 @@ -0,0 +1,321 @@ +/* + * Carsten Langgaard, carstenl@mips.com @@ -1683,7 +1747,7 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/prom.c linux-2.6.29.1/arch/mips/ar7/ +#endif diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/setup.c linux-2.6.29.1/arch/mips/ar7/setup.c --- linux-2.6.29.1.orig/arch/mips/ar7/setup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar7/setup.c 2009-06-01 12:36:33.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/ar7/setup.c 2009-06-05 23:38:22.908939139 +0200 @@ -0,0 +1,105 @@ +/* + * Carsten Langgaard, carstenl@mips.com @@ -1792,7 +1856,7 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/setup.c linux-2.6.29.1/arch/mips/ar7 +console_initcall(ar7_init_console); diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/time.c linux-2.6.29.1/arch/mips/ar7/time.c --- linux-2.6.29.1.orig/arch/mips/ar7/time.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar7/time.c 2009-06-01 12:37:00.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/ar7/time.c 2009-06-05 23:38:22.908939139 +0200 @@ -0,0 +1,28 @@ +/* + * Carsten Langgaard, carstenl@mips.com @@ -1824,7 +1888,7 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/ar7/time.c linux-2.6.29.1/arch/mips/ar7/ +} diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/ar7.h linux-2.6.29.1/arch/mips/include/asm/mach-ar7/ar7.h --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/ar7.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar7/ar7.h 2009-05-31 19:50:04.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/include/asm/mach-ar7/ar7.h 2009-06-05 23:38:22.912938811 +0200 @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2006,2007 Felix Fietkau <nbd@openwrt.org> @@ -1998,7 +2062,7 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/ar7.h linux-2.6.29. +#endif /* __AR7_H__ */ diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/gpio.h linux-2.6.29.1/arch/mips/include/asm/mach-ar7/gpio.h --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/gpio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar7/gpio.h 2009-05-31 20:26:23.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/include/asm/mach-ar7/gpio.h 2009-06-05 23:38:22.920939272 +0200 @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2007 Florian Fainelli <florian@openwrt.org> @@ -2111,7 +2175,7 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/gpio.h linux-2.6.29 +#endif diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/irq.h linux-2.6.29.1/arch/mips/include/asm/mach-ar7/irq.h --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/irq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar7/irq.h 2009-05-31 19:50:04.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/include/asm/mach-ar7/irq.h 2009-06-05 23:38:22.957186350 +0200 @@ -0,0 +1,16 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public @@ -2131,7 +2195,7 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/irq.h linux-2.6.29. +#endif /* __ASM_AR7_IRQ_H */ diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/prom.h linux-2.6.29.1/arch/mips/include/asm/mach-ar7/prom.h --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/prom.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar7/prom.h 2009-05-31 19:50:04.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/include/asm/mach-ar7/prom.h 2009-06-05 23:38:22.957186350 +0200 @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2006, 2007 Florian Fainelli <florian@openwrt.org> @@ -2161,7 +2225,7 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/prom.h linux-2.6.29 +#endif /* __PROM_H__ */ diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/spaces.h linux-2.6.29.1/arch/mips/include/asm/mach-ar7/spaces.h --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/spaces.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar7/spaces.h 2009-05-31 19:50:04.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/include/asm/mach-ar7/spaces.h 2009-06-05 23:38:22.957186350 +0200 @@ -0,0 +1,32 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public @@ -2197,7 +2261,7 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/spaces.h linux-2.6. +#endif /* __ASM_AR7_SPACES_H */ diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/war.h linux-2.6.29.1/arch/mips/include/asm/mach-ar7/war.h --- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/war.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar7/war.h 2009-05-31 19:50:04.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/include/asm/mach-ar7/war.h 2009-06-05 23:38:22.957186350 +0200 @@ -0,0 +1,25 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public @@ -2226,7 +2290,7 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar7/war.h linux-2.6.29. +#endif /* __ASM_MIPS_MACH_BCM947XX_WAR_H */ diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/page.h linux-2.6.29.1/arch/mips/include/asm/page.h --- linux-2.6.29.1.orig/arch/mips/include/asm/page.h 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/arch/mips/include/asm/page.h 2009-05-31 19:57:06.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/include/asm/page.h 2009-06-05 23:38:22.964942366 +0200 @@ -182,8 +182,11 @@ #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) @@ -2241,37 +2305,9 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/page.h linux-2.6.29.1/arch/m #include <asm-generic/memory_model.h> #include <asm-generic/page.h> -diff -Nur linux-2.6.29.1.orig/arch/mips/Kconfig linux-2.6.29.1/arch/mips/Kconfig ---- linux-2.6.29.1.orig/arch/mips/Kconfig 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/arch/mips/Kconfig 2009-05-31 19:55:40.000000000 +0200 -@@ -19,6 +19,24 @@ - prompt "System type" - default SGI_IP22 - -+config AR7 -+ bool "Texas Instruments AR7" -+ select BOOT_ELF32 -+ select DMA_NONCOHERENT -+ select CEVT_R4K -+ select CSRC_R4K -+ select IRQ_CPU -+ select NO_EXCEPT_FILL -+ select SWAP_IO_SPACE -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_HAS_EARLY_PRINTK -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_KGDB -+ select SYS_SUPPORTS_LITTLE_ENDIAN -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select GENERIC_GPIO -+ select GENERIC_HARDIRQS_NO__DO_IRQ -+ - config MACH_ALCHEMY - bool "Alchemy processor based machines" - diff -Nur linux-2.6.29.1.orig/arch/mips/kernel/traps.c linux-2.6.29.1/arch/mips/kernel/traps.c --- linux-2.6.29.1.orig/arch/mips/kernel/traps.c 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/arch/mips/kernel/traps.c 2009-05-31 23:46:49.000000000 +0200 ++++ linux-2.6.29.1/arch/mips/kernel/traps.c 2009-06-05 23:38:22.972943665 +0200 @@ -1256,9 +1256,22 @@ exception_handlers[n] = handler; @@ -2298,26 +2334,62 @@ diff -Nur linux-2.6.29.1.orig/arch/mips/kernel/traps.c linux-2.6.29.1/arch/mips/ } return (void *)old_handler; } -diff -Nur linux-2.6.29.1.orig/arch/mips/Makefile linux-2.6.29.1/arch/mips/Makefile ---- linux-2.6.29.1.orig/arch/mips/Makefile 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/arch/mips/Makefile 2009-05-31 20:01:45.000000000 +0200 -@@ -173,6 +173,13 @@ - # +diff -Nur linux-2.6.29.1.orig/drivers/Kconfig linux-2.6.29.1/drivers/Kconfig +--- linux-2.6.29.1.orig/drivers/Kconfig 2009-04-02 22:55:27.000000000 +0200 ++++ linux-2.6.29.1/drivers/Kconfig 2009-06-05 23:38:22.988945146 +0200 +@@ -104,6 +104,8 @@ - # -+# Texas Instruments AR7 -+# -+core-$(CONFIG_AR7) += arch/mips/ar7/ -+cflags-$(CONFIG_AR7) += -I$(srctree)/arch/mips/include/asm/mach-ar7 -+load-$(CONFIG_AR7) += 0xffffffff94100000 + source "drivers/uio/Kconfig" + ++source "drivers/vlynq/Kconfig" + -+# - # Acer PICA 61, Mips Magnum 4000 and Olivetti M700. - # - core-$(CONFIG_MACH_JAZZ) += arch/mips/jazz/ + source "drivers/xen/Kconfig" + + source "drivers/staging/Kconfig" +diff -Nur linux-2.6.29.1.orig/drivers/Makefile linux-2.6.29.1/drivers/Makefile +--- linux-2.6.29.1.orig/drivers/Makefile 2009-04-02 22:55:27.000000000 +0200 ++++ linux-2.6.29.1/drivers/Makefile 2009-06-05 23:38:22.988945146 +0200 +@@ -102,6 +102,7 @@ + obj-$(CONFIG_HID) += hid/ + obj-$(CONFIG_PPC_PS3) += ps3/ + obj-$(CONFIG_OF) += of/ ++obj-$(CONFIG_VLYNQ) += vlynq/ + obj-$(CONFIG_SSB) += ssb/ + obj-$(CONFIG_VIRTIO) += virtio/ + obj-$(CONFIG_STAGING) += staging/ +diff -Nur linux-2.6.29.1.orig/drivers/char/Kconfig linux-2.6.29.1/drivers/char/Kconfig +--- linux-2.6.29.1.orig/drivers/char/Kconfig 2009-04-02 22:55:27.000000000 +0200 ++++ linux-2.6.29.1/drivers/char/Kconfig 2009-06-05 23:38:22.984944077 +0200 +@@ -974,6 +974,15 @@ + To compile this driver as a module, choose M here: the + module will be called mwave. + ++config AR7_GPIO ++ tristate "TI AR7 GPIO Support" ++ depends on AR7 ++ help ++ Give userspace access to the GPIO pins on the Texas Instruments AR7 ++ processors. ++ ++ If compiled as a module, it will be called ar7_gpio. ++ + config SCx200_GPIO + tristate "NatSemi SCx200 GPIO Support" + depends on SCx200 +diff -Nur linux-2.6.29.1.orig/drivers/char/Makefile linux-2.6.29.1/drivers/char/Makefile +--- linux-2.6.29.1.orig/drivers/char/Makefile 2009-04-02 22:55:27.000000000 +0200 ++++ linux-2.6.29.1/drivers/char/Makefile 2009-06-05 23:38:22.984944077 +0200 +@@ -90,6 +90,7 @@ + obj-$(CONFIG_PPDEV) += ppdev.o + obj-$(CONFIG_NWBUTTON) += nwbutton.o + obj-$(CONFIG_NWFLASH) += nwflash.o ++obj-$(CONFIG_AR7_GPIO) += ar7_gpio.o + obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o + obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o + obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o diff -Nur linux-2.6.29.1.orig/drivers/char/ar7_gpio.c linux-2.6.29.1/drivers/char/ar7_gpio.c --- linux-2.6.29.1.orig/drivers/char/ar7_gpio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/char/ar7_gpio.c 2009-05-31 19:53:09.000000000 +0200 ++++ linux-2.6.29.1/drivers/char/ar7_gpio.c 2009-06-05 23:38:22.980943288 +0200 @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2007 Nicolas Thill <nico@openwrt.org> @@ -2477,62 +2549,9 @@ diff -Nur linux-2.6.29.1.orig/drivers/char/ar7_gpio.c linux-2.6.29.1/drivers/cha + +module_init(ar7_gpio_init); +module_exit(ar7_gpio_exit); -diff -Nur linux-2.6.29.1.orig/drivers/char/Kconfig linux-2.6.29.1/drivers/char/Kconfig ---- linux-2.6.29.1.orig/drivers/char/Kconfig 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/char/Kconfig 2009-05-31 20:03:22.000000000 +0200 -@@ -974,6 +974,15 @@ - To compile this driver as a module, choose M here: the - module will be called mwave. - -+config AR7_GPIO -+ tristate "TI AR7 GPIO Support" -+ depends on AR7 -+ help -+ Give userspace access to the GPIO pins on the Texas Instruments AR7 -+ processors. -+ -+ If compiled as a module, it will be called ar7_gpio. -+ - config SCx200_GPIO - tristate "NatSemi SCx200 GPIO Support" - depends on SCx200 -diff -Nur linux-2.6.29.1.orig/drivers/char/Makefile linux-2.6.29.1/drivers/char/Makefile ---- linux-2.6.29.1.orig/drivers/char/Makefile 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/char/Makefile 2009-05-31 20:03:22.000000000 +0200 -@@ -90,6 +90,7 @@ - obj-$(CONFIG_PPDEV) += ppdev.o - obj-$(CONFIG_NWBUTTON) += nwbutton.o - obj-$(CONFIG_NWFLASH) += nwflash.o -+obj-$(CONFIG_AR7_GPIO) += ar7_gpio.o - obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o - obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o - obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o -diff -Nur linux-2.6.29.1.orig/drivers/Kconfig linux-2.6.29.1/drivers/Kconfig ---- linux-2.6.29.1.orig/drivers/Kconfig 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/Kconfig 2009-05-31 20:03:35.000000000 +0200 -@@ -104,6 +104,8 @@ - - source "drivers/uio/Kconfig" - -+source "drivers/vlynq/Kconfig" -+ - source "drivers/xen/Kconfig" - - source "drivers/staging/Kconfig" -diff -Nur linux-2.6.29.1.orig/drivers/Makefile linux-2.6.29.1/drivers/Makefile ---- linux-2.6.29.1.orig/drivers/Makefile 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/Makefile 2009-05-31 20:03:35.000000000 +0200 -@@ -102,6 +102,7 @@ - obj-$(CONFIG_HID) += hid/ - obj-$(CONFIG_PPC_PS3) += ps3/ - obj-$(CONFIG_OF) += of/ -+obj-$(CONFIG_VLYNQ) += vlynq/ - obj-$(CONFIG_SSB) += ssb/ - obj-$(CONFIG_VIRTIO) += virtio/ - obj-$(CONFIG_STAGING) += staging/ diff -Nur linux-2.6.29.1.orig/drivers/mtd/maps/physmap.c linux-2.6.29.1/drivers/mtd/maps/physmap.c --- linux-2.6.29.1.orig/drivers/mtd/maps/physmap.c 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/mtd/maps/physmap.c 2009-05-31 20:02:55.000000000 +0200 ++++ linux-2.6.29.1/drivers/mtd/maps/physmap.c 2009-06-05 23:38:22.996945327 +0200 @@ -80,7 +80,7 @@ "map_rom", NULL }; @@ -2542,9 +2561,21 @@ diff -Nur linux-2.6.29.1.orig/drivers/mtd/maps/physmap.c linux-2.6.29.1/drivers/ #endif static int physmap_flash_probe(struct platform_device *dev) +diff -Nur linux-2.6.29.1.orig/drivers/net/Kconfig linux-2.6.29.1/drivers/net/Kconfig +--- linux-2.6.29.1.orig/drivers/net/Kconfig 2009-04-02 22:55:27.000000000 +0200 ++++ linux-2.6.29.1/drivers/net/Kconfig 2009-06-05 23:38:23.012945970 +0200 +@@ -1741,7 +1741,7 @@ + + config CPMAC + tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)" +- depends on NET_ETHERNET && EXPERIMENTAL && AR7 && BROKEN ++ depends on NET_ETHERNET && EXPERIMENTAL && AR7 + select PHYLIB + help + TI AR7 CPMAC Ethernet support diff -Nur linux-2.6.29.1.orig/drivers/net/cpmac.c linux-2.6.29.1/drivers/net/cpmac.c --- linux-2.6.29.1.orig/drivers/net/cpmac.c 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/net/cpmac.c 2009-06-01 15:23:14.000000000 +0200 ++++ linux-2.6.29.1/drivers/net/cpmac.c 2009-06-11 11:03:25.823065413 +0200 @@ -615,13 +615,13 @@ dev_kfree_skb_irq(desc->skb); @@ -2577,12 +2608,8 @@ diff -Nur linux-2.6.29.1.orig/drivers/net/cpmac.c linux-2.6.29.1/drivers/net/cpm struct cpmac_priv *priv = netdev_priv(dev); spin_lock(&priv->lock); -@@ -1093,12 +1091,10 @@ - return 0; - } +@@ -1097,15 +1095,18 @@ --static int external_switch; -- static int __devinit cpmac_probe(struct platform_device *pdev) { - int rc, phy_id, i; @@ -2592,25 +2619,53 @@ diff -Nur linux-2.6.29.1.orig/drivers/net/cpmac.c linux-2.6.29.1/drivers/net/cpm struct resource *mem; struct cpmac_priv *priv; struct net_device *dev; -@@ -1115,16 +1111,13 @@ - } + struct plat_cpmac_data *pdata; + + pdata = pdev->dev.platform_data; ++ strncpy(mdio_bus_id, "0", BUS_ID_SIZE); ++ phy_id = pdev->id; + ++ /* + for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) { + if (!(pdata->phy_mask & (1 << phy_id))) + continue; +@@ -1116,15 +1117,17 @@ if (phy_id == PHY_MAX_ADDR) { -- if (external_switch || dumb_switch) { + if (external_switch || dumb_switch) { - mdio_bus_id = 0; /* fixed phys bus */ -- phy_id = pdev->id; -- } else { ++ mdio_bus_id = 0; + phy_id = pdev->id; + } else { dev_err(&pdev->dev, "no PHY present\n"); return -ENODEV; } } ++ */ dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES); + //~ dev = alloc_etherdev(sizeof(*priv)); if (!dev) { printk(KERN_ERR "cpmac: Unable to allocate net_device\n"); -@@ -1236,17 +1229,11 @@ +@@ -1161,7 +1164,8 @@ + priv->msg_enable = netif_msg_init(debug_level, 0xff); + memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr)); + +- priv->phy = phy_connect(dev, cpmac_mii->phy_map[phy_id]->dev.bus_id, ++ snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id); ++ priv->phy = phy_connect(dev, priv->phy_name, + &cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII); + if (IS_ERR(priv->phy)) { + if (netif_msg_drv(priv)) +@@ -1230,31 +1234,34 @@ + #warning FIXME: unhardcode gpio&reset bits + ar7_gpio_disable(26); + ar7_gpio_disable(27); +- ar7_device_reset(AR7_RESET_BIT_CPMAC_LO); + ar7_device_reset(AR7_RESET_BIT_CPMAC_HI); ++ ar7_device_reset(AR7_RESET_BIT_CPMAC_LO); + ar7_device_reset(AR7_RESET_BIT_EPHY); cpmac_mii->reset(cpmac_mii); @@ -2620,1320 +2675,33 @@ diff -Nur linux-2.6.29.1.orig/drivers/net/cpmac.c linux-2.6.29.1/drivers/net/cpm break; else - cpu_relax(); -- -- mask &= 0x7fffffff; ++ msleep(10); + + mask &= 0x7fffffff; - if (mask & (mask - 1)) { -- external_switch = 1; -- mask = 0; ++ ++ //if (mask & (mask - 1)) { + external_switch = 1; + mask = 0; - } -+ msleep(10); ++ //} ++ /* cpmac_mii->phy_mask = ~(mask | 0x80000000); - snprintf(cpmac_mii->id, MII_BUS_ID_SIZE, "0"); -diff -Nur linux-2.6.29.1.orig/drivers/net/cpmac.c.orig linux-2.6.29.1/drivers/net/cpmac.c.orig ---- linux-2.6.29.1.orig/drivers/net/cpmac.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/net/cpmac.c.orig 2009-06-01 14:37:40.000000000 +0200 -@@ -0,0 +1,1285 @@ -+/* -+ * Copyright (C) 2006, 2007 Eugene Konev -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/moduleparam.h> -+ -+#include <linux/sched.h> -+#include <linux/kernel.h> -+#include <linux/slab.h> -+#include <linux/errno.h> -+#include <linux/types.h> -+#include <linux/delay.h> -+ -+#include <linux/netdevice.h> -+#include <linux/etherdevice.h> -+#include <linux/ethtool.h> -+#include <linux/skbuff.h> -+#include <linux/mii.h> -+#include <linux/phy.h> -+#include <linux/phy_fixed.h> -+#include <linux/platform_device.h> -+#include <linux/dma-mapping.h> -+#include <asm/gpio.h> -+#include <asm/atomic.h> -+ -+MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>"); -+MODULE_DESCRIPTION("TI AR7 ethernet driver (CPMAC)"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:cpmac"); -+ -+static int debug_level = 8; -+static int dumb_switch; -+ -+/* Next 2 are only used in cpmac_probe, so it's pointless to change them */ -+module_param(debug_level, int, 0444); -+module_param(dumb_switch, int, 0444); -+ -+MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable"); -+MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus"); -+ -+#define CPMAC_VERSION "0.5.0" -+/* frame size + 802.1q tag */ -+#define CPMAC_SKB_SIZE (ETH_FRAME_LEN + 4) -+#define CPMAC_QUEUES 8 -+ -+/* Ethernet registers */ -+#define CPMAC_TX_CONTROL 0x0004 -+#define CPMAC_TX_TEARDOWN 0x0008 -+#define CPMAC_RX_CONTROL 0x0014 -+#define CPMAC_RX_TEARDOWN 0x0018 -+#define CPMAC_MBP 0x0100 -+# define MBP_RXPASSCRC 0x40000000 -+# define MBP_RXQOS 0x20000000 -+# define MBP_RXNOCHAIN 0x10000000 -+# define MBP_RXCMF 0x01000000 -+# define MBP_RXSHORT 0x00800000 -+# define MBP_RXCEF 0x00400000 -+# define MBP_RXPROMISC 0x00200000 -+# define MBP_PROMISCCHAN(channel) (((channel) & 0x7) << 16) -+# define MBP_RXBCAST 0x00002000 -+# define MBP_BCASTCHAN(channel) (((channel) & 0x7) << 8) -+# define MBP_RXMCAST 0x00000020 -+# define MBP_MCASTCHAN(channel) ((channel) & 0x7) -+#define CPMAC_UNICAST_ENABLE 0x0104 -+#define CPMAC_UNICAST_CLEAR 0x0108 -+#define CPMAC_MAX_LENGTH 0x010c -+#define CPMAC_BUFFER_OFFSET 0x0110 -+#define CPMAC_MAC_CONTROL 0x0160 -+# define MAC_TXPTYPE 0x00000200 -+# define MAC_TXPACE 0x00000040 -+# define MAC_MII 0x00000020 -+# define MAC_TXFLOW 0x00000010 -+# define MAC_RXFLOW 0x00000008 -+# define MAC_MTEST 0x00000004 -+# define MAC_LOOPBACK 0x00000002 -+# define MAC_FDX 0x00000001 -+#define CPMAC_MAC_STATUS 0x0164 -+# define MAC_STATUS_QOS 0x00000004 -+# define MAC_STATUS_RXFLOW 0x00000002 -+# define MAC_STATUS_TXFLOW 0x00000001 -+#define CPMAC_TX_INT_ENABLE 0x0178 -+#define CPMAC_TX_INT_CLEAR 0x017c -+#define CPMAC_MAC_INT_VECTOR 0x0180 -+# define MAC_INT_STATUS 0x00080000 -+# define MAC_INT_HOST 0x00040000 -+# define MAC_INT_RX 0x00020000 -+# define MAC_INT_TX 0x00010000 -+#define CPMAC_MAC_EOI_VECTOR 0x0184 -+#define CPMAC_RX_INT_ENABLE 0x0198 -+#define CPMAC_RX_INT_CLEAR 0x019c -+#define CPMAC_MAC_INT_ENABLE 0x01a8 -+#define CPMAC_MAC_INT_CLEAR 0x01ac -+#define CPMAC_MAC_ADDR_LO(channel) (0x01b0 + (channel) * 4) -+#define CPMAC_MAC_ADDR_MID 0x01d0 -+#define CPMAC_MAC_ADDR_HI 0x01d4 -+#define CPMAC_MAC_HASH_LO 0x01d8 -+#define CPMAC_MAC_HASH_HI 0x01dc -+#define CPMAC_TX_PTR(channel) (0x0600 + (channel) * 4) -+#define CPMAC_RX_PTR(channel) (0x0620 + (channel) * 4) -+#define CPMAC_TX_ACK(channel) (0x0640 + (channel) * 4) -+#define CPMAC_RX_ACK(channel) (0x0660 + (channel) * 4) -+#define CPMAC_REG_END 0x0680 -+/* -+ * Rx/Tx statistics -+ * TODO: use some of them to fill stats in cpmac_stats() -+ */ -+#define CPMAC_STATS_RX_GOOD 0x0200 -+#define CPMAC_STATS_RX_BCAST 0x0204 -+#define CPMAC_STATS_RX_MCAST 0x0208 -+#define CPMAC_STATS_RX_PAUSE 0x020c -+#define CPMAC_STATS_RX_CRC 0x0210 -+#define CPMAC_STATS_RX_ALIGN 0x0214 -+#define CPMAC_STATS_RX_OVER 0x0218 -+#define CPMAC_STATS_RX_JABBER 0x021c -+#define CPMAC_STATS_RX_UNDER 0x0220 -+#define CPMAC_STATS_RX_FRAG 0x0224 -+#define CPMAC_STATS_RX_FILTER 0x0228 -+#define CPMAC_STATS_RX_QOSFILTER 0x022c -+#define CPMAC_STATS_RX_OCTETS 0x0230 -+ -+#define CPMAC_STATS_TX_GOOD 0x0234 -+#define CPMAC_STATS_TX_BCAST 0x0238 -+#define CPMAC_STATS_TX_MCAST 0x023c -+#define CPMAC_STATS_TX_PAUSE 0x0240 -+#define CPMAC_STATS_TX_DEFER 0x0244 -+#define CPMAC_STATS_TX_COLLISION 0x0248 -+#define CPMAC_STATS_TX_SINGLECOLL 0x024c -+#define CPMAC_STATS_TX_MULTICOLL 0x0250 -+#define CPMAC_STATS_TX_EXCESSCOLL 0x0254 -+#define CPMAC_STATS_TX_LATECOLL 0x0258 -+#define CPMAC_STATS_TX_UNDERRUN 0x025c -+#define CPMAC_STATS_TX_CARRIERSENSE 0x0260 -+#define CPMAC_STATS_TX_OCTETS 0x0264 -+ -+#define cpmac_read(base, reg) (readl((void __iomem *)(base) + (reg))) -+#define cpmac_write(base, reg, val) (writel(val, (void __iomem *)(base) + \ -+ (reg))) -+ -+/* MDIO bus */ -+#define CPMAC_MDIO_VERSION 0x0000 -+#define CPMAC_MDIO_CONTROL 0x0004 -+# define MDIOC_IDLE 0x80000000 -+# define MDIOC_ENABLE 0x40000000 -+# define MDIOC_PREAMBLE 0x00100000 -+# define MDIOC_FAULT 0x00080000 -+# define MDIOC_FAULTDETECT 0x00040000 -+# define MDIOC_INTTEST 0x00020000 -+# define MDIOC_CLKDIV(div) ((div) & 0xff) -+#define CPMAC_MDIO_ALIVE 0x0008 -+#define CPMAC_MDIO_LINK 0x000c -+#define CPMAC_MDIO_ACCESS(channel) (0x0080 + (channel) * 8) -+# define MDIO_BUSY 0x80000000 -+# define MDIO_WRITE 0x40000000 -+# define MDIO_REG(reg) (((reg) & 0x1f) << 21) -+# define MDIO_PHY(phy) (((phy) & 0x1f) << 16) -+# define MDIO_DATA(data) ((data) & 0xffff) -+#define CPMAC_MDIO_PHYSEL(channel) (0x0084 + (channel) * 8) -+# define PHYSEL_LINKSEL 0x00000040 -+# define PHYSEL_LINKINT 0x00000020 -+ -+struct cpmac_desc { -+ u32 hw_next; -+ u32 hw_data; -+ u16 buflen; -+ u16 bufflags; -+ u16 datalen; -+ u16 dataflags; -+#define CPMAC_SOP 0x8000 -+#define CPMAC_EOP 0x4000 -+#define CPMAC_OWN 0x2000 -+#define CPMAC_EOQ 0x1000 -+ struct sk_buff *skb; -+ struct cpmac_desc *next; -+ struct cpmac_desc *prev; -+ dma_addr_t mapping; -+ dma_addr_t data_mapping; -+}; -+ -+struct cpmac_priv { -+ spinlock_t lock; -+ spinlock_t rx_lock; -+ struct cpmac_desc *rx_head; -+ int ring_size; -+ struct cpmac_desc *desc_ring; -+ dma_addr_t dma_ring; -+ void __iomem *regs; -+ struct mii_bus *mii_bus; -+ struct phy_device *phy; -+ char phy_name[BUS_ID_SIZE]; -+ int oldlink, oldspeed, oldduplex; -+ u32 msg_enable; -+ struct net_device *dev; -+ struct work_struct reset_work; -+ struct platform_device *pdev; -+ struct napi_struct napi; -+ atomic_t reset_pending; -+}; -+ -+static irqreturn_t cpmac_irq(int, void *); -+static void cpmac_hw_start(struct net_device *dev); -+static void cpmac_hw_stop(struct net_device *dev); -+static int cpmac_stop(struct net_device *dev); -+static int cpmac_open(struct net_device *dev); -+ -+static void cpmac_dump_regs(struct net_device *dev) -+{ -+ int i; -+ struct cpmac_priv *priv = netdev_priv(dev); -+ for (i = 0; i < CPMAC_REG_END; i += 4) { -+ if (i % 16 == 0) { -+ if (i) -+ printk("\n"); -+ printk(KERN_DEBUG "%s: reg[%p]:", dev->name, -+ priv->regs + i); -+ } -+ printk(" %08x", cpmac_read(priv->regs, i)); -+ } -+ printk("\n"); -+} -+ -+static void cpmac_dump_desc(struct net_device *dev, struct cpmac_desc *desc) -+{ -+ int i; -+ printk(KERN_DEBUG "%s: desc[%p]:", dev->name, desc); -+ for (i = 0; i < sizeof(*desc) / 4; i++) -+ printk(" %08x", ((u32 *)desc)[i]); -+ printk("\n"); -+} -+ -+static void cpmac_dump_all_desc(struct net_device *dev) -+{ -+ struct cpmac_priv *priv = netdev_priv(dev); -+ struct cpmac_desc *dump = priv->rx_head; -+ do { -+ cpmac_dump_desc(dev, dump); -+ dump = dump->next; -+ } while (dump != priv->rx_head); -+} -+ -+static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb) -+{ -+ int i; -+ printk(KERN_DEBUG "%s: skb 0x%p, len=%d\n", dev->name, skb, skb->len); -+ for (i = 0; i < skb->len; i++) { -+ if (i % 16 == 0) { -+ if (i) -+ printk("\n"); -+ printk(KERN_DEBUG "%s: data[%p]:", dev->name, -+ skb->data + i); -+ } -+ printk(" %02x", ((u8 *)skb->data)[i]); -+ } -+ printk("\n"); -+} -+ -+static int cpmac_mdio_read(struct mii_bus *bus, int phy_id, int reg) -+{ -+ u32 val; -+ -+ while (cpmac_read(bus->priv, CPMAC_MDIO_ACCESS(0)) & MDIO_BUSY) -+ cpu_relax(); -+ cpmac_write(bus->priv, CPMAC_MDIO_ACCESS(0), MDIO_BUSY | MDIO_REG(reg) | -+ MDIO_PHY(phy_id)); -+ while ((val = cpmac_read(bus->priv, CPMAC_MDIO_ACCESS(0))) & MDIO_BUSY) -+ cpu_relax(); -+ return MDIO_DATA(val); -+} -+ -+static int cpmac_mdio_write(struct mii_bus *bus, int phy_id, -+ int reg, u16 val) -+{ -+ while (cpmac_read(bus->priv, CPMAC_MDIO_ACCESS(0)) & MDIO_BUSY) -+ cpu_relax(); -+ cpmac_write(bus->priv, CPMAC_MDIO_ACCESS(0), MDIO_BUSY | MDIO_WRITE | -+ MDIO_REG(reg) | MDIO_PHY(phy_id) | MDIO_DATA(val)); -+ return 0; -+} -+ -+static int cpmac_mdio_reset(struct mii_bus *bus) -+{ -+ ar7_device_reset(AR7_RESET_BIT_MDIO); -+ cpmac_write(bus->priv, CPMAC_MDIO_CONTROL, MDIOC_ENABLE | -+ MDIOC_CLKDIV(ar7_cpmac_freq() / 2200000 - 1)); -+ return 0; -+} -+ -+static int mii_irqs[PHY_MAX_ADDR] = { PHY_POLL, }; -+ -+static struct mii_bus *cpmac_mii; -+ -+static int cpmac_config(struct net_device *dev, struct ifmap *map) -+{ -+ if (dev->flags & IFF_UP) -+ return -EBUSY; -+ -+ /* Don't allow changing the I/O address */ -+ if (map->base_addr != dev->base_addr) -+ return -EOPNOTSUPP; -+ -+ /* ignore other fields */ -+ return 0; -+} -+ -+static void cpmac_set_multicast_list(struct net_device *dev) -+{ -+ struct dev_mc_list *iter; -+ int i; -+ u8 tmp; -+ u32 mbp, bit, hash[2] = { 0, }; -+ struct cpmac_priv *priv = netdev_priv(dev); -+ -+ mbp = cpmac_read(priv->regs, CPMAC_MBP); -+ if (dev->flags & IFF_PROMISC) { -+ cpmac_write(priv->regs, CPMAC_MBP, (mbp & ~MBP_PROMISCCHAN(0)) | -+ MBP_RXPROMISC); -+ } else { -+ cpmac_write(priv->regs, CPMAC_MBP, mbp & ~MBP_RXPROMISC); -+ if (dev->flags & IFF_ALLMULTI) { -+ /* enable all multicast mode */ -+ cpmac_write(priv->regs, CPMAC_MAC_HASH_LO, 0xffffffff); -+ cpmac_write(priv->regs, CPMAC_MAC_HASH_HI, 0xffffffff); -+ } else { -+ /* -+ * cpmac uses some strange mac address hashing -+ * (not crc32) -+ */ -+ for (i = 0, iter = dev->mc_list; i < dev->mc_count; -+ i++, iter = iter->next) { -+ bit = 0; -+ tmp = iter->dmi_addr[0]; -+ bit ^= (tmp >> 2) ^ (tmp << 4); -+ tmp = iter->dmi_addr[1]; -+ bit ^= (tmp >> 4) ^ (tmp << 2); -+ tmp = iter->dmi_addr[2]; -+ bit ^= (tmp >> 6) ^ tmp; -+ tmp = iter->dmi_addr[3]; -+ bit ^= (tmp >> 2) ^ (tmp << 4); -+ tmp = iter->dmi_addr[4]; -+ bit ^= (tmp >> 4) ^ (tmp << 2); -+ tmp = iter->dmi_addr[5]; -+ bit ^= (tmp >> 6) ^ tmp; -+ bit &= 0x3f; -+ hash[bit / 32] |= 1 << (bit % 32); -+ } -+ -+ cpmac_write(priv->regs, CPMAC_MAC_HASH_LO, hash[0]); -+ cpmac_write(priv->regs, CPMAC_MAC_HASH_HI, hash[1]); -+ } -+ } -+} -+ -+static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv, -+ struct cpmac_desc *desc) -+{ -+ struct sk_buff *skb, *result = NULL; -+ -+ if (unlikely(netif_msg_hw(priv))) -+ cpmac_dump_desc(priv->dev, desc); -+ cpmac_write(priv->regs, CPMAC_RX_ACK(0), (u32)desc->mapping); -+ if (unlikely(!desc->datalen)) { -+ if (netif_msg_rx_err(priv) && net_ratelimit()) -+ printk(KERN_WARNING "%s: rx: spurious interrupt\n", -+ priv->dev->name); -+ return NULL; -+ } -+ -+ skb = netdev_alloc_skb(priv->dev, CPMAC_SKB_SIZE); -+ if (likely(skb)) { -+ skb_reserve(skb, 2); -+ skb_put(desc->skb, desc->datalen); -+ desc->skb->protocol = eth_type_trans(desc->skb, priv->dev); -+ desc->skb->ip_summed = CHECKSUM_NONE; -+ priv->dev->stats.rx_packets++; -+ priv->dev->stats.rx_bytes += desc->datalen; -+ result = desc->skb; -+ dma_unmap_single(&priv->dev->dev, desc->data_mapping, -+ CPMAC_SKB_SIZE, DMA_FROM_DEVICE); -+ desc->skb = skb; -+ desc->data_mapping = dma_map_single(&priv->dev->dev, skb->data, -+ CPMAC_SKB_SIZE, -+ DMA_FROM_DEVICE); -+ desc->hw_data = (u32)desc->data_mapping; -+ if (unlikely(netif_msg_pktdata(priv))) { -+ printk(KERN_DEBUG "%s: received packet:\n", -+ priv->dev->name); -+ cpmac_dump_skb(priv->dev, result); -+ } -+ } else { -+ if (netif_msg_rx_err(priv) && net_ratelimit()) -+ printk(KERN_WARNING -+ "%s: low on skbs, dropping packet\n", -+ priv->dev->name); -+ priv->dev->stats.rx_dropped++; -+ } -+ -+ desc->buflen = CPMAC_SKB_SIZE; -+ desc->dataflags = CPMAC_OWN; -+ -+ return result; -+} -+ -+static int cpmac_poll(struct napi_struct *napi, int budget) -+{ -+ struct sk_buff *skb; -+ struct cpmac_desc *desc, *restart; -+ struct cpmac_priv *priv = container_of(napi, struct cpmac_priv, napi); -+ int received = 0, processed = 0; -+ -+ spin_lock(&priv->rx_lock); -+ if (unlikely(!priv->rx_head)) { -+ if (netif_msg_rx_err(priv) && net_ratelimit()) -+ printk(KERN_WARNING "%s: rx: polling, but no queue\n", -+ priv->dev->name); -+ spin_unlock(&priv->rx_lock); -+ netif_rx_complete(napi); -+ return 0; -+ } -+ -+ desc = priv->rx_head; -+ restart = NULL; -+ while (((desc->dataflags & CPMAC_OWN) == 0) && (received < budget)) { -+ processed++; -+ -+ if ((desc->dataflags & CPMAC_EOQ) != 0) { -+ /* The last update to eoq->hw_next didn't happen -+ * soon enough, and the receiver stopped here. -+ *Remember this descriptor so we can restart -+ * the receiver after freeing some space. -+ */ -+ if (unlikely(restart)) { -+ if (netif_msg_rx_err(priv)) -+ printk(KERN_ERR "%s: poll found a" -+ " duplicate EOQ: %p and %p\n", -+ priv->dev->name, restart, desc); -+ goto fatal_error; -+ } -+ -+ restart = desc->next; -+ } -+ -+ skb = cpmac_rx_one(priv, desc); -+ if (likely(skb)) { -+ netif_receive_skb(skb); -+ received++; -+ } -+ desc = desc->next; -+ } -+ -+ if (desc != priv->rx_head) { -+ /* We freed some buffers, but not the whole ring, -+ * add what we did free to the rx list */ -+ desc->prev->hw_next = (u32)0; -+ priv->rx_head->prev->hw_next = priv->rx_head->mapping; -+ } -+ -+ /* Optimization: If we did not actually process an EOQ (perhaps because -+ * of quota limits), check to see if the tail of the queue has EOQ set. -+ * We should immediately restart in that case so that the receiver can -+ * restart and run in parallel with more packet processing. -+ * This lets us handle slightly larger bursts before running -+ * out of ring space (assuming dev->weight < ring_size) */ -+ -+ if (!restart && -+ (priv->rx_head->prev->dataflags & (CPMAC_OWN|CPMAC_EOQ)) -+ == CPMAC_EOQ && -+ (priv->rx_head->dataflags & CPMAC_OWN) != 0) { -+ /* reset EOQ so the poll loop (above) doesn't try to -+ * restart this when it eventually gets to this descriptor. -+ */ -+ priv->rx_head->prev->dataflags &= ~CPMAC_EOQ; -+ restart = priv->rx_head; -+ } -+ -+ if (restart) { -+ priv->dev->stats.rx_errors++; -+ priv->dev->stats.rx_fifo_errors++; -+ if (netif_msg_rx_err(priv) && net_ratelimit()) -+ printk(KERN_WARNING "%s: rx dma ring overrun\n", -+ priv->dev->name); -+ -+ if (unlikely((restart->dataflags & CPMAC_OWN) == 0)) { -+ if (netif_msg_drv(priv)) -+ printk(KERN_ERR "%s: cpmac_poll is trying to " -+ "restart rx from a descriptor that's " -+ "not free: %p\n", -+ priv->dev->name, restart); -+ goto fatal_error; -+ } -+ -+ cpmac_write(priv->regs, CPMAC_RX_PTR(0), restart->mapping); -+ } -+ -+ priv->rx_head = desc; -+ spin_unlock(&priv->rx_lock); -+ if (unlikely(netif_msg_rx_status(priv))) -+ printk(KERN_DEBUG "%s: poll processed %d packets\n", -+ priv->dev->name, received); -+ if (processed == 0) { -+ /* we ran out of packets to read, -+ * revert to interrupt-driven mode */ -+ netif_rx_complete(napi); -+ cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1); -+ return 0; -+ } -+ -+ return 1; -+ -+fatal_error: -+ /* Something went horribly wrong. -+ * Reset hardware to try to recover rather than wedging. */ -+ -+ if (netif_msg_drv(priv)) { -+ printk(KERN_ERR "%s: cpmac_poll is confused. " -+ "Resetting hardware\n", priv->dev->name); -+ cpmac_dump_all_desc(priv->dev); -+ printk(KERN_DEBUG "%s: RX_PTR(0)=0x%08x RX_ACK(0)=0x%08x\n", -+ priv->dev->name, -+ cpmac_read(priv->regs, CPMAC_RX_PTR(0)), -+ cpmac_read(priv->regs, CPMAC_RX_ACK(0))); -+ } -+ -+ spin_unlock(&priv->rx_lock); -+ netif_rx_complete(napi); -+ netif_tx_stop_all_queues(priv->dev); -+ napi_disable(&priv->napi); -+ -+ atomic_inc(&priv->reset_pending); -+ cpmac_hw_stop(priv->dev); -+ if (!schedule_work(&priv->reset_work)) -+ atomic_dec(&priv->reset_pending); -+ return 0; -+ -+} -+ -+static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ int queue, len; -+ struct cpmac_desc *desc; -+ struct cpmac_priv *priv = netdev_priv(dev); -+ -+ if (unlikely(atomic_read(&priv->reset_pending))) -+ return NETDEV_TX_BUSY; -+ -+ if (unlikely(skb_padto(skb, ETH_ZLEN))) -+ return NETDEV_TX_OK; -+ -+ len = max(skb->len, ETH_ZLEN); -+ queue = skb_get_queue_mapping(skb); -+ netif_stop_subqueue(dev, queue); -+ -+ desc = &priv->desc_ring[queue]; -+ if (unlikely(desc->dataflags & CPMAC_OWN)) { -+ if (netif_msg_tx_err(priv) && net_ratelimit()) -+ printk(KERN_WARNING "%s: tx dma ring full\n", -+ dev->name); -+ return NETDEV_TX_BUSY; -+ } -+ -+ spin_lock(&priv->lock); -+ dev->trans_start = jiffies; -+ spin_unlock(&priv->lock); -+ desc->dataflags = CPMAC_SOP | CPMAC_EOP | CPMAC_OWN; -+ desc->skb = skb; -+ desc->data_mapping = dma_map_single(&dev->dev, skb->data, len, -+ DMA_TO_DEVICE); -+ desc->hw_data = (u32)desc->data_mapping; -+ desc->datalen = len; -+ desc->buflen = len; -+ if (unlikely(netif_msg_tx_queued(priv))) -+ printk(KERN_DEBUG "%s: sending 0x%p, len=%d\n", dev->name, skb, -+ skb->len); -+ if (unlikely(netif_msg_hw(priv))) -+ cpmac_dump_desc(dev, desc); -+ if (unlikely(netif_msg_pktdata(priv))) -+ cpmac_dump_skb(dev, skb); -+ cpmac_write(priv->regs, CPMAC_TX_PTR(queue), (u32)desc->mapping); -+ -+ return NETDEV_TX_OK; -+} -+ -+static void cpmac_end_xmit(struct net_device *dev, int queue) -+{ -+ struct cpmac_desc *desc; -+ struct cpmac_priv *priv = netdev_priv(dev); -+ -+ desc = &priv->desc_ring[queue]; -+ cpmac_write(priv->regs, CPMAC_TX_ACK(queue), (u32)desc->mapping); -+ if (likely(desc->skb)) { -+ spin_lock(&priv->lock); -+ dev->stats.tx_packets++; -+ dev->stats.tx_bytes += desc->skb->len; -+ spin_unlock(&priv->lock); -+ dma_unmap_single(&dev->dev, desc->data_mapping, desc->skb->len, -+ DMA_TO_DEVICE); -+ -+ if (unlikely(netif_msg_tx_done(priv))) -+ printk(KERN_DEBUG "%s: sent 0x%p, len=%d\n", dev->name, -+ desc->skb, desc->skb->len); -+ -+ dev_kfree_skb_irq(desc->skb); -+ desc->skb = NULL; -+ if (netif_subqueue_stopped(dev, queue)) -+ netif_wake_subqueue(dev, queue); -+ } else { -+ if (netif_msg_tx_err(priv) && net_ratelimit()) -+ printk(KERN_WARNING -+ "%s: end_xmit: spurious interrupt\n", dev->name); -+ if (netif_subqueue_stopped(dev, queue)) -+ netif_wake_subqueue(dev, queue); -+ } -+} -+ -+static void cpmac_hw_stop(struct net_device *dev) -+{ -+ int i; -+ struct cpmac_priv *priv = netdev_priv(dev); -+ struct plat_cpmac_data *pdata = priv->pdev->dev.platform_data; -+ -+ ar7_device_reset(pdata->reset_bit); -+ cpmac_write(priv->regs, CPMAC_RX_CONTROL, -+ cpmac_read(priv->regs, CPMAC_RX_CONTROL) & ~1); -+ cpmac_write(priv->regs, CPMAC_TX_CONTROL, -+ cpmac_read(priv->regs, CPMAC_TX_CONTROL) & ~1); -+ for (i = 0; i < 8; i++) { -+ cpmac_write(priv->regs, CPMAC_TX_PTR(i), 0); -+ cpmac_write(priv->regs, CPMAC_RX_PTR(i), 0); -+ } -+ cpmac_write(priv->regs, CPMAC_UNICAST_CLEAR, 0xff); -+ cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 0xff); -+ cpmac_write(priv->regs, CPMAC_TX_INT_CLEAR, 0xff); -+ cpmac_write(priv->regs, CPMAC_MAC_INT_CLEAR, 0xff); -+ cpmac_write(priv->regs, CPMAC_MAC_CONTROL, -+ cpmac_read(priv->regs, CPMAC_MAC_CONTROL) & ~MAC_MII); -+} -+ -+static void cpmac_hw_start(struct net_device *dev) -+{ -+ int i; -+ struct cpmac_priv *priv = netdev_priv(dev); -+ struct plat_cpmac_data *pdata = priv->pdev->dev.platform_data; -+ -+ ar7_device_reset(pdata->reset_bit); -+ for (i = 0; i < 8; i++) { -+ cpmac_write(priv->regs, CPMAC_TX_PTR(i), 0); -+ cpmac_write(priv->regs, CPMAC_RX_PTR(i), 0); -+ } -+ cpmac_write(priv->regs, CPMAC_RX_PTR(0), priv->rx_head->mapping); -+ -+ cpmac_write(priv->regs, CPMAC_MBP, MBP_RXSHORT | MBP_RXBCAST | -+ MBP_RXMCAST); -+ cpmac_write(priv->regs, CPMAC_BUFFER_OFFSET, 0); -+ for (i = 0; i < 8; i++) -+ cpmac_write(priv->regs, CPMAC_MAC_ADDR_LO(i), dev->dev_addr[5]); -+ cpmac_write(priv->regs, CPMAC_MAC_ADDR_MID, dev->dev_addr[4]); -+ cpmac_write(priv->regs, CPMAC_MAC_ADDR_HI, dev->dev_addr[0] | -+ (dev->dev_addr[1] << 8) | (dev->dev_addr[2] << 16) | -+ (dev->dev_addr[3] << 24)); -+ cpmac_write(priv->regs, CPMAC_MAX_LENGTH, CPMAC_SKB_SIZE); -+ cpmac_write(priv->regs, CPMAC_UNICAST_CLEAR, 0xff); -+ cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 0xff); -+ cpmac_write(priv->regs, CPMAC_TX_INT_CLEAR, 0xff); -+ cpmac_write(priv->regs, CPMAC_MAC_INT_CLEAR, 0xff); -+ cpmac_write(priv->regs, CPMAC_UNICAST_ENABLE, 1); -+ cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1); -+ cpmac_write(priv->regs, CPMAC_TX_INT_ENABLE, 0xff); -+ cpmac_write(priv->regs, CPMAC_MAC_INT_ENABLE, 3); -+ -+ cpmac_write(priv->regs, CPMAC_RX_CONTROL, -+ cpmac_read(priv->regs, CPMAC_RX_CONTROL) | 1); -+ cpmac_write(priv->regs, CPMAC_TX_CONTROL, -+ cpmac_read(priv->regs, CPMAC_TX_CONTROL) | 1); -+ cpmac_write(priv->regs, CPMAC_MAC_CONTROL, -+ cpmac_read(priv->regs, CPMAC_MAC_CONTROL) | MAC_MII | -+ MAC_FDX); -+} -+ -+static void cpmac_clear_rx(struct net_device *dev) -+{ -+ struct cpmac_priv *priv = netdev_priv(dev); -+ struct cpmac_desc *desc; -+ int i; -+ if (unlikely(!priv->rx_head)) -+ return; -+ desc = priv->rx_head; -+ for (i = 0; i < priv->ring_size; i++) { -+ if ((desc->dataflags & CPMAC_OWN) == 0) { -+ if (netif_msg_rx_err(priv) && net_ratelimit()) -+ printk(KERN_WARNING "%s: packet dropped\n", -+ dev->name); -+ if (unlikely(netif_msg_hw(priv))) -+ cpmac_dump_desc(dev, desc); -+ desc->dataflags = CPMAC_OWN; -+ dev->stats.rx_dropped++; -+ } -+ desc->hw_next = desc->next->mapping; -+ desc = desc->next; -+ } -+ priv->rx_head->prev->hw_next = 0; -+} -+ -+static void cpmac_clear_tx(struct net_device *dev) -+{ -+ struct cpmac_priv *priv = netdev_priv(dev); -+ int i; -+ if (unlikely(!priv->desc_ring)) -+ return; -+ for (i = 0; i < CPMAC_QUEUES; i++) { -+ priv->desc_ring[i].dataflags = 0; -+ if (priv->desc_ring[i].skb) { -+ dev_kfree_skb_any(priv->desc_ring[i].skb); -+ priv->desc_ring[i].skb = NULL; -+ } -+ } -+} -+ -+static void cpmac_hw_error(struct work_struct *work) -+{ -+ int i; -+ struct cpmac_priv *priv = -+ container_of(work, struct cpmac_priv, reset_work); -+ -+ spin_lock(&priv->rx_lock); -+ cpmac_clear_rx(priv->dev); -+ spin_unlock(&priv->rx_lock); -+ cpmac_clear_tx(priv->dev); -+ cpmac_hw_start(priv->dev); -+ barrier(); -+ atomic_dec(&priv->reset_pending); -+ -+ netif_tx_wake_all_queues(priv->dev); -+ cpmac_write(priv->regs, CPMAC_MAC_INT_ENABLE, 3); -+} -+ -+static void cpmac_check_status(struct net_device *dev) -+{ -+ struct cpmac_priv *priv = netdev_priv(dev); -+ -+ u32 macstatus = cpmac_read(priv->regs, CPMAC_MAC_STATUS); -+ int rx_channel = (macstatus >> 8) & 7; -+ int rx_code = (macstatus >> 12) & 15; -+ int tx_channel = (macstatus >> 16) & 7; -+ int tx_code = (macstatus >> 20) & 15; -+ -+ if (rx_code || tx_code) { -+ if (netif_msg_drv(priv) && net_ratelimit()) { -+ /* Can't find any documentation on what these -+ *error codes actually are. So just log them and hope.. -+ */ -+ if (rx_code) -+ printk(KERN_WARNING "%s: host error %d on rx " -+ "channel %d (macstatus %08x), resetting\n", -+ dev->name, rx_code, rx_channel, macstatus); -+ if (tx_code) -+ printk(KERN_WARNING "%s: host error %d on tx " -+ "channel %d (macstatus %08x), resetting\n", -+ dev->name, tx_code, tx_channel, macstatus); -+ } -+ -+ netif_tx_stop_all_queues(dev); -+ cpmac_hw_stop(dev); -+ if (schedule_work(&priv->reset_work)) -+ atomic_inc(&priv->reset_pending); -+ if (unlikely(netif_msg_hw(priv))) -+ cpmac_dump_regs(dev); -+ } -+ cpmac_write(priv->regs, CPMAC_MAC_INT_CLEAR, 0xff); -+} -+ -+static irqreturn_t cpmac_irq(int irq, void *dev_id) -+{ -+ struct net_device *dev = dev_id; -+ struct cpmac_priv *priv; -+ int queue; -+ u32 status; -+ -+ priv = netdev_priv(dev); -+ -+ status = cpmac_read(priv->regs, CPMAC_MAC_INT_VECTOR); -+ -+ if (unlikely(netif_msg_intr(priv))) -+ printk(KERN_DEBUG "%s: interrupt status: 0x%08x\n", dev->name, -+ status); -+ -+ if (status & MAC_INT_TX) -+ cpmac_end_xmit(dev, (status & 7)); -+ -+ if (status & MAC_INT_RX) { -+ queue = (status >> 8) & 7; -+ if (netif_rx_schedule_prep(&priv->napi)) { -+ cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 1 << queue); -+ __netif_rx_schedule(&priv->napi); -+ } -+ } -+ -+ cpmac_write(priv->regs, CPMAC_MAC_EOI_VECTOR, 0); -+ -+ if (unlikely(status & (MAC_INT_HOST | MAC_INT_STATUS))) -+ cpmac_check_status(dev); -+ -+ return IRQ_HANDLED; -+} -+ -+static void cpmac_tx_timeout(struct net_device *dev) -+{ -+ int i; -+ struct cpmac_priv *priv = netdev_priv(dev); -+ -+ spin_lock(&priv->lock); -+ dev->stats.tx_errors++; -+ spin_unlock(&priv->lock); -+ if (netif_msg_tx_err(priv) && net_ratelimit()) -+ printk(KERN_WARNING "%s: transmit timeout\n", dev->name); -+ -+ atomic_inc(&priv->reset_pending); -+ barrier(); -+ cpmac_clear_tx(dev); -+ barrier(); -+ atomic_dec(&priv->reset_pending); -+ -+ netif_tx_wake_all_queues(priv->dev); -+} -+ -+static int cpmac_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -+{ -+ struct cpmac_priv *priv = netdev_priv(dev); -+ if (!(netif_running(dev))) -+ return -EINVAL; -+ if (!priv->phy) -+ return -EINVAL; -+ if ((cmd == SIOCGMIIPHY) || (cmd == SIOCGMIIREG) || -+ (cmd == SIOCSMIIREG)) -+ return phy_mii_ioctl(priv->phy, if_mii(ifr), cmd); -+ -+ return -EOPNOTSUPP; -+} -+ -+static int cpmac_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -+{ -+ struct cpmac_priv *priv = netdev_priv(dev); -+ -+ if (priv->phy) -+ return phy_ethtool_gset(priv->phy, cmd); -+ -+ return -EINVAL; -+} -+ -+static int cpmac_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -+{ -+ struct cpmac_priv *priv = netdev_priv(dev); -+ -+ if (!capable(CAP_NET_ADMIN)) -+ return -EPERM; -+ -+ if (priv->phy) -+ return phy_ethtool_sset(priv->phy, cmd); -+ -+ return -EINVAL; -+} -+ -+static void cpmac_get_ringparam(struct net_device *dev, struct ethtool_ringparam* ring) -+{ -+ struct cpmac_priv *priv = netdev_priv(dev); -+ -+ ring->rx_max_pending = 1024; -+ ring->rx_mini_max_pending = 1; -+ ring->rx_jumbo_max_pending = 1; -+ ring->tx_max_pending = 1; -+ -+ ring->rx_pending = priv->ring_size; -+ ring->rx_mini_pending = 1; -+ ring->rx_jumbo_pending = 1; -+ ring->tx_pending = 1; -+} -+ -+static int cpmac_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ring) -+{ -+ struct cpmac_priv *priv = netdev_priv(dev); -+ -+ if (netif_running(dev)) -+ return -EBUSY; -+ priv->ring_size = ring->rx_pending; -+ return 0; -+} -+ -+static void cpmac_get_drvinfo(struct net_device *dev, -+ struct ethtool_drvinfo *info) -+{ -+ strcpy(info->driver, "cpmac"); -+ strcpy(info->version, CPMAC_VERSION); -+ info->fw_version[0] = '\0'; -+ sprintf(info->bus_info, "%s", "cpmac"); -+ info->regdump_len = 0; -+} -+ -+static const struct ethtool_ops cpmac_ethtool_ops = { -+ .get_settings = cpmac_get_settings, -+ .set_settings = cpmac_set_settings, -+ .get_drvinfo = cpmac_get_drvinfo, -+ .get_link = ethtool_op_get_link, -+ .get_ringparam = cpmac_get_ringparam, -+ .set_ringparam = cpmac_set_ringparam, -+}; -+ -+static void cpmac_adjust_link(struct net_device *dev) -+{ -+ struct cpmac_priv *priv = netdev_priv(dev); -+ int new_state = 0; -+ -+ spin_lock(&priv->lock); -+ if (priv->phy->link) { -+ netif_tx_start_all_queues(dev); -+ if (priv->phy->duplex != priv->oldduplex) { -+ new_state = 1; -+ priv->oldduplex = priv->phy->duplex; -+ } -+ -+ if (priv->phy->speed != priv->oldspeed) { -+ new_state = 1; -+ priv->oldspeed = priv->phy->speed; -+ } -+ -+ if (!priv->oldlink) { -+ new_state = 1; -+ priv->oldlink = 1; -+ } -+ } else if (priv->oldlink) { -+ new_state = 1; -+ priv->oldlink = 0; -+ priv->oldspeed = 0; -+ priv->oldduplex = -1; -+ } -+ -+ if (new_state && netif_msg_link(priv) && net_ratelimit()) -+ phy_print_status(priv->phy); -+ -+ spin_unlock(&priv->lock); -+} -+ -+static int cpmac_open(struct net_device *dev) -+{ -+ int i, size, res; -+ struct cpmac_priv *priv = netdev_priv(dev); -+ struct resource *mem; -+ struct cpmac_desc *desc; -+ struct sk_buff *skb; -+ -+ mem = platform_get_resource_byname(priv->pdev, IORESOURCE_MEM, "regs"); -+ if (!request_mem_region(mem->start, mem->end - mem->start, dev->name)) { -+ if (netif_msg_drv(priv)) -+ printk(KERN_ERR "%s: failed to request registers\n", -+ dev->name); -+ res = -ENXIO; -+ goto fail_reserve; -+ } -+ -+ priv->regs = ioremap(mem->start, mem->end - mem->start); -+ if (!priv->regs) { -+ if (netif_msg_drv(priv)) -+ printk(KERN_ERR "%s: failed to remap registers\n", -+ dev->name); -+ res = -ENXIO; -+ goto fail_remap; -+ } -+ -+ size = priv->ring_size + CPMAC_QUEUES; -+ priv->desc_ring = dma_alloc_coherent(&dev->dev, -+ sizeof(struct cpmac_desc) * size, -+ &priv->dma_ring, -+ GFP_KERNEL); -+ if (!priv->desc_ring) { -+ res = -ENOMEM; -+ goto fail_alloc; -+ } -+ -+ for (i = 0; i < size; i++) -+ priv->desc_ring[i].mapping = priv->dma_ring + sizeof(*desc) * i; -+ -+ priv->rx_head = &priv->desc_ring[CPMAC_QUEUES]; -+ for (i = 0, desc = priv->rx_head; i < priv->ring_size; i++, desc++) { -+ skb = netdev_alloc_skb(dev, CPMAC_SKB_SIZE); -+ if (unlikely(!skb)) { -+ res = -ENOMEM; -+ goto fail_desc; -+ } -+ skb_reserve(skb, 2); -+ desc->skb = skb; -+ desc->data_mapping = dma_map_single(&dev->dev, skb->data, -+ CPMAC_SKB_SIZE, -+ DMA_FROM_DEVICE); -+ desc->hw_data = (u32)desc->data_mapping; -+ desc->buflen = CPMAC_SKB_SIZE; -+ desc->dataflags = CPMAC_OWN; -+ desc->next = &priv->rx_head[(i + 1) % priv->ring_size]; -+ desc->next->prev = desc; -+ desc->hw_next = (u32)desc->next->mapping; -+ } -+ -+ priv->rx_head->prev->hw_next = (u32)0; -+ -+ if ((res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED, -+ dev->name, dev))) { -+ if (netif_msg_drv(priv)) -+ printk(KERN_ERR "%s: failed to obtain irq\n", -+ dev->name); -+ goto fail_irq; -+ } -+ -+ atomic_set(&priv->reset_pending, 0); -+ INIT_WORK(&priv->reset_work, cpmac_hw_error); -+ cpmac_hw_start(dev); -+ -+ napi_enable(&priv->napi); -+ priv->phy->state = PHY_CHANGELINK; -+ phy_start(priv->phy); -+ -+ return 0; -+ -+fail_irq: -+fail_desc: -+ for (i = 0; i < priv->ring_size; i++) { -+ if (priv->rx_head[i].skb) { -+ dma_unmap_single(&dev->dev, -+ priv->rx_head[i].data_mapping, -+ CPMAC_SKB_SIZE, -+ DMA_FROM_DEVICE); -+ kfree_skb(priv->rx_head[i].skb); -+ } -+ } -+fail_alloc: -+ kfree(priv->desc_ring); -+ iounmap(priv->regs); -+ -+fail_remap: -+ release_mem_region(mem->start, mem->end - mem->start); -+ -+fail_reserve: -+ return res; -+} -+ -+static int cpmac_stop(struct net_device *dev) -+{ -+ int i; -+ struct cpmac_priv *priv = netdev_priv(dev); -+ struct resource *mem; -+ -+ netif_tx_stop_all_queues(dev); -+ -+ cancel_work_sync(&priv->reset_work); -+ napi_disable(&priv->napi); -+ phy_stop(priv->phy); -+ -+ cpmac_hw_stop(dev); -+ -+ for (i = 0; i < 8; i++) -+ cpmac_write(priv->regs, CPMAC_TX_PTR(i), 0); -+ cpmac_write(priv->regs, CPMAC_RX_PTR(0), 0); -+ cpmac_write(priv->regs, CPMAC_MBP, 0); -+ -+ free_irq(dev->irq, dev); -+ iounmap(priv->regs); -+ mem = platform_get_resource_byname(priv->pdev, IORESOURCE_MEM, "regs"); -+ release_mem_region(mem->start, mem->end - mem->start); -+ priv->rx_head = &priv->desc_ring[CPMAC_QUEUES]; -+ for (i = 0; i < priv->ring_size; i++) { -+ if (priv->rx_head[i].skb) { -+ dma_unmap_single(&dev->dev, -+ priv->rx_head[i].data_mapping, -+ CPMAC_SKB_SIZE, -+ DMA_FROM_DEVICE); -+ kfree_skb(priv->rx_head[i].skb); -+ } -+ } -+ -+ dma_free_coherent(&dev->dev, sizeof(struct cpmac_desc) * -+ (CPMAC_QUEUES + priv->ring_size), -+ priv->desc_ring, priv->dma_ring); -+ return 0; -+} -+ -+static int external_switch; -+ -+static int __devinit cpmac_probe(struct platform_device *pdev) -+{ -+ int rc, phy_id, i; -+ char *mdio_bus_id = "0"; -+ struct resource *mem; -+ struct cpmac_priv *priv; -+ struct net_device *dev; -+ struct plat_cpmac_data *pdata; -+ -+ pdata = pdev->dev.platform_data; -+ -+ for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) { -+ if (!(pdata->phy_mask & (1 << phy_id))) -+ continue; -+ if (!cpmac_mii->phy_map[phy_id]) -+ continue; -+ break; -+ } -+ -+ if (phy_id == PHY_MAX_ADDR) { -+ if (external_switch || dumb_switch) { -+ mdio_bus_id = 0; /* fixed phys bus */ -+ phy_id = pdev->id; -+ } else { -+ dev_err(&pdev->dev, "no PHY present\n"); -+ return -ENODEV; -+ } -+ } -+ -+ dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES); -+ -+ if (!dev) { -+ printk(KERN_ERR "cpmac: Unable to allocate net_device\n"); -+ return -ENOMEM; -+ } -+ -+ platform_set_drvdata(pdev, dev); -+ priv = netdev_priv(dev); -+ -+ priv->pdev = pdev; -+ mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); -+ if (!mem) { -+ rc = -ENODEV; -+ goto fail; -+ } -+ -+ dev->irq = platform_get_irq_byname(pdev, "irq"); -+ -+ dev->open = cpmac_open; -+ dev->stop = cpmac_stop; -+ dev->set_config = cpmac_config; -+ dev->hard_start_xmit = cpmac_start_xmit; -+ dev->do_ioctl = cpmac_ioctl; -+ dev->set_multicast_list = cpmac_set_multicast_list; -+ dev->tx_timeout = cpmac_tx_timeout; -+ dev->ethtool_ops = &cpmac_ethtool_ops; -+ -+ netif_napi_add(dev, &priv->napi, cpmac_poll, 64); -+ -+ spin_lock_init(&priv->lock); -+ spin_lock_init(&priv->rx_lock); -+ priv->dev = dev; -+ priv->ring_size = 64; -+ priv->msg_enable = netif_msg_init(debug_level, 0xff); -+ memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr)); -+ -+ priv->phy = phy_connect(dev, cpmac_mii->phy_map[phy_id]->dev.bus_id, -+ &cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII); -+ if (IS_ERR(priv->phy)) { -+ if (netif_msg_drv(priv)) -+ printk(KERN_ERR "%s: Could not attach to PHY\n", -+ dev->name); -+ return PTR_ERR(priv->phy); -+ } -+ -+ if ((rc = register_netdev(dev))) { -+ printk(KERN_ERR "cpmac: error %i registering device %s\n", rc, -+ dev->name); -+ goto fail; -+ } -+ -+ if (netif_msg_probe(priv)) { -+ printk(KERN_INFO -+ "cpmac: device %s (regs: %p, irq: %d, phy: %s, " -+ "mac: %pM)\n", dev->name, (void *)mem->start, dev->irq, -+ priv->phy_name, dev->dev_addr); -+ } -+ return 0; -+ -+fail: -+ free_netdev(dev); -+ return rc; -+} -+ -+static int __devexit cpmac_remove(struct platform_device *pdev) -+{ -+ struct net_device *dev = platform_get_drvdata(pdev); -+ unregister_netdev(dev); -+ free_netdev(dev); -+ return 0; -+} -+ -+static struct platform_driver cpmac_driver = { -+ .driver.name = "cpmac", -+ .driver.owner = THIS_MODULE, -+ .probe = cpmac_probe, -+ .remove = __devexit_p(cpmac_remove), -+}; -+ -+int __devinit cpmac_init(void) -+{ -+ u32 mask; -+ int i, res; -+ -+ cpmac_mii = mdiobus_alloc(); -+ if (cpmac_mii == NULL) -+ return -ENOMEM; -+ -+ cpmac_mii->name = "cpmac-mii"; -+ cpmac_mii->read = cpmac_mdio_read; -+ cpmac_mii->write = cpmac_mdio_write; -+ cpmac_mii->reset = cpmac_mdio_reset; -+ cpmac_mii->irq = mii_irqs; -+ -+ cpmac_mii->priv = ioremap(AR7_REGS_MDIO, 256); -+ -+ if (!cpmac_mii->priv) { -+ printk(KERN_ERR "Can't ioremap mdio registers\n"); -+ res = -ENXIO; -+ goto fail_alloc; -+ } -+ -+#warning FIXME: unhardcode gpio&reset bits -+ ar7_gpio_disable(26); -+ ar7_gpio_disable(27); -+ ar7_device_reset(AR7_RESET_BIT_CPMAC_LO); -+ ar7_device_reset(AR7_RESET_BIT_CPMAC_HI); -+ ar7_device_reset(AR7_RESET_BIT_EPHY); -+ -+ cpmac_mii->reset(cpmac_mii); -+ -+ for (i = 0; i < 300000; i++) -+ if ((mask = cpmac_read(cpmac_mii->priv, CPMAC_MDIO_ALIVE))) -+ break; -+ else -+ cpu_relax(); -+ -+ mask &= 0x7fffffff; -+ if (mask & (mask - 1)) { -+ external_switch = 1; -+ mask = 0; -+ } -+ -+ cpmac_mii->phy_mask = ~(mask | 0x80000000); -+ snprintf(cpmac_mii->id, MII_BUS_ID_SIZE, "0"); -+ -+ res = mdiobus_register(cpmac_mii); -+ if (res) -+ goto fail_mii; -+ -+ res = platform_driver_register(&cpmac_driver); -+ if (res) -+ goto fail_cpmac; -+ -+ return 0; -+ -+fail_cpmac: -+ mdiobus_unregister(cpmac_mii); -+ -+fail_mii: -+ iounmap(cpmac_mii->priv); -+ -+fail_alloc: -+ mdiobus_free(cpmac_mii); -+ -+ return res; -+} -+ -+void __devexit cpmac_exit(void) -+{ -+ platform_driver_unregister(&cpmac_driver); -+ mdiobus_unregister(cpmac_mii); -+ mdiobus_free(cpmac_mii); -+ iounmap(cpmac_mii->priv); -+} -+ -+module_init(cpmac_init); -+module_exit(cpmac_exit); -diff -Nur linux-2.6.29.1.orig/drivers/net/Kconfig linux-2.6.29.1/drivers/net/Kconfig ---- linux-2.6.29.1.orig/drivers/net/Kconfig 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/net/Kconfig 2009-05-31 20:04:03.000000000 +0200 -@@ -1741,7 +1741,7 @@ +- snprintf(cpmac_mii->id, MII_BUS_ID_SIZE, "0"); ++ snprintf(cpmac_mii->id, MII_BUS_ID_SIZE, "1"); - config CPMAC - tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)" -- depends on NET_ETHERNET && EXPERIMENTAL && AR7 && BROKEN -+ depends on NET_ETHERNET && EXPERIMENTAL && AR7 - select PHYLIB - help - TI AR7 CPMAC Ethernet support + res = mdiobus_register(cpmac_mii); + if (res) + goto fail_mii; + ++ */ + res = platform_driver_register(&cpmac_driver); + if (res) + goto fail_cpmac; diff -Nur linux-2.6.29.1.orig/drivers/vlynq/Kconfig linux-2.6.29.1/drivers/vlynq/Kconfig --- linux-2.6.29.1.orig/drivers/vlynq/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/vlynq/Kconfig 2009-05-31 19:50:05.000000000 +0200 ++++ linux-2.6.29.1/drivers/vlynq/Kconfig 2009-06-05 23:38:23.016945921 +0200 @@ -0,0 +1,13 @@ +menu "TI VLYNQ" + @@ -3950,7 +2718,7 @@ diff -Nur linux-2.6.29.1.orig/drivers/vlynq/Kconfig linux-2.6.29.1/drivers/vlynq +endmenu diff -Nur linux-2.6.29.1.orig/drivers/vlynq/Makefile linux-2.6.29.1/drivers/vlynq/Makefile --- linux-2.6.29.1.orig/drivers/vlynq/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/vlynq/Makefile 2009-05-31 19:50:06.000000000 +0200 ++++ linux-2.6.29.1/drivers/vlynq/Makefile 2009-06-05 23:38:23.016945921 +0200 @@ -0,0 +1,5 @@ +# +# Makefile for kernel vlynq drivers @@ -3959,7 +2727,7 @@ diff -Nur linux-2.6.29.1.orig/drivers/vlynq/Makefile linux-2.6.29.1/drivers/vlyn +obj-$(CONFIG_VLYNQ) += vlynq.o diff -Nur linux-2.6.29.1.orig/drivers/vlynq/vlynq.c linux-2.6.29.1/drivers/vlynq/vlynq.c --- linux-2.6.29.1.orig/drivers/vlynq/vlynq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/vlynq/vlynq.c 2009-05-31 19:50:06.000000000 +0200 ++++ linux-2.6.29.1/drivers/vlynq/vlynq.c 2009-06-05 23:38:23.020946151 +0200 @@ -0,0 +1,783 @@ +/* + * Copyright (C) 2006, 2007 Eugene Konev <ejka@openwrt.org> @@ -4746,7 +3514,7 @@ diff -Nur linux-2.6.29.1.orig/drivers/vlynq/vlynq.c linux-2.6.29.1/drivers/vlynq +module_exit(vlynq_exit); diff -Nur linux-2.6.29.1.orig/drivers/watchdog/ar7_wdt.c linux-2.6.29.1/drivers/watchdog/ar7_wdt.c --- linux-2.6.29.1.orig/drivers/watchdog/ar7_wdt.c 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/watchdog/ar7_wdt.c 2009-05-31 19:54:01.000000000 +0200 ++++ linux-2.6.29.1/drivers/watchdog/ar7_wdt.c 2009-06-05 23:38:23.024946661 +0200 @@ -69,8 +69,7 @@ u32 prescale; }; @@ -4885,7 +3653,7 @@ diff -Nur linux-2.6.29.1.orig/drivers/watchdog/ar7_wdt.c linux-2.6.29.1/drivers/ printk(KERN_ERR DRVNAME diff -Nur linux-2.6.29.1.orig/include/linux/vlynq.h linux-2.6.29.1/include/linux/vlynq.h --- linux-2.6.29.1.orig/include/linux/vlynq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/include/linux/vlynq.h 2009-05-31 20:25:54.000000000 +0200 ++++ linux-2.6.29.1/include/linux/vlynq.h 2009-06-05 23:38:23.032946563 +0200 @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2006, 2007 Eugene Konev <ejka@openwrt.org> @@ -5050,7 +3818,7 @@ diff -Nur linux-2.6.29.1.orig/include/linux/vlynq.h linux-2.6.29.1/include/linux +#endif /* __VLYNQ_H__ */ diff -Nur linux-2.6.29.1.orig/kernel/futex.c linux-2.6.29.1/kernel/futex.c --- linux-2.6.29.1.orig/kernel/futex.c 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/kernel/futex.c 2009-06-01 12:42:57.000000000 +0200 ++++ linux-2.6.29.1/kernel/futex.c 2009-06-05 23:38:23.036947073 +0200 @@ -2027,9 +2027,11 @@ * implementation, the non functional ones will return * -ENOSYS. @@ -5068,7 +3836,7 @@ diff -Nur linux-2.6.29.1.orig/kernel/futex.c linux-2.6.29.1/kernel/futex.c plist_head_init(&futex_queues[i].chain, &futex_queues[i].lock); diff -Nur linux-2.6.29.1.orig/kernel/printk.c linux-2.6.29.1/kernel/printk.c --- linux-2.6.29.1.orig/kernel/printk.c 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/kernel/printk.c 2009-06-01 13:40:39.000000000 +0200 ++++ linux-2.6.29.1/kernel/printk.c 2009-06-05 23:38:23.036947073 +0200 @@ -1253,6 +1253,7 @@ static int __init disable_boot_consoles(void) |