From 5c105d9f3fd086aff195d3849dcf847d6b0bd927 Mon Sep 17 00:00:00 2001 From: blogic Date: Fri, 5 Oct 2012 10:12:53 +0000 Subject: branch Attitude Adjustment git-svn-id: svn://svn.openwrt.org/openwrt/branches/attitude_adjustment@33625 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- target/linux/Makefile | 13 + target/linux/adm5120/Makefile | 22 + target/linux/adm5120/base-files/etc/config/network | 27 + target/linux/adm5120/base-files/etc/config/system | 40 + target/linux/adm5120/base-files/etc/diag.sh | 48 + target/linux/adm5120/base-files/lib/adm5120.sh | 53 + .../lib/preinit/05_preinit_do_adm5120.sh | 7 + .../base-files/lib/preinit/05_reset_button_adm5120 | 12 + .../lib/preinit/05_set_preinit_iface_adm5120 | 9 + .../adm5120/base-files/lib/upgrade/platform.sh | 44 + target/linux/adm5120/config-3.3 | 194 + .../linux/adm5120/files/arch/mips/adm5120/Kconfig | 197 + .../linux/adm5120/files/arch/mips/adm5120/Platform | 19 + .../files/arch/mips/adm5120/cellvision/Makefile | 4 + .../files/arch/mips/adm5120/cellvision/cas-771.c | 37 + .../arch/mips/adm5120/cellvision/cellvision.c | 147 + .../arch/mips/adm5120/cellvision/cellvision.h | 28 + .../files/arch/mips/adm5120/cellvision/nfs-101.c | 47 + .../files/arch/mips/adm5120/common/Makefile | 8 + .../files/arch/mips/adm5120/common/adm5120.c | 76 + .../adm5120/files/arch/mips/adm5120/common/clock.c | 65 + .../files/arch/mips/adm5120/common/early-printk.c | 31 + .../adm5120/files/arch/mips/adm5120/common/gpio.c | 330 + .../adm5120/files/arch/mips/adm5120/common/irq.c | 171 + .../files/arch/mips/adm5120/common/memory.c | 149 + .../files/arch/mips/adm5120/common/platform.c | 395 + .../adm5120/files/arch/mips/adm5120/common/prom.c | 264 + .../adm5120/files/arch/mips/adm5120/common/setup.c | 128 + .../files/arch/mips/adm5120/compex/Makefile | 5 + .../files/arch/mips/adm5120/compex/compex.c | 64 + .../files/arch/mips/adm5120/compex/compex.h | 23 + .../adm5120/files/arch/mips/adm5120/compex/np27g.c | 28 + .../adm5120/files/arch/mips/adm5120/compex/np28g.c | 63 + .../adm5120/files/arch/mips/adm5120/compex/wp54.c | 95 + .../files/arch/mips/adm5120/edimax/Makefile | 5 + .../files/arch/mips/adm5120/edimax/br-6104k.c | 36 + .../files/arch/mips/adm5120/edimax/br-6104kp.c | 39 + .../files/arch/mips/adm5120/edimax/br-61x4wg.c | 43 + .../files/arch/mips/adm5120/edimax/br-61xx.c | 88 + .../files/arch/mips/adm5120/edimax/br-61xx.h | 23 + .../files/arch/mips/adm5120/generic/Makefile | 1 + .../files/arch/mips/adm5120/generic/eb-214a.c | 123 + .../files/arch/mips/adm5120/infineon/Makefile | 6 + .../files/arch/mips/adm5120/infineon/easy5120-rt.c | 48 + .../arch/mips/adm5120/infineon/easy5120-wvoip.c | 24 + .../arch/mips/adm5120/infineon/easy5120p-ata.c | 22 + .../files/arch/mips/adm5120/infineon/easy83000.c | 23 + .../files/arch/mips/adm5120/infineon/infineon.c | 108 + .../files/arch/mips/adm5120/infineon/infineon.h | 25 + .../files/arch/mips/adm5120/mikrotik/Makefile | 8 + .../files/arch/mips/adm5120/mikrotik/rb-11x.c | 36 + .../files/arch/mips/adm5120/mikrotik/rb-133.c | 41 + .../files/arch/mips/adm5120/mikrotik/rb-133c.c | 37 + .../files/arch/mips/adm5120/mikrotik/rb-150.c | 137 + .../files/arch/mips/adm5120/mikrotik/rb-153.c | 75 + .../files/arch/mips/adm5120/mikrotik/rb-192.c | 28 + .../files/arch/mips/adm5120/mikrotik/rb-1xx.c | 150 + .../files/arch/mips/adm5120/mikrotik/rb-1xx.h | 33 + .../files/arch/mips/adm5120/motorola/Makefile | 1 + .../files/arch/mips/adm5120/motorola/pmugw.c | 96 + .../files/arch/mips/adm5120/osbridge/5gxi.c | 71 + .../files/arch/mips/adm5120/osbridge/Makefile | 1 + .../adm5120/files/arch/mips/adm5120/prom/Makefile | 10 + .../adm5120/files/arch/mips/adm5120/prom/admboot.c | 55 + .../files/arch/mips/adm5120/prom/bootbase.c | 119 + .../adm5120/files/arch/mips/adm5120/prom/cfe.c | 69 + .../adm5120/files/arch/mips/adm5120/prom/generic.c | 47 + .../files/arch/mips/adm5120/prom/myloader.c | 68 + .../files/arch/mips/adm5120/prom/prom_read.h | 50 + .../files/arch/mips/adm5120/prom/routerboot.c | 121 + .../adm5120/files/arch/mips/adm5120/zyxel/Makefile | 4 + .../files/arch/mips/adm5120/zyxel/p-334wt.c | 34 + .../adm5120/files/arch/mips/adm5120/zyxel/p-335.c | 21 + .../adm5120/files/arch/mips/adm5120/zyxel/p-33x.c | 89 + .../adm5120/files/arch/mips/adm5120/zyxel/p-33x.h | 22 + .../mips/include/asm/mach-adm5120/adm5120_defs.h | 53 + .../mips/include/asm/mach-adm5120/adm5120_info.h | 129 + .../mips/include/asm/mach-adm5120/adm5120_intc.h | 63 + .../mips/include/asm/mach-adm5120/adm5120_mpmc.h | 92 + .../mips/include/asm/mach-adm5120/adm5120_nand.h | 89 + .../include/asm/mach-adm5120/adm5120_platform.h | 88 + .../mips/include/asm/mach-adm5120/adm5120_switch.h | 300 + .../mips/include/asm/mach-adm5120/adm5120_uart.h | 64 + .../arch/mips/include/asm/mach-adm5120/asm/sizes.h | 56 + .../asm/mach-adm5120/cpu-feature-overrides.h | 71 + .../arch/mips/include/asm/mach-adm5120/gpio.h | 115 + .../files/arch/mips/include/asm/mach-adm5120/irq.h | 43 + .../mips/include/asm/mach-adm5120/prom/admboot.h | 17 + .../arch/mips/include/asm/mach-adm5120/prom/cfe.h | 18 + .../mips/include/asm/mach-adm5120/prom/generic.h | 18 + .../mips/include/asm/mach-adm5120/prom/myloader.h | 179 + .../include/asm/mach-adm5120/prom/routerboot.h | 36 + .../mips/include/asm/mach-adm5120/prom/zynos.h | 86 + .../files/arch/mips/include/asm/mach-adm5120/war.h | 25 + .../adm5120/files/arch/mips/pci/pci-adm5120.c | 277 + .../adm5120/files/drivers/ata/pata_rb153_cf.c | 267 + .../files/drivers/leds/ledtrig-adm5120-switch.c | 149 + .../adm5120/files/drivers/mtd/maps/adm5120-flash.c | 482 + target/linux/adm5120/files/drivers/mtd/trxsplit.c | 217 + target/linux/adm5120/files/drivers/net/adm5120sw.c | 1219 + target/linux/adm5120/files/drivers/net/adm5120sw.h | 23 + .../adm5120/files/drivers/usb/host/adm5120-dbg.c | 836 + .../adm5120/files/drivers/usb/host/adm5120-drv.c | 228 + .../adm5120/files/drivers/usb/host/adm5120-hcd.c | 844 + .../adm5120/files/drivers/usb/host/adm5120-hub.c | 430 + .../adm5120/files/drivers/usb/host/adm5120-mem.c | 202 + .../adm5120/files/drivers/usb/host/adm5120-pm.c | 449 + .../adm5120/files/drivers/usb/host/adm5120-q.c | 964 + .../linux/adm5120/files/drivers/usb/host/adm5120.h | 755 + .../adm5120/files/drivers/watchdog/adm5120_wdt.c | 202 + target/linux/adm5120/image/Makefile | 116 + target/linux/adm5120/image/lzma-loader/Makefile | 62 + .../adm5120/image/lzma-loader/src/LzmaDecode.c | 584 + .../adm5120/image/lzma-loader/src/LzmaDecode.h | 113 + .../adm5120/image/lzma-loader/src/LzmaTypes.h | 45 + .../linux/adm5120/image/lzma-loader/src/Makefile | 99 + target/linux/adm5120/image/lzma-loader/src/README | 55 + target/linux/adm5120/image/lzma-loader/src/board.c | 185 + .../linux/adm5120/image/lzma-loader/src/config.h | 143 + .../adm5120/image/lzma-loader/src/decompress.c | 353 + target/linux/adm5120/image/lzma-loader/src/head.S | 209 + .../linux/adm5120/image/lzma-loader/src/loader.lds | 29 + .../adm5120/image/lzma-loader/src/lzma-data.lds | 8 + .../linux/adm5120/image/lzma-loader/src/printf.c | 350 + .../linux/adm5120/image/lzma-loader/src/printf.h | 18 + target/linux/adm5120/image/rb1xx.mk | 24 + target/linux/adm5120/image/router_be.mk | 48 + target/linux/adm5120/image/router_le.mk | 401 + target/linux/adm5120/modules.mk | 56 + target/linux/adm5120/patches-3.3/001-adm5120.patch | 43 + .../adm5120/patches-3.3/002-adm5120_flash.patch | 21 + .../adm5120/patches-3.3/003-adm5120_switch.patch | 23 + .../adm5120/patches-3.3/005-adm5120_usb.patch | 33 + .../adm5120/patches-3.3/007-adm5120_pci.patch | 22 + .../009-adm5120_leds_switch_trigger.patch | 22 + .../101-cfi_fixup_macronix_bootloc.patch | 84 + .../patches-3.3/102-jedec_pmc_39lvxxx_chips.patch | 68 + .../adm5120/patches-3.3/103-mtd_trxsplit.patch | 23 + .../adm5120/patches-3.3/120-rb153_cf_driver.patch | 28 + .../adm5120/patches-3.3/200-amba_pl010_hacks.patch | 378 + .../adm5120/patches-3.3/201-amba_bus_hacks.patch | 13 + .../patches-3.3/203-gpio_leds_brightness.patch | 27 + .../adm5120/patches-3.3/310-adm5120_wdt.patch | 31 + .../linux/adm5120/rb1xx/base-files/sbin/wget2nand | 78 + target/linux/adm5120/rb1xx/config-3.3 | 54 + target/linux/adm5120/rb1xx/profiles/RB1xx.mk | 18 + target/linux/adm5120/rb1xx/target.mk | 9 + target/linux/adm5120/router_be/config-3.3 | 15 + .../adm5120/router_be/profiles/010-Generic.mk | 17 + .../linux/adm5120/router_be/profiles/200-ZyXEL.mk | 27 + target/linux/adm5120/router_be/target.mk | 11 + target/linux/adm5120/router_le/config-3.3 | 0 .../adm5120/router_le/profiles/010-Generic.mk | 28 + .../linux/adm5120/router_le/profiles/Cellvision.mk | 146 + target/linux/adm5120/router_le/profiles/Compex.mk | 37 + target/linux/adm5120/router_le/profiles/Edimax.mk | 47 + .../linux/adm5120/router_le/profiles/Infineon.mk | 27 + .../linux/adm5120/router_le/profiles/Motorola.mk | 16 + .../linux/adm5120/router_le/profiles/Osbridge.mk | 16 + target/linux/adm5120/router_le/target.mk | 11 + target/linux/adm8668/Makefile | 26 + target/linux/adm8668/base-files.mk | 3 + target/linux/adm8668/base-files/etc/config/network | 16 + target/linux/adm8668/base-files/etc/diag.sh | 21 + .../lib/preinit/03_init_hotplug_failsafe_adm8668 | 9 + .../lib/preinit/05_set_preinit_face_adm8668 | 9 + .../base-files/lib/preinit/45_failsafe_adm8668 | 11 + .../adm8668/base-files/lib/upgrade/platform.sh | 15 + .../linux/adm8668/base-files/sbin/hotplug.failsafe | 4 + target/linux/adm8668/config-3.3 | 77 + .../linux/adm8668/files/arch/mips/adm8668/Makefile | 5 + .../linux/adm8668/files/arch/mips/adm8668/Platform | 6 + target/linux/adm8668/files/arch/mips/adm8668/irq.c | 117 + target/linux/adm8668/files/arch/mips/adm8668/net.h | 277 + .../adm8668/files/arch/mips/adm8668/net_core.c | 618 + .../adm8668/files/arch/mips/adm8668/net_intr.c | 446 + target/linux/adm8668/files/arch/mips/adm8668/pci.c | 171 + .../adm8668/files/arch/mips/adm8668/platform.c | 151 + .../linux/adm8668/files/arch/mips/adm8668/proc.c | 114 + .../linux/adm8668/files/arch/mips/adm8668/prom.c | 137 + .../linux/adm8668/files/arch/mips/adm8668/serial.c | 638 + .../linux/adm8668/files/arch/mips/adm8668/u-boot.h | 52 + .../arch/mips/include/asm/mach-adm8668/adm8668.h | 139 + .../files/arch/mips/include/asm/mach-adm8668/irq.h | 16 + .../files/arch/mips/include/asm/mach-adm8668/war.h | 25 + .../linux/adm8668/files/drivers/mtd/maps/adm8668.c | 334 + target/linux/adm8668/image/Makefile | 58 + target/linux/adm8668/image/lzma-loader/Makefile | 41 + .../adm8668/image/lzma-loader/src/LzmaDecode.c | 590 + .../adm8668/image/lzma-loader/src/LzmaDecode.h | 131 + .../linux/adm8668/image/lzma-loader/src/Makefile | 47 + .../adm8668/image/lzma-loader/src/decompress.c | 118 + .../image/lzma-loader/src/include/_exports.h | 18 + .../lzma-loader/src/include/asm/global_data.h | 60 + .../image/lzma-loader/src/include/asm/u-boot.h | 42 + .../adm8668/image/lzma-loader/src/include/common.h | 48 + .../image/lzma-loader/src/include/exports.h | 38 + .../adm8668/image/lzma-loader/src/include/image.h | 157 + .../adm8668/image/lzma-loader/src/lzma.lds.in | 24 + target/linux/adm8668/image/lzma-loader/src/stubs.c | 52 + target/linux/adm8668/image/my-mkimage | 32 + .../adm8668/patches-3.3/001-adm8668_arch.patch | 39 + .../adm8668/patches-3.3/002-adm8668_uart.patch | 40 + .../adm8668/patches-3.3/003-adm8668_nor_map.patch | 25 + target/linux/amazon/Makefile | 27 + target/linux/amazon/base-files/etc/config/network | 14 + target/linux/amazon/config-3.3 | 104 + target/linux/amazon/files/arch/mips/amazon/Kconfig | 67 + .../linux/amazon/files/arch/mips/amazon/Makefile | 9 + target/linux/amazon/files/arch/mips/amazon/board.c | 69 + .../linux/amazon/files/arch/mips/amazon/dma-core.c | 1462 + .../linux/amazon/files/arch/mips/amazon/dma-core.h | 69 + .../amazon/files/arch/mips/amazon/interrupt.c | 187 + target/linux/amazon/files/arch/mips/amazon/pci.c | 279 + target/linux/amazon/files/arch/mips/amazon/prom.c | 72 + target/linux/amazon/files/arch/mips/amazon/setup.c | 193 + .../files/arch/mips/include/asm/mach-amazon/irq.h | 7 + .../mips/include/asm/mach-amazon/mangle-port.h | 52 + .../files/arch/mips/include/asm/mach-amazon/war.h | 24 + target/linux/amazon/files/drivers/atm/amazon_tpe.c | 3074 + .../linux/amazon/files/drivers/char/amazon_mei.c | 7918 ++ target/linux/amazon/files/drivers/char/ifx_ssc.c | 2121 + .../linux/amazon/files/drivers/mtd/maps/amazon.c | 204 + .../amazon/files/drivers/net/ethernet/admmod.c | 1493 + .../amazon/files/drivers/net/ethernet/amazon_sw.c | 899 + .../amazon/files/drivers/tty/serial/amazon_asc.c | 711 + .../amazon/files/drivers/watchdog/amazon_wdt.c | 277 + .../amazon/files/include/asm-mips/amazon/adm6996.h | 232 + .../amazon/files/include/asm-mips/amazon/amazon.h | 1447 + .../files/include/asm-mips/amazon/amazon_dma.h | 148 + .../files/include/asm-mips/amazon/amazon_mei.h | 220 + .../files/include/asm-mips/amazon/amazon_mei_app.h | 54 + .../include/asm-mips/amazon/amazon_mei_app_ioctl.h | 1169 + .../include/asm-mips/amazon/amazon_mei_ioctl.h | 757 + .../files/include/asm-mips/amazon/amazon_sw.h | 177 + .../files/include/asm-mips/amazon/amazon_tpe.h | 258 + .../files/include/asm-mips/amazon/amazon_wdt.h | 23 + .../files/include/asm-mips/amazon/atm_defines.h | 540 + .../amazon/files/include/asm-mips/amazon/atm_mib.h | 142 + .../asm-mips/amazon/ifx_peripheral_definitions.h | 96 + .../amazon/files/include/asm-mips/amazon/ifx_ssc.h | 263 + .../include/asm-mips/amazon/ifx_ssc_defines.h | 552 + .../amazon/files/include/asm-mips/amazon/irq.h | 200 + .../amazon/files/include/asm-mips/amazon/model.h | 29 + .../amazon/files/include/asm-mips/amazon/port.h | 72 + .../amazon/files/include/asm-mips/amazon/serial.h | 146 + target/linux/amazon/image/Makefile | 30 + .../amazon/patches-3.3/000-mips-bad-intctl.patch | 33 + .../010-mips_clocksource_init_war.patch | 33 + .../linux/amazon/patches-3.3/017-wdt-driver.patch | 10 + target/linux/amazon/patches-3.3/100-board.patch | 53 + .../linux/amazon/patches-3.3/130-mtd_drivers.patch | 7 + .../linux/amazon/patches-3.3/140-net_drivers.patch | 9 + .../amazon/patches-3.3/150-serial_driver.patch | 7 + target/linux/amazon/patches-3.3/160-cfi-swap.patch | 56 + target/linux/ar7/Makefile | 26 + target/linux/ar7/base-files.mk | 11 + target/linux/ar7/base-files/etc/config/network | 42 + target/linux/ar7/base-files/etc/diag.sh | 34 + target/linux/ar7/base-files/etc/init.d/adam2 | 13 + .../linux/ar7/base-files/etc/uci-defaults/network | 30 + target/linux/ar7/config-3.3 | 99 + target/linux/ar7/files/drivers/char/ar7_gpio.c | 158 + target/linux/ar7/files/drivers/mtd/titanpart.c | 234 + target/linux/ar7/image/Makefile | 109 + target/linux/ar7/patches-3.3/110-flash.patch | 22 + target/linux/ar7/patches-3.3/120-gpio_chrdev.patch | 28 + .../patches-3.3/160-vlynq_try_remote_first.patch | 20 + .../linux/ar7/patches-3.3/500-serial_kludge.patch | 28 + target/linux/ar7/patches-3.3/920-ar7part.patch | 56 + target/linux/ar7/patches-3.3/950-cpmac_titan.patch | 52 + target/linux/ar7/patches-3.3/972-cpmac_fixup.patch | 218 + target/linux/ar7/profiles/100-Annex-A.mk | 17 + target/linux/ar7/profiles/110-Annex-B.mk | 17 + target/linux/ar7/profiles/200-Texas.mk | 18 + target/linux/ar7/profiles/210-None.mk | 17 + target/linux/ar7/src/adam2patcher.c | 59 + target/linux/ar71xx/Makefile | 29 + target/linux/ar71xx/base-files.mk | 5 + .../base-files/etc/defconfig/wndr3700/network | 69 + target/linux/ar71xx/base-files/etc/diag.sh | 196 + .../base-files/etc/hotplug.d/net/10-ar922x-led-fix | 51 + .../linux/ar71xx/base-files/etc/init.d/defconfig | 20 + target/linux/ar71xx/base-files/etc/inittab | 2 + .../etc/uci-defaults/inittab-console-fixup | 27 + .../linux/ar71xx/base-files/etc/uci-defaults/leds | 209 + .../ar71xx/base-files/etc/uci-defaults/network | 215 + .../base-files/etc/uci-defaults/vlan-migration | 13 + .../ar71xx/base-files/etc/uci-defaults/wrt160nl | 16 + target/linux/ar71xx/base-files/lib/ar71xx.sh | 455 + .../base-files/lib/preinit/03_preinit_do_ar71xx.sh | 9 + .../lib/preinit/05_enable_reset_button_ar71xx | 13 + .../base-files/lib/preinit/05_set_iface_mac_ar71xx | 39 + .../lib/preinit/05_set_preinit_iface_ar71xx | 16 + .../linux/ar71xx/base-files/lib/upgrade/allnet.sh | 160 + .../linux/ar71xx/base-files/lib/upgrade/dir825.sh | 177 + target/linux/ar71xx/base-files/lib/upgrade/om2p.sh | 169 + .../ar71xx/base-files/lib/upgrade/platform.sh | 269 + target/linux/ar71xx/base-files/sbin/wget2nand | 85 + target/linux/ar71xx/config-3.3 | 233 + .../ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c | 153 + .../ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h | 46 + .../linux/ar71xx/files/arch/mips/ath79/dev-dsa.c | 36 + .../linux/ar71xx/files/arch/mips/ath79/dev-dsa.h | 21 + .../linux/ar71xx/files/arch/mips/ath79/dev-eth.c | 1029 + .../linux/ar71xx/files/arch/mips/ath79/dev-eth.h | 48 + .../ar71xx/files/arch/mips/ath79/dev-m25p80.c | 117 + .../ar71xx/files/arch/mips/ath79/dev-m25p80.h | 17 + .../linux/ar71xx/files/arch/mips/ath79/dev-nfc.c | 95 + .../linux/ar71xx/files/arch/mips/ath79/dev-nfc.h | 27 + .../ar71xx/files/arch/mips/ath79/mach-alfa-ap96.c | 154 + .../ar71xx/files/arch/mips/ath79/mach-alfa-nx.c | 113 + .../ar71xx/files/arch/mips/ath79/mach-all0258n.c | 88 + .../ar71xx/files/arch/mips/ath79/mach-all0315n.c | 85 + .../ar71xx/files/arch/mips/ath79/mach-ap113.c | 84 + .../linux/ar71xx/files/arch/mips/ath79/mach-ap83.c | 275 + .../linux/ar71xx/files/arch/mips/ath79/mach-ap96.c | 142 + .../ar71xx/files/arch/mips/ath79/mach-aw-nr580.c | 107 + .../ar71xx/files/arch/mips/ath79/mach-dir-600-a1.c | 151 + .../ar71xx/files/arch/mips/ath79/mach-dir-615-c1.c | 133 + .../ar71xx/files/arch/mips/ath79/mach-dir-825-b1.c | 200 + .../ar71xx/files/arch/mips/ath79/mach-eap7660d.c | 181 + .../ar71xx/files/arch/mips/ath79/mach-ew-dorin.c | 144 + .../ar71xx/files/arch/mips/ath79/mach-hornet-ub.c | 136 + .../ar71xx/files/arch/mips/ath79/mach-ja76pf.c | 190 + .../ar71xx/files/arch/mips/ath79/mach-jwap003.c | 95 + .../ar71xx/files/arch/mips/ath79/mach-mzk-w04nu.c | 124 + .../ar71xx/files/arch/mips/ath79/mach-mzk-w300nh.c | 115 + .../ar71xx/files/arch/mips/ath79/mach-nbg460n.c | 220 + .../linux/ar71xx/files/arch/mips/ath79/mach-om2p.c | 176 + .../linux/ar71xx/files/arch/mips/ath79/mach-pb42.c | 83 + .../linux/ar71xx/files/arch/mips/ath79/mach-pb92.c | 70 + .../ar71xx/files/arch/mips/ath79/mach-rb2011.c | 271 + .../ar71xx/files/arch/mips/ath79/mach-rb4xx.c | 405 + .../ar71xx/files/arch/mips/ath79/mach-rb750.c | 337 + .../ar71xx/files/arch/mips/ath79/mach-rw2458n.c | 100 + .../ar71xx/files/arch/mips/ath79/mach-tew-632brp.c | 109 + .../ar71xx/files/arch/mips/ath79/mach-tew-673gru.c | 210 + .../ar71xx/files/arch/mips/ath79/mach-tew-712br.c | 163 + .../ar71xx/files/arch/mips/ath79/mach-tl-mr11u.c | 130 + .../ar71xx/files/arch/mips/ath79/mach-tl-mr3020.c | 125 + .../ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c | 146 + .../files/arch/mips/ath79/mach-tl-wa901nd-v2.c | 104 + .../ar71xx/files/arch/mips/ath79/mach-tl-wa901nd.c | 109 + .../ar71xx/files/arch/mips/ath79/mach-tl-wdr4300.c | 204 + .../files/arch/mips/ath79/mach-tl-wr1041n-v2.c | 154 + .../files/arch/mips/ath79/mach-tl-wr1043nd.c | 141 + .../ar71xx/files/arch/mips/ath79/mach-tl-wr2543n.c | 156 + .../ar71xx/files/arch/mips/ath79/mach-tl-wr703n.c | 85 + .../files/arch/mips/ath79/mach-tl-wr741nd-v4.c | 135 + .../ar71xx/files/arch/mips/ath79/mach-tl-wr741nd.c | 130 + .../files/arch/mips/ath79/mach-tl-wr841n-v8.c | 159 + .../ar71xx/files/arch/mips/ath79/mach-tl-wr841n.c | 140 + .../ar71xx/files/arch/mips/ath79/mach-tl-wr941nd.c | 121 + .../linux/ar71xx/files/arch/mips/ath79/mach-ubnt.c | 205 + .../files/arch/mips/ath79/mach-whr-hp-g300n.c | 155 + .../files/arch/mips/ath79/mach-wlae-ag300n.c | 114 + .../ar71xx/files/arch/mips/ath79/mach-wndr3700.c | 172 + .../ar71xx/files/arch/mips/ath79/mach-wnr2000.c | 145 + .../ar71xx/files/arch/mips/ath79/mach-wp543.c | 107 + .../ar71xx/files/arch/mips/ath79/mach-wpe72.c | 96 + .../ar71xx/files/arch/mips/ath79/mach-wrt160nl.c | 126 + .../ar71xx/files/arch/mips/ath79/mach-wrt400n.c | 161 + .../files/arch/mips/ath79/mach-wzr-hp-ag300h.c | 213 + .../files/arch/mips/ath79/mach-wzr-hp-g300nh.c | 287 + .../files/arch/mips/ath79/mach-wzr-hp-g300nh2.c | 177 + .../files/arch/mips/ath79/mach-wzr-hp-g450h.c | 169 + .../ar71xx/files/arch/mips/ath79/mach-zcn-1523h.c | 157 + target/linux/ar71xx/files/arch/mips/ath79/nvram.c | 75 + target/linux/ar71xx/files/arch/mips/ath79/nvram.h | 19 + .../ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.c | 123 + .../ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.h | 6 + .../ar71xx/files/arch/mips/ath79/routerboot.c | 100 + .../ar71xx/files/arch/mips/ath79/routerboot.h | 26 + .../arch/mips/include/asm/fw/myloader/myloader.h | 34 + .../mips/include/asm/mach-ath79/ag71xx_platform.h | 60 + .../arch/mips/include/asm/mach-ath79/mach-rb750.h | 84 + .../arch/mips/include/asm/mach-ath79/rb4xx_cpld.h | 48 + .../ar71xx/files/drivers/gpio/gpio-nxp-74hc153.c | 247 + .../linux/ar71xx/files/drivers/leds/leds-rb750.c | 144 + .../ar71xx/files/drivers/leds/leds-wndr3700-usb.c | 76 + .../ar71xx/files/drivers/mtd/nand/ar934x_nfc.c | 1151 + .../ar71xx/files/drivers/mtd/nand/rb4xx_nand.c | 309 + .../ar71xx/files/drivers/mtd/nand/rb750_nand.c | 367 + target/linux/ar71xx/files/drivers/mtd/tplinkpart.c | 197 + .../linux/ar71xx/files/drivers/mtd/wrt160nl_part.c | 205 + .../linux/ar71xx/files/drivers/net/dsa/mv88e6063.c | 294 + .../drivers/net/ethernet/atheros/ag71xx/Kconfig | 33 + .../drivers/net/ethernet/atheros/ag71xx/Makefile | 15 + .../drivers/net/ethernet/atheros/ag71xx/ag71xx.h | 477 + .../net/ethernet/atheros/ag71xx/ag71xx_ar7240.c | 1193 + .../net/ethernet/atheros/ag71xx/ag71xx_ar8216.c | 44 + .../net/ethernet/atheros/ag71xx/ag71xx_debugfs.c | 280 + .../net/ethernet/atheros/ag71xx/ag71xx_ethtool.c | 124 + .../net/ethernet/atheros/ag71xx/ag71xx_main.c | 1258 + .../net/ethernet/atheros/ag71xx/ag71xx_mdio.c | 315 + .../net/ethernet/atheros/ag71xx/ag71xx_phy.c | 235 + target/linux/ar71xx/files/drivers/spi/spi-ap83.c | 283 + .../ar71xx/files/drivers/spi/spi-rb4xx-cpld.c | 441 + target/linux/ar71xx/files/drivers/spi/spi-rb4xx.c | 507 + .../linux/ar71xx/files/drivers/spi/spi-vsc7385.c | 621 + .../linux/ar71xx/files/include/linux/nxp_74hc153.h | 24 + .../files/include/linux/platform/ar934x_nfc.h | 30 + .../linux/ar71xx/files/include/linux/spi/vsc7385.h | 19 + target/linux/ar71xx/files/net/dsa/mv88e6063.c | 294 + target/linux/ar71xx/generic/config-default | 1 + target/linux/ar71xx/generic/profiles/00-default.mk | 17 + target/linux/ar71xx/generic/profiles/01-minimal.mk | 16 + target/linux/ar71xx/generic/profiles/02-ath5k.mk | 16 + target/linux/ar71xx/generic/profiles/alfa.mk | 42 + target/linux/ar71xx/generic/profiles/allnet.mk | 39 + target/linux/ar71xx/generic/profiles/atheros.mk | 129 + target/linux/ar71xx/generic/profiles/atlantis.mk | 17 + target/linux/ar71xx/generic/profiles/buffalo.mk | 96 + target/linux/ar71xx/generic/profiles/compex.mk | 28 + target/linux/ar71xx/generic/profiles/d-link.mk | 63 + target/linux/ar71xx/generic/profiles/ew.mk | 20 + target/linux/ar71xx/generic/profiles/jjplus.mk | 39 + target/linux/ar71xx/generic/profiles/linksys.mk | 27 + target/linux/ar71xx/generic/profiles/netgear.mk | 17 + target/linux/ar71xx/generic/profiles/openmesh.mk | 18 + target/linux/ar71xx/generic/profiles/planex.mk | 28 + target/linux/ar71xx/generic/profiles/redwave.mk | 17 + target/linux/ar71xx/generic/profiles/tp-link.mk | 204 + target/linux/ar71xx/generic/profiles/trendnet.mk | 51 + target/linux/ar71xx/generic/profiles/ubnt.mk | 50 + target/linux/ar71xx/generic/profiles/zcomax.mk | 28 + target/linux/ar71xx/generic/profiles/zyxel.mk | 17 + target/linux/ar71xx/generic/target.mk | 7 + target/linux/ar71xx/image/Makefile | 901 + target/linux/ar71xx/image/lzma-loader/Makefile | 64 + .../ar71xx/image/lzma-loader/src/LzmaDecode.c | 584 + .../ar71xx/image/lzma-loader/src/LzmaDecode.h | 113 + .../linux/ar71xx/image/lzma-loader/src/LzmaTypes.h | 45 + target/linux/ar71xx/image/lzma-loader/src/Makefile | 99 + .../ar71xx/image/lzma-loader/src/ar71xx_regs.h | 725 + target/linux/ar71xx/image/lzma-loader/src/board.c | 56 + target/linux/ar71xx/image/lzma-loader/src/cache.c | 43 + target/linux/ar71xx/image/lzma-loader/src/cache.h | 17 + .../linux/ar71xx/image/lzma-loader/src/cacheops.h | 85 + target/linux/ar71xx/image/lzma-loader/src/config.h | 31 + .../linux/ar71xx/image/lzma-loader/src/cp0regdef.h | 39 + target/linux/ar71xx/image/lzma-loader/src/head.S | 118 + target/linux/ar71xx/image/lzma-loader/src/loader.c | 263 + .../linux/ar71xx/image/lzma-loader/src/loader.lds | 35 + .../ar71xx/image/lzma-loader/src/lzma-data.lds | 8 + target/linux/ar71xx/image/lzma-loader/src/printf.c | 350 + target/linux/ar71xx/image/lzma-loader/src/printf.h | 18 + target/linux/ar71xx/modules.mk | 86 + target/linux/ar71xx/nand/config-default | 29 + target/linux/ar71xx/nand/profiles/01-minimal.mk | 16 + target/linux/ar71xx/nand/profiles/02-ath5k.mk | 16 + target/linux/ar71xx/nand/target.mk | 8 + ...OHCI-Add-a-generic-platform-device-driver.patch | 293 + ...EHCI-Add-a-generic-platform-device-driver.patch | 305 + ...-USB-use-generic-platform-driver-on-ath79.patch | 544 + .../100-MIPS-ath79-separate-common-PCI-code.patch | 150 + .../101-MIPS-ath79-rename-pci-ath724x.h.patch | 102 + ...make-ath724x_pcibios_init-visible-for-ext.patch | 61 + ...79-add-a-common-PCI-registration-function.patch | 78 + ...rename-pci-ath724x.c-to-make-it-reflect-t.patch | 316 + .../105-MIPS-ath79-replace-ath724x-to-ar724x.patch | 264 + ...79-use-io-accessor-macros-in-pci-ar724x.c.patch | 131 + ...remove-superfluous-alignment-checks-from-.patch | 38 + ...fix-broken-ar724x_pci_-read-write-functio.patch | 134 + ...add-a-workaround-for-a-PCI-controller-bug.patch | 134 + .../110-MIPS-ath79-fix-a-wrong-IRQ-number.patch | 73 + ...add-PCI-IRQ-handling-code-for-AR724X-SoCs.patch | 213 + ...-get-rid-of-some-ifdefs-in-mach-ubnt-xm.c.patch | 64 + ...allow-to-use-board-specific-pci_plat_dev_.patch | 141 + ...add-support-for-the-PCI-host-controller-o.patch | 436 + ...79-allow-to-use-SoC-specific-PCI-IRQ-maps.patch | 165 + ...ath79-remove-ar724x_pci_add_data-function.patch | 86 + ...register-PCI-controller-on-the-PB44-board.patch | 34 + ...update-copyright-headers-of-PCI-related-f.patch | 71 + ...ath79-add-early_printk-support-for-AR934X.patch | 56 + ...sort-case-statements-in-ath79_detect_sys_.patch | 58 + ...S-ath79-add-SoC-detection-code-for-AR934X.patch | 124 + ...-add-clock-initialization-code-for-AR934X.patch | 198 + ...PS-ath79-add-GPIO-support-code-for-AR934X.patch | 102 + ...S-ath79-rework-IP2-IP3-interrupt-handling.patch | 158 + ...PS-ath79-add-IRQ-handling-code-for-AR934X.patch | 194 + ...add-AR934X-specific-glue-to-ath79_device_.patch | 60 + ...th79-register-UART-device-for-AR934X-SoCs.patch | 27 + ...h79-add-WMAC-registration-code-for-AR934X.patch | 116 + ...-MIPS-ath79-add-PCI_AR724X-Kconfig-symbol.patch | 66 + ...th79-add-PCI-registration-code-for-AR934X.patch | 62 + ...add-initial-support-for-the-Atheros-DB120.patch | 196 + ...use-correct-IRQ-number-for-the-OHCI-contr.patch | 37 + ...use-a-helper-function-for-USB-resource-in.patch | 140 + ...79-add-USB-platform-setup-code-for-AR934X.patch | 78 + ...register-USB-host-controller-on-the-DB120.patch | 28 + ...use-correct-fractional-dividers-for-CPU-D.patch | 49 + ...fix-CPU-DDR-frequency-calculation-for-SRI.patch | 205 + ...724x-avoid-data-bus-error-due-to-a-missin.patch | 78 + ...724x-use-correct-value-for-AR724X_PCI_MEM.patch | 24 + ...2-MIPS-pci-ar71xx-fix-AR71XX_PCI_MEM_SIZE.patch | 21 + ...S-pci-ar724x-convert-to-a-platform-driver.patch | 94 + ...S-pci-ar71xx-convert-to-a-platform-driver.patch | 104 + ...move-global-PCI-defines-into-a-common-hea.patch | 94 + ...register-platform-devices-for-the-PCI-con.patch | 119 + ...remove-unused-ar7-1x-24-x_pcibios_init-fu.patch | 147 + ...possible-resource-conflict-in-register_pc.patch | 35 + ...724x-use-dynamically-allocated-PCI-contro.patch | 307 + ...PS-pci-ar724x-remove-static-PCI-resources.patch | 131 + ...PS-pci-ar724x-use-per-controller-IRQ-base.patch | 110 + ...724x-setup-command-register-of-the-PCI-co.patch | 165 + ...71xx-use-dynamically-allocated-PCI-contro.patch | 228 + ...71xx-remove-static-PCI-controller-resourc.patch | 70 + ...add-early-printk-support-for-the-QCA955X-.patch | 31 + ...add-SoC-detection-code-for-the-QCA9558-So.patch | 91 + ...th79-add-clock-setup-for-the-QCA955X-SoCs.patch | 167 + ...add-IRQ-handling-code-for-the-QCA955X-SoC.patch | 239 + ...-add-GPIO-setup-code-for-the-QCA955X-SoCs.patch | 39 + ...add-QCA955X-specific-glue-to-ath79_device.patch | 31 + ...-ath79-register-UART-for-the-QCA955X-SoCs.patch | 22 + ...add-USB-controller-registration-code-for-.patch | 93 + ...add-WMAC-registration-code-for-the-QCA955.patch | 70 + ...allow-to-specify-bus-number-in-PCI-IRQ-ma.patch | 34 + ...add-PCI-controller-registration-code-for-.patch | 103 + ...add-support-for-the-Qualcomm-Atheros-AP13.patch | 213 + ...0-spi-ath79-add-delay-between-SCK-changes.patch | 122 + ...ath79-add-missing-HIGH-LOW-SCK-transition.patch | 21 + ...ath79-remove-superfluous-chip-select-code.patch | 30 + .../203-spi-ath79-use-gpio_request_one.patch | 56 + ...void-multiple-initialization-of-the-SPI-c.patch | 108 + .../205-spi-ath79-add-shutdown-handler.patch | 45 + ...ath79-make-chipselect-logic-more-flexible.patch | 313 + ...210-MIPS-ath79-simplify-misc-irq-handling.patch | 66 + ...33x_uart-improve-serial-clock-calculation.patch | 181 + ...-ehcpi-platform-remove-ehci_update_device.patch | 11 + .../310-lib-add-rle-decompression.patch | 114 + .../401-mtd-physmap-add-lock-unlock.patch | 94 + .../patches-3.3/402-mtd-SST39VF6401B-support.patch | 29 + .../403-mtd_fix_cfi_cmdset_0002_status_check.patch | 69 + .../patches-3.3/404-mtd-wrt160nl-trx-parser.patch | 25 + .../405-mtd-tp-link-partition-parser.patch | 34 + ...mtd-m25p80-allow-to-specify-max-read-size.patch | 112 + ...low-to-pass-probe-types-via-platform-data.patch | 23 + .../408-mtd-redboot_partition_scan.patch | 45 + .../patches-3.3/409-mtd-rb4xx_nand_driver.patch | 21 + .../patches-3.3/410-mtd-rb750-nand-driver.patch | 21 + .../411-mtd-cfi_cmdset_0002-force-word-write.patch | 61 + ...412-mtd-m25p80-zero-partition-parser-data.patch | 10 + .../patches-3.3/413-mtd-ar934x-nand-driver.patch | 21 + .../patches-3.3/420-net-ar71xx_mac_driver.patch | 28 + .../422-dsa-trailer-tag-validation-fix.patch | 11 + .../patches-3.3/423-dsa-add-88e6063-driver.patch | 24 + .../430-drivers-link-spi-before-mtd.patch | 12 + .../patches-3.3/431-spi-add-various-flags.patch | 19 + .../patches-3.3/432-spi-rb4xx-spi-driver.patch | 25 + .../patches-3.3/433-spi-rb4xx-cpld-driver.patch | 26 + .../patches-3.3/434-spi-ap83_spi_controller.patch | 27 + .../patches-3.3/435-spi-vsc7385_driver.patch | 23 + .../440-leds-wndr3700-usb-led-driver.patch | 26 + .../patches-3.3/441-leds-rb750-led-driver.patch | 23 + .../450-gpio-nxp-74hc153-gpio-chip-driver.patch | 26 + .../460-spi-bitbang-export-spi_bitbang_bufs.patch | 28 + .../461-spi-add-type-field-to-spi_transfer.patch | 23 + .../462-mtd-m25p80-set-spi-transfer-type.patch | 15 + .../463-spi-ath79-add-fast-flash-read.patch | 185 + ...MIPS-ath79-swizzle-pci-address-for-ar71xx.patch | 111 + .../ar71xx/patches-3.3/500-MIPS-fw-myloader.patch | 22 + ...9-add-mac-argument-to-ath79_register_wmac.patch | 81 + .../502-MIPS-ath79-export-ath79_gpio_base.patch | 23 + .../503-MIPS-ath79-add-flash-acquire-release.patch | 37 + ...504-MIPS-ath79-add-ath79_device_reset_get.patch | 45 + ...MIPS-ath79-add-ath79_gpio_function_select.patch | 47 + .../506-MIPS-ath79-prom-parse-redboot-args.patch | 86 + .../507-MIPS-ath79-prom-add-myloader-support.patch | 58 + ...8-MIPS-ath79-prom-image-command-line-hack.patch | 57 + ...09-MIPS-ath79-process-board-kernel-option.patch | 11 + ...0-MIPS-ath79-init-gpio-pin-of-wmac-device.patch | 14 + ...1-MIPS-ath79-add-ath79_set_usb_power_gpio.patch | 47 + .../520-MIPS-ath79-enable-UART-function.patch | 18 + ...1-MIPS-ath79-enable-UART-for-early_serial.patch | 61 + .../601-MIPS-ath79-add-more-register-defines.patch | 304 + .../602-MIPS-ath79-add-openwrt-stuff.patch | 76 + .../patches-3.3/603-MIPS-ath79-ap121-fixes.patch | 163 + .../patches-3.3/604-MIPS-ath79-ap81-fixes.patch | 128 + .../patches-3.3/605-MIPS-ath79-db120-fixes.patch | 219 + .../patches-3.3/606-MIPS-ath79-pb44-fixes.patch | 153 + .../patches-3.3/607-MIPS-ath79-ubnt-xm-fixes.patch | 109 + .../608-MIPS-ath79-ubnt-xm-add-more-boards.patch | 200 + .../patches-3.3/609-MIPS-ath79-ap136-fixes.patch | 175 + .../610-MIPS-ath79-openwrt-machines.patch | 793 + .../611-MIPS-ath79-TL-MR3040-support.patch | 21 + .../612-MIPS-ath79-TL-WR841N-v8-support.patch | 38 + .../patches-3.3/620-MIPS-ath79-OTP-support.patch | 166 + .../patches-3.3/630-MIPS-ath79-enable-dsp.patch | 10 + .../650-MIPS-ath79-fix-ar933x-reset.patch | 31 + .../901-mdio_bitbang_ignore_ta_value.patch | 20 + .../patches-3.3/902-unaligned_access_hacks.patch | 117 + .../linux/at91/9260/base-files/etc/config/network | 20 + .../linux/at91/9260/base-files/etc/config/system | 9 + .../9260/base-files/etc/init.d/custom-user-startup | 22 + target/linux/at91/9260/config-default | 12 + .../at91/9260/profiles/000-flexibity-minimal.mk | 18 + .../linux/at91/9260/profiles/001-flexibity-xwrt.mk | 26 + .../linux/at91/9260/profiles/002-flexibity-luci.mk | 26 + target/linux/at91/9260/target.mk | 16 + target/linux/at91/9263/config-default | 21 + target/linux/at91/9263/target.mk | 11 + target/linux/at91/9g20/config-default | 7 + target/linux/at91/9g20/target.mk | 12 + target/linux/at91/Makefile | 25 + target/linux/at91/base-files/etc/config/firewall | 6 + target/linux/at91/base-files/etc/config/network | 20 + target/linux/at91/config-default | 199 + .../at91/files/arch/arm/mach-at91/board-tqma9263.c | 219 + target/linux/at91/files/drivers/misc/at91-adc.c | 355 + target/linux/at91/files/drivers/misc/at91_adc.h | 62 + target/linux/at91/files/drivers/mtd/at91part.c | 120 + target/linux/at91/image/Config.in | 37 + target/linux/at91/image/Makefile | 38 + target/linux/at91/image/dfboot/Makefile | 35 + target/linux/at91/image/dfboot/src/Makefile | 94 + target/linux/at91/image/dfboot/src/_udivsi3.S | 77 + target/linux/at91/image/dfboot/src/_umodsi3.S | 88 + target/linux/at91/image/dfboot/src/asm_isr.S | 75 + target/linux/at91/image/dfboot/src/asm_mci_isr.S | 75 + target/linux/at91/image/dfboot/src/at45.c | 595 + target/linux/at91/image/dfboot/src/com.c | 368 + target/linux/at91/image/dfboot/src/com.h | 28 + target/linux/at91/image/dfboot/src/config.h | 17 + target/linux/at91/image/dfboot/src/cstartup_ram.S | 144 + target/linux/at91/image/dfboot/src/dataflash.c | 208 + target/linux/at91/image/dfboot/src/dataflash.h | 181 + target/linux/at91/image/dfboot/src/div0.c | 28 + .../at91/image/dfboot/src/elf32-littlearm.lds | 19 + .../at91/image/dfboot/src/embedded_services.h | 500 + .../image/dfboot/src/include/AT91C_MCI_Device.h | 379 + .../at91/image/dfboot/src/include/AT91RM9200.h | 2745 + .../at91/image/dfboot/src/include/AT91RM9200.inc | 2437 + .../at91/image/dfboot/src/include/AT91RM9200_inc.h | 2401 + target/linux/at91/image/dfboot/src/include/led.h | 49 + .../at91/image/dfboot/src/include/lib_AT91RM9200.h | 2978 + target/linux/at91/image/dfboot/src/init.c | 165 + target/linux/at91/image/dfboot/src/jump.S | 4 + target/linux/at91/image/dfboot/src/led.c | 103 + target/linux/at91/image/dfboot/src/main.c | 811 + target/linux/at91/image/dfboot/src/main.h | 43 + target/linux/at91/image/dfboot/src/mci_device.c | 743 + target/linux/at91/image/dfboot/src/stdio.h | 18 + target/linux/at91/image/u-boot/Makefile | 51 + .../at91/image/u-boot/patches/100-netusg20.patch | 574 + .../at91/image/u-boot/patches/200-clock.patch | 24 + target/linux/at91/image/u-boot/ubclient/Makefile | 15 + target/linux/at91/image/u-boot/ubclient/ubpar.c | 135 + target/linux/at91/modules.mk | 68 + .../linux/at91/patches/700-tqma9263-support.patch | 25 + .../at91/patches/805-free_some_portc_pins.patch | 11 + ...AT91-Add-external-RTC-for-Flexibity-board.patch | 35 + ...-AT91-flexibity-default-leds-to-heartbeat.patch | 60 + target/linux/atheros/Makefile | 24 + target/linux/atheros/base-files/etc/config/system | 23 + .../base-files/etc/hotplug.d/button/00-button | 24 + .../linux/atheros/base-files/etc/uci-defaults/leds | 11 + .../atheros/base-files/etc/uci-defaults/network | 45 + .../lib/preinit/15_preinit_iface_atheros | 35 + .../atheros/base-files/lib/upgrade/platform.sh | 76 + target/linux/atheros/config-3.3 | 113 + target/linux/atheros/image/Makefile | 62 + .../patches-3.3/001-get_c0_compare_int_fix.patch | 39 + target/linux/atheros/patches-3.3/100-board.patch | 3165 + .../patches-3.3/101-early-printk-support.patch | 68 + .../linux/atheros/patches-3.3/105-ar2315_pci.patch | 294 + .../atheros/patches-3.3/110-ar2313_ethernet.patch | 1620 + .../linux/atheros/patches-3.3/120-spiflash.patch | 661 + .../linux/atheros/patches-3.3/130-watchdog.patch | 228 + .../patches-3.3/140-redboot_partition_scan.patch | 45 + .../141-redboot_various_erase_size_fix.patch | 72 + .../atheros/patches-3.3/210-reset_button.patch | 72 + .../patches-3.3/220-enet_micrel_workaround.patch | 55 + target/linux/au1000/Makefile | 32 + target/linux/au1000/au1500/config-3.3 | 141 + target/linux/au1000/au1500/profiles/Atheros.mk | 13 + target/linux/au1000/au1500/profiles/InternetBox.mk | 18 + target/linux/au1000/au1500/profiles/MeshCube.mk | 18 + target/linux/au1000/au1500/target.mk | 7 + target/linux/au1000/au1550/config-3.3 | 140 + target/linux/au1000/au1550/profiles/DBAu1550.mk | 13 + target/linux/au1000/au1550/target.mk | 7 + target/linux/au1000/base-files/etc/diag.sh | 25 + .../au1000/base-files/lib/upgrade/platform.sh | 36 + target/linux/au1000/image/Makefile | 71 + target/linux/au1000/modules.mk | 16 + .../au1000/patches-3.3/002-openwrt_rootfs.patch | 11 + .../au1000/patches-3.3/003-au1000_eth_ioctl.patch | 17 + .../au1000/patches-3.3/004-pci-idsel-cb.patch | 12 + target/linux/avr32/Makefile | 23 + target/linux/avr32/config-3.3 | 103 + target/linux/avr32/image/Config.in | 13 + target/linux/avr32/image/Makefile | 55 + target/linux/avr32/image/u-boot/Makefile | 35 + .../patches/100-ngw100_enable_lzma_support.patch | 10 + target/linux/avr32/modules.mk | 38 + .../avr32/patches-3.3/110-openwrt_flashmap.patch | 19 + target/linux/brcm2708/Makefile | 28 + .../linux/brcm2708/base-files/etc/config/network | 13 + target/linux/brcm2708/base-files/etc/inittab | 5 + target/linux/brcm2708/config-3.3 | 248 + target/linux/brcm2708/image/Config.in | 5 + target/linux/brcm2708/image/Makefile | 46 + target/linux/brcm2708/image/cmdline.txt | 1 + target/linux/brcm2708/image/gen_rpi_sdcard_img.sh | 29 + target/linux/brcm2708/modules.mk | 26 + .../patches-3.3/0001-Add-dwc_otg-driver.patch | 43253 ++++++++++ .../patches-3.3/0002-Main-bcm2708-linux-port.patch | 11023 +++ .../patches-3.3/0003-bcm2708-watchdog-driver.patch | 436 + .../0004-bcm2708-framebuffer-driver.patch | 2990 + .../patches-3.3/0005-bcm2708-vchiq-driver.patch | 16383 ++++ ...6-Allow-mac-address-to-be-set-in-smsc95xx.patch | 96 + ...07-Fix-headers-for-vchiq-vcos-to-be-GPLv2.patch | 1493 + .../0500-rpi-patches-geaf792a-9efb4705.patch | 10488 +++ .../brcm2708/patches-3.3/0510-fix_divdi3.patch | 11 + target/linux/brcm2708/profiles/100-RaspberryPi.mk | 17 + target/linux/brcm47xx/Makefile | 24 + target/linux/brcm47xx/base-files.mk | 5 + target/linux/brcm47xx/base-files/etc/diag.sh | 28 + .../linux/brcm47xx/base-files/etc/init.d/netconfig | 247 + .../linux/brcm47xx/base-files/etc/init.d/wmacfixup | 33 + .../lib/preinit/03_init_hotplug_failsafe_brcm | 9 + .../base-files/lib/preinit/05_init_interfaces_brcm | 37 + .../base-files/lib/preinit/05_reset_button_brcm | 8 + .../lib/preinit/05_set_failsafe_switch_brcm | 15 + .../base-files/lib/preinit/15_mount_proc_brcm | 6 + .../lib/preinit/15_set_preinit_interface_brcm | 39 + .../lib/preinit/20_failsafe_net_echo_brcm | 12 + .../lib/preinit/20_failsafe_set_boot_wait_brcm | 14 + .../brcm47xx/base-files/lib/upgrade/platform.sh | 16 + .../brcm47xx/base-files/sbin/hotplug.failsafe | 4 + target/linux/brcm47xx/config-3.3 | 146 + target/linux/brcm47xx/image/Makefile | 129 + target/linux/brcm47xx/image/lzma-loader/Makefile | 33 + .../brcm47xx/image/lzma-loader/src/LzmaDecode.c | 663 + .../brcm47xx/image/lzma-loader/src/LzmaDecode.h | 100 + .../linux/brcm47xx/image/lzma-loader/src/Makefile | 77 + target/linux/brcm47xx/image/lzma-loader/src/README | 55 + .../brcm47xx/image/lzma-loader/src/decompress.c | 186 + .../image/lzma-loader/src/decompress.lds.in | 20 + target/linux/brcm47xx/image/lzma-loader/src/head.S | 160 + .../brcm47xx/image/lzma-loader/src/loader.lds.in | 17 + target/linux/brcm47xx/modules.mk | 51 + ...X-return-number-of-written-bytes-in-nvram.patch | 12 + ...47XX-fix-signature-of-nvram_parse_macaddr.patch | 11 + ...IPS-BCM47XX-move-and-extend-sprom-parsing.patch | 802 + ...04-MIPS-BCM47XX-provide-sprom-to-bcma-bus.patch | 80 + .../005-ssb-remove-rev-from-boardinfo.patch | 11 + ...MIPS-bcm47xx-refactor-fetching-board-data.patch | 46 + .../007-bcma-add-boardinfo-struct.patch | 41 + ...x-read-baordrev-without-prefix-from-sprom.patch | 11 + .../patches-3.3/009-bcma_reorder_sprom_fill.patch | 44 + ...MIPS-BCM47xx-Fix-BCMA_DRIVER_PCI_HOSTMODE.patch | 10 + ...020-bcma-move-parallel-flash-into-a-union.patch | 129 + ...021-bcma-add-serial-flash-support-to-bcma.patch | 505 + .../022-ssb-move-flash-to-chipcommon.patch | 151 + .../023-ssb-add-serial-flash-support.patch | 573 + ...-brcm47xx-add-common-interface-for-sflash.patch | 168 + .../025-mtd-bcm47xx-add-bcm47xx-part-parser.patch | 571 + ...026-mtd-bcm47xx-add-parallel-flash-driver.patch | 216 + .../027-mtd-bcm47xx-add-serial-flash-driver.patch | 291 + .../028-bcm47xx-register-flash-drivers.patch | 136 + .../029-bcm47xx-read-nvram-from-sflash.patch | 143 + .../patches-3.3/030-bcm47xx-bcma-nandflash.patch | 1146 + .../044-bcma-add-PCIe-host-controller.patch | 76 + ...S-BCM47xx-Setup-and-register-serial-early.patch | 69 + .../116-MIPS-BCM47xx-Remove-CFE-console.patch | 141 + .../linux/brcm47xx/patches-3.3/119-fix-boot.patch | 16 + .../linux/brcm47xx/patches-3.3/150-cpu_fixes.patch | 367 + .../brcm47xx/patches-3.3/160-kmap_coherent.patch | 77 + .../brcm47xx/patches-3.3/170-fix-74k-cpu.patch | 12 + ...OHCI-Add-a-generic-platform-device-driver.patch | 271 + ...EHCI-Add-a-generic-platform-device-driver.patch | 283 + .../183-USB-Add-driver-for-the-bcma-bus.patch | 362 + .../184-USB-Add-driver-for-the-ssb-bus.patch | 308 + .../185-USB-OHCI-remove-old-SSB-OHCI-driver.patch | 340 + .../patches-3.3/186-USB-EHCI-bcma-fix-driver.patch | 11 + .../187-USB-EHCI-platform-remove-update.patch | 11 + .../191-MIPS-BCM47XX-ignore-last-memory-page.patch | 33 + ...IPS-BCM47XX-improve-memory-size-detection.patch | 38 + ...193-MIPS-BCM47xx-read-out-full-board-data.patch | 81 + ...X-read-sprom-without-prefix-if-no-ieee802.patch | 11 + ...x-sprom-read-values-without-prefix-as-fal.patch | 1095 + ...do-the-necessary-things-in-early-register.patch | 181 + .../202-bcma-init-sprom-struct-earlier.patch | 37 + ...llback-sprom-if-sprom-on-card-was-not-val.patch | 15 + ...-do-not-initialize-deactivated-PCIe-cores.patch | 26 + .../brcm47xx/patches-3.3/210-b44_phy_fix.patch | 54 + .../patches-3.3/211-b44_timeout_spam.patch | 15 + .../patches-3.3/240-bcma-pcie-config-access.patch | 104 + .../280-activate_ssb_support_in_usb.patch | 25 + .../brcm47xx/patches-3.3/300-fork_cacheflush.patch | 11 + .../brcm47xx/patches-3.3/310-no_highpage.patch | 66 + .../brcm47xx/patches-3.3/400-arch-bcm47xx.patch | 56 + ...d-function-to-return-number-of-gpio-lines.patch | 40 + .../patches-3.3/501-bcma-add-gpio-driver.patch | 140 + .../502-bcm47xx-rewrite-gpio-handling.patch | 493 + .../brcm47xx/patches-3.3/610-pci_ide_fix.patch | 14 + .../700-ssb-gigabit-ethernet-driver.patch | 439 + .../patches-3.3/812-disable_wgt634u_crap.patch | 187 + .../patches-3.3/820-wgt634u-nvram-fix.patch | 305 + .../patches-3.3/900-bcm47xx_wdt-noprescale.patch | 104 + .../brcm47xx/patches-3.3/920-cache-wround.patch | 138 + .../brcm47xx/patches-3.3/940-bcm47xx-yenta.patch | 46 + .../patches-3.3/976-ssb_increase_pci_delay.patch | 11 + .../980-wnr834b_no_cardbus_invariant.patch | 13 + .../brcm47xx/patches-3.3/999-wl_exports.patch | 22 + target/linux/brcm47xx/profiles/100-Broadcom-b43.mk | 19 + target/linux/brcm47xx/profiles/101-Broadcom-wl.mk | 20 + .../linux/brcm47xx/profiles/104-Broadcom-ath5k.mk | 18 + .../linux/brcm47xx/profiles/105-Broadcom-none.mk | 17 + target/linux/brcm47xx/profiles/110-Bcm4705-b43.mk | 19 + target/linux/brcm47xx/profiles/115-Bcm4705-none.mk | 17 + target/linux/brcm47xx/profiles/PS-1208MFG.mk | 18 + target/linux/brcm47xx/profiles/WGT634U.mk | 17 + target/linux/brcm47xx/profiles/WL500GPv1-ATH.mk | 16 + target/linux/brcm47xx/profiles/WRT350Nv1.mk | 16 + target/linux/brcm47xx/profiles/WRTSL54GS.mk | 17 + target/linux/brcm63xx/Makefile | 27 + target/linux/brcm63xx/base-files.mk | 5 + target/linux/brcm63xx/base-files/etc/diag.sh | 71 + .../linux/brcm63xx/base-files/etc/init.d/defconfig | 18 + .../base-files/etc/uci-defaults/brcm63xx_fixcrc.sh | 28 + .../brcm63xx/base-files/etc/uci-defaults/network | 54 + target/linux/brcm63xx/base-files/lib/brcm63xx.sh | 94 + .../base-files/lib/preinit/03_do_brcm63xx.sh | 7 + .../lib/preinit/05_failsafe_config_switch_brcm63xx | 15 + .../lib/preinit/05_init_interfaces_brcm63xx | 26 + .../lib/preinit/05_reset_button_brcm63xx | 16 + .../lib/preinit/15_set_preinit_interface_brcm63xx | 44 + .../lib/preinit/20_failsafe_net_echo_brcm63xx | 12 + .../brcm63xx/base-files/lib/upgrade/platform.sh | 16 + target/linux/brcm63xx/config-3.3 | 161 + .../arch/mips/include/asm/mach-bcm63xx/bcm_tag.h | 70 + target/linux/brcm63xx/image/Makefile | 259 + target/linux/brcm63xx/image/README.images-bcm63xx | 127 + target/linux/brcm63xx/image/lzma-loader/Makefile | 33 + .../brcm63xx/image/lzma-loader/src/LzmaDecode.c | 663 + .../brcm63xx/image/lzma-loader/src/LzmaDecode.h | 100 + .../linux/brcm63xx/image/lzma-loader/src/Makefile | 77 + target/linux/brcm63xx/image/lzma-loader/src/README | 55 + .../brcm63xx/image/lzma-loader/src/decompress.c | 175 + .../image/lzma-loader/src/decompress.lds.in | 20 + target/linux/brcm63xx/image/lzma-loader/src/head.S | 155 + .../brcm63xx/image/lzma-loader/src/loader.lds.in | 17 + target/linux/brcm63xx/modules.mk | 37 + .../001-MIPS-BCM63XX-fix-platform_devices-id.patch | 36 + ...X-be-consistent-in-clock-bits-enable-nami.patch | 93 + ...X-add-IRQ_SPI-and-CPU-specific-SPI-IRQ-va.patch | 68 + ...S-BCM63XX-define-BCM6358-SPI-base-address.patch | 21 + ...5-MIPS-BCM63XX-add-BCM6368-SPI-clock-mask.patch | 26 + ...06-MIPS-BCM63XX-define-SPI-register-sizes.patch | 26 + .../007-MIPS-BCM63XX-remove-SPI2-register.patch | 83 + ...X-define-internal-registers-offsets-of-th.patch | 140 + ...X-add-stub-to-register-the-SPI-platform-d.patch | 243 + ...X-make-board-setup-code-register-the-spi-.patch | 29 + ...dd-Broadcom-BCM63xx-SPI-controller-driver.patch | 532 + ...m63xxpart-handle-Broadcom-partition-order.patch | 101 + ...-convert-to-the-pump-message-infrastructu.patch | 289 + ...-spi-bcm63xx-don-t-use-the-stopping-state.patch | 68 + ...5-spi-bcm63xx-set-master-driver-mode_bits.patch | 24 + .../016-spi-bcm63xx-fix-bcm6348-38.patch | 128 + ...-MIPS-BCM63XX-fix-BCM6368-IPSec-clock-bit.patch | 23 + ...-MIPS-BCM63XX-add-support-for-ipsec-clock.patch | 48 + ...PS-BCM63XX-add-RNG-peripheral-definitions.patch | 113 + ...M63XX-add-RNG-driver-platform_device-stub.patch | 71 + ...hw_random-add-Broadcom-BCM63xx-RNG-driver.patch | 229 + ...X-Move-flash-registration-out-of-board_bc.patch | 202 + ...023-MIPS-BCM63XX-Add-flash-type-detection.patch | 137 + ...X-Use-the-Chip-ID-register-for-identifyin.patch | 53 + ...25-MIPS-BCM63XX-Add-basic-BCM6328-support.patch | 590 + ...X-Move-the-PCI-initialization-into-its-ow.patch | 61 + ...MIPS-BCM63XX-Add-PCIe-Support-for-BCM6328.patch | 427 + .../028-MIPS-Expose-PCIe-drivers-for-MIPS.patch | 28 + ...XX-add-missing-include-for-bcm63xx_gpio.h.patch | 41 + ...01-MTD-bcm63xxpart-remove-unused-variable.patch | 41 + ...TD-bcm63xxpart-merge-sparelen-calculation.patch | 33 + ...part-make-fixed-part-length-calculation-m.patch | 49 + ...part-move-the-last-curpart-to-its-correct.patch | 26 + ...part-use-correct-printk-format-for-partit.patch | 27 + .../106-bcm63xx_watchdog_section_mismatch.patch | 20 + ...-BCM63XX-Fix-USB-IRQ-definitions-for-6328.patch | 26 + ...X-Add-register-definitions-for-USBD-depen.patch | 62 + ...llow-specifying-the-parsers-for-SPI-flash.patch | 38 + ...-m25p80-use-parsers-if-provided-in-flash-.patch | 23 + ...CES-m25p80-add-support-for-limiting-reads.patch | 92 + .../brcm63xx/patches-3.3/300-reset_buttons.patch | 116 + .../linux/brcm63xx/patches-3.3/301-led_count.patch | 41 + .../302-extended-platform-devices.patch | 25 + .../brcm63xx/patches-3.3/303-spi-board-info.patch | 33 + .../brcm63xx/patches-3.3/304-boardid_fixup.patch | 61 + .../patches-3.3/305-missing_ext_irq_bits.patch | 96 + ...-BCM63XX-Call-board_register_device-from-.patch | 23 + ...MIPS-BCM63XX-allow-second-UART-on-BCM6328.patch | 22 + .../308-MIPS-BCM63XX-expose-the-HS-SPI-clock.patch | 48 + ...PS-BCM63XX-add-HSSPI-register-definitions.patch | 211 + .../patches-3.3/310-board_leds_naming.patch | 267 + .../brcm63xx/patches-3.3/311-cfe_version_mod.patch | 26 + ...12-MIPS-BCM63XX-add-basic-BCM6362-support.patch | 497 + .../313-MIPS-BCM63XX-enable-pcie-for-BCM6362.patch | 110 + ...-driver-for-bcm63xx-integrated-controller.patch | 234 + .../401-MIPS-BCM63XX-register-ohci-device.patch | 143 + ...-driver-for-bcm63xx-integrated-controller.patch | 241 + .../403-MIPS-BCM63XX-register-ehci-device.patch | 125 + .../patches-3.3/404-bcm963xx_flashmap.patch | 65 + .../405-bcm963xx_real_rootfs_length.patch | 27 + .../406_bcm63xx_enet_vlan_incoming_fixed.patch | 11 + .../408-6358-enet1-external-mii-clk.patch | 22 + ..._enet-move-phy_-dis-connect-into-probe-re.patch | 169 + ...63xx_enet-implement-reset_autoneg-ethtool.patch | 40 + .../412-bcm63xx_enet-use-resource_size.patch | 69 + ...t-disable-clock-when-uninitializing-devic.patch | 20 + ...4-bcm63xx_enet-split-dma-registers-access.patch | 381 + ...t-add-support-for-bcm6368-internal-ethern.patch | 1490 + ...t-reset-port-link-state-in-bcm_enetsw_ope.patch | 28 + ...t-don-t-overwrite-settings-when-setting-d.patch | 20 + ...t-store-the-number-of-ports-instead-of-ha.patch | 98 + ...t-store-is_sw-in-a-variable-instead-of-ch.patch | 73 + .../420-BCM63XX-allow-enetsw-without-tx-irq.patch | 69 + ...3XX-use-port-id-for-deciding-external-phy.patch | 87 + ...enet-enable-rgmii-clock-on-external-ports.patch | 53 + .../423-bcm63xx_enet-fix-lockup-on-BCM6328.patch | 93 + ...3XX-add-support-for-BCM6328-in-bcm_enetsw.patch | 103 + ...X-add-HS-SPI-platform-device-and-register.patch | 128 + .../426-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch | 481 + ...IPS-BCM63XX-Register-SPI-flash-if-present.patch | 102 + ...S-BCM63XX-add-flash-detection-for-BCM6362.patch | 50 + ...X-move-nvram-related-functions-into-their.patch | 351 + ...9-MIPS-BCM63XX-export-PSI-size-from-nvram.patch | 44 + ...30-MTD-bcm63xxpart-use-nvram-for-PSI-size.patch | 29 + .../431-MTD-physmap-allow-passing-pp_data.patch | 41 + ...-allow-providing-fixup-data-in-board-data.patch | 81 + .../433-MTD-m25p80-allow-passing-pp_data.patch | 40 + ...X-store-the-flash-type-in-global-variable.patch | 122 + ...435-BCM63XX-add-a-fixup-for-ath9k-devices.patch | 227 + ...cm63xxpart-allow-passing-a-caldata-offset.patch | 118 + ...7-MIPS-BCM63XX-pass-caldata-info-to-flash.patch | 82 + .../438-MIPS-BCM63XX-enable-USB-for-BCM6328.patch | 60 + ...X-wire-up-the-HS-SPI-controller-for-BCM63.patch | 56 + ...BCM63XX-enable-SPI-controller-for-BCM6362.patch | 101 + .../441-MIPS-BCM63XX-enable-USB-for-BCM6362.patch | 84 + ...42-MIPS-BCM63XX-enable-enetsw-for-BCM6362.patch | 77 + .../brcm63xx/patches-3.3/500-board-D4PW.patch | 65 + .../linux/brcm63xx/patches-3.3/501-board-NB4.patch | 640 + .../patches-3.3/502-board-96338W2_E7T.patch | 49 + .../brcm63xx/patches-3.3/503-board-CPVA642.patch | 107 + .../patches-3.3/504-board_dsl_274xb_rev_c.patch | 70 + .../brcm63xx/patches-3.3/505-board_spw500v.patch | 78 + .../patches-3.3/506-board_gw6200_gw6000.patch | 124 + .../brcm63xx/patches-3.3/507-board-MAGIC.patch | 87 + .../brcm63xx/patches-3.3/508-board_hw553.patch | 91 + .../patches-3.3/509-board_rta1320_16m.patch | 54 + .../brcm63xx/patches-3.3/510-board_spw303v.patch | 83 + .../brcm63xx/patches-3.3/511-board_V2500V.patch | 122 + .../brcm63xx/patches-3.3/512-board_BTV2110.patch | 73 + .../brcm63xx/patches-3.3/513-board_livebox.patch | 391 + .../patches-3.3/514-board_ct536_ct5621.patch | 60 + .../patches-3.3/515-board_DWV-S0_fixes.patch | 19 + .../patches-3.3/516-board_96348A-122.patch | 78 + .../patches-3.3/517-RTA1205W_16_uart_fixes.patch | 10 + .../patches-3.3/519_board_CPVA502plus.patch | 55 + ...0-bcm63xx-add-support-for-96368MVWG-board.patch | 128 + ...-bcm63xx-add-support-for-96368MVNgr-board.patch | 92 + ...IPS-BCM63XX-add-96328avng-reference-board.patch | 102 + ...IPS-BCM63XX-add-963281TAN-reference-board.patch | 96 + .../patches-3.3/524-board_dsl_274xb_rev_f.patch | 130 + .../brcm63xx/patches-3.3/525-board_96348w3.patch | 68 + .../brcm63xx/patches-3.3/526-board_CT6373-1.patch | 136 + .../patches-3.3/527-board_dva-g3810bn-tl-1.patch | 82 + .../linux/brcm63xx/patches-3.3/528-board_nb6.patch | 146 + .../patches-3.3/550-alice_gate2_leds.patch | 102 + .../brcm63xx/patches-3.3/551-96348gw_a_leds.patch | 22 + .../552-board_96348gw-10_reset_button.patch | 20 + .../brcm63xx/patches-3.3/800-wl_exports.patch | 34 + .../801-ssb_export_fallback_sprom.patch | 27 + .../802-rtl8367r_fix_RGMII_support.patch | 30 + target/linux/brcm63xx/profiles/100-Broadcom.mk | 17 + target/linux/brcm63xx/profiles/101-Broadcom-wl.mk | 19 + target/linux/brcm63xx/profiles/102-Atheros.mk | 17 + target/linux/brcm63xx/profiles/103-Ralink.mk | 13 + target/linux/brcm63xx/profiles/104-No-WiFi.mk | 17 + .../brcm63xx/profiles/105-Broadcom-brcmsmac.mk | 17 + target/linux/brcm63xx/profiles/200-GW6X00.mk | 21 + target/linux/cns21xx/Makefile | 27 + target/linux/cns21xx/base-files/etc/diag.sh | 54 + .../linux/cns21xx/base-files/etc/uci-defaults/leds | 21 + target/linux/cns21xx/base-files/lib/cns21xx.sh | 25 + .../lib/preinit/05_cns21xx_load_button_drivers | 11 + .../cns21xx/base-files/lib/upgrade/platform.sh | 45 + target/linux/cns21xx/config-3.3 | 135 + target/linux/cns21xx/image/Makefile | 120 + .../patches-3.3/002-arm-debugll-printk.patch | 24 + .../003-arm-introduce-fa-platform.patch | 56 + .../cns21xx/patches-3.3/004-arm-add-fa-time.patch | 143 + .../patches-3.3/005-arm-add-fa-gpio-driver.patch | 343 + .../006-arm-add-fa-watchdog-driver.patch | 458 + .../cns21xx/patches-3.3/100-cns21xx-core.patch | 2048 + .../patches-3.3/101-cns21xx-serial-support.patch | 103 + .../patches-3.3/102-cns21xx-gpiolib-support.patch | 85 + .../patches-3.3/103-cns21xx-usb-ohci-support.patch | 230 + .../patches-3.3/104-cns21xx-usb-ehci-support.patch | 213 + .../patches-3.3/105-cns21xx-spi-driver.patch | 578 + .../patches-3.3/106-cns21xx-gec-driver.patch | 2507 + .../patches-3.3/201-cns21xx-add-usb-devices.patch | 104 + .../202-cns21xx-add-watchdog-device.patch | 63 + .../203-cns21xx-add-spi-master-device.patch | 117 + .../patches-3.3/204-cns21xx-add-gec-device.patch | 178 + .../patches-3.3/301-cns21xx-mach-ns-k330.patch | 234 + .../patches-3.3/302-cns21xx-mach-nsb3ast.patch | 201 + target/linux/cns21xx/profiles/00-default.mk | 17 + target/linux/cns3xxx/Makefile | 27 + target/linux/cns3xxx/config-3.3 | 194 + target/linux/cns3xxx/image/Makefile | 41 + .../patches-3.3/001-cns3xxx-clkdev-support.patch | 69 + .../cns3xxx/patches-3.3/002-cns3xxx_wdt.patch | 69 + .../patches-3.3/049-cns3xxx_smp_support.patch | 414 + .../patches-3.3/050-cns3xxx_i2c_controller.patch | 421 + .../cns3xxx/patches-3.3/051-cns3xxx_gigabit.patch | 1385 + .../cns3xxx/patches-3.3/052-cns3xxx_spi.patch | 509 + .../patches-3.3/054-cns3xxx_pcie_clock.patch | 11 + .../patches-3.3/055-cns3xxx_pci_iospace_init.patch | 76 + .../patches-3.3/060-move_virtual_io_space.patch | 198 + .../linux/cns3xxx/patches-3.3/061-twd_base.patch | 20 + .../cns3xxx/patches-3.3/100-add_io_spaces.patch | 19 + .../patches-3.3/101-laguna_sdhci_card_detect.patch | 16 + .../cns3xxx/patches-3.3/102-cns3xxx_timers.patch | 109 + .../cns3xxx/patches-3.3/104-cns3xxx_gpio.patch | 218 + .../cns3xxx/patches-3.3/105-cns3xxx_pcie_io.patch | 88 + .../patches-3.3/106-cns3xxx_sata_support.patch | 97 + .../107-cns3xxx_pcie-section-mismatch-fixes.patch | 17 + .../patches-3.3/108-cns3xxx_pcie-abort.patch | 128 + .../patches-3.3/110-gateworks_gsp_support.patch | 339 + target/linux/cns3xxx/patches-3.3/200-dwc_otg.patch | 22807 +++++ .../cns3xxx/patches-3.3/300-laguna_support.patch | 949 + .../400-ethernet_fix_tx_csum_offload.patch | 89 + .../patches-3.3/410-ethernet_fix_jumbo_frame.patch | 506 + .../420-ethernet_optimize_rx_offload.patch | 27 + .../430-ethernet_fix_tx_completion.patch | 110 + .../linux/cns3xxx/patches-3.3/440-i2c_retry.patch | 72 + .../linux/cns3xxx/patches-3.3/450-smp_ncores.patch | 109 + .../patches-3.3/460-cns3xxx_fiq_support.patch | 429 + target/linux/cobalt/Makefile | 24 + target/linux/cobalt/base-files/etc/diag.sh | 20 + target/linux/cobalt/config-3.3 | 171 + target/linux/cobalt/image/Makefile | 23 + target/linux/cobalt/modules.mk | 36 + target/linux/coldfire/Makefile | 23 + target/linux/coldfire/config-default | 116 + target/linux/coldfire/image/Makefile | 34 + ...fire-architecture-support-in-Linux-2.6.38.patch | 11199 +++ ...4451-and-MCF54455-support-in-Linux-2.6.38.patch | 10546 +++ ...F547x-and-MCF548x-support-in-Linux-2.6.38.patch | 7673 ++ .../004-MCF54418-support-in-Linux-2.6.38.patch | 6643 ++ ...driver-and-irda-driver-support-for-MCF544.patch | 200 + ...ver-support-for-MCF5445x-MCF5441x-MCF547x.patch | 2759 + .../007-Add-eDMA-support-for-MCF5445x.patch | 1639 + ...DSPI-driver-support-for-MCF5445x-MCF5441x.patch | 1580 + .../patches/009-Add-ALSA-driver-for-MCF5445x.patch | 1869 + ...M-char-device-driver-support-for-MCF5445x.patch | 198 + ...-Add-CAU-driver-for-MCF5445x-and-MCF5441x.patch | 2514 + ...12-Add-vDSO-support-for-Coldfire-platform.patch | 497 + ...13-Add-MCD-DMA-driver-for-MCF547x-MCF548x.patch | 5318 ++ ...Add-CFV4E-FPU-support-for-MCF547x-MCF548x.patch | 23 + ...r-to-support-ten-UART-devices-on-MCF5441x.patch | 104 + ...d-nand-driver-support-for-M54418TWR-board.patch | 1381 + ...u-dma-sync-function-for-coldfire-platform.patch | 68 + ...-TFT-LCD-framebuffer-driver-on-TWR-MCF544.patch | 973 + ...mat-field-for-the-Coldfire-exception-fram.patch | 27 + .../020-Add-dual-FEC-1588-timer-support.patch | 1257 + ...1-Add-ethernet-switch-driver-for-MCF54418.patch | 6152 ++ ...022-Redefine-I-O-read-and-write-functions.patch | 32 + ...3-Replace-readl-and-writel-for-FEC-driver.patch | 357 + ...d-SEC-1.1-support-for-MCF547x-and-MCF548x.patch | 2093 + ...d-I2C-driver-for-MCF5445x-MCF547x-MCF548x.patch | 1216 + .../026-Add-RTC-driver-support-for-MCF5445x.patch | 627 + ...d-RTC-driver-support-on-MCF5441x-platform.patch | 681 + ...SDIO-over-SPI-support-for-MCF54451-and-MC.patch | 195 + .../029-Add-eSDHC-driver-for-MCF5441x.patch | 2214 + ...ice-configuration-for-FXS-and-FXO-on-MCF5.patch | 38 + ...g-driver-support-for-MCF5445x-and-MCF547x.patch | 338 + ...2-Change-some-jffs2-warning-to-debug-info.patch | 33 + ...re-fsl_ssd1289_data-definition-bug-for-SS.patch | 49 + .../034-Enable-the-NFC-driver-for-soft_ecc.patch | 50 + ...-support-on-ColdFire-M548X-M54418-platfor.patch | 764 + ...-ColdFire-MCF54455-PATA-interface-support.patch | 934 + ...mebuffer-support-for-Silicon-Motion-s-Lyn.patch | 1287 + ...PCI-bus-driver-for-M54455EVB-and-M547X_8X.patch | 3051 + ...Add-USB-support-for-MCF5445x-and-MCF54418.patch | 7007 ++ ...-CAU-driver-bug-for-SHA1-digest-algorithm.patch | 25 + ...LTIPLE_NODES-unmet-direct-dependencies-wa.patch | 24 + ...d-for-zero-page-used-on-ColdFire-platform.patch | 33 + .../patches/044-Fix-Max3353-otg-toggle-bug.patch | 26 + ...-Add-high-resolution-kernel-timer-support.patch | 24 + ...-drivers-to-use-the-alarm_irq_enable-meth.patch | 109 + ...ix-DSPI-compile-error-for-MCF547x-MCF548x.patch | 37 + ...i2c-driver-bug-when-reinserting-as-module.patch | 75 + ...date-FEC-driver-for-MCF5445x-and-MCF54418.patch | 113 + ...date-the-DMA-map-function-for-CF-platform.patch | 37 + ...MC-over-SPI-driver-for-MCF54451-and-MCF54.patch | 105 + ...default-configurations-for-ColdFire-V4-bo.patch | 6983 ++ ...8-Fix-FEC-driver-bugs-for-MCF547x-MCF548x.patch | 180 + ...mebuffer-driver-data-swap-bug-for-MCF5441.patch | 49 + ...SDIO-over-SPI-driver-bug-when-reinserting.patch | 34 + ...8-Fix-i2c-driver-could-not-work-as-module.patch | 30 + .../coldfire/patches/200-fec_select_phylib.patch | 10 + target/linux/ep93xx/Makefile | 24 + target/linux/ep93xx/base-files/etc/inittab | 5 + .../base-files/lib/preinit/05_set_ether_mac_rdc | 12 + target/linux/ep93xx/config-3.3 | 196 + target/linux/ep93xx/image/Makefile | 51 + target/linux/ep93xx/modules.mk | 104 + .../ep93xx/patches-3.3/001-ep93xx_cpuinfo.patch | 59 + .../patches-3.3/003-ep93xx_touchscreen.patch | 1061 + .../patches-3.3/004-simone_add_mmc_spi.patch | 180 + target/linux/ep93xx/profiles/00-default.mk | 17 + target/linux/ep93xx/profiles/01-simone.mk | 22 + target/linux/etrax/Makefile | 33 + target/linux/etrax/base-files/etc/config/firewall | 6 + target/linux/etrax/base-files/etc/config/network | 18 + target/linux/etrax/config-default | 173 + .../files/arch/cris/arch-v10/drivers/etraxi2c.h | 49 + .../files/arch/cris/arch-v10/drivers/i2c_errno.h | 20 + .../files/arch/cris/arch-v10/drivers/i2c_gvc.c | 1404 + .../files/arch/cris/arch-v10/drivers/i2c_gvc.h | 30 + .../etrax/files/drivers/usb/host/hc-cris-dbg.h | 142 + .../etrax/files/drivers/usb/host/hc-crisv10.c | 4959 ++ .../etrax/files/drivers/usb/host/hc-crisv10.h | 334 + target/linux/etrax/image/Config.in | 5 + target/linux/etrax/image/Makefile | 42 + target/linux/etrax/image/boot_linux | 511 + target/linux/etrax/image/e100boot/Makefile | 34 + target/linux/etrax/image/mkfimage/Makefile | 29 + target/linux/etrax/image/mkfimage/src/Makefile | 4 + target/linux/etrax/image/mkfimage/src/mkfimage.c | 72 + .../etrax/patches-2.6.32/100-cris-makefiles.patch | 53 + .../linux/etrax/patches-2.6.32/201-flashsize.patch | 88 + .../etrax/patches-2.6.32/300-usb_support.patch | 20 + .../etrax/patches-2.6.32/400-Kconfig_source.patch | 86 + .../linux/etrax/patches-2.6.32/500-i2c_gvc.patch | 54 + .../patches-2.6.32/600-create-device-serial.patch | 44 + .../610-create-the-gpio-devices.patch | 50 + .../620-create-the-i2c-devices.patch | 32 + .../etrax/patches-2.6.32/985-cris-headers.patch | 27 + target/linux/etrax/profiles/100-generic.mk | 16 + target/linux/etrax/profiles/101-vhdl-nofb.mk | 16 + target/linux/gemini/Makefile | 20 + .../base-files/lib/preinit/05_set_ether_mac_gemini | 13 + target/linux/gemini/config-3.3 | 138 + target/linux/gemini/image/Makefile | 58 + .../001-gemini-fix-gpio_set_irq_type.patch | 11 + ...emini-fix-platform_register_rtc-prototype.patch | 23 + .../110-watchdog-add-gemini_wdt-driver.patch | 410 + .../111-arm-gemini-add-watchdog-device.patch | 32 + .../112-arm-gemini-register-watchdog-devices.patch | 40 + .../120-net-add-gemini-gmac-driver.patch | 2901 + .../121-arm-gemini-add-ethernet-device.patch | 81 + .../122-arm-gemini-wbd111-register-ethernet.patch | 41 + .../123-arm-gemini-wbd222-register-eth.patch | 43 + .../124-arm-gemini-rut100-register-ethernet.patch | 47 + .../130-usb-ehci-gemini-fot2gxx-support.patch | 615 + .../131-arm-gemini-add-usb-platform-device.patch | 74 + .../132-arm-gemini-wbd111-register-usb.patch | 24 + .../133-arm-gemini-wbd222-register-usb.patch | 10 + .../134-arm-gemini-rut100-register-usb.patch | 10 + .../135-arm-gemini-nas4220-register-usb.patch | 11 + .../140-arm-gemini-add-pci-support.patch | 390 + target/linux/generic/PATCHES | 15 + target/linux/generic/base-files/init | 96 + target/linux/generic/config-3.3 | 3473 + .../files/Documentation/networking/adm6996.txt | 110 + target/linux/generic/files/Documentation/pwm.txt | 260 + .../generic/files/arch/mips/fw/myloader/Makefile | 5 + .../generic/files/arch/mips/fw/myloader/myloader.c | 63 + target/linux/generic/files/crypto/ocf/Config.in | 38 + target/linux/generic/files/crypto/ocf/Kconfig | 125 + target/linux/generic/files/crypto/ocf/Makefile | 148 + .../linux/generic/files/crypto/ocf/c7108/Makefile | 12 + .../generic/files/crypto/ocf/c7108/aes-7108.c | 841 + .../generic/files/crypto/ocf/c7108/aes-7108.h | 134 + target/linux/generic/files/crypto/ocf/criov.c | 215 + target/linux/generic/files/crypto/ocf/crypto.c | 1766 + .../generic/files/crypto/ocf/cryptocteon/Makefile | 17 + .../files/crypto/ocf/cryptocteon/README.txt | 11 + .../files/crypto/ocf/cryptocteon/cavium_crypto.c | 2283 + .../files/crypto/ocf/cryptocteon/cryptocteon.c | 576 + target/linux/generic/files/crypto/ocf/cryptodev.c | 1069 + target/linux/generic/files/crypto/ocf/cryptodev.h | 480 + target/linux/generic/files/crypto/ocf/cryptosoft.c | 1322 + .../generic/files/crypto/ocf/ep80579/Makefile | 119 + .../files/crypto/ocf/ep80579/environment.mk | 78 + .../generic/files/crypto/ocf/ep80579/icp_asym.c | 1334 + .../generic/files/crypto/ocf/ep80579/icp_common.c | 773 + .../generic/files/crypto/ocf/ep80579/icp_ocf.h | 376 + .../generic/files/crypto/ocf/ep80579/icp_sym.c | 1153 + .../crypto/ocf/ep80579/linux_2.6_kernel_space.mk | 69 + .../linux/generic/files/crypto/ocf/hifn/Makefile | 13 + .../linux/generic/files/crypto/ocf/hifn/hifn7751.c | 2954 + .../generic/files/crypto/ocf/hifn/hifn7751reg.h | 540 + .../generic/files/crypto/ocf/hifn/hifn7751var.h | 368 + .../linux/generic/files/crypto/ocf/hifn/hifnHIPP.c | 421 + .../generic/files/crypto/ocf/hifn/hifnHIPPreg.h | 46 + .../generic/files/crypto/ocf/hifn/hifnHIPPvar.h | 93 + .../linux/generic/files/crypto/ocf/ixp4xx/Makefile | 104 + .../linux/generic/files/crypto/ocf/ixp4xx/ixp4xx.c | 1339 + .../generic/files/crypto/ocf/kirkwood/Makefile | 19 + .../files/crypto/ocf/kirkwood/cesa/AES/mvAes.h | 62 + .../files/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c | 317 + .../files/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h | 19 + .../files/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c | 312 + .../crypto/ocf/kirkwood/cesa/AES/mvAesBoxes.dat | 123 + .../files/crypto/ocf/kirkwood/cesa/mvCesa.c | 3126 + .../files/crypto/ocf/kirkwood/cesa/mvCesa.h | 412 + .../files/crypto/ocf/kirkwood/cesa/mvCesaDebug.c | 484 + .../files/crypto/ocf/kirkwood/cesa/mvCesaRegs.h | 357 + .../files/crypto/ocf/kirkwood/cesa/mvCesaTest.c | 3096 + .../files/crypto/ocf/kirkwood/cesa/mvCompVer.txt | 4 + .../generic/files/crypto/ocf/kirkwood/cesa/mvLru.c | 158 + .../generic/files/crypto/ocf/kirkwood/cesa/mvLru.h | 112 + .../generic/files/crypto/ocf/kirkwood/cesa/mvMD5.c | 349 + .../generic/files/crypto/ocf/kirkwood/cesa/mvMD5.h | 93 + .../files/crypto/ocf/kirkwood/cesa/mvSHA1.c | 239 + .../files/crypto/ocf/kirkwood/cesa/mvSHA1.h | 88 + .../files/crypto/ocf/kirkwood/cesa_ocf_drv.c | 1302 + .../crypto/ocf/kirkwood/mvHal/common/mv802_3.h | 213 + .../crypto/ocf/kirkwood/mvHal/common/mvCommon.c | 277 + .../crypto/ocf/kirkwood/mvHal/common/mvCommon.h | 308 + .../crypto/ocf/kirkwood/mvHal/common/mvCompVer.txt | 4 + .../crypto/ocf/kirkwood/mvHal/common/mvDebug.c | 326 + .../crypto/ocf/kirkwood/mvHal/common/mvDebug.h | 178 + .../crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h | 225 + .../crypto/ocf/kirkwood/mvHal/common/mvHalVer.h | 73 + .../crypto/ocf/kirkwood/mvHal/common/mvStack.c | 100 + .../crypto/ocf/kirkwood/mvHal/common/mvStack.h | 140 + .../crypto/ocf/kirkwood/mvHal/common/mvTypes.h | 245 + .../files/crypto/ocf/kirkwood/mvHal/dbg-trace.c | 110 + .../files/crypto/ocf/kirkwood/mvHal/dbg-trace.h | 24 + .../mvHal/kw_family/boardEnv/mvBoardEnvLib.c | 2513 + .../mvHal/kw_family/boardEnv/mvBoardEnvLib.h | 376 + .../mvHal/kw_family/boardEnv/mvBoardEnvSpec.c | 848 + .../mvHal/kw_family/boardEnv/mvBoardEnvSpec.h | 262 + .../ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c | 320 + .../ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h | 99 + .../mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c | 296 + .../mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h | 203 + .../mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h | 98 + .../mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c | 1825 + .../mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h | 185 + .../mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h | 419 + .../mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h | 257 + .../mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c | 1048 + .../mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h | 130 + .../mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h | 143 + .../kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c | 1036 + .../kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h | 120 + .../mvHal/kw_family/ctrlEnv/sys/mvCpuIfInit.S | 163 + .../mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h | 304 + .../mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c | 324 + .../mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h | 123 + .../mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c | 382 + .../mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h | 100 + .../mvHal/kw_family/ctrlEnv/sys/mvSysDram.c | 348 + .../mvHal/kw_family/ctrlEnv/sys/mvSysDram.h | 80 + .../mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c | 658 + .../mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h | 113 + .../mvHal/kw_family/ctrlEnv/sys/mvSysPex.c | 1697 + .../mvHal/kw_family/ctrlEnv/sys/mvSysPex.h | 348 + .../mvHal/kw_family/ctrlEnv/sys/mvSysSata.c | 430 + .../mvHal/kw_family/ctrlEnv/sys/mvSysSata.h | 128 + .../mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c | 427 + .../mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h | 125 + .../mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c | 462 + .../mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h | 106 + .../kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c | 591 + .../kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h | 110 + .../mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c | 497 + .../mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h | 125 + .../mvHal/kw_family/ctrlEnv/sys/mvSysXor.c | 662 + .../mvHal/kw_family/ctrlEnv/sys/mvSysXor.h | 140 + .../ocf/kirkwood/mvHal/kw_family/device/mvDevice.c | 75 + .../ocf/kirkwood/mvHal/kw_family/device/mvDevice.h | 74 + .../kirkwood/mvHal/kw_family/device/mvDeviceRegs.h | 101 + .../ocf/kirkwood/mvHal/kw_family/mvCompVer.txt | 4 + .../crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c | 211 + .../crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h | 423 + .../crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h | 158 + .../crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h | 375 + .../ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c | 376 + .../ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h | 121 + .../ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h | 121 + .../ocf/kirkwood/mvHal/mv_hal/cntmr/mvCompVer.txt | 4 + .../ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c | 207 + .../ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h | 213 + .../ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c | 143 + .../ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h | 151 + .../ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvCompVer.txt | 4 + .../ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c | 1479 + .../ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h | 191 + .../ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c | 1599 + .../ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h | 179 + .../mvHal/mv_hal/ddr1_2/mvDramIfBasicInit.S | 988 + .../kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.S | 668 + .../kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h | 192 + .../kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h | 306 + .../ocf/kirkwood/mvHal/mv_hal/ddr2/mvCompVer.txt | 4 + .../ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c | 1855 + .../ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h | 172 + .../kirkwood/mvHal/mv_hal/ddr2/mvDramIfBasicInit.S | 986 + .../kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.S | 528 + .../kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h | 157 + .../ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h | 423 + .../mvHal/mv_hal/ddr2/mvDramIfStaticInit.h | 179 + .../ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c | 1474 + .../ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h | 192 + .../ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c | 2952 + .../ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c | 748 + .../ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h | 146 + .../ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h | 751 + .../ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h | 700 + .../ocf/kirkwood/mvHal/mv_hal/eth/mvCompVer.txt | 4 + .../crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h | 356 + .../ocf/kirkwood/mvHal/mv_hal/gpp/mvCompVer.txt | 4 + .../crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c | 362 + .../crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h | 118 + .../ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h | 116 + .../ocf/kirkwood/mvHal/mv_hal/pci-if/mvCompVer.txt | 4 + .../ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c | 669 + .../ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h | 134 + .../ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h | 245 + .../mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c | 1006 + .../mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h | 323 + .../ocf/kirkwood/mvHal/mv_hal/pci/mvCompVer.txt | 4 + .../crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c | 1047 + .../crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h | 185 + .../ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h | 411 + .../ocf/kirkwood/mvHal/mv_hal/pex/mvCompVer.txt | 4 + .../crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c | 1143 + .../crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h | 168 + .../ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h | 751 + .../ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c | 313 + .../ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h | 82 + .../ocf/kirkwood/mvHal/mv_hal/sflash/mvCompVer.txt | 4 + .../ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c | 1522 + .../ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h | 166 + .../kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h | 233 + .../ocf/kirkwood/mvHal/mv_hal/spi/mvCompVer.txt | 4 + .../crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c | 576 + .../crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h | 94 + .../ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c | 249 + .../ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h | 82 + .../ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h | 98 + .../ocf/kirkwood/mvHal/mv_hal/twsi/mvCompVer.txt | 4 + .../crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c | 1023 + .../crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h | 121 + .../ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiEeprom.S | 457 + .../ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h | 160 + target/linux/generic/files/crypto/ocf/ocf-bench.c | 514 + target/linux/generic/files/crypto/ocf/ocf-compat.h | 372 + .../generic/files/crypto/ocf/ocfnull/Makefile | 12 + .../generic/files/crypto/ocf/ocfnull/ocfnull.c | 204 + .../linux/generic/files/crypto/ocf/pasemi/Makefile | 12 + .../linux/generic/files/crypto/ocf/pasemi/pasemi.c | 1007 + .../generic/files/crypto/ocf/pasemi/pasemi_fnu.h | 410 + target/linux/generic/files/crypto/ocf/random.c | 317 + target/linux/generic/files/crypto/ocf/rndtest.c | 300 + target/linux/generic/files/crypto/ocf/rndtest.h | 54 + .../linux/generic/files/crypto/ocf/safe/Makefile | 12 + .../linux/generic/files/crypto/ocf/safe/hmachack.h | 37 + target/linux/generic/files/crypto/ocf/safe/md5.c | 308 + target/linux/generic/files/crypto/ocf/safe/md5.h | 76 + target/linux/generic/files/crypto/ocf/safe/safe.c | 2230 + .../linux/generic/files/crypto/ocf/safe/safereg.h | 421 + .../linux/generic/files/crypto/ocf/safe/safevar.h | 229 + target/linux/generic/files/crypto/ocf/safe/sha1.c | 279 + target/linux/generic/files/crypto/ocf/safe/sha1.h | 72 + .../generic/files/crypto/ocf/talitos/Makefile | 12 + .../generic/files/crypto/ocf/talitos/talitos.c | 1355 + .../generic/files/crypto/ocf/talitos/talitos_dev.h | 277 + .../files/crypto/ocf/talitos/talitos_soft.h | 76 + .../generic/files/crypto/ocf/ubsec_ssb/Makefile | 12 + .../generic/files/crypto/ocf/ubsec_ssb/bsdqueue.h | 527 + .../generic/files/crypto/ocf/ubsec_ssb/ubsec_ssb.c | 2220 + .../generic/files/crypto/ocf/ubsec_ssb/ubsecreg.h | 233 + .../generic/files/crypto/ocf/ubsec_ssb/ubsecvar.h | 228 + target/linux/generic/files/crypto/ocf/uio.h | 54 + target/linux/generic/files/drivers/char/gpio_dev.c | 181 + .../files/drivers/input/misc/gpio_buttons.c | 232 + .../generic/files/drivers/leds/ledtrig-morse.c | 366 + .../generic/files/drivers/leds/ledtrig-netdev.c | 451 + .../generic/files/drivers/leds/ledtrig-usbdev.c | 348 + target/linux/generic/files/drivers/mtd/myloader.c | 186 + .../linux/generic/files/drivers/net/phy/adm6996.c | 737 + .../linux/generic/files/drivers/net/phy/adm6996.h | 162 + .../linux/generic/files/drivers/net/phy/ar8216.c | 1536 + .../linux/generic/files/drivers/net/phy/ar8216.h | 341 + .../linux/generic/files/drivers/net/phy/ip17xx.c | 1410 + .../linux/generic/files/drivers/net/phy/micrel.c | 83 + .../linux/generic/files/drivers/net/phy/mvswitch.c | 422 + .../linux/generic/files/drivers/net/phy/mvswitch.h | 145 + .../linux/generic/files/drivers/net/phy/psb6970.c | 438 + .../linux/generic/files/drivers/net/phy/rtl8306.c | 1056 + .../generic/files/drivers/net/phy/rtl8366_smi.c | 1375 + .../generic/files/drivers/net/phy/rtl8366_smi.h | 149 + .../generic/files/drivers/net/phy/rtl8366rb.c | 1271 + .../linux/generic/files/drivers/net/phy/rtl8366s.c | 1150 + .../linux/generic/files/drivers/net/phy/rtl8367.c | 1775 + .../linux/generic/files/drivers/net/phy/swconfig.c | 1043 + .../generic/files/drivers/net/phy/swconfig_leds.c | 354 + target/linux/generic/files/drivers/pwm/Kconfig | 20 + target/linux/generic/files/drivers/pwm/Makefile | 5 + target/linux/generic/files/drivers/pwm/gpio-pwm.c | 298 + target/linux/generic/files/drivers/pwm/pwm.c | 643 + target/linux/generic/files/fs/yaffs2/Kconfig | 175 + target/linux/generic/files/fs/yaffs2/Makefile | 11 + target/linux/generic/files/fs/yaffs2/devextras.h | 264 + .../linux/generic/files/fs/yaffs2/moduleconfig.h | 65 + .../generic/files/fs/yaffs2/yaffs_checkptrw.c | 404 + .../generic/files/fs/yaffs2/yaffs_checkptrw.h | 35 + target/linux/generic/files/fs/yaffs2/yaffs_ecc.c | 331 + target/linux/generic/files/fs/yaffs2/yaffs_ecc.h | 44 + target/linux/generic/files/fs/yaffs2/yaffs_fs.c | 2299 + target/linux/generic/files/fs/yaffs2/yaffs_guts.c | 7469 ++ target/linux/generic/files/fs/yaffs2/yaffs_guts.h | 902 + target/linux/generic/files/fs/yaffs2/yaffs_mtdif.c | 241 + target/linux/generic/files/fs/yaffs2/yaffs_mtdif.h | 27 + .../generic/files/fs/yaffs2/yaffs_mtdif1-compat.c | 434 + .../linux/generic/files/fs/yaffs2/yaffs_mtdif1.c | 363 + .../linux/generic/files/fs/yaffs2/yaffs_mtdif1.h | 28 + .../linux/generic/files/fs/yaffs2/yaffs_mtdif2.c | 232 + .../linux/generic/files/fs/yaffs2/yaffs_mtdif2.h | 29 + target/linux/generic/files/fs/yaffs2/yaffs_nand.c | 134 + target/linux/generic/files/fs/yaffs2/yaffs_nand.h | 44 + .../generic/files/fs/yaffs2/yaffs_nandemul2k.h | 39 + .../generic/files/fs/yaffs2/yaffs_packedtags1.c | 52 + .../generic/files/fs/yaffs2/yaffs_packedtags1.h | 37 + .../generic/files/fs/yaffs2/yaffs_packedtags2.c | 182 + .../generic/files/fs/yaffs2/yaffs_packedtags2.h | 38 + target/linux/generic/files/fs/yaffs2/yaffs_qsort.c | 160 + target/linux/generic/files/fs/yaffs2/yaffs_qsort.h | 23 + .../generic/files/fs/yaffs2/yaffs_tagscompat.c | 530 + .../generic/files/fs/yaffs2/yaffs_tagscompat.h | 40 + .../generic/files/fs/yaffs2/yaffs_tagsvalidity.c | 28 + .../generic/files/fs/yaffs2/yaffs_tagsvalidity.h | 24 + .../linux/generic/files/fs/yaffs2/yaffsinterface.h | 21 + target/linux/generic/files/fs/yaffs2/yportenv.h | 187 + .../generic/files/include/linux/ar8216_platform.h | 81 + .../generic/files/include/linux/ath5k_platform.h | 30 + .../generic/files/include/linux/ath9k_platform.h | 41 + .../generic/files/include/linux/glamo-engine.h | 27 + target/linux/generic/files/include/linux/glamofb.h | 35 + .../generic/files/include/linux/gpio_buttons.h | 33 + .../linux/generic/files/include/linux/gpio_dev.h | 42 + .../linux/generic/files/include/linux/myloader.h | 121 + target/linux/generic/files/include/linux/pwm/pwm.h | 165 + .../linux/generic/files/include/linux/routerboot.h | 105 + .../generic/files/include/linux/rt2x00_platform.h | 23 + target/linux/generic/files/include/linux/rtl8366.h | 40 + target/linux/generic/files/include/linux/rtl8367.h | 59 + target/linux/generic/files/include/linux/switch.h | 237 + target/linux/generic/image/Makefile | 12 + .../linux/generic/image/initramfs-base-files.txt | 9 + target/linux/generic/image/lzma-loader/Makefile | 46 + .../generic/image/lzma-loader/src/LzmaDecode.c | 590 + .../generic/image/lzma-loader/src/LzmaDecode.h | 131 + .../linux/generic/image/lzma-loader/src/Makefile | 68 + .../generic/image/lzma-loader/src/decompress.c | 157 + .../generic/image/lzma-loader/src/lzma-copy.lds.in | 20 + .../generic/image/lzma-loader/src/lzma.lds.in | 24 + target/linux/generic/image/lzma-loader/src/print.c | 324 + target/linux/generic/image/lzma-loader/src/print.h | 36 + .../linux/generic/image/lzma-loader/src/printf.c | 35 + .../linux/generic/image/lzma-loader/src/printf.h | 18 + target/linux/generic/image/lzma-loader/src/start.S | 160 + .../generic/image/lzma-loader/src/uart16550.c | 86 + .../generic/image/lzma-loader/src/uart16550.h | 47 + .../patches-3.3/006-arm_kernel_xz_support.patch | 96 + .../linux/generic/patches-3.3/020-ssb_update.patch | 837 + .../generic/patches-3.3/025-bcma_backport.patch | 3330 + .../patches-3.3/026-bcma_pmu_regression.patch | 29 + ...27-bcma-add-missing-iounmap-on-error-path.patch | 55 + ...egression-in-interrupt-assignment-on-mips.patch | 29 + .../patches-3.3/040-Controlled-Delay-AQM.patch | 757 + ...Newton-method-instead-of-sqrt-and-divides.patch | 185 + .../042-fq_codel-Fair-Queue-Codel-AQM.patch | 839 + ...odel-Add-missing-include-linux-prefetch.h.patch | 33 + .../044-net-codel-fix-build-errors.patch | 51 + ...16-field-instead-of-31bits-for-rec_inv_sq.patch | 86 + .../patches-3.3/046-fq_codel-qdisc-backlog.patch | 132 + .../patches-3.3/047-spi_message_queue.patch | 603 + ...ll-prepare-unprepare-transfer-if-not-popu.patch | 39 + ...one-condition-to-avoid-a-nul-rec_inv_sqrt.patch | 52 + .../generic/patches-3.3/050-rng_git_backport.patch | 783 + ...ng_git_backport-remove_irqf_sample_random.patch | 543 + .../generic/patches-3.3/100-overlayfs_v12.patch | 3232 + .../patches-3.3/102-ehci_hcd_ignore_oc.patch | 41 + .../generic/patches-3.3/110-fix_mtd_include.patch | 10 + .../patches-3.3/130-pppoatm-queue-depth.patch | 188 + .../140-ixp4xx_hss_module_h_include.patch | 39 + .../generic/patches-3.3/200-fix_localversion.patch | 11 + .../patches-3.3/201-extra_optimization.patch | 24 + .../patches-3.3/202-reduce_module_size.patch | 11 + .../patches-3.3/210-darwin_scripts_include.patch | 78 + .../generic/patches-3.3/211-stddef_include.patch | 17 + .../patches-3.3/212-x86_reloc_portability.patch | 22 + .../generic/patches-3.3/220-module_exports.patch | 89 + .../patches-3.3/230-openwrt_lzma_options.patch | 54 + .../patches-3.3/250-netfilter_depends.patch | 18 + .../generic/patches-3.3/251-sound_kconfig.patch | 11 + .../generic/patches-3.3/252-mv_cesa_depends.patch | 10 + .../patches-3.3/253-ssb_b43_default_on.patch | 29 + .../patches-3.3/254-textsearch_kconfig_hacks.patch | 23 + .../patches-3.3/255-lib80211_kconfig_hacks.patch | 19 + .../256-crypto_add_kconfig_prompts.patch | 47 + .../257-wireless_ext_kconfig_hack.patch | 22 + .../258-netfilter_netlink_kconfig_hack.patch | 11 + .../patches-3.3/300-mips_expose_boot_raw.patch | 39 + .../patches-3.3/301-mips_image_cmdline_hack.patch | 28 + ...02-mips_use_generic_thread_info_allocator.patch | 18 + .../generic/patches-3.3/303-mips_fix_kexec.patch | 11 + .../generic/patches-3.3/304-mips_disable_fpu.patch | 160 + .../patches-3.3/305-mips_module_reloc.patch | 371 + .../306-mips_mem_functions_performance.patch | 83 + .../patches-3.3/307-mips_oprofile_fix.patch | 35 + .../308-mips-show-correct-cpu-name-for-24KEc.patch | 17 + .../patches-3.3/309-mips_fuse_workaround.patch | 32 + .../310-arm_module_unresolved_weak_sym.patch | 13 + .../patches-3.3/320-ppc4xx_optimization.patch | 31 + .../patches-3.3/321-powerpc_crtsavres_prereq.patch | 10 + .../322-ppc4xx-crypto-compile-fix.patch | 10 + .../330-mips-add-crash-and-kdump-support.patch | 616 + .../331-mips-kexec-enhanche-the-support.patch | 159 + ...it-the-arguments-for-the-new-kernel-image.patch | 52 + ...ec-get-kernel-parameters-from-kexec-tools.patch | 88 + ...-fix-compiling-failure-of-relocate_kernel.patch | 83 + ...ec-cleanup-kexec-tools-parameter-handling.patch | 186 + .../patches-3.3/340-module_alloc_size_check.patch | 20 + .../generic/patches-3.3/400-rootfs_split.patch | 327 + .../patches-3.3/401-partial_eraseblock_write.patch | 145 + .../410-mtd_info_move_forward_decl.patch | 18 + .../generic/patches-3.3/420-redboot_space.patch | 30 + .../patches-3.3/421-redboot_boardconfig.patch | 60 + .../430-mtd_myloader_partition_parser.patch | 35 + .../generic/patches-3.3/440-block2mtd_init.patch | 116 + .../patches-3.3/441-block2mtd_refresh.patch | 291 + .../generic/patches-3.3/442-block2mtd_probe.patch | 10 + ...ck2mtd-avoid-recursive-call-of-mtd_writev.patch | 10 + .../patches-3.3/450-mtd_plat_nand_chip_fixup.patch | 37 + ...451-mtd_fix_nand_correct_data_return_code.patch | 12 + .../460-cfi_cmdset_0002_no_erase_suspend.patch | 11 + .../470-mtd_m25p80_add_pm25lv_flash_support.patch | 39 + .../patches-3.3/473-mtd_m25p80_add_w25q128.patch | 10 + ..._cmdset_0002-add-buffer-write-cmd-timeout.patch | 18 + ...25p80-allow-to-disable-small-sector-erase.patch | 41 + ...5p80-add-support-for-the-EON-EN25Q64-chip.patch | 10 + .../generic/patches-3.3/500-yaffs_support.patch | 18 + .../patches-3.3/501-yaffs_cvs_2009_04_24.patch | 12344 +++ .../patches-3.3/502-yaffs_git_2010_10_20.patch | 27068 ++++++ .../patches-3.3/503-yaffs_symlink_bug.patch | 17 + .../generic/patches-3.3/504-yaffs_mutex_fix.patch | 20 + .../linux/generic/patches-3.3/505-2.6.39_fix.patch | 147 + .../generic/patches-3.3/506-yaffs2-3.2_fix.patch | 289 + .../generic/patches-3.3/507-yaffs2-3.3_fix.patch | 71 + .../510-jffs2_make_lzma_available.patch | 5142 ++ .../generic/patches-3.3/511-debloat_lzma.patch | 485 + .../generic/patches-3.3/512-jffs2_eofdetect.patch | 132 + .../520-squashfs_update_xz_comp_opts.patch | 25 + .../540-crypto-xz-decompression-support.patch | 146 + .../541-ubifs-xz-decompression-support.patch | 94 + .../550-ubifs-symlink-xattr-support.patch | 67 + .../patches-3.3/600-netfilter_layer7_2.22.patch | 2142 + .../601-netfilter_layer7_pktmatch.patch | 108 + .../patches-3.3/602-netfilter_layer7_match.patch | 51 + .../603-netfilter_layer7_2.6.36_fix.patch | 61 + .../604-netfilter_cisco_794x_iphone.patch | 118 + ...610-netfilter_match_bypass_default_checks.patch | 93 + .../611-netfilter_match_bypass_default_table.patch | 81 + .../612-netfilter_match_reduce_memory_access.patch | 16 + .../613-netfilter_optional_tcp_window_check.patch | 36 + .../linux/generic/patches-3.3/620-sched_esfq.patch | 791 + .../patches-3.3/621-sched_act_connmark.patch | 172 + .../patches-3.3/630-packet_socket_type.patch | 132 + .../patches-3.3/640-bridge_no_eap_forward.patch | 15 + .../patches-3.3/641-bridge_always_accept_eap.patch | 11 + .../patches-3.3/642-bridge_port_isolate.patch | 103 + .../643-bridge_remove_ipv6_dependency.patch | 107 + .../644-bridge_optimize_netfilter_hooks.patch | 146 + .../generic/patches-3.3/650-pppoe_header_pad.patch | 20 + .../patches-3.3/651-wireless_mesh_header.patch | 11 + .../patches-3.3/652-atm_header_changes.patch | 12 + .../patches-3.3/653-disable_netlink_trim.patch | 28 + .../patches-3.3/654-avoid_skb_cow_realloc.patch | 21 + .../generic/patches-3.3/655-increase_skb_pad.patch | 11 + .../linux/generic/patches-3.3/700-swconfig.patch | 29 + .../generic/patches-3.3/701-phy_extension.patch | 72 + .../702-phy_add_aneg_done_function.patch | 45 + .../710-phy-add-mdio_register_board_info.patch | 191 + .../generic/patches-3.3/720-phy_adm6996.patch | 26 + .../generic/patches-3.3/721-phy_packets.patch | 175 + .../generic/patches-3.3/722-phy_mvswitch.patch | 23 + .../linux/generic/patches-3.3/723-phy_ip175c.patch | 23 + .../linux/generic/patches-3.3/724-phy_ar8216.patch | 24 + .../generic/patches-3.3/725-phy_rtl8306.patch | 23 + .../generic/patches-3.3/726-phy_rtl8366.patch | 45 + .../generic/patches-3.3/727-phy-rtl8367.patch | 23 + .../linux/generic/patches-3.3/728-phy-micrel.patch | 24 + .../linux/generic/patches-3.3/729-phy-tantos.patch | 21 + .../generic/patches-3.3/750-hostap_txpower.patch | 154 + .../810-pci_disable_common_quirks.patch | 43 + .../811-pci_disable_usb_common_quirks.patch | 38 + .../820-usb_add_usb_find_device_by_name.patch | 84 + .../generic/patches-3.3/830-ledtrig_morse.patch | 28 + .../generic/patches-3.3/831-ledtrig_netdev.patch | 51 + .../generic/patches-3.3/832-ledtrig_usbdev.patch | 31 + target/linux/generic/patches-3.3/835-gpiodev.patch | 27 + target/linux/generic/patches-3.3/840-rtc7301.patch | 250 + .../generic/patches-3.3/841-rtc_pt7c4338.patch | 247 + .../generic/patches-3.3/850-glamo_headers.patch | 21 + .../861-04_spi_gpio_implement_spi_delay.patch | 58 + .../generic/patches-3.3/862-gpio_spi_driver.patch | 373 + target/linux/generic/patches-3.3/863-gpiommc.patch | 844 + .../patches-3.3/864-gpiommc_configfs_locking.patch | 58 + target/linux/generic/patches-3.3/865-gpiopwm.patch | 21 + .../patches-3.3/870-hifn795x_byteswap.patch | 17 + .../generic/patches-3.3/900-slab_maxsize.patch | 13 + .../generic/patches-3.3/910-kobject_uevent.patch | 21 + .../911-kobject_add_broadcast_uevent.patch | 85 + .../patches-3.3/920-unable_to_open_console.patch | 11 + .../patches-3.3/921-use_preinit_as_init.patch | 14 + .../linux/generic/patches-3.3/930-crashlog.patch | 285 + .../patches-3.3/940-ocf_kbuild_integration.patch | 20 + .../generic/patches-3.3/941-ocf_20120127.patch | 164 + .../linux/generic/patches-3.3/950-vm_exports.patch | 117 + .../patches-3.3/960-decompress_unlzo_fix.patch | 23 + .../patches-3.3/980-update_arm_machtypes.patch | 3618 + ...2-mpcore_wdt_fix_watchdog_counter_loading.patch | 64 + ...-mpcore_wdt_fix_wdioc_setoptions_handling.patch | 29 + .../994-mpcore_wdt_fix_timer_mode_setup.patch | 57 + target/linux/goldfish/Makefile | 25 + target/linux/goldfish/config-2.6.30 | 199 + target/linux/goldfish/image/Makefile | 40 + target/linux/goldfish/image/run-emulator.sh | 3 + target/linux/goldfish/image/ubinize.cfg | 14 + .../0042-ARM-Make-low-level-printk-work.patch | 36 + ...iller-Only-iterate-over-process-list-when.patch | 66 + ...iller-Don-t-count-free-space-unless-it-me.patch | 48 + ...-Separate-timed_output-class-into-a-separ.patch | 415 + .../0055-mm-Add-min_free_order_shift-tunable.patch | 62 + ...f-any-page-in-a-pageblock-is-reserved-bef.patch | 45 + ...le-might_sleep-before-initializing-driver.patch | 43 + ...ode-to-prevent-system-calls-from-being-re.patch | 35 + ...1--ARM-Save-thread-registers-in-coredumps.patch | 50 + .../patches-2.6.30/0064-PM-Add-wake-lock-api.patch | 104 + .../0065-PM-Add-early-suspend-api.patch | 69 + .../0066-PM-Implement-wakelock-api.patch | 673 + .../0067-PM-Implement-early-suspend-api.patch | 244 + ...ble-early-suspend-through-sys-power-state.patch | 52 + .../0069-PM-Add-user-space-wake-lock-api.patch | 314 + ...ock-Abort-task-freezing-if-a-wake-lock-is.patch | 64 + ...uspend-Add-console-switch-when-user-reque.patch | 133 + ...rlysuspend-Removing-dependence-on-console.patch | 217 + ...-ioctl-to-reset-connections-matching-loca.patch | 132 + ...ipv4-Add-sysfs-based-knobs-for-controllin.patch | 128 + .../0086-Input-Generic-GPIO-Input-device.patch | 1460 + ...-wake-lock-while-event-queue-is-not-empty.patch | 67 + ...-Use-monotonic-time-for-event-time-stamps.patch | 31 + .../0090-input-Add-keyreset-driver.patch | 313 + ...tatus-IRQ-and-status-callback-function-to.patch | 21 + ...d-new-CONFIG_MMC_PARANOID_SD_INIT-for-ena.patch | 69 + ...mc-Add-concept-of-an-embedded-SDIO-device.patch | 274 + ...new-API-call-sdio_reset_comm-for-resettin.patch | 74 + ...When-resuming-try-a-little-harder-to-init.patch | 44 + ...lk-Add-new-feature-CONFIG_MMC_BLOCK_PARAN.patch | 104 + .../0100-mmc-sd-Add-retries-in-re-detection.patch | 91 + ...b-Composite-USB-gadget-driver-for-android.patch | 4127 + ...ck_dump-Add-number-of-sectors-to-debug-ou.patch | 27 + .../0108-mmc-sd-Remove-debugging-printk.patch | 20 + ...intk-remove-unused-code-from-kernel-print.patch | 58 + .../0110-printk-Fix-log_buf_copy-termination.patch | 24 + .../0118--ARM-goldfish-Add-goldfish-platform.patch | 2127 + ...RM-goldfish-Add-audio-driver-for-goldfish.patch | 404 + ...fish-Implement-suspend-as-wait-for-interr.patch | 72 + ...ldfish-tty-Adding-tty-driver-for-goldfish.patch | 368 + ...dfish-events-Add-event-driver-for-goldfis.patch | 234 + ...dfish-mmc-goldfish-MMC-driver-building-an.patch | 626 + ...oldfish-NAND-Add-nand-driver-for-goldfish.patch | 521 + ...dfish-POWER-New-power-supply-driver-for-g.patch | 298 + ...-goldfish-RTC-Add-RTC-driver-for-goldfish.patch | 186 + ...RM-goldfish-fb-Add-fb-driver-for-goldfish.patch | 384 + ...dfish-qemutrace-Kernel-instrumentation-fo.patch | 854 + ...--ARM-goldfish-qemutrace-Add-mmap-support.patch | 84 + .../patches-2.6.30/1000-nand_driver_fixes.patch | 94 + target/linux/imx21/Makefile | 24 + target/linux/imx21/config-default | 130 + .../imx21/files/arch/arm/mach-mx2/mach-vp6500.c | 255 + .../arch/arm/plat-mxc/include/mach/board-vp6500.h | 17 + target/linux/imx21/image/Makefile | 28 + target/linux/imx21/patches/010-mach-vp6500.patch | 22 + target/linux/imx21/patches/011-mach-type.patch | 11 + target/linux/imx21/patches/040-pwm.patch | 137 + target/linux/iop32x/Makefile | 19 + target/linux/iop32x/base-files/etc/config/network | 11 + target/linux/iop32x/config-3.3 | 147 + target/linux/iop32x/image/Makefile | 41 + ...sing-linux-types.h-inclusion-in-asm-hardw.patch | 33 + .../002-Disintegrate-asm-system.h-for-ARM.patch | 24 + .../003-plat-iop-fix-section-mismatch.patch | 11 + target/linux/ixp4xx/Makefile | 22 + .../base-files/lib/preinit/05_set_ether_mac_ixp4xx | 23 + target/linux/ixp4xx/config-3.3 | 186 + .../linux/ixp4xx/generic/profiles/100-Default.mk | 17 + .../ixp4xx/generic/profiles/105-Atheros-ath5k.mk | 17 + target/linux/ixp4xx/generic/profiles/200-NSLU2.mk | 19 + .../linux/ixp4xx/generic/profiles/300-NAS100d.mk | 21 + .../ixp4xx/generic/profiles/400-DSMG600RevA.mk | 22 + .../linux/ixp4xx/generic/profiles/500-USR8200.mk | 20 + target/linux/ixp4xx/generic/target.mk | 9 + target/linux/ixp4xx/harddisk/config-default | 18 + target/linux/ixp4xx/harddisk/profiles/100-FSG3.mk | 20 + target/linux/ixp4xx/harddisk/target.mk | 6 + target/linux/ixp4xx/image/Makefile | 64 + target/linux/ixp4xx/modules.mk | 74 + .../ixp4xx/patches-3.3/020-gateworks_i2c_pld.patch | 423 + .../patches-3.3/090-increase_entropy_pools.patch | 15 + .../100-wg302v2_gateway7001_mac_plat_info.patch | 68 + .../ixp4xx/patches-3.3/105-wg302v1_support.patch | 259 + .../patches-3.3/110-pronghorn_series_support.patch | 389 + .../patches-3.3/111-pronghorn_swap_uarts.patch | 44 + .../patches-3.3/115-sidewinder_support.patch | 283 + .../patches-3.3/116-sidewinder_fis_location.patch | 30 + .../ixp4xx/patches-3.3/120-compex_support.patch | 213 + .../ixp4xx/patches-3.3/130-wrt300nv2_support.patch | 227 + .../patches-3.3/131-wrt300nv2_mac_plat_info.patch | 40 + .../ixp4xx/patches-3.3/132-wrt300nv2_mac_fix.patch | 72 + .../patches-3.3/150-lanready_ap1000_support.patch | 201 + .../151-lanready_ap1000_mac_plat_info.patch | 49 + .../ixp4xx/patches-3.3/162-wg302v1_mem_fixup.patch | 38 + .../patches-3.3/170-ixdpg425_mac_plat_info.patch | 41 + .../ixp4xx/patches-3.3/180-tw5334_support.patch | 285 + .../ixp4xx/patches-3.3/185-mi424wr_support.patch | 501 + .../ixp4xx/patches-3.3/190-cambria_support.patch | 554 + .../patches-3.3/191-cambria_optional_uart.patch | 217 + .../patches-3.3/192-cambria_gpio_device.patch | 46 + .../ixp4xx/patches-3.3/193-cambria_pld_gpio.patch | 107 + .../201-npe_driver_print_license_location.patch | 11 + .../203-npe_driver_mask_phy_features.patch | 13 + .../205-npe_driver_separate_phy_functions.patch | 122 + .../206-npe_driver_add_update_link_function.patch | 98 + .../207-npe_driver_multiphy_support.patch | 154 + .../ixp4xx/patches-3.3/295-latch_led_driver.patch | 202 + .../ixp4xx/patches-3.3/300-avila_fetch_mac.patch | 242 + .../linux/ixp4xx/patches-3.3/301-avila_led.patch | 161 + .../ixp4xx/patches-3.3/302-avila_gpio_device.patch | 16 + .../patches-3.3/304-ixp4xx_eth_jumboframe.patch | 80 + .../ixp4xx/patches-3.3/310-gtwx5717_spi_bus.patch | 52 + .../patches-3.3/311-gtwx5717_mac_plat_info.patch | 40 + .../patches-3.3/312-ixp4xx_pata_optimization.patch | 137 + .../ixp4xx/patches-3.3/402-ixp4xx_gpiolib.patch | 134 + .../ixp4xx/patches-3.3/500-usr8200_support.patch | 344 + .../ixp4xx/patches-3.3/520-tw2662_support.patch | 333 + .../patches-3.3/600-skb_avoid_dmabounce.patch | 24 + .../900-ixp4xx-crypto-include-module.h.patch | 10 + target/linux/kirkwood/Makefile | 23 + target/linux/kirkwood/base-files.mk | 3 + .../kirkwood/base-files/etc/uci-defaults/leds | 23 + .../kirkwood/base-files/etc/uci-defaults/network | 42 + target/linux/kirkwood/base-files/lib/kirkwood.sh | 5 + target/linux/kirkwood/config-3.3 | 177 + .../arch/arm/mach-kirkwood/goflexhome-setup.c | 123 + .../files/arch/arm/mach-kirkwood/goflexnet-setup.c | 176 + .../files/arch/arm/mach-kirkwood/iconnect-setup.c | 190 + .../files/arch/arm/mach-kirkwood/nas6210-setup.c | 190 + .../files/arch/arm/mach-kirkwood/nsa-310-setup.c | 273 + target/linux/kirkwood/image/Makefile | 41 + target/linux/kirkwood/patches/000-boards.patch | 66 + .../linux/kirkwood/patches/001-partition_map.patch | 11 + .../linux/kirkwood/patches/002-mvsdio_delay.patch | 32 + target/linux/lantiq/Makefile | 24 + target/linux/lantiq/ar9/config-default | 40 + target/linux/lantiq/ar9/profiles/000-generic.mk | 5 + target/linux/lantiq/ar9/profiles/001-lantiq.mk | 10 + target/linux/lantiq/ar9/profiles/002-netgear.mk | 11 + target/linux/lantiq/ar9/profiles/003-buffalo.mk | 11 + target/linux/lantiq/ar9/profiles/004-avm.mk | 7 + target/linux/lantiq/ar9/profiles/005-zyxel.mk | 7 + target/linux/lantiq/ar9/profiles/006-zte.mk | 7 + target/linux/lantiq/ar9/target.mk | 12 + target/linux/lantiq/ase/config-default | 22 + target/linux/lantiq/ase/profiles/000-generic.mk | 6 + target/linux/lantiq/ase/profiles/001-lantiq.mk | 10 + target/linux/lantiq/ase/target.mk | 10 + target/linux/lantiq/base-files.mk | 5 + .../base-files/etc/hotplug.d/button/10-generic.sh | 22 + .../etc/hotplug.d/firmware/10-rt2x00-eeprom | 41 + target/linux/lantiq/base-files/etc/inittab | 4 + .../linux/lantiq/base-files/etc/uci-defaults/leds | 58 + .../lantiq/base-files/etc/uci-defaults/network | 87 + target/linux/lantiq/base-files/lib/lantiq.sh | 17 + .../linux/lantiq/base-files/lib/preinit/42_athfix | 19 + .../lantiq/base-files/lib/upgrade/platform.sh | 25 + target/linux/lantiq/config-3.3 | 111 + target/linux/lantiq/danube/config-default | 38 + target/linux/lantiq/danube/profiles/000-generic.mk | 5 + target/linux/lantiq/danube/profiles/001-lantiq.mk | 10 + .../linux/lantiq/danube/profiles/002-arcadyan.mk | 135 + target/linux/lantiq/danube/profiles/003-gigaset.mk | 12 + target/linux/lantiq/danube/profiles/004-bt.mk | 23 + target/linux/lantiq/danube/target.mk | 12 + target/linux/lantiq/falcon/config-default | 20 + target/linux/lantiq/falcon/profiles/000-generic.mk | 12 + target/linux/lantiq/falcon/profiles/001-lantiq.mk | 24 + target/linux/lantiq/falcon/target.mk | 13 + .../lantiq/files/arch/mips/configs/ase_defconfig | 67 + .../files/arch/mips/configs/falcon_defconfig | 72 + .../lantiq/files/arch/mips/configs/xway_defconfig | 66 + .../lantiq/files/arch/mips/include/asm/clkdev.h | 25 + .../include/asm/mach-lantiq/dev-gpio-buttons.h | 26 + .../mips/include/asm/mach-lantiq/dev-gpio-leds.h | 21 + .../include/asm/mach-lantiq/falcon/falcon_irq.h | 268 + .../arch/mips/include/asm/mach-lantiq/falcon/irq.h | 18 + .../include/asm/mach-lantiq/falcon/lantiq_soc.h | 152 + .../mips/include/asm/mach-lantiq/lantiq_timer.h | 155 + .../mips/include/asm/mach-lantiq/svip/base_reg.h | 56 + .../mips/include/asm/mach-lantiq/svip/boot_reg.h | 37 + .../mips/include/asm/mach-lantiq/svip/dma_reg.h | 308 + .../mips/include/asm/mach-lantiq/svip/ebu_reg.h | 615 + .../mips/include/asm/mach-lantiq/svip/es_reg.h | 2098 + .../arch/mips/include/asm/mach-lantiq/svip/irq.h | 36 + .../mips/include/asm/mach-lantiq/svip/lantiq_soc.h | 71 + .../mips/include/asm/mach-lantiq/svip/mps_reg.h | 242 + .../mips/include/asm/mach-lantiq/svip/port_reg.h | 3262 + .../mips/include/asm/mach-lantiq/svip/ssc_reg.h | 624 + .../mips/include/asm/mach-lantiq/svip/status_reg.h | 130 + .../mips/include/asm/mach-lantiq/svip/svip_dma.h | 245 + .../mips/include/asm/mach-lantiq/svip/svip_irq.h | 35 + .../mips/include/asm/mach-lantiq/svip/svip_mux.h | 467 + .../mips/include/asm/mach-lantiq/svip/svip_pms.h | 23 + .../mips/include/asm/mach-lantiq/svip/sys0_reg.h | 165 + .../mips/include/asm/mach-lantiq/svip/sys1_reg.h | 370 + .../mips/include/asm/mach-lantiq/svip/sys2_reg.h | 494 + .../files/arch/mips/lantiq/dev-gpio-buttons.c | 58 + .../lantiq/files/arch/mips/lantiq/dev-gpio-leds.c | 57 + .../lantiq/files/arch/mips/lantiq/falcon/Kconfig | 11 + .../lantiq/files/arch/mips/lantiq/falcon/Makefile | 2 + .../arch/mips/lantiq/falcon/addon-easy98000.c | 213 + .../mips/lantiq/falcon/dev-leds-easy98000-cpld.c | 161 + .../mips/lantiq/falcon/dev-leds-easy98000-cpld.h | 20 + .../lantiq/files/arch/mips/lantiq/falcon/devices.c | 152 + .../lantiq/files/arch/mips/lantiq/falcon/devices.h | 25 + .../lantiq/files/arch/mips/lantiq/falcon/gpio.c | 409 + .../files/arch/mips/lantiq/falcon/mach-95C3AM1.c | 94 + .../files/arch/mips/lantiq/falcon/mach-easy98000.c | 138 + .../files/arch/mips/lantiq/falcon/mach-easy98020.c | 118 + .../lantiq/files/arch/mips/lantiq/falcon/prom.c | 84 + .../lantiq/files/arch/mips/lantiq/falcon/reset.c | 87 + .../lantiq/files/arch/mips/lantiq/falcon/sysctrl.c | 211 + .../lantiq/files/arch/mips/lantiq/svip/Kconfig | 16 + .../lantiq/files/arch/mips/lantiq/svip/Makefile | 3 + .../lantiq/files/arch/mips/lantiq/svip/clk-svip.c | 100 + .../lantiq/files/arch/mips/lantiq/svip/devices.c | 385 + .../lantiq/files/arch/mips/lantiq/svip/devices.h | 23 + .../linux/lantiq/files/arch/mips/lantiq/svip/dma.c | 1206 + .../lantiq/files/arch/mips/lantiq/svip/gpio.c | 553 + .../files/arch/mips/lantiq/svip/mach-easy33016.c | 73 + .../files/arch/mips/lantiq/svip/mach-easy336.c | 221 + .../linux/lantiq/files/arch/mips/lantiq/svip/mux.c | 187 + .../linux/lantiq/files/arch/mips/lantiq/svip/pms.c | 101 + .../lantiq/files/arch/mips/lantiq/svip/prom.c | 73 + .../lantiq/files/arch/mips/lantiq/svip/reset.c | 95 + .../files/arch/mips/lantiq/svip/switchip_setup.c | 666 + .../linux/lantiq/files/arch/mips/lantiq/xway/clk.c | 329 + .../files/arch/mips/lantiq/xway/dev-dwc_otg.c | 70 + .../files/arch/mips/lantiq/xway/dev-dwc_otg.h | 17 + .../files/arch/mips/lantiq/xway/dev-ifxhcd.c | 45 + .../files/arch/mips/lantiq/xway/dev-ifxhcd.h | 17 + .../files/arch/mips/lantiq/xway/dev-wifi-athxk.c | 53 + .../files/arch/mips/lantiq/xway/dev-wifi-athxk.h | 16 + .../files/arch/mips/lantiq/xway/dev-wifi-rt2x00.c | 32 + .../files/arch/mips/lantiq/xway/dev-wifi-rt2x00.h | 14 + .../lantiq/files/arch/mips/lantiq/xway/gptu.c | 176 + .../lantiq/files/arch/mips/lantiq/xway/mach-arv.c | 793 + .../arch/mips/lantiq/xway/mach-bthomehubv2b.c | 542 + .../files/arch/mips/lantiq/xway/mach-fritz_ar9.c | 115 + .../files/arch/mips/lantiq/xway/mach-fritz_vr9.c | 164 + .../files/arch/mips/lantiq/xway/mach-gigasx76x.c | 168 + .../files/arch/mips/lantiq/xway/mach-gigasx76x.h | 210 + .../files/arch/mips/lantiq/xway/mach-h201l.c | 100 + .../files/arch/mips/lantiq/xway/mach-netgear.c | 239 + .../files/arch/mips/lantiq/xway/mach-p2601hnfx.c | 113 + .../lantiq/files/arch/mips/lantiq/xway/mach-wbmr.c | 120 + .../lantiq/files/arch/mips/lantiq/xway/nand.c | 216 + .../files/arch/mips/lantiq/xway/pci-ath-fixup.c | 109 + .../files/arch/mips/lantiq/xway/pci-ath-fixup.h | 6 + .../lantiq/files/arch/mips/lantiq/xway/prom.c | 110 + .../lantiq/files/arch/mips/lantiq/xway/sysctrl.c | 283 + .../lantiq/files/arch/mips/lantiq/xway/timer.c | 846 + .../lantiq/files/arch/mips/pci/fixup-lantiq-pcie.c | 81 + .../lantiq/files/arch/mips/pci/fixup-lantiq.c | 42 + .../lantiq/files/arch/mips/pci/pcie-lantiq-msi.c | 399 + .../lantiq/files/arch/mips/pci/pcie-lantiq-phy.c | 408 + .../linux/lantiq/files/arch/mips/pci/pcie-lantiq.c | 1146 + .../linux/lantiq/files/arch/mips/pci/pcie-lantiq.h | 1305 + .../lantiq/files/drivers/i2c/busses/i2c-falcon.c | 1040 + .../files/drivers/net/ethernet/lantiq_vrx200.c | 1358 + .../lantiq/files/drivers/net/ethernet/svip_eth.c | 636 + .../files/drivers/net/ethernet/svip_virtual_eth.c | 346 + target/linux/lantiq/files/drivers/spi/spi-falcon.c | 483 + target/linux/lantiq/files/drivers/spi/spi-xway.c | 1070 + target/linux/lantiq/files/drivers/spi/spi_svip.c | 955 + .../linux/lantiq/files/drivers/usb/dwc_otg/Kconfig | 37 + .../lantiq/files/drivers/usb/dwc_otg/Makefile | 39 + .../files/drivers/usb/dwc_otg/dwc_otg_attr.c | 802 + .../files/drivers/usb/dwc_otg/dwc_otg_attr.h | 67 + .../lantiq/files/drivers/usb/dwc_otg/dwc_otg_cil.c | 3025 + .../lantiq/files/drivers/usb/dwc_otg/dwc_otg_cil.h | 911 + .../files/drivers/usb/dwc_otg/dwc_otg_cil_ifx.h | 58 + .../files/drivers/usb/dwc_otg/dwc_otg_cil_intr.c | 708 + .../files/drivers/usb/dwc_otg/dwc_otg_driver.c | 1277 + .../files/drivers/usb/dwc_otg/dwc_otg_driver.h | 84 + .../lantiq/files/drivers/usb/dwc_otg/dwc_otg_hcd.c | 2870 + .../lantiq/files/drivers/usb/dwc_otg/dwc_otg_hcd.h | 676 + .../files/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c | 1839 + .../files/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c | 794 + .../lantiq/files/drivers/usb/dwc_otg/dwc_otg_ifx.c | 103 + .../lantiq/files/drivers/usb/dwc_otg/dwc_otg_ifx.h | 85 + .../files/drivers/usb/dwc_otg/dwc_otg_plat.h | 269 + .../files/drivers/usb/dwc_otg/dwc_otg_regs.h | 1797 + .../linux/lantiq/files/drivers/usb/ifxhcd/Kconfig | 58 + .../linux/lantiq/files/drivers/usb/ifxhcd/Makefile | 85 + .../lantiq/files/drivers/usb/ifxhcd/TagHistory | 171 + .../linux/lantiq/files/drivers/usb/ifxhcd/ifxhcd.c | 2523 + .../linux/lantiq/files/drivers/usb/ifxhcd/ifxhcd.h | 628 + .../lantiq/files/drivers/usb/ifxhcd/ifxhcd_es.c | 549 + .../lantiq/files/drivers/usb/ifxhcd/ifxhcd_intr.c | 3742 + .../lantiq/files/drivers/usb/ifxhcd/ifxhcd_queue.c | 418 + .../lantiq/files/drivers/usb/ifxhcd/ifxusb_cif.c | 1458 + .../lantiq/files/drivers/usb/ifxhcd/ifxusb_cif.h | 665 + .../lantiq/files/drivers/usb/ifxhcd/ifxusb_cif_d.c | 458 + .../lantiq/files/drivers/usb/ifxhcd/ifxusb_cif_h.c | 846 + .../lantiq/files/drivers/usb/ifxhcd/ifxusb_ctl.c | 1385 + .../files/drivers/usb/ifxhcd/ifxusb_driver.c | 970 + .../lantiq/files/drivers/usb/ifxhcd/ifxusb_plat.h | 1018 + .../lantiq/files/drivers/usb/ifxhcd/ifxusb_regs.h | 1420 + .../files/drivers/usb/ifxhcd/ifxusb_version.h | 5 + target/linux/lantiq/files/include/linux/svip_nat.h | 37 + .../linux/lantiq/files/include/linux/svip_nat_io.h | 103 + target/linux/lantiq/files/net/ipv4/svip_nat.c | 1569 + target/linux/lantiq/image/Makefile | 284 + target/linux/lantiq/image/eva.dummy.squashfs | Bin 0 -> 256 bytes target/linux/lantiq/modules.mk | 95 + .../lantiq/patches-3.3/0001-falcon-support.patch | 25 + .../lantiq/patches-3.3/0002-xway-support.patch | 1586 + .../linux/lantiq/patches-3.3/0003-svip-hack.patch | 42 + .../patches-3.3/0004-lantiq-core-support.patch | 1009 + .../lantiq/patches-3.3/0005-pci-support.patch | 355 + .../lantiq/patches-3.3/0006-mtd-support.patch | 98 + .../lantiq/patches-3.3/0007-usb-support.patch | 71 + .../lantiq/patches-3.3/0008-spi-support.patch | 74 + .../lantiq/patches-3.3/0009-ethernet-support.patch | 785 + .../lantiq/patches-3.3/0010-watchdog-support.patch | 74 + .../lantiq/patches-3.3/0011-i2c-support.patch | 46 + .../lantiq/patches-3.3/0012-tty-support.patch | 90 + .../lantiq/patches-3.3/0013-machtype-support.patch | 568 + .../patches-3.3/0014-import-compat-headers.patch | 82118 +++++++++++++++++++ .../lantiq/patches-3.3/0015-VPE-extensions.patch | 1221 + .../patches-3.3/0016-falcon-VPE-softdog.patch | 180 + .../patches-3.3/0017-udp-in-kernel-redirect.patch | 378 + .../lantiq/patches-3.3/0018-cache-split.patch | 321 + .../lantiq/patches-3.3/0019-owrt-mtd-split.patch | 265 + .../linux/lantiq/patches-3.3/0020-owrt-atm.patch | 83 + .../lantiq/patches-3.3/0021-owrt-cmdline.patch | 59 + .../patches-3.3/0022-owrt-dm9000-polling.patch | 131 + .../lantiq/patches-3.3/0023-owrt-gpio-export.patch | 64 + .../lantiq/patches-3.3/0024-fritzbox-ram.patch | 29 + .../linux/lantiq/patches-3.3/0025-svip-cp1.patch | 95 + target/linux/lantiq/svip_be/config-default | 38 + .../linux/lantiq/svip_be/profiles/000-generic.mk | 8 + target/linux/lantiq/svip_be/profiles/001-lantiq.mk | 25 + target/linux/lantiq/svip_be/target.mk | 11 + target/linux/lantiq/svip_le/config-default | 34 + .../linux/lantiq/svip_le/profiles/000-generic.mk | 8 + target/linux/lantiq/svip_le/profiles/001-lantiq.mk | 10 + target/linux/lantiq/svip_le/target.mk | 11 + target/linux/lantiq/vr9/config-default | 54 + target/linux/lantiq/vr9/profiles/000-generic.mk | 6 + target/linux/lantiq/vr9/profiles/001-avm.mk | 6 + target/linux/lantiq/vr9/target.mk | 10 + target/linux/leon/Makefile | 24 + target/linux/leon/config-default | 136 + target/linux/leon/image/Makefile | 19 + .../patches/001-find_irq_and_timer_via_of.patch | 48 + .../leon/patches/002-sparc_uimage_target.patch | 79 + .../linux/leon/patches/003-smp_cpu_stuck_fix.patch | 23 + .../leon/patches/004-extended_irq_controller.patch | 119 + .../patches/005-avoid_openprom_duplicates.patch | 58 + target/linux/leon/patches/006-amp_support.patch | 85 + target/linux/leon/patches/007-amp_timer.patch | 120 + .../leon/patches/008-hz_specific_timer_init.patch | 30 + .../leon/patches/009-remove_second_timer.patch | 187 + .../linux/leon/patches/010-apbuart_ampopts.patch | 41 + .../leon/patches/011-greth_fix_unhandled_irq.patch | 21 + .../patches/012-greth_amba_vendor_device.patch | 22 + .../patches/013-apbuart_amba_vendor_device.patch | 22 + .../014-timer_irqctrl_amba_vendor_device.patch | 32 + target/linux/leon/patches/015-dma_ops.patch | 296 + target/linux/leon/patches/016-ioport_update.patch | 51 + target/linux/leon/patches/017-greth_no_gbit.patch | 66 + .../linux/leon/patches/018-greth_compat_mode.patch | 41 + .../leon/patches/019-greth_fix_open_close.patch | 34 + ...reth_optimize_gbit_tx_descriptor_handling.patch | 61 + .../leon/patches/021-greth_fix_memory_leak.patch | 49 + .../patches/022-greth_avoid_bad_speed_duplex.patch | 50 + .../023-greth_handle_frame_error_interrupts.patch | 49 + .../024-greth_resolve_smp_and_other_issues.patch | 399 + .../025-greth_bootloader_disable_device_node.patch | 25 + .../026-greth_gbit_mac_set_ee_when_edcl.patch | 31 + .../leon/patches/027-sparc_v8_assembler.patch | 31 + target/linux/malta/Makefile | 24 + target/linux/malta/README | 13 + target/linux/malta/base-files/etc/inittab | 7 + target/linux/malta/be/config-default | 2 + target/linux/malta/be/target.mk | 10 + target/linux/malta/config-3.3 | 296 + target/linux/malta/image/Makefile | 23 + target/linux/malta/le/target.mk | 10 + .../001-remove_unused_perf_function.patch | 14 + target/linux/mcs814x/Makefile | 31 + target/linux/mcs814x/base-files/etc/config/network | 13 + .../linux/mcs814x/base-files/etc/uci-defaults/leds | 26 + target/linux/mcs814x/base-files/lib/mcs814x.sh | 42 + .../lib/preinit/03_preinit_do_mcs814x.sh | 9 + target/linux/mcs814x/config-default | 188 + .../arch/arm/boot/dts/dlan-usb-extender.dts | 68 + .../files-3.3/arch/arm/boot/dts/mcs8140.dtsi | 207 + .../files-3.3/arch/arm/boot/dts/rbt-832.dts | 83 + .../files-3.3/arch/arm/mach-mcs814x/Kconfig | 29 + .../files-3.3/arch/arm/mach-mcs814x/Makefile | 6 + .../files-3.3/arch/arm/mach-mcs814x/Makefile.boot | 6 + .../arch/arm/mach-mcs814x/board-mcs8140-dt.c | 46 + .../files-3.3/arch/arm/mach-mcs814x/clock.c | 271 + .../files-3.3/arch/arm/mach-mcs814x/common.c | 165 + .../files-3.3/arch/arm/mach-mcs814x/common.h | 15 + .../arch/arm/mach-mcs814x/include/mach/cpu.h | 16 + .../arm/mach-mcs814x/include/mach/debug-macro.S | 11 + .../arm/mach-mcs814x/include/mach/entry-macro.S | 29 + .../arch/arm/mach-mcs814x/include/mach/gpio.h | 21 + .../arch/arm/mach-mcs814x/include/mach/hardware.h | 16 + .../arch/arm/mach-mcs814x/include/mach/io.h | 27 + .../arch/arm/mach-mcs814x/include/mach/irqs.h | 22 + .../arch/arm/mach-mcs814x/include/mach/mcs814x.h | 53 + .../arch/arm/mach-mcs814x/include/mach/memory.h | 16 + .../arch/arm/mach-mcs814x/include/mach/param.h | 15 + .../arch/arm/mach-mcs814x/include/mach/system.h | 18 + .../arch/arm/mach-mcs814x/include/mach/timex.h | 18 + .../arm/mach-mcs814x/include/mach/uncompress.h | 40 + .../mcs814x/files-3.3/arch/arm/mach-mcs814x/irq.c | 69 + .../mcs814x/files-3.3/arch/arm/mach-mcs814x/pci.c | 453 + .../files-3.3/arch/arm/mach-mcs814x/timer.c | 136 + .../files-3.3/drivers/char/hw_random/mcs814x-rng.c | 128 + .../mcs814x/files-3.3/drivers/gpio/gpio-mcs814x.c | 148 + .../files-3.3/drivers/net/ethernet/mcs8140/Kconfig | 4 + .../drivers/net/ethernet/mcs8140/Makefile | 3 + .../drivers/net/ethernet/mcs8140/nuport_mac.c | 1188 + .../mcs814x/files-3.3/drivers/net/phy/mcs814x.c | 64 + .../files-3.3/drivers/usb/host/ehci-mcs814x.c | 165 + .../files-3.3/drivers/usb/host/ohci-mcs814x.c | 202 + .../files-3.3/drivers/watchdog/mcs814x_wdt.c | 207 + target/linux/mcs814x/image/Makefile | 58 + target/linux/mcs814x/modules.mk | 20 + .../linux/mcs814x/patches-3.3/001-platform.patch | 43 + .../linux/mcs814x/patches-3.3/003-ethernet.patch | 16 + target/linux/mcs814x/patches-3.3/004-usb.patch | 29 + .../mcs814x/patches-3.3/005-mcs814x_rng.patch | 31 + .../mcs814x/patches-3.3/006-mcs814x_wdt.patch | 25 + .../mcs814x/patches-3.3/008-mcs814x_gpio.patch | 25 + .../010-fdt_config_cmdline_extend.patch | 140 + .../patches-3.3/011-mcs814x_internal_phy.patch | 20 + .../012-mtd-cfi_cmdset_0002-force-word-write.patch | 14 + .../mcs814x/patches-3.3/013-ohci_workarounds.patch | 64 + target/linux/mcs814x/profiles/000-Generic.mk | 16 + .../mcs814x/profiles/100-dLAN-USB-Extender.mk | 18 + target/linux/mpc52xx/Makefile | 23 + target/linux/mpc52xx/base-files/etc/inittab | 3 + target/linux/mpc52xx/config-3.3 | 274 + target/linux/mpc52xx/image/Makefile | 26 + target/linux/mpc83xx/Makefile | 26 + target/linux/mpc83xx/base-files.mk | 5 + target/linux/mpc83xx/base-files/etc/inittab | 4 + .../mpc83xx/base-files/etc/uci-defaults/network | 29 + target/linux/mpc83xx/base-files/lib/mpc83xx.sh | 44 + .../lib/preinit/03_preinit_do_mpc83xx.sh | 9 + target/linux/mpc83xx/config-3.3 | 392 + target/linux/mpc83xx/files/scripts/mkits.sh | 111 + target/linux/mpc83xx/image/Makefile | 33 + .../100-powerpc_create_fit_uImages.patch | 86 + .../101-mpc8377_wlan-dts-add-gpio-leds.patch | 21 + .../mpc83xx/patches-3.3/110-vitesse_8601.patch | 116 + .../mpc83xx/patches-3.3/111-etsec27_war.patch | 20 + target/linux/mpc83xx/patches-3.3/120-ucc_tdm.patch | 1307 + .../200-powerpc-add-rbppc-support.patch | 1317 + .../patches-3.3/201-powerpc-add-rb_iomap.patch | 262 + .../202-ata-add-pata_rbppc_cf-driver.patch | 727 + .../203-mtd-add-rbppc_nand-driver.patch | 280 + .../300-mpc8377_wlan-dts-add-openwrt-hacks.patch | 23 + target/linux/mpc85xx/Makefile | 26 + target/linux/mpc85xx/config-3.3 | 242 + target/linux/mpc85xx/image/Makefile | 29 + .../mpc85xx/patches-3.3/100-fix_mpc8568e_mds.patch | 32 + .../mpc85xx/patches-3.3/110-fix_mpc8548_cds.patch | 40 + .../120-mpc8548_cds_i8259_noirq_init.patch | 23 + .../130-mpc8548_cds_disable_i8259_irq.patch | 13 + target/linux/octeon/Makefile | 26 + target/linux/octeon/base-files/etc/config/network | 18 + target/linux/octeon/config-default | 237 + target/linux/octeon/config/profile-mototech | 2 + target/linux/octeon/image/Makefile | 26 + target/linux/octeon/modules.mk | 55 + .../linux/octeon/patches/001-wndap330_hacks.patch | 77 + target/linux/octeon/patches/002-nb5_fixup.patch | 11 + target/linux/octeon/profiles/000-Generic.mk | 17 + target/linux/octeon/profiles/100-Mototech.mk | 18 + target/linux/omap24xx/Makefile | 25 + target/linux/omap24xx/base-files/etc/config/fstab | 13 + .../linux/omap24xx/base-files/etc/config/network | 15 + .../linux/omap24xx/base-files/etc/config/wireless | 20 + .../etc/hotplug.d/firmware/10-bme-pmm-image | 15 + .../etc/hotplug.d/firmware/20-p54spi-eeprom | 30 + .../linux/omap24xx/base-files/etc/init.d/watchdog | 17 + target/linux/omap24xx/base-files/etc/inittab | 5 + target/linux/omap24xx/base-files/etc/pointercal | 1 + .../omap24xx/base-files/lib/firmware/bc4fw.bin | Bin 0 -> 2034 bytes target/linux/omap24xx/config-3.3 | 688 + target/linux/omap24xx/image/Makefile | 29 + target/linux/omap24xx/modules.mk | 136 + .../omap24xx/patches-3.3/200-omap-platform.patch | 897 + target/linux/omap24xx/patches-3.3/250-cbus.patch | 3463 + .../patches-3.3/251-cbus-tahvo-lock-fix.patch | 12 + .../patches-3.3/252-cbus-retu-tahvo-ack-fix.patch | 142 + .../254-cbus-retu-tahvo-irq-mask-init-fix.patch | 24 + .../omap24xx/patches-3.3/300-cbus-platform.patch | 175 + .../309-omapfb-circular-mutex-workaround.patch | 41 + .../linux/omap24xx/patches-3.3/310-n810-lcd.patch | 368 + .../patches-3.3/311-omapfb-clock-fixes.patch | 30 + .../omap24xx/patches-3.3/312-no-hwmod-reset.patch | 28 + .../315-n800-touchscreen-and-keypad-drivers.patch | 2791 + .../omap24xx/patches-3.3/320-nokia-various.patch | 194 + .../patches-3.3/330-n800-tsc2301-platform.patch | 212 + .../patches-3.3/350-n8x0-gpioswitch-input.patch | 98 + .../patches-3.3/400-bluetooth-hci_h4p.patch | 1946 + .../omap24xx/patches-3.3/410-hci-h4p-fixes.patch | 46 + .../420-hci-h4p-interrupt-workaround.patch | 36 + .../patches-3.3/597-cbus-tahvo-usb-platform.patch | 34 + .../710-evdev-events-without-grab.patch | 31 + .../linux/omap24xx/patches-3.3/810-mmc-fixes.patch | 50 + .../patches-3.3/830-omap2-serial-fixes.patch | 23 + .../patches-3.3/850-musb-tusb-modular-fixes.patch | 135 + .../patches-3.3/900-n810-battery-management.patch | 1917 + .../910-omap-fix-section-mismatch-warnings.patch | 116 + target/linux/omap24xx/profiles/100-n810.mk | 31 + target/linux/omap24xx/profiles/110-n810-gui.mk | 22 + target/linux/omap35xx/Makefile | 26 + .../beagleboard/base-files/etc/config/network | 14 + .../omap35xx/beagleboard/base-files/etc/inittab | 7 + .../omap35xx/beagleboard/profiles/beagleboard.mk | 16 + target/linux/omap35xx/beagleboard/target.mk | 6 + target/linux/omap35xx/config-2.6.32 | 1682 + target/linux/omap35xx/files/boot-mmc.cmd | 12 + .../omap35xx/gumstix/base-files/etc/config/network | 15 + .../omap35xx/gumstix/base-files/etc/fw_env.config | 2 + .../linux/omap35xx/gumstix/base-files/etc/inittab | 5 + .../gumstix/base-files/lib/preinit/95_ttyS1_noecho | 9 + target/linux/omap35xx/gumstix/config-2.6.36 | 418 + target/linux/omap35xx/gumstix/config-default | 334 + target/linux/omap35xx/gumstix/defconfig.es | 24 + target/linux/omap35xx/gumstix/defconfig.gumstix | 20 + target/linux/omap35xx/gumstix/defconfig.vpp | 26 + target/linux/omap35xx/gumstix/profiles/000-hegw.mk | 27 + target/linux/omap35xx/gumstix/profiles/001-vpp.mk | 27 + target/linux/omap35xx/gumstix/profiles/002-es.mk | 27 + target/linux/omap35xx/gumstix/target.mk | 7 + target/linux/omap35xx/image/Makefile | 32 + target/linux/omap35xx/image/gen_image.sh | 35 + target/linux/omap35xx/image/ubinize.cfg | 14 + .../linux/omap35xx/patches-2.6.32/001-DSS2.patch | 22645 +++++ .../linux/omap35xx/patches-2.6.32/002-OMAP.patch | 9583 +++ .../003-enable_dss2_beagleboard.patch | 195 + .../patches-2.6.32/004-compile_fix_dispc.patch | 13 + .../patches-2.6.36/001-expose_omap3_die_id.patch | 48 + ...-omap-nand-remove-hardware-ECC-as-default.patch | 36 + .../003-change_partition_table.patch | 34 + .../patches-2.6.36/004-nand_subpage_align.patch | 22 + .../patches-2.6.36/005-add_cti_usbids.patch | 24 + .../patches-3.0/001-change_partition_table.patch | 34 + .../omap35xx/patches-3.0/002-fix_twl_rtc.patch | 26 + target/linux/omap4/Makefile | 31 + target/linux/omap4/base-files/etc/inittab | 4 + target/linux/omap4/config-default | 370 + target/linux/omap4/image/Makefile | 36 + target/linux/omap4/image/boot.script | 3 + .../patches/001-omap4_pandaboard-wlan_fix.patch | 10 + target/linux/orion/Makefile | 24 + target/linux/orion/base-files/etc/config/network | 22 + .../orion/base-files/etc/hotplug.d/usb/10-usb | 54 + target/linux/orion/config-3.3 | 182 + .../orion/dns323/base-files/etc/config/network | 12 + target/linux/orion/dns323/config-3.3 | 47 + target/linux/orion/dns323/target.mk | 6 + .../orion/files/arch/arm/mach-orion5x/dt2-common.h | 82 + .../orion/files/arch/arm/mach-orion5x/dt2-setup.c | 446 + .../generic/base-files/etc/uci-defaults/hardware | 54 + .../generic/base-files/lib/upgrade/platform.sh | 38 + target/linux/orion/generic/target.mk | 14 + target/linux/orion/harddisk/config-3.3 | 28 + target/linux/orion/harddisk/target.mk | 14 + target/linux/orion/image/Makefile | 12 + target/linux/orion/image/dns323.mk | 36 + target/linux/orion/image/generic.mk | 218 + target/linux/orion/image/harddisk.mk | 55 + .../100-wrt350nv2_openwrt_partition_map.patch | 32 + .../patches-3.3/101-wnr854t_partition_map.patch | 13 + .../orion/patches-3.3/200-dt2_board_support.patch | 26 + .../patches-3.3/300-dns323_partition_map.patch | 30 + .../400-fix-section-mismatch-warnings.patch | 31 + .../orion/patches-3.3/a01-dt2-fixes-for-3.3.patch | 34 + target/linux/ppc40x/Makefile | 24 + target/linux/ppc40x/base-files/lib/ppc40x.sh | 11 + .../ppc40x/base-files/lib/upgrade/platform.sh | 38 + target/linux/ppc40x/config-3.3 | 219 + target/linux/ppc40x/image/Makefile | 73 + target/linux/ppc40x/modules.mk | 41 + .../003-powerpc-add-EBC_BXCR-defines.patch | 27 + target/linux/ppc40x/patches-3.3/004-magicbox.patch | 445 + target/linux/ppc40x/patches-3.3/005-openrb.patch | 447 + .../patches-3.3/101-pata-magicbox-cf-driver.patch | 433 + .../patches-3.3/110-kilauea_openwrt_flashmap.patch | 55 + .../120-usb-isp116x-hcd-add-of-binding.patch | 289 + ...21-usb-isp116x-hcd-ppc405-register-access.patch | 111 + target/linux/ppc44x/Makefile | 26 + target/linux/ppc44x/base-files/etc/inittab | 4 + target/linux/ppc44x/config-3.3 | 220 + target/linux/ppc44x/image/Makefile | 45 + .../ppc44x/patches-3.3/100-openwrt_flashmap.patch | 56 + .../patches-3.3/110-openwrt_dts_cmdline.patch | 9 + target/linux/ps3/Makefile | 35 + target/linux/ps3/README | 43 + target/linux/ps3/config-2.6.30 | 321 + target/linux/ps3/image/Makefile | 21 + target/linux/ps3/modules.mk | 58 + .../patches-2.6.30/0016-ps3-gelic-fix-rxdmac.patch | 89 + target/linux/ps3/petitboot/base-files/bin/login | 45 + target/linux/ps3/petitboot/base-files/etc/banner | 6 + .../ps3/petitboot/base-files/etc/config/network | 11 + .../ps3/petitboot/base-files/etc/config/system | 3 + .../linux/ps3/petitboot/base-files/etc/init.d/boot | 73 + target/linux/ps3/petitboot/base-files/etc/inittab | 7 + .../linux/ps3/petitboot/base-files/etc/sysctl.conf | 11 + target/linux/ps3/petitboot/base-files/sbin/initrun | 18 + .../ps3/petitboot/base-files/sbin/ps3-bl-option | 119 + target/linux/ps3/petitboot/defconfig-ps3-petitboot | 19 + target/linux/ps3/petitboot/profiles/000-Default.mk | 19 + target/linux/ps3/petitboot/target.mk | 6 + target/linux/pxa/Makefile | 25 + target/linux/pxa/config-3.3 | 202 + target/linux/pxa/image/Makefile | 47 + .../001-gumstix_verdex_pro_arch_support.patch | 882 + .../pxa/patches-3.3/002-verdex_lcd_support.patch | 52 + .../003-gumstix_h_verdex_pro_support.patch | 214 + .../004-smsc911x_verdex_pro_support.patch | 100 + .../patches-3.3/005-verdex_pcmcia_support.patch | 236 + .../pxa/patches-3.3/a01-arm-debugll-printk.patch | 24 + target/linux/pxa/profiles/100-Default.mk | 17 + target/linux/pxa/profiles/200-Gumstix.mk | 17 + target/linux/pxcab/Makefile | 29 + .../base-files/lib/preinit/15_essential_fs_pxcab | 8 + .../pxcab/base-files/lib/preinit/45_failsafe_pxcab | 14 + target/linux/pxcab/config-2.6.30 | 427 + target/linux/pxcab/image/Makefile | 20 + target/linux/pxcab/modules.mk | 21 + target/linux/ramips/Makefile | 28 + target/linux/ramips/base-files.mk | 5 + target/linux/ramips/base-files/etc/diag.sh | 139 + .../etc/hotplug.d/firmware/10-rt2x00-eeprom | 111 + target/linux/ramips/base-files/etc/inittab | 4 + .../linux/ramips/base-files/etc/uci-defaults/leds | 86 + .../ramips/base-files/etc/uci-defaults/network | 217 + .../base-files/lib/preinit/03_preinit_do_ramips.sh | 7 + .../lib/preinit/05_ramips_load-input_drivers | 12 + .../ramips/base-files/lib/preinit/06_set_iface_mac | 66 + target/linux/ramips/base-files/lib/ramips.sh | 194 + .../ramips/base-files/lib/upgrade/platform.sh | 84 + .../arch/mips/include/asm/mach-ralink/common.h | 27 + .../include/asm/mach-ralink/dev-gpio-buttons.h | 29 + .../mips/include/asm/mach-ralink/dev-gpio-leds.h | 26 + .../files/arch/mips/include/asm/mach-ralink/gpio.h | 24 + .../arch/mips/include/asm/mach-ralink/machine.h | 72 + .../include/asm/mach-ralink/ramips_eth_platform.h | 41 + .../mips/include/asm/mach-ralink/ramips_gpio.h | 48 + .../include/asm/mach-ralink/ramips_nand_platform.h | 23 + .../arch/mips/include/asm/mach-ralink/rt288x.h | 76 + .../asm/mach-ralink/rt288x/cpu-feature-overrides.h | 56 + .../arch/mips/include/asm/mach-ralink/rt288x/irq.h | 17 + .../mips/include/asm/mach-ralink/rt288x_regs.h | 127 + .../arch/mips/include/asm/mach-ralink/rt305x.h | 169 + .../asm/mach-ralink/rt305x/cpu-feature-overrides.h | 56 + .../arch/mips/include/asm/mach-ralink/rt305x/irq.h | 17 + .../include/asm/mach-ralink/rt305x_esw_platform.h | 27 + .../mips/include/asm/mach-ralink/rt305x_regs.h | 214 + .../arch/mips/include/asm/mach-ralink/rt3883.h | 152 + .../asm/mach-ralink/rt3883/cpu-feature-overrides.h | 55 + .../arch/mips/include/asm/mach-ralink/rt3883/irq.h | 16 + .../include/asm/mach-ralink/rt3883_ehci_platform.h | 20 + .../include/asm/mach-ralink/rt3883_ohci_platform.h | 20 + .../mips/include/asm/mach-ralink/rt3883_regs.h | 207 + .../files/arch/mips/include/asm/mach-ralink/war.h | 25 + .../linux/ramips/files/arch/mips/pci/pci-rt288x.c | 250 + .../linux/ramips/files/arch/mips/pci/pci-rt3883.c | 487 + target/linux/ramips/files/arch/mips/ralink/Kconfig | 80 + .../linux/ramips/files/arch/mips/ralink/Platform | 26 + .../ramips/files/arch/mips/ralink/common/Makefile | 13 + .../arch/mips/ralink/common/dev-gpio-buttons.c | 57 + .../files/arch/mips/ralink/common/dev-gpio-leds.c | 54 + .../ramips/files/arch/mips/ralink/common/gpio.c | 113 + .../ramips/files/arch/mips/ralink/common/intc.c | 99 + .../ramips/files/arch/mips/ralink/common/prom.c | 168 + .../ramips/files/arch/mips/ralink/common/setup.c | 98 + .../ramips/files/arch/mips/ralink/rt288x/Kconfig | 31 + .../ramips/files/arch/mips/ralink/rt288x/Makefile | 20 + .../ramips/files/arch/mips/ralink/rt288x/clock.c | 99 + .../ramips/files/arch/mips/ralink/rt288x/common.h | 16 + .../ramips/files/arch/mips/ralink/rt288x/devices.c | 211 + .../ramips/files/arch/mips/ralink/rt288x/devices.h | 28 + .../files/arch/mips/ralink/rt288x/early_printk.c | 30 + .../ramips/files/arch/mips/ralink/rt288x/irq.c | 81 + .../arch/mips/ralink/rt288x/mach-f5d8235-v1.c | 106 + .../files/arch/mips/ralink/rt288x/mach-rt-n15.c | 99 + .../files/arch/mips/ralink/rt288x/mach-v11st-fe.c | 75 + .../arch/mips/ralink/rt288x/mach-wli-tx4-ag300n.c | 102 + .../arch/mips/ralink/rt288x/mach-wzr-agl300nh.c | 77 + .../ramips/files/arch/mips/ralink/rt288x/rt288x.c | 153 + .../ramips/files/arch/mips/ralink/rt288x/setup.c | 88 + .../ramips/files/arch/mips/ralink/rt305x/Kconfig | 184 + .../ramips/files/arch/mips/ralink/rt305x/Makefile | 49 + .../ramips/files/arch/mips/ralink/rt305x/clock.c | 133 + .../ramips/files/arch/mips/ralink/rt305x/common.h | 16 + .../ramips/files/arch/mips/ralink/rt305x/devices.c | 413 + .../ramips/files/arch/mips/ralink/rt305x/devices.h | 32 + .../files/arch/mips/ralink/rt305x/early_printk.c | 29 + .../ramips/files/arch/mips/ralink/rt305x/irq.c | 82 + .../files/arch/mips/ralink/rt305x/mach-3g-6200n.c | 86 + .../files/arch/mips/ralink/rt305x/mach-all0256n.c | 90 + .../files/arch/mips/ralink/rt305x/mach-all5002.c | 61 + .../arch/mips/ralink/rt305x/mach-argus-atp52b.c | 81 + .../files/arch/mips/ralink/rt305x/mach-bc2.c | 70 + .../files/arch/mips/ralink/rt305x/mach-carambola.c | 42 + .../files/arch/mips/ralink/rt305x/mach-dap-1350.c | 94 + .../arch/mips/ralink/rt305x/mach-dir-300-revb.c | 155 + .../arch/mips/ralink/rt305x/mach-dir-615-h1.c | 112 + .../files/arch/mips/ralink/rt305x/mach-esr-9753.c | 81 + .../arch/mips/ralink/rt305x/mach-f5d8235-v2.c | 108 + .../files/arch/mips/ralink/rt305x/mach-fonera20n.c | 87 + .../arch/mips/ralink/rt305x/mach-freestation5.c | 34 + .../files/arch/mips/ralink/rt305x/mach-hw550-3g.c | 105 + .../arch/mips/ralink/rt305x/mach-mofi3500-3gn.c | 102 + .../files/arch/mips/ralink/rt305x/mach-nbg-419n.c | 78 + .../files/arch/mips/ralink/rt305x/mach-nw718.c | 95 + .../files/arch/mips/ralink/rt305x/mach-omni-emb.c | 74 + .../files/arch/mips/ralink/rt305x/mach-psr-680w.c | 73 + .../files/arch/mips/ralink/rt305x/mach-pwh2004.c | 69 + .../arch/mips/ralink/rt305x/mach-rt-g32-revb.c | 78 + .../arch/mips/ralink/rt305x/mach-rt-n10-plus.c | 74 + .../files/arch/mips/ralink/rt305x/mach-sl-r7205.c | 76 + .../files/arch/mips/ralink/rt305x/mach-ur-336un.c | 92 + .../files/arch/mips/ralink/rt305x/mach-v22rw-2x2.c | 79 + .../files/arch/mips/ralink/rt305x/mach-w306r-v20.c | 72 + .../files/arch/mips/ralink/rt305x/mach-w502u.c | 83 + .../files/arch/mips/ralink/rt305x/mach-wcr150gn.c | 80 + .../files/arch/mips/ralink/rt305x/mach-whr-g300n.c | 100 + .../files/arch/mips/ralink/rt305x/mach-wl-330n.c | 94 + .../files/arch/mips/ralink/rt305x/mach-wl-330n3g.c | 100 + .../files/arch/mips/ralink/rt305x/mach-wl341v3.c | 105 + .../files/arch/mips/ralink/rt305x/mach-wl351.c | 118 + .../files/arch/mips/ralink/rt305x/mach-wr512-3gn.c | 110 + .../files/arch/mips/ralink/rt305x/mach-wr6202.c | 90 + .../arch/mips/ralink/rt305x/mach-xdx-rn502j.c | 79 + .../ramips/files/arch/mips/ralink/rt305x/rt305x.c | 247 + .../ramips/files/arch/mips/ralink/rt305x/setup.c | 88 + .../ramips/files/arch/mips/ralink/rt3883/Kconfig | 13 + .../ramips/files/arch/mips/ralink/rt3883/Makefile | 14 + .../ramips/files/arch/mips/ralink/rt3883/clock.c | 103 + .../ramips/files/arch/mips/ralink/rt3883/common.h | 16 + .../ramips/files/arch/mips/ralink/rt3883/devices.c | 403 + .../ramips/files/arch/mips/ralink/rt3883/devices.h | 34 + .../files/arch/mips/ralink/rt3883/early_printk.c | 29 + .../ramips/files/arch/mips/ralink/rt3883/irq.c | 84 + .../files/arch/mips/ralink/rt3883/mach-rt-n56u.c | 155 + .../ramips/files/arch/mips/ralink/rt3883/rt3883.c | 216 + .../ramips/files/arch/mips/ralink/rt3883/setup.c | 88 + .../files/drivers/net/ethernet/ramips/Kconfig | 18 + .../files/drivers/net/ethernet/ramips/Makefile | 9 + .../drivers/net/ethernet/ramips/ramips_debugfs.c | 127 + .../files/drivers/net/ethernet/ramips/ramips_esw.c | 1128 + .../files/drivers/net/ethernet/ramips/ramips_eth.h | 358 + .../drivers/net/ethernet/ramips/ramips_main.c | 1200 + target/linux/ramips/files/drivers/spi/spi-ramips.c | 559 + .../linux/ramips/files/drivers/usb/dwc_otg/Kconfig | 24 + .../ramips/files/drivers/usb/dwc_otg/Makefile | 25 + .../ramips/files/drivers/usb/dwc_otg/dummy_audio.c | 1575 + .../files/drivers/usb/dwc_otg/dwc_otg_attr.c | 966 + .../files/drivers/usb/dwc_otg/dwc_otg_attr.h | 67 + .../ramips/files/drivers/usb/dwc_otg/dwc_otg_cil.c | 3692 + .../ramips/files/drivers/usb/dwc_otg/dwc_otg_cil.h | 1098 + .../files/drivers/usb/dwc_otg/dwc_otg_cil_intr.c | 750 + .../files/drivers/usb/dwc_otg/dwc_otg_driver.c | 1265 + .../files/drivers/usb/dwc_otg/dwc_otg_driver.h | 83 + .../ramips/files/drivers/usb/dwc_otg/dwc_otg_hcd.c | 2852 + .../ramips/files/drivers/usb/dwc_otg/dwc_otg_hcd.h | 668 + .../files/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c | 1873 + .../files/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c | 684 + .../ramips/files/drivers/usb/dwc_otg/dwc_otg_pcd.c | 2523 + .../ramips/files/drivers/usb/dwc_otg/dwc_otg_pcd.h | 248 + .../files/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c | 3654 + .../files/drivers/usb/dwc_otg/dwc_otg_regs.h | 2075 + .../files/drivers/usb/dwc_otg/linux/dwc_otg_plat.h | 260 + .../ramips/files/drivers/usb/host/ehci-rt3883.c | 162 + .../ramips/files/drivers/usb/host/ohci-rt3883.c | 161 + .../ramips/files/drivers/watchdog/ramips_wdt.c | 355 + target/linux/ramips/image/Makefile | 606 + target/linux/ramips/modules.mk | 26 + .../001-mips-add-cp0-compare-irq-function.patch | 29 + ...td_fix_cfi_cmdset_0002_erase_status_check.patch | 20 + .../011-mtd-cfi_cmdset_0002-force-word-write.patch | 61 + .../ramips/patches-3.3/100-mips-ralink-core.patch | 39 + .../101-rt288x_serial_driver_hack.patch | 91 + .../patches-3.3/102-rt288x-pci-driver-hook.patch | 10 + target/linux/ramips/patches-3.3/103-ethernet.patch | 20 + .../patches-3.3/104-ramips-watchdog-driver.patch | 26 + .../ramips/patches-3.3/105-ramips-spi-driver.patch | 25 + .../linux/ramips/patches-3.3/105-usb_dwc_otg.patch | 20 + .../patches-3.3/106-rt3883-pci-support.patch | 10 + .../ramips/patches-3.3/200-rt3883-ehci-glue.patch | 32 + .../ramips/patches-3.3/201-rt3883-ohci-glue.patch | 31 + target/linux/ramips/rt288x/config-3.3 | 117 + target/linux/ramips/rt288x/profiles/00-default.mk | 16 + target/linux/ramips/rt288x/profiles/asus.mk | 18 + target/linux/ramips/rt288x/profiles/belkin.mk | 18 + target/linux/ramips/rt288x/target.mk | 11 + target/linux/ramips/rt305x/config-3.3 | 146 + target/linux/ramips/rt305x/profiles/00-default.mk | 18 + target/linux/ramips/rt305x/profiles/allnet.mk | 41 + target/linux/ramips/rt305x/profiles/aztech.mk | 19 + target/linux/ramips/rt305x/profiles/belkin.mk | 20 + target/linux/ramips/rt305x/profiles/engenius.mk | 16 + .../linux/ramips/rt305x/profiles/freestation5.mk | 18 + target/linux/ramips/rt305x/profiles/tenda.mk | 17 + target/linux/ramips/rt305x/profiles/upvel.mk | 18 + target/linux/ramips/rt305x/target.mk | 11 + target/linux/ramips/rt3883/config-3.3 | 113 + target/linux/ramips/rt3883/profiles/00-default.mk | 16 + target/linux/ramips/rt3883/profiles/asus.mk | 16 + target/linux/ramips/rt3883/target.mk | 11 + target/linux/rb532/Makefile | 19 + target/linux/rb532/base-files.mk | 11 + target/linux/rb532/base-files/etc/config/network | 13 + target/linux/rb532/base-files/etc/diag.sh | 19 + target/linux/rb532/base-files/sbin/cf2nand | 67 + target/linux/rb532/base-files/sbin/wget2nand | 71 + target/linux/rb532/config-3.3 | 130 + target/linux/rb532/image/Makefile | 74 + target/linux/rb532/image/gen_image.sh | 17 + target/linux/rb532/modules.mk | 45 + .../linux/rb532/patches-3.3/001-cmdline_hack.patch | 20 + .../rb532/patches-3.3/002-rb532_nand_fixup.patch | 48 + target/linux/rb532/src/patch-cmdline.c | 79 + target/linux/rdc/Makefile | 30 + target/linux/rdc/base-files/etc/config/network | 18 + target/linux/rdc/base-files/etc/diag.sh | 19 + .../base-files/lib/preinit/05_set_ether_mac_rdc | 36 + .../linux/rdc/base-files/lib/upgrade/platform.sh | 10 + target/linux/rdc/config-3.3 | 326 + target/linux/rdc/image/Makefile | 47 + target/linux/rdc/image/mkimg_bifferboard.py | 50 + target/linux/rdc/image/mkimg_sitecom.pl | 11 + target/linux/rdc/modules.mk | 22 + .../linux/rdc/patches-3.3/006-yenta_mistery.patch | 20 + .../patches-3.3/009-rdc321x_select_embedded.patch | 11 + .../linux/rdc/patches-3.3/010-rdc_cpu_ident.patch | 176 + .../rdc/patches-3.3/011-tune_lzma_options.patch | 22 + .../rdc/patches-3.3/012-export_erase_write.patch | 23 + target/linux/rdc/patches-3.3/100-rdc_boards.patch | 741 + .../patches-3.3/120-panic_on_unrecovered_nmi.patch | 11 + .../linux/rdc/patches-3.3/150-pit-tick-rate.patch | 14 + target/linux/rdc/patches-3.3/160-kexec-fix.patch | 43 + target/linux/rdc/profiles/ar525w.mk | 12 + target/linux/rdc/profiles/bifferboard.mk | 13 + target/linux/rdc/profiles/r8610.mk | 15 + target/linux/rdc/profiles/sitecom.mk | 12 + target/linux/realview/Makefile | 28 + target/linux/realview/README | 12 + target/linux/realview/base-files/etc/inittab | 5 + target/linux/realview/config-3.3 | 235 + target/linux/realview/image/Makefile | 23 + ...001-arm-fix-REALVIEW_EB11MP_PRIV_MEM_BASE.patch | 11 + .../patches-3.3/002-disable_fmrx_instr.patch | 13 + target/linux/s3c24xx/Makefile | 26 + .../arch/arm/mach-s3c2442/gta02-pm-bt.c | 252 + .../arch/arm/mach-s3c2442/gta02-pm-gps.c | 242 + .../arch/arm/mach-s3c2442/gta02-pm-gsm.c | 317 + .../arch/arm/mach-s3c2442/gta02-pm-wlan.c | 194 + .../arm/mach-s3c2442/include/mach/gta02-pm-gps.h | 1 + .../arm/mach-s3c2442/include/mach/gta02-pm-gsm.h | 1 + .../arm/mach-s3c2442/include/mach/gta02-pm-wlan.h | 10 + .../arch/arm/mach-s3c2442/include/mach/gta02.h | 89 + .../arch/arm/mach-s3c2442/mach-gta02.c | 1806 + .../s3c24xx/files-2.6.30/drivers/ar6000/Kconfig | 31 + .../s3c24xx/files-2.6.30/drivers/ar6000/Makefile | 38 + .../drivers/ar6000/ar6000/ar6000_drv.c | 3129 + .../drivers/ar6000/ar6000/ar6000_drv.h | 360 + .../drivers/ar6000/ar6000/ar6000_raw_if.c | 440 + .../drivers/ar6000/ar6000/ar6xapi_linux.h | 128 + .../drivers/ar6000/ar6000/athdrv_linux.h | 993 + .../drivers/ar6000/ar6000/athtypes_linux.h | 47 + .../drivers/ar6000/ar6000/config_linux.h | 44 + .../drivers/ar6000/ar6000/debug_linux.h | 86 + .../files-2.6.30/drivers/ar6000/ar6000/ioctl.c | 2532 + .../files-2.6.30/drivers/ar6000/ar6000/netbuf.c | 225 + .../drivers/ar6000/ar6000/osapi_linux.h | 319 + .../drivers/ar6000/ar6000/wireless_ext.c | 1979 + .../s3c24xx/files-2.6.30/drivers/ar6000/bmi/bmi.c | 657 + .../files-2.6.30/drivers/ar6000/bmi/bmi_internal.h | 45 + .../s3c24xx/files-2.6.30/drivers/ar6000/hif/hif.c | 824 + .../s3c24xx/files-2.6.30/drivers/ar6000/hif/hif2.c | 768 + .../files-2.6.30/drivers/ar6000/hif/hif_internal.h | 102 + .../s3c24xx/files-2.6.30/drivers/ar6000/htc/ar6k.c | 991 + .../s3c24xx/files-2.6.30/drivers/ar6000/htc/ar6k.h | 191 + .../files-2.6.30/drivers/ar6000/htc/ar6k_events.c | 638 + .../s3c24xx/files-2.6.30/drivers/ar6000/htc/htc.c | 508 + .../files-2.6.30/drivers/ar6000/htc/htc_debug.h | 65 + .../files-2.6.30/drivers/ar6000/htc/htc_internal.h | 168 + .../files-2.6.30/drivers/ar6000/htc/htc_recv.c | 703 + .../files-2.6.30/drivers/ar6000/htc/htc_send.c | 538 + .../files-2.6.30/drivers/ar6000/htc/htc_services.c | 403 + .../drivers/ar6000/include/AR6001_regdump.h | 100 + .../drivers/ar6000/include/AR6K_version.h | 36 + .../drivers/ar6000/include/AR6K_version.h.NEW | 36 + .../drivers/ar6000/include/AR6Khwreg.h | 147 + .../files-2.6.30/drivers/ar6000/include/a_config.h | 27 + .../files-2.6.30/drivers/ar6000/include/a_debug.h | 41 + .../files-2.6.30/drivers/ar6000/include/a_drv.h | 28 + .../drivers/ar6000/include/a_drv_api.h | 185 + .../files-2.6.30/drivers/ar6000/include/a_osapi.h | 28 + .../files-2.6.30/drivers/ar6000/include/a_types.h | 28 + .../drivers/ar6000/include/ar6000_api.h | 29 + .../drivers/ar6000/include/ar6000_diag.h | 38 + .../files-2.6.30/drivers/ar6000/include/athdefs.h | 85 + .../files-2.6.30/drivers/ar6000/include/athdrv.h | 32 + .../drivers/ar6000/include/athendpack.h | 41 + .../drivers/ar6000/include/athstartpack.h | 42 + .../files-2.6.30/drivers/ar6000/include/bmi.h | 100 + .../files-2.6.30/drivers/ar6000/include/bmi_msg.h | 199 + .../drivers/ar6000/include/common_drv.h | 61 + .../files-2.6.30/drivers/ar6000/include/dbglog.h | 107 + .../drivers/ar6000/include/dbglog_api.h | 46 + .../drivers/ar6000/include/dbglog_id.h | 307 + .../files-2.6.30/drivers/ar6000/include/dl_list.h | 114 + .../files-2.6.30/drivers/ar6000/include/dset_api.h | 63 + .../drivers/ar6000/include/dset_internal.h | 39 + .../files-2.6.30/drivers/ar6000/include/dsetid.h | 110 + .../files-2.6.30/drivers/ar6000/include/gpio.h | 34 + .../files-2.6.30/drivers/ar6000/include/gpio_api.h | 57 + .../files-2.6.30/drivers/ar6000/include/hif.h | 296 + .../drivers/ar6000/include/host_version.h | 49 + .../files-2.6.30/drivers/ar6000/include/htc.h | 190 + .../files-2.6.30/drivers/ar6000/include/htc_api.h | 439 + .../drivers/ar6000/include/htc_packet.h | 138 + .../drivers/ar6000/include/htc_services.h | 37 + .../drivers/ar6000/include/ieee80211.h | 342 + .../drivers/ar6000/include/ieee80211_ioctl.h | 163 + .../drivers/ar6000/include/ieee80211_node.h | 77 + .../files-2.6.30/drivers/ar6000/include/ini_dset.h | 40 + .../files-2.6.30/drivers/ar6000/include/regDb.h | 19 + .../files-2.6.30/drivers/ar6000/include/regdump.h | 33 + .../drivers/ar6000/include/targaddrs.h | 158 + .../files-2.6.30/drivers/ar6000/include/testcmd.h | 144 + .../files-2.6.30/drivers/ar6000/include/wlan_api.h | 101 + .../drivers/ar6000/include/wlan_dset.h | 20 + .../files-2.6.30/drivers/ar6000/include/wmi.h | 1743 + .../files-2.6.30/drivers/ar6000/include/wmi_api.h | 260 + .../files-2.6.30/drivers/ar6000/include/wmix.h | 233 + .../drivers/ar6000/miscdrv/common_drv.c | 467 + .../drivers/ar6000/miscdrv/credit_dist.c | 346 + .../files-2.6.30/drivers/ar6000/wlan/wlan_node.c | 371 + .../drivers/ar6000/wlan/wlan_recv_beacon.c | 192 + .../files-2.6.30/drivers/ar6000/wlan/wlan_utils.c | 59 + .../s3c24xx/files-2.6.30/drivers/ar6000/wmi/wmi.c | 3954 + .../files-2.6.30/drivers/ar6000/wmi/wmi_doc.h | 4421 + .../files-2.6.30/drivers/ar6000/wmi/wmi_host.h | 71 + .../files-2.6.30/drivers/input/misc/lis302dl.c | 957 + .../drivers/input/touchscreen/s3c2410_ts.c | 593 + .../drivers/input/touchscreen/ts_filter_chain.c | 183 + .../drivers/input/touchscreen/ts_filter_group.c | 296 + .../drivers/input/touchscreen/ts_filter_linear.c | 212 + .../drivers/input/touchscreen/ts_filter_mean.c | 174 + .../drivers/input/touchscreen/ts_filter_median.c | 261 + .../drivers/leds/leds-gta02-vibrator.c | 190 + .../s3c24xx/files-2.6.30/drivers/mfd/glamo/Kconfig | 41 + .../files-2.6.30/drivers/mfd/glamo/Makefile | 11 + .../files-2.6.30/drivers/mfd/glamo/glamo-core.c | 1301 + .../files-2.6.30/drivers/mfd/glamo/glamo-core.h | 67 + .../files-2.6.30/drivers/mfd/glamo/glamo-fb.c | 1026 + .../files-2.6.30/drivers/mfd/glamo/glamo-gpio.c | 281 + .../files-2.6.30/drivers/mfd/glamo/glamo-mci.c | 987 + .../files-2.6.30/drivers/mfd/glamo/glamo-regs.h | 632 + .../files-2.6.30/drivers/misc/gta02_pm_host.c | 97 + .../drivers/misc/gta02_pm_resume_reason.c | 118 + .../files-2.6.30/drivers/power/bq27000_battery.c | 477 + .../linux/s3c24xx/files-2.6.30/drivers/power/hdq.c | 515 + .../files-2.6.30/drivers/video/display/jbt6k74.c | 835 + .../files-2.6.30/include/linux/bq27000_battery.h | 16 + .../files-2.6.30/include/linux/gta02-vibrator.h | 5 + .../s3c24xx/files-2.6.30/include/linux/gta02_hdq.h | 18 + .../linux/s3c24xx/files-2.6.30/include/linux/hdq.h | 32 + .../s3c24xx/files-2.6.30/include/linux/jbt6k74.h | 12 + .../s3c24xx/files-2.6.30/include/linux/lis302dl.h | 152 + .../s3c24xx/files-2.6.30/include/linux/mfd/glamo.h | 50 + .../include/linux/touchscreen/ts_filter.h | 74 + .../include/linux/touchscreen/ts_filter_chain.h | 58 + .../include/linux/touchscreen/ts_filter_group.h | 36 + .../include/linux/touchscreen/ts_filter_linear.h | 31 + .../include/linux/touchscreen/ts_filter_mean.h | 28 + .../include/linux/touchscreen/ts_filter_median.h | 32 + .../files-2.6.30/sound/soc/s3c24xx/gta02_wm8753.c | 535 + target/linux/s3c24xx/image/Makefile | 33 + target/linux/s3c24xx/modules.mk | 28 + .../openmoko-gta02/base-files/etc/acpi/sleep.sh | 4 + .../openmoko-gta02/base-files/etc/config/fstab | 6 + .../openmoko-gta02/base-files/etc/config/network | 14 + target/linux/s3c24xx/openmoko-gta02/config-2.6.30 | 416 + .../openmoko-gta02/profiles/100-gta02-minimal.mk | 17 + .../openmoko-gta02/profiles/101-gta02-full.mk | 17 + target/linux/s3c24xx/openmoko-gta02/target.mk | 7 + .../patches-2.6.30/001-merge-openmoko.patch | 2207 + .../linux/s3c24xx/patches-2.6.30/010-s3c-dma.patch | 1324 + .../linux/s3c24xx/patches-2.6.30/011-s3c-pwm.patch | 802 + .../linux/s3c24xx/patches-2.6.30/012-s3c-usb.patch | 478 + .../s3c24xx/patches-2.6.30/013-fiq_c_handler.patch | 286 + .../s3c24xx/patches-2.6.30/014-neo1973_mach.patch | 43 + .../s3c24xx/patches-2.6.30/015-mach-gta02.patch | 86 + ...030-dont-override-logo-with-early-printks.patch | 78 + .../patches-2.6.30/031-add-openwrt-logo.patch | 38448 +++++++++ .../patches-2.6.30/040-rename-serialdevs.patch | 11 + .../patches-2.6.30/050-s3c2442-touchscreen.patch | 142 + .../patches-2.6.30/052-touchscreen_filter.patch | 68 + .../linux/s3c24xx/patches-2.6.30/053-glamo.patch | 21 + .../linux/s3c24xx/patches-2.6.30/054-bq27000.patch | 31 + .../s3c24xx/patches-2.6.30/055-gta02-leds.patch | 25 + .../linux/s3c24xx/patches-2.6.30/055-jbt6k74.patch | 26 + .../s3c24xx/patches-2.6.30/056-pcf50633.patch | 461 + .../s3c24xx/patches-2.6.30/057-lis302dl.patch | 25 + .../s3c24xx/patches-2.6.30/058-gta02-wm8752.patch | 37 + .../patches-2.6.30/060-spi-gpio-non-blocking.patch | 418 + .../linux/s3c24xx/patches-2.6.30/068-ar6000.patch | 21 + .../s3c24xx/patches-2.6.30/070-s3c24xx-time.patch | 483 + .../patches-2.6.30/080-nr-tty-devices.patch | 43 + .../s3c24xx/patches-2.6.30/100-udc-poll-vbus.patch | 224 + .../linux/s3c24xx/patches-2.6.30/110-serial.patch | 38 + .../patches-2.6.30/120-fix-wm8753-reg_cache.patch | 26 + .../130-fix-s3c_gpiolib_getchip.patch | 11 + .../patches-2.6.30/150-ignore-init-argument.patch | 19 + target/linux/sibyte/Makefile | 24 + target/linux/sibyte/base-files/etc/inittab | 4 + target/linux/sibyte/config-3.3 | 145 + target/linux/sibyte/image/Makefile | 38 + .../sibyte/patches-3.3/101-rhone_physmap.patch | 82 + .../sibyte/patches-3.3/103-m41t80_smbus.patch | 367 + .../patches-3.3/104-sibyte_rtc_cleanup.patch | 80 + .../sibyte/patches-3.3/105-sibyte_hwmon.patch | 23 + .../sibyte/patches-3.3/106-no_module_reloc.patch | 370 + target/linux/sparc/Makefile | 19 + target/linux/sparc/config-default | 192 + target/linux/sparc/image/Makefile | 20 + target/linux/ubicom32/Makefile | 27 + target/linux/ubicom32/config-default | 171 + target/linux/ubicom32/files/arch/ubicom32/Kconfig | 403 + .../ubicom32/files/arch/ubicom32/Kconfig.debug | 129 + target/linux/ubicom32/files/arch/ubicom32/Makefile | 104 + .../ubicom32/files/arch/ubicom32/crypto/Makefile | 36 + .../files/arch/ubicom32/crypto/aes_ubicom32.c | 458 + .../files/arch/ubicom32/crypto/crypto_des.h | 34 + .../files/arch/ubicom32/crypto/crypto_ubicom32.c | 50 + .../files/arch/ubicom32/crypto/crypto_ubicom32.h | 346 + .../files/arch/ubicom32/crypto/des_check_key.c | 148 + .../files/arch/ubicom32/crypto/des_ubicom32.c | 761 + .../files/arch/ubicom32/crypto/md5_ubicom32.c | 200 + .../files/arch/ubicom32/crypto/md5_ubicom32_asm.S | 234 + .../files/arch/ubicom32/crypto/sha1_ubicom32.c | 354 + .../files/arch/ubicom32/crypto/sha1_ubicom32_asm.S | 244 + .../files/arch/ubicom32/include/asm/.gitignore | 1 + .../files/arch/ubicom32/include/asm/Kbuild | 1 + .../files/arch/ubicom32/include/asm/a.out.h | 47 + .../files/arch/ubicom32/include/asm/atomic.h | 353 + .../files/arch/ubicom32/include/asm/audio.h | 40 + .../files/arch/ubicom32/include/asm/audionode.h | 152 + .../files/arch/ubicom32/include/asm/auxvec.h | 32 + .../files/arch/ubicom32/include/asm/bitops.h | 172 + .../files/arch/ubicom32/include/asm/bitsperlong.h | 1 + .../files/arch/ubicom32/include/asm/board.h | 34 + .../files/arch/ubicom32/include/asm/bootargs.h | 34 + .../files/arch/ubicom32/include/asm/bootinfo.h | 34 + .../ubicom32/files/arch/ubicom32/include/asm/bug.h | 95 + .../files/arch/ubicom32/include/asm/bugs.h | 44 + .../files/arch/ubicom32/include/asm/byteorder.h | 33 + .../files/arch/ubicom32/include/asm/cache.h | 40 + .../files/arch/ubicom32/include/asm/cachectl.h | 39 + .../files/arch/ubicom32/include/asm/cacheflush.h | 111 + .../files/arch/ubicom32/include/asm/checksum.h | 149 + .../ubicom32/files/arch/ubicom32/include/asm/cpu.h | 45 + .../files/arch/ubicom32/include/asm/cputime.h | 33 + .../files/arch/ubicom32/include/asm/current.h | 44 + .../files/arch/ubicom32/include/asm/delay.h | 75 + .../files/arch/ubicom32/include/asm/device.h | 35 + .../files/arch/ubicom32/include/asm/devtree.h | 52 + .../files/arch/ubicom32/include/asm/div64.h | 33 + .../files/arch/ubicom32/include/asm/dma-mapping.h | 328 + .../ubicom32/files/arch/ubicom32/include/asm/dma.h | 34 + .../ubicom32/files/arch/ubicom32/include/asm/elf.h | 173 + .../arch/ubicom32/include/asm/emergency-restart.h | 33 + .../files/arch/ubicom32/include/asm/entry.h | 34 + .../files/arch/ubicom32/include/asm/errno.h | 33 + .../ubicom32/files/arch/ubicom32/include/asm/fb.h | 39 + .../files/arch/ubicom32/include/asm/fcntl.h | 38 + .../files/arch/ubicom32/include/asm/flat.h | 73 + .../ubicom32/files/arch/ubicom32/include/asm/fpu.h | 37 + .../files/arch/ubicom32/include/asm/ftrace.h | 1 + .../files/arch/ubicom32/include/asm/futex.h | 33 + .../files/arch/ubicom32/include/asm/gpio.h | 453 + .../files/arch/ubicom32/include/asm/hardirq.h | 55 + .../files/arch/ubicom32/include/asm/hw_irq.h | 31 + .../ubicom32/files/arch/ubicom32/include/asm/io.h | 313 + .../files/arch/ubicom32/include/asm/ioctl.h | 33 + .../files/arch/ubicom32/include/asm/ioctls.h | 111 + .../files/arch/ubicom32/include/asm/ip5000-asm.h | 156 + .../files/arch/ubicom32/include/asm/ip5000.h | 845 + .../files/arch/ubicom32/include/asm/ipcbuf.h | 55 + .../ubicom32/files/arch/ubicom32/include/asm/irq.h | 45 + .../files/arch/ubicom32/include/asm/irq_regs.h | 33 + .../files/arch/ubicom32/include/asm/irqflags.h | 96 + .../files/arch/ubicom32/include/asm/kdebug.h | 33 + .../files/arch/ubicom32/include/asm/kmap_types.h | 48 + .../files/arch/ubicom32/include/asm/ldsr.h | 186 + .../files/arch/ubicom32/include/asm/linkage.h | 34 + .../files/arch/ubicom32/include/asm/local.h | 33 + .../files/arch/ubicom32/include/asm/machdep.h | 43 + .../files/arch/ubicom32/include/asm/mc146818rtc.h | 36 + .../files/arch/ubicom32/include/asm/memory_map.h | 66 + .../files/arch/ubicom32/include/asm/mman.h | 44 + .../ubicom32/files/arch/ubicom32/include/asm/mmu.h | 41 + .../files/arch/ubicom32/include/asm/mmu_context.h | 60 + .../files/arch/ubicom32/include/asm/module.h | 48 + .../files/arch/ubicom32/include/asm/msgbuf.h | 58 + .../files/arch/ubicom32/include/asm/mutex.h | 41 + .../files/arch/ubicom32/include/asm/namei.h | 38 + .../files/arch/ubicom32/include/asm/ocm-alloc.h | 36 + .../files/arch/ubicom32/include/asm/ocm_size.h | 3 + .../arch/ubicom32/include/asm/ocm_text.lds.inc | 175 + .../files/arch/ubicom32/include/asm/page.h | 116 + .../files/arch/ubicom32/include/asm/page_offset.h | 35 + .../files/arch/ubicom32/include/asm/param.h | 49 + .../ubicom32/files/arch/ubicom32/include/asm/pci.h | 210 + .../files/arch/ubicom32/include/asm/pcm_tio.h | 84 + .../files/arch/ubicom32/include/asm/percpu.h | 33 + .../files/arch/ubicom32/include/asm/pgalloc.h | 36 + .../files/arch/ubicom32/include/asm/pgtable.h | 128 + .../files/arch/ubicom32/include/asm/plio.h | 313 + .../files/arch/ubicom32/include/asm/poll.h | 36 + .../files/arch/ubicom32/include/asm/posix_types.h | 93 + .../files/arch/ubicom32/include/asm/processor.h | 163 + .../arch/ubicom32/include/asm/profilesample.h | 44 + .../files/arch/ubicom32/include/asm/ptrace.h | 177 + .../arch/ubicom32/include/asm/range-protect-asm.h | 91 + .../arch/ubicom32/include/asm/range-protect.h | 62 + .../files/arch/ubicom32/include/asm/resource.h | 33 + .../files/arch/ubicom32/include/asm/ring_tio.h | 42 + .../files/arch/ubicom32/include/asm/scatterlist.h | 49 + .../files/arch/ubicom32/include/asm/sd_tio.h | 36 + .../files/arch/ubicom32/include/asm/sections.h | 33 + .../files/arch/ubicom32/include/asm/segment.h | 78 + .../arch/ubicom32/include/asm/semaphore-helper.h | 109 + .../files/arch/ubicom32/include/asm/semaphore.h | 140 + .../files/arch/ubicom32/include/asm/sembuf.h | 52 + .../files/arch/ubicom32/include/asm/setup.h | 35 + .../files/arch/ubicom32/include/asm/shmbuf.h | 69 + .../files/arch/ubicom32/include/asm/shmparam.h | 35 + .../files/arch/ubicom32/include/asm/sigcontext.h | 37 + .../files/arch/ubicom32/include/asm/siginfo.h | 33 + .../files/arch/ubicom32/include/asm/signal.h | 185 + .../ubicom32/files/arch/ubicom32/include/asm/smp.h | 87 + .../files/arch/ubicom32/include/asm/socket.h | 90 + .../files/arch/ubicom32/include/asm/sockios.h | 40 + .../files/arch/ubicom32/include/asm/spinlock.h | 296 + .../arch/ubicom32/include/asm/spinlock_types.h | 43 + .../files/arch/ubicom32/include/asm/stacktrace.h | 72 + .../files/arch/ubicom32/include/asm/stat.h | 104 + .../files/arch/ubicom32/include/asm/statfs.h | 33 + .../files/arch/ubicom32/include/asm/string.h | 40 + .../files/arch/ubicom32/include/asm/swab.h | 45 + .../files/arch/ubicom32/include/asm/switch-dev.h | 51 + .../files/arch/ubicom32/include/asm/system.h | 101 + .../files/arch/ubicom32/include/asm/termbits.h | 227 + .../files/arch/ubicom32/include/asm/termios.h | 119 + .../files/arch/ubicom32/include/asm/thread-asm.h | 51 + .../files/arch/ubicom32/include/asm/thread.h | 320 + .../files/arch/ubicom32/include/asm/thread_info.h | 134 + .../files/arch/ubicom32/include/asm/timex.h | 56 + .../ubicom32/files/arch/ubicom32/include/asm/tlb.h | 47 + .../files/arch/ubicom32/include/asm/tlbflush.h | 79 + .../files/arch/ubicom32/include/asm/topology.h | 33 + .../files/arch/ubicom32/include/asm/traps.h | 55 + .../files/arch/ubicom32/include/asm/types.h | 75 + .../files/arch/ubicom32/include/asm/uaccess.h | 347 + .../files/arch/ubicom32/include/asm/uart_tio.h | 126 + .../files/arch/ubicom32/include/asm/ubi32-cs4384.h | 52 + .../files/arch/ubicom32/include/asm/ubi32-pcm.h | 54 + .../ubicom32/include/asm/ubicom32-common-asm.h | 49 + .../arch/ubicom32/include/asm/ubicom32-common.h | 128 + .../arch/ubicom32/include/asm/ubicom32-spi-gpio.h | 62 + .../files/arch/ubicom32/include/asm/ubicom32-tio.h | 42 + .../files/arch/ubicom32/include/asm/ubicom32bl.h | 84 + .../files/arch/ubicom32/include/asm/ubicom32fb.h | 56 + .../files/arch/ubicom32/include/asm/ubicom32hid.h | 133 + .../arch/ubicom32/include/asm/ubicom32input.h | 76 + .../arch/ubicom32/include/asm/ubicom32input_i2c.h | 71 + .../files/arch/ubicom32/include/asm/ubicom32lcd.h | 38 + .../arch/ubicom32/include/asm/ubicom32lcdpower.h | 39 + .../files/arch/ubicom32/include/asm/ubicom32ring.h | 103 + .../files/arch/ubicom32/include/asm/ubicom32sd.h | 45 + .../arch/ubicom32/include/asm/ubicom32suart.h | 36 + .../files/arch/ubicom32/include/asm/ucontext.h | 39 + .../files/arch/ubicom32/include/asm/unaligned.h | 44 + .../files/arch/ubicom32/include/asm/unistd.h | 400 + .../files/arch/ubicom32/include/asm/user.h | 82 + .../files/arch/ubicom32/include/asm/vdc_tio.h | 129 + .../ubicom32/files/arch/ubicom32/include/asm/vga.h | 71 + .../ubicom32/files/arch/ubicom32/include/asm/xor.h | 33 + .../ubicom32/files/arch/ubicom32/kernel/Makefile | 64 + .../files/arch/ubicom32/kernel/asm-offsets.c | 161 + .../ubicom32/files/arch/ubicom32/kernel/devtree.c | 173 + .../ubicom32/files/arch/ubicom32/kernel/dma.c | 60 + .../ubicom32/files/arch/ubicom32/kernel/flat.c | 206 + .../ubicom32/files/arch/ubicom32/kernel/head.S | 273 + .../files/arch/ubicom32/kernel/init_task.c | 65 + .../ubicom32/files/arch/ubicom32/kernel/irq.c | 597 + .../ubicom32/files/arch/ubicom32/kernel/ldsr.c | 1185 + .../ubicom32/files/arch/ubicom32/kernel/module.c | 463 + .../ubicom32/files/arch/ubicom32/kernel/os_node.c | 88 + .../ubicom32/files/arch/ubicom32/kernel/process.c | 634 + .../files/arch/ubicom32/kernel/processor.c | 348 + .../ubicom32/files/arch/ubicom32/kernel/ptrace.c | 275 + .../files/arch/ubicom32/kernel/semaphore.c | 159 + .../ubicom32/files/arch/ubicom32/kernel/setup.c | 194 + .../ubicom32/files/arch/ubicom32/kernel/signal.c | 458 + .../ubicom32/files/arch/ubicom32/kernel/smp.c | 806 + .../files/arch/ubicom32/kernel/stacktrace.c | 244 + .../files/arch/ubicom32/kernel/sys_ubicom32.c | 237 + .../files/arch/ubicom32/kernel/syscalltable.S | 376 + .../ubicom32/files/arch/ubicom32/kernel/thread.c | 228 + .../ubicom32/files/arch/ubicom32/kernel/time.c | 212 + .../files/arch/ubicom32/kernel/timer_broadcast.c | 102 + .../files/arch/ubicom32/kernel/timer_device.c | 301 + .../files/arch/ubicom32/kernel/timer_tick.c | 109 + .../ubicom32/files/arch/ubicom32/kernel/topology.c | 47 + .../ubicom32/files/arch/ubicom32/kernel/traps.c | 514 + .../ubicom32/files/arch/ubicom32/kernel/uaccess.c | 109 + .../arch/ubicom32/kernel/ubicom32_context_switch.S | 359 + .../files/arch/ubicom32/kernel/ubicom32_ksyms.c | 98 + .../files/arch/ubicom32/kernel/ubicom32_syscall.S | 694 + .../files/arch/ubicom32/kernel/unaligned_trap.c | 698 + .../files/arch/ubicom32/kernel/vmlinux.lds.S | 370 + .../ubicom32/files/arch/ubicom32/lib/Makefile | 32 + .../ubicom32/files/arch/ubicom32/lib/checksum.c | 250 + .../linux/ubicom32/files/arch/ubicom32/lib/delay.c | 49 + .../files/arch/ubicom32/lib/mem_ubicom32.c | 343 + .../files/arch/ubicom32/mach-common/Kconfig.switch | 12 + .../files/arch/ubicom32/mach-common/Makefile | 41 + .../files/arch/ubicom32/mach-common/audio.c | 134 + .../files/arch/ubicom32/mach-common/board.c | 63 + .../files/arch/ubicom32/mach-common/bootargs.c | 63 + .../files/arch/ubicom32/mach-common/cachectl.c | 136 + .../files/arch/ubicom32/mach-common/common.c | 64 + .../ubicom32/files/arch/ubicom32/mach-common/io.c | 250 + .../ubicom32/files/arch/ubicom32/mach-common/pci.c | 1157 + .../files/arch/ubicom32/mach-common/plio.c | 92 + .../files/arch/ubicom32/mach-common/profile.c | 549 + .../files/arch/ubicom32/mach-common/profile.h | 82 + .../files/arch/ubicom32/mach-common/profpkt.h | 158 + .../files/arch/ubicom32/mach-common/ring_tio.c | 123 + .../arch/ubicom32/mach-common/switch-bcm539x-reg.h | 221 + .../arch/ubicom32/mach-common/switch-bcm539x.c | 1195 + .../files/arch/ubicom32/mach-common/switch-core.c | 737 + .../files/arch/ubicom32/mach-common/switch-core.h | 92 + .../files/arch/ubicom32/mach-common/ubi32-gpio.c | 411 + .../files/arch/ubicom32/mach-common/ubicom32hid.c | 557 + .../arch/ubicom32/mach-common/ubicom32input.c | 265 + .../arch/ubicom32/mach-common/ubicom32input_i2c.c | 325 + .../ubicom32/files/arch/ubicom32/mach-common/usb.c | 132 + .../files/arch/ubicom32/mach-common/usb_tio.c | 356 + .../files/arch/ubicom32/mach-common/usb_tio.h | 111 + .../files/arch/ubicom32/mach-common/vdc_tio.c | 111 + .../ubicom32/files/arch/ubicom32/mach-ip5k/Kconfig | 28 + .../files/arch/ubicom32/mach-ip5k/Makefile | 31 + .../arch/ubicom32/mach-ip5k/board-ip5160dev.c | 109 + .../arch/ubicom32/mach-ip5k/board-ip5160rgw.c | 75 + .../arch/ubicom32/mach-ip5k/board-ip5170dpf.c | 279 + .../ubicom32/files/arch/ubicom32/mach-ip7k/Kconfig | 205 + .../files/arch/ubicom32/mach-ip7k/Makefile | 38 + .../arch/ubicom32/mach-ip7k/board-ip7145dpf.c | 715 + .../arch/ubicom32/mach-ip7k/board-ip7160bringup.c | 134 + .../arch/ubicom32/mach-ip7k/board-ip7160dpf.c | 326 + .../arch/ubicom32/mach-ip7k/board-ip7160rgw.c | 355 + .../files/arch/ubicom32/mach-ip7k/board-ip7500av.c | 273 + .../arch/ubicom32/mach-ip7k/board-ip7500iap.c | 414 + .../arch/ubicom32/mach-ip7k/board-ip7500media.c | 732 + .../arch/ubicom32/mach-ip7k/board-ip7500module.c | 55 + .../arch/ubicom32/mach-ip7k/board-ip7500wspkr.c | 101 + .../linux/ubicom32/files/arch/ubicom32/mm/Makefile | 32 + .../linux/ubicom32/files/arch/ubicom32/mm/fault.c | 80 + .../linux/ubicom32/files/arch/ubicom32/mm/init.c | 262 + .../linux/ubicom32/files/arch/ubicom32/mm/kmap.c | 79 + .../linux/ubicom32/files/arch/ubicom32/mm/memory.c | 58 + .../ubicom32/files/arch/ubicom32/mm/ocm-alloc.c | 487 + .../ubicom32/files/arch/ubicom32/oprofile/Makefile | 37 + .../ubicom32/files/arch/ubicom32/oprofile/ipProf.h | 39 + .../files/arch/ubicom32/oprofile/profile.c | 221 + .../files/drivers/char/hw_random/ubicom32-rng.c | 105 + .../ubicom32/files/drivers/mmc/host/ubicom32sd.c | 773 + .../files/drivers/mtd/devices/nand-spi-er.c | 1017 + .../files/drivers/mtd/devices/ubi32-m25p80.c | 1066 + .../files/drivers/mtd/devices/ubi32-nand-spi-er.c | 1188 + .../linux/ubicom32/files/drivers/net/ubi32-eth.c | 766 + .../linux/ubicom32/files/drivers/net/ubi32-eth.h | 132 + .../ubicom32/files/drivers/serial/ubi32_mailbox.c | 938 + .../ubicom32/files/drivers/serial/ubi32_serdes.c | 817 + .../ubicom32/files/drivers/serial/ubi32_uarttio.c | 1172 + .../ubicom32/files/drivers/spi/spi_ubicom32_gpio.c | 267 + .../ubicom32/files/drivers/uio/uio_ubicom32ring.c | 288 + .../ubicom32/files/drivers/usb/musb/ubi32_usb.c | 156 + .../files/drivers/video/backlight/ubicom32bl.c | 399 + .../files/drivers/video/backlight/ubicom32lcd.c | 372 + .../files/drivers/video/backlight/ubicom32lcd.h | 546 + .../drivers/video/backlight/ubicom32lcdpower.c | 194 + .../ubicom32/files/drivers/video/ubicom32fb.c | 779 + .../ubicom32/files/drivers/video/ubicom32plio80.c | 780 + .../ubicom32/files/drivers/video/ubicom32vfb.c | 603 + .../ubicom32/files/drivers/watchdog/ubi32_wdt.c | 630 + target/linux/ubicom32/files/sound/ubicom32/Kconfig | 42 + .../linux/ubicom32/files/sound/ubicom32/Makefile | 41 + .../ubicom32/files/sound/ubicom32/ubi32-cs4350.c | 583 + .../ubicom32/files/sound/ubicom32/ubi32-cs4384.c | 996 + .../files/sound/ubicom32/ubi32-generic-capture.c | 167 + .../ubicom32/files/sound/ubicom32/ubi32-generic.c | 166 + .../ubicom32/files/sound/ubicom32/ubi32-pcm.c | 711 + target/linux/ubicom32/files/sound/ubicom32/ubi32.h | 102 + target/linux/ubicom32/image/Makefile | 12 + .../patches-2.6.30/100-ubicom32_support.patch | 1741 + .../patches-2.6.30/110-vmlinux_lds_fix.patch | 150 + .../ubicom32/patches-2.6.30/120-libgcc_func.patch | 419 + .../patches-2.6.30/130-flash_driver_fix.patch | 13 + .../ubicom32/patches-2.6.30/140-arch_cflags.patch | 13 + .../patches-2.6.32/100-ubicom32_support.patch | 1725 + .../patches-2.6.32/110-vmlinux_lds_fix.patch | 150 + .../ubicom32/patches-2.6.32/120-libgcc_func.patch | 419 + .../patches-2.6.32/130-flash_driver_fix.patch | 13 + .../ubicom32/patches-2.6.32/140-arch_cflags.patch | 13 + target/linux/uml/Makefile | 36 + target/linux/uml/README | 45 + target/linux/uml/config/i386 | 168 + target/linux/uml/config/x86_64 | 147 + target/linux/uml/image/Makefile | 19 + .../patches-3.2/901-lib_zlib_deflate_visible.patch | 14 + .../patches-3.3/001-include_sys_resource_h.patch | 10 + .../patches-3.3/901-lib_zlib_deflate_visible.patch | 14 + target/linux/x86/Makefile | 23 + .../linux/x86/alix2/base-files/etc/config/network | 20 + .../linux/x86/alix2/base-files/etc/config/system | 29 + .../base-files/etc/hotplug.d/button/50-reboot | 13 + target/linux/x86/alix2/config-3.3 | 25 + target/linux/x86/alix2/target.mk | 34 + target/linux/x86/base-files.mk | 6 + .../x86/base-files/etc/defconfig/net4801/network | 16 + .../x86/base-files/etc/defconfig/net4826/network | 12 + target/linux/x86/base-files/etc/init.d/defconfig | 20 + .../x86/base-files/lib/preinit/15_essential_fs_x86 | 8 + .../x86/base-files/lib/preinit/45_failsafe_x86 | 13 + .../x86/base-files/lib/preinit/89_move_config | 22 + target/linux/x86/base-files/lib/soekris.sh | 19 + .../linux/x86/base-files/lib/upgrade/platform.sh | 50 + target/linux/x86/config-3.3 | 382 + target/linux/x86/ep80579/config-3.3 | 11 + target/linux/x86/ep80579/target.mk | 9 + target/linux/x86/generic/config-3.3 | 188 + target/linux/x86/generic/profiles/000-Generic.mk | 18 + target/linux/x86/generic/profiles/Soekris45xx.mk | 16 + target/linux/x86/generic/profiles/Soekris48xx.mk | 16 + target/linux/x86/generic/profiles/Wrap.mk | 16 + target/linux/x86/generic/target.mk | 7 + .../linux/x86/geos/base-files/etc/config/network | 44 + target/linux/x86/geos/base-files/etc/config/system | 30 + .../geos/base-files/etc/hotplug.d/button/50-reboot | 13 + target/linux/x86/geos/config-3.3 | 25 + target/linux/x86/geos/target.mk | 36 + target/linux/x86/image/Config.in | 106 + target/linux/x86/image/Makefile | 256 + target/linux/x86/image/gen_image_generic.sh | 39 + target/linux/x86/image/gen_image_grub.sh | 13 + target/linux/x86/image/gen_image_olpc.sh | 35 + target/linux/x86/image/grub-early.cfg | 1 + target/linux/x86/image/grub.cfg | 13 + target/linux/x86/image/menu.lst | 15 + target/linux/x86/image/olpc.fth | 5 + target/linux/x86/kvm_guest/config-3.3 | 82 + target/linux/x86/kvm_guest/target.mk | 2 + target/linux/x86/modules.mk | 314 + .../x86/net5501/base-files/etc/config/network | 18 + .../linux/x86/net5501/base-files/etc/config/system | 16 + .../base-files/etc/hotplug.d/button/50-reboot | 13 + target/linux/x86/net5501/config-3.3 | 19 + target/linux/x86/net5501/target.mk | 34 + target/linux/x86/olpc/base-files/etc/X11/xorg.conf | 71 + .../linux/x86/olpc/base-files/etc/config/network | 11 + .../base-files/lib/preinit/15_essential_fs_x86 | 9 + .../olpc/base-files/lib/preinit/45_failsafe_x86 | 14 + .../x86/olpc/base-files/lib/upgrade/platform.sh | 27 + target/linux/x86/olpc/config-3.3 | 122 + target/linux/x86/olpc/target.mk | 2 + .../linux/x86/patches-3.3/001-alix_platform.patch | 131 + .../linux/x86/patches-3.3/002-geos_platform.patch | 178 + .../x86/patches-3.3/003-via-rhine-crash-fix.patch | 60 + .../linux/x86/thincan/base-files/etc/init.d/alsa | 9 + target/linux/x86/thincan/config-3.3 | 15 + target/linux/x86/thincan/profiles/dbe61.mk | 25 + target/linux/x86/thincan/target.mk | 37 + target/linux/x86/xen_domu/base-files/etc/inittab | 5 + .../xen_domu/base-files/lib/preinit/45_mount_xenfs | 11 + target/linux/x86/xen_domu/config-3.3 | 77 + target/linux/x86/xen_domu/target.mk | 3 + target/linux/xburst/Makefile | 25 + target/linux/xburst/base-files/etc/config/fstab | 6 + target/linux/xburst/base-files/etc/config/network | 13 + target/linux/xburst/base-files/etc/config/system | 3 + target/linux/xburst/config-3.3 | 302 + target/linux/xburst/id800wt/config-3.3 | 51 + target/linux/xburst/id800wt/target.mk | 8 + target/linux/xburst/image/Makefile | 46 + target/linux/xburst/image/ubinize.cfg | 14 + target/linux/xburst/modules.mk | 50 + target/linux/xburst/n516/config-3.3 | 11 + target/linux/xburst/n516/target.mk | 8 + target/linux/xburst/n526/config-3.3 | 1 + target/linux/xburst/n526/target.mk | 7 + ...ly-the-vid-header-instead-of-the-whole-pa.patch | 21 + .../patches-3.3/0002-Add-jz4740-udc-driver.patch | 2371 + ...-NAND-Optimize-NAND_ECC_HW_OOB_FIRST-read.patch | 40 + ...pport-for-subpage-reads-for-NAND_ECC_HW_O.patch | 144 + ...imize-reading-the-eec-data-for-the-JZ4740.patch | 53 + ...4740-Multi-bank-support-with-autodetectio.patch | 417 + .../patches-3.3/0007-Add-ili8960-lcd-driver.patch | 304 + ...-t-use-3-wire-spi-mode-for-the-display-fo.patch | 21 + ...-kernel-config-option-to-omit-this-device.patch | 124 + ...ts-Support-runtime-changes-to-frequency-t.patch | 301 + ...-Added-setting-of-PLL-rate-and-main-divid.patch | 351 + .../0012-MIPS-JZ4740-Add-cpufreq-support.patch | 298 + ...-Added-support-for-CPU-frequency-changing.patch | 129 + ...-reset-Initialize-hibernate-wakeup-counte.patch | 91 + ...-Replaced-comma-operators-with-semicolons.patch | 31 + ...-Support-buffer-size-that-is-not-a-multip.patch | 89 + ...4740-qi_lb60-Look-for-NAND-chip-in-bank-1.patch | 21 + ...-Convert-qi_lb60-to-use-snd_soc_register_.patch | 121 + ...-notifier-Call-notifier-callbacks-prior-t.patch | 38 + .../0020-qi_lb60-NAND-add-data-partition.patch | 26 + ...0021-rtc-jz4740-fix-hwclock-give-time-out.patch | 20 + target/linux/xburst/qi_lb60/config-3.3 | 33 + target/linux/xburst/qi_lb60/target.mk | 1 + 3080 files changed, 1045021 insertions(+) create mode 100644 target/linux/Makefile create mode 100644 target/linux/adm5120/Makefile create mode 100644 target/linux/adm5120/base-files/etc/config/network create mode 100644 target/linux/adm5120/base-files/etc/config/system create mode 100755 target/linux/adm5120/base-files/etc/diag.sh create mode 100755 target/linux/adm5120/base-files/lib/adm5120.sh create mode 100644 target/linux/adm5120/base-files/lib/preinit/05_preinit_do_adm5120.sh create mode 100644 target/linux/adm5120/base-files/lib/preinit/05_reset_button_adm5120 create mode 100644 target/linux/adm5120/base-files/lib/preinit/05_set_preinit_iface_adm5120 create mode 100644 target/linux/adm5120/base-files/lib/upgrade/platform.sh create mode 100644 target/linux/adm5120/config-3.3 create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/Kconfig create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/Platform create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/cellvision/Makefile create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/cellvision/cas-771.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/cellvision/cellvision.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/cellvision/cellvision.h create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/cellvision/nfs-101.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/common/Makefile create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/common/adm5120.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/common/clock.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/common/early-printk.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/common/gpio.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/common/irq.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/common/memory.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/common/platform.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/common/prom.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/common/setup.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/compex/Makefile create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/compex/compex.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/compex/compex.h create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/compex/np27g.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/compex/np28g.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/compex/wp54.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/edimax/Makefile create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/edimax/br-6104k.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/edimax/br-6104kp.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/edimax/br-61x4wg.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/edimax/br-61xx.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/edimax/br-61xx.h create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/generic/Makefile create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/generic/eb-214a.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/infineon/Makefile create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/infineon/easy5120-rt.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/infineon/easy5120-wvoip.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/infineon/easy5120p-ata.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/infineon/easy83000.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/infineon/infineon.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/infineon/infineon.h create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/mikrotik/Makefile create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-11x.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-133.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-133c.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-150.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-153.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-192.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-1xx.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-1xx.h create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/motorola/Makefile create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/motorola/pmugw.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/osbridge/5gxi.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/osbridge/Makefile create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/prom/Makefile create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/prom/admboot.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/prom/bootbase.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/prom/cfe.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/prom/generic.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/prom/myloader.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/prom/prom_read.h create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/prom/routerboot.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/zyxel/Makefile create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-334wt.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-335.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-33x.c create mode 100644 target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-33x.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_defs.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_info.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_intc.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_mpmc.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_nand.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_platform.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_switch.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_uart.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/asm/sizes.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/cpu-feature-overrides.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/gpio.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/irq.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/admboot.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/cfe.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/generic.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/myloader.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/routerboot.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/zynos.h create mode 100644 target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/war.h create mode 100644 target/linux/adm5120/files/arch/mips/pci/pci-adm5120.c create mode 100644 target/linux/adm5120/files/drivers/ata/pata_rb153_cf.c create mode 100644 target/linux/adm5120/files/drivers/leds/ledtrig-adm5120-switch.c create mode 100644 target/linux/adm5120/files/drivers/mtd/maps/adm5120-flash.c create mode 100644 target/linux/adm5120/files/drivers/mtd/trxsplit.c create mode 100644 target/linux/adm5120/files/drivers/net/adm5120sw.c create mode 100644 target/linux/adm5120/files/drivers/net/adm5120sw.h create mode 100644 target/linux/adm5120/files/drivers/usb/host/adm5120-dbg.c create mode 100644 target/linux/adm5120/files/drivers/usb/host/adm5120-drv.c create mode 100644 target/linux/adm5120/files/drivers/usb/host/adm5120-hcd.c create mode 100644 target/linux/adm5120/files/drivers/usb/host/adm5120-hub.c create mode 100644 target/linux/adm5120/files/drivers/usb/host/adm5120-mem.c create mode 100644 target/linux/adm5120/files/drivers/usb/host/adm5120-pm.c create mode 100644 target/linux/adm5120/files/drivers/usb/host/adm5120-q.c create mode 100644 target/linux/adm5120/files/drivers/usb/host/adm5120.h create mode 100644 target/linux/adm5120/files/drivers/watchdog/adm5120_wdt.c create mode 100644 target/linux/adm5120/image/Makefile create mode 100644 target/linux/adm5120/image/lzma-loader/Makefile create mode 100644 target/linux/adm5120/image/lzma-loader/src/LzmaDecode.c create mode 100644 target/linux/adm5120/image/lzma-loader/src/LzmaDecode.h create mode 100644 target/linux/adm5120/image/lzma-loader/src/LzmaTypes.h create mode 100644 target/linux/adm5120/image/lzma-loader/src/Makefile create mode 100644 target/linux/adm5120/image/lzma-loader/src/README create mode 100644 target/linux/adm5120/image/lzma-loader/src/board.c create mode 100644 target/linux/adm5120/image/lzma-loader/src/config.h create mode 100644 target/linux/adm5120/image/lzma-loader/src/decompress.c create mode 100644 target/linux/adm5120/image/lzma-loader/src/head.S create mode 100644 target/linux/adm5120/image/lzma-loader/src/loader.lds create mode 100644 target/linux/adm5120/image/lzma-loader/src/lzma-data.lds create mode 100644 target/linux/adm5120/image/lzma-loader/src/printf.c create mode 100644 target/linux/adm5120/image/lzma-loader/src/printf.h create mode 100644 target/linux/adm5120/image/rb1xx.mk create mode 100644 target/linux/adm5120/image/router_be.mk create mode 100644 target/linux/adm5120/image/router_le.mk create mode 100644 target/linux/adm5120/modules.mk create mode 100644 target/linux/adm5120/patches-3.3/001-adm5120.patch create mode 100644 target/linux/adm5120/patches-3.3/002-adm5120_flash.patch create mode 100644 target/linux/adm5120/patches-3.3/003-adm5120_switch.patch create mode 100644 target/linux/adm5120/patches-3.3/005-adm5120_usb.patch create mode 100644 target/linux/adm5120/patches-3.3/007-adm5120_pci.patch create mode 100644 target/linux/adm5120/patches-3.3/009-adm5120_leds_switch_trigger.patch create mode 100644 target/linux/adm5120/patches-3.3/101-cfi_fixup_macronix_bootloc.patch create mode 100644 target/linux/adm5120/patches-3.3/102-jedec_pmc_39lvxxx_chips.patch create mode 100644 target/linux/adm5120/patches-3.3/103-mtd_trxsplit.patch create mode 100644 target/linux/adm5120/patches-3.3/120-rb153_cf_driver.patch create mode 100644 target/linux/adm5120/patches-3.3/200-amba_pl010_hacks.patch create mode 100644 target/linux/adm5120/patches-3.3/201-amba_bus_hacks.patch create mode 100644 target/linux/adm5120/patches-3.3/203-gpio_leds_brightness.patch create mode 100644 target/linux/adm5120/patches-3.3/310-adm5120_wdt.patch create mode 100755 target/linux/adm5120/rb1xx/base-files/sbin/wget2nand create mode 100644 target/linux/adm5120/rb1xx/config-3.3 create mode 100644 target/linux/adm5120/rb1xx/profiles/RB1xx.mk create mode 100644 target/linux/adm5120/rb1xx/target.mk create mode 100644 target/linux/adm5120/router_be/config-3.3 create mode 100644 target/linux/adm5120/router_be/profiles/010-Generic.mk create mode 100644 target/linux/adm5120/router_be/profiles/200-ZyXEL.mk create mode 100644 target/linux/adm5120/router_be/target.mk create mode 100644 target/linux/adm5120/router_le/config-3.3 create mode 100644 target/linux/adm5120/router_le/profiles/010-Generic.mk create mode 100644 target/linux/adm5120/router_le/profiles/Cellvision.mk create mode 100644 target/linux/adm5120/router_le/profiles/Compex.mk create mode 100644 target/linux/adm5120/router_le/profiles/Edimax.mk create mode 100644 target/linux/adm5120/router_le/profiles/Infineon.mk create mode 100644 target/linux/adm5120/router_le/profiles/Motorola.mk create mode 100644 target/linux/adm5120/router_le/profiles/Osbridge.mk create mode 100644 target/linux/adm5120/router_le/target.mk create mode 100644 target/linux/adm8668/Makefile create mode 100644 target/linux/adm8668/base-files.mk create mode 100644 target/linux/adm8668/base-files/etc/config/network create mode 100644 target/linux/adm8668/base-files/etc/diag.sh create mode 100644 target/linux/adm8668/base-files/lib/preinit/03_init_hotplug_failsafe_adm8668 create mode 100644 target/linux/adm8668/base-files/lib/preinit/05_set_preinit_face_adm8668 create mode 100644 target/linux/adm8668/base-files/lib/preinit/45_failsafe_adm8668 create mode 100644 target/linux/adm8668/base-files/lib/upgrade/platform.sh create mode 100644 target/linux/adm8668/base-files/sbin/hotplug.failsafe create mode 100644 target/linux/adm8668/config-3.3 create mode 100644 target/linux/adm8668/files/arch/mips/adm8668/Makefile create mode 100644 target/linux/adm8668/files/arch/mips/adm8668/Platform create mode 100644 target/linux/adm8668/files/arch/mips/adm8668/irq.c create mode 100644 target/linux/adm8668/files/arch/mips/adm8668/net.h create mode 100644 target/linux/adm8668/files/arch/mips/adm8668/net_core.c create mode 100644 target/linux/adm8668/files/arch/mips/adm8668/net_intr.c create mode 100644 target/linux/adm8668/files/arch/mips/adm8668/pci.c create mode 100644 target/linux/adm8668/files/arch/mips/adm8668/platform.c create mode 100644 target/linux/adm8668/files/arch/mips/adm8668/proc.c create mode 100644 target/linux/adm8668/files/arch/mips/adm8668/prom.c create mode 100644 target/linux/adm8668/files/arch/mips/adm8668/serial.c create mode 100644 target/linux/adm8668/files/arch/mips/adm8668/u-boot.h create mode 100644 target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h create mode 100644 target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/irq.h create mode 100644 target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/war.h create mode 100644 target/linux/adm8668/files/drivers/mtd/maps/adm8668.c create mode 100644 target/linux/adm8668/image/Makefile create mode 100644 target/linux/adm8668/image/lzma-loader/Makefile create mode 100644 target/linux/adm8668/image/lzma-loader/src/LzmaDecode.c create mode 100644 target/linux/adm8668/image/lzma-loader/src/LzmaDecode.h create mode 100644 target/linux/adm8668/image/lzma-loader/src/Makefile create mode 100644 target/linux/adm8668/image/lzma-loader/src/decompress.c create mode 100644 target/linux/adm8668/image/lzma-loader/src/include/_exports.h create mode 100644 target/linux/adm8668/image/lzma-loader/src/include/asm/global_data.h create mode 100644 target/linux/adm8668/image/lzma-loader/src/include/asm/u-boot.h create mode 100644 target/linux/adm8668/image/lzma-loader/src/include/common.h create mode 100644 target/linux/adm8668/image/lzma-loader/src/include/exports.h create mode 100644 target/linux/adm8668/image/lzma-loader/src/include/image.h create mode 100644 target/linux/adm8668/image/lzma-loader/src/lzma.lds.in create mode 100644 target/linux/adm8668/image/lzma-loader/src/stubs.c create mode 100755 target/linux/adm8668/image/my-mkimage create mode 100644 target/linux/adm8668/patches-3.3/001-adm8668_arch.patch create mode 100644 target/linux/adm8668/patches-3.3/002-adm8668_uart.patch create mode 100644 target/linux/adm8668/patches-3.3/003-adm8668_nor_map.patch create mode 100644 target/linux/amazon/Makefile create mode 100644 target/linux/amazon/base-files/etc/config/network create mode 100644 target/linux/amazon/config-3.3 create mode 100644 target/linux/amazon/files/arch/mips/amazon/Kconfig create mode 100644 target/linux/amazon/files/arch/mips/amazon/Makefile create mode 100644 target/linux/amazon/files/arch/mips/amazon/board.c create mode 100644 target/linux/amazon/files/arch/mips/amazon/dma-core.c create mode 100644 target/linux/amazon/files/arch/mips/amazon/dma-core.h create mode 100644 target/linux/amazon/files/arch/mips/amazon/interrupt.c create mode 100644 target/linux/amazon/files/arch/mips/amazon/pci.c create mode 100644 target/linux/amazon/files/arch/mips/amazon/prom.c create mode 100644 target/linux/amazon/files/arch/mips/amazon/setup.c create mode 100644 target/linux/amazon/files/arch/mips/include/asm/mach-amazon/irq.h create mode 100644 target/linux/amazon/files/arch/mips/include/asm/mach-amazon/mangle-port.h create mode 100644 target/linux/amazon/files/arch/mips/include/asm/mach-amazon/war.h create mode 100644 target/linux/amazon/files/drivers/atm/amazon_tpe.c create mode 100644 target/linux/amazon/files/drivers/char/amazon_mei.c create mode 100644 target/linux/amazon/files/drivers/char/ifx_ssc.c create mode 100644 target/linux/amazon/files/drivers/mtd/maps/amazon.c create mode 100644 target/linux/amazon/files/drivers/net/ethernet/admmod.c create mode 100644 target/linux/amazon/files/drivers/net/ethernet/amazon_sw.c create mode 100644 target/linux/amazon/files/drivers/tty/serial/amazon_asc.c create mode 100644 target/linux/amazon/files/drivers/watchdog/amazon_wdt.c create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/adm6996.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/amazon.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/amazon_dma.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/amazon_mei.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_app.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_app_ioctl.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_ioctl.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/amazon_sw.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/amazon_tpe.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/amazon_wdt.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/atm_defines.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/atm_mib.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/ifx_peripheral_definitions.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/ifx_ssc.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/ifx_ssc_defines.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/irq.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/model.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/port.h create mode 100644 target/linux/amazon/files/include/asm-mips/amazon/serial.h create mode 100644 target/linux/amazon/image/Makefile create mode 100644 target/linux/amazon/patches-3.3/000-mips-bad-intctl.patch create mode 100644 target/linux/amazon/patches-3.3/010-mips_clocksource_init_war.patch create mode 100644 target/linux/amazon/patches-3.3/017-wdt-driver.patch create mode 100644 target/linux/amazon/patches-3.3/100-board.patch create mode 100644 target/linux/amazon/patches-3.3/130-mtd_drivers.patch create mode 100644 target/linux/amazon/patches-3.3/140-net_drivers.patch create mode 100644 target/linux/amazon/patches-3.3/150-serial_driver.patch create mode 100644 target/linux/amazon/patches-3.3/160-cfi-swap.patch create mode 100644 target/linux/ar7/Makefile create mode 100644 target/linux/ar7/base-files.mk create mode 100644 target/linux/ar7/base-files/etc/config/network create mode 100644 target/linux/ar7/base-files/etc/diag.sh create mode 100755 target/linux/ar7/base-files/etc/init.d/adam2 create mode 100644 target/linux/ar7/base-files/etc/uci-defaults/network create mode 100644 target/linux/ar7/config-3.3 create mode 100644 target/linux/ar7/files/drivers/char/ar7_gpio.c create mode 100644 target/linux/ar7/files/drivers/mtd/titanpart.c create mode 100644 target/linux/ar7/image/Makefile create mode 100644 target/linux/ar7/patches-3.3/110-flash.patch create mode 100644 target/linux/ar7/patches-3.3/120-gpio_chrdev.patch create mode 100644 target/linux/ar7/patches-3.3/160-vlynq_try_remote_first.patch create mode 100644 target/linux/ar7/patches-3.3/500-serial_kludge.patch create mode 100644 target/linux/ar7/patches-3.3/920-ar7part.patch create mode 100644 target/linux/ar7/patches-3.3/950-cpmac_titan.patch create mode 100644 target/linux/ar7/patches-3.3/972-cpmac_fixup.patch create mode 100644 target/linux/ar7/profiles/100-Annex-A.mk create mode 100644 target/linux/ar7/profiles/110-Annex-B.mk create mode 100644 target/linux/ar7/profiles/200-Texas.mk create mode 100644 target/linux/ar7/profiles/210-None.mk create mode 100644 target/linux/ar7/src/adam2patcher.c create mode 100644 target/linux/ar71xx/Makefile create mode 100644 target/linux/ar71xx/base-files.mk create mode 100644 target/linux/ar71xx/base-files/etc/defconfig/wndr3700/network create mode 100755 target/linux/ar71xx/base-files/etc/diag.sh create mode 100644 target/linux/ar71xx/base-files/etc/hotplug.d/net/10-ar922x-led-fix create mode 100755 target/linux/ar71xx/base-files/etc/init.d/defconfig create mode 100644 target/linux/ar71xx/base-files/etc/inittab create mode 100755 target/linux/ar71xx/base-files/etc/uci-defaults/inittab-console-fixup create mode 100755 target/linux/ar71xx/base-files/etc/uci-defaults/leds create mode 100755 target/linux/ar71xx/base-files/etc/uci-defaults/network create mode 100755 target/linux/ar71xx/base-files/etc/uci-defaults/vlan-migration create mode 100755 target/linux/ar71xx/base-files/etc/uci-defaults/wrt160nl create mode 100755 target/linux/ar71xx/base-files/lib/ar71xx.sh create mode 100644 target/linux/ar71xx/base-files/lib/preinit/03_preinit_do_ar71xx.sh create mode 100644 target/linux/ar71xx/base-files/lib/preinit/05_enable_reset_button_ar71xx create mode 100644 target/linux/ar71xx/base-files/lib/preinit/05_set_iface_mac_ar71xx create mode 100644 target/linux/ar71xx/base-files/lib/preinit/05_set_preinit_iface_ar71xx create mode 100644 target/linux/ar71xx/base-files/lib/upgrade/allnet.sh create mode 100644 target/linux/ar71xx/base-files/lib/upgrade/dir825.sh create mode 100644 target/linux/ar71xx/base-files/lib/upgrade/om2p.sh create mode 100755 target/linux/ar71xx/base-files/lib/upgrade/platform.sh create mode 100755 target/linux/ar71xx/base-files/sbin/wget2nand create mode 100644 target/linux/ar71xx/config-3.3 create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.h create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-eth.h create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.h create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.h create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-ap96.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-nx.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-all0258n.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-all0315n.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ap113.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ap83.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ap96.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-aw-nr580.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dir-600-a1.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-c1.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dir-825-b1.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-eap7660d.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ew-dorin.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-hornet-ub.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ja76pf.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-jwap003.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w04nu.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w300nh.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-nbg460n.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-om2p.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-pb42.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-pb92.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rb2011.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rb4xx.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rb750.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-rw2458n.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tew-632brp.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tew-673gru.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tew-712br.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr11u.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3020.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd-v2.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr4300.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1041n-v2.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr2543n.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr703n.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd-v4.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v8.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr941nd.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-whr-hp-g300n.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wlae-ag300n.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wndr3700.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wp543.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wpe72.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wrt160nl.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wrt400n.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-ag300h.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh2.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g450h.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-zcn-1523h.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/nvram.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/nvram.h create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.h create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/routerboot.c create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/routerboot.h create mode 100644 target/linux/ar71xx/files/arch/mips/include/asm/fw/myloader/myloader.h create mode 100644 target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h create mode 100644 target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/mach-rb750.h create mode 100644 target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/rb4xx_cpld.h create mode 100644 target/linux/ar71xx/files/drivers/gpio/gpio-nxp-74hc153.c create mode 100644 target/linux/ar71xx/files/drivers/leds/leds-rb750.c create mode 100644 target/linux/ar71xx/files/drivers/leds/leds-wndr3700-usb.c create mode 100644 target/linux/ar71xx/files/drivers/mtd/nand/ar934x_nfc.c create mode 100644 target/linux/ar71xx/files/drivers/mtd/nand/rb4xx_nand.c create mode 100644 target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c create mode 100644 target/linux/ar71xx/files/drivers/mtd/tplinkpart.c create mode 100644 target/linux/ar71xx/files/drivers/mtd/wrt160nl_part.c create mode 100644 target/linux/ar71xx/files/drivers/net/dsa/mv88e6063.c create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Kconfig create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Makefile create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar8216.c create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ethtool.c create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c create mode 100644 target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_phy.c create mode 100644 target/linux/ar71xx/files/drivers/spi/spi-ap83.c create mode 100644 target/linux/ar71xx/files/drivers/spi/spi-rb4xx-cpld.c create mode 100644 target/linux/ar71xx/files/drivers/spi/spi-rb4xx.c create mode 100644 target/linux/ar71xx/files/drivers/spi/spi-vsc7385.c create mode 100644 target/linux/ar71xx/files/include/linux/nxp_74hc153.h create mode 100644 target/linux/ar71xx/files/include/linux/platform/ar934x_nfc.h create mode 100644 target/linux/ar71xx/files/include/linux/spi/vsc7385.h create mode 100644 target/linux/ar71xx/files/net/dsa/mv88e6063.c create mode 100644 target/linux/ar71xx/generic/config-default create mode 100644 target/linux/ar71xx/generic/profiles/00-default.mk create mode 100644 target/linux/ar71xx/generic/profiles/01-minimal.mk create mode 100644 target/linux/ar71xx/generic/profiles/02-ath5k.mk create mode 100644 target/linux/ar71xx/generic/profiles/alfa.mk create mode 100644 target/linux/ar71xx/generic/profiles/allnet.mk create mode 100644 target/linux/ar71xx/generic/profiles/atheros.mk create mode 100644 target/linux/ar71xx/generic/profiles/atlantis.mk create mode 100644 target/linux/ar71xx/generic/profiles/buffalo.mk create mode 100644 target/linux/ar71xx/generic/profiles/compex.mk create mode 100644 target/linux/ar71xx/generic/profiles/d-link.mk create mode 100644 target/linux/ar71xx/generic/profiles/ew.mk create mode 100644 target/linux/ar71xx/generic/profiles/jjplus.mk create mode 100644 target/linux/ar71xx/generic/profiles/linksys.mk create mode 100644 target/linux/ar71xx/generic/profiles/netgear.mk create mode 100644 target/linux/ar71xx/generic/profiles/openmesh.mk create mode 100644 target/linux/ar71xx/generic/profiles/planex.mk create mode 100644 target/linux/ar71xx/generic/profiles/redwave.mk create mode 100644 target/linux/ar71xx/generic/profiles/tp-link.mk create mode 100644 target/linux/ar71xx/generic/profiles/trendnet.mk create mode 100644 target/linux/ar71xx/generic/profiles/ubnt.mk create mode 100644 target/linux/ar71xx/generic/profiles/zcomax.mk create mode 100644 target/linux/ar71xx/generic/profiles/zyxel.mk create mode 100644 target/linux/ar71xx/generic/target.mk create mode 100644 target/linux/ar71xx/image/Makefile create mode 100644 target/linux/ar71xx/image/lzma-loader/Makefile create mode 100644 target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.c create mode 100644 target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.h create mode 100644 target/linux/ar71xx/image/lzma-loader/src/LzmaTypes.h create mode 100644 target/linux/ar71xx/image/lzma-loader/src/Makefile create mode 100644 target/linux/ar71xx/image/lzma-loader/src/ar71xx_regs.h create mode 100644 target/linux/ar71xx/image/lzma-loader/src/board.c create mode 100644 target/linux/ar71xx/image/lzma-loader/src/cache.c create mode 100644 target/linux/ar71xx/image/lzma-loader/src/cache.h create mode 100644 target/linux/ar71xx/image/lzma-loader/src/cacheops.h create mode 100644 target/linux/ar71xx/image/lzma-loader/src/config.h create mode 100644 target/linux/ar71xx/image/lzma-loader/src/cp0regdef.h create mode 100644 target/linux/ar71xx/image/lzma-loader/src/head.S create mode 100644 target/linux/ar71xx/image/lzma-loader/src/loader.c create mode 100644 target/linux/ar71xx/image/lzma-loader/src/loader.lds create mode 100644 target/linux/ar71xx/image/lzma-loader/src/lzma-data.lds create mode 100644 target/linux/ar71xx/image/lzma-loader/src/printf.c create mode 100644 target/linux/ar71xx/image/lzma-loader/src/printf.h create mode 100644 target/linux/ar71xx/modules.mk create mode 100644 target/linux/ar71xx/nand/config-default create mode 100644 target/linux/ar71xx/nand/profiles/01-minimal.mk create mode 100644 target/linux/ar71xx/nand/profiles/02-ath5k.mk create mode 100644 target/linux/ar71xx/nand/target.mk create mode 100644 target/linux/ar71xx/patches-3.3/000-USB-OHCI-Add-a-generic-platform-device-driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/001-USB-EHCI-Add-a-generic-platform-device-driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/002-USB-use-generic-platform-driver-on-ath79.patch create mode 100644 target/linux/ar71xx/patches-3.3/100-MIPS-ath79-separate-common-PCI-code.patch create mode 100644 target/linux/ar71xx/patches-3.3/101-MIPS-ath79-rename-pci-ath724x.h.patch create mode 100644 target/linux/ar71xx/patches-3.3/102-MIPS-ath79-make-ath724x_pcibios_init-visible-for-ext.patch create mode 100644 target/linux/ar71xx/patches-3.3/103-MIPS-ath79-add-a-common-PCI-registration-function.patch create mode 100644 target/linux/ar71xx/patches-3.3/104-MIPS-ath79-rename-pci-ath724x.c-to-make-it-reflect-t.patch create mode 100644 target/linux/ar71xx/patches-3.3/105-MIPS-ath79-replace-ath724x-to-ar724x.patch create mode 100644 target/linux/ar71xx/patches-3.3/106-MIPS-ath79-use-io-accessor-macros-in-pci-ar724x.c.patch create mode 100644 target/linux/ar71xx/patches-3.3/107-MIPS-ath79-remove-superfluous-alignment-checks-from-.patch create mode 100644 target/linux/ar71xx/patches-3.3/108-MIPS-ath79-fix-broken-ar724x_pci_-read-write-functio.patch create mode 100644 target/linux/ar71xx/patches-3.3/109-MIPS-ath79-add-a-workaround-for-a-PCI-controller-bug.patch create mode 100644 target/linux/ar71xx/patches-3.3/110-MIPS-ath79-fix-a-wrong-IRQ-number.patch create mode 100644 target/linux/ar71xx/patches-3.3/111-MIPS-ath79-add-PCI-IRQ-handling-code-for-AR724X-SoCs.patch create mode 100644 target/linux/ar71xx/patches-3.3/112-MIPS-ath79-get-rid-of-some-ifdefs-in-mach-ubnt-xm.c.patch create mode 100644 target/linux/ar71xx/patches-3.3/113-MIPS-ath79-allow-to-use-board-specific-pci_plat_dev_.patch create mode 100644 target/linux/ar71xx/patches-3.3/114-MIPS-ath79-add-support-for-the-PCI-host-controller-o.patch create mode 100644 target/linux/ar71xx/patches-3.3/115-MIPS-ath79-allow-to-use-SoC-specific-PCI-IRQ-maps.patch create mode 100644 target/linux/ar71xx/patches-3.3/116-MIPS-ath79-remove-ar724x_pci_add_data-function.patch create mode 100644 target/linux/ar71xx/patches-3.3/117-MIPS-ath79-register-PCI-controller-on-the-PB44-board.patch create mode 100644 target/linux/ar71xx/patches-3.3/118-MIPS-ath79-update-copyright-headers-of-PCI-related-f.patch create mode 100644 target/linux/ar71xx/patches-3.3/119-MIPS-ath79-add-early_printk-support-for-AR934X.patch create mode 100644 target/linux/ar71xx/patches-3.3/120-MIPS-ath79-sort-case-statements-in-ath79_detect_sys_.patch create mode 100644 target/linux/ar71xx/patches-3.3/121-MIPS-ath79-add-SoC-detection-code-for-AR934X.patch create mode 100644 target/linux/ar71xx/patches-3.3/122-MIPS-ath79-add-clock-initialization-code-for-AR934X.patch create mode 100644 target/linux/ar71xx/patches-3.3/123-MIPS-ath79-add-GPIO-support-code-for-AR934X.patch create mode 100644 target/linux/ar71xx/patches-3.3/124-MIPS-ath79-rework-IP2-IP3-interrupt-handling.patch create mode 100644 target/linux/ar71xx/patches-3.3/125-MIPS-ath79-add-IRQ-handling-code-for-AR934X.patch create mode 100644 target/linux/ar71xx/patches-3.3/126-MIPS-ath79-add-AR934X-specific-glue-to-ath79_device_.patch create mode 100644 target/linux/ar71xx/patches-3.3/127-MIPS-ath79-register-UART-device-for-AR934X-SoCs.patch create mode 100644 target/linux/ar71xx/patches-3.3/128-MIPS-ath79-add-WMAC-registration-code-for-AR934X.patch create mode 100644 target/linux/ar71xx/patches-3.3/129-MIPS-ath79-add-PCI_AR724X-Kconfig-symbol.patch create mode 100644 target/linux/ar71xx/patches-3.3/130-MIPS-ath79-add-PCI-registration-code-for-AR934X.patch create mode 100644 target/linux/ar71xx/patches-3.3/131-MIPS-ath79-add-initial-support-for-the-Atheros-DB120.patch create mode 100644 target/linux/ar71xx/patches-3.3/132-MIPS-ath79-use-correct-IRQ-number-for-the-OHCI-contr.patch create mode 100644 target/linux/ar71xx/patches-3.3/133-MIPS-ath79-use-a-helper-function-for-USB-resource-in.patch create mode 100644 target/linux/ar71xx/patches-3.3/134-MIPS-ath79-add-USB-platform-setup-code-for-AR934X.patch create mode 100644 target/linux/ar71xx/patches-3.3/135-MIPS-ath79-register-USB-host-controller-on-the-DB120.patch create mode 100644 target/linux/ar71xx/patches-3.3/136-MIPS-ath79-use-correct-fractional-dividers-for-CPU-D.patch create mode 100644 target/linux/ar71xx/patches-3.3/137-MIPS-ath79-fix-CPU-DDR-frequency-calculation-for-SRI.patch create mode 100644 target/linux/ar71xx/patches-3.3/140-MIPS-pci-ar724x-avoid-data-bus-error-due-to-a-missin.patch create mode 100644 target/linux/ar71xx/patches-3.3/141-MIPS-pci-ar724x-use-correct-value-for-AR724X_PCI_MEM.patch create mode 100644 target/linux/ar71xx/patches-3.3/142-MIPS-pci-ar71xx-fix-AR71XX_PCI_MEM_SIZE.patch create mode 100644 target/linux/ar71xx/patches-3.3/143-MIPS-pci-ar724x-convert-to-a-platform-driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/144-MIPS-pci-ar71xx-convert-to-a-platform-driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/145-MIPS-ath79-move-global-PCI-defines-into-a-common-hea.patch create mode 100644 target/linux/ar71xx/patches-3.3/146-MIPS-ath79-register-platform-devices-for-the-PCI-con.patch create mode 100644 target/linux/ar71xx/patches-3.3/147-MIPS-ath79-remove-unused-ar7-1x-24-x_pcibios_init-fu.patch create mode 100644 target/linux/ar71xx/patches-3.3/148-MIPS-avoid-possible-resource-conflict-in-register_pc.patch create mode 100644 target/linux/ar71xx/patches-3.3/149-MIPS-pci-ar724x-use-dynamically-allocated-PCI-contro.patch create mode 100644 target/linux/ar71xx/patches-3.3/150-MIPS-pci-ar724x-remove-static-PCI-resources.patch create mode 100644 target/linux/ar71xx/patches-3.3/151-MIPS-pci-ar724x-use-per-controller-IRQ-base.patch create mode 100644 target/linux/ar71xx/patches-3.3/152-MIPS-pci-ar724x-setup-command-register-of-the-PCI-co.patch create mode 100644 target/linux/ar71xx/patches-3.3/153-MIPS-pci-ar71xx-use-dynamically-allocated-PCI-contro.patch create mode 100644 target/linux/ar71xx/patches-3.3/154-MIPS-pci-ar71xx-remove-static-PCI-controller-resourc.patch create mode 100644 target/linux/ar71xx/patches-3.3/160-MIPS-ath79-add-early-printk-support-for-the-QCA955X-.patch create mode 100644 target/linux/ar71xx/patches-3.3/161-MIPS-ath79-add-SoC-detection-code-for-the-QCA9558-So.patch create mode 100644 target/linux/ar71xx/patches-3.3/162-MIPS-ath79-add-clock-setup-for-the-QCA955X-SoCs.patch create mode 100644 target/linux/ar71xx/patches-3.3/163-MIPS-ath79-add-IRQ-handling-code-for-the-QCA955X-SoC.patch create mode 100644 target/linux/ar71xx/patches-3.3/164-MIPS-ath79-add-GPIO-setup-code-for-the-QCA955X-SoCs.patch create mode 100644 target/linux/ar71xx/patches-3.3/165-MIPS-ath79-add-QCA955X-specific-glue-to-ath79_device.patch create mode 100644 target/linux/ar71xx/patches-3.3/166-MIPS-ath79-register-UART-for-the-QCA955X-SoCs.patch create mode 100644 target/linux/ar71xx/patches-3.3/167-MIPS-ath79-add-USB-controller-registration-code-for-.patch create mode 100644 target/linux/ar71xx/patches-3.3/168-MIPS-ath79-add-WMAC-registration-code-for-the-QCA955.patch create mode 100644 target/linux/ar71xx/patches-3.3/169-MIPS-ath79-allow-to-specify-bus-number-in-PCI-IRQ-ma.patch create mode 100644 target/linux/ar71xx/patches-3.3/170-MIPS-ath79-add-PCI-controller-registration-code-for-.patch create mode 100644 target/linux/ar71xx/patches-3.3/171-MIPS-ath79-add-support-for-the-Qualcomm-Atheros-AP13.patch create mode 100644 target/linux/ar71xx/patches-3.3/200-spi-ath79-add-delay-between-SCK-changes.patch create mode 100644 target/linux/ar71xx/patches-3.3/201-spi-ath79-add-missing-HIGH-LOW-SCK-transition.patch create mode 100644 target/linux/ar71xx/patches-3.3/202-spi-ath79-remove-superfluous-chip-select-code.patch create mode 100644 target/linux/ar71xx/patches-3.3/203-spi-ath79-use-gpio_request_one.patch create mode 100644 target/linux/ar71xx/patches-3.3/204-spi-ath79-avoid-multiple-initialization-of-the-SPI-c.patch create mode 100644 target/linux/ar71xx/patches-3.3/205-spi-ath79-add-shutdown-handler.patch create mode 100644 target/linux/ar71xx/patches-3.3/206-spi-ath79-make-chipselect-logic-more-flexible.patch create mode 100644 target/linux/ar71xx/patches-3.3/210-MIPS-ath79-simplify-misc-irq-handling.patch create mode 100644 target/linux/ar71xx/patches-3.3/211-ar933x_uart-improve-serial-clock-calculation.patch create mode 100644 target/linux/ar71xx/patches-3.3/300-ehcpi-platform-remove-ehci_update_device.patch create mode 100644 target/linux/ar71xx/patches-3.3/310-lib-add-rle-decompression.patch create mode 100644 target/linux/ar71xx/patches-3.3/401-mtd-physmap-add-lock-unlock.patch create mode 100644 target/linux/ar71xx/patches-3.3/402-mtd-SST39VF6401B-support.patch create mode 100644 target/linux/ar71xx/patches-3.3/403-mtd_fix_cfi_cmdset_0002_status_check.patch create mode 100644 target/linux/ar71xx/patches-3.3/404-mtd-wrt160nl-trx-parser.patch create mode 100644 target/linux/ar71xx/patches-3.3/405-mtd-tp-link-partition-parser.patch create mode 100644 target/linux/ar71xx/patches-3.3/406-mtd-m25p80-allow-to-specify-max-read-size.patch create mode 100644 target/linux/ar71xx/patches-3.3/407-mtd-m25p80-allow-to-pass-probe-types-via-platform-data.patch create mode 100644 target/linux/ar71xx/patches-3.3/408-mtd-redboot_partition_scan.patch create mode 100644 target/linux/ar71xx/patches-3.3/409-mtd-rb4xx_nand_driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/410-mtd-rb750-nand-driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/411-mtd-cfi_cmdset_0002-force-word-write.patch create mode 100644 target/linux/ar71xx/patches-3.3/412-mtd-m25p80-zero-partition-parser-data.patch create mode 100644 target/linux/ar71xx/patches-3.3/413-mtd-ar934x-nand-driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/420-net-ar71xx_mac_driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/422-dsa-trailer-tag-validation-fix.patch create mode 100644 target/linux/ar71xx/patches-3.3/423-dsa-add-88e6063-driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/430-drivers-link-spi-before-mtd.patch create mode 100644 target/linux/ar71xx/patches-3.3/431-spi-add-various-flags.patch create mode 100644 target/linux/ar71xx/patches-3.3/432-spi-rb4xx-spi-driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/433-spi-rb4xx-cpld-driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/434-spi-ap83_spi_controller.patch create mode 100644 target/linux/ar71xx/patches-3.3/435-spi-vsc7385_driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/440-leds-wndr3700-usb-led-driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/441-leds-rb750-led-driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/450-gpio-nxp-74hc153-gpio-chip-driver.patch create mode 100644 target/linux/ar71xx/patches-3.3/460-spi-bitbang-export-spi_bitbang_bufs.patch create mode 100644 target/linux/ar71xx/patches-3.3/461-spi-add-type-field-to-spi_transfer.patch create mode 100644 target/linux/ar71xx/patches-3.3/462-mtd-m25p80-set-spi-transfer-type.patch create mode 100644 target/linux/ar71xx/patches-3.3/463-spi-ath79-add-fast-flash-read.patch create mode 100644 target/linux/ar71xx/patches-3.3/470-MIPS-ath79-swizzle-pci-address-for-ar71xx.patch create mode 100644 target/linux/ar71xx/patches-3.3/500-MIPS-fw-myloader.patch create mode 100644 target/linux/ar71xx/patches-3.3/501-MIPS-ath79-add-mac-argument-to-ath79_register_wmac.patch create mode 100644 target/linux/ar71xx/patches-3.3/502-MIPS-ath79-export-ath79_gpio_base.patch create mode 100644 target/linux/ar71xx/patches-3.3/503-MIPS-ath79-add-flash-acquire-release.patch create mode 100644 target/linux/ar71xx/patches-3.3/504-MIPS-ath79-add-ath79_device_reset_get.patch create mode 100644 target/linux/ar71xx/patches-3.3/505-MIPS-ath79-add-ath79_gpio_function_select.patch create mode 100644 target/linux/ar71xx/patches-3.3/506-MIPS-ath79-prom-parse-redboot-args.patch create mode 100644 target/linux/ar71xx/patches-3.3/507-MIPS-ath79-prom-add-myloader-support.patch create mode 100644 target/linux/ar71xx/patches-3.3/508-MIPS-ath79-prom-image-command-line-hack.patch create mode 100644 target/linux/ar71xx/patches-3.3/509-MIPS-ath79-process-board-kernel-option.patch create mode 100644 target/linux/ar71xx/patches-3.3/510-MIPS-ath79-init-gpio-pin-of-wmac-device.patch create mode 100644 target/linux/ar71xx/patches-3.3/511-MIPS-ath79-add-ath79_set_usb_power_gpio.patch create mode 100644 target/linux/ar71xx/patches-3.3/520-MIPS-ath79-enable-UART-function.patch create mode 100644 target/linux/ar71xx/patches-3.3/521-MIPS-ath79-enable-UART-for-early_serial.patch create mode 100644 target/linux/ar71xx/patches-3.3/601-MIPS-ath79-add-more-register-defines.patch create mode 100644 target/linux/ar71xx/patches-3.3/602-MIPS-ath79-add-openwrt-stuff.patch create mode 100644 target/linux/ar71xx/patches-3.3/603-MIPS-ath79-ap121-fixes.patch create mode 100644 target/linux/ar71xx/patches-3.3/604-MIPS-ath79-ap81-fixes.patch create mode 100644 target/linux/ar71xx/patches-3.3/605-MIPS-ath79-db120-fixes.patch create mode 100644 target/linux/ar71xx/patches-3.3/606-MIPS-ath79-pb44-fixes.patch create mode 100644 target/linux/ar71xx/patches-3.3/607-MIPS-ath79-ubnt-xm-fixes.patch create mode 100644 target/linux/ar71xx/patches-3.3/608-MIPS-ath79-ubnt-xm-add-more-boards.patch create mode 100644 target/linux/ar71xx/patches-3.3/609-MIPS-ath79-ap136-fixes.patch create mode 100644 target/linux/ar71xx/patches-3.3/610-MIPS-ath79-openwrt-machines.patch create mode 100644 target/linux/ar71xx/patches-3.3/611-MIPS-ath79-TL-MR3040-support.patch create mode 100644 target/linux/ar71xx/patches-3.3/612-MIPS-ath79-TL-WR841N-v8-support.patch create mode 100644 target/linux/ar71xx/patches-3.3/620-MIPS-ath79-OTP-support.patch create mode 100644 target/linux/ar71xx/patches-3.3/630-MIPS-ath79-enable-dsp.patch create mode 100644 target/linux/ar71xx/patches-3.3/650-MIPS-ath79-fix-ar933x-reset.patch create mode 100644 target/linux/ar71xx/patches-3.3/901-mdio_bitbang_ignore_ta_value.patch create mode 100644 target/linux/ar71xx/patches-3.3/902-unaligned_access_hacks.patch create mode 100644 target/linux/at91/9260/base-files/etc/config/network create mode 100644 target/linux/at91/9260/base-files/etc/config/system create mode 100644 target/linux/at91/9260/base-files/etc/init.d/custom-user-startup create mode 100644 target/linux/at91/9260/config-default create mode 100644 target/linux/at91/9260/profiles/000-flexibity-minimal.mk create mode 100644 target/linux/at91/9260/profiles/001-flexibity-xwrt.mk create mode 100644 target/linux/at91/9260/profiles/002-flexibity-luci.mk create mode 100644 target/linux/at91/9260/target.mk create mode 100644 target/linux/at91/9263/config-default create mode 100644 target/linux/at91/9263/target.mk create mode 100644 target/linux/at91/9g20/config-default create mode 100644 target/linux/at91/9g20/target.mk create mode 100644 target/linux/at91/Makefile create mode 100644 target/linux/at91/base-files/etc/config/firewall create mode 100644 target/linux/at91/base-files/etc/config/network create mode 100644 target/linux/at91/config-default create mode 100644 target/linux/at91/files/arch/arm/mach-at91/board-tqma9263.c create mode 100644 target/linux/at91/files/drivers/misc/at91-adc.c create mode 100644 target/linux/at91/files/drivers/misc/at91_adc.h create mode 100644 target/linux/at91/files/drivers/mtd/at91part.c create mode 100644 target/linux/at91/image/Config.in create mode 100644 target/linux/at91/image/Makefile create mode 100644 target/linux/at91/image/dfboot/Makefile create mode 100644 target/linux/at91/image/dfboot/src/Makefile create mode 100644 target/linux/at91/image/dfboot/src/_udivsi3.S create mode 100644 target/linux/at91/image/dfboot/src/_umodsi3.S create mode 100644 target/linux/at91/image/dfboot/src/asm_isr.S create mode 100644 target/linux/at91/image/dfboot/src/asm_mci_isr.S create mode 100644 target/linux/at91/image/dfboot/src/at45.c create mode 100644 target/linux/at91/image/dfboot/src/com.c create mode 100644 target/linux/at91/image/dfboot/src/com.h create mode 100644 target/linux/at91/image/dfboot/src/config.h create mode 100644 target/linux/at91/image/dfboot/src/cstartup_ram.S create mode 100644 target/linux/at91/image/dfboot/src/dataflash.c create mode 100644 target/linux/at91/image/dfboot/src/dataflash.h create mode 100644 target/linux/at91/image/dfboot/src/div0.c create mode 100644 target/linux/at91/image/dfboot/src/elf32-littlearm.lds create mode 100644 target/linux/at91/image/dfboot/src/embedded_services.h create mode 100644 target/linux/at91/image/dfboot/src/include/AT91C_MCI_Device.h create mode 100644 target/linux/at91/image/dfboot/src/include/AT91RM9200.h create mode 100644 target/linux/at91/image/dfboot/src/include/AT91RM9200.inc create mode 100644 target/linux/at91/image/dfboot/src/include/AT91RM9200_inc.h create mode 100644 target/linux/at91/image/dfboot/src/include/led.h create mode 100644 target/linux/at91/image/dfboot/src/include/lib_AT91RM9200.h create mode 100644 target/linux/at91/image/dfboot/src/init.c create mode 100644 target/linux/at91/image/dfboot/src/jump.S create mode 100644 target/linux/at91/image/dfboot/src/led.c create mode 100644 target/linux/at91/image/dfboot/src/main.c create mode 100644 target/linux/at91/image/dfboot/src/main.h create mode 100644 target/linux/at91/image/dfboot/src/mci_device.c create mode 100644 target/linux/at91/image/dfboot/src/stdio.h create mode 100644 target/linux/at91/image/u-boot/Makefile create mode 100644 target/linux/at91/image/u-boot/patches/100-netusg20.patch create mode 100644 target/linux/at91/image/u-boot/patches/200-clock.patch create mode 100644 target/linux/at91/image/u-boot/ubclient/Makefile create mode 100644 target/linux/at91/image/u-boot/ubclient/ubpar.c create mode 100644 target/linux/at91/modules.mk create mode 100644 target/linux/at91/patches/700-tqma9263-support.patch create mode 100644 target/linux/at91/patches/805-free_some_portc_pins.patch create mode 100644 target/linux/at91/patches/900-AT91-Add-external-RTC-for-Flexibity-board.patch create mode 100644 target/linux/at91/patches/901-AT91-flexibity-default-leds-to-heartbeat.patch create mode 100644 target/linux/atheros/Makefile create mode 100644 target/linux/atheros/base-files/etc/config/system create mode 100644 target/linux/atheros/base-files/etc/hotplug.d/button/00-button create mode 100644 target/linux/atheros/base-files/etc/uci-defaults/leds create mode 100644 target/linux/atheros/base-files/etc/uci-defaults/network create mode 100644 target/linux/atheros/base-files/lib/preinit/15_preinit_iface_atheros create mode 100644 target/linux/atheros/base-files/lib/upgrade/platform.sh create mode 100644 target/linux/atheros/config-3.3 create mode 100644 target/linux/atheros/image/Makefile create mode 100644 target/linux/atheros/patches-3.3/001-get_c0_compare_int_fix.patch create mode 100644 target/linux/atheros/patches-3.3/100-board.patch create mode 100644 target/linux/atheros/patches-3.3/101-early-printk-support.patch create mode 100644 target/linux/atheros/patches-3.3/105-ar2315_pci.patch create mode 100644 target/linux/atheros/patches-3.3/110-ar2313_ethernet.patch create mode 100644 target/linux/atheros/patches-3.3/120-spiflash.patch create mode 100644 target/linux/atheros/patches-3.3/130-watchdog.patch create mode 100644 target/linux/atheros/patches-3.3/140-redboot_partition_scan.patch create mode 100644 target/linux/atheros/patches-3.3/141-redboot_various_erase_size_fix.patch create mode 100644 target/linux/atheros/patches-3.3/210-reset_button.patch create mode 100644 target/linux/atheros/patches-3.3/220-enet_micrel_workaround.patch create mode 100644 target/linux/au1000/Makefile create mode 100644 target/linux/au1000/au1500/config-3.3 create mode 100644 target/linux/au1000/au1500/profiles/Atheros.mk create mode 100644 target/linux/au1000/au1500/profiles/InternetBox.mk create mode 100644 target/linux/au1000/au1500/profiles/MeshCube.mk create mode 100644 target/linux/au1000/au1500/target.mk create mode 100644 target/linux/au1000/au1550/config-3.3 create mode 100644 target/linux/au1000/au1550/profiles/DBAu1550.mk create mode 100644 target/linux/au1000/au1550/target.mk create mode 100644 target/linux/au1000/base-files/etc/diag.sh create mode 100644 target/linux/au1000/base-files/lib/upgrade/platform.sh create mode 100644 target/linux/au1000/image/Makefile create mode 100644 target/linux/au1000/modules.mk create mode 100644 target/linux/au1000/patches-3.3/002-openwrt_rootfs.patch create mode 100644 target/linux/au1000/patches-3.3/003-au1000_eth_ioctl.patch create mode 100644 target/linux/au1000/patches-3.3/004-pci-idsel-cb.patch create mode 100644 target/linux/avr32/Makefile create mode 100644 target/linux/avr32/config-3.3 create mode 100644 target/linux/avr32/image/Config.in create mode 100644 target/linux/avr32/image/Makefile create mode 100644 target/linux/avr32/image/u-boot/Makefile create mode 100644 target/linux/avr32/image/u-boot/patches/100-ngw100_enable_lzma_support.patch create mode 100644 target/linux/avr32/modules.mk create mode 100644 target/linux/avr32/patches-3.3/110-openwrt_flashmap.patch create mode 100644 target/linux/brcm2708/Makefile create mode 100644 target/linux/brcm2708/base-files/etc/config/network create mode 100644 target/linux/brcm2708/base-files/etc/inittab create mode 100644 target/linux/brcm2708/config-3.3 create mode 100644 target/linux/brcm2708/image/Config.in create mode 100644 target/linux/brcm2708/image/Makefile create mode 100644 target/linux/brcm2708/image/cmdline.txt create mode 100755 target/linux/brcm2708/image/gen_rpi_sdcard_img.sh create mode 100644 target/linux/brcm2708/modules.mk create mode 100644 target/linux/brcm2708/patches-3.3/0001-Add-dwc_otg-driver.patch create mode 100644 target/linux/brcm2708/patches-3.3/0002-Main-bcm2708-linux-port.patch create mode 100644 target/linux/brcm2708/patches-3.3/0003-bcm2708-watchdog-driver.patch create mode 100644 target/linux/brcm2708/patches-3.3/0004-bcm2708-framebuffer-driver.patch create mode 100644 target/linux/brcm2708/patches-3.3/0005-bcm2708-vchiq-driver.patch create mode 100644 target/linux/brcm2708/patches-3.3/0006-Allow-mac-address-to-be-set-in-smsc95xx.patch create mode 100644 target/linux/brcm2708/patches-3.3/0007-Fix-headers-for-vchiq-vcos-to-be-GPLv2.patch create mode 100644 target/linux/brcm2708/patches-3.3/0500-rpi-patches-geaf792a-9efb4705.patch create mode 100644 target/linux/brcm2708/patches-3.3/0510-fix_divdi3.patch create mode 100644 target/linux/brcm2708/profiles/100-RaspberryPi.mk create mode 100644 target/linux/brcm47xx/Makefile create mode 100644 target/linux/brcm47xx/base-files.mk create mode 100644 target/linux/brcm47xx/base-files/etc/diag.sh create mode 100755 target/linux/brcm47xx/base-files/etc/init.d/netconfig create mode 100755 target/linux/brcm47xx/base-files/etc/init.d/wmacfixup create mode 100644 target/linux/brcm47xx/base-files/lib/preinit/03_init_hotplug_failsafe_brcm create mode 100644 target/linux/brcm47xx/base-files/lib/preinit/05_init_interfaces_brcm create mode 100644 target/linux/brcm47xx/base-files/lib/preinit/05_reset_button_brcm create mode 100644 target/linux/brcm47xx/base-files/lib/preinit/05_set_failsafe_switch_brcm create mode 100644 target/linux/brcm47xx/base-files/lib/preinit/15_mount_proc_brcm create mode 100644 target/linux/brcm47xx/base-files/lib/preinit/15_set_preinit_interface_brcm create mode 100644 target/linux/brcm47xx/base-files/lib/preinit/20_failsafe_net_echo_brcm create mode 100644 target/linux/brcm47xx/base-files/lib/preinit/20_failsafe_set_boot_wait_brcm create mode 100644 target/linux/brcm47xx/base-files/lib/upgrade/platform.sh create mode 100755 target/linux/brcm47xx/base-files/sbin/hotplug.failsafe create mode 100644 target/linux/brcm47xx/config-3.3 create mode 100644 target/linux/brcm47xx/image/Makefile create mode 100644 target/linux/brcm47xx/image/lzma-loader/Makefile create mode 100644 target/linux/brcm47xx/image/lzma-loader/src/LzmaDecode.c create mode 100644 target/linux/brcm47xx/image/lzma-loader/src/LzmaDecode.h create mode 100644 target/linux/brcm47xx/image/lzma-loader/src/Makefile create mode 100644 target/linux/brcm47xx/image/lzma-loader/src/README create mode 100644 target/linux/brcm47xx/image/lzma-loader/src/decompress.c create mode 100644 target/linux/brcm47xx/image/lzma-loader/src/decompress.lds.in create mode 100644 target/linux/brcm47xx/image/lzma-loader/src/head.S create mode 100644 target/linux/brcm47xx/image/lzma-loader/src/loader.lds.in create mode 100644 target/linux/brcm47xx/modules.mk create mode 100644 target/linux/brcm47xx/patches-3.3/001-MIPS-BCM47XX-return-number-of-written-bytes-in-nvram.patch create mode 100644 target/linux/brcm47xx/patches-3.3/002-MIPS-BCM47XX-fix-signature-of-nvram_parse_macaddr.patch create mode 100644 target/linux/brcm47xx/patches-3.3/003-MIPS-BCM47XX-move-and-extend-sprom-parsing.patch create mode 100644 target/linux/brcm47xx/patches-3.3/004-MIPS-BCM47XX-provide-sprom-to-bcma-bus.patch create mode 100644 target/linux/brcm47xx/patches-3.3/005-ssb-remove-rev-from-boardinfo.patch create mode 100644 target/linux/brcm47xx/patches-3.3/006-MIPS-bcm47xx-refactor-fetching-board-data.patch create mode 100644 target/linux/brcm47xx/patches-3.3/007-bcma-add-boardinfo-struct.patch create mode 100644 target/linux/brcm47xx/patches-3.3/008-MIPS-bcm47xx-read-baordrev-without-prefix-from-sprom.patch create mode 100644 target/linux/brcm47xx/patches-3.3/009-bcma_reorder_sprom_fill.patch create mode 100644 target/linux/brcm47xx/patches-3.3/010-MIPS-BCM47xx-Fix-BCMA_DRIVER_PCI_HOSTMODE.patch create mode 100644 target/linux/brcm47xx/patches-3.3/020-bcma-move-parallel-flash-into-a-union.patch create mode 100644 target/linux/brcm47xx/patches-3.3/021-bcma-add-serial-flash-support-to-bcma.patch create mode 100644 target/linux/brcm47xx/patches-3.3/022-ssb-move-flash-to-chipcommon.patch create mode 100644 target/linux/brcm47xx/patches-3.3/023-ssb-add-serial-flash-support.patch create mode 100644 target/linux/brcm47xx/patches-3.3/024-brcm47xx-add-common-interface-for-sflash.patch create mode 100644 target/linux/brcm47xx/patches-3.3/025-mtd-bcm47xx-add-bcm47xx-part-parser.patch create mode 100644 target/linux/brcm47xx/patches-3.3/026-mtd-bcm47xx-add-parallel-flash-driver.patch create mode 100644 target/linux/brcm47xx/patches-3.3/027-mtd-bcm47xx-add-serial-flash-driver.patch create mode 100644 target/linux/brcm47xx/patches-3.3/028-bcm47xx-register-flash-drivers.patch create mode 100644 target/linux/brcm47xx/patches-3.3/029-bcm47xx-read-nvram-from-sflash.patch create mode 100644 target/linux/brcm47xx/patches-3.3/030-bcm47xx-bcma-nandflash.patch create mode 100644 target/linux/brcm47xx/patches-3.3/044-bcma-add-PCIe-host-controller.patch create mode 100644 target/linux/brcm47xx/patches-3.3/114-MIPS-BCM47xx-Setup-and-register-serial-early.patch create mode 100644 target/linux/brcm47xx/patches-3.3/116-MIPS-BCM47xx-Remove-CFE-console.patch create mode 100644 target/linux/brcm47xx/patches-3.3/119-fix-boot.patch create mode 100644 target/linux/brcm47xx/patches-3.3/150-cpu_fixes.patch create mode 100644 target/linux/brcm47xx/patches-3.3/160-kmap_coherent.patch create mode 100644 target/linux/brcm47xx/patches-3.3/170-fix-74k-cpu.patch create mode 100644 target/linux/brcm47xx/patches-3.3/180-USB-OHCI-Add-a-generic-platform-device-driver.patch create mode 100644 target/linux/brcm47xx/patches-3.3/181-USB-EHCI-Add-a-generic-platform-device-driver.patch create mode 100644 target/linux/brcm47xx/patches-3.3/183-USB-Add-driver-for-the-bcma-bus.patch create mode 100644 target/linux/brcm47xx/patches-3.3/184-USB-Add-driver-for-the-ssb-bus.patch create mode 100644 target/linux/brcm47xx/patches-3.3/185-USB-OHCI-remove-old-SSB-OHCI-driver.patch create mode 100644 target/linux/brcm47xx/patches-3.3/186-USB-EHCI-bcma-fix-driver.patch create mode 100644 target/linux/brcm47xx/patches-3.3/187-USB-EHCI-platform-remove-update.patch create mode 100644 target/linux/brcm47xx/patches-3.3/191-MIPS-BCM47XX-ignore-last-memory-page.patch create mode 100644 target/linux/brcm47xx/patches-3.3/192-MIPS-BCM47XX-improve-memory-size-detection.patch create mode 100644 target/linux/brcm47xx/patches-3.3/193-MIPS-BCM47xx-read-out-full-board-data.patch create mode 100644 target/linux/brcm47xx/patches-3.3/194-MIPS-BCM47XX-read-sprom-without-prefix-if-no-ieee802.patch create mode 100644 target/linux/brcm47xx/patches-3.3/195-MIPS-BCM47xx-sprom-read-values-without-prefix-as-fal.patch create mode 100644 target/linux/brcm47xx/patches-3.3/201-bcma-just-do-the-necessary-things-in-early-register.patch create mode 100644 target/linux/brcm47xx/patches-3.3/202-bcma-init-sprom-struct-earlier.patch create mode 100644 target/linux/brcm47xx/patches-3.3/203-bcma-use-fallback-sprom-if-sprom-on-card-was-not-val.patch create mode 100644 target/linux/brcm47xx/patches-3.3/204-bcma-do-not-initialize-deactivated-PCIe-cores.patch create mode 100644 target/linux/brcm47xx/patches-3.3/210-b44_phy_fix.patch create mode 100644 target/linux/brcm47xx/patches-3.3/211-b44_timeout_spam.patch create mode 100644 target/linux/brcm47xx/patches-3.3/240-bcma-pcie-config-access.patch create mode 100644 target/linux/brcm47xx/patches-3.3/280-activate_ssb_support_in_usb.patch create mode 100644 target/linux/brcm47xx/patches-3.3/300-fork_cacheflush.patch create mode 100644 target/linux/brcm47xx/patches-3.3/310-no_highpage.patch create mode 100644 target/linux/brcm47xx/patches-3.3/400-arch-bcm47xx.patch create mode 100644 target/linux/brcm47xx/patches-3.3/500-ssb-add-function-to-return-number-of-gpio-lines.patch create mode 100644 target/linux/brcm47xx/patches-3.3/501-bcma-add-gpio-driver.patch create mode 100644 target/linux/brcm47xx/patches-3.3/502-bcm47xx-rewrite-gpio-handling.patch create mode 100644 target/linux/brcm47xx/patches-3.3/610-pci_ide_fix.patch create mode 100644 target/linux/brcm47xx/patches-3.3/700-ssb-gigabit-ethernet-driver.patch create mode 100644 target/linux/brcm47xx/patches-3.3/812-disable_wgt634u_crap.patch create mode 100644 target/linux/brcm47xx/patches-3.3/820-wgt634u-nvram-fix.patch create mode 100644 target/linux/brcm47xx/patches-3.3/900-bcm47xx_wdt-noprescale.patch create mode 100644 target/linux/brcm47xx/patches-3.3/920-cache-wround.patch create mode 100644 target/linux/brcm47xx/patches-3.3/940-bcm47xx-yenta.patch create mode 100644 target/linux/brcm47xx/patches-3.3/976-ssb_increase_pci_delay.patch create mode 100644 target/linux/brcm47xx/patches-3.3/980-wnr834b_no_cardbus_invariant.patch create mode 100644 target/linux/brcm47xx/patches-3.3/999-wl_exports.patch create mode 100644 target/linux/brcm47xx/profiles/100-Broadcom-b43.mk create mode 100644 target/linux/brcm47xx/profiles/101-Broadcom-wl.mk create mode 100644 target/linux/brcm47xx/profiles/104-Broadcom-ath5k.mk create mode 100644 target/linux/brcm47xx/profiles/105-Broadcom-none.mk create mode 100644 target/linux/brcm47xx/profiles/110-Bcm4705-b43.mk create mode 100644 target/linux/brcm47xx/profiles/115-Bcm4705-none.mk create mode 100644 target/linux/brcm47xx/profiles/PS-1208MFG.mk create mode 100644 target/linux/brcm47xx/profiles/WGT634U.mk create mode 100644 target/linux/brcm47xx/profiles/WL500GPv1-ATH.mk create mode 100644 target/linux/brcm47xx/profiles/WRT350Nv1.mk create mode 100644 target/linux/brcm47xx/profiles/WRTSL54GS.mk create mode 100644 target/linux/brcm63xx/Makefile create mode 100644 target/linux/brcm63xx/base-files.mk create mode 100755 target/linux/brcm63xx/base-files/etc/diag.sh create mode 100755 target/linux/brcm63xx/base-files/etc/init.d/defconfig create mode 100755 target/linux/brcm63xx/base-files/etc/uci-defaults/brcm63xx_fixcrc.sh create mode 100755 target/linux/brcm63xx/base-files/etc/uci-defaults/network create mode 100755 target/linux/brcm63xx/base-files/lib/brcm63xx.sh create mode 100644 target/linux/brcm63xx/base-files/lib/preinit/03_do_brcm63xx.sh create mode 100644 target/linux/brcm63xx/base-files/lib/preinit/05_failsafe_config_switch_brcm63xx create mode 100644 target/linux/brcm63xx/base-files/lib/preinit/05_init_interfaces_brcm63xx create mode 100644 target/linux/brcm63xx/base-files/lib/preinit/05_reset_button_brcm63xx create mode 100644 target/linux/brcm63xx/base-files/lib/preinit/15_set_preinit_interface_brcm63xx create mode 100644 target/linux/brcm63xx/base-files/lib/preinit/20_failsafe_net_echo_brcm63xx create mode 100644 target/linux/brcm63xx/base-files/lib/upgrade/platform.sh create mode 100644 target/linux/brcm63xx/config-3.3 create mode 100644 target/linux/brcm63xx/files/arch/mips/include/asm/mach-bcm63xx/bcm_tag.h create mode 100644 target/linux/brcm63xx/image/Makefile create mode 100644 target/linux/brcm63xx/image/README.images-bcm63xx create mode 100644 target/linux/brcm63xx/image/lzma-loader/Makefile create mode 100644 target/linux/brcm63xx/image/lzma-loader/src/LzmaDecode.c create mode 100644 target/linux/brcm63xx/image/lzma-loader/src/LzmaDecode.h create mode 100644 target/linux/brcm63xx/image/lzma-loader/src/Makefile create mode 100644 target/linux/brcm63xx/image/lzma-loader/src/README create mode 100644 target/linux/brcm63xx/image/lzma-loader/src/decompress.c create mode 100644 target/linux/brcm63xx/image/lzma-loader/src/decompress.lds.in create mode 100644 target/linux/brcm63xx/image/lzma-loader/src/head.S create mode 100644 target/linux/brcm63xx/image/lzma-loader/src/loader.lds.in create mode 100644 target/linux/brcm63xx/modules.mk create mode 100644 target/linux/brcm63xx/patches-3.3/001-MIPS-BCM63XX-fix-platform_devices-id.patch create mode 100644 target/linux/brcm63xx/patches-3.3/002-MIPS-BCM63XX-be-consistent-in-clock-bits-enable-nami.patch create mode 100644 target/linux/brcm63xx/patches-3.3/003-MIPS-BCM63XX-add-IRQ_SPI-and-CPU-specific-SPI-IRQ-va.patch create mode 100644 target/linux/brcm63xx/patches-3.3/004-MIPS-BCM63XX-define-BCM6358-SPI-base-address.patch create mode 100644 target/linux/brcm63xx/patches-3.3/005-MIPS-BCM63XX-add-BCM6368-SPI-clock-mask.patch create mode 100644 target/linux/brcm63xx/patches-3.3/006-MIPS-BCM63XX-define-SPI-register-sizes.patch create mode 100644 target/linux/brcm63xx/patches-3.3/007-MIPS-BCM63XX-remove-SPI2-register.patch create mode 100644 target/linux/brcm63xx/patches-3.3/008-MIPS-BCM63XX-define-internal-registers-offsets-of-th.patch create mode 100644 target/linux/brcm63xx/patches-3.3/009-MIPS-BCM63XX-add-stub-to-register-the-SPI-platform-d.patch create mode 100644 target/linux/brcm63xx/patches-3.3/010-MIPS-BCM63XX-make-board-setup-code-register-the-spi-.patch create mode 100644 target/linux/brcm63xx/patches-3.3/011-spi-add-Broadcom-BCM63xx-SPI-controller-driver.patch create mode 100644 target/linux/brcm63xx/patches-3.3/012-mtd-bcm63xxpart-handle-Broadcom-partition-order.patch create mode 100644 target/linux/brcm63xx/patches-3.3/013-spi-bcm63xx-convert-to-the-pump-message-infrastructu.patch create mode 100644 target/linux/brcm63xx/patches-3.3/014-spi-bcm63xx-don-t-use-the-stopping-state.patch create mode 100644 target/linux/brcm63xx/patches-3.3/015-spi-bcm63xx-set-master-driver-mode_bits.patch create mode 100644 target/linux/brcm63xx/patches-3.3/016-spi-bcm63xx-fix-bcm6348-38.patch create mode 100644 target/linux/brcm63xx/patches-3.3/017-MIPS-BCM63XX-fix-BCM6368-IPSec-clock-bit.patch create mode 100644 target/linux/brcm63xx/patches-3.3/018-MIPS-BCM63XX-add-support-for-ipsec-clock.patch create mode 100644 target/linux/brcm63xx/patches-3.3/019-MIPS-BCM63XX-add-RNG-peripheral-definitions.patch create mode 100644 target/linux/brcm63xx/patches-3.3/020-MIPS-BCM63XX-add-RNG-driver-platform_device-stub.patch create mode 100644 target/linux/brcm63xx/patches-3.3/021-hw_random-add-Broadcom-BCM63xx-RNG-driver.patch create mode 100644 target/linux/brcm63xx/patches-3.3/022-MIPS-BCM63XX-Move-flash-registration-out-of-board_bc.patch create mode 100644 target/linux/brcm63xx/patches-3.3/023-MIPS-BCM63XX-Add-flash-type-detection.patch create mode 100644 target/linux/brcm63xx/patches-3.3/024-MIPS-BCM63XX-Use-the-Chip-ID-register-for-identifyin.patch create mode 100644 target/linux/brcm63xx/patches-3.3/025-MIPS-BCM63XX-Add-basic-BCM6328-support.patch create mode 100644 target/linux/brcm63xx/patches-3.3/026-MIPS-BCM63XX-Move-the-PCI-initialization-into-its-ow.patch create mode 100644 target/linux/brcm63xx/patches-3.3/027-MIPS-BCM63XX-Add-PCIe-Support-for-BCM6328.patch create mode 100644 target/linux/brcm63xx/patches-3.3/028-MIPS-Expose-PCIe-drivers-for-MIPS.patch create mode 100644 target/linux/brcm63xx/patches-3.3/100-MIPS-BCM63XX-add-missing-include-for-bcm63xx_gpio.h.patch create mode 100644 target/linux/brcm63xx/patches-3.3/101-MTD-bcm63xxpart-remove-unused-variable.patch create mode 100644 target/linux/brcm63xx/patches-3.3/102-MTD-bcm63xxpart-merge-sparelen-calculation.patch create mode 100644 target/linux/brcm63xx/patches-3.3/103-MTD-bcm63xxpart-make-fixed-part-length-calculation-m.patch create mode 100644 target/linux/brcm63xx/patches-3.3/104-MTD-bcm63xxpart-move-the-last-curpart-to-its-correct.patch create mode 100644 target/linux/brcm63xx/patches-3.3/105-MTD-bcm63xxpart-use-correct-printk-format-for-partit.patch create mode 100644 target/linux/brcm63xx/patches-3.3/106-bcm63xx_watchdog_section_mismatch.patch create mode 100644 target/linux/brcm63xx/patches-3.3/107-MIPS-BCM63XX-Fix-USB-IRQ-definitions-for-6328.patch create mode 100644 target/linux/brcm63xx/patches-3.3/108-BCM63XX-Add-register-definitions-for-USBD-depen.patch create mode 100644 target/linux/brcm63xx/patches-3.3/201-SPI-Allow-specifying-the-parsers-for-SPI-flash.patch create mode 100644 target/linux/brcm63xx/patches-3.3/202-MTD-DEVICES-m25p80-use-parsers-if-provided-in-flash-.patch create mode 100644 target/linux/brcm63xx/patches-3.3/203-MTD-DEVICES-m25p80-add-support-for-limiting-reads.patch create mode 100644 target/linux/brcm63xx/patches-3.3/300-reset_buttons.patch create mode 100644 target/linux/brcm63xx/patches-3.3/301-led_count.patch create mode 100644 target/linux/brcm63xx/patches-3.3/302-extended-platform-devices.patch create mode 100644 target/linux/brcm63xx/patches-3.3/303-spi-board-info.patch create mode 100644 target/linux/brcm63xx/patches-3.3/304-boardid_fixup.patch create mode 100644 target/linux/brcm63xx/patches-3.3/305-missing_ext_irq_bits.patch create mode 100644 target/linux/brcm63xx/patches-3.3/306-Revert-MIPS-BCM63XX-Call-board_register_device-from-.patch create mode 100644 target/linux/brcm63xx/patches-3.3/307-MIPS-BCM63XX-allow-second-UART-on-BCM6328.patch create mode 100644 target/linux/brcm63xx/patches-3.3/308-MIPS-BCM63XX-expose-the-HS-SPI-clock.patch create mode 100644 target/linux/brcm63xx/patches-3.3/309-MIPS-BCM63XX-add-HSSPI-register-definitions.patch create mode 100644 target/linux/brcm63xx/patches-3.3/310-board_leds_naming.patch create mode 100644 target/linux/brcm63xx/patches-3.3/311-cfe_version_mod.patch create mode 100644 target/linux/brcm63xx/patches-3.3/312-MIPS-BCM63XX-add-basic-BCM6362-support.patch create mode 100644 target/linux/brcm63xx/patches-3.3/313-MIPS-BCM63XX-enable-pcie-for-BCM6362.patch create mode 100644 target/linux/brcm63xx/patches-3.3/400-ohci-add-driver-for-bcm63xx-integrated-controller.patch create mode 100644 target/linux/brcm63xx/patches-3.3/401-MIPS-BCM63XX-register-ohci-device.patch create mode 100644 target/linux/brcm63xx/patches-3.3/402-ehci-add-driver-for-bcm63xx-integrated-controller.patch create mode 100644 target/linux/brcm63xx/patches-3.3/403-MIPS-BCM63XX-register-ehci-device.patch create mode 100644 target/linux/brcm63xx/patches-3.3/404-bcm963xx_flashmap.patch create mode 100644 target/linux/brcm63xx/patches-3.3/405-bcm963xx_real_rootfs_length.patch create mode 100644 target/linux/brcm63xx/patches-3.3/406_bcm63xx_enet_vlan_incoming_fixed.patch create mode 100644 target/linux/brcm63xx/patches-3.3/408-6358-enet1-external-mii-clk.patch create mode 100644 target/linux/brcm63xx/patches-3.3/410-NET-bcm63xx_enet-move-phy_-dis-connect-into-probe-re.patch create mode 100644 target/linux/brcm63xx/patches-3.3/411-bcm63xx_enet-implement-reset_autoneg-ethtool.patch create mode 100644 target/linux/brcm63xx/patches-3.3/412-bcm63xx_enet-use-resource_size.patch create mode 100644 target/linux/brcm63xx/patches-3.3/413-bcm63xx_enet-disable-clock-when-uninitializing-devic.patch create mode 100644 target/linux/brcm63xx/patches-3.3/414-bcm63xx_enet-split-dma-registers-access.patch create mode 100644 target/linux/brcm63xx/patches-3.3/415-bcm63xx_enet-add-support-for-bcm6368-internal-ethern.patch create mode 100644 target/linux/brcm63xx/patches-3.3/416-bcm63xx_enet-reset-port-link-state-in-bcm_enetsw_ope.patch create mode 100644 target/linux/brcm63xx/patches-3.3/417-bcm63xx_enet-don-t-overwrite-settings-when-setting-d.patch create mode 100644 target/linux/brcm63xx/patches-3.3/418-bcm63xx_enet-store-the-number-of-ports-instead-of-ha.patch create mode 100644 target/linux/brcm63xx/patches-3.3/419-bcm63xx_enet-store-is_sw-in-a-variable-instead-of-ch.patch create mode 100644 target/linux/brcm63xx/patches-3.3/420-BCM63XX-allow-enetsw-without-tx-irq.patch create mode 100644 target/linux/brcm63xx/patches-3.3/421-BCM63XX-use-port-id-for-deciding-external-phy.patch create mode 100644 target/linux/brcm63xx/patches-3.3/422-bcm63xx_enet-enable-rgmii-clock-on-external-ports.patch create mode 100644 target/linux/brcm63xx/patches-3.3/423-bcm63xx_enet-fix-lockup-on-BCM6328.patch create mode 100644 target/linux/brcm63xx/patches-3.3/424-MIPS-BCM63XX-add-support-for-BCM6328-in-bcm_enetsw.patch create mode 100644 target/linux/brcm63xx/patches-3.3/425-MIPS-BCM63XX-add-HS-SPI-platform-device-and-register.patch create mode 100644 target/linux/brcm63xx/patches-3.3/426-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch create mode 100644 target/linux/brcm63xx/patches-3.3/427-MIPS-BCM63XX-Register-SPI-flash-if-present.patch create mode 100644 target/linux/brcm63xx/patches-3.3/428-MIPS-BCM63XX-add-flash-detection-for-BCM6362.patch create mode 100644 target/linux/brcm63xx/patches-3.3/428-MIPS-BCM63XX-move-nvram-related-functions-into-their.patch create mode 100644 target/linux/brcm63xx/patches-3.3/429-MIPS-BCM63XX-export-PSI-size-from-nvram.patch create mode 100644 target/linux/brcm63xx/patches-3.3/430-MTD-bcm63xxpart-use-nvram-for-PSI-size.patch create mode 100644 target/linux/brcm63xx/patches-3.3/431-MTD-physmap-allow-passing-pp_data.patch create mode 100644 target/linux/brcm63xx/patches-3.3/432-BCM63XX-allow-providing-fixup-data-in-board-data.patch create mode 100644 target/linux/brcm63xx/patches-3.3/433-MTD-m25p80-allow-passing-pp_data.patch create mode 100644 target/linux/brcm63xx/patches-3.3/434-MIPS-BCM63XX-store-the-flash-type-in-global-variable.patch create mode 100644 target/linux/brcm63xx/patches-3.3/435-BCM63XX-add-a-fixup-for-ath9k-devices.patch create mode 100644 target/linux/brcm63xx/patches-3.3/436-MTD-bcm63xxpart-allow-passing-a-caldata-offset.patch create mode 100644 target/linux/brcm63xx/patches-3.3/437-MIPS-BCM63XX-pass-caldata-info-to-flash.patch create mode 100644 target/linux/brcm63xx/patches-3.3/438-MIPS-BCM63XX-enable-USB-for-BCM6328.patch create mode 100644 target/linux/brcm63xx/patches-3.3/439-MIPS-BCM63XX-wire-up-the-HS-SPI-controller-for-BCM63.patch create mode 100644 target/linux/brcm63xx/patches-3.3/440-MIPS-BCM63XX-enable-SPI-controller-for-BCM6362.patch create mode 100644 target/linux/brcm63xx/patches-3.3/441-MIPS-BCM63XX-enable-USB-for-BCM6362.patch create mode 100644 target/linux/brcm63xx/patches-3.3/442-MIPS-BCM63XX-enable-enetsw-for-BCM6362.patch create mode 100644 target/linux/brcm63xx/patches-3.3/500-board-D4PW.patch create mode 100644 target/linux/brcm63xx/patches-3.3/501-board-NB4.patch create mode 100644 target/linux/brcm63xx/patches-3.3/502-board-96338W2_E7T.patch create mode 100644 target/linux/brcm63xx/patches-3.3/503-board-CPVA642.patch create mode 100644 target/linux/brcm63xx/patches-3.3/504-board_dsl_274xb_rev_c.patch create mode 100644 target/linux/brcm63xx/patches-3.3/505-board_spw500v.patch create mode 100644 target/linux/brcm63xx/patches-3.3/506-board_gw6200_gw6000.patch create mode 100644 target/linux/brcm63xx/patches-3.3/507-board-MAGIC.patch create mode 100644 target/linux/brcm63xx/patches-3.3/508-board_hw553.patch create mode 100644 target/linux/brcm63xx/patches-3.3/509-board_rta1320_16m.patch create mode 100644 target/linux/brcm63xx/patches-3.3/510-board_spw303v.patch create mode 100644 target/linux/brcm63xx/patches-3.3/511-board_V2500V.patch create mode 100644 target/linux/brcm63xx/patches-3.3/512-board_BTV2110.patch create mode 100644 target/linux/brcm63xx/patches-3.3/513-board_livebox.patch create mode 100644 target/linux/brcm63xx/patches-3.3/514-board_ct536_ct5621.patch create mode 100644 target/linux/brcm63xx/patches-3.3/515-board_DWV-S0_fixes.patch create mode 100644 target/linux/brcm63xx/patches-3.3/516-board_96348A-122.patch create mode 100644 target/linux/brcm63xx/patches-3.3/517-RTA1205W_16_uart_fixes.patch create mode 100644 target/linux/brcm63xx/patches-3.3/519_board_CPVA502plus.patch create mode 100644 target/linux/brcm63xx/patches-3.3/520-bcm63xx-add-support-for-96368MVWG-board.patch create mode 100644 target/linux/brcm63xx/patches-3.3/521-bcm63xx-add-support-for-96368MVNgr-board.patch create mode 100644 target/linux/brcm63xx/patches-3.3/522-MIPS-BCM63XX-add-96328avng-reference-board.patch create mode 100644 target/linux/brcm63xx/patches-3.3/523-MIPS-BCM63XX-add-963281TAN-reference-board.patch create mode 100644 target/linux/brcm63xx/patches-3.3/524-board_dsl_274xb_rev_f.patch create mode 100644 target/linux/brcm63xx/patches-3.3/525-board_96348w3.patch create mode 100644 target/linux/brcm63xx/patches-3.3/526-board_CT6373-1.patch create mode 100644 target/linux/brcm63xx/patches-3.3/527-board_dva-g3810bn-tl-1.patch create mode 100644 target/linux/brcm63xx/patches-3.3/528-board_nb6.patch create mode 100644 target/linux/brcm63xx/patches-3.3/550-alice_gate2_leds.patch create mode 100644 target/linux/brcm63xx/patches-3.3/551-96348gw_a_leds.patch create mode 100644 target/linux/brcm63xx/patches-3.3/552-board_96348gw-10_reset_button.patch create mode 100644 target/linux/brcm63xx/patches-3.3/800-wl_exports.patch create mode 100644 target/linux/brcm63xx/patches-3.3/801-ssb_export_fallback_sprom.patch create mode 100644 target/linux/brcm63xx/patches-3.3/802-rtl8367r_fix_RGMII_support.patch create mode 100644 target/linux/brcm63xx/profiles/100-Broadcom.mk create mode 100644 target/linux/brcm63xx/profiles/101-Broadcom-wl.mk create mode 100644 target/linux/brcm63xx/profiles/102-Atheros.mk create mode 100644 target/linux/brcm63xx/profiles/103-Ralink.mk create mode 100644 target/linux/brcm63xx/profiles/104-No-WiFi.mk create mode 100644 target/linux/brcm63xx/profiles/105-Broadcom-brcmsmac.mk create mode 100644 target/linux/brcm63xx/profiles/200-GW6X00.mk create mode 100644 target/linux/cns21xx/Makefile create mode 100755 target/linux/cns21xx/base-files/etc/diag.sh create mode 100755 target/linux/cns21xx/base-files/etc/uci-defaults/leds create mode 100755 target/linux/cns21xx/base-files/lib/cns21xx.sh create mode 100644 target/linux/cns21xx/base-files/lib/preinit/05_cns21xx_load_button_drivers create mode 100755 target/linux/cns21xx/base-files/lib/upgrade/platform.sh create mode 100644 target/linux/cns21xx/config-3.3 create mode 100644 target/linux/cns21xx/image/Makefile create mode 100644 target/linux/cns21xx/patches-3.3/002-arm-debugll-printk.patch create mode 100644 target/linux/cns21xx/patches-3.3/003-arm-introduce-fa-platform.patch create mode 100644 target/linux/cns21xx/patches-3.3/004-arm-add-fa-time.patch create mode 100644 target/linux/cns21xx/patches-3.3/005-arm-add-fa-gpio-driver.patch create mode 100644 target/linux/cns21xx/patches-3.3/006-arm-add-fa-watchdog-driver.patch create mode 100644 target/linux/cns21xx/patches-3.3/100-cns21xx-core.patch create mode 100644 target/linux/cns21xx/patches-3.3/101-cns21xx-serial-support.patch create mode 100644 target/linux/cns21xx/patches-3.3/102-cns21xx-gpiolib-support.patch create mode 100644 target/linux/cns21xx/patches-3.3/103-cns21xx-usb-ohci-support.patch create mode 100644 target/linux/cns21xx/patches-3.3/104-cns21xx-usb-ehci-support.patch create mode 100644 target/linux/cns21xx/patches-3.3/105-cns21xx-spi-driver.patch create mode 100644 target/linux/cns21xx/patches-3.3/106-cns21xx-gec-driver.patch create mode 100644 target/linux/cns21xx/patches-3.3/201-cns21xx-add-usb-devices.patch create mode 100644 target/linux/cns21xx/patches-3.3/202-cns21xx-add-watchdog-device.patch create mode 100644 target/linux/cns21xx/patches-3.3/203-cns21xx-add-spi-master-device.patch create mode 100644 target/linux/cns21xx/patches-3.3/204-cns21xx-add-gec-device.patch create mode 100644 target/linux/cns21xx/patches-3.3/301-cns21xx-mach-ns-k330.patch create mode 100644 target/linux/cns21xx/patches-3.3/302-cns21xx-mach-nsb3ast.patch create mode 100644 target/linux/cns21xx/profiles/00-default.mk create mode 100644 target/linux/cns3xxx/Makefile create mode 100644 target/linux/cns3xxx/config-3.3 create mode 100644 target/linux/cns3xxx/image/Makefile create mode 100644 target/linux/cns3xxx/patches-3.3/001-cns3xxx-clkdev-support.patch create mode 100644 target/linux/cns3xxx/patches-3.3/002-cns3xxx_wdt.patch create mode 100644 target/linux/cns3xxx/patches-3.3/049-cns3xxx_smp_support.patch create mode 100644 target/linux/cns3xxx/patches-3.3/050-cns3xxx_i2c_controller.patch create mode 100644 target/linux/cns3xxx/patches-3.3/051-cns3xxx_gigabit.patch create mode 100644 target/linux/cns3xxx/patches-3.3/052-cns3xxx_spi.patch create mode 100644 target/linux/cns3xxx/patches-3.3/054-cns3xxx_pcie_clock.patch create mode 100644 target/linux/cns3xxx/patches-3.3/055-cns3xxx_pci_iospace_init.patch create mode 100644 target/linux/cns3xxx/patches-3.3/060-move_virtual_io_space.patch create mode 100644 target/linux/cns3xxx/patches-3.3/061-twd_base.patch create mode 100644 target/linux/cns3xxx/patches-3.3/100-add_io_spaces.patch create mode 100644 target/linux/cns3xxx/patches-3.3/101-laguna_sdhci_card_detect.patch create mode 100644 target/linux/cns3xxx/patches-3.3/102-cns3xxx_timers.patch create mode 100644 target/linux/cns3xxx/patches-3.3/104-cns3xxx_gpio.patch create mode 100644 target/linux/cns3xxx/patches-3.3/105-cns3xxx_pcie_io.patch create mode 100644 target/linux/cns3xxx/patches-3.3/106-cns3xxx_sata_support.patch create mode 100644 target/linux/cns3xxx/patches-3.3/107-cns3xxx_pcie-section-mismatch-fixes.patch create mode 100644 target/linux/cns3xxx/patches-3.3/108-cns3xxx_pcie-abort.patch create mode 100644 target/linux/cns3xxx/patches-3.3/110-gateworks_gsp_support.patch create mode 100644 target/linux/cns3xxx/patches-3.3/200-dwc_otg.patch create mode 100644 target/linux/cns3xxx/patches-3.3/300-laguna_support.patch create mode 100644 target/linux/cns3xxx/patches-3.3/400-ethernet_fix_tx_csum_offload.patch create mode 100644 target/linux/cns3xxx/patches-3.3/410-ethernet_fix_jumbo_frame.patch create mode 100644 target/linux/cns3xxx/patches-3.3/420-ethernet_optimize_rx_offload.patch create mode 100644 target/linux/cns3xxx/patches-3.3/430-ethernet_fix_tx_completion.patch create mode 100644 target/linux/cns3xxx/patches-3.3/440-i2c_retry.patch create mode 100644 target/linux/cns3xxx/patches-3.3/450-smp_ncores.patch create mode 100644 target/linux/cns3xxx/patches-3.3/460-cns3xxx_fiq_support.patch create mode 100644 target/linux/cobalt/Makefile create mode 100644 target/linux/cobalt/base-files/etc/diag.sh create mode 100644 target/linux/cobalt/config-3.3 create mode 100644 target/linux/cobalt/image/Makefile create mode 100644 target/linux/cobalt/modules.mk create mode 100644 target/linux/coldfire/Makefile create mode 100644 target/linux/coldfire/config-default create mode 100644 target/linux/coldfire/image/Makefile create mode 100644 target/linux/coldfire/patches/001-Coldfire-architecture-support-in-Linux-2.6.38.patch create mode 100644 target/linux/coldfire/patches/002-MCF54451-and-MCF54455-support-in-Linux-2.6.38.patch create mode 100644 target/linux/coldfire/patches/003-MCF547x-and-MCF548x-support-in-Linux-2.6.38.patch create mode 100644 target/linux/coldfire/patches/004-MCF54418-support-in-Linux-2.6.38.patch create mode 100644 target/linux/coldfire/patches/005-Add-serial-driver-and-irda-driver-support-for-MCF544.patch create mode 100644 target/linux/coldfire/patches/006-Add-FEC-driver-support-for-MCF5445x-MCF5441x-MCF547x.patch create mode 100644 target/linux/coldfire/patches/007-Add-eDMA-support-for-MCF5445x.patch create mode 100644 target/linux/coldfire/patches/008-Add-DSPI-driver-support-for-MCF5445x-MCF5441x.patch create mode 100644 target/linux/coldfire/patches/009-Add-ALSA-driver-for-MCF5445x.patch create mode 100644 target/linux/coldfire/patches/010-Add-SRAM-char-device-driver-support-for-MCF5445x.patch create mode 100644 target/linux/coldfire/patches/011-Add-CAU-driver-for-MCF5445x-and-MCF5441x.patch create mode 100644 target/linux/coldfire/patches/012-Add-vDSO-support-for-Coldfire-platform.patch create mode 100644 target/linux/coldfire/patches/013-Add-MCD-DMA-driver-for-MCF547x-MCF548x.patch create mode 100644 target/linux/coldfire/patches/014-Add-CFV4E-FPU-support-for-MCF547x-MCF548x.patch create mode 100644 target/linux/coldfire/patches/015-Add-driver-to-support-ten-UART-devices-on-MCF5441x.patch create mode 100644 target/linux/coldfire/patches/016-Add-nand-driver-support-for-M54418TWR-board.patch create mode 100644 target/linux/coldfire/patches/017-Add-cpu-dma-sync-function-for-coldfire-platform.patch create mode 100644 target/linux/coldfire/patches/018-Add-SSD1289-TFT-LCD-framebuffer-driver-on-TWR-MCF544.patch create mode 100644 target/linux/coldfire/patches/019-Fix-the-format-field-for-the-Coldfire-exception-fram.patch create mode 100644 target/linux/coldfire/patches/020-Add-dual-FEC-1588-timer-support.patch create mode 100644 target/linux/coldfire/patches/021-Add-ethernet-switch-driver-for-MCF54418.patch create mode 100644 target/linux/coldfire/patches/022-Redefine-I-O-read-and-write-functions.patch create mode 100644 target/linux/coldfire/patches/023-Replace-readl-and-writel-for-FEC-driver.patch create mode 100644 target/linux/coldfire/patches/024-Add-SEC-1.1-support-for-MCF547x-and-MCF548x.patch create mode 100644 target/linux/coldfire/patches/025-Add-I2C-driver-for-MCF5445x-MCF547x-MCF548x.patch create mode 100644 target/linux/coldfire/patches/026-Add-RTC-driver-support-for-MCF5445x.patch create mode 100644 target/linux/coldfire/patches/027-Add-RTC-driver-support-on-MCF5441x-platform.patch create mode 100644 target/linux/coldfire/patches/028-Add-SD-MMC-SDIO-over-SPI-support-for-MCF54451-and-MC.patch create mode 100644 target/linux/coldfire/patches/029-Add-eSDHC-driver-for-MCF5441x.patch create mode 100644 target/linux/coldfire/patches/030-Add-SPI-device-configuration-for-FXS-and-FXO-on-MCF5.patch create mode 100644 target/linux/coldfire/patches/031-Add-watchdog-driver-support-for-MCF5445x-and-MCF547x.patch create mode 100644 target/linux/coldfire/patches/032-Change-some-jffs2-warning-to-debug-info.patch create mode 100644 target/linux/coldfire/patches/033-Fix-structure-fsl_ssd1289_data-definition-bug-for-SS.patch create mode 100644 target/linux/coldfire/patches/034-Enable-the-NFC-driver-for-soft_ecc.patch create mode 100644 target/linux/coldfire/patches/036-Add-FlexCAN-support-on-ColdFire-M548X-M54418-platfor.patch create mode 100644 target/linux/coldfire/patches/037-Add-ColdFire-MCF54455-PATA-interface-support.patch create mode 100644 target/linux/coldfire/patches/038-Add-PCI-Framebuffer-support-for-Silicon-Motion-s-Lyn.patch create mode 100644 target/linux/coldfire/patches/039-Add-PCI-bus-driver-for-M54455EVB-and-M547X_8X.patch create mode 100644 target/linux/coldfire/patches/040-Add-USB-support-for-MCF5445x-and-MCF54418.patch create mode 100644 target/linux/coldfire/patches/041-Fix-CAU-driver-bug-for-SHA1-digest-algorithm.patch create mode 100644 target/linux/coldfire/patches/042-Fix-NEED_MULTIPLE_NODES-unmet-direct-dependencies-wa.patch create mode 100644 target/linux/coldfire/patches/043-workaround-for-zero-page-used-on-ColdFire-platform.patch create mode 100644 target/linux/coldfire/patches/044-Fix-Max3353-otg-toggle-bug.patch create mode 100644 target/linux/coldfire/patches/045-Add-high-resolution-kernel-timer-support.patch create mode 100644 target/linux/coldfire/patches/046-Convert-rtc-drivers-to-use-the-alarm_irq_enable-meth.patch create mode 100644 target/linux/coldfire/patches/047-Fix-DSPI-compile-error-for-MCF547x-MCF548x.patch create mode 100644 target/linux/coldfire/patches/048-Fix-i2c-driver-bug-when-reinserting-as-module.patch create mode 100644 target/linux/coldfire/patches/049-Update-FEC-driver-for-MCF5445x-and-MCF54418.patch create mode 100644 target/linux/coldfire/patches/050-Update-the-DMA-map-function-for-CF-platform.patch create mode 100644 target/linux/coldfire/patches/051-Update-SD-MMC-over-SPI-driver-for-MCF54451-and-MCF54.patch create mode 100644 target/linux/coldfire/patches/052-Update-the-default-configurations-for-ColdFire-V4-bo.patch create mode 100644 target/linux/coldfire/patches/100-kernel-2.6.38-Fix-FEC-driver-bugs-for-MCF547x-MCF548x.patch create mode 100644 target/linux/coldfire/patches/101-kernel-2.6.38-Fix-LCD-framebuffer-driver-data-swap-bug-for-MCF5441.patch create mode 100644 target/linux/coldfire/patches/102-kernel-2.6.38-Fix-SD-MMC-SDIO-over-SPI-driver-bug-when-reinserting.patch create mode 100644 target/linux/coldfire/patches/103-kernel-2.6.38-Fix-i2c-driver-could-not-work-as-module.patch create mode 100644 target/linux/coldfire/patches/200-fec_select_phylib.patch create mode 100644 target/linux/ep93xx/Makefile create mode 100644 target/linux/ep93xx/base-files/etc/inittab create mode 100644 target/linux/ep93xx/base-files/lib/preinit/05_set_ether_mac_rdc create mode 100644 target/linux/ep93xx/config-3.3 create mode 100644 target/linux/ep93xx/image/Makefile create mode 100644 target/linux/ep93xx/modules.mk create mode 100644 target/linux/ep93xx/patches-3.3/001-ep93xx_cpuinfo.patch create mode 100644 target/linux/ep93xx/patches-3.3/003-ep93xx_touchscreen.patch create mode 100644 target/linux/ep93xx/patches-3.3/004-simone_add_mmc_spi.patch create mode 100644 target/linux/ep93xx/profiles/00-default.mk create mode 100644 target/linux/ep93xx/profiles/01-simone.mk create mode 100644 target/linux/etrax/Makefile create mode 100644 target/linux/etrax/base-files/etc/config/firewall create mode 100644 target/linux/etrax/base-files/etc/config/network create mode 100644 target/linux/etrax/config-default create mode 100644 target/linux/etrax/files/arch/cris/arch-v10/drivers/etraxi2c.h create mode 100644 target/linux/etrax/files/arch/cris/arch-v10/drivers/i2c_errno.h create mode 100644 target/linux/etrax/files/arch/cris/arch-v10/drivers/i2c_gvc.c create mode 100644 target/linux/etrax/files/arch/cris/arch-v10/drivers/i2c_gvc.h create mode 100644 target/linux/etrax/files/drivers/usb/host/hc-cris-dbg.h create mode 100644 target/linux/etrax/files/drivers/usb/host/hc-crisv10.c create mode 100644 target/linux/etrax/files/drivers/usb/host/hc-crisv10.h create mode 100644 target/linux/etrax/image/Config.in create mode 100644 target/linux/etrax/image/Makefile create mode 100755 target/linux/etrax/image/boot_linux create mode 100644 target/linux/etrax/image/e100boot/Makefile create mode 100644 target/linux/etrax/image/mkfimage/Makefile create mode 100644 target/linux/etrax/image/mkfimage/src/Makefile create mode 100644 target/linux/etrax/image/mkfimage/src/mkfimage.c create mode 100644 target/linux/etrax/patches-2.6.32/100-cris-makefiles.patch create mode 100644 target/linux/etrax/patches-2.6.32/201-flashsize.patch create mode 100644 target/linux/etrax/patches-2.6.32/300-usb_support.patch create mode 100644 target/linux/etrax/patches-2.6.32/400-Kconfig_source.patch create mode 100644 target/linux/etrax/patches-2.6.32/500-i2c_gvc.patch create mode 100644 target/linux/etrax/patches-2.6.32/600-create-device-serial.patch create mode 100644 target/linux/etrax/patches-2.6.32/610-create-the-gpio-devices.patch create mode 100644 target/linux/etrax/patches-2.6.32/620-create-the-i2c-devices.patch create mode 100644 target/linux/etrax/patches-2.6.32/985-cris-headers.patch create mode 100644 target/linux/etrax/profiles/100-generic.mk create mode 100644 target/linux/etrax/profiles/101-vhdl-nofb.mk create mode 100644 target/linux/gemini/Makefile create mode 100644 target/linux/gemini/base-files/lib/preinit/05_set_ether_mac_gemini create mode 100644 target/linux/gemini/config-3.3 create mode 100644 target/linux/gemini/image/Makefile create mode 100644 target/linux/gemini/patches-3.3/001-gemini-fix-gpio_set_irq_type.patch create mode 100644 target/linux/gemini/patches-3.3/002-arm-gemini-fix-platform_register_rtc-prototype.patch create mode 100644 target/linux/gemini/patches-3.3/110-watchdog-add-gemini_wdt-driver.patch create mode 100644 target/linux/gemini/patches-3.3/111-arm-gemini-add-watchdog-device.patch create mode 100644 target/linux/gemini/patches-3.3/112-arm-gemini-register-watchdog-devices.patch create mode 100644 target/linux/gemini/patches-3.3/120-net-add-gemini-gmac-driver.patch create mode 100644 target/linux/gemini/patches-3.3/121-arm-gemini-add-ethernet-device.patch create mode 100644 target/linux/gemini/patches-3.3/122-arm-gemini-wbd111-register-ethernet.patch create mode 100644 target/linux/gemini/patches-3.3/123-arm-gemini-wbd222-register-eth.patch create mode 100644 target/linux/gemini/patches-3.3/124-arm-gemini-rut100-register-ethernet.patch create mode 100644 target/linux/gemini/patches-3.3/130-usb-ehci-gemini-fot2gxx-support.patch create mode 100644 target/linux/gemini/patches-3.3/131-arm-gemini-add-usb-platform-device.patch create mode 100644 target/linux/gemini/patches-3.3/132-arm-gemini-wbd111-register-usb.patch create mode 100644 target/linux/gemini/patches-3.3/133-arm-gemini-wbd222-register-usb.patch create mode 100644 target/linux/gemini/patches-3.3/134-arm-gemini-rut100-register-usb.patch create mode 100644 target/linux/gemini/patches-3.3/135-arm-gemini-nas4220-register-usb.patch create mode 100644 target/linux/gemini/patches-3.3/140-arm-gemini-add-pci-support.patch create mode 100644 target/linux/generic/PATCHES create mode 100755 target/linux/generic/base-files/init create mode 100644 target/linux/generic/config-3.3 create mode 100644 target/linux/generic/files/Documentation/networking/adm6996.txt create mode 100644 target/linux/generic/files/Documentation/pwm.txt create mode 100644 target/linux/generic/files/arch/mips/fw/myloader/Makefile create mode 100644 target/linux/generic/files/arch/mips/fw/myloader/myloader.c create mode 100644 target/linux/generic/files/crypto/ocf/Config.in create mode 100644 target/linux/generic/files/crypto/ocf/Kconfig create mode 100644 target/linux/generic/files/crypto/ocf/Makefile create mode 100644 target/linux/generic/files/crypto/ocf/c7108/Makefile create mode 100644 target/linux/generic/files/crypto/ocf/c7108/aes-7108.c create mode 100644 target/linux/generic/files/crypto/ocf/c7108/aes-7108.h create mode 100644 target/linux/generic/files/crypto/ocf/criov.c create mode 100644 target/linux/generic/files/crypto/ocf/crypto.c create mode 100644 target/linux/generic/files/crypto/ocf/cryptocteon/Makefile create mode 100644 target/linux/generic/files/crypto/ocf/cryptocteon/README.txt create mode 100644 target/linux/generic/files/crypto/ocf/cryptocteon/cavium_crypto.c create mode 100644 target/linux/generic/files/crypto/ocf/cryptocteon/cryptocteon.c create mode 100644 target/linux/generic/files/crypto/ocf/cryptodev.c create mode 100644 target/linux/generic/files/crypto/ocf/cryptodev.h create mode 100644 target/linux/generic/files/crypto/ocf/cryptosoft.c create mode 100644 target/linux/generic/files/crypto/ocf/ep80579/Makefile create mode 100644 target/linux/generic/files/crypto/ocf/ep80579/environment.mk create mode 100644 target/linux/generic/files/crypto/ocf/ep80579/icp_asym.c create mode 100644 target/linux/generic/files/crypto/ocf/ep80579/icp_common.c create mode 100644 target/linux/generic/files/crypto/ocf/ep80579/icp_ocf.h create mode 100644 target/linux/generic/files/crypto/ocf/ep80579/icp_sym.c create mode 100644 target/linux/generic/files/crypto/ocf/ep80579/linux_2.6_kernel_space.mk create mode 100644 target/linux/generic/files/crypto/ocf/hifn/Makefile create mode 100644 target/linux/generic/files/crypto/ocf/hifn/hifn7751.c create mode 100644 target/linux/generic/files/crypto/ocf/hifn/hifn7751reg.h create mode 100644 target/linux/generic/files/crypto/ocf/hifn/hifn7751var.h create mode 100644 target/linux/generic/files/crypto/ocf/hifn/hifnHIPP.c create mode 100644 target/linux/generic/files/crypto/ocf/hifn/hifnHIPPreg.h create mode 100644 target/linux/generic/files/crypto/ocf/hifn/hifnHIPPvar.h create mode 100644 target/linux/generic/files/crypto/ocf/ixp4xx/Makefile create mode 100644 target/linux/generic/files/crypto/ocf/ixp4xx/ixp4xx.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/Makefile create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAes.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAesBoxes.dat create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/mvCesa.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/mvCesa.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/mvCesaDebug.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/mvCesaRegs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/mvCesaTest.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/mvCompVer.txt create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/mvLru.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/mvLru.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/mvMD5.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/mvMD5.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/mvSHA1.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa/mvSHA1.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/cesa_ocf_drv.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/common/mv802_3.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/common/mvCommon.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/common/mvCommon.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/common/mvCompVer.txt create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/common/mvDebug.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/common/mvDebug.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/common/mvStack.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/common/mvStack.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/common/mvTypes.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/dbg-trace.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/dbg-trace.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfInit.S create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/kw_family/mvCompVer.txt create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCompVer.txt create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvCompVer.txt create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfBasicInit.S create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.S create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvCompVer.txt create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfBasicInit.S create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.S create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvCompVer.txt create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvCompVer.txt create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvCompVer.txt create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvCompVer.txt create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvCompVer.txt create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvCompVer.txt create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvCompVer.txt create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvCompVer.txt create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiEeprom.S create mode 100644 target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h create mode 100644 target/linux/generic/files/crypto/ocf/ocf-bench.c create mode 100644 target/linux/generic/files/crypto/ocf/ocf-compat.h create mode 100644 target/linux/generic/files/crypto/ocf/ocfnull/Makefile create mode 100644 target/linux/generic/files/crypto/ocf/ocfnull/ocfnull.c create mode 100644 target/linux/generic/files/crypto/ocf/pasemi/Makefile create mode 100644 target/linux/generic/files/crypto/ocf/pasemi/pasemi.c create mode 100644 target/linux/generic/files/crypto/ocf/pasemi/pasemi_fnu.h create mode 100644 target/linux/generic/files/crypto/ocf/random.c create mode 100644 target/linux/generic/files/crypto/ocf/rndtest.c create mode 100644 target/linux/generic/files/crypto/ocf/rndtest.h create mode 100644 target/linux/generic/files/crypto/ocf/safe/Makefile create mode 100644 target/linux/generic/files/crypto/ocf/safe/hmachack.h create mode 100644 target/linux/generic/files/crypto/ocf/safe/md5.c create mode 100644 target/linux/generic/files/crypto/ocf/safe/md5.h create mode 100644 target/linux/generic/files/crypto/ocf/safe/safe.c create mode 100644 target/linux/generic/files/crypto/ocf/safe/safereg.h create mode 100644 target/linux/generic/files/crypto/ocf/safe/safevar.h create mode 100644 target/linux/generic/files/crypto/ocf/safe/sha1.c create mode 100644 target/linux/generic/files/crypto/ocf/safe/sha1.h create mode 100644 target/linux/generic/files/crypto/ocf/talitos/Makefile create mode 100644 target/linux/generic/files/crypto/ocf/talitos/talitos.c create mode 100644 target/linux/generic/files/crypto/ocf/talitos/talitos_dev.h create mode 100644 target/linux/generic/files/crypto/ocf/talitos/talitos_soft.h create mode 100644 target/linux/generic/files/crypto/ocf/ubsec_ssb/Makefile create mode 100644 target/linux/generic/files/crypto/ocf/ubsec_ssb/bsdqueue.h create mode 100644 target/linux/generic/files/crypto/ocf/ubsec_ssb/ubsec_ssb.c create mode 100644 target/linux/generic/files/crypto/ocf/ubsec_ssb/ubsecreg.h create mode 100644 target/linux/generic/files/crypto/ocf/ubsec_ssb/ubsecvar.h create mode 100644 target/linux/generic/files/crypto/ocf/uio.h create mode 100644 target/linux/generic/files/drivers/char/gpio_dev.c create mode 100644 target/linux/generic/files/drivers/input/misc/gpio_buttons.c create mode 100644 target/linux/generic/files/drivers/leds/ledtrig-morse.c create mode 100644 target/linux/generic/files/drivers/leds/ledtrig-netdev.c create mode 100644 target/linux/generic/files/drivers/leds/ledtrig-usbdev.c create mode 100644 target/linux/generic/files/drivers/mtd/myloader.c create mode 100644 target/linux/generic/files/drivers/net/phy/adm6996.c create mode 100644 target/linux/generic/files/drivers/net/phy/adm6996.h create mode 100644 target/linux/generic/files/drivers/net/phy/ar8216.c create mode 100644 target/linux/generic/files/drivers/net/phy/ar8216.h create mode 100644 target/linux/generic/files/drivers/net/phy/ip17xx.c create mode 100644 target/linux/generic/files/drivers/net/phy/micrel.c create mode 100644 target/linux/generic/files/drivers/net/phy/mvswitch.c create mode 100644 target/linux/generic/files/drivers/net/phy/mvswitch.h create mode 100644 target/linux/generic/files/drivers/net/phy/psb6970.c create mode 100644 target/linux/generic/files/drivers/net/phy/rtl8306.c create mode 100644 target/linux/generic/files/drivers/net/phy/rtl8366_smi.c create mode 100644 target/linux/generic/files/drivers/net/phy/rtl8366_smi.h create mode 100644 target/linux/generic/files/drivers/net/phy/rtl8366rb.c create mode 100644 target/linux/generic/files/drivers/net/phy/rtl8366s.c create mode 100644 target/linux/generic/files/drivers/net/phy/rtl8367.c create mode 100644 target/linux/generic/files/drivers/net/phy/swconfig.c create mode 100644 target/linux/generic/files/drivers/net/phy/swconfig_leds.c create mode 100644 target/linux/generic/files/drivers/pwm/Kconfig create mode 100644 target/linux/generic/files/drivers/pwm/Makefile create mode 100644 target/linux/generic/files/drivers/pwm/gpio-pwm.c create mode 100644 target/linux/generic/files/drivers/pwm/pwm.c create mode 100644 target/linux/generic/files/fs/yaffs2/Kconfig create mode 100644 target/linux/generic/files/fs/yaffs2/Makefile create mode 100644 target/linux/generic/files/fs/yaffs2/devextras.h create mode 100644 target/linux/generic/files/fs/yaffs2/moduleconfig.h create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_checkptrw.c create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_checkptrw.h create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_ecc.c create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_ecc.h create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_fs.c create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_guts.c create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_guts.h create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_mtdif.c create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_mtdif.h create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_mtdif1-compat.c create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_mtdif1.c create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_mtdif1.h create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_mtdif2.c create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_mtdif2.h create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_nand.c create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_nand.h create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_nandemul2k.h create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_packedtags1.c create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_packedtags1.h create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_packedtags2.c create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_packedtags2.h create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_qsort.c create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_qsort.h create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_tagscompat.c create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_tagscompat.h create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_tagsvalidity.c create mode 100644 target/linux/generic/files/fs/yaffs2/yaffs_tagsvalidity.h create mode 100644 target/linux/generic/files/fs/yaffs2/yaffsinterface.h create mode 100644 target/linux/generic/files/fs/yaffs2/yportenv.h create mode 100644 target/linux/generic/files/include/linux/ar8216_platform.h create mode 100644 target/linux/generic/files/include/linux/ath5k_platform.h create mode 100644 target/linux/generic/files/include/linux/ath9k_platform.h create mode 100644 target/linux/generic/files/include/linux/glamo-engine.h create mode 100644 target/linux/generic/files/include/linux/glamofb.h create mode 100644 target/linux/generic/files/include/linux/gpio_buttons.h create mode 100644 target/linux/generic/files/include/linux/gpio_dev.h create mode 100644 target/linux/generic/files/include/linux/myloader.h create mode 100644 target/linux/generic/files/include/linux/pwm/pwm.h create mode 100644 target/linux/generic/files/include/linux/routerboot.h create mode 100644 target/linux/generic/files/include/linux/rt2x00_platform.h create mode 100644 target/linux/generic/files/include/linux/rtl8366.h create mode 100644 target/linux/generic/files/include/linux/rtl8367.h create mode 100644 target/linux/generic/files/include/linux/switch.h create mode 100644 target/linux/generic/image/Makefile create mode 100644 target/linux/generic/image/initramfs-base-files.txt create mode 100644 target/linux/generic/image/lzma-loader/Makefile create mode 100644 target/linux/generic/image/lzma-loader/src/LzmaDecode.c create mode 100644 target/linux/generic/image/lzma-loader/src/LzmaDecode.h create mode 100644 target/linux/generic/image/lzma-loader/src/Makefile create mode 100644 target/linux/generic/image/lzma-loader/src/decompress.c create mode 100644 target/linux/generic/image/lzma-loader/src/lzma-copy.lds.in create mode 100644 target/linux/generic/image/lzma-loader/src/lzma.lds.in create mode 100644 target/linux/generic/image/lzma-loader/src/print.c create mode 100644 target/linux/generic/image/lzma-loader/src/print.h create mode 100644 target/linux/generic/image/lzma-loader/src/printf.c create mode 100644 target/linux/generic/image/lzma-loader/src/printf.h create mode 100644 target/linux/generic/image/lzma-loader/src/start.S create mode 100644 target/linux/generic/image/lzma-loader/src/uart16550.c create mode 100644 target/linux/generic/image/lzma-loader/src/uart16550.h create mode 100644 target/linux/generic/patches-3.3/006-arm_kernel_xz_support.patch create mode 100644 target/linux/generic/patches-3.3/020-ssb_update.patch create mode 100644 target/linux/generic/patches-3.3/025-bcma_backport.patch create mode 100644 target/linux/generic/patches-3.3/026-bcma_pmu_regression.patch create mode 100644 target/linux/generic/patches-3.3/027-bcma-add-missing-iounmap-on-error-path.patch create mode 100644 target/linux/generic/patches-3.3/028-bcma-fix-regression-in-interrupt-assignment-on-mips.patch create mode 100644 target/linux/generic/patches-3.3/040-Controlled-Delay-AQM.patch create mode 100644 target/linux/generic/patches-3.3/041-codel-use-Newton-method-instead-of-sqrt-and-divides.patch create mode 100644 target/linux/generic/patches-3.3/042-fq_codel-Fair-Queue-Codel-AQM.patch create mode 100644 target/linux/generic/patches-3.3/043-net-codel-Add-missing-include-linux-prefetch.h.patch create mode 100644 target/linux/generic/patches-3.3/044-net-codel-fix-build-errors.patch create mode 100644 target/linux/generic/patches-3.3/045-codel-use-u16-field-instead-of-31bits-for-rec_inv_sq.patch create mode 100644 target/linux/generic/patches-3.3/046-fq_codel-qdisc-backlog.patch create mode 100644 target/linux/generic/patches-3.3/047-spi_message_queue.patch create mode 100644 target/linux/generic/patches-3.3/048-spi-Dont-call-prepare-unprepare-transfer-if-not-popu.patch create mode 100644 target/linux/generic/patches-3.3/049-codel-refine-one-condition-to-avoid-a-nul-rec_inv_sqrt.patch create mode 100644 target/linux/generic/patches-3.3/050-rng_git_backport.patch create mode 100644 target/linux/generic/patches-3.3/051-rng_git_backport-remove_irqf_sample_random.patch create mode 100644 target/linux/generic/patches-3.3/100-overlayfs_v12.patch create mode 100644 target/linux/generic/patches-3.3/102-ehci_hcd_ignore_oc.patch create mode 100644 target/linux/generic/patches-3.3/110-fix_mtd_include.patch create mode 100644 target/linux/generic/patches-3.3/130-pppoatm-queue-depth.patch create mode 100644 target/linux/generic/patches-3.3/140-ixp4xx_hss_module_h_include.patch create mode 100644 target/linux/generic/patches-3.3/200-fix_localversion.patch create mode 100644 target/linux/generic/patches-3.3/201-extra_optimization.patch create mode 100644 target/linux/generic/patches-3.3/202-reduce_module_size.patch create mode 100644 target/linux/generic/patches-3.3/210-darwin_scripts_include.patch create mode 100644 target/linux/generic/patches-3.3/211-stddef_include.patch create mode 100644 target/linux/generic/patches-3.3/212-x86_reloc_portability.patch create mode 100644 target/linux/generic/patches-3.3/220-module_exports.patch create mode 100644 target/linux/generic/patches-3.3/230-openwrt_lzma_options.patch create mode 100644 target/linux/generic/patches-3.3/250-netfilter_depends.patch create mode 100644 target/linux/generic/patches-3.3/251-sound_kconfig.patch create mode 100644 target/linux/generic/patches-3.3/252-mv_cesa_depends.patch create mode 100644 target/linux/generic/patches-3.3/253-ssb_b43_default_on.patch create mode 100644 target/linux/generic/patches-3.3/254-textsearch_kconfig_hacks.patch create mode 100644 target/linux/generic/patches-3.3/255-lib80211_kconfig_hacks.patch create mode 100644 target/linux/generic/patches-3.3/256-crypto_add_kconfig_prompts.patch create mode 100644 target/linux/generic/patches-3.3/257-wireless_ext_kconfig_hack.patch create mode 100644 target/linux/generic/patches-3.3/258-netfilter_netlink_kconfig_hack.patch create mode 100644 target/linux/generic/patches-3.3/300-mips_expose_boot_raw.patch create mode 100644 target/linux/generic/patches-3.3/301-mips_image_cmdline_hack.patch create mode 100644 target/linux/generic/patches-3.3/302-mips_use_generic_thread_info_allocator.patch create mode 100644 target/linux/generic/patches-3.3/303-mips_fix_kexec.patch create mode 100644 target/linux/generic/patches-3.3/304-mips_disable_fpu.patch create mode 100644 target/linux/generic/patches-3.3/305-mips_module_reloc.patch create mode 100644 target/linux/generic/patches-3.3/306-mips_mem_functions_performance.patch create mode 100644 target/linux/generic/patches-3.3/307-mips_oprofile_fix.patch create mode 100644 target/linux/generic/patches-3.3/308-mips-show-correct-cpu-name-for-24KEc.patch create mode 100644 target/linux/generic/patches-3.3/309-mips_fuse_workaround.patch create mode 100644 target/linux/generic/patches-3.3/310-arm_module_unresolved_weak_sym.patch create mode 100644 target/linux/generic/patches-3.3/320-ppc4xx_optimization.patch create mode 100644 target/linux/generic/patches-3.3/321-powerpc_crtsavres_prereq.patch create mode 100644 target/linux/generic/patches-3.3/322-ppc4xx-crypto-compile-fix.patch create mode 100644 target/linux/generic/patches-3.3/330-mips-add-crash-and-kdump-support.patch create mode 100644 target/linux/generic/patches-3.3/331-mips-kexec-enhanche-the-support.patch create mode 100644 target/linux/generic/patches-3.3/332-mips-kexec-init-the-arguments-for-the-new-kernel-image.patch create mode 100644 target/linux/generic/patches-3.3/333-mips-kexec-get-kernel-parameters-from-kexec-tools.patch create mode 100644 target/linux/generic/patches-3.3/334-mips-fix-compiling-failure-of-relocate_kernel.patch create mode 100644 target/linux/generic/patches-3.3/335-mips-kexec-cleanup-kexec-tools-parameter-handling.patch create mode 100644 target/linux/generic/patches-3.3/340-module_alloc_size_check.patch create mode 100644 target/linux/generic/patches-3.3/400-rootfs_split.patch create mode 100644 target/linux/generic/patches-3.3/401-partial_eraseblock_write.patch create mode 100644 target/linux/generic/patches-3.3/410-mtd_info_move_forward_decl.patch create mode 100644 target/linux/generic/patches-3.3/420-redboot_space.patch create mode 100644 target/linux/generic/patches-3.3/421-redboot_boardconfig.patch create mode 100644 target/linux/generic/patches-3.3/430-mtd_myloader_partition_parser.patch create mode 100644 target/linux/generic/patches-3.3/440-block2mtd_init.patch create mode 100644 target/linux/generic/patches-3.3/441-block2mtd_refresh.patch create mode 100644 target/linux/generic/patches-3.3/442-block2mtd_probe.patch create mode 100644 target/linux/generic/patches-3.3/443-block2mtd-avoid-recursive-call-of-mtd_writev.patch create mode 100644 target/linux/generic/patches-3.3/450-mtd_plat_nand_chip_fixup.patch create mode 100644 target/linux/generic/patches-3.3/451-mtd_fix_nand_correct_data_return_code.patch create mode 100644 target/linux/generic/patches-3.3/460-cfi_cmdset_0002_no_erase_suspend.patch create mode 100644 target/linux/generic/patches-3.3/470-mtd_m25p80_add_pm25lv_flash_support.patch create mode 100644 target/linux/generic/patches-3.3/473-mtd_m25p80_add_w25q128.patch create mode 100644 target/linux/generic/patches-3.3/475-mtd_cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch create mode 100644 target/linux/generic/patches-3.3/476-mtd-m25p80-allow-to-disable-small-sector-erase.patch create mode 100644 target/linux/generic/patches-3.3/477-mtd-m25p80-add-support-for-the-EON-EN25Q64-chip.patch create mode 100644 target/linux/generic/patches-3.3/500-yaffs_support.patch create mode 100644 target/linux/generic/patches-3.3/501-yaffs_cvs_2009_04_24.patch create mode 100644 target/linux/generic/patches-3.3/502-yaffs_git_2010_10_20.patch create mode 100644 target/linux/generic/patches-3.3/503-yaffs_symlink_bug.patch create mode 100644 target/linux/generic/patches-3.3/504-yaffs_mutex_fix.patch create mode 100644 target/linux/generic/patches-3.3/505-2.6.39_fix.patch create mode 100644 target/linux/generic/patches-3.3/506-yaffs2-3.2_fix.patch create mode 100644 target/linux/generic/patches-3.3/507-yaffs2-3.3_fix.patch create mode 100644 target/linux/generic/patches-3.3/510-jffs2_make_lzma_available.patch create mode 100644 target/linux/generic/patches-3.3/511-debloat_lzma.patch create mode 100644 target/linux/generic/patches-3.3/512-jffs2_eofdetect.patch create mode 100644 target/linux/generic/patches-3.3/520-squashfs_update_xz_comp_opts.patch create mode 100644 target/linux/generic/patches-3.3/540-crypto-xz-decompression-support.patch create mode 100644 target/linux/generic/patches-3.3/541-ubifs-xz-decompression-support.patch create mode 100644 target/linux/generic/patches-3.3/550-ubifs-symlink-xattr-support.patch create mode 100644 target/linux/generic/patches-3.3/600-netfilter_layer7_2.22.patch create mode 100644 target/linux/generic/patches-3.3/601-netfilter_layer7_pktmatch.patch create mode 100644 target/linux/generic/patches-3.3/602-netfilter_layer7_match.patch create mode 100644 target/linux/generic/patches-3.3/603-netfilter_layer7_2.6.36_fix.patch create mode 100644 target/linux/generic/patches-3.3/604-netfilter_cisco_794x_iphone.patch create mode 100644 target/linux/generic/patches-3.3/610-netfilter_match_bypass_default_checks.patch create mode 100644 target/linux/generic/patches-3.3/611-netfilter_match_bypass_default_table.patch create mode 100644 target/linux/generic/patches-3.3/612-netfilter_match_reduce_memory_access.patch create mode 100644 target/linux/generic/patches-3.3/613-netfilter_optional_tcp_window_check.patch create mode 100644 target/linux/generic/patches-3.3/620-sched_esfq.patch create mode 100644 target/linux/generic/patches-3.3/621-sched_act_connmark.patch create mode 100644 target/linux/generic/patches-3.3/630-packet_socket_type.patch create mode 100644 target/linux/generic/patches-3.3/640-bridge_no_eap_forward.patch create mode 100644 target/linux/generic/patches-3.3/641-bridge_always_accept_eap.patch create mode 100644 target/linux/generic/patches-3.3/642-bridge_port_isolate.patch create mode 100644 target/linux/generic/patches-3.3/643-bridge_remove_ipv6_dependency.patch create mode 100644 target/linux/generic/patches-3.3/644-bridge_optimize_netfilter_hooks.patch create mode 100644 target/linux/generic/patches-3.3/650-pppoe_header_pad.patch create mode 100644 target/linux/generic/patches-3.3/651-wireless_mesh_header.patch create mode 100644 target/linux/generic/patches-3.3/652-atm_header_changes.patch create mode 100644 target/linux/generic/patches-3.3/653-disable_netlink_trim.patch create mode 100644 target/linux/generic/patches-3.3/654-avoid_skb_cow_realloc.patch create mode 100644 target/linux/generic/patches-3.3/655-increase_skb_pad.patch create mode 100644 target/linux/generic/patches-3.3/700-swconfig.patch create mode 100644 target/linux/generic/patches-3.3/701-phy_extension.patch create mode 100644 target/linux/generic/patches-3.3/702-phy_add_aneg_done_function.patch create mode 100644 target/linux/generic/patches-3.3/710-phy-add-mdio_register_board_info.patch create mode 100644 target/linux/generic/patches-3.3/720-phy_adm6996.patch create mode 100644 target/linux/generic/patches-3.3/721-phy_packets.patch create mode 100644 target/linux/generic/patches-3.3/722-phy_mvswitch.patch create mode 100644 target/linux/generic/patches-3.3/723-phy_ip175c.patch create mode 100644 target/linux/generic/patches-3.3/724-phy_ar8216.patch create mode 100644 target/linux/generic/patches-3.3/725-phy_rtl8306.patch create mode 100644 target/linux/generic/patches-3.3/726-phy_rtl8366.patch create mode 100644 target/linux/generic/patches-3.3/727-phy-rtl8367.patch create mode 100644 target/linux/generic/patches-3.3/728-phy-micrel.patch create mode 100644 target/linux/generic/patches-3.3/729-phy-tantos.patch create mode 100644 target/linux/generic/patches-3.3/750-hostap_txpower.patch create mode 100644 target/linux/generic/patches-3.3/810-pci_disable_common_quirks.patch create mode 100644 target/linux/generic/patches-3.3/811-pci_disable_usb_common_quirks.patch create mode 100644 target/linux/generic/patches-3.3/820-usb_add_usb_find_device_by_name.patch create mode 100644 target/linux/generic/patches-3.3/830-ledtrig_morse.patch create mode 100644 target/linux/generic/patches-3.3/831-ledtrig_netdev.patch create mode 100644 target/linux/generic/patches-3.3/832-ledtrig_usbdev.patch create mode 100644 target/linux/generic/patches-3.3/835-gpiodev.patch create mode 100644 target/linux/generic/patches-3.3/840-rtc7301.patch create mode 100644 target/linux/generic/patches-3.3/841-rtc_pt7c4338.patch create mode 100644 target/linux/generic/patches-3.3/850-glamo_headers.patch create mode 100644 target/linux/generic/patches-3.3/861-04_spi_gpio_implement_spi_delay.patch create mode 100644 target/linux/generic/patches-3.3/862-gpio_spi_driver.patch create mode 100644 target/linux/generic/patches-3.3/863-gpiommc.patch create mode 100644 target/linux/generic/patches-3.3/864-gpiommc_configfs_locking.patch create mode 100644 target/linux/generic/patches-3.3/865-gpiopwm.patch create mode 100644 target/linux/generic/patches-3.3/870-hifn795x_byteswap.patch create mode 100644 target/linux/generic/patches-3.3/900-slab_maxsize.patch create mode 100644 target/linux/generic/patches-3.3/910-kobject_uevent.patch create mode 100644 target/linux/generic/patches-3.3/911-kobject_add_broadcast_uevent.patch create mode 100644 target/linux/generic/patches-3.3/920-unable_to_open_console.patch create mode 100644 target/linux/generic/patches-3.3/921-use_preinit_as_init.patch create mode 100644 target/linux/generic/patches-3.3/930-crashlog.patch create mode 100644 target/linux/generic/patches-3.3/940-ocf_kbuild_integration.patch create mode 100644 target/linux/generic/patches-3.3/941-ocf_20120127.patch create mode 100644 target/linux/generic/patches-3.3/950-vm_exports.patch create mode 100644 target/linux/generic/patches-3.3/960-decompress_unlzo_fix.patch create mode 100644 target/linux/generic/patches-3.3/980-update_arm_machtypes.patch create mode 100644 target/linux/generic/patches-3.3/992-mpcore_wdt_fix_watchdog_counter_loading.patch create mode 100644 target/linux/generic/patches-3.3/993-mpcore_wdt_fix_wdioc_setoptions_handling.patch create mode 100644 target/linux/generic/patches-3.3/994-mpcore_wdt_fix_timer_mode_setup.patch create mode 100644 target/linux/goldfish/Makefile create mode 100644 target/linux/goldfish/config-2.6.30 create mode 100644 target/linux/goldfish/image/Makefile create mode 100644 target/linux/goldfish/image/run-emulator.sh create mode 100644 target/linux/goldfish/image/ubinize.cfg create mode 100644 target/linux/goldfish/patches-2.6.30/0042-ARM-Make-low-level-printk-work.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0052-lowmemorykiller-Only-iterate-over-process-list-when.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0053-lowmemorykiller-Don-t-count-free-space-unless-it-me.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0054-timed_gpio-Separate-timed_output-class-into-a-separ.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0055-mm-Add-min_free_order_shift-tunable.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0056-mm-Check-if-any-page-in-a-pageblock-is-reserved-bef.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0058-sched-Enable-might_sleep-before-initializing-driver.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0060--ARM-Add-code-to-prevent-system-calls-from-being-re.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0061--ARM-Save-thread-registers-in-coredumps.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0064-PM-Add-wake-lock-api.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0065-PM-Add-early-suspend-api.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0066-PM-Implement-wakelock-api.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0067-PM-Implement-early-suspend-api.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0068-PM-Enable-early-suspend-through-sys-power-state.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0069-PM-Add-user-space-wake-lock-api.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0070-PM-wakelock-Abort-task-freezing-if-a-wake-lock-is.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0071-PM-earlysuspend-Add-console-switch-when-user-reque.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0072-PM-earlysuspend-Removing-dependence-on-console.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0081-net-socket-ioctl-to-reset-connections-matching-loca.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0082-sysfs_net_ipv4-Add-sysfs-based-knobs-for-controllin.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0086-Input-Generic-GPIO-Input-device.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0087-Input-Hold-wake-lock-while-event-queue-is-not-empty.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0088-Input-Use-monotonic-time-for-event-time-stamps.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0090-input-Add-keyreset-driver.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0093-mmc-Add-status-IRQ-and-status-callback-function-to.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0094-mmc-sd-Add-new-CONFIG_MMC_PARANOID_SD_INIT-for-ena.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0095-mmc-Add-concept-of-an-embedded-SDIO-device.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0097-mmc-Add-new-API-call-sdio_reset_comm-for-resettin.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0098-mmc-sd-When-resuming-try-a-little-harder-to-init.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0099-mmc-mmcblk-Add-new-feature-CONFIG_MMC_BLOCK_PARAN.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0100-mmc-sd-Add-retries-in-re-detection.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0101-android_usb-Composite-USB-gadget-driver-for-android.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0105-block-block_dump-Add-number-of-sectors-to-debug-ou.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0108-mmc-sd-Remove-debugging-printk.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0109-Revert-printk-remove-unused-code-from-kernel-print.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0110-printk-Fix-log_buf_copy-termination.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0118--ARM-goldfish-Add-goldfish-platform.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0120--ARM-goldfish-Add-audio-driver-for-goldfish.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0121--ARM-goldfish-Implement-suspend-as-wait-for-interr.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0122--ARM-goldfish-tty-Adding-tty-driver-for-goldfish.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0123--ARM-goldfish-events-Add-event-driver-for-goldfis.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0124--ARM-goldfish-mmc-goldfish-MMC-driver-building-an.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0125--ARM-goldfish-NAND-Add-nand-driver-for-goldfish.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0126--ARM-goldfish-POWER-New-power-supply-driver-for-g.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0127--ARM-goldfish-RTC-Add-RTC-driver-for-goldfish.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0128--ARM-goldfish-fb-Add-fb-driver-for-goldfish.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0129--ARM-goldfish-qemutrace-Kernel-instrumentation-fo.patch create mode 100644 target/linux/goldfish/patches-2.6.30/0133--ARM-goldfish-qemutrace-Add-mmap-support.patch create mode 100644 target/linux/goldfish/patches-2.6.30/1000-nand_driver_fixes.patch create mode 100644 target/linux/imx21/Makefile create mode 100644 target/linux/imx21/config-default create mode 100644 target/linux/imx21/files/arch/arm/mach-mx2/mach-vp6500.c create mode 100644 target/linux/imx21/files/arch/arm/plat-mxc/include/mach/board-vp6500.h create mode 100644 target/linux/imx21/image/Makefile create mode 100644 target/linux/imx21/patches/010-mach-vp6500.patch create mode 100644 target/linux/imx21/patches/011-mach-type.patch create mode 100644 target/linux/imx21/patches/040-pwm.patch create mode 100644 target/linux/iop32x/Makefile create mode 100644 target/linux/iop32x/base-files/etc/config/network create mode 100644 target/linux/iop32x/config-3.3 create mode 100644 target/linux/iop32x/image/Makefile create mode 100644 target/linux/iop32x/patches-3.3/001-ARM-Fix-missing-linux-types.h-inclusion-in-asm-hardw.patch create mode 100644 target/linux/iop32x/patches-3.3/002-Disintegrate-asm-system.h-for-ARM.patch create mode 100644 target/linux/iop32x/patches-3.3/003-plat-iop-fix-section-mismatch.patch create mode 100644 target/linux/ixp4xx/Makefile create mode 100644 target/linux/ixp4xx/base-files/lib/preinit/05_set_ether_mac_ixp4xx create mode 100644 target/linux/ixp4xx/config-3.3 create mode 100644 target/linux/ixp4xx/generic/profiles/100-Default.mk create mode 100644 target/linux/ixp4xx/generic/profiles/105-Atheros-ath5k.mk create mode 100644 target/linux/ixp4xx/generic/profiles/200-NSLU2.mk create mode 100644 target/linux/ixp4xx/generic/profiles/300-NAS100d.mk create mode 100644 target/linux/ixp4xx/generic/profiles/400-DSMG600RevA.mk create mode 100644 target/linux/ixp4xx/generic/profiles/500-USR8200.mk create mode 100644 target/linux/ixp4xx/generic/target.mk create mode 100644 target/linux/ixp4xx/harddisk/config-default create mode 100644 target/linux/ixp4xx/harddisk/profiles/100-FSG3.mk create mode 100644 target/linux/ixp4xx/harddisk/target.mk create mode 100644 target/linux/ixp4xx/image/Makefile create mode 100644 target/linux/ixp4xx/modules.mk create mode 100644 target/linux/ixp4xx/patches-3.3/020-gateworks_i2c_pld.patch create mode 100644 target/linux/ixp4xx/patches-3.3/090-increase_entropy_pools.patch create mode 100644 target/linux/ixp4xx/patches-3.3/100-wg302v2_gateway7001_mac_plat_info.patch create mode 100644 target/linux/ixp4xx/patches-3.3/105-wg302v1_support.patch create mode 100644 target/linux/ixp4xx/patches-3.3/110-pronghorn_series_support.patch create mode 100644 target/linux/ixp4xx/patches-3.3/111-pronghorn_swap_uarts.patch create mode 100644 target/linux/ixp4xx/patches-3.3/115-sidewinder_support.patch create mode 100644 target/linux/ixp4xx/patches-3.3/116-sidewinder_fis_location.patch create mode 100644 target/linux/ixp4xx/patches-3.3/120-compex_support.patch create mode 100644 target/linux/ixp4xx/patches-3.3/130-wrt300nv2_support.patch create mode 100644 target/linux/ixp4xx/patches-3.3/131-wrt300nv2_mac_plat_info.patch create mode 100644 target/linux/ixp4xx/patches-3.3/132-wrt300nv2_mac_fix.patch create mode 100644 target/linux/ixp4xx/patches-3.3/150-lanready_ap1000_support.patch create mode 100644 target/linux/ixp4xx/patches-3.3/151-lanready_ap1000_mac_plat_info.patch create mode 100644 target/linux/ixp4xx/patches-3.3/162-wg302v1_mem_fixup.patch create mode 100644 target/linux/ixp4xx/patches-3.3/170-ixdpg425_mac_plat_info.patch create mode 100644 target/linux/ixp4xx/patches-3.3/180-tw5334_support.patch create mode 100644 target/linux/ixp4xx/patches-3.3/185-mi424wr_support.patch create mode 100644 target/linux/ixp4xx/patches-3.3/190-cambria_support.patch create mode 100644 target/linux/ixp4xx/patches-3.3/191-cambria_optional_uart.patch create mode 100644 target/linux/ixp4xx/patches-3.3/192-cambria_gpio_device.patch create mode 100644 target/linux/ixp4xx/patches-3.3/193-cambria_pld_gpio.patch create mode 100644 target/linux/ixp4xx/patches-3.3/201-npe_driver_print_license_location.patch create mode 100644 target/linux/ixp4xx/patches-3.3/203-npe_driver_mask_phy_features.patch create mode 100644 target/linux/ixp4xx/patches-3.3/205-npe_driver_separate_phy_functions.patch create mode 100644 target/linux/ixp4xx/patches-3.3/206-npe_driver_add_update_link_function.patch create mode 100644 target/linux/ixp4xx/patches-3.3/207-npe_driver_multiphy_support.patch create mode 100644 target/linux/ixp4xx/patches-3.3/295-latch_led_driver.patch create mode 100644 target/linux/ixp4xx/patches-3.3/300-avila_fetch_mac.patch create mode 100644 target/linux/ixp4xx/patches-3.3/301-avila_led.patch create mode 100644 target/linux/ixp4xx/patches-3.3/302-avila_gpio_device.patch create mode 100644 target/linux/ixp4xx/patches-3.3/304-ixp4xx_eth_jumboframe.patch create mode 100644 target/linux/ixp4xx/patches-3.3/310-gtwx5717_spi_bus.patch create mode 100644 target/linux/ixp4xx/patches-3.3/311-gtwx5717_mac_plat_info.patch create mode 100644 target/linux/ixp4xx/patches-3.3/312-ixp4xx_pata_optimization.patch create mode 100644 target/linux/ixp4xx/patches-3.3/402-ixp4xx_gpiolib.patch create mode 100644 target/linux/ixp4xx/patches-3.3/500-usr8200_support.patch create mode 100644 target/linux/ixp4xx/patches-3.3/520-tw2662_support.patch create mode 100644 target/linux/ixp4xx/patches-3.3/600-skb_avoid_dmabounce.patch create mode 100644 target/linux/ixp4xx/patches-3.3/900-ixp4xx-crypto-include-module.h.patch create mode 100644 target/linux/kirkwood/Makefile create mode 100644 target/linux/kirkwood/base-files.mk create mode 100644 target/linux/kirkwood/base-files/etc/uci-defaults/leds create mode 100644 target/linux/kirkwood/base-files/etc/uci-defaults/network create mode 100644 target/linux/kirkwood/base-files/lib/kirkwood.sh create mode 100644 target/linux/kirkwood/config-3.3 create mode 100644 target/linux/kirkwood/files/arch/arm/mach-kirkwood/goflexhome-setup.c create mode 100644 target/linux/kirkwood/files/arch/arm/mach-kirkwood/goflexnet-setup.c create mode 100644 target/linux/kirkwood/files/arch/arm/mach-kirkwood/iconnect-setup.c create mode 100644 target/linux/kirkwood/files/arch/arm/mach-kirkwood/nas6210-setup.c create mode 100644 target/linux/kirkwood/files/arch/arm/mach-kirkwood/nsa-310-setup.c create mode 100644 target/linux/kirkwood/image/Makefile create mode 100644 target/linux/kirkwood/patches/000-boards.patch create mode 100644 target/linux/kirkwood/patches/001-partition_map.patch create mode 100644 target/linux/kirkwood/patches/002-mvsdio_delay.patch create mode 100644 target/linux/lantiq/Makefile create mode 100644 target/linux/lantiq/ar9/config-default create mode 100644 target/linux/lantiq/ar9/profiles/000-generic.mk create mode 100644 target/linux/lantiq/ar9/profiles/001-lantiq.mk create mode 100644 target/linux/lantiq/ar9/profiles/002-netgear.mk create mode 100644 target/linux/lantiq/ar9/profiles/003-buffalo.mk create mode 100644 target/linux/lantiq/ar9/profiles/004-avm.mk create mode 100644 target/linux/lantiq/ar9/profiles/005-zyxel.mk create mode 100644 target/linux/lantiq/ar9/profiles/006-zte.mk create mode 100644 target/linux/lantiq/ar9/target.mk create mode 100644 target/linux/lantiq/ase/config-default create mode 100644 target/linux/lantiq/ase/profiles/000-generic.mk create mode 100644 target/linux/lantiq/ase/profiles/001-lantiq.mk create mode 100644 target/linux/lantiq/ase/target.mk create mode 100644 target/linux/lantiq/base-files.mk create mode 100644 target/linux/lantiq/base-files/etc/hotplug.d/button/10-generic.sh create mode 100644 target/linux/lantiq/base-files/etc/hotplug.d/firmware/10-rt2x00-eeprom create mode 100644 target/linux/lantiq/base-files/etc/inittab create mode 100755 target/linux/lantiq/base-files/etc/uci-defaults/leds create mode 100755 target/linux/lantiq/base-files/etc/uci-defaults/network create mode 100644 target/linux/lantiq/base-files/lib/lantiq.sh create mode 100644 target/linux/lantiq/base-files/lib/preinit/42_athfix create mode 100755 target/linux/lantiq/base-files/lib/upgrade/platform.sh create mode 100644 target/linux/lantiq/config-3.3 create mode 100644 target/linux/lantiq/danube/config-default create mode 100644 target/linux/lantiq/danube/profiles/000-generic.mk create mode 100644 target/linux/lantiq/danube/profiles/001-lantiq.mk create mode 100644 target/linux/lantiq/danube/profiles/002-arcadyan.mk create mode 100644 target/linux/lantiq/danube/profiles/003-gigaset.mk create mode 100644 target/linux/lantiq/danube/profiles/004-bt.mk create mode 100644 target/linux/lantiq/danube/target.mk create mode 100644 target/linux/lantiq/falcon/config-default create mode 100644 target/linux/lantiq/falcon/profiles/000-generic.mk create mode 100644 target/linux/lantiq/falcon/profiles/001-lantiq.mk create mode 100644 target/linux/lantiq/falcon/target.mk create mode 100644 target/linux/lantiq/files/arch/mips/configs/ase_defconfig create mode 100644 target/linux/lantiq/files/arch/mips/configs/falcon_defconfig create mode 100644 target/linux/lantiq/files/arch/mips/configs/xway_defconfig create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/clkdev.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/dev-gpio-buttons.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/dev-gpio-leds.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/falcon/irq.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/lantiq_timer.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/base_reg.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/boot_reg.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/dma_reg.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/ebu_reg.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/es_reg.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/irq.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/lantiq_soc.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/mps_reg.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/port_reg.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/ssc_reg.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/status_reg.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/svip_dma.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/svip_irq.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/svip_mux.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/svip_pms.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/sys0_reg.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/sys1_reg.h create mode 100644 target/linux/lantiq/files/arch/mips/include/asm/mach-lantiq/svip/sys2_reg.h create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/dev-gpio-buttons.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/dev-gpio-leds.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/falcon/Kconfig create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/falcon/Makefile create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/falcon/addon-easy98000.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/falcon/dev-leds-easy98000-cpld.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/falcon/dev-leds-easy98000-cpld.h create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/falcon/devices.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/falcon/devices.h create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/falcon/gpio.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/falcon/mach-95C3AM1.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/falcon/mach-easy98000.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/falcon/mach-easy98020.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/falcon/prom.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/falcon/reset.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/falcon/sysctrl.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/svip/Kconfig create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/svip/Makefile create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/svip/clk-svip.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/svip/devices.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/svip/devices.h create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/svip/dma.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/svip/gpio.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/svip/mach-easy33016.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/svip/mach-easy336.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/svip/mux.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/svip/pms.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/svip/prom.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/svip/reset.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/svip/switchip_setup.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/clk.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/dev-dwc_otg.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/dev-dwc_otg.h create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/dev-ifxhcd.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/dev-ifxhcd.h create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/dev-wifi-athxk.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/dev-wifi-athxk.h create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/dev-wifi-rt2x00.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/dev-wifi-rt2x00.h create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/gptu.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/mach-arv.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/mach-bthomehubv2b.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/mach-fritz_ar9.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/mach-fritz_vr9.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/mach-gigasx76x.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/mach-gigasx76x.h create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/mach-h201l.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/mach-netgear.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/mach-p2601hnfx.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/mach-wbmr.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/nand.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/pci-ath-fixup.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/pci-ath-fixup.h create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/prom.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/sysctrl.c create mode 100644 target/linux/lantiq/files/arch/mips/lantiq/xway/timer.c create mode 100644 target/linux/lantiq/files/arch/mips/pci/fixup-lantiq-pcie.c create mode 100644 target/linux/lantiq/files/arch/mips/pci/fixup-lantiq.c create mode 100644 target/linux/lantiq/files/arch/mips/pci/pcie-lantiq-msi.c create mode 100644 target/linux/lantiq/files/arch/mips/pci/pcie-lantiq-phy.c create mode 100644 target/linux/lantiq/files/arch/mips/pci/pcie-lantiq.c create mode 100644 target/linux/lantiq/files/arch/mips/pci/pcie-lantiq.h create mode 100644 target/linux/lantiq/files/drivers/i2c/busses/i2c-falcon.c create mode 100644 target/linux/lantiq/files/drivers/net/ethernet/lantiq_vrx200.c create mode 100644 target/linux/lantiq/files/drivers/net/ethernet/svip_eth.c create mode 100644 target/linux/lantiq/files/drivers/net/ethernet/svip_virtual_eth.c create mode 100644 target/linux/lantiq/files/drivers/spi/spi-falcon.c create mode 100644 target/linux/lantiq/files/drivers/spi/spi-xway.c create mode 100644 target/linux/lantiq/files/drivers/spi/spi_svip.c create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/Kconfig create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/Makefile create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_attr.c create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_attr.h create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_cil.c create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_cil.h create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_cil_ifx.h create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_cil_intr.c create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_driver.c create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_driver.h create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_hcd.c create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_hcd.h create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_ifx.c create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_ifx.h create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_plat.h create mode 100644 target/linux/lantiq/files/drivers/usb/dwc_otg/dwc_otg_regs.h create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/Kconfig create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/Makefile create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/TagHistory create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/ifxhcd.c create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/ifxhcd.h create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/ifxhcd_es.c create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/ifxhcd_intr.c create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/ifxhcd_queue.c create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/ifxusb_cif.c create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/ifxusb_cif.h create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/ifxusb_cif_d.c create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/ifxusb_cif_h.c create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/ifxusb_ctl.c create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/ifxusb_driver.c create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/ifxusb_plat.h create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/ifxusb_regs.h create mode 100644 target/linux/lantiq/files/drivers/usb/ifxhcd/ifxusb_version.h create mode 100644 target/linux/lantiq/files/include/linux/svip_nat.h create mode 100644 target/linux/lantiq/files/include/linux/svip_nat_io.h create mode 100644 target/linux/lantiq/files/net/ipv4/svip_nat.c create mode 100644 target/linux/lantiq/image/Makefile create mode 100644 target/linux/lantiq/image/eva.dummy.squashfs create mode 100644 target/linux/lantiq/modules.mk create mode 100644 target/linux/lantiq/patches-3.3/0001-falcon-support.patch create mode 100644 target/linux/lantiq/patches-3.3/0002-xway-support.patch create mode 100644 target/linux/lantiq/patches-3.3/0003-svip-hack.patch create mode 100644 target/linux/lantiq/patches-3.3/0004-lantiq-core-support.patch create mode 100644 target/linux/lantiq/patches-3.3/0005-pci-support.patch create mode 100644 target/linux/lantiq/patches-3.3/0006-mtd-support.patch create mode 100644 target/linux/lantiq/patches-3.3/0007-usb-support.patch create mode 100644 target/linux/lantiq/patches-3.3/0008-spi-support.patch create mode 100644 target/linux/lantiq/patches-3.3/0009-ethernet-support.patch create mode 100644 target/linux/lantiq/patches-3.3/0010-watchdog-support.patch create mode 100644 target/linux/lantiq/patches-3.3/0011-i2c-support.patch create mode 100644 target/linux/lantiq/patches-3.3/0012-tty-support.patch create mode 100644 target/linux/lantiq/patches-3.3/0013-machtype-support.patch create mode 100644 target/linux/lantiq/patches-3.3/0014-import-compat-headers.patch create mode 100644 target/linux/lantiq/patches-3.3/0015-VPE-extensions.patch create mode 100644 target/linux/lantiq/patches-3.3/0016-falcon-VPE-softdog.patch create mode 100644 target/linux/lantiq/patches-3.3/0017-udp-in-kernel-redirect.patch create mode 100644 target/linux/lantiq/patches-3.3/0018-cache-split.patch create mode 100644 target/linux/lantiq/patches-3.3/0019-owrt-mtd-split.patch create mode 100644 target/linux/lantiq/patches-3.3/0020-owrt-atm.patch create mode 100644 target/linux/lantiq/patches-3.3/0021-owrt-cmdline.patch create mode 100644 target/linux/lantiq/patches-3.3/0022-owrt-dm9000-polling.patch create mode 100644 target/linux/lantiq/patches-3.3/0023-owrt-gpio-export.patch create mode 100644 target/linux/lantiq/patches-3.3/0024-fritzbox-ram.patch create mode 100644 target/linux/lantiq/patches-3.3/0025-svip-cp1.patch create mode 100644 target/linux/lantiq/svip_be/config-default create mode 100644 target/linux/lantiq/svip_be/profiles/000-generic.mk create mode 100644 target/linux/lantiq/svip_be/profiles/001-lantiq.mk create mode 100644 target/linux/lantiq/svip_be/target.mk create mode 100644 target/linux/lantiq/svip_le/config-default create mode 100644 target/linux/lantiq/svip_le/profiles/000-generic.mk create mode 100644 target/linux/lantiq/svip_le/profiles/001-lantiq.mk create mode 100644 target/linux/lantiq/svip_le/target.mk create mode 100644 target/linux/lantiq/vr9/config-default create mode 100644 target/linux/lantiq/vr9/profiles/000-generic.mk create mode 100644 target/linux/lantiq/vr9/profiles/001-avm.mk create mode 100644 target/linux/lantiq/vr9/target.mk create mode 100644 target/linux/leon/Makefile create mode 100644 target/linux/leon/config-default create mode 100644 target/linux/leon/image/Makefile create mode 100644 target/linux/leon/patches/001-find_irq_and_timer_via_of.patch create mode 100644 target/linux/leon/patches/002-sparc_uimage_target.patch create mode 100644 target/linux/leon/patches/003-smp_cpu_stuck_fix.patch create mode 100644 target/linux/leon/patches/004-extended_irq_controller.patch create mode 100644 target/linux/leon/patches/005-avoid_openprom_duplicates.patch create mode 100644 target/linux/leon/patches/006-amp_support.patch create mode 100644 target/linux/leon/patches/007-amp_timer.patch create mode 100644 target/linux/leon/patches/008-hz_specific_timer_init.patch create mode 100644 target/linux/leon/patches/009-remove_second_timer.patch create mode 100644 target/linux/leon/patches/010-apbuart_ampopts.patch create mode 100644 target/linux/leon/patches/011-greth_fix_unhandled_irq.patch create mode 100644 target/linux/leon/patches/012-greth_amba_vendor_device.patch create mode 100644 target/linux/leon/patches/013-apbuart_amba_vendor_device.patch create mode 100644 target/linux/leon/patches/014-timer_irqctrl_amba_vendor_device.patch create mode 100644 target/linux/leon/patches/015-dma_ops.patch create mode 100644 target/linux/leon/patches/016-ioport_update.patch create mode 100644 target/linux/leon/patches/017-greth_no_gbit.patch create mode 100644 target/linux/leon/patches/018-greth_compat_mode.patch create mode 100644 target/linux/leon/patches/019-greth_fix_open_close.patch create mode 100644 target/linux/leon/patches/020-greth_optimize_gbit_tx_descriptor_handling.patch create mode 100644 target/linux/leon/patches/021-greth_fix_memory_leak.patch create mode 100644 target/linux/leon/patches/022-greth_avoid_bad_speed_duplex.patch create mode 100644 target/linux/leon/patches/023-greth_handle_frame_error_interrupts.patch create mode 100644 target/linux/leon/patches/024-greth_resolve_smp_and_other_issues.patch create mode 100644 target/linux/leon/patches/025-greth_bootloader_disable_device_node.patch create mode 100644 target/linux/leon/patches/026-greth_gbit_mac_set_ee_when_edcl.patch create mode 100644 target/linux/leon/patches/027-sparc_v8_assembler.patch create mode 100644 target/linux/malta/Makefile create mode 100644 target/linux/malta/README create mode 100644 target/linux/malta/base-files/etc/inittab create mode 100644 target/linux/malta/be/config-default create mode 100644 target/linux/malta/be/target.mk create mode 100644 target/linux/malta/config-3.3 create mode 100644 target/linux/malta/image/Makefile create mode 100644 target/linux/malta/le/target.mk create mode 100644 target/linux/malta/patches-3.3/001-remove_unused_perf_function.patch create mode 100644 target/linux/mcs814x/Makefile create mode 100644 target/linux/mcs814x/base-files/etc/config/network create mode 100644 target/linux/mcs814x/base-files/etc/uci-defaults/leds create mode 100644 target/linux/mcs814x/base-files/lib/mcs814x.sh create mode 100755 target/linux/mcs814x/base-files/lib/preinit/03_preinit_do_mcs814x.sh create mode 100644 target/linux/mcs814x/config-default create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/boot/dts/dlan-usb-extender.dts create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/boot/dts/mcs8140.dtsi create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/boot/dts/rbt-832.dts create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/Kconfig create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/Makefile create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/Makefile.boot create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/board-mcs8140-dt.c create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/clock.c create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/common.c create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/common.h create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/cpu.h create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/debug-macro.S create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/entry-macro.S create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/gpio.h create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/hardware.h create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/io.h create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/irqs.h create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/mcs814x.h create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/memory.h create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/param.h create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/system.h create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/timex.h create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/include/mach/uncompress.h create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/irq.c create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/pci.c create mode 100644 target/linux/mcs814x/files-3.3/arch/arm/mach-mcs814x/timer.c create mode 100644 target/linux/mcs814x/files-3.3/drivers/char/hw_random/mcs814x-rng.c create mode 100644 target/linux/mcs814x/files-3.3/drivers/gpio/gpio-mcs814x.c create mode 100644 target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/Kconfig create mode 100644 target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/Makefile create mode 100644 target/linux/mcs814x/files-3.3/drivers/net/ethernet/mcs8140/nuport_mac.c create mode 100644 target/linux/mcs814x/files-3.3/drivers/net/phy/mcs814x.c create mode 100644 target/linux/mcs814x/files-3.3/drivers/usb/host/ehci-mcs814x.c create mode 100644 target/linux/mcs814x/files-3.3/drivers/usb/host/ohci-mcs814x.c create mode 100644 target/linux/mcs814x/files-3.3/drivers/watchdog/mcs814x_wdt.c create mode 100644 target/linux/mcs814x/image/Makefile create mode 100644 target/linux/mcs814x/modules.mk create mode 100644 target/linux/mcs814x/patches-3.3/001-platform.patch create mode 100644 target/linux/mcs814x/patches-3.3/003-ethernet.patch create mode 100644 target/linux/mcs814x/patches-3.3/004-usb.patch create mode 100644 target/linux/mcs814x/patches-3.3/005-mcs814x_rng.patch create mode 100644 target/linux/mcs814x/patches-3.3/006-mcs814x_wdt.patch create mode 100644 target/linux/mcs814x/patches-3.3/008-mcs814x_gpio.patch create mode 100644 target/linux/mcs814x/patches-3.3/010-fdt_config_cmdline_extend.patch create mode 100644 target/linux/mcs814x/patches-3.3/011-mcs814x_internal_phy.patch create mode 100644 target/linux/mcs814x/patches-3.3/012-mtd-cfi_cmdset_0002-force-word-write.patch create mode 100644 target/linux/mcs814x/patches-3.3/013-ohci_workarounds.patch create mode 100644 target/linux/mcs814x/profiles/000-Generic.mk create mode 100644 target/linux/mcs814x/profiles/100-dLAN-USB-Extender.mk create mode 100644 target/linux/mpc52xx/Makefile create mode 100644 target/linux/mpc52xx/base-files/etc/inittab create mode 100644 target/linux/mpc52xx/config-3.3 create mode 100644 target/linux/mpc52xx/image/Makefile create mode 100644 target/linux/mpc83xx/Makefile create mode 100644 target/linux/mpc83xx/base-files.mk create mode 100644 target/linux/mpc83xx/base-files/etc/inittab create mode 100755 target/linux/mpc83xx/base-files/etc/uci-defaults/network create mode 100755 target/linux/mpc83xx/base-files/lib/mpc83xx.sh create mode 100644 target/linux/mpc83xx/base-files/lib/preinit/03_preinit_do_mpc83xx.sh create mode 100644 target/linux/mpc83xx/config-3.3 create mode 100755 target/linux/mpc83xx/files/scripts/mkits.sh create mode 100644 target/linux/mpc83xx/image/Makefile create mode 100644 target/linux/mpc83xx/patches-3.3/100-powerpc_create_fit_uImages.patch create mode 100644 target/linux/mpc83xx/patches-3.3/101-mpc8377_wlan-dts-add-gpio-leds.patch create mode 100644 target/linux/mpc83xx/patches-3.3/110-vitesse_8601.patch create mode 100644 target/linux/mpc83xx/patches-3.3/111-etsec27_war.patch create mode 100644 target/linux/mpc83xx/patches-3.3/120-ucc_tdm.patch create mode 100644 target/linux/mpc83xx/patches-3.3/200-powerpc-add-rbppc-support.patch create mode 100644 target/linux/mpc83xx/patches-3.3/201-powerpc-add-rb_iomap.patch create mode 100644 target/linux/mpc83xx/patches-3.3/202-ata-add-pata_rbppc_cf-driver.patch create mode 100644 target/linux/mpc83xx/patches-3.3/203-mtd-add-rbppc_nand-driver.patch create mode 100644 target/linux/mpc83xx/patches-3.3/300-mpc8377_wlan-dts-add-openwrt-hacks.patch create mode 100644 target/linux/mpc85xx/Makefile create mode 100644 target/linux/mpc85xx/config-3.3 create mode 100644 target/linux/mpc85xx/image/Makefile create mode 100644 target/linux/mpc85xx/patches-3.3/100-fix_mpc8568e_mds.patch create mode 100644 target/linux/mpc85xx/patches-3.3/110-fix_mpc8548_cds.patch create mode 100644 target/linux/mpc85xx/patches-3.3/120-mpc8548_cds_i8259_noirq_init.patch create mode 100644 target/linux/mpc85xx/patches-3.3/130-mpc8548_cds_disable_i8259_irq.patch create mode 100644 target/linux/octeon/Makefile create mode 100644 target/linux/octeon/base-files/etc/config/network create mode 100644 target/linux/octeon/config-default create mode 100644 target/linux/octeon/config/profile-mototech create mode 100644 target/linux/octeon/image/Makefile create mode 100644 target/linux/octeon/modules.mk create mode 100644 target/linux/octeon/patches/001-wndap330_hacks.patch create mode 100644 target/linux/octeon/patches/002-nb5_fixup.patch create mode 100644 target/linux/octeon/profiles/000-Generic.mk create mode 100644 target/linux/octeon/profiles/100-Mototech.mk create mode 100644 target/linux/omap24xx/Makefile create mode 100644 target/linux/omap24xx/base-files/etc/config/fstab create mode 100644 target/linux/omap24xx/base-files/etc/config/network create mode 100644 target/linux/omap24xx/base-files/etc/config/wireless create mode 100644 target/linux/omap24xx/base-files/etc/hotplug.d/firmware/10-bme-pmm-image create mode 100644 target/linux/omap24xx/base-files/etc/hotplug.d/firmware/20-p54spi-eeprom create mode 100755 target/linux/omap24xx/base-files/etc/init.d/watchdog create mode 100644 target/linux/omap24xx/base-files/etc/inittab create mode 100644 target/linux/omap24xx/base-files/etc/pointercal create mode 100644 target/linux/omap24xx/base-files/lib/firmware/bc4fw.bin create mode 100644 target/linux/omap24xx/config-3.3 create mode 100644 target/linux/omap24xx/image/Makefile create mode 100644 target/linux/omap24xx/modules.mk create mode 100644 target/linux/omap24xx/patches-3.3/200-omap-platform.patch create mode 100644 target/linux/omap24xx/patches-3.3/250-cbus.patch create mode 100644 target/linux/omap24xx/patches-3.3/251-cbus-tahvo-lock-fix.patch create mode 100644 target/linux/omap24xx/patches-3.3/252-cbus-retu-tahvo-ack-fix.patch create mode 100644 target/linux/omap24xx/patches-3.3/254-cbus-retu-tahvo-irq-mask-init-fix.patch create mode 100644 target/linux/omap24xx/patches-3.3/300-cbus-platform.patch create mode 100644 target/linux/omap24xx/patches-3.3/309-omapfb-circular-mutex-workaround.patch create mode 100644 target/linux/omap24xx/patches-3.3/310-n810-lcd.patch create mode 100644 target/linux/omap24xx/patches-3.3/311-omapfb-clock-fixes.patch create mode 100644 target/linux/omap24xx/patches-3.3/312-no-hwmod-reset.patch create mode 100644 target/linux/omap24xx/patches-3.3/315-n800-touchscreen-and-keypad-drivers.patch create mode 100644 target/linux/omap24xx/patches-3.3/320-nokia-various.patch create mode 100644 target/linux/omap24xx/patches-3.3/330-n800-tsc2301-platform.patch create mode 100644 target/linux/omap24xx/patches-3.3/350-n8x0-gpioswitch-input.patch create mode 100644 target/linux/omap24xx/patches-3.3/400-bluetooth-hci_h4p.patch create mode 100644 target/linux/omap24xx/patches-3.3/410-hci-h4p-fixes.patch create mode 100644 target/linux/omap24xx/patches-3.3/420-hci-h4p-interrupt-workaround.patch create mode 100644 target/linux/omap24xx/patches-3.3/597-cbus-tahvo-usb-platform.patch create mode 100644 target/linux/omap24xx/patches-3.3/710-evdev-events-without-grab.patch create mode 100644 target/linux/omap24xx/patches-3.3/810-mmc-fixes.patch create mode 100644 target/linux/omap24xx/patches-3.3/830-omap2-serial-fixes.patch create mode 100644 target/linux/omap24xx/patches-3.3/850-musb-tusb-modular-fixes.patch create mode 100644 target/linux/omap24xx/patches-3.3/900-n810-battery-management.patch create mode 100644 target/linux/omap24xx/patches-3.3/910-omap-fix-section-mismatch-warnings.patch create mode 100644 target/linux/omap24xx/profiles/100-n810.mk create mode 100644 target/linux/omap24xx/profiles/110-n810-gui.mk create mode 100644 target/linux/omap35xx/Makefile create mode 100644 target/linux/omap35xx/beagleboard/base-files/etc/config/network create mode 100644 target/linux/omap35xx/beagleboard/base-files/etc/inittab create mode 100644 target/linux/omap35xx/beagleboard/profiles/beagleboard.mk create mode 100644 target/linux/omap35xx/beagleboard/target.mk create mode 100644 target/linux/omap35xx/config-2.6.32 create mode 100644 target/linux/omap35xx/files/boot-mmc.cmd create mode 100644 target/linux/omap35xx/gumstix/base-files/etc/config/network create mode 100644 target/linux/omap35xx/gumstix/base-files/etc/fw_env.config create mode 100644 target/linux/omap35xx/gumstix/base-files/etc/inittab create mode 100644 target/linux/omap35xx/gumstix/base-files/lib/preinit/95_ttyS1_noecho create mode 100644 target/linux/omap35xx/gumstix/config-2.6.36 create mode 100644 target/linux/omap35xx/gumstix/config-default create mode 100644 target/linux/omap35xx/gumstix/defconfig.es create mode 100644 target/linux/omap35xx/gumstix/defconfig.gumstix create mode 100644 target/linux/omap35xx/gumstix/defconfig.vpp create mode 100644 target/linux/omap35xx/gumstix/profiles/000-hegw.mk create mode 100644 target/linux/omap35xx/gumstix/profiles/001-vpp.mk create mode 100644 target/linux/omap35xx/gumstix/profiles/002-es.mk create mode 100644 target/linux/omap35xx/gumstix/target.mk create mode 100644 target/linux/omap35xx/image/Makefile create mode 100755 target/linux/omap35xx/image/gen_image.sh create mode 100644 target/linux/omap35xx/image/ubinize.cfg create mode 100644 target/linux/omap35xx/patches-2.6.32/001-DSS2.patch create mode 100644 target/linux/omap35xx/patches-2.6.32/002-OMAP.patch create mode 100644 target/linux/omap35xx/patches-2.6.32/003-enable_dss2_beagleboard.patch create mode 100644 target/linux/omap35xx/patches-2.6.32/004-compile_fix_dispc.patch create mode 100644 target/linux/omap35xx/patches-2.6.36/001-expose_omap3_die_id.patch create mode 100644 target/linux/omap35xx/patches-2.6.36/002-omap-nand-remove-hardware-ECC-as-default.patch create mode 100644 target/linux/omap35xx/patches-2.6.36/003-change_partition_table.patch create mode 100644 target/linux/omap35xx/patches-2.6.36/004-nand_subpage_align.patch create mode 100644 target/linux/omap35xx/patches-2.6.36/005-add_cti_usbids.patch create mode 100644 target/linux/omap35xx/patches-3.0/001-change_partition_table.patch create mode 100644 target/linux/omap35xx/patches-3.0/002-fix_twl_rtc.patch create mode 100644 target/linux/omap4/Makefile create mode 100644 target/linux/omap4/base-files/etc/inittab create mode 100644 target/linux/omap4/config-default create mode 100644 target/linux/omap4/image/Makefile create mode 100644 target/linux/omap4/image/boot.script create mode 100644 target/linux/omap4/patches/001-omap4_pandaboard-wlan_fix.patch create mode 100644 target/linux/orion/Makefile create mode 100644 target/linux/orion/base-files/etc/config/network create mode 100644 target/linux/orion/base-files/etc/hotplug.d/usb/10-usb create mode 100644 target/linux/orion/config-3.3 create mode 100644 target/linux/orion/dns323/base-files/etc/config/network create mode 100644 target/linux/orion/dns323/config-3.3 create mode 100644 target/linux/orion/dns323/target.mk create mode 100644 target/linux/orion/files/arch/arm/mach-orion5x/dt2-common.h create mode 100644 target/linux/orion/files/arch/arm/mach-orion5x/dt2-setup.c create mode 100644 target/linux/orion/generic/base-files/etc/uci-defaults/hardware create mode 100644 target/linux/orion/generic/base-files/lib/upgrade/platform.sh create mode 100644 target/linux/orion/generic/target.mk create mode 100644 target/linux/orion/harddisk/config-3.3 create mode 100644 target/linux/orion/harddisk/target.mk create mode 100644 target/linux/orion/image/Makefile create mode 100644 target/linux/orion/image/dns323.mk create mode 100644 target/linux/orion/image/generic.mk create mode 100644 target/linux/orion/image/harddisk.mk create mode 100644 target/linux/orion/patches-3.3/100-wrt350nv2_openwrt_partition_map.patch create mode 100644 target/linux/orion/patches-3.3/101-wnr854t_partition_map.patch create mode 100644 target/linux/orion/patches-3.3/200-dt2_board_support.patch create mode 100644 target/linux/orion/patches-3.3/300-dns323_partition_map.patch create mode 100644 target/linux/orion/patches-3.3/400-fix-section-mismatch-warnings.patch create mode 100644 target/linux/orion/patches-3.3/a01-dt2-fixes-for-3.3.patch create mode 100644 target/linux/ppc40x/Makefile create mode 100755 target/linux/ppc40x/base-files/lib/ppc40x.sh create mode 100644 target/linux/ppc40x/base-files/lib/upgrade/platform.sh create mode 100644 target/linux/ppc40x/config-3.3 create mode 100644 target/linux/ppc40x/image/Makefile create mode 100644 target/linux/ppc40x/modules.mk create mode 100644 target/linux/ppc40x/patches-3.3/003-powerpc-add-EBC_BXCR-defines.patch create mode 100644 target/linux/ppc40x/patches-3.3/004-magicbox.patch create mode 100644 target/linux/ppc40x/patches-3.3/005-openrb.patch create mode 100644 target/linux/ppc40x/patches-3.3/101-pata-magicbox-cf-driver.patch create mode 100644 target/linux/ppc40x/patches-3.3/110-kilauea_openwrt_flashmap.patch create mode 100644 target/linux/ppc40x/patches-3.3/120-usb-isp116x-hcd-add-of-binding.patch create mode 100644 target/linux/ppc40x/patches-3.3/121-usb-isp116x-hcd-ppc405-register-access.patch create mode 100644 target/linux/ppc44x/Makefile create mode 100644 target/linux/ppc44x/base-files/etc/inittab create mode 100644 target/linux/ppc44x/config-3.3 create mode 100644 target/linux/ppc44x/image/Makefile create mode 100644 target/linux/ppc44x/patches-3.3/100-openwrt_flashmap.patch create mode 100644 target/linux/ppc44x/patches-3.3/110-openwrt_dts_cmdline.patch create mode 100644 target/linux/ps3/Makefile create mode 100644 target/linux/ps3/README create mode 100644 target/linux/ps3/config-2.6.30 create mode 100644 target/linux/ps3/image/Makefile create mode 100644 target/linux/ps3/modules.mk create mode 100644 target/linux/ps3/patches-2.6.30/0016-ps3-gelic-fix-rxdmac.patch create mode 100755 target/linux/ps3/petitboot/base-files/bin/login create mode 100644 target/linux/ps3/petitboot/base-files/etc/banner create mode 100644 target/linux/ps3/petitboot/base-files/etc/config/network create mode 100644 target/linux/ps3/petitboot/base-files/etc/config/system create mode 100755 target/linux/ps3/petitboot/base-files/etc/init.d/boot create mode 100644 target/linux/ps3/petitboot/base-files/etc/inittab create mode 100644 target/linux/ps3/petitboot/base-files/etc/sysctl.conf create mode 100755 target/linux/ps3/petitboot/base-files/sbin/initrun create mode 100755 target/linux/ps3/petitboot/base-files/sbin/ps3-bl-option create mode 100644 target/linux/ps3/petitboot/defconfig-ps3-petitboot create mode 100644 target/linux/ps3/petitboot/profiles/000-Default.mk create mode 100644 target/linux/ps3/petitboot/target.mk create mode 100644 target/linux/pxa/Makefile create mode 100644 target/linux/pxa/config-3.3 create mode 100644 target/linux/pxa/image/Makefile create mode 100644 target/linux/pxa/patches-3.3/001-gumstix_verdex_pro_arch_support.patch create mode 100644 target/linux/pxa/patches-3.3/002-verdex_lcd_support.patch create mode 100644 target/linux/pxa/patches-3.3/003-gumstix_h_verdex_pro_support.patch create mode 100644 target/linux/pxa/patches-3.3/004-smsc911x_verdex_pro_support.patch create mode 100644 target/linux/pxa/patches-3.3/005-verdex_pcmcia_support.patch create mode 100644 target/linux/pxa/patches-3.3/a01-arm-debugll-printk.patch create mode 100644 target/linux/pxa/profiles/100-Default.mk create mode 100644 target/linux/pxa/profiles/200-Gumstix.mk create mode 100644 target/linux/pxcab/Makefile create mode 100644 target/linux/pxcab/base-files/lib/preinit/15_essential_fs_pxcab create mode 100644 target/linux/pxcab/base-files/lib/preinit/45_failsafe_pxcab create mode 100644 target/linux/pxcab/config-2.6.30 create mode 100644 target/linux/pxcab/image/Makefile create mode 100644 target/linux/pxcab/modules.mk create mode 100644 target/linux/ramips/Makefile create mode 100644 target/linux/ramips/base-files.mk create mode 100755 target/linux/ramips/base-files/etc/diag.sh create mode 100644 target/linux/ramips/base-files/etc/hotplug.d/firmware/10-rt2x00-eeprom create mode 100644 target/linux/ramips/base-files/etc/inittab create mode 100755 target/linux/ramips/base-files/etc/uci-defaults/leds create mode 100755 target/linux/ramips/base-files/etc/uci-defaults/network create mode 100644 target/linux/ramips/base-files/lib/preinit/03_preinit_do_ramips.sh create mode 100644 target/linux/ramips/base-files/lib/preinit/05_ramips_load-input_drivers create mode 100644 target/linux/ramips/base-files/lib/preinit/06_set_iface_mac create mode 100755 target/linux/ramips/base-files/lib/ramips.sh create mode 100755 target/linux/ramips/base-files/lib/upgrade/platform.sh create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/common.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/dev-gpio-buttons.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/dev-gpio-leds.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/gpio.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/machine.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/ramips_eth_platform.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/ramips_gpio.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/ramips_nand_platform.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x/cpu-feature-overrides.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x/irq.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x_regs.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x/cpu-feature-overrides.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x/irq.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_esw_platform.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt3883.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt3883/cpu-feature-overrides.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt3883/irq.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt3883_ehci_platform.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt3883_ohci_platform.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt3883_regs.h create mode 100644 target/linux/ramips/files/arch/mips/include/asm/mach-ralink/war.h create mode 100644 target/linux/ramips/files/arch/mips/pci/pci-rt288x.c create mode 100644 target/linux/ramips/files/arch/mips/pci/pci-rt3883.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/Kconfig create mode 100644 target/linux/ramips/files/arch/mips/ralink/Platform create mode 100644 target/linux/ramips/files/arch/mips/ralink/common/Makefile create mode 100644 target/linux/ramips/files/arch/mips/ralink/common/dev-gpio-buttons.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/common/dev-gpio-leds.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/common/gpio.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/common/intc.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/common/prom.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/common/setup.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/Kconfig create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/Makefile create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/clock.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/common.h create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/devices.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/devices.h create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/early_printk.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/irq.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/mach-f5d8235-v1.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/mach-rt-n15.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/mach-v11st-fe.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/mach-wli-tx4-ag300n.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/mach-wzr-agl300nh.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/rt288x.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt288x/setup.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/Kconfig create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/Makefile create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/clock.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/common.h create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/devices.h create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/early_printk.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/irq.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-3g-6200n.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-all0256n.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-all5002.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-argus-atp52b.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-bc2.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-carambola.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-dap-1350.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-dir-300-revb.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-dir-615-h1.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-esr-9753.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-f5d8235-v2.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-fonera20n.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-freestation5.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-hw550-3g.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-mofi3500-3gn.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-nbg-419n.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-nw718.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-omni-emb.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-psr-680w.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-pwh2004.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-rt-g32-revb.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-rt-n10-plus.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-sl-r7205.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-ur-336un.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-v22rw-2x2.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-w306r-v20.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-w502u.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-wcr150gn.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-whr-g300n.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-wl-330n.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-wl-330n3g.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-wl341v3.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-wl351.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-wr512-3gn.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-wr6202.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/mach-xdx-rn502j.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/rt305x.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt305x/setup.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt3883/Kconfig create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt3883/Makefile create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt3883/clock.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt3883/common.h create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt3883/devices.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt3883/devices.h create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt3883/early_printk.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt3883/irq.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt3883/mach-rt-n56u.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt3883/rt3883.c create mode 100644 target/linux/ramips/files/arch/mips/ralink/rt3883/setup.c create mode 100644 target/linux/ramips/files/drivers/net/ethernet/ramips/Kconfig create mode 100644 target/linux/ramips/files/drivers/net/ethernet/ramips/Makefile create mode 100644 target/linux/ramips/files/drivers/net/ethernet/ramips/ramips_debugfs.c create mode 100644 target/linux/ramips/files/drivers/net/ethernet/ramips/ramips_esw.c create mode 100644 target/linux/ramips/files/drivers/net/ethernet/ramips/ramips_eth.h create mode 100644 target/linux/ramips/files/drivers/net/ethernet/ramips/ramips_main.c create mode 100644 target/linux/ramips/files/drivers/spi/spi-ramips.c create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/Kconfig create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/Makefile create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dummy_audio.c create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_attr.c create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_attr.h create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_cil.c create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_cil.h create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_cil_intr.c create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_driver.c create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_driver.h create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_hcd.c create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_hcd.h create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_hcd_intr.c create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_hcd_queue.c create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_pcd.c create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_pcd.h create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_pcd_intr.c create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/dwc_otg_regs.h create mode 100644 target/linux/ramips/files/drivers/usb/dwc_otg/linux/dwc_otg_plat.h create mode 100644 target/linux/ramips/files/drivers/usb/host/ehci-rt3883.c create mode 100644 target/linux/ramips/files/drivers/usb/host/ohci-rt3883.c create mode 100644 target/linux/ramips/files/drivers/watchdog/ramips_wdt.c create mode 100644 target/linux/ramips/image/Makefile create mode 100644 target/linux/ramips/modules.mk create mode 100644 target/linux/ramips/patches-3.3/001-mips-add-cp0-compare-irq-function.patch create mode 100644 target/linux/ramips/patches-3.3/010-mtd_fix_cfi_cmdset_0002_erase_status_check.patch create mode 100644 target/linux/ramips/patches-3.3/011-mtd-cfi_cmdset_0002-force-word-write.patch create mode 100644 target/linux/ramips/patches-3.3/100-mips-ralink-core.patch create mode 100644 target/linux/ramips/patches-3.3/101-rt288x_serial_driver_hack.patch create mode 100644 target/linux/ramips/patches-3.3/102-rt288x-pci-driver-hook.patch create mode 100644 target/linux/ramips/patches-3.3/103-ethernet.patch create mode 100644 target/linux/ramips/patches-3.3/104-ramips-watchdog-driver.patch create mode 100644 target/linux/ramips/patches-3.3/105-ramips-spi-driver.patch create mode 100644 target/linux/ramips/patches-3.3/105-usb_dwc_otg.patch create mode 100644 target/linux/ramips/patches-3.3/106-rt3883-pci-support.patch create mode 100644 target/linux/ramips/patches-3.3/200-rt3883-ehci-glue.patch create mode 100644 target/linux/ramips/patches-3.3/201-rt3883-ohci-glue.patch create mode 100644 target/linux/ramips/rt288x/config-3.3 create mode 100644 target/linux/ramips/rt288x/profiles/00-default.mk create mode 100644 target/linux/ramips/rt288x/profiles/asus.mk create mode 100644 target/linux/ramips/rt288x/profiles/belkin.mk create mode 100644 target/linux/ramips/rt288x/target.mk create mode 100644 target/linux/ramips/rt305x/config-3.3 create mode 100644 target/linux/ramips/rt305x/profiles/00-default.mk create mode 100644 target/linux/ramips/rt305x/profiles/allnet.mk create mode 100644 target/linux/ramips/rt305x/profiles/aztech.mk create mode 100644 target/linux/ramips/rt305x/profiles/belkin.mk create mode 100644 target/linux/ramips/rt305x/profiles/engenius.mk create mode 100644 target/linux/ramips/rt305x/profiles/freestation5.mk create mode 100644 target/linux/ramips/rt305x/profiles/tenda.mk create mode 100644 target/linux/ramips/rt305x/profiles/upvel.mk create mode 100644 target/linux/ramips/rt305x/target.mk create mode 100644 target/linux/ramips/rt3883/config-3.3 create mode 100644 target/linux/ramips/rt3883/profiles/00-default.mk create mode 100644 target/linux/ramips/rt3883/profiles/asus.mk create mode 100644 target/linux/ramips/rt3883/target.mk create mode 100644 target/linux/rb532/Makefile create mode 100644 target/linux/rb532/base-files.mk create mode 100644 target/linux/rb532/base-files/etc/config/network create mode 100644 target/linux/rb532/base-files/etc/diag.sh create mode 100755 target/linux/rb532/base-files/sbin/cf2nand create mode 100755 target/linux/rb532/base-files/sbin/wget2nand create mode 100644 target/linux/rb532/config-3.3 create mode 100644 target/linux/rb532/image/Makefile create mode 100755 target/linux/rb532/image/gen_image.sh create mode 100644 target/linux/rb532/modules.mk create mode 100644 target/linux/rb532/patches-3.3/001-cmdline_hack.patch create mode 100644 target/linux/rb532/patches-3.3/002-rb532_nand_fixup.patch create mode 100644 target/linux/rb532/src/patch-cmdline.c create mode 100644 target/linux/rdc/Makefile create mode 100644 target/linux/rdc/base-files/etc/config/network create mode 100644 target/linux/rdc/base-files/etc/diag.sh create mode 100644 target/linux/rdc/base-files/lib/preinit/05_set_ether_mac_rdc create mode 100644 target/linux/rdc/base-files/lib/upgrade/platform.sh create mode 100644 target/linux/rdc/config-3.3 create mode 100644 target/linux/rdc/image/Makefile create mode 100755 target/linux/rdc/image/mkimg_bifferboard.py create mode 100755 target/linux/rdc/image/mkimg_sitecom.pl create mode 100644 target/linux/rdc/modules.mk create mode 100644 target/linux/rdc/patches-3.3/006-yenta_mistery.patch create mode 100644 target/linux/rdc/patches-3.3/009-rdc321x_select_embedded.patch create mode 100644 target/linux/rdc/patches-3.3/010-rdc_cpu_ident.patch create mode 100644 target/linux/rdc/patches-3.3/011-tune_lzma_options.patch create mode 100644 target/linux/rdc/patches-3.3/012-export_erase_write.patch create mode 100644 target/linux/rdc/patches-3.3/100-rdc_boards.patch create mode 100644 target/linux/rdc/patches-3.3/120-panic_on_unrecovered_nmi.patch create mode 100644 target/linux/rdc/patches-3.3/150-pit-tick-rate.patch create mode 100644 target/linux/rdc/patches-3.3/160-kexec-fix.patch create mode 100644 target/linux/rdc/profiles/ar525w.mk create mode 100644 target/linux/rdc/profiles/bifferboard.mk create mode 100644 target/linux/rdc/profiles/r8610.mk create mode 100644 target/linux/rdc/profiles/sitecom.mk create mode 100644 target/linux/realview/Makefile create mode 100644 target/linux/realview/README create mode 100644 target/linux/realview/base-files/etc/inittab create mode 100644 target/linux/realview/config-3.3 create mode 100644 target/linux/realview/image/Makefile create mode 100644 target/linux/realview/patches-3.3/001-arm-fix-REALVIEW_EB11MP_PRIV_MEM_BASE.patch create mode 100644 target/linux/realview/patches-3.3/002-disable_fmrx_instr.patch create mode 100644 target/linux/s3c24xx/Makefile create mode 100644 target/linux/s3c24xx/files-2.6.30/arch/arm/mach-s3c2442/gta02-pm-bt.c create mode 100644 target/linux/s3c24xx/files-2.6.30/arch/arm/mach-s3c2442/gta02-pm-gps.c create mode 100644 target/linux/s3c24xx/files-2.6.30/arch/arm/mach-s3c2442/gta02-pm-gsm.c create mode 100644 target/linux/s3c24xx/files-2.6.30/arch/arm/mach-s3c2442/gta02-pm-wlan.c create mode 100644 target/linux/s3c24xx/files-2.6.30/arch/arm/mach-s3c2442/include/mach/gta02-pm-gps.h create mode 100644 target/linux/s3c24xx/files-2.6.30/arch/arm/mach-s3c2442/include/mach/gta02-pm-gsm.h create mode 100644 target/linux/s3c24xx/files-2.6.30/arch/arm/mach-s3c2442/include/mach/gta02-pm-wlan.h create mode 100644 target/linux/s3c24xx/files-2.6.30/arch/arm/mach-s3c2442/include/mach/gta02.h create mode 100644 target/linux/s3c24xx/files-2.6.30/arch/arm/mach-s3c2442/mach-gta02.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/Kconfig create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/Makefile create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/ar6000/ar6000_drv.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/ar6000/ar6000_drv.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/ar6000/ar6000_raw_if.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/ar6000/ar6xapi_linux.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/ar6000/athdrv_linux.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/ar6000/athtypes_linux.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/ar6000/config_linux.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/ar6000/debug_linux.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/ar6000/ioctl.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/ar6000/netbuf.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/ar6000/osapi_linux.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/ar6000/wireless_ext.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/bmi/bmi.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/bmi/bmi_internal.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/hif/hif.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/hif/hif2.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/hif/hif_internal.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/htc/ar6k.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/htc/ar6k.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/htc/ar6k_events.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/htc/htc.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/htc/htc_debug.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/htc/htc_internal.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/htc/htc_recv.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/htc/htc_send.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/htc/htc_services.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/AR6001_regdump.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/AR6K_version.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/AR6K_version.h.NEW create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/AR6Khwreg.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/a_config.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/a_debug.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/a_drv.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/a_drv_api.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/a_osapi.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/a_types.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/ar6000_api.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/ar6000_diag.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/athdefs.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/athdrv.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/athendpack.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/athstartpack.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/bmi.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/bmi_msg.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/common_drv.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/dbglog.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/dbglog_api.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/dbglog_id.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/dl_list.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/dset_api.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/dset_internal.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/dsetid.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/gpio.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/gpio_api.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/hif.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/host_version.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/htc.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/htc_api.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/htc_packet.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/htc_services.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/ieee80211.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/ieee80211_ioctl.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/ieee80211_node.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/ini_dset.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/regDb.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/regdump.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/targaddrs.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/testcmd.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/wlan_api.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/wlan_dset.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/wmi.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/wmi_api.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/include/wmix.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/miscdrv/common_drv.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/miscdrv/credit_dist.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/wlan/wlan_node.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/wlan/wlan_recv_beacon.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/wlan/wlan_utils.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/wmi/wmi.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/wmi/wmi_doc.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/ar6000/wmi/wmi_host.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/input/misc/lis302dl.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/input/touchscreen/s3c2410_ts.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/input/touchscreen/ts_filter_chain.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/input/touchscreen/ts_filter_group.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/input/touchscreen/ts_filter_linear.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/input/touchscreen/ts_filter_mean.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/input/touchscreen/ts_filter_median.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/leds/leds-gta02-vibrator.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/Kconfig create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/Makefile create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-core.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-core.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-fb.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-gpio.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-mci.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/mfd/glamo/glamo-regs.h create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/misc/gta02_pm_host.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/misc/gta02_pm_resume_reason.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/power/bq27000_battery.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/power/hdq.c create mode 100644 target/linux/s3c24xx/files-2.6.30/drivers/video/display/jbt6k74.c create mode 100644 target/linux/s3c24xx/files-2.6.30/include/linux/bq27000_battery.h create mode 100644 target/linux/s3c24xx/files-2.6.30/include/linux/gta02-vibrator.h create mode 100644 target/linux/s3c24xx/files-2.6.30/include/linux/gta02_hdq.h create mode 100644 target/linux/s3c24xx/files-2.6.30/include/linux/hdq.h create mode 100644 target/linux/s3c24xx/files-2.6.30/include/linux/jbt6k74.h create mode 100644 target/linux/s3c24xx/files-2.6.30/include/linux/lis302dl.h create mode 100644 target/linux/s3c24xx/files-2.6.30/include/linux/mfd/glamo.h create mode 100644 target/linux/s3c24xx/files-2.6.30/include/linux/touchscreen/ts_filter.h create mode 100644 target/linux/s3c24xx/files-2.6.30/include/linux/touchscreen/ts_filter_chain.h create mode 100644 target/linux/s3c24xx/files-2.6.30/include/linux/touchscreen/ts_filter_group.h create mode 100644 target/linux/s3c24xx/files-2.6.30/include/linux/touchscreen/ts_filter_linear.h create mode 100644 target/linux/s3c24xx/files-2.6.30/include/linux/touchscreen/ts_filter_mean.h create mode 100644 target/linux/s3c24xx/files-2.6.30/include/linux/touchscreen/ts_filter_median.h create mode 100644 target/linux/s3c24xx/files-2.6.30/sound/soc/s3c24xx/gta02_wm8753.c create mode 100644 target/linux/s3c24xx/image/Makefile create mode 100644 target/linux/s3c24xx/modules.mk create mode 100644 target/linux/s3c24xx/openmoko-gta02/base-files/etc/acpi/sleep.sh create mode 100644 target/linux/s3c24xx/openmoko-gta02/base-files/etc/config/fstab create mode 100644 target/linux/s3c24xx/openmoko-gta02/base-files/etc/config/network create mode 100644 target/linux/s3c24xx/openmoko-gta02/config-2.6.30 create mode 100644 target/linux/s3c24xx/openmoko-gta02/profiles/100-gta02-minimal.mk create mode 100644 target/linux/s3c24xx/openmoko-gta02/profiles/101-gta02-full.mk create mode 100644 target/linux/s3c24xx/openmoko-gta02/target.mk create mode 100644 target/linux/s3c24xx/patches-2.6.30/001-merge-openmoko.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/010-s3c-dma.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/011-s3c-pwm.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/012-s3c-usb.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/013-fiq_c_handler.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/014-neo1973_mach.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/015-mach-gta02.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/030-dont-override-logo-with-early-printks.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/031-add-openwrt-logo.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/040-rename-serialdevs.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/050-s3c2442-touchscreen.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/052-touchscreen_filter.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/053-glamo.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/054-bq27000.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/055-gta02-leds.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/055-jbt6k74.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/056-pcf50633.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/057-lis302dl.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/058-gta02-wm8752.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/060-spi-gpio-non-blocking.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/068-ar6000.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/070-s3c24xx-time.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/080-nr-tty-devices.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/100-udc-poll-vbus.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/110-serial.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/120-fix-wm8753-reg_cache.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/130-fix-s3c_gpiolib_getchip.patch create mode 100644 target/linux/s3c24xx/patches-2.6.30/150-ignore-init-argument.patch create mode 100644 target/linux/sibyte/Makefile create mode 100644 target/linux/sibyte/base-files/etc/inittab create mode 100644 target/linux/sibyte/config-3.3 create mode 100644 target/linux/sibyte/image/Makefile create mode 100644 target/linux/sibyte/patches-3.3/101-rhone_physmap.patch create mode 100644 target/linux/sibyte/patches-3.3/103-m41t80_smbus.patch create mode 100644 target/linux/sibyte/patches-3.3/104-sibyte_rtc_cleanup.patch create mode 100644 target/linux/sibyte/patches-3.3/105-sibyte_hwmon.patch create mode 100644 target/linux/sibyte/patches-3.3/106-no_module_reloc.patch create mode 100644 target/linux/sparc/Makefile create mode 100644 target/linux/sparc/config-default create mode 100644 target/linux/sparc/image/Makefile create mode 100644 target/linux/ubicom32/Makefile create mode 100644 target/linux/ubicom32/config-default create mode 100644 target/linux/ubicom32/files/arch/ubicom32/Kconfig create mode 100644 target/linux/ubicom32/files/arch/ubicom32/Kconfig.debug create mode 100644 target/linux/ubicom32/files/arch/ubicom32/Makefile create mode 100644 target/linux/ubicom32/files/arch/ubicom32/crypto/Makefile create mode 100644 target/linux/ubicom32/files/arch/ubicom32/crypto/aes_ubicom32.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/crypto/crypto_des.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/crypto/crypto_ubicom32.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/crypto/crypto_ubicom32.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/crypto/des_check_key.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/crypto/des_ubicom32.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/crypto/md5_ubicom32.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/crypto/md5_ubicom32_asm.S create mode 100644 target/linux/ubicom32/files/arch/ubicom32/crypto/sha1_ubicom32.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/crypto/sha1_ubicom32_asm.S create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/.gitignore create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/Kbuild create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/a.out.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/atomic.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/audio.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/audionode.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/auxvec.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/bitops.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/bitsperlong.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/board.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/bootargs.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/bootinfo.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/bug.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/bugs.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/byteorder.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/cache.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/cachectl.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/cacheflush.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/checksum.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/cpu.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/cputime.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/current.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/delay.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/device.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/devtree.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/div64.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/dma-mapping.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/dma.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/elf.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/emergency-restart.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/entry.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/errno.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/fb.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/fcntl.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/flat.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/fpu.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ftrace.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/futex.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/gpio.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/hardirq.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/hw_irq.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/io.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ioctl.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ioctls.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ip5000-asm.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ip5000.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ipcbuf.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/irq.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/irq_regs.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/irqflags.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/kdebug.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/kmap_types.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ldsr.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/linkage.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/local.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/machdep.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/mc146818rtc.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/memory_map.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/mman.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/mmu.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/mmu_context.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/module.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/msgbuf.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/mutex.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/namei.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ocm-alloc.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ocm_size.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ocm_text.lds.inc create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/page.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/page_offset.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/param.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/pci.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/pcm_tio.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/percpu.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/pgalloc.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/pgtable.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/plio.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/poll.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/posix_types.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/processor.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/profilesample.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ptrace.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/range-protect-asm.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/range-protect.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/resource.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ring_tio.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/scatterlist.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/sd_tio.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/sections.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/segment.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/semaphore-helper.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/semaphore.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/sembuf.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/setup.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/shmbuf.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/shmparam.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/sigcontext.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/siginfo.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/signal.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/smp.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/socket.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/sockios.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/spinlock.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/spinlock_types.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/stacktrace.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/stat.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/statfs.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/string.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/swab.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/switch-dev.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/system.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/termbits.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/termios.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/thread-asm.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/thread.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/thread_info.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/timex.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/tlb.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/tlbflush.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/topology.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/traps.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/types.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/uaccess.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/uart_tio.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubi32-cs4384.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubi32-pcm.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubicom32-common-asm.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubicom32-common.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubicom32-spi-gpio.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubicom32-tio.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubicom32bl.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubicom32fb.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubicom32hid.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubicom32input.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubicom32input_i2c.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubicom32lcd.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubicom32lcdpower.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubicom32ring.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubicom32sd.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ubicom32suart.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/ucontext.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/unaligned.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/unistd.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/user.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/vdc_tio.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/vga.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/include/asm/xor.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/Makefile create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/asm-offsets.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/devtree.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/dma.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/flat.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/head.S create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/init_task.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/irq.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/ldsr.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/module.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/os_node.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/process.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/processor.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/ptrace.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/semaphore.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/setup.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/signal.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/smp.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/stacktrace.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/sys_ubicom32.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/syscalltable.S create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/thread.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/time.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/timer_broadcast.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/timer_device.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/timer_tick.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/topology.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/traps.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/uaccess.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/ubicom32_context_switch.S create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/ubicom32_ksyms.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/ubicom32_syscall.S create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/unaligned_trap.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/kernel/vmlinux.lds.S create mode 100644 target/linux/ubicom32/files/arch/ubicom32/lib/Makefile create mode 100644 target/linux/ubicom32/files/arch/ubicom32/lib/checksum.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/lib/delay.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/lib/mem_ubicom32.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/Kconfig.switch create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/Makefile create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/audio.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/board.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/bootargs.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/cachectl.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/common.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/io.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/pci.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/plio.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/profile.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/profile.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/profpkt.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/ring_tio.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/switch-bcm539x-reg.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/switch-bcm539x.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/switch-core.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/switch-core.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/ubi32-gpio.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/ubicom32hid.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/ubicom32input.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/ubicom32input_i2c.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/usb.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/usb_tio.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/usb_tio.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-common/vdc_tio.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip5k/Kconfig create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip5k/Makefile create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip5k/board-ip5160dev.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip5k/board-ip5160rgw.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip5k/board-ip5170dpf.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip7k/Kconfig create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip7k/Makefile create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip7k/board-ip7145dpf.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip7k/board-ip7160bringup.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip7k/board-ip7160dpf.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip7k/board-ip7160rgw.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip7k/board-ip7500av.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip7k/board-ip7500iap.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip7k/board-ip7500media.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip7k/board-ip7500module.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mach-ip7k/board-ip7500wspkr.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mm/Makefile create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mm/fault.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mm/init.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mm/kmap.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mm/memory.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/mm/ocm-alloc.c create mode 100644 target/linux/ubicom32/files/arch/ubicom32/oprofile/Makefile create mode 100644 target/linux/ubicom32/files/arch/ubicom32/oprofile/ipProf.h create mode 100644 target/linux/ubicom32/files/arch/ubicom32/oprofile/profile.c create mode 100644 target/linux/ubicom32/files/drivers/char/hw_random/ubicom32-rng.c create mode 100644 target/linux/ubicom32/files/drivers/mmc/host/ubicom32sd.c create mode 100644 target/linux/ubicom32/files/drivers/mtd/devices/nand-spi-er.c create mode 100644 target/linux/ubicom32/files/drivers/mtd/devices/ubi32-m25p80.c create mode 100644 target/linux/ubicom32/files/drivers/mtd/devices/ubi32-nand-spi-er.c create mode 100644 target/linux/ubicom32/files/drivers/net/ubi32-eth.c create mode 100644 target/linux/ubicom32/files/drivers/net/ubi32-eth.h create mode 100644 target/linux/ubicom32/files/drivers/serial/ubi32_mailbox.c create mode 100644 target/linux/ubicom32/files/drivers/serial/ubi32_serdes.c create mode 100644 target/linux/ubicom32/files/drivers/serial/ubi32_uarttio.c create mode 100644 target/linux/ubicom32/files/drivers/spi/spi_ubicom32_gpio.c create mode 100644 target/linux/ubicom32/files/drivers/uio/uio_ubicom32ring.c create mode 100644 target/linux/ubicom32/files/drivers/usb/musb/ubi32_usb.c create mode 100644 target/linux/ubicom32/files/drivers/video/backlight/ubicom32bl.c create mode 100644 target/linux/ubicom32/files/drivers/video/backlight/ubicom32lcd.c create mode 100644 target/linux/ubicom32/files/drivers/video/backlight/ubicom32lcd.h create mode 100644 target/linux/ubicom32/files/drivers/video/backlight/ubicom32lcdpower.c create mode 100644 target/linux/ubicom32/files/drivers/video/ubicom32fb.c create mode 100644 target/linux/ubicom32/files/drivers/video/ubicom32plio80.c create mode 100644 target/linux/ubicom32/files/drivers/video/ubicom32vfb.c create mode 100644 target/linux/ubicom32/files/drivers/watchdog/ubi32_wdt.c create mode 100644 target/linux/ubicom32/files/sound/ubicom32/Kconfig create mode 100644 target/linux/ubicom32/files/sound/ubicom32/Makefile create mode 100644 target/linux/ubicom32/files/sound/ubicom32/ubi32-cs4350.c create mode 100644 target/linux/ubicom32/files/sound/ubicom32/ubi32-cs4384.c create mode 100644 target/linux/ubicom32/files/sound/ubicom32/ubi32-generic-capture.c create mode 100644 target/linux/ubicom32/files/sound/ubicom32/ubi32-generic.c create mode 100644 target/linux/ubicom32/files/sound/ubicom32/ubi32-pcm.c create mode 100644 target/linux/ubicom32/files/sound/ubicom32/ubi32.h create mode 100644 target/linux/ubicom32/image/Makefile create mode 100644 target/linux/ubicom32/patches-2.6.30/100-ubicom32_support.patch create mode 100644 target/linux/ubicom32/patches-2.6.30/110-vmlinux_lds_fix.patch create mode 100644 target/linux/ubicom32/patches-2.6.30/120-libgcc_func.patch create mode 100644 target/linux/ubicom32/patches-2.6.30/130-flash_driver_fix.patch create mode 100644 target/linux/ubicom32/patches-2.6.30/140-arch_cflags.patch create mode 100644 target/linux/ubicom32/patches-2.6.32/100-ubicom32_support.patch create mode 100644 target/linux/ubicom32/patches-2.6.32/110-vmlinux_lds_fix.patch create mode 100644 target/linux/ubicom32/patches-2.6.32/120-libgcc_func.patch create mode 100644 target/linux/ubicom32/patches-2.6.32/130-flash_driver_fix.patch create mode 100644 target/linux/ubicom32/patches-2.6.32/140-arch_cflags.patch create mode 100644 target/linux/uml/Makefile create mode 100644 target/linux/uml/README create mode 100644 target/linux/uml/config/i386 create mode 100644 target/linux/uml/config/x86_64 create mode 100644 target/linux/uml/image/Makefile create mode 100644 target/linux/uml/patches-3.2/901-lib_zlib_deflate_visible.patch create mode 100644 target/linux/uml/patches-3.3/001-include_sys_resource_h.patch create mode 100644 target/linux/uml/patches-3.3/901-lib_zlib_deflate_visible.patch create mode 100644 target/linux/x86/Makefile create mode 100644 target/linux/x86/alix2/base-files/etc/config/network create mode 100644 target/linux/x86/alix2/base-files/etc/config/system create mode 100644 target/linux/x86/alix2/base-files/etc/hotplug.d/button/50-reboot create mode 100644 target/linux/x86/alix2/config-3.3 create mode 100644 target/linux/x86/alix2/target.mk create mode 100644 target/linux/x86/base-files.mk create mode 100644 target/linux/x86/base-files/etc/defconfig/net4801/network create mode 100644 target/linux/x86/base-files/etc/defconfig/net4826/network create mode 100755 target/linux/x86/base-files/etc/init.d/defconfig create mode 100644 target/linux/x86/base-files/lib/preinit/15_essential_fs_x86 create mode 100644 target/linux/x86/base-files/lib/preinit/45_failsafe_x86 create mode 100644 target/linux/x86/base-files/lib/preinit/89_move_config create mode 100755 target/linux/x86/base-files/lib/soekris.sh create mode 100644 target/linux/x86/base-files/lib/upgrade/platform.sh create mode 100644 target/linux/x86/config-3.3 create mode 100644 target/linux/x86/ep80579/config-3.3 create mode 100644 target/linux/x86/ep80579/target.mk create mode 100644 target/linux/x86/generic/config-3.3 create mode 100644 target/linux/x86/generic/profiles/000-Generic.mk create mode 100644 target/linux/x86/generic/profiles/Soekris45xx.mk create mode 100644 target/linux/x86/generic/profiles/Soekris48xx.mk create mode 100644 target/linux/x86/generic/profiles/Wrap.mk create mode 100644 target/linux/x86/generic/target.mk create mode 100644 target/linux/x86/geos/base-files/etc/config/network create mode 100644 target/linux/x86/geos/base-files/etc/config/system create mode 100644 target/linux/x86/geos/base-files/etc/hotplug.d/button/50-reboot create mode 100644 target/linux/x86/geos/config-3.3 create mode 100644 target/linux/x86/geos/target.mk create mode 100644 target/linux/x86/image/Config.in create mode 100644 target/linux/x86/image/Makefile create mode 100755 target/linux/x86/image/gen_image_generic.sh create mode 100755 target/linux/x86/image/gen_image_grub.sh create mode 100755 target/linux/x86/image/gen_image_olpc.sh create mode 100644 target/linux/x86/image/grub-early.cfg create mode 100644 target/linux/x86/image/grub.cfg create mode 100644 target/linux/x86/image/menu.lst create mode 100644 target/linux/x86/image/olpc.fth create mode 100644 target/linux/x86/kvm_guest/config-3.3 create mode 100644 target/linux/x86/kvm_guest/target.mk create mode 100644 target/linux/x86/modules.mk create mode 100644 target/linux/x86/net5501/base-files/etc/config/network create mode 100644 target/linux/x86/net5501/base-files/etc/config/system create mode 100644 target/linux/x86/net5501/base-files/etc/hotplug.d/button/50-reboot create mode 100644 target/linux/x86/net5501/config-3.3 create mode 100644 target/linux/x86/net5501/target.mk create mode 100644 target/linux/x86/olpc/base-files/etc/X11/xorg.conf create mode 100644 target/linux/x86/olpc/base-files/etc/config/network create mode 100644 target/linux/x86/olpc/base-files/lib/preinit/15_essential_fs_x86 create mode 100644 target/linux/x86/olpc/base-files/lib/preinit/45_failsafe_x86 create mode 100644 target/linux/x86/olpc/base-files/lib/upgrade/platform.sh create mode 100644 target/linux/x86/olpc/config-3.3 create mode 100644 target/linux/x86/olpc/target.mk create mode 100644 target/linux/x86/patches-3.3/001-alix_platform.patch create mode 100644 target/linux/x86/patches-3.3/002-geos_platform.patch create mode 100644 target/linux/x86/patches-3.3/003-via-rhine-crash-fix.patch create mode 100644 target/linux/x86/thincan/base-files/etc/init.d/alsa create mode 100644 target/linux/x86/thincan/config-3.3 create mode 100644 target/linux/x86/thincan/profiles/dbe61.mk create mode 100644 target/linux/x86/thincan/target.mk create mode 100644 target/linux/x86/xen_domu/base-files/etc/inittab create mode 100644 target/linux/x86/xen_domu/base-files/lib/preinit/45_mount_xenfs create mode 100644 target/linux/x86/xen_domu/config-3.3 create mode 100644 target/linux/x86/xen_domu/target.mk create mode 100644 target/linux/xburst/Makefile create mode 100644 target/linux/xburst/base-files/etc/config/fstab create mode 100644 target/linux/xburst/base-files/etc/config/network create mode 100644 target/linux/xburst/base-files/etc/config/system create mode 100644 target/linux/xburst/config-3.3 create mode 100644 target/linux/xburst/id800wt/config-3.3 create mode 100644 target/linux/xburst/id800wt/target.mk create mode 100644 target/linux/xburst/image/Makefile create mode 100644 target/linux/xburst/image/ubinize.cfg create mode 100644 target/linux/xburst/modules.mk create mode 100644 target/linux/xburst/n516/config-3.3 create mode 100644 target/linux/xburst/n516/target.mk create mode 100644 target/linux/xburst/n526/config-3.3 create mode 100644 target/linux/xburst/n526/target.mk create mode 100644 target/linux/xburst/patches-3.3/0001-ubi-Read-only-the-vid-header-instead-of-the-whole-pa.patch create mode 100644 target/linux/xburst/patches-3.3/0002-Add-jz4740-udc-driver.patch create mode 100644 target/linux/xburst/patches-3.3/0003-NAND-Optimize-NAND_ECC_HW_OOB_FIRST-read.patch create mode 100644 target/linux/xburst/patches-3.3/0004-NAND-Add-support-for-subpage-reads-for-NAND_ECC_HW_O.patch create mode 100644 target/linux/xburst/patches-3.3/0005-NAND-Optimize-reading-the-eec-data-for-the-JZ4740.patch create mode 100644 target/linux/xburst/patches-3.3/0006-MTD-NAND-JZ4740-Multi-bank-support-with-autodetectio.patch create mode 100644 target/linux/xburst/patches-3.3/0007-Add-ili8960-lcd-driver.patch create mode 100644 target/linux/xburst/patches-3.3/0008-qi_lb60-Don-t-use-3-wire-spi-mode-for-the-display-fo.patch create mode 100644 target/linux/xburst/patches-3.3/0009-dev-mem-Add-kernel-config-option-to-omit-this-device.patch create mode 100644 target/linux/xburst/patches-3.3/0010-cpufreq_stats-Support-runtime-changes-to-frequency-t.patch create mode 100644 target/linux/xburst/patches-3.3/0011-MIPS-JZ4740-Added-setting-of-PLL-rate-and-main-divid.patch create mode 100644 target/linux/xburst/patches-3.3/0012-MIPS-JZ4740-Add-cpufreq-support.patch create mode 100644 target/linux/xburst/patches-3.3/0013-MMC-JZ4740-Added-support-for-CPU-frequency-changing.patch create mode 100644 target/linux/xburst/patches-3.3/0014-MIPS-JZ4740-reset-Initialize-hibernate-wakeup-counte.patch create mode 100644 target/linux/xburst/patches-3.3/0015-ASoC-JZ4740-Replaced-comma-operators-with-semicolons.patch create mode 100644 target/linux/xburst/patches-3.3/0016-ASoC-JZ4740-Support-buffer-size-that-is-not-a-multip.patch create mode 100644 target/linux/xburst/patches-3.3/0017-MIPS-JZ4740-qi_lb60-Look-for-NAND-chip-in-bank-1.patch create mode 100644 target/linux/xburst/patches-3.3/0018-ASoC-jz4740-Convert-qi_lb60-to-use-snd_soc_register_.patch create mode 100644 target/linux/xburst/patches-3.3/0019-Framebuffer-notifier-Call-notifier-callbacks-prior-t.patch create mode 100644 target/linux/xburst/patches-3.3/0020-qi_lb60-NAND-add-data-partition.patch create mode 100644 target/linux/xburst/patches-3.3/0021-rtc-jz4740-fix-hwclock-give-time-out.patch create mode 100644 target/linux/xburst/qi_lb60/config-3.3 create mode 100644 target/linux/xburst/qi_lb60/target.mk (limited to 'target/linux') diff --git a/target/linux/Makefile b/target/linux/Makefile new file mode 100644 index 000000000..f7bbdffbf --- /dev/null +++ b/target/linux/Makefile @@ -0,0 +1,13 @@ +# +# Copyright (C) 2006-2007 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/target.mk + +export TARGET_BUILD=1 + +prereq clean download prepare compile install menuconfig nconfig oldconfig update refresh: FORCE + @+$(NO_TRACE_MAKE) -C $(BOARD) $@ diff --git a/target/linux/adm5120/Makefile b/target/linux/adm5120/Makefile new file mode 100644 index 000000000..273a28093 --- /dev/null +++ b/target/linux/adm5120/Makefile @@ -0,0 +1,22 @@ +# +# Copyright (C) 2007-2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +BOARD:=adm5120 +BOARDNAME:=Infineon/ADMtek ADM5120 +LINUX_VERSION:=3.3.8 +SUBTARGETS:=router_le router_be rb1xx +INITRAMFS_EXTRA_FILES:= + +include $(INCLUDE_DIR)/target.mk + +DEFAULT_PACKAGES += admswconfig wpad-mini kmod-input-core \ + kmod-input-polldev kmod-input-gpio-buttons kmod-button-hotplug \ + kmod-leds-gpio kmod-ledtrig-adm5120-switch + +$(eval $(call BuildTarget)) diff --git a/target/linux/adm5120/base-files/etc/config/network b/target/linux/adm5120/base-files/etc/config/network new file mode 100644 index 000000000..df2f20105 --- /dev/null +++ b/target/linux/adm5120/base-files/etc/config/network @@ -0,0 +1,27 @@ +#### VLAN configuration +config switch + option eth0 "0 1 2 3" + option eth1 "4" + + +#### Loopback configuration +config interface loopback + option ifname "lo" + option proto static + option ipaddr 127.0.0.1 + option netmask 255.0.0.0 + + +#### LAN configuration +config interface lan + option type bridge + option ifname "eth0" + option proto static + option ipaddr 192.168.1.1 + option netmask 255.255.255.0 + + +#### WAN configuration +config interface wan + option ifname "eth1" + option proto dhcp diff --git a/target/linux/adm5120/base-files/etc/config/system b/target/linux/adm5120/base-files/etc/config/system new file mode 100644 index 000000000..ea54ca1dc --- /dev/null +++ b/target/linux/adm5120/base-files/etc/config/system @@ -0,0 +1,40 @@ +config system + option hostname OpenWrt + option timezone UTC + +config timeserver ntp + list server 0.openwrt.pool.ntp.org + list server 1.openwrt.pool.ntp.org + list server 2.openwrt.pool.ntp.org + list server 3.openwrt.pool.ntp.org + +config led + option sysfs lan1 + option trigger port_state + option port_state link_act + +config led + option sysfs lan2 + option trigger port_state + option port_state link_act + +config led + option sysfs lan3 + option trigger port_state + option port_state link_act + +config led + option sysfs lan4 + option trigger port_state + option port_state link_act + +config led + option sysfs wan + option trigger port_state + option port_state link_act + +config led + option sysfs wlan + option trigger netdev + option dev wlan0 + diff --git a/target/linux/adm5120/base-files/etc/diag.sh b/target/linux/adm5120/base-files/etc/diag.sh new file mode 100755 index 000000000..3a66dfc87 --- /dev/null +++ b/target/linux/adm5120/base-files/etc/diag.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# +# Copyright (C) 2007 OpenWrt.org +# +# + +. /lib/adm5120.sh + +led_set_attr() { + [ -f "/sys/class/leds/$1/$2" ] && echo "$3" > "/sys/class/leds/$1/$2" +} + +status_led_set_timer() { + led_set_attr $status_led "trigger" "timer" + led_set_attr $status_led "delay_on" "$1" + led_set_attr $status_led "delay_off" "$2" +} + +status_led_set_morse() { + led_set_attr $status_led "trigger" "morse" + led_set_attr $status_led "delay" "$1" + led_set_attr $status_led "message" "$2" +} + +status_led_on() { + led_set_attr $status_led "trigger" "none" + led_set_attr $status_led "brightness" 255 +} + +status_led_off() { + led_set_attr $status_led "trigger" "none" + led_set_attr $status_led "brightness" 0 +} + +set_state() { + case "$1" in + preinit) + insmod leds-gpio + status_led_set_timer 200 200 + ;; + failsafe) + status_led_set_timer 50 50 + ;; + done) + status_led_on + ;; + esac +} diff --git a/target/linux/adm5120/base-files/lib/adm5120.sh b/target/linux/adm5120/base-files/lib/adm5120.sh new file mode 100755 index 000000000..496fc06f3 --- /dev/null +++ b/target/linux/adm5120/base-files/lib/adm5120.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# +# Copyright (C) 2007 OpenWrt.org +# +# + +board_name="" +status_led="" +sys_mtd_part="" + +adm5120_detect() { + board_name=$(awk 'BEGIN{FS="[ \t]+:[ \t]"} /machine/ {print $2}' /proc/cpuinfo) + + case "$board_name" in + "Cellvision"*) + status_led="status" + sys_mtd_part="firmware" + ;; + "Compex"*) + status_led="diag" + case "$board_name" in + *-WRT) + sys_mtd_part="trx" + ;; + *) + sys_mtd_part="partition1" + ;; + esac + ;; + "Edimax"*) + status_led="power" + sys_mtd_part="firmware" + ;; + "Infineon"*) + sys_mtd_part="firmware" + ;; + "Mikrotik"*) + status_led="power" + ;; + "ZyXEL"*) + status_led="power" + sys_mtd_part="trx" + ;; + "EB-214A"*) + status_led="power" + sys_mtd_part="firmware" + ;; + *) + ;; + esac +} + +adm5120_detect diff --git a/target/linux/adm5120/base-files/lib/preinit/05_preinit_do_adm5120.sh b/target/linux/adm5120/base-files/lib/preinit/05_preinit_do_adm5120.sh new file mode 100644 index 000000000..4fca1e71b --- /dev/null +++ b/target/linux/adm5120/base-files/lib/preinit/05_preinit_do_adm5120.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +do_adm5120() { + . /lib/adm5120.sh +} + +boot_hook_add preinit_main do_adm5120 diff --git a/target/linux/adm5120/base-files/lib/preinit/05_reset_button_adm5120 b/target/linux/adm5120/base-files/lib/preinit/05_reset_button_adm5120 new file mode 100644 index 000000000..44f164adb --- /dev/null +++ b/target/linux/adm5120/base-files/lib/preinit/05_reset_button_adm5120 @@ -0,0 +1,12 @@ +#!/bin/sh + +enable_reset_button() { + insmod input-core + insmod input-polldev + insmod gpio_buttons + insmod button-hotplug +} + +boot_hook_add preinit_main enable_reset_button + + diff --git a/target/linux/adm5120/base-files/lib/preinit/05_set_preinit_iface_adm5120 b/target/linux/adm5120/base-files/lib/preinit/05_set_preinit_iface_adm5120 new file mode 100644 index 000000000..ac2a7cbb6 --- /dev/null +++ b/target/linux/adm5120/base-files/lib/preinit/05_set_preinit_iface_adm5120 @@ -0,0 +1,9 @@ +#!/bin/sh + +set_preinit_ifname() { + ifname=eth0 +} + +boot_hook_add preinit_main set_preinit_ifname + + diff --git a/target/linux/adm5120/base-files/lib/upgrade/platform.sh b/target/linux/adm5120/base-files/lib/upgrade/platform.sh new file mode 100644 index 000000000..f067089fa --- /dev/null +++ b/target/linux/adm5120/base-files/lib/upgrade/platform.sh @@ -0,0 +1,44 @@ +# +# Copyright (C) 2009-2010 OpenWrt.org +# + +. /lib/adm5120.sh + +PART_NAME="firmware" +RAMFS_COPY_DATA=/lib/adm5120.sh + +platform_check_image() { + local magic="$(get_magic_word "$1")" + + [ "$ARGC" -gt 1 ] && return 1 + + case "$board_name" in + "ZyXEL"*|"Compex WP54 family") + # .trx files + [ "$magic" != "4844" ] && { + echo "Invalid image type." + return 1 + } + return 0 + ;; + *) + ;; + esac + + echo "Sysupgrade is not yet supported on $board_name." + return 1 +} + +platform_do_upgrade() { + PART_NAME="$sys_mtd_part" + default_do_upgrade "$ARGV" +} + +disable_watchdog() { + killall watchdog + ( ps | grep -v 'grep' | grep '/dev/watchdog' ) && { + echo 'Could not disable watchdog' + return 1 + } +} +append sysupgrade_pre_upgrade disable_watchdog diff --git a/target/linux/adm5120/config-3.3 b/target/linux/adm5120/config-3.3 new file mode 100644 index 000000000..18739367b --- /dev/null +++ b/target/linux/adm5120/config-3.3 @@ -0,0 +1,194 @@ +CONFIG_ADM5120=y +CONFIG_ADM5120_ENET=y +CONFIG_ADM5120_MACH_5GXI=y +CONFIG_ADM5120_MACH_BR_6104K=y +CONFIG_ADM5120_MACH_BR_6104KP=y +CONFIG_ADM5120_MACH_BR_61X4WG=y +CONFIG_ADM5120_MACH_CAS_771=y +CONFIG_ADM5120_MACH_EASY5120P_ATA=y +CONFIG_ADM5120_MACH_EASY5120_RT=y +CONFIG_ADM5120_MACH_EASY5120_WVOIP=y +CONFIG_ADM5120_MACH_EASY83000=y +CONFIG_ADM5120_MACH_EB_214A=y +CONFIG_ADM5120_MACH_NFS_101=y +CONFIG_ADM5120_MACH_NP27G=y +CONFIG_ADM5120_MACH_NP28G=y +CONFIG_ADM5120_MACH_PMUGW=y +# CONFIG_ADM5120_MACH_RB_11X is not set +# CONFIG_ADM5120_MACH_RB_133 is not set +# CONFIG_ADM5120_MACH_RB_133C is not set +# CONFIG_ADM5120_MACH_RB_150 is not set +# CONFIG_ADM5120_MACH_RB_153 is not set +# CONFIG_ADM5120_MACH_RB_192 is not set +CONFIG_ADM5120_MACH_WP54=y +CONFIG_ADM5120_OEM_CELLVISION=y +CONFIG_ADM5120_OEM_COMPEX=y +CONFIG_ADM5120_OEM_EDIMAX=y +CONFIG_ADM5120_OEM_GENERIC=y +CONFIG_ADM5120_OEM_INFINEON=y +# CONFIG_ADM5120_OEM_MIKROTIK is not set +CONFIG_ADM5120_OEM_MOTOROLA=y +CONFIG_ADM5120_OEM_OSBRIDGE=y +# CONFIG_ADM5120_OEM_ZYXEL is not set +CONFIG_ADM5120_SOC_BGA=y +CONFIG_ADM5120_WDT=y +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +CONFIG_ARCH_DISCARD_MEMBLOCK=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM_AMBA=y +# CONFIG_ARM_SP805_WATCHDOG is not set +CONFIG_ATA=m +CONFIG_BCMA_POSSIBLE=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_CEVT_R4K=y +CONFIG_CEVT_R4K_LIB=y +CONFIG_CMDLINE="console=ttyS0,115200 rootfstype=squashfs,jffs2" +CONFIG_CMDLINE_BOOL=y +# CONFIG_CMDLINE_OVERRIDE is not set +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPS32_R1=y +CONFIG_CPU_MIPSR1=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CRYPTO=m +CONFIG_CRYPTO_AEAD2=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_ALGAPI2=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_HASH=m +CONFIG_CRYPTO_HASH2=m +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER2=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_PCOMP2=m +CONFIG_CRYPTO_RNG2=m +CONFIG_CRYPTO_WORKQUEUE=m +CONFIG_CSRC_R4K=y +CONFIG_CSRC_R4K_LIB=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_EARLY_PRINTK=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_GENERIC_ATOMIC64=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GPIOLIB=y +# CONFIG_GPIO_PL061 is not set +CONFIG_GPIO_SYSFS=y +CONFIG_HARDWARE_WATCHPOINTS=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_GENERIC_HARDIRQS=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_WORK=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HID=m +CONFIG_HID_SUPPORT=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +# CONFIG_HOSTAP_FIRMWARE_NVRAM is not set +CONFIG_HOSTAP_PCI=m +CONFIG_HW_HAS_PCI=y +CONFIG_HW_RANDOM=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_IMAGE_CMDLINE_HACK=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INPUT=m +# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set +CONFIG_IRQ_CPU=y +CONFIG_IRQ_FORCED_THREADING=y +# CONFIG_LEDS_TRIGGER_ADM5120_SWITCH is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_MII=m +CONFIG_MIPS=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +CONFIG_MIPS_MACHINE=y +CONFIG_MIPS_MT_DISABLED=y +CONFIG_MTD_ADM5120=y +CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC=y +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_MYLOADER_PARTS=y +CONFIG_MTD_TRXSPLIT=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NLS=m +CONFIG_NO_EXCEPT_FILL=y +CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y +CONFIG_NO_HZ=y +CONFIG_PAGEFLAGS_EXTENDED=y +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_PCI=y +CONFIG_PCI_DISABLE_COMMON_QUIRKS=y +CONFIG_PCI_DOMAINS=y +CONFIG_PERF_USE_VMALLOC=y +# CONFIG_PREEMPT_RCU is not set +CONFIG_SCSI=m +CONFIG_SCSI_MOD=m +# CONFIG_SERIAL_8250 is not set +CONFIG_SERIAL_AMBA_PL010=y +CONFIG_SERIAL_AMBA_PL010_CONSOLE=y +CONFIG_SERIAL_AMBA_PL010_NUMPORTS=2 +CONFIG_SERIAL_AMBA_PL010_PORTNAME="ttyS" +# CONFIG_SERIAL_AMBA_PL011 is not set +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SOFT_WATCHDOG=m +# CONFIG_SWAP is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_USB=m +CONFIG_USB_ADM5120_HCD=m +CONFIG_USB_ARCH_HAS_XHCI=y +CONFIG_USB_COMMON=m +CONFIG_USB_EHCI_HCD=m +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_SUPPORT=y +# CONFIG_USB_UHCI_HCD is not set +CONFIG_XZ_DEC=y +CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/adm5120/files/arch/mips/adm5120/Kconfig b/target/linux/adm5120/files/arch/mips/adm5120/Kconfig new file mode 100644 index 000000000..be35a8f72 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/Kconfig @@ -0,0 +1,197 @@ +if ADM5120 + +menu "ADM5120 Board selection" + +config ADM5120_MACH_CAS_771 + bool "Cellvision CAS-771/771W support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_CELLVISION + default y + +config ADM5120_MACH_NFS_101 + bool "Cellvision NFS-101U/101WU support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_CELLVISION + default y + +config ADM5120_MACH_NP27G + bool "Compex NP27G support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_COMPEX + default y + +config ADM5120_MACH_NP28G + bool "Compex NP28G support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_COMPEX + default y + +config ADM5120_MACH_WP54 + bool "Compex WP54 family support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_COMPEX + default y + +config ADM5120_MACH_EB_214A + bool "EB-214A support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_GENERIC + default y + +config ADM5120_MACH_BR_6104K + bool "Edimax BR-6104K support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_OEM_EDIMAX + default y + +config ADM5120_MACH_BR_6104KP + bool "Edimax BR-6104KP support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_OEM_EDIMAX + default y + +config ADM5120_MACH_BR_61X4WG + bool "Edimax BR-6104WG/6114WG support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_EDIMAX + default y + +config ADM5120_MACH_EASY5120_RT + bool "Infineon EASY 5120-RT Reference Board support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_INFINEON + default y + +config ADM5120_MACH_EASY5120_WVOIP + bool "Infineon EASY 5120-WVoIP Reference Board support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_INFINEON + default y + +config ADM5120_MACH_EASY5120P_ATA + bool "Infineon EASY 5120P-ATA Reference Board support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_OEM_INFINEON + default y + +config ADM5120_MACH_EASY83000 + bool "Infineon EASY 83000 Reference Board support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_OEM_INFINEON + default y + +config ADM5120_MACH_RB_11X + bool "MikroTik RouterBOARD 111/112 support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_MIKROTIK + default y + +config ADM5120_MACH_RB_133 + bool "MikroTik RouterBOARD 133 support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_MIKROTIK + default y + +config ADM5120_MACH_RB_133C + bool "MikroTik RouterBOARD 133C support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_MIKROTIK + default y + +config ADM5120_MACH_RB_150 + bool "MikroTik RouterBOARD 150 support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_OEM_MIKROTIK + default y + +config ADM5120_MACH_RB_153 + bool "MikroTik RouterBOARD 153 support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_MIKROTIK + default y + +config ADM5120_MACH_RB_192 + bool "MikroTik RouterBOARD 192 support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_MIKROTIK + default y + +config ADM5120_MACH_PMUGW + bool "Motorola Powerline MU Gateway" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_MOTOROLA + default y + +config ADM5120_MACH_5GXI + bool "OSBRiDGE 5GXi/5XLi support" + depends on CPU_LITTLE_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_OSBRIDGE + default y + +config ADM5120_MACH_P_334WT + bool "ZyXEL Prestige 334WT" + depends on CPU_BIG_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_ZYXEL + default y + +config ADM5120_MACH_P_335 + bool "ZyXEL Prestige 335/335WT" + depends on CPU_BIG_ENDIAN + select ADM5120_SOC_BGA + select ADM5120_OEM_ZYXEL + default y + +endmenu + +config ADM5120_SOC_BGA + select HW_HAS_PCI + def_bool n + +config ADM5120_OEM_CELLVISION + def_bool n + +config ADM5120_OEM_COMPEX + def_bool n + +config ADM5120_OEM_EDIMAX + def_bool n + +config ADM5120_OEM_GENERIC + def_bool n + +config ADM5120_OEM_INFINEON + def_bool n + +config ADM5120_OEM_MIKROTIK + def_bool n + +config ADM5120_OEM_MOTOROLA + def_bool n + +config ADM5120_OEM_OSBRIDGE + def_bool n + +config ADM5120_OEM_ZYXEL + def_bool n + +config ARM_AMBA + def_bool y + +endif diff --git a/target/linux/adm5120/files/arch/mips/adm5120/Platform b/target/linux/adm5120/files/arch/mips/adm5120/Platform new file mode 100644 index 000000000..0c9edf218 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/Platform @@ -0,0 +1,19 @@ +# +# Infineon/ADMtek ADM5120 +# + +platform-$(CONFIG_ADM5120) += adm5120/common/ + +platform-$(CONFIG_ADM5120_OEM_CELLVISION) += adm5120/cellvision/ +platform-$(CONFIG_ADM5120_OEM_COMPEX) += adm5120/compex/ +platform-$(CONFIG_ADM5120_OEM_EDIMAX) += adm5120/edimax/ +platform-$(CONFIG_ADM5120_OEM_GENERIC) += adm5120/generic/ +platform-$(CONFIG_ADM5120_OEM_INFINEON) += adm5120/infineon/ +platform-$(CONFIG_ADM5120_OEM_MIKROTIK) += adm5120/mikrotik/ +platform-$(CONFIG_ADM5120_OEM_MOTOROLA) += adm5120/motorola/ +platform-$(CONFIG_ADM5120_OEM_OSBRIDGE) += adm5120/osbridge/ +platform-$(CONFIG_ADM5120_OEM_ZYXEL) += adm5120/zyxel/ + +cflags-$(CONFIG_ADM5120) += -I$(srctree)/arch/mips/include/asm/mach-adm5120 +libs-$(CONFIG_ADM5120) += arch/mips/adm5120/prom/ +load-$(CONFIG_ADM5120) += 0xffffffff80001000 diff --git a/target/linux/adm5120/files/arch/mips/adm5120/cellvision/Makefile b/target/linux/adm5120/files/arch/mips/adm5120/cellvision/Makefile new file mode 100644 index 000000000..a949fc9f6 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/cellvision/Makefile @@ -0,0 +1,4 @@ +obj-y += cellvision.o + +obj-$(CONFIG_ADM5120_MACH_CAS_771) += cas-771.o +obj-$(CONFIG_ADM5120_MACH_NFS_101) += nfs-101.o diff --git a/target/linux/adm5120/files/arch/mips/adm5120/cellvision/cas-771.c b/target/linux/adm5120/files/arch/mips/adm5120/cellvision/cas-771.c new file mode 100644 index 000000000..5033e0246 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/cellvision/cas-771.c @@ -0,0 +1,37 @@ +/* + * Cellvision/SparkLAN CAS-771/771W support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "cellvision.h" + +static struct adm5120_pci_irq cas771_pci_irqs[] __initdata = { + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI0), + PCIIRQ(3, 0, 1, ADM5120_IRQ_PCI1), + PCIIRQ(3, 2, 3, ADM5120_IRQ_PCI2) +}; + +static struct gpio_led cas771_gpio_leds[] __initdata = { + GPIO_LED_STD(ADM5120_GPIO_PIN0, "cam_flash", NULL), + /* GPIO PIN3 is the reset */ + GPIO_LED_STD(ADM5120_GPIO_PIN6, "access", NULL), + GPIO_LED_STD(ADM5120_GPIO_P0L1, "status", NULL), + GPIO_LED_STD(ADM5120_GPIO_P0L2, "diag", NULL), +}; + +static void __init cas771_setup(void) +{ + cas7xx_setup(); + adm5120_add_device_gpio_leds(ARRAY_SIZE(cas771_gpio_leds), + cas771_gpio_leds); + adm5120_pci_set_irq_map(ARRAY_SIZE(cas771_pci_irqs), cas771_pci_irqs); +} + +MIPS_MACHINE(MACH_ADM5120_CAS771, "CAS-771", "Cellvision CAS-771/771W", + cas771_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/cellvision/cellvision.c b/target/linux/adm5120/files/arch/mips/adm5120/cellvision/cellvision.c new file mode 100644 index 000000000..a7cedf03b --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/cellvision/cellvision.c @@ -0,0 +1,147 @@ +/* + * Cellvision/SparkLAN boards + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "cellvision.h" + +#include + +#define CELLVISION_GPIO_FLASH_A20 ADM5120_GPIO_PIN5 +#define CELLVISION_GPIO_DEV_MASK (1 << CELLVISION_GPIO_FLASH_A20) + +#define CELLVISION_CONFIG_OFFSET 0x8000 +#define CELLVISION_CONFIG_SIZE 0x1000 + +static struct mtd_partition cas6xx_partitions[] = { + { + .name = "admboot", + .offset = 0, + .size = 32*1024, + .mask_flags = MTD_WRITEABLE, + } , { + .name = "config", + .offset = MTDPART_OFS_APPEND, + .size = 32*1024, + } , { + .name = "nvfs1", + .offset = MTDPART_OFS_APPEND, + .size = 64*1024, + } , { + .name = "nvfs2", + .offset = MTDPART_OFS_APPEND, + .size = 64*1024, + } , { + .name = "firmware", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct mtd_partition cas7xx_partitions[] = { + { + .name = "admboot", + .offset = 0, + .size = 32*1024, + .mask_flags = MTD_WRITEABLE, + } , { + .name = "config", + .offset = MTDPART_OFS_APPEND, + .size = 32*1024, + } , { + .name = "nvfs", + .offset = MTDPART_OFS_APPEND, + .size = 128*1024, + } , { + .name = "firmware", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + } +}; + +static void switch_bank_gpio5(unsigned bank) +{ + switch (bank) { + case 0: + gpio_set_value(CELLVISION_GPIO_FLASH_A20, 0); + break; + case 1: + gpio_set_value(CELLVISION_GPIO_FLASH_A20, 1); + break; + } +} + +static void __init cellvision_flash_setup(void) +{ + /* setup flash A20 line */ + gpio_request(CELLVISION_GPIO_FLASH_A20, NULL); + gpio_direction_output(CELLVISION_GPIO_FLASH_A20, 0); + + adm5120_flash0_data.switch_bank = switch_bank_gpio5; + adm5120_add_device_flash(0); +} + +void __init cellvision_mac_setup(void) +{ + u8 mac_base[6]; + int err; + + err = admboot_get_mac_base(CELLVISION_CONFIG_OFFSET, + CELLVISION_CONFIG_SIZE, mac_base); + + if ((err) || !is_valid_ether_addr(mac_base)) + random_ether_addr(mac_base); + + adm5120_setup_eth_macs(mac_base); +} + +void __init cas6xx_flash_setup(void) +{ + adm5120_flash0_data.nr_parts = ARRAY_SIZE(cas6xx_partitions); + adm5120_flash0_data.parts = cas6xx_partitions; + + cellvision_flash_setup(); +} + +void __init cas7xx_flash_setup(void) +{ + adm5120_flash0_data.nr_parts = ARRAY_SIZE(cas7xx_partitions); + adm5120_flash0_data.parts = cas7xx_partitions; + + cellvision_flash_setup(); +} + +void __init cas6xx_setup(void) +{ + cas6xx_flash_setup(); + adm5120_add_device_uart(0); + adm5120_add_device_uart(1); + adm5120_add_device_switch(1, NULL); +} + +MIPS_MACHINE(MACH_ADM5120_CAS630, "CAS-630", "Cellvision CAS-630/630W", + cas6xx_setup); +MIPS_MACHINE(MACH_ADM5120_CAS670, "CAS-670", "Cellvision CAS-670/670W", + cas6xx_setup); + +void __init cas7xx_setup(void) +{ + cas7xx_flash_setup(); + cellvision_mac_setup(); + adm5120_add_device_uart(0); + adm5120_add_device_uart(1); + adm5120_add_device_switch(1, NULL); +} + +MIPS_MACHINE(MACH_ADM5120_CAS700, "CAS-700", "Cellvision CAS-700/700W", + cas7xx_setup); +MIPS_MACHINE(MACH_ADM5120_CAS790, "CAS-790", "Cellvision CAS-790", + cas7xx_setup); +MIPS_MACHINE(MACH_ADM5120_CAS861, "CAS-861", "Cellvision CAS-861/861W", + cas7xx_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/cellvision/cellvision.h b/target/linux/adm5120/files/arch/mips/adm5120/cellvision/cellvision.h new file mode 100644 index 000000000..2b55ebf76 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/cellvision/cellvision.h @@ -0,0 +1,28 @@ +/* + * Cellvision/SparkLAN boards + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include + +extern void cellvision_mac_setup(void) __init; + +extern void cas6xx_flash_setup(void) __init; +extern void cas7xx_flash_setup(void) __init; +extern void cas6xx_setup(void) __init; +extern void cas7xx_setup(void) __init; diff --git a/target/linux/adm5120/files/arch/mips/adm5120/cellvision/nfs-101.c b/target/linux/adm5120/files/arch/mips/adm5120/cellvision/nfs-101.c new file mode 100644 index 000000000..7d214c090 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/cellvision/nfs-101.c @@ -0,0 +1,47 @@ +/* + * Cellvision/SparkLAN NFS-101U/WU support + * + * Copyright (C) 2007-2009 Gabor Juhos + * + * This program 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. + * + */ + +#include "cellvision.h" + +static struct adm5120_pci_irq nfs101_pci_irqs[] __initdata = { + /* miniPCI slot */ + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI0), + + /* ALi USB controller */ + PCIIRQ(3, 0, 2, ADM5120_IRQ_PCI2), + PCIIRQ(3, 3, 1, ADM5120_IRQ_PCI1), + + /* NEC USB controller */ + PCIIRQ(3, 0, 1, ADM5120_IRQ_PCI1), + PCIIRQ(3, 1, 2, ADM5120_IRQ_PCI2), + PCIIRQ(3, 2, 3, ADM5120_IRQ_PCI2), +}; + +static u8 nfs101_vlans[6] __initdata = { + /* FIXME: not tested */ + 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static void __init nfs101_setup(void) +{ + cas6xx_flash_setup(); + cellvision_mac_setup(); + + adm5120_add_device_uart(0); + adm5120_add_device_uart(1); + adm5120_add_device_switch(1, nfs101_vlans); + + adm5120_pci_set_irq_map(ARRAY_SIZE(nfs101_pci_irqs), + nfs101_pci_irqs); +} + +MIPS_MACHINE(MACH_ADM5120_NFS101U, "NFS-101U", "Cellvision NFS-101U/101WU", + nfs101_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/common/Makefile b/target/linux/adm5120/files/arch/mips/adm5120/common/Makefile new file mode 100644 index 000000000..8d302c593 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/common/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the Infineon/ADMtek ADM5120 SoC specific parts of the kernel +# + +obj-y := adm5120.o setup.o prom.o irq.o memory.o clock.o \ + gpio.o platform.o + +obj-$(CONFIG_EARLY_PRINTK) += early-printk.o diff --git a/target/linux/adm5120/files/arch/mips/adm5120/common/adm5120.c b/target/linux/adm5120/files/arch/mips/adm5120/common/adm5120.c new file mode 100644 index 000000000..28388342c --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/common/adm5120.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include + +unsigned int adm5120_product_code; +unsigned int adm5120_revision; +unsigned int adm5120_package; +unsigned int adm5120_nand_boot; +unsigned long adm5120_speed; + +/* + * CPU settings detection + */ +#define CODE_GET_PC(c) ((c) & CODE_PC_MASK) +#define CODE_GET_REV(c) (((c) >> CODE_REV_SHIFT) & CODE_REV_MASK) +#define CODE_GET_PK(c) (((c) >> CODE_PK_SHIFT) & CODE_PK_MASK) +#define CODE_GET_CLKS(c) (((c) >> CODE_CLKS_SHIFT) & CODE_CLKS_MASK) +#define CODE_GET_NAB(c) (((c) & CODE_NAB) != 0) + +void adm5120_ndelay(u32 ns) +{ + u32 t; + + SW_WRITE_REG(SWITCH_REG_TIMER, TIMER_PERIOD_DEFAULT); + SW_WRITE_REG(SWITCH_REG_TIMER_INT, (TIMER_INT_TOS | TIMER_INT_TOM)); + + t = (ns+640) / 640; + t &= TIMER_PERIOD_MASK; + SW_WRITE_REG(SWITCH_REG_TIMER, t | TIMER_TE); + + /* wait until the timer expires */ + do { + t = SW_READ_REG(SWITCH_REG_TIMER_INT); + } while ((t & TIMER_INT_TOS) == 0); + + /* leave the timer disabled */ + SW_WRITE_REG(SWITCH_REG_TIMER, TIMER_PERIOD_DEFAULT); + SW_WRITE_REG(SWITCH_REG_TIMER_INT, (TIMER_INT_TOS | TIMER_INT_TOM)); +} + +void __init adm5120_soc_init(void) +{ + u32 code; + u32 clks; + + code = SW_READ_REG(SWITCH_REG_CODE); + + adm5120_product_code = CODE_GET_PC(code); + adm5120_revision = CODE_GET_REV(code); + adm5120_package = (CODE_GET_PK(code) == CODE_PK_BGA) ? + ADM5120_PACKAGE_BGA : ADM5120_PACKAGE_PQFP; + adm5120_nand_boot = CODE_GET_NAB(code); + + clks = CODE_GET_CLKS(code); + adm5120_speed = ADM5120_SPEED_175; + if (clks & 1) + adm5120_speed += 25000000; + if (clks & 2) + adm5120_speed += 50000000; +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/common/clock.c b/target/linux/adm5120/files/arch/mips/adm5120/common/clock.c new file mode 100644 index 000000000..52ae64c41 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/common/clock.c @@ -0,0 +1,65 @@ +/* + * ADM5120 minimal CLK API implementation + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This file was based on the CLK API implementation in: + * arch/mips/tx4938/toshiba_rbtx4938/setup.c + * Copyright (C) 2000-2001 Toshiba Corporation + * 2003-2005 (c) MontaVista Software, Inc. + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include + +#include + +struct clk { + unsigned long rate; +}; + +static struct clk uart_clk = { + .rate = ADM5120_UART_CLOCK +}; + +struct clk *clk_get(struct device *dev, const char *id) +{ + const char *name = dev_name(dev); + + if (!strcmp(name, "apb:uart0") || !strcmp(name, "apb:uart1")) + return &uart_clk; + + return ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL(clk_get); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/common/early-printk.c b/target/linux/adm5120/files/arch/mips/adm5120/common/early-printk.c new file mode 100644 index 000000000..d90071263 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/common/early-printk.c @@ -0,0 +1,31 @@ +/* + * ADM5120 specific early printk support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include + +#include +#include +#include + +#define UART_READ(r) \ + __raw_readl((void __iomem *)(KSEG1ADDR(ADM5120_UART0_BASE)+(r))) +#define UART_WRITE(r, v) \ + __raw_writel((v), (void __iomem *)(KSEG1ADDR(ADM5120_UART0_BASE)+(r))) + +void __init prom_putchar(char ch) +{ + while ((UART_READ(UART_REG_FLAG) & UART_FLAG_TXFE) == 0) + ; + UART_WRITE(UART_REG_DATA, ch); + while ((UART_READ(UART_REG_FLAG) & UART_FLAG_TXFE) == 0) + ; +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/common/gpio.c b/target/linux/adm5120/files/arch/mips/adm5120/common/gpio.c new file mode 100644 index 000000000..e60ed7ad0 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/common/gpio.c @@ -0,0 +1,330 @@ +/* + * ADM5120 generic GPIO API support via GPIOLIB + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#define GPIO_REG(r) (void __iomem *)(KSEG1ADDR(ADM5120_SWITCH_BASE) + r) + +struct gpio1_desc { + void __iomem *reg; /* register address */ + u8 iv_shift; /* shift amount for input bit */ + u8 mode_shift; /* shift amount for mode bits */ +}; + +#define GPIO1_DESC(p, l) { \ + .reg = GPIO_REG(SWITCH_REG_PORT0_LED + ((p) * 4)), \ + .iv_shift = LED0_IV_SHIFT + (l), \ + .mode_shift = (l) * 4 \ + } + +static struct gpio1_desc gpio1_table[15] = { + GPIO1_DESC(0, 0), GPIO1_DESC(0, 1), GPIO1_DESC(0, 2), + GPIO1_DESC(1, 0), GPIO1_DESC(1, 1), GPIO1_DESC(1, 2), + GPIO1_DESC(2, 0), GPIO1_DESC(2, 1), GPIO1_DESC(2, 2), + GPIO1_DESC(3, 0), GPIO1_DESC(3, 1), GPIO1_DESC(3, 2), + GPIO1_DESC(4, 0), GPIO1_DESC(4, 1), GPIO1_DESC(4, 2) +}; + +static u32 gpio_conf2; + +int adm5120_gpio_to_irq(unsigned gpio) +{ + int ret; + + switch (gpio) { + case ADM5120_GPIO_PIN2: + ret = ADM5120_IRQ_GPIO2; + break; + case ADM5120_GPIO_PIN4: + ret = ADM5120_IRQ_GPIO4; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} +EXPORT_SYMBOL(adm5120_gpio_to_irq); + +int adm5120_irq_to_gpio(unsigned irq) +{ + int ret; + + switch (irq) { + case ADM5120_IRQ_GPIO2: + ret = ADM5120_GPIO_PIN2; + break; + case ADM5120_IRQ_GPIO4: + ret = ADM5120_GPIO_PIN4; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} +EXPORT_SYMBOL(adm5120_irq_to_gpio); + +/* + * Helpers for GPIO lines in GPIO_CONF0 register + */ +#define PIN_IM(p) ((1 << GPIO_CONF0_IM_SHIFT) << p) +#define PIN_IV(p) ((1 << GPIO_CONF0_IV_SHIFT) << p) +#define PIN_OE(p) ((1 << GPIO_CONF0_OE_SHIFT) << p) +#define PIN_OV(p) ((1 << GPIO_CONF0_OV_SHIFT) << p) + +int __adm5120_gpio0_get_value(unsigned offset) +{ + void __iomem **reg; + u32 t; + + reg = GPIO_REG(SWITCH_REG_GPIO_CONF0); + + t = __raw_readl(reg); + if ((t & PIN_IM(offset)) != 0) + t &= PIN_IV(offset); + else + t &= PIN_OV(offset); + + return (t) ? 1 : 0; +} +EXPORT_SYMBOL(__adm5120_gpio0_get_value); + +void __adm5120_gpio0_set_value(unsigned offset, int value) +{ + void __iomem **reg; + u32 t; + + reg = GPIO_REG(SWITCH_REG_GPIO_CONF0); + + t = __raw_readl(reg); + if (value == 0) + t &= ~(PIN_OV(offset)); + else + t |= PIN_OV(offset); + + __raw_writel(t, reg); +} +EXPORT_SYMBOL(__adm5120_gpio0_set_value); + +static int adm5120_gpio0_get_value(struct gpio_chip *chip, unsigned offset) +{ + return __adm5120_gpio0_get_value(offset); +} + +static void adm5120_gpio0_set_value(struct gpio_chip *chip, + unsigned offset, int value) +{ + __adm5120_gpio0_set_value(offset, value); +} + +static int adm5120_gpio0_direction_input(struct gpio_chip *chip, + unsigned offset) +{ + void __iomem **reg; + u32 t; + + reg = GPIO_REG(SWITCH_REG_GPIO_CONF0); + + t = __raw_readl(reg); + t &= ~(PIN_OE(offset)); + t |= PIN_IM(offset); + __raw_writel(t, reg); + + return 0; +} + +static int adm5120_gpio0_direction_output(struct gpio_chip *chip, + unsigned offset, int value) +{ + void __iomem **reg; + u32 t; + + reg = GPIO_REG(SWITCH_REG_GPIO_CONF0); + + t = __raw_readl(reg); + t &= ~(PIN_IM(offset) | PIN_OV(offset)); + t |= PIN_OE(offset); + + if (value) + t |= PIN_OV(offset); + + __raw_writel(t, reg); + + return 0; +} + +static struct gpio_chip adm5120_gpio0_chip = { + .label = "adm5120 gpio0", + .get = adm5120_gpio0_get_value, + .set = adm5120_gpio0_set_value, + .direction_input = adm5120_gpio0_direction_input, + .direction_output = adm5120_gpio0_direction_output, + .base = ADM5120_GPIO_PIN0, + .ngpio = ADM5120_GPIO_PIN7 - ADM5120_GPIO_PIN0 + 1, +}; + +int __adm5120_gpio1_get_value(unsigned offset) +{ + void __iomem **reg; + u32 t, m; + + reg = gpio1_table[offset].reg; + + t = __raw_readl(reg); + m = (t >> gpio1_table[offset].mode_shift) & LED_MODE_MASK; + if (m == LED_MODE_INPUT) + return (t >> gpio1_table[offset].iv_shift) & 1; + + if (m == LED_MODE_OUT_LOW) + return 0; + + return 1; +} +EXPORT_SYMBOL(__adm5120_gpio1_get_value); + +void __adm5120_gpio1_set_value(unsigned offset, int value) +{ + void __iomem **reg; + u32 t, s; + + reg = gpio1_table[offset].reg; + s = gpio1_table[offset].mode_shift; + + t = __raw_readl(reg); + t &= ~(LED_MODE_MASK << s); + + switch (value) { + case ADM5120_GPIO_LOW: + t |= (LED_MODE_OUT_LOW << s); + break; + case ADM5120_GPIO_FLASH: + case ADM5120_GPIO_LINK: + case ADM5120_GPIO_SPEED: + case ADM5120_GPIO_DUPLEX: + case ADM5120_GPIO_ACT: + case ADM5120_GPIO_COLL: + case ADM5120_GPIO_LINK_ACT: + case ADM5120_GPIO_DUPLEX_COLL: + case ADM5120_GPIO_10M_ACT: + case ADM5120_GPIO_100M_ACT: + t |= ((value & LED_MODE_MASK) << s); + break; + default: + t |= (LED_MODE_OUT_HIGH << s); + break; + } + + __raw_writel(t, reg); +} +EXPORT_SYMBOL(__adm5120_gpio1_set_value); + +static int adm5120_gpio1_get_value(struct gpio_chip *chip, unsigned offset) +{ + return __adm5120_gpio1_get_value(offset); +} + +static void adm5120_gpio1_set_value(struct gpio_chip *chip, + unsigned offset, int value) +{ + __adm5120_gpio1_set_value(offset, value); +} + +static int adm5120_gpio1_direction_input(struct gpio_chip *chip, + unsigned offset) +{ + void __iomem **reg; + u32 t; + + reg = gpio1_table[offset].reg; + t = __raw_readl(reg); + t &= ~(LED_MODE_MASK << gpio1_table[offset].mode_shift); + __raw_writel(t, reg); + + return 0; +} + +static int adm5120_gpio1_direction_output(struct gpio_chip *chip, + unsigned offset, int value) +{ + __adm5120_gpio1_set_value(offset, value); + return 0; +} + +static struct gpio_chip adm5120_gpio1_chip = { + .label = "adm5120 gpio1", + .get = adm5120_gpio1_get_value, + .set = adm5120_gpio1_set_value, + .direction_input = adm5120_gpio1_direction_input, + .direction_output = adm5120_gpio1_direction_output, + .base = ADM5120_GPIO_P0L0, + .ngpio = ADM5120_GPIO_P4L2 - ADM5120_GPIO_P0L0 + 1, +}; + +void __init adm5120_gpio_csx0_enable(void) +{ + gpio_conf2 |= GPIO_CONF2_CSX0; + SW_WRITE_REG(SWITCH_REG_GPIO_CONF2, gpio_conf2); + + gpio_request(ADM5120_GPIO_PIN1, "CSX0"); +} + +void __init adm5120_gpio_csx1_enable(void) +{ + gpio_conf2 |= GPIO_CONF2_CSX1; + SW_WRITE_REG(SWITCH_REG_GPIO_CONF2, gpio_conf2); + + gpio_request(ADM5120_GPIO_PIN3, "CSX1"); +} + +void __init adm5120_gpio_ew_enable(void) +{ + gpio_conf2 |= GPIO_CONF2_EW; + SW_WRITE_REG(SWITCH_REG_GPIO_CONF2, gpio_conf2); + + gpio_request(ADM5120_GPIO_PIN0, "EW"); +} + +void __init adm5120_gpio_init(void) +{ + int err; + + SW_WRITE_REG(SWITCH_REG_GPIO_CONF2, gpio_conf2); + + if (adm5120_package_pqfp()) { + gpiochip_reserve(ADM5120_GPIO_PIN4, 4); + adm5120_gpio0_chip.ngpio = 4; + } + + err = gpiochip_add(&adm5120_gpio0_chip); + if (err) + panic("cannot add ADM5120 GPIO0 chip, error=%d", err); + + err = gpiochip_add(&adm5120_gpio1_chip); + if (err) + panic("cannot add ADM5120 GPIO1 chip, error=%d", err); + +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/common/irq.c b/target/linux/adm5120/files/arch/mips/adm5120/common/irq.c new file mode 100644 index 000000000..a26e65176 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/common/irq.c @@ -0,0 +1,171 @@ +/* + * ADM5120 specific interrupt handlers + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +static void adm5120_intc_irq_unmask(struct irq_data *d); +static void adm5120_intc_irq_mask(struct irq_data *d); +static int adm5120_intc_irq_set_type(struct irq_data *d, unsigned int flow_type); + +static inline void intc_write_reg(unsigned int reg, u32 val) +{ + void __iomem *base = (void __iomem *)KSEG1ADDR(ADM5120_INTC_BASE); + + __raw_writel(val, base + reg); +} + +static inline u32 intc_read_reg(unsigned int reg) +{ + void __iomem *base = (void __iomem *)KSEG1ADDR(ADM5120_INTC_BASE); + + return __raw_readl(base + reg); +} + +static struct irq_chip adm5120_intc_irq_chip = { + .name = "INTC", + .irq_unmask = adm5120_intc_irq_unmask, + .irq_mask = adm5120_intc_irq_mask, + .irq_mask_ack = adm5120_intc_irq_mask, + .irq_set_type = adm5120_intc_irq_set_type +}; + +static struct irqaction adm5120_intc_irq_action = { + .handler = no_action, + .name = "cascade [INTC]" +}; + +static void adm5120_intc_irq_unmask(struct irq_data *d) +{ + intc_write_reg(INTC_REG_IRQ_ENABLE, 1 << (d->irq - ADM5120_INTC_IRQ_BASE)); +} + +static void adm5120_intc_irq_mask(struct irq_data *d) +{ + intc_write_reg(INTC_REG_IRQ_DISABLE, 1 << (d->irq - ADM5120_INTC_IRQ_BASE)); +} + +static int adm5120_intc_irq_set_type(struct irq_data *d, unsigned int flow_type) +{ + unsigned int irq = d->irq; + unsigned int sense; + unsigned long mode; + int err = 0; + + sense = flow_type & (IRQ_TYPE_SENSE_MASK); + switch (sense) { + case IRQ_TYPE_NONE: + case IRQ_TYPE_LEVEL_HIGH: + break; + case IRQ_TYPE_LEVEL_LOW: + switch (irq) { + case ADM5120_IRQ_GPIO2: + case ADM5120_IRQ_GPIO4: + break; + default: + err = -EINVAL; + break; + } + break; + default: + err = -EINVAL; + break; + } + + if (err) + return err; + + switch (irq) { + case ADM5120_IRQ_GPIO2: + case ADM5120_IRQ_GPIO4: + mode = intc_read_reg(INTC_REG_INT_MODE); + if (sense == IRQ_TYPE_LEVEL_LOW) + mode |= (1 << (irq - ADM5120_INTC_IRQ_BASE)); + else + mode &= ~(1 << (irq - ADM5120_INTC_IRQ_BASE)); + + intc_write_reg(INTC_REG_INT_MODE, mode); + break; + } + + return 0; +} + +static void adm5120_intc_irq_dispatch(void) +{ + unsigned long status; + int irq; + + status = intc_read_reg(INTC_REG_IRQ_STATUS) & INTC_INT_ALL; + if (status) { + irq = ADM5120_INTC_IRQ_BASE + fls(status) - 1; + do_IRQ(irq); + } else + spurious_interrupt(); +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned long pending; + + pending = read_c0_status() & read_c0_cause() & ST0_IM; + + if (pending & STATUSF_IP7) + do_IRQ(ADM5120_IRQ_COUNTER); + else if (pending & STATUSF_IP2) + adm5120_intc_irq_dispatch(); + else + spurious_interrupt(); +} + +#define INTC_IRQ_STATUS (IRQ_LEVEL | IRQ_TYPE_LEVEL_HIGH | IRQ_DISABLED) +static void __init adm5120_intc_irq_init(void) +{ + int i; + + /* disable all interrupts */ + intc_write_reg(INTC_REG_IRQ_DISABLE, INTC_INT_ALL); + + /* setup all interrupts to generate IRQ instead of FIQ */ + intc_write_reg(INTC_REG_INT_MODE, 0); + + /* set active level for all external interrupts to HIGH */ + intc_write_reg(INTC_REG_INT_LEVEL, 0); + + /* disable usage of the TEST_SOURCE register */ + intc_write_reg(INTC_REG_IRQ_SOURCE_SELECT, 0); + + for (i = ADM5120_INTC_IRQ_BASE; + i <= ADM5120_INTC_IRQ_BASE + INTC_IRQ_LAST; + i++) { + irq_set_chip_and_handler(i, &adm5120_intc_irq_chip, + handle_level_irq); + } + + setup_irq(ADM5120_IRQ_INTC, &adm5120_intc_irq_action); +} + +void __init arch_init_irq(void) +{ + mips_cpu_irq_init(); + adm5120_intc_irq_init(); +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/common/memory.c b/target/linux/adm5120/files/arch/mips/adm5120/common/memory.c new file mode 100644 index 000000000..d07266fa3 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/common/memory.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#ifdef DEBUG +# define mem_dbg(f, a...) printk(KERN_INFO "mem_detect: " f, ## a) +#else +# define mem_dbg(f, a...) +#endif + +unsigned long adm5120_memsize; + +#define MEM_READL(a) __raw_readl((void __iomem *)(a)) +#define MEM_WRITEL(a, v) __raw_writel((v), (void __iomem *)(a)) + +static int __init mem_check_pattern(u8 *addr, unsigned long offs) +{ + u32 *p1 = (u32 *)addr; + u32 *p2 = (u32 *)(addr+offs); + u32 t, u, v; + + /* save original value */ + t = MEM_READL(p1); + + u = MEM_READL(p2); + if (t != u) + return 0; + + v = 0x55555555; + if (u == v) + v = 0xAAAAAAAA; + + mem_dbg("write 0x%08X to 0x%08lX\n", v, (unsigned long)p1); + + MEM_WRITEL(p1, v); + adm5120_ndelay(1000); + u = MEM_READL(p2); + + mem_dbg("pattern at 0x%08lX is 0x%08X\n", (unsigned long)p2, u); + + /* restore original value */ + MEM_WRITEL(p1, t); + + return (v == u); +} + +static void __init adm5120_detect_memsize(void) +{ + u32 memctrl; + u32 size, maxsize; + u8 *p; + + memctrl = SW_READ_REG(SWITCH_REG_MEMCTRL); + switch (memctrl & MEMCTRL_SDRS_MASK) { + case MEMCTRL_SDRS_4M: + maxsize = 4 << 20; + break; + case MEMCTRL_SDRS_8M: + maxsize = 8 << 20; + break; + case MEMCTRL_SDRS_16M: + maxsize = 16 << 20; + break; + default: + maxsize = 64 << 20; + break; + } + + mem_dbg("checking for %uMB chip in 1st bank\n", maxsize >> 20); + + /* detect size of the 1st SDRAM bank */ + p = (u8 *)KSEG1ADDR(0); + for (size = 2<<20; size <= (maxsize >> 1); size <<= 1) { + if (mem_check_pattern(p, size)) { + /* mirrored address */ + mem_dbg("mirrored data found at offset 0x%08X\n", size); + break; + } + } + + mem_dbg("chip size in 1st bank is %uMB\n", size >> 20); + adm5120_memsize = size; + + if (size != maxsize) + /* 2nd bank is not supported */ + goto out; + + if ((memctrl & MEMCTRL_SDR1_ENABLE) == 0) + /* 2nd bank is disabled */ + goto out; + + /* + * some bootloaders enable 2nd bank, even if the 2nd SDRAM chip + * are missing. + */ + mem_dbg("check presence of 2nd bank\n"); + + p = (u8 *)KSEG1ADDR(maxsize+size-4); + if (mem_check_pattern(p, 0)) + adm5120_memsize += size; + + if (maxsize != size) { + /* adjusting MECTRL register */ + memctrl &= ~(MEMCTRL_SDRS_MASK); + switch (size>>20) { + case 4: + memctrl |= MEMCTRL_SDRS_4M; + break; + case 8: + memctrl |= MEMCTRL_SDRS_8M; + break; + case 16: + memctrl |= MEMCTRL_SDRS_16M; + break; + default: + memctrl |= MEMCTRL_SDRS_64M; + break; + } + SW_WRITE_REG(SWITCH_REG_MEMCTRL, memctrl); + } + +out: + mem_dbg("%dx%uMB memory found\n", (adm5120_memsize == size) ? 1 : 2 , + size>>20); +} + +void __init adm5120_mem_init(void) +{ + adm5120_detect_memsize(); + add_memory_region(0, adm5120_memsize, BOOT_MEM_RAM); +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/common/platform.c b/target/linux/adm5120/files/arch/mips/adm5120/common/platform.c new file mode 100644 index 000000000..809d77b8a --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/common/platform.c @@ -0,0 +1,395 @@ +/* + * ADM5120 generic platform devices + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#if 1 +/* + * TODO:remove global adm5120_eth* variables when the switch driver will be + * converted into a real platform driver + */ +unsigned int adm5120_eth_num_ports = 6; +EXPORT_SYMBOL_GPL(adm5120_eth_num_ports); + +unsigned char adm5120_eth_macs[6][6] = { + {'\00', 'A', 'D', 'M', '\x51', '\x20' }, + {'\00', 'A', 'D', 'M', '\x51', '\x21' }, + {'\00', 'A', 'D', 'M', '\x51', '\x22' }, + {'\00', 'A', 'D', 'M', '\x51', '\x23' }, + {'\00', 'A', 'D', 'M', '\x51', '\x24' }, + {'\00', 'A', 'D', 'M', '\x51', '\x25' } +}; +EXPORT_SYMBOL_GPL(adm5120_eth_macs); + +unsigned char adm5120_eth_vlans[6] = { + 0x41, 0x42, 0x44, 0x48, 0x50, 0x60 +}; +EXPORT_SYMBOL_GPL(adm5120_eth_vlans); +#endif + +void __init adm5120_setup_eth_macs(u8 *mac_base) +{ + u32 t; + int i, j; + + t = ((u32) mac_base[3] << 16) | ((u32) mac_base[4] << 8) + | ((u32) mac_base[5]); + + for (i = 0; i < ARRAY_SIZE(adm5120_eth_macs); i++) { + for (j = 0; j < 3; j++) + adm5120_eth_macs[i][j] = mac_base[j]; + + adm5120_eth_macs[i][3] = (t >> 16) & 0xff; + adm5120_eth_macs[i][4] = (t >> 8) & 0xff; + adm5120_eth_macs[i][5] = t & 0xff; + + t++; + } +} + +/* + * Built-in ethernet switch + */ +struct resource adm5120_switch_resources[] = { + [0] = { + .start = ADM5120_SWITCH_BASE, + .end = ADM5120_SWITCH_BASE+ADM5120_SWITCH_SIZE-1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = ADM5120_IRQ_SWITCH, + .end = ADM5120_IRQ_SWITCH, + .flags = IORESOURCE_IRQ, + }, +}; + +struct adm5120_switch_platform_data adm5120_switch_data; +struct platform_device adm5120_switch_device = { + .name = "adm5120-switch", + .id = -1, + .num_resources = ARRAY_SIZE(adm5120_switch_resources), + .resource = adm5120_switch_resources, + .dev.platform_data = &adm5120_switch_data, +}; + +void __init adm5120_add_device_switch(unsigned num_ports, u8 *vlan_map) +{ + if (num_ports > 0) + adm5120_eth_num_ports = num_ports; + + if (vlan_map) + memcpy(adm5120_eth_vlans, vlan_map, sizeof(adm5120_eth_vlans)); + + platform_device_register(&adm5120_switch_device); +} + +/* + * USB Host Controller + */ +struct resource adm5120_hcd_resources[] = { + [0] = { + .start = ADM5120_USBC_BASE, + .end = ADM5120_USBC_BASE+ADM5120_USBC_SIZE-1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = ADM5120_IRQ_USBC, + .end = ADM5120_IRQ_USBC, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 adm5120_hcd_dma_mask = DMA_BIT_MASK(24); +struct platform_device adm5120_hcd_device = { + .name = "adm5120-hcd", + .id = -1, + .num_resources = ARRAY_SIZE(adm5120_hcd_resources), + .resource = adm5120_hcd_resources, + .dev = { + .dma_mask = &adm5120_hcd_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(24), + } +}; + +void __init adm5120_add_device_usb(void) +{ + platform_device_register(&adm5120_hcd_device); +} + +/* + * NOR flash devices + */ +struct adm5120_flash_platform_data adm5120_flash0_data; +struct platform_device adm5120_flash0_device = { + .name = "adm5120-flash", + .id = 0, + .dev.platform_data = &adm5120_flash0_data, +}; + +struct adm5120_flash_platform_data adm5120_flash1_data; +struct platform_device adm5120_flash1_device = { + .name = "adm5120-flash", + .id = 1, + .dev.platform_data = &adm5120_flash1_data, +}; + +void __init adm5120_add_device_flash(unsigned id) +{ + struct platform_device *pdev; + + switch (id) { + case 0: + pdev = &adm5120_flash0_device; + break; + case 1: + pdev = &adm5120_flash1_device; + break; + default: + pdev = NULL; + break; + } + + if (pdev) + platform_device_register(pdev); +} + +/* + * built-in UARTs + */ +static void adm5120_uart_set_mctrl(struct amba_device *dev, void __iomem *base, + unsigned int mctrl) +{ +} + +struct amba_pl010_data adm5120_uart0_data = { + .set_mctrl = adm5120_uart_set_mctrl +}; + +struct amba_device adm5120_uart0_device = { + .dev = { + .init_name = "apb:uart0", + .platform_data = &adm5120_uart0_data, + }, + .res = { + .start = ADM5120_UART0_BASE, + .end = ADM5120_UART0_BASE + ADM5120_UART_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + .irq = { ADM5120_IRQ_UART0, -1 }, + .periphid = 0x0041010, +}; + +struct amba_pl010_data adm5120_uart1_data = { + .set_mctrl = adm5120_uart_set_mctrl +}; + +struct amba_device adm5120_uart1_device = { + .dev = { + .init_name = "apb:uart1", + .platform_data = &adm5120_uart1_data, + }, + .res = { + .start = ADM5120_UART1_BASE, + .end = ADM5120_UART1_BASE + ADM5120_UART_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + .irq = { ADM5120_IRQ_UART1, -1 }, + .periphid = 0x0041010, +}; + +void __init adm5120_add_device_uart(unsigned id) +{ + struct amba_device *dev; + + switch (id) { + case 0: + dev = &adm5120_uart0_device; + break; + case 1: + dev = &adm5120_uart1_device; + break; + default: + dev = NULL; + break; + } + + if (dev) + amba_device_register(dev, &iomem_resource); +} + +/* + * GPIO buttons + */ +void __init adm5120_register_gpio_buttons(int id, + unsigned poll_interval, + unsigned nbuttons, + struct gpio_keys_button *buttons) +{ + struct platform_device *pdev; + struct gpio_keys_platform_data pdata; + struct gpio_keys_button *p; + int err; + + p = kmemdup(buttons, nbuttons * sizeof(*p), GFP_KERNEL); + if (!p) + return; + + pdev = platform_device_alloc("gpio-keys-polled", id); + if (!pdev) + goto err_free_buttons; + + memset(&pdata, 0, sizeof(pdata)); + pdata.poll_interval = poll_interval; + pdata.nbuttons = nbuttons; + pdata.buttons = p; + + err = platform_device_add_data(pdev, &pdata, sizeof(pdata)); + if (err) + goto err_put_pdev; + + err = platform_device_add(pdev); + if (err) + goto err_put_pdev; + + return; + +err_put_pdev: + platform_device_put(pdev); + +err_free_buttons: + kfree(p); +} + +/* + * GPIO LEDS + */ +struct gpio_led_platform_data adm5120_gpio_leds_data; +struct platform_device adm5120_gpio_leds_device = { + .name = "leds-gpio", + .id = -1, + .dev.platform_data = &adm5120_gpio_leds_data, +}; + +void __init adm5120_add_device_gpio_leds(unsigned num_leds, + struct gpio_led *leds) +{ + struct gpio_led *p; + + p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL); + if (!p) + return; + + memcpy(p, leds, num_leds * sizeof(*p)); + adm5120_gpio_leds_data.num_leds = num_leds; + adm5120_gpio_leds_data.leds = p; + + platform_device_register(&adm5120_gpio_leds_device); +} + +/* + * GPIO device + */ +static struct resource adm5120_gpio_resource[] __initdata = { + { + .start = 0x3fffff, + }, +}; + +void __init adm5120_add_device_gpio(u32 disable_mask) +{ + if (adm5120_package_pqfp()) + disable_mask |= 0xf0; + + adm5120_gpio_resource[0].start &= ~disable_mask; + platform_device_register_simple("GPIODEV", -1, + adm5120_gpio_resource, + ARRAY_SIZE(adm5120_gpio_resource)); +} + +/* + * NAND flash + */ +struct resource adm5120_nand_resources[] = { + [0] = { + .start = ADM5120_NAND_BASE, + .end = ADM5120_NAND_BASE + ADM5120_NAND_SIZE-1, + .flags = IORESOURCE_MEM, + }, +}; + +static int adm5120_nand_ready(struct mtd_info *mtd) +{ + return ((adm5120_nand_get_status() & ADM5120_NAND_STATUS_READY) != 0); +} + +static void adm5120_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + if (ctrl & NAND_CTRL_CHANGE) { + adm5120_nand_set_cle(ctrl & NAND_CLE); + adm5120_nand_set_ale(ctrl & NAND_ALE); + adm5120_nand_set_cen(ctrl & NAND_NCE); + } + + if (cmd != NAND_CMD_NONE) + NAND_WRITE_REG(NAND_REG_DATA, cmd); +} + +void __init adm5120_add_device_nand(struct platform_nand_data *pdata) +{ + struct platform_device *pdev; + int err; + + pdev = platform_device_alloc("gen_nand", -1); + if (!pdev) + goto err_out; + + err = platform_device_add_resources(pdev, adm5120_nand_resources, + ARRAY_SIZE(adm5120_nand_resources)); + if (err) + goto err_put; + + err = platform_device_add_data(pdev, pdata, sizeof(*pdata)); + if (err) + goto err_put; + + pdata = pdev->dev.platform_data; + pdata->ctrl.dev_ready = adm5120_nand_ready; + pdata->ctrl.cmd_ctrl = adm5120_nand_cmd_ctrl; + + err = platform_device_add(pdev); + if (err) + goto err_put; + + return; + +err_put: + platform_device_put(pdev); +err_out: + return; +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/common/prom.c b/target/linux/adm5120/files/arch/mips/adm5120/common/prom.c new file mode 100644 index 000000000..5c52ea27e --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/common/prom.c @@ -0,0 +1,264 @@ +/* + * ADM5120 specific prom routines + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +unsigned int adm5120_prom_type = ADM5120_PROM_GENERIC; + +struct board_desc { + unsigned long mach_type; + char *name; +}; + +#define DEFBOARD(n, mt) { .mach_type = (mt), .name = (n)} +static struct board_desc common_boards[] __initdata = { + /* Cellvision/SparkLAN boards */ + DEFBOARD("CAS-630", MACH_ADM5120_CAS630), + DEFBOARD("CAS-670", MACH_ADM5120_CAS670), + DEFBOARD("CAS-700", MACH_ADM5120_CAS700), + DEFBOARD("CAS-771", MACH_ADM5120_CAS771), + DEFBOARD("CAS-790", MACH_ADM5120_CAS790), + DEFBOARD("CAS-861", MACH_ADM5120_CAS861), + DEFBOARD("NFS-101U", MACH_ADM5120_NFS101U), + /* Compex boards */ + DEFBOARD("WP54G-WRT", MACH_ADM5120_WP54G_WRT), + /* Edimax boards */ + DEFBOARD("BR-6104K", MACH_ADM5120_BR6104K), + DEFBOARD("BR-6104KP", MACH_ADM5120_BR6104KP), + DEFBOARD("BR-6104WG", MACH_ADM5120_BR61X4WG), + DEFBOARD("BR-6114WG", MACH_ADM5120_BR61X4WG), + /* Infineon boards */ + DEFBOARD("EASY 5120P-ATA", MACH_ADM5120_EASY5120PATA), + DEFBOARD("EASY 5120-RT", MACH_ADM5120_EASY5120RT), + DEFBOARD("EASY 5120-WVoIP", MACH_ADM5120_EASY5120WVOIP), + DEFBOARD("EASY 83000", MACH_ADM5120_EASY83000), + /* Mikrotik RouterBOARDs */ + DEFBOARD("111", MACH_ADM5120_RB_11X), + DEFBOARD("112", MACH_ADM5120_RB_11X), + DEFBOARD("133", MACH_ADM5120_RB_133), + DEFBOARD("133C", MACH_ADM5120_RB_133C), + DEFBOARD("133C3", MACH_ADM5120_RB_133C), + DEFBOARD("150", MACH_ADM5120_RB_153), /* it's intentional */ + DEFBOARD("153", MACH_ADM5120_RB_153), + DEFBOARD("192", MACH_ADM5120_RB_192), + DEFBOARD("miniROUTER", MACH_ADM5120_RB_150), + /* OSBRiDGE boards */ + DEFBOARD("OSBRiDGE 5GXi", MACH_ADM5120_5GXI), + /* Motorola boards */ + DEFBOARD("Powerline MU Gateway", MACH_ADM5120_PMUGW), + /* Generic EB-214A */ + DEFBOARD("ADM5120", MACH_ADM5120_EB_214A), +}; + +static unsigned long __init find_machtype_byname(char *name) +{ + unsigned long ret; + int i; + + ret = MACH_ADM5120_GENERIC; + if (name == NULL) + goto out; + + if (*name == '\0') + goto out; + + for (i = 0; i < ARRAY_SIZE(common_boards); i++) { + if (strcmp(common_boards[i].name, name) == 0) { + ret = common_boards[i].mach_type; + break; + } + } + +out: + return ret; +} + +static unsigned long __init detect_machtype_routerboot(void) +{ + char *name; + + name = routerboot_get_boardname(); + return find_machtype_byname(name); +} + +static unsigned long __init detect_machtype_generic(void) +{ + char *name; + + name = generic_prom_getenv("board_name"); + return find_machtype_byname(name); +} + +unsigned long __init detect_machtype_cfe(void) +{ + char *name; + + name = cfe_getenv("BOARD_NAME"); + return find_machtype_byname(name); +} + +static struct { + unsigned long mach_type; + u16 vendor_id; + u16 board_id; +} zynos_boards[] __initdata = { +#define ZYNOS_BOARD(vi, bi, mt) \ + {.vendor_id = (vi), .board_id = (bi), .mach_type = (mt)} + +#define ZYXEL_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_ZYXEL, bi, mt) +#define DLINK_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_DLINK, bi, mt) +#define LUCENT_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_LUCENT, bi, mt) + ZYXEL_BOARD(ZYNOS_BOARD_HS100, MACH_ADM5120_HS100), + ZYXEL_BOARD(ZYNOS_BOARD_P334U, MACH_ADM5120_P334U), + ZYXEL_BOARD(ZYNOS_BOARD_P334W, MACH_ADM5120_P334W), + ZYXEL_BOARD(ZYNOS_BOARD_P334WH, MACH_ADM5120_P334WH), + ZYXEL_BOARD(ZYNOS_BOARD_P334WHD, MACH_ADM5120_P334WHD), + ZYXEL_BOARD(ZYNOS_BOARD_P334WT, MACH_ADM5120_P334WT), + ZYXEL_BOARD(ZYNOS_BOARD_P334WT_ALT, MACH_ADM5120_P334WT), + ZYXEL_BOARD(ZYNOS_BOARD_P335, MACH_ADM5120_P335), + ZYXEL_BOARD(ZYNOS_BOARD_P335PLUS, MACH_ADM5120_P335PLUS), + ZYXEL_BOARD(ZYNOS_BOARD_P335U, MACH_ADM5120_P335U) +}; + +static unsigned long __init detect_machtype_bootbase(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(zynos_boards); i++) { + if (zynos_boards[i].vendor_id == bootbase_info.vendor_id && + zynos_boards[i].board_id == bootbase_info.board_id) { + return zynos_boards[i].mach_type; + break; + } + } + + printk(KERN_WARNING "Unknown ZyXEL model (%u)\n", + bootbase_info.board_id); + return MACH_ADM5120_GENERIC; +} + +static struct { + unsigned long mach_type; + u16 vid; + u16 did; + u16 svid; + u16 sdid; +} mylo_boards[] __initdata = { +#define MYLO_BOARD(v, d, sv, sd, mt) \ + {.vid = (v), .did = (d), .svid = (sv), .sdid = (sd), .mach_type = (mt)} +#define COMPEX_BOARD(d, mt) \ + MYLO_BOARD(VENID_COMPEX, (d), VENID_COMPEX, (d), (mt)) + + COMPEX_BOARD(DEVID_COMPEX_NP27G, MACH_ADM5120_NP27G), + COMPEX_BOARD(DEVID_COMPEX_NP28G, MACH_ADM5120_NP28G), + COMPEX_BOARD(DEVID_COMPEX_NP28GHS, MACH_ADM5120_NP28GHS), + COMPEX_BOARD(DEVID_COMPEX_WP54G, MACH_ADM5120_WP54), + COMPEX_BOARD(DEVID_COMPEX_WP54Gv1C, MACH_ADM5120_WP54Gv1C), + COMPEX_BOARD(DEVID_COMPEX_WP54AG, MACH_ADM5120_WP54), + COMPEX_BOARD(DEVID_COMPEX_WPP54G, MACH_ADM5120_WP54), + COMPEX_BOARD(DEVID_COMPEX_WPP54AG, MACH_ADM5120_WP54), +}; + +static unsigned long __init detect_machtype_myloader(void) +{ + unsigned long ret; + int i; + + ret = MACH_ADM5120_GENERIC; + for (i = 0; i < ARRAY_SIZE(mylo_boards); i++) { + if (mylo_boards[i].vid == myloader_info.vid && + mylo_boards[i].did == myloader_info.did && + mylo_boards[i].svid == myloader_info.svid && + mylo_boards[i].sdid == myloader_info.sdid) { + ret = mylo_boards[i].mach_type; + break; + } + } + + return ret; +} + +static void __init prom_detect_machtype(void) +{ + if (bootbase_present()) { + adm5120_prom_type = ADM5120_PROM_BOOTBASE; + mips_machtype = detect_machtype_bootbase(); + return; + } + + if (cfe_present()) { + adm5120_prom_type = ADM5120_PROM_CFE; + mips_machtype = detect_machtype_cfe(); + return; + } + + if (myloader_present()) { + adm5120_prom_type = ADM5120_PROM_MYLOADER; + mips_machtype = detect_machtype_myloader(); + return; + } + + if (routerboot_present()) { + adm5120_prom_type = ADM5120_PROM_ROUTERBOOT; + mips_machtype = detect_machtype_routerboot(); + return; + } + + if (generic_prom_present()) { + adm5120_prom_type = ADM5120_PROM_GENERIC; + mips_machtype = detect_machtype_generic(); + return; + } + + mips_machtype = MACH_ADM5120_GENERIC; +} + +#ifdef CONFIG_IMAGE_CMDLINE_HACK +extern char __image_cmdline[]; + +static void __init prom_init_cmdline(void) +{ + char *cmd; + + /* init command line, register a default kernel command line */ + cmd = __image_cmdline; + if (strlen(cmd) > 0) + strlcpy(arcs_cmdline, cmd, sizeof(arcs_cmdline)); + +} +#else +static inline void prom_init_cmdline(void) {} +#endif /* CONFIG_IMAGE_CMDLINE_HACK */ + +void __init prom_init(void) +{ + prom_detect_machtype(); + prom_init_cmdline(); +} + +void __init prom_free_prom_memory(void) +{ + /* We do not have to prom memory to free */ +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/common/setup.c b/target/linux/adm5120/files/arch/mips/adm5120/common/setup.c new file mode 100644 index 000000000..c4be84517 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/common/setup.c @@ -0,0 +1,128 @@ +/* + * ADM5120 specific setup + * + * Copyright (C) 2007-2009 Gabor Juhos + * + * This code was based on the ADM5120 specific port of the Linux 2.6.10 kernel + * done by Jeroen Vreeken + * Copyright (C) 2005 Jeroen Vreeken (pe1rxq@amsat.org) + * + * Jeroen's code was based on the Linux 2.4.xx source codes found in various + * tarballs released by Edimax for it's ADM5120 based devices + * Copyright (C) ADMtek Incorporated + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#define ADM5120_SYS_TYPE_LEN 64 + +unsigned char adm5120_sys_type[ADM5120_SYS_TYPE_LEN]; +void (*adm5120_board_reset)(void); + +static char *prom_names[ADM5120_PROM_LAST+1] __initdata = { + [ADM5120_PROM_GENERIC] = "Generic", + [ADM5120_PROM_CFE] = "CFE", + [ADM5120_PROM_UBOOT] = "U-Boot", + [ADM5120_PROM_MYLOADER] = "MyLoader", + [ADM5120_PROM_ROUTERBOOT] = "RouterBOOT", + [ADM5120_PROM_BOOTBASE] = "Bootbase" +}; + +static void __init adm5120_report(void) +{ + printk(KERN_INFO "SoC : %s\n", adm5120_sys_type); + printk(KERN_INFO "Bootdev : %s flash\n", + adm5120_nand_boot ? "NAND" : "NOR"); + printk(KERN_INFO "Prom : %s\n", prom_names[adm5120_prom_type]); +} + +const char *get_system_type(void) +{ + return adm5120_sys_type; +} + +static void adm5120_restart(char *command) +{ + /* TODO: stop switch before reset */ + + if (adm5120_board_reset) + adm5120_board_reset(); + + SW_WRITE_REG(SWITCH_REG_SOFT_RESET, 1); +} + +static void adm5120_halt(void) +{ + local_irq_disable(); + + while (1) { + if (cpu_wait) + cpu_wait(); + } +} + +void __init plat_time_init(void) +{ + mips_hpt_frequency = adm5120_speed / 2; +} + +void __init plat_mem_setup(void) +{ + adm5120_soc_init(); + adm5120_mem_init(); + + sprintf(adm5120_sys_type, "ADM%04X%s rev %u, running at %lu.%03lu MHz", + adm5120_product_code, + adm5120_package_bga() ? "" : "P", + adm5120_revision, + (adm5120_speed / 1000000), (adm5120_speed / 1000) % 1000); + + adm5120_report(); + + _machine_restart = adm5120_restart; + _machine_halt = adm5120_halt; + pm_power_off = adm5120_halt; + + set_io_port_base(KSEG1); +} + +static int __init adm5120_board_setup(void) +{ + adm5120_gpio_init(); + + mips_machine_setup(); + + return 0; +} +arch_initcall(adm5120_board_setup); + +static void __init adm5120_generic_board_setup(void) +{ + adm5120_add_device_uart(0); + adm5120_add_device_uart(1); + + adm5120_add_device_flash(0); + adm5120_add_device_switch(6, NULL); +} + +MIPS_MACHINE(MACH_ADM5120_GENERIC, "Generic", "Generic ADM5120 board", + adm5120_generic_board_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/compex/Makefile b/target/linux/adm5120/files/arch/mips/adm5120/compex/Makefile new file mode 100644 index 000000000..8c66c171e --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/compex/Makefile @@ -0,0 +1,5 @@ +obj-y += compex.o + +obj-$(CONFIG_ADM5120_MACH_NP27G) += np27g.o +obj-$(CONFIG_ADM5120_MACH_NP28G) += np28g.o +obj-$(CONFIG_ADM5120_MACH_WP54) += wp54.o diff --git a/target/linux/adm5120/files/arch/mips/adm5120/compex/compex.c b/target/linux/adm5120/files/arch/mips/adm5120/compex/compex.c new file mode 100644 index 000000000..c14655ada --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/compex/compex.c @@ -0,0 +1,64 @@ +/* + * Compex boards + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "compex.h" + +#include + +#define COMPEX_GPIO_DEV_MASK (1 << ADM5120_GPIO_PIN5) + +static void switch_bank_gpio5(unsigned bank) +{ + switch (bank) { + case 0: + gpio_set_value(ADM5120_GPIO_PIN5, 0); + break; + case 1: + gpio_set_value(ADM5120_GPIO_PIN5, 1); + break; + } +} + +void __init compex_mac_setup(void) +{ + if (myloader_present()) { + int i; + + for (i = 0; i < 6; i++) { + if (is_valid_ether_addr(myloader_info.macs[i])) + memcpy(adm5120_eth_macs[i], + myloader_info.macs[i], ETH_ALEN); + else + random_ether_addr(adm5120_eth_macs[i]); + } + } else { + u8 mac[ETH_ALEN]; + + random_ether_addr(mac); + adm5120_setup_eth_macs(mac); + } +} + +void __init compex_generic_setup(void) +{ + gpio_request(ADM5120_GPIO_PIN5, NULL); /* for flash A20 line */ + gpio_direction_output(ADM5120_GPIO_PIN5, 0); + + adm5120_flash0_data.switch_bank = switch_bank_gpio5; + adm5120_add_device_flash(0); + + adm5120_add_device_uart(0); + adm5120_add_device_uart(1); + + adm5120_add_device_gpio(COMPEX_GPIO_DEV_MASK); + + compex_mac_setup(); +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/compex/compex.h b/target/linux/adm5120/files/arch/mips/adm5120/compex/compex.h new file mode 100644 index 000000000..124e67697 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/compex/compex.h @@ -0,0 +1,23 @@ +/* + * Compex boards + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include + +extern void compex_generic_setup(void) __init; diff --git a/target/linux/adm5120/files/arch/mips/adm5120/compex/np27g.c b/target/linux/adm5120/files/arch/mips/adm5120/compex/np27g.c new file mode 100644 index 000000000..82da46d1c --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/compex/np27g.c @@ -0,0 +1,28 @@ +/* + * Compex NP27G board support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "compex.h" + +static u8 np27g_vlans[6] __initdata = { + /* FIXME: untested */ + 0x41, 0x42, 0x44, 0x48, 0x50, 0x00 +}; + +static void __init np27g_setup(void) +{ + compex_generic_setup(); + adm5120_add_device_switch(5, np27g_vlans); + adm5120_add_device_usb(); + + /* TODO: add PCI IRQ map */ +} + +MIPS_MACHINE(MACH_ADM5120_NP27G, "NP27G", "Compex NetPassage 27G", np27g_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/compex/np28g.c b/target/linux/adm5120/files/arch/mips/adm5120/compex/np28g.c new file mode 100644 index 000000000..a54143999 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/compex/np28g.c @@ -0,0 +1,63 @@ +/* + * Compex NP28G board support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "compex.h" + +static struct adm5120_pci_irq np28g_pci_irqs[] __initdata = { + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI0), + PCIIRQ(3, 0, 1, ADM5120_IRQ_PCI0), + PCIIRQ(3, 1, 2, ADM5120_IRQ_PCI1), + PCIIRQ(3, 2, 3, ADM5120_IRQ_PCI2) +}; + +static struct gpio_led np28g_gpio_leds[] __initdata = { + GPIO_LED_INV(ADM5120_GPIO_PIN2, "diag", NULL), + GPIO_LED_INV(ADM5120_GPIO_PIN3, "power", NULL), + GPIO_LED_INV(ADM5120_GPIO_PIN6, "wan_cond", NULL), + GPIO_LED_INV(ADM5120_GPIO_PIN7, "wifi", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L2, "usb1", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L0, "lan1", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L2, "usb2", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L0, "lan2", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L2, "usb3", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L0, "lan3", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L2, "usb4", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L0, "wan", NULL), +}; + +static u8 np28g_vlans[6] __initdata = { + 0x50, 0x42, 0x44, 0x48, 0x00, 0x00 +}; + +static void np28g_reset(void) +{ + gpio_set_value(ADM5120_GPIO_PIN4, 0); +} + +static void __init np28g_setup(void) +{ + compex_generic_setup(); + + /* setup reset line */ + gpio_request(ADM5120_GPIO_PIN4, NULL); + gpio_direction_output(ADM5120_GPIO_PIN4, 1); + adm5120_board_reset = np28g_reset; + + adm5120_add_device_switch(4, np28g_vlans); + adm5120_add_device_usb(); + + adm5120_add_device_gpio_leds(ARRAY_SIZE(np28g_gpio_leds), + np28g_gpio_leds); + + adm5120_pci_set_irq_map(ARRAY_SIZE(np28g_pci_irqs), np28g_pci_irqs); +} + +MIPS_MACHINE(MACH_ADM5120_NP28G, "NP28G", "Compex NetPassage 28G", np28g_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/compex/wp54.c b/target/linux/adm5120/files/arch/mips/adm5120/compex/wp54.c new file mode 100644 index 000000000..8aa35c555 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/compex/wp54.c @@ -0,0 +1,95 @@ +/* + * Compex WP54 board support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "compex.h" + +#define WP54_KEYS_POLL_INTERVAL 20 +#define WP54_KEYS_DEBOUNCE_INTERVAL (3 * WP54_KEYS_POLL_INTERVAL) + +static struct mtd_partition wp54g_wrt_partitions[] = { + { + .name = "cfe", + .offset = 0, + .size = 0x050000, + .mask_flags = MTD_WRITEABLE, + } , { + .name = "trx", + .offset = MTDPART_OFS_APPEND, + .size = 0x3A0000, + } , { + .name = "nvram", + .offset = MTDPART_OFS_APPEND, + .size = 0x010000, + } +}; + +static struct adm5120_pci_irq wp54_pci_irqs[] __initdata = { + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI0), +}; + +static struct gpio_keys_button wp54_gpio_buttons[] __initdata = { + { + .desc = "reset_button", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = WP54_KEYS_DEBOUNCE_INTERVAL, + .gpio = ADM5120_GPIO_PIN4, + } +}; + +static struct gpio_led wp54_gpio_leds[] __initdata = { + GPIO_LED_INV(ADM5120_GPIO_PIN2, "diag", NULL), + GPIO_LED_INV(ADM5120_GPIO_PIN6, "wlan", NULL), + GPIO_LED_INV(ADM5120_GPIO_PIN7, "wan", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L0, "lan1", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L0, "lan2", NULL), +}; + +static u8 wp54_vlans[6] __initdata = { + 0x41, 0x42, 0x00, 0x00, 0x00, 0x00 +}; + +static void wp54_reset(void) +{ + gpio_set_value(ADM5120_GPIO_PIN3, 0); +} + +static void __init wp54_setup(void) +{ + compex_generic_setup(); + + /* setup reset line */ + gpio_request(ADM5120_GPIO_PIN3, NULL); + gpio_direction_output(ADM5120_GPIO_PIN3, 1); + adm5120_board_reset = wp54_reset; + + adm5120_add_device_switch(2, wp54_vlans); + adm5120_register_gpio_buttons(-1, WP54_KEYS_POLL_INTERVAL, + ARRAY_SIZE(wp54_gpio_buttons), + wp54_gpio_buttons); + adm5120_add_device_gpio_leds(ARRAY_SIZE(wp54_gpio_leds), + wp54_gpio_leds); + + adm5120_pci_set_irq_map(ARRAY_SIZE(wp54_pci_irqs), wp54_pci_irqs); +} + +MIPS_MACHINE(MACH_ADM5120_WP54, "WP54", "Compex WP54 family", wp54_setup); + +static void __init wp54_wrt_setup(void) +{ + adm5120_flash0_data.nr_parts = ARRAY_SIZE(wp54g_wrt_partitions); + adm5120_flash0_data.parts = wp54g_wrt_partitions; + + wp54_setup(); +} + +MIPS_MACHINE(MACH_ADM5120_WP54G_WRT, "WP54G-WRT", "Compex WP54G-WRT", + wp54_wrt_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/edimax/Makefile b/target/linux/adm5120/files/arch/mips/adm5120/edimax/Makefile new file mode 100644 index 000000000..1286ed4c1 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/edimax/Makefile @@ -0,0 +1,5 @@ +obj-y := br-61xx.o + +obj-$(CONFIG_ADM5120_MACH_BR_6104K) += br-6104k.o +obj-$(CONFIG_ADM5120_MACH_BR_6104KP) += br-6104kp.o +obj-$(CONFIG_ADM5120_MACH_BR_61X4WG) += br-61x4wg.o diff --git a/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-6104k.c b/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-6104k.c new file mode 100644 index 000000000..8b2b44550 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-6104k.c @@ -0,0 +1,36 @@ +/* + * Edimax BR-6104K board support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "br-61xx.h" + +static struct gpio_led br6104k_gpio_leds[] __initdata = { + GPIO_LED_STD(ADM5120_GPIO_PIN0, "power", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L1, "wan_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L0, "wan_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L1, "lan1_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L0, "lan1_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L1, "lan2_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L0, "lan2_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L1, "lan3_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L0, "lan3_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L1, "lan4_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L0, "lan4_lnkact", NULL), +}; + +static void __init br6104k_setup(void) +{ + br61xx_generic_setup(); + adm5120_add_device_gpio_leds(ARRAY_SIZE(br6104k_gpio_leds), + br6104k_gpio_leds); +} + +MIPS_MACHINE(MACH_ADM5120_BR6104K, "BR-6104K", "Edimax BR-6104K", + br6104k_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-6104kp.c b/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-6104kp.c new file mode 100644 index 000000000..034575d6b --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-6104kp.c @@ -0,0 +1,39 @@ +/* + * Edimax BR-6104KP board support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "br-61xx.h" + +static struct gpio_led br6104kp_gpio_leds[] __initdata = { + GPIO_LED_STD(ADM5120_GPIO_PIN0, "power", NULL), + GPIO_LED_INV(ADM5120_GPIO_PIN3, "usb1", NULL), + GPIO_LED_INV(ADM5120_GPIO_PIN1, "usb2", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L1, "wan_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L0, "wan_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L1, "lan1_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L0, "lan1_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L1, "lan2_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L0, "lan2_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L1, "lan3_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L0, "lan3_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L1, "lan4_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L0, "lan4_lnkact", NULL), +}; + +static void __init br6104kp_setup(void) +{ + br61xx_generic_setup(); + adm5120_add_device_gpio_leds(ARRAY_SIZE(br6104kp_gpio_leds), + br6104kp_gpio_leds); + adm5120_add_device_usb(); +} + +MIPS_MACHINE(MACH_ADM5120_BR6104KP, "BR-6104KP", "Edimax BR-6104KP", + br6104kp_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-61x4wg.c b/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-61x4wg.c new file mode 100644 index 000000000..5d5750710 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-61x4wg.c @@ -0,0 +1,43 @@ +/* + * Edimax BR-6104Wg/6114WG board support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "br-61xx.h" + +static struct adm5120_pci_irq br61x4wg_pci_irqs[] __initdata = { + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI0), +}; + +static struct gpio_led br61x4wg_gpio_leds[] __initdata = { + GPIO_LED_STD(ADM5120_GPIO_PIN0, "power", NULL), + GPIO_LED_STD(ADM5120_GPIO_PIN5, "wlan", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L1, "wan_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L0, "wan_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L1, "lan1_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L0, "lan1_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L1, "lan2_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L0, "lan2_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L1, "lan3_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L0, "lan3_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L1, "lan4_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L0, "lan4_lnkact", NULL), +}; + +static void __init br61x4wg_setup(void) +{ + br61xx_generic_setup(); + adm5120_add_device_gpio_leds(ARRAY_SIZE(br61x4wg_gpio_leds), + br61x4wg_gpio_leds); + adm5120_pci_set_irq_map(ARRAY_SIZE(br61x4wg_pci_irqs), + br61x4wg_pci_irqs); +} + +MIPS_MACHINE(MACH_ADM5120_BR61X4WG, "BR-6104WG", "Edimax BR-6104WG/6114WG", + br61x4wg_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-61xx.c b/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-61xx.c new file mode 100644 index 000000000..cc64ccba2 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-61xx.c @@ -0,0 +1,88 @@ +/* + * Edimax BR-61xx support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "br-61xx.h" + +#include + +#define BR61XX_GPIO_DEV_MASK 0 + +#define BR61XX_CONFIG_OFFSET 0x8000 +#define BR61XX_CONFIG_SIZE 0x1000 + +#define BR61XX_KEYS_POLL_INTERVAL 20 +#define BR61XX_KEYS_DEBOUNCE_INTERVAL (3 * BR61XX_KEYS_POLL_INTERVAL) + +static struct mtd_partition br61xx_partitions[] = { + { + .name = "admboot", + .offset = 0, + .size = 32*1024, + .mask_flags = MTD_WRITEABLE, + } , { + .name = "config", + .offset = MTDPART_OFS_APPEND, + .size = 32*1024, + } , { + .name = "firmware", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct gpio_keys_button br61xx_gpio_buttons[] __initdata = { + { + .desc = "reset_button", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = BR61XX_KEYS_DEBOUNCE_INTERVAL, + .gpio = ADM5120_GPIO_PIN2, + } +}; + +static u8 br61xx_vlans[6] __initdata = { + 0x41, 0x42, 0x44, 0x48, 0x50, 0x00 +}; + +static void __init br61xx_mac_setup(void) +{ + u8 mac_base[6]; + int err; + + err = admboot_get_mac_base(BR61XX_CONFIG_OFFSET, + BR61XX_CONFIG_SIZE, mac_base); + + if ((err) || !is_valid_ether_addr(mac_base)) + random_ether_addr(mac_base); + + adm5120_setup_eth_macs(mac_base); +} + +void __init br61xx_generic_setup(void) +{ + + adm5120_flash0_data.nr_parts = ARRAY_SIZE(br61xx_partitions); + adm5120_flash0_data.parts = br61xx_partitions; + adm5120_add_device_flash(0); + + adm5120_add_device_gpio(BR61XX_GPIO_DEV_MASK); + + adm5120_add_device_uart(0); + adm5120_add_device_uart(1); + + adm5120_add_device_switch(5, br61xx_vlans); + + adm5120_register_gpio_buttons(-1, BR61XX_KEYS_POLL_INTERVAL, + ARRAY_SIZE(br61xx_gpio_buttons), + br61xx_gpio_buttons); + + br61xx_mac_setup(); +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-61xx.h b/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-61xx.h new file mode 100644 index 000000000..c4a9eced5 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/edimax/br-61xx.h @@ -0,0 +1,23 @@ +/* + * Edimax BR-61xx board support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include + +extern void __init br61xx_generic_setup(void) __init; diff --git a/target/linux/adm5120/files/arch/mips/adm5120/generic/Makefile b/target/linux/adm5120/files/arch/mips/adm5120/generic/Makefile new file mode 100644 index 000000000..0c032e3a5 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/generic/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ADM5120_MACH_EB_214A) += eb-214a.o diff --git a/target/linux/adm5120/files/arch/mips/adm5120/generic/eb-214a.c b/target/linux/adm5120/files/arch/mips/adm5120/generic/eb-214a.c new file mode 100644 index 000000000..c62c147c5 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/generic/eb-214a.c @@ -0,0 +1,123 @@ +/* + * EB-214A board support + * + * Copyright (C) 2007-2008 Gabor Juhos + * Copyright (C) 2010 Cezary Jackiewicz + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + + +#define EB214A_GPIO_DEV_MASK 0 +#define EB214A_CONFIG_OFFSET 0x4000 + +#define EB214A_KEYS_POLL_INTERVAL 20 +#define EB214A_KEYS_DEBOUNCE_INTERVAL (3 * EB214A_KEYS_POLL_INTERVAL) + +static struct mtd_partition eb214a_partitions[] = { + { + .name = "bootloader", + .offset = 0, + .size = 32*1024, + .mask_flags = MTD_WRITEABLE, + } , { + .name = "config", + .offset = MTDPART_OFS_APPEND, + .size = 32*1024, + } , { + .name = "firmware", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct adm5120_pci_irq eb214a_pci_irqs[] __initdata = { + PCIIRQ(4, 0, 1, ADM5120_IRQ_PCI0), + PCIIRQ(4, 1, 2, ADM5120_IRQ_PCI0), + PCIIRQ(4, 2, 3, ADM5120_IRQ_PCI0), +}; + +static struct gpio_led eb214a_gpio_leds[] __initdata = { + GPIO_LED_INV(ADM5120_GPIO_PIN7, "power", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L0, "lan", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L0, "usb1", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L1, "usb2", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L2, "usb3", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L0, "usb4", NULL), +}; + +static struct gpio_keys_button eb214a_gpio_buttons[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = EB214A_KEYS_DEBOUNCE_INTERVAL, + .gpio = ADM5120_GPIO_PIN1, + } +}; + +static u8 eb214a_vlans[6] __initdata = { + 0x41, 0x42, 0x44, 0x48, 0x50, 0x00 +}; + +static void __init eb214a_mac_setup(void) +{ + u8 mac_base[6]; + u8 *cfg; + int i; + + cfg = (u8 *) KSEG1ADDR(ADM5120_SRAM0_BASE + EB214A_CONFIG_OFFSET); + for (i = 0; i < 6; i++) + mac_base[i] = cfg[i]; + + if (!is_valid_ether_addr(mac_base)) + random_ether_addr(mac_base); + + adm5120_setup_eth_macs(mac_base); +} + +static void __init eb214a_setup(void) +{ + adm5120_flash0_data.nr_parts = ARRAY_SIZE(eb214a_partitions); + adm5120_flash0_data.parts = eb214a_partitions; + adm5120_add_device_flash(0); + + adm5120_add_device_gpio(EB214A_GPIO_DEV_MASK); + + adm5120_add_device_uart(0); + /* adm5120_add_device_uart(1); */ + + adm5120_add_device_switch(5, eb214a_vlans); + + eb214a_mac_setup(); + + adm5120_register_gpio_buttons(-1, EB214A_KEYS_POLL_INTERVAL, + ARRAY_SIZE(eb214a_gpio_buttons), + eb214a_gpio_buttons); + + adm5120_add_device_gpio_leds(ARRAY_SIZE(eb214a_gpio_leds), + eb214a_gpio_leds); + + adm5120_pci_set_irq_map(ARRAY_SIZE(eb214a_pci_irqs), + eb214a_pci_irqs); + /* adm5120_add_device_usb(); */ +} + +MIPS_MACHINE(MACH_ADM5120_EB_214A, "EB-214A", "Generic EB-214A", eb214a_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/infineon/Makefile b/target/linux/adm5120/files/arch/mips/adm5120/infineon/Makefile new file mode 100644 index 000000000..49453cba9 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/infineon/Makefile @@ -0,0 +1,6 @@ +obj-y += infineon.o + +obj-$(CONFIG_ADM5120_MACH_EASY5120_RT) += easy5120-rt.o +obj-$(CONFIG_ADM5120_MACH_EASY5120_WVOIP) += easy5120-wvoip.o +obj-$(CONFIG_ADM5120_MACH_EASY5120P_ATA) += easy5120p-ata.o +obj-$(CONFIG_ADM5120_MACH_EASY83000) += easy83000.o diff --git a/target/linux/adm5120/files/arch/mips/adm5120/infineon/easy5120-rt.c b/target/linux/adm5120/files/arch/mips/adm5120/infineon/easy5120-rt.c new file mode 100644 index 000000000..31eaee772 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/infineon/easy5120-rt.c @@ -0,0 +1,48 @@ +/* + * Infineon EASY 5120-RT Reference Board support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "infineon.h" + +static struct gpio_led easy5120_rt_gpio_leds[] __initdata = { + GPIO_LED_INV(ADM5120_GPIO_PIN6, "user", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L0, "lan0_led1", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L1, "lan0_led2", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L0, "lan1_led1", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L1, "lan1_led2", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L0, "lan2_led1", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L1, "lan2_led2", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L0, "lan3_led1", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L1, "lan3_led2", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L0, "wan", NULL), +}; + +static struct adm5120_pci_irq easy5120_rt_pci_irqs[] __initdata = { + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI0), +}; + +static u8 easy5120_rt_vlans[6] __initdata = { + 0x41, 0x42, 0x44, 0x48, 0x50, 0x00 +}; + +static void __init easy5120_rt_setup(void) +{ + easy_setup_bga(); + + adm5120_add_device_switch(5, easy5120_rt_vlans); + adm5120_add_device_usb(); + adm5120_add_device_gpio_leds(ARRAY_SIZE(easy5120_rt_gpio_leds), + easy5120_rt_gpio_leds); + adm5120_pci_set_irq_map(ARRAY_SIZE(easy5120_rt_pci_irqs), + easy5120_rt_pci_irqs); +} + +MIPS_MACHINE(MACH_ADM5120_EASY5120RT, "EASY5120-RT", + "Infineon EASY 5120-RT Reference Board", easy5120_rt_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/infineon/easy5120-wvoip.c b/target/linux/adm5120/files/arch/mips/adm5120/infineon/easy5120-wvoip.c new file mode 100644 index 000000000..0bf404cc2 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/infineon/easy5120-wvoip.c @@ -0,0 +1,24 @@ +/* + * Infineon EASY 5120-WVoIP Reference Board support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "infineon.h" + +static void __init easy5120wvoip_setup(void) +{ + easy_setup_bga(); + adm5120_add_device_switch(6, NULL); + + /* TODO: add VINETIC2 device */ + /* TODO: setup PCI IRQ map */ +} + +MIPS_MACHINE(MACH_ADM5120_EASY5120WVOIP, "EASY5120WVoIP", + "Infineon EASY 5120-WVoIP Reference Board", easy5120wvoip_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/infineon/easy5120p-ata.c b/target/linux/adm5120/files/arch/mips/adm5120/infineon/easy5120p-ata.c new file mode 100644 index 000000000..fafe0238b --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/infineon/easy5120p-ata.c @@ -0,0 +1,22 @@ +/* + * Infineon EASY 5120P-ATA Reference Board support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "infineon.h" + +static void __init easy5120pata_setup(void) +{ + easy_setup_pqfp(); + + adm5120_add_device_switch(6, NULL); +} + +MIPS_MACHINE(MACH_ADM5120_EASY5120PATA, "EASY5120P-ATA", + "Infineon EASY 5120P-ATA Reference Board", easy5120pata_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/infineon/easy83000.c b/target/linux/adm5120/files/arch/mips/adm5120/infineon/easy83000.c new file mode 100644 index 000000000..051b85274 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/infineon/easy83000.c @@ -0,0 +1,23 @@ +/* + * Infineon EASY 83000 Reference Board support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "infineon.h" + +static void __init easy83000_setup(void) +{ + easy_setup_pqfp(); + adm5120_add_device_switch(6, NULL); + + /* TODO: add VINAX device */ +} + +MIPS_MACHINE(MACH_ADM5120_EASY83000, "EASY8300", + "Infineon EASY 83000 Reference Board", easy83000_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/infineon/infineon.c b/target/linux/adm5120/files/arch/mips/adm5120/infineon/infineon.c new file mode 100644 index 000000000..5c441da90 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/infineon/infineon.c @@ -0,0 +1,108 @@ +/* + * Infineon Reference Boards + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "infineon.h" + +#include + +#define EASY_CONFIG_OFFSET 0x10000 +#define EASY_CONFIG_SIZE 0x1000 + +static struct mtd_partition easy_partitions[] = { + { + .name = "admboot", + .offset = 0, + .size = 64*1024, + .mask_flags = MTD_WRITEABLE, + } , { + .name = "boardcfg", + .offset = MTDPART_OFS_APPEND, + .size = 64*1024, + } , { + .name = "firmware", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + } +}; + +static __init void easy_setup_mac(void) +{ + u8 mac_base[6]; + int err; + + err = admboot_get_mac_base(EASY_CONFIG_OFFSET, + EASY_CONFIG_SIZE, mac_base); + + if ((err) || !is_valid_ether_addr(mac_base)) + random_ether_addr(mac_base); + + adm5120_setup_eth_macs(mac_base); +} + +static void switch_bank_gpio3(unsigned bank) +{ + switch (bank) { + case 0: + gpio_set_value(ADM5120_GPIO_PIN3, 0); + break; + case 1: + gpio_set_value(ADM5120_GPIO_PIN3, 1); + break; + } +} + +void __init easy_setup_pqfp(void) +{ + /* setup flash A20 line */ + gpio_request(ADM5120_GPIO_PIN3, NULL); + gpio_direction_output(ADM5120_GPIO_PIN3, 0); + adm5120_flash0_data.switch_bank = switch_bank_gpio3; + + adm5120_flash0_data.nr_parts = ARRAY_SIZE(easy_partitions); + adm5120_flash0_data.parts = easy_partitions; + + adm5120_add_device_uart(0); + adm5120_add_device_uart(1); + + adm5120_add_device_flash(0); + + easy_setup_mac(); +} + +static void switch_bank_gpio5(unsigned bank) +{ + switch (bank) { + case 0: + gpio_set_value(ADM5120_GPIO_PIN5, 0); + break; + case 1: + gpio_set_value(ADM5120_GPIO_PIN5, 1); + break; + } +} + +void __init easy_setup_bga(void) +{ + /* setup flash A20 line */ + gpio_request(ADM5120_GPIO_PIN5, NULL); + gpio_direction_output(ADM5120_GPIO_PIN5, 0); + adm5120_flash0_data.switch_bank = switch_bank_gpio5; + + adm5120_flash0_data.nr_parts = ARRAY_SIZE(easy_partitions); + adm5120_flash0_data.parts = easy_partitions; + + adm5120_add_device_uart(0); + adm5120_add_device_uart(1); + + adm5120_add_device_flash(0); + + easy_setup_mac(); +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/infineon/infineon.h b/target/linux/adm5120/files/arch/mips/adm5120/infineon/infineon.h new file mode 100644 index 000000000..a5f28b4fe --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/infineon/infineon.h @@ -0,0 +1,25 @@ +/* + * Infineon Reference Boards + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +extern void easy_setup_pqfp(void) __init; +extern void easy_setup_bga(void) __init; diff --git a/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/Makefile b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/Makefile new file mode 100644 index 000000000..34ea0a3d8 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/Makefile @@ -0,0 +1,8 @@ +obj-y += rb-1xx.o + +obj-${CONFIG_ADM5120_MACH_RB_11X} += rb-11x.o +obj-${CONFIG_ADM5120_MACH_RB_133} += rb-133.o +obj-${CONFIG_ADM5120_MACH_RB_133C} += rb-133c.o +obj-${CONFIG_ADM5120_MACH_RB_150} += rb-150.o +obj-${CONFIG_ADM5120_MACH_RB_153} += rb-153.o +obj-${CONFIG_ADM5120_MACH_RB_192} += rb-192.o diff --git a/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-11x.c b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-11x.c new file mode 100644 index 000000000..30625c920 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-11x.c @@ -0,0 +1,36 @@ +/* + * Mikrotik RouterBOARD 111/112 support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "rb-1xx.h" + +static struct gpio_led rb11x_gpio_leds[] __initdata = { + GPIO_LED_STD(ADM5120_GPIO_PIN3, "user", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L1, "lan_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L0, "lan_lnkact", NULL), +}; + +static u8 rb11x_vlans[6] __initdata = { + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static void __init rb11x_setup(void) +{ + rb1xx_generic_setup(); + rb1xx_add_device_nand(); + + adm5120_add_device_switch(1, rb11x_vlans); + adm5120_add_device_gpio(0); + adm5120_add_device_gpio_leds(ARRAY_SIZE(rb11x_gpio_leds), + rb11x_gpio_leds); +} + +MIPS_MACHINE(MACH_ADM5120_RB_11X, "11x", "Mikrotik RouterBOARD 111/112", + rb11x_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-133.c b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-133.c new file mode 100644 index 000000000..4d8fae011 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-133.c @@ -0,0 +1,41 @@ +/* + * Mikrotik RouterBOARD 133 support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "rb-1xx.h" + +static struct gpio_led rb133_gpio_leds[] __initdata = { + GPIO_LED_STD(ADM5120_GPIO_PIN6, "power", NULL), + GPIO_LED_STD(ADM5120_GPIO_PIN5, "user", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L1, "lan1_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L0, "lan1_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L1, "lan2_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L0, "lan2_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L1, "lan3_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L0, "lan3_lnkact", NULL), +}; + +static u8 rb133_vlans[6] __initdata = { + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static void __init rb133_setup(void) +{ + rb1xx_generic_setup(); + rb1xx_add_device_nand(); + + adm5120_add_device_switch(3, rb133_vlans); + adm5120_add_device_gpio(0); + adm5120_add_device_gpio_leds(ARRAY_SIZE(rb133_gpio_leds), + rb133_gpio_leds); +} + +MIPS_MACHINE(MACH_ADM5120_RB_133, "133", "Mikrotik RouterBOARD 133", + rb133_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-133c.c b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-133c.c new file mode 100644 index 000000000..11924c132 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-133c.c @@ -0,0 +1,37 @@ +/* + * Mikrotik RouterBOARD 133C support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "rb-1xx.h" + +static struct gpio_led rb133c_gpio_leds[] __initdata = { + GPIO_LED_STD(ADM5120_GPIO_PIN6, "power", NULL), + GPIO_LED_STD(ADM5120_GPIO_PIN5, "user", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L1, "lan1_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L0, "lan1_lnkact", NULL), +}; + +static u8 rb133c_vlans[6] __initdata = { + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static void __init rb133c_setup(void) +{ + rb1xx_generic_setup(); + rb1xx_add_device_nand(); + + adm5120_add_device_switch(1, rb133c_vlans); + adm5120_add_device_gpio(0); + adm5120_add_device_gpio_leds(ARRAY_SIZE(rb133c_gpio_leds), + rb133c_gpio_leds); +} + +MIPS_MACHINE(MACH_ADM5120_RB_133C, "133C", "Mikrotik RouterBOARD 133C", + rb133c_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-150.c b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-150.c new file mode 100644 index 000000000..af9525635 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-150.c @@ -0,0 +1,137 @@ +/* + * Mikrotik RouterBOARD 150 support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "rb-1xx.h" + +#define RB150_NAND_BASE 0x1FC80000 +#define RB150_NAND_SIZE 1 + +#define RB150_GPIO_NAND_READY ADM5120_GPIO_PIN0 +#define RB150_GPIO_NAND_NCE ADM5120_GPIO_PIN1 +#define RB150_GPIO_NAND_CLE ADM5120_GPIO_P2L2 +#define RB150_GPIO_NAND_ALE ADM5120_GPIO_P3L2 +#define RB150_GPIO_RESET_BUTTON ADM5120_GPIO_PIN1 /* FIXME */ + +#define RB150_GPIO_DEV_MASK (1 << RB150_GPIO_NAND_READY \ + | 1 << RB150_GPIO_NAND_NCE \ + | 1 << RB150_GPIO_NAND_CLE \ + | 1 << RB150_GPIO_NAND_ALE) + +#define RB150_NAND_DELAY 100 + +#define RB150_NAND_WRITE(v) \ + writeb((v), (void __iomem *)KSEG1ADDR(RB150_NAND_BASE)) + +static struct resource rb150_nand_resources[] __initdata = { + [0] = { + .start = RB150_NAND_BASE, + .end = RB150_NAND_BASE + RB150_NAND_SIZE-1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct gpio_led rb150_gpio_leds[] __initdata = { + GPIO_LED_STD(ADM5120_GPIO_P0L2, "user", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L1, "lan1_led1", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L0, "lan1_led2", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L1, "lan5_led1", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L0, "lan5_led2", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L1, "lan4_led1", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L0, "lan4_led2", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L1, "lan3_led1", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L0, "lan3_led2", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L1, "lan2_led1", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L0, "lan2_led2", NULL), +}; + +static u8 rb150_vlans[6] __initdata = { + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static int rb150_nand_dev_ready(struct mtd_info *mtd) +{ + return gpio_get_value(RB150_GPIO_NAND_READY); +} + +static void rb150_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + if (ctrl & NAND_CTRL_CHANGE) { + gpio_set_value(RB150_GPIO_NAND_CLE, (ctrl & NAND_CLE) ? 1 : 0); + gpio_set_value(RB150_GPIO_NAND_ALE, (ctrl & NAND_ALE) ? 1 : 0); + gpio_set_value(RB150_GPIO_NAND_NCE, (ctrl & NAND_NCE) ? 0 : 1); + } + + udelay(RB150_NAND_DELAY); + + if (cmd != NAND_CMD_NONE) + RB150_NAND_WRITE(cmd); +} + +static void __init rb150_add_device_nand(void) +{ + struct platform_device *pdev; + int err; + + /* setup GPIO pins for NAND flash chip */ + gpio_request(RB150_GPIO_NAND_READY, "nand-ready"); + gpio_direction_input(RB150_GPIO_NAND_READY); + gpio_request(RB150_GPIO_NAND_NCE, "nand-nce"); + gpio_direction_output(RB150_GPIO_NAND_NCE, 1); + gpio_request(RB150_GPIO_NAND_CLE, "nand-cle"); + gpio_direction_output(RB150_GPIO_NAND_CLE, 0); + gpio_request(RB150_GPIO_NAND_ALE, "nand-ale"); + gpio_direction_output(RB150_GPIO_NAND_ALE, 0); + + pdev = platform_device_alloc("gen_nand", -1); + if (!pdev) + goto err_out; + + err = platform_device_add_resources(pdev, rb150_nand_resources, + ARRAY_SIZE(rb150_nand_resources)); + if (err) + goto err_put; + + + rb1xx_nand_data.ctrl.cmd_ctrl = rb150_nand_cmd_ctrl; + rb1xx_nand_data.ctrl.dev_ready = rb150_nand_dev_ready; + + err = platform_device_add_data(pdev, &rb1xx_nand_data, + sizeof(rb1xx_nand_data)); + if (err) + goto err_put; + + err = platform_device_add(pdev); + if (err) + goto err_put; + + return; + +err_put: + platform_device_put(pdev); +err_out: + return; +} + +static void __init rb150_setup(void) +{ + rb1xx_gpio_buttons[0].gpio = RB150_GPIO_RESET_BUTTON; + rb1xx_generic_setup(); + rb150_add_device_nand(); + + adm5120_add_device_gpio(RB150_GPIO_DEV_MASK); + adm5120_add_device_gpio_leds(ARRAY_SIZE(rb150_gpio_leds), + rb150_gpio_leds); + adm5120_add_device_switch(5, rb150_vlans); +} + +MIPS_MACHINE(MACH_ADM5120_RB_150, "miniROUTER", "Mikrotik RouterBOARD 150", + rb150_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-153.c b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-153.c new file mode 100644 index 000000000..b2ebdc7c1 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-153.c @@ -0,0 +1,75 @@ +/* + * Mikrotik RouterBOARD 153 support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "rb-1xx.h" + +#define RB153_GPIO_DEV_MASK (1 << ADM5120_GPIO_PIN0 \ + | 1 << ADM5120_GPIO_PIN3 \ + | 1 << ADM5120_GPIO_PIN4) + +static struct resource rb153_cf_resources[] __initdata = { + { + .name = "cf_membase", + .start = ADM5120_EXTIO1_BASE, + .end = ADM5120_EXTIO1_BASE + ADM5120_EXTIO1_SIZE-1 , + .flags = IORESOURCE_MEM + }, { + .name = "cf_irq", + .start = ADM5120_IRQ_GPIO4, + .end = ADM5120_IRQ_GPIO4, + .flags = IORESOURCE_IRQ + } +}; + +static struct gpio_led rb153_gpio_leds[] __initdata = { + GPIO_LED_STD(ADM5120_GPIO_PIN5, "user", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L1, "lan1_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L0, "lan1_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L1, "lan5_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L0, "lan5_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L1, "lan4_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L0, "lan4_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L1, "lan3_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L0, "lan3_lnkact", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L1, "lan2_speed", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L0, "lan2_lnkact", NULL), +}; + +static u8 rb153_vlans[6] __initdata = { + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static void __init rb153_add_device_cf(void) +{ + /* enable CSX1:INTX1 on GPIO[3:4] for the CF slot */ + adm5120_gpio_csx1_enable(); + + /* enable the wait state pin GPIO[0] for external I/O control */ + adm5120_gpio_ew_enable(); + + platform_device_register_simple("pata-rb153-cf", -1, + rb153_cf_resources, ARRAY_SIZE(rb153_cf_resources)); +} + +static void __init rb153_setup(void) +{ + rb1xx_generic_setup(); + rb1xx_add_device_nand(); + rb153_add_device_cf(); + + adm5120_add_device_gpio(RB153_GPIO_DEV_MASK); + adm5120_add_device_gpio_leds(ARRAY_SIZE(rb153_gpio_leds), + rb153_gpio_leds); + adm5120_add_device_switch(5, rb153_vlans); +} + +MIPS_MACHINE(MACH_ADM5120_RB_153, "150", "Mikrotik RouterBOARD 153", + rb153_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-192.c b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-192.c new file mode 100644 index 000000000..8cf8941b7 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-192.c @@ -0,0 +1,28 @@ +/* + * Mikrotik RouterBOARD 192 support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "rb-1xx.h" + +static u8 rb192_vlans[6] __initdata = { + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static void __init rb192_setup(void) +{ + rb1xx_generic_setup(); + rb1xx_add_device_nand(); + + adm5120_add_device_gpio(0); + adm5120_add_device_switch(6, rb192_vlans); +} + +MIPS_MACHINE(MACH_ADM5120_RB_192, "192", "Mikrotik RouterBOARD 192", + rb192_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-1xx.c b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-1xx.c new file mode 100644 index 000000000..2ad8c4220 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-1xx.c @@ -0,0 +1,150 @@ +/* + * Mikrotik RouterBOARD 1xx series support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * NAND initialization code was based on a driver for Linux 2.6.19+ which + * was derived from the driver for Linux 2.4.xx published by Mikrotik for + * their RouterBoard 1xx and 5xx series boards. + * Copyright (C) 2007 David Goodenough + * Copyright (C) 2007 Florian Fainelli + * + * This program 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. + * + */ + +#include "rb-1xx.h" + +#define RB1XX_NAND_CHIP_DELAY 25 + +#define RB1XX_KEYS_POLL_INTERVAL 20 +#define RB1XX_KEYS_DEBOUNCE_INTERVAL (3 * RB1XX_KEYS_POLL_INTERVAL) + +static struct adm5120_pci_irq rb1xx_pci_irqs[] __initdata = { + PCIIRQ(1, 0, 1, ADM5120_IRQ_PCI0), + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI1), + PCIIRQ(3, 0, 1, ADM5120_IRQ_PCI2) +}; + +static struct mtd_partition rb1xx_nor_parts[] = { + { + .name = "booter", + .offset = 0, + .size = 64*1024, + .mask_flags = MTD_WRITEABLE, + } , { + .name = "firmware", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct mtd_partition rb1xx_nand_parts[] = { + { + .name = "kernel", + .offset = 0, + .size = 4 * 1024 * 1024, + } , { + .name = "rootfs", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + } +}; + +/* + * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader + * will not be able to find the kernel that we load. So set the oobinfo + * when creating the partitions + */ +static struct nand_ecclayout rb1xx_nand_ecclayout = { + .eccbytes = 6, + .eccpos = { 8, 9, 10, 13, 14, 15 }, + .oobavail = 9, + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } +}; + +/*--------------------------------------------------------------------------*/ + +static int rb1xx_nand_fixup(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + + if (mtd->writesize == 512) + chip->ecc.layout = &rb1xx_nand_ecclayout; + + return 0; +} + +struct platform_nand_data rb1xx_nand_data __initdata = { + .chip = { + .nr_chips = 1, + .nr_partitions = ARRAY_SIZE(rb1xx_nand_parts), + .partitions = rb1xx_nand_parts, + .chip_delay = RB1XX_NAND_CHIP_DELAY, + .options = NAND_NO_AUTOINCR, + .chip_fixup = rb1xx_nand_fixup, + }, +}; + +struct gpio_keys_button rb1xx_gpio_buttons[] __initdata = { + { + .desc = "reset_button", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = RB1XX_KEYS_DEBOUNCE_INTERVAL, + .gpio = ADM5120_GPIO_PIN7, + } +}; + +static void __init rb1xx_mac_setup(void) +{ + if (rb_hs.mac_base != NULL && is_valid_ether_addr(rb_hs.mac_base)) { + adm5120_setup_eth_macs(rb_hs.mac_base); + } else { + u8 mac[ETH_ALEN]; + + random_ether_addr(mac); + adm5120_setup_eth_macs(mac); + } +} + +void __init rb1xx_add_device_flash(void) +{ + /* setup data for flash0 device */ + adm5120_flash0_data.nr_parts = ARRAY_SIZE(rb1xx_nor_parts); + adm5120_flash0_data.parts = rb1xx_nor_parts; + adm5120_flash0_data.window_size = 128*1024; + + adm5120_add_device_flash(0); +} + +void __init rb1xx_add_device_nand(void) +{ + /* enable NAND flash interface */ + adm5120_nand_enable(); + + /* initialize NAND chip */ + adm5120_nand_set_spn(1); + adm5120_nand_set_wpn(0); + + adm5120_add_device_nand(&rb1xx_nand_data); +} + +void __init rb1xx_generic_setup(void) +{ + if (adm5120_package_bga()) + adm5120_pci_set_irq_map(ARRAY_SIZE(rb1xx_pci_irqs), + rb1xx_pci_irqs); + + adm5120_add_device_uart(0); + adm5120_add_device_uart(1); + + adm5120_register_gpio_buttons(-1, RB1XX_KEYS_POLL_INTERVAL, + ARRAY_SIZE(rb1xx_gpio_buttons), + rb1xx_gpio_buttons); + + rb1xx_add_device_flash(); + rb1xx_mac_setup(); +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-1xx.h b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-1xx.h new file mode 100644 index 000000000..05e68bd0a --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/mikrotik/rb-1xx.h @@ -0,0 +1,33 @@ +/* + * Mikrotik RouterBOARD 1xx series support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +extern struct platform_nand_data rb1xx_nand_data __initdata; +extern struct gpio_keys_button rb1xx_gpio_buttons[] __initdata; + +extern void rb1xx_add_device_flash(void) __init; +extern void rb1xx_add_device_nand(void) __init; +extern void rb1xx_generic_setup(void) __init; diff --git a/target/linux/adm5120/files/arch/mips/adm5120/motorola/Makefile b/target/linux/adm5120/files/arch/mips/adm5120/motorola/Makefile new file mode 100644 index 000000000..239d5a088 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/motorola/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ADM5120_MACH_PMUGW) += pmugw.o diff --git a/target/linux/adm5120/files/arch/mips/adm5120/motorola/pmugw.c b/target/linux/adm5120/files/arch/mips/adm5120/motorola/pmugw.c new file mode 100644 index 000000000..a706e573c --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/motorola/pmugw.c @@ -0,0 +1,96 @@ +/* + * Motorola Powerline MU Gateway board + * + * Copyright (C) 2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#define PMUGW_CONFIG_OFFSET 0x10000 +#define PMUGW_CONFIG_SIZE 0x1000 + +static struct mtd_partition pmugw_partitions[] = { + { + .name = "admboot", + .offset = 0, + .size = 64*1024, + .mask_flags = MTD_WRITEABLE, + } , { + .name = "boardcfg", + .offset = MTDPART_OFS_APPEND, + .size = 64*1024, + } , { + .name = "firmware", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + } +}; + +static u8 pmugw_vlans[6] __initdata = { + 0x41, 0x42, 0x44, 0x48, 0x50, 0x00 +}; + +static __init void pmugw_setup_mac(void) +{ + u8 mac_base[6]; + int err; + + err = admboot_get_mac_base(PMUGW_CONFIG_OFFSET, + PMUGW_CONFIG_SIZE, mac_base); + + if ((err) || !is_valid_ether_addr(mac_base)) + random_ether_addr(mac_base); + + adm5120_setup_eth_macs(mac_base); +} + +static void switch_bank_gpio5(unsigned bank) +{ + switch (bank) { + case 0: + gpio_set_value(ADM5120_GPIO_PIN5, 0); + break; + case 1: + gpio_set_value(ADM5120_GPIO_PIN5, 1); + break; + } +} + +void __init pmugw_setup(void) +{ + /* setup flash A20 line */ + gpio_request(ADM5120_GPIO_PIN5, NULL); + gpio_direction_output(ADM5120_GPIO_PIN5, 0); + adm5120_flash0_data.switch_bank = switch_bank_gpio5; + + adm5120_flash0_data.nr_parts = ARRAY_SIZE(pmugw_partitions); + adm5120_flash0_data.parts = pmugw_partitions; + + adm5120_add_device_uart(1); /* ttyS0 */ + adm5120_add_device_uart(0); /* ttyS1 */ + + adm5120_add_device_flash(0); + + pmugw_setup_mac(); + adm5120_add_device_switch(5, pmugw_vlans); +} + +MIPS_MACHINE(MACH_ADM5120_PMUGW, "PMUGW", "Motorola Powerline MU Gateway", + pmugw_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/osbridge/5gxi.c b/target/linux/adm5120/files/arch/mips/adm5120/osbridge/5gxi.c new file mode 100644 index 000000000..a5c2c3653 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/osbridge/5gxi.c @@ -0,0 +1,71 @@ +/* + * OSBRiDGE 5GXi/5XLi board support + * + * Copyright (C) 2009 Gabor Juhos + * + * This program 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. + * + */ +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +static struct mtd_partition osbridge_5gxi_partitions[] = { + { + .name = "bootloader", + .offset = 0, + .size = 64*1024, + .mask_flags = MTD_WRITEABLE, + } , { + .name = "boardcfg", + .offset = 64*1024, + .size = 64*1024, + } , { + .name = "firmware", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct gpio_led osbridge_5gxi_gpio_leds[] __initdata = { + GPIO_LED_INV(ADM5120_GPIO_PIN6, "5gxi:green:user", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L0, "5gxi:yellow:lan", NULL), +}; + +static struct adm5120_pci_irq osbridge_5gxi_pci_irqs[] __initdata = { + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI0), +}; + +static u8 osbridge_5gxi_vlans[6] __initdata = { + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static void __init osbridge_5gxi_setup(void) +{ + adm5120_flash0_data.nr_parts = ARRAY_SIZE(osbridge_5gxi_partitions); + adm5120_flash0_data.parts = osbridge_5gxi_partitions; + + adm5120_add_device_uart(0); + adm5120_add_device_uart(1); + + adm5120_add_device_flash(0); + + adm5120_add_device_switch(1, osbridge_5gxi_vlans); + adm5120_add_device_gpio_leds(ARRAY_SIZE(osbridge_5gxi_gpio_leds), + osbridge_5gxi_gpio_leds); + adm5120_pci_set_irq_map(ARRAY_SIZE(osbridge_5gxi_pci_irqs), + osbridge_5gxi_pci_irqs); +} + +MIPS_MACHINE(MACH_ADM5120_5GXI, "5GXi", "OSBRiDGE 5GXi/5XLi board", + osbridge_5gxi_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/osbridge/Makefile b/target/linux/adm5120/files/arch/mips/adm5120/osbridge/Makefile new file mode 100644 index 000000000..34946c5e5 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/osbridge/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ADM5120_MACH_5GXI) += 5gxi.o diff --git a/target/linux/adm5120/files/arch/mips/adm5120/prom/Makefile b/target/linux/adm5120/files/arch/mips/adm5120/prom/Makefile new file mode 100644 index 000000000..650be4077 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/prom/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the ADMtek ADM5120 SoC specific parts of the kernel +# + +lib-y += admboot.o +lib-y += bootbase.o +lib-y += cfe.o +lib-y += generic.o +lib-y += myloader.o +lib-y += routerboot.o diff --git a/target/linux/adm5120/files/arch/mips/adm5120/prom/admboot.c b/target/linux/adm5120/files/arch/mips/adm5120/prom/admboot.c new file mode 100644 index 000000000..b655390c1 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/prom/admboot.c @@ -0,0 +1,55 @@ +/* + * ADMBoot specific prom routines + * + * Copyright (C) 2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include "prom_read.h" + +#define ADMBOOT_MAGIC_MAC_BASE 0x636D676D /* 'mgmc' */ +#define ADMBOOT_MAGIC_MAC_BASE_BR6104XX 0x31305348 /* 'HS01' */ + +int __init admboot_get_mac_base(u32 offset, u32 len, u8 *mac) +{ + u8 *cfg; + int i; + + cfg = (u8 *) KSEG1ADDR(ADM5120_SRAM0_BASE + offset); + for (i = 0; i < len; i += 4) { + u32 magic; + + magic = prom_read_le32(cfg + i); + if (magic == ADMBOOT_MAGIC_MAC_BASE) { + int j; + + for (j = 0; j < 6; j++) + mac[j] = cfg[i + 4 + j]; + + return 0; + } + if (magic == ADMBOOT_MAGIC_MAC_BASE_BR6104XX) { + int j; + + for (j = 0; j < 6; j++) + mac[j] = cfg[i + 7 + j]; + + return 0; + } + } + + return -ENXIO; +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/prom/bootbase.c b/target/linux/adm5120/files/arch/mips/adm5120/prom/bootbase.c new file mode 100644 index 000000000..063281e3f --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/prom/bootbase.c @@ -0,0 +1,119 @@ +/* + * ZyXEL's Bootbase specific prom routines + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include "prom_read.h" + +#define ZYNOS_INFO_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x3F90) +#define ZYNOS_HDBG_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x4000) +#define BOOTEXT_ADDR_MIN KSEG1ADDR(ADM5120_SRAM0_BASE) +#define BOOTEXT_ADDR_MAX (BOOTEXT_ADDR_MIN + (2*1024*1024)) + +static int bootbase_found; +static struct zynos_board_info *board_info; + +struct bootbase_info bootbase_info; + +static inline int bootbase_dbgarea_present(u8 *data) +{ + u32 t; + + t = prom_read_be32(data+5); + if (t != ZYNOS_MAGIC_DBGAREA1) + return 0; + + t = prom_read_be32(data+9); + if (t != ZYNOS_MAGIC_DBGAREA2) + return 0; + + return 1; +} + +static inline u32 bootbase_get_bootext_addr(void) +{ + return prom_read_be32(&board_info->bootext_addr); +} + +static inline void bootbase_get_mac(u8 *mac) +{ + int i; + + for (i = 0; i < 6; i++) + mac[i] = board_info->mac[i]; +} + +static inline u16 bootbase_get_vendor_id(void) +{ +#define CHECK_VENDOR(n) (strnicmp(board_info->vendor, (n), strlen(n)) == 0) + unsigned char vendor[ZYNOS_NAME_LEN]; + int i; + + for (i = 0; i < ZYNOS_NAME_LEN; i++) + vendor[i] = board_info->vendor[i]; + + if CHECK_VENDOR(ZYNOS_VENDOR_ZYXEL) + return ZYNOS_VENDOR_ID_ZYXEL; + + if CHECK_VENDOR(ZYNOS_VENDOR_DLINK) + return ZYNOS_VENDOR_ID_DLINK; + + if CHECK_VENDOR(ZYNOS_VENDOR_LUCENT) + return ZYNOS_VENDOR_ID_LUCENT; + + if CHECK_VENDOR(ZYNOS_VENDOR_NETGEAR) + return ZYNOS_VENDOR_ID_NETGEAR; + + return ZYNOS_VENDOR_ID_OTHER; +} + +static inline u16 bootbase_get_board_id(void) +{ + return prom_read_be16(&board_info->board_id); +} + +int __init bootbase_present(void) +{ + u32 t; + + if (bootbase_found) + goto out; + + /* check presence of the dbgarea */ + if (bootbase_dbgarea_present((u8 *)ZYNOS_HDBG_ADDR) == 0) + goto out; + + board_info = (struct zynos_board_info *)(ZYNOS_INFO_ADDR); + + /* check for a valid BootExt address */ + t = bootbase_get_bootext_addr(); + if ((t < BOOTEXT_ADDR_MIN) || (t > BOOTEXT_ADDR_MAX)) + goto out; + + bootbase_info.vendor_id = bootbase_get_vendor_id(); + bootbase_info.board_id = bootbase_get_board_id(); + bootbase_get_mac(bootbase_info.mac); + + bootbase_found = 1; + +out: + return bootbase_found; +} + diff --git a/target/linux/adm5120/files/arch/mips/adm5120/prom/cfe.c b/target/linux/adm5120/files/arch/mips/adm5120/prom/cfe.c new file mode 100644 index 000000000..5a343cd7e --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/prom/cfe.c @@ -0,0 +1,69 @@ +/* + * Broadcom's CFE specific prom routines + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include + +#include +#include + +#include +#include "prom_read.h" + +/* + * CFE based boards + */ +#define CFE_EPTSEAL 0x43464531 /* CFE1 is the magic number to recognize CFE +from other bootloaders */ + +static int cfe_found; + +static u32 cfe_handle; +static u32 cfe_entry; +static u32 cfe_seal; + +int __init cfe_present(void) +{ + /* + * This method only works, when we are booted directly from the CFE. + */ + u32 a1 = (u32) fw_arg1; + + if (cfe_found) + return 1; + + cfe_handle = (u32) fw_arg0; + cfe_entry = (u32) fw_arg2; + cfe_seal = (u32) fw_arg3; + + /* Check for CFE by finding the CFE magic number */ + if (cfe_seal != CFE_EPTSEAL) + return 0; + + /* cfe_a1_val must be 0, because only one CPU present in the ADM5120 */ + if (a1 != 0) + return 0; + + /* The cfe_handle, and the cfe_entry must be kernel mode addresses */ + if ((cfe_handle < KSEG0) || (cfe_entry < KSEG0)) + return 0; + + cfe_found = 1; + return 1; +} + +char *cfe_getenv(char *envname) +{ + if (cfe_found == 0) + return NULL; + + return NULL; +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/prom/generic.c b/target/linux/adm5120/files/arch/mips/adm5120/prom/generic.c new file mode 100644 index 000000000..4d4caa847 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/prom/generic.c @@ -0,0 +1,47 @@ +/* + * Generic PROM routines + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include + +#include + +#include + +static int *_prom_argc; +static char **_prom_argv; +static char **_prom_envp; + +char *generic_prom_getenv(char *envname) +{ + char **env; + char *ret; + + ret = NULL; + for (env = _prom_envp; *env != NULL; env++) { + if (strcmp(envname, *env++) == 0) { + ret = *env; + break; + } + } + + return ret; +} + +int generic_prom_present(void) +{ + _prom_argc = (int *)fw_arg0; + _prom_argv = (char **)fw_arg1; + _prom_envp = (char **)fw_arg2; + + return 1; +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/prom/myloader.c b/target/linux/adm5120/files/arch/mips/adm5120/prom/myloader.c new file mode 100644 index 000000000..5357db511 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/prom/myloader.c @@ -0,0 +1,68 @@ +/* + * Compex's MyLoader specific prom routines + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include "prom_read.h" + +#define SYS_PARAMS_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x0F000) +#define BOARD_PARAMS_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x0F800) +#define PART_TABLE_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x10000) + +static int myloader_found; + +struct myloader_info myloader_info; + +int __init myloader_present(void) +{ + struct mylo_system_params *sysp; + struct mylo_board_params *boardp; + struct mylo_partition_table *parts; + int i; + + if (myloader_found) + goto out; + + sysp = (struct mylo_system_params *)(SYS_PARAMS_ADDR); + boardp = (struct mylo_board_params *)(BOARD_PARAMS_ADDR); + parts = (struct mylo_partition_table *)(PART_TABLE_ADDR); + + /* Check for some magic numbers */ + if ((le32_to_cpu(sysp->magic) != MYLO_MAGIC_SYS_PARAMS) || + (le32_to_cpu(boardp->magic) != MYLO_MAGIC_BOARD_PARAMS) || + (le32_to_cpu(parts->magic) != MYLO_MAGIC_PARTITIONS)) + goto out; + + myloader_info.vid = le32_to_cpu(sysp->vid); + myloader_info.did = le32_to_cpu(sysp->did); + myloader_info.svid = le32_to_cpu(sysp->svid); + myloader_info.sdid = le32_to_cpu(sysp->sdid); + + for (i = 0; i < MYLO_ETHADDR_COUNT; i++) { + int j; + for (j = 0; j < 6; j++) + myloader_info.macs[i][j] = boardp->addr[i].mac[j]; + } + + myloader_found = 1; + +out: + return myloader_found; +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/prom/prom_read.h b/target/linux/adm5120/files/arch/mips/adm5120/prom/prom_read.h new file mode 100644 index 000000000..1a6ea110c --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/prom/prom_read.h @@ -0,0 +1,50 @@ +/* + * Generic prom definitions + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _ADM5120_PROM_H_ +#define _ADM5120_PROM_H_ + +/* + * Helper routines + */ +static inline u16 prom_read_le16(void *buf) +{ + u8 *p = buf; + + return ((u16)p[0] + ((u16)p[1] << 8)); +} + +static inline u32 prom_read_le32(void *buf) +{ + u8 *p = buf; + + return ((u32)p[0] + ((u32)p[1] << 8) + ((u32)p[2] << 16) + + ((u32)p[3] << 24)); +} + +static inline u16 prom_read_be16(void *buf) +{ + u8 *p = buf; + + return (((u16)p[0] << 8) + (u16)p[1]); +} + +static inline u32 prom_read_be32(void *buf) +{ + u8 *p = buf; + + return (((u32)p[0] << 24) + ((u32)p[1] << 16) + ((u32)p[2] << 8) + + ((u32)p[3])); +} + +#endif /* _ADM5120_PROM_H_ */ + + diff --git a/target/linux/adm5120/files/arch/mips/adm5120/prom/routerboot.c b/target/linux/adm5120/files/arch/mips/adm5120/prom/routerboot.c new file mode 100644 index 000000000..d9a06d968 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/prom/routerboot.c @@ -0,0 +1,121 @@ +/* + * Mikrotik's RouterBOOT specific prom routines + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include "prom_read.h" + +struct rb_hard_settings rb_hs; +static int rb_found; + +static int __init routerboot_load_hs(u8 *buf, u16 buflen) +{ + u16 id, len; + + memset(&rb_hs, 0, sizeof(rb_hs)); + + if (buflen < 4) + return -1; + + if (prom_read_le32(buf) != RB_MAGIC_HARD) + return -1; + + /* skip magic value */ + buf += 4; + buflen -= 4; + + while (buflen > 2) { + id = prom_read_le16(buf); + buf += 2; + buflen -= 2; + if (id == RB_ID_TERMINATOR || buflen < 2) + break; + + len = prom_read_le16(buf); + buf += 2; + buflen -= 2; + + if (buflen < len) + break; + + switch (id) { + case RB_ID_BIOS_VERSION: + rb_hs.bios_ver = (char *)buf; + break; + case RB_ID_BOARD_NAME: + rb_hs.name = (char *)buf; + break; + case RB_ID_MEMORY_SIZE: + rb_hs.mem_size = prom_read_le32(buf); + break; + case RB_ID_MAC_ADDRESS_COUNT: + rb_hs.mac_count = prom_read_le32(buf); + break; + case RB_ID_MAC_ADDRESS_PACK: + if ((len / RB_MAC_SIZE) > 0) + rb_hs.mac_base = buf; + break; + } + + buf += len; + buflen -= len; + + } + + return 0; +} + +#define RB_BS_OFFS 0x14 +#define RB_OFFS_MAX (128*1024) + +int __init routerboot_present(void) +{ + struct rb_bios_settings *bs; + u8 *base; + u32 off, len; + + if (rb_found) + goto out; + + base = (u8 *)KSEG1ADDR(ADM5120_SRAM0_BASE); + bs = (struct rb_bios_settings *)(base + RB_BS_OFFS); + + off = prom_read_le32(&bs->hs_offs); + len = prom_read_le32(&bs->hs_size); + if (off > RB_OFFS_MAX) + goto out; + + if (routerboot_load_hs(base+off, len) != 0) + goto out; + + rb_found = 1; + +out: + return rb_found; +} + +char *routerboot_get_boardname(void) +{ + if (rb_found == 0) + return NULL; + + return rb_hs.name; +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/zyxel/Makefile b/target/linux/adm5120/files/arch/mips/adm5120/zyxel/Makefile new file mode 100644 index 000000000..e8325a1b1 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/zyxel/Makefile @@ -0,0 +1,4 @@ +obj-y += p-33x.o + +obj-${CONFIG_ADM5120_MACH_P_334WT} += p-334wt.o +obj-${CONFIG_ADM5120_MACH_P_335} += p-335.o \ No newline at end of file diff --git a/target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-334wt.c b/target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-334wt.c new file mode 100644 index 000000000..6cc9aee85 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-334wt.c @@ -0,0 +1,34 @@ +/* + * ZyXEL Prestige P-334WT support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "p-33x.h" + +static struct gpio_led p334wt_gpio_leds[] __initdata = { + GPIO_LED_INV(ADM5120_GPIO_PIN2, "power", NULL), + GPIO_LED_INV(ADM5120_GPIO_P3L0, "lan1", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L0, "lan2", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L0, "lan3", NULL), + GPIO_LED_INV(ADM5120_GPIO_P0L0, "lan4", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L0, "wan", NULL), + GPIO_LED_INV(ADM5120_GPIO_P4L2, "wlan", NULL), + GPIO_LED_INV(ADM5120_GPIO_P2L2, "otist", NULL), + GPIO_LED_INV(ADM5120_GPIO_P1L2, "hidden", NULL), +}; + +static void __init p334wt_setup(void) +{ + p33x_generic_setup(); + adm5120_add_device_gpio_leds(ARRAY_SIZE(p334wt_gpio_leds), + p334wt_gpio_leds); +} + +MIPS_MACHINE(MACH_ADM5120_P334WT, "P-334WT", "ZyXEL Prestige 334WT", + p334wt_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-335.c b/target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-335.c new file mode 100644 index 000000000..6ac2b0915 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-335.c @@ -0,0 +1,21 @@ +/* + * ZyXEL Prestige P-335/335WT support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "p-33x.h" + +static void __init p335_setup(void) +{ + p33x_generic_setup(); + adm5120_add_device_usb(); +} + +MIPS_MACHINE(MACH_ADM5120_P335, "P-335", "ZyXEL Prestige 335/335WT", + p335_setup); diff --git a/target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-33x.c b/target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-33x.c new file mode 100644 index 000000000..7f86cab85 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-33x.c @@ -0,0 +1,89 @@ +/* + * ZyXEL Prestige P-33x boards support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include "p-33x.h" + +#include + +#define P33X_GPIO_FLASH_A20 ADM5120_GPIO_PIN5 +#define P33X_GPIO_DEV_MASK (1 << P33X_GPIO_FLASH_A20) + +static struct mtd_partition p33x_partitions[] = { + { + .name = "bootbase", + .offset = 0, + .size = 16*1024, + .mask_flags = MTD_WRITEABLE, + } , { + .name = "rom", + .offset = MTDPART_OFS_APPEND, + .size = 16*1024, + .mask_flags = MTD_WRITEABLE, + } , { + .name = "bootext1", + .offset = MTDPART_OFS_APPEND, + .size = 32*1024, + } , { + .name = "bootext2", + .offset = MTDPART_OFS_APPEND, + .size = 64*1024, + } , { + .name = "trx", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + } , { + .name = "firmware", + .offset = 32*1024, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct adm5120_pci_irq p33x_pci_irqs[] __initdata = { + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI0), +}; + +static u8 p33x_vlans[6] __initdata = { + /* FIXME: untested */ + 0x50, 0x48, 0x44, 0x42, 0x41, 0x00 +}; + +static void switch_bank_gpio5(unsigned bank) +{ + switch (bank) { + case 0: + gpio_set_value(P33X_GPIO_FLASH_A20, 0); + break; + case 1: + gpio_set_value(P33X_GPIO_FLASH_A20, 1); + break; + } +} + +void __init p33x_generic_setup(void) +{ + /* setup data for flash0 device */ + gpio_request(P33X_GPIO_FLASH_A20, NULL); /* for flash A20 line */ + gpio_direction_output(P33X_GPIO_FLASH_A20, 0); + adm5120_flash0_data.switch_bank = switch_bank_gpio5; + adm5120_flash0_data.nr_parts = ARRAY_SIZE(p33x_partitions); + adm5120_flash0_data.parts = p33x_partitions; + adm5120_add_device_flash(0); + + adm5120_add_device_uart(0); + adm5120_add_device_uart(1); + + adm5120_add_device_gpio(P33X_GPIO_DEV_MASK); + + adm5120_setup_eth_macs(bootbase_info.mac); + adm5120_add_device_switch(6, p33x_vlans); + + adm5120_pci_set_irq_map(ARRAY_SIZE(p33x_pci_irqs), p33x_pci_irqs); +} diff --git a/target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-33x.h b/target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-33x.h new file mode 100644 index 000000000..8a7340cb5 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/adm5120/zyxel/p-33x.h @@ -0,0 +1,22 @@ +/* + * ZyXEL Prestige P-33x boards support + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include + +#include + +#include +#include + +extern void p33x_generic_setup(void) __init; diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_defs.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_defs.h new file mode 100644 index 000000000..bf220ff4d --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_defs.h @@ -0,0 +1,53 @@ +/* + * ADM5120 SoC definitions + * + * This file defines some constants specific to the ADM5120 SoC + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ +#ifndef _ASM_MIPS_MACH_ADM5120_DEFS_H +#define _ASM_MIPS_MACH_ADM5120_DEFS_H + +#define ADM5120_SDRAM0_BASE 0x00000000 +#define ADM5120_SDRAM1_BASE 0x01000000 +#define ADM5120_SRAM1_BASE 0x10000000 +#define ADM5120_EXTIO0_BASE 0x10C00000 +#define ADM5120_EXTIO0_SIZE 0x00200000 +#define ADM5120_EXTIO1_BASE 0x10E00000 +#define ADM5120_EXTIO1_SIZE 0x00200000 +#define ADM5120_MPMC_BASE 0x11000000 +#define ADM5120_MPMC_SIZE 0x00200000 +#define ADM5120_USBC_BASE 0x11200000 +#define ADM5120_USBC_SIZE 0x00200000 +#define ADM5120_PCIMEM_BASE 0x11400000 +#define ADM5120_PCIMEM_SIZE 0x00100000 +#define ADM5120_PCIIO_BASE 0x11500000 +#define ADM5120_PCIIO_SIZE 0x000FFFF0 +#define ADM5120_PCICFG_ADDR 0x115FFFF0 +#define ADM5120_PCICFG_DATA 0x115FFFF8 +#define ADM5120_PCICFG_SIZE 0x00000010 +#define ADM5120_SWITCH_BASE 0x12000000 +#define ADM5120_SWITCH_SIZE 0x00200000 +#define ADM5120_INTC_BASE 0x12200000 +#define ADM5120_INTC_SIZE 0x00200000 +#define ADM5120_UART0_BASE 0x12600000 +#define ADM5120_UART1_BASE 0x12800000 +#define ADM5120_UART_SIZE 0x00200000 +#define ADM5120_SRAM0_BASE 0x1FC00000 + +#define ADM5120_NAND_BASE ADM5120_SRAM1_BASE +#define ADM5120_NAND_SIZE 0xB + +#define ADM5120_CLK_175 175000000 +#define ADM5120_CLK_200 200000000 +#define ADM5120_CLK_225 225000000 +#define ADM5120_CLK_250 250000000 + +#define ADM5120_UART_CLOCK 62500000 + +#endif /* _ASM_MIPS_MACH_ADM5120_DEFS_H */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_info.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_info.h new file mode 100644 index 000000000..1d34d80ee --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_info.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2007-2009 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _MACH_ADM5120_INFO_H +#define _MACH_ADM5120_INFO_H + +#include + +extern unsigned int adm5120_prom_type; +#define ADM5120_PROM_GENERIC 0 +#define ADM5120_PROM_CFE 1 +#define ADM5120_PROM_MYLOADER 2 +#define ADM5120_PROM_ROUTERBOOT 3 +#define ADM5120_PROM_BOOTBASE 4 +#define ADM5120_PROM_UBOOT 5 +#define ADM5120_PROM_LAST 5 + +extern unsigned int adm5120_product_code; +extern unsigned int adm5120_revision; +extern unsigned int adm5120_nand_boot; + +extern unsigned long adm5120_speed; +#define ADM5120_SPEED_175 175000000 +#define ADM5120_SPEED_200 200000000 +#define ADM5120_SPEED_225 225000000 +#define ADM5120_SPEED_250 250000000 + +extern unsigned int adm5120_package; +#define ADM5120_PACKAGE_PQFP 0 +#define ADM5120_PACKAGE_BGA 1 + +extern unsigned long adm5120_memsize; + +enum { + MACH_ADM5120_GENERIC = 0, /* Generic board */ + MACH_ADM5120_5GXI, /* OSBRiDGE 5GXi/5XLi */ + MACH_ADM5120_BR6104K, /* Edimax BR-6104K */ + MACH_ADM5120_BR6104KP, /* Edimax BR-6104KP */ + MACH_ADM5120_BR61X4WG, /* Edimax BR-6104Wg/BR-6114WG */ + MACH_ADM5120_CAS630, /* Cellvision CAS-630/630W */ + MACH_ADM5120_CAS670, /* Cellvision CAS-670/670W */ + MACH_ADM5120_CAS700, /* Cellvision CAS-700/700W */ + MACH_ADM5120_CAS771, /* Cellvision CAS-771/771W */ + MACH_ADM5120_CAS790, /* Cellvision CAS-790 */ + MACH_ADM5120_CAS861, /* Cellvision CAS-861/861W */ + MACH_ADM5120_EASY5120PATA, /* Infineon EASY 5120P-ATA */ + MACH_ADM5120_EASY5120RT, /* Infineon EASY 5120-RT */ + MACH_ADM5120_EASY5120WVOIP, /* Infineon EASY 5120-WVoIP */ + MACH_ADM5120_EASY83000, /* Infineon EASY-83000 */ + MACH_ADM5120_ES2108, /* ZyXEL Ethernet Switch 2108 */ + MACH_ADM5120_ES2108F, /* ZyXEL Ethernet Switch 2108-F */ + MACH_ADM5120_ES2108G, /* ZyXEL Ethernet Switch 2108-G */ + MACH_ADM5120_ES2108LC, /* ZyXEL Ethernet Switch 2108-LC */ + MACH_ADM5120_ES2108PWR, /* ZyXEL Ethernet Switch 2108-PWR */ + MACH_ADM5120_ES2024A, /* ZyXEL Ethernet Switch 2024A */ + MACH_ADM5120_ES2024PWR, /* ZyXEL Ethernet Switch 2024PWR */ + MACH_ADM5120_HS100, /* ZyXEL HomeSafe 100/100W */ + MACH_ADM5120_NFS101U, /* Cellvision NFS-101U/101WU */ + MACH_ADM5120_NFS202U, /* Cellvision NFS-202U/202WU */ + MACH_ADM5120_NP28G, /* Compex NP28G */ + MACH_ADM5120_NP28GHS, /* Compex NP28G HotSpot */ + MACH_ADM5120_NP27G, /* Compex NP27G */ + MACH_ADM5120_RB_11X, /* Mikrotik RouterBOARD 111/112 */ + MACH_ADM5120_RB_133, /* Mikrotik RouterBOARD 133 */ + MACH_ADM5120_RB_133C, /* Mikrotik RouterBOARD 133c */ + MACH_ADM5120_RB_150, /* Mikrotik RouterBOARD 150 */ + MACH_ADM5120_RB_153, /* Mikrotik RouterBOARD 153 */ + MACH_ADM5120_RB_192, /* Mikrotik RouterBOARD 192 */ + MACH_ADM5120_P334U, /* ZyXEL Prestige 334U */ + MACH_ADM5120_P334W, /* ZyXEL Prestige 334W */ + MACH_ADM5120_P334WH, /* ZyXEL Prestige 334WH */ + MACH_ADM5120_P334WHD, /* ZyXEL Prestige 334WHD */ + MACH_ADM5120_P334WT, /* ZyXEL Prestige 334WT */ + MACH_ADM5120_P335, /* ZyXEL Prestige 335/335WT */ + MACH_ADM5120_P335PLUS, /* ZyXEL Prestige 335Plus */ + MACH_ADM5120_P335U, /* ZyXEL Prestige 335U */ + MACH_ADM5120_PMUGW, /* Motorola Powerline MU Gateway */ + MACH_ADM5120_WP54, /* Compex WP54G/WP54AG/WPP54G/WPP54AG */ + MACH_ADM5120_WP54G_WRT, /* Compex WP54G-WRT */ + MACH_ADM5120_WP54Gv1C, /* Compex WP54G version 1C */ + MACH_ADM5120_EB_214A, /* Generic EB-214A */ +}; + +/* + * TODO:remove adm5120_eth* variables when the switch driver will be + * converted into a real platform driver + */ +extern unsigned int adm5120_eth_num_ports; +extern unsigned char adm5120_eth_macs[6][6]; +extern unsigned char adm5120_eth_vlans[6]; + +extern void adm5120_soc_init(void) __init; +extern void adm5120_mem_init(void) __init; +extern void adm5120_ndelay(u32 ns); + +extern void (*adm5120_board_reset)(void); + +extern void adm5120_gpio_init(void) __init; +extern void adm5120_gpio_csx0_enable(void) __init; +extern void adm5120_gpio_csx1_enable(void) __init; +extern void adm5120_gpio_ew_enable(void) __init; + +static inline int adm5120_package_pqfp(void) +{ + return (adm5120_package == ADM5120_PACKAGE_PQFP); +} + +static inline int adm5120_package_bga(void) +{ + return (adm5120_package == ADM5120_PACKAGE_BGA); +} + +static inline int adm5120_has_pci(void) +{ + return (adm5120_package == ADM5120_PACKAGE_BGA); +} + +static inline int adm5120_has_gmii(void) +{ + return (adm5120_package == ADM5120_PACKAGE_BGA); +} + +#endif /* _MACH_ADM5120_INFO_H */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_intc.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_intc.h new file mode 100644 index 000000000..70dd6bbe8 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_intc.h @@ -0,0 +1,63 @@ +/* + * ADM5120 interrupt controller definitions + * + * This header file defines the hardware registers of the ADM5120 SoC + * built-in interrupt controller. + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _MACH_ADM5120_INTC_H +#define _MACH_ADM5120_INTC_H + +/* + * INTC register offsets + */ +#define INTC_REG_IRQ_STATUS 0x00 /* Interrupt status after masking */ +#define INTC_REG_IRQ_RAW_STATUS 0x04 /* Interrupt status before masking */ +#define INTC_REG_IRQ_ENABLE 0x08 /* Used to enable the interrupt sources */ +#define INTC_REG_IRQ_ENABLE_CLEAR 0x0C /* Used to disable the interrupt sources */ +#define INTC_REG_IRQ_DISABLE INTC_REG_IRQ_ENABLE_CLEAR +#define INTC_REG_INT_MODE 0x14 /* The interrupt mode of the sources */ +#define INTC_REG_FIQ_STATUS 0x18 /* FIQ status */ +#define INTC_REG_IRQ_TEST_SOURCE 0x1C +#define INTC_REG_IRQ_SOURCE_SELECT 0x20 +#define INTC_REG_INT_LEVEL 0x24 + +/* + * INTC IRQ numbers + */ +#define INTC_IRQ_TIMER 0 /* built in timer */ +#define INTC_IRQ_UART0 1 /* built-in UART0 */ +#define INTC_IRQ_UART1 2 /* built-in UART1 */ +#define INTC_IRQ_USBC 3 /* USB Host Controller */ +#define INTC_IRQ_GPIO2 4 /* GPIO line 2 */ +#define INTC_IRQ_GPIO4 5 /* GPIO line 4 */ +#define INTC_IRQ_PCI0 6 /* PCI slot 2 */ +#define INTC_IRQ_PCI1 7 /* PCI slot 3 */ +#define INTC_IRQ_PCI2 8 /* PCI slot 4 */ +#define INTC_IRQ_SWITCH 9 /* built-in ethernet switch */ +#define INTC_IRQ_LAST INTC_IRQ_SWITCH +#define INTC_IRQ_COUNT 10 + +/* + * INTC register bits + */ +#define INTC_INT_TIMER (1 << INTC_IRQ_TIMER) +#define INTC_INT_UART0 (1 << INTC_IRQ_UART0) +#define INTC_INT_UART1 (1 << INTC_IRQ_UART1) +#define INTC_INT_USBC (1 << INTC_IRQ_USBC) +#define INTC_INT_INTX0 (1 << INTC_IRQ_INTX0) +#define INTC_INT_INTX1 (1 << INTC_IRQ_INTX1) +#define INTC_INT_PCI0 (1 << INTC_IRQ_PCI0) +#define INTC_INT_PCI1 (1 << INTC_IRQ_PCI1) +#define INTC_INT_PCI2 (1 << INTC_IRQ_PCI2) +#define INTC_INT_SWITCH (1 << INTC_IRQ_SWITCH) +#define INTC_INT_ALL ((1 << INTC_IRQ_COUNT) - 1) + +#endif /* _MACH_ADM5120_INTC_H */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_mpmc.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_mpmc.h new file mode 100644 index 000000000..c4e9591fb --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_mpmc.h @@ -0,0 +1,92 @@ +/* + * ADM5120 MPMC (Multiport Memory Controller) register definitions + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _MACH_ADM5120_MPMC_H +#define _MACH_ADM5120_MPMC_H + +#define MPMC_READ_REG(r) __raw_readl( \ + (void __iomem *)KSEG1ADDR(ADM5120_MPMC_BASE) + MPMC_REG_ ## r) +#define MPMC_WRITE_REG(r, v) __raw_writel((v), \ + (void __iomem *)KSEG1ADDR(ADM5120_MPMC_BASE) + MPMC_REG_ ## r) + +#define MPMC_REG_CTRL 0x0000 +#define MPMC_REG_STATUS 0x0004 +#define MPMC_REG_CONF 0x0008 +#define MPMC_REG_DC 0x0020 +#define MPMC_REG_DR 0x0024 +#define MPMC_REG_DRP 0x0030 + +#define MPMC_REG_DC0 0x0100 +#define MPMC_REG_DRC0 0x0104 +#define MPMC_REG_DC1 0x0120 +#define MPMC_REG_DRC1 0x0124 +#define MPMC_REG_DC2 0x0140 +#define MPMC_REG_DRC2 0x0144 +#define MPMC_REG_DC3 0x0160 +#define MPMC_REG_DRC3 0x0164 +#define MPMC_REG_SC0 0x0200 /* for F_CS1_N */ +#define MPMC_REG_SC1 0x0220 /* for F_CS0_N */ +#define MPMC_REG_SC2 0x0240 +#define MPMC_REG_WEN2 0x0244 +#define MPMC_REG_OEN2 0x0248 +#define MPMC_REG_RD2 0x024C +#define MPMC_REG_PG2 0x0250 +#define MPMC_REG_WR2 0x0254 +#define MPMC_REG_TN2 0x0258 +#define MPMC_REG_SC3 0x0260 + +/* Control register bits */ +#define MPMC_CTRL_AM (1 << 1) /* Address Mirror */ +#define MPMC_CTRL_LPM (1 << 2) /* Low Power Mode */ +#define MPMC_CTRL_DWB (1 << 3) /* Drain Write Buffers */ + +/* Status register bits */ +#define MPMC_STATUS_BUSY (1 << 0) /* Busy */ +#define MPMC_STATUS_WBS (1 << 1) /* Write Buffer Status */ +#define MPMC_STATUS_SRA (1 << 2) /* Self-Refresh Acknowledge*/ + +/* Dynamic Control register bits */ +#define MPMC_DC_CE (1 << 0) +#define MPMC_DC_DMC (1 << 1) +#define MPMC_DC_SRR (1 << 2) +#define MPMC_DC_SI_SHIFT 7 +#define MPMC_DC_SI_MASK (3 << 7) +#define MPMC_DC_SI_NORMAL (0 << 7) +#define MPMC_DC_SI_MODE (1 << 7) +#define MPMC_DC_SI_PALL (2 << 7) +#define MPMC_DC_SI_NOP (3 << 7) + +#define SRAM_REG_CONF 0x00 +#define SRAM_REG_WWE 0x04 +#define SRAM_REG_WOE 0x08 +#define SRAM_REG_WRD 0x0C +#define SRAM_REG_WPG 0x10 +#define SRAM_REG_WWR 0x14 +#define SRAM_REG_WTR 0x18 + +/* Dynamic Configuration register bits */ +#define DC_BE (1 << 19) /* buffer enable */ +#define DC_RW_SHIFT 28 /* shift for number of rows */ +#define DC_RW_MASK 0x03 +#define DC_NB_SHIFT 26 /* shift for number of banks */ +#define DC_NB_MASK 0x01 +#define DC_CW_SHIFT 22 /* shift for number of columns */ +#define DC_CW_MASK 0x07 +#define DC_DW_SHIFT 7 /* shift for device width */ +#define DC_DW_MASK 0x03 + +/* Static Configuration register bits */ +#define SC_MW_MASK 0x03 /* memory width mask */ +#define SC_MW_8 0x00 /* 8 bit memory width */ +#define SC_MW_16 0x01 /* 16 bit memory width */ +#define SC_MW_32 0x02 /* 32 bit memory width */ + +#endif /* _MACH_ADM5120_MPMC_H */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_nand.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_nand.h new file mode 100644 index 000000000..1e2f3bd15 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_nand.h @@ -0,0 +1,89 @@ +/* + * ADM5120 NAND interface definitions + * + * This header file defines the hardware registers of the ADM5120 SoC + * built-in NAND interface. + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * NAND interface routines was based on a driver for Linux 2.6.19+ which + * was derived from the driver for Linux 2.4.xx published by Mikrotik for + * their RouterBoard 1xx and 5xx series boards. + * Copyright (C) 2007 David Goodenough + * Copyright (C) 2007 Florian Fainelli + * + * This program 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. + * + */ + +#ifndef _MACH_ADM5120_NAND_H +#define _MACH_ADM5120_NAND_H + +#include +#include + +#include +#include + +/* NAND control registers */ +#define NAND_REG_DATA 0x0 /* data register */ +#define NAND_REG_SET_CEn 0x1 /* CE# low */ +#define NAND_REG_CLR_CEn 0x2 /* CE# high */ +#define NAND_REG_CLR_CLE 0x3 /* CLE low */ +#define NAND_REG_SET_CLE 0x4 /* CLE high */ +#define NAND_REG_CLR_ALE 0x5 /* ALE low */ +#define NAND_REG_SET_ALE 0x6 /* ALE high */ +#define NAND_REG_SET_SPn 0x7 /* SP# low (use spare area) */ +#define NAND_REG_CLR_SPn 0x8 /* SP# high (do not use spare area) */ +#define NAND_REG_SET_WPn 0x9 /* WP# low */ +#define NAND_REG_CLR_WPn 0xA /* WP# high */ +#define NAND_REG_STATUS 0xB /* Status register */ + +#define ADM5120_NAND_STATUS_READY 0x80 + +#define NAND_READ_REG(r) \ + readb((void __iomem *)KSEG1ADDR(ADM5120_NAND_BASE) + (r)) +#define NAND_WRITE_REG(r, v) \ + writeb((v), (void __iomem *)KSEG1ADDR(ADM5120_NAND_BASE) + (r)) + +/*-------------------------------------------------------------------------*/ + +static inline void adm5120_nand_enable(void) +{ + SW_WRITE_REG(SWITCH_REG_BW_CNTL1, BW_CNTL1_NAND_ENABLE); + SW_WRITE_REG(SWITCH_REG_BOOT_DONE, 1); +} + +static inline void adm5120_nand_set_wpn(unsigned int set) +{ + NAND_WRITE_REG((set) ? NAND_REG_SET_WPn : NAND_REG_CLR_WPn, 1); +} + +static inline void adm5120_nand_set_spn(unsigned int set) +{ + NAND_WRITE_REG((set) ? NAND_REG_SET_SPn : NAND_REG_CLR_SPn, 1); +} + +static inline void adm5120_nand_set_cle(unsigned int set) +{ + NAND_WRITE_REG((set) ? NAND_REG_SET_CLE : NAND_REG_CLR_CLE, 1); +} + +static inline void adm5120_nand_set_ale(unsigned int set) +{ + NAND_WRITE_REG((set) ? NAND_REG_SET_ALE : NAND_REG_CLR_ALE, 1); +} + +static inline void adm5120_nand_set_cen(unsigned int set) +{ + NAND_WRITE_REG((set) ? NAND_REG_SET_CEn : NAND_REG_CLR_CEn, 1); +} + +static inline u8 adm5120_nand_get_status(void) +{ + return NAND_READ_REG(NAND_REG_STATUS); +} + +#endif /* _MACH_ADM5120_NAND_H */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_platform.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_platform.h new file mode 100644 index 000000000..952c7adc8 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_platform.h @@ -0,0 +1,88 @@ +/* + * ADM5120 specific platform definitions + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _ASM_MIPS_MACH_ADM5120_PLATFORM_H +#define _ASM_MIPS_MACH_ADM5120_PLATFORM_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct adm5120_flash_platform_data { + void (*set_vpp)(struct map_info *, int); + void (*switch_bank)(unsigned); + u32 window_size; + unsigned int nr_parts; + struct mtd_partition *parts; +}; + +struct adm5120_switch_platform_data { + /* TODO: not yet implemented */ +}; + +struct adm5120_pci_irq { + u8 slot; + u8 func; + u8 pin; + unsigned irq; +}; + +#define PCIIRQ(s, f, p, i) {.slot = (s), .func = (f), .pin = (p), .irq = (i)} + +#ifdef CONFIG_PCI +extern void adm5120_pci_set_irq_map(unsigned int nr_irqs, + struct adm5120_pci_irq *map) __init; +#else +static inline void adm5120_pci_set_irq_map(unsigned int nr_irqs, + struct adm5120_pci_irq *map) +{ +} +#endif + +extern void adm5120_setup_eth_macs(u8 *mac_base) __init; + +extern struct adm5120_flash_platform_data adm5120_flash0_data; +extern struct adm5120_flash_platform_data adm5120_flash1_data; + +extern void adm5120_add_device_flash(unsigned id) __init; +extern void adm5120_add_device_usb(void) __init; +extern void adm5120_add_device_uart(unsigned id) __init; +extern void adm5120_add_device_nand(struct platform_nand_data *pdata) __init; +extern void adm5120_add_device_switch(unsigned num_ports, u8 *vlan_map) __init; +extern void adm5120_add_device_gpio(u32 disable_mask) __init; +extern void adm5120_register_gpio_buttons(int id, + unsigned poll_interval, + unsigned nbuttons, + struct gpio_keys_button *buttons); + +#define GPIO_LED_DEF(g, n, t, a) { \ + .name = (n), \ + .default_trigger = (t), \ + .gpio = (g), \ + .active_low = (a) \ +} + +#define GPIO_LED_STD(g, n, t) GPIO_LED_DEF((g), (n), (t), 0) +#define GPIO_LED_INV(g, n, t) GPIO_LED_DEF((g), (n), (t), 1) + +extern void adm5120_add_device_gpio_leds(unsigned num_leds, + struct gpio_led *leds) __init; + +#endif /* _ASM_MIPS_MACH_ADM5120_PLATFORM_H */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_switch.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_switch.h new file mode 100644 index 000000000..91adc5bae --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_switch.h @@ -0,0 +1,300 @@ +/* + * ADM5120 ethernet switch definitions + * + * This header file defines the hardware registers of the ADM5120 SoC + * built-in Ethernet switch. + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _MACH_ADM5120_SWITCH_H +#define _MACH_ADM5120_SWITCH_H + +#ifndef BIT +# define BIT(at) (1 << (at)) +#endif +#define BITMASK(len) (BIT(len)-1) + +#define SW_READ_REG(r) __raw_readl( \ + (void __iomem *)KSEG1ADDR(ADM5120_SWITCH_BASE) + r) +#define SW_WRITE_REG(r, v) __raw_writel((v), \ + (void __iomem *)KSEG1ADDR(ADM5120_SWITCH_BASE) + r) + +/* Switch register offsets */ +#define SWITCH_REG_CODE 0x0000 +#define SWITCH_REG_SOFT_RESET 0x0004 /* Soft Reset */ +#define SWITCH_REG_BOOT_DONE 0x0008 /* Boot Done */ +#define SWITCH_REG_SW_RESET 0x000C /* Switch Reset */ +#define SWITCH_REG_PHY_STATUS 0x0014 /* PHY Status */ +#define SWITCH_REG_MEMCTRL 0x001C /* Memory Control */ +#define SWITCH_REG_CPUP_CONF 0x0024 /* CPU Port Configuration */ +#define SWITCH_REG_PORT_CONF0 0x0028 /* Port Configuration 0 */ +#define SWITCH_REG_PORT_CONF1 0x002C /* Port Configuration 1 */ +#define SWITCH_REG_PORT_CONF2 0x0030 /* Port Configuration 2 */ +#define SWITCH_REG_VLAN_G1 0x0040 /* VLAN group 1 */ +#define SWITCH_REG_VLAN_G2 0x0044 /* VLAN group 2 */ +#define SWITCH_REG_SEND_TRIG 0x0048 /* Send Trigger */ +#define SWITCH_REG_MAC_WT0 0x0058 /* MAC Write Address 0 */ +#define SWITCH_REG_MAC_WT1 0x005C /* MAC Write Address 1 */ +#define SWITCH_REG_BW_CNTL0 0x0060 /* Bandwidth Control 0 */ +#define SWITCH_REG_BW_CNTL1 0x0064 /* Bandwidth Control 1 */ +#define SWITCH_REG_PHY_CNTL0 0x0068 /* PHY Control 0 */ +#define SWITCH_REG_PHY_CNTL1 0x006C /* PHY Control 1 */ +#define SWITCH_REG_PORT_TH 0x0078 /* Port Threshold */ +#define SWITCH_REG_PHY_CNTL2 0x007C /* PHY Control 2 */ +#define SWITCH_REG_PHY_CNTL3 0x0080 /* PHY Control 3 */ +#define SWITCH_REG_PRI_CNTL 0x0084 /* Priority Control */ +#define SWITCH_REG_PHY_CNTL4 0x00A0 /* PHY Control 4 */ +#define SWITCH_REG_EMPTY_CNT 0x00A4 /* Empty Count */ +#define SWITCH_REG_PORT_CNTLS 0x00A8 /* Port Control Select */ +#define SWITCH_REG_PORT_CNTL 0x00AC /* Port Control */ +#define SWITCH_REG_INT_STATUS 0x00B0 /* Interrupt Status */ +#define SWITCH_REG_INT_MASK 0x00B4 /* Interrupt Mask */ +#define SWITCH_REG_GPIO_CONF0 0x00B8 /* GPIO Configuration 0 */ +#define SWITCH_REG_GPIO_CONF2 0x00BC /* GPIO Configuration 1 */ +#define SWITCH_REG_WDOG0 0x00C0 /* Watchdog 0 */ +#define SWITCH_REG_WDOG1 0x00C4 /* Watchdog 1 */ + +#define SWITCH_REG_SHDA 0x00D0 /* Send High Descriptors Address */ +#define SWITCH_REG_SLDA 0x00D4 /* Send Low Descriptors Address */ +#define SWITCH_REG_RHDA 0x00D8 /* Receive High Descriptor Address */ +#define SWITCH_REG_RLDA 0x00DC /* Receive Low Descriptor Address */ +#define SWITCH_REG_SHWA 0x00E0 /* Send High Working Address */ +#define SWITCH_REG_SLWA 0x00E4 /* Send Low Working Address */ +#define SWITCH_REG_RHWA 0x00E8 /* Receive High Working Address */ +#define SWITCH_REG_RLWA 0x00EC /* Receive Low Working Address */ + +#define SWITCH_REG_TIMER_INT 0x00F0 /* Timer */ +#define SWITCH_REG_TIMER 0x00F4 /* Timer Interrupt */ + +#define SWITCH_REG_PORT0_LED 0x0100 +#define SWITCH_REG_PORT1_LED 0x0104 +#define SWITCH_REG_PORT2_LED 0x0108 +#define SWITCH_REG_PORT3_LED 0x010C +#define SWITCH_REG_PORT4_LED 0x0110 + +/* CODE register bits */ +#define CODE_PC_MASK BITMASK(16) /* Product Code */ +#define CODE_REV_SHIFT 16 +#define CODE_REV_MASK BITMASK(4) /* Product Revision */ +#define CODE_CLKS_SHIFT 20 +#define CODE_CLKS_MASK BITMASK(2) /* Clock Speed */ +#define CODE_CLKS_175 0 /* 175 MHz */ +#define CODE_CLKS_200 1 /* 200 MHz */ +#define CODE_CLKS_225 2 /* 225 MHz */ +#define CODE_CLKS_250 3 /* 250 MHz */ +#define CODE_NAB BIT(24) /* NAND boot */ +#define CODE_PK_MASK BITMASK(1) /* Package type */ +#define CODE_PK_SHIFT 29 +#define CODE_PK_BGA 0 /* BGA package */ +#define CODE_PK_PQFP 1 /* PQFP package */ + +/* MEMCTRL register bits */ +#define MEMCTRL_SDRS_MASK BITMASK(3) /* SDRAM bank size */ +#define MEMCTRL_SDRS_4M 0x01 +#define MEMCTRL_SDRS_8M 0x02 +#define MEMCTRL_SDRS_16M 0x03 +#define MEMCTRL_SDRS_64M 0x04 +#define MEMCTRL_SDRS_128M 0x05 +#define MEMCTRL_SDR1_ENABLE BIT(5) /* enable SDRAM bank 1 */ + +#define MEMCTRL_SRS0_SHIFT 8 /* shift for SRAM0 size */ +#define MEMCTRL_SRS1_SHIFT 16 /* shift for SRAM1 size */ +#define MEMCTRL_SRS_MASK BITMASK(3) /* SRAM size mask */ +#define MEMCTRL_SRS_DISABLED 0x00 /* Disabled */ +#define MEMCTRL_SRS_512K 0x01 /* 512KB*/ +#define MEMCTRL_SRS_1M 0x02 /* 1MB */ +#define MEMCTRL_SRS_2M 0x03 /* 2MB */ +#define MEMCTRL_SRS_4M 0x04 /* 4MB */ + +/* Port bits used in various registers */ +#define SWITCH_PORT_PHY0 BIT(0) +#define SWITCH_PORT_PHY1 BIT(1) +#define SWITCH_PORT_PHY2 BIT(2) +#define SWITCH_PORT_PHY3 BIT(3) +#define SWITCH_PORT_PHY4 BIT(4) +#define SWITCH_PORT_MII BIT(5) +#define SWITCH_PORT_CPU BIT(6) + +/* Port bit shorthands */ +#define SWITCH_PORTS_PHY 0x1F /* phy ports */ +#define SWITCH_PORTS_NOCPU 0x3F /* physical ports */ +#define SWITCH_PORTS_ALL 0x7F /* all ports */ + +/* CPUP_CONF register bits */ +#define CPUP_CONF_DCPUP BIT(0) /* Disable CPU port */ +#define CPUP_CONF_CRCP BIT(1) /* CRC padding from CPU */ +#define CPUP_CONF_BTM BIT(2) /* Bridge Testing Mode */ +#define CPUP_CONF_DUNP_SHIFT 9 /* Disable Unknown Packets for portX */ +#define CPUP_CONF_DMCP_SHIFT 16 /* Disable Mcast Packets form portX */ +#define CPUP_CONF_DBCP_SHIFT 24 /* Disable Bcast Packets form portX */ + +/* PORT_CONF0 register bits */ +#define PORT_CONF0_DP_SHIFT 0 /* Disable Port */ +#define PORT_CONF0_EMCP_SHIFT 8 /* Enable All MC Packets */ +#define PORT_CONF0_BP_SHIFT 16 /* Enable Back Pressure */ + +/* PORT_CONF1 register bits */ +#define PORT_CONF1_DISL_SHIFT 0 /* Disable Learning */ +#define PORT_CONF1_BS_SHIFT 6 /* Blocking State */ +#define PORT_CONF1_BM_SHIFT 12 /* Blocking Mode */ + +/* SEND_TRIG register bits */ +#define SEND_TRIG_STL BIT(0) /* Send Trigger Low */ +#define SEND_TRIG_STH BIT(1) /* Send Trigger High */ + +/* MAC_WT0 register bits */ +#define MAC_WT0_MAWC BIT(0) /* MAC address write command */ +#define MAC_WT0_MWD_SHIFT 1 +#define MAC_WT0_MWD BIT(1) /* MAC write done */ +#define MAC_WT0_WFB BIT(2) /* Write Filter Bit */ +#define MAC_WT0_WVN_SHIFT 3 /* Write Vlan Number shift */ +#define MAC_WT0_WVE BIT(6) /* Write VLAN enable */ +#define MAC_WT0_WPMN_SHIFT 7 +#define MAC_WT0_WAF_SHIFT 13 /* Write Age Field shift */ +#define MAC_WT0_WAF_EMPTY 0 +#define MAC_WT0_WAF_STATIC 7 /* age: static */ +#define MAC_WT0_MAC0_SHIFT 16 +#define MAC_WT0_MAC1_SHIFT 24 + +/* MAC_WT1 register bits */ +#define MAC_WT1_MAC2_SHIFT 0 +#define MAC_WT1_MAC3_SHIFT 8 +#define MAC_WT1_MAC4_SHIFT 16 +#define MAC_WT1_MAC5_SHIFT 24 + +/* BW_CNTL0/BW_CNTL1 register bits */ +#define BW_CNTL_DISABLE 0x00 +#define BW_CNTL_64K 0x01 +#define BW_CNTL_128K 0x02 +#define BW_CNTL_256K 0x03 +#define BW_CNTL_512K 0x04 +#define BW_CNTL_1M 0x05 +#define BW_CNTL_4M 0x06 +#define BW_CNTL_10M 0x07 + +#define P4TBC_SHIFT 0 +#define P4RBC_SHIFT 4 +#define P5TBC_SHIFT 8 +#define P5RBC_SHIFT 12 + +#define BW_CNTL1_NAND_ENABLE 0x100 + +/* PHY_CNTL0 register bits */ +#define PHY_CNTL0_PHYA_MASK BITMASK(5) +#define PHY_CNTL0_PHYR_MASK BITMASK(5) +#define PHY_CNTL0_PHYR_SHIFT 8 +#define PHY_CNTL0_WC BIT(13) /* Write Command */ +#define PHY_CNTL0_RC BIT(14) /* Read Command */ +#define PHY_CNTL0_WTD_MASK BIT(16) /* Read Command */ +#define PHY_CNTL0_WTD_SHIFT 16 + +/* PHY_CNTL1 register bits */ +#define PHY_CNTL1_WOD BIT(0) /* Write Operation Done */ +#define PHY_CNTL1_ROD BIT(1) /* Read Operation Done */ +#define PHY_CNTL1_RD_MASK BITMASK(16) +#define PHY_CNTL1_RD_SHIFT 16 + +/* PHY_CNTL2 register bits */ +#define PHY_CNTL2_ANE_SHIFT 0 /* Auto Negotiation Enable */ +#define PHY_CNTL2_SC_SHIFT 5 /* Speed Control */ +#define PHY_CNTL2_DC_SHIFT 10 /* Duplex Control */ +#define PHY_CNTL2_FNCV_SHIFT 15 /* Recommended FC Value */ +#define PHY_CNTL2_PHYR_SHIFT 20 /* PHY reset */ +#define PHY_CNTL2_AMDIX_SHIFT 25 /* Auto MDIX enable */ +/* PHY_CNTL2_RMAE is bad in datasheet */ +#define PHY_CNTL2_RMAE BIT(31) /* Recommended MCC Average enable */ + +/* PHY_CNTL3 register bits */ +#define PHY_CNTL3_RNT BIT(10) /* Recommend Normal Threshold */ + +/* PORT_TH register bits */ +#define PORT_TH_PPT_MASK BITMASK(8) /* Per Port Threshold */ +#define PORT_TH_CPUT_SHIFT 8 /* CPU Port Buffer Threshold */ +#define PORT_TH_CPUT_MASK BITMASK(8) +#define PORT_TH_CPUHT_SHIFT 16 /* CPU Hold Threshold */ +#define PORT_TH_CPUHT_MASK BITMASK(8) +#define PORT_TH_CPURT_SHIFT 24 /* CPU Release Threshold */ +#define PORT_TH_CPURT_MASK BITMASK(8) + +/* EMPTY_CNT register bits */ +#define EMPTY_CNT_EBGB_MASK BITMASK(9) /* Empty Blocks in the Global Buffer */ + +/* GPIO_CONF0 register bits */ +#define GPIO_CONF0_MASK BITMASK(8) +#define GPIO_CONF0_IM_SHIFT 0 +#define GPIO_CONF0_IV_SHIFT 8 +#define GPIO_CONF0_OE_SHIFT 16 +#define GPIO_CONF0_OV_SHIFT 24 +#define GPIO_CONF0_IM_MASK (0xFF << GPIO_CONF0_IM_SHIFT) +#define GPIO_CONF0_IV_MASK (0xFF << GPIO_CONF0_IV_SHIFT) +#define GPIO_CONF0_OE_MASK (0xFF << GPIO_CONF0_OE_SHIFT) +#define GPIO_CONF0_OV_MASK (0xFF << GPIO_CONF0_OV_SHIFT) + +/* GPIO_CONF2 register bits */ +#define GPIO_CONF2_CSX0 BIT(4) /* enable CSX0:INTX0 on GPIO 1:2 */ +#define GPIO_CONF2_CSX1 BIT(5) /* enable CSX1:INTX1 on GPIO 3:4 */ +#define GPIO_CONF2_EW BIT(6) /* enable wait state pin for CSX0/1 */ + +/* INT_STATUS/INT_MASK register bits */ +#define SWITCH_INT_SHD BIT(0) /* Send High Done */ +#define SWITCH_INT_SLD BIT(1) /* Send Low Done */ +#define SWITCH_INT_RHD BIT(2) /* Receive High Done */ +#define SWITCH_INT_RLD BIT(3) /* Receive Low Done */ +#define SWITCH_INT_HDF BIT(4) /* High Descriptor Full */ +#define SWITCH_INT_LDF BIT(5) /* Low Descriptor Full */ +#define SWITCH_INT_P0QF BIT(6) /* Port0 Queue Full */ +#define SWITCH_INT_P1QF BIT(7) /* Port1 Queue Full */ +#define SWITCH_INT_P2QF BIT(8) /* Port2 Queue Full */ +#define SWITCH_INT_P3QF BIT(9) /* Port3 Queue Full */ +#define SWITCH_INT_P4QF BIT(10) /* Port4 Queue Full */ +#define SWITCH_INT_P5QF BIT(11) /* Port5 Queue Full */ +#define SWITCH_INT_CPQF BIT(13) /* CPU Queue Full */ +#define SWITCH_INT_GQF BIT(14) /* Global Queue Full */ +#define SWITCH_INT_MD BIT(15) /* Must Drop */ +#define SWITCH_INT_BCS BIT(16) /* BC Storm */ +#define SWITCH_INT_PSC BIT(18) /* Port Status Change */ +#define SWITCH_INT_ID BIT(19) /* Intruder Detected */ +#define SWITCH_INT_W0TE BIT(20) /* Watchdog 0 Timer Expired */ +#define SWITCH_INT_W1TE BIT(21) /* Watchdog 1 Timer Expired */ +#define SWITCH_INT_RDE BIT(22) /* Receive Descriptor Error */ +#define SWITCH_INT_SDE BIT(23) /* Send Descriptor Error */ +#define SWITCH_INT_CPUH BIT(24) /* CPU Hold */ + +/* TIMER_INT register bits */ +#define TIMER_INT_TOS BIT(0) /* time-out status */ +#define TIMER_INT_TOM BIT(16) /* mask time-out interrupt */ + +/* TIMER register bits */ +#define TIMER_PERIOD_MASK BITMASK(16) /* mask for timer period */ +#define TIMER_PERIOD_DEFAULT 0xFFFF /* default timer period */ +#define TIMER_TE BIT(16) /* timer enable bit */ + +/* PORTx_LED register bits */ +#define LED_MODE_MASK BITMASK(4) +#define LED_MODE_INPUT 0 +#define LED_MODE_FLASH 1 +#define LED_MODE_OUT_HIGH 2 +#define LED_MODE_OUT_LOW 3 +#define LED_MODE_LINK 4 +#define LED_MODE_SPEED 5 +#define LED_MODE_DUPLEX 6 +#define LED_MODE_ACT 7 +#define LED_MODE_COLL 8 +#define LED_MODE_LINK_ACT 9 +#define LED_MODE_DUPLEX_COLL 10 +#define LED_MODE_10M_ACT 11 +#define LED_MODE_100M_ACT 12 +#define LED0_MODE_SHIFT 0 /* LED0 mode shift */ +#define LED1_MODE_SHIFT 4 /* LED1 mode shift */ +#define LED2_MODE_SHIFT 8 /* LED2 mode shift */ +#define LED0_IV_SHIFT 12 /* LED0 input value shift */ +#define LED1_IV_SHIFT 13 /* LED1 input value shift */ +#define LED2_IV_SHIFT 14 /* LED2 input value shift */ + +#endif /* _MACH_ADM5120_SWITCH_H */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_uart.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_uart.h new file mode 100644 index 000000000..81d3067da --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/adm5120_uart.h @@ -0,0 +1,64 @@ +/* + * ADM5120 UART definitions + * + * This header file defines the hardware registers of the ADM5120 SoC + * built-in UARTs. + * + * Copyright (C) 2007 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _MACH_ADM5120_UART_H +#define _MACH_ADM5120_UART_H + +#define UART_BAUDDIV(clk, baud) ((clk/(16 * (baud)))-1) + +#define UART_REG_DATA 0x00 +#define UART_REG_RSR 0x04 +#define UART_REG_ECR UART_REG_RSR +#define UART_REG_LCRH 0x08 +#define UART_REG_LCRM 0x0C +#define UART_REG_LCRL 0x10 +#define UART_REG_CTRL 0x14 +#define UART_REG_FLAG 0x18 + +/* Receive Status Register bits */ +#define UART_RSR_FE (1 << 0) +#define UART_RSR_PE (1 << 1) +#define UART_RSR_BE (1 << 2) +#define UART_RSR_OE (1 << 3) +#define UART_RSR_ERR (UART_RSR_FE | UART_RSR_PE | UART_RSR_BE) + +#define UART_ECR_ALL 0xFF + +/* Line Control High register bits */ +#define UART_LCRH_BRK (1 << 0) /* send break */ +#define UART_LCRH_PEN (1 << 1) /* parity enable */ +#define UART_LCRH_EPS (1 << 2) /* even parity select */ +#define UART_LCRH_STP1 (0 << 3) /* one stop bits select */ +#define UART_LCRH_STP2 (1 << 3) /* two stop bits select */ +#define UART_LCRH_FEN (1 << 4) /* FIFO enable */ + +#define UART_LCRH_WLEN5 (0 << 5) +#define UART_LCRH_WLEN6 (1 << 5) +#define UART_LCRH_WLEN7 (2 << 5) +#define UART_LCRH_WLEN8 (3 << 5) + +/* Control register bits */ +#define UART_CTRL_EN (1 << 0) + +/* Flag register bits */ +#define UART_FLAG_CTS (1 << 0) +#define UART_FLAG_DSR (1 << 1) +#define UART_FLAG_DCD (1 << 2) +#define UART_FLAG_BUSY (1 << 3) +#define UART_FLAG_RXFE (1 << 4) +#define UART_FLAG_TXFF (1 << 5) +#define UART_FLAG_RXFF (1 << 6) +#define UART_FLAG_TXFE (1 << 7) + +#endif /* _MACH_ADM5120_UART_H */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/asm/sizes.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/asm/sizes.h new file mode 100644 index 000000000..503843db1 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/asm/sizes.h @@ -0,0 +1,56 @@ +/* + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* DO NOT EDIT!! - this file automatically generated + * from .s file by awk -f s2h.awk + */ +/* Size definitions + * Copyright (C) ARM Limited 1998. All rights reserved. + */ + +#ifndef __sizes_h +#define __sizes_h 1 + +/* handy sizes */ +#define SZ_16 0x00000010 +#define SZ_256 0x00000100 +#define SZ_512 0x00000200 + +#define SZ_1K 0x00000400 +#define SZ_4K 0x00001000 +#define SZ_8K 0x00002000 +#define SZ_16K 0x00004000 +#define SZ_64K 0x00010000 +#define SZ_128K 0x00020000 +#define SZ_256K 0x00040000 +#define SZ_512K 0x00080000 + +#define SZ_1M 0x00100000 +#define SZ_2M 0x00200000 +#define SZ_4M 0x00400000 +#define SZ_8M 0x00800000 +#define SZ_16M 0x01000000 +#define SZ_32M 0x02000000 +#define SZ_64M 0x04000000 +#define SZ_128M 0x08000000 +#define SZ_256M 0x10000000 +#define SZ_512M 0x20000000 + +#define SZ_1G 0x40000000 +#define SZ_2G 0x80000000 + +#endif + +/* END */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/cpu-feature-overrides.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/cpu-feature-overrides.h new file mode 100644 index 000000000..c6310cc6e --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/cpu-feature-overrides.h @@ -0,0 +1,71 @@ +/* + * ADM5120 specific CPU feature overrides + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This file was derived from: include/asm-mips/cpu-features.h + * Copyright (C) 2003, 2004 Ralf Baechle + * Copyright (C) 2004 Maciej W. Rozycki + * + * This program 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. + * + */ +#ifndef __ASM_MACH_ADM5120_CPU_FEATURE_OVERRIDES_H +#define __ASM_MACH_ADM5120_CPU_FEATURE_OVERRIDES_H + +/* + * The ADM5120 SOC has a built-in MIPS 4Kc core. + */ +#define cpu_has_tlb 1 +#define cpu_has_4kex 1 +#define cpu_has_3k_cache 0 +#define cpu_has_4k_cache 1 +#define cpu_has_tx39_cache 0 +#define cpu_has_sb1_cache 0 +#define cpu_has_fpu 0 +#define cpu_has_32fpr 0 +#define cpu_has_counter 1 +#define cpu_has_watch 1 +#define cpu_has_divec 1 +/* #define cpu_has_vce ? */ +/* #define cpu_has_cache_cdex_p ? */ +/* #define cpu_has_cache_cdex_s ? */ +#define cpu_has_prefetch 1 +/* #define cpu_has_mcheck ? */ +#define cpu_has_ejtag 1 +#define cpu_has_llsc 1 + +#define cpu_has_mips16 0 +#define cpu_has_mdmx 0 +#define cpu_has_mips3d 0 +#define cpu_has_smartmips 0 + +/* #define cpu_has_vtag_icache ? */ +/* #define cpu_has_dc_aliases ? */ +/* #define cpu_has_ic_fills_f_dc ? */ +/* #define cpu_has_pindexed_dcache ? */ + +/* #define cpu_icache_snoops_remote_store ? */ + +#define cpu_has_mips32r1 1 +#define cpu_has_mips32r2 0 +#define cpu_has_mips64r1 0 +#define cpu_has_mips64r2 0 + +#define cpu_has_dsp 0 +#define cpu_has_mipsmt 0 + +/* #define cpu_has_nofpuex ? */ +#define cpu_has_64bits 0 +#define cpu_has_64bit_zero_reg 0 +#define cpu_has_64bit_gp_regs 0 +#define cpu_has_64bit_addresses 0 + +/* #define cpu_has_inclusive_pcaches ? */ + +#define cpu_dcache_line_size() 16 +#define cpu_icache_line_size() 16 + +#endif /* __ASM_MACH_ADM5120_CPU_FEATURE_OVERRIDES_H */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/gpio.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/gpio.h new file mode 100644 index 000000000..7ba7efca1 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/gpio.h @@ -0,0 +1,115 @@ +/* + * ADM5120 GPIO wrappers for arch-neutral GPIO calls + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _ASM_MIPS_MACH_ADM5120_GPIO_H +#define _ASM_MIPS_MACH_ADM5120_GPIO_H + +#define ARCH_NR_GPIOS 64 + +#include + +#include + +#define ADM5120_GPIO_PIN0 0 +#define ADM5120_GPIO_PIN1 1 +#define ADM5120_GPIO_PIN2 2 +#define ADM5120_GPIO_PIN3 3 +#define ADM5120_GPIO_PIN4 4 +#define ADM5120_GPIO_PIN5 5 +#define ADM5120_GPIO_PIN6 6 +#define ADM5120_GPIO_PIN7 7 +#define ADM5120_GPIO_P0L0 8 +#define ADM5120_GPIO_P0L1 9 +#define ADM5120_GPIO_P0L2 10 +#define ADM5120_GPIO_P1L0 11 +#define ADM5120_GPIO_P1L1 12 +#define ADM5120_GPIO_P1L2 13 +#define ADM5120_GPIO_P2L0 14 +#define ADM5120_GPIO_P2L1 15 +#define ADM5120_GPIO_P2L2 16 +#define ADM5120_GPIO_P3L0 17 +#define ADM5120_GPIO_P3L1 18 +#define ADM5120_GPIO_P3L2 19 +#define ADM5120_GPIO_P4L0 20 +#define ADM5120_GPIO_P4L1 21 +#define ADM5120_GPIO_P4L2 22 +#define ADM5120_GPIO_MAX 22 +#define ADM5120_GPIO_COUNT ADM5120_GPIO_MAX+1 + +#define ADM5120_GPIO_LOW 0 +#define ADM5120_GPIO_HIGH 1 + +#define ADM5120_GPIO_SWITCH 0x10 +#define ADM5120_GPIO_FLASH (ADM5120_GPIO_SWITCH | LED_MODE_FLASH) +#define ADM5120_GPIO_LINK (ADM5120_GPIO_SWITCH | LED_MODE_LINK) +#define ADM5120_GPIO_SPEED (ADM5120_GPIO_SWITCH | LED_MODE_SPEED) +#define ADM5120_GPIO_DUPLEX (ADM5120_GPIO_SWITCH | LED_MODE_DUPLEX) +#define ADM5120_GPIO_ACT (ADM5120_GPIO_SWITCH | LED_MODE_ACT) +#define ADM5120_GPIO_COLL (ADM5120_GPIO_SWITCH | LED_MODE_COLL) +#define ADM5120_GPIO_LINK_ACT (ADM5120_GPIO_SWITCH | LED_MODE_LINK_ACT) +#define ADM5120_GPIO_DUPLEX_COLL (ADM5120_GPIO_SWITCH | LED_MODE_DUPLEX_COLL) +#define ADM5120_GPIO_10M_ACT (ADM5120_GPIO_SWITCH | LED_MODE_10M_ACT) +#define ADM5120_GPIO_100M_ACT (ADM5120_GPIO_SWITCH | LED_MODE_100M_ACT) + +extern int __adm5120_gpio0_get_value(unsigned gpio); +extern void __adm5120_gpio0_set_value(unsigned gpio, int value); +extern int __adm5120_gpio1_get_value(unsigned gpio); +extern void __adm5120_gpio1_set_value(unsigned gpio, int value); +extern int adm5120_gpio_to_irq(unsigned gpio); +extern int adm5120_irq_to_gpio(unsigned irq); + +static inline int gpio_get_value(unsigned gpio) +{ + int ret; + + switch (gpio) { + case ADM5120_GPIO_PIN0 ... ADM5120_GPIO_PIN7: + ret = __adm5120_gpio0_get_value(gpio); + break; + case ADM5120_GPIO_P0L0 ... ADM5120_GPIO_P4L2: + ret = __adm5120_gpio1_get_value(gpio - ADM5120_GPIO_P0L0); + break; + default: + ret = __gpio_get_value(gpio); + break; + } + + return ret; +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + switch (gpio) { + case ADM5120_GPIO_PIN0 ... ADM5120_GPIO_PIN7: + __adm5120_gpio0_set_value(gpio, value); + break; + case ADM5120_GPIO_P0L0 ... ADM5120_GPIO_P4L2: + __adm5120_gpio1_set_value(gpio - ADM5120_GPIO_P0L0, value); + break; + default: + __gpio_set_value(gpio, value); + break; + } +} + +static inline int gpio_to_irq(unsigned gpio) +{ + return adm5120_gpio_to_irq(gpio); +} + +static inline int irq_to_gpio(unsigned irq) +{ + return adm5120_irq_to_gpio(irq); +} + +#define gpio_cansleep __gpio_cansleep + +#endif /* _ASM_MIPS_MACH_ADM5120_GPIO_H */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/irq.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/irq.h new file mode 100644 index 000000000..b0350c8b8 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/irq.h @@ -0,0 +1,43 @@ +/* + * ADM5120 specific IRQ numbers + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ +#ifndef _ASM_MIPS_MACH_ADM5120_IRQ_H +#define _ASM_MIPS_MACH_ADM5120_IRQ_H + +#define MIPS_CPU_IRQ_BASE 0 +#define NR_IRQS 24 + +#include_next + +#include + +#define NO_IRQ (-1) + +#define MIPS_CPU_IRQ_COUNT 8 +#define MIPS_CPU_IRQ(x) (MIPS_CPU_IRQ_BASE + (x)) + +#define ADM5120_INTC_IRQ_BASE (MIPS_CPU_IRQ_BASE + MIPS_CPU_IRQ_COUNT) +#define ADM5120_INTC_IRQ(x) (ADM5120_INTC_IRQ_BASE + (x)) + +#define ADM5120_IRQ_INTC MIPS_CPU_IRQ(2) +#define ADM5120_IRQ_COUNTER MIPS_CPU_IRQ(7) + +#define ADM5120_IRQ_TIMER ADM5120_INTC_IRQ(INTC_IRQ_TIMER) +#define ADM5120_IRQ_UART0 ADM5120_INTC_IRQ(INTC_IRQ_UART0) +#define ADM5120_IRQ_UART1 ADM5120_INTC_IRQ(INTC_IRQ_UART1) +#define ADM5120_IRQ_USBC ADM5120_INTC_IRQ(INTC_IRQ_USBC) +#define ADM5120_IRQ_GPIO2 ADM5120_INTC_IRQ(INTC_IRQ_GPIO2) +#define ADM5120_IRQ_GPIO4 ADM5120_INTC_IRQ(INTC_IRQ_GPIO4) +#define ADM5120_IRQ_PCI0 ADM5120_INTC_IRQ(INTC_IRQ_PCI0) +#define ADM5120_IRQ_PCI1 ADM5120_INTC_IRQ(INTC_IRQ_PCI1) +#define ADM5120_IRQ_PCI2 ADM5120_INTC_IRQ(INTC_IRQ_PCI2) +#define ADM5120_IRQ_SWITCH ADM5120_INTC_IRQ(INTC_IRQ_SWITCH) + +#endif /* _ASM_MIPS_MACH_ADM5120_IRQ_H */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/admboot.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/admboot.h new file mode 100644 index 000000000..fa42bf714 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/admboot.h @@ -0,0 +1,17 @@ +/* + * ADMBoot specific definitions + * + * Copyright (C) 2008 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _ADMBOOT_H +#define _ADMBOOT_H + +extern int admboot_get_mac_base(u32 offset, u32 len, u8 *mac) __init; + +#endif /* _ADMBOOT_H */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/cfe.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/cfe.h new file mode 100644 index 000000000..0cb3eee70 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/cfe.h @@ -0,0 +1,18 @@ +/* + * Broadcom's CFE definitions + * + * Copyright (C) 2006-2008 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _PROM_CFE_H_ +#define _PROM_CFE_H_ + +extern int cfe_present(void) __init; +extern char *cfe_getenv(char *); + +#endif /*_PROM_CFE_H_*/ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/generic.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/generic.h new file mode 100644 index 000000000..778df2467 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/generic.h @@ -0,0 +1,18 @@ +/* + * Generic prom definitions + * + * Copyright (C) 2006-2008 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _PROM_GENERIC_H_ +#define _PROM_GENERIC_H_ + +extern int generic_prom_present(void) __init; +extern char *generic_prom_getenv(char *); + +#endif /*_PROM_GENERIC_H_*/ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/myloader.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/myloader.h new file mode 100644 index 000000000..ea8db81ed --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/myloader.h @@ -0,0 +1,179 @@ +/* + * Compex's MyLoader specific definitions + * + * Copyright (C) 2006-2008 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _MYLOADER_H_ +#define _MYLOADER_H_ + +/* + * Firmware file format: + * + *
+ * [] + * ... + * [] + * + * [] + * ... + * [] + * + * + */ + +/* Myloader specific magic numbers */ +#define MYLO_MAGIC_FIRMWARE 0x4C594D00 +#define MYLO_MAGIC_20021103 0x20021103 +#define MYLO_MAGIC_20021107 0x20021107 + +#define MYLO_MAGIC_SYS_PARAMS MYLO_MAGIC_20021107 +#define MYLO_MAGIC_PARTITIONS MYLO_MAGIC_20021103 +#define MYLO_MAGIC_BOARD_PARAMS MYLO_MAGIC_20021103 + +/* + * Addresses of the data structures provided by MyLoader + */ +#define MYLO_MIPS_SYS_PARAMS 0x80000800 /* System Parameters */ +#define MYLO_MIPS_BOARD_PARAMS 0x80000A00 /* Board Parameters */ +#define MYLO_MIPS_PARTITIONS 0x80000C00 /* Partition Table */ +#define MYLO_MIPS_BOOT_PARAMS 0x80000E00 /* Boot Parameters */ + +/* Vendor ID's (seems to be same as the PCI vendor ID's) */ +#define VENID_COMPEX 0x11F6 + +/* Devices based on the ADM5120 */ +#define DEVID_COMPEX_NP27G 0x0078 +#define DEVID_COMPEX_NP28G 0x044C +#define DEVID_COMPEX_NP28GHS 0x044E +#define DEVID_COMPEX_WP54Gv1C 0x0514 +#define DEVID_COMPEX_WP54G 0x0515 +#define DEVID_COMPEX_WP54AG 0x0546 +#define DEVID_COMPEX_WPP54AG 0x0550 +#define DEVID_COMPEX_WPP54G 0x0555 + +/* Devices based on the IXP422 */ +#define DEVID_COMPEX_WP18 0x047E +#define DEVID_COMPEX_NP18A 0x0489 + +/* Other devices */ +#define DEVID_COMPEX_NP26G8M 0x03E8 +#define DEVID_COMPEX_NP26G16M 0x03E9 + +struct mylo_fw_header { + uint32_t magic; /* must be MYLO_MAGIC_FIRMWARE */ + uint32_t crc; /* CRC of the whole firmware */ + uint32_t res0; /* unknown/unused */ + uint32_t res1; /* unknown/unused */ + uint16_t vid; /* vendor ID */ + uint16_t did; /* device ID */ + uint16_t svid; /* sub vendor ID */ + uint16_t sdid; /* sub device ID */ + uint32_t rev; /* device revision */ + uint32_t fwhi; /* FIXME: firmware version high? */ + uint32_t fwlo; /* FIXME: firmware version low? */ + uint32_t flags; /* firmware flags */ +}; + +#define FW_FLAG_BOARD_PARAMS_WP 0x01 /* board parameters are write protected */ +#define FW_FLAG_BOOT_SECTOR_WE 0x02 /* enable of write boot sectors (below 64K) */ + +struct mylo_fw_blockdesc { + uint32_t type; /* block type */ + uint32_t addr; /* relative address to flash start */ + uint32_t dlen; /* size of block data in bytes */ + uint32_t blen; /* total size of block in bytes */ +}; + +#define FW_DESC_TYPE_UNUSED 0 +#define FW_DESC_TYPE_USED 1 + +struct mylo_partition { + uint16_t flags; /* partition flags */ + uint16_t type; /* type of the partition */ + uint32_t addr; /* relative address of the partition from the + flash start */ + uint32_t size; /* size of the partition in bytes */ + uint32_t param; /* if this is the active partition, the + MyLoader load code to this address */ +}; + +#define PARTITION_FLAG_ACTIVE 0x8000 /* this is the active partition, + * MyLoader loads firmware from here */ +#define PARTITION_FLAG_ISRAM 0x2000 /* FIXME: this is a RAM partition? */ +#define PARTIIION_FLAG_RAMLOAD 0x1000 /* FIXME: load this partition into the RAM? */ +#define PARTITION_FLAG_PRELOAD 0x0800 /* the partition data preloaded to RAM + * before decompression */ +#define PARTITION_FLAG_HAVEHDR 0x0002 /* the partition data have a header */ + +#define PARTITION_TYPE_FREE 0 +#define PARTITION_TYPE_USED 1 + +#define MYLO_MAX_PARTITIONS 8 /* maximum number of partitions in the + partition table */ + +struct mylo_partition_table { + uint32_t magic; /* must be MYLO_MAGIC_PARTITIONS */ + uint32_t res0; /* unknown/unused */ + uint32_t res1; /* unknown/unused */ + uint32_t res2; /* unknown/unused */ + struct mylo_partition partitions[MYLO_MAX_PARTITIONS]; +}; + +struct mylo_partition_header { + uint32_t len; /* length of the partition data */ + uint32_t crc; /* CRC value of the partition data */ +}; + +struct mylo_system_params { + uint32_t magic; /* must be MYLO_MAGIC_SYS_PARAMS */ + uint32_t res0; + uint32_t res1; + uint32_t mylo_ver; + uint16_t vid; /* Vendor ID */ + uint16_t did; /* Device ID */ + uint16_t svid; /* Sub Vendor ID */ + uint16_t sdid; /* Sub Device ID */ + uint32_t rev; /* device revision */ + uint32_t fwhi; + uint32_t fwlo; + uint32_t tftp_addr; + uint32_t prog_start; + uint32_t flash_size; /* Size of boot FLASH in bytes */ + uint32_t dram_size; /* Size of onboard RAM in bytes */ +}; + + +struct mylo_eth_addr { + uint8_t mac[6]; + uint8_t csum[2]; +}; + +#define MYLO_ETHADDR_COUNT 8 /* maximum number of ethernet address + in the board parameters */ + +struct mylo_board_params { + uint32_t magic; /* must be MYLO_MAGIC_BOARD_PARAMS */ + uint32_t res0; + uint32_t res1; + uint32_t res2; + struct mylo_eth_addr addr[MYLO_ETHADDR_COUNT]; +}; + +struct myloader_info { + u32 vid; + u32 did; + u32 svid; + u32 sdid; + uint8_t macs[MYLO_ETHADDR_COUNT][6]; +}; + +extern struct myloader_info myloader_info; +extern int myloader_present(void) __init; + +#endif /* _MYLOADER_H_*/ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/routerboot.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/routerboot.h new file mode 100644 index 000000000..91ac05a63 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/routerboot.h @@ -0,0 +1,36 @@ +/* + * Mikrotik's RouterBOOT definitions + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _PROM_ROUTERBOOT_H_ +#define _PROM_ROUTERBOOT_H_ + +struct rb_bios_settings { + u32 hs_offs; /* hard settings offset */ + u32 hs_size; /* hard settings size */ + u32 fw_offs; /* firmware offset */ + u32 ss_offs; /* soft settings offset */ + u32 ss_size; /* soft settings size */ +}; + +struct rb_hard_settings { + char *name; /* board name */ + char *bios_ver; /* BIOS version */ + u32 mem_size; /* memory size in bytes */ + u32 mac_count; /* number of mac addresses */ + u8 *mac_base; /* mac address base */ +}; + +extern int routerboot_present(void) __init; +extern char *routerboot_get_boardname(void); + +extern struct rb_hard_settings rb_hs; + +#endif /* _PROM_ROUTERBOOT_H_ */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/zynos.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/zynos.h new file mode 100644 index 000000000..d1e3e5b94 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/prom/zynos.h @@ -0,0 +1,86 @@ +/* + * ZyNOS (ZyXEL's Networking OS) definitions + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _ZYNOS_H +#define _ZYNOS_H + +#define ZYNOS_NAME_LEN 32 +#define ZYNOS_FEAT_BYTES 22 +#define ZYNOS_MAC_LEN 6 + +struct zynos_board_info { + unsigned char vendor[ZYNOS_NAME_LEN]; + unsigned char product[ZYNOS_NAME_LEN]; + u32 bootext_addr; + u32 res0; + u16 board_id; + u8 res1[6]; + u8 feat_other[ZYNOS_FEAT_BYTES]; + u8 feat_main; + u8 res2; + u8 mac[ZYNOS_MAC_LEN]; + u8 country; + u8 dbgflag; +} __attribute__ ((packed)); + +/* + * Vendor IDs + */ +#define ZYNOS_VENDOR_ID_ZYXEL 0 +#define ZYNOS_VENDOR_ID_NETGEAR 1 +#define ZYNOS_VENDOR_ID_DLINK 2 +#define ZYNOS_VENDOR_ID_OTHER 3 +#define ZYNOS_VENDOR_ID_LUCENT 4 + +/* + * Vendor names + */ +#define ZYNOS_VENDOR_DLINK "D-Link" +#define ZYNOS_VENDOR_LUCENT "LUCENT" +#define ZYNOS_VENDOR_NETGEAR "NetGear" +#define ZYNOS_VENDOR_ZYXEL "ZyXEL" + +/* + * Board IDs (big-endian) + */ +#define ZYNOS_BOARD_ES2108 0x00F2 /* Ethernet Switch 2108 */ +#define ZYNOS_BOARD_ES2108F 0x01AF /* Ethernet Switch 2108-F */ +#define ZYNOS_BOARD_ES2108G 0x00F3 /* Ethernet Switch 2108-G */ +#define ZYNOS_BOARD_ES2108LC 0x00FC /* Ethernet Switch 2108-LC */ +#define ZYNOS_BOARD_ES2108PWR 0x00F4 /* Ethernet Switch 2108PWR */ +#define ZYNOS_BOARD_HS100 0x9FF1 /* HomeSafe 100/100W */ +#define ZYNOS_BOARD_P334 0x9FF5 /* Prestige 334 */ +#define ZYNOS_BOARD_P334U 0x9FDD /* Prestige 334U */ +#define ZYNOS_BOARD_P334W 0x9FF3 /* Prestige 334W */ +#define ZYNOS_BOARD_P334WH 0x00E0 /* Prestige 334WH */ +#define ZYNOS_BOARD_P334WHD 0x00E1 /* Prestige 334WHD */ +#define ZYNOS_BOARD_P334WT 0x9FEF /* Prestige 334WT */ +#define ZYNOS_BOARD_P334WT_ALT 0x9F02 /* Prestige 334WT alternative*/ +#define ZYNOS_BOARD_P335 0x9FED /* Prestige 335/335WT */ +#define ZYNOS_BOARD_P335PLUS 0x0025 /* Prestige 335Plus */ +#define ZYNOS_BOARD_P335U 0x9FDC /* Prestige 335U */ + +/* + * Some magic numbers (big-endian) + */ +#define ZYNOS_MAGIC_DBGAREA1 0x48646267 /* "Hdbg" */ +#define ZYNOS_MAGIC_DBGAREA2 0x61726561 /* "area" */ + +struct bootbase_info { + u16 vendor_id; + u16 board_id; + u8 mac[6]; +}; + +extern struct bootbase_info bootbase_info; +extern int bootbase_present(void) __init; + +#endif /* _ZYNOS_H */ diff --git a/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/war.h b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/war.h new file mode 100644 index 000000000..87c35f375 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/include/asm/mach-adm5120/war.h @@ -0,0 +1,25 @@ +/* + * 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) 2002, 2004, 2007 by Ralf Baechle + */ +#ifndef __ASM_MIPS_MACH_ADM5120_WAR_H +#define __ASM_MIPS_MACH_ADM5120_WAR_H + +#define R4600_V1_INDEX_ICACHEOP_WAR 0 +#define R4600_V1_HIT_CACHEOP_WAR 0 +#define R4600_V2_HIT_CACHEOP_WAR 0 +#define R5432_CP0_INTERRUPT_WAR 0 +#define BCM1250_M3_WAR 0 +#define SIBYTE_1956_WAR 0 +#define MIPS4K_ICACHE_REFILL_WAR 0 +#define MIPS_CACHE_SYNC_WAR 0 +#define TX49XX_ICACHE_INDEX_INV_WAR 0 +#define RM9000_CDEX_SMP_WAR 0 +#define ICACHE_REFILLS_WORKAROUND_WAR 0 +#define R10000_LLSC_WAR 0 +#define MIPS34K_MISSED_ITLB_WAR 0 + +#endif /* __ASM_MIPS_MACH_ADM5120_WAR_H */ diff --git a/target/linux/adm5120/files/arch/mips/pci/pci-adm5120.c b/target/linux/adm5120/files/arch/mips/pci/pci-adm5120.c new file mode 100644 index 000000000..f8d359806 --- /dev/null +++ b/target/linux/adm5120/files/arch/mips/pci/pci-adm5120.c @@ -0,0 +1,277 @@ +/* + * ADM5120 PCI Host Controller driver + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This code was based on the ADM5120 specific port of the Linux 2.6.10 kernel + * done by Jeroen Vreeken + * Copyright (C) 2005 Jeroen Vreeken (pe1rxq@amsat.org) + * + * Jeroen's code was based on the Linux 2.4.xx source codes found in various + * tarballs released by Edimax for it's ADM5120 based devices + * Copyright (C) ADMtek Incorporated + * + * This program 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. + * + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#undef DEBUG + +#ifdef DEBUG +#define DBG(f, a...) printk(KERN_DEBUG f, ## a) +#else +#define DBG(f, a...) do {} while (0) +#endif + +#define PCI_ENABLE 0x80000000 + +/* -------------------------------------------------------------------------*/ + +static unsigned int adm5120_pci_nr_irqs __initdata; +static struct adm5120_pci_irq *adm5120_pci_irq_map __initdata; + +static DEFINE_SPINLOCK(pci_lock); + +/* -------------------------------------------------------------------------*/ + +static inline void write_cfgaddr(u32 addr) +{ + __raw_writel((addr | PCI_ENABLE), + (void __iomem *)(KSEG1ADDR(ADM5120_PCICFG_ADDR))); +} + +static inline void write_cfgdata(u32 data) +{ + __raw_writel(data, (void __iomem *)KSEG1ADDR(ADM5120_PCICFG_DATA)); +} + +static inline u32 read_cfgdata(void) +{ + return __raw_readl((void __iomem *)KSEG1ADDR(ADM5120_PCICFG_DATA)); +} + +static inline u32 mkaddr(struct pci_bus *bus, unsigned int devfn, int where) +{ + return ((bus->number & 0xFF) << 16) | ((devfn & 0xFF) << 8) | \ + (where & 0xFC); +} + +/* -------------------------------------------------------------------------*/ + +static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *val) +{ + unsigned long flags; + u32 data; + + spin_lock_irqsave(&pci_lock, flags); + + write_cfgaddr(mkaddr(bus, devfn, where)); + data = read_cfgdata(); + + DBG("PCI: cfg_read %02u.%02u.%01u/%02X:%01d, cfg:0x%08X", + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), + where, size, data); + + switch (size) { + case 1: + if (where & 1) + data >>= 8; + if (where & 2) + data >>= 16; + data &= 0xFF; + break; + case 2: + if (where & 2) + data >>= 16; + data &= 0xFFFF; + break; + } + + *val = data; + DBG(", 0x%08X returned\n", data); + + spin_unlock_irqrestore(&pci_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 val) +{ + unsigned long flags; + u32 data; + int s; + + spin_lock_irqsave(&pci_lock, flags); + + write_cfgaddr(mkaddr(bus, devfn, where)); + data = read_cfgdata(); + + DBG("PCI: cfg_write %02u.%02u.%01u/%02X:%01d, cfg:0x%08X", + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), + where, size, data); + + switch (size) { + case 1: + s = ((where & 3) << 3); + data &= ~(0xFF << s); + data |= ((val & 0xFF) << s); + break; + case 2: + s = ((where & 2) << 4); + data &= ~(0xFFFF << s); + data |= ((val & 0xFFFF) << s); + break; + case 4: + data = val; + break; + } + + write_cfgdata(data); + DBG(", 0x%08X written\n", data); + + spin_unlock_irqrestore(&pci_lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops adm5120_pci_ops = { + .read = pci_config_read, + .write = pci_config_write, +}; + +/* -------------------------------------------------------------------------*/ + +static void adm5120_pci_fixup(struct pci_dev *dev) +{ + if (dev->devfn != 0) + return; + + /* setup COMMAND register */ + pci_write_config_word(dev, PCI_COMMAND, + (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER)); + + /* setup CACHE_LINE_SIZE register */ + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 4); + + /* setup BARS */ + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0); +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ADMTEK, PCI_DEVICE_ID_ADMTEK_ADM5120, + adm5120_pci_fixup); + +/* -------------------------------------------------------------------------*/ + +void __init adm5120_pci_set_irq_map(unsigned int nr_irqs, + struct adm5120_pci_irq *map) +{ + adm5120_pci_nr_irqs = nr_irqs; + adm5120_pci_irq_map = map; +} + +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq = -1; + int i; + + if ((!adm5120_pci_nr_irqs) || (!adm5120_pci_irq_map)) { + printk(KERN_ALERT "PCI: pci_irq_map is not initialized\n"); + goto out; + } + + if (slot < 1 || slot > 4) { + printk(KERN_ALERT "PCI: slot number %u is not supported\n", + slot); + goto out; + } + + for (i = 0; i < adm5120_pci_nr_irqs; i++) { + if ((adm5120_pci_irq_map[i].slot == slot) + && (adm5120_pci_irq_map[i].func == PCI_FUNC(dev->devfn)) + && (adm5120_pci_irq_map[i].pin == pin)) { + irq = adm5120_pci_irq_map[i].irq; + break; + } + } + + if (irq < 0) { + printk(KERN_ALERT "PCI: no irq found for %s pin:%u\n", + pci_name((struct pci_dev *)dev), pin); + } else { + printk(KERN_INFO "PCI: mapping irq for %s pin:%u, irq:%d\n", + pci_name((struct pci_dev *)dev), pin, irq); + } + +out: + return irq; +} + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +/* -------------------------------------------------------------------------*/ + +static struct resource pci_io_resource = { + .name = "ADM5120 PCI I/O", + .start = ADM5120_PCIIO_BASE, + .end = ADM5120_PCICFG_ADDR-1, + .flags = IORESOURCE_IO +}; + +static struct resource pci_mem_resource = { + .name = "ADM5120 PCI MEM", + .start = ADM5120_PCIMEM_BASE, + .end = ADM5120_PCIIO_BASE-1, + .flags = IORESOURCE_MEM +}; + +static struct pci_controller adm5120_controller = { + .pci_ops = &adm5120_pci_ops, + .io_resource = &pci_io_resource, + .mem_resource = &pci_mem_resource, +}; + +static int __init adm5120_pci_setup(void) +{ + if (adm5120_package_pqfp()) { + printk(KERN_INFO "PCI: not available on ADM5120P\n"); + return -1; + } + + /* Avoid ISA compat ranges. */ + PCIBIOS_MIN_IO = 0x00000000; + PCIBIOS_MIN_MEM = 0x00000000; + + /* Set I/O resource limits. */ + ioport_resource.end = 0x1fffffff; + iomem_resource.end = 0xffffffff; + + register_pci_controller(&adm5120_controller); + return 0; +} + +arch_initcall(adm5120_pci_setup); diff --git a/target/linux/adm5120/files/drivers/ata/pata_rb153_cf.c b/target/linux/adm5120/files/drivers/ata/pata_rb153_cf.c new file mode 100644 index 000000000..71f8ad6b8 --- /dev/null +++ b/target/linux/adm5120/files/drivers/ata/pata_rb153_cf.c @@ -0,0 +1,267 @@ +/* + * A low-level PATA driver to handle a Compact Flash connected on the + * Mikrotik's RouterBoard 153 board. + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This file was based on: drivers/ata/pata_ixp4xx_cf.c + * Copyright (C) 2006-07 Tower Technologies + * Author: Alessandro Zummo + * + * Also was based on the driver for Linux 2.4.xx published by Mikrotik for + * their RouterBoard 1xx and 5xx series devices. The original Mikrotik code + * seems not to have a license. + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DRV_NAME "pata-rb153-cf" +#define DRV_VERSION "0.5.0" +#define DRV_DESC "PATA driver for RouterBOARD 153 Compact Flash" + +#define RB153_CF_MAXPORTS 1 +#define RB153_CF_IO_DELAY 100 + +#define RB153_CF_REG_CMD 0x0800 +#define RB153_CF_REG_CTRL 0x080E +#define RB153_CF_REG_DATA 0x0C00 + +struct rb153_cf_info { + void __iomem *iobase; + unsigned int gpio_line; + int frozen; + unsigned int irq; +}; + +static inline void rb153_pata_finish_io(struct ata_port *ap) +{ + struct rb153_cf_info *info = ap->host->private_data; + + /* FIXME: Keep previous delay. If this is merely a fence then + * ata_sff_sync might be sufficient. */ + ata_sff_dma_pause(ap); + ndelay(RB153_CF_IO_DELAY); + + irq_set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); +} + +static void rb153_pata_exec_command(struct ata_port *ap, + const struct ata_taskfile *tf) +{ + writeb(tf->command, ap->ioaddr.command_addr); + rb153_pata_finish_io(ap); +} + +static unsigned int rb153_pata_data_xfer(struct ata_device *adev, + unsigned char *buf, + unsigned int buflen, + int write_data) +{ + void __iomem *ioaddr = adev->link->ap->ioaddr.data_addr; + unsigned int t; + + t = buflen; + if (write_data) { + for (; t > 0; t--, buf++) + writeb(*buf, ioaddr); + } else { + for (; t > 0; t--, buf++) + *buf = readb(ioaddr); + } + + rb153_pata_finish_io(adev->link->ap); + return buflen; +} + +static void rb153_pata_freeze(struct ata_port *ap) +{ + struct rb153_cf_info *info = ap->host->private_data; + + info->frozen = 1; +} + +static void rb153_pata_thaw(struct ata_port *ap) +{ + struct rb153_cf_info *info = ap->host->private_data; + + info->frozen = 0; +} + +static irqreturn_t rb153_pata_irq_handler(int irq, void *dev_instance) +{ + struct ata_host *ah = dev_instance; + struct rb153_cf_info *info = ah->private_data; + + if (gpio_get_value(info->gpio_line)) { + irq_set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW); + if (!info->frozen) + ata_sff_interrupt(irq, dev_instance); + } else { + irq_set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); + } + + return IRQ_HANDLED; +} + +static struct ata_port_operations rb153_pata_port_ops = { + .inherits = &ata_sff_port_ops, + .sff_exec_command = rb153_pata_exec_command, + .sff_data_xfer = rb153_pata_data_xfer, + .freeze = rb153_pata_freeze, + .thaw = rb153_pata_thaw, +}; + +static struct scsi_host_template rb153_pata_sht = { + ATA_PIO_SHT(DRV_NAME), +}; + +static void rb153_pata_setup_port(struct ata_host *ah) +{ + struct rb153_cf_info *info = ah->private_data; + struct ata_port *ap; + + ap = ah->ports[0]; + + ap->ops = &rb153_pata_port_ops; + ap->pio_mask = 0x1f; /* PIO4 */ + + ap->ioaddr.cmd_addr = info->iobase + RB153_CF_REG_CMD; + ap->ioaddr.ctl_addr = info->iobase + RB153_CF_REG_CTRL; + ap->ioaddr.altstatus_addr = info->iobase + RB153_CF_REG_CTRL; + + ata_sff_std_ports(&ap->ioaddr); + + ap->ioaddr.data_addr = info->iobase + RB153_CF_REG_DATA; +} + +static __devinit int rb153_pata_driver_probe(struct platform_device *pdev) +{ + unsigned int irq; + int gpio; + struct resource *res; + struct ata_host *ah; + struct rb153_cf_info *info; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "no IOMEM resource found\n"); + return -EINVAL; + } + + irq = platform_get_irq(pdev, 0); + if (irq <= 0) { + dev_err(&pdev->dev, "no IRQ resource found\n"); + return -ENOENT; + } + + gpio = irq_to_gpio(irq); + if (gpio < 0) { + dev_err(&pdev->dev, "no GPIO found for irq%d\n", irq); + return -ENOENT; + } + + ret = gpio_request(gpio, DRV_NAME); + if (ret) { + dev_err(&pdev->dev, "GPIO request failed\n"); + return ret; + } + + ah = ata_host_alloc(&pdev->dev, RB153_CF_MAXPORTS); + if (!ah) + return -ENOMEM; + + platform_set_drvdata(pdev, ah); + + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + ah->private_data = info; + info->gpio_line = gpio; + info->irq = irq; + + info->iobase = devm_ioremap_nocache(&pdev->dev, res->start, + res->end - res->start + 1); + if (!info->iobase) + return -ENOMEM; + + ret = gpio_direction_input(gpio); + if (ret) { + dev_err(&pdev->dev, "unable to set GPIO direction, err=%d\n", + ret); + goto err_free_gpio; + } + + rb153_pata_setup_port(ah); + + ret = ata_host_activate(ah, irq, rb153_pata_irq_handler, + IRQF_TRIGGER_LOW, &rb153_pata_sht); + if (ret) + goto err_free_gpio; + + return 0; + +err_free_gpio: + gpio_free(gpio); + + return ret; +} + +static __devexit int rb153_pata_driver_remove(struct platform_device *pdev) +{ + struct ata_host *ah = platform_get_drvdata(pdev); + struct rb153_cf_info *info = ah->private_data; + + ata_host_detach(ah); + gpio_free(info->gpio_line); + + return 0; +} + +static struct platform_driver rb153_pata_platform_driver = { + .probe = rb153_pata_driver_probe, + .remove = __devexit_p(rb153_pata_driver_remove), + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +/* ------------------------------------------------------------------------ */ + +#define DRV_INFO DRV_DESC " version " DRV_VERSION + +static int __init rb153_pata_module_init(void) +{ + printk(KERN_INFO DRV_INFO "\n"); + + return platform_driver_register(&rb153_pata_platform_driver); +} + +static void __exit rb153_pata_module_exit(void) +{ + platform_driver_unregister(&rb153_pata_platform_driver); +} + +MODULE_AUTHOR("Gabor Juhos "); +MODULE_DESCRIPTION(DRV_DESC); +MODULE_VERSION(DRV_VERSION); +MODULE_LICENSE("GPL v2"); + +module_init(rb153_pata_module_init); +module_exit(rb153_pata_module_exit); diff --git a/target/linux/adm5120/files/drivers/leds/ledtrig-adm5120-switch.c b/target/linux/adm5120/files/drivers/leds/ledtrig-adm5120-switch.c new file mode 100644 index 000000000..23a54a0b9 --- /dev/null +++ b/target/linux/adm5120/files/drivers/leds/ledtrig-adm5120-switch.c @@ -0,0 +1,149 @@ +/* + * LED ADM5120 Switch Port State Trigger + * + * Copyright (C) 2007 Bernhard Held + * Copyright (C) 2007-2008 Gabor Juhos + * + * This file was based on: drivers/leds/ledtrig-timer.c + * Copyright 2005-2006 Openedhand Ltd. + * Author: Richard Purdie + * + * This program 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. + * + */ + +#include +#include +#include +#include + +#include + +#include "leds.h" + +#define DRV_NAME "port_state" +#define DRV_DESC "LED ADM5120 Switch Port State Trigger" + +struct port_state { + char *name; + unsigned int value; +}; + +#define PORT_STATE(n, v) {.name = (n), .value = (v)} + +static struct port_state port_states[] = { + PORT_STATE("off", LED_OFF), + PORT_STATE("on", LED_FULL), + PORT_STATE("flash", ADM5120_GPIO_FLASH), + PORT_STATE("link", ADM5120_GPIO_LINK), + PORT_STATE("speed", ADM5120_GPIO_SPEED), + PORT_STATE("duplex", ADM5120_GPIO_DUPLEX), + PORT_STATE("act", ADM5120_GPIO_ACT), + PORT_STATE("coll", ADM5120_GPIO_COLL), + PORT_STATE("link_act", ADM5120_GPIO_LINK_ACT), + PORT_STATE("duplex_coll", ADM5120_GPIO_DUPLEX_COLL), + PORT_STATE("10M_act", ADM5120_GPIO_10M_ACT), + PORT_STATE("100M_act", ADM5120_GPIO_100M_ACT), +}; + +static ssize_t led_port_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct port_state *state = led_cdev->trigger_data; + int len = 0; + int i; + + *buf = '\0'; + for (i = 0; i < ARRAY_SIZE(port_states); i++) { + if (&port_states[i] == state) + len += sprintf(buf+len, "[%s] ", port_states[i].name); + else + len += sprintf(buf+len, "%s ", port_states[i].name); + } + len += sprintf(buf+len, "\n"); + + return len; +} + +static ssize_t led_port_state_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + size_t len; + int i; + + for (i = 0; i < ARRAY_SIZE(port_states); i++) { + len = strlen(port_states[i].name); + if (strncmp(port_states[i].name, buf, len) != 0) + continue; + + if (buf[len] != '\0' && buf[len] != '\n') + continue; + + led_cdev->trigger_data = &port_states[i]; + led_set_brightness(led_cdev, port_states[i].value); + return size; + } + + return -EINVAL; +} + +static DEVICE_ATTR(port_state, 0644, led_port_state_show, + led_port_state_store); + +static void adm5120_switch_trig_activate(struct led_classdev *led_cdev) +{ + struct port_state *state = port_states; + int rc; + + led_cdev->trigger_data = state; + + rc = device_create_file(led_cdev->dev, &dev_attr_port_state); + if (rc) + goto err; + + led_set_brightness(led_cdev, state->value); + + return; +err: + led_cdev->trigger_data = NULL; +} + +static void adm5120_switch_trig_deactivate(struct led_classdev *led_cdev) +{ + struct port_state *state = led_cdev->trigger_data; + + if (!state) + return; + + device_remove_file(led_cdev->dev, &dev_attr_port_state); + +} + +static struct led_trigger adm5120_switch_led_trigger = { + .name = DRV_NAME, + .activate = adm5120_switch_trig_activate, + .deactivate = adm5120_switch_trig_deactivate, +}; + +static int __init adm5120_switch_trig_init(void) +{ + led_trigger_register(&adm5120_switch_led_trigger); + return 0; +} + +static void __exit adm5120_switch_trig_exit(void) +{ + led_trigger_unregister(&adm5120_switch_led_trigger); +} + +module_init(adm5120_switch_trig_init); +module_exit(adm5120_switch_trig_exit); + +MODULE_AUTHOR("Bernhard Held , " + "Gabor Juhos "); +MODULE_DESCRIPTION(DRV_DESC); +MODULE_LICENSE("GPL v2"); diff --git a/target/linux/adm5120/files/drivers/mtd/maps/adm5120-flash.c b/target/linux/adm5120/files/drivers/mtd/maps/adm5120-flash.c new file mode 100644 index 000000000..f6a86f489 --- /dev/null +++ b/target/linux/adm5120/files/drivers/mtd/maps/adm5120-flash.c @@ -0,0 +1,482 @@ +/* + * Platform driver for NOR flash devices on ADM5120 based boards + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This file was derived from: drivers/mtd/map/physmap.c + * Copyright (C) 2003 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define DRV_NAME "adm5120-flash" +#define DRV_DESC "ADM5120 flash MAP driver" +#define MAX_PARSED_PARTS 8 + +#ifdef ADM5120_FLASH_DEBUG +#define MAP_DBG(m, f, a...) printk(KERN_INFO "%s: " f, (m->name) , ## a) +#else +#define MAP_DBG(m, f, a...) do {} while (0) +#endif +#define MAP_ERR(m, f, a...) printk(KERN_ERR "%s: " f, (m->name) , ## a) +#define MAP_INFO(m, f, a...) printk(KERN_INFO "%s: " f, (m->name) , ## a) + +struct adm5120_map_info { + struct map_info map; + void (*switch_bank)(unsigned); + unsigned long window_size; +}; + +struct adm5120_flash_info { + struct mtd_info *mtd; + struct resource *res; + struct platform_device *dev; + struct adm5120_map_info amap; +}; + +struct flash_desc { + u32 phys; + u32 srs_shift; +}; + +/* + * Globals + */ +static DEFINE_SPINLOCK(adm5120_flash_spin); +#define FLASH_LOCK() spin_lock(&adm5120_flash_spin) +#define FLASH_UNLOCK() spin_unlock(&adm5120_flash_spin) + +static u32 flash_bankwidths[4] = { 1, 2, 4, 0 }; + +static u32 flash_sizes[8] = { + 0, 512*1024, 1024*1024, 2*1024*1024, + 4*1024*1024, 0, 0, 0 +}; + +static struct flash_desc flash_descs[2] = { + { + .phys = ADM5120_SRAM0_BASE, + .srs_shift = MEMCTRL_SRS0_SHIFT, + }, { + .phys = ADM5120_SRAM1_BASE, + .srs_shift = MEMCTRL_SRS1_SHIFT, + } +}; + +static const char const *probe_types[] = { + "cfi_probe", + "jedec_probe", + "map_rom", + NULL +}; + +static const char const *parse_types[] = { + "cmdlinepart", +#ifdef CONFIG_MTD_REDBOOT_PARTS + "RedBoot", +#endif +#ifdef CONFIG_MTD_MYLOADER_PARTS + "MyLoader", +#endif + NULL, +}; + +#define BANK_SIZE (2<<20) +#define BANK_SIZE_MAX (4<<20) +#define BANK_OFFS_MASK (BANK_SIZE-1) +#define BANK_START_MASK (~BANK_OFFS_MASK) + +static inline struct adm5120_map_info *map_to_amap(struct map_info *map) +{ + return (struct adm5120_map_info *)map; +} + +static void adm5120_flash_switchbank(struct map_info *map, + unsigned long ofs) +{ + struct adm5120_map_info *amap = map_to_amap(map); + unsigned bank; + + if (amap->switch_bank == NULL) + return; + + bank = (ofs & BANK_START_MASK) >> 21; + if (bank > 1) + BUG(); + + MAP_DBG(map, "switching to bank %u, ofs=%lX\n", bank, ofs); + amap->switch_bank(bank); +} + +static map_word adm5120_flash_read(struct map_info *map, unsigned long ofs) +{ + struct adm5120_map_info *amap = map_to_amap(map); + map_word ret; + + MAP_DBG(map, "reading from ofs %lX\n", ofs); + + if (ofs >= amap->window_size) + return map_word_ff(map); + + FLASH_LOCK(); + adm5120_flash_switchbank(map, ofs); + ret = inline_map_read(map, (ofs & (amap->window_size-1))); + FLASH_UNLOCK(); + + return ret; +} + +static void adm5120_flash_write(struct map_info *map, const map_word datum, + unsigned long ofs) +{ + struct adm5120_map_info *amap = map_to_amap(map); + + MAP_DBG(map, "writing to ofs %lX\n", ofs); + + if (ofs > amap->window_size) + return; + + FLASH_LOCK(); + adm5120_flash_switchbank(map, ofs); + inline_map_write(map, datum, (ofs & (amap->window_size-1))); + FLASH_UNLOCK(); +} + +static void adm5120_flash_copy_from(struct map_info *map, void *to, + unsigned long from, ssize_t len) +{ + struct adm5120_map_info *amap = map_to_amap(map); + char *p; + ssize_t t; + + MAP_DBG(map, "copy_from, to=%lX, from=%lX, len=%lX\n", + (unsigned long)to, from, (unsigned long)len); + + if (from > amap->window_size) + return; + + p = (char *)to; + while (len > 0) { + t = len; + if ((from < BANK_SIZE) && ((from+len) > BANK_SIZE)) + t = BANK_SIZE-from; + + FLASH_LOCK(); + MAP_DBG(map, "copying %lu byte(s) from %lX to %lX\n", + (unsigned long)t, (from & (amap->window_size-1)), + (unsigned long)p); + adm5120_flash_switchbank(map, from); + inline_map_copy_from(map, p, (from & (amap->window_size-1)), t); + FLASH_UNLOCK(); + p += t; + from += t; + len -= t; + } +} + +static int adm5120_flash_initres(struct adm5120_flash_info *info) +{ + struct map_info *map = &info->amap.map; + int err = 0; + + info->res = request_mem_region(map->phys, info->amap.window_size, + map->name); + if (info->res == NULL) { + MAP_ERR(map, "could not reserve memory region\n"); + err = -ENOMEM; + goto out; + } + + map->virt = ioremap_nocache(map->phys, info->amap.window_size); + if (map->virt == NULL) { + MAP_ERR(map, "failed to ioremap flash region\n"); + err = -ENOMEM; + goto out; + } + +out: + return err; +} + +static int adm5120_flash_initinfo(struct adm5120_flash_info *info, + struct platform_device *dev) +{ + struct map_info *map = &info->amap.map; + struct adm5120_flash_platform_data *pdata = dev->dev.platform_data; + struct flash_desc *fdesc; + u32 t = 0; + + map->name = dev_name(&dev->dev); + + if (dev->id > 1) { + MAP_ERR(map, "invalid flash id\n"); + goto err_out; + } + + fdesc = &flash_descs[dev->id]; + + if (pdata) + info->amap.window_size = pdata->window_size; + + if (info->amap.window_size == 0) { + /* get memory window size */ + t = SW_READ_REG(SWITCH_REG_MEMCTRL) >> fdesc->srs_shift; + t &= MEMCTRL_SRS_MASK; + info->amap.window_size = flash_sizes[t]; + } + + if (info->amap.window_size == 0) { + MAP_ERR(map, "unable to determine window size\n"); + goto err_out; + } + + /* get flash bus width */ + switch (dev->id) { + case 0: + t = MPMC_READ_REG(SC1) & SC_MW_MASK; + break; + case 1: + t = MPMC_READ_REG(SC0) & SC_MW_MASK; + break; + } + map->bankwidth = flash_bankwidths[t]; + if (map->bankwidth == 0) { + MAP_ERR(map, "invalid bus width detected\n"); + goto err_out; + } + + map->phys = fdesc->phys; + map->size = BANK_SIZE_MAX; + + simple_map_init(map); + map->read = adm5120_flash_read; + map->write = adm5120_flash_write; + map->copy_from = adm5120_flash_copy_from; + + if (pdata) { + map->set_vpp = pdata->set_vpp; + info->amap.switch_bank = pdata->switch_bank; + } + + info->dev = dev; + + MAP_INFO(map, "probing at 0x%lX, size:%ldKiB, width:%d bits\n", + (unsigned long)map->phys, + (unsigned long)info->amap.window_size >> 10, + map->bankwidth*8); + + return 0; + +err_out: + return -ENODEV; +} + +static void adm5120_flash_initbanks(struct adm5120_flash_info *info) +{ + struct map_info *map = &info->amap.map; + + if (info->mtd->size <= BANK_SIZE) + /* no bank switching needed */ + return; + + if (info->amap.switch_bank) { + info->amap.window_size = info->mtd->size; + return; + } + + MAP_ERR(map, "reduce visibility from %ldKiB to %ldKiB\n", + (unsigned long)map->size >> 10, + (unsigned long)info->mtd->size >> 10); + + info->mtd->size = info->amap.window_size; +} + +static int adm5120_flash_remove(struct platform_device *dev) +{ + struct adm5120_flash_info *info; + + info = platform_get_drvdata(dev); + if (info == NULL) + return 0; + + platform_set_drvdata(dev, NULL); + + if (info->mtd != NULL) { + mtd_device_unregister(info->mtd); + map_destroy(info->mtd); + } + + if (info->amap.map.virt != NULL) + iounmap(info->amap.map.virt); + + if (info->res != NULL) { + release_resource(info->res); + kfree(info->res); + } + + return 0; +} + +static int adm5120_flash_probe(struct platform_device *dev) +{ + struct adm5120_flash_platform_data *pdata; + struct adm5120_flash_info *info; + struct map_info *map; + const char **probe_type; + int err; + + pdata = dev->dev.platform_data; + if (!pdata) { + dev_err(&dev->dev, "no platform data\n"); + return -EINVAL; + } + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (info == NULL) { + err = -ENOMEM; + goto err_out; + } + + platform_set_drvdata(dev, info); + + err = adm5120_flash_initinfo(info, dev); + if (err) + goto err_out; + + err = adm5120_flash_initres(info); + if (err) + goto err_out; + + map = &info->amap.map; + for (probe_type = probe_types; info->mtd == NULL && *probe_type != NULL; + probe_type++) + info->mtd = do_map_probe(*probe_type, map); + + if (info->mtd == NULL) { + MAP_ERR(map, "map_probe failed\n"); + err = -ENXIO; + goto err_out; + } + + adm5120_flash_initbanks(info); + + if (info->mtd->size < info->amap.window_size) { + /* readjust resources */ + iounmap(map->virt); + release_resource(info->res); + kfree(info->res); + + info->amap.window_size = info->mtd->size; + map->size = info->mtd->size; + MAP_INFO(map, "reducing map size to %ldKiB\n", + (unsigned long)map->size >> 10); + err = adm5120_flash_initres(info); + if (err) + goto err_out; + } + + MAP_INFO(map, "found at 0x%lX, size:%ldKiB, width:%d bits\n", + (unsigned long)map->phys, (unsigned long)info->mtd->size >> 10, + map->bankwidth*8); + + info->mtd->owner = THIS_MODULE; + + err = mtd_device_parse_register(info->mtd, parse_types, 0, + pdata->parts, pdata->nr_parts); + if (err) + goto err_out; + + return 0; + +err_out: + adm5120_flash_remove(dev); + return err; +} + +#ifdef CONFIG_PM +static int adm5120_flash_suspend(struct platform_device *dev, + pm_message_t state) +{ + struct adm5120_flash_info *info = platform_get_drvdata(dev); + int ret = 0; + + if (info) + ret = info->mtd->suspend(info->mtd); + + return ret; +} + +static int adm5120_flash_resume(struct platform_device *dev) +{ + struct adm5120_flash_info *info = platform_get_drvdata(dev); + + if (info) + info->mtd->resume(info->mtd); + + return 0; +} + +static void adm5120_flash_shutdown(struct platform_device *dev) +{ + struct adm5120_flash_info *info = platform_get_drvdata(dev); + + if (info && info->mtd->suspend(info->mtd) == 0) + info->mtd->resume(info->mtd); +} +#endif + +static struct platform_driver adm5120_flash_driver = { + .probe = adm5120_flash_probe, + .remove = adm5120_flash_remove, +#ifdef CONFIG_PM + .suspend = adm5120_flash_suspend, + .resume = adm5120_flash_resume, + .shutdown = adm5120_flash_shutdown, +#endif + .driver = { + .name = DRV_NAME, + }, +}; + +static int __init adm5120_flash_init(void) +{ + int err; + + err = platform_driver_register(&adm5120_flash_driver); + + return err; +} + +static void __exit adm5120_flash_exit(void) +{ + platform_driver_unregister(&adm5120_flash_driver); +} + +module_init(adm5120_flash_init); +module_exit(adm5120_flash_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_DESCRIPTION(DRV_DESC); diff --git a/target/linux/adm5120/files/drivers/mtd/trxsplit.c b/target/linux/adm5120/files/drivers/mtd/trxsplit.c new file mode 100644 index 000000000..6f60264ac --- /dev/null +++ b/target/linux/adm5120/files/drivers/mtd/trxsplit.c @@ -0,0 +1,217 @@ +/* + * Copyright (C) Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define PFX "trxsplit: " + +#define TRX_MAGIC 0x30524448 /* "HDR0" */ +#define TRX_VERSION 1 +#define TRX_MAX_LEN 0x3A0000 +#define TRX_NO_HEADER 0x1 /* do not write TRX header */ +#define TRX_GZ_FILES 0x2 /* contains individual gzip files */ +#define TRX_MAX_OFFSET 3 +#define TRX_MIN_KERNEL_SIZE (256 * 1024) + +struct trx_header { + u32 magic; /* "HDR0" */ + u32 len; /* Length of file including header */ + u32 crc32; /* 32-bit CRC from flag_version to end of file */ + u32 flag_version; /* 0:15 flags, 16:31 version */ + u32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions */ +}; + +#define TRX_ALIGN 0x1000 + +static int trx_nr_parts; +static unsigned long trx_offset; +static struct mtd_info *trx_mtd; +static struct mtd_partition trx_parts[TRX_MAX_OFFSET]; +static struct trx_header trx_hdr; + +static int trxsplit_refresh_partitions(struct mtd_info *mtd); + +static int trxsplit_checktrx(struct mtd_info *mtd, unsigned long offset) +{ + size_t retlen; + int err; + + err = mtd->read(mtd, offset, sizeof(trx_hdr), &retlen, + (void *)&trx_hdr); + if (err) { + printk(KERN_ALERT PFX "unable to read from '%s'\n", mtd->name); + goto err_out; + } + + if (retlen != sizeof(trx_hdr)) { + printk(KERN_ALERT PFX "reading failed on '%s'\n", mtd->name); + goto err_out; + } + + trx_hdr.magic = le32_to_cpu(trx_hdr.magic); + trx_hdr.len = le32_to_cpu(trx_hdr.len); + trx_hdr.crc32 = le32_to_cpu(trx_hdr.crc32); + trx_hdr.flag_version = le32_to_cpu(trx_hdr.flag_version); + trx_hdr.offsets[0] = le32_to_cpu(trx_hdr.offsets[0]); + trx_hdr.offsets[1] = le32_to_cpu(trx_hdr.offsets[1]); + trx_hdr.offsets[2] = le32_to_cpu(trx_hdr.offsets[2]); + + /* sanity checks */ + if (trx_hdr.magic != TRX_MAGIC) + goto err_out; + + if (trx_hdr.len > mtd->size - offset) + goto err_out; + + /* TODO: add crc32 checking too? */ + + return 0; + +err_out: + return -1; +} + +static void trxsplit_findtrx(struct mtd_info *mtd) +{ + unsigned long offset; + int err; + + printk(KERN_INFO PFX "searching TRX header in '%s'\n", mtd->name); + + err = 0; + for (offset = 0; offset < mtd->size; offset += TRX_ALIGN) { + err = trxsplit_checktrx(mtd, offset); + if (err == 0) + break; + } + + if (err) + return; + + printk(KERN_INFO PFX "TRX header found at 0x%lX\n", offset); + + trx_mtd = mtd; + trx_offset = offset; +} + +static void trxsplit_create_partitions(struct mtd_info *mtd) +{ + struct mtd_partition *part = trx_parts; + int err; + int i; + + for (i = 0; i < TRX_MAX_OFFSET; i++) { + part = &trx_parts[i]; + if (trx_hdr.offsets[i] == 0) + continue; + part->offset = trx_offset + trx_hdr.offsets[i]; + trx_nr_parts++; + } + + for (i = 0; i < trx_nr_parts-1; i++) + trx_parts[i].size = trx_parts[i+1].offset - trx_parts[i].offset; + + trx_parts[i].size = mtd->size - trx_parts[i].offset; + + i = 0; + part = &trx_parts[i]; + if (part->size < TRX_MIN_KERNEL_SIZE) { + part->name = "loader"; + i++; + } + + part = &trx_parts[i]; + part->name = "kernel"; + i++; + + part = &trx_parts[i]; + part->name = "rootfs"; + + err = mtd_device_register(mtd, trx_parts, trx_nr_parts); + if (err) { + printk(KERN_ALERT PFX "adding TRX partitions failed\n"); + return; + } + + mtd->refresh_device = trxsplit_refresh_partitions; +} + +static int trxsplit_refresh_partitions(struct mtd_info *mtd) +{ + printk(KERN_INFO PFX "refreshing TRX partitions in '%s' (%d,%d)\n", + mtd->name, MTD_BLOCK_MAJOR, mtd->index); + + /* remove old partitions */ + mtd_device_unregister(mtd); + + trxsplit_findtrx(mtd); + if (!trx_mtd) + goto err; + + trxsplit_create_partitions(trx_mtd); + return 1; + +err: + return 0; +} + +static void __init trxsplit_add_mtd(struct mtd_info *mtd) +{ + if (mtd->type != MTD_NORFLASH) { + printk(KERN_INFO PFX "'%s' is not a NOR flash, skipped\n", + mtd->name); + return; + } + + if (!trx_mtd) + trxsplit_findtrx(mtd); +} + +static void __init trxsplit_remove_mtd(struct mtd_info *mtd) +{ + /* nothing to do */ +} + +static struct mtd_notifier trxsplit_notifier __initdata = { + .add = trxsplit_add_mtd, + .remove = trxsplit_remove_mtd, +}; + +static void __init trxsplit_scan(void) +{ + register_mtd_user(&trxsplit_notifier); + unregister_mtd_user(&trxsplit_notifier); +} + +static int __init trxsplit_init(void) +{ + trxsplit_scan(); + + if (trx_mtd) { + printk(KERN_INFO PFX "creating TRX partitions in '%s' " + "(%d,%d)\n", trx_mtd->name, MTD_BLOCK_MAJOR, + trx_mtd->index); + trxsplit_create_partitions(trx_mtd); + } + + return 0; +} + +late_initcall(trxsplit_init); diff --git a/target/linux/adm5120/files/drivers/net/adm5120sw.c b/target/linux/adm5120/files/drivers/net/adm5120sw.c new file mode 100644 index 000000000..d80a6a3a1 --- /dev/null +++ b/target/linux/adm5120/files/drivers/net/adm5120sw.c @@ -0,0 +1,1219 @@ +/* + * ADM5120 built-in ethernet switch driver + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This code was based on a driver for Linux 2.6.xx by Jeroen Vreeken. + * Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2005 + * NAPI extension for the Jeroen's driver + * Copyright Thomas Langer (Thomas.Langer@infineon.com), 2007 + * Copyright Friedrich Beckmann (Friedrich.Beckmann@infineon.com), 2007 + * Inspiration for the Jeroen's driver came from the ADMtek 2.4 driver. + * Copyright ADMtek Inc. + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include "adm5120sw.h" +#include + +#define DRV_NAME "adm5120-switch" +#define DRV_DESC "ADM5120 built-in ethernet switch driver" +#define DRV_VERSION "0.1.1" + +#define CONFIG_ADM5120_SWITCH_NAPI 1 +#undef CONFIG_ADM5120_SWITCH_DEBUG + +/* ------------------------------------------------------------------------ */ + +#ifdef CONFIG_ADM5120_SWITCH_DEBUG +#define SW_DBG(f, a...) printk(KERN_DEBUG "%s: " f, DRV_NAME , ## a) +#else +#define SW_DBG(f, a...) do {} while (0) +#endif +#define SW_ERR(f, a...) printk(KERN_ERR "%s: " f, DRV_NAME , ## a) +#define SW_INFO(f, a...) printk(KERN_INFO "%s: " f, DRV_NAME , ## a) + +#define SWITCH_NUM_PORTS 6 +#define ETH_CSUM_LEN 4 + +#define RX_MAX_PKTLEN 1550 +#define RX_RING_SIZE 64 + +#define TX_RING_SIZE 32 +#define TX_QUEUE_LEN 28 /* Limit ring entries actually used. */ +#define TX_TIMEOUT (HZ * 400) + +#define RX_DESCS_SIZE (RX_RING_SIZE * sizeof(struct dma_desc *)) +#define RX_SKBS_SIZE (RX_RING_SIZE * sizeof(struct sk_buff *)) +#define TX_DESCS_SIZE (TX_RING_SIZE * sizeof(struct dma_desc *)) +#define TX_SKBS_SIZE (TX_RING_SIZE * sizeof(struct sk_buff *)) + +#define SKB_ALLOC_LEN (RX_MAX_PKTLEN + 32) +#define SKB_RESERVE_LEN (NET_IP_ALIGN + NET_SKB_PAD) + +#define SWITCH_INTS_HIGH (SWITCH_INT_SHD | SWITCH_INT_RHD | SWITCH_INT_HDF) +#define SWITCH_INTS_LOW (SWITCH_INT_SLD | SWITCH_INT_RLD | SWITCH_INT_LDF) +#define SWITCH_INTS_ERR (SWITCH_INT_RDE | SWITCH_INT_SDE | SWITCH_INT_CPUH) +#define SWITCH_INTS_Q (SWITCH_INT_P0QF | SWITCH_INT_P1QF | SWITCH_INT_P2QF | \ + SWITCH_INT_P3QF | SWITCH_INT_P4QF | SWITCH_INT_P5QF | \ + SWITCH_INT_CPQF | SWITCH_INT_GQF) + +#define SWITCH_INTS_ALL (SWITCH_INTS_HIGH | SWITCH_INTS_LOW | \ + SWITCH_INTS_ERR | SWITCH_INTS_Q | \ + SWITCH_INT_MD | SWITCH_INT_PSC) + +#define SWITCH_INTS_USED (SWITCH_INTS_LOW | SWITCH_INT_PSC) +#define SWITCH_INTS_POLL (SWITCH_INT_RLD | SWITCH_INT_LDF | SWITCH_INT_SLD) + +/* ------------------------------------------------------------------------ */ + +struct adm5120_if_priv { + struct net_device *dev; + + unsigned int vlan_no; + unsigned int port_mask; + +#ifdef CONFIG_ADM5120_SWITCH_NAPI + struct napi_struct napi; +#endif +}; + +struct dma_desc { + __u32 buf1; +#define DESC_OWN (1UL << 31) /* Owned by the switch */ +#define DESC_EOR (1UL << 28) /* End of Ring */ +#define DESC_ADDR_MASK 0x1FFFFFF +#define DESC_ADDR(x) ((__u32)(x) & DESC_ADDR_MASK) + __u32 buf2; +#define DESC_BUF2_EN (1UL << 31) /* Buffer 2 enable */ + __u32 buflen; + __u32 misc; +/* definitions for tx/rx descriptors */ +#define DESC_PKTLEN_SHIFT 16 +#define DESC_PKTLEN_MASK 0x7FF +/* tx descriptor specific part */ +#define DESC_CSUM (1UL << 31) /* Append checksum */ +#define DESC_DSTPORT_SHIFT 8 +#define DESC_DSTPORT_MASK 0x3F +#define DESC_VLAN_MASK 0x3F +/* rx descriptor specific part */ +#define DESC_SRCPORT_SHIFT 12 +#define DESC_SRCPORT_MASK 0x7 +#define DESC_DA_MASK 0x3 +#define DESC_DA_SHIFT 4 +#define DESC_IPCSUM_FAIL (1UL << 3) /* IP checksum fail */ +#define DESC_VLAN_TAG (1UL << 2) /* VLAN tag present */ +#define DESC_TYPE_MASK 0x3 /* mask for Packet type */ +#define DESC_TYPE_IP 0x0 /* IP packet */ +#define DESC_TYPE_PPPoE 0x1 /* PPPoE packet */ +} __attribute__ ((aligned(16))); + +/* ------------------------------------------------------------------------ */ + +static int adm5120_nrdevs; + +static struct net_device *adm5120_devs[SWITCH_NUM_PORTS]; +/* Lookup table port -> device */ +static struct net_device *adm5120_port[SWITCH_NUM_PORTS]; + +static struct dma_desc *txl_descs; +static struct dma_desc *rxl_descs; + +static dma_addr_t txl_descs_dma; +static dma_addr_t rxl_descs_dma; + +static struct sk_buff **txl_skbuff; +static struct sk_buff **rxl_skbuff; + +static unsigned int cur_rxl, dirty_rxl; /* producer/consumer ring indices */ +static unsigned int cur_txl, dirty_txl; + +static unsigned int sw_used; + +static DEFINE_SPINLOCK(tx_lock); + +/* ------------------------------------------------------------------------ */ + +static inline u32 sw_read_reg(u32 reg) +{ + return __raw_readl((void __iomem *)KSEG1ADDR(ADM5120_SWITCH_BASE)+reg); +} + +static inline void sw_write_reg(u32 reg, u32 val) +{ + __raw_writel(val, (void __iomem *)KSEG1ADDR(ADM5120_SWITCH_BASE)+reg); +} + +static inline void sw_int_mask(u32 mask) +{ + u32 t; + + t = sw_read_reg(SWITCH_REG_INT_MASK); + t |= mask; + sw_write_reg(SWITCH_REG_INT_MASK, t); +} + +static inline void sw_int_unmask(u32 mask) +{ + u32 t; + + t = sw_read_reg(SWITCH_REG_INT_MASK); + t &= ~mask; + sw_write_reg(SWITCH_REG_INT_MASK, t); +} + +static inline void sw_int_ack(u32 mask) +{ + sw_write_reg(SWITCH_REG_INT_STATUS, mask); +} + +static inline u32 sw_int_status(void) +{ + u32 t; + + t = sw_read_reg(SWITCH_REG_INT_STATUS); + t &= ~sw_read_reg(SWITCH_REG_INT_MASK); + return t; +} + +static inline u32 desc_get_srcport(struct dma_desc *desc) +{ + return (desc->misc >> DESC_SRCPORT_SHIFT) & DESC_SRCPORT_MASK; +} + +static inline u32 desc_get_pktlen(struct dma_desc *desc) +{ + return (desc->misc >> DESC_PKTLEN_SHIFT) & DESC_PKTLEN_MASK; +} + +static inline int desc_ipcsum_fail(struct dma_desc *desc) +{ + return ((desc->misc & DESC_IPCSUM_FAIL) != 0); +} + +/* ------------------------------------------------------------------------ */ + +#ifdef CONFIG_ADM5120_SWITCH_DEBUG +static void sw_dump_desc(char *label, struct dma_desc *desc, int tx) +{ + u32 t; + + SW_DBG("%s %s desc/%p\n", label, tx ? "tx" : "rx", desc); + + t = desc->buf1; + SW_DBG(" buf1 %08X addr=%08X; len=%08X %s%s\n", t, + t & DESC_ADDR_MASK, + desc->buflen, + (t & DESC_OWN) ? "SWITCH" : "CPU", + (t & DESC_EOR) ? " RE" : ""); + + t = desc->buf2; + SW_DBG(" buf2 %08X addr=%08X%s\n", desc->buf2, + t & DESC_ADDR_MASK, + (t & DESC_BUF2_EN) ? " EN" : ""); + + t = desc->misc; + if (tx) + SW_DBG(" misc %08X%s pktlen=%04X ports=%02X vlan=%02X\n", t, + (t & DESC_CSUM) ? " CSUM" : "", + (t >> DESC_PKTLEN_SHIFT) & DESC_PKTLEN_MASK, + (t >> DESC_DSTPORT_SHIFT) & DESC_DSTPORT_MASK, + t & DESC_VLAN_MASK); + else + SW_DBG(" misc %08X pktlen=%04X port=%d DA=%d%s%s type=%d\n", + t, + (t >> DESC_PKTLEN_SHIFT) & DESC_PKTLEN_MASK, + (t >> DESC_SRCPORT_SHIFT) & DESC_SRCPORT_MASK, + (t >> DESC_DA_SHIFT) & DESC_DA_MASK, + (t & DESC_IPCSUM_FAIL) ? " IPCF" : "", + (t & DESC_VLAN_TAG) ? " VLAN" : "", + (t & DESC_TYPE_MASK)); +} + +static void sw_dump_intr_mask(char *label, u32 mask) +{ + SW_DBG("%s %08X%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + label, mask, + (mask & SWITCH_INT_SHD) ? " SHD" : "", + (mask & SWITCH_INT_SLD) ? " SLD" : "", + (mask & SWITCH_INT_RHD) ? " RHD" : "", + (mask & SWITCH_INT_RLD) ? " RLD" : "", + (mask & SWITCH_INT_HDF) ? " HDF" : "", + (mask & SWITCH_INT_LDF) ? " LDF" : "", + (mask & SWITCH_INT_P0QF) ? " P0QF" : "", + (mask & SWITCH_INT_P1QF) ? " P1QF" : "", + (mask & SWITCH_INT_P2QF) ? " P2QF" : "", + (mask & SWITCH_INT_P3QF) ? " P3QF" : "", + (mask & SWITCH_INT_P4QF) ? " P4QF" : "", + (mask & SWITCH_INT_CPQF) ? " CPQF" : "", + (mask & SWITCH_INT_GQF) ? " GQF" : "", + (mask & SWITCH_INT_MD) ? " MD" : "", + (mask & SWITCH_INT_BCS) ? " BCS" : "", + (mask & SWITCH_INT_PSC) ? " PSC" : "", + (mask & SWITCH_INT_ID) ? " ID" : "", + (mask & SWITCH_INT_W0TE) ? " W0TE" : "", + (mask & SWITCH_INT_W1TE) ? " W1TE" : "", + (mask & SWITCH_INT_RDE) ? " RDE" : "", + (mask & SWITCH_INT_SDE) ? " SDE" : "", + (mask & SWITCH_INT_CPUH) ? " CPUH" : ""); +} + +static void sw_dump_regs(void) +{ + u32 t; + + t = sw_read_reg(SWITCH_REG_PHY_STATUS); + SW_DBG("phy_status: %08X\n", t); + + t = sw_read_reg(SWITCH_REG_CPUP_CONF); + SW_DBG("cpup_conf: %08X%s%s%s\n", t, + (t & CPUP_CONF_DCPUP) ? " DCPUP" : "", + (t & CPUP_CONF_CRCP) ? " CRCP" : "", + (t & CPUP_CONF_BTM) ? " BTM" : ""); + + t = sw_read_reg(SWITCH_REG_PORT_CONF0); + SW_DBG("port_conf0: %08X\n", t); + t = sw_read_reg(SWITCH_REG_PORT_CONF1); + SW_DBG("port_conf1: %08X\n", t); + t = sw_read_reg(SWITCH_REG_PORT_CONF2); + SW_DBG("port_conf2: %08X\n", t); + + t = sw_read_reg(SWITCH_REG_VLAN_G1); + SW_DBG("vlan g1: %08X\n", t); + t = sw_read_reg(SWITCH_REG_VLAN_G2); + SW_DBG("vlan g2: %08X\n", t); + + t = sw_read_reg(SWITCH_REG_BW_CNTL0); + SW_DBG("bw_cntl0: %08X\n", t); + t = sw_read_reg(SWITCH_REG_BW_CNTL1); + SW_DBG("bw_cntl1: %08X\n", t); + + t = sw_read_reg(SWITCH_REG_PHY_CNTL0); + SW_DBG("phy_cntl0: %08X\n", t); + t = sw_read_reg(SWITCH_REG_PHY_CNTL1); + SW_DBG("phy_cntl1: %08X\n", t); + t = sw_read_reg(SWITCH_REG_PHY_CNTL2); + SW_DBG("phy_cntl2: %08X\n", t); + t = sw_read_reg(SWITCH_REG_PHY_CNTL3); + SW_DBG("phy_cntl3: %08X\n", t); + t = sw_read_reg(SWITCH_REG_PHY_CNTL4); + SW_DBG("phy_cntl4: %08X\n", t); + + t = sw_read_reg(SWITCH_REG_INT_STATUS); + sw_dump_intr_mask("int_status: ", t); + + t = sw_read_reg(SWITCH_REG_INT_MASK); + sw_dump_intr_mask("int_mask: ", t); + + t = sw_read_reg(SWITCH_REG_SHDA); + SW_DBG("shda: %08X\n", t); + t = sw_read_reg(SWITCH_REG_SLDA); + SW_DBG("slda: %08X\n", t); + t = sw_read_reg(SWITCH_REG_RHDA); + SW_DBG("rhda: %08X\n", t); + t = sw_read_reg(SWITCH_REG_RLDA); + SW_DBG("rlda: %08X\n", t); +} +#else +static inline void sw_dump_desc(char *label, struct dma_desc *desc, int tx) {} +static void sw_dump_intr_mask(char *label, u32 mask) {} +static inline void sw_dump_regs(void) {} +#endif /* CONFIG_ADM5120_SWITCH_DEBUG */ + +/* ------------------------------------------------------------------------ */ + +static inline void adm5120_rx_dma_update(struct dma_desc *desc, + struct sk_buff *skb, int end) +{ + desc->misc = 0; + desc->buf2 = 0; + desc->buflen = RX_MAX_PKTLEN; + desc->buf1 = DESC_ADDR(skb->data) | + DESC_OWN | (end ? DESC_EOR : 0); +} + +static void adm5120_switch_rx_refill(void) +{ + unsigned int entry; + + for (; cur_rxl - dirty_rxl > 0; dirty_rxl++) { + struct dma_desc *desc; + struct sk_buff *skb; + + entry = dirty_rxl % RX_RING_SIZE; + desc = &rxl_descs[entry]; + + skb = rxl_skbuff[entry]; + if (skb == NULL) { + skb = alloc_skb(SKB_ALLOC_LEN, GFP_ATOMIC); + if (skb) { + skb_reserve(skb, SKB_RESERVE_LEN); + rxl_skbuff[entry] = skb; + } else { + SW_ERR("no memory for skb\n"); + desc->buflen = 0; + desc->buf2 = 0; + desc->misc = 0; + desc->buf1 = (desc->buf1 & DESC_EOR) | DESC_OWN; + break; + } + } + + desc->buf2 = 0; + desc->buflen = RX_MAX_PKTLEN; + desc->misc = 0; + desc->buf1 = (desc->buf1 & DESC_EOR) | DESC_OWN | + DESC_ADDR(skb->data); + } +} + +static int adm5120_switch_rx(int limit) +{ + unsigned int done = 0; + + SW_DBG("rx start, limit=%d, cur_rxl=%u, dirty_rxl=%u\n", + limit, cur_rxl, dirty_rxl); + + while (done < limit) { + int entry = cur_rxl % RX_RING_SIZE; + struct dma_desc *desc = &rxl_descs[entry]; + struct net_device *rdev; + unsigned int port; + + if (desc->buf1 & DESC_OWN) + break; + + if (dirty_rxl + RX_RING_SIZE == cur_rxl) + break; + + port = desc_get_srcport(desc); + rdev = adm5120_port[port]; + + SW_DBG("rx descriptor %u, desc=%p, skb=%p\n", entry, desc, + rxl_skbuff[entry]); + + if ((rdev) && netif_running(rdev)) { + struct sk_buff *skb = rxl_skbuff[entry]; + int pktlen; + + pktlen = desc_get_pktlen(desc); + pktlen -= ETH_CSUM_LEN; + + if ((pktlen == 0) || desc_ipcsum_fail(desc)) { + rdev->stats.rx_errors++; + if (pktlen == 0) + rdev->stats.rx_length_errors++; + if (desc_ipcsum_fail(desc)) + rdev->stats.rx_crc_errors++; + SW_DBG("rx error, recycling skb %u\n", entry); + } else { + skb_put(skb, pktlen); + + skb->dev = rdev; + skb->protocol = eth_type_trans(skb, rdev); + skb->ip_summed = CHECKSUM_UNNECESSARY; + + dma_cache_wback_inv((unsigned long)skb->data, + skb->len); + +#ifdef CONFIG_ADM5120_SWITCH_NAPI + netif_receive_skb(skb); +#else + netif_rx(skb); +#endif + + rdev->last_rx = jiffies; + rdev->stats.rx_packets++; + rdev->stats.rx_bytes += pktlen; + + rxl_skbuff[entry] = NULL; + done++; + } + } else { + SW_DBG("no rx device, recycling skb %u\n", entry); + } + + cur_rxl++; + if (cur_rxl - dirty_rxl > RX_RING_SIZE / 4) + adm5120_switch_rx_refill(); + } + + adm5120_switch_rx_refill(); + + SW_DBG("rx finished, cur_rxl=%u, dirty_rxl=%u, processed %d\n", + cur_rxl, dirty_rxl, done); + + return done; +} + +static void adm5120_switch_tx(void) +{ + unsigned int entry; + + spin_lock(&tx_lock); + entry = dirty_txl % TX_RING_SIZE; + while (dirty_txl != cur_txl) { + struct dma_desc *desc = &txl_descs[entry]; + struct sk_buff *skb = txl_skbuff[entry]; + + if (desc->buf1 & DESC_OWN) + break; + + if (netif_running(skb->dev)) { + skb->dev->stats.tx_bytes += skb->len; + skb->dev->stats.tx_packets++; + } + + dev_kfree_skb_irq(skb); + txl_skbuff[entry] = NULL; + entry = (++dirty_txl) % TX_RING_SIZE; + } + + if ((cur_txl - dirty_txl) < TX_QUEUE_LEN - 4) { + int i; + for (i = 0; i < SWITCH_NUM_PORTS; i++) { + if (!adm5120_devs[i]) + continue; + netif_wake_queue(adm5120_devs[i]); + } + } + spin_unlock(&tx_lock); +} + +#ifdef CONFIG_ADM5120_SWITCH_NAPI +static int adm5120_if_poll(struct napi_struct *napi, int limit) +{ + struct adm5120_if_priv *priv = container_of(napi, + struct adm5120_if_priv, napi); + struct net_device *dev __maybe_unused = priv->dev; + int done; + u32 status; + + sw_int_ack(SWITCH_INTS_POLL); + + SW_DBG("%s: processing TX ring\n", dev->name); + adm5120_switch_tx(); + + SW_DBG("%s: processing RX ring\n", dev->name); + done = adm5120_switch_rx(limit); + + status = sw_int_status() & SWITCH_INTS_POLL; + if ((done < limit) && (!status)) { + SW_DBG("disable polling mode for %s\n", dev->name); + napi_complete(napi); + sw_int_unmask(SWITCH_INTS_POLL); + return 0; + } + + SW_DBG("%s still in polling mode, done=%d, status=%x\n", + dev->name, done, status); + return 1; +} +#endif /* CONFIG_ADM5120_SWITCH_NAPI */ + + +static irqreturn_t adm5120_switch_irq(int irq, void *dev_id) +{ + u32 status; + + status = sw_int_status(); + status &= SWITCH_INTS_ALL; + if (!status) + return IRQ_NONE; + +#ifdef CONFIG_ADM5120_SWITCH_NAPI + sw_int_ack(status & ~SWITCH_INTS_POLL); + + if (status & SWITCH_INTS_POLL) { + struct net_device *dev = dev_id; + struct adm5120_if_priv *priv = netdev_priv(dev); + + sw_dump_intr_mask("poll ints", status); + SW_DBG("enable polling mode for %s\n", dev->name); + sw_int_mask(SWITCH_INTS_POLL); + napi_schedule(&priv->napi); + } +#else + sw_int_ack(status); + + if (status & (SWITCH_INT_RLD | SWITCH_INT_LDF)) + adm5120_switch_rx(RX_RING_SIZE); + + if (status & SWITCH_INT_SLD) + adm5120_switch_tx(); +#endif + + return IRQ_HANDLED; +} + +static void adm5120_set_bw(char *matrix) +{ + unsigned long val; + + /* Port 0 to 3 are set using the bandwidth control 0 register */ + val = matrix[0] + (matrix[1]<<8) + (matrix[2]<<16) + (matrix[3]<<24); + sw_write_reg(SWITCH_REG_BW_CNTL0, val); + + /* Port 4 and 5 are set using the bandwidth control 1 register */ + val = matrix[4]; + if (matrix[5] == 1) + sw_write_reg(SWITCH_REG_BW_CNTL1, val | 0x80000000); + else + sw_write_reg(SWITCH_REG_BW_CNTL1, val & ~0x8000000); + + SW_DBG("D: ctl0 0x%ux, ctl1 0x%ux\n", sw_read_reg(SWITCH_REG_BW_CNTL0), + sw_read_reg(SWITCH_REG_BW_CNTL1)); +} + +static void adm5120_switch_tx_ring_reset(struct dma_desc *desc, + struct sk_buff **skbl, int num) +{ + memset(desc, 0, num * sizeof(*desc)); + desc[num-1].buf1 |= DESC_EOR; + memset(skbl, 0, sizeof(struct skb *) * num); + + cur_txl = 0; + dirty_txl = 0; +} + +static void adm5120_switch_rx_ring_reset(struct dma_desc *desc, + struct sk_buff **skbl, int num) +{ + int i; + + memset(desc, 0, num * sizeof(*desc)); + for (i = 0; i < num; i++) { + skbl[i] = dev_alloc_skb(SKB_ALLOC_LEN); + if (!skbl[i]) { + i = num; + break; + } + skb_reserve(skbl[i], SKB_RESERVE_LEN); + adm5120_rx_dma_update(&desc[i], skbl[i], (num - 1 == i)); + } + + cur_rxl = 0; + dirty_rxl = 0; +} + +static int adm5120_switch_tx_ring_alloc(void) +{ + int err; + + txl_descs = dma_alloc_coherent(NULL, TX_DESCS_SIZE, &txl_descs_dma, + GFP_ATOMIC); + if (!txl_descs) { + err = -ENOMEM; + goto err; + } + + txl_skbuff = kzalloc(TX_SKBS_SIZE, GFP_KERNEL); + if (!txl_skbuff) { + err = -ENOMEM; + goto err; + } + + return 0; + +err: + return err; +} + +static void adm5120_switch_tx_ring_free(void) +{ + int i; + + if (txl_skbuff) { + for (i = 0; i < TX_RING_SIZE; i++) + if (txl_skbuff[i]) + kfree_skb(txl_skbuff[i]); + kfree(txl_skbuff); + } + + if (txl_descs) + dma_free_coherent(NULL, TX_DESCS_SIZE, txl_descs, + txl_descs_dma); +} + +static int adm5120_switch_rx_ring_alloc(void) +{ + int err; + int i; + + /* init RX ring */ + rxl_descs = dma_alloc_coherent(NULL, RX_DESCS_SIZE, &rxl_descs_dma, + GFP_ATOMIC); + if (!rxl_descs) { + err = -ENOMEM; + goto err; + } + + rxl_skbuff = kzalloc(RX_SKBS_SIZE, GFP_KERNEL); + if (!rxl_skbuff) { + err = -ENOMEM; + goto err; + } + + for (i = 0; i < RX_RING_SIZE; i++) { + struct sk_buff *skb; + skb = alloc_skb(SKB_ALLOC_LEN, GFP_ATOMIC); + if (!skb) { + err = -ENOMEM; + goto err; + } + rxl_skbuff[i] = skb; + skb_reserve(skb, SKB_RESERVE_LEN); + } + + return 0; + +err: + return err; +} + +static void adm5120_switch_rx_ring_free(void) +{ + int i; + + if (rxl_skbuff) { + for (i = 0; i < RX_RING_SIZE; i++) + if (rxl_skbuff[i]) + kfree_skb(rxl_skbuff[i]); + kfree(rxl_skbuff); + } + + if (rxl_descs) + dma_free_coherent(NULL, RX_DESCS_SIZE, rxl_descs, + rxl_descs_dma); +} + +static void adm5120_write_mac(struct net_device *dev) +{ + struct adm5120_if_priv *priv = netdev_priv(dev); + unsigned char *mac = dev->dev_addr; + u32 t; + + t = mac[2] | (mac[3] << MAC_WT1_MAC3_SHIFT) | + (mac[4] << MAC_WT1_MAC4_SHIFT) | (mac[5] << MAC_WT1_MAC5_SHIFT); + sw_write_reg(SWITCH_REG_MAC_WT1, t); + + t = (mac[0] << MAC_WT0_MAC0_SHIFT) | (mac[1] << MAC_WT0_MAC1_SHIFT) | + MAC_WT0_MAWC | MAC_WT0_WVE | (priv->vlan_no<<3); + + sw_write_reg(SWITCH_REG_MAC_WT0, t); + + while (!(sw_read_reg(SWITCH_REG_MAC_WT0) & MAC_WT0_MWD)) + ; +} + +static void adm5120_set_vlan(char *matrix) +{ + unsigned long val; + int vlan_port, port; + + val = matrix[0] + (matrix[1]<<8) + (matrix[2]<<16) + (matrix[3]<<24); + sw_write_reg(SWITCH_REG_VLAN_G1, val); + val = matrix[4] + (matrix[5]<<8); + sw_write_reg(SWITCH_REG_VLAN_G2, val); + + /* Now set/update the port vs. device lookup table */ + for (port = 0; port < SWITCH_NUM_PORTS; port++) { + for (vlan_port = 0; vlan_port < SWITCH_NUM_PORTS && !(matrix[vlan_port] & (0x00000001 << port)); vlan_port++) + ; + if (vlan_port < SWITCH_NUM_PORTS) + adm5120_port[port] = adm5120_devs[vlan_port]; + else + adm5120_port[port] = NULL; + } +} + +static void adm5120_switch_set_vlan_mac(unsigned int vlan, unsigned char *mac) +{ + u32 t; + + t = mac[2] | (mac[3] << MAC_WT1_MAC3_SHIFT) + | (mac[4] << MAC_WT1_MAC4_SHIFT) + | (mac[5] << MAC_WT1_MAC5_SHIFT); + sw_write_reg(SWITCH_REG_MAC_WT1, t); + + t = (mac[0] << MAC_WT0_MAC0_SHIFT) | (mac[1] << MAC_WT0_MAC1_SHIFT) | + MAC_WT0_MAWC | MAC_WT0_WVE | (vlan << MAC_WT0_WVN_SHIFT) | + (MAC_WT0_WAF_STATIC << MAC_WT0_WAF_SHIFT); + sw_write_reg(SWITCH_REG_MAC_WT0, t); + + do { + t = sw_read_reg(SWITCH_REG_MAC_WT0); + } while ((t & MAC_WT0_MWD) == 0); +} + +static void adm5120_switch_set_vlan_ports(unsigned int vlan, u32 ports) +{ + unsigned int reg; + u32 t; + + if (vlan < 4) + reg = SWITCH_REG_VLAN_G1; + else { + vlan -= 4; + reg = SWITCH_REG_VLAN_G2; + } + + t = sw_read_reg(reg); + t &= ~(0xFF << (vlan*8)); + t |= (ports << (vlan*8)); + sw_write_reg(reg, t); +} + +/* ------------------------------------------------------------------------ */ + +#ifdef CONFIG_ADM5120_SWITCH_NAPI +static inline void adm5120_if_napi_enable(struct net_device *dev) +{ + struct adm5120_if_priv *priv = netdev_priv(dev); + napi_enable(&priv->napi); +} + +static inline void adm5120_if_napi_disable(struct net_device *dev) +{ + struct adm5120_if_priv *priv = netdev_priv(dev); + napi_disable(&priv->napi); +} +#else +static inline void adm5120_if_napi_enable(struct net_device *dev) {} +static inline void adm5120_if_napi_disable(struct net_device *dev) {} +#endif /* CONFIG_ADM5120_SWITCH_NAPI */ + +static int adm5120_if_open(struct net_device *dev) +{ + u32 t; + int err; + int i; + + adm5120_if_napi_enable(dev); + + err = request_irq(dev->irq, adm5120_switch_irq, IRQF_SHARED, + dev->name, dev); + if (err) { + SW_ERR("unable to get irq for %s\n", dev->name); + goto err; + } + + if (!sw_used++) + /* enable interrupts on first open */ + sw_int_unmask(SWITCH_INTS_USED); + + /* enable (additional) port */ + t = sw_read_reg(SWITCH_REG_PORT_CONF0); + for (i = 0; i < SWITCH_NUM_PORTS; i++) { + if (dev == adm5120_devs[i]) + t &= ~adm5120_eth_vlans[i]; + } + sw_write_reg(SWITCH_REG_PORT_CONF0, t); + + netif_start_queue(dev); + + return 0; + +err: + adm5120_if_napi_disable(dev); + return err; +} + +static int adm5120_if_stop(struct net_device *dev) +{ + u32 t; + int i; + + netif_stop_queue(dev); + adm5120_if_napi_disable(dev); + + /* disable port if not assigned to other devices */ + t = sw_read_reg(SWITCH_REG_PORT_CONF0); + t |= SWITCH_PORTS_NOCPU; + for (i = 0; i < SWITCH_NUM_PORTS; i++) { + if ((dev != adm5120_devs[i]) && netif_running(adm5120_devs[i])) + t &= ~adm5120_eth_vlans[i]; + } + sw_write_reg(SWITCH_REG_PORT_CONF0, t); + + if (!--sw_used) + sw_int_mask(SWITCH_INTS_USED); + + free_irq(dev->irq, dev); + + return 0; +} + +static int adm5120_if_hard_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct dma_desc *desc; + struct adm5120_if_priv *priv = netdev_priv(dev); + unsigned int entry; + unsigned long data; + int i; + + /* lock switch irq */ + spin_lock_irq(&tx_lock); + + /* calculate the next TX descriptor entry. */ + entry = cur_txl % TX_RING_SIZE; + + desc = &txl_descs[entry]; + if (desc->buf1 & DESC_OWN) { + /* We want to write a packet but the TX queue is still + * occupied by the DMA. We are faster than the DMA... */ + SW_DBG("%s unable to transmit, packet dopped\n", dev->name); + dev_kfree_skb(skb); + dev->stats.tx_dropped++; + return 0; + } + + txl_skbuff[entry] = skb; + data = (desc->buf1 & DESC_EOR); + data |= DESC_ADDR(skb->data); + + desc->misc = + ((skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len) << DESC_PKTLEN_SHIFT) | + (0x1 << priv->vlan_no); + + desc->buflen = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; + + desc->buf1 = data | DESC_OWN; + sw_write_reg(SWITCH_REG_SEND_TRIG, SEND_TRIG_STL); + + cur_txl++; + if (cur_txl == dirty_txl + TX_QUEUE_LEN) { + for (i = 0; i < SWITCH_NUM_PORTS; i++) { + if (!adm5120_devs[i]) + continue; + netif_stop_queue(adm5120_devs[i]); + } + } + + dev->trans_start = jiffies; + + spin_unlock_irq(&tx_lock); + + return 0; +} + +static void adm5120_if_tx_timeout(struct net_device *dev) +{ + SW_INFO("TX timeout on %s\n", dev->name); +} + +static void adm5120_if_set_rx_mode(struct net_device *dev) +{ + struct adm5120_if_priv *priv = netdev_priv(dev); + u32 ports; + u32 t; + + ports = adm5120_eth_vlans[priv->vlan_no] & SWITCH_PORTS_NOCPU; + + t = sw_read_reg(SWITCH_REG_CPUP_CONF); + if (dev->flags & IFF_PROMISC) + /* enable unknown packets */ + t &= ~(ports << CPUP_CONF_DUNP_SHIFT); + else + /* disable unknown packets */ + t |= (ports << CPUP_CONF_DUNP_SHIFT); + + if (dev->flags & IFF_PROMISC || dev->flags & IFF_ALLMULTI || + netdev_mc_count(dev)) + /* enable multicast packets */ + t &= ~(ports << CPUP_CONF_DMCP_SHIFT); + else + /* disable multicast packets */ + t |= (ports << CPUP_CONF_DMCP_SHIFT); + + /* If there is any port configured to be in promiscuous mode, then the */ + /* Bridge Test Mode has to be activated. This will result in */ + /* transporting also packets learned in another VLAN to be forwarded */ + /* to the CPU. */ + /* The difficult scenario is when we want to build a bridge on the CPU.*/ + /* Assume we have port0 and the CPU port in VLAN0 and port1 and the */ + /* CPU port in VLAN1. Now we build a bridge on the CPU between */ + /* VLAN0 and VLAN1. Both ports of the VLANs are set in promisc mode. */ + /* Now assume a packet with ethernet source address 99 enters port 0 */ + /* It will be forwarded to the CPU because it is unknown. Then the */ + /* bridge in the CPU will send it to VLAN1 and it goes out at port 1. */ + /* When now a packet with ethernet destination address 99 comes in at */ + /* port 1 in VLAN1, then the switch has learned that this address is */ + /* located at port 0 in VLAN0. Therefore the switch will drop */ + /* this packet. In order to avoid this and to send the packet still */ + /* to the CPU, the Bridge Test Mode has to be activated. */ + + /* Check if there is any vlan in promisc mode. */ + if (~t & (SWITCH_PORTS_NOCPU << CPUP_CONF_DUNP_SHIFT)) + t |= CPUP_CONF_BTM; /* Enable Bridge Testing Mode */ + else + t &= ~CPUP_CONF_BTM; /* Disable Bridge Testing Mode */ + + sw_write_reg(SWITCH_REG_CPUP_CONF, t); + +} + +static int adm5120_if_set_mac_address(struct net_device *dev, void *p) +{ + int ret; + + ret = eth_mac_addr(dev, p); + if (ret) + return ret; + + adm5120_write_mac(dev); + return 0; +} + +static int adm5120_if_do_ioctl(struct net_device *dev, struct ifreq *rq, + int cmd) +{ + int err; + struct adm5120_sw_info info; + struct adm5120_if_priv *priv = netdev_priv(dev); + + switch (cmd) { + case SIOCGADMINFO: + info.magic = 0x5120; + info.ports = adm5120_nrdevs; + info.vlan = priv->vlan_no; + err = copy_to_user(rq->ifr_data, &info, sizeof(info)); + if (err) + return -EFAULT; + break; + case SIOCSMATRIX: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + err = copy_from_user(adm5120_eth_vlans, rq->ifr_data, + sizeof(adm5120_eth_vlans)); + if (err) + return -EFAULT; + adm5120_set_vlan(adm5120_eth_vlans); + break; + case SIOCGMATRIX: + err = copy_to_user(rq->ifr_data, adm5120_eth_vlans, + sizeof(adm5120_eth_vlans)); + if (err) + return -EFAULT; + break; + default: + return -EOPNOTSUPP; + } + return 0; +} + +static const struct net_device_ops adm5120sw_netdev_ops = { + .ndo_open = adm5120_if_open, + .ndo_stop = adm5120_if_stop, + .ndo_start_xmit = adm5120_if_hard_start_xmit, + .ndo_set_rx_mode = adm5120_if_set_rx_mode, + .ndo_do_ioctl = adm5120_if_do_ioctl, + .ndo_tx_timeout = adm5120_if_tx_timeout, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = adm5120_if_set_mac_address, +}; + +static struct net_device *adm5120_if_alloc(void) +{ + struct net_device *dev; + struct adm5120_if_priv *priv; + + dev = alloc_etherdev(sizeof(*priv)); + if (!dev) + return NULL; + + priv = netdev_priv(dev); + priv->dev = dev; + + dev->irq = ADM5120_IRQ_SWITCH; + dev->netdev_ops = &adm5120sw_netdev_ops; + dev->watchdog_timeo = TX_TIMEOUT; + +#ifdef CONFIG_ADM5120_SWITCH_NAPI + netif_napi_add(dev, &priv->napi, adm5120_if_poll, 64); +#endif + + return dev; +} + +/* ------------------------------------------------------------------------ */ + +static void adm5120_switch_cleanup(void) +{ + int i; + + /* disable interrupts */ + sw_int_mask(SWITCH_INTS_ALL); + + for (i = 0; i < SWITCH_NUM_PORTS; i++) { + struct net_device *dev = adm5120_devs[i]; + if (dev) { + unregister_netdev(dev); + free_netdev(dev); + } + } + + adm5120_switch_tx_ring_free(); + adm5120_switch_rx_ring_free(); +} + +static int __devinit adm5120_switch_probe(struct platform_device *pdev) +{ + u32 t; + int i, err; + + adm5120_nrdevs = adm5120_eth_num_ports; + + t = CPUP_CONF_DCPUP | CPUP_CONF_CRCP | + SWITCH_PORTS_NOCPU << CPUP_CONF_DUNP_SHIFT | + SWITCH_PORTS_NOCPU << CPUP_CONF_DMCP_SHIFT ; + sw_write_reg(SWITCH_REG_CPUP_CONF, t); + + t = (SWITCH_PORTS_NOCPU << PORT_CONF0_EMCP_SHIFT) | + (SWITCH_PORTS_NOCPU << PORT_CONF0_BP_SHIFT) | + (SWITCH_PORTS_NOCPU); + sw_write_reg(SWITCH_REG_PORT_CONF0, t); + + /* setup ports to Autoneg/100M/Full duplex/Auto MDIX */ + t = SWITCH_PORTS_PHY | + (SWITCH_PORTS_PHY << PHY_CNTL2_SC_SHIFT) | + (SWITCH_PORTS_PHY << PHY_CNTL2_DC_SHIFT) | + (SWITCH_PORTS_PHY << PHY_CNTL2_PHYR_SHIFT) | + (SWITCH_PORTS_PHY << PHY_CNTL2_AMDIX_SHIFT) | + PHY_CNTL2_RMAE; + sw_write_reg(SWITCH_REG_PHY_CNTL2, t); + + t = sw_read_reg(SWITCH_REG_PHY_CNTL3); + t |= PHY_CNTL3_RNT; + sw_write_reg(SWITCH_REG_PHY_CNTL3, t); + + /* Force all the packets from all ports are low priority */ + sw_write_reg(SWITCH_REG_PRI_CNTL, 0); + + sw_int_mask(SWITCH_INTS_ALL); + sw_int_ack(SWITCH_INTS_ALL); + + err = adm5120_switch_rx_ring_alloc(); + if (err) + goto err; + + err = adm5120_switch_tx_ring_alloc(); + if (err) + goto err; + + adm5120_switch_tx_ring_reset(txl_descs, txl_skbuff, TX_RING_SIZE); + adm5120_switch_rx_ring_reset(rxl_descs, rxl_skbuff, RX_RING_SIZE); + + sw_write_reg(SWITCH_REG_SHDA, 0); + sw_write_reg(SWITCH_REG_SLDA, KSEG1ADDR(txl_descs)); + sw_write_reg(SWITCH_REG_RHDA, 0); + sw_write_reg(SWITCH_REG_RLDA, KSEG1ADDR(rxl_descs)); + + for (i = 0; i < SWITCH_NUM_PORTS; i++) { + struct net_device *dev; + struct adm5120_if_priv *priv; + + dev = adm5120_if_alloc(); + if (!dev) { + err = -ENOMEM; + goto err; + } + + adm5120_devs[i] = dev; + priv = netdev_priv(dev); + + priv->vlan_no = i; + priv->port_mask = adm5120_eth_vlans[i]; + + memcpy(dev->dev_addr, adm5120_eth_macs[i], 6); + adm5120_write_mac(dev); + + err = register_netdev(dev); + if (err) { + SW_INFO("%s register failed, error=%d\n", + dev->name, err); + goto err; + } + } + + /* setup vlan/port mapping after devs are filled up */ + adm5120_set_vlan(adm5120_eth_vlans); + + /* enable CPU port */ + t = sw_read_reg(SWITCH_REG_CPUP_CONF); + t &= ~CPUP_CONF_DCPUP; + sw_write_reg(SWITCH_REG_CPUP_CONF, t); + + return 0; + +err: + adm5120_switch_cleanup(); + + SW_ERR("init failed\n"); + return err; +} + +static int adm5120_switch_remove(struct platform_device *pdev) +{ + adm5120_switch_cleanup(); + return 0; +} + +static struct platform_driver adm5120_switch_driver = { + .probe = adm5120_switch_probe, + .remove = adm5120_switch_remove, + .driver = { + .name = DRV_NAME, + }, +}; + +/* -------------------------------------------------------------------------- */ + +static int __init adm5120_switch_mod_init(void) +{ + int err; + + pr_info(DRV_DESC " version " DRV_VERSION "\n"); + err = platform_driver_register(&adm5120_switch_driver); + + return err; +} + +static void __exit adm5120_switch_mod_exit(void) +{ + platform_driver_unregister(&adm5120_switch_driver); +} + +module_init(adm5120_switch_mod_init); +module_exit(adm5120_switch_mod_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_DESCRIPTION(DRV_DESC); +MODULE_VERSION(DRV_VERSION); diff --git a/target/linux/adm5120/files/drivers/net/adm5120sw.h b/target/linux/adm5120/files/drivers/net/adm5120sw.h new file mode 100644 index 000000000..fa9e50335 --- /dev/null +++ b/target/linux/adm5120/files/drivers/net/adm5120sw.h @@ -0,0 +1,23 @@ +/* + * Defines for ADM5120 built in ethernet switch driver + * + * Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2005 + * + * Values come from ADM5120 datasheet and original ADMtek 2.4 driver, + * Copyright ADMtek Inc. + */ + +#ifndef _INCLUDE_ADM5120SW_H_ +#define _INCLUDE_ADM5120SW_H_ + +#define SIOCSMATRIX SIOCDEVPRIVATE +#define SIOCGMATRIX (SIOCDEVPRIVATE + 1) +#define SIOCGADMINFO (SIOCDEVPRIVATE + 2) + +struct adm5120_sw_info { + u16 magic; + u16 ports; + u16 vlan; +}; + +#endif /* _INCLUDE_ADM5120SW_H_ */ diff --git a/target/linux/adm5120/files/drivers/usb/host/adm5120-dbg.c b/target/linux/adm5120/files/drivers/usb/host/adm5120-dbg.c new file mode 100644 index 000000000..2d5dc2a5a --- /dev/null +++ b/target/linux/adm5120/files/drivers/usb/host/adm5120-dbg.c @@ -0,0 +1,836 @@ +/* + * ADM5120 HCD (Host Controller Driver) for USB + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This file was derived from: drivers/usb/host/ohci-dbg.c + * (C) Copyright 1999 Roman Weissgaerber + * (C) Copyright 2000-2002 David Brownell + * + * This program 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. + * + */ + +/*-------------------------------------------------------------------------*/ + +static inline char *ed_typestring(int ed_type) +{ + switch (ed_type) { + case PIPE_CONTROL: + return "ctrl"; + case PIPE_BULK: + return "bulk"; + case PIPE_INTERRUPT: + return "intr"; + case PIPE_ISOCHRONOUS: + return "isoc"; + } + return "(bad ed_type)"; +} + +static inline char *ed_statestring(int state) +{ + switch (state) { + case ED_IDLE: + return "IDLE"; + case ED_UNLINK: + return "UNLINK"; + case ED_OPER: + return "OPER"; + } + return "?STATE"; +} + +static inline char *pipestring(int pipe) +{ + return ed_typestring(usb_pipetype(pipe)); +} + +static inline char *td_pidstring(u32 info) +{ + switch (info & TD_DP) { + case TD_DP_SETUP: + return "SETUP"; + case TD_DP_IN: + return "IN"; + case TD_DP_OUT: + return "OUT"; + } + return "?PID"; +} + +static inline char *td_togglestring(u32 info) +{ + switch (info & TD_T) { + case TD_T_DATA0: + return "DATA0"; + case TD_T_DATA1: + return "DATA1"; + case TD_T_CARRY: + return "CARRY"; + } + return "?TOGGLE"; +} + +/*-------------------------------------------------------------------------*/ + +#ifdef DEBUG + +/* debug| print the main components of an URB + * small: 0) header + data packets 1) just header + */ +static void __attribute__((unused)) +urb_print(struct admhcd *ahcd, struct urb *urb, char *str, int small, int status) +{ + unsigned int pipe = urb->pipe; + + if (!urb->dev || !urb->dev->bus) { + admhc_dbg(ahcd, "%s URB: no dev", str); + return; + } + +#ifndef ADMHC_VERBOSE_DEBUG + if (status != 0) +#endif + admhc_dbg(ahcd, "URB-%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d " + "stat=%d\n", + str, + urb, + usb_pipedevice(pipe), + usb_pipeendpoint(pipe), + usb_pipeout(pipe) ? "out" : "in", + pipestring(pipe), + urb->transfer_flags, + urb->actual_length, + urb->transfer_buffer_length, + status); + +#ifdef ADMHC_VERBOSE_DEBUG + if (!small) { + int i, len; + + if (usb_pipecontrol(pipe)) { + admhc_dbg(ahcd, "setup(8):"); + for (i = 0; i < 8 ; i++) + printk(KERN_INFO" %02x", ((__u8 *)urb->setup_packet)[i]); + printk(KERN_INFO "\n"); + } + if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) { + admhc_dbg(ahcd, "data(%d/%d):", + urb->actual_length, + urb->transfer_buffer_length); + len = usb_pipeout(pipe) ? + urb->transfer_buffer_length : urb->actual_length; + for (i = 0; i < 16 && i < len; i++) + printk(KERN_INFO " %02x", ((__u8 *)urb->transfer_buffer)[i]); + printk(KERN_INFO "%s stat:%d\n", i < len ? "..." : "", status); + } + } +#endif /* ADMHC_VERBOSE_DEBUG */ +} + +#define admhc_dbg_sw(ahcd, next, size, format, arg...) \ + do { \ + if (next) { \ + unsigned s_len; \ + s_len = scnprintf(*next, *size, format, ## arg); \ + *size -= s_len; *next += s_len; \ + } else \ + admhc_dbg(ahcd, format, ## arg); \ + } while (0); + + +static void admhc_dump_intr_mask(struct admhcd *ahcd, char *label, u32 mask, + char **next, unsigned *size) +{ + admhc_dbg_sw(ahcd, next, size, "%s 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s\n", + label, + mask, + (mask & ADMHC_INTR_INTA) ? " INTA" : "", + (mask & ADMHC_INTR_FATI) ? " FATI" : "", + (mask & ADMHC_INTR_SWI) ? " SWI" : "", + (mask & ADMHC_INTR_TDC) ? " TDC" : "", + (mask & ADMHC_INTR_FNO) ? " FNO" : "", + (mask & ADMHC_INTR_SO) ? " SO" : "", + (mask & ADMHC_INTR_INSM) ? " INSM" : "", + (mask & ADMHC_INTR_BABI) ? " BABI" : "", + (mask & ADMHC_INTR_7) ? " !7!" : "", + (mask & ADMHC_INTR_6) ? " !6!" : "", + (mask & ADMHC_INTR_RESI) ? " RESI" : "", + (mask & ADMHC_INTR_SOFI) ? " SOFI" : "" + ); +} + +static void maybe_print_eds(struct admhcd *ahcd, char *label, u32 value, + char **next, unsigned *size) +{ + if (value) + admhc_dbg_sw(ahcd, next, size, "%s %08x\n", label, value); +} + +static char *buss2string(int state) +{ + switch (state) { + case ADMHC_BUSS_RESET: + return "reset"; + case ADMHC_BUSS_RESUME: + return "resume"; + case ADMHC_BUSS_OPER: + return "operational"; + case ADMHC_BUSS_SUSPEND: + return "suspend"; + } + return "?state"; +} + +static void +admhc_dump_status(struct admhcd *ahcd, char **next, unsigned *size) +{ + struct admhcd_regs __iomem *regs = ahcd->regs; + u32 temp; + + temp = admhc_readl(ahcd, ®s->gencontrol); + admhc_dbg_sw(ahcd, next, size, + "gencontrol 0x%08x%s%s%s%s\n", + temp, + (temp & ADMHC_CTRL_UHFE) ? " UHFE" : "", + (temp & ADMHC_CTRL_SIR) ? " SIR" : "", + (temp & ADMHC_CTRL_DMAA) ? " DMAA" : "", + (temp & ADMHC_CTRL_SR) ? " SR" : "" + ); + + temp = admhc_readl(ahcd, ®s->host_control); + admhc_dbg_sw(ahcd, next, size, + "host_control 0x%08x BUSS=%s%s\n", + temp, + buss2string(temp & ADMHC_HC_BUSS), + (temp & ADMHC_HC_DMAE) ? " DMAE" : "" + ); + + admhc_dump_intr_mask(ahcd, "int_status", + admhc_readl(ahcd, ®s->int_status), + next, size); + admhc_dump_intr_mask(ahcd, "int_enable", + admhc_readl(ahcd, ®s->int_enable), + next, size); + + maybe_print_eds(ahcd, "hosthead", + admhc_readl(ahcd, ®s->hosthead), next, size); +} + +#define dbg_port_sw(hc, num, value, next, size) \ + admhc_dbg_sw(hc, next, size, \ + "portstatus [%d] " \ + "0x%08x%s%s%s%s%s%s%s%s%s%s%s%s\n", \ + num, temp, \ + (temp & ADMHC_PS_PRSC) ? " PRSC" : "", \ + (temp & ADMHC_PS_OCIC) ? " OCIC" : "", \ + (temp & ADMHC_PS_PSSC) ? " PSSC" : "", \ + (temp & ADMHC_PS_PESC) ? " PESC" : "", \ + (temp & ADMHC_PS_CSC) ? " CSC" : "", \ + \ + (temp & ADMHC_PS_LSDA) ? " LSDA" : "", \ + (temp & ADMHC_PS_PPS) ? " PPS" : "", \ + (temp & ADMHC_PS_PRS) ? " PRS" : "", \ + (temp & ADMHC_PS_POCI) ? " POCI" : "", \ + (temp & ADMHC_PS_PSS) ? " PSS" : "", \ + \ + (temp & ADMHC_PS_PES) ? " PES" : "", \ + (temp & ADMHC_PS_CCS) ? " CCS" : "" \ + ); + + +static void +admhc_dump_roothub( + struct admhcd *ahcd, + int verbose, + char **next, + unsigned *size) +{ + u32 temp, i; + + temp = admhc_read_rhdesc(ahcd); + if (temp == ~(u32)0) + return; + + if (verbose) { + admhc_dbg_sw(ahcd, next, size, + "rhdesc %08x%s%s%s%s%s%s PPCM=%02x%s%s%s%s NUMP=%d(%d)\n", + temp, + (temp & ADMHC_RH_CRWE) ? " CRWE" : "", + (temp & ADMHC_RH_OCIC) ? " OCIC" : "", + (temp & ADMHC_RH_LPSC) ? " LPSC" : "", + (temp & ADMHC_RH_LPSC) ? " DRWE" : "", + (temp & ADMHC_RH_LPSC) ? " OCI" : "", + (temp & ADMHC_RH_LPSC) ? " LPS" : "", + ((temp & ADMHC_RH_PPCM) >> 16), + (temp & ADMHC_RH_NOCP) ? " NOCP" : "", + (temp & ADMHC_RH_OCPM) ? " OCPM" : "", + (temp & ADMHC_RH_NPS) ? " NPS" : "", + (temp & ADMHC_RH_PSM) ? " PSM" : "", + (temp & ADMHC_RH_NUMP), ahcd->num_ports + ); + } + + for (i = 0; i < ahcd->num_ports; i++) { + temp = admhc_read_portstatus(ahcd, i); + dbg_port_sw(ahcd, i, temp, next, size); + } +} + +static void admhc_dump(struct admhcd *ahcd, int verbose) +{ + admhc_dbg(ahcd, "ADMHC ahcd state\n"); + + /* dumps some of the state we know about */ + admhc_dump_status(ahcd, NULL, NULL); + admhc_dbg(ahcd, "current frame #%04x\n", + admhc_frame_no(ahcd)); + + admhc_dump_roothub(ahcd, verbose, NULL, NULL); +} + +static const char data0[] = "DATA0"; +static const char data1[] = "DATA1"; + +static void admhc_dump_td(const struct admhcd *ahcd, const char *label, + const struct td *td) +{ + u32 tmp; + + admhc_dbg(ahcd, "%s td %p; urb %p index %d; hwNextTD %08x\n", + label, td, + td->urb, td->index, + hc32_to_cpup(ahcd, &td->hwNextTD)); + + tmp = hc32_to_cpup(ahcd, &td->hwINFO); + admhc_dbg(ahcd, " status %08x%s CC=%x EC=%d %s %s ISI=%x FN=%x\n", + tmp, + (tmp & TD_OWN) ? " OWN" : "", + TD_CC_GET(tmp), + TD_EC_GET(tmp), + td_togglestring(tmp), + td_pidstring(tmp), + TD_ISI_GET(tmp), + TD_FN_GET(tmp)); + + tmp = hc32_to_cpup(ahcd, &td->hwCBL); + admhc_dbg(ahcd, " dbp %08x; cbl %08x; LEN=%d%s\n", + hc32_to_cpup(ahcd, &td->hwDBP), + tmp, + TD_BL_GET(tmp), + (tmp & TD_IE) ? " IE" : ""); +} + +/* caller MUST own hcd spinlock if verbose is set! */ +static void __attribute__((unused)) +admhc_dump_ed(const struct admhcd *ahcd, const char *label, + const struct ed *ed, int verbose) +{ + u32 tmp = hc32_to_cpu(ahcd, ed->hwINFO); + + admhc_dbg(ahcd, "%s ed %p %s type %s; next ed %08x\n", + label, + ed, ed_statestring(ed->state), ed_typestring(ed->type), + hc32_to_cpup(ahcd, &ed->hwNextED)); + + admhc_dbg(ahcd, " info %08x MAX=%d%s%s%s%s EP=%d DEV=%d\n", tmp, + ED_MPS_GET(tmp), + (tmp & ED_ISO) ? " ISO" : "", + (tmp & ED_SKIP) ? " SKIP" : "", + (tmp & ED_SPEED_FULL) ? " FULL" : " LOW", + (tmp & ED_INT) ? " INT" : "", + ED_EN_GET(tmp), + ED_FA_GET(tmp)); + + tmp = hc32_to_cpup(ahcd, &ed->hwHeadP); + admhc_dbg(ahcd, " tds: head %08x tail %08x %s%s%s\n", + tmp & TD_MASK, + hc32_to_cpup(ahcd, &ed->hwTailP), + (tmp & ED_C) ? data1 : data0, + (tmp & ED_H) ? " HALT" : "", + verbose ? " td list follows" : " (not listing)"); + + if (verbose) { + struct list_head *tmp; + + /* use ed->td_list because HC concurrently modifies + * hwNextTD as it accumulates ed_donelist. + */ + list_for_each(tmp, &ed->td_list) { + struct td *td; + td = list_entry(tmp, struct td, td_list); + admhc_dump_td(ahcd, " ->", td); + } + } +} + +#else /* ifdef DEBUG */ + +static inline void urb_print(struct admhcd *ahcd, struct urb * urb, char * str, + int small, int status) {} +static inline void admhc_dump_ed(const struct admhcd *ahcd, const char *label, + const struct ed *ed, int verbose) {} +static inline void admhc_dump_td(const struct admhcd *ahcd, const char *label, + const struct td *td) {} +static inline void admhc_dump(struct admhcd *ahcd, int verbose) {} + +#undef ADMHC_VERBOSE_DEBUG + +#endif /* DEBUG */ + +/*-------------------------------------------------------------------------*/ + +#ifdef STUB_DEBUG_FILES + +static inline void create_debug_files(struct admhcd *bus) { } +static inline void remove_debug_files(struct admhcd *bus) { } + +#else + +static int debug_async_open(struct inode *, struct file *); +static int debug_periodic_open(struct inode *, struct file *); +static int debug_registers_open(struct inode *, struct file *); +static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*); +static int debug_close(struct inode *, struct file *); + +static const struct file_operations debug_async_fops = { + .owner = THIS_MODULE, + .open = debug_async_open, + .read = debug_output, + .release = debug_close, + .llseek = default_llseek, +}; +static const struct file_operations debug_periodic_fops = { + .owner = THIS_MODULE, + .open = debug_periodic_open, + .read = debug_output, + .release = debug_close, + .llseek = default_llseek, +}; +static const struct file_operations debug_registers_fops = { + .owner = THIS_MODULE, + .open = debug_registers_open, + .read = debug_output, + .release = debug_close, + .llseek = default_llseek, +}; + +static struct dentry *admhc_debug_root; + +struct debug_buffer { + ssize_t (*fill_func)(struct debug_buffer *); /* fill method */ + struct admhcd *ahcd; + struct mutex mutex; /* protect filling of buffer */ + size_t count; /* number of characters filled into buffer */ + char *page; +}; + +static ssize_t +show_list(struct admhcd *ahcd, char *buf, size_t count, struct ed *ed) +{ + unsigned temp; + unsigned size = count; + + if (!ed) + return 0; + + /* dump a snapshot of the bulk or control schedule */ + while (ed) { + u32 info = hc32_to_cpu(ahcd, ed->hwINFO); + u32 headp = hc32_to_cpu(ahcd, ed->hwHeadP); + u32 tailp = hc32_to_cpu(ahcd, ed->hwTailP); + struct list_head *entry; + struct td *td; + + temp = scnprintf(buf, size, + "ed/%p %s %s %cs dev%d ep%d %s%smax %d %08x%s%s %s" + " h:%08x t:%08x", + ed, + ed_statestring(ed->state), + ed_typestring(ed->type), + (info & ED_SPEED_FULL) ? 'f' : 'l', + info & ED_FA_MASK, + (info >> ED_EN_SHIFT) & ED_EN_MASK, + (info & ED_INT) ? "INT " : "", + (info & ED_ISO) ? "ISO " : "", + (info >> ED_MPS_SHIFT) & ED_MPS_MASK , + info, + (info & ED_SKIP) ? " S" : "", + (headp & ED_H) ? " H" : "", + (headp & ED_C) ? data1 : data0, + headp & ED_MASK, tailp); + size -= temp; + buf += temp; + + list_for_each(entry, &ed->td_list) { + u32 dbp, cbl; + + td = list_entry(entry, struct td, td_list); + info = hc32_to_cpup(ahcd, &td->hwINFO); + dbp = hc32_to_cpup(ahcd, &td->hwDBP); + cbl = hc32_to_cpup(ahcd, &td->hwCBL); + + temp = scnprintf(buf, size, + "\n\ttd/%p %s %d %s%scc=%x urb %p (%08x,%08x)", + td, + td_pidstring(info), + TD_BL_GET(cbl), + (info & TD_OWN) ? "" : "DONE ", + (cbl & TD_IE) ? "IE " : "", + TD_CC_GET(info), td->urb, info, cbl); + size -= temp; + buf += temp; + } + + temp = scnprintf(buf, size, "\n"); + size -= temp; + buf += temp; + + ed = ed->ed_next; + } + + return count - size; +} + +static ssize_t fill_async_buffer(struct debug_buffer *buf) +{ + struct admhcd *ahcd; + size_t temp; + unsigned long flags; + + ahcd = buf->ahcd; + + spin_lock_irqsave(&ahcd->lock, flags); + temp = show_list(ahcd, buf->page, PAGE_SIZE, ahcd->ed_head); + spin_unlock_irqrestore(&ahcd->lock, flags); + + return temp; +} + + +#define DBG_SCHED_LIMIT 64 + +static ssize_t fill_periodic_buffer(struct debug_buffer *buf) +{ + struct admhcd *ahcd; + struct ed **seen, *ed; + unsigned long flags; + unsigned temp, size, seen_count; + char *next; + unsigned i; + + seen = kmalloc(DBG_SCHED_LIMIT * sizeof(*seen), GFP_ATOMIC); + if (!seen) + return 0; + seen_count = 0; + + ahcd = buf->ahcd; + next = buf->page; + size = PAGE_SIZE; + + temp = scnprintf(next, size, "size = %d\n", NUM_INTS); + size -= temp; + next += temp; + + /* dump a snapshot of the periodic schedule (and load) */ + spin_lock_irqsave(&ahcd->lock, flags); + for (i = 0; i < NUM_INTS; i++) { + ed = ahcd->periodic[i]; + if (!ed) + continue; + + temp = scnprintf(next, size, "%2d [%3d]:", i, ahcd->load[i]); + size -= temp; + next += temp; + + do { + temp = scnprintf(next, size, " ed%d/%p", + ed->interval, ed); + size -= temp; + next += temp; + for (temp = 0; temp < seen_count; temp++) { + if (seen[temp] == ed) + break; + } + + /* show more info the first time around */ + if (temp == seen_count) { + u32 info = hc32_to_cpu(ahcd, ed->hwINFO); + struct list_head *entry; + unsigned qlen = 0; + + /* qlen measured here in TDs, not urbs */ + list_for_each(entry, &ed->td_list) + qlen++; + temp = scnprintf(next, size, + " (%cs dev%d ep%d%s qlen %u" + " max %d %08x%s%s)", + (info & ED_SPEED_FULL) ? 'f' : 'l', + ED_FA_GET(info), + ED_EN_GET(info), + (info & ED_ISO) ? "iso" : "int", + qlen, + ED_MPS_GET(info), + info, + (info & ED_SKIP) ? " K" : "", + (ed->hwHeadP & + cpu_to_hc32(ahcd, ED_H)) ? + " H" : ""); + size -= temp; + next += temp; + + if (seen_count < DBG_SCHED_LIMIT) + seen[seen_count++] = ed; + + ed = ed->ed_next; + + } else { + /* we've seen it and what's after */ + temp = 0; + ed = NULL; + } + + } while (ed); + + temp = scnprintf(next, size, "\n"); + size -= temp; + next += temp; + } + spin_unlock_irqrestore(&ahcd->lock, flags); + kfree(seen); + + return PAGE_SIZE - size; +} + + +#undef DBG_SCHED_LIMIT + +static ssize_t fill_registers_buffer(struct debug_buffer *buf) +{ + struct usb_hcd *hcd; + struct admhcd *ahcd; + struct admhcd_regs __iomem *regs; + unsigned long flags; + unsigned temp, size; + char *next; + u32 rdata; + + ahcd = buf->ahcd; + hcd = admhc_to_hcd(ahcd); + regs = ahcd->regs; + next = buf->page; + size = PAGE_SIZE; + + spin_lock_irqsave(&ahcd->lock, flags); + + /* dump driver info, then registers in spec order */ + + admhc_dbg_sw(ahcd, &next, &size, + "bus %s, device %s\n" + "%s\n" + "%s\n", + hcd->self.controller->bus->name, + dev_name(hcd->self.controller), + hcd->product_desc, + hcd_name); + + if (!HCD_HW_ACCESSIBLE(hcd)) { + size -= scnprintf(next, size, + "SUSPENDED (no register access)\n"); + goto done; + } + + admhc_dump_status(ahcd, &next, &size); + + /* other registers mostly affect frame timings */ + rdata = admhc_readl(ahcd, ®s->fminterval); + temp = scnprintf(next, size, + "fmintvl 0x%08x %sFSLDP=0x%04x FI=0x%04x\n", + rdata, (rdata & ADMHC_SFI_FIT) ? "FIT " : "", + (rdata >> ADMHC_SFI_FSLDP_SHIFT) & ADMHC_SFI_FSLDP_MASK, + rdata & ADMHC_SFI_FI_MASK); + size -= temp; + next += temp; + + rdata = admhc_readl(ahcd, ®s->fmnumber); + temp = scnprintf(next, size, "fmnumber 0x%08x %sFR=0x%04x FN=%04x\n", + rdata, (rdata & ADMHC_SFN_FRT) ? "FRT " : "", + (rdata >> ADMHC_SFN_FR_SHIFT) & ADMHC_SFN_FR_MASK, + rdata & ADMHC_SFN_FN_MASK); + size -= temp; + next += temp; + + /* TODO: use predefined bitmask */ + rdata = admhc_readl(ahcd, ®s->lsthresh); + temp = scnprintf(next, size, "lsthresh 0x%04x\n", + rdata & 0x3fff); + size -= temp; + next += temp; + + temp = scnprintf(next, size, "hub poll timer: %s\n", + admhcd_to_hcd(ahcd)->poll_rh ? "ON" : "OFF"); + size -= temp; + next += temp; + + /* roothub */ + admhc_dump_roothub(ahcd, 1, &next, &size); + +done: + spin_unlock_irqrestore(&ahcd->lock, flags); + return PAGE_SIZE - size; +} + + +static struct debug_buffer *alloc_buffer(struct admhcd *ahcd, + ssize_t (*fill_func)(struct debug_buffer *)) +{ + struct debug_buffer *buf; + + buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL); + + if (buf) { + buf->ahcd = ahcd; + buf->fill_func = fill_func; + mutex_init(&buf->mutex); + } + + return buf; +} + +static int fill_buffer(struct debug_buffer *buf) +{ + int ret = 0; + + if (!buf->page) + buf->page = (char *)get_zeroed_page(GFP_KERNEL); + + if (!buf->page) { + ret = -ENOMEM; + goto out; + } + + ret = buf->fill_func(buf); + + if (ret >= 0) { + buf->count = ret; + ret = 0; + } + +out: + return ret; +} + +static ssize_t debug_output(struct file *file, char __user *user_buf, + size_t len, loff_t *offset) +{ + struct debug_buffer *buf = file->private_data; + int ret = 0; + + mutex_lock(&buf->mutex); + if (buf->count == 0) { + ret = fill_buffer(buf); + if (ret != 0) { + mutex_unlock(&buf->mutex); + goto out; + } + } + mutex_unlock(&buf->mutex); + + ret = simple_read_from_buffer(user_buf, len, offset, + buf->page, buf->count); + +out: + return ret; +} + +static int debug_close(struct inode *inode, struct file *file) +{ + struct debug_buffer *buf = file->private_data; + + if (buf) { + if (buf->page) + free_page((unsigned long)buf->page); + kfree(buf); + } + + return 0; +} + +static int debug_async_open(struct inode *inode, struct file *file) +{ + file->private_data = alloc_buffer(inode->i_private, fill_async_buffer); + + return file->private_data ? 0 : -ENOMEM; +} + +static int debug_periodic_open(struct inode *inode, struct file *file) +{ + file->private_data = alloc_buffer(inode->i_private, + fill_periodic_buffer); + + return file->private_data ? 0 : -ENOMEM; +} + +static int debug_registers_open(struct inode *inode, struct file *file) +{ + file->private_data = alloc_buffer(inode->i_private, + fill_registers_buffer); + + return file->private_data ? 0 : -ENOMEM; +} + +static inline void create_debug_files(struct admhcd *ahcd) +{ + struct usb_bus *bus = &admhcd_to_hcd(ahcd)->self; + + ahcd->debug_dir = debugfs_create_dir(bus->bus_name, admhc_debug_root); + if (!ahcd->debug_dir) + goto dir_error; + + ahcd->debug_async = debugfs_create_file("async", S_IRUGO, + ahcd->debug_dir, ahcd, + &debug_async_fops); + if (!ahcd->debug_async) + goto async_error; + + ahcd->debug_periodic = debugfs_create_file("periodic", S_IRUGO, + ahcd->debug_dir, ahcd, + &debug_periodic_fops); + if (!ahcd->debug_periodic) + goto periodic_error; + + ahcd->debug_registers = debugfs_create_file("registers", S_IRUGO, + ahcd->debug_dir, ahcd, + &debug_registers_fops); + if (!ahcd->debug_registers) + goto registers_error; + + admhc_dbg(ahcd, "created debug files\n"); + return; + +registers_error: + debugfs_remove(ahcd->debug_periodic); +periodic_error: + debugfs_remove(ahcd->debug_async); +async_error: + debugfs_remove(ahcd->debug_dir); +dir_error: + ahcd->debug_periodic = NULL; + ahcd->debug_async = NULL; + ahcd->debug_dir = NULL; +} + +static inline void remove_debug_files(struct admhcd *ahcd) +{ + debugfs_remove(ahcd->debug_registers); + debugfs_remove(ahcd->debug_periodic); + debugfs_remove(ahcd->debug_async); + debugfs_remove(ahcd->debug_dir); +} + +#endif + +/*-------------------------------------------------------------------------*/ diff --git a/target/linux/adm5120/files/drivers/usb/host/adm5120-drv.c b/target/linux/adm5120/files/drivers/usb/host/adm5120-drv.c new file mode 100644 index 000000000..99ea9d530 --- /dev/null +++ b/target/linux/adm5120/files/drivers/usb/host/adm5120-drv.c @@ -0,0 +1,228 @@ +/* + * ADM5120 HCD (Host Controller Driver) for USB + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This file was derived from: drivers/usb/host/ohci-au1xxx.c + * (C) Copyright 1999 Roman Weissgaerber + * (C) Copyright 2000-2002 David Brownell + * (C) Copyright 2002 Hewlett-Packard Company + * + * Written by Christopher Hoover + * Based on fragments of previous driver by Russell King et al. + * + * Modified for LH7A404 from ahcd-sa1111.c + * by Durgesh Pattamatta + * Modified for AMD Alchemy Au1xxx + * by Matt Porter + * + * This program 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. + * + */ + +#include +#include + +#include +#include + +#ifdef DEBUG +#define HCD_DBG(f, a...) printk(KERN_DEBUG "%s: " f, hcd_name, ## a) +#else +#define HCD_DBG(f, a...) do {} while (0) +#endif +#define HCD_ERR(f, a...) printk(KERN_ERR "%s: " f, hcd_name, ## a) +#define HCD_INFO(f, a...) printk(KERN_INFO "%s: " f, hcd_name, ## a) + +/*-------------------------------------------------------------------------*/ + +static int admhc_adm5120_probe(const struct hc_driver *driver, + struct platform_device *dev) +{ + int retval; + struct usb_hcd *hcd; + int irq; + struct resource *regs; + + /* sanity checks */ + regs = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (!regs) { + HCD_DBG("no IOMEM resource found\n"); + return -ENODEV; + } + + irq = platform_get_irq(dev, 0); + if (irq < 0) { + HCD_DBG("no IRQ resource found\n"); + return -ENODEV; + } + + hcd = usb_create_hcd(driver, &dev->dev, "ADM5120"); + if (!hcd) + return -ENOMEM; + + hcd->rsrc_start = regs->start; + hcd->rsrc_len = regs->end - regs->start + 1; + + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { + HCD_DBG("request_mem_region failed\n"); + retval = -EBUSY; + goto err_dev; + } + + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + if (!hcd->regs) { + HCD_DBG("ioremap failed\n"); + retval = -ENOMEM; + goto err_mem; + } + + admhc_hcd_init(hcd_to_admhcd(hcd)); + + retval = usb_add_hcd(hcd, irq, 0); + if (retval) + goto err_io; + + return 0; + +err_io: + iounmap(hcd->regs); +err_mem: + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +err_dev: + usb_put_hcd(hcd); + return retval; +} + + +/* may be called without controller electrically present */ +/* may be called with controller, bus, and devices active */ + +static void admhc_adm5120_remove(struct usb_hcd *hcd, + struct platform_device *dev) +{ + usb_remove_hcd(hcd); + iounmap(hcd->regs); + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + usb_put_hcd(hcd); +} + +static int __devinit admhc_adm5120_start(struct usb_hcd *hcd) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + int ret; + + ret = admhc_init(ahcd); + if (ret < 0) { + HCD_ERR("unable to init %s\n", hcd->self.bus_name); + goto err; + } + + ret = admhc_run(ahcd); + if (ret < 0) { + HCD_ERR("unable to run %s\n", hcd->self.bus_name); + goto err_stop; + } + + return 0; + +err_stop: + admhc_stop(hcd); +err: + return ret; +} + +static const struct hc_driver adm5120_hc_driver = { + .description = hcd_name, + .product_desc = "ADM5120 built-in USB 1.1 Host Controller", + .hcd_priv_size = sizeof(struct admhcd), + + /* + * generic hardware linkage + */ + .irq = admhc_irq, + .flags = HCD_USB11 | HCD_MEMORY, + + /* + * basic lifecycle operations + */ + .start = admhc_adm5120_start, + .stop = admhc_stop, + .shutdown = admhc_shutdown, + + /* + * managing i/o requests and associated device resources + */ + .urb_enqueue = admhc_urb_enqueue, + .urb_dequeue = admhc_urb_dequeue, + .endpoint_disable = admhc_endpoint_disable, + + /* + * scheduling support + */ + .get_frame_number = admhc_get_frame_number, + + /* + * root hub support + */ + .hub_status_data = admhc_hub_status_data, + .hub_control = admhc_hub_control, +#ifdef CONFIG_PM + .bus_suspend = admhc_bus_suspend, + .bus_resume = admhc_bus_resume, +#endif + .start_port_reset = admhc_start_port_reset, +}; + +static int usb_hcd_adm5120_probe(struct platform_device *pdev) +{ + int ret; + + ret = admhc_adm5120_probe(&adm5120_hc_driver, pdev); + + return ret; +} + +static int usb_hcd_adm5120_remove(struct platform_device *pdev) +{ + struct usb_hcd *hcd = platform_get_drvdata(pdev); + + admhc_adm5120_remove(hcd, pdev); + + return 0; +} + +#ifdef CONFIG_PM +/* TODO */ +static int usb_hcd_adm5120_suspend(struct platform_device *dev) +{ + struct usb_hcd *hcd = platform_get_drvdata(dev); + + return 0; +} + +static int usb_hcd_adm5120_resume(struct platform_device *dev) +{ + struct usb_hcd *hcd = platform_get_drvdata(dev); + + return 0; +} +#else +#define usb_hcd_adm5120_suspend NULL +#define usb_hcd_adm5120_resume NULL +#endif /* CONFIG_PM */ + +static struct platform_driver usb_hcd_adm5120_driver = { + .probe = usb_hcd_adm5120_probe, + .remove = usb_hcd_adm5120_remove, + .shutdown = usb_hcd_platform_shutdown, + .suspend = usb_hcd_adm5120_suspend, + .resume = usb_hcd_adm5120_resume, + .driver = { + .name = "adm5120-hcd", + .owner = THIS_MODULE, + }, +}; + diff --git a/target/linux/adm5120/files/drivers/usb/host/adm5120-hcd.c b/target/linux/adm5120/files/drivers/usb/host/adm5120-hcd.c new file mode 100644 index 000000000..7dfa80448 --- /dev/null +++ b/target/linux/adm5120/files/drivers/usb/host/adm5120-hcd.c @@ -0,0 +1,844 @@ +/* + * ADM5120 HCD (Host Controller Driver) for USB + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This file was derived from: drivers/usb/host/ohci-hcd.c + * (C) Copyright 1999 Roman Weissgaerber + * (C) Copyright 2000-2004 David Brownell + * + * [ Initialisation is based on Linus' ] + * [ uhci code and gregs ahcd fragments ] + * [ (C) Copyright 1999 Linus Torvalds ] + * [ (C) Copyright 1999 Gregory P. Smith] + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define DRIVER_VERSION "0.27.0" +#define DRIVER_AUTHOR "Gabor Juhos " +#define DRIVER_DESC "ADMtek USB 1.1 Host Controller Driver" + +/*-------------------------------------------------------------------------*/ + +#undef ADMHC_VERBOSE_DEBUG /* not always helpful */ + +/* For initializing controller (mask in an HCFS mode too) */ +#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR + +#define ADMHC_INTR_INIT \ + (ADMHC_INTR_MIE | ADMHC_INTR_INSM | ADMHC_INTR_FATI \ + | ADMHC_INTR_RESI | ADMHC_INTR_TDC | ADMHC_INTR_BABI) + +/*-------------------------------------------------------------------------*/ + +static const char hcd_name[] = "admhc-hcd"; + +#define STATECHANGE_DELAY msecs_to_jiffies(300) + +#include "adm5120.h" + +static void admhc_dump(struct admhcd *ahcd, int verbose); +static int admhc_init(struct admhcd *ahcd); +static void admhc_stop(struct usb_hcd *hcd); + +#include "adm5120-dbg.c" +#include "adm5120-mem.c" +#include "adm5120-pm.c" +#include "adm5120-hub.c" +#include "adm5120-q.c" + +/*-------------------------------------------------------------------------*/ + +/* + * queue up an urb for anything except the root hub + */ +static int admhc_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, + gfp_t mem_flags) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + struct ed *ed; + struct urb_priv *urb_priv; + unsigned int pipe = urb->pipe; + int td_cnt = 0; + unsigned long flags; + int ret = 0; + +#ifdef ADMHC_VERBOSE_DEBUG + spin_lock_irqsave(&ahcd->lock, flags); + urb_print(ahcd, urb, "ENQEUE", usb_pipein(pipe), -EINPROGRESS); + spin_unlock_irqrestore(&ahcd->lock, flags); +#endif + + /* every endpoint has an ed, locate and maybe (re)initialize it */ + ed = ed_get(ahcd, urb->ep, urb->dev, pipe, urb->interval); + if (!ed) + return -ENOMEM; + + /* for the private part of the URB we need the number of TDs */ + switch (ed->type) { + case PIPE_CONTROL: + if (urb->transfer_buffer_length > TD_DATALEN_MAX) + /* td_submit_urb() doesn't yet handle these */ + return -EMSGSIZE; + + /* 1 TD for setup, 1 for ACK, plus ... */ + td_cnt = 2; + /* FALLTHROUGH */ + case PIPE_BULK: + /* one TD for every 4096 Bytes (can be up to 8K) */ + td_cnt += urb->transfer_buffer_length / TD_DATALEN_MAX; + /* ... and for any remaining bytes ... */ + if ((urb->transfer_buffer_length % TD_DATALEN_MAX) != 0) + td_cnt++; + /* ... and maybe a zero length packet to wrap it up */ + if (td_cnt == 0) + td_cnt++; + else if ((urb->transfer_flags & URB_ZERO_PACKET) != 0 + && (urb->transfer_buffer_length + % usb_maxpacket(urb->dev, pipe, + usb_pipeout(pipe))) == 0) + td_cnt++; + break; + case PIPE_INTERRUPT: + /* + * for Interrupt IN/OUT transactions, each ED contains + * only 1 TD. + * TODO: check transfer_buffer_length? + */ + td_cnt = 1; + break; + case PIPE_ISOCHRONOUS: + /* number of packets from URB */ + td_cnt = urb->number_of_packets; + break; + } + + urb_priv = urb_priv_alloc(ahcd, td_cnt, mem_flags); + if (!urb_priv) + return -ENOMEM; + + urb_priv->ed = ed; + + spin_lock_irqsave(&ahcd->lock, flags); + /* don't submit to a dead HC */ + if (!HCD_HW_ACCESSIBLE(hcd)) { + ret = -ENODEV; + goto fail; + } + if (!HC_IS_RUNNING(hcd->state)) { + ret = -ENODEV; + goto fail; + } + + ret = usb_hcd_link_urb_to_ep(hcd, urb); + if (ret) + goto fail; + + /* schedule the ed if needed */ + if (ed->state == ED_IDLE) { + ret = ed_schedule(ahcd, ed); + if (ret < 0) { + usb_hcd_unlink_urb_from_ep(hcd, urb); + goto fail; + } + if (ed->type == PIPE_ISOCHRONOUS) { + u16 frame = admhc_frame_no(ahcd); + + /* delay a few frames before the first TD */ + frame += max_t (u16, 8, ed->interval); + frame &= ~(ed->interval - 1); + frame |= ed->branch; + urb->start_frame = frame; + + /* yes, only URB_ISO_ASAP is supported, and + * urb->start_frame is never used as input. + */ + } + } else if (ed->type == PIPE_ISOCHRONOUS) + urb->start_frame = ed->last_iso + ed->interval; + + /* fill the TDs and link them to the ed; and + * enable that part of the schedule, if needed + * and update count of queued periodic urbs + */ + urb->hcpriv = urb_priv; + td_submit_urb(ahcd, urb); + +#ifdef ADMHC_VERBOSE_DEBUG + admhc_dump_ed(ahcd, "admhc_urb_enqueue", urb_priv->ed, 1); +#endif + +fail: + if (ret) + urb_priv_free(ahcd, urb_priv); + + spin_unlock_irqrestore(&ahcd->lock, flags); + return ret; +} + +/* + * decouple the URB from the HC queues (TDs, urb_priv); + * reporting is always done + * asynchronously, and we might be dealing with an urb that's + * partially transferred, or an ED with other urbs being unlinked. + */ +static int admhc_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, + int status) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + unsigned long flags; + int ret; + + spin_lock_irqsave(&ahcd->lock, flags); + +#ifdef ADMHC_VERBOSE_DEBUG + urb_print(ahcd, urb, "DEQUEUE", 1, status); +#endif + ret = usb_hcd_check_unlink_urb(hcd, urb, status); + if (ret) { + /* Do nothing */ + ; + } else if (HC_IS_RUNNING(hcd->state)) { + struct urb_priv *urb_priv; + + /* Unless an IRQ completed the unlink while it was being + * handed to us, flag it for unlink and giveback, and force + * some upcoming INTR_SF to call finish_unlinks() + */ + urb_priv = urb->hcpriv; + if (urb_priv) { + if (urb_priv->ed->state == ED_OPER) + start_ed_unlink(ahcd, urb_priv->ed); + } + } else { + /* + * with HC dead, we won't respect hc queue pointers + * any more ... just clean up every urb's memory. + */ + if (urb->hcpriv) + finish_urb(ahcd, urb, status); + } + spin_unlock_irqrestore(&ahcd->lock, flags); + + return ret; +} + +/*-------------------------------------------------------------------------*/ + +/* frees config/altsetting state for endpoints, + * including ED memory, dummy TD, and bulk/intr data toggle + */ + +static void admhc_endpoint_disable(struct usb_hcd *hcd, + struct usb_host_endpoint *ep) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + unsigned long flags; + struct ed *ed = ep->hcpriv; + unsigned limit = 1000; + + /* ASSERT: any requests/urbs are being unlinked */ + /* ASSERT: nobody can be submitting urbs for this any more */ + + if (!ed) + return; + +#ifdef ADMHC_VERBOSE_DEBUG + spin_lock_irqsave(&ahcd->lock, flags); + admhc_dump_ed(ahcd, "EP-DISABLE", ed, 1); + spin_unlock_irqrestore(&ahcd->lock, flags); +#endif + +rescan: + spin_lock_irqsave(&ahcd->lock, flags); + + if (!HC_IS_RUNNING(hcd->state)) { +sanitize: + ed->state = ED_IDLE; + finish_unlinks(ahcd, 0); + } + + switch (ed->state) { + case ED_UNLINK: /* wait for hw to finish? */ + /* major IRQ delivery trouble loses INTR_SOFI too... */ + if (limit-- == 0) { + admhc_warn(ahcd, "IRQ INTR_SOFI lossage\n"); + goto sanitize; + } + spin_unlock_irqrestore(&ahcd->lock, flags); + schedule_timeout_uninterruptible(1); + goto rescan; + case ED_IDLE: /* fully unlinked */ + if (list_empty(&ed->td_list)) { + td_free(ahcd, ed->dummy); + ed_free(ahcd, ed); + break; + } + /* else FALL THROUGH */ + default: + /* caller was supposed to have unlinked any requests; + * that's not our job. can't recover; must leak ed. + */ + admhc_err(ahcd, "leak ed %p (#%02x) state %d%s\n", + ed, ep->desc.bEndpointAddress, ed->state, + list_empty(&ed->td_list) ? "" : " (has tds)"); + td_free(ahcd, ed->dummy); + break; + } + + ep->hcpriv = NULL; + + spin_unlock_irqrestore(&ahcd->lock, flags); +} + +static int admhc_get_frame_number(struct usb_hcd *hcd) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + + return admhc_frame_no(ahcd); +} + +static void admhc_usb_reset(struct admhcd *ahcd) +{ +#if 0 + ahcd->hc_control = admhc_readl(ahcd, &ahcd->regs->control); + ahcd->hc_control &= OHCI_CTRL_RWC; + admhc_writel(ahcd, ahcd->hc_control, &ahcd->regs->control); +#else + /* FIXME */ + ahcd->host_control = ADMHC_BUSS_RESET; + admhc_writel(ahcd, ahcd->host_control, &ahcd->regs->host_control); +#endif +} + +/* admhc_shutdown forcibly disables IRQs and DMA, helping kexec and + * other cases where the next software may expect clean state from the + * "firmware". this is bus-neutral, unlike shutdown() methods. + */ +static void +admhc_shutdown(struct usb_hcd *hcd) +{ + struct admhcd *ahcd; + + ahcd = hcd_to_admhcd(hcd); + admhc_intr_disable(ahcd, ADMHC_INTR_MIE); + admhc_dma_disable(ahcd); + admhc_usb_reset(ahcd); + /* flush the writes */ + admhc_writel_flush(ahcd); +} + +/*-------------------------------------------------------------------------* + * HC functions + *-------------------------------------------------------------------------*/ + +static void admhc_eds_cleanup(struct admhcd *ahcd) +{ + if (ahcd->ed_tails[PIPE_INTERRUPT]) { + ed_free(ahcd, ahcd->ed_tails[PIPE_INTERRUPT]); + ahcd->ed_tails[PIPE_INTERRUPT] = NULL; + } + + if (ahcd->ed_tails[PIPE_ISOCHRONOUS]) { + ed_free(ahcd, ahcd->ed_tails[PIPE_ISOCHRONOUS]); + ahcd->ed_tails[PIPE_ISOCHRONOUS] = NULL; + } + + if (ahcd->ed_tails[PIPE_CONTROL]) { + ed_free(ahcd, ahcd->ed_tails[PIPE_CONTROL]); + ahcd->ed_tails[PIPE_CONTROL] = NULL; + } + + if (ahcd->ed_tails[PIPE_BULK]) { + ed_free(ahcd, ahcd->ed_tails[PIPE_BULK]); + ahcd->ed_tails[PIPE_BULK] = NULL; + } + + ahcd->ed_head = NULL; +} + +#define ED_DUMMY_INFO (ED_SPEED_FULL | ED_SKIP) + +static int admhc_eds_init(struct admhcd *ahcd) +{ + struct ed *ed; + + ed = ed_create(ahcd, PIPE_INTERRUPT, ED_DUMMY_INFO); + if (!ed) + goto err; + + ahcd->ed_tails[PIPE_INTERRUPT] = ed; + + ed = ed_create(ahcd, PIPE_ISOCHRONOUS, ED_DUMMY_INFO); + if (!ed) + goto err; + + ahcd->ed_tails[PIPE_ISOCHRONOUS] = ed; + ed->ed_prev = ahcd->ed_tails[PIPE_INTERRUPT]; + ahcd->ed_tails[PIPE_INTERRUPT]->ed_next = ed; + ahcd->ed_tails[PIPE_INTERRUPT]->hwNextED = cpu_to_hc32(ahcd, ed->dma); + + ed = ed_create(ahcd, PIPE_CONTROL, ED_DUMMY_INFO); + if (!ed) + goto err; + + ahcd->ed_tails[PIPE_CONTROL] = ed; + ed->ed_prev = ahcd->ed_tails[PIPE_ISOCHRONOUS]; + ahcd->ed_tails[PIPE_ISOCHRONOUS]->ed_next = ed; + ahcd->ed_tails[PIPE_ISOCHRONOUS]->hwNextED = cpu_to_hc32(ahcd, ed->dma); + + ed = ed_create(ahcd, PIPE_BULK, ED_DUMMY_INFO); + if (!ed) + goto err; + + ahcd->ed_tails[PIPE_BULK] = ed; + ed->ed_prev = ahcd->ed_tails[PIPE_CONTROL]; + ahcd->ed_tails[PIPE_CONTROL]->ed_next = ed; + ahcd->ed_tails[PIPE_CONTROL]->hwNextED = cpu_to_hc32(ahcd, ed->dma); + + ahcd->ed_head = ahcd->ed_tails[PIPE_INTERRUPT]; + +#ifdef ADMHC_VERBOSE_DEBUG + admhc_dump_ed(ahcd, "ed intr", ahcd->ed_tails[PIPE_INTERRUPT], 1); + admhc_dump_ed(ahcd, "ed isoc", ahcd->ed_tails[PIPE_ISOCHRONOUS], 1); + admhc_dump_ed(ahcd, "ed ctrl", ahcd->ed_tails[PIPE_CONTROL], 1); + admhc_dump_ed(ahcd, "ed bulk", ahcd->ed_tails[PIPE_BULK], 1); +#endif + + return 0; + +err: + admhc_eds_cleanup(ahcd); + return -ENOMEM; +} + +/* init memory, and kick BIOS/SMM off */ + +static int admhc_init(struct admhcd *ahcd) +{ + struct usb_hcd *hcd = admhcd_to_hcd(ahcd); + int ret; + + admhc_disable(ahcd); + ahcd->regs = hcd->regs; + + /* Disable HC interrupts */ + admhc_intr_disable(ahcd, ADMHC_INTR_MIE); + + /* Read the number of ports unless overridden */ + if (ahcd->num_ports == 0) + ahcd->num_ports = admhc_read_rhdesc(ahcd) & ADMHC_RH_NUMP; + + ret = admhc_mem_init(ahcd); + if (ret) + goto err; + + /* init dummy endpoints */ + ret = admhc_eds_init(ahcd); + if (ret) + goto err; + + create_debug_files(ahcd); + + return 0; + +err: + admhc_stop(hcd); + return ret; +} + +/*-------------------------------------------------------------------------*/ + +/* Start an OHCI controller, set the BUS operational + * resets USB and controller + * enable interrupts + */ +static int admhc_run(struct admhcd *ahcd) +{ + u32 val; + int first = ahcd->fminterval == 0; + struct usb_hcd *hcd = admhcd_to_hcd(ahcd); + + admhc_disable(ahcd); + + /* boot firmware should have set this up (5.1.1.3.1) */ + if (first) { + val = admhc_readl(ahcd, &ahcd->regs->fminterval); + ahcd->fminterval = val & ADMHC_SFI_FI_MASK; + if (ahcd->fminterval != FI) + admhc_dbg(ahcd, "fminterval delta %d\n", + ahcd->fminterval - FI); + ahcd->fminterval |= + (FSLDP(ahcd->fminterval) << ADMHC_SFI_FSLDP_SHIFT); + /* also: power/overcurrent flags in rhdesc */ + } + +#if 0 /* TODO: not applicable */ + /* Reset USB nearly "by the book". RemoteWakeupConnected has + * to be checked in case boot firmware (BIOS/SMM/...) has set up + * wakeup in a way the bus isn't aware of (e.g., legacy PCI PM). + * If the bus glue detected wakeup capability then it should + * already be enabled; if so we'll just enable it again. + */ + if ((ahcd->hc_control & OHCI_CTRL_RWC) != 0) + device_set_wakeup_capable(hcd->self.controller, 1); +#endif + + switch (ahcd->host_control & ADMHC_HC_BUSS) { + case ADMHC_BUSS_OPER: + val = 0; + break; + case ADMHC_BUSS_SUSPEND: + /* FALLTHROUGH ? */ + case ADMHC_BUSS_RESUME: + ahcd->host_control = ADMHC_BUSS_RESUME; + val = 10 /* msec wait */; + break; + /* case ADMHC_BUSS_RESET: */ + default: + ahcd->host_control = ADMHC_BUSS_RESET; + val = 50 /* msec wait */; + break; + } + admhc_writel(ahcd, ahcd->host_control, &ahcd->regs->host_control); + + /* flush the writes */ + admhc_writel_flush(ahcd); + + msleep(val); + val = admhc_read_rhdesc(ahcd); + if (!(val & ADMHC_RH_NPS)) { + /* power down each port */ + for (val = 0; val < ahcd->num_ports; val++) + admhc_write_portstatus(ahcd, val, ADMHC_PS_CPP); + } + /* flush those writes */ + admhc_writel_flush(ahcd); + + /* 2msec timelimit here means no irqs/preempt */ + spin_lock_irq(&ahcd->lock); + + admhc_writel(ahcd, ADMHC_CTRL_SR, &ahcd->regs->gencontrol); + val = 30; /* ... allow extra time */ + while ((admhc_readl(ahcd, &ahcd->regs->gencontrol) & ADMHC_CTRL_SR) != 0) { + if (--val == 0) { + spin_unlock_irq(&ahcd->lock); + admhc_err(ahcd, "USB HC reset timed out!\n"); + return -1; + } + udelay(1); + } + + /* enable HOST mode, before access any host specific register */ + admhc_writel(ahcd, ADMHC_CTRL_UHFE, &ahcd->regs->gencontrol); + + /* Tell the controller where the descriptor list is */ + admhc_writel(ahcd, (u32)ahcd->ed_head->dma, &ahcd->regs->hosthead); + + periodic_reinit(ahcd); + + /* use rhsc irqs after khubd is fully initialized */ + set_bit(HCD_FLAG_POLL_RH, &hcd->flags); + hcd->uses_new_polling = 1; + +#if 0 + /* wake on ConnectStatusChange, matching external hubs */ + admhc_writel(ahcd, RH_HS_DRWE, &ahcd->regs->roothub.status); +#else + /* FIXME roothub_write_status (ahcd, ADMHC_RH_DRWE); */ +#endif + + /* Choose the interrupts we care about now, others later on demand */ + admhc_intr_ack(ahcd, ~0); + admhc_intr_enable(ahcd, ADMHC_INTR_INIT); + + admhc_writel(ahcd, ADMHC_RH_NPS | ADMHC_RH_LPSC, &ahcd->regs->rhdesc); + + /* flush those writes */ + admhc_writel_flush(ahcd); + + /* start controller operations */ + ahcd->host_control = ADMHC_BUSS_OPER; + admhc_writel(ahcd, ahcd->host_control, &ahcd->regs->host_control); + + val = 20; + while ((admhc_readl(ahcd, &ahcd->regs->host_control) + & ADMHC_HC_BUSS) != ADMHC_BUSS_OPER) { + if (--val == 0) { + spin_unlock_irq(&ahcd->lock); + admhc_err(ahcd, "unable to setup operational mode!\n"); + return -1; + } + mdelay(1); + } + + hcd->state = HC_STATE_RUNNING; + + ahcd->next_statechange = jiffies + STATECHANGE_DELAY; + +#if 0 + /* FIXME: enabling DMA is always failed here for an unknown reason */ + admhc_dma_enable(ahcd); + + val = 200; + while ((admhc_readl(ahcd, &ahcd->regs->host_control) + & ADMHC_HC_DMAE) != ADMHC_HC_DMAE) { + if (--val == 0) { + spin_unlock_irq(&ahcd->lock); + admhc_err(ahcd, "unable to enable DMA!\n"); + admhc_dump(ahcd, 1); + return -1; + } + mdelay(1); + } + +#endif + + spin_unlock_irq(&ahcd->lock); + + mdelay(ADMHC_POTPGT); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* an interrupt happens */ + +static irqreturn_t admhc_irq(struct usb_hcd *hcd) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + struct admhcd_regs __iomem *regs = ahcd->regs; + u32 ints; + + ints = admhc_readl(ahcd, ®s->int_status); + if ((ints & ADMHC_INTR_INTA) == 0) { + /* no unmasked interrupt status is set */ + return IRQ_NONE; + } + + ints &= admhc_readl(ahcd, ®s->int_enable); + + if (ints & ADMHC_INTR_FATI) { + /* e.g. due to PCI Master/Target Abort */ + admhc_disable(ahcd); + admhc_err(ahcd, "Fatal Error, controller disabled\n"); + admhc_dump(ahcd, 1); + admhc_usb_reset(ahcd); + } + + if (ints & ADMHC_INTR_BABI) { + admhc_intr_disable(ahcd, ADMHC_INTR_BABI); + admhc_intr_ack(ahcd, ADMHC_INTR_BABI); + admhc_err(ahcd, "Babble Detected\n"); + } + + if (ints & ADMHC_INTR_INSM) { + admhc_vdbg(ahcd, "Root Hub Status Change\n"); + ahcd->next_statechange = jiffies + STATECHANGE_DELAY; + admhc_intr_ack(ahcd, ADMHC_INTR_RESI | ADMHC_INTR_INSM); + + /* NOTE: Vendors didn't always make the same implementation + * choices for RHSC. Many followed the spec; RHSC triggers + * on an edge, like setting and maybe clearing a port status + * change bit. With others it's level-triggered, active + * until khubd clears all the port status change bits. We'll + * always disable it here and rely on polling until khubd + * re-enables it. + */ + admhc_intr_disable(ahcd, ADMHC_INTR_INSM); + usb_hcd_poll_rh_status(hcd); + } else if (ints & ADMHC_INTR_RESI) { + /* For connect and disconnect events, we expect the controller + * to turn on RHSC along with RD. But for remote wakeup events + * this might not happen. + */ + admhc_vdbg(ahcd, "Resume Detect\n"); + admhc_intr_ack(ahcd, ADMHC_INTR_RESI); + set_bit(HCD_FLAG_POLL_RH, &hcd->flags); + if (ahcd->autostop) { + spin_lock(&ahcd->lock); + admhc_rh_resume(ahcd); + spin_unlock(&ahcd->lock); + } else + usb_hcd_resume_root_hub(hcd); + } + + if (ints & ADMHC_INTR_TDC) { + admhc_vdbg(ahcd, "Transfer Descriptor Complete\n"); + admhc_intr_ack(ahcd, ADMHC_INTR_TDC); + if (HC_IS_RUNNING(hcd->state)) + admhc_intr_disable(ahcd, ADMHC_INTR_TDC); + spin_lock(&ahcd->lock); + admhc_td_complete(ahcd); + spin_unlock(&ahcd->lock); + if (HC_IS_RUNNING(hcd->state)) + admhc_intr_enable(ahcd, ADMHC_INTR_TDC); + } + + if (ints & ADMHC_INTR_SO) { + /* could track INTR_SO to reduce available PCI/... bandwidth */ + admhc_vdbg(ahcd, "Schedule Overrun\n"); + } + +#if 1 + spin_lock(&ahcd->lock); + if (ahcd->ed_rm_list) + finish_unlinks(ahcd, admhc_frame_no(ahcd)); + + if ((ints & ADMHC_INTR_SOFI) != 0 && !ahcd->ed_rm_list + && HC_IS_RUNNING(hcd->state)) + admhc_intr_disable(ahcd, ADMHC_INTR_SOFI); + spin_unlock(&ahcd->lock); +#else + if (ints & ADMHC_INTR_SOFI) { + admhc_vdbg(ahcd, "Start Of Frame\n"); + spin_lock(&ahcd->lock); + + /* handle any pending ED removes */ + finish_unlinks(ahcd, admhc_frameno(ahcd)); + + /* leaving INTR_SOFI enabled when there's still unlinking + * to be done in the (next frame). + */ + if ((ahcd->ed_rm_list == NULL) || + HC_IS_RUNNING(hcd->state) == 0) + /* + * disable INTR_SOFI if there are no unlinking to be + * done (in the next frame) + */ + admhc_intr_disable(ahcd, ADMHC_INTR_SOFI); + + spin_unlock(&ahcd->lock); + } +#endif + + if (HC_IS_RUNNING(hcd->state)) { + admhc_intr_ack(ahcd, ints); + admhc_intr_enable(ahcd, ADMHC_INTR_MIE); + admhc_writel_flush(ahcd); + } + + return IRQ_HANDLED; +} + +/*-------------------------------------------------------------------------*/ + +static void admhc_stop(struct usb_hcd *hcd) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + + admhc_dump(ahcd, 1); + + flush_scheduled_work(); + + admhc_usb_reset(ahcd); + admhc_intr_disable(ahcd, ADMHC_INTR_MIE); + + free_irq(hcd->irq, hcd); + hcd->irq = -1; + + remove_debug_files(ahcd); + admhc_eds_cleanup(ahcd); + admhc_mem_cleanup(ahcd); +} + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_ADM5120 +#include "adm5120-drv.c" +#define PLATFORM_DRIVER usb_hcd_adm5120_driver +#endif + +#if !defined(PLATFORM_DRIVER) +#error "missing bus glue for admhc-hcd" +#endif + +#define DRIVER_INFO DRIVER_DESC " version " DRIVER_VERSION + +static int __init admhc_hcd_mod_init(void) +{ + int ret = 0; + + if (usb_disabled()) + return -ENODEV; + + pr_info("%s: " DRIVER_INFO "\n", hcd_name); + pr_info("%s: block sizes: ed %Zd td %Zd\n", hcd_name, + sizeof(struct ed), sizeof(struct td)); + set_bit(USB_OHCI_LOADED, &usb_hcds_loaded); + +#ifdef DEBUG + admhc_debug_root = debugfs_create_dir("admhc", usb_debug_root); + if (!admhc_debug_root) { + ret = -ENOENT; + goto error_debug; + } +#endif + +#ifdef PLATFORM_DRIVER + ret = platform_driver_register(&PLATFORM_DRIVER); + if (ret < 0) + goto error_platform; +#endif + + return ret; + +#ifdef PLATFORM_DRIVER + platform_driver_unregister(&PLATFORM_DRIVER); +error_platform: +#endif + +#ifdef DEBUG + debugfs_remove(admhc_debug_root); + admhc_debug_root = NULL; +error_debug: +#endif + clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded); + return ret; +} +module_init(admhc_hcd_mod_init); + +static void __exit admhc_hcd_mod_exit(void) +{ + platform_driver_unregister(&PLATFORM_DRIVER); +#ifdef DEBUG + debugfs_remove(admhc_debug_root); +#endif + clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded); +} +module_exit(admhc_hcd_mod_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_INFO); +MODULE_VERSION(DRIVER_VERSION); +MODULE_LICENSE("GPL v2"); diff --git a/target/linux/adm5120/files/drivers/usb/host/adm5120-hub.c b/target/linux/adm5120/files/drivers/usb/host/adm5120-hub.c new file mode 100644 index 000000000..8cabaf902 --- /dev/null +++ b/target/linux/adm5120/files/drivers/usb/host/adm5120-hub.c @@ -0,0 +1,430 @@ +/* + * ADM5120 HCD (Host Controller Driver) for USB + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This file was derived from: drivers/usb/host/ohci-hub.c + * (C) Copyright 1999 Roman Weissgaerber + * (C) Copyright 2000-2004 David Brownell + * + * This program 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. + * + */ + +/*-------------------------------------------------------------------------*/ + +/* + * ADM5120 Root Hub ... the nonsharable stuff + */ + +#define dbg_port(hc, label, num, value) \ + admhc_dbg(hc, \ + "%s port%d " \ + "= 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s\n", \ + label, num, value, \ + (value & ADMHC_PS_PRSC) ? " PRSC" : "", \ + (value & ADMHC_PS_OCIC) ? " OCIC" : "", \ + (value & ADMHC_PS_PSSC) ? " PSSC" : "", \ + (value & ADMHC_PS_PESC) ? " PESC" : "", \ + (value & ADMHC_PS_CSC) ? " CSC" : "", \ + \ + (value & ADMHC_PS_LSDA) ? " LSDA" : "", \ + (value & ADMHC_PS_PPS) ? " PPS" : "", \ + (value & ADMHC_PS_PRS) ? " PRS" : "", \ + (value & ADMHC_PS_POCI) ? " POCI" : "", \ + (value & ADMHC_PS_PSS) ? " PSS" : "", \ + \ + (value & ADMHC_PS_PES) ? " PES" : "", \ + (value & ADMHC_PS_CCS) ? " CCS" : "" \ + ); + +#define dbg_port_write(hc, label, num, value) \ + admhc_dbg(hc, \ + "%s port%d " \ + "= 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s\n", \ + label, num, value, \ + (value & ADMHC_PS_PRSC) ? " PRSC" : "", \ + (value & ADMHC_PS_OCIC) ? " OCIC" : "", \ + (value & ADMHC_PS_PSSC) ? " PSSC" : "", \ + (value & ADMHC_PS_PESC) ? " PESC" : "", \ + (value & ADMHC_PS_CSC) ? " CSC" : "", \ + \ + (value & ADMHC_PS_CPP) ? " CPP" : "", \ + (value & ADMHC_PS_SPP) ? " SPP" : "", \ + (value & ADMHC_PS_SPR) ? " SPR" : "", \ + (value & ADMHC_PS_CPS) ? " CPS" : "", \ + (value & ADMHC_PS_SPS) ? " SPS" : "", \ + \ + (value & ADMHC_PS_SPE) ? " SPE" : "", \ + (value & ADMHC_PS_CPE) ? " CPE" : "" \ + ); + +/*-------------------------------------------------------------------------*/ + +/* build "status change" packet (one or two bytes) from HC registers */ + +static int +admhc_hub_status_data(struct usb_hcd *hcd, char *buf) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + int i, changed = 0, length = 1; + int any_connected = 0; + unsigned long flags; + u32 status; + + spin_lock_irqsave(&ahcd->lock, flags); + if (!HCD_HW_ACCESSIBLE(hcd)) + goto done; + + /* init status */ + status = admhc_read_rhdesc(ahcd); + if (status & (ADMHC_RH_LPSC | ADMHC_RH_OCIC)) + buf[0] = changed = 1; + else + buf[0] = 0; + if (ahcd->num_ports > 7) { + buf[1] = 0; + length++; + } + + /* look at each port */ + for (i = 0; i < ahcd->num_ports; i++) { + status = admhc_read_portstatus(ahcd, i); + + /* can't autostop if ports are connected */ + any_connected |= (status & ADMHC_PS_CCS); + + if (status & (ADMHC_PS_CSC | ADMHC_PS_PESC | ADMHC_PS_PSSC + | ADMHC_PS_OCIC | ADMHC_PS_PRSC)) { + changed = 1; + if (i < 7) + buf[0] |= 1 << (i + 1); + else + buf[1] |= 1 << (i - 7); + } + } + + if (admhc_root_hub_state_changes(ahcd, changed, + any_connected)) + set_bit(HCD_FLAG_POLL_RH, &hcd->flags); + else + clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); + +done: + spin_unlock_irqrestore(&ahcd->lock, flags); + + return changed ? length : 0; +} + +/*-------------------------------------------------------------------------*/ + +static int admhc_get_hub_descriptor(struct admhcd *ahcd, char *buf) +{ + struct usb_hub_descriptor *desc = (struct usb_hub_descriptor *)buf; + u32 rh = admhc_read_rhdesc(ahcd); + u16 temp; + + desc->bDescriptorType = USB_DT_HUB; /* Hub-descriptor */ + desc->bPwrOn2PwrGood = ADMHC_POTPGT/2; /* use default value */ + desc->bHubContrCurrent = 0x00; /* 0mA */ + + desc->bNbrPorts = ahcd->num_ports; + temp = 1 + (ahcd->num_ports / 8); + desc->bDescLength = USB_DT_HUB_NONVAR_SIZE + 2 * temp; + + /* FIXME */ + temp = 0; + if (rh & ADMHC_RH_NPS) /* no power switching? */ + temp |= 0x0002; + if (rh & ADMHC_RH_PSM) /* per-port power switching? */ + temp |= 0x0001; + if (rh & ADMHC_RH_NOCP) /* no overcurrent reporting? */ + temp |= 0x0010; + else if (rh & ADMHC_RH_OCPM) /* per-port overcurrent reporting? */ + temp |= 0x0008; + desc->wHubCharacteristics = (__force __u16)cpu_to_hc16(ahcd, temp); + + /* ports removable, and usb 1.0 legacy PortPwrCtrlMask */ + desc->u.hs.DeviceRemovable[0] = 0; + desc->u.hs.DeviceRemovable[0] = ~0; + + return 0; +} + +static int admhc_get_hub_status(struct admhcd *ahcd, char *buf) +{ + struct usb_hub_status *hs = (struct usb_hub_status *)buf; + u32 t = admhc_read_rhdesc(ahcd); + u16 status, change; + + status = 0; + status |= (t & ADMHC_RH_LPS) ? HUB_STATUS_LOCAL_POWER : 0; + status |= (t & ADMHC_RH_OCI) ? HUB_STATUS_OVERCURRENT : 0; + + change = 0; + change |= (t & ADMHC_RH_LPSC) ? HUB_CHANGE_LOCAL_POWER : 0; + change |= (t & ADMHC_RH_OCIC) ? HUB_CHANGE_OVERCURRENT : 0; + + hs->wHubStatus = (__force __u16)cpu_to_hc16(ahcd, status); + hs->wHubChange = (__force __u16)cpu_to_hc16(ahcd, change); + + return 0; +} + +static int admhc_get_port_status(struct admhcd *ahcd, unsigned port, char *buf) +{ + struct usb_port_status *ps = (struct usb_port_status *)buf; + u32 t = admhc_read_portstatus(ahcd, port); + u16 status, change; + + status = 0; + status |= (t & ADMHC_PS_CCS) ? USB_PORT_STAT_CONNECTION : 0; + status |= (t & ADMHC_PS_PES) ? USB_PORT_STAT_ENABLE : 0; + status |= (t & ADMHC_PS_PSS) ? USB_PORT_STAT_SUSPEND : 0; + status |= (t & ADMHC_PS_POCI) ? USB_PORT_STAT_OVERCURRENT : 0; + status |= (t & ADMHC_PS_PRS) ? USB_PORT_STAT_RESET : 0; + status |= (t & ADMHC_PS_PPS) ? USB_PORT_STAT_POWER : 0; + status |= (t & ADMHC_PS_LSDA) ? USB_PORT_STAT_LOW_SPEED : 0; + + change = 0; + change |= (t & ADMHC_PS_CSC) ? USB_PORT_STAT_C_CONNECTION : 0; + change |= (t & ADMHC_PS_PESC) ? USB_PORT_STAT_C_ENABLE : 0; + change |= (t & ADMHC_PS_PSSC) ? USB_PORT_STAT_C_SUSPEND : 0; + change |= (t & ADMHC_PS_OCIC) ? USB_PORT_STAT_C_OVERCURRENT : 0; + change |= (t & ADMHC_PS_PRSC) ? USB_PORT_STAT_C_RESET : 0; + + ps->wPortStatus = (__force __u16)cpu_to_hc16(ahcd, status); + ps->wPortChange = (__force __u16)cpu_to_hc16(ahcd, change); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_USB_OTG + +static int admhc_start_port_reset(struct usb_hcd *hcd, unsigned port) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + u32 status; + + if (!port) + return -EINVAL; + port--; + + /* start port reset before HNP protocol times out */ + status = admhc_read_portstatus(ahcd, port); + if (!(status & ADMHC_PS_CCS)) + return -ENODEV; + + /* khubd will finish the reset later */ + admhc_write_portstatus(ahcd, port, ADMHC_PS_PRS); + return 0; +} + +static void start_hnp(struct admhcd *ahcd); + +#else + +#define admhc_start_port_reset NULL + +#endif + +/*-------------------------------------------------------------------------*/ + + +/* See usb 7.1.7.5: root hubs must issue at least 50 msec reset signaling, + * not necessarily continuous ... to guard against resume signaling. + * The short timeout is safe for non-root hubs, and is backward-compatible + * with earlier Linux hosts. + */ +#ifdef CONFIG_USB_SUSPEND +#define PORT_RESET_MSEC 50 +#else +#define PORT_RESET_MSEC 10 +#endif + +/* this timer value might be vendor-specific ... */ +#define PORT_RESET_HW_MSEC 10 + +/* wrap-aware logic morphed from */ +#define tick_before(t1, t2) ((s16)(((s16)(t1)) - ((s16)(t2))) < 0) + +/* called from some task, normally khubd */ +static inline int admhc_port_reset(struct admhcd *ahcd, unsigned port) +{ + u32 t; + + admhc_vdbg(ahcd, "reset port%d\n", port); + t = admhc_read_portstatus(ahcd, port); + if (!(t & ADMHC_PS_CCS)) + return -ENODEV; + + admhc_write_portstatus(ahcd, port, ADMHC_PS_SPR); + mdelay(10); + admhc_write_portstatus(ahcd, port, (ADMHC_PS_SPE | ADMHC_PS_CSC)); + mdelay(100); + + return 0; +} + +static inline int admhc_port_enable(struct admhcd *ahcd, unsigned port) +{ + u32 t; + + admhc_vdbg(ahcd, "enable port%d\n", port); + t = admhc_read_portstatus(ahcd, port); + if (!(t & ADMHC_PS_CCS)) + return -ENODEV; + + admhc_write_portstatus(ahcd, port, ADMHC_PS_SPE); + + return 0; +} + +static inline int admhc_port_disable(struct admhcd *ahcd, unsigned port) +{ + u32 t; + + admhc_vdbg(ahcd, "disable port%d\n", port); + t = admhc_read_portstatus(ahcd, port); + if (!(t & ADMHC_PS_CCS)) + return -ENODEV; + + admhc_write_portstatus(ahcd, port, ADMHC_PS_CPE); + + return 0; +} + +static inline int admhc_port_write(struct admhcd *ahcd, unsigned port, + u32 val) +{ +#ifdef ADMHC_VERBOSE_DEBUG + dbg_port_write(ahcd, "write", port, val); +#endif + admhc_write_portstatus(ahcd, port, val); + + return 0; +} + +static int admhc_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, + u16 wIndex, char *buf, u16 wLength) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + int ports = ahcd->num_ports; + int ret = 0; + + if (unlikely(!HCD_HW_ACCESSIBLE(hcd))) + return -ESHUTDOWN; + + switch (typeReq) { + case ClearHubFeature: + switch (wValue) { + case C_HUB_OVER_CURRENT: +#if 0 /* FIXME */ + admhc_writel(ahcd, ADMHC_RH_OCIC, + &ahcd->regs->roothub.status); +#endif + case C_HUB_LOCAL_POWER: + break; + default: + goto error; + } + break; + case ClearPortFeature: + if (!wIndex || wIndex > ports) + goto error; + wIndex--; + + switch (wValue) { + case USB_PORT_FEAT_ENABLE: + ret = admhc_port_disable(ahcd, wIndex); + break; + case USB_PORT_FEAT_SUSPEND: + ret = admhc_port_write(ahcd, wIndex, ADMHC_PS_CPS); + break; + case USB_PORT_FEAT_POWER: + ret = admhc_port_write(ahcd, wIndex, ADMHC_PS_CPP); + break; + case USB_PORT_FEAT_C_CONNECTION: + ret = admhc_port_write(ahcd, wIndex, ADMHC_PS_CSC); + break; + case USB_PORT_FEAT_C_ENABLE: + ret = admhc_port_write(ahcd, wIndex, ADMHC_PS_PESC); + break; + case USB_PORT_FEAT_C_SUSPEND: + ret = admhc_port_write(ahcd, wIndex, ADMHC_PS_PSSC); + break; + case USB_PORT_FEAT_C_OVER_CURRENT: + ret = admhc_port_write(ahcd, wIndex, ADMHC_PS_OCIC); + break; + case USB_PORT_FEAT_C_RESET: + ret = admhc_port_write(ahcd, wIndex, ADMHC_PS_PRSC); + break; + default: + goto error; + } + break; + case GetHubDescriptor: + ret = admhc_get_hub_descriptor(ahcd, buf); + break; + case GetHubStatus: + ret = admhc_get_hub_status(ahcd, buf); + break; + case GetPortStatus: + if (!wIndex || wIndex > ports) + goto error; + wIndex--; + + ret = admhc_get_port_status(ahcd, wIndex, buf); + break; + case SetHubFeature: + switch (wValue) { + case C_HUB_OVER_CURRENT: + /* FIXME: this can be cleared, yes? */ + case C_HUB_LOCAL_POWER: + break; + default: + goto error; + } + break; + case SetPortFeature: + if (!wIndex || wIndex > ports) + goto error; + wIndex--; + + switch (wValue) { + case USB_PORT_FEAT_ENABLE: + ret = admhc_port_enable(ahcd, wIndex); + break; + case USB_PORT_FEAT_RESET: + ret = admhc_port_reset(ahcd, wIndex); + break; + case USB_PORT_FEAT_SUSPEND: +#ifdef CONFIG_USB_OTG + if (hcd->self.otg_port == (wIndex + 1) + && hcd->self.b_hnp_enable) + start_hnp(ahcd); + else +#endif + ret = admhc_port_write(ahcd, wIndex, ADMHC_PS_SPS); + break; + case USB_PORT_FEAT_POWER: + ret = admhc_port_write(ahcd, wIndex, ADMHC_PS_SPP); + break; + default: + goto error; + } + break; + + default: +error: + /* "protocol stall" on error */ + ret = -EPIPE; + } + + return ret; +} + diff --git a/target/linux/adm5120/files/drivers/usb/host/adm5120-mem.c b/target/linux/adm5120/files/drivers/usb/host/adm5120-mem.c new file mode 100644 index 000000000..79fff70e2 --- /dev/null +++ b/target/linux/adm5120/files/drivers/usb/host/adm5120-mem.c @@ -0,0 +1,202 @@ +/* + * ADM5120 HCD (Host Controller Driver) for USB + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This file was derived from: drivers/usb/host/ohci-mem.c + * (C) Copyright 1999 Roman Weissgaerber + * (C) Copyright 2000-2002 David Brownell + * + * This program 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. + * + */ + +/*-------------------------------------------------------------------------*/ + +/* + * OHCI deals with three types of memory: + * - data used only by the HCD ... kmalloc is fine + * - async and periodic schedules, shared by HC and HCD ... these + * need to use dma_pool or dma_alloc_coherent + * - driver buffers, read/written by HC ... the hcd glue or the + * device driver provides us with dma addresses + * + * There's also "register" data, which is memory mapped. + * No memory seen by this driver (or any HCD) may be paged out. + */ + +/*-------------------------------------------------------------------------*/ + +static void admhc_hcd_init(struct admhcd *ahcd) +{ + ahcd->next_statechange = jiffies; + spin_lock_init(&ahcd->lock); + INIT_LIST_HEAD(&ahcd->pending); +} + +/*-------------------------------------------------------------------------*/ + +static int admhc_mem_init(struct admhcd *ahcd) +{ + ahcd->td_cache = dma_pool_create("admhc_td", + admhcd_to_hcd(ahcd)->self.controller, + sizeof(struct td), + TD_ALIGN, /* byte alignment */ + 0 /* no page-crossing issues */ + ); + if (!ahcd->td_cache) + goto err; + + ahcd->ed_cache = dma_pool_create("admhc_ed", + admhcd_to_hcd(ahcd)->self.controller, + sizeof(struct ed), + ED_ALIGN, /* byte alignment */ + 0 /* no page-crossing issues */ + ); + if (!ahcd->ed_cache) + goto err_td_cache; + + return 0; + +err_td_cache: + dma_pool_destroy(ahcd->td_cache); + ahcd->td_cache = NULL; +err: + return -ENOMEM; +} + +static void admhc_mem_cleanup(struct admhcd *ahcd) +{ + if (ahcd->td_cache) { + dma_pool_destroy(ahcd->td_cache); + ahcd->td_cache = NULL; + } + + if (ahcd->ed_cache) { + dma_pool_destroy(ahcd->ed_cache); + ahcd->ed_cache = NULL; + } +} + +/*-------------------------------------------------------------------------*/ + +/* ahcd "done list" processing needs this mapping */ +static inline struct td *dma_to_td(struct admhcd *ahcd, dma_addr_t td_dma) +{ + struct td *td; + + td_dma &= TD_MASK; + td = ahcd->td_hash[TD_HASH_FUNC(td_dma)]; + while (td && td->td_dma != td_dma) + td = td->td_hash; + + return td; +} + +/* TDs ... */ +static struct td *td_alloc(struct admhcd *ahcd, gfp_t mem_flags) +{ + dma_addr_t dma; + struct td *td; + + td = dma_pool_alloc(ahcd->td_cache, mem_flags, &dma); + if (!td) + return NULL; + + /* in case ahcd fetches it, make it look dead */ + memset(td, 0, sizeof *td); + td->hwNextTD = cpu_to_hc32(ahcd, dma); + td->td_dma = dma; + /* hashed in td_fill */ + + return td; +} + +static void td_free(struct admhcd *ahcd, struct td *td) +{ + struct td **prev = &ahcd->td_hash[TD_HASH_FUNC(td->td_dma)]; + + while (*prev && *prev != td) + prev = &(*prev)->td_hash; + if (*prev) + *prev = td->td_hash; +#if 0 + /* TODO: remove */ + else if ((td->hwINFO & cpu_to_hc32(ahcd, TD_DONE)) != 0) + admhc_dbg(ahcd, "no hash for td %p\n", td); +#else + else if ((td->flags & TD_FLAG_DONE) != 0) + admhc_dbg(ahcd, "no hash for td %p\n", td); +#endif + dma_pool_free(ahcd->td_cache, td, td->td_dma); +} + +/*-------------------------------------------------------------------------*/ + +/* EDs ... */ +static struct ed *ed_alloc(struct admhcd *ahcd, gfp_t mem_flags) +{ + dma_addr_t dma; + struct ed *ed; + + ed = dma_pool_alloc(ahcd->ed_cache, mem_flags, &dma); + if (!ed) + return NULL; + + memset(ed, 0, sizeof(*ed)); + ed->dma = dma; + + INIT_LIST_HEAD(&ed->td_list); + INIT_LIST_HEAD(&ed->urb_list); + + return ed; +} + +static void ed_free(struct admhcd *ahcd, struct ed *ed) +{ + dma_pool_free(ahcd->ed_cache, ed, ed->dma); +} + +/*-------------------------------------------------------------------------*/ + +/* URB priv ... */ +static void urb_priv_free(struct admhcd *ahcd, struct urb_priv *urb_priv) +{ + int i; + + for (i = 0; i < urb_priv->td_cnt; i++) + if (urb_priv->td[i]) + td_free(ahcd, urb_priv->td[i]); + + list_del(&urb_priv->pending); + kfree(urb_priv); +} + +static struct urb_priv *urb_priv_alloc(struct admhcd *ahcd, int num_tds, + gfp_t mem_flags) +{ + struct urb_priv *priv; + + /* allocate the private part of the URB */ + priv = kzalloc(sizeof(*priv) + sizeof(struct td) * num_tds, mem_flags); + if (!priv) + goto err; + + /* allocate the TDs (deferring hash chain updates) */ + for (priv->td_cnt = 0; priv->td_cnt < num_tds; priv->td_cnt++) { + priv->td[priv->td_cnt] = td_alloc(ahcd, mem_flags); + if (priv->td[priv->td_cnt] == NULL) + goto err_free; + } + + INIT_LIST_HEAD(&priv->pending); + + return priv; + +err_free: + urb_priv_free(ahcd, priv); +err: + return NULL; +} diff --git a/target/linux/adm5120/files/drivers/usb/host/adm5120-pm.c b/target/linux/adm5120/files/drivers/usb/host/adm5120-pm.c new file mode 100644 index 000000000..7d7fc2438 --- /dev/null +++ b/target/linux/adm5120/files/drivers/usb/host/adm5120-pm.c @@ -0,0 +1,449 @@ +/* + * ADM5120 HCD (Host Controller Driver) for USB + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This file was derived from fragments of the OHCI driver. + * (C) Copyright 1999 Roman Weissgaerber + * (C) Copyright 2000-2004 David Brownell + * + * This program 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 OHCI_SCHED_ENABLES \ + (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) + +#ifdef CONFIG_PM +static int admhc_restart(struct admhcd *ahcd); + +static int admhc_rh_suspend(struct admhcd *ahcd, int autostop) +__releases(ahcd->lock) +__acquires(ahcd->lock) +{ + int status = 0; + + ahcd->hc_control = admhc_readl(ahcd, &ahcd->regs->control); + switch (ahcd->hc_control & OHCI_CTRL_HCFS) { + case OHCI_USB_RESUME: + admhc_dbg(ahcd, "resume/suspend?\n"); + ahcd->hc_control &= ~OHCI_CTRL_HCFS; + ahcd->hc_control |= OHCI_USB_RESET; + admhc_writel(ahcd, ahcd->hc_control, &ahcd->ahcd->regs->control); + (void) admhc_readl(ahcd, &ahcd->regs->control); + /* FALL THROUGH */ + case OHCI_USB_RESET: + status = -EBUSY; + admhc_dbg(ahcd, "needs reinit!\n"); + goto done; + case OHCI_USB_SUSPEND: + if (!ahcd->autostop) { + admhc_dbg(ahcd, "already suspended\n"); + goto done; + } + } + admhc_dbg(ahcd, "%s root hub\n", + autostop ? "auto-stop" : "suspend"); + + /* First stop any processing */ + if (!autostop && (ahcd->hc_control & OHCI_SCHED_ENABLES)) { + ahcd->hc_control &= ~OHCI_SCHED_ENABLES; + admhc_writel(ahcd, ahcd->hc_control, &ahcd->ahcd->regs->control); + ahcd->hc_control = admhc_readl(ahcd, &ahcd->regs->control); + admhc_writel(ahcd, OHCI_INTR_SF, &ahcd->regs->intrstatus); + + /* sched disables take effect on the next frame, + * then the last WDH could take 6+ msec + */ + admhc_dbg(ahcd, "stopping schedules ...\n"); + ahcd->autostop = 0; + spin_unlock_irq (&ahcd->lock); + msleep (8); + spin_lock_irq(&ahcd->lock); + } + dl_done_list (ahcd); + finish_unlinks (ahcd, admhc_frame_no(ahcd)); + + /* maybe resume can wake root hub */ + if (device_may_wakeup(&admhcd_to_hcd(ahcd)->self.root_hub->dev) || + autostop) + ahcd->hc_control |= OHCI_CTRL_RWE; + else { + admhc_writel(ahcd, OHCI_INTR_RHSC, &ahcd->regs->intrdisable); + ahcd->hc_control &= ~OHCI_CTRL_RWE; + } + + /* Suspend hub ... this is the "global (to this bus) suspend" mode, + * which doesn't imply ports will first be individually suspended. + */ + ahcd->hc_control &= ~OHCI_CTRL_HCFS; + ahcd->hc_control |= OHCI_USB_SUSPEND; + admhc_writel(ahcd, ahcd->hc_control, &ahcd->ahcd->regs->control); + (void) admhc_readl(ahcd, &ahcd->regs->control); + + /* no resumes until devices finish suspending */ + if (!autostop) { + ahcd->next_statechange = jiffies + msecs_to_jiffies (5); + ahcd->autostop = 0; + } + +done: + return status; +} + +static inline struct ed *find_head(struct ed *ed) +{ + /* for bulk and control lists */ + while (ed->ed_prev) + ed = ed->ed_prev; + return ed; +} + +/* caller has locked the root hub */ +static int admhc_rh_resume(struct admhcd *ahcd) +__releases(ahcd->lock) +__acquires(ahcd->lock) +{ + struct usb_hcd *hcd = admhcd_to_hcd (ahcd); + u32 temp, enables; + int status = -EINPROGRESS; + int autostopped = ahcd->autostop; + + ahcd->autostop = 0; + ahcd->hc_control = admhc_readl(ahcd, &ahcd->regs->control); + + if (ahcd->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { + /* this can happen after resuming a swsusp snapshot */ + if (hcd->state == HC_STATE_RESUMING) { + admhc_dbg(ahcd, "BIOS/SMM active, control %03x\n", + ahcd->hc_control); + status = -EBUSY; + /* this happens when pmcore resumes HC then root */ + } else { + admhc_dbg(ahcd, "duplicate resume\n"); + status = 0; + } + } else switch (ahcd->hc_control & OHCI_CTRL_HCFS) { + case OHCI_USB_SUSPEND: + ahcd->hc_control &= ~(OHCI_CTRL_HCFS|OHCI_SCHED_ENABLES); + ahcd->hc_control |= OHCI_USB_RESUME; + admhc_writel(ahcd, ahcd->hc_control, &ahcd->ahcd->regs->control); + (void) admhc_readl(ahcd, &ahcd->regs->control); + admhc_dbg(ahcd, "%s root hub\n", + autostopped ? "auto-start" : "resume"); + break; + case OHCI_USB_RESUME: + /* HCFS changes sometime after INTR_RD */ + admhc_dbg(ahcd, "%swakeup root hub\n", + autostopped ? "auto-" : ""); + break; + case OHCI_USB_OPER: + /* this can happen after resuming a swsusp snapshot */ + admhc_dbg(ahcd, "snapshot resume? reinit\n"); + status = -EBUSY; + break; + default: /* RESET, we lost power */ + admhc_dbg(ahcd, "lost power\n"); + status = -EBUSY; + } + if (status == -EBUSY) { + if (!autostopped) { + spin_unlock_irq (&ahcd->lock); + (void) ahcd_init (ahcd); + status = admhc_restart (ahcd); + spin_lock_irq(&ahcd->lock); + } + return status; + } + if (status != -EINPROGRESS) + return status; + if (autostopped) + goto skip_resume; + spin_unlock_irq (&ahcd->lock); + + /* Some controllers (lucent erratum) need extra-long delays */ + msleep (20 /* usb 11.5.1.10 */ + 12 /* 32 msec counter */ + 1); + + temp = admhc_readl(ahcd, &ahcd->regs->control); + temp &= OHCI_CTRL_HCFS; + if (temp != OHCI_USB_RESUME) { + admhc_err (ahcd, "controller won't resume\n"); + spin_lock_irq(&ahcd->lock); + return -EBUSY; + } + + /* disable old schedule state, reinit from scratch */ + admhc_writel(ahcd, 0, &ahcd->regs->ed_controlhead); + admhc_writel(ahcd, 0, &ahcd->regs->ed_controlcurrent); + admhc_writel(ahcd, 0, &ahcd->regs->ed_bulkhead); + admhc_writel(ahcd, 0, &ahcd->regs->ed_bulkcurrent); + admhc_writel(ahcd, 0, &ahcd->regs->ed_periodcurrent); + admhc_writel(ahcd, (u32) ahcd->hcca_dma, &ahcd->ahcd->regs->hcca); + + /* Sometimes PCI D3 suspend trashes frame timings ... */ + periodic_reinit(ahcd); + + /* the following code is executed with ahcd->lock held and + * irqs disabled if and only if autostopped is true + */ + +skip_resume: + /* interrupts might have been disabled */ + admhc_writel(ahcd, OHCI_INTR_INIT, &ahcd->regs->int_enable); + if (ahcd->ed_rm_list) + admhc_writel(ahcd, OHCI_INTR_SF, &ahcd->regs->int_enable); + + /* Then re-enable operations */ + admhc_writel(ahcd, OHCI_USB_OPER, &ahcd->regs->control); + (void) admhc_readl(ahcd, &ahcd->regs->control); + if (!autostopped) + msleep (3); + + temp = ahcd->hc_control; + temp &= OHCI_CTRL_RWC; + temp |= OHCI_CONTROL_INIT | OHCI_USB_OPER; + ahcd->hc_control = temp; + admhc_writel(ahcd, temp, &ahcd->regs->control); + (void) admhc_readl(ahcd, &ahcd->regs->control); + + /* TRSMRCY */ + if (!autostopped) { + msleep (10); + spin_lock_irq(&ahcd->lock); + } + /* now ahcd->lock is always held and irqs are always disabled */ + + /* keep it alive for more than ~5x suspend + resume costs */ + ahcd->next_statechange = jiffies + STATECHANGE_DELAY; + + /* maybe turn schedules back on */ + enables = 0; + temp = 0; + if (!ahcd->ed_rm_list) { + if (ahcd->ed_controltail) { + admhc_writel(ahcd, + find_head (ahcd->ed_controltail)->dma, + &ahcd->regs->ed_controlhead); + enables |= OHCI_CTRL_CLE; + temp |= OHCI_CLF; + } + if (ahcd->ed_bulktail) { + admhc_writel(ahcd, find_head (ahcd->ed_bulktail)->dma, + &ahcd->regs->ed_bulkhead); + enables |= OHCI_CTRL_BLE; + temp |= OHCI_BLF; + } + } + if (hcd->self.bandwidth_isoc_reqs || hcd->self.bandwidth_int_reqs) + enables |= OHCI_CTRL_PLE|OHCI_CTRL_IE; + if (enables) { + admhc_dbg(ahcd, "restarting schedules ... %08x\n", enables); + ahcd->hc_control |= enables; + admhc_writel(ahcd, ahcd->hc_control, &ahcd->ahcd->regs->control); + if (temp) + admhc_writel(ahcd, temp, &ahcd->regs->cmdstatus); + (void) admhc_readl(ahcd, &ahcd->regs->control); + } + + return 0; +} + +static int admhc_bus_suspend(struct usb_hcd *hcd) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + int rc; + + spin_lock_irq(&ahcd->lock); + + if (unlikely(!HCD_HW_ACCESSIBLE(hcd))) + rc = -ESHUTDOWN; + else + rc = admhc_rh_suspend(ahcd, 0); + spin_unlock_irq(&ahcd->lock); + return rc; +} + +static int admhc_bus_resume(struct usb_hcd *hcd) +{ + struct admhcd *ahcd = hcd_to_admhcd(hcd); + int rc; + + if (time_before(jiffies, ahcd->next_statechange)) + msleep(5); + + spin_lock_irq(&ahcd->lock); + + if (unlikely(!HCD_HW_ACCESSIBLE(hcd))) + rc = -ESHUTDOWN; + else + rc = admhc_rh_resume(ahcd); + spin_unlock_irq(&ahcd->lock); + + /* poll until we know a device is connected or we autostop */ + if (rc == 0) + usb_hcd_poll_rh_status(hcd); + return rc; +} + +/* Carry out polling-, autostop-, and autoresume-related state changes */ +static int admhc_root_hub_state_changes(struct admhcd *ahcd, int changed, + int any_connected) +{ + int poll_rh = 1; + + switch (ahcd->hc_control & OHCI_CTRL_HCFS) { + + case OHCI_USB_OPER: + /* keep on polling until we know a device is connected + * and RHSC is enabled */ + if (!ahcd->autostop) { + if (any_connected || + !device_may_wakeup(&admhcd_to_hcd(ahcd) + ->self.root_hub->dev)) { + if (admhc_readl(ahcd, &ahcd->regs->int_enable) & + OHCI_INTR_RHSC) + poll_rh = 0; + } else { + ahcd->autostop = 1; + ahcd->next_statechange = jiffies + HZ; + } + + /* if no devices have been attached for one second, autostop */ + } else { + if (changed || any_connected) { + ahcd->autostop = 0; + ahcd->next_statechange = jiffies + + STATECHANGE_DELAY; + } else if (time_after_eq(jiffies, + ahcd->next_statechange) + && !ahcd->ed_rm_list + && !(ahcd->hc_control & + OHCI_SCHED_ENABLES)) { + ahcd_rh_suspend(ahcd, 1); + } + } + break; + + /* if there is a port change, autostart or ask to be resumed */ + case OHCI_USB_SUSPEND: + case OHCI_USB_RESUME: + if (changed) { + if (ahcd->autostop) + admhc_rh_resume(ahcd); + else + usb_hcd_resume_root_hub(admhcd_to_hcd(ahcd)); + } else { + /* everything is idle, no need for polling */ + poll_rh = 0; + } + break; + } + return poll_rh; +} + +/*-------------------------------------------------------------------------*/ + +/* must not be called from interrupt context */ +static int admhc_restart(struct admhcd *ahcd) +{ + int temp; + int i; + struct urb_priv *priv; + + /* mark any devices gone, so they do nothing till khubd disconnects. + * recycle any "live" eds/tds (and urbs) right away. + * later, khubd disconnect processing will recycle the other state, + * (either as disconnect/reconnect, or maybe someday as a reset). + */ + spin_lock_irq(&ahcd->lock); + admhc_disable(ahcd); + usb_root_hub_lost_power(admhcd_to_hcd(ahcd)->self.root_hub); + if (!list_empty(&ahcd->pending)) + admhc_dbg(ahcd, "abort schedule...\n"); + list_for_each_entry(priv, &ahcd->pending, pending) { + struct urb *urb = priv->td[0]->urb; + struct ed *ed = priv->ed; + + switch (ed->state) { + case ED_OPER: + ed->state = ED_UNLINK; + ed->hwINFO |= cpu_to_hc32(ahcd, ED_DEQUEUE); + ed_deschedule (ahcd, ed); + + ed->ed_next = ahcd->ed_rm_list; + ed->ed_prev = NULL; + ahcd->ed_rm_list = ed; + /* FALLTHROUGH */ + case ED_UNLINK: + break; + default: + admhc_dbg(ahcd, "bogus ed %p state %d\n", + ed, ed->state); + } + + if (!urb->unlinked) + urb->unlinked = -ESHUTDOWN; + } + finish_unlinks(ahcd, 0); + spin_unlock_irq(&ahcd->lock); + + /* paranoia, in case that didn't work: */ + + /* empty the interrupt branches */ + for (i = 0; i < NUM_INTS; i++) ahcd->load[i] = 0; + for (i = 0; i < NUM_INTS; i++) ahcd->hcca->int_table[i] = 0; + + /* no EDs to remove */ + ahcd->ed_rm_list = NULL; + + /* empty control and bulk lists */ + ahcd->ed_controltail = NULL; + ahcd->ed_bulktail = NULL; + + if ((temp = admhc_run(ahcd)) < 0) { + admhc_err(ahcd, "can't restart, %d\n", temp); + return temp; + } else { + /* here we "know" root ports should always stay powered, + * and that if we try to turn them back on the root hub + * will respond to CSC processing. + */ + i = ahcd->num_ports; + while (i--) + admhc_writel(ahcd, RH_PS_PSS, + &ahcd->regs->portstatus[i]); + admhc_dbg(ahcd, "restart complete\n"); + } + return 0; +} + +#else /* CONFIG_PM */ + +static inline int admhc_rh_resume(struct admhcd *ahcd) +{ + return 0; +} + +/* Carry out polling-related state changes. + * autostop isn't used when CONFIG_PM is turned off. + */ +static int admhc_root_hub_state_changes(struct admhcd *ahcd, int changed, + int any_connected) +{ + /* If INSM is enabled, don't poll */ + if (admhc_readl(ahcd, &ahcd->regs->int_enable) & ADMHC_INTR_INSM) + return 0; + + /* If no status changes are pending, enable status-change interrupts */ + if (!changed) { + admhc_intr_enable(ahcd, ADMHC_INTR_INSM); + return 0; + } + + return 1; +} + +#endif /* CONFIG_PM */ + diff --git a/target/linux/adm5120/files/drivers/usb/host/adm5120-q.c b/target/linux/adm5120/files/drivers/usb/host/adm5120-q.c new file mode 100644 index 000000000..cd9c8920a --- /dev/null +++ b/target/linux/adm5120/files/drivers/usb/host/adm5120-q.c @@ -0,0 +1,964 @@ +/* + * ADM5120 HCD (Host Controller Driver) for USB + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This file was derived from: drivers/usb/host/ohci-q.c + * (C) Copyright 1999 Roman Weissgaerber + * (C) Copyright 2000-2002 David Brownell + * + * This program 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. + * + */ + +#include +#include + +/*-------------------------------------------------------------------------*/ + +/* + * URB goes back to driver, and isn't reissued. + * It's completely gone from HC data structures. + * PRECONDITION: ahcd lock held, irqs blocked. + */ +static void +finish_urb(struct admhcd *ahcd, struct urb *urb, int status) +__releases(ahcd->lock) +__acquires(ahcd->lock) +{ + urb_priv_free(ahcd, urb->hcpriv); + + if (likely(status == -EINPROGRESS)) + status = 0; + + switch (usb_pipetype(urb->pipe)) { + case PIPE_ISOCHRONOUS: + admhcd_to_hcd(ahcd)->self.bandwidth_isoc_reqs--; + break; + case PIPE_INTERRUPT: + admhcd_to_hcd(ahcd)->self.bandwidth_int_reqs--; + break; + } + +#ifdef ADMHC_VERBOSE_DEBUG + urb_print(ahcd, urb, "RET", usb_pipeout(urb->pipe), status); +#endif + + /* urb->complete() can reenter this HCD */ + usb_hcd_unlink_urb_from_ep(admhcd_to_hcd(ahcd), urb); + spin_unlock(&ahcd->lock); + usb_hcd_giveback_urb(admhcd_to_hcd(ahcd), urb, status); + spin_lock(&ahcd->lock); +} + + +/*-------------------------------------------------------------------------* + * ED handling functions + *-------------------------------------------------------------------------*/ + +#if 0 /* FIXME */ +/* search for the right schedule branch to use for a periodic ed. + * does some load balancing; returns the branch, or negative errno. + */ +static int balance(struct admhcd *ahcd, int interval, int load) +{ + int i, branch = -ENOSPC; + + /* iso periods can be huge; iso tds specify frame numbers */ + if (interval > NUM_INTS) + interval = NUM_INTS; + + /* search for the least loaded schedule branch of that period + * that has enough bandwidth left unreserved. + */ + for (i = 0; i < interval ; i++) { + if (branch < 0 || ahcd->load[branch] > ahcd->load[i]) { + int j; + + /* usb 1.1 says 90% of one frame */ + for (j = i; j < NUM_INTS; j += interval) { + if ((ahcd->load[j] + load) > 900) + break; + } + if (j < NUM_INTS) + continue; + branch = i; + } + } + return branch; +} +#endif + +/*-------------------------------------------------------------------------*/ + +#if 0 /* FIXME */ +/* both iso and interrupt requests have periods; this routine puts them + * into the schedule tree in the apppropriate place. most iso devices use + * 1msec periods, but that's not required. + */ +static void periodic_link(struct admhcd *ahcd, struct ed *ed) +{ + unsigned i; + + admhc_vdbg(ahcd, "link %sed %p branch %d [%dus.], interval %d\n", + (ed->hwINFO & cpu_to_hc32(ahcd, ED_ISO)) ? "iso " : "", + ed, ed->branch, ed->load, ed->interval); + + for (i = ed->branch; i < NUM_INTS; i += ed->interval) { + struct ed **prev = &ahcd->periodic[i]; + __hc32 *prev_p = &ahcd->hcca->int_table[i]; + struct ed *here = *prev; + + /* sorting each branch by period (slow before fast) + * lets us share the faster parts of the tree. + * (plus maybe: put interrupt eds before iso) + */ + while (here && ed != here) { + if (ed->interval > here->interval) + break; + prev = &here->ed_next; + prev_p = &here->hwNextED; + here = *prev; + } + if (ed != here) { + ed->ed_next = here; + if (here) + ed->hwNextED = *prev_p; + wmb(); + *prev = ed; + *prev_p = cpu_to_hc32(ahcd, ed->dma); + wmb(); + } + ahcd->load[i] += ed->load; + } + admhcd_to_hcd(ahcd)->self.bandwidth_allocated += ed->load / ed->interval; +} +#endif + +/* link an ed into the HC chain */ + +static int ed_schedule(struct admhcd *ahcd, struct ed *ed) +{ + struct ed *old_tail; + + if (admhcd_to_hcd(ahcd)->state == HC_STATE_QUIESCING) + return -EAGAIN; + + ed->state = ED_OPER; + + old_tail = ahcd->ed_tails[ed->type]; + + ed->ed_next = old_tail->ed_next; + if (ed->ed_next) { + ed->ed_next->ed_prev = ed; + ed->hwNextED = cpu_to_hc32(ahcd, ed->ed_next->dma); + } + ed->ed_prev = old_tail; + + old_tail->ed_next = ed; + old_tail->hwNextED = cpu_to_hc32(ahcd, ed->dma); + + ahcd->ed_tails[ed->type] = ed; + + admhc_dma_enable(ahcd); + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +#if 0 /* FIXME */ +/* scan the periodic table to find and unlink this ED */ +static void periodic_unlink(struct admhcd *ahcd, struct ed *ed) +{ + int i; + + for (i = ed->branch; i < NUM_INTS; i += ed->interval) { + struct ed *temp; + struct ed **prev = &ahcd->periodic[i]; + __hc32 *prev_p = &ahcd->hcca->int_table[i]; + + while (*prev && (temp = *prev) != ed) { + prev_p = &temp->hwNextED; + prev = &temp->ed_next; + } + if (*prev) { + *prev_p = ed->hwNextED; + *prev = ed->ed_next; + } + ahcd->load[i] -= ed->load; + } + + admhcd_to_hcd(ahcd)->self.bandwidth_allocated -= ed->load / ed->interval; + admhc_vdbg(ahcd, "unlink %sed %p branch %d [%dus.], interval %d\n", + (ed->hwINFO & cpu_to_hc32(ahcd, ED_ISO)) ? "iso " : "", + ed, ed->branch, ed->load, ed->interval); +} +#endif + +/* unlink an ed from the HC chain. + * just the link to the ed is unlinked. + * the link from the ed still points to another operational ed or 0 + * so the HC can eventually finish the processing of the unlinked ed + * (assuming it already started that, which needn't be true). + * + * ED_UNLINK is a transient state: the HC may still see this ED, but soon + * it won't. ED_SKIP means the HC will finish its current transaction, + * but won't start anything new. The TD queue may still grow; device + * drivers don't know about this HCD-internal state. + * + * When the HC can't see the ED, something changes ED_UNLINK to one of: + * + * - ED_OPER: when there's any request queued, the ED gets rescheduled + * immediately. HC should be working on them. + * + * - ED_IDLE: when there's no TD queue. there's no reason for the HC + * to care about this ED; safe to disable the endpoint. + * + * When finish_unlinks() runs later, after SOF interrupt, it will often + * complete one or more URB unlinks before making that state change. + */ +static void ed_deschedule(struct admhcd *ahcd, struct ed *ed) +{ + +#ifdef ADMHC_VERBOSE_DEBUG + admhc_dump_ed(ahcd, "ED-DESCHED", ed, 1); +#endif + + ed->hwINFO |= cpu_to_hc32(ahcd, ED_SKIP); + wmb(); + ed->state = ED_UNLINK; + + /* remove this ED from the HC list */ + ed->ed_prev->hwNextED = ed->hwNextED; + + /* and remove it from our list also */ + ed->ed_prev->ed_next = ed->ed_next; + + if (ed->ed_next) + ed->ed_next->ed_prev = ed->ed_prev; + + if (ahcd->ed_tails[ed->type] == ed) + ahcd->ed_tails[ed->type] = ed->ed_prev; +} + +/*-------------------------------------------------------------------------*/ + +static struct ed *ed_create(struct admhcd *ahcd, unsigned int type, u32 info) +{ + struct ed *ed; + struct td *td; + + ed = ed_alloc(ahcd, GFP_ATOMIC); + if (!ed) + goto err; + + /* dummy td; end of td list for this ed */ + td = td_alloc(ahcd, GFP_ATOMIC); + if (!td) + goto err_free_ed; + + switch (type) { + case PIPE_INTERRUPT: + info |= ED_INT; + break; + case PIPE_ISOCHRONOUS: + info |= ED_ISO; + break; + } + + ed->dummy = td; + ed->state = ED_IDLE; + ed->type = type; + + ed->hwINFO = cpu_to_hc32(ahcd, info); + ed->hwTailP = cpu_to_hc32(ahcd, td->td_dma); + ed->hwHeadP = ed->hwTailP; /* ED_C, ED_H zeroed */ + + return ed; + +err_free_ed: + ed_free(ahcd, ed); +err: + return NULL; +} + +/* get and maybe (re)init an endpoint. init _should_ be done only as part + * of enumeration, usb_set_configuration() or usb_set_interface(). + */ +static struct ed *ed_get(struct admhcd *ahcd, struct usb_host_endpoint *ep, + struct usb_device *udev, unsigned int pipe, int interval) +{ + struct ed *ed; + unsigned long flags; + + spin_lock_irqsave(&ahcd->lock, flags); + + ed = ep->hcpriv; + if (!ed) { + u32 info; + + /* FIXME: usbcore changes dev->devnum before SET_ADDRESS + * succeeds ... otherwise we wouldn't need "pipe". + */ + info = usb_pipedevice(pipe); + info |= (ep->desc.bEndpointAddress & ~USB_DIR_IN) << ED_EN_SHIFT; + info |= le16_to_cpu(ep->desc.wMaxPacketSize) << ED_MPS_SHIFT; + if (udev->speed == USB_SPEED_FULL) + info |= ED_SPEED_FULL; + + ed = ed_create(ahcd, usb_pipetype(pipe), info); + if (ed) + ep->hcpriv = ed; + } + + spin_unlock_irqrestore(&ahcd->lock, flags); + + return ed; +} + +/*-------------------------------------------------------------------------*/ + +/* request unlinking of an endpoint from an operational HC. + * put the ep on the rm_list + * real work is done at the next start frame (SOFI) hardware interrupt + * caller guarantees HCD is running, so hardware access is safe, + * and that ed->state is ED_OPER + */ +static void start_ed_unlink(struct admhcd *ahcd, struct ed *ed) +{ + +#ifdef ADMHC_VERBOSE_DEBUG + admhc_dump_ed(ahcd, "ED-UNLINK", ed, 1); +#endif + + ed->hwINFO |= cpu_to_hc32(ahcd, ED_DEQUEUE); + ed_deschedule(ahcd, ed); + + /* add this ED into the remove list */ + ed->ed_rm_next = ahcd->ed_rm_list; + ahcd->ed_rm_list = ed; + + /* enable SOF interrupt */ + admhc_intr_ack(ahcd, ADMHC_INTR_SOFI); + admhc_intr_enable(ahcd, ADMHC_INTR_SOFI); + /* flush those writes */ + admhc_writel_flush(ahcd); + + /* SOF interrupt might get delayed; record the frame counter value that + * indicates when the HC isn't looking at it, so concurrent unlinks + * behave. frame_no wraps every 2^16 msec, and changes right before + * SOF is triggered. + */ + ed->tick = admhc_frame_no(ahcd) + 1; +} + +/*-------------------------------------------------------------------------* + * TD handling functions + *-------------------------------------------------------------------------*/ + +/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ + +static void +td_fill(struct admhcd *ahcd, u32 info, dma_addr_t data, int len, + struct urb *urb, int index) +{ + struct td *td, *td_pt; + struct urb_priv *urb_priv = urb->hcpriv; + int hash; + u32 cbl = 0; + +#if 1 + if (index == (urb_priv->td_cnt - 1) && + ((urb->transfer_flags & URB_NO_INTERRUPT) == 0)) + cbl |= TD_IE; +#else + if (index == (urb_priv->td_cnt - 1)) + cbl |= TD_IE; +#endif + + /* use this td as the next dummy */ + td_pt = urb_priv->td[index]; + + /* fill the old dummy TD */ + td = urb_priv->td[index] = urb_priv->ed->dummy; + urb_priv->ed->dummy = td_pt; + + td->ed = urb_priv->ed; + td->next_dl_td = NULL; + td->index = index; + td->urb = urb; + td->data_dma = data; + if (!len) + data = 0; + + if (data) + cbl |= (len & TD_BL_MASK); + + info |= TD_OWN; + + /* setup hardware specific fields */ + td->hwINFO = cpu_to_hc32(ahcd, info); + td->hwDBP = cpu_to_hc32(ahcd, data); + td->hwCBL = cpu_to_hc32(ahcd, cbl); + td->hwNextTD = cpu_to_hc32(ahcd, td_pt->td_dma); + + /* append to queue */ + list_add_tail(&td->td_list, &td->ed->td_list); + + /* hash it for later reverse mapping */ + hash = TD_HASH_FUNC(td->td_dma); + td->td_hash = ahcd->td_hash[hash]; + ahcd->td_hash[hash] = td; + + /* HC might read the TD (or cachelines) right away ... */ + wmb(); + td->ed->hwTailP = td->hwNextTD; +} + +/*-------------------------------------------------------------------------*/ + +/* Prepare all TDs of a transfer, and queue them onto the ED. + * Caller guarantees HC is active. + * Usually the ED is already on the schedule, so TDs might be + * processed as soon as they're queued. + */ +static void td_submit_urb(struct admhcd *ahcd, struct urb *urb) +{ + struct urb_priv *urb_priv = urb->hcpriv; + dma_addr_t data; + int data_len = urb->transfer_buffer_length; + int cnt = 0; + u32 info = 0; + int is_out = usb_pipeout(urb->pipe); + u32 toggle = 0; + + /* OHCI handles the bulk/interrupt data toggles itself. We just + * use the device toggle bits for resetting, and rely on the fact + * that resetting toggle is meaningless if the endpoint is active. + */ + + if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), is_out)) { + toggle = TD_T_CARRY; + } else { + toggle = TD_T_DATA0; + usb_settoggle(urb->dev, usb_pipeendpoint (urb->pipe), + is_out, 1); + } + + urb_priv->td_idx = 0; + list_add(&urb_priv->pending, &ahcd->pending); + + if (data_len) + data = urb->transfer_dma; + else + data = 0; + + /* NOTE: TD_CC is set so we can tell which TDs the HC processed by + * using TD_CC_GET, as well as by seeing them on the done list. + * (CC = NotAccessed ... 0x0F, or 0x0E in PSWs for ISO.) + */ + switch (urb_priv->ed->type) { + case PIPE_INTERRUPT: + info = is_out + ? TD_T_CARRY | TD_SCC_NOTACCESSED | TD_DP_OUT + : TD_T_CARRY | TD_SCC_NOTACCESSED | TD_DP_IN; + + /* setup service interval and starting frame number */ + info |= (urb->start_frame & TD_FN_MASK); + info |= (urb->interval & TD_ISI_MASK) << TD_ISI_SHIFT; + + td_fill(ahcd, info, data, data_len, urb, cnt); + cnt++; + + admhcd_to_hcd(ahcd)->self.bandwidth_int_reqs++; + break; + + case PIPE_BULK: + info = is_out + ? TD_SCC_NOTACCESSED | TD_DP_OUT + : TD_SCC_NOTACCESSED | TD_DP_IN; + + /* TDs _could_ transfer up to 8K each */ + while (data_len > TD_DATALEN_MAX) { + td_fill(ahcd, info | ((cnt) ? TD_T_CARRY : toggle), + data, TD_DATALEN_MAX, urb, cnt); + data += TD_DATALEN_MAX; + data_len -= TD_DATALEN_MAX; + cnt++; + } + + td_fill(ahcd, info | ((cnt) ? TD_T_CARRY : toggle), data, + data_len, urb, cnt); + cnt++; + + if ((urb->transfer_flags & URB_ZERO_PACKET) + && (cnt < urb_priv->td_cnt)) { + td_fill(ahcd, info | ((cnt) ? TD_T_CARRY : toggle), + 0, 0, urb, cnt); + cnt++; + } + break; + + /* control manages DATA0/DATA1 toggle per-request; SETUP resets it, + * any DATA phase works normally, and the STATUS ack is special. + */ + case PIPE_CONTROL: + /* fill a TD for the setup */ + info = TD_SCC_NOTACCESSED | TD_DP_SETUP | TD_T_DATA0; + td_fill(ahcd, info, urb->setup_dma, 8, urb, cnt++); + + if (data_len > 0) { + /* fill a TD for the data */ + info = TD_SCC_NOTACCESSED | TD_T_DATA1; + info |= is_out ? TD_DP_OUT : TD_DP_IN; + /* NOTE: mishandles transfers >8K, some >4K */ + td_fill(ahcd, info, data, data_len, urb, cnt++); + } + + /* fill a TD for the ACK */ + info = (is_out || data_len == 0) + ? TD_SCC_NOTACCESSED | TD_DP_IN | TD_T_DATA1 + : TD_SCC_NOTACCESSED | TD_DP_OUT | TD_T_DATA1; + td_fill(ahcd, info, data, 0, urb, cnt++); + + break; + + /* ISO has no retransmit, so no toggle; + * Each TD could handle multiple consecutive frames (interval 1); + * we could often reduce the number of TDs here. + */ + case PIPE_ISOCHRONOUS: + info = is_out + ? TD_T_CARRY | TD_SCC_NOTACCESSED | TD_DP_OUT + : TD_T_CARRY | TD_SCC_NOTACCESSED | TD_DP_IN; + + for (cnt = 0; cnt < urb->number_of_packets; cnt++) { + int frame = urb->start_frame; + + frame += cnt * urb->interval; + frame &= TD_FN_MASK; + td_fill(ahcd, info | frame, + data + urb->iso_frame_desc[cnt].offset, + urb->iso_frame_desc[cnt].length, urb, cnt); + } + admhcd_to_hcd(ahcd)->self.bandwidth_isoc_reqs++; + break; + } + + if (urb_priv->td_cnt != cnt) + admhc_err(ahcd, "bad number of tds created for urb %p\n", urb); +} + +/*-------------------------------------------------------------------------* + * Done List handling functions + *-------------------------------------------------------------------------*/ + +/* calculate transfer length/status and update the urb */ +static int td_done(struct admhcd *ahcd, struct urb *urb, struct td *td) +{ + struct urb_priv *urb_priv = urb->hcpriv; + u32 info; + u32 bl; + u32 tdDBP; + int type = usb_pipetype(urb->pipe); + int cc; + int status = -EINPROGRESS; + + info = hc32_to_cpup(ahcd, &td->hwINFO); + tdDBP = hc32_to_cpup(ahcd, &td->hwDBP); + bl = TD_BL_GET(hc32_to_cpup(ahcd, &td->hwCBL)); + cc = TD_CC_GET(info); + + /* ISO ... drivers see per-TD length/status */ + if (type == PIPE_ISOCHRONOUS) { + /* TODO */ + int dlen = 0; + + /* NOTE: assumes FC in tdINFO == 0, and that + * only the first of 0..MAXPSW psws is used. + */ + if (info & TD_CC) /* hc didn't touch? */ + return status; + + if (usb_pipeout(urb->pipe)) + dlen = urb->iso_frame_desc[td->index].length; + else { + /* short reads are always OK for ISO */ + if (cc == TD_CC_DATAUNDERRUN) + cc = TD_CC_NOERROR; + dlen = tdDBP - td->data_dma + bl; + } + + urb->actual_length += dlen; + urb->iso_frame_desc[td->index].actual_length = dlen; + urb->iso_frame_desc[td->index].status = cc_to_error[cc]; + + if (cc != TD_CC_NOERROR) + admhc_vdbg(ahcd, + "urb %p iso td %p (%d) len %d cc %d\n", + urb, td, 1 + td->index, dlen, cc); + + /* BULK, INT, CONTROL ... drivers see aggregate length/status, + * except that "setup" bytes aren't counted and "short" transfers + * might not be reported as errors. + */ + } else { + /* update packet status if needed (short is normally ok) */ + if (cc == TD_CC_DATAUNDERRUN + && !(urb->transfer_flags & URB_SHORT_NOT_OK)) + cc = TD_CC_NOERROR; + + if (cc != TD_CC_NOERROR && cc < TD_CC_HCD0) + status = cc_to_error[cc]; + + + /* count all non-empty packets except control SETUP packet */ + if ((type != PIPE_CONTROL || td->index != 0) && tdDBP != 0) + urb->actual_length += tdDBP - td->data_dma + bl; + + if (cc != TD_CC_NOERROR && cc < TD_CC_HCD0) + admhc_vdbg(ahcd, + "urb %p td %p (%d) cc %d, len=%d/%d\n", + urb, td, td->index, cc, + urb->actual_length, + urb->transfer_buffer_length); + } + + list_del(&td->td_list); + urb_priv->td_idx++; + + return status; +} + +/*-------------------------------------------------------------------------*/ + +static void ed_halted(struct admhcd *ahcd, struct td *td, int cc) +{ + struct urb *urb = td->urb; + struct urb_priv *urb_priv = urb->hcpriv; + struct ed *ed = td->ed; + struct list_head *tmp = td->td_list.next; + __hc32 toggle = ed->hwHeadP & cpu_to_hc32(ahcd, ED_C); + + admhc_dump_ed(ahcd, "ed halted", td->ed, 1); + /* clear ed halt; this is the td that caused it, but keep it inactive + * until its urb->complete() has a chance to clean up. + */ + ed->hwINFO |= cpu_to_hc32(ahcd, ED_SKIP); + wmb(); + ed->hwHeadP &= ~cpu_to_hc32(ahcd, ED_H); + + /* Get rid of all later tds from this urb. We don't have + * to be careful: no errors and nothing was transferred. + * Also patch the ed so it looks as if those tds completed normally. + */ + while (tmp != &ed->td_list) { + struct td *next; + + next = list_entry(tmp, struct td, td_list); + tmp = next->td_list.next; + + if (next->urb != urb) + break; + + /* NOTE: if multi-td control DATA segments get supported, + * this urb had one of them, this td wasn't the last td + * in that segment (TD_R clear), this ed halted because + * of a short read, _and_ URB_SHORT_NOT_OK is clear ... + * then we need to leave the control STATUS packet queued + * and clear ED_SKIP. + */ + list_del(&next->td_list); + urb_priv->td_cnt++; + ed->hwHeadP = next->hwNextTD | toggle; + } + + /* help for troubleshooting: report anything that + * looks odd ... that doesn't include protocol stalls + * (or maybe some other things) + */ + switch (cc) { + case TD_CC_DATAUNDERRUN: + if ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0) + break; + /* fallthrough */ + case TD_CC_STALL: + if (usb_pipecontrol(urb->pipe)) + break; + /* fallthrough */ + default: + admhc_dbg(ahcd, + "urb %p path %s ep%d%s %08x cc %d --> status %d\n", + urb, urb->dev->devpath, + usb_pipeendpoint (urb->pipe), + usb_pipein(urb->pipe) ? "in" : "out", + hc32_to_cpu(ahcd, td->hwINFO), + cc, cc_to_error[cc]); + } +} + +/*-------------------------------------------------------------------------*/ + +/* there are some urbs/eds to unlink; called in_irq(), with HCD locked */ +static void +finish_unlinks(struct admhcd *ahcd, u16 tick) +{ + struct ed *ed, **last; + +rescan_all: + for (last = &ahcd->ed_rm_list, ed = *last; ed != NULL; ed = *last) { + struct list_head *entry, *tmp; + int completed, modified; + __hc32 *prev; + + /* only take off EDs that the HC isn't using, accounting for + * frame counter wraps and EDs with partially retired TDs + */ + if (likely(HC_IS_RUNNING(admhcd_to_hcd(ahcd)->state))) { + if (tick_before(tick, ed->tick)) { +skip_ed: + last = &ed->ed_rm_next; + continue; + } +#if 0 + if (!list_empty(&ed->td_list)) { + struct td *td; + u32 head; + + td = list_entry(ed->td_list.next, struct td, + td_list); + head = hc32_to_cpu(ahcd, ed->hwHeadP) & + TD_MASK; + + /* INTR_WDH may need to clean up first */ + if (td->td_dma != head) + goto skip_ed; + } +#endif + } + + /* reentrancy: if we drop the schedule lock, someone might + * have modified this list. normally it's just prepending + * entries (which we'd ignore), but paranoia won't hurt. + */ + *last = ed->ed_rm_next; + ed->ed_rm_next = NULL; + modified = 0; + + /* unlink urbs as requested, but rescan the list after + * we call a completion since it might have unlinked + * another (earlier) urb + * + * When we get here, the HC doesn't see this ed. But it + * must not be rescheduled until all completed URBs have + * been given back to the driver. + */ +rescan_this: + completed = 0; + prev = &ed->hwHeadP; + list_for_each_safe(entry, tmp, &ed->td_list) { + struct td *td; + struct urb *urb; + struct urb_priv *urb_priv; + __hc32 savebits; + u32 tdINFO; + int status; + + td = list_entry(entry, struct td, td_list); + urb = td->urb; + urb_priv = td->urb->hcpriv; + + if (!urb->unlinked) { + prev = &td->hwNextTD; + continue; + } + + if ((urb_priv) == NULL) + continue; + + /* patch pointer hc uses */ + savebits = *prev & ~cpu_to_hc32(ahcd, TD_MASK); + *prev = td->hwNextTD | savebits; + /* If this was unlinked, the TD may not have been + * retired ... so manually save dhe data toggle. + * The controller ignores the value we save for + * control and ISO endpoints. + */ + tdINFO = hc32_to_cpup(ahcd, &td->hwINFO); + if ((tdINFO & TD_T) == TD_T_DATA0) + ed->hwHeadP &= ~cpu_to_hc32(ahcd, ED_C); + else if ((tdINFO & TD_T) == TD_T_DATA1) + ed->hwHeadP |= cpu_to_hc32(ahcd, ED_C); + + /* HC may have partly processed this TD */ +#ifdef ADMHC_VERBOSE_DEBUG + urb_print(ahcd, urb, "PARTIAL", 0); +#endif + status = td_done(ahcd, urb, td); + + /* if URB is done, clean up */ + if (urb_priv->td_idx == urb_priv->td_cnt) { + modified = completed = 1; + finish_urb(ahcd, urb, status); + } + } + if (completed && !list_empty(&ed->td_list)) + goto rescan_this; + + /* ED's now officially unlinked, hc doesn't see */ + ed->state = ED_IDLE; + ed->hwHeadP &= ~cpu_to_hc32(ahcd, ED_H); + ed->hwNextED = 0; + wmb(); + ed->hwINFO &= ~cpu_to_hc32(ahcd, ED_SKIP | ED_DEQUEUE); + + /* but if there's work queued, reschedule */ + if (!list_empty(&ed->td_list)) { + if (HC_IS_RUNNING(admhcd_to_hcd(ahcd)->state)) + ed_schedule(ahcd, ed); + } + + if (modified) + goto rescan_all; + } +} + +/*-------------------------------------------------------------------------*/ +/* + * Process normal completions (error or success) and clean the schedules. + * + * This is the main path for handing urbs back to drivers. The only other + * normal path is finish_unlinks(), which unlinks URBs using ed_rm_list, + * instead of scanning the (re-reversed) donelist as this does. + */ + +static void ed_unhalt(struct admhcd *ahcd, struct ed *ed, struct urb *urb) +{ + struct list_head *entry, *tmp; + __hc32 toggle = ed->hwHeadP & cpu_to_hc32(ahcd, ED_C); + +#ifdef ADMHC_VERBOSE_DEBUG + admhc_dump_ed(ahcd, "UNHALT", ed, 0); +#endif + /* clear ed halt; this is the td that caused it, but keep it inactive + * until its urb->complete() has a chance to clean up. + */ + ed->hwINFO |= cpu_to_hc32(ahcd, ED_SKIP); + wmb(); + ed->hwHeadP &= ~cpu_to_hc32(ahcd, ED_H); + + list_for_each_safe(entry, tmp, &ed->td_list) { + struct td *td = list_entry(entry, struct td, td_list); + __hc32 info; + + if (td->urb != urb) + break; + + info = td->hwINFO; + info &= ~cpu_to_hc32(ahcd, TD_CC | TD_OWN); + td->hwINFO = info; + + ed->hwHeadP = td->hwNextTD | toggle; + wmb(); + } + +} + +static void ed_intr_refill(struct admhcd *ahcd, struct ed *ed) +{ + __hc32 toggle = ed->hwHeadP & cpu_to_hc32(ahcd, ED_C); + + ed->hwHeadP = ed->hwTailP | toggle; +} + + +static inline int is_ed_halted(struct admhcd *ahcd, struct ed *ed) +{ + return ((hc32_to_cpup(ahcd, &ed->hwHeadP) & ED_H) == ED_H); +} + +static inline int is_td_halted(struct admhcd *ahcd, struct ed *ed, + struct td *td) +{ + return ((hc32_to_cpup(ahcd, &ed->hwHeadP) & TD_MASK) == + (hc32_to_cpup(ahcd, &td->hwNextTD) & TD_MASK)); +} + +static void ed_update(struct admhcd *ahcd, struct ed *ed) +{ + struct list_head *entry, *tmp; + +#ifdef ADMHC_VERBOSE_DEBUG + admhc_dump_ed(ahcd, "UPDATE", ed, 1); +#endif + + list_for_each_safe(entry, tmp, &ed->td_list) { + struct td *td = list_entry(entry, struct td, td_list); + struct urb *urb = td->urb; + struct urb_priv *urb_priv = urb->hcpriv; + int status; + + if (hc32_to_cpup(ahcd, &td->hwINFO) & TD_OWN) + break; + + /* update URB's length and status from TD */ + status = td_done(ahcd, urb, td); + if (is_ed_halted(ahcd, ed) && is_td_halted(ahcd, ed, td)) + ed_unhalt(ahcd, ed, urb); + + if (ed->type == PIPE_INTERRUPT) + ed_intr_refill(ahcd, ed); + + /* If all this urb's TDs are done, call complete() */ + if (urb_priv->td_idx == urb_priv->td_cnt) + finish_urb(ahcd, urb, status); + + /* clean schedule: unlink EDs that are no longer busy */ + if (list_empty(&ed->td_list)) { + if (ed->state == ED_OPER) + start_ed_unlink(ahcd, ed); + + /* ... reenabling halted EDs only after fault cleanup */ + } else if ((ed->hwINFO & cpu_to_hc32(ahcd, + ED_SKIP | ED_DEQUEUE)) + == cpu_to_hc32(ahcd, ED_SKIP)) { + td = list_entry(ed->td_list.next, struct td, td_list); +#if 0 + if (!(td->hwINFO & cpu_to_hc32(ahcd, TD_DONE))) { + ed->hwINFO &= ~cpu_to_hc32(ahcd, ED_SKIP); + /* ... hc may need waking-up */ + switch (ed->type) { + case PIPE_CONTROL: + admhc_writel(ahcd, OHCI_CLF, + &ahcd->regs->cmdstatus); + break; + case PIPE_BULK: + admhc_writel(ahcd, OHCI_BLF, + &ahcd->regs->cmdstatus); + break; + } + } +#else + if ((td->hwINFO & cpu_to_hc32(ahcd, TD_OWN))) + ed->hwINFO &= ~cpu_to_hc32(ahcd, ED_SKIP); +#endif + } + + } +} + +/* there are some tds completed; called in_irq(), with HCD locked */ +static void admhc_td_complete(struct admhcd *ahcd) +{ + struct ed *ed; + + for (ed = ahcd->ed_head; ed; ed = ed->ed_next) { + if (ed->state != ED_OPER) + continue; + + ed_update(ahcd, ed); + } +} diff --git a/target/linux/adm5120/files/drivers/usb/host/adm5120.h b/target/linux/adm5120/files/drivers/usb/host/adm5120.h new file mode 100644 index 000000000..e47aac8e7 --- /dev/null +++ b/target/linux/adm5120/files/drivers/usb/host/adm5120.h @@ -0,0 +1,755 @@ +/* + * ADM5120 HCD (Host Controller Driver) for USB + * + * Copyright (C) 2007-2008 Gabor Juhos + * + * This file was derived from: drivers/usb/host/ohci.h + * (C) Copyright 1999 Roman Weissgaerber + * (C) Copyright 2000-2002 David Brownell + * + * This program 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. + * + */ + +/* + * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to + * __leXX (normally) or __beXX (given OHCI_BIG_ENDIAN), depending on the + * host controller implementation. + */ +typedef __u32 __bitwise __hc32; +typedef __u16 __bitwise __hc16; + +/* + * OHCI Endpoint Descriptor (ED) ... holds TD queue + * See OHCI spec, section 4.2 + * + * This is a "Queue Head" for those transfers, which is why + * both EHCI and UHCI call similar structures a "QH". + */ + +#define TD_DATALEN_MAX 4096 + +#define ED_ALIGN 16 +#define ED_MASK ((u32)~(ED_ALIGN-1)) /* strip hw status in low addr bits */ + +struct ed { + /* first fields are hardware-specified */ + __hc32 hwINFO; /* endpoint config bitmap */ + /* info bits defined by hcd */ +#define ED_DEQUEUE (1 << 27) + /* info bits defined by the hardware */ +#define ED_MPS_SHIFT 16 +#define ED_MPS_MASK ((1 << 11)-1) +#define ED_MPS_GET(x) (((x) >> ED_MPS_SHIFT) & ED_MPS_MASK) +#define ED_ISO (1 << 15) /* isochronous endpoint */ +#define ED_SKIP (1 << 14) +#define ED_SPEED_FULL (1 << 13) /* fullspeed device */ +#define ED_INT (1 << 11) /* interrupt endpoint */ +#define ED_EN_SHIFT 7 /* endpoint shift */ +#define ED_EN_MASK ((1 << 4)-1) /* endpoint mask */ +#define ED_EN_GET(x) (((x) >> ED_EN_SHIFT) & ED_EN_MASK) +#define ED_FA_MASK ((1 << 7)-1) /* function address mask */ +#define ED_FA_GET(x) ((x) & ED_FA_MASK) + __hc32 hwTailP; /* tail of TD list */ + __hc32 hwHeadP; /* head of TD list (hc r/w) */ +#define ED_C (0x02) /* toggle carry */ +#define ED_H (0x01) /* halted */ + __hc32 hwNextED; /* next ED in list */ + + /* rest are purely for the driver's use */ + dma_addr_t dma; /* addr of ED */ + struct td *dummy; /* next TD to activate */ + + struct list_head urb_list; /* list of our URBs */ + + /* host's view of schedule */ + struct ed *ed_next; /* on schedule list */ + struct ed *ed_prev; /* for non-interrupt EDs */ + struct ed *ed_rm_next; /* on rm list */ + struct list_head td_list; /* "shadow list" of our TDs */ + + /* create --> IDLE --> OPER --> ... --> IDLE --> destroy + * usually: OPER --> UNLINK --> (IDLE | OPER) --> ... + */ + u8 state; /* ED_{IDLE,UNLINK,OPER} */ +#define ED_IDLE 0x00 /* NOT linked to HC */ +#define ED_UNLINK 0x01 /* being unlinked from hc */ +#define ED_OPER 0x02 /* IS linked to hc */ + + u8 type; /* PIPE_{BULK,...} */ + + /* periodic scheduling params (for intr and iso) */ + u8 branch; + u16 interval; + u16 load; + u16 last_iso; /* iso only */ + + /* HC may see EDs on rm_list until next frame (frame_no == tick) */ + u16 tick; +} __attribute__ ((aligned(ED_ALIGN))); + +/* + * OHCI Transfer Descriptor (TD) ... one per transfer segment + * See OHCI spec, sections 4.3.1 (general = control/bulk/interrupt) + * and 4.3.2 (iso) + */ + +#define TD_ALIGN 32 +#define TD_MASK ((u32)~(TD_ALIGN-1)) /* strip hw status in low addr bits */ + +struct td { + /* first fields are hardware-specified */ + __hc32 hwINFO; /* transfer info bitmask */ + + /* hwINFO bits */ +#define TD_OWN (1 << 31) /* owner of the descriptor */ +#define TD_CC_SHIFT 27 /* condition code */ +#define TD_CC_MASK 0xf +#define TD_CC (TD_CC_MASK << TD_CC_SHIFT) +#define TD_CC_GET(x) (((x) >> TD_CC_SHIFT) & TD_CC_MASK) + +#define TD_EC_SHIFT 25 /* error count */ +#define TD_EC_MASK 0x3 +#define TD_EC (TD_EC_MASK << TD_EC_SHIFT) +#define TD_EC_GET(x) ((x >> TD_EC_SHIFT) & TD_EC_MASK) +#define TD_T_SHIFT 23 /* data toggle state */ +#define TD_T_MASK 0x3 +#define TD_T (TD_T_MASK << TD_T_SHIFT) +#define TD_T_DATA0 (0x2 << TD_T_SHIFT) /* DATA0 */ +#define TD_T_DATA1 (0x3 << TD_T_SHIFT) /* DATA1 */ +#define TD_T_CARRY (0x0 << TD_T_SHIFT) /* uses ED_C */ +#define TD_T_GET(x) (((x) >> TD_T_SHIFT) & TD_T_MASK) +#define TD_DP_SHIFT 21 /* direction/pid */ +#define TD_DP_MASK 0x3 +#define TD_DP (TD_DP_MASK << TD_DP_SHIFT) +#define TD_DP_GET (((x) >> TD_DP_SHIFT) & TD_DP_MASK) +#define TD_DP_SETUP (0x0 << TD_DP_SHIFT) /* SETUP pid */ +#define TD_DP_OUT (0x1 << TD_DP_SHIFT) /* OUT pid */ +#define TD_DP_IN (0x2 << TD_DP_SHIFT) /* IN pid */ +#define TD_ISI_SHIFT 8 /* Interrupt Service Interval */ +#define TD_ISI_MASK 0x3f +#define TD_ISI_GET(x) (((x) >> TD_ISI_SHIFT) & TD_ISI_MASK) +#define TD_FN_MASK 0x3f /* frame number */ +#define TD_FN_GET(x) ((x) & TD_FN_MASK) + + __hc32 hwDBP; /* Data Buffer Pointer (or 0) */ + __hc32 hwCBL; /* Controller/Buffer Length */ + + /* hwCBL bits */ +#define TD_BL_MASK 0xffff /* buffer length */ +#define TD_BL_GET(x) ((x) & TD_BL_MASK) +#define TD_IE (1 << 16) /* interrupt enable */ + __hc32 hwNextTD; /* Next TD Pointer */ + + /* rest are purely for the driver's use */ + __u8 index; + struct ed *ed; + struct td *td_hash; /* dma-->td hashtable */ + struct td *next_dl_td; + struct urb *urb; + + dma_addr_t td_dma; /* addr of this TD */ + dma_addr_t data_dma; /* addr of data it points to */ + + struct list_head td_list; /* "shadow list", TDs on same ED */ + + u32 flags; +#define TD_FLAG_DONE (1 << 17) /* retired to done list */ +#define TD_FLAG_ISO (1 << 16) /* copy of ED_ISO */ +} __attribute__ ((aligned(TD_ALIGN))); /* c/b/i need 16; only iso needs 32 */ + +/* + * Hardware transfer status codes -- CC from td->hwINFO + */ +#define TD_CC_NOERROR 0x00 +#define TD_CC_CRC 0x01 +#define TD_CC_BITSTUFFING 0x02 +#define TD_CC_DATATOGGLEM 0x03 +#define TD_CC_STALL 0x04 +#define TD_CC_DEVNOTRESP 0x05 +#define TD_CC_PIDCHECKFAIL 0x06 +#define TD_CC_UNEXPECTEDPID 0x07 +#define TD_CC_DATAOVERRUN 0x08 +#define TD_CC_DATAUNDERRUN 0x09 + /* 0x0A, 0x0B reserved for hardware */ +#define TD_CC_BUFFEROVERRUN 0x0C +#define TD_CC_BUFFERUNDERRUN 0x0D + /* 0x0E, 0x0F reserved for HCD */ +#define TD_CC_HCD0 0x0E +#define TD_CC_NOTACCESSED 0x0F + +/* + * preshifted status codes + */ +#define TD_SCC_NOTACCESSED (TD_CC_NOTACCESSED << TD_CC_SHIFT) + + +/* map OHCI TD status codes (CC) to errno values */ +static const int cc_to_error[16] = { + /* No Error */ 0, + /* CRC Error */ -EILSEQ, + /* Bit Stuff */ -EPROTO, + /* Data Togg */ -EILSEQ, + /* Stall */ -EPIPE, + /* DevNotResp */ -ETIME, + /* PIDCheck */ -EPROTO, + /* UnExpPID */ -EPROTO, + /* DataOver */ -EOVERFLOW, + /* DataUnder */ -EREMOTEIO, + /* (for hw) */ -EIO, + /* (for hw) */ -EIO, + /* BufferOver */ -ECOMM, + /* BuffUnder */ -ENOSR, + /* (for HCD) */ -EALREADY, + /* (for HCD) */ -EALREADY +}; + +#define NUM_INTS 32 + +/* + * This is the structure of the OHCI controller's memory mapped I/O region. + * You must use readl() and writel() (in ) to access these fields!! + * Layout is in section 7 (and appendix B) of the spec. + */ +struct admhcd_regs { + __hc32 gencontrol; /* General Control */ + __hc32 int_status; /* Interrupt Status */ + __hc32 int_enable; /* Interrupt Enable */ + __hc32 reserved00; + __hc32 host_control; /* Host General Control */ + __hc32 reserved01; + __hc32 fminterval; /* Frame Interval */ + __hc32 fmnumber; /* Frame Number */ + __hc32 reserved02; + __hc32 reserved03; + __hc32 reserved04; + __hc32 reserved05; + __hc32 reserved06; + __hc32 reserved07; + __hc32 reserved08; + __hc32 reserved09; + __hc32 reserved10; + __hc32 reserved11; + __hc32 reserved12; + __hc32 reserved13; + __hc32 reserved14; + __hc32 reserved15; + __hc32 reserved16; + __hc32 reserved17; + __hc32 reserved18; + __hc32 reserved19; + __hc32 reserved20; + __hc32 reserved21; + __hc32 lsthresh; /* Low Speed Threshold */ + __hc32 rhdesc; /* Root Hub Descriptor */ +#define MAX_ROOT_PORTS 2 + __hc32 portstatus[MAX_ROOT_PORTS]; /* Port Status */ + __hc32 hosthead; /* Host Descriptor Head */ +} __attribute__ ((aligned(32))); + +/* + * General Control register bits + */ +#define ADMHC_CTRL_UHFE (1 << 0) /* USB Host Function Enable */ +#define ADMHC_CTRL_SIR (1 << 1) /* Software Interrupt request */ +#define ADMHC_CTRL_DMAA (1 << 2) /* DMA Arbitration Control */ +#define ADMHC_CTRL_SR (1 << 3) /* Software Reset */ + +/* + * Host General Control register bits + */ +#define ADMHC_HC_BUSS 0x3 /* USB bus state */ +#define ADMHC_BUSS_RESET 0x0 +#define ADMHC_BUSS_RESUME 0x1 +#define ADMHC_BUSS_OPER 0x2 +#define ADMHC_BUSS_SUSPEND 0x3 +#define ADMHC_HC_DMAE (1 << 2) /* DMA enable */ + +/* + * Interrupt Status/Enable register bits + */ +#define ADMHC_INTR_SOFI (1 << 4) /* start of frame */ +#define ADMHC_INTR_RESI (1 << 5) /* resume detected */ +#define ADMHC_INTR_6 (1 << 6) /* unknown */ +#define ADMHC_INTR_7 (1 << 7) /* unknown */ +#define ADMHC_INTR_BABI (1 << 8) /* babble detected */ +#define ADMHC_INTR_INSM (1 << 9) /* root hub status change */ +#define ADMHC_INTR_SO (1 << 10) /* scheduling overrun */ +#define ADMHC_INTR_FNO (1 << 11) /* frame number overflow */ +#define ADMHC_INTR_TDC (1 << 20) /* transfer descriptor completed */ +#define ADMHC_INTR_SWI (1 << 29) /* software interrupt */ +#define ADMHC_INTR_FATI (1 << 30) /* fatal error */ +#define ADMHC_INTR_INTA (1 << 31) /* interrupt active */ + +#define ADMHC_INTR_MIE (1 << 31) /* master interrupt enable */ + +/* + * SOF Frame Interval register bits + */ +#define ADMHC_SFI_FI_MASK ((1 << 14)-1) /* Frame Interval value */ +#define ADMHC_SFI_FSLDP_SHIFT 16 +#define ADMHC_SFI_FSLDP_MASK ((1 << 15)-1) +#define ADMHC_SFI_FIT (1 << 31) /* Frame Interval Toggle */ + +/* + * SOF Frame Number register bits + */ +#define ADMHC_SFN_FN_MASK ((1 << 16)-1) /* Frame Number Mask */ +#define ADMHC_SFN_FR_SHIFT 16 /* Frame Remaining Shift */ +#define ADMHC_SFN_FR_MASK ((1 << 14)-1) /* Frame Remaining Mask */ +#define ADMHC_SFN_FRT (1 << 31) /* Frame Remaining Toggle */ + +/* + * Root Hub Descriptor register bits + */ +#define ADMHC_RH_NUMP 0xff /* number of ports */ +#define ADMHC_RH_PSM (1 << 8) /* power switching mode */ +#define ADMHC_RH_NPS (1 << 9) /* no power switching */ +#define ADMHC_RH_OCPM (1 << 10) /* over current protection mode */ +#define ADMHC_RH_NOCP (1 << 11) /* no over current protection */ +#define ADMHC_RH_PPCM (0xff << 16) /* port power control */ + +#define ADMHC_RH_LPS (1 << 24) /* local power switch */ +#define ADMHC_RH_OCI (1 << 25) /* over current indicator */ + +/* status change bits */ +#define ADMHC_RH_LPSC (1 << 26) /* local power switch change */ +#define ADMHC_RH_OCIC (1 << 27) /* over current indicator change */ + +#define ADMHC_RH_DRWE (1 << 28) /* device remote wakeup enable */ +#define ADMHC_RH_CRWE (1 << 29) /* clear remote wakeup enable */ + +#define ADMHC_RH_CGP (1 << 24) /* clear global power */ +#define ADMHC_RH_SGP (1 << 26) /* set global power */ + +/* + * Port Status register bits + */ +#define ADMHC_PS_CCS (1 << 0) /* current connect status */ +#define ADMHC_PS_PES (1 << 1) /* port enable status */ +#define ADMHC_PS_PSS (1 << 2) /* port suspend status */ +#define ADMHC_PS_POCI (1 << 3) /* port over current indicator */ +#define ADMHC_PS_PRS (1 << 4) /* port reset status */ +#define ADMHC_PS_PPS (1 << 8) /* port power status */ +#define ADMHC_PS_LSDA (1 << 9) /* low speed device attached */ + +/* status change bits */ +#define ADMHC_PS_CSC (1 << 16) /* connect status change */ +#define ADMHC_PS_PESC (1 << 17) /* port enable status change */ +#define ADMHC_PS_PSSC (1 << 18) /* port suspend status change */ +#define ADMHC_PS_OCIC (1 << 19) /* over current indicator change */ +#define ADMHC_PS_PRSC (1 << 20) /* port reset status change */ + +/* port feature bits */ +#define ADMHC_PS_CPE (1 << 0) /* clear port enable */ +#define ADMHC_PS_SPE (1 << 1) /* set port enable */ +#define ADMHC_PS_SPS (1 << 2) /* set port suspend */ +#define ADMHC_PS_CPS (1 << 3) /* clear suspend status */ +#define ADMHC_PS_SPR (1 << 4) /* set port reset */ +#define ADMHC_PS_SPP (1 << 8) /* set port power */ +#define ADMHC_PS_CPP (1 << 9) /* clear port power */ + +/* + * the POTPGT value is not defined in the ADMHC, so define a dummy value + */ +#define ADMHC_POTPGT 2 /* in ms */ + +/* hcd-private per-urb state */ +struct urb_priv { + struct ed *ed; + struct list_head pending; /* URBs on the same ED */ + + u32 td_cnt; /* # tds in this request */ + u32 td_idx; /* index of the current td */ + struct td *td[0]; /* all TDs in this request */ +}; + +#define TD_HASH_SIZE 64 /* power'o'two */ +/* sizeof (struct td) ~= 64 == 2^6 ... */ +#define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 6)) % TD_HASH_SIZE) + +/* + * This is the full ADMHCD controller description + * + * Note how the "proper" USB information is just + * a subset of what the full implementation needs. (Linus) + */ + +struct admhcd { + spinlock_t lock; + + /* + * I/O memory used to communicate with the HC (dma-consistent) + */ + struct admhcd_regs __iomem *regs; + + /* + * hcd adds to schedule for a live hc any time, but removals finish + * only at the start of the next frame. + */ + + struct ed *ed_head; + struct ed *ed_tails[4]; + + struct ed *ed_rm_list; /* to be removed */ + + struct ed *periodic[NUM_INTS]; /* shadow int_table */ + +#if 0 /* TODO: remove? */ + /* + * OTG controllers and transceivers need software interaction; + * other external transceivers should be software-transparent + */ + struct otg_transceiver *transceiver; + void (*start_hnp)(struct admhcd *ahcd); +#endif + + /* + * memory management for queue data structures + */ + struct dma_pool *td_cache; + struct dma_pool *ed_cache; + struct td *td_hash[TD_HASH_SIZE]; + struct list_head pending; + + /* + * driver state + */ + int num_ports; + int load[NUM_INTS]; + u32 host_control; /* copy of the host_control reg */ + unsigned long next_statechange; /* suspend/resume */ + u32 fminterval; /* saved register */ + unsigned autostop:1; /* rh auto stopping/stopped */ + + unsigned long flags; /* for HC bugs */ +#define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ +#define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ +#define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */ +#define OHCI_QUIRK_BE_DESC 0x08 /* BE descriptors */ +#define OHCI_QUIRK_BE_MMIO 0x10 /* BE registers */ +#define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ + /* there are also chip quirks/bugs in init logic */ + +#ifdef DEBUG + struct dentry *debug_dir; + struct dentry *debug_async; + struct dentry *debug_periodic; + struct dentry *debug_registers; +#endif +}; + +/* convert between an hcd pointer and the corresponding ahcd_hcd */ +static inline struct admhcd *hcd_to_admhcd(struct usb_hcd *hcd) +{ + return (struct admhcd *)(hcd->hcd_priv); +} +static inline struct usb_hcd *admhcd_to_hcd(const struct admhcd *ahcd) +{ + return container_of((void *)ahcd, struct usb_hcd, hcd_priv); +} + +/*-------------------------------------------------------------------------*/ + +#ifndef DEBUG +#define STUB_DEBUG_FILES +#endif /* DEBUG */ + +#ifdef DEBUG +# define admhc_dbg(ahcd, fmt, args...) \ + printk(KERN_DEBUG "adm5120-hcd: " fmt, ## args) +#else +# define admhc_dbg(ahcd, fmt, args...) do { } while (0) +#endif + +#define admhc_err(ahcd, fmt, args...) \ + printk(KERN_ERR "adm5120-hcd: " fmt, ## args) +#define admhc_info(ahcd, fmt, args...) \ + printk(KERN_INFO "adm5120-hcd: " fmt, ## args) +#define admhc_warn(ahcd, fmt, args...) \ + printk(KERN_WARNING "adm5120-hcd: " fmt, ## args) + +#ifdef ADMHC_VERBOSE_DEBUG +# define admhc_vdbg admhc_dbg +#else +# define admhc_vdbg(ahcd, fmt, args...) do { } while (0) +#endif + +/*-------------------------------------------------------------------------*/ + +/* + * While most USB host controllers implement their registers and + * in-memory communication descriptors in little-endian format, + * a minority (notably the IBM STB04XXX and the Motorola MPC5200 + * processors) implement them in big endian format. + * + * In addition some more exotic implementations like the Toshiba + * Spider (aka SCC) cell southbridge are "mixed" endian, that is, + * they have a different endianness for registers vs. in-memory + * descriptors. + * + * This attempts to support either format at compile time without a + * runtime penalty, or both formats with the additional overhead + * of checking a flag bit. + * + * That leads to some tricky Kconfig rules howevber. There are + * different defaults based on some arch/ppc platforms, though + * the basic rules are: + * + * Controller type Kconfig options needed + * --------------- ---------------------- + * little endian CONFIG_USB_ADMHC_LITTLE_ENDIAN + * + * fully big endian CONFIG_USB_ADMHC_BIG_ENDIAN_DESC _and_ + * CONFIG_USB_ADMHC_BIG_ENDIAN_MMIO + * + * mixed endian CONFIG_USB_ADMHC_LITTLE_ENDIAN _and_ + * CONFIG_USB_OHCI_BIG_ENDIAN_{MMIO,DESC} + * + * (If you have a mixed endian controller, you -must- also define + * CONFIG_USB_ADMHC_LITTLE_ENDIAN or things will not work when building + * both your mixed endian and a fully big endian controller support in + * the same kernel image). + */ + +#ifdef CONFIG_USB_ADMHC_BIG_ENDIAN_DESC +#ifdef CONFIG_USB_ADMHC_LITTLE_ENDIAN +#define big_endian_desc(ahcd) (ahcd->flags & OHCI_QUIRK_BE_DESC) +#else +#define big_endian_desc(ahcd) 1 /* only big endian */ +#endif +#else +#define big_endian_desc(ahcd) 0 /* only little endian */ +#endif + +#ifdef CONFIG_USB_ADMHC_BIG_ENDIAN_MMIO +#ifdef CONFIG_USB_ADMHC_LITTLE_ENDIAN +#define big_endian_mmio(ahcd) (ahcd->flags & OHCI_QUIRK_BE_MMIO) +#else +#define big_endian_mmio(ahcd) 1 /* only big endian */ +#endif +#else +#define big_endian_mmio(ahcd) 0 /* only little endian */ +#endif + +/* + * Big-endian read/write functions are arch-specific. + * Other arches can be added if/when they're needed. + * + */ +static inline unsigned int admhc_readl(const struct admhcd *ahcd, + __hc32 __iomem *regs) +{ +#ifdef CONFIG_USB_ADMHC_BIG_ENDIAN_MMIO + return big_endian_mmio(ahcd) ? + readl_be(regs) : + readl(regs); +#else + return readl(regs); +#endif +} + +static inline void admhc_writel(const struct admhcd *ahcd, + const unsigned int val, __hc32 __iomem *regs) +{ +#ifdef CONFIG_USB_ADMHC_BIG_ENDIAN_MMIO + big_endian_mmio(ahcd) ? + writel_be(val, regs) : + writel(val, regs); +#else + writel(val, regs); +#endif +} + +static inline void admhc_writel_flush(const struct admhcd *ahcd) +{ +#if 0 + /* TODO: remove? */ + (void) admhc_readl(ahcd, &ahcd->regs->gencontrol); +#endif +} + + +/*-------------------------------------------------------------------------*/ + +/* cpu to ahcd */ +static inline __hc16 cpu_to_hc16(const struct admhcd *ahcd, const u16 x) +{ + return big_endian_desc(ahcd) ? + (__force __hc16)cpu_to_be16(x) : + (__force __hc16)cpu_to_le16(x); +} + +static inline __hc16 cpu_to_hc16p(const struct admhcd *ahcd, const u16 *x) +{ + return big_endian_desc(ahcd) ? + cpu_to_be16p(x) : + cpu_to_le16p(x); +} + +static inline __hc32 cpu_to_hc32(const struct admhcd *ahcd, const u32 x) +{ + return big_endian_desc(ahcd) ? + (__force __hc32)cpu_to_be32(x) : + (__force __hc32)cpu_to_le32(x); +} + +static inline __hc32 cpu_to_hc32p(const struct admhcd *ahcd, const u32 *x) +{ + return big_endian_desc(ahcd) ? + cpu_to_be32p(x) : + cpu_to_le32p(x); +} + +/* ahcd to cpu */ +static inline u16 hc16_to_cpu(const struct admhcd *ahcd, const __hc16 x) +{ + return big_endian_desc(ahcd) ? + be16_to_cpu((__force __be16)x) : + le16_to_cpu((__force __le16)x); +} + +static inline u16 hc16_to_cpup(const struct admhcd *ahcd, const __hc16 *x) +{ + return big_endian_desc(ahcd) ? + be16_to_cpup((__force __be16 *)x) : + le16_to_cpup((__force __le16 *)x); +} + +static inline u32 hc32_to_cpu(const struct admhcd *ahcd, const __hc32 x) +{ + return big_endian_desc(ahcd) ? + be32_to_cpu((__force __be32)x) : + le32_to_cpu((__force __le32)x); +} + +static inline u32 hc32_to_cpup(const struct admhcd *ahcd, const __hc32 *x) +{ + return big_endian_desc(ahcd) ? + be32_to_cpup((__force __be32 *)x) : + le32_to_cpup((__force __le32 *)x); +} + +/*-------------------------------------------------------------------------*/ + +static inline u16 admhc_frame_no(const struct admhcd *ahcd) +{ + u32 t; + + t = admhc_readl(ahcd, &ahcd->regs->fmnumber) & ADMHC_SFN_FN_MASK; + return (u16)t; +} + +static inline u16 admhc_frame_remain(const struct admhcd *ahcd) +{ + u32 t; + + t = admhc_readl(ahcd, &ahcd->regs->fmnumber) >> ADMHC_SFN_FR_SHIFT; + t &= ADMHC_SFN_FR_MASK; + return (u16)t; +} + +/*-------------------------------------------------------------------------*/ + +static inline void admhc_disable(struct admhcd *ahcd) +{ + admhcd_to_hcd(ahcd)->state = HC_STATE_HALT; +} + +#define FI 0x2edf /* 12000 bits per frame (-1) */ +#define FSLDP(fi) (0x7fff & ((6 * ((fi) - 1200)) / 7)) +#define FIT ADMHC_SFI_FIT +#define LSTHRESH 0x628 /* lowspeed bit threshold */ + +static inline void periodic_reinit(struct admhcd *ahcd) +{ +#if 0 + u32 fi = ahcd->fminterval & ADMHC_SFI_FI_MASK; + u32 fit = admhc_readl(ahcd, &ahcd->regs->fminterval) & FIT; + + /* TODO: adjust FSLargestDataPacket value too? */ + admhc_writel(ahcd, (fit ^ FIT) | ahcd->fminterval, + &ahcd->regs->fminterval); +#else + u32 fit = admhc_readl(ahcd, &ahcd->regs->fminterval) & FIT; + + /* TODO: adjust FSLargestDataPacket value too? */ + admhc_writel(ahcd, (fit ^ FIT) | ahcd->fminterval, + &ahcd->regs->fminterval); +#endif +} + +static inline u32 admhc_read_rhdesc(struct admhcd *ahcd) +{ + return admhc_readl(ahcd, &ahcd->regs->rhdesc); +} + +static inline u32 admhc_read_portstatus(struct admhcd *ahcd, int port) +{ + return admhc_readl(ahcd, &ahcd->regs->portstatus[port]); +} + +static inline void admhc_write_portstatus(struct admhcd *ahcd, int port, + u32 value) +{ + admhc_writel(ahcd, value, &ahcd->regs->portstatus[port]); +} + +static inline void roothub_write_status(struct admhcd *ahcd, u32 value) +{ + /* FIXME: read-only bits must be masked out */ + admhc_writel(ahcd, value, &ahcd->regs->rhdesc); +} + +static inline void admhc_intr_disable(struct admhcd *ahcd, u32 ints) +{ + u32 t; + + t = admhc_readl(ahcd, &ahcd->regs->int_enable); + t &= ~(ints); + admhc_writel(ahcd, t, &ahcd->regs->int_enable); + /* TODO: flush writes ?*/ +} + +static inline void admhc_intr_enable(struct admhcd *ahcd, u32 ints) +{ + u32 t; + + t = admhc_readl(ahcd, &ahcd->regs->int_enable); + t |= ints; + admhc_writel(ahcd, t, &ahcd->regs->int_enable); + /* TODO: flush writes ?*/ +} + +static inline void admhc_intr_ack(struct admhcd *ahcd, u32 ints) +{ + admhc_writel(ahcd, ints, &ahcd->regs->int_status); +} + +static inline void admhc_dma_enable(struct admhcd *ahcd) +{ + u32 t; + + t = admhc_readl(ahcd, &ahcd->regs->host_control); + if (t & ADMHC_HC_DMAE) + return; + + t |= ADMHC_HC_DMAE; + admhc_writel(ahcd, t, &ahcd->regs->host_control); + admhc_vdbg(ahcd, "DMA enabled\n"); +} + +static inline void admhc_dma_disable(struct admhcd *ahcd) +{ + u32 t; + + t = admhc_readl(ahcd, &ahcd->regs->host_control); + if (!(t & ADMHC_HC_DMAE)) + return; + + t &= ~ADMHC_HC_DMAE; + admhc_writel(ahcd, t, &ahcd->regs->host_control); + admhc_vdbg(ahcd, "DMA disabled\n"); +} diff --git a/target/linux/adm5120/files/drivers/watchdog/adm5120_wdt.c b/target/linux/adm5120/files/drivers/watchdog/adm5120_wdt.c new file mode 100644 index 000000000..d5d63b27a --- /dev/null +++ b/target/linux/adm5120/files/drivers/watchdog/adm5120_wdt.c @@ -0,0 +1,202 @@ +/* + * ADM5120_WDT 0.01: Infineon ADM5120 SoC watchdog driver + * Copyright (c) Ondrej Zajicek , 2007 + * + * based on + * + * RC32434_WDT 0.01: IDT Interprise 79RC32434 watchdog 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. + * + */ +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#define DEFAULT_TIMEOUT 15 /* (secs) Default is 15 seconds */ +#define MAX_TIMEOUT 327 +/* Max is 327 seconds, counter is 15-bit integer, step is 10 ms */ + +#define NAME "adm5120_wdt" +#define VERSION "0.1" + +static int expect_close; +static int access; +static unsigned int timeout = DEFAULT_TIMEOUT; + +static int nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); +MODULE_LICENSE("GPL"); + + +static inline void wdt_set_timeout(void) +{ + u32 val = (1 << 31) | (((timeout * 100) & 0x7FFF) << 16); + SW_WRITE_REG(SWITCH_REG_WDOG0, val); +} + +/* + It looks like WDOG0-register-write don't modify counter, + but WDOG0-register-read resets counter. +*/ + +static inline void wdt_reset_counter(void) +{ + SW_READ_REG(SWITCH_REG_WDOG0); +} + +static inline void wdt_disable(void) +{ + SW_WRITE_REG(SWITCH_REG_WDOG0, 0x7FFF0000); +} + + + +static int wdt_open(struct inode *inode, struct file *file) +{ + /* Allow only one person to hold it open */ + if (access) + return -EBUSY; + + if (nowayout) + __module_get(THIS_MODULE); + + /* Activate timer */ + wdt_reset_counter(); + wdt_set_timeout(); + printk(KERN_INFO NAME ": enabling watchdog timer\n"); + access = 1; + return 0; +} + +static int wdt_release(struct inode *inode, struct file *file) +{ + /* + * Shut off the timer. + * Lock it in if it's a module and we set nowayout + */ + if (expect_close && (nowayout == 0)) { + wdt_disable(); + printk(KERN_INFO NAME ": disabling watchdog timer\n"); + module_put(THIS_MODULE); + } else + printk(KERN_CRIT NAME ": device closed unexpectedly. WDT will not stop!\n"); + + access = 0; + return 0; +} + +static ssize_t wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) +{ + /* Refresh the timer. */ + if (len) { + if (!nowayout) { + size_t i; + + /* In case it was set long ago */ + expect_close = 0; + + for (i = 0; i != len; i++) { + char c; + if (get_user(c, data + i)) + return -EFAULT; + if (c == 'V') + expect_close = 1; + } + } + wdt_reset_counter(); + return len; + } + return 0; +} + +static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int new_timeout; + static struct watchdog_info ident = { + .options = WDIOF_SETTIMEOUT | + WDIOF_KEEPALIVEPING | + WDIOF_MAGICCLOSE, + .firmware_version = 0, + .identity = "ADM5120_WDT Watchdog", + }; + switch (cmd) { + default: + return -ENOTTY; + case WDIOC_GETSUPPORT: + if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))) + return -EFAULT; + return 0; + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + return put_user(0, (int *)arg); + case WDIOC_KEEPALIVE: + wdt_reset_counter(); + return 0; + case WDIOC_SETTIMEOUT: + if (get_user(new_timeout, (int *)arg)) + return -EFAULT; + if (new_timeout < 1) + return -EINVAL; + if (new_timeout > MAX_TIMEOUT) + return -EINVAL; + timeout = new_timeout; + wdt_set_timeout(); + /* Fall */ + case WDIOC_GETTIMEOUT: + return put_user(timeout, (int *)arg); + } +} + +static const struct file_operations wdt_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = wdt_write, + .unlocked_ioctl = wdt_ioctl, + .open = wdt_open, + .release = wdt_release, +}; + +static struct miscdevice wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &wdt_fops, +}; + +static char banner[] __initdata = KERN_INFO NAME ": Watchdog Timer version " VERSION "\n"; + +static int __init watchdog_init(void) +{ + int ret; + + ret = misc_register(&wdt_miscdev); + + if (ret) + return ret; + + wdt_disable(); + printk(banner); + + return 0; +} + +static void __exit watchdog_exit(void) +{ + misc_deregister(&wdt_miscdev); +} + +module_init(watchdog_init); +module_exit(watchdog_exit); diff --git a/target/linux/adm5120/image/Makefile b/target/linux/adm5120/image/Makefile new file mode 100644 index 000000000..7ced198a2 --- /dev/null +++ b/target/linux/adm5120/image/Makefile @@ -0,0 +1,116 @@ +# +# Copyright (C) 2006-2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/image.mk + +LOADER_MAKE := $(NO_TRACE_MAKE) -C lzma-loader KDIR=$(KDIR) +JFFS2BLOCK := $(KDIR)/jffs2.block +JFFS2MARK := $(KDIR)/jffs2.mark + +define imgname +$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(patsubst jffs2-%,jffs2,$(1)) +endef + +VMLINUX:=$(BIN_DIR)/$(IMG_PREFIX)-vmlinux +fs_squash:=squashfs-only +fs_all:=all +fs_4k:=4k +fs_64k:=64k +fs_128k:=128k +ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y) + fs_squash:=initramfs + fs_all:=initramfs + fs_4k:=initramfs + fs_64k:=initramfs + fs_128k:=initramfs + VMLINUX:=$(BIN_DIR)/$(IMG_PREFIX)-vmlinux-initramfs +endif + +define Build/Clean + $(LOADER_MAKE) clean +endef + +define Image/Prepare + cat $(KDIR)/vmlinux | $(STAGING_DIR_HOST)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma + rm -f $(JFFS2BLOCK) + touch $(JFFS2BLOCK) + $(call prepare_generic_squashfs,$(JFFS2BLOCK)) + rm -f $(JFFS2MARK) + touch $(JFFS2MARK) + $(call add_jffs2_mark,$(JFFS2MARK)) +endef + +define Image/Build/Loader + $(LOADER_MAKE) LOADER=loader-$(1).$(2) LOADER_DATA="" \ + LZMA_TEXT_START=$(3) LZMA_STARTUP_ORG=$(4) \ + CONFIG_PASS_KARGS=$(5) CONFIG_BOARD=$(6) \ + compile loader.$(2) +endef + +define Image/Build/LZMAKernel + $(LOADER_MAKE) TARGET_DIR=$(BIN_DIR) \ + LOADER=$(BIN_DIR)/$(IMG_PREFIX)-$(1)-ramfs.$(2) \ + LOADER_DATA=$(KDIR)/vmlinux.lzma \ + LZMA_TEXT_START=$(3) LZMA_STARTUP_ORG=$(4) \ + CONFIG_PASS_KARGS=$(5) CONFIG_BOARD=$(6) \ + compile loader.$(2) +endef + +define Image/Build/LZMAKernel/Generic + $(call Image/Build/LZMAKernel,$(1),$(2),0x80500000,0) +endef + +define Image/Build/LZMAKernel/Admboot + $(call Image/Build/LZMAKernel,$(1),$(2),0x80500000,0x6D8,y,$(1)) +endef + +define Image/Build/LZMAKernel/Cellvision + $(call Image/Build/LZMAKernel,$(1),$(3),0x80500000,0x6D8,y,$(2)) +endef + +define Image/Build/LZMAKernel/KArgs + $(call Image/Build/LZMAKernel,$(1),$(2),0x80500000,0,y,$(1)) +endef + +define trxalign/jffs2-128k +-a 0x20000 -f $(KDIR)/root.jffs2-128k +endef + +define trxalign/jffs2-64k +-a 0x10000 -f $(KDIR)/root.jffs2-64k +endef + +define trxalign/squashfs +-a 1024 -f $(KDIR)/root.squashfs -a 0x10000 -A $(JFFS2BLOCK) +endef + +define Image/Build/TRX + $(STAGING_DIR_HOST)/bin/trx -o $(1) -f $(3) -f $(KDIR)/vmlinux.lzma \ + $(call trxalign/$(2)) +endef + +define Image/Build/TRXNoloader + $(STAGING_DIR_HOST)/bin/trx -o $(1) -f $(KDIR)/vmlinux.lzma \ + $(call trxalign/$(2)) +endef + +include $(SUBTARGET).mk + +define Image/Build + $(call Image/Build/Profile/$(PROFILE),$(1)) +endef + +define Image/Build/Initramfs + $(call Image/Build/Profile/$(PROFILE),Initramfs) +endef + +define Image/BuildKernel + cp $(KDIR)/vmlinux.elf $(VMLINUX).elf + cp $(KDIR)/vmlinux $(VMLINUX).bin +endef + +$(eval $(call BuildImage)) diff --git a/target/linux/adm5120/image/lzma-loader/Makefile b/target/linux/adm5120/image/lzma-loader/Makefile new file mode 100644 index 000000000..36dfd09ea --- /dev/null +++ b/target/linux/adm5120/image/lzma-loader/Makefile @@ -0,0 +1,62 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +LOADER := loader.bin +LOADER_NAME := $(basename $(notdir $(LOADER))) +LOADER_DATA := +TARGET_DIR := + +ifeq ($(TARGET_DIR),) +TARGET_DIR := $(KDIR) +endif + +LOADER_BIN := $(TARGET_DIR)/$(LOADER_NAME).bin +LOADER_GZ := $(TARGET_DIR)/$(LOADER_NAME).gz +LOADER_ELF := $(TARGET_DIR)/$(LOADER_NAME).elf + +LZMA_STARTUP_ORG:= 0 +LZMA_TEXT_START := 0x80300000 + +PKG_NAME := lzma-loader +PKG_BUILD_DIR := $(KDIR)/$(PKG_NAME) + +.PHONY : loader-compile loader.bin loader.elf loader.gz + +$(PKG_BUILD_DIR)/.prepared: + mkdir $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ + touch $@ + +loader-compile: $(PKG_BUILD_DIR)/.prepared + $(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE="$(TARGET_CROSS)" \ + LZMA_STARTUP_ORG=$(LZMA_STARTUP_ORG) \ + LZMA_TEXT_START=$(LZMA_TEXT_START) \ + LOADER_DATA=$(LOADER_DATA) \ + CONFIG_BOARD=$(CONFIG_BOARD) \ + CONFIG_PASS_KARGS=$(CONFIG_PASS_KARGS) \ + clean all + +loader.gz: $(PKG_BUILD_DIR)/loader.bin + gzip -nc9 $< > $(LOADER_GZ) + +loader.elf: $(PKG_BUILD_DIR)/loader.elf + $(CP) $< $(LOADER_ELF) + +loader.bin: $(PKG_BUILD_DIR)/loader.bin + $(CP) $< $(LOADER_BIN) + +download: +prepare: $(PKG_BUILD_DIR)/.prepared +compile: loader-compile + +install: + +clean: + rm -rf $(PKG_BUILD_DIR) + diff --git a/target/linux/adm5120/image/lzma-loader/src/LzmaDecode.c b/target/linux/adm5120/image/lzma-loader/src/LzmaDecode.c new file mode 100644 index 000000000..cb8345377 --- /dev/null +++ b/target/linux/adm5120/image/lzma-loader/src/LzmaDecode.c @@ -0,0 +1,584 @@ +/* + LzmaDecode.c + LZMA Decoder (optimized for Speed version) + + LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this Code, expressly permits you to + statically or dynamically link your Code (or bind by name) to the + interfaces of this file without subjecting your linked Code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#include "LzmaDecode.h" + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_READ_BYTE (*Buffer++) + +#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ + { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} + +#ifdef _LZMA_IN_CB + +#define RC_TEST { if (Buffer == BufferLim) \ + { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \ + BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }} + +#define RC_INIT Buffer = BufferLim = 0; RC_INIT2 + +#else + +#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } + +#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 + +#endif + +#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } + +#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) +#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; +#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; + +#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ + { UpdateBit0(p); mi <<= 1; A0; } else \ + { UpdateBit1(p); mi = (mi + mi) + 1; A1; } + +#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) + +#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ + { int i = numLevels; res = 1; \ + do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ + res -= (1 << numLevels); } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) +{ + unsigned char prop0; + if (size < LZMA_PROPERTIES_SIZE) + return LZMA_RESULT_DATA_ERROR; + prop0 = propsData[0]; + if (prop0 >= (9 * 5 * 5)) + return LZMA_RESULT_DATA_ERROR; + { + for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); + for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); + propsRes->lc = prop0; + /* + unsigned char remainder = (unsigned char)(prop0 / 9); + propsRes->lc = prop0 % 9; + propsRes->pb = remainder / 5; + propsRes->lp = remainder % 5; + */ + } + + #ifdef _LZMA_OUT_READ + { + int i; + propsRes->DictionarySize = 0; + for (i = 0; i < 4; i++) + propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); + if (propsRes->DictionarySize == 0) + propsRes->DictionarySize = 1; + } + #endif + return LZMA_RESULT_OK; +} + +#define kLzmaStreamWasFinishedId (-1) + +int LzmaDecode(CLzmaDecoderState *vs, + #ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback, + #else + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + #endif + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) +{ + CProb *p = vs->Probs; + SizeT nowPos = 0; + Byte previousByte = 0; + UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; + UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; + int lc = vs->Properties.lc; + + #ifdef _LZMA_OUT_READ + + UInt32 Range = vs->Range; + UInt32 Code = vs->Code; + #ifdef _LZMA_IN_CB + const Byte *Buffer = vs->Buffer; + const Byte *BufferLim = vs->BufferLim; + #else + const Byte *Buffer = inStream; + const Byte *BufferLim = inStream + inSize; + #endif + int state = vs->State; + UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; + int len = vs->RemainLen; + UInt32 globalPos = vs->GlobalPos; + UInt32 distanceLimit = vs->DistanceLimit; + + Byte *dictionary = vs->Dictionary; + UInt32 dictionarySize = vs->Properties.DictionarySize; + UInt32 dictionaryPos = vs->DictionaryPos; + + Byte tempDictionary[4]; + + #ifndef _LZMA_IN_CB + *inSizeProcessed = 0; + #endif + *outSizeProcessed = 0; + if (len == kLzmaStreamWasFinishedId) + return LZMA_RESULT_OK; + + if (dictionarySize == 0) + { + dictionary = tempDictionary; + dictionarySize = 1; + tempDictionary[0] = vs->TempDictionary[0]; + } + + if (len == kLzmaNeedInitId) + { + { + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + UInt32 i; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + rep0 = rep1 = rep2 = rep3 = 1; + state = 0; + globalPos = 0; + distanceLimit = 0; + dictionaryPos = 0; + dictionary[dictionarySize - 1] = 0; + #ifdef _LZMA_IN_CB + RC_INIT; + #else + RC_INIT(inStream, inSize); + #endif + } + len = 0; + } + while(len != 0 && nowPos < outSize) + { + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + len--; + } + if (dictionaryPos == 0) + previousByte = dictionary[dictionarySize - 1]; + else + previousByte = dictionary[dictionaryPos - 1]; + + #else /* if !_LZMA_OUT_READ */ + + int state = 0; + UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; + int len = 0; + const Byte *Buffer; + const Byte *BufferLim; + UInt32 Range; + UInt32 Code; + + #ifndef _LZMA_IN_CB + *inSizeProcessed = 0; + #endif + *outSizeProcessed = 0; + + { + UInt32 i; + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + } + + #ifdef _LZMA_IN_CB + RC_INIT; + #else + RC_INIT(inStream, inSize); + #endif + + #endif /* _LZMA_OUT_READ */ + + while(nowPos < outSize) + { + CProb *prob; + UInt32 bound; + int posState = (int)( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & posStateMask); + + prob = p + IsMatch + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + int symbol = 1; + UpdateBit0(prob) + prob = p + Literal + (LZMA_LIT_SIZE * + ((( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & literalPosMask) << lc) + (previousByte >> (8 - lc)))); + + if (state >= kNumLitStates) + { + int matchByte; + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + matchByte = dictionary[pos]; + #else + matchByte = outStream[nowPos - rep0]; + #endif + do + { + int bit; + CProb *probLit; + matchByte <<= 1; + bit = (matchByte & 0x100); + probLit = prob + 0x100 + bit + symbol; + RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) + } + while (symbol < 0x100); + } + while (symbol < 0x100) + { + CProb *probLit = prob + symbol; + RC_GET_BIT(probLit, symbol) + } + previousByte = (Byte)symbol; + + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + if (distanceLimit < dictionarySize) + distanceLimit++; + + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #endif + if (state < 4) state = 0; + else if (state < 10) state -= 3; + else state -= 6; + } + else + { + UpdateBit1(prob); + prob = p + IsRep + state; + IfBit0(prob) + { + UpdateBit0(prob); + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + state = state < kNumLitStates ? 0 : 3; + prob = p + LenCoder; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG0 + state; + IfBit0(prob) + { + UpdateBit0(prob); + prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + #ifdef _LZMA_OUT_READ + UInt32 pos; + #endif + UpdateBit0(prob); + + #ifdef _LZMA_OUT_READ + if (distanceLimit == 0) + #else + if (nowPos == 0) + #endif + return LZMA_RESULT_DATA_ERROR; + + state = state < kNumLitStates ? 9 : 11; + #ifdef _LZMA_OUT_READ + pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + if (distanceLimit < dictionarySize) + distanceLimit++; + #endif + + continue; + } + else + { + UpdateBit1(prob); + } + } + else + { + UInt32 distance; + UpdateBit1(prob); + prob = p + IsRepG1 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep1; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG2 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep2; + } + else + { + UpdateBit1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = p + RepLenCoder; + } + { + int numBits, offset; + CProb *probLen = prob + LenChoice; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + numBits = kLenNumLowBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenChoice2; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + numBits = kLenNumMidBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + numBits = kLenNumHighBits; + } + } + RangeDecoderBitTreeDecode(probLen, numBits, len); + len += offset; + } + + if (state < 4) + { + int posSlot; + state += kNumLitStates; + prob = p + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + rep0 = (2 | ((UInt32)posSlot & 1)); + if (posSlot < kEndPosModelIndex) + { + rep0 <<= numDirectBits; + prob = p + SpecPos + rep0 - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + RC_NORMALIZE + Range >>= 1; + rep0 <<= 1; + if (Code >= Range) + { + Code -= Range; + rep0 |= 1; + } + } + while (--numDirectBits != 0); + prob = p + Align; + rep0 <<= kNumAlignBits; + numDirectBits = kNumAlignBits; + } + { + int i = 1; + int mi = 1; + do + { + CProb *prob3 = prob + mi; + RC_GET_BIT2(prob3, mi, ; , rep0 |= i); + i <<= 1; + } + while(--numDirectBits != 0); + } + } + else + rep0 = posSlot; + if (++rep0 == (UInt32)(0)) + { + /* it's for stream version */ + len = kLzmaStreamWasFinishedId; + break; + } + } + + len += kMatchMinLen; + #ifdef _LZMA_OUT_READ + if (rep0 > distanceLimit) + #else + if (rep0 > nowPos) + #endif + return LZMA_RESULT_DATA_ERROR; + + #ifdef _LZMA_OUT_READ + if (dictionarySize - distanceLimit > (UInt32)len) + distanceLimit += len; + else + distanceLimit = dictionarySize; + #endif + + do + { + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + len--; + outStream[nowPos++] = previousByte; + } + while(len != 0 && nowPos < outSize); + } + } + RC_NORMALIZE; + + #ifdef _LZMA_OUT_READ + vs->Range = Range; + vs->Code = Code; + vs->DictionaryPos = dictionaryPos; + vs->GlobalPos = globalPos + (UInt32)nowPos; + vs->DistanceLimit = distanceLimit; + vs->Reps[0] = rep0; + vs->Reps[1] = rep1; + vs->Reps[2] = rep2; + vs->Reps[3] = rep3; + vs->State = state; + vs->RemainLen = len; + vs->TempDictionary[0] = tempDictionary[0]; + #endif + + #ifdef _LZMA_IN_CB + vs->Buffer = Buffer; + vs->BufferLim = BufferLim; + #else + *inSizeProcessed = (SizeT)(Buffer - inStream); + #endif + *outSizeProcessed = nowPos; + return LZMA_RESULT_OK; +} diff --git a/target/linux/adm5120/image/lzma-loader/src/LzmaDecode.h b/target/linux/adm5120/image/lzma-loader/src/LzmaDecode.h new file mode 100644 index 000000000..2870eeb9c --- /dev/null +++ b/target/linux/adm5120/image/lzma-loader/src/LzmaDecode.h @@ -0,0 +1,113 @@ +/* + LzmaDecode.h + LZMA Decoder interface + + LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to the + interfaces of this file without subjecting your linked code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#ifndef __LZMADECODE_H +#define __LZMADECODE_H + +#include "LzmaTypes.h" + +/* #define _LZMA_IN_CB */ +/* Use callback for input data */ + +/* #define _LZMA_OUT_READ */ +/* Use read function for output data */ + +/* #define _LZMA_PROB32 */ +/* It can increase speed on some 32-bit CPUs, + but memory usage will be doubled in that case */ + +/* #define _LZMA_LOC_OPT */ +/* Enable local speed optimizations inside code */ + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb UInt16 +#endif + +#define LZMA_RESULT_OK 0 +#define LZMA_RESULT_DATA_ERROR 1 + +#ifdef _LZMA_IN_CB +typedef struct _ILzmaInCallback +{ + int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize); +} ILzmaInCallback; +#endif + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LZMA_PROPERTIES_SIZE 5 + +typedef struct _CLzmaProperties +{ + int lc; + int lp; + int pb; + #ifdef _LZMA_OUT_READ + UInt32 DictionarySize; + #endif +}CLzmaProperties; + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); + +#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) + +#define kLzmaNeedInitId (-2) + +typedef struct _CLzmaDecoderState +{ + CLzmaProperties Properties; + CProb *Probs; + + #ifdef _LZMA_IN_CB + const unsigned char *Buffer; + const unsigned char *BufferLim; + #endif + + #ifdef _LZMA_OUT_READ + unsigned char *Dictionary; + UInt32 Range; + UInt32 Code; + UInt32 DictionaryPos; + UInt32 GlobalPos; + UInt32 DistanceLimit; + UInt32 Reps[4]; + int State; + int RemainLen; + unsigned char TempDictionary[4]; + #endif +} CLzmaDecoderState; + +#ifdef _LZMA_OUT_READ +#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; } +#endif + +int LzmaDecode(CLzmaDecoderState *vs, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback, + #else + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + #endif + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); + +#endif diff --git a/target/linux/adm5120/image/lzma-loader/src/LzmaTypes.h b/target/linux/adm5120/image/lzma-loader/src/LzmaTypes.h new file mode 100644 index 000000000..9c2729075 --- /dev/null +++ b/target/linux/adm5120/image/lzma-loader/src/LzmaTypes.h @@ -0,0 +1,45 @@ +/* +LzmaTypes.h + +Types for LZMA Decoder + +This file written and distributed to public domain by Igor Pavlov. +This file is part of LZMA SDK 4.40 (2006-05-01) +*/ + +#ifndef __LZMATYPES_H +#define __LZMATYPES_H + +#ifndef _7ZIP_BYTE_DEFINED +#define _7ZIP_BYTE_DEFINED +typedef unsigned char Byte; +#endif + +#ifndef _7ZIP_UINT16_DEFINED +#define _7ZIP_UINT16_DEFINED +typedef unsigned short UInt16; +#endif + +#ifndef _7ZIP_UINT32_DEFINED +#define _7ZIP_UINT32_DEFINED +#ifdef _LZMA_UINT32_IS_ULONG +typedef unsigned long UInt32; +#else +typedef unsigned int UInt32; +#endif +#endif + +/* #define _LZMA_NO_SYSTEM_SIZE_T */ +/* You can use it, if you don't want */ + +#ifndef _7ZIP_SIZET_DEFINED +#define _7ZIP_SIZET_DEFINED +#ifdef _LZMA_NO_SYSTEM_SIZE_T +typedef UInt32 SizeT; +#else +#include +typedef size_t SizeT; +#endif +#endif + +#endif diff --git a/target/linux/adm5120/image/lzma-loader/src/Makefile b/target/linux/adm5120/image/lzma-loader/src/Makefile new file mode 100644 index 000000000..f23d040cd --- /dev/null +++ b/target/linux/adm5120/image/lzma-loader/src/Makefile @@ -0,0 +1,99 @@ +# +# Makefile for Broadcom BCM947XX boards +# +# Copyright 2001-2003, Broadcom Corporation +# All Rights Reserved. +# +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. +# +# Copyright 2004 Manuel Novoa III +# Modified to support bzip'd kernels. +# Of course, it would be better to integrate bunzip capability into CFE. +# +# Copyright 2005 Oleg I. Vdovikin +# Cleaned up, modified for lzma support, removed from kernel +# +# Copyright 2007 Gabor Juhos +# Modified to support user defined entry point address. +# Added support for make targets with different names +# + +LOADADDR := 0x80001000 +LZMA_TEXT_START := 0x80500000 +LZMA_STARTUP_ORG:= 0 +LOADER_DATA := +CONFIG_PASS_KARGS := +CONFIG_BOARD := + +CC := $(CROSS_COMPILE)gcc +LD := $(CROSS_COMPILE)ld +OBJCOPY := $(CROSS_COMPILE)objcopy +OBJDUMP := $(CROSS_COMPILE)objdump + +BIN_FLAGS := -O binary -R .reginfo -R .note -R .comment -R .mdebug -S + +CFLAGS = -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ + -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic \ + -ffunction-sections -pipe -mlong-calls -fno-common -ffreestanding \ + -fhonour-copts \ + -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap +CFLAGS += -DLOADADDR=$(LOADADDR) -D_LZMA_PROB32 + +ASFLAGS = $(CFLAGS) -D__ASSEMBLY__ -DLZMA_STARTUP_ORG=$(LZMA_STARTUP_ORG) + +LDFLAGS = -static --gc-sections -no-warn-mismatch +LDFLAGS += -e startup -T loader.lds -Ttext $(LZMA_TEXT_START) + +O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32) + +OBJECTS := head.o decompress.o board.o printf.o LzmaDecode.o + +ifneq ($(strip $(LOADER_DATA)),) +OBJECTS += data.o +CFLAGS += -DLZMA_WRAPPER=1 +else +CFLAGS += -D_LZMA_IN_CB +endif + +ifneq ($(strip $(CONFIG_PASS_KARGS)),) +CFLAGS += -DCONFIG_PASS_KARGS +endif + +BOARD_DEF := $(strip $(CONFIG_BOARD)) +BOARD_DEF := $(shell echo $(BOARD_DEF) | tr a-z A-Z | tr -d -) +ifneq ($(BOARD_DEF),) +CFLAGS += -DCONFIG_BOARD_$(BOARD_DEF) +endif + +all: loader.bin + +# Don't build dependencies, this may die if $(CC) isn't gcc +dep: + +install: + +%.o : %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.o : %.S + $(CC) $(ASFLAGS) -c -o $@ $< + +data.o: $(LOADER_DATA) + $(LD) -r -b binary --oformat $(O_FORMAT) -T lzma-data.lds -o $@ $< + +loader.bin: loader.elf + $(OBJCOPY) $(BIN_FLAGS) $< $@ + +loader.elf: $(OBJECTS) + $(LD) $(LDFLAGS) -o $@ $(OBJECTS) + +mrproper: clean + +clean: + rm -f *.elf *.bin *.o + + + diff --git a/target/linux/adm5120/image/lzma-loader/src/README b/target/linux/adm5120/image/lzma-loader/src/README new file mode 100644 index 000000000..16649e950 --- /dev/null +++ b/target/linux/adm5120/image/lzma-loader/src/README @@ -0,0 +1,55 @@ +/* + * LZMA compressed kernel decompressor for bcm947xx boards + * + * Copyright (C) 2005 by Oleg I. Vdovikin + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +The code is intended to decompress kernel, being compressed using lzma utility +build using 7zip LZMA SDK. This utility is located in the LZMA_Alone directory + +decompressor code expects that your .trx file consist of three partitions: + +1) decompressor itself (this is gziped code which pmon/cfe will extract and run +on boot-up instead of real kernel) +2) LZMA compressed kernel (both streamed and regular modes are supported now) +3) Root filesystem + +Please be sure to apply the following patch for use this new trx layout (it will +allow using both new and old trx files for root filesystem lookup code) + +--- linuz/arch/mips/brcm-boards/bcm947xx/setup.c 2005-01-23 19:24:27.503322896 +0300 ++++ linux/arch/mips/brcm-boards/bcm947xx/setup.c 2005-01-23 19:29:05.237100944 +0300 +@@ -221,7 +221,9 @@ + /* Try looking at TRX header for rootfs offset */ + if (le32_to_cpu(trx->magic) == TRX_MAGIC) { + bcm947xx_parts[1].offset = off; +- if (le32_to_cpu(trx->offsets[1]) > off) ++ if (le32_to_cpu(trx->offsets[2]) > off) ++ off = le32_to_cpu(trx->offsets[2]); ++ else if (le32_to_cpu(trx->offsets[1]) > off) + off = le32_to_cpu(trx->offsets[1]); + continue; + } + + +Revision history: + 0.02 Initial release + 0.03 Added Mineharu Takahara patch to pass actual + output size to decoder (stream mode compressed input is not + a requirement anymore) + 0.04 Reordered functions using lds script diff --git a/target/linux/adm5120/image/lzma-loader/src/board.c b/target/linux/adm5120/image/lzma-loader/src/board.c new file mode 100644 index 000000000..5ebdbc3b1 --- /dev/null +++ b/target/linux/adm5120/image/lzma-loader/src/board.c @@ -0,0 +1,185 @@ +/* + * ADM5120 specific board support for LZMA decompressor + * + * Copyright (C) 2007-2008 OpenWrt.org + * Copyright (C) 2007-2008 Gabor Juhos + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" +#include + +#define READREG(r) *(volatile unsigned int *)(r) +#define WRITEREG(r,v) *(volatile unsigned int *)(r) = v + +/* + * INTC definitions + */ +#define INTC_BASE 0xB2200000 + +/* INTC registers */ +#define INTC_REG_IRQ_DISABLE 0x0C + +/* + * UART definitions + */ +#define UART0_BASE 0xB2600000 +#define UART1_BASE 0xB2800000 +/* UART registers */ +#define UART_REG_DATA 0x00 /* Data register */ +#define UART_REG_ECR 0x04 /* Error Clear register */ +#define UART_REG_LCRH 0x08 /* Line Control High register */ +#define UART_REG_LCRM 0x0C /* Line Control Middle register */ +#define UART_REG_LCRL 0x10 /* Line Control Low register */ +#define UART_REG_CTRL 0x14 /* Control register */ +#define UART_REG_FLAG 0x18 /* Flag register */ + +/* Control register bits */ +#define UART_CTRL_EN ( 1 << 0 ) /* UART enable */ + +/* Line Control High register bits */ +#define UART_LCRH_FEN ( 1 << 4 ) /* FIFO enable */ + +/* Flag register bits */ +#define UART_FLAG_CTS ( 1 << 0 ) +#define UART_FLAG_DSR ( 1 << 1 ) +#define UART_FLAG_DCD ( 1 << 2 ) +#define UART_FLAG_BUSY ( 1 << 3 ) +#define UART_FLAG_RXFE ( 1 << 4 ) /* RX FIFO empty */ +#define UART_FLAG_TXFF ( 1 << 5 ) /* TX FIFO full */ +#define UART_FLAG_RXFF ( 1 << 6 ) /* RX FIFO full */ +#define UART_FLAG_TXFE ( 1 << 7 ) /* TX FIFO empty */ + +/* + * SWITCH definitions + */ +#define SWITCH_BASE 0xB2000000 + +#define SWITCH_REG_CPUP_CONF 0x0024 +#define SWITCH_REG_PORT_CONF0 0x0028 + +#define SWITCH_REG_GPIO_CONF0 0x00B8 +#define SWITCH_REG_GPIO_CONF2 0x00BC + +#define SWITCH_REG_PORT0_LED 0x0100 +#define SWITCH_REG_PORT1_LED 0x0104 +#define SWITCH_REG_PORT2_LED 0x0108 +#define SWITCH_REG_PORT3_LED 0x010C +#define SWITCH_REG_PORT4_LED 0x0110 + +#define SWITCH_PORTS_HW 0x3F /* Hardware Ports */ + +/* CPUP_CONF register bits */ +#define CPUP_CONF_DCPUP ( 1 << 0 ) /* Disable CPU port */ + +/* PORT_CONF0 register bits */ +#define PORT_CONF0_DP_SHIFT 0 /* disable port shift*/ + + +/* + * UART routines + */ + +#if defined(CONFIG_USE_UART0) +# define UART_READ(r) READREG(UART0_BASE+(r)) +# define UART_WRITE(r,v) WRITEREG(UART0_BASE+(r),(v)) +#else +# define UART_READ(r) READREG(UART1_BASE+(r)) +# define UART_WRITE(r,v) WRITEREG(UART1_BASE+(r),(v)) +#endif + +static void uart_init(void) +{ +#if 0 + unsigned int t; + + /* disable uart */ + UART_WRITE(UART_REG_CTRL, 0); + + /* keep current baud rate */ + t = UART_READ(UART_REG_LCRM); + UART_WRITE(UART_REG_LCRM, t); + t = UART_READ(UART_REG_LCRL); + UART_WRITE(UART_REG_LCRL, t); + + /* keep data, stop, and parity bits, but disable FIFO */ + t = UART_READ(UART_REG_LCRH); + t &= ~(UART_LCRH_FEN); + UART_WRITE(UART_REG_LCRH, t ); + + /* clear error bits */ + UART_WRITE(UART_REG_ECR, 0xFF); + + /* enable uart, and disable interrupts */ + UART_WRITE(UART_REG_CTRL, UART_CTRL_EN); +#endif +} + +/* + * INTC routines + */ + +#define INTC_READ(r) READREG(INTC_BASE+(r)) +#define INTC_WRITE(r,v) WRITEREG(INTC_BASE+(r),v) + +static void intc_init(void) +{ + INTC_WRITE(INTC_REG_IRQ_DISABLE, 0xFFFFFFFF); +} + +/* + * SWITCH routines + */ + +#define SWITCH_READ(r) READREG(SWITCH_BASE+(r)) +#define SWITCH_WRITE(r,v) WRITEREG(SWITCH_BASE+(r),v) + +static void switch_init(void) +{ + /* disable PHYS ports */ + SWITCH_WRITE(SWITCH_REG_PORT_CONF0, + (SWITCH_PORTS_HW << PORT_CONF0_DP_SHIFT)); + + /* disable CPU port */ + SWITCH_WRITE(SWITCH_REG_CPUP_CONF, CPUP_CONF_DCPUP); + + /* disable GPIO lines */ + SWITCH_WRITE(SWITCH_REG_GPIO_CONF0, 0); + SWITCH_WRITE(SWITCH_REG_GPIO_CONF2, 0); + + /* disable LED lines */ + SWITCH_WRITE(SWITCH_REG_PORT0_LED, 0); + SWITCH_WRITE(SWITCH_REG_PORT1_LED, 0); + SWITCH_WRITE(SWITCH_REG_PORT2_LED, 0); + SWITCH_WRITE(SWITCH_REG_PORT3_LED, 0); + SWITCH_WRITE(SWITCH_REG_PORT4_LED, 0); +} + +void board_putc(int ch) +{ + while ((UART_READ(UART_REG_FLAG) & UART_FLAG_TXFE) == 0); + + UART_WRITE(UART_REG_DATA, ch); + + while ((UART_READ(UART_REG_FLAG) & UART_FLAG_TXFE) == 0); +} + +void board_init(void) +{ + intc_init(); + switch_init(); + uart_init(); +} diff --git a/target/linux/adm5120/image/lzma-loader/src/config.h b/target/linux/adm5120/image/lzma-loader/src/config.h new file mode 100644 index 000000000..e5511d16f --- /dev/null +++ b/target/linux/adm5120/image/lzma-loader/src/config.h @@ -0,0 +1,143 @@ +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +#define FLASH_2M (2<<20) +#define FLASH_4M (4<<20) + +/* + * Cellvision/SparkLAN boards + */ + +#if defined(CONFIG_BOARD_CAS630) +# define CONFIG_BOARD_NAME "CAS-630" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +#if defined(CONFIG_BOARD_CAS670) +# define CONFIG_BOARD_NAME "CAS-670" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +#if defined(CONFIG_BOARD_CAS700) +# define CONFIG_BOARD_NAME "CAS-700" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +#if defined(CONFIG_BOARD_CAS790) +# define CONFIG_BOARD_NAME "CAS-790" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +#if defined(CONFIG_BOARD_CAS771) +# define CONFIG_BOARD_NAME "CAS-771" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +#if defined(CONFIG_BOARD_CAS861) +# define CONFIG_BOARD_NAME "CAS-861" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +#if defined(CONFIG_BOARD_NFS101U) +# define CONFIG_BOARD_NAME "NFS-101U" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +#if defined(CONFIG_BOARD_NFS202U) +# define CONFIG_BOARD_NAME "NFS-202U" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +/* + * Compex boards + */ +#if defined(CONFIG_BOARD_WP54GWRT) +# define CONFIG_BOARD_NAME "WP54G-WRT" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +/* + * Edimax boards + */ +#if defined(CONFIG_BOARD_BR6104K) +# define CONFIG_BOARD_NAME "BR-6104K" +# define CONFIG_FLASH_SIZE FLASH_2M +#endif + +#if defined(CONFIG_BOARD_BR6104KP) +# define CONFIG_BOARD_NAME "BR-6104KP" +# define CONFIG_FLASH_SIZE FLASH_2M +#endif + +#if defined(CONFIG_BOARD_BR6104WG) +# define CONFIG_BOARD_NAME "BR-6104WG" +# define CONFIG_FLASH_SIZE FLASH_2M +#endif + +/* + * Infineon boards + */ +#if defined(CONFIG_BOARD_EASY5120PATA) +# define CONFIG_BOARD_NAME "EASY 5120P-ATA" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +#if defined(CONFIG_BOARD_EASY5120RT) +# define CONFIG_BOARD_NAME "EASY 5120-RT" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +#if defined(CONFIG_BOARD_EASY5120WVOIP) +# define CONFIG_BOARD_NAME "EASY 5120-WVOIP" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +#if defined(CONFIG_BOARD_EASY83000) +# define CONFIG_BOARD_NAME "EASY 83000" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +/* + * Motorola boards + */ +#if defined(CONFIG_BOARD_POWERLINEMUGW) +# define CONFIG_BOARD_NAME "Powerline MU Gateway" +# define CONFIG_USE_UART1 1 +#endif + +/* + * OSBRiDGE boards + */ +#if defined(CONFIG_BOARD_5GXI) +# define CONFIG_BOARD_NAME "OSBRiDGE 5GXi" +#endif + +/* + * ZyXEL boards + */ +#if defined(CONFIG_BOARD_P334WT) +# define CONFIG_BOARD_NAME "P-334WT" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +#if defined(CONFIG_BOARD_P335) +# define CONFIG_BOARD_NAME "P-335" +# define CONFIG_FLASH_SIZE FLASH_4M +#endif + +/* + * Default values + */ +#ifndef CONFIG_BOARD_NAME +# define CONFIG_BOARD_NAME "ADM5120" +#endif + +#ifndef CONFIG_FLASH_SIZE +# define CONFIG_FLASH_SIZE FLASH_2M +#endif + +#if !defined(CONFIG_USE_UART0) && !defined(CONFIG_USE_UART1) +# define CONFIG_USE_UART0 +#endif + +#endif /* _CONFIG_H_ */ diff --git a/target/linux/adm5120/image/lzma-loader/src/decompress.c b/target/linux/adm5120/image/lzma-loader/src/decompress.c new file mode 100644 index 000000000..cd4b8fa60 --- /dev/null +++ b/target/linux/adm5120/image/lzma-loader/src/decompress.c @@ -0,0 +1,353 @@ +/* + * + * LZMA compressed kernel decompressor for ADM5120 boards + * + * Copyright (C) 2005 by Oleg I. Vdovikin + * Copyright (C) 2007-2008 OpenWrt.org + * Copyright (C) 2007-2008 Gabor Juhos + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * Please note, this was code based on the bunzip2 decompressor code + * by Manuel Novoa III (mjn3@codepoet.org), although the only thing left + * is an idea and part of original vendor code + * + * + * 12-Mar-2005 Mineharu Takahara + * pass actual output size to decoder (stream mode + * compressed input is not a requirement anymore) + * + * 24-Apr-2005 Oleg I. Vdovikin + * reordered functions using lds script, removed forward decl + * + * 24-Mar-2007 Gabor Juhos + * pass original values of the a0,a1,a2,a3 registers to the kernel + * + * 19-May-2007 Gabor Juhos + * endiannes related cleanups + * add support for decompressing an embedded kernel + * + */ + +#include + +#include "config.h" +#include "printf.h" +#include "LzmaDecode.h" + +#define ADM5120_FLASH_START 0x1fc00000 /* Flash start */ +#define ADM5120_FLASH_END 0x1fe00000 /* Flash end */ + +#define KSEG0 0x80000000 +#define KSEG1 0xa0000000 + +#define KSEG1ADDR(a) ((((unsigned)(a)) & 0x1fffffffU) | KSEG1) + +#define Index_Invalidate_I 0x00 +#define Index_Writeback_Inv_D 0x01 + +#define cache_unroll(base,op) \ + __asm__ __volatile__( \ + ".set noreorder;\n" \ + ".set mips3;\n" \ + "cache %1, (%0);\n" \ + ".set mips0;\n" \ + ".set reorder\n" \ + : \ + : "r" (base), \ + "i" (op)); + +#ifdef LZMA_DEBUG +# define DBG(f, a...) printf(f, ## a) +#else +# define DBG(f, a...) do {} while (0) +#endif + +static __inline__ void blast_icache(unsigned long size, unsigned long lsize) +{ + unsigned long start = KSEG0; + unsigned long end = (start + size); + + while(start < end) { + cache_unroll(start,Index_Invalidate_I); + start += lsize; + } +} + +static __inline__ void blast_dcache(unsigned long size, unsigned long lsize) +{ + unsigned long start = KSEG0; + unsigned long end = (start + size); + + while(start < end) { + cache_unroll(start,Index_Writeback_Inv_D); + start += lsize; + } +} + +#define TRX_MAGIC 0x30524448 /* "HDR0" */ +#define TRX_ALIGN 0x1000 + +struct trx_header { + unsigned int magic; /* "HDR0" */ + unsigned int len; /* Length of file including header */ + unsigned int crc32; /* 32-bit CRC from flag_version to end of file */ + unsigned int flag_version; /* 0:15 flags, 16:31 version */ + unsigned int offsets[3]; /* Offsets of partitions from start of header */ +}; + +struct env_var { + char *name; + char *value; +}; + +/* beyound the image end, size not known in advance */ +extern unsigned char workspace[]; +extern void board_init(void); + +static CLzmaDecoderState lzma_state; + +typedef void (*kernel_entry)(unsigned long reg_a0, unsigned long reg_a1, + unsigned long reg_a2, unsigned long reg_a3); + +static int decompress_data(CLzmaDecoderState *vs, unsigned char *outStream, + UInt32 outSize); + +#ifdef CONFIG_PASS_KARGS +#define ENVV(n,v) {.name = (n), .value = (v)} +struct env_var env_vars[] = { + ENVV("board_name", CONFIG_BOARD_NAME), + ENVV(NULL, NULL) +}; +#endif + +static void halt(void) +{ + printf("\nSystem halted!\n"); + for(;;); +} + +#if (LZMA_WRAPPER) +extern unsigned char _lzma_data_start[]; +extern unsigned char _lzma_data_end[]; + +unsigned char *data; +unsigned long datalen; + +static __inline__ unsigned char get_byte(void) +{ + datalen--; + return *data++; +} + +static void decompress_init(void) +{ + data = _lzma_data_start; + datalen = _lzma_data_end - _lzma_data_start; +} + +static int decompress_data(CLzmaDecoderState *vs, unsigned char *outStream, + SizeT outSize) +{ + SizeT ip, op; + + return LzmaDecode(vs, data, datalen, &ip, outStream, outSize, &op); +} +#endif /* LZMA_WRAPPER */ + +#if !(LZMA_WRAPPER) + +#define FLASH_BANK_SIZE (2<<20) + +static unsigned char *flash_base = (unsigned char *) KSEG1ADDR(ADM5120_FLASH_START); +static unsigned long flash_ofs = 0; +static unsigned long flash_max = 0; +static unsigned long flash_ofs_mask = (FLASH_BANK_SIZE-1); + +static __inline__ unsigned char get_byte(void) +{ + return *(flash_base+flash_ofs++); +} + +static int lzma_read_byte(void *object, const unsigned char **buffer, + SizeT *bufferSize) +{ + unsigned long len; + + if (flash_ofs >= flash_max) + return LZMA_RESULT_DATA_ERROR; + + len = flash_max-flash_ofs; + +#if (CONFIG_FLASH_SIZE > FLASH_BANK_SIZE) + if (flash_ofs < FLASH_BANK_SIZE) { + /* switch to bank 0 */ + DBG("lzma_read_byte: switch to bank 0\n"); + + if (len > FLASH_BANK_SIZE-flash_ofs) + len = FLASH_BANK_SIZE-flash_ofs; + } else { + /* switch to bank 1 */ + DBG("lzma_read_byte: switch to bank 1\n"); + } +#endif + DBG("lzma_read_byte: ofs=%08X, len=%08X\n", flash_ofs, len); + + *buffer = flash_base+(flash_ofs & flash_ofs_mask); + *bufferSize = len; + flash_ofs += len; + + return LZMA_RESULT_OK; +} + +static ILzmaInCallback lzma_callback = { + .Read = lzma_read_byte, +}; + +static __inline__ unsigned int read_le32(void *buf) +{ + unsigned char *p = buf; + + return ((unsigned int)p[0] + ((unsigned int)p[1] << 8) + + ((unsigned int)p[2] << 16) +((unsigned int)p[3] << 24)); +} + +static void decompress_init(void) +{ + struct trx_header *hdr = NULL; + unsigned long kofs,klen; + + printf("Looking for TRX header... "); + /* look for trx header, 32-bit data access */ + for (flash_ofs = 0; flash_ofs < FLASH_BANK_SIZE; flash_ofs += TRX_ALIGN) { + if (read_le32(&flash_base[flash_ofs]) == TRX_MAGIC) { + hdr = (struct trx_header *)&flash_base[flash_ofs]; + break; + } + } + + if (hdr == NULL) { + printf("not found!\n"); + /* no compressed kernel found, halting */ + halt(); + } + + /* compressed kernel is in the partition 0 or 1 */ + kofs = read_le32(&hdr->offsets[1]); + if (kofs == 0 || kofs > 65536) { + klen = kofs-read_le32(&hdr->offsets[0]); + kofs = read_le32(&hdr->offsets[0]); + } else { + klen = read_le32(&hdr->offsets[2]); + if (klen > kofs) + klen -= kofs; + else + klen = read_le32(&hdr->len)-kofs; + } + + printf("found at %08X, kernel:%08X len:%08X\n", flash_ofs, + kofs, klen); + + flash_ofs += kofs; + flash_max = flash_ofs+klen; +} + +static int decompress_data(CLzmaDecoderState *vs, unsigned char *outStream, + SizeT outSize) +{ + SizeT op; + +#if 0 + vs->Buffer = data; + vs->BufferLim = datalen; +#endif + + return LzmaDecode(vs, &lzma_callback, outStream, outSize, &op); +} +#endif /* !(LZMA_WRAPPER) */ + +/* should be the first function */ +void decompress_entry(unsigned long reg_a0, unsigned long reg_a1, + unsigned long reg_a2, unsigned long reg_a3, + unsigned long icache_size, unsigned long icache_lsize, + unsigned long dcache_size, unsigned long dcache_lsize) +{ + unsigned char props[LZMA_PROPERTIES_SIZE]; + unsigned int i; /* temp value */ + SizeT osize; /* uncompressed size */ + int res; + + board_init(); + + printf("\n\nLZMA loader for " CONFIG_BOARD_NAME + ", Copyright (C) 2007-2008 OpenWrt.org\n\n"); + + decompress_init(); + + /* lzma args */ + for (i = 0; i < LZMA_PROPERTIES_SIZE; i++) + props[i] = get_byte(); + + /* skip rest of the LZMA coder property */ + /* read the lower half of uncompressed size in the header */ + osize = ((SizeT)get_byte()) + + ((SizeT)get_byte() << 8) + + ((SizeT)get_byte() << 16) + + ((SizeT)get_byte() << 24); + + /* skip rest of the header (upper half of uncompressed size) */ + for (i = 0; i < 4; i++) + get_byte(); + + res = LzmaDecodeProperties(&lzma_state.Properties, props, + LZMA_PROPERTIES_SIZE); + if (res != LZMA_RESULT_OK) { + printf("Incorrect LZMA stream properties!\n"); + halt(); + } + + printf("decompressing kernel... "); + + lzma_state.Probs = (CProb *)workspace; + res = decompress_data(&lzma_state, (unsigned char *)LOADADDR, osize); + + if (res != LZMA_RESULT_OK) { + printf("failed, "); + switch (res) { + case LZMA_RESULT_DATA_ERROR: + printf("data error!\n"); + break; + default: + printf("unknown error %d!\n", res); + } + halt(); + } else + printf("done!\n"); + + blast_dcache(dcache_size, dcache_lsize); + blast_icache(icache_size, icache_lsize); + + printf("launching kernel...\n\n"); + +#ifdef CONFIG_PASS_KARGS + reg_a0 = 0; + reg_a1 = 0; + reg_a2 = (unsigned long)env_vars; + reg_a3 = 0; +#endif + /* Jump to load address */ + ((kernel_entry) LOADADDR)(reg_a0, reg_a1, reg_a2, reg_a3); +} diff --git a/target/linux/adm5120/image/lzma-loader/src/head.S b/target/linux/adm5120/image/lzma-loader/src/head.S new file mode 100644 index 000000000..ee8b3200c --- /dev/null +++ b/target/linux/adm5120/image/lzma-loader/src/head.S @@ -0,0 +1,209 @@ +/* Copyright 2007 Gabor Juhos */ +/* keep original values of the a0,a1,a2,a3 registers */ +/* modifed to support user defined entry point address */ +/* Copyright 2005 Oleg I. Vdovikin (oleg@cs.msu.su) */ +/* cache manipulation adapted from Broadcom code */ +/* idea taken from original bunzip2 decompressor code */ +/* Copyright 2004 Manuel Novoa III (mjn3@codepoet.org) */ +/* Licensed under the linux kernel's version of the GPL.*/ + +#include +#include + +#define KSEG0 0x80000000 + +#define C0_STATUS $12 +#define C0_CAUSE $13 +#define C0_CONFIG $16 +#define C0_WATCHLO $18 +#define C0_WATCHHI $19 +#define C0_TAGLO $28 +#define C0_TAGHI $29 + +#define CONF1_DA_SHIFT 7 /* D$ associativity */ +#define CONF1_DA_MASK 0x00000380 +#define CONF1_DA_BASE 1 +#define CONF1_DL_SHIFT 10 /* D$ line size */ +#define CONF1_DL_MASK 0x00001c00 +#define CONF1_DL_BASE 2 +#define CONF1_DS_SHIFT 13 /* D$ sets/way */ +#define CONF1_DS_MASK 0x0000e000 +#define CONF1_DS_BASE 64 +#define CONF1_IA_SHIFT 16 /* I$ associativity */ +#define CONF1_IA_MASK 0x00070000 +#define CONF1_IA_BASE 1 +#define CONF1_IL_SHIFT 19 /* I$ line size */ +#define CONF1_IL_MASK 0x00380000 +#define CONF1_IL_BASE 2 +#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */ +#define CONF1_IS_MASK 0x01c00000 +#define CONF1_IS_BASE 64 + +#define Index_Invalidate_I 0x00 +#define Index_Writeback_Inv_D 0x01 + + .text + +#if (LZMA_STARTUP_ORG) + .set noreorder + + b startup + nop + + .org LZMA_STARTUP_ORG +#endif + +LEAF(startup) + .set noreorder + .set mips32 + + mtc0 zero, C0_WATCHLO # clear watch registers + mtc0 zero, C0_WATCHHI + + mtc0 zero, C0_CAUSE # clear before writing status register + + mfc0 t0, C0_STATUS # get status register + li t1, ~(0xFF01) + and t0, t1 # mask interrupts + mtc0 t0, C0_STATUS # set up status register + + move t1, ra # save return address + la t0, __reloc_label # get linked address of label + bal __reloc_label # branch and link to label to + nop # get actual address +__reloc_label: + subu t0, ra, t0 # get reloc_delta + move ra, t1 # restore return address + + beqz t0, __reloc_end # if delta is 0 we are in the right place + nop + + /* Copy our code to the right place */ + la t1, _code_start # get linked address of _code_start + la t2, _code_end # get linked address of _code_end + addu t0, t0, t1 # calculate actual address of _code_start + +__reloc_copy: + lw t3, 0(t0) + sw t3, 0(t1) + add t1, 4 + blt t1, t2, __reloc_copy + add t0, 4 + +__reloc_end: + + /* At this point we need to invalidate dcache and */ + /* icache before jumping to new code */ + +1: /* Get cache sizes */ + .set mips32 + mfc0 s0,C0_CONFIG,1 + .set mips0 + + li s1,CONF1_DL_MASK + and s1,s0 + beq s1,zero,nodc + nop + + srl s1,CONF1_DL_SHIFT + li t0,CONF1_DL_BASE + sll s1,t0,s1 /* s1 has D$ cache line size */ + + li s2,CONF1_DA_MASK + and s2,s0 + srl s2,CONF1_DA_SHIFT + addiu s2,CONF1_DA_BASE /* s2 now has D$ associativity */ + + li t0,CONF1_DS_MASK + and t0,s0 + srl t0,CONF1_DS_SHIFT + li s3,CONF1_DS_BASE + sll s3,s3,t0 /* s3 has D$ sets per way */ + + multu s2,s3 /* sets/way * associativity */ + mflo t0 /* total cache lines */ + + multu s1,t0 /* D$ linesize * lines */ + mflo s2 /* s2 is now D$ size in bytes */ + + /* Initilize the D$: */ + mtc0 zero,C0_TAGLO + mtc0 zero,C0_TAGHI + + li t0,KSEG0 /* Just an address for the first $ line */ + addu t1,t0,s2 /* + size of cache == end */ + + .set mips3 +1: cache Index_Writeback_Inv_D,0(t0) + .set mips0 + bne t0,t1,1b + addu t0,s1 + +nodc: + /* Now we get to do it all again for the I$ */ + + move s3,zero /* just in case there is no icache */ + move s4,zero + + li t0,CONF1_IL_MASK + and t0,s0 + beq t0,zero,noic + nop + + srl t0,CONF1_IL_SHIFT + li s3,CONF1_IL_BASE + sll s3,t0 /* s3 has I$ cache line size */ + + li t0,CONF1_IA_MASK + and t0,s0 + srl t0,CONF1_IA_SHIFT + addiu s4,t0,CONF1_IA_BASE /* s4 now has I$ associativity */ + + li t0,CONF1_IS_MASK + and t0,s0 + srl t0,CONF1_IS_SHIFT + li s5,CONF1_IS_BASE + sll s5,t0 /* s5 has I$ sets per way */ + + multu s4,s5 /* sets/way * associativity */ + mflo t0 /* s4 is now total cache lines */ + + multu s3,t0 /* I$ linesize * lines */ + mflo s4 /* s4 is cache size in bytes */ + + /* Initilize the I$: */ + mtc0 zero,C0_TAGLO + mtc0 zero,C0_TAGHI + + li t0,KSEG0 /* Just an address for the first $ line */ + addu t1,t0,s4 /* + size of cache == end */ + + .set mips3 +1: cache Index_Invalidate_I,0(t0) + .set mips0 + bne t0,t1,1b + addu t0,s3 + +noic: + /* Setup new "C" stack */ + la sp, _stack + + addiu sp, -32 /* reserve stack for parameters */ +#if 0 + sw a0, 0(sp) + sw a1, 4(sp) + sw a2, 8(sp) + sw a3, 12(sp) +#endif + sw s3, 16(sp) /* icache line size */ + sw s4, 20(sp) /* icache size */ + sw s1, 24(sp) /* dcache line size */ + sw s2, 28(sp) /* dcache size */ + + /* jump to the decompressor routine */ + la t0, decompress_entry + jr t0 + nop + + .set reorder +END(startup) diff --git a/target/linux/adm5120/image/lzma-loader/src/loader.lds b/target/linux/adm5120/image/lzma-loader/src/loader.lds new file mode 100644 index 000000000..bae70fb6e --- /dev/null +++ b/target/linux/adm5120/image/lzma-loader/src/loader.lds @@ -0,0 +1,29 @@ +OUTPUT_ARCH(mips) +SECTIONS { + .text : { + _code_start = .; + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + . = ALIGN(16); + *(.data.lzma) + } + + .data : { + *(.data) + *(.data.*) + } + _code_end = .; + + .bss : { + *(.bss) + *(.bss.*) + } + + . = ALIGN(16); + . = . + 8192; + _stack = .; + + workspace = .; +} diff --git a/target/linux/adm5120/image/lzma-loader/src/lzma-data.lds b/target/linux/adm5120/image/lzma-loader/src/lzma-data.lds new file mode 100644 index 000000000..abf756ba1 --- /dev/null +++ b/target/linux/adm5120/image/lzma-loader/src/lzma-data.lds @@ -0,0 +1,8 @@ +OUTPUT_ARCH(mips) +SECTIONS { + .data.lzma : { + _lzma_data_start = .; + *(.data) + _lzma_data_end = .; + } +} diff --git a/target/linux/adm5120/image/lzma-loader/src/printf.c b/target/linux/adm5120/image/lzma-loader/src/printf.c new file mode 100644 index 000000000..7bb5a86e1 --- /dev/null +++ b/target/linux/adm5120/image/lzma-loader/src/printf.c @@ -0,0 +1,350 @@ +/* + * Copyright (C) 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * 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. + * + */ + +#include "printf.h" + +extern void board_putc(int ch); + +/* this is the maximum width for a variable */ +#define LP_MAX_BUF 256 + +/* macros */ +#define IsDigit(x) ( ((x) >= '0') && ((x) <= '9') ) +#define Ctod(x) ( (x) - '0') + +/* forward declaration */ +static int PrintChar(char *, char, int, int); +static int PrintString(char *, char *, int, int); +static int PrintNum(char *, unsigned long, int, int, int, int, char, int); + +/* private variable */ +static const char theFatalMsg[] = "fatal error in lp_Print!"; + +/* -*- + * A low level printf() function. + */ +static void +lp_Print(void (*output)(void *, char *, int), + void * arg, + char *fmt, + va_list ap) +{ + +#define OUTPUT(arg, s, l) \ + { if (((l) < 0) || ((l) > LP_MAX_BUF)) { \ + (*output)(arg, (char*)theFatalMsg, sizeof(theFatalMsg)-1); for(;;); \ + } else { \ + (*output)(arg, s, l); \ + } \ + } + + char buf[LP_MAX_BUF]; + + char c; + char *s; + long int num; + + int longFlag; + int negFlag; + int width; + int prec; + int ladjust; + char padc; + + int length; + + for(;;) { + { + /* scan for the next '%' */ + char *fmtStart = fmt; + while ( (*fmt != '\0') && (*fmt != '%')) { + fmt ++; + } + + /* flush the string found so far */ + OUTPUT(arg, fmtStart, fmt-fmtStart); + + /* are we hitting the end? */ + if (*fmt == '\0') break; + } + + /* we found a '%' */ + fmt ++; + + /* check for long */ + if (*fmt == 'l') { + longFlag = 1; + fmt ++; + } else { + longFlag = 0; + } + + /* check for other prefixes */ + width = 0; + prec = -1; + ladjust = 0; + padc = ' '; + + if (*fmt == '-') { + ladjust = 1; + fmt ++; + } + + if (*fmt == '0') { + padc = '0'; + fmt++; + } + + if (IsDigit(*fmt)) { + while (IsDigit(*fmt)) { + width = 10 * width + Ctod(*fmt++); + } + } + + if (*fmt == '.') { + fmt ++; + if (IsDigit(*fmt)) { + prec = 0; + while (IsDigit(*fmt)) { + prec = prec*10 + Ctod(*fmt++); + } + } + } + + + /* check format flag */ + negFlag = 0; + switch (*fmt) { + case 'b': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 2, 0, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'd': + case 'D': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + if (num < 0) { + num = - num; + negFlag = 1; + } + length = PrintNum(buf, num, 10, negFlag, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'o': + case 'O': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 8, 0, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'u': + case 'U': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 10, 0, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'x': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'X': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 1); + OUTPUT(arg, buf, length); + break; + + case 'c': + c = (char)va_arg(ap, int); + length = PrintChar(buf, c, width, ladjust); + OUTPUT(arg, buf, length); + break; + + case 's': + s = (char*)va_arg(ap, char *); + length = PrintString(buf, s, width, ladjust); + OUTPUT(arg, buf, length); + break; + + case '\0': + fmt --; + break; + + default: + /* output this char as it is */ + OUTPUT(arg, fmt, 1); + } /* switch (*fmt) */ + + fmt ++; + } /* for(;;) */ + + /* special termination call */ + OUTPUT(arg, "\0", 1); +} + + +/* --------------- local help functions --------------------- */ +static int +PrintChar(char * buf, char c, int length, int ladjust) +{ + int i; + + if (length < 1) length = 1; + if (ladjust) { + *buf = c; + for (i=1; i< length; i++) buf[i] = ' '; + } else { + for (i=0; i< length-1; i++) buf[i] = ' '; + buf[length - 1] = c; + } + return length; +} + +static int +PrintString(char * buf, char* s, int length, int ladjust) +{ + int i; + int len=0; + char* s1 = s; + while (*s1++) len++; + if (length < len) length = len; + + if (ladjust) { + for (i=0; i< len; i++) buf[i] = s[i]; + for (i=len; i< length; i++) buf[i] = ' '; + } else { + for (i=0; i< length-len; i++) buf[i] = ' '; + for (i=length-len; i < length; i++) buf[i] = s[i-length+len]; + } + return length; +} + +static int +PrintNum(char * buf, unsigned long u, int base, int negFlag, + int length, int ladjust, char padc, int upcase) +{ + /* algorithm : + * 1. prints the number from left to right in reverse form. + * 2. fill the remaining spaces with padc if length is longer than + * the actual length + * TRICKY : if left adjusted, no "0" padding. + * if negtive, insert "0" padding between "0" and number. + * 3. if (!ladjust) we reverse the whole string including paddings + * 4. otherwise we only reverse the actual string representing the num. + */ + + int actualLength =0; + char *p = buf; + int i; + + do { + int tmp = u %base; + if (tmp <= 9) { + *p++ = '0' + tmp; + } else if (upcase) { + *p++ = 'A' + tmp - 10; + } else { + *p++ = 'a' + tmp - 10; + } + u /= base; + } while (u != 0); + + if (negFlag) { + *p++ = '-'; + } + + /* figure out actual length and adjust the maximum length */ + actualLength = p - buf; + if (length < actualLength) length = actualLength; + + /* add padding */ + if (ladjust) { + padc = ' '; + } + if (negFlag && !ladjust && (padc == '0')) { + for (i = actualLength-1; i< length-1; i++) buf[i] = padc; + buf[length -1] = '-'; + } else { + for (i = actualLength; i< length; i++) buf[i] = padc; + } + + + /* prepare to reverse the string */ + { + int begin = 0; + int end; + if (ladjust) { + end = actualLength - 1; + } else { + end = length -1; + } + + while (end > begin) { + char tmp = buf[begin]; + buf[begin] = buf[end]; + buf[end] = tmp; + begin ++; + end --; + } + } + + /* adjust the string pointer */ + return length; +} + +static void printf_output(void *arg, char *s, int l) +{ + int i; + + // special termination call + if ((l==1) && (s[0] == '\0')) return; + + for (i=0; i< l; i++) { + board_putc(s[i]); + if (s[i] == '\n') board_putc('\r'); + } +} + +void printf(char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + lp_Print(printf_output, 0, fmt, ap); + va_end(ap); +} diff --git a/target/linux/adm5120/image/lzma-loader/src/printf.h b/target/linux/adm5120/image/lzma-loader/src/printf.h new file mode 100644 index 000000000..9b1c1df23 --- /dev/null +++ b/target/linux/adm5120/image/lzma-loader/src/printf.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * 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. + * + */ + +#ifndef _printf_h_ +#define _printf_h_ + +#include +void printf(char *fmt, ...); + +#endif /* _printf_h_ */ diff --git a/target/linux/adm5120/image/rb1xx.mk b/target/linux/adm5120/image/rb1xx.mk new file mode 100644 index 000000000..333adce80 --- /dev/null +++ b/target/linux/adm5120/image/rb1xx.mk @@ -0,0 +1,24 @@ +# +# Copyright (C) 2007,2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + + +define Image/cmdline/yaffs2 + root=/dev/mtdblock3 rootfstype=yaffs2 +endef + +define Image/BuildKernel/RouterBoard + $(CP) $(KDIR)/vmlinux.elf $(call imgname,kernel,rb1xx) + $(STAGING_DIR_HOST)/bin/patch-cmdline $(call imgname,kernel,rb1xx) \ + '$(strip $(call Image/cmdline/yaffs2))' +endef + +ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y) + define Image/BuildKernel + $(call Image/BuildKernel/RouterBoard) + endef +endif + diff --git a/target/linux/adm5120/image/router_be.mk b/target/linux/adm5120/image/router_be.mk new file mode 100644 index 000000000..5a166722f --- /dev/null +++ b/target/linux/adm5120/image/router_be.mk @@ -0,0 +1,48 @@ +# +# Copyright (C) 2007,2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Image/Build/ZyXEL + $(call Image/Build/Loader,$(2),bin,0x80500000,0,y,$(2)) + $(call Image/Build/TRXNoloader,$(call imgname,$(1),$(2)).trx,$(1)) + $(STAGING_DIR_HOST)/bin/mkzynfw -B $(2) \ + -b $(KDIR)/loader-$(2).bin \ + -r $(call imgname,$(1),$(2)).trx:0x10000 \ + -o $(call imgname,$(1),$(2))-webui.bin +endef + +define Image/Build/Template/ZyXEL + $(call Image/Build/ZyXEL,$(1),$(2)) +endef + +define Image/Build/Template/ZyXEL/squashfs + $(call Image/Build/Template/ZyXEL,squashfs,$(1)) +endef + +define Image/Build/Template/ZyXEL/jffs2 + $(call Image/Build/Template/ZyXEL,jffs2,$(1)) +endef + +define Image/Build/Template/ZyXEL/Initramfs + $(call Image/Build/LZMAKernel/KArgs,$(1),bin) +endef + +# +# Profiles +# +define Image/Build/Profile/P334WT + $(call Image/Build/Template/ZyXEL/$(1),p-334wt) +endef + +define Image/Build/Profile/P335WT + $(call Image/Build/Template/ZyXEL/$(1),p-335wt) +endef + +define Image/Build/Profile/Generic + $(call Image/Build/Profile/P334WT,$(1)) + $(call Image/Build/Profile/P335WT,$(1)) +endef + diff --git a/target/linux/adm5120/image/router_le.mk b/target/linux/adm5120/image/router_le.mk new file mode 100644 index 000000000..6df6dcd8c --- /dev/null +++ b/target/linux/adm5120/image/router_le.mk @@ -0,0 +1,401 @@ +# +# Copyright (C) 2007-2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define trxedimax/jffs2-128k +-a 0x20000 -f $(KDIR)/root.jffs2-128k +endef + +define trxedimax/jffs2-64k +-a 0x10000 -f $(KDIR)/root.jffs2-64k +endef + +define trxedimax/squashfs +-a 1024 -f $(KDIR)/root.squashfs +endef + +define Image/Build/TRXEdimax + $(STAGING_DIR_HOST)/bin/trx -o $(1) -f $(KDIR)/vmlinux.lzma \ + $(call trxedimax/$(2)) +endef + +define Image/Build/Compex + $(call Image/Build/Loader,$(2),gz,0x80500000,0,y,$(2)) + $(call Image/Build/TRX,$(call imgname,$(1),$(2)).trx,$(1),$(KDIR)/loader-$(2).gz) +endef + +define Image/Build/Edimax + $(call Image/Build/Loader,$(2),gz,0x80500000,0x6D8,y,$(2)) + $(call Image/Build/TRXEdimax,$(call imgname,$(1),$(2)).trx,$(1)) + $(STAGING_DIR_HOST)/bin/mkcsysimg -B $(2) -d -w \ + -r $(KDIR)/loader-$(2).gz::0x1000 \ + -x $(call imgname,$(1),$(2)).trx:0x10000 \ + -x $(JFFS2MARK):0x10000 \ + $(call imgname,$(1),$(2))-webui.bin + $(STAGING_DIR_HOST)/bin/mkcsysimg -B $(2) -d \ + -r $(KDIR)/loader-$(2).gz::0x1000 \ + -x $(call imgname,$(1),$(2)).trx:0x10000 \ + -x $(JFFS2MARK):0x10000 \ + $(call imgname,$(1),$(2))-xmodem.bin + rm -f $(call imgname,$(1),$(2)).trx +endef + +define Image/Build/Osbridge + $(call Image/Build/Loader,$(2),gz,0x80500000,0x6D8,y,$(2)) + $(call Image/Build/TRXEdimax,$(call imgname,$(1),$(2)).trx,$(1)) + $(STAGING_DIR_HOST)/bin/mkcsysimg -B $(2) -d \ + -r $(KDIR)/loader-$(2).gz::0x1000 \ + -x $(call imgname,$(1),$(2)).trx:0x10000 \ + -x $(JFFS2MARK):0x10000 \ + $(call imgname,$(1),$(2))-firmware.bin + $(STAGING_DIR_HOST)/bin/osbridge-crc \ + -i $(call imgname,$(1),$(2))-firmware.bin \ + -o $(call imgname,$(1),$(2))-temp.bin + $(STAGING_DIR_HOST)/bin/pc1crypt \ + -i $(call imgname,$(1),$(2))-temp.bin \ + -o $(call imgname,$(1),$(2))-webui.bin + rm -f $(call imgname,$(1),$(2))-temp.bin + rm -f $(call imgname,$(1),$(2)).trx +endef + +define Image/Build/Infineon + $(call Image/Build/Loader,$(2),gz,0x80500000,0x6D8,y,$(2)) + $(call Image/Build/TRXNoloader,$(call imgname,$(1),$(2)).trx,$(1)) + dd if=$(KDIR)/loader-$(2).gz of=$(call imgname,$(1),$(2)).img bs=64k conv=sync + cat $(call imgname,$(1),$(2)).trx >> $(call imgname,$(1),$(2)).img +endef + +define Image/Build/Cellvision + $(call Image/Build/Loader,$(2),bin,0x80500000,0x6D8,y,$(3)) + mkdir -p $(BIN_DIR)/tmp + cp $(KDIR)/loader-$(2).bin $(BIN_DIR)/tmp/vmlinux.bin + gzip -9 $(BIN_DIR)/tmp/vmlinux.bin + dd if=$(BIN_DIR)/tmp/vmlinux.bin.gz of=$(call imgname,$(1),$(2))-xmodem.bin bs=64k conv=sync + rm -rf $(BIN_DIR)/tmp + $(call Image/Build/TRXNoloader,$(call imgname,$(1),$(2)).trx,$(1)) + cat $(call imgname,$(1),$(2)).trx >> $(call imgname,$(1),$(2))-xmodem.bin + $(STAGING_DIR_HOST)/bin/mkcasfw -B $(2) -d \ + -K $(call imgname,$(1),$(2))-xmodem.bin \ + $(call imgname,$(1),$(2))-webui.bin +endef + +define Image/Build/Cellvision2 + # only for CAS-700/771/790/861 + $(call Image/Build/Loader,$(2),gz,0x80500000,0x6D8,y,$(3)) + $(call Image/Build/TRXNoloader,$(call imgname,$(1),$(2)).trx,$(1)) + dd if=$(KDIR)/loader-$(2).gz of=$(call imgname,$(1),$(2)).bin bs=64k conv=sync + cat $(call imgname,$(1),$(2)).trx >> $(call imgname,$(1),$(2)).bin + echo -ne '\x14\x07\x24\x06$(2)' | dd bs=14 count=1 conv=sync >> $(call imgname,$(1),$(2)).bin + echo -ne 'OpenWrt\x00\x00\x00' >> $(call imgname,$(1),$(2)).bin +endef + +define Image/Build/MyLoader + $(call Image/Build/Loader,$(2),gz,0x80500000,0) + $(call Image/Build/TRXNoloader,$(call imgname,$(1),$(2)).trx,$(1)) + $(STAGING_DIR_HOST)/bin/mkmylofw -B $(2) \ + -p0x20000:0x10000:ahp:0x80001000 \ + -p0x30000:0 \ + -b0x20000:0x10000:h:$(KDIR)/loader-$(2).gz \ + -b0x30000:0::$(call imgname,$(1),$(2)).trx \ + $(call imgname,$(1),$(2)).bin +endef + +# +# Cellvision CAS-630/630W, CAS-670/670W, NFS-101U/101WU, NFS-202U/202WU +# +define Image/Build/Template/Cellvision + $(call Image/Build/Cellvision,$(1),$(2),$(3)) +endef + +define Image/Build/Template/Cellvision/squashfs + $(call Image/Build/Template/Cellvision,squashfs,$(1),$(2)) +endef + +define Image/Build/Template/Cellvision/jffs2-64k + $(call Image/Build/Template/Cellvision,jffs2-64k,$(1),$(2)) +endef + +# +# Cellvision CAS-700/700W, CAS-771/771W, CAS-790, CAS-861/861W +# +define Image/Build/Template/Cellvision2 + $(call Image/Build/Cellvision2,$(1),$(2),$(3)) +endef + +define Image/Build/Template/Cellvision2/squashfs + $(call Image/Build/Template/Cellvision2,squashfs,$(1),$(2)) +endef + +define Image/Build/Template/Cellvision2/jffs2-64k + $(call Image/Build/Template/Cellvision2,jffs2-64k,$(1),$(2)) +endef + +define Image/Build/Template/Cellvision2/Initramfs + $(call Image/Build/LZMAKernel/Cellvision,$(1),$(2),gz) +endef + +# +# Compex NP27G, NP28G, WP54G, WP54AG, WPP54G, WPP54AG +# +define Image/Build/Template/Compex + $(call Image/Build/MyLoader,$(1),$(2)) +endef + +define Image/Build/Template/Compex/squashfs + $(call Image/Build/Template/Compex,squashfs,$(1)) +endef + +define Image/Build/Template/Compex/jffs2-64k + $(call Image/Build/Template/Compex,jffs2-64k,$(1)) +endef + +define Image/Build/Template/Compex/Initramfs + $(call Image/Build/LZMAKernel/Generic,$(1),bin) +endef + +# +# Compex WP54G-WRT +# +define Image/Build/Template/WP54GWRT + $(call Image/Build/Compex,$(1),wp54g-wrt) +endef + +define Image/Build/Template/WP54GWRT/squashfs + $(call Image/Build/Template/WP54GWRT,squashfs) +endef + +define Image/Build/Template/WP54GWRT/jffs2-64k + $(call Image/Build/Template/WP54GWRT,jffs2-64k) +endef + +define Image/Build/Template/WP54GWRT/Initramfs + $(call Image/Build/LZMAKernel/KArgs,wp54g-wrt,bin) +endef + +# +# Edimax BR-6104K, BR-6104KP, BR-6104Wg, BR-6114WG +# +define Image/Build/Template/Edimax + $(call Image/Build/Edimax,$(1),$(2)) +endef + +define Image/Build/Template/Edimax/squashfs + $(call Image/Build/Template/Edimax,squashfs,$(1)) +endef + +define Image/Build/Template/Edimax/Initramfs + $(call Image/Build/LZMAKernel/Admboot,$(1),gz) +endef + +# +# Infineon EASY 5120, EASY 83000 +# +define Image/Build/Template/Infineon + $(call Image/Build/Infineon,$(1),$(2)) +endef + +define Image/Build/Template/Infineon/squashfs + $(call Image/Build/Template/Infineon,squashfs,$(1)) +endef + +define Image/Build/Template/Infineon/jffs2-64k + $(call Image/Build/Template/Infineon,jffs2-64k,$(1)) +endef + +define Image/Build/Template/Infineon/Initramfs + $(call Image/Build/LZMAKernel/Admboot,$(1),gz) +endef + +# +# Generic EB-214A +# +define Image/Build/Template/Edimax/Initramfs + $(call Image/Build/LZMAKernel/Admboot,eb-214a,bin) +endef + + +# +# Mikrotik RouterBOARD 1xx +# +define Image/Build/Template/Mikrotik/Initramfs + $(CP) $(KDIR)/vmlinux.elf $(call imgname,netboot,rb1xx) +endef + +# +# OSBRiDGE 5GXi/5XLi +# +define Image/Build/Template/Osbridge + $(call Image/Build/Osbridge,$(1),$(2)) +endef + +define Image/Build/Template/Osbridge/squashfs + $(call Image/Build/Template/Osbridge,squashfs,$(1)) +endef + +define Image/Build/Template/Osbridge/Initramfs + $(call Image/Build/LZMAKernel/Admboot,$(1),gz) +endef + +# +# Profiles +# +define Image/Build/Profile/CAS630 + $(call Image/Build/Template/Cellvision/$(1),cas-630,cas-630) +endef + +define Image/Build/Profile/CAS630W + $(call Image/Build/Template/Cellvision/$(1),cas-630w,cas-630) +endef + +define Image/Build/Profile/CAS670 + $(call Image/Build/Template/Cellvision/$(1),cas-670,cas-670) +endef + +define Image/Build/Profile/CAS670W + $(call Image/Build/Template/Cellvision/$(1),cas-670w,cas-670) +endef + +define Image/Build/Profile/NFS101U + $(call Image/Build/Template/Cellvision/$(1),nfs-101u,nfs-101u) + $(call Image/Build/Template/Cellvision/$(1),dn-7013,nfs-101u) + $(call Image/Build/Template/Cellvision/$(1),dns-120,nfs-101u) + $(call Image/Build/Template/Cellvision/$(1),mu-5000fs,nfs-101u) + $(call Image/Build/Template/Cellvision/$(1),tn-u100,nfs-101u) + $(call Image/Build/Template/Cellvision/$(1),cg-nsadp,nfs-101u) +endef + +define Image/Build/Profile/NFS101WU + $(call Image/Build/Template/Cellvision/$(1),nfs-101wu,nfs-101u) + $(call Image/Build/Template/Cellvision/$(1),dns-g120,nfs-101u) +endef + +define Image/Build/Profile/CAS700 + $(call Image/Build/Template/Cellvision2/$(1),cas-700,cas-700) +endef + +define Image/Build/Profile/CAS700W + $(call Image/Build/Template/Cellvision2/$(1),cas-700w,cas-700) +endef + +define Image/Build/Profile/CAS771 + $(call Image/Build/Template/Cellvision2/$(1),cas-771,cas-771) +endef + +define Image/Build/Profile/CAS771W + $(call Image/Build/Template/Cellvision2/$(1),cas-771w,cas-771) +endef + +define Image/Build/Profile/CAS790 + $(call Image/Build/Template/Cellvision2/$(1),cas-790,cas-790) +endef + +define Image/Build/Profile/CAS861 + $(call Image/Build/Template/Cellvision2/$(1),cas-861,cas-861) +endef + +define Image/Build/Profile/CAS861W + $(call Image/Build/Template/Cellvision2/$(1),cas-861w,cas-861) +endef + +define Image/Build/Profile/NP27G + $(call Image/Build/Template/Compex/$(1),np27g) +endef + +define Image/Build/Profile/NP28G + $(call Image/Build/Template/Compex/$(1),np28g) +endef + +define Image/Build/Profile/WP54 + $(call Image/Build/Template/Compex/$(1),wp54g) + $(call Image/Build/Template/Compex/$(1),wp54ag) + $(call Image/Build/Template/Compex/$(1),wpp54g) + $(call Image/Build/Template/Compex/$(1),wpp54ag) + $(call Image/Build/Template/WP54GWRT/$(1)) +endef + +define Image/Build/Profile/BR6104K + $(call Image/Build/Template/Edimax/$(1),br-6104k) +endef + +define Image/Build/Profile/BR6104KP + $(call Image/Build/Template/Edimax/$(1),br-6104kp) +endef + +define Image/Build/Profile/BR6104WG + $(call Image/Build/Template/Edimax/$(1),br-6104wg) +endef + +define Image/Build/Profile/BR6114WG + $(call Image/Build/Template/Edimax/$(1),br-6114wg) +endef + +define Image/Build/Profile/EASY83000 + $(call Image/Build/Template/Infineon/$(1),easy-83000) +endef + +define Image/Build/Profile/EASY5120RT + $(call Image/Build/Template/Infineon/$(1),easy-5120-rt) +endef + +define Image/Build/Profile/EASY5120PATA + $(call Image/Build/Template/Infineon/$(1),easy-5120p-ata) +endef + +define Image/Build/Profile/PMUGW + $(call Image/Build/Template/Infineon/$(1),powerline-mugw) +endef + +define Image/Build/Profile/5GXI + $(call Image/Build/Template/Osbridge/$(1),5gxi) +endef + +define Image/Build/Profile/RouterBoard + $(call Image/Build/Template/Mikrotik/$(1)) +endef + +ifeq ($(CONFIG_BROKEN),y) + define Image/Build/Experimental + # Cellvison + $(call Image/Build/Profile/CAS630,$(1)) + $(call Image/Build/Profile/CAS630W,$(1)) + $(call Image/Build/Profile/CAS670,$(1)) + $(call Image/Build/Profile/CAS670W,$(1)) + $(call Image/Build/Profile/CAS700,$(1)) + $(call Image/Build/Profile/CAS700W,$(1)) + $(call Image/Build/Profile/CAS771,$(1)) + $(call Image/Build/Profile/CAS771W,$(1)) + $(call Image/Build/Profile/CAS861,$(1)) + $(call Image/Build/Profile/CAS861W,$(1)) + # Motorola + $(call Image/Build/Profile/PMUGW,$(1)) + # OSBRiDGE + $(call Image/Build/Profile/5GXI,$(1)) + endef +endif + +define Image/Build/Profile/Generic + # Cellvision + $(call Image/Build/Profile/NFS101U,$(1)) + $(call Image/Build/Profile/NFS101WU,$(1)) + # Compex + $(call Image/Build/Profile/WP54,$(1)) + $(call Image/Build/Profile/NP27G,$(1)) + $(call Image/Build/Profile/NP28G,$(1)) + # Edimax + $(call Image/Build/Profile/BR6104K,$(1)) + $(call Image/Build/Profile/BR6104KP,$(1)) + $(call Image/Build/Profile/BR6104WG,$(1)) + $(call Image/Build/Profile/BR6114WG,$(1)) + $(call Image/Build/Profile/EB214A,$(1)) + # Infineon + $(call Image/Build/Profile/EASY83000,$(1)) + $(call Image/Build/Profile/EASY5120RT,$(1)) + $(call Image/Build/Profile/EASY5120PATA,$(1)) + # Mikrotik + $(call Image/Build/Profile/RB1xx/$(1)) + + $(call Image/Build/Experimental,$(1)) +endef diff --git a/target/linux/adm5120/modules.mk b/target/linux/adm5120/modules.mk new file mode 100644 index 000000000..0d0ccc69c --- /dev/null +++ b/target/linux/adm5120/modules.mk @@ -0,0 +1,56 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define KernelPackage/ledtrig-adm5120-switch + SUBMENU:=$(OTHER_MENU) + TITLE:=LED ADM5120 Switch Port Status Trigger + DEPENDS:=@TARGET_adm5120 + KCONFIG:=CONFIG_LEDS_TRIGGER_ADM5120_SWITCH + FILES:=$(LINUX_DIR)/drivers/leds/ledtrig-adm5120-switch.ko + AUTOLOAD:=$(call AutoLoad,50,ledtrig-adm5120-switch) +endef + +define KernelPackage/ledtrig-adm5120-switch/description + Kernel module to allow LEDs to be controlled by the port states + of the ADM5120 built-in ethernet switch. +endef + +$(eval $(call KernelPackage,ledtrig-adm5120-switch)) + + +define KernelPackage/pata-rb153-cf + SUBMENU:=$(BLOCK_MENU) + TITLE:=RouterBOARD 153 CF Slot support + DEPENDS:=@TARGET_adm5120_router_le + KCONFIG:=CONFIG_PATA_RB153_CF + FILES:=$(LINUX_DIR)/drivers/ata/pata_rb153_cf.ko + AUTOLOAD:=$(call AutoLoad,30,pata_rb153_cf,1) + $(call AddDepends/ata) +endef + +define KernelPackage/pata-rb153-cf/description + Kernel support for the RouterBoard 153 CF slot. +endef + +$(eval $(call KernelPackage,pata-rb153-cf,1)) + + +define KernelPackage/usb-adm5120 + SUBMENU:=$(USB_MENU) + TITLE:=Support for the ADM5120 HCD controller + DEPENDS:=@TARGET_adm5120 + KCONFIG:=CONFIG_USB_ADM5120_HCD + FILES:=$(LINUX_DIR)/drivers/usb/host/adm5120-hcd.ko + AUTOLOAD:=$(call AutoLoad,50,adm5120-hcd,1) + $(call AddDepends/usb) +endef + +define KernelPackage/usb-adm5120/description + Kernel support for the ADM5120 HCD USB controller +endef + +$(eval $(call KernelPackage,usb-adm5120)) diff --git a/target/linux/adm5120/patches-3.3/001-adm5120.patch b/target/linux/adm5120/patches-3.3/001-adm5120.patch new file mode 100644 index 000000000..edb3979b7 --- /dev/null +++ b/target/linux/adm5120/patches-3.3/001-adm5120.patch @@ -0,0 +1,43 @@ +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -39,6 +39,23 @@ choice + prompt "System type" + default SGI_IP22 + ++config ADM5120 ++ bool "Infineon/ADMtek ADM5120 SoC based machines" ++ select BOOT_RAW ++ select NO_EXCEPT_FILL ++ select CEVT_R4K ++ select CSRC_R4K ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_HAS_EARLY_PRINTK ++ select DMA_NONCOHERENT ++ select IRQ_CPU ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select ARCH_REQUIRE_GPIOLIB ++ select SWAP_IO_SPACE if CPU_BIG_ENDIAN ++ select MIPS_MACHINE ++ + config MIPS_ALCHEMY + bool "Alchemy processor based machines" + select 64BIT_PHYS_ADDR +@@ -813,6 +830,7 @@ config NLM_XLP_BOARD + + endchoice + ++source "arch/mips/adm5120/Kconfig" + source "arch/mips/alchemy/Kconfig" + source "arch/mips/ath79/Kconfig" + source "arch/mips/bcm47xx/Kconfig" +--- a/arch/mips/Kbuild.platforms ++++ b/arch/mips/Kbuild.platforms +@@ -1,5 +1,6 @@ + # All platforms listed in alphabetic order + ++platforms += adm5120 + platforms += alchemy + platforms += ar7 + platforms += ath79 diff --git a/target/linux/adm5120/patches-3.3/002-adm5120_flash.patch b/target/linux/adm5120/patches-3.3/002-adm5120_flash.patch new file mode 100644 index 000000000..98b1f2a62 --- /dev/null +++ b/target/linux/adm5120/patches-3.3/002-adm5120_flash.patch @@ -0,0 +1,21 @@ +--- a/drivers/mtd/maps/Kconfig ++++ b/drivers/mtd/maps/Kconfig +@@ -526,4 +526,8 @@ config MTD_LATCH_ADDR + + If compiled as a module, it will be called latch-addr-flash. + ++config MTD_ADM5120 ++ tristate "Map driver for ADM5120 based boards" ++ depends on ADM5120 ++ + endmenu +--- a/drivers/mtd/maps/Makefile ++++ b/drivers/mtd/maps/Makefile +@@ -38,6 +38,7 @@ obj-$(CONFIG_MTD_SCx200_DOCFLASH)+= scx2 + obj-$(CONFIG_MTD_DBOX2) += dbox2-flash.o + obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o + obj-$(CONFIG_MTD_PCI) += pci.o ++obj-$(CONFIG_MTD_ADM5120) += adm5120-flash.o + obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o + obj-$(CONFIG_MTD_IMPA7) += impa7.o + obj-$(CONFIG_MTD_FORTUNET) += fortunet.o diff --git a/target/linux/adm5120/patches-3.3/003-adm5120_switch.patch b/target/linux/adm5120/patches-3.3/003-adm5120_switch.patch new file mode 100644 index 000000000..ef9d692ea --- /dev/null +++ b/target/linux/adm5120/patches-3.3/003-adm5120_switch.patch @@ -0,0 +1,23 @@ +--- a/drivers/net/Kconfig ++++ b/drivers/net/Kconfig +@@ -247,6 +247,10 @@ source "drivers/net/dsa/Kconfig" + + source "drivers/net/ethernet/Kconfig" + ++config ADM5120_ENET ++ tristate "ADM5120 Ethernet switch support" ++ depends on ADM5120 ++ + source "drivers/net/fddi/Kconfig" + + source "drivers/net/hippi/Kconfig" +--- a/drivers/net/Makefile ++++ b/drivers/net/Makefile +@@ -32,6 +32,7 @@ obj-$(CONFIG_CAN) += can/ + obj-$(CONFIG_ETRAX_ETHERNET) += cris/ + obj-$(CONFIG_NET_DSA) += dsa/ + obj-$(CONFIG_ETHERNET) += ethernet/ ++obj-$(CONFIG_ADM5120_ENET) += adm5120sw.o + obj-$(CONFIG_FDDI) += fddi/ + obj-$(CONFIG_HIPPI) += hippi/ + obj-$(CONFIG_HAMRADIO) += hamradio/ diff --git a/target/linux/adm5120/patches-3.3/005-adm5120_usb.patch b/target/linux/adm5120/patches-3.3/005-adm5120_usb.patch new file mode 100644 index 000000000..fd809dab1 --- /dev/null +++ b/target/linux/adm5120/patches-3.3/005-adm5120_usb.patch @@ -0,0 +1,33 @@ +--- a/drivers/usb/Makefile ++++ b/drivers/usb/Makefile +@@ -13,6 +13,7 @@ obj-$(CONFIG_USB_DWC3) += dwc3/ + obj-$(CONFIG_USB_MON) += mon/ + + obj-$(CONFIG_PCI) += host/ ++obj-$(CONFIG_USB_ADM5120_HCD) += host/ + obj-$(CONFIG_USB_EHCI_HCD) += host/ + obj-$(CONFIG_USB_ISP116X_HCD) += host/ + obj-$(CONFIG_USB_OHCI_HCD) += host/ +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -4,6 +4,10 @@ + comment "USB Host Controller Drivers" + depends on USB + ++config USB_ADM5120_HCD ++ tristate "ADM5120 HCD support (EXPERIMENTAL)" ++ depends on USB && ADM5120 && EXPERIMENTAL ++ + config USB_C67X00_HCD + tristate "Cypress C67x00 HCD support" + depends on USB +--- a/drivers/usb/host/Makefile ++++ b/drivers/usb/host/Makefile +@@ -19,6 +19,7 @@ obj-$(CONFIG_USB_WHCI_HCD) += whci/ + + obj-$(CONFIG_PCI) += pci-quirks.o + ++obj-$(CONFIG_USB_ADM5120_HCD) += adm5120-hcd.o + obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o + obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o + obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o diff --git a/target/linux/adm5120/patches-3.3/007-adm5120_pci.patch b/target/linux/adm5120/patches-3.3/007-adm5120_pci.patch new file mode 100644 index 000000000..e757bb50b --- /dev/null +++ b/target/linux/adm5120/patches-3.3/007-adm5120_pci.patch @@ -0,0 +1,22 @@ +--- a/arch/mips/pci/Makefile ++++ b/arch/mips/pci/Makefile +@@ -20,6 +20,7 @@ obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o + ops-bcm63xx.o + obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o + obj-$(CONFIG_SOC_AR724X) += pci-ath724x.o ++obj-$(CONFIG_ADM5120) += pci-adm5120.o + + # + # These are still pretty much in the old state, watch, go blind. +--- a/include/linux/pci_ids.h ++++ b/include/linux/pci_ids.h +@@ -1803,6 +1803,9 @@ + #define PCI_VENDOR_ID_ESDGMBH 0x12fe + #define PCI_DEVICE_ID_ESDGMBH_CPCIASIO4 0x0111 + ++#define PCI_VENDOR_ID_ADMTEK 0x1317 ++#define PCI_DEVICE_ID_ADMTEK_ADM5120 0x5120 ++ + #define PCI_VENDOR_ID_SIIG 0x131f + #define PCI_SUBVENDOR_ID_SIIG 0x131f + #define PCI_DEVICE_ID_SIIG_1S_10x_550 0x1000 diff --git a/target/linux/adm5120/patches-3.3/009-adm5120_leds_switch_trigger.patch b/target/linux/adm5120/patches-3.3/009-adm5120_leds_switch_trigger.patch new file mode 100644 index 000000000..5d896e67a --- /dev/null +++ b/target/linux/adm5120/patches-3.3/009-adm5120_leds_switch_trigger.patch @@ -0,0 +1,22 @@ +--- a/drivers/leds/Kconfig ++++ b/drivers/leds/Kconfig +@@ -498,4 +498,12 @@ config LEDS_TRIGGER_USBDEV + This allows LEDs to be controlled by the presence/activity of + an USB device. If unsure, say N. + ++config LEDS_TRIGGER_ADM5120_SWITCH ++ tristate "LED ADM5120 Switch Port Status Trigger" ++ depends on LEDS_TRIGGERS && ADM5120 ++ help ++ This allows LEDs to be controlled by the port states of ++ the ADM5120 built-in Ethernet Switch ++ If unsure, say N. ++ + endif # NEW_LEDS +--- a/drivers/leds/Makefile ++++ b/drivers/leds/Makefile +@@ -60,3 +60,4 @@ obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += + obj-$(CONFIG_LEDS_TRIGGER_MORSE) += ledtrig-morse.o + obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o + obj-$(CONFIG_LEDS_TRIGGER_USBDEV) += ledtrig-usbdev.o ++obj-$(CONFIG_LEDS_TRIGGER_ADM5120_SWITCH) += ledtrig-adm5120-switch.o diff --git a/target/linux/adm5120/patches-3.3/101-cfi_fixup_macronix_bootloc.patch b/target/linux/adm5120/patches-3.3/101-cfi_fixup_macronix_bootloc.patch new file mode 100644 index 000000000..12f914a2a --- /dev/null +++ b/target/linux/adm5120/patches-3.3/101-cfi_fixup_macronix_bootloc.patch @@ -0,0 +1,84 @@ +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -48,6 +48,12 @@ + #define SST49LF008A 0x005a + #define AT49BV6416 0x00d6 + ++/* Macronix */ ++#define MX29LV160B 0x2249 /* MX29LV160 Bottom-boot chip */ ++#define MX29LV160T 0x22C4 /* MX29LV160 Top-boot chip */ ++#define MX29LV320B 0x22A8 /* MX29LV320 Bottom-boot chip */ ++#define MX29LV320T 0x22A7 /* MX29LV320 Top-boot chip */ ++ + static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); + static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); + static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); +@@ -342,6 +348,41 @@ static struct cfi_fixup cfi_nopri_fixup_ + { 0, 0, NULL } + }; + ++#ifdef CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC ++/* ++ * Some Macronix chips has no/bad bootblock information in the CFI table ++ */ ++static void fixup_macronix_bootloc(struct mtd_info *mtd) ++{ ++ struct map_info *map = mtd->priv; ++ struct cfi_private *cfi = map->fldrv_priv; ++ struct cfi_pri_amdstd *extp = cfi->cmdset_priv; ++ __u8 t; ++ ++ switch (cfi->id) { ++ /* TODO: put affected chip ids here */ ++ case MX29LV160B: ++ case MX29LV320B: ++ t = 2; /* Bottom boot */ ++ break; ++ case MX29LV160T: ++ case MX29LV320T: ++ t = 3; /* Top boot */ ++ break; ++ default: ++ return; ++ } ++ ++ if (extp->TopBottom == t) ++ /* boot location detected by the CFI layer is correct */ ++ return; ++ ++ extp->TopBottom = t; ++ printk("%s: Macronix chip detected, id:0x%04X, boot location forced " ++ "to %s\n", map->name, cfi->id, (t == 2) ? "bottom" : "top"); ++} ++#endif /* CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC */ ++ + static struct cfi_fixup cfi_fixup_table[] = { + { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri }, + #ifdef AMD_BOOTLOC_BUG +@@ -383,6 +424,9 @@ static struct cfi_fixup fixup_table[] = + */ + { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip }, + { CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock }, ++#ifdef CONFIG_MTD_CFI_FIXUP_MACRONIX_BOOTLOC ++ { CFI_MFR_MACRONIX, CFI_ID_ANY, fixup_macronix_bootloc }, ++#endif + { 0, 0, NULL } + }; + +--- a/drivers/mtd/chips/Kconfig ++++ b/drivers/mtd/chips/Kconfig +@@ -196,6 +196,14 @@ config MTD_CFI_AMDSTD + provides support for one of those command sets, used on chips + including the AMD Am29LV320. + ++config MTD_CFI_FIXUP_MACRONIX_BOOTLOC ++ bool "Fix boot-block location for Macronix flash chips" ++ depends on MTD_CFI_AMDSTD ++ help ++ Some Macronix flash chips have no/wrong boot-block location in the ++ CFI table, and the driver may detect the type incorrectly. Select ++ this if your board has such chip. ++ + config MTD_CFI_STAA + tristate "Support for ST (Advanced Architecture) flash chips" + depends on MTD_GEN_PROBE diff --git a/target/linux/adm5120/patches-3.3/102-jedec_pmc_39lvxxx_chips.patch b/target/linux/adm5120/patches-3.3/102-jedec_pmc_39lvxxx_chips.patch new file mode 100644 index 000000000..00148fa60 --- /dev/null +++ b/target/linux/adm5120/patches-3.3/102-jedec_pmc_39lvxxx_chips.patch @@ -0,0 +1,68 @@ +--- a/drivers/mtd/chips/jedec_probe.c ++++ b/drivers/mtd/chips/jedec_probe.c +@@ -115,6 +115,10 @@ + #define UPD29F064115 0x221C + + /* PMC */ ++#define PM39LV512 0x001B ++#define PM39LV010 0x001C ++#define PM39LV020 0x003D ++#define PM39LV040 0x003E + #define PM49FL002 0x006D + #define PM49FL004 0x006E + #define PM49FL008 0x006A +@@ -1259,6 +1263,54 @@ static const struct amd_flash_info jedec + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1), + } ++ }, { ++ .mfr_id = CFI_MFR_PMC, ++ .dev_id = PM39LV512, ++ .name = "PMC Pm39LV512", ++ .devtypes = CFI_DEVICETYPE_X8, ++ .uaddr = MTD_UADDR_0x0555_0x02AA, ++ .dev_size = SIZE_64KiB, ++ .cmd_set = P_ID_AMD_STD, ++ .nr_regions = 1, ++ .regions = { ++ ERASEINFO(0x01000,16), ++ } ++ }, { ++ .mfr_id = CFI_MFR_PMC, ++ .dev_id = PM39LV010, ++ .name = "PMC Pm39LV010", ++ .devtypes = CFI_DEVICETYPE_X8, ++ .uaddr = MTD_UADDR_0x0555_0x02AA, ++ .dev_size = SIZE_128KiB, ++ .cmd_set = P_ID_AMD_STD, ++ .nr_regions = 1, ++ .regions = { ++ ERASEINFO(0x01000,32), ++ } ++ }, { ++ .mfr_id = CFI_MFR_PMC, ++ .dev_id = PM39LV020, ++ .name = "PMC Pm39LV020", ++ .devtypes = CFI_DEVICETYPE_X8, ++ .uaddr = MTD_UADDR_0x0555_0x02AA, ++ .dev_size = SIZE_256KiB, ++ .cmd_set = P_ID_AMD_STD, ++ .nr_regions = 1, ++ .regions = { ++ ERASEINFO(0x01000,64), ++ } ++ }, { ++ .mfr_id = CFI_MFR_PMC, ++ .dev_id = PM39LV040, ++ .name = "PMC Pm39LV040", ++ .devtypes = CFI_DEVICETYPE_X8, ++ .uaddr = MTD_UADDR_0x0555_0x02AA, ++ .dev_size = SIZE_512KiB, ++ .cmd_set = P_ID_AMD_STD, ++ .nr_regions = 1, ++ .regions = { ++ ERASEINFO(0x01000,128), ++ } + }, { + .mfr_id = CFI_MFR_PMC, + .dev_id = PM49FL002, diff --git a/target/linux/adm5120/patches-3.3/103-mtd_trxsplit.patch b/target/linux/adm5120/patches-3.3/103-mtd_trxsplit.patch new file mode 100644 index 000000000..421dcaa62 --- /dev/null +++ b/target/linux/adm5120/patches-3.3/103-mtd_trxsplit.patch @@ -0,0 +1,23 @@ +--- a/drivers/mtd/Kconfig ++++ b/drivers/mtd/Kconfig +@@ -31,6 +31,10 @@ config MTD_ROOTFS_SPLIT + bool "Automatically split 'rootfs' partition for squashfs" + default y + ++config MTD_TRXSPLIT ++ bool "Automatically find and split TRX partitions" ++ default n ++ + config MTD_REDBOOT_PARTS + tristate "RedBoot partition table parsing" + ---help--- +--- a/drivers/mtd/Makefile ++++ b/drivers/mtd/Makefile +@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o + obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o + obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o + obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o ++obj-$(CONFIG_MTD_TRXSPLIT) += trxsplit.o + + # 'Users' - code which presents functionality to userspace. + obj-$(CONFIG_MTD_CHAR) += mtdchar.o diff --git a/target/linux/adm5120/patches-3.3/120-rb153_cf_driver.patch b/target/linux/adm5120/patches-3.3/120-rb153_cf_driver.patch new file mode 100644 index 000000000..cc2caf5a3 --- /dev/null +++ b/target/linux/adm5120/patches-3.3/120-rb153_cf_driver.patch @@ -0,0 +1,28 @@ +--- a/drivers/ata/Makefile ++++ b/drivers/ata/Makefile +@@ -88,6 +88,7 @@ obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia + obj-$(CONFIG_PATA_PALMLD) += pata_palmld.o + obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o + obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o ++obj-$(CONFIG_PATA_RB153_CF) += pata_rb153_cf.o + obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o + obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o + obj-$(CONFIG_PATA_SAMSUNG_CF) += pata_samsung_cf.o +--- a/drivers/ata/Kconfig ++++ b/drivers/ata/Kconfig +@@ -835,6 +835,15 @@ config PATA_QDI + help + Support for QDI 6500 and 6580 PATA controllers on VESA local bus. + ++config PATA_RB153_CF ++ tristate "RouterBOARD 153 Compact Flash support" ++ depends on ADM5120_MACH_RB_153 ++ help ++ This option enables support for a Compact Flash connected on ++ the RouterBOARD 153. ++ ++ If unsure, say N. ++ + config PATA_RB532 + tristate "RouterBoard 532 PATA CompactFlash support" + depends on MIKROTIK_RB532 diff --git a/target/linux/adm5120/patches-3.3/200-amba_pl010_hacks.patch b/target/linux/adm5120/patches-3.3/200-amba_pl010_hacks.patch new file mode 100644 index 000000000..3c4ea35a1 --- /dev/null +++ b/target/linux/adm5120/patches-3.3/200-amba_pl010_hacks.patch @@ -0,0 +1,378 @@ +--- a/drivers/tty/serial/amba-pl010.c ++++ b/drivers/tty/serial/amba-pl010.c +@@ -49,11 +49,10 @@ + + #include + +-#define UART_NR 8 +- + #define SERIAL_AMBA_MAJOR 204 + #define SERIAL_AMBA_MINOR 16 +-#define SERIAL_AMBA_NR UART_NR ++#define SERIAL_AMBA_NR CONFIG_SERIAL_AMBA_PL010_NUMPORTS ++#define SERIAL_AMBA_NAME CONFIG_SERIAL_AMBA_PL010_PORTNAME + + #define AMBA_ISR_PASS_LIMIT 256 + +@@ -79,9 +78,9 @@ static void pl010_stop_tx(struct uart_po + struct uart_amba_port *uap = (struct uart_amba_port *)port; + unsigned int cr; + +- cr = readb(uap->port.membase + UART010_CR); ++ cr = __raw_readl(uap->port.membase + UART010_CR); + cr &= ~UART010_CR_TIE; +- writel(cr, uap->port.membase + UART010_CR); ++ __raw_writel(cr, uap->port.membase + UART010_CR); + } + + static void pl010_start_tx(struct uart_port *port) +@@ -89,9 +88,9 @@ static void pl010_start_tx(struct uart_p + struct uart_amba_port *uap = (struct uart_amba_port *)port; + unsigned int cr; + +- cr = readb(uap->port.membase + UART010_CR); ++ cr = __raw_readl(uap->port.membase + UART010_CR); + cr |= UART010_CR_TIE; +- writel(cr, uap->port.membase + UART010_CR); ++ __raw_writel(cr, uap->port.membase + UART010_CR); + } + + static void pl010_stop_rx(struct uart_port *port) +@@ -99,9 +98,9 @@ static void pl010_stop_rx(struct uart_po + struct uart_amba_port *uap = (struct uart_amba_port *)port; + unsigned int cr; + +- cr = readb(uap->port.membase + UART010_CR); ++ cr = __raw_readl(uap->port.membase + UART010_CR); + cr &= ~(UART010_CR_RIE | UART010_CR_RTIE); +- writel(cr, uap->port.membase + UART010_CR); ++ __raw_writel(cr, uap->port.membase + UART010_CR); + } + + static void pl010_enable_ms(struct uart_port *port) +@@ -109,9 +108,9 @@ static void pl010_enable_ms(struct uart_ + struct uart_amba_port *uap = (struct uart_amba_port *)port; + unsigned int cr; + +- cr = readb(uap->port.membase + UART010_CR); ++ cr = __raw_readl(uap->port.membase + UART010_CR); + cr |= UART010_CR_MSIE; +- writel(cr, uap->port.membase + UART010_CR); ++ __raw_writel(cr, uap->port.membase + UART010_CR); + } + + static void pl010_rx_chars(struct uart_amba_port *uap) +@@ -119,9 +118,9 @@ static void pl010_rx_chars(struct uart_a + struct tty_struct *tty = uap->port.state->port.tty; + unsigned int status, ch, flag, rsr, max_count = 256; + +- status = readb(uap->port.membase + UART01x_FR); ++ status = __raw_readl(uap->port.membase + UART01x_FR); + while (UART_RX_DATA(status) && max_count--) { +- ch = readb(uap->port.membase + UART01x_DR); ++ ch = __raw_readl(uap->port.membase + UART01x_DR); + flag = TTY_NORMAL; + + uap->port.icount.rx++; +@@ -130,9 +129,9 @@ static void pl010_rx_chars(struct uart_a + * Note that the error handling code is + * out of the main execution path + */ +- rsr = readb(uap->port.membase + UART01x_RSR) | UART_DUMMY_RSR_RX; ++ rsr = __raw_readl(uap->port.membase + UART01x_RSR) | UART_DUMMY_RSR_RX; + if (unlikely(rsr & UART01x_RSR_ANY)) { +- writel(0, uap->port.membase + UART01x_ECR); ++ __raw_writel(0, uap->port.membase + UART01x_ECR); + + if (rsr & UART01x_RSR_BE) { + rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE); +@@ -162,7 +161,7 @@ static void pl010_rx_chars(struct uart_a + uart_insert_char(&uap->port, rsr, UART01x_RSR_OE, ch, flag); + + ignore_char: +- status = readb(uap->port.membase + UART01x_FR); ++ status = __raw_readl(uap->port.membase + UART01x_FR); + } + spin_unlock(&uap->port.lock); + tty_flip_buffer_push(tty); +@@ -175,7 +174,7 @@ static void pl010_tx_chars(struct uart_a + int count; + + if (uap->port.x_char) { +- writel(uap->port.x_char, uap->port.membase + UART01x_DR); ++ __raw_writel(uap->port.x_char, uap->port.membase + UART01x_DR); + uap->port.icount.tx++; + uap->port.x_char = 0; + return; +@@ -187,7 +186,7 @@ static void pl010_tx_chars(struct uart_a + + count = uap->port.fifosize >> 1; + do { +- writel(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR); ++ __raw_writel(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + uap->port.icount.tx++; + if (uart_circ_empty(xmit)) +@@ -205,9 +204,9 @@ static void pl010_modem_status(struct ua + { + unsigned int status, delta; + +- writel(0, uap->port.membase + UART010_ICR); ++ __raw_writel(0, uap->port.membase + UART010_ICR); + +- status = readb(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; ++ status = __raw_readl(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; + + delta = status ^ uap->old_status; + uap->old_status = status; +@@ -235,7 +234,7 @@ static irqreturn_t pl010_int(int irq, vo + + spin_lock(&uap->port.lock); + +- status = readb(uap->port.membase + UART010_IIR); ++ status = __raw_readl(uap->port.membase + UART010_IIR); + if (status) { + do { + if (status & (UART010_IIR_RTIS | UART010_IIR_RIS)) +@@ -248,7 +247,7 @@ static irqreturn_t pl010_int(int irq, vo + if (pass_counter-- == 0) + break; + +- status = readb(uap->port.membase + UART010_IIR); ++ status = __raw_readl(uap->port.membase + UART010_IIR); + } while (status & (UART010_IIR_RTIS | UART010_IIR_RIS | + UART010_IIR_TIS)); + handled = 1; +@@ -262,7 +261,7 @@ static irqreturn_t pl010_int(int irq, vo + static unsigned int pl010_tx_empty(struct uart_port *port) + { + struct uart_amba_port *uap = (struct uart_amba_port *)port; +- unsigned int status = readb(uap->port.membase + UART01x_FR); ++ unsigned int status = __raw_readl(uap->port.membase + UART01x_FR); + return status & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT; + } + +@@ -272,7 +271,7 @@ static unsigned int pl010_get_mctrl(stru + unsigned int result = 0; + unsigned int status; + +- status = readb(uap->port.membase + UART01x_FR); ++ status = __raw_readl(uap->port.membase + UART01x_FR); + if (status & UART01x_FR_DCD) + result |= TIOCM_CAR; + if (status & UART01x_FR_DSR) +@@ -298,12 +297,12 @@ static void pl010_break_ctl(struct uart_ + unsigned int lcr_h; + + spin_lock_irqsave(&uap->port.lock, flags); +- lcr_h = readb(uap->port.membase + UART010_LCRH); ++ lcr_h = __raw_readl(uap->port.membase + UART010_LCRH); + if (break_state == -1) + lcr_h |= UART01x_LCRH_BRK; + else + lcr_h &= ~UART01x_LCRH_BRK; +- writel(lcr_h, uap->port.membase + UART010_LCRH); ++ __raw_writel(lcr_h, uap->port.membase + UART010_LCRH); + spin_unlock_irqrestore(&uap->port.lock, flags); + } + +@@ -335,12 +334,12 @@ static int pl010_startup(struct uart_por + /* + * initialise the old status of the modem signals + */ +- uap->old_status = readb(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; ++ uap->old_status = __raw_readl(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; + + /* + * Finally, enable interrupts + */ +- writel(UART01x_CR_UARTEN | UART010_CR_RIE | UART010_CR_RTIE, ++ __raw_writel(UART01x_CR_UARTEN | UART010_CR_RIE | UART010_CR_RTIE, + uap->port.membase + UART010_CR); + + return 0; +@@ -365,10 +364,10 @@ static void pl010_shutdown(struct uart_p + /* + * disable all interrupts, disable the port + */ +- writel(0, uap->port.membase + UART010_CR); ++ __raw_writel(0, uap->port.membase + UART010_CR); + + /* disable break condition and fifos */ +- writel(readb(uap->port.membase + UART010_LCRH) & ++ __raw_writel(__raw_readl(uap->port.membase + UART010_LCRH) & + ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN), + uap->port.membase + UART010_LCRH); + +@@ -391,7 +390,7 @@ pl010_set_termios(struct uart_port *port + /* + * Ask the core to calculate the divisor for us. + */ +- baud = uart_get_baud_rate(port, termios, old, 0, uap->port.uartclk/16); ++ baud = uart_get_baud_rate(port, termios, old, 0, uap->port.uartclk/16); + quot = uart_get_divisor(port, baud); + + switch (termios->c_cflag & CSIZE) { +@@ -454,25 +453,25 @@ pl010_set_termios(struct uart_port *port + uap->port.ignore_status_mask |= UART_DUMMY_RSR_RX; + + /* first, disable everything */ +- old_cr = readb(uap->port.membase + UART010_CR) & ~UART010_CR_MSIE; ++ old_cr = __raw_readl(uap->port.membase + UART010_CR) & ~UART010_CR_MSIE; + + if (UART_ENABLE_MS(port, termios->c_cflag)) + old_cr |= UART010_CR_MSIE; + +- writel(0, uap->port.membase + UART010_CR); ++ __raw_writel(0, uap->port.membase + UART010_CR); + + /* Set baud rate */ + quot -= 1; +- writel((quot & 0xf00) >> 8, uap->port.membase + UART010_LCRM); +- writel(quot & 0xff, uap->port.membase + UART010_LCRL); ++ __raw_writel((quot & 0xf00) >> 8, uap->port.membase + UART010_LCRM); ++ __raw_writel(quot & 0xff, uap->port.membase + UART010_LCRL); + + /* + * ----------v----------v----------v----------v----- + * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L + * ----------^----------^----------^----------^----- + */ +- writel(lcr_h, uap->port.membase + UART010_LCRH); +- writel(old_cr, uap->port.membase + UART010_CR); ++ __raw_writel(lcr_h, uap->port.membase + UART010_LCRH); ++ __raw_writel(old_cr, uap->port.membase + UART010_CR); + + spin_unlock_irqrestore(&uap->port.lock, flags); + } +@@ -554,7 +553,7 @@ static struct uart_ops amba_pl010_pops = + .verify_port = pl010_verify_port, + }; + +-static struct uart_amba_port *amba_ports[UART_NR]; ++static struct uart_amba_port *amba_ports[SERIAL_AMBA_NR]; + + #ifdef CONFIG_SERIAL_AMBA_PL010_CONSOLE + +@@ -564,10 +563,10 @@ static void pl010_console_putchar(struct + unsigned int status; + + do { +- status = readb(uap->port.membase + UART01x_FR); ++ status = __raw_readl(uap->port.membase + UART01x_FR); + barrier(); + } while (!UART_TX_READY(status)); +- writel(ch, uap->port.membase + UART01x_DR); ++ __raw_writel(ch, uap->port.membase + UART01x_DR); + } + + static void +@@ -581,8 +580,8 @@ pl010_console_write(struct console *co, + /* + * First save the CR then disable the interrupts + */ +- old_cr = readb(uap->port.membase + UART010_CR); +- writel(UART01x_CR_UARTEN, uap->port.membase + UART010_CR); ++ old_cr = __raw_readl(uap->port.membase + UART010_CR); ++ __raw_writel(UART01x_CR_UARTEN, uap->port.membase + UART010_CR); + + uart_console_write(&uap->port, s, count, pl010_console_putchar); + +@@ -591,10 +590,10 @@ pl010_console_write(struct console *co, + * and restore the TCR + */ + do { +- status = readb(uap->port.membase + UART01x_FR); ++ status = __raw_readl(uap->port.membase + UART01x_FR); + barrier(); + } while (status & UART01x_FR_BUSY); +- writel(old_cr, uap->port.membase + UART010_CR); ++ __raw_writel(old_cr, uap->port.membase + UART010_CR); + + clk_disable(uap->clk); + } +@@ -603,9 +602,9 @@ static void __init + pl010_console_get_options(struct uart_amba_port *uap, int *baud, + int *parity, int *bits) + { +- if (readb(uap->port.membase + UART010_CR) & UART01x_CR_UARTEN) { ++ if (__raw_readl(uap->port.membase + UART010_CR) & UART01x_CR_UARTEN) { + unsigned int lcr_h, quot; +- lcr_h = readb(uap->port.membase + UART010_LCRH); ++ lcr_h = __raw_readl(uap->port.membase + UART010_LCRH); + + *parity = 'n'; + if (lcr_h & UART01x_LCRH_PEN) { +@@ -620,8 +619,8 @@ pl010_console_get_options(struct uart_am + else + *bits = 8; + +- quot = readb(uap->port.membase + UART010_LCRL) | +- readb(uap->port.membase + UART010_LCRM) << 8; ++ quot = __raw_readl(uap->port.membase + UART010_LCRL) | ++ __raw_readl(uap->port.membase + UART010_LCRM) << 8; + *baud = uap->port.uartclk / (16 * (quot + 1)); + } + } +@@ -640,7 +639,7 @@ static int __init pl010_console_setup(st + * if so, search for the first available port that does have + * console support. + */ +- if (co->index >= UART_NR) ++ if (co->index >= SERIAL_AMBA_NR) + co->index = 0; + uap = amba_ports[co->index]; + if (!uap) +@@ -662,7 +661,7 @@ static int __init pl010_console_setup(st + + static struct uart_driver amba_reg; + static struct console amba_console = { +- .name = "ttyAM", ++ .name = SERIAL_AMBA_NAME, + .write = pl010_console_write, + .device = uart_console_device, + .setup = pl010_console_setup, +@@ -678,11 +677,11 @@ static struct console amba_console = { + + static struct uart_driver amba_reg = { + .owner = THIS_MODULE, +- .driver_name = "ttyAM", +- .dev_name = "ttyAM", ++ .driver_name = SERIAL_AMBA_NAME, ++ .dev_name = SERIAL_AMBA_NAME, + .major = SERIAL_AMBA_MAJOR, + .minor = SERIAL_AMBA_MINOR, +- .nr = UART_NR, ++ .nr = SERIAL_AMBA_NR, + .cons = AMBA_CONSOLE, + }; + +--- a/drivers/tty/serial/Kconfig ++++ b/drivers/tty/serial/Kconfig +@@ -16,10 +16,25 @@ config SERIAL_AMBA_PL010 + help + This selects the ARM(R) AMBA(R) PrimeCell PL010 UART. If you have + an Integrator/AP or Integrator/PP2 platform, or if you have a +- Cirrus Logic EP93xx CPU, say Y or M here. ++ Cirrus Logic EP93xx CPU or an Infineon ADM5120 SOC, say Y or M here. + + If unsure, say N. + ++config SERIAL_AMBA_PL010_NUMPORTS ++ int "Maximum number of AMBA PL010 serial ports" ++ depends on SERIAL_AMBA_PL010 ++ default "8" ++ ---help--- ++ Set this to the number of serial ports you want the AMBA PL010 driver ++ to support. ++ ++config SERIAL_AMBA_PL010_PORTNAME ++ string "Name of the AMBA PL010 serial ports" ++ depends on SERIAL_AMBA_PL010 ++ default "ttyAM" ++ ---help--- ++ ::: To be written ::: ++ + config SERIAL_AMBA_PL010_CONSOLE + bool "Support for console on AMBA serial port" + depends on SERIAL_AMBA_PL010=y diff --git a/target/linux/adm5120/patches-3.3/201-amba_bus_hacks.patch b/target/linux/adm5120/patches-3.3/201-amba_bus_hacks.patch new file mode 100644 index 000000000..2364d2a66 --- /dev/null +++ b/target/linux/adm5120/patches-3.3/201-amba_bus_hacks.patch @@ -0,0 +1,13 @@ +--- a/drivers/amba/bus.c ++++ b/drivers/amba/bus.c +@@ -20,6 +20,10 @@ + #include + #include + ++#ifndef NO_IRQ ++#define NO_IRQ (-1) ++#endif ++ + #define to_amba_driver(d) container_of(d, struct amba_driver, drv) + + static const struct amba_id * diff --git a/target/linux/adm5120/patches-3.3/203-gpio_leds_brightness.patch b/target/linux/adm5120/patches-3.3/203-gpio_leds_brightness.patch new file mode 100644 index 000000000..5345022da --- /dev/null +++ b/target/linux/adm5120/patches-3.3/203-gpio_leds_brightness.patch @@ -0,0 +1,27 @@ +--- a/drivers/leds/leds-gpio.c ++++ b/drivers/leds/leds-gpio.c +@@ -55,13 +55,17 @@ static void gpio_led_set(struct led_clas + container_of(led_cdev, struct gpio_led_data, cdev); + int level; + +- if (value == LED_OFF) +- level = 0; +- else +- level = 1; +- +- if (led_dat->active_low) +- level = !level; ++ switch (value) { ++ case LED_OFF: ++ level = led_dat->active_low ? 1 : 0; ++ break; ++ case LED_FULL: ++ level = led_dat->active_low ? 0 : 1; ++ break; ++ default: ++ level = value; ++ break; ++ } + + /* Setting GPIOs with I2C/etc requires a task context, and we don't + * seem to have a reliable way to know if we're already in one; so diff --git a/target/linux/adm5120/patches-3.3/310-adm5120_wdt.patch b/target/linux/adm5120/patches-3.3/310-adm5120_wdt.patch new file mode 100644 index 000000000..ca537ecb7 --- /dev/null +++ b/target/linux/adm5120/patches-3.3/310-adm5120_wdt.patch @@ -0,0 +1,31 @@ +--- a/drivers/watchdog/Kconfig ++++ b/drivers/watchdog/Kconfig +@@ -943,6 +943,18 @@ config RC32434_WDT + To compile this driver as a module, choose M here: the + module will be called rc32434_wdt. + ++config ADM5120_WDT ++ tristate "Infineon ADM5120 SoC hardware watchdog" ++ depends on WATCHDOG && ADM5120 ++ help ++ This is a driver for hardware watchdog integrated in Infineon ++ ADM5120 SoC. This watchdog simply watches your kernel to make sure ++ it doesn't freeze, and if it does, it reboots your computer after a ++ certain amount of time. ++ ++ To compile this driver as a module, choose M here: the module will be ++ called adm5120_wdt. ++ + config INDYDOG + tristate "Indy/I2 Hardware Watchdog" + depends on SGI_HAS_INDYDOG +--- a/drivers/watchdog/Makefile ++++ b/drivers/watchdog/Makefile +@@ -122,6 +122,7 @@ obj-$(CONFIG_ATH79_WDT) += ath79_wdt.o + obj-$(CONFIG_BCM47XX_WDT) += bcm47xx_wdt.o + obj-$(CONFIG_BCM63XX_WDT) += bcm63xx_wdt.o + obj-$(CONFIG_RC32434_WDT) += rc32434_wdt.o ++obj-$(CONFIG_ADM5120_WDT) += adm5120_wdt.o + obj-$(CONFIG_INDYDOG) += indydog.o + obj-$(CONFIG_JZ4740_WDT) += jz4740_wdt.o + obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o diff --git a/target/linux/adm5120/rb1xx/base-files/sbin/wget2nand b/target/linux/adm5120/rb1xx/base-files/sbin/wget2nand new file mode 100755 index 000000000..6cd8d6fbd --- /dev/null +++ b/target/linux/adm5120/rb1xx/base-files/sbin/wget2nand @@ -0,0 +1,78 @@ +#!/bin/sh +# wget2nand +# This script can be used to download a TGZ file from your build system which +# contains the files to be installed on the NAND flash on your RB1xx card. +# The one parameter is the URL of the TGZ file to be downloaded. +# Licence GPL V2 +# Author david.goodenough@linkchoose.co.uk +# Based on cf2nand from RB532 support +. /etc/functions.sh + +[ -d /tmp/wget2nand-rootfs ] && { + echo "/tmp/wget2nand-rootfs already exists" + exit 1 +} + +[ -d /tmp/wget2nand-kernel ] && { + echo "/tmp/wget2nand-kernel already exists" + exit 1 +} + +# need to find the wget server from the command line +url=$1 +[ -z "$url" ] && { + echo "No URL specified for image TGZ" + echo "Usage : $0 URL" + exit 1 +} + +# first get an address for br-lan using udhcpc +killall udhcpc +/sbin/udhcpc -i br-lan + +mtd_kernel="$(find_mtd_part 'kernel')" +mtd_rootfs="$(find_mtd_part 'rootfs')" +[ -z "$mtd_kernel" -o -z "$mtd_rootfs" ] && { + echo "Cannot find NAND Flash partitions" + exit 1 +} + +echo "Erasing filesystem..." +mtd erase kernel 2>/dev/null >/dev/null +mtd erase rootfs 2>/dev/null >/dev/null + +echo "Mounting $mtd_rootfs as new root and $mtd_kernel as kernel partition" + +mkdir /tmp/wget2nand-rootfs +mkdir /tmp/wget2nand-kernel +mount -t yaffs2 "$mtd_rootfs" /tmp/wget2nand-rootfs +mount -t yaffs2 "$mtd_kernel" /tmp/wget2nand-kernel + +echo "Erasing existing files..." +rm -rf /tmp/wget2nand-rootfs/* + +echo "Copying filesystem..." +( wget -O - $url/openwrt-adm5120-rb1xx-rootfs.tar.gz) | ( cd /tmp/wget2nand-rootfs/; tar xvz ) +# RouterBOOT is looking for a kernel named "kernel" +wget -O /tmp/wget2nand-kernel/kernel $url/openwrt-adm5120-rb1xx-vmlinux.elf + +chmod +x /tmp/wget2nand-kernel/kernel + +# make sure everything is written before we unmount the partitions +echo "chmod ugo+x /" > /tmp/wget2nand-rootfs/etc/uci-defaults/set_root_permission +sync +ls /tmp/wget2nand-kernel/ +ls /tmp/wget2nand-rootfs/ +# use kexec if present +[ -x /usr/sbin/kexec ] && { + kexec -l /tmp/wget2nand-kernel/kernel --command-line="$(cat /proc/cmdline) rootfstype=yaffs2 root=$mtd_kernel" + kexec -e +} +# unmount the partitions and remove the directories into which they were mounted +umount /tmp/wget2nand-kernel +umount /tmp/wget2nand-rootfs +rmdir /tmp/wget2nand-kernel +rmdir /tmp/wget2nand-rootfs + +# all done +echo "Image written, you can now reboot. Remember to change the boot source to Boot from Nand" diff --git a/target/linux/adm5120/rb1xx/config-3.3 b/target/linux/adm5120/rb1xx/config-3.3 new file mode 100644 index 000000000..fc173cc21 --- /dev/null +++ b/target/linux/adm5120/rb1xx/config-3.3 @@ -0,0 +1,54 @@ +# CONFIG_ADM5120_MACH_5GXI is not set +# CONFIG_ADM5120_MACH_BR_6104K is not set +# CONFIG_ADM5120_MACH_BR_6104KP is not set +# CONFIG_ADM5120_MACH_BR_61X4WG is not set +# CONFIG_ADM5120_MACH_CAS_771 is not set +# CONFIG_ADM5120_MACH_EASY5120P_ATA is not set +# CONFIG_ADM5120_MACH_EASY5120_RT is not set +# CONFIG_ADM5120_MACH_EASY5120_WVOIP is not set +# CONFIG_ADM5120_MACH_EASY83000 is not set +# CONFIG_ADM5120_MACH_EB_214A is not set +# CONFIG_ADM5120_MACH_NFS_101 is not set +# CONFIG_ADM5120_MACH_NP27G is not set +# CONFIG_ADM5120_MACH_NP28G is not set +# CONFIG_ADM5120_MACH_PMUGW is not set +CONFIG_ADM5120_MACH_RB_11X=y +CONFIG_ADM5120_MACH_RB_133=y +CONFIG_ADM5120_MACH_RB_133C=y +CONFIG_ADM5120_MACH_RB_150=y +CONFIG_ADM5120_MACH_RB_153=y +CONFIG_ADM5120_MACH_RB_192=y +# CONFIG_ADM5120_MACH_WP54 is not set +# CONFIG_ADM5120_OEM_CELLVISION is not set +# CONFIG_ADM5120_OEM_COMPEX is not set +# CONFIG_ADM5120_OEM_EDIMAX is not set +# CONFIG_ADM5120_OEM_GENERIC is not set +# CONFIG_ADM5120_OEM_INFINEON is not set +CONFIG_ADM5120_OEM_MIKROTIK=y +# CONFIG_ADM5120_OEM_MOTOROLA is not set +# CONFIG_ADM5120_OEM_OSBRIDGE is not set +CONFIG_CMDLINE="console=ttyS0,115200 rootfstype=yaffs2" +# CONFIG_JFFS2_FS is not set +# CONFIG_MTD_MYLOADER_PARTS is not set +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_PLATFORM=y +# CONFIG_MTD_ROOTFS_SPLIT is not set +# CONFIG_MTD_SM_COMMON is not set +# CONFIG_MTD_TRXSPLIT is not set +# CONFIG_OVERLAYFS_FS is not set +# CONFIG_PATA_RB153_CF is not set +# CONFIG_SQUASHFS is not set +CONFIG_YAFFS_9BYTE_TAGS=y +# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_BACKGROUND is not set +# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set +CONFIG_YAFFS_DISABLE_TAGS_ECC=y +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_XATTR=y +CONFIG_YAFFS_YAFFS1=y +CONFIG_YAFFS_YAFFS2=y diff --git a/target/linux/adm5120/rb1xx/profiles/RB1xx.mk b/target/linux/adm5120/rb1xx/profiles/RB1xx.mk new file mode 100644 index 000000000..b9da1640d --- /dev/null +++ b/target/linux/adm5120/rb1xx/profiles/RB1xx.mk @@ -0,0 +1,18 @@ +# +# Copyright (C) 2007 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/RouterBoard + NAME:=Mikrotik RouterBoard 1xx family + PACKAGES:=kmod-ath5k kmod-pata-rb153-cf +endef + +define Profile/RouterBoard/Description + Package set compatible with the RouterBoard RB1xx devices. Contains RouterOS to OpenWrt\\\ + installation scripts. +endef + +$(eval $(call Profile,RouterBoard)) diff --git a/target/linux/adm5120/rb1xx/target.mk b/target/linux/adm5120/rb1xx/target.mk new file mode 100644 index 000000000..2e9b08e51 --- /dev/null +++ b/target/linux/adm5120/rb1xx/target.mk @@ -0,0 +1,9 @@ +ARCH:=mipsel +ARCH_PACKAGES:=adm5120_mipsel +SUBTARGET:=rb1xx +BOARDNAME:=MikroTik RB-1xx boards +FEATURES:=tgz + +define Target/Description + Build firmware images for Mikrotik RB-1xx series. +endef diff --git a/target/linux/adm5120/router_be/config-3.3 b/target/linux/adm5120/router_be/config-3.3 new file mode 100644 index 000000000..97025375d --- /dev/null +++ b/target/linux/adm5120/router_be/config-3.3 @@ -0,0 +1,15 @@ +# CONFIG_ADM5120_MACH_5GXI is not set +CONFIG_ADM5120_MACH_P_334WT=y +CONFIG_ADM5120_MACH_P_335=y +# CONFIG_ADM5120_OEM_CELLVISION is not set +# CONFIG_ADM5120_OEM_COMPEX is not set +# CONFIG_ADM5120_OEM_EDIMAX is not set +# CONFIG_ADM5120_OEM_GENERIC is not set +# CONFIG_ADM5120_OEM_INFINEON is not set +# CONFIG_ADM5120_OEM_MIKROTIK is not set +# CONFIG_ADM5120_OEM_MOTOROLA is not set +# CONFIG_ADM5120_OEM_OSBRIDGE is not set +CONFIG_ADM5120_OEM_ZYXEL=y +CONFIG_CPU_BIG_ENDIAN=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_SWAP_IO_SPACE=y diff --git a/target/linux/adm5120/router_be/profiles/010-Generic.mk b/target/linux/adm5120/router_be/profiles/010-Generic.mk new file mode 100644 index 000000000..1d477319d --- /dev/null +++ b/target/linux/adm5120/router_be/profiles/010-Generic.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2007 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Generic + NAME:=Generic (default) + PACKAGES:= +endef + +define Profile/Generic/Description + Generic package set compatible with most boards. +endef +$(eval $(call Profile,Generic)) + diff --git a/target/linux/adm5120/router_be/profiles/200-ZyXEL.mk b/target/linux/adm5120/router_be/profiles/200-ZyXEL.mk new file mode 100644 index 000000000..19ac9f5e9 --- /dev/null +++ b/target/linux/adm5120/router_be/profiles/200-ZyXEL.mk @@ -0,0 +1,27 @@ +# +# Copyright (C) 2007 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/P334WT + NAME:=ZyXEL Prestige 334WT + PACKAGES:=kmod-acx-mac80211 +endef + +define Profile/P334WT/Description + Package set optimized for the ZyXEL Prestige 334WT board. +endef + +define Profile/P335WT + NAME:=ZyXEL Prestige 335WT + PACKAGES:=kmod-acx-mac80211 kmod-usb-core kmod-usb-adm5120 +endef + +define Profile/P335WT/Description + Package set optimized for the ZyXEL Prestige 335WT board. +endef + +$(eval $(call Profile,P334WT)) +$(eval $(call Profile,P335WT)) diff --git a/target/linux/adm5120/router_be/target.mk b/target/linux/adm5120/router_be/target.mk new file mode 100644 index 000000000..ab937f2c3 --- /dev/null +++ b/target/linux/adm5120/router_be/target.mk @@ -0,0 +1,11 @@ +ARCH:=mips +ARCH_PACKAGES:=adm5120_mips +SUBTARGET:=router_be +BOARDNAME:=Big Endian +FEATURES:=squashfs jffs2 + +define Target/Description + Build firmware images for Infineon/ADMTek ADM5120 based boards + running in big-endian mode (e.g : ZyXEL Prestige 335WT ...) +endef + diff --git a/target/linux/adm5120/router_le/config-3.3 b/target/linux/adm5120/router_le/config-3.3 new file mode 100644 index 000000000..e69de29bb diff --git a/target/linux/adm5120/router_le/profiles/010-Generic.mk b/target/linux/adm5120/router_le/profiles/010-Generic.mk new file mode 100644 index 000000000..6c3e5f30e --- /dev/null +++ b/target/linux/adm5120/router_le/profiles/010-Generic.mk @@ -0,0 +1,28 @@ +# +# Copyright (C) 2007 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Generic + NAME:=Generic (default) + PACKAGES:= +endef + +define Profile/Generic/Description + Generic package set compatible with most boards. +endef + +define Profile/EB-214A + NAME:=Generic EB-214A + PACKAGES:=-wpad-mini -admswconfig -kmod-usb-adm5120 -kmod-ledtrig-adm5120-switch -dnsmasq kmod-usb-uhci kmod-usb2 +endef + +define Profile/EB-214A/Description + Package set optimized for generic EB-214A boards. +endef + +$(eval $(call Profile,Generic)) +$(eval $(call Profile,EB-214A)) + diff --git a/target/linux/adm5120/router_le/profiles/Cellvision.mk b/target/linux/adm5120/router_le/profiles/Cellvision.mk new file mode 100644 index 000000000..4093b4f49 --- /dev/null +++ b/target/linux/adm5120/router_le/profiles/Cellvision.mk @@ -0,0 +1,146 @@ +# +# Copyright (C) 2007-2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/CAS630 + NAME:=Cellvision CAS-630 IP camera (Experimental) + # TODO: add default packages + PACKAGES:=-wpad-mini +endef + +define Profile/CAS630/Description + Package set optimized for the Cellvision CAS-630 device. +endef + +define Profile/CAS630W + NAME:=Cellvision CAS-630W IP camera (Experimental) + # TODO: add default packages + PACKAGES:=-wpad-mini +endef + +define Profile/CAS630W/Description + Package set optimized for the Cellvision CAS-630W device. +endef + +define Profile/CAS670 + NAME:=Cellvision CAS-670 IP camera (Experimental) + # TODO: add default packages + PACKAGES:=-wpad-mini +endef + +define Profile/CAS670/Description + Package set optimized for the Cellvision CAS-670 device. +endef + +define Profile/CAS670W + NAME:=Cellvision CAS-670W IP camera (Experimental) + # TODO: add default packages + PACKAGES:=-wpad-mini +endef + +define Profile/CAS670W/Description + Package set optimized for the Cellvision CAS-670 device. +endef + +define Profile/CAS700 + NAME:=Cellvision CAS-700 IP camera (Experimental) + # TODO: add default packages + PACKAGES:=-wpad-mini +endef + +define Profile/CAS700/Description + Package set optimized for the Cellvision CAS-700 device. +endef + +define Profile/CAS700W + NAME:=Cellvision CAS-700W IP camera (Experimental) + # TODO: add default packages + PACKAGES:=-wpad-mini +endef + +define Profile/CAS700W/Description + Package set optimized for the Cellvision CAS-700W device. +endef + +define Profile/CAS771 + NAME:=Cellvision CAS-771 IP camera (Experimental) + PACKAGES:=-wpad-mini kmod-video-cpia2 kmod-usb-ohci kmod-usb2 kmod-usb-audio +endef + +define Profile/CAS771/Description + Package set optimized for the Cellvision CAS-771 device. +endef + +define Profile/CAS771W + NAME:=Cellvision CAS-771W IP camera (Experimental) + PACKAGES:=-wpad-mini kmod-video-cpia2 kmod-usb-ohci kmod-usb2 kmod-usb-audio kmod-rt2500-pci +endef + +define Profile/CAS771W/Description + Package set optimized for the Cellvision CAS-771W device. +endef + +define Profile/CAS790 + NAME:=Cellvision CAS-790 IP camera (Experimental) + # TODO: add default packages + PACKAGES:=-wpad-mini +endef + +define Profile/CAS790/Description + Package set optimized for the Cellvision CAS-790 device. +endef + +define Profile/CAS861 + NAME:=Cellvision CAS-861 IP camera (Experimental) + # TODO: add default packages + PACKAGES:=-wpad-mini +endef + +define Profile/CAS861/Description + Package set optimized for the Cellvision CAS-861 device. +endef + +define Profile/CAS861W + NAME:=Cellvision CAS-861W IP camera (Experimental) + PACKAGES:=kmod-rt2500-pci +endef + +define Profile/CAS861W/Description + Package set optimized for the Cellvision CAS-861W device. +endef + +define Profile/NFS101U + NAME:=Cellvision NFS-101U Network File Server (Experimental) + PACKAGES:=-wpad-mini kmod-usb-ohci kmod-usb2 +endef + +define Profile/NFS101U/Description + Package set optimized for the Cellvision NFS-101U device. +endef + +define Profile/NFS101WU + NAME:=Cellvision NFS-101WU Network File Server (Experimental) + PACKAGES:=-wpad-mini kmod-usb-ohci kmod-usb2 +endef + +define Profile/NFS101WU/Description + Package set optimized for the Cellvision NFS-101WU device. +endef + +$(eval $(call Profile,CAS630)) +$(eval $(call Profile,CAS630W)) +$(eval $(call Profile,CAS670)) +$(eval $(call Profile,CAS670W)) +$(eval $(call Profile,CAS700)) +$(eval $(call Profile,CAS700W)) +$(eval $(call Profile,CAS771)) +$(eval $(call Profile,CAS771W)) +$(eval $(call Profile,CAS790)) +$(eval $(call Profile,CAS861)) +$(eval $(call Profile,CAS861W)) +$(eval $(call Profile,NFS101U)) +$(eval $(call Profile,NFS101WU)) + diff --git a/target/linux/adm5120/router_le/profiles/Compex.mk b/target/linux/adm5120/router_le/profiles/Compex.mk new file mode 100644 index 000000000..79d1f3f91 --- /dev/null +++ b/target/linux/adm5120/router_le/profiles/Compex.mk @@ -0,0 +1,37 @@ +# +# Copyright (C) 2007 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/NP27G + NAME:=Compex NP27G + PACKAGES:=kmod-ath5k kmod-usb-core kmod-usb-adm5120 +endef + +define Profile/NP27G/Description + Package set optimized for the Compex NP27G. +endef + +define Profile/NP28G + NAME:=Compex NP28G + PACKAGES:=kmod-ath5k kmod-usb-core kmod-usb-uhci kmod-usb2 +endef + +define Profile/NP28G/Description + Package set optimized for the Compex NP28G. +endef + +define Profile/WP54 + NAME:=Compex WP54 family + PACKAGES:=kmod-ath5k +endef + +define Profile/WP54/Description + Package set optimized for the Compex WP54 family. +endef + +$(eval $(call Profile,NP27G)) +$(eval $(call Profile,NP28G)) +$(eval $(call Profile,WP54)) diff --git a/target/linux/adm5120/router_le/profiles/Edimax.mk b/target/linux/adm5120/router_le/profiles/Edimax.mk new file mode 100644 index 000000000..55c295875 --- /dev/null +++ b/target/linux/adm5120/router_le/profiles/Edimax.mk @@ -0,0 +1,47 @@ +# +# Copyright (C) 2007,2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/BR6104K + NAME:=Edimax BR-6104K (Unofficial) + PACKAGES:=-wpad-mini +endef + +define Profile/BR6104K/Description + Package set optimized for the Edimax BR-6104K +endef + +define Profile/BR6104KP + NAME:=Edimax BR-6104KP (Unofficial) + PACKAGES:=-wpad-mini kmod-usb-core kmod-usb-adm5120 +endef + +define Profile/BR6104KP/Description + Package set optimized for the Edimax BR-6104KP +endef + +define Profile/BR6104WG + NAME:=Edimax BR-6104Wg (Unofficial, No WiFi) + PACKAGES:=-wpad-mini +endef + +define Profile/BR6104WG/Description + Package set optimized for the Edimax BR-6104Wg +endef + +define Profile/BR6114WG + NAME:=Edimax BR-6114WG (Unofficial, No WiFi) + PACKAGES:=-wpad-mini +endef + +define Profile/BR6114WG/Description + Package set optimized for the Edimax BR-6114WG +endef + +$(eval $(call Profile,BR6104K)) +$(eval $(call Profile,BR6104KP)) +$(eval $(call Profile,BR6104WG)) +$(eval $(call Profile,BR6114WG)) diff --git a/target/linux/adm5120/router_le/profiles/Infineon.mk b/target/linux/adm5120/router_le/profiles/Infineon.mk new file mode 100644 index 000000000..d650406b7 --- /dev/null +++ b/target/linux/adm5120/router_le/profiles/Infineon.mk @@ -0,0 +1,27 @@ +# +# Copyright (C) 2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/EASY5120RT + NAME:=Infineon EASY 5120-RT Reference Board + PACKAGES:=kmod-usb-core kmod-usb-adm5120 +endef + +define Profile/EASY5120RT/Description + Package set optimized for the Infineon EASY 5120-RT Reference Board +endef + +$(eval $(call Profile,EASY5120RT)) + +define Profile/EASY5120PATA + NAME:=Infineon EASY 5120P-ATA Reference Board +endef + +define Profile/EASY5120RT/Description + Package set optimized for the Infineon EASY 5120P-ATA Reference Board +endef + +$(eval $(call Profile,EASY5120PATA)) diff --git a/target/linux/adm5120/router_le/profiles/Motorola.mk b/target/linux/adm5120/router_le/profiles/Motorola.mk new file mode 100644 index 000000000..e640b81a1 --- /dev/null +++ b/target/linux/adm5120/router_le/profiles/Motorola.mk @@ -0,0 +1,16 @@ +# +# Copyright (C) 2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/PMUGW + NAME:=Motorola Powerline MU Gateway (EXPERIMENTAL) +endef + +define Profile/PMUGW/Description + Package set optimized for the Motorola Powerline MU Gateway board +endef + +$(eval $(call Profile,PMUGW)) diff --git a/target/linux/adm5120/router_le/profiles/Osbridge.mk b/target/linux/adm5120/router_le/profiles/Osbridge.mk new file mode 100644 index 000000000..459d524ba --- /dev/null +++ b/target/linux/adm5120/router_le/profiles/Osbridge.mk @@ -0,0 +1,16 @@ +# +# Copyright (C) 2007-2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/5GXI + NAME:=Osbridge 5GXi/5XLi (Unofficial) +endef + +define Profile/5GXI/Description + Package set optimized for the OSBRiDGE 5GXi/5XLi boards. +endef + +$(eval $(call Profile,5GXI)) diff --git a/target/linux/adm5120/router_le/target.mk b/target/linux/adm5120/router_le/target.mk new file mode 100644 index 000000000..1d394e864 --- /dev/null +++ b/target/linux/adm5120/router_le/target.mk @@ -0,0 +1,11 @@ +ARCH:=mipsel +ARCH_PACKAGES:=adm5120_mipsel +SUBTARGET:=router_le +BOARDNAME:=Little Endian +FEATURES:=squashfs jffs2 tgz + +define Target/Description + Build firmware images for Infineon/ADMtek ADM5120 based boards + running in little-endian mode (e.g: RouterBoard RB1xx, Compex WP54x ...) +endef + diff --git a/target/linux/adm8668/Makefile b/target/linux/adm8668/Makefile new file mode 100644 index 000000000..8ad2e71ea --- /dev/null +++ b/target/linux/adm8668/Makefile @@ -0,0 +1,26 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +ARCH:=mipsel +BOARD:=adm8668 +BOARDNAME:=Infineon WildPass ADM8668 +FEATURES:=squashfs +MAINTAINER:=Florian Fainelli + +LINUX_VERSION:=3.3.8 + +include $(INCLUDE_DIR)/target.mk +DEFAULT_PACKAGES += wpad-mini kmod-rt61-pci +# kmod-switch kmod-diag nvram + +define Target/Description + Build firmware images for Infineon WildPass (ADM8668) based routers + (e.g. T-Mobile branded Linksys WRTU54G-TM) +endef + +$(eval $(call BuildTarget)) diff --git a/target/linux/adm8668/base-files.mk b/target/linux/adm8668/base-files.mk new file mode 100644 index 000000000..a09623604 --- /dev/null +++ b/target/linux/adm8668/base-files.mk @@ -0,0 +1,3 @@ +#define Package/base-files/install-target +# rm -f $(1)/etc/config/network +#endef diff --git a/target/linux/adm8668/base-files/etc/config/network b/target/linux/adm8668/base-files/etc/config/network new file mode 100644 index 000000000..120db236f --- /dev/null +++ b/target/linux/adm8668/base-files/etc/config/network @@ -0,0 +1,16 @@ +config interface loopback + option ifname lo + option proto static + option ipaddr 127.0.0.1 + option netmask 255.0.0.0 + +config interface lan + option ifname eth0 + option type bridge + option proto static + option ipaddr 192.168.1.1 + option netmask 255.255.255.0 + +config interface wan + option ifname eth1 + option proto dhcp diff --git a/target/linux/adm8668/base-files/etc/diag.sh b/target/linux/adm8668/base-files/etc/diag.sh new file mode 100644 index 000000000..edcc7536a --- /dev/null +++ b/target/linux/adm8668/base-files/etc/diag.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# Copyright (C) 2010 OpenWrt.org + +set_led() { + local state="$1" + [ -f "/proc/adm8668/sesled" ] && echo "$state" > "/proc/adm8668/sesled" +} + +set_state() { + case "$1" in + preinit) + set_led 1 + ;; + failsafe) + set_led 2 + ;; + done) + set_led 0 + ;; + esac +} diff --git a/target/linux/adm8668/base-files/lib/preinit/03_init_hotplug_failsafe_adm8668 b/target/linux/adm8668/base-files/lib/preinit/03_init_hotplug_failsafe_adm8668 new file mode 100644 index 000000000..b0f4a4efa --- /dev/null +++ b/target/linux/adm8668/base-files/lib/preinit/03_init_hotplug_failsafe_adm8668 @@ -0,0 +1,9 @@ +#!/bin/sh + +init_hotplug_failsafe() { + echo '/sbin/hotplug.failsafe' > /proc/sys/kernel/hotplug +} + +boot_hook_add preinit_main init_hotplug_failsafe + + diff --git a/target/linux/adm8668/base-files/lib/preinit/05_set_preinit_face_adm8668 b/target/linux/adm8668/base-files/lib/preinit/05_set_preinit_face_adm8668 new file mode 100644 index 000000000..ac2a7cbb6 --- /dev/null +++ b/target/linux/adm8668/base-files/lib/preinit/05_set_preinit_face_adm8668 @@ -0,0 +1,9 @@ +#!/bin/sh + +set_preinit_ifname() { + ifname=eth0 +} + +boot_hook_add preinit_main set_preinit_ifname + + diff --git a/target/linux/adm8668/base-files/lib/preinit/45_failsafe_adm8668 b/target/linux/adm8668/base-files/lib/preinit/45_failsafe_adm8668 new file mode 100644 index 000000000..c54aaed1e --- /dev/null +++ b/target/linux/adm8668/base-files/lib/preinit/45_failsafe_adm8668 @@ -0,0 +1,11 @@ +#!/bin/sh + +failsafe_wait() { + FAILSAFE= + grep -q 'SES: UP FLIP' /proc/adm8668/buttons && FAILSAFE=true && export FAILSAFE + grep -q 'SES: DOWN' /proc/adm8668/buttons && FAILSAFE=true && export FAILSAFE + if [ "$FAILSAFE" != "true" ]; then + preinit_net_echo "Please press button now to enter failsafe" + fs_wait_for_key f 'to enter failsafe mode' $fs_failsafe_wait_timeout && FAILSAFE=true && export FAILSAFE + fi +} diff --git a/target/linux/adm8668/base-files/lib/upgrade/platform.sh b/target/linux/adm8668/base-files/lib/upgrade/platform.sh new file mode 100644 index 000000000..583fa2e1d --- /dev/null +++ b/target/linux/adm8668/base-files/lib/upgrade/platform.sh @@ -0,0 +1,15 @@ +PART_NAME=linux +platform_check_image() { + [ "$ARGC" -gt 1 ] && return 1 + + case "$(get_magic_word "$1")" in + # u-boot + 2705) return 0;; + *) + echo "Invalid image type. Please use only u-boot files" + return 1 + ;; + esac +} + +# use default for platform_do_upgrade() diff --git a/target/linux/adm8668/base-files/sbin/hotplug.failsafe b/target/linux/adm8668/base-files/sbin/hotplug.failsafe new file mode 100644 index 000000000..0544339de --- /dev/null +++ b/target/linux/adm8668/base-files/sbin/hotplug.failsafe @@ -0,0 +1,4 @@ +#!/bin/sh +case "$1" in + button) kill -USR1 1;; +esac diff --git a/target/linux/adm8668/config-3.3 b/target/linux/adm8668/config-3.3 new file mode 100644 index 000000000..c5e486053 --- /dev/null +++ b/target/linux/adm8668/config-3.3 @@ -0,0 +1,77 @@ +CONFIG_ADM8668=y +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +CONFIG_ARCH_DISCARD_MEMBLOCK=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_BCMA_POSSIBLE=y +CONFIG_CEVT_R4K=y +CONFIG_CEVT_R4K_LIB=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPS32_R1=y +CONFIG_CPU_MIPSR1=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CSRC_R4K=y +CONFIG_CSRC_R4K_LIB=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_EEPROM_93CX6=m +CONFIG_GENERIC_ATOMIC64=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_HARDWARE_WATCHPOINTS=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_GENERIC_HARDIRQS=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_WORK=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HW_HAS_PCI=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IRQ_CPU=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_MIPS=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +# CONFIG_MIPS_MACHINE is not set +CONFIG_MIPS_MT_DISABLED=y +CONFIG_MTD_ADM8668_NOR=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NO_EXCEPT_FILL=y +CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PERF_USE_VMALLOC=y +# CONFIG_PREEMPT_RCU is not set +# CONFIG_SCSI_DMA is not set +CONFIG_SERIAL_ADM8668=y +CONFIG_SERIAL_ADM8668_CONSOLE=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_XZ_DEC=y +CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/adm8668/files/arch/mips/adm8668/Makefile b/target/linux/adm8668/files/arch/mips/adm8668/Makefile new file mode 100644 index 000000000..0b31b97d4 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/Makefile @@ -0,0 +1,5 @@ +# +# something witty --neutronscott +# + +obj-y := irq.o pci.o prom.o platform.o serial.o proc.o net_core.o net_intr.o diff --git a/target/linux/adm8668/files/arch/mips/adm8668/Platform b/target/linux/adm8668/files/arch/mips/adm8668/Platform new file mode 100644 index 000000000..c70cd270b --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/Platform @@ -0,0 +1,6 @@ +# +# Infineon ADM8668 WildPass +# +platform-$(CONFIG_ADM8668) += adm8668/ +cflags-$(CONFIG_ADM8668) += -I$(srctree)/arch/mips/include/asm/mach-adm8668 +load-$(CONFIG_ADM8668) += 0xffffffff80002000 diff --git a/target/linux/adm8668/files/arch/mips/adm8668/irq.c b/target/linux/adm8668/files/arch/mips/adm8668/irq.c new file mode 100644 index 000000000..e048c15c8 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/irq.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2010 Scott Nicholas + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void adm8668_irq_cascade(void) +{ + int i; + unsigned long intsrc; + + intsrc = ADM8668_INTC_REG(IRQ_STATUS_REG) & IRQ_MASK; + for (i = 0; intsrc; intsrc >>= 1, i++) + if (intsrc & 0x1) + do_IRQ(i); +} + +/* + * System irq dispatch + */ +void plat_irq_dispatch(void) +{ + unsigned int pending; + + pending = read_c0_cause() & read_c0_status() & ST0_IM; + + /* timer interrupt, that we renumbered */ + if (pending & STATUSF_IP7) + do_IRQ(MIPS_CPU_IRQ_BASE + 7); + if (pending & STATUSF_IP2) + adm8668_irq_cascade(); +} + +/* + * enable 8668 irq + */ +static void enable_adm8668_irq(struct irq_data *d) +{ + int irq = d->irq; + + if ((irq < 0) || (irq > NR_IRQS)) + return; + + ADM8668_INTC_REG(IRQ_ENABLE_REG) = (1 << irq); +} + + +/* + * disable 8668 irq + */ +static void disable_adm8668_irq(struct irq_data *d) +{ + int irq = d->irq; + + if ((irq < 0) || (irq > NR_IRQS)) + return; + + ADM8668_INTC_REG(IRQ_DISABLE_REG) = (1 << irq); +} + +static void ack_adm8668_irq(struct irq_data *d) +{ + int irq = d->irq; + + ADM8668_INTC_REG(IRQ_DISABLE_REG) = (1 << irq); +} + +/* + * system irq type + */ + +static struct irq_chip adm8668_irq_type = { + .name = "adm8668", + .irq_ack = ack_adm8668_irq, + .irq_mask = disable_adm8668_irq, + .irq_unmask = enable_adm8668_irq +}; + +/* + * irq init + */ +static void __init init_adm8668_irqs(void) +{ + int i; + + for (i = 0; i <= INT_LVL_MAX; i++) + irq_set_chip_and_handler(i, &adm8668_irq_type, + handle_level_irq); + + /* hw0 is where our interrupts are uh.. interrupted at. */ + set_c0_status(IE_IRQ0); +} + +/* + * system init + */ +void __init arch_init_irq(void) +{ + mips_cpu_irq_init(); + init_adm8668_irqs(); +} diff --git a/target/linux/adm8668/files/arch/mips/adm8668/net.h b/target/linux/adm8668/files/arch/mips/adm8668/net.h new file mode 100644 index 000000000..c7aef8cf6 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/net.h @@ -0,0 +1,277 @@ +/* + * originally drivers/net/tulip/tulip.h + * Copyright 2000,2001 The Linux Kernel Team + * Written/copyright 1994-2001 by Donald Becker. + * + * 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. + */ + +#ifndef __NET_TULIP_H__ +#define __NET_TULIP_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* undefine, or define to various debugging levels (>4 == obscene levels) */ +#define TULIP_DEBUG 1 +#define VALID_INTR 0x0001a451 +#define ADM8668_WAN_IRQ 8 +#define ADM8668_LAN_IRQ 7 +#define ADM8668_WAN_MACADDR 0xb00205ac +#define ADM8668_LAN_MACADDR 0xb0020404 + +/* Offsets to the Command and Status Registers, "CSRs". All accesses + must be longword instructions and quadword aligned. */ +enum tulip_offsets { + CSR0 = 0, + CSR1 = 0x08, + CSR2 = 0x10, + CSR3 = 0x18, + CSR4 = 0x20, + CSR5 = 0x28, + CSR6 = 0x30, + CSR7 = 0x38, + CSR8 = 0x40, + CSR9 = 0x48, + CSR10 = 0x50, + CSR11 = 0x58, + CSR12 = 0x60, + CSR13 = 0x68, + CSR14 = 0x70, + CSR15 = 0x78, + CSR18 = 0x88, + CSR19 = 0x8c, + CSR20 = 0x90, + CSR27 = 0xAC, + CSR28 = 0xB0, +}; + +#define RxPollInt (RxIntr|RxNoBuf|RxDied|RxJabber) + +/* The bits in the CSR5 status registers, mostly interrupt sources. */ +enum status_bits { + TimerInt = 0x800, + SystemError = 0x2000, + TPLnkFail = 0x1000, + TPLnkPass = 0x10, + NormalIntr = 0x10000, + AbnormalIntr = 0x8000, + RxJabber = 0x200, + RxDied = 0x100, + RxNoBuf = 0x80, + RxIntr = 0x40, + TxFIFOUnderflow = 0x20, + RxErrIntr = 0x10, + TxJabber = 0x08, + TxNoBuf = 0x04, + TxDied = 0x02, + TxIntr = 0x01, +}; + +/* bit mask for CSR5 TX/RX process state */ +#define CSR5_TS 0x00700000 +#define CSR5_RS 0x000e0000 + +enum tulip_mode_bits { + TxThreshold = (1 << 22), + FullDuplex = (1 << 9), + TxOn = 0x2000, + AcceptBroadcast = 0x0100, + AcceptAllMulticast = 0x0080, + AcceptAllPhys = 0x0040, + AcceptRunt = 0x0008, + RxOn = 0x0002, + RxTx = (TxOn | RxOn), +}; + +/* The Tulip Rx and Tx buffer descriptors. */ +struct tulip_rx_desc { + __le32 status; + __le32 length; + __le32 buffer1; + __le32 buffer2; +}; + +struct tulip_tx_desc { + __le32 status; + __le32 length; + __le32 buffer1; + __le32 buffer2; /* We use only buffer 1. */ +}; + +enum desc_status_bits { + DescOwned = 0x80000000, + DescWholePkt = 0x60000000, + DescEndPkt = 0x40000000, + DescStartPkt = 0x20000000, + DescEndRing = 0x02000000, + DescUseLink = 0x01000000, + + /* + * Error summary flag is logical or of 'CRC Error', 'Collision Seen', + * 'Frame Too Long', 'Runt' and 'Descriptor Error' flags generated + * within tulip chip. + */ + RxDescErrorSummary = 0x8000, + RxDescCRCError = 0x0002, + RxDescCollisionSeen = 0x0040, + + /* + * 'Frame Too Long' flag is set if packet length including CRC exceeds + * 1518. However, a full sized VLAN tagged frame is 1522 bytes + * including CRC. + * + * The tulip chip does not block oversized frames, and if this flag is + * set on a receive descriptor it does not indicate the frame has been + * truncated. The receive descriptor also includes the actual length. + * Therefore we can safety ignore this flag and check the length + * ourselves. + */ + RxDescFrameTooLong = 0x0080, + RxDescRunt = 0x0800, + RxDescDescErr = 0x4000, + RxWholePkt = 0x00000300, + /* + * Top three bits of 14 bit frame length (status bits 27-29) should + * never be set as that would make frame over 2047 bytes. The Receive + * Watchdog flag (bit 4) may indicate the length is over 2048 and the + * length field is invalid. + */ + RxLengthOver2047 = 0x38000010 +}; + +/* Keep the ring sizes a power of two for efficiency. + Making the Tx ring too large decreases the effectiveness of channel + bonding and packet priority. + There are no ill effects from too-large receive rings. */ + +#define TX_RING_SIZE 32 +#define RX_RING_SIZE 128 + +/* The receiver on the DC21143 rev 65 can fail to close the last + * receive descriptor in certain circumstances (see errata) when + * using MWI. This can only occur if the receive buffer ends on + * a cache line boundary, so the "+ 4" below ensures it doesn't. + */ +#define PKT_BUF_SZ (1536 + 4) /* Size of each temporary Rx buffer. */ + +/* Ring-wrap flag in length field, use for last ring entry. + 0x01000000 means chain on buffer2 address, + 0x02000000 means use the ring start address in CSR2/3. + Note: Some work-alike chips do not function correctly in chained mode. + The ASIX chip works only in chained mode. + Thus we indicates ring mode, but always write the 'next' field for + chained mode as well. +*/ +#define DESC_RING_WRAP 0x02000000 + +struct ring_info { + struct sk_buff *skb; + dma_addr_t mapping; +}; + +struct tulip_private { + struct tulip_rx_desc *rx_ring; + struct tulip_tx_desc *tx_ring; + dma_addr_t rx_ring_dma; + dma_addr_t tx_ring_dma; + /* The saved address of a sent-in-place packet/buffer, for skfree(). */ + struct ring_info tx_buffers[TX_RING_SIZE]; + /* The addresses of receive-in-place skbuffs. */ + struct ring_info rx_buffers[RX_RING_SIZE]; + struct napi_struct napi; + struct net_device_stats stats; + struct timer_list oom_timer; /* Out of memory timer. */ + u32 mc_filter[2]; + spinlock_t lock; + unsigned int cur_rx, cur_tx; /* The next free ring entry */ + unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ + unsigned int csr0; /* CSR0 setting. */ + unsigned int csr6; /* Current CSR6 control settings. */ + void (*link_change) (struct net_device * dev, int csr5); + struct platform_device *pdev; + unsigned long nir; + void __iomem *base_addr; + int pad0; /* Used for 8-byte alignment */ + struct net_device *dev; +}; + + +/* interrupt.c */ +irqreturn_t tulip_interrupt(int irq, void *dev_instance); +int tulip_refill_rx(struct net_device *dev); +int tulip_poll(struct napi_struct *napi, int budget); + +/* tulip_core.c */ +extern int tulip_debug; +void oom_timer(unsigned long data); + +static inline void tulip_start_rxtx(struct tulip_private *tp) +{ + void __iomem *ioaddr = tp->base_addr; + iowrite32(tp->csr6 | RxTx, ioaddr + CSR6); + barrier(); + (void) ioread32(ioaddr + CSR6); /* mmio sync */ +} + +static inline void tulip_stop_rxtx(struct tulip_private *tp) +{ + void __iomem *ioaddr = tp->base_addr; + u32 csr6 = ioread32(ioaddr + CSR6); + + if (csr6 & RxTx) { + unsigned i=1300/10; + iowrite32(csr6 & ~RxTx, ioaddr + CSR6); + barrier(); + /* wait until in-flight frame completes. + * Max time @ 10BT: 1500*8b/10Mbps == 1200us (+ 100us margin) + * Typically expect this loop to end in < 50 us on 100BT. + */ + while (--i && (ioread32(ioaddr + CSR5) & (CSR5_TS|CSR5_RS))) + udelay(10); + + if (!i) + printk(KERN_DEBUG "fixme: tulip_stop_rxtx() failed" + " (CSR5 0x%x CSR6 0x%x)\n", + ioread32(ioaddr + CSR5), + ioread32(ioaddr + CSR6)); + } +} + +static inline void tulip_restart_rxtx(struct tulip_private *tp) +{ + tulip_stop_rxtx(tp); + udelay(5); + tulip_start_rxtx(tp); +} + +static inline void tulip_tx_timeout_complete(struct tulip_private *tp, void __iomem *ioaddr) +{ + /* Stop and restart the chip's Tx processes. */ + tulip_restart_rxtx(tp); + /* Trigger an immediate transmit demand. */ + iowrite32(0, ioaddr + CSR1); + + tp->stats.tx_errors++; +} + +#endif /* __NET_TULIP_H__ */ diff --git a/target/linux/adm8668/files/arch/mips/adm8668/net_core.c b/target/linux/adm8668/files/arch/mips/adm8668/net_core.c new file mode 100644 index 000000000..3348c224b --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/net_core.c @@ -0,0 +1,618 @@ +/* + * originally drivers/net/tulip_core.c + * Copyright 2000,2001 The Linux Kernel Team + * Written/copyright 1994-2001 by Donald Becker. + * + * 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. + */ + +#define DRV_NAME "tulip" +#define DRV_VERSION "1.1.15-NAPI" /* Keep at least for test */ +#define DRV_RELDATE "Feb 27, 2007" + +#include "net.h" + +static char version[] __devinitdata = + "ADM8668net driver version " DRV_VERSION " (" DRV_RELDATE ")\n"; + +#define MAX_UNITS 2 + +/* + Set the bus performance register. + Typical: Set 16 longword cache alignment, no burst limit. + Cache alignment bits 15:14 Burst length 13:8 + 0000 No alignment 0x00000000 unlimited 0800 8 longwords + 4000 8 longwords 0100 1 longword 1000 16 longwords + 8000 16 longwords 0200 2 longwords 2000 32 longwords + C000 32 longwords 0400 4 longwords + Warning: many older 486 systems are broken and require setting 0x00A04800 + 8 longword cache alignment, 8 longword burst. + ToDo: Non-Intel setting could be better. +*/ + +//static int csr0 = 0x00200000 | 0x4000; +static int csr0 = 0; + +/* Operational parameters that usually are not changed. */ +/* Time in jiffies before concluding the transmitter is hung. */ +#define TX_TIMEOUT (4*HZ) + +MODULE_AUTHOR("Scott Nicholas "); +MODULE_DESCRIPTION("ADM8668 new ethernet driver."); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); + +#ifdef TULIP_DEBUG +int tulip_debug = TULIP_DEBUG; +#else +int tulip_debug = 1; +#endif + +static void tulip_tx_timeout(struct net_device *dev); +static void tulip_init_ring(struct net_device *dev); +static void tulip_free_ring(struct net_device *dev); +static netdev_tx_t tulip_start_xmit(struct sk_buff *skb, + struct net_device *dev); +static int tulip_open(struct net_device *dev); +static int tulip_close(struct net_device *dev); +static void tulip_up(struct net_device *dev); +static void tulip_down(struct net_device *dev); +static struct net_device_stats *tulip_get_stats(struct net_device *dev); +//static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static void set_rx_mode(struct net_device *dev); +#ifdef CONFIG_NET_POLL_CONTROLLER +static void poll_tulip(struct net_device *dev); +#endif + +static void tulip_up(struct net_device *dev) +{ + struct tulip_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->base_addr; + + napi_enable(&tp->napi); + + /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */ + iowrite32(0x00000001, ioaddr + CSR0); + + /* Deassert reset. + Wait the specified 50 PCI cycles after a reset by initializing + Tx and Rx queues and the address filter list. */ + iowrite32(tp->csr0, ioaddr + CSR0); + + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: tulip_up(), irq==%d\n", + dev->name, dev->irq); + + iowrite32(tp->rx_ring_dma, ioaddr + CSR3); + iowrite32(tp->tx_ring_dma, ioaddr + CSR4); + tp->cur_rx = tp->cur_tx = 0; + tp->dirty_rx = tp->dirty_tx = 0; + + /* set mac address */ + iowrite32(get_unaligned_le32(dev->dev_addr), ioaddr + 0xA4); + iowrite32(get_unaligned_le16(dev->dev_addr + 4), ioaddr + 0xA8); + iowrite32(0, ioaddr + CSR27); + iowrite32(0, ioaddr + CSR28); + + tp->csr6 = 0; + + /* Enable automatic Tx underrun recovery. */ + iowrite32(ioread32(ioaddr + CSR18) | 1, ioaddr + CSR18); + tp->csr6 = 0x00040000; + + /* Start the chip's Tx to process setup frame. */ + tulip_stop_rxtx(tp); + barrier(); + udelay(5); + iowrite32(tp->csr6 | TxOn, ioaddr + CSR6); + + /* Enable interrupts by setting the interrupt mask. */ + iowrite32(VALID_INTR, ioaddr + CSR5); + iowrite32(VALID_INTR, ioaddr + CSR7); + tulip_start_rxtx(tp); + iowrite32(0, ioaddr + CSR2); /* Rx poll demand */ + + if (tulip_debug > 2) { + printk(KERN_DEBUG "%s: Done tulip_up(), CSR0 %08x, CSR5 %08x CSR6 %08x\n", + dev->name, ioread32(ioaddr + CSR0), + ioread32(ioaddr + CSR5), + ioread32(ioaddr + CSR6)); + } + + init_timer(&tp->oom_timer); + tp->oom_timer.data = (unsigned long)dev; + tp->oom_timer.function = oom_timer; +} + +static int +tulip_open(struct net_device *dev) +{ + int retval; + + tulip_init_ring (dev); + + retval = request_irq(dev->irq, tulip_interrupt, 0, dev->name, dev); + if (retval) + goto free_ring; + + tulip_up (dev); + + netif_start_queue (dev); + + return 0; + +free_ring: + tulip_free_ring (dev); + return retval; +} + + +static void tulip_tx_timeout(struct net_device *dev) +{ + struct tulip_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->base_addr; + unsigned long flags; + + spin_lock_irqsave (&tp->lock, flags); + + dev_warn(&dev->dev, + "Transmit timed out, status %08x, CSR12 %08x, resetting...\n", + ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12)); + + tulip_tx_timeout_complete(tp, ioaddr); + + spin_unlock_irqrestore (&tp->lock, flags); + dev->trans_start = jiffies; /* prevent tx timeout */ + netif_wake_queue (dev); +} + + +/* Initialize the Rx and Tx rings, along with various 'dev' bits. */ +static void tulip_init_ring(struct net_device *dev) +{ + struct tulip_private *tp = netdev_priv(dev); + int i; + + tp->nir = 0; + + for (i = 0; i < RX_RING_SIZE; i++) { + tp->rx_ring[i].status = 0x00000000; + tp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ); + tp->rx_ring[i].buffer2 = cpu_to_le32(tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * (i + 1)); + tp->rx_buffers[i].skb = NULL; + tp->rx_buffers[i].mapping = 0; + } + /* Mark the last entry as wrapping the ring. */ + tp->rx_ring[i-1].length = cpu_to_le32(PKT_BUF_SZ | DESC_RING_WRAP); + tp->rx_ring[i-1].buffer2 = cpu_to_le32(tp->rx_ring_dma); + + for (i = 0; i < RX_RING_SIZE; i++) { + dma_addr_t mapping; + /* Note the receive buffer must be longword aligned. + dev_alloc_skb() provides 16 byte alignment. But do *not* + use skb_reserve() to align the IP header! */ + struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ); + tp->rx_buffers[i].skb = skb; + if (skb == NULL) + break; + mapping = dma_map_single(&dev->dev, skb->data, + PKT_BUF_SZ, DMA_FROM_DEVICE); + tp->rx_buffers[i].mapping = mapping; + skb->dev = dev; /* Mark as being used by this device. */ + tp->rx_ring[i].status = cpu_to_le32(DescOwned); /* Owned by Tulip chip */ + tp->rx_ring[i].buffer1 = cpu_to_le32(mapping); + } + tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); + + /* The Tx buffer descriptor is filled in as needed, but we + do need to clear the ownership bit. */ + for (i = 0; i < TX_RING_SIZE; i++) { + tp->tx_buffers[i].skb = NULL; + tp->tx_buffers[i].mapping = 0; + tp->tx_ring[i].status = 0x00000000; + tp->tx_ring[i].buffer2 = cpu_to_le32(tp->tx_ring_dma + sizeof(struct tulip_tx_desc) * (i + 1)); + } + tp->tx_ring[i-1].buffer2 = cpu_to_le32(tp->tx_ring_dma); +} + +static netdev_tx_t +tulip_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct tulip_private *tp = netdev_priv(dev); + int entry; + u32 flag; + dma_addr_t mapping; + unsigned long flags; + + spin_lock_irqsave(&tp->lock, flags); + + /* Calculate the next Tx descriptor entry. */ + entry = tp->cur_tx % TX_RING_SIZE; + + tp->tx_buffers[entry].skb = skb; + mapping = dma_map_single(&tp->pdev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + tp->tx_buffers[entry].mapping = mapping; + tp->tx_ring[entry].buffer1 = cpu_to_le32(mapping); + + if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE/2) {/* Typical path */ + flag = 0x60000000; /* No interrupt */ + } else if (tp->cur_tx - tp->dirty_tx == TX_RING_SIZE/2) { + flag = 0xe0000000; /* Tx-done intr. */ + } else if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE - 2) { + flag = 0x60000000; /* No Tx-done intr. */ + } else { /* Leave room for set_rx_mode() to fill entries. */ + flag = 0xe0000000; /* Tx-done intr. */ + netif_stop_queue(dev); + } + if (entry == TX_RING_SIZE-1) + flag = 0xe0000000 | DESC_RING_WRAP; + + tp->tx_ring[entry].length = cpu_to_le32(skb->len | flag); + /* if we were using Transmit Automatic Polling, we would need a + * wmb() here. */ + tp->tx_ring[entry].status = cpu_to_le32(DescOwned); + wmb(); + + tp->cur_tx++; + + /* Trigger an immediate transmit demand. */ + iowrite32(0, tp->base_addr + CSR1); + + spin_unlock_irqrestore(&tp->lock, flags); + + return NETDEV_TX_OK; +} + +static void tulip_clean_tx_ring(struct tulip_private *tp) +{ + unsigned int dirty_tx; + + for (dirty_tx = tp->dirty_tx ; tp->cur_tx - dirty_tx > 0; + dirty_tx++) { + int entry = dirty_tx % TX_RING_SIZE; + int status = le32_to_cpu(tp->tx_ring[entry].status); + + if (status < 0) { + tp->stats.tx_errors++; /* It wasn't Txed */ + tp->tx_ring[entry].status = 0; + } + + dma_unmap_single(&tp->pdev->dev, tp->tx_buffers[entry].mapping, + tp->tx_buffers[entry].skb->len, + DMA_TO_DEVICE); + + /* Free the original skb. */ + dev_kfree_skb_irq(tp->tx_buffers[entry].skb); + tp->tx_buffers[entry].skb = NULL; + tp->tx_buffers[entry].mapping = 0; + } +} + +static void tulip_down (struct net_device *dev) +{ + struct tulip_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->base_addr; + unsigned long flags; + + napi_disable(&tp->napi); + del_timer_sync (&tp->oom_timer); + spin_lock_irqsave (&tp->lock, flags); + + /* Disable interrupts by clearing the interrupt mask. */ + iowrite32 (0x00000000, ioaddr + CSR7); + + /* Stop the Tx and Rx processes. */ + tulip_stop_rxtx(tp); + + /* prepare receive buffers */ + tulip_refill_rx(dev); + + /* release any unconsumed transmit buffers */ + tulip_clean_tx_ring(tp); + + if (ioread32 (ioaddr + CSR6) != 0xffffffff) + tp->stats.rx_missed_errors += ioread32 (ioaddr + CSR8) & 0xffff; + + spin_unlock_irqrestore (&tp->lock, flags); +} + +static void tulip_free_ring (struct net_device *dev) +{ + struct tulip_private *tp = netdev_priv(dev); + int i; + + /* Free all the skbuffs in the Rx queue. */ + for (i = 0; i < RX_RING_SIZE; i++) { + struct sk_buff *skb = tp->rx_buffers[i].skb; + dma_addr_t mapping = tp->rx_buffers[i].mapping; + + tp->rx_buffers[i].skb = NULL; + tp->rx_buffers[i].mapping = 0; + + tp->rx_ring[i].status = 0; /* Not owned by Tulip chip. */ + tp->rx_ring[i].length = 0; + /* An invalid address. */ + tp->rx_ring[i].buffer1 = cpu_to_le32(0xBADF00D0); + if (skb) { + dma_unmap_single(&tp->pdev->dev, mapping, PKT_BUF_SZ, + DMA_FROM_DEVICE); + dev_kfree_skb (skb); + } + } + + for (i = 0; i < TX_RING_SIZE; i++) { + struct sk_buff *skb = tp->tx_buffers[i].skb; + + if (skb != NULL) { + dma_unmap_single(&tp->pdev->dev, + tp->tx_buffers[i].mapping, skb->len, DMA_TO_DEVICE); + dev_kfree_skb (skb); + } + tp->tx_buffers[i].skb = NULL; + tp->tx_buffers[i].mapping = 0; + } +} + +static int tulip_close (struct net_device *dev) +{ + struct tulip_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->base_addr; + + netif_stop_queue (dev); + + tulip_down (dev); + + if (tulip_debug > 1) + dev_printk(KERN_DEBUG, &dev->dev, + "Shutting down ethercard, status was %02x\n", + ioread32 (ioaddr + CSR5)); + + free_irq (dev->irq, dev); + + tulip_free_ring (dev); + + return 0; +} + +static struct net_device_stats *tulip_get_stats(struct net_device *dev) +{ + struct tulip_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->base_addr; + + if (netif_running(dev)) { + unsigned long flags; + + spin_lock_irqsave (&tp->lock, flags); + + tp->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff; + + spin_unlock_irqrestore(&tp->lock, flags); + } + + return &tp->stats; +} + + +static void tulip_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, "mmio"); +} + +static const struct ethtool_ops ops = { + .get_drvinfo = tulip_get_drvinfo +}; + +static void set_rx_mode(struct net_device *dev) +{ + struct tulip_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->base_addr; + int csr6; + + csr6 = ioread32(ioaddr + CSR6) & ~0x00D5; + + tp->csr6 &= ~0x00D5; + if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ + tp->csr6 |= AcceptAllMulticast | AcceptAllPhys; + csr6 |= AcceptAllMulticast | AcceptAllPhys; + } else if ((netdev_mc_count(dev) > 1000) || + (dev->flags & IFF_ALLMULTI)) { + /* Too many to filter well -- accept all multicasts. */ + tp->csr6 |= AcceptAllMulticast; + csr6 |= AcceptAllMulticast; + } else { + /* Some work-alikes have only a 64-entry hash filter table. */ + /* Should verify correctness on big-endian/__powerpc__ */ + struct netdev_hw_addr *ha; + if (netdev_mc_count(dev) > 64) { + /* Arbitrary non-effective limit. */ + tp->csr6 |= AcceptAllMulticast; + csr6 |= AcceptAllMulticast; + } else { + u32 mc_filter[2] = {0, 0}; /* Multicast hash filter */ + int filterbit; + netdev_for_each_mc_addr(ha, dev) { + filterbit = ether_crc_le(ETH_ALEN, ha->addr); + filterbit &= 0x3f; + mc_filter[filterbit >> 5] |= 1 << (filterbit & 31); + if (tulip_debug > 2) + dev_info(&dev->dev, + "Added filter for %pM %08x bit %d\n", + ha->addr, + ether_crc(ETH_ALEN, ha->addr), + filterbit); + } + if (mc_filter[0] == tp->mc_filter[0] && + mc_filter[1] == tp->mc_filter[1]) + ; /* No change. */ + iowrite32(mc_filter[0], ioaddr + CSR27); + iowrite32(mc_filter[1], ioaddr + CSR28); + tp->mc_filter[0] = mc_filter[0]; + tp->mc_filter[1] = mc_filter[1]; + } + } + + if (dev->irq == ADM8668_LAN_IRQ) + csr6 |= (1 << 9); /* force 100Mbps full duplex */ +// csr6 |= 1; /* pad 2 bytes. vlan? */ + + iowrite32(csr6, ioaddr + CSR6); +} + +static const struct net_device_ops tulip_netdev_ops = { + .ndo_open = tulip_open, + .ndo_start_xmit = tulip_start_xmit, + .ndo_tx_timeout = tulip_tx_timeout, + .ndo_stop = tulip_close, + .ndo_get_stats = tulip_get_stats, + .ndo_set_rx_mode = set_rx_mode, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = poll_tulip, +#endif +}; + +static int __devinit adm8668net_probe(struct platform_device *pdev) +{ + struct tulip_private *tp; + struct net_device *dev; + struct resource *res; + void __iomem *ioaddr; + int irq; + + if (pdev->id < 0 || pdev->id >= MAX_UNITS) + return -EINVAL; + + if (!(res = platform_get_resource(pdev, IORESOURCE_IRQ, 0))) + return -ENODEV; + irq = res->start; + if (!(res = platform_get_resource(pdev, IORESOURCE_MEM, 0))) + return -ENODEV; + if (!(ioaddr = ioremap(res->start, res->end - res->start))) + return -ENODEV; + if (!(dev = alloc_etherdev(sizeof (*tp)))) + return -ENOMEM; + + /* setup net dev */ + dev->base_addr = (unsigned long)res->start; + dev->irq = irq; + SET_NETDEV_DEV(dev, &pdev->dev); + + /* tulip private struct */ + tp = netdev_priv(dev); + tp->dev = dev; + tp->base_addr = ioaddr; + tp->csr0 = csr0; + tp->pdev = pdev; + tp->rx_ring = dma_alloc_coherent(&pdev->dev, + sizeof(struct tulip_rx_desc) * RX_RING_SIZE + + sizeof(struct tulip_tx_desc) * TX_RING_SIZE, + &tp->rx_ring_dma, GFP_KERNEL); + if (!tp->rx_ring) + return -ENODEV; + tp->tx_ring = (struct tulip_tx_desc *)(tp->rx_ring + RX_RING_SIZE); + tp->tx_ring_dma = tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * RX_RING_SIZE; + + spin_lock_init(&tp->lock); + + /* Stop the chip's Tx and Rx processes. */ + tulip_stop_rxtx(tp); + + /* Clear the missed-packet counter. */ + ioread32(ioaddr + CSR8); + + /* Addresses are stored in BSP area of NOR flash */ + if (irq == ADM8668_WAN_IRQ) + memcpy(dev->dev_addr, (char *)ADM8668_WAN_MACADDR, 6); + else + memcpy(dev->dev_addr, (char *)ADM8668_LAN_MACADDR, 6); + + /* The Tulip-specific entries in the device structure. */ + dev->netdev_ops = &tulip_netdev_ops; + dev->watchdog_timeo = TX_TIMEOUT; + netif_napi_add(dev, &tp->napi, tulip_poll, 16); + SET_ETHTOOL_OPS(dev, &ops); + + if (register_netdev(dev)) + goto err_out_free_ring; + + dev_info(&dev->dev, + "ADM8668net at MMIO %#lx %pM, IRQ %d\n", + (unsigned long)dev->base_addr, dev->dev_addr, irq); + + platform_set_drvdata(pdev, dev); + return 0; + +err_out_free_ring: + dma_free_coherent(&pdev->dev, + sizeof (struct tulip_rx_desc) * RX_RING_SIZE + + sizeof (struct tulip_tx_desc) * TX_RING_SIZE, + tp->rx_ring, tp->rx_ring_dma); + return -ENODEV; +} + +static int __devexit adm8668net_remove(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata (pdev); + struct tulip_private *tp; + + if (!dev) + return -ENODEV; + + tp = netdev_priv(dev); + unregister_netdev(dev); + dma_free_coherent(&pdev->dev, + sizeof (struct tulip_rx_desc) * RX_RING_SIZE + + sizeof (struct tulip_tx_desc) * TX_RING_SIZE, + tp->rx_ring, tp->rx_ring_dma); + iounmap(tp->base_addr); + free_netdev(dev); + platform_set_drvdata(pdev, NULL); + return 0; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +/* + * Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. + */ + +static void poll_tulip (struct net_device *dev) +{ + /* disable_irq here is not very nice, but with the lockless + interrupt handler we have no other choice. */ + disable_irq(dev->irq); + tulip_interrupt(dev->irq, dev); + enable_irq(dev->irq); +} +#endif + +static struct platform_driver adm8668net_platform_driver = { + .probe = adm8668net_probe, + .remove = __devexit_p(adm8668net_remove), + .driver = { + .owner = THIS_MODULE, + .name = "adm8668_eth" + }, +}; + +static int __init adm8668net_init(void) +{ + pr_info("%s", version); + return platform_driver_register(&adm8668net_platform_driver); +} + +static void __exit adm8668net_exit(void) +{ + platform_driver_unregister(&adm8668net_platform_driver); +} + +module_init(adm8668net_init); +module_exit(adm8668net_exit); diff --git a/target/linux/adm8668/files/arch/mips/adm8668/net_intr.c b/target/linux/adm8668/files/arch/mips/adm8668/net_intr.c new file mode 100644 index 000000000..113dbaebd --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/net_intr.c @@ -0,0 +1,446 @@ +/* + * originally drivers/net/tulip/interrupt.c + * Copyright 2000,2001 The Linux Kernel Team + * Written/copyright 1994-2001 by Donald Becker. + * + * 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. + */ + +#include "net.h" + +int tulip_refill_rx(struct net_device *dev) +{ + struct tulip_private *tp = netdev_priv(dev); + int entry; + int refilled = 0; + + /* Refill the Rx ring buffers. */ + for (; tp->cur_rx - tp->dirty_rx > 0; tp->dirty_rx++) { + entry = tp->dirty_rx % RX_RING_SIZE; + if (tp->rx_buffers[entry].skb == NULL) { + struct sk_buff *skb; + dma_addr_t mapping; + + skb = tp->rx_buffers[entry].skb = dev_alloc_skb(PKT_BUF_SZ); + if (skb == NULL) + break; + + mapping = dma_map_single(&dev->dev, skb->data, + PKT_BUF_SZ, DMA_FROM_DEVICE); + tp->rx_buffers[entry].mapping = mapping; + + skb->dev = dev; /* Mark as being used by this device. */ + tp->rx_ring[entry].buffer1 = cpu_to_le32(mapping); + refilled++; + } + tp->rx_ring[entry].status = cpu_to_le32(DescOwned); + } + return refilled; +} + +void oom_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct tulip_private *tp = netdev_priv(dev); + napi_schedule(&tp->napi); +} + +int tulip_poll(struct napi_struct *napi, int budget) +{ + struct tulip_private *tp = container_of(napi, struct tulip_private, napi); + struct net_device *dev = tp->dev; + int entry = tp->cur_rx % RX_RING_SIZE; + int work_done = 0; + + if (tulip_debug > 4) + printk(KERN_DEBUG " In tulip_rx(), entry %d %08x\n", + entry, tp->rx_ring[entry].status); + + do { + if (ioread32(tp->base_addr + CSR5) == 0xffffffff) { + printk(KERN_DEBUG " In tulip_poll(), hardware disappeared\n"); + break; + } + /* Acknowledge current RX interrupt sources. */ + iowrite32((RxIntr | RxNoBuf), tp->base_addr + CSR5); + + + /* If we own the next entry, it is a new packet. Send it up. */ + while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) { + s32 status = le32_to_cpu(tp->rx_ring[entry].status); + short pkt_len; + + if (tp->dirty_rx + RX_RING_SIZE == tp->cur_rx) + break; + + if (tulip_debug > 5) + printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %08x\n", + dev->name, entry, status); + + if (++work_done >= budget) + goto not_done; + + /* + * Omit the four octet CRC from the length. + * (May not be considered valid until we have + * checked status for RxLengthOver2047 bits) + */ + pkt_len = ((status >> 16) & 0x7ff) - 4; + +#if 0 + csr6 = ioread32(tp->base_addr + CSR6); + if (csr6 & 0x1) + pkt_len += 2; + +#endif + /* + * Maximum pkt_len is 1518 (1514 + vlan header) + * Anything higher than this is always invalid + * regardless of RxLengthOver2047 bits + */ + + if ((status & (RxLengthOver2047 | + RxDescCRCError | + RxDescCollisionSeen | + RxDescRunt | + RxDescDescErr | + RxWholePkt)) != RxWholePkt || + pkt_len > 1518) { + if ((status & (RxLengthOver2047 | + RxWholePkt)) != RxWholePkt) { + /* Ingore earlier buffers. */ + if ((status & 0xffff) != 0x7fff) { + if (tulip_debug > 1) + dev_warn(&dev->dev, + "Oversized Ethernet frame spanned multiple buffers, status %08x!\n", + status); + tp->stats.rx_length_errors++; + } + } else { + /* There was a fatal error. */ + if (tulip_debug > 2) + printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n", + dev->name, status); + tp->stats.rx_errors++; /* end of a packet.*/ + if (pkt_len > 1518 || + (status & RxDescRunt)) + tp->stats.rx_length_errors++; + + if (status & 0x0004) tp->stats.rx_frame_errors++; + if (status & 0x0002) tp->stats.rx_crc_errors++; + if (status & 0x0001) tp->stats.rx_fifo_errors++; + } + } else { + struct sk_buff *skb = tp->rx_buffers[entry].skb; + char *temp = skb_put(skb, pkt_len); + +#if 0 + if (csr6 & 1) + skb_pull(skb, 2); +#endif +#ifndef final_version + if (tp->rx_buffers[entry].mapping != + le32_to_cpu(tp->rx_ring[entry].buffer1)) { + dev_err(&dev->dev, + "Internal fault: The skbuff addresses do not match in tulip_rx: %08x vs. %08llx %p / %p\n", + le32_to_cpu(tp->rx_ring[entry].buffer1), + (unsigned long long)tp->rx_buffers[entry].mapping, + skb->head, temp); + } +#endif + + tp->rx_buffers[entry].skb = NULL; + tp->rx_buffers[entry].mapping = 0; + skb->protocol = eth_type_trans(skb, dev); + + netif_receive_skb(skb); + + tp->stats.rx_packets++; + tp->stats.rx_bytes += pkt_len; + } + entry = (++tp->cur_rx) % RX_RING_SIZE; + if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/4) + tulip_refill_rx(dev); + + } + + /* New ack strategy... irq does not ack Rx any longer + hopefully this helps */ + + /* Really bad things can happen here... If new packet arrives + * and an irq arrives (tx or just due to occasionally unset + * mask), it will be acked by irq handler, but new thread + * is not scheduled. It is major hole in design. + * No idea how to fix this if "playing with fire" will fail + * tomorrow (night 011029). If it will not fail, we won + * finally: amount of IO did not increase at all. */ + } while ((ioread32(tp->base_addr + CSR5) & RxIntr)); + + tulip_refill_rx(dev); + + /* If RX ring is not full we are out of memory. */ + if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) + goto oom; + + /* Remove us from polling list and enable RX intr. */ + napi_complete(napi); + iowrite32(VALID_INTR, tp->base_addr+CSR7); + + /* The last op happens after poll completion. Which means the following: + * 1. it can race with disabling irqs in irq handler + * 2. it can race with dise/enabling irqs in other poll threads + * 3. if an irq raised after beginning loop, it will be immediately + * triggered here. + * + * Summarizing: the logic results in some redundant irqs both + * due to races in masking and due to too late acking of already + * processed irqs. But it must not result in losing events. + */ + + return work_done; + + not_done: + if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/2 || + tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) + tulip_refill_rx(dev); + + if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) + goto oom; + + return work_done; + + oom: /* Executed with RX ints disabled */ + + /* Start timer, stop polling, but do not enable rx interrupts. */ + mod_timer(&tp->oom_timer, jiffies+1); + + /* Think: timer_pending() was an explicit signature of bug. + * Timer can be pending now but fired and completed + * before we did napi_complete(). See? We would lose it. */ + + /* remove ourselves from the polling list */ + napi_complete(napi); + + return work_done; +} + +/* The interrupt handler does all of the Rx thread work and cleans up + after the Tx thread. */ +irqreturn_t tulip_interrupt(int irq, void *dev_instance) +{ + struct net_device *dev = (struct net_device *)dev_instance; + struct tulip_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->base_addr; + int csr5; + int missed; + int rx = 0; + int tx = 0; + int oi = 0; + int maxrx = RX_RING_SIZE; + int maxtx = TX_RING_SIZE; + int maxoi = TX_RING_SIZE; + int rxd = 0; + unsigned int work_count = 25; + unsigned int handled = 0; + + /* Let's see whether the interrupt really is for us */ + csr5 = ioread32(ioaddr + CSR5); + + if ((csr5 & (NormalIntr|AbnormalIntr)) == 0) + return IRQ_RETVAL(handled); + + tp->nir++; + + do { + + if (!rxd && (csr5 & (RxIntr | RxNoBuf))) { + rxd++; + /* Mask RX intrs and add the device to poll list. */ + iowrite32(VALID_INTR&~RxPollInt, ioaddr + CSR7); + napi_schedule(&tp->napi); + + if (!(csr5&~(AbnormalIntr|NormalIntr|RxPollInt|TPLnkPass))) + break; + } + + /* Acknowledge the interrupt sources we handle here ASAP + the poll function does Rx and RxNoBuf acking */ + + iowrite32(csr5 & 0x0001ff3f, ioaddr + CSR5); + + if (tulip_debug > 4) + printk(KERN_DEBUG "%s: interrupt csr5=%#8.8x new csr5=%#8.8x\n", + dev->name, csr5, ioread32(ioaddr + CSR5)); + + + if (csr5 & (TxNoBuf | TxDied | TxIntr | TimerInt)) { + unsigned int dirty_tx; + + spin_lock(&tp->lock); + + for (dirty_tx = tp->dirty_tx; tp->cur_tx - dirty_tx > 0; + dirty_tx++) { + int entry = dirty_tx % TX_RING_SIZE; + int status = le32_to_cpu(tp->tx_ring[entry].status); + + if (status < 0) + break; /* It still has not been Txed */ + + if (status & 0x8000) { + /* There was an major error, log it. */ +#ifndef final_version + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: Transmit error, Tx status %08x\n", + dev->name, status); +#endif + tp->stats.tx_errors++; + if (status & 0x4104) tp->stats.tx_aborted_errors++; + if (status & 0x0C00) tp->stats.tx_carrier_errors++; + if (status & 0x0200) tp->stats.tx_window_errors++; + if (status & 0x0002) tp->stats.tx_fifo_errors++; + if (status & 0x0080) tp->stats.tx_heartbeat_errors++; + } else { + tp->stats.tx_bytes += + tp->tx_buffers[entry].skb->len; + tp->stats.collisions += (status >> 3) & 15; + tp->stats.tx_packets++; + } + + dma_unmap_single(&tp->pdev->dev, tp->tx_buffers[entry].mapping, + tp->tx_buffers[entry].skb->len, DMA_TO_DEVICE); + /* Free the original skb. */ + dev_kfree_skb_irq(tp->tx_buffers[entry].skb); + tp->tx_buffers[entry].skb = NULL; + tp->tx_buffers[entry].mapping = 0; + tx++; + } + +#ifndef final_version + if (tp->cur_tx - dirty_tx > TX_RING_SIZE) { + dev_err(&dev->dev, + "Out-of-sync dirty pointer, %d vs. %d\n", + dirty_tx, tp->cur_tx); + dirty_tx += TX_RING_SIZE; + } +#endif + + if (tp->cur_tx - dirty_tx < TX_RING_SIZE - 2) + netif_wake_queue(dev); + + tp->dirty_tx = dirty_tx; + if (csr5 & TxDied) { + if (tulip_debug > 2) + dev_warn(&dev->dev, + "The transmitter stopped. CSR5 is %x, CSR6 %x, new CSR6 %x\n", + csr5, ioread32(ioaddr + CSR6), + tp->csr6); + tulip_restart_rxtx(tp); + } + spin_unlock(&tp->lock); + } + + /* Log errors. */ + if (csr5 & AbnormalIntr) { /* Abnormal error summary bit. */ + if (csr5 == 0xffffffff) + break; + if (csr5 & TxJabber) tp->stats.tx_errors++; + if (csr5 & TxFIFOUnderflow) { + if ((tp->csr6 & 0xC000) != 0xC000) + tp->csr6 += 0x4000; /* Bump up the Tx threshold */ + else + tp->csr6 |= 0x00200000; /* Store-n-forward. */ + /* Restart the transmit process. */ + tulip_restart_rxtx(tp); + iowrite32(0, ioaddr + CSR1); + } + if (csr5 & (RxDied | RxNoBuf)) { + iowrite32(tp->mc_filter[0], ioaddr + CSR27); + iowrite32(tp->mc_filter[1], ioaddr + CSR28); + } + if (csr5 & RxDied) { /* Missed a Rx frame. */ + tp->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff; + tp->stats.rx_errors++; + tulip_start_rxtx(tp); + } + /* + * NB: t21142_lnk_change() does a del_timer_sync(), so be careful if this + * call is ever done under the spinlock + */ + if (csr5 & (TPLnkPass | TPLnkFail | 0x08000000)) { + if (tp->link_change) + (tp->link_change)(dev, csr5); + } + if (csr5 & SystemError) { + int error = (csr5 >> 23) & 7; + /* oops, we hit a PCI error. The code produced corresponds + * to the reason: + * 0 - parity error + * 1 - master abort + * 2 - target abort + * Note that on parity error, we should do a software reset + * of the chip to get it back into a sane state (according + * to the 21142/3 docs that is). + * -- rmk + */ + dev_err(&dev->dev, + "(%lu) System Error occurred (%d)\n", + tp->nir, error); + } + /* Clear all error sources, included undocumented ones! */ + iowrite32(0x0800f7ba, ioaddr + CSR5); + oi++; + } + if (csr5 & TimerInt) { + + if (tulip_debug > 2) + dev_err(&dev->dev, + "Re-enabling interrupts, %08x\n", + csr5); + iowrite32(VALID_INTR, ioaddr + CSR7); + oi++; + } + if (tx > maxtx || rx > maxrx || oi > maxoi) { + if (tulip_debug > 1) + dev_warn(&dev->dev, "Too much work during an interrupt, csr5=0x%08x. (%lu) (%d,%d,%d)\n", + csr5, tp->nir, tx, rx, oi); + + /* Acknowledge all interrupt sources. */ + iowrite32(0x8001ffff, ioaddr + CSR5); + /* Mask all interrupting sources, set timer to + re-enable. */ + iowrite32(((~csr5) & 0x0001ebef) | AbnormalIntr | TimerInt, ioaddr + CSR7); + iowrite32(0x0012, ioaddr + CSR11); + break; + } + + work_count--; + if (work_count == 0) + break; + + csr5 = ioread32(ioaddr + CSR5); + + if (rxd) + csr5 &= ~RxPollInt; + } while ((csr5 & (TxNoBuf | + TxDied | + TxIntr | + TimerInt | + /* Abnormal intr. */ + RxDied | + TxFIFOUnderflow | + TxJabber | + TPLnkFail | + SystemError )) != 0); + + if ((missed = ioread32(ioaddr + CSR8) & 0x1ffff)) { + tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed; + } + + if (tulip_debug > 4) + printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#04x\n", + dev->name, ioread32(ioaddr + CSR5)); + + return IRQ_HANDLED; +} diff --git a/target/linux/adm8668/files/arch/mips/adm8668/pci.c b/target/linux/adm8668/files/arch/mips/adm8668/pci.c new file mode 100644 index 000000000..2bf119297 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/pci.c @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2010 Scott Nicholas + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +volatile u32* pci_config_address_reg = (volatile u32*)KSEG1ADDR(PCICFG_BASE); +volatile u32* pci_config_data_reg = (volatile u32*)KSEG1ADDR(PCIDAT_BASE); + +#define PCI_ENABLE 0x80000000 +#define ADMPCI_IO_BASE 0x12600000 +#define ADMPCI_IO_SIZE 0x1fffff +#define ADMPCI_MEM_BASE 0x16000000 +#define ADMPCI_MEM_SIZE 0x7ffffff +#define PCI_CMM_IOACC_EN 0x1 +#define PCI_CMM_MEMACC_EN 0x2 +#define PCI_CMM_MASTER_EN 0x4 +#define PCI_CMM_DEF (PCI_CMM_IOACC_EN | PCI_CMM_MEMACC_EN | PCI_CMM_MASTER_EN) + +#define PCI_DEF_CACHE_LINE_SZ 0 +#define PCI_DEF_LATENCY_TIMER 0x20 +#define PCI_DEF_CACHE_LATENCY ((PCI_DEF_LATENCY_TIMER << 8) | PCI_DEF_CACHE_LINE_SZ) + + +#define cfgaddr(bus, devfn, where) ( \ + (bus ? ((bus->number & 0xff) << 0x10) : 0) | \ + ((devfn & 0xff) << 0x08) | \ + (where & 0xfc)) | PCI_ENABLE + +/* assumed little endian */ +static int adm8668_read_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + switch (size) + { + case 1: + *pci_config_address_reg = cfgaddr(bus, devfn, where); + *val = (le32_to_cpu(*pci_config_data_reg) >> ((where&3)<<3)) & 0xff; + break; + case 2: + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + *pci_config_address_reg = cfgaddr(bus, devfn, where); + *val = (le32_to_cpu(*pci_config_data_reg) >> ((where&3)<<3)) & 0xffff; + break; + case 4: + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + *pci_config_address_reg = cfgaddr(bus, devfn, where); + *val = le32_to_cpu(*pci_config_data_reg); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int adm8668_write_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + switch (size) + { + case 1: + *pci_config_address_reg = cfgaddr(bus, devfn, where); + *(volatile u8 *)(((int)pci_config_data_reg) + (where & 3)) = val; + break; + case 2: + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + *pci_config_address_reg = cfgaddr(bus, devfn, where); + *(volatile u16 *)(((int)pci_config_data_reg) + (where & 2)) = val; + break; + case 4: + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + *pci_config_address_reg = cfgaddr(bus, devfn, where); + *pci_config_data_reg = (val); + } + + return PCIBIOS_SUCCESSFUL; +} + + +struct pci_ops adm8668_pci_ops = { + .read = adm8668_read_config, + .write = adm8668_write_config +}; + + +struct resource pciioport_resource = { + .name = "adm8668_pci", + .start = ADMPCI_IO_BASE, + .end = ADMPCI_IO_BASE + ADMPCI_IO_SIZE, + .flags = IORESOURCE_IO +}; + + +struct resource pciiomem_resource = { + .name = "adm8668_pci", + .start = ADMPCI_MEM_BASE, + .end = ADMPCI_MEM_BASE + ADMPCI_MEM_SIZE, + .flags = IORESOURCE_MEM +}; + +#ifdef CONFIG_ADM8668_DISABLE_PCI +struct pci_controller mips_pci_channels[] = { + { NULL, NULL, NULL , NULL , NULL} +}; +#else +struct pci_controller mips_pci_channels = { + .pci_ops = &adm8668_pci_ops, + .io_resource = &pciioport_resource, + .mem_resource = &pciiomem_resource, +}; +#endif + +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + switch (slot) + { + case 1: + return 14; + case 2: + return 13; + case 3: + return 12; + default: + return dev->irq; + } +} + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +static int __init adm8668_pci_init(void) +{ + void __iomem *io_map_base; + + printk("adm8668_pci_init()\n"); + + /* what's an io port? this is MIPS... *shrug* */ + ioport_resource.start = ADMPCI_IO_BASE; + ioport_resource.end = ADMPCI_IO_BASE + ADMPCI_IO_SIZE; + + io_map_base = ioremap(ADMPCI_IO_BASE, ADMPCI_IO_SIZE); + if (!io_map_base) + printk("io_map_base didn't work.\n"); + mips_pci_channels.io_map_base = (unsigned long)io_map_base; + register_pci_controller(&mips_pci_channels); + + /* this needed? linksys' gpl 2.4 did it... */ + adm8668_write_config(NULL, 0, PCI_CACHE_LINE_SIZE, 2, 0); + adm8668_write_config(NULL, 0, PCI_BASE_ADDRESS_0, 4, 0); + adm8668_write_config(NULL, 0, PCI_BASE_ADDRESS_1, 4, 0); + adm8668_write_config(NULL, 0, PCI_COMMAND, 4, PCI_CMM_DEF); + + return 0; +} + +arch_initcall(adm8668_pci_init); diff --git a/target/linux/adm8668/files/arch/mips/adm8668/platform.c b/target/linux/adm8668/files/arch/mips/adm8668/platform.c new file mode 100644 index 000000000..803af09aa --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/platform.c @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2010 Scott Nicholas + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct resource uart_resources[] = { + { + .start = ADM8668_UART0_BASE, + .end = ADM8668_UART0_BASE + 0xF, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_LVL_UART0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device adm8668_uart_device = { + .name = "adm8668_uart", + .id = 0, + .resource = uart_resources, + .num_resources = ARRAY_SIZE(uart_resources), +}; + +static struct resource eth0_resources[] = { + { + .start = ADM8668_LAN_BASE, + .end = ADM8668_LAN_BASE + 256, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_LVL_LAN, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device adm8668_eth0_device = { + .name = "adm8668_eth", + .id = 0, + .resource = eth0_resources, + .num_resources = ARRAY_SIZE(eth0_resources), +}; + +static struct resource eth1_resources[] = { + { + .start = ADM8668_WAN_BASE, + .end = ADM8668_WAN_BASE + 256, + .flags = IORESOURCE_MEM, + }, + { + .start = INT_LVL_WAN, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device adm8668_eth1_device = { + .name = "adm8668_eth", + .id = 1, + .resource = eth1_resources, + .num_resources = ARRAY_SIZE(eth1_resources), +}; + +static void adm8668_restart(char *cmd) +{ + int i; + + /* stop eth0 and eth1 */ + ADM8668_LAN_REG(NETCSR6) = (1 << 13) | (1 << 1); + ADM8668_LAN_REG(NETCSR7) = 0; + ADM8668_WAN_REG(NETCSR6) = (1 << 13) | (1 << 1); + ADM8668_WAN_REG(NETCSR7) = 0; + + /* reset PHY */ + ADM8668_WAN_REG(NETCSR37) = 0x20; + for (i = 0; i < 10000; i++) + ; + ADM8668_WAN_REG(NETCSR37) = 0; + for (i = 0; i < 10000; i++) + ; + + *(volatile unsigned int *)0xB1600000 = 1; /* reset eth0 mac */ + *(volatile unsigned int *)0xB1A00000 = 1; /* reset eth1 mac */ + *(volatile unsigned int *)0xB1800000 = 1; /* reset wlan0 mac */ + + /* the real deal */ + for (i = 0; i < 1000; i++) + ; + ADM8668_CONFIG_REG(ADM8668_CR1) = 1; +} + +int __devinit adm8668_devs_register(void) +{ + _machine_restart = adm8668_restart; + platform_device_register(&adm8668_uart_device); + platform_device_register(&adm8668_eth0_device); + platform_device_register(&adm8668_eth1_device); + + return 0; +} + +void __init plat_time_init(void) +{ + int adj = (ADM8668_CONFIG_REG(ADM8668_CR3) >> 11) & 0xf; + + /* adjustable clock selection + CR3 bit 14~11, 0000 -> 175MHz, 0001 -> 180MHz, etc... */ + + mips_hpt_frequency = (SYS_CLOCK + adj * 5000000) / 2; + printk("ADM8668 CPU clock: %d MHz\n", 2*mips_hpt_frequency / 1000000); +} + +void __init plat_mem_setup(void) +{ + /* prom_init seemed like easier place for this. it's tooo simple */ +} + +const char *get_system_type(void) +{ + unsigned long chipid = ADM8668_CONFIG_REG(ADM8668_CR0); + int adj = (ADM8668_CONFIG_REG(ADM8668_CR3) >> 11) & 0xf; + int product, revision, mhz; + static char ret[32]; + + product = chipid >> 16; + revision = chipid & 0xffff; + mhz = (SYS_CLOCK/1000000) + (adj * 5); + + /* i getting fancy :\ */ + snprintf(ret, sizeof(ret), "ADM%xr%x %dMHz", product, revision, mhz); + + return ret; +} + +arch_initcall(adm8668_devs_register); diff --git a/target/linux/adm8668/files/arch/mips/adm8668/proc.c b/target/linux/adm8668/files/arch/mips/adm8668/proc.c new file mode 100644 index 000000000..77dbb1faf --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/proc.c @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2010 Scott Nicholas + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +int adm8668_sesled_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) +{ + char buf[8]; + int num; + + num = (count < 8) ? count : 8; + + if (copy_from_user(buf, buffer, num)) + { + printk("copy_from_user failed"); + return -EFAULT; + } + num = simple_strtoul(buf, NULL, 16); + switch (num) + { + case 0: + GPIO_SET_LOW(0); + CRGPIO_SET_LOW(2); + break; + case 1: + GPIO_SET_LOW(0); + CRGPIO_SET_HI(2); + break; + case 2: + GPIO_SET_HI(0); + CRGPIO_SET_HI(2); + break; + default: + break; + } + + return count; +} + +int adm8668_sesled_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data) +{ + int len = 0; + int led_state = 0; + + led_state = (ADM8668_CONFIG_REG(CRGPIO_REG) & 0x100) ? 1 : 0; + led_state += (ADM8668_WLAN_REG(GPIO_REG) & 0x40) ? 2 : 0; + len += sprintf(buf+len, "%s\n", + (led_state&1) ? + ((led_state&2) ? "ORANGE" : "GREEN") : "OFF"); + + return len; +} + +int adm8668_button_read_proc(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + int len = 0; + int read_once = ADM8668_CONFIG_REG(CRGPIO_REG); + int button_flip = (read_once >> 20) & 0x3; + int button_state = read_once & 0x3; + + len += sprintf(buf+len, "SES: %s %s\nRESET: %s %s\n", + (button_state&2) ? "UP" : "DOWN", + (button_flip&2) ? "FLIP" : "", + (button_state&1) ? "UP" : "DOWN", + (button_flip&1) ? "FLIP" : ""); + + return len; +} + +int __init adm8668_init_proc(void) +{ + struct proc_dir_entry *adm8668_proc_dir = NULL; + struct proc_dir_entry *sesled = NULL; + int __maybe_unused bogus; + + /* these are known to be lights. rest are input...? */ + ADM8668_CONFIG_REG(CRGPIO_REG) = GPIO2_OUTPUT_ENABLE; + ADM8668_WLAN_REG(GPIO_REG) = GPIO0_OUTPUT_ENABLE; + + /* inital read off of the flipper switcher on the button thingie */ + bogus = ADM8668_CONFIG_REG(CRGPIO_REG); + + adm8668_proc_dir = proc_mkdir("adm8668", 0); + if (adm8668_proc_dir == NULL) { + printk(KERN_ERR "ADM8668 proc: unable to create proc dir.\n"); + return 0; + } + create_proc_read_entry("buttons", 0444, adm8668_proc_dir, + adm8668_button_read_proc, NULL); + sesled = create_proc_entry("sesled", S_IRUGO|S_IWUGO, adm8668_proc_dir); + if (sesled) { + sesled->read_proc = adm8668_sesled_read_proc; + sesled->write_proc = adm8668_sesled_write_proc; + } + + return 0; +} + +module_init(adm8668_init_proc); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Scott Nicholas "); +MODULE_DESCRIPTION("ADM8668 ghetto button driver"); diff --git a/target/linux/adm8668/files/arch/mips/adm8668/prom.c b/target/linux/adm8668/files/arch/mips/adm8668/prom.c new file mode 100644 index 000000000..7187f2982 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/prom.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2010 Scott Nicholas + * + * based on work of rb532 prom.c + * Copyright (C) 2003, Peter Sadik + * Copyright (C) 2005-2006, P.Christeas + * Copyright (C) 2007, Gabor Juhos + * Felix Fietkau + * Florian Fainelli + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "u-boot.h" + +register volatile struct global_data *gd asm ("k0"); + +#ifdef CONFIG_SERIAL_ADM8668_CONSOLE +static inline unsigned int adm_uart_readl(unsigned int offset) +{ + return (*(volatile unsigned int *)(0xbe400000 + offset)); +} + +static inline void adm_uart_writel(unsigned int value, unsigned int offset) +{ + (*((volatile unsigned int *)(0xbe400000 + offset))) = value; +} + +static void prom_putchar(char c) +{ + adm_uart_writel(c, UART_DR_REG); + while ((adm_uart_readl(UART_FR_REG) & UART_TX_FIFO_FULL) != 0) + ; +} + +static void __init +early_console_write(struct console *con, const char *s, unsigned n) +{ + while (n-- && *s) { + if (*s == '\n') + prom_putchar('\r'); + prom_putchar(*s); + s++; + } +} + +static struct console early_console __initdata = { + .name = "early", + .write = early_console_write, + .flags = CON_BOOT, + .index = -1 +}; + +#endif + +void __init prom_free_prom_memory(void) +{ + /* No prom memory to free */ +} + +static inline int match_tag(char *arg, const char *tag) +{ + return strncmp(arg, tag, strlen(tag)) == 0; +} + +static inline unsigned long tag2ul(char *arg, const char *tag) +{ + char *num; + + num = arg + strlen(tag); + return simple_strtoul(num, 0, 10); +} + +void __init prom_setup_cmdline(void) +{ + char *cp; + int prom_argc; + char **prom_argv; + int i; + + prom_argc = fw_arg0; + prom_argv = (char **)KSEG0ADDR(fw_arg1); + + cp = &(arcs_cmdline[0]); + for (i = 1; i < prom_argc; i++) { + prom_argv[i] = (char *)KSEG0ADDR(prom_argv[i]); + + /* default bootargs has "console=/dev/ttyS0" yet console won't + * show up at all if you include the '/dev/' nowadays ... */ + if (match_tag(prom_argv[i], "console=/dev/")) { + char *ptr = prom_argv[i] + strlen("console=/dev/"); + + strcpy(cp, "console="); + cp += strlen("console="); + strcpy(cp, ptr); + cp += strlen(ptr); + *cp++ = ' '; + continue; + } + strcpy(cp, prom_argv[i]); + cp += strlen(prom_argv[i]); + *cp++ = ' '; + } + if (prom_argc > 1) + --cp; /* trailing space */ + + *cp = '\0'; +} + +void __init prom_init(void) +{ + bd_t *bd = gd->bd; + int memsize; + +#ifdef CONFIG_SERIAL_ADM8668_CONSOLE + register_console(&early_console); +#endif + + memsize = bd->bi_memsize; + printk("Board info:\n"); + printk(" RAM size: %d MB\n", (int)memsize/(1024*1024)); + printk(" NOR start: %#lx\n", bd->bi_flashstart); + printk(" NOR size: %#lx\n", bd->bi_flashsize); + + prom_setup_cmdline(); + add_memory_region(0, memsize, BOOT_MEM_RAM); +} diff --git a/target/linux/adm8668/files/arch/mips/adm8668/serial.c b/target/linux/adm8668/files/arch/mips/adm8668/serial.c new file mode 100644 index 000000000..7d684b810 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/serial.c @@ -0,0 +1,638 @@ +/* + * 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. + * + * ADM8668 serial driver, totally ripped the source from BCM63xx and changed + * all the registers to fit our hardware, and removed all the features that + * I didn't know because our GPL'd serial driver was way lame. + * + * Copyright (C) 2010 Scott Nicholas + * Derived directly from bcm63xx_uart + * Copyright (C) 2008 Maxime Bizon + * + */ + +#if defined(CONFIG_SERIAL_ADM8668_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ADM8668_NR_UARTS 1 + +static struct uart_port ports[ADM8668_NR_UARTS]; + +/* + * handy uart register accessor + */ +static inline unsigned int adm_uart_readl(struct uart_port *port, + unsigned int offset) +{ + return (*(volatile unsigned int *)(port->membase + offset)); +} + +static inline void adm_uart_writel(struct uart_port *port, + unsigned int value, unsigned int offset) +{ + (*((volatile unsigned int *)(port->membase + offset))) = value; +} + +/* + * serial core request to check if uart tx fifo is empty + */ +static unsigned int adm_uart_tx_empty(struct uart_port *port) +{ + /* we always wait for completion, no buffer is made... */ + return 1; +} + +/* + * serial core request to set RTS and DTR pin state and loopback mode + */ +static void adm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ +} + +/* + * serial core request to return RI, CTS, DCD and DSR pin state + */ +static unsigned int adm_uart_get_mctrl(struct uart_port *port) +{ + return 0; +} + +/* + * serial core request to disable tx ASAP (used for flow control) + */ +static void adm_uart_stop_tx(struct uart_port *port) +{ + unsigned int val; + + val = adm_uart_readl(port, UART_CR_REG); + val &= ~(UART_TX_INT_EN); + adm_uart_writel(port, val, UART_CR_REG); +} + +/* + * serial core request to (re)enable tx + */ +static void adm_uart_start_tx(struct uart_port *port) +{ + unsigned int val; + + val = adm_uart_readl(port, UART_CR_REG); + val |= UART_TX_INT_EN; + adm_uart_writel(port, val, UART_CR_REG); +} + +/* + * serial core request to stop rx, called before port shutdown + */ +static void adm_uart_stop_rx(struct uart_port *port) +{ + unsigned int val; + + val = adm_uart_readl(port, UART_CR_REG); + val &= ~UART_RX_INT_EN; + adm_uart_writel(port, val, UART_CR_REG); +} + +/* + * serial core request to enable modem status interrupt reporting + */ +static void adm_uart_enable_ms(struct uart_port *port) +{ +} + +/* + * serial core request to start/stop emitting break char + */ +static void adm_uart_break_ctl(struct uart_port *port, int ctl) +{ +} + +/* + * return port type in string format + */ +static const char *adm_uart_type(struct uart_port *port) +{ + return (port->type == PORT_ADM8668) ? "adm8668_uart" : NULL; +} + +/* + * read all chars in rx fifo and send them to core + */ +static void adm_uart_do_rx(struct uart_port *port) +{ + struct tty_struct *tty; + unsigned int max_count; + + /* limit number of char read in interrupt, should not be + * higher than fifo size anyway since we're much faster than + * serial port */ + max_count = 32; + tty = port->state->port.tty; + do { + unsigned int iestat, c, cstat; + char flag; + + /* get overrun/fifo empty information from ier + * register */ + iestat = adm_uart_readl(port, UART_FR_REG); + if (iestat & UART_RX_FIFO_EMPTY) + break; + + /* recieve status */ + cstat = adm_uart_readl(port, UART_RSR_REG); + /* clear errors */ + adm_uart_writel(port, cstat, UART_RSR_REG); + + c = adm_uart_readl(port, UART_DR_REG); + port->icount.rx++; + flag = TTY_NORMAL; + + if (unlikely((cstat & UART_RX_STATUS_MASK))) { + /* do stats first */ + if (cstat & UART_BREAK_ERR) { + port->icount.brk++; + if (uart_handle_break(port)) + continue; + } + + if (cstat & UART_PARITY_ERR) + port->icount.parity++; + if (cstat & UART_FRAMING_ERR) + port->icount.frame++; + if (cstat & UART_OVERRUN_ERR) { + port->icount.overrun++; + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } + + /* update flag wrt read_status_mask */ + cstat &= port->read_status_mask; + if (cstat & UART_BREAK_ERR) + flag = TTY_BREAK; + if (cstat & UART_FRAMING_ERR) + flag = TTY_FRAME; + if (cstat & UART_PARITY_ERR) + flag = TTY_PARITY; + } + + if (uart_handle_sysrq_char(port, c)) + continue; + + /* fixthis */ + if ((cstat & port->ignore_status_mask) == 0) + tty_insert_flip_char(tty, c, flag); + } while (max_count--); + + tty_flip_buffer_push(tty); +} + +/* + * fill tx fifo with chars to send, stop when fifo is about to be full + * or when all chars have been sent. + */ +static void adm_uart_do_tx(struct uart_port *port) +{ + struct circ_buf *xmit; + + if (port->x_char) { + adm_uart_writel(port, port->x_char, UART_DR_REG); + port->icount.tx++; + port->x_char = 0; + return; + } + + if (uart_tx_stopped(port)) + adm_uart_stop_tx(port); + + xmit = &port->state->xmit; + + if (uart_circ_empty(xmit)) + goto txq_empty; + do + { + while ((adm_uart_readl(port, UART_FR_REG) & UART_TX_FIFO_FULL) != 0) + ; + adm_uart_writel(port, xmit->buf[xmit->tail], UART_DR_REG); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + port->icount.tx++; + if (uart_circ_empty(xmit)) + break; + } while (1); + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); + + if (uart_circ_empty(xmit)) + goto txq_empty; + + return; + +txq_empty: + adm_uart_stop_tx(port); +} + +/* + * process uart interrupt + */ +static irqreturn_t adm_uart_interrupt(int irq, void *dev_id) +{ + struct uart_port *port; + unsigned int irqstat; + + port = dev_id; + spin_lock(&port->lock); + + irqstat = adm_uart_readl(port, UART_IIR_REG); + + if (irqstat & (UART_RX_INT|UART_RX_TIMEOUT_INT)) { + adm_uart_do_rx(port); + } + + if (irqstat & UART_TX_INT) { + adm_uart_do_tx(port); + } + spin_unlock(&port->lock); + return IRQ_HANDLED; +} + +/* + * enable rx & tx operation on uart + */ +static void adm_uart_enable(struct uart_port *port) +{ + unsigned int val; + + val = adm_uart_readl(port, UART_CR_REG); + // BREAK_INT too + val |= (UART_RX_INT_EN | UART_RX_TIMEOUT_INT_EN); + adm_uart_writel(port, val, UART_CR_REG); +} + +/* + * disable rx & tx operation on uart + */ +static void adm_uart_disable(struct uart_port *port) +{ + unsigned int val; + + val = adm_uart_readl(port, UART_CR_REG); + val &= ~(UART_TX_INT_EN | UART_RX_INT_EN | UART_RX_TIMEOUT_INT_EN); + adm_uart_writel(port, val, UART_CR_REG); +} + +/* + * clear all unread data in rx fifo and unsent data in tx fifo + */ +static void adm_uart_flush(struct uart_port *port) +{ + /* read any pending char to make sure all irq status are + * cleared */ + (void)adm_uart_readl(port, UART_DR_REG); +} + +/* + * serial core request to initialize uart and start rx operation + */ +static int adm_uart_startup(struct uart_port *port) +{ + int ret; + + /* clear any pending external input interrupt */ + (void)adm_uart_readl(port, UART_IIR_REG); + + /* register irq and enable rx interrupts */ + ret = request_irq(port->irq, adm_uart_interrupt, 0, + adm_uart_type(port), port); + if (ret) + return ret; + + adm_uart_enable(port); + + return 0; +} + +/* + * serial core request to flush & disable uart + */ +static void adm_uart_shutdown(struct uart_port *port) +{ + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); +// adm_uart_writel(port, 0, UART_CR_REG); + spin_unlock_irqrestore(&port->lock, flags); + + adm_uart_disable(port); + adm_uart_flush(port); + free_irq(port->irq, port); +} + +/* + * serial core request to change current uart setting + */ +static void adm_uart_set_termios(struct uart_port *port, + struct ktermios *new, + struct ktermios *old) +{ + port->ignore_status_mask = 0; + uart_update_timeout(port, new->c_cflag, 115200); +} + +/* + * serial core request to claim uart iomem + */ +static int adm_uart_request_port(struct uart_port *port) +{ + unsigned int size = 0xf; + if (!request_mem_region(port->mapbase, size, "adm8668")) { + dev_err(port->dev, "Memory region busy\n"); + return -EBUSY; + } + + port->membase = ioremap(port->mapbase, size); + if (!port->membase) { + dev_err(port->dev, "Unable to map registers\n"); + release_mem_region(port->mapbase, size); + return -EBUSY; + } + return 0; +} + +/* + * serial core request to release uart iomem + */ +static void adm_uart_release_port(struct uart_port *port) +{ + release_mem_region(port->mapbase, 0xf); + iounmap(port->membase); +} + +/* + * serial core request to do any port required autoconfiguration + */ +static void adm_uart_config_port(struct uart_port *port, int flags) +{ + if (flags & UART_CONFIG_TYPE) { + if (adm_uart_request_port(port)) + return; + port->type = PORT_ADM8668; + } +} + +/* + * serial core request to check that port information in serinfo are + * suitable + */ +static int adm_uart_verify_port(struct uart_port *port, + struct serial_struct *serinfo) +{ + if (port->type != PORT_ADM8668) + return -EINVAL; + if (port->irq != serinfo->irq) + return -EINVAL; + if (port->iotype != serinfo->io_type) + return -EINVAL; + if (port->mapbase != (unsigned long)serinfo->iomem_base) + return -EINVAL; + return 0; +} + +/* serial core callbacks */ +static struct uart_ops adm_uart_ops = { + .tx_empty = adm_uart_tx_empty, + .get_mctrl = adm_uart_get_mctrl, + .set_mctrl = adm_uart_set_mctrl, + .start_tx = adm_uart_start_tx, + .stop_tx = adm_uart_stop_tx, + .stop_rx = adm_uart_stop_rx, + .enable_ms = adm_uart_enable_ms, + .break_ctl = adm_uart_break_ctl, + .startup = adm_uart_startup, + .shutdown = adm_uart_shutdown, + .set_termios = adm_uart_set_termios, + .type = adm_uart_type, + .release_port = adm_uart_release_port, + .request_port = adm_uart_request_port, + .config_port = adm_uart_config_port, + .verify_port = adm_uart_verify_port, +}; + +#ifdef CONFIG_SERIAL_ADM8668_CONSOLE +static inline void wait_for_xmitr(struct uart_port *port) +{ + while ((adm_uart_readl(port, UART_FR_REG) & UART_TX_FIFO_FULL) != 0) + ; +} + +/* + * output given char + */ +static void adm_console_putchar(struct uart_port *port, int ch) +{ + wait_for_xmitr(port); + adm_uart_writel(port, ch, UART_DR_REG); +} + +/* + * console core request to output given string + */ +static void adm_console_write(struct console *co, const char *s, + unsigned int count) +{ + struct uart_port *port; + unsigned long flags; + int locked; + + port = &ports[co->index]; + + local_irq_save(flags); + if (port->sysrq) { + /* adm_uart_interrupt() already took the lock */ + locked = 0; + } else if (oops_in_progress) { + locked = spin_trylock(&port->lock); + } else { + spin_lock(&port->lock); + locked = 1; + } + + /* call helper to deal with \r\n */ + uart_console_write(port, s, count, adm_console_putchar); + + /* and wait for char to be transmitted */ + wait_for_xmitr(port); + + if (locked) + spin_unlock(&port->lock); + local_irq_restore(flags); +} + +/* + * console core request to setup given console, find matching uart + * port and setup it. + */ +static int adm_console_setup(struct console *co, char *options) +{ + struct uart_port *port; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + if (co->index < 0 || co->index >= ADM8668_NR_UARTS) + return -EINVAL; + port = &ports[co->index]; + if (!port->membase) + return -ENODEV; + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + + return uart_set_options(port, co, baud, parity, bits, flow); +} + +static struct uart_driver adm_uart_driver; + +static struct console adm8668_console = { + .name = "ttyS", + .write = adm_console_write, + .device = uart_console_device, + .setup = adm_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &adm_uart_driver, +}; + +static int __init adm8668_console_init(void) +{ + register_console(&adm8668_console); + return 0; +} + +console_initcall(adm8668_console_init); + +#define ADM8668_CONSOLE (&adm8668_console) +#else +#define ADM8668_CONSOLE NULL +#endif /* CONFIG_SERIAL_ADM8668_CONSOLE */ + +static struct uart_driver adm_uart_driver = { + .owner = THIS_MODULE, + .driver_name = "adm8668_uart", + .dev_name = "ttyS", + .major = TTY_MAJOR, + .minor = 64, + .nr = 1, + .cons = ADM8668_CONSOLE, +}; + +/* + * platform driver probe/remove callback + */ +static int __devinit adm_uart_probe(struct platform_device *pdev) +{ + struct resource *res_mem, *res_irq; + struct uart_port *port; + int ret; + + if (pdev->id < 0 || pdev->id >= ADM8668_NR_UARTS) + return -EINVAL; + + if (ports[pdev->id].membase) + return -EBUSY; + + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res_mem) + return -ENODEV; + + res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res_irq) + return -ENODEV; + + port = &ports[pdev->id]; + memset(port, 0, sizeof(*port)); + port->iotype = UPIO_MEM; + port->mapbase = res_mem->start; + port->irq = res_irq->start; + port->ops = &adm_uart_ops; + port->flags = UPF_BOOT_AUTOCONF; + port->dev = &pdev->dev; + port->fifosize = 8; + port->uartclk = ADM8668_UARTCLK_FREQ; + + ret = uart_add_one_port(&adm_uart_driver, port); + if (ret) { + ports[pdev->id].membase = 0; + return ret; + } + platform_set_drvdata(pdev, port); + return 0; +} + +static int __devexit adm_uart_remove(struct platform_device *pdev) +{ + struct uart_port *port; + + port = platform_get_drvdata(pdev); + uart_remove_one_port(&adm_uart_driver, port); + platform_set_drvdata(pdev, NULL); + /* mark port as free */ + ports[pdev->id].membase = 0; + return 0; +} + +/* + * platform driver stuff + */ +static struct platform_driver adm_uart_platform_driver = { + .probe = adm_uart_probe, + .remove = __devexit_p(adm_uart_remove), + .driver = { + .owner = THIS_MODULE, + .name = "adm8668_uart", + }, +}; + +static int __init adm_uart_init(void) +{ + int ret; + + ret = uart_register_driver(&adm_uart_driver); + if (ret) + return ret; + + ret = platform_driver_register(&adm_uart_platform_driver); + if (ret) + uart_unregister_driver(&adm_uart_driver); + + return ret; +} + +static void __exit adm_uart_exit(void) +{ + platform_driver_unregister(&adm_uart_platform_driver); + uart_unregister_driver(&adm_uart_driver); +} + +module_init(adm_uart_init); +module_exit(adm_uart_exit); + +MODULE_AUTHOR("Scott Nicholas "); +MODULE_DESCRIPTION("ADM8668 integrated uart driver"); +MODULE_LICENSE("GPL"); diff --git a/target/linux/adm8668/files/arch/mips/adm8668/u-boot.h b/target/linux/adm8668/files/arch/mips/adm8668/u-boot.h new file mode 100644 index 000000000..d9d226889 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/adm8668/u-boot.h @@ -0,0 +1,52 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _U_BOOT_H_ +#define _U_BOOT_H_ 1 + +typedef struct bd_info { + int bi_baudrate; /* serial console baudrate */ + unsigned long bi_ip_addr; /* IP Address */ + unsigned char bi_enetaddr[6]; /* Ethernet adress */ + unsigned long bi_arch_number; /* unique id for this board */ + unsigned long bi_boot_params; /* where this board expects params */ + unsigned long bi_memstart; /* start of DRAM memory */ + unsigned long bi_memsize; /* size of DRAM memory in bytes */ + unsigned long bi_flashstart; /* start of FLASH memory */ + unsigned long bi_flashsize; /* size of FLASH memory */ + unsigned long bi_flashoffset; /* reserved area for startup monitor */ +} bd_t; + +struct global_data { + bd_t *bd; /* board data... */ + unsigned long flags; + unsigned long baudrate; + unsigned long have_console; /* serial_init() was called */ + unsigned long ram_size; /* RAM size */ + unsigned long reloc_off; /* Relocation Offset */ + unsigned long env_addr; /* Address of Environment struct */ + unsigned long env_valid; /* Checksum of Environment valid? */ + void **jt; /* jump table */ +}; + +#endif /* _U_BOOT_H_ */ diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h new file mode 100644 index 000000000..2cf65d81a --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h @@ -0,0 +1,139 @@ +/************************************************************************ + * + * Copyright (c) 2005 + * Infineon Technologies AG + * St. Martin Strasse 53; 81669 Muenchen; Germany + * + ************************************************************************/ + +#ifndef __ADM8668_H__ +#define __ADM8668_H__ + +#define SYS_CLOCK 175000000 + +/*======================= Physical Memory Map ============================*/ +#define ADM8668_SDRAM_BASE 0 +#define ADM8668_SMEM1_BASE 0x10000000 +#define ADM8668_MPMC_BASE 0x11000000 +#define ADM8668_USB_BASE 0x11200000 +#define ADM8668_CONFIG_BASE 0x11400000 +#define ADM8668_WAN_BASE 0x11600000 +#define ADM8668_WLAN_BASE 0x11800000 +#define ADM8668_LAN_BASE 0x11A00000 +#define ADM8668_INTC_BASE 0x1E000000 +#define ADM8668_TMR_BASE 0x1E200000 +#define ADM8668_UART0_BASE 0x1E400000 +#define ADM8668_SMEM0_BASE 0x1FC00000 +#define ADM8668_NAND_BASE 0x1FFFFF00 + +#define PCICFG_BASE 0x12200000 +#define PCIDAT_BASE 0x12400000 + +/** onboard uart **/ +#define ADM8668_UARTCLK_FREQ 62500000 +/* registers */ +#define UART_DR_REG 0x00 +#define UART_RSR_REG 0x04 +#define UART_CR_REG 0x14 +#define UART_FR_REG 0x18 +#define UART_IIR_REG 0x1C + +/* rsr reg */ +#define UART_FRAMING_ERR 0x01 +#define UART_PARITY_ERR 0x02 +#define UART_BREAK_ERR 0x04 +#define UART_OVERRUN_ERR 0x08 +#define UART_RX_STATUS_MASK 0x0F + +/* cr reg */ +#define UART_RX_INT_EN 0x10 +#define UART_TX_INT_EN 0x20 +#define UART_RX_TIMEOUT_INT_EN 0x40 + +/* fr reg */ +#define UART_RX_FIFO_EMPTY 0x10 +#define UART_TX_FIFO_FULL 0x20 + +/* iir reg */ +#define UART_RX_INT 0x02 +#define UART_TX_INT 0x04 +#define UART_RX_TIMEOUT_INT 0x08 + +/* interrupt controller */ +#define IRQ_STATUS_REG 0x00 /* Read */ +#define IRQ_ENABLE_REG 0x08 /* Read/Write */ +#define IRQ_DISABLE_REG 0x0C /* Write */ + +/* interrupt levels */ +#define INT_LVL_SWI 1 +#define INT_LVL_COMMS_RX 2 +#define INT_LVL_COMMS_TX 3 +#define INT_LVL_TIMERINT0 4 +#define INT_LVL_TIMERINT1 5 +#define INT_LVL_UART0 6 +#define INT_LVL_LAN 7 +#define INT_LVL_WAN 8 +#define INT_LVL_WLAN 9 +#define INT_LVL_GPIO 10 +#define INT_LVL_IDE 11 +#define INT_LVL_PCI2 12 +#define INT_LVL_PCI1 13 +#define INT_LVL_PCI0 14 +#define INT_LVL_USB 15 +#define INT_LVL_MAX INT_LVL_USB + +/* register access macros */ +#define ADM8668_INTC_REG(_reg) \ + (*((volatile unsigned long *)(KSEG1ADDR(ADM8668_INTC_BASE + (_reg))))) +#define ADM8668_LAN_REG(_reg) \ + (*((volatile unsigned int *)(KSEG1ADDR(ADM8668_LAN_BASE + (_reg))))) +#define ADM8668_WAN_REG(_reg) \ + (*((volatile unsigned int *)(KSEG1ADDR(ADM8668_WAN_BASE + (_reg))))) +#define ADM8668_WLAN_REG(_reg) \ + (*((volatile unsigned int *)(KSEG1ADDR(ADM8668_WLAN_BASE + (_reg))))) +#define ADM8668_CONFIG_REG(_reg) \ + (*((volatile unsigned int *)(KSEG1ADDR(ADM8668_CONFIG_BASE + (_reg))))) + +/* lan registers */ +#define NETCSR6 0x30 +#define NETCSR7 0x38 +#define NETCSR37 0xF8 + +/* known/used CPU configuration registers */ +#define ADM8668_CR0 0x00 +#define ADM8668_CR1 0x04 +#define ADM8668_CR3 0x0C + +/** For GPIO control **/ +#define GPIO_REG 0x5C /* on WLAN */ +#define CRGPIO_REG 0x20 /* on CPU */ +#define GPIO0_OUTPUT_ENABLE 0x1000 +#define GPIO1_OUTPUT_ENABLE 0x2000 +#define GPIO2_OUTPUT_ENABLE 0x4000 +#define GPIO_OUTPUT_ENABLE_ALL 0x7000 +#define GPIO0_OUTPUT_1 0x40 +#define GPIO1_OUTPUT_1 0x80 +#define GPIO2_OUTPUT_1 0x100 +#define GPIO0_INPUT_1 0x1 +#define GPIO1_INPUT_1 0x2 +#define GPIO2_INPUT_1 0x4 + +#define GPIO_SET_HI(num) \ + ADM8668_WLAN_REG(GPIO_REG) |= (1 << (6 + num)) + +#define GPIO_SET_LOW(num) \ + ADM8668_WLAN_REG(GPIO_REG) &= ~(1 << (6 + num)) + +#define GPIO_TOGGLE(num) \ + ADM8668_WLAN_REG(GPIO_REG) ^= (1 << (6 + num)) + +#define CRGPIO_SET_HI(num) \ + ADM8668_CONFIG_REG(CRGPIO_REG) |= (1 << (6 + num)) + +#define CRGPIO_SET_LOW(num) \ + ADM8668_CONFIG_REG(CRGPIO_REG) &= ~(1 << (6 + num)) + +#define CRGPIO_TOGGLE(num) \ + ADM8668_CONFIG_REG(CRGPIO_REG) ^= (1 << (6 + num)) + +#endif /* __ADM8668_H__ */ diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/irq.h b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/irq.h new file mode 100644 index 000000000..1341309f2 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/irq.h @@ -0,0 +1,16 @@ +/* + * 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 by Ralf Baechle + */ +#ifndef __ASM_MACH_ADM8668_IRQ_H +#define __ASM_MACH_ADM8668_IRQ_H + +#define NR_IRQS 32 +#define MIPS_CPU_IRQ_BASE 16 + +#define IRQ_MASK 0xffff + +#endif /* __ASM_MACH_ADM8668_IRQ_H */ diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/war.h b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/war.h new file mode 100644 index 000000000..7180043d3 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/war.h @@ -0,0 +1,25 @@ +/* + * 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) 2002, 2004, 2007 by Ralf Baechle + */ +#ifndef __ASM_MIPS_MACH_ADM8668_WAR_H +#define __ASM_MIPS_MACH_ADM8668_WAR_H + +#define R4600_V1_INDEX_ICACHEOP_WAR 0 +#define R4600_V1_HIT_CACHEOP_WAR 0 +#define R4600_V2_HIT_CACHEOP_WAR 0 +#define R5432_CP0_INTERRUPT_WAR 0 +#define BCM1250_M3_WAR 0 +#define SIBYTE_1956_WAR 0 +#define MIPS4K_ICACHE_REFILL_WAR 0 +#define MIPS_CACHE_SYNC_WAR 0 +#define TX49XX_ICACHE_INDEX_INV_WAR 0 +#define RM9000_CDEX_SMP_WAR 0 +#define ICACHE_REFILLS_WORKAROUND_WAR 0 +#define R10000_LLSC_WAR 0 +#define MIPS34K_MISSED_ITLB_WAR 0 + +#endif /* __ASM_MIPS_MACH_ADM8668_WAR_H */ diff --git a/target/linux/adm8668/files/drivers/mtd/maps/adm8668.c b/target/linux/adm8668/files/drivers/mtd/maps/adm8668.c new file mode 100644 index 000000000..e360a0d78 --- /dev/null +++ b/target/linux/adm8668/files/drivers/mtd/maps/adm8668.c @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2010 Scott Nicholas + * Copyright (C) 2006 Felix Fietkau + * Copyright (C) 2005 Waldemar Brodkorb + * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) + * + * original functions for finding root filesystem from Mike Baker + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * Copyright 2004, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * Flash mapping for adm8668 boards + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WINDOW_ADDR 0x10000000 +#define WINDOW_SIZE 0x800000 +#define BANKWIDTH 2 + +/* first a little bit about the headers i need.. */ + +/* just interested in part of the full struct */ +struct squashfs_super_block { + __le32 s_magic; + __le32 pad0[9]; /* it's not really padding */ + __le64 bytes_used; +}; + +#define IH_MAGIC 0x56190527 /* Image Magic Number */ +struct uboot_header { + uint32_t ih_magic; /* Image Header Magic Number */ + uint32_t ih_hcrc; /* Image Header CRC Checksum */ + uint32_t ih_time; /* Image Creation Timestamp */ + uint32_t ih_size; /* Image Data Size */ + uint32_t ih_load; /* Data Load Address */ + uint32_t ih_ep; /* Entry Point Address */ + uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ + uint8_t ih_comp; /* Compression Type */ + char ih_name[32]; /* image name */ +}; + +/************************************************/ + +static struct mtd_info *adm8668_mtd; + +struct map_info adm8668_map = { + name: "adm8668-nor", + size: WINDOW_SIZE, + phys: WINDOW_ADDR, + bankwidth: BANKWIDTH, +}; + +/* + * Copied from mtdblock.c + * + * Cache stuff... + * + * Since typical flash erasable sectors are much larger than what Linux's + * buffer cache can handle, we must implement read-modify-write on flash + * sectors for each block write requests. To avoid over-erasing flash sectors + * and to speed things up, we locally cache a whole flash sector while it is + * being written to until a different sector is required. + */ + +static void erase_callback(struct erase_info *done) +{ + wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv; + wake_up(wait_q); +} + +static int erase_write (struct mtd_info *mtd, unsigned long pos, + int len, const char *buf) +{ + struct erase_info erase; + DECLARE_WAITQUEUE(wait, current); + wait_queue_head_t wait_q; + size_t retlen; + int ret; + + /* + * First, let's erase the flash block. + */ + + init_waitqueue_head(&wait_q); + erase.mtd = mtd; + erase.callback = erase_callback; + erase.addr = pos; + erase.len = len; + erase.priv = (u_long)&wait_q; + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&wait_q, &wait); + + ret = mtd->erase(mtd, &erase); + if (ret) { + set_current_state(TASK_RUNNING); + remove_wait_queue(&wait_q, &wait); + printk (KERN_WARNING "erase of region [0x%lx, 0x%x] " + "on \"%s\" failed\n", + pos, len, mtd->name); + return ret; + } + + schedule(); /* Wait for erase to finish. */ + remove_wait_queue(&wait_q, &wait); + + /* + * Next, write data to flash. + */ + + ret = mtd->write (mtd, pos, len, &retlen, buf); + if (ret) + return ret; + if (retlen != len) + return -EIO; + return 0; +} + +/* decent defaults in case... shrug */ +static struct mtd_partition adm8668_parts[] = { + { name: "linux", offset: 0x40000, size: WINDOW_SIZE-0x40000, }, + { name: "rootfs", offset: 0xe0000, size: 0x140000, }, + { name: "uboot_env", offset: 0x20000, size: 0x20000, }, + { name: NULL, }, +}; + +/* in case i wanna change stuff later, and to clarify the math section... */ +#define PART_LINUX 0 +#define PART_ROOTFS 1 +#define NR_PARTS 3 + +static int __init +init_mtd_partitions(struct mtd_info *mtd, size_t size) +{ + struct uboot_header uhdr; + int off, blocksize; + size_t len, linux_len; + struct squashfs_super_block shdr; + + blocksize = mtd->erasesize; + if (blocksize < 0x10000) + blocksize = 0x10000; + + /* now find squashfs */ + memset(&shdr, 0xe5, sizeof(shdr)); + for (off = adm8668_parts[PART_LINUX].offset; off < size; off += blocksize) { + /* + * Read into buffer + */ + if (mtd->read(mtd, off, sizeof(shdr), &len, (char *)&shdr) || + len != sizeof(shdr)) + continue; + + if (shdr.s_magic == SQUASHFS_MAGIC) { + uint32_t fs_size = (uint32_t)shdr.bytes_used; + + printk(KERN_INFO "%s: Filesystem type: squashfs, size=%dkB\n", + mtd->name, fs_size>>10); + + /* Update rootfs based on the superblock info, and + * stretch to end of MTD. rootfs_split will split it */ + adm8668_parts[PART_ROOTFS].offset = off; + adm8668_parts[PART_ROOTFS].size = mtd->size - + adm8668_parts[PART_ROOTFS].offset; + + /* kernel ends where rootfs starts + * but we'll keep it full-length for upgrades */ + linux_len = adm8668_parts[PART_LINUX+1].offset - + adm8668_parts[PART_LINUX].offset; +#if 1 + adm8668_parts[PART_LINUX].size = mtd->size - + adm8668_parts[PART_LINUX].offset; +#else + adm8668_parts[PART_LINUX].size = linux_len; +#endif + goto found; + } + } + + printk(KERN_NOTICE + "%s: Couldn't find root filesystem\n", + mtd->name); + return NR_PARTS; + + found: + if (mtd->read(mtd, adm8668_parts[PART_LINUX].offset, sizeof(uhdr), &len, (char *)&uhdr) || + len != sizeof(uhdr)) + return NR_PARTS; + + /* that's odd. how'd ya boot it then */ + if (uhdr.ih_magic != IH_MAGIC) + return NR_PARTS; + + if (be32_to_cpu(uhdr.ih_size) != (linux_len - sizeof(uhdr))) { + unsigned char *block, *data; + unsigned int offset; + + offset = adm8668_parts[PART_LINUX].offset + + sizeof(struct uboot_header); + data = (unsigned char *)(WINDOW_ADDR | 0xA0000000 | offset); + + printk(KERN_NOTICE "Updating U-boot image:\n"); + printk(KERN_NOTICE " old: [size: %8d crc32: 0x%08x]\n", + be32_to_cpu(uhdr.ih_size), be32_to_cpu(uhdr.ih_dcrc)); + + /* Update the data length & crc32 */ + uhdr.ih_size = cpu_to_be32(linux_len - sizeof(uhdr)); + uhdr.ih_dcrc = crc32_le(~0, data, linux_len - sizeof(uhdr)) ^ (~0); + uhdr.ih_dcrc = cpu_to_be32(uhdr.ih_dcrc); + + printk(KERN_NOTICE " new: [size: %8d crc32: 0x%08x]\n", + be32_to_cpu(uhdr.ih_size), be32_to_cpu(uhdr.ih_dcrc)); + + /* update header's crc... */ + uhdr.ih_hcrc = 0; + uhdr.ih_hcrc = crc32_le(~0, (unsigned char *)&uhdr, + sizeof(uhdr)) ^ (~0); + uhdr.ih_hcrc = cpu_to_be32(uhdr.ih_hcrc); + + /* read first eraseblock from the image */ + block = kmalloc(mtd->erasesize, GFP_KERNEL); + if (mtd->read(mtd, adm8668_parts[PART_LINUX].offset, mtd->erasesize, &len, block) || len != mtd->erasesize) { + printk("Error copying first eraseblock\n"); + return 0; + } + + /* Write updated header to the flash */ + memcpy(block, &uhdr, sizeof(uhdr)); + if (mtd->unlock) + mtd->unlock(mtd, off, mtd->erasesize); + erase_write(mtd, adm8668_parts[PART_LINUX].offset, mtd->erasesize, block); + if (mtd->sync) + mtd->sync(mtd); + kfree(block); + printk(KERN_NOTICE "Done\n"); + } + + return NR_PARTS; +} + +int __init init_adm8668_map(void) +{ + int nr_parts, ret; + + adm8668_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); + + if (!adm8668_map.virt) { + printk(KERN_ERR "Failed to ioremap\n"); + return -EIO; + } + + simple_map_init(&adm8668_map); + if (!(adm8668_mtd = do_map_probe("cfi_probe", &adm8668_map))) { + printk(KERN_ERR "cfi_probe failed\n"); + iounmap((void *)adm8668_map.virt); + return -ENXIO; + } + + adm8668_mtd->owner = THIS_MODULE; + + nr_parts = init_mtd_partitions(adm8668_mtd, adm8668_mtd->size); + ret = mtd_device_register(adm8668_mtd, adm8668_parts, nr_parts); + if (ret) { + printk(KERN_ERR "Flash: mtd_device_register failed\n"); + goto fail; + } + + return 0; + + fail: + if (adm8668_mtd) + map_destroy(adm8668_mtd); + if (adm8668_map.virt) + iounmap((void *) adm8668_map.virt); + adm8668_map.virt = 0; + return ret; +} + +void __exit cleanup_adm8668_map(void) +{ + mtd_device_unregister(adm8668_mtd); + map_destroy(adm8668_mtd); + iounmap((void *) adm8668_map.virt); + adm8668_map.virt = 0; +} + +module_init(init_adm8668_map); +module_exit(cleanup_adm8668_map); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Scott Nicholas "); +MODULE_DESCRIPTION("MTD map driver for ADM8668 NOR Flash"); diff --git a/target/linux/adm8668/image/Makefile b/target/linux/adm8668/image/Makefile new file mode 100644 index 000000000..bc412a609 --- /dev/null +++ b/target/linux/adm8668/image/Makefile @@ -0,0 +1,58 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/image.mk + +VMLINUX:=$(BIN_DIR)/$(IMG_PREFIX)-vmlinux +UIMAGE:=$(IMG_PREFIX)-uImage +ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y) + VMLINUX:=$(BIN_DIR)/$(IMG_PREFIX)-vmlinux-initramfs + UIMAGE:=$(IMG_PREFIX)-uImage-initramfs +endif + +define kernel_entry +-a 0x80002000 -e 0x80002000 +endef + + +define CompressGzip + gzip -9 -c $(1) > $(2) +endef + +define MkImage + mkimage -A mips -O linux -T kernel $(call kernel_entry) -C $(1) $(2) \ + -n "ADM8668 Linux Kernel(2.4.31)" \ + -d $(3) $(4) +endef + +define Build/Clean + $(MAKE) -C lzma-loader clean +endef + +define Image/Prepare + cat $(KDIR)/vmlinux | $(STAGING_DIR_HOST)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma + $(MAKE) -C lzma-loader \ + KDIR="$(KDIR)" \ + clean compile + rm -f $(KDIR)/fs_mark + touch $(KDIR)/fs_mark + $(call prepare_generic_squashfs,$(KDIR)/fs_mark) +endef + +define Image/Build + ./my-mkimage $(KDIR)/loader.bin $(KDIR)/root.squashfs \ + $(KDIR)/fs_mark $(BIN_DIR)/$(IMG_PREFIX)-$(1).bin +endef + +define Image/BuildKernel + cp $(KDIR)/vmlinux.elf $(VMLINUX).elf + cp $(KDIR)/vmlinux $(VMLINUX).bin + $(call CompressGzip,$(KDIR)/vmlinux,$(KDIR)/vmlinux.bin.gz) + $(call MkImage,gzip,,$(KDIR)/vmlinux.bin.gz,$(BIN_DIR)/$(UIMAGE)-gzip.bin) +endef + +$(eval $(call BuildImage)) diff --git a/target/linux/adm8668/image/lzma-loader/Makefile b/target/linux/adm8668/image/lzma-loader/Makefile new file mode 100644 index 000000000..f6bc7cef3 --- /dev/null +++ b/target/linux/adm8668/image/lzma-loader/Makefile @@ -0,0 +1,41 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME := loader +PKG_VERSION := 0.05 + +PKG_BUILD_DIR := $(KDIR)/$(PKG_NAME)-$(PKG_VERSION)$(LOADER_TYPE) + +$(PKG_BUILD_DIR)/.prepared: + mkdir $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ + touch $@ + +$(PKG_BUILD_DIR)/lzma.elf: $(PKG_BUILD_DIR)/.prepared $(PKG_BUILD_DIR)/vmlinux.lzma + PATH="$(TARGET_PATH)" $(MAKE) -C $(PKG_BUILD_DIR) \ + CC="$(TARGET_CC)" CROSS_COMPILE="$(TARGET_CROSS)" + +$(PKG_BUILD_DIR)/vmlinux.lzma: $(KDIR)/vmlinux.lzma + $(CP) $< $@ + +$(KDIR)/loader$(LOADER_TYPE).elf: $(PKG_BUILD_DIR)/lzma.elf + $(CP) $< $@ + +$(KDIR)/loader$(LOADER_TYPE).bin: $(PKG_BUILD_DIR)/lzma.bin + $(CP) $< $@ + +download: +prepare: $(PKG_BUILD_DIR)/.prepared +compile: $(KDIR)/loader$(LOADER_TYPE).elf $(KDIR)/loader$(LOADER_TYPE).bin +install: + +clean: + rm -rf $(PKG_BUILD_DIR) + rm -f $(KDIR)/loader.elf + rm -f $(KDIR)/loader.bin diff --git a/target/linux/adm8668/image/lzma-loader/src/LzmaDecode.c b/target/linux/adm8668/image/lzma-loader/src/LzmaDecode.c new file mode 100644 index 000000000..8c863efe5 --- /dev/null +++ b/target/linux/adm8668/image/lzma-loader/src/LzmaDecode.c @@ -0,0 +1,590 @@ +/* + LzmaDecode.c + LZMA Decoder (optimized for Speed version) + + LZMA SDK 4.22 Copyright (c) 1999-2005 Igor Pavlov (2005-06-10) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this Code, expressly permits you to + statically or dynamically link your Code (or bind by name) to the + interfaces of this file without subjecting your linked Code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#include "LzmaDecode.h" + +#ifndef Byte +#define Byte unsigned char +#endif + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_READ_BYTE (*Buffer++) + +#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ + { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} + +#ifdef _LZMA_IN_CB + +#define RC_TEST { if (Buffer == BufferLim) \ + { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \ + BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }} + +#define RC_INIT Buffer = BufferLim = 0; RC_INIT2 + +#else + +#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } + +#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 + +#endif + +#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } + +#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) +#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; +#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; + +#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ + { UpdateBit0(p); mi <<= 1; A0; } else \ + { UpdateBit1(p); mi = (mi + mi) + 1; A1; } + +#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) + +#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ + { int i = numLevels; res = 1; \ + do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ + res -= (1 << numLevels); } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +#if 0 +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) +{ + unsigned char prop0; + if (size < LZMA_PROPERTIES_SIZE) + return LZMA_RESULT_DATA_ERROR; + prop0 = propsData[0]; + if (prop0 >= (9 * 5 * 5)) + return LZMA_RESULT_DATA_ERROR; + { + for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); + for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); + propsRes->lc = prop0; + /* + unsigned char remainder = (unsigned char)(prop0 / 9); + propsRes->lc = prop0 % 9; + propsRes->pb = remainder / 5; + propsRes->lp = remainder % 5; + */ + } + + #ifdef _LZMA_OUT_READ + { + int i; + propsRes->DictionarySize = 0; + for (i = 0; i < 4; i++) + propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); + if (propsRes->DictionarySize == 0) + propsRes->DictionarySize = 1; + } + #endif + return LZMA_RESULT_OK; +} +#endif + +#define kLzmaStreamWasFinishedId (-1) + +int LzmaDecode(CLzmaDecoderState *vs, + #ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback, + #else + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + #endif + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) +{ + CProb *p = vs->Probs; + SizeT nowPos = 0; + Byte previousByte = 0; + UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; + UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; + int lc = vs->Properties.lc; + + #ifdef _LZMA_OUT_READ + + UInt32 Range = vs->Range; + UInt32 Code = vs->Code; + #ifdef _LZMA_IN_CB + const Byte *Buffer = vs->Buffer; + const Byte *BufferLim = vs->BufferLim; + #else + const Byte *Buffer = inStream; + const Byte *BufferLim = inStream + inSize; + #endif + int state = vs->State; + UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; + int len = vs->RemainLen; + UInt32 globalPos = vs->GlobalPos; + UInt32 distanceLimit = vs->DistanceLimit; + + Byte *dictionary = vs->Dictionary; + UInt32 dictionarySize = vs->Properties.DictionarySize; + UInt32 dictionaryPos = vs->DictionaryPos; + + Byte tempDictionary[4]; + + #ifndef _LZMA_IN_CB + *inSizeProcessed = 0; + #endif + *outSizeProcessed = 0; + if (len == kLzmaStreamWasFinishedId) + return LZMA_RESULT_OK; + + if (dictionarySize == 0) + { + dictionary = tempDictionary; + dictionarySize = 1; + tempDictionary[0] = vs->TempDictionary[0]; + } + + if (len == kLzmaNeedInitId) + { + { + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + UInt32 i; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + rep0 = rep1 = rep2 = rep3 = 1; + state = 0; + globalPos = 0; + distanceLimit = 0; + dictionaryPos = 0; + dictionary[dictionarySize - 1] = 0; + #ifdef _LZMA_IN_CB + RC_INIT; + #else + RC_INIT(inStream, inSize); + #endif + } + len = 0; + } + while(len != 0 && nowPos < outSize) + { + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + len--; + } + if (dictionaryPos == 0) + previousByte = dictionary[dictionarySize - 1]; + else + previousByte = dictionary[dictionaryPos - 1]; + + #else /* if !_LZMA_OUT_READ */ + + int state = 0; + UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; + int len = 0; + const Byte *Buffer; + const Byte *BufferLim; + UInt32 Range; + UInt32 Code; + + #ifndef _LZMA_IN_CB + *inSizeProcessed = 0; + #endif + *outSizeProcessed = 0; + + { + UInt32 i; + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + } + + #ifdef _LZMA_IN_CB + RC_INIT; + #else + RC_INIT(inStream, inSize); + #endif + + #endif /* _LZMA_OUT_READ */ + + while(nowPos < outSize) + { + CProb *prob; + UInt32 bound; + int posState = (int)( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & posStateMask); + + prob = p + IsMatch + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + int symbol = 1; + UpdateBit0(prob) + prob = p + Literal + (LZMA_LIT_SIZE * + ((( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & literalPosMask) << lc) + (previousByte >> (8 - lc)))); + + if (state >= kNumLitStates) + { + int matchByte; + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + matchByte = dictionary[pos]; + #else + matchByte = outStream[nowPos - rep0]; + #endif + do + { + int bit; + CProb *probLit; + matchByte <<= 1; + bit = (matchByte & 0x100); + probLit = prob + 0x100 + bit + symbol; + RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) + } + while (symbol < 0x100); + } + while (symbol < 0x100) + { + CProb *probLit = prob + symbol; + RC_GET_BIT(probLit, symbol) + } + previousByte = (Byte)symbol; + + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + if (distanceLimit < dictionarySize) + distanceLimit++; + + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #endif + if (state < 4) state = 0; + else if (state < 10) state -= 3; + else state -= 6; + } + else + { + UpdateBit1(prob); + prob = p + IsRep + state; + IfBit0(prob) + { + UpdateBit0(prob); + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + state = state < kNumLitStates ? 0 : 3; + prob = p + LenCoder; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG0 + state; + IfBit0(prob) + { + UpdateBit0(prob); + prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + #ifdef _LZMA_OUT_READ + UInt32 pos; + #endif + UpdateBit0(prob); + + #ifdef _LZMA_OUT_READ + if (distanceLimit == 0) + #else + if (nowPos == 0) + #endif + return LZMA_RESULT_DATA_ERROR; + + state = state < kNumLitStates ? 9 : 11; + #ifdef _LZMA_OUT_READ + pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + if (distanceLimit < dictionarySize) + distanceLimit++; + #endif + + continue; + } + else + { + UpdateBit1(prob); + } + } + else + { + UInt32 distance; + UpdateBit1(prob); + prob = p + IsRepG1 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep1; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG2 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep2; + } + else + { + UpdateBit1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = p + RepLenCoder; + } + { + int numBits, offset; + CProb *probLen = prob + LenChoice; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + numBits = kLenNumLowBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenChoice2; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + numBits = kLenNumMidBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + numBits = kLenNumHighBits; + } + } + RangeDecoderBitTreeDecode(probLen, numBits, len); + len += offset; + } + + if (state < 4) + { + int posSlot; + state += kNumLitStates; + prob = p + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + rep0 = (2 | ((UInt32)posSlot & 1)); + if (posSlot < kEndPosModelIndex) + { + rep0 <<= numDirectBits; + prob = p + SpecPos + rep0 - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + RC_NORMALIZE + Range >>= 1; + rep0 <<= 1; + if (Code >= Range) + { + Code -= Range; + rep0 |= 1; + } + } + while (--numDirectBits != 0); + prob = p + Align; + rep0 <<= kNumAlignBits; + numDirectBits = kNumAlignBits; + } + { + int i = 1; + int mi = 1; + do + { + CProb *prob3 = prob + mi; + RC_GET_BIT2(prob3, mi, ; , rep0 |= i); + i <<= 1; + } + while(--numDirectBits != 0); + } + } + else + rep0 = posSlot; + if (++rep0 == (UInt32)(0)) + { + /* it's for stream version */ + len = kLzmaStreamWasFinishedId; + break; + } + } + + len += kMatchMinLen; + #ifdef _LZMA_OUT_READ + if (rep0 > distanceLimit) + #else + if (rep0 > nowPos) + #endif + return LZMA_RESULT_DATA_ERROR; + + #ifdef _LZMA_OUT_READ + if (dictionarySize - distanceLimit > (UInt32)len) + distanceLimit += len; + else + distanceLimit = dictionarySize; + #endif + + do + { + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + len--; + outStream[nowPos++] = previousByte; + } + while(len != 0 && nowPos < outSize); + } + } + RC_NORMALIZE; + + #ifdef _LZMA_OUT_READ + vs->Range = Range; + vs->Code = Code; + vs->DictionaryPos = dictionaryPos; + vs->GlobalPos = globalPos + (UInt32)nowPos; + vs->DistanceLimit = distanceLimit; + vs->Reps[0] = rep0; + vs->Reps[1] = rep1; + vs->Reps[2] = rep2; + vs->Reps[3] = rep3; + vs->State = state; + vs->RemainLen = len; + vs->TempDictionary[0] = tempDictionary[0]; + #endif + + #ifdef _LZMA_IN_CB + vs->Buffer = Buffer; + vs->BufferLim = BufferLim; + #else + *inSizeProcessed = (SizeT)(Buffer - inStream); + #endif + *outSizeProcessed = nowPos; + return LZMA_RESULT_OK; +} diff --git a/target/linux/adm8668/image/lzma-loader/src/LzmaDecode.h b/target/linux/adm8668/image/lzma-loader/src/LzmaDecode.h new file mode 100644 index 000000000..abc02d7ed --- /dev/null +++ b/target/linux/adm8668/image/lzma-loader/src/LzmaDecode.h @@ -0,0 +1,131 @@ +/* + LzmaDecode.h + LZMA Decoder interface + + LZMA SDK 4.21 Copyright (c) 1999-2005 Igor Pavlov (2005-06-08) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to the + interfaces of this file without subjecting your linked code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#ifndef __LZMADECODE_H +#define __LZMADECODE_H + +/* #define _LZMA_IN_CB */ +/* Use callback for input data */ + +/* #define _LZMA_OUT_READ */ +/* Use read function for output data */ + +/* #define _LZMA_PROB32 */ +/* It can increase speed on some 32-bit CPUs, + but memory usage will be doubled in that case */ + +/* #define _LZMA_LOC_OPT */ +/* Enable local speed optimizations inside code */ + +/* #define _LZMA_SYSTEM_SIZE_T */ +/* Use system's size_t. You can use it to enable 64-bit sizes supporting*/ + +#ifndef UInt32 +#ifdef _LZMA_UINT32_IS_ULONG +#define UInt32 unsigned long +#else +#define UInt32 unsigned int +#endif +#endif + +#ifndef SizeT +#ifdef _LZMA_SYSTEM_SIZE_T +#include +#define SizeT size_t +#else +#define SizeT UInt32 +#endif +#endif + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb unsigned short +#endif + +#define LZMA_RESULT_OK 0 +#define LZMA_RESULT_DATA_ERROR 1 + +#ifdef _LZMA_IN_CB +typedef struct _ILzmaInCallback +{ + int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize); +} ILzmaInCallback; +#endif + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LZMA_PROPERTIES_SIZE 5 + +typedef struct _CLzmaProperties +{ + int lc; + int lp; + int pb; + #ifdef _LZMA_OUT_READ + UInt32 DictionarySize; + #endif +}CLzmaProperties; + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); + +#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) + +#define kLzmaNeedInitId (-2) + +typedef struct _CLzmaDecoderState +{ + CLzmaProperties Properties; + CProb *Probs; + + #ifdef _LZMA_IN_CB + const unsigned char *Buffer; + const unsigned char *BufferLim; + #endif + + #ifdef _LZMA_OUT_READ + unsigned char *Dictionary; + UInt32 Range; + UInt32 Code; + UInt32 DictionaryPos; + UInt32 GlobalPos; + UInt32 DistanceLimit; + UInt32 Reps[4]; + int State; + int RemainLen; + unsigned char TempDictionary[4]; + #endif +} CLzmaDecoderState; + +#ifdef _LZMA_OUT_READ +#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; } +#endif + +int LzmaDecode(CLzmaDecoderState *vs, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback, + #else + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + #endif + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); + +#endif diff --git a/target/linux/adm8668/image/lzma-loader/src/Makefile b/target/linux/adm8668/image/lzma-loader/src/Makefile new file mode 100644 index 000000000..998e39081 --- /dev/null +++ b/target/linux/adm8668/image/lzma-loader/src/Makefile @@ -0,0 +1,47 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +RAMSTART = 0x80000000 +RAMSIZE = 0x00800000 # 8MB +LOADADDR = 0x80400000 # RAM start + 4M +KERNEL_ENTRY = 0x80002000 + +CROSS_COMPILE = mipsel-openwrt-linux- + +OBJCOPY:= $(CROSS_COMPILE)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S +CFLAGS := -I./include -fno-builtin -Os -G 0 -ffunction-sections -mno-abicalls -fno-pic -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap -Wall -DRAMSTART=${RAMSTART} -DRAMSIZE=${RAMSIZE} -DKERNEL_ENTRY=${KERNEL_ENTRY} + +.c.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +CC = $(CROSS_COMPILE)gcc +LD = $(CROSS_COMPILE)ld +OBJDUMP = $(CROSS_COMPILE)objdump + +O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32) + +# Drop some uninteresting sections in the kernel. +# This is only relevant for ELF kernels but doesn't hurt a.out +drop-sections = .reginfo .mdebug .comment +strip-flags = $(addprefix --remove-section=,$(drop-sections)) + +all : lzma.elf lzma.bin + +lzma.lds: lzma.lds.in + sed -e 's,@LOADADDR@,$(LOADADDR),g' $< >$@ + +kernel.o: vmlinux.lzma lzma.lds + $(LD) -r -b binary --oformat $(O_FORMAT) -o $@ $< + +lzma.bin: lzma.elf + $(OBJCOPY) $< $@ + +lzma.elf: decompress.o stubs.o LzmaDecode.o kernel.o lzma.lds + $(LD) -T lzma.lds -o $@ $^ +#-s ^ + +clean: + rm -f *.o lzma.elf lzma.bin *.tmp *.lds diff --git a/target/linux/adm8668/image/lzma-loader/src/decompress.c b/target/linux/adm8668/image/lzma-loader/src/decompress.c new file mode 100644 index 000000000..f328058a1 --- /dev/null +++ b/target/linux/adm8668/image/lzma-loader/src/decompress.c @@ -0,0 +1,118 @@ +/* + * LZMA compressed kernel decompressor for bcm947xx boards + * + * Copyright (C) 2005 by Oleg I. Vdovikin + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * Please note, this was code based on the bunzip2 decompressor code + * by Manuel Novoa III (mjn3@codepoet.org), although the only thing left + * is an idea and part of original vendor code + * + * + * 12-Mar-2005 Mineharu Takahara + * pass actual output size to decoder (stream mode + * compressed input is not a requirement anymore) + * + * 24-Apr-2005 Oleg I. Vdovikin + * reordered functions using lds script, removed forward decl + * + * ??-Nov-2005 Mike Baker + * reorder the script as an lzma wrapper; do not depend on flash access + */ + +#include "LzmaDecode.h" +#include + +#define KSEG0ADDR(addr) (0x80000000|addr) + +register volatile gd_t *gd asm ("k0"); +unsigned char *data; + +static __inline__ unsigned char get_byte() +{ + unsigned char *buffer; + + buffer = data; + data++; + + return *buffer; +} + +/* This puts lzma workspace 128k below RAM end. + * That should be enough for both lzma and stack + */ +static char *buffer = (char *)(RAMSTART + RAMSIZE - 0x00020000); +extern char _binary_vmlinux_lzma_start[]; +extern char _binary_vmlinux_lzma_end[]; +extern char lzma_start[]; +extern char lzma_end[]; + +/* should be the first function */ +void entry(unsigned int arg0, unsigned int arg1, + unsigned int arg2, unsigned int arg3) +{ + unsigned int i; /* temp value */ + unsigned int isize; /* compressed size */ + unsigned int osize; /* uncompressed size */ + int argc = arg0; + char **argv = (char **)arg1; + char **envp = (char **)arg2; + + CLzmaDecoderState vs; + + data = (unsigned char *)_binary_vmlinux_lzma_start; + isize = _binary_vmlinux_lzma_end - _binary_vmlinux_lzma_start + 1; + + puts("\nLZMA kernel loader\n"); + + printf("lzma data @ %#x - %#x\n", _binary_vmlinux_lzma_start, _binary_vmlinux_lzma_end); + printf("load addr @ %#x\n\n", KERNEL_ENTRY); + printf("jump table @ %#x\n", gd->jt[3]); + + /* lzma args */ + i = get_byte(); + vs.Properties.lc = i % 9, i = i / 9; + vs.Properties.lp = i % 5, vs.Properties.pb = i / 5; + + vs.Probs = (CProb *)buffer; + + /* skip rest of the LZMA coder property */ + data += 4; + + /* read the lower half of uncompressed size in the header */ + osize = ((unsigned int)get_byte()) + + ((unsigned int)get_byte() << 8) + + ((unsigned int)get_byte() << 16) + + ((unsigned int)get_byte() << 24); + + /* skip rest of the header (upper half of uncompressed size) */ + data += 4; + + /* decompress kernel */ + puts("\nDecompressing kernel..."); + if ((i = LzmaDecode(&vs, + (unsigned char*)data, isize, &isize, + (unsigned char*)KERNEL_ENTRY, osize, &osize)) == LZMA_RESULT_OK) + { + puts("success!\n"); + + /* Jump to load address */ +// ((void (*)(int a0, int a1, int a2, int a3))KERNEL_ENTRY)(0,0,0,0); + ((void (*)(int a0, int a1, int a2, int a3))KERNEL_ENTRY)(arg0, arg1, arg2, arg3); + } + puts("failure!\n"); +} diff --git a/target/linux/adm8668/image/lzma-loader/src/include/_exports.h b/target/linux/adm8668/image/lzma-loader/src/include/_exports.h new file mode 100644 index 000000000..61dcaaf33 --- /dev/null +++ b/target/linux/adm8668/image/lzma-loader/src/include/_exports.h @@ -0,0 +1,18 @@ +EXPORT_FUNC(get_version) +EXPORT_FUNC(getc) +EXPORT_FUNC(tstc) +EXPORT_FUNC(putc) +EXPORT_FUNC(puts) +EXPORT_FUNC(printf) +EXPORT_FUNC(install_hdlr) +EXPORT_FUNC(free_hdlr) +EXPORT_FUNC(malloc) +EXPORT_FUNC(free) +EXPORT_FUNC(udelay) +EXPORT_FUNC(get_timer) +EXPORT_FUNC(vprintf) +EXPORT_FUNC(do_reset) +#if (CONFIG_COMMANDS & CFG_CMD_I2C) +EXPORT_FUNC(i2c_write) +EXPORT_FUNC(i2c_read) +#endif /* CFG_CMD_I2C */ diff --git a/target/linux/adm8668/image/lzma-loader/src/include/asm/global_data.h b/target/linux/adm8668/image/lzma-loader/src/include/asm/global_data.h new file mode 100644 index 000000000..a024194ba --- /dev/null +++ b/target/linux/adm8668/image/lzma-loader/src/include/asm/global_data.h @@ -0,0 +1,60 @@ +/* + * (C) Copyright 2002-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_GBL_DATA_H +#define __ASM_GBL_DATA_H + +#include + +/* + * The following data structure is placed in some memory wich is + * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or + * some locked parts of the data cache) to allow for a minimum set of + * global variables during system initialization (until we have set + * up the memory controller so that we can use RAM). + * + * Keep it *SMALL* and remember to set CFG_GBL_DATA_SIZE > sizeof(gd_t) + */ + +typedef struct global_data { + bd_t *bd; + unsigned long flags; + unsigned long baudrate; + unsigned long have_console; /* serial_init() was called */ + unsigned long ram_size; /* RAM size */ + unsigned long reloc_off; /* Relocation Offset */ + unsigned long env_addr; /* Address of Environment struct */ + unsigned long env_valid; /* Checksum of Environment valid? */ + void **jt; /* jump table */ +} gd_t; + +/* + * Global Data Flags + */ +#define GD_FLG_RELOC 0x00001 /* Code was relocated to RAM */ +#define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */ +#define GD_FLG_SILENT 0x00004 /* Silent mode */ + +#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("k0") + +#endif /* __ASM_GBL_DATA_H */ diff --git a/target/linux/adm8668/image/lzma-loader/src/include/asm/u-boot.h b/target/linux/adm8668/image/lzma-loader/src/include/asm/u-boot.h new file mode 100644 index 000000000..0de0b4da8 --- /dev/null +++ b/target/linux/adm8668/image/lzma-loader/src/include/asm/u-boot.h @@ -0,0 +1,42 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _U_BOOT_H_ +#define _U_BOOT_H_ 1 + +typedef struct bd_info { + int bi_baudrate; /* serial console baudrate */ + unsigned long bi_ip_addr; /* IP Address */ + unsigned char bi_enetaddr[6]; /* Ethernet adress */ + unsigned long bi_arch_number; /* unique id for this board */ + unsigned long bi_boot_params; /* where this board expects params */ + unsigned long bi_memstart; /* start of DRAM memory */ + unsigned long bi_memsize; /* size of DRAM memory in bytes */ + unsigned long bi_flashstart; /* start of FLASH memory */ + unsigned long bi_flashsize; /* size of FLASH memory */ + unsigned long bi_flashoffset; /* reserved area for startup monitor */ +} bd_t; +#define bi_env_data bi_env->data +#define bi_env_crc bi_env->crc + +#endif /* _U_BOOT_H_ */ diff --git a/target/linux/adm8668/image/lzma-loader/src/include/common.h b/target/linux/adm8668/image/lzma-loader/src/include/common.h new file mode 100644 index 000000000..5d957af6a --- /dev/null +++ b/target/linux/adm8668/image/lzma-loader/src/include/common.h @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __COMMON_H_ +#define __COMMON_H_ 1 + +#undef _LINUX_CONFIG_H +#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ + +typedef unsigned char uchar; +typedef volatile unsigned long vu_long; +typedef volatile unsigned short vu_short; +typedef volatile unsigned char vu_char; + +#include +#include +#include +#include +#include +#include + +typedef void (interrupt_handler_t)(void *); + +#include /* boot information for Linux kernel */ +#include /* global data used for startup functions */ + + +#endif /* __COMMON_H_ */ diff --git a/target/linux/adm8668/image/lzma-loader/src/include/exports.h b/target/linux/adm8668/image/lzma-loader/src/include/exports.h new file mode 100644 index 000000000..4cdc36e37 --- /dev/null +++ b/target/linux/adm8668/image/lzma-loader/src/include/exports.h @@ -0,0 +1,38 @@ +#ifndef __EXPORTS_H__ +#define __EXPORTS_H__ +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#ifndef __ASSEMBLY__ + +#include + +/* These are declarations of exported functions available in C code */ +unsigned long get_version(void); +int getc(void); +int tstc(void); +void putc(const char); +void puts(const char*); +void printf(const char* fmt, ...); +void install_hdlr(int, interrupt_handler_t*, void*); +void free_hdlr(int); +void *malloc(size_t); +void free(void*); +void udelay(unsigned long); +unsigned long get_timer(unsigned long); +void vprintf(const char *, va_list); +void do_reset (void); + +void app_startup(char **); + +#endif /* ifndef __ASSEMBLY__ */ + +enum { +#define EXPORT_FUNC(x) XF_ ## x , +#include <_exports.h> +#undef EXPORT_FUNC + + XF_MAX +}; + +#define XF_VERSION 2 + +#endif /* __EXPORTS_H__ */ diff --git a/target/linux/adm8668/image/lzma-loader/src/include/image.h b/target/linux/adm8668/image/lzma-loader/src/include/image.h new file mode 100644 index 000000000..69c73b71d --- /dev/null +++ b/target/linux/adm8668/image/lzma-loader/src/include/image.h @@ -0,0 +1,157 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __IMAGE_H__ +#define __IMAGE_H__ + +/* + * Operating System Codes + */ +#define IH_OS_INVALID 0 /* Invalid OS */ +#define IH_OS_OPENBSD 1 /* OpenBSD */ +#define IH_OS_NETBSD 2 /* NetBSD */ +#define IH_OS_FREEBSD 3 /* FreeBSD */ +#define IH_OS_4_4BSD 4 /* 4.4BSD */ +#define IH_OS_LINUX 5 /* Linux */ +#define IH_OS_SVR4 6 /* SVR4 */ +#define IH_OS_ESIX 7 /* Esix */ +#define IH_OS_SOLARIS 8 /* Solaris */ +#define IH_OS_IRIX 9 /* Irix */ +#define IH_OS_SCO 10 /* SCO */ +#define IH_OS_DELL 11 /* Dell */ +#define IH_OS_NCR 12 /* NCR */ +#define IH_OS_LYNXOS 13 /* LynxOS */ +#define IH_OS_VXWORKS 14 /* VxWorks */ +#define IH_OS_PSOS 15 /* pSOS */ +#define IH_OS_QNX 16 /* QNX */ +#define IH_OS_U_BOOT 17 /* Firmware */ +#define IH_OS_RTEMS 18 /* RTEMS */ +#define IH_OS_ARTOS 19 /* ARTOS */ +#define IH_OS_UNITY 20 /* Unity OS */ + +/* + * CPU Architecture Codes (supported by Linux) + */ +#define IH_CPU_INVALID 0 /* Invalid CPU */ +#define IH_CPU_ALPHA 1 /* Alpha */ +#define IH_CPU_ARM 2 /* ARM */ +#define IH_CPU_I386 3 /* Intel x86 */ +#define IH_CPU_IA64 4 /* IA64 */ +#define IH_CPU_MIPS 5 /* MIPS */ +#define IH_CPU_MIPS64 6 /* MIPS 64 Bit */ +#define IH_CPU_PPC 7 /* PowerPC */ +#define IH_CPU_S390 8 /* IBM S390 */ +#define IH_CPU_SH 9 /* SuperH */ +#define IH_CPU_SPARC 10 /* Sparc */ +#define IH_CPU_SPARC64 11 /* Sparc 64 Bit */ +#define IH_CPU_M68K 12 /* M68K */ +#define IH_CPU_NIOS 13 /* Nios-32 */ +#define IH_CPU_MICROBLAZE 14 /* MicroBlaze */ +#define IH_CPU_NIOS2 15 /* Nios-II */ + +/* + * Image Types + * + * "Standalone Programs" are directly runnable in the environment + * provided by U-Boot; it is expected that (if they behave + * well) you can continue to work in U-Boot after return from + * the Standalone Program. + * "OS Kernel Images" are usually images of some Embedded OS which + * will take over control completely. Usually these programs + * will install their own set of exception handlers, device + * drivers, set up the MMU, etc. - this means, that you cannot + * expect to re-enter U-Boot except by resetting the CPU. + * "RAMDisk Images" are more or less just data blocks, and their + * parameters (address, size) are passed to an OS kernel that is + * being started. + * "Multi-File Images" contain several images, typically an OS + * (Linux) kernel image and one or more data images like + * RAMDisks. This construct is useful for instance when you want + * to boot over the network using BOOTP etc., where the boot + * server provides just a single image file, but you want to get + * for instance an OS kernel and a RAMDisk image. + * + * "Multi-File Images" start with a list of image sizes, each + * image size (in bytes) specified by an "uint32_t" in network + * byte order. This list is terminated by an "(uint32_t)0". + * Immediately after the terminating 0 follow the images, one by + * one, all aligned on "uint32_t" boundaries (size rounded up to + * a multiple of 4 bytes - except for the last file). + * + * "Firmware Images" are binary images containing firmware (like + * U-Boot or FPGA images) which usually will be programmed to + * flash memory. + * + * "Script files" are command sequences that will be executed by + * U-Boot's command interpreter; this feature is especially + * useful when you configure U-Boot to use a real shell (hush) + * as command interpreter (=> Shell Scripts). + */ + +#define IH_TYPE_INVALID 0 /* Invalid Image */ +#define IH_TYPE_STANDALONE 1 /* Standalone Program */ +#define IH_TYPE_KERNEL 2 /* OS Kernel Image */ +#define IH_TYPE_RAMDISK 3 /* RAMDisk Image */ +#define IH_TYPE_MULTI 4 /* Multi-File Image */ +#define IH_TYPE_FIRMWARE 5 /* Firmware Image */ +#define IH_TYPE_SCRIPT 6 /* Script file */ +#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */ + +/* + * Compression Types + */ +#define IH_COMP_NONE 0 /* No Compression Used */ +#define IH_COMP_GZIP 1 /* gzip Compression Used */ +#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */ + +#define IH_MAGIC 0x27051956 /* Image Magic Number */ +#define IH_NMLEN 32 /* Image Name Length */ + +#define IH_NAMEMAGIC 0x86680001 /* Name Magic Number */ +#define IH_SIZEMAX 5800000 /* Max image size */ +/* + * all data in network byte order (aka natural aka bigendian) + */ + +typedef struct image_header { + uint32_t ih_magic; /* Image Header Magic Number */ + uint32_t ih_hcrc; /* Image Header CRC Checksum */ + uint32_t ih_time; /* Image Creation Timestamp */ + uint32_t ih_size; /* Image Data Size */ + uint32_t ih_load; /* Data Load Address */ + uint32_t ih_ep; /* Entry Point Address */ + uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ + uint8_t ih_comp; /* Compression Type */ +#ifdef NEW_IMAGE_HEADER + uint32_t ih_namemagic; /* image name CRC */ + uint8_t ih_name[IH_NMLEN-4]; /* image name */ +#else + uint8_t ih_name[IH_NMLEN]; /* Image Name */ +#endif +} image_header_t; + + +#endif /* __IMAGE_H__ */ diff --git a/target/linux/adm8668/image/lzma-loader/src/lzma.lds.in b/target/linux/adm8668/image/lzma-loader/src/lzma.lds.in new file mode 100644 index 000000000..d6c60ca0d --- /dev/null +++ b/target/linux/adm8668/image/lzma-loader/src/lzma.lds.in @@ -0,0 +1,24 @@ +OUTPUT_ARCH(mips) +ENTRY(entry) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = @LOADADDR@; + .text : + { + _ftext = . ; + *(.text.entry) + *(.text) + lzma_start = .; + kernel.o + lzma_end = .; + *(.rodata) + } =0 + + .reginfo : { *(.reginfo) } + + .bss : + { + *(.bss) + } +} diff --git a/target/linux/adm8668/image/lzma-loader/src/stubs.c b/target/linux/adm8668/image/lzma-loader/src/stubs.c new file mode 100644 index 000000000..468e5a1fd --- /dev/null +++ b/target/linux/adm8668/image/lzma-loader/src/stubs.c @@ -0,0 +1,52 @@ +#include + +#ifndef GCC_VERSION +#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) +#endif /* GCC_VERSION */ + +/* + * k0 ($26) holds the pointer to the global_data; t9 ($25) is a call- + * clobbered register that is also used to set gp ($26). Note that the + * jr instruction also executes the instruction immediately following + * it; however, GCC/mips generates an additional `nop' after each asm + * statement + */ +#define EXPORT_FUNC(x) \ + asm volatile ( \ +" .globl " #x "\n" \ +#x ":\n" \ +" lw $25, %0($26)\n" \ +" lw $25, %1($25)\n" \ +" jr $25\n" \ + : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "t9"); + +/* This function is necessary to prevent the compiler from + * generating prologue/epilogue, preparing stack frame etc. + * The stub functions are special, they do not use the stack + * frame passed to them, but pass it intact to the actual + * implementation. On the other hand, asm() statements with + * arguments can be used only inside the functions (gcc limitation) + */ +#if GCC_VERSION < 3004 +static +#endif /* GCC_VERSION */ +void __attribute__((unused)) dummy(void) +{ +#include <_exports.h> +} + +#if 0 +extern unsigned long __bss_start, _end; + +void app_startup(char **argv) +{ + unsigned long * cp = &__bss_start; + + /* Zero out BSS */ + while (cp < &_end) { + *cp++ = 0; + } +} +#endif + +#undef EXPORT_FUNC diff --git a/target/linux/adm8668/image/my-mkimage b/target/linux/adm8668/image/my-mkimage new file mode 100755 index 000000000..7ed6666e7 --- /dev/null +++ b/target/linux/adm8668/image/my-mkimage @@ -0,0 +1,32 @@ +#!/bin/sh +# my-mkimage +# This will pad given files to 64k boundaries to make a single u-boot image. +# we have to be fancy because u-boot mkimage is going to add 64 byte header, ... +# and i only know basic arithmetic.. ;) +# +# Copyright (C) 2010 Scott Nicholas +[ $# -lt 2 ] && { + echo usage: $0 loader.bin [rootfs.squashfs [fs_mark [...]]] output.bin +} + +OLDSIZE=$(stat -c%s $1) +NEWSIZE=$(((OLDSIZE / 65536 + 1) * 65536 - 64)) + +dd if=$1 of=vmlinuz.tmp bs=$NEWSIZE conv=sync >/dev/null 2>&1 +shift +appends=$(($# - 1)) +echo +while [ $appends -gt 0 ]; do + dd if=$1 of=temp bs=64k conv=sync >/dev/null 2>&1 + printf "### '%s' starts at 0x%x\n" "`basename $1`" "$((NEWSIZE+64))" + cat temp >>vmlinuz.tmp + shift + appends=$((appends-1)) + NEWSIZE=$(stat -c%s vmlinuz.tmp) +done +echo +../../../../staging_dir/host/bin/mkimage -A mips -O linux -T kernel \ +-C none -a 0x80400000 -e 0x80400000 -n "ADM8668 Linux Kernel(2.4.31)" \ +-d vmlinuz.tmp $1 + +rm temp vmlinuz.tmp diff --git a/target/linux/adm8668/patches-3.3/001-adm8668_arch.patch b/target/linux/adm8668/patches-3.3/001-adm8668_arch.patch new file mode 100644 index 000000000..c00188cf0 --- /dev/null +++ b/target/linux/adm8668/patches-3.3/001-adm8668_arch.patch @@ -0,0 +1,39 @@ +--- a/arch/mips/Kbuild.platforms ++++ b/arch/mips/Kbuild.platforms +@@ -30,6 +30,7 @@ platforms += sni + platforms += txx9 + platforms += vr41xx + platforms += wrppmc ++platforms += adm8668 + + # include the platform specific files + include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms)) +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -105,6 +105,26 @@ config BCM47XX + help + Support for BCM47XX based boards + ++config ADM8668 ++ bool "WildPass ADM8668" ++ select SYS_HAS_CPU_MIPS32_R1 ++ select BOOT_RAW ++ select NO_EXCEPT_FILL ++ select IRQ_CPU ++ select CEVT_R4K ++ select CSRC_R4K ++ select HW_HAS_PCI ++ select PCI ++ select SYS_SUPPORTS_LITTLE_ENDIAN ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select DMA_NONCOHERENT ++ select SWAP_IO_SPACE ++ select SERIAL_ADM8668 ++ select SERIAL_ADM8668_CONSOLE ++ help ++ ADM8668 board support by neutronscott ++ Scott Nicholas ++ + config BCM63XX + bool "Broadcom BCM63XX based boards" + select CEVT_R4K diff --git a/target/linux/adm8668/patches-3.3/002-adm8668_uart.patch b/target/linux/adm8668/patches-3.3/002-adm8668_uart.patch new file mode 100644 index 000000000..ed55cbbaa --- /dev/null +++ b/target/linux/adm8668/patches-3.3/002-adm8668_uart.patch @@ -0,0 +1,40 @@ +--- a/drivers/tty/serial/Kconfig ++++ b/drivers/tty/serial/Kconfig +@@ -1192,6 +1192,25 @@ config SERIAL_BCM63XX_CONSOLE + If you have enabled the serial port on the bcm63xx CPU + you can make it the console by answering Y to this option. + ++config SERIAL_ADM8668 ++ tristate "ADM8668 serial port support" ++ select SERIAL_CORE ++ depends on ADM8668 ++ help ++ If you have an adm8668 CPU, you can enable its onboard ++ serial port by enabling this options. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called adm8668_uart. ++ ++config SERIAL_ADM8668_CONSOLE ++ bool "Console on adm8668 serial port" ++ depends on SERIAL_ADM8668=y ++ select SERIAL_CORE_CONSOLE ++ help ++ If you have enabled the serial port on the adm8668 CPU ++ you can make it the console by answering Y to this option. ++ + config SERIAL_GRLIB_GAISLER_APBUART + tristate "GRLIB APBUART serial support" + depends on OF && SPARC +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -211,6 +211,9 @@ + #define PORT_AR933X 99 + + ++/* ADM8668 UART */ ++#define PORT_ADM8668 100 ++ + #ifdef __KERNEL__ + + #include diff --git a/target/linux/adm8668/patches-3.3/003-adm8668_nor_map.patch b/target/linux/adm8668/patches-3.3/003-adm8668_nor_map.patch new file mode 100644 index 000000000..eca9bc468 --- /dev/null +++ b/target/linux/adm8668/patches-3.3/003-adm8668_nor_map.patch @@ -0,0 +1,25 @@ +--- a/drivers/mtd/maps/Kconfig ++++ b/drivers/mtd/maps/Kconfig +@@ -96,6 +96,12 @@ config MSP_FLASH_MAP_LIMIT + default "0x02000000" + depends on MSP_FLASH_MAP_LIMIT_32M + ++config MTD_ADM8668_NOR ++ tristate "ADM8668 NOR mapping" ++ depends on ADM8668 && MTD_CFI ++ help ++ mapping driver for ADM8668 NOR ++ + config MTD_SUN_UFLASH + tristate "Sun Microsystems userflash support" + depends on SPARC && MTD_CFI && PCI +--- a/drivers/mtd/maps/Makefile ++++ b/drivers/mtd/maps/Makefile +@@ -7,6 +7,7 @@ obj-$(CONFIG_MTD) += map_funcs.o + endif + + # Chip mappings ++obj-$(CONFIG_MTD_ADM8668_NOR) += adm8668.o + obj-$(CONFIG_MTD_CDB89712) += cdb89712.o + obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o + obj-$(CONFIG_MTD_DC21285) += dc21285.o diff --git a/target/linux/amazon/Makefile b/target/linux/amazon/Makefile new file mode 100644 index 000000000..8b5607e10 --- /dev/null +++ b/target/linux/amazon/Makefile @@ -0,0 +1,27 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +ARCH:=mips +BOARD:=amazon +BOARDNAME:=Infineon Amazon +FEATURES:=squashfs jffs2 broken +LINUX_VERSION:=3.3.8 + +include $(INCLUDE_DIR)/target.mk + +define Target/Description + Build firmware images for Infineon Amazon boards +endef + +define Kernel/Prepare + $(call Kernel/Prepare/Default) + mkdir -p $(LINUX_DIR)/arch/mips/include/asm/amazon + $(CP) $(LINUX_DIR)/include/asm-mips/amazon/*.h $(LINUX_DIR)/arch/mips/include/asm/amazon +endef + +$(eval $(call BuildTarget)) diff --git a/target/linux/amazon/base-files/etc/config/network b/target/linux/amazon/base-files/etc/config/network new file mode 100644 index 000000000..72e39f88a --- /dev/null +++ b/target/linux/amazon/base-files/etc/config/network @@ -0,0 +1,14 @@ +# Copyright (C) 2006 OpenWrt.org + +config interface loopback + option ifname lo + option proto static + option ipaddr 127.0.0.1 + option netmask 255.0.0.0 + +config interface lan + option ifname eth1 + option type bridge + option proto static + option ipaddr 192.168.1.1 + option netmask 255.255.255.0 diff --git a/target/linux/amazon/config-3.3 b/target/linux/amazon/config-3.3 new file mode 100644 index 000000000..e3120a8ba --- /dev/null +++ b/target/linux/amazon/config-3.3 @@ -0,0 +1,104 @@ +CONFIG_ADM6996_SUPPORT=y +CONFIG_AMAZON=y +CONFIG_AMAZON_ASC_UART=y +CONFIG_AMAZON_MTD=y +CONFIG_AMAZON_NET_SW=y +CONFIG_AMAZON_PCI=y +CONFIG_AMAZON_WDT=y +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +CONFIG_ARCH_DISCARD_MEMBLOCK=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_BCMA_POSSIBLE=y +CONFIG_CEVT_R4K=y +CONFIG_CEVT_R4K_LIB=y +CONFIG_CMDLINE="console=ttyS0,115200 rootfstype=squashfs,jffs2 init=/bin/sh" +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE_OVERRIDE=y +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS32_R1 is not set +CONFIG_CPU_MIPS32_R2=y +CONFIG_CPU_MIPSR2=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CSRC_R4K=y +CONFIG_CSRC_R4K_LIB=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_ATOMIC64=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_HARDWARE_WATCHPOINTS=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_GENERIC_HARDIRQS=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_WORK=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_STD_PC_SERIAL_PORT=y +CONFIG_HW_HAS_PCI=y +CONFIG_HW_RANDOM=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IRQ_CPU=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_KALLSYMS=y +CONFIG_MIPS=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +# CONFIG_MIPS_MACHINE is not set +CONFIG_MIPS_MT_DISABLED=y +CONFIG_MTD_AMAZON_BUS_WIDTH_16=y +# CONFIG_MTD_AMAZON_BUS_WIDTH_32 is not set +# CONFIG_MTD_AMAZON_BUS_WIDTH_8 is not set +# CONFIG_MTD_AMAZON_FLASH_SIZE_16 is not set +# CONFIG_MTD_AMAZON_FLASH_SIZE_2 is not set +CONFIG_MTD_AMAZON_FLASH_SIZE_4=y +# CONFIG_MTD_AMAZON_FLASH_SIZE_8 is not set +CONFIG_MTD_CFI_ADV_OPTIONS=y +# CONFIG_MTD_CFI_GEOMETRY is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-3 +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PERF_USE_VMALLOC=y +# CONFIG_PREEMPT_RCU is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SERIAL_8250 is not set +CONFIG_SWAP_IO_SPACE=y +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_SYS_HAS_CPU_MIPS32_R2=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_USB_ARCH_HAS_XHCI=y +CONFIG_USB_SUPPORT=y +CONFIG_XZ_DEC=y +CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/amazon/files/arch/mips/amazon/Kconfig b/target/linux/amazon/files/arch/mips/amazon/Kconfig new file mode 100644 index 000000000..63055fc2a --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/Kconfig @@ -0,0 +1,67 @@ +# copyright 2007 john crispin + +menu "Amazon built-in" + +config AMAZON_ASC_UART + bool "Amazon asc uart" + select SERIAL_CORE + select SERIAL_CORE_CONSOLE + default y + +config AMAZON_PCI + bool "Amazon PCI support" + default y + select HW_HAS_PCI + select PCI + +config AMAZON_NET_SW + bool "Amazon network" + default y + +config AMAZON_WDT + bool "Amazon watchdog timer" + default y + +config AMAZON_MTD + bool "Amazon MTD map" + default y + +config ADM6996_SUPPORT + bool "Amazon ADM6996 Switch driver" + default y + +choice + prompt "Flash Size" + depends on AMAZON_MTD + +config MTD_AMAZON_FLASH_SIZE_2 + bool "2MB" + +config MTD_AMAZON_FLASH_SIZE_4 + bool "4MB" + +config MTD_AMAZON_FLASH_SIZE_8 + bool "8MB" + +config MTD_AMAZON_FLASH_SIZE_16 + bool "16MB" + +endchoice + +choice + prompt "Bus Width" + depends on AMAZON_MTD + +config MTD_AMAZON_BUS_WIDTH_8 + bool "8-bit" + +config MTD_AMAZON_BUS_WIDTH_16 + bool "16-bit" + +config MTD_AMAZON_BUS_WIDTH_32 + bool "32-bit" + +endchoice + + +endmenu diff --git a/target/linux/amazon/files/arch/mips/amazon/Makefile b/target/linux/amazon/files/arch/mips/amazon/Makefile new file mode 100644 index 000000000..47761a277 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/Makefile @@ -0,0 +1,9 @@ +# +# Copyright 2007 openwrt.org +# John Crispin +# +# Makefile for Infineon Amazon +# +obj-y := dma-core.o interrupt.o prom.o setup.o board.o +obj-$(CONFIG_PCI) += pci.o + diff --git a/target/linux/amazon/files/arch/mips/amazon/board.c b/target/linux/amazon/files/arch/mips/amazon/board.c new file mode 100644 index 000000000..330cec608 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/board.c @@ -0,0 +1,69 @@ +/* + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) 2009 Hauke Mehrtens + */ + + +#include +#include + +#define AMAZON_FLASH_START 0x13000000 +#define AMAZON_FLASH_MAX 0x1000000 + +static struct platform_device amazon_mii = { + .id = 0, + .name = "amazon_mii0", +// .dev = { +// .platform_data = amazon_ethaddr, +// } +}; + +static struct platform_device amazon_wdt = { + .id = 0, + .name = "amazon_wdt", +}; + +static struct platform_device amazon_asc = { + .id = 0, + .name = "amazon_asc", +}; + +static struct resource amazon_mtd_resource = { + .start = AMAZON_FLASH_START, + .end = AMAZON_FLASH_START + AMAZON_FLASH_MAX - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device amazon_mtd = { + .id = 0, + .name = "amazon_mtd", + .num_resources = 1, + .resource = &amazon_mtd_resource, +}; + + +struct platform_device *amazon_devs[] = { + &amazon_mii, &amazon_mtd, &amazon_wdt, &amazon_asc +}; + + +int __init amazon_init_devices(void) +{ + printk(KERN_INFO ""); + return platform_add_devices(amazon_devs, 4); +} + +arch_initcall(amazon_init_devices); diff --git a/target/linux/amazon/files/arch/mips/amazon/dma-core.c b/target/linux/amazon/files/arch/mips/amazon/dma-core.c new file mode 100644 index 000000000..8cb408520 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/dma-core.c @@ -0,0 +1,1462 @@ +/* + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +//----------------------------------------------------------------------- +/* + * Description: + * Driver for Infineon Amazon DMA + */ +//----------------------------------------------------------------------- +/* Author: Wu Qi Ming[Qi-Ming.Wu@infineon.com] + * Created: 7-April-2004 + */ +//----------------------------------------------------------------------- +/* History + * Last changed on: 4-May-2004 + * Last changed by: + * Reason: debug + */ +//----------------------------------------------------------------------- +/* Last changed on: 03-Dec-2004 + * Last changed by: peng.liu@infineon.com + * Reason: recover from TPE bug + */ + +//000004:fchang 2005/6/2 Modified by Linpeng as described below +//----------------------------------------------------------------------- +/* Last changed on: 28-Jan-2004 + * Last changed by: peng.liu@infineon.com + * Reason: + * - handle "out of memory" bug + */ +//000003:tc.chen 2005/06/16 fix memory leak when Tx buffer full (heaving traffic). +//507261:tc.chen 2005/07/26 re-organize code address map to improve performance. + +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) +#define MODVERSIONS +#endif + +#if defined(MODVERSIONS) && !defined(__GENKSYMS__) +#include +#endif + +#ifndef EXPORT_SYMTAB +#define EXPORT_SYMTAB /* need this one 'cause we export symbols */ +#endif + +#undef DMA_NO_POLLING + +/* no TX interrupt handling */ +#define NO_TX_INT +/* need for DMA workaround */ +#undef AMAZON_DMA_TPE_AAL5_RECOVERY + +#ifdef AMAZON_DMA_TPE_AAL5_RECOVERY +#define MAX_SYNC_FAILS 1000000 // 000004:fchang +unsigned int dma_sync_fails = 0; +unsigned int total_dma_tpe_reset = 0; +int (*tpe_reset) (void); +int (*tpe_start) (void); +int (*tpe_inject) (void); +#endif // AMAZON_DMA_TPE_AAL5_RECOVERY + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "dma-core.h" + +#define AMAZON_DMA_EMSG(fmt, args...) printk( KERN_ERR "%s: " fmt,__FUNCTION__, ## args) + +static irqreturn_t dma_interrupt(int irq, void *dev_id); +extern void mask_and_ack_amazon_irq(unsigned int irq_nr); + +/***************************************** global data *******************************************/ +u64 *g_desc_list; +dev_list *g_current_dev = NULL; +dev_list *g_head_dev = NULL; +dev_list *g_tail_dev = NULL; +channel_info g_log_chan[CHAN_TOTAL_NUM + 1]; +struct proc_dir_entry *g_amazon_dma_dir; +static u8 rx_chan_list_len = 0; +static u8 tx_chan_list_len = 0; +static int rx_chan_list[RX_CHAN_NUM + 1]; +static int tx_chan_list[TX_CHAN_NUM + 1]; +static u32 comb_isr_mask[CHAN_TOTAL_NUM]; + +static inline int is_rx_chan(int chan_no) +/*judge if this is an rx channel*/ +{ + int result = 0; + if (chan_no < RX_CHAN_NUM) + result = 1; + return result; +} + +/* Ugly, Channel ON register is badly mapped to channel no. */ +static u8 ch_on_mapping[CHAN_TOTAL_NUM] = + { 0, 1, 2, 3, 6, 7, 10, 4, 5, 8, 9, 11 }; + +/* Brief: check wether the chan_no is legal + * Parameter: chan_no: logical channel number + * Return: 0 if is not valid + * 1 if is valid + */ +static inline int is_valid_dma_ch(int chan_no) +{ + return ((chan_no >= 0) && (chan_no < CHAN_TOTAL_NUM)); +} + +/* Brief: check whether a channel is open through Channel ON register + * Parameter: chan_no: logical channel number + * Return: 1 channel is open + * 0 not yet + * EINVAL: invalid parameter + */ +static inline int is_channel_open(int chan_no) +{ + return (AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) & + (1 << ch_on_mapping[chan_no])); +} + +/* Brief: add a list entry + * Description: + * always add to the tail and no redundancy allowed. (i.e. entries are unique) + * 0 : entry deleted + * <0 : not deleted (due to not unique) + */ +static inline int _add_list_entry(int *list, int size_of_list, int entry) +{ + int i; + for (i = 0; i < size_of_list; i++) { + if (list[i] == entry) + break; + if (list[i] < 0) { + list[i] = entry; + return 0; + } + } + return -1; +} + +/* Brief: delete a list entry + * Description: + * find the entry and remove it. shift all entries behind it one step forward if necessary\ + * Return: + * 0 : entry deleted + * <0 : not deleted (due to not found?) + */ +static inline int _delete_list_entry(int *list, int size_of_list, + int entry) +{ + int i, j; + for (i = 0; i < size_of_list; i++) { + if (list[i] == entry) { + for (j = i; j < size_of_list; j++) { + list[j] = list[j + 1]; + if (list[j + 1] < 0) { + break; + } + } + return 0; + } + } + return -1; +} + +/* Brief: enable a channel through Channel ON register + * Parameter: chan_no: logical channel number + * Description: + * Please don't open a channel without a valid descriptor (hardware pitfall) + */ +static inline void open_channel(int chan_no) +{ + AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) |= (1 << ch_on_mapping[chan_no]); + if (is_rx_chan(chan_no)) { + if (_add_list_entry(rx_chan_list, RX_CHAN_NUM, chan_no) == 0) { + rx_chan_list_len++; + } else { + AMAZON_DMA_DMSG("cannot add chan %d to open list\n", chan_no); + } + } else { + if (_add_list_entry(tx_chan_list, TX_CHAN_NUM, chan_no) == 0) { + tx_chan_list_len++; + } else { + AMAZON_DMA_DMSG("cannot add chan %d to open list\n", chan_no); + } + } +} + +/* Brief: disable a channel through Channel ON register + * Parameter: chan_no: logical channel number + */ + +static inline void close_channel(int chan_no) +{ + AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) &= ~(1 << ch_on_mapping[chan_no]); + if (is_rx_chan(chan_no)) { + if (_delete_list_entry(rx_chan_list, RX_CHAN_NUM, chan_no) == 0) { + rx_chan_list_len--; + } else { + AMAZON_DMA_DMSG("cannot remove chan %d from open list \n", + chan_no); + } + } else { + if (_delete_list_entry(tx_chan_list, TX_CHAN_NUM, chan_no) == 0) { + tx_chan_list_len--; + } else { + AMAZON_DMA_DMSG("cannot remove chan %d from open list \n", + chan_no); + } + } +} + +/* Brief: clear RX interrupt + */ +inline void rx_chan_clear_isr(int chan_no) +{ +#ifdef DMA_NO_POLLING + AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR + chan_no * AMAZON_DMA_CH_STEP) = + (AMAZON_DMA_REG32 + (AMAZON_DMA_CH0_ISR + + chan_no * + AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT | DMA_ISR_EOP | DMA_ISR_CMDCPT + | DMA_ISR_DURR)); +#else + AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR + chan_no * AMAZON_DMA_CH_STEP) = + (AMAZON_DMA_REG32 + (AMAZON_DMA_CH0_ISR + + chan_no * + AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT | DMA_ISR_EOP | + DMA_ISR_CMDCPT)); +#endif +} + +#ifdef AMAZON_DMA_TPE_AAL5_RECOVERY +/* Brief: hacking function, this will reset all descriptors back to DMA + */ +static void dma_reset_all_descriptors(int chan_no) +{ + volatile struct rx_desc *rx_desc_p = NULL; + int i; + rx_desc_p = + (struct rx_desc *) g_desc_list + + g_log_chan[chan_no].offset_from_base; + for (i = 0; i < g_log_chan[chan_no].desc_len; i++) { + rx_desc_p->status.word &= + (~(DMA_DESC_SOP_SET | DMA_DESC_EOP_SET | DMA_DESC_CPT_SET)); + rx_desc_p->status.word |= + (DMA_DESC_OWN_DMA | g_log_chan[chan_no].packet_size); + rx_desc_p++; + } +} + +/* Brief: Reset DMA descriptors + */ +static void amazon_dma_reset_tpe_rx(int chan_no) +{ + struct tx_desc *tx_desc_p = NULL; + int j, i = 0; + + // wait until all TX channels stop transmitting + for (j = 9; j <= 10; j++) { + tx_desc_p = + (struct tx_desc *) g_desc_list + + g_log_chan[j].offset_from_base; + for (i = 0; i < g_log_chan[j].desc_len; i++) { + while ((tx_desc_p->status.field.OWN != CPU_OWN)) { + AMAZON_DMA_DMSG("DMA TX in progress\n"); // 000004:fchang + udelay(100); + } + tx_desc_p++; + } + } + + if (tpe_reset) { + total_dma_tpe_reset++; + AMAZON_DMA_DMSG + ("\n===============resetting TPE========================== \n"); + if ((*tpe_reset) ()) { + panic("cannot reset TPE engien\n"); // 000004:fchang + } + } else { + panic("no tpe_reset function\n"); // 000004:fchang + return; + } + dma_reset_all_descriptors(chan_no); + rx_chan_clear_isr(chan_no); + mb(); + + // send EoP + if (tpe_inject) { + if ((*tpe_inject) ()) { + panic("cannot inject a cell\n"); // 000004:fchang + } + } else { + AMAZON_DMA_EMSG("no tpe_inject function\n"); + return; + } + mb(); + while (1) { + if (AMAZON_DMA_REG32 + (AMAZON_DMA_CH0_ISR + + chan_no * AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT)) { + rx_chan_clear_isr(chan_no); + mb(); + dma_reset_all_descriptors(chan_no); + if (g_log_chan[chan_no].current_desc == + (g_log_chan[chan_no].desc_len - 1)) { + g_log_chan[chan_no].current_desc = 0; + } else { + g_log_chan[chan_no].current_desc++; + } + break; + } + mdelay(1); + } + mb(); +#if 0 + AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) &= ~(1 << ch_on_mapping[chan_no]); + while (AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) & + (1 << ch_on_mapping[chan_no])) { + printk("TPE channel still on\n"); + mdelay(1); + } + + // AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = (1<current_rx_chan = + chan_no - g_log_chan[chan_no].dma_dev->logic_rx_chan_base; + + // workaround for DMA pitfall: complete bit set happends before the + // other two bits (own,eop) are ready + if ((rx_desc_p->status.field.EoP != 1) + || (rx_desc_p->status.field.OWN != CPU_OWN) + || (rx_desc_p->status.field.data_length == + g_log_chan[chan_no].packet_size)) { +#ifdef AMAZON_DMA_TPE_AAL5_RECOVERY + if (chan_no == 4 || chan_no == 5) { + dma_sync_fails++; + if (dma_sync_fails > MAX_SYNC_FAILS) { + // detect bug + rx_desc_p0 = + (struct rx_desc *) g_desc_list + + g_log_chan[chan_no].offset_from_base; + rx_desc_p1 = + (struct rx_desc *) g_desc_list + + g_log_chan[chan_no].offset_from_base + 1; + if ((rx_desc_p0->status.field.OWN == CPU_OWN + && rx_desc_p0->status.field.EoP != 1) + && (rx_desc_p1->status.field.OWN == CPU_OWN + && rx_desc_p1->status.field.EoP != 1)) { + amazon_dma_reset_tpe_rx(chan_no); + dma_sync_fails = 0; + return; + } + dma_sync_fails = 0; + AMAZON_DMA_DMSG("too many times ch:%d\n", chan_no); // 000004:fchang + return; + } + udelay(10); // 000004:fchang + } +#endif // //AMAZON_DMA_TPE_AAL5_RECOVERY + return; + } + + /* inform the upper layer to receive the packet */ + g_log_chan[chan_no].intr_handler(g_log_chan[chan_no].dma_dev, RCV_INT); + /* check the next descriptor, if still contains the incoming packet, + then do not clear the interrupt status */ + rx_desc_p = + (struct rx_desc *) g_desc_list + + g_log_chan[chan_no].offset_from_base + + g_log_chan[chan_no].current_desc; + if (! + ((rx_desc_p->status.field.OWN == CPU_OWN) + && (rx_desc_p->status.field.C == 1))) { + rx_chan_clear_isr(chan_no); + } +} + + +/* Brief: TX channel interrupt handler + * Parameter: TX channel no + * Description: the interrupt handler for each TX channel + * 1. check all the descripters,if any of them had transmitted a packet, then free buffer + * because we cannot garantee the which one has already transmitted out, we have to go through all the descriptors here + * 2. clear the interrupt status bit + */ +inline void tx_chan_intr_handler(int chan_no) +{ + struct tx_desc *tx_desc_p = NULL; + int i = 0; + + tx_desc_p = + (struct tx_desc *) g_desc_list + + g_log_chan[chan_no].offset_from_base; + + for (i = 0; i < g_log_chan[chan_no].desc_len; i++) { + if ((tx_desc_p->status.field.OWN == CPU_OWN) + && (tx_desc_p->status.field.C == 1)) { + /* if already transmitted, then free the buffer */ + g_log_chan[chan_no]. + buffer_free((u8 *) __va(tx_desc_p->Data_Pointer), + g_log_chan[chan_no].opt[i]); + tx_desc_p->status.field.C = 0; + /* inform the upper layer about the completion of the + transmitted packet, the upper layer may want to free the + packet */ + g_log_chan[chan_no].intr_handler(g_log_chan[chan_no].dma_dev, + TRANSMIT_CPT_INT); + } + tx_desc_p++; + } + + /* after all these operations, clear the interrupt status bit */ + AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR + chan_no * AMAZON_DMA_CH_STEP) = + (AMAZON_DMA_REG32 + (AMAZON_DMA_CH0_ISR + + chan_no * + AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT | DMA_ISR_EOP | + DMA_ISR_CMDCPT)); +} + +/* Brief: DMA interrupt handler + */ +static irqreturn_t dma_interrupt(int irq, void *dev_id) +{ + int i = 0; + int chan_no; + u32 isr = 0; +#ifdef NO_TX_INT // 000004:fchang + static int cnt = 0; // 000004:fchang +#endif // 000004:fchang + while ((isr = + AMAZON_DMA_REG32(AMAZON_DMA_COMB_ISR)) & (COMB_ISR_RX_MASK | + COMB_ISR_TX_MASK)) { + if (isr & COMB_ISR_RX_MASK) { + // RX Channels: start WFQ algorithm + chan_no = CHAN_TOTAL_NUM; + for (i = 0; i < RX_CHAN_NUM; i++) { + if ((isr & (comb_isr_mask[i])) + && (g_log_chan[i].weight > 0)) { + if (g_log_chan[chan_no].weight < g_log_chan[i].weight) { + chan_no = i; + } + } + } + if (chan_no < CHAN_TOTAL_NUM) { + rx_chan_intr_handler(chan_no); + } else { + for (i = 0; i < RX_CHAN_NUM; i++) { + g_log_chan[i].weight = g_log_chan[i].default_weight; + } + } + } +#ifdef NO_TX_INT + cnt++; + if (cnt == 10) { + cnt = 0; + for (i = 0; i < tx_chan_list_len; i++) { + if (AMAZON_DMA_REG32 + (AMAZON_DMA_CH0_ISR + + tx_chan_list[i] * + AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT | DMA_ISR_EOP)) { + tx_chan_intr_handler(tx_chan_list[i]); + } + } + } +#else + if (isr & COMB_ISR_TX_MASK) { + // TX channels: RR + for (i = 0; i < tx_chan_list_len; i++) { + if (isr & (comb_isr_mask[tx_chan_list[i]])) { + tx_chan_intr_handler(tx_chan_list[i]); + } + } + } +#endif + } // while + return IRQ_HANDLED; +} + + +/* Brief: read a packet from DMA RX channel + * Parameter: + * Return: packet length + * Description: + * This is called back in a context of DMA interrupt + * 1. prepare new descriptor + * 2. read data + * 3. update WFQ weight + */ +//507261:tc.chen int dma_device_read(struct dma_device_info* dma_dev, u8** dataptr, void** opt) +int asmlinkage dma_device_read(struct dma_device_info *dma_dev, + u8 ** dataptr, void **opt) +{ + u8 *buf; + int len; + int chan_no = 0; + int byte_offset = 0; + + struct rx_desc *rx_desc_p; + void *p = NULL; + int current_desc; + + chan_no = dma_dev->logic_rx_chan_base + dma_dev->current_rx_chan; + current_desc = g_log_chan[chan_no].current_desc; + rx_desc_p = + (struct rx_desc *) (g_desc_list + + g_log_chan[chan_no].offset_from_base + + current_desc); + buf = (u8 *) __va(rx_desc_p->Data_Pointer); /* extract the virtual + address of the data + pointer */ + len = rx_desc_p->status.field.data_length; /* extract the data length */ +#ifndef CONFIG_MIPS_UNCACHED + dma_cache_inv((unsigned long) buf, len); +#endif // CONFIG_MIPS_UNCACHED + *(u32 *) dataptr = (u32) buf; + if (opt) { + *(int *) opt = (int) g_log_chan[chan_no].opt[current_desc]; /* read + out + the + opt + information */ + } + + buf = + (u8 *) g_log_chan[chan_no].buffer_alloc(g_log_chan[chan_no]. + packet_size, &byte_offset, + &p); + // should check null!!!! + if (buf == NULL || p == NULL) { + *(u32 *) dataptr = 0; + *(int *) opt = 0; + len = 0; + } else { + g_log_chan[chan_no].opt[current_desc] = p; + /* reduce the weight for WFQ algorithm */ + g_log_chan[chan_no].weight -= len; + rx_desc_p->Data_Pointer = (u32) CPHYSADDR((u32) buf); + } + if (current_desc == g_log_chan[chan_no].desc_len - 1) { + current_desc = 0; + } else { + current_desc++; + } + g_log_chan[chan_no].current_desc = current_desc; + + rx_desc_p->status.word = DMA_DESC_OWN_DMA + | (byte_offset << DMA_DESC_BYTEOFF_SHIFT) + | g_log_chan[chan_no].packet_size; + return len; +} + +/* Brief: write a packet through DMA RX channel to peripheral + * Parameter: + * Return: packet length + * Description: + * + */ +u64 dma_tx_drop = 0; +//507261:tc.chen int dma_device_write(struct dma_device_info* dma_dev, u8* dataptr, int len,void* opt) +int asmlinkage dma_device_write(struct dma_device_info *dma_dev, + u8 * dataptr, int len, void *opt) +{ + int chan_no = 0; + struct tx_desc *tx_desc_p; + + int byte_offset = 0; + int current_desc; + static int cnt = 0; // 000004:fchang + + unsigned long flag; + local_irq_save(flag); + + chan_no = dma_dev->logic_tx_chan_base + dma_dev->current_tx_chan; + current_desc = g_log_chan[chan_no].current_desc; + tx_desc_p = + (struct tx_desc *) (g_desc_list + + g_log_chan[chan_no].offset_from_base + + current_desc); + // 000003:tc.chen if(tx_desc_p->status.field.OWN==DMA_OWN){ + if (tx_desc_p->status.field.OWN == DMA_OWN || tx_desc_p->status.field.C == 1) { // 000003:tc.chen + AMAZON_DMA_DMSG("no TX desc for CPU, drop packet\n"); + dma_tx_drop++; + g_log_chan[chan_no].intr_handler(dma_dev, TX_BUF_FULL_INT); + local_irq_restore(flag); + return 0; + } + g_log_chan[chan_no].opt[current_desc] = opt; + + /* byte offset----to adjust the starting address of the data buffer, + should be multiple of the burst length. */ + byte_offset = + ((u32) CPHYSADDR((u32) dataptr)) % (g_log_chan[chan_no].burst_len * + 4); +#ifndef CONFIG_MIPS_UNCACHED + dma_cache_wback((unsigned long) dataptr, len); + wmb(); +#endif // CONFIG_MIPS_UNCACHED + + tx_desc_p->Data_Pointer = (u32) CPHYSADDR((u32) dataptr) - byte_offset; + wmb(); + tx_desc_p->status.word = DMA_DESC_OWN_DMA + | DMA_DESC_SOP_SET + | DMA_DESC_EOP_SET | (byte_offset << DMA_DESC_BYTEOFF_SHIFT) + | len; + wmb(); + if (is_channel_open(chan_no) == 0) { + // turn on if necessary + open_channel(chan_no); + } +#ifdef DMA_NO_POLLING + if ((AMAZON_DMA_REG32 + (AMAZON_DMA_CH0_ISR + + chan_no * AMAZON_DMA_CH_STEP) & (DMA_ISR_DURR | DMA_ISR_CPT)) == + (DMA_ISR_DURR)) { + // clear DURR if (CPT is AND set and DURR is set) + AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR + + chan_no * AMAZON_DMA_CH_STEP) = DMA_ISR_DURR; + } +#endif + + if (current_desc == (g_log_chan[chan_no].desc_len - 1)) { + current_desc = 0; + } else { + current_desc++; + } + + + g_log_chan[chan_no].current_desc = current_desc; + tx_desc_p = + (struct tx_desc *) (g_desc_list + + g_log_chan[chan_no].offset_from_base + + current_desc); + // 000003:tc.chen if(tx_desc_p->status.field.OWN==DMA_OWN){ + if (tx_desc_p->status.field.OWN == DMA_OWN || tx_desc_p->status.field.C == 1) { // 000003:tc.chen + g_log_chan[chan_no].intr_handler(dma_dev, TX_BUF_FULL_INT); + } +#ifdef NO_TX_INT +//000004:fchang Start + cnt++; + if (cnt == 5) { + cnt = 0; + tx_chan_intr_handler(chan_no); + } +//000004:fchang End +#endif + local_irq_restore(flag); // 000004:fchang + return len; +} + + + +int desc_list_proc_read(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + int i; + u32 *p = (u32 *) g_desc_list; + int len = 0; + len += sprintf(buf + len, "descriptor list:\n"); + for (i = 0; i < 120; i++) { + len += sprintf(buf + len, "%d\n", i); + len += sprintf(buf + len, "%08x\n", *(p + i * 2 + 1)); + len += sprintf(buf + len, "%08x\n", *(p + i * 2)); + + } + + return len; + +} + +int channel_weight_proc_read(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + + // int i=0; + int len = 0; + len += sprintf(buf + len, "Qos dma channel weight list\n"); + len += + sprintf(buf + len, + "channel_num default_weight current_weight device Tx/Rx\n"); + len += + sprintf(buf + len, + " 0 %08x %08x Switch Rx0\n", + g_log_chan[0].default_weight, g_log_chan[0].weight); + len += + sprintf(buf + len, + " 1 %08x %08x Switch Rx1\n", + g_log_chan[1].default_weight, g_log_chan[1].weight); + len += + sprintf(buf + len, + " 2 %08x %08x Switch Rx2\n", + g_log_chan[2].default_weight, g_log_chan[2].weight); + len += + sprintf(buf + len, + " 3 %08x %08x Switch Rx3\n", + g_log_chan[3].default_weight, g_log_chan[3].weight); + len += + sprintf(buf + len, + " 4 %08x %08x Switch Tx0\n", + g_log_chan[4].default_weight, g_log_chan[4].weight); + len += + sprintf(buf + len, + " 5 %08x %08x Switch Tx1\n", + g_log_chan[5].default_weight, g_log_chan[5].weight); + /* + len+=sprintf(buf+len," 6 %08x %08x TPE + Rx0\n",g_log_chan[6].default_weight, g_log_chan[6].weight); + len+=sprintf(buf+len," 7 %08x %08x TPE + Rx0\n",g_log_chan[7].default_weight, g_log_chan[7].weight); + len+=sprintf(buf+len," 8 %08x %08x TPE + Tx0\n",g_log_chan[8].default_weight, g_log_chan[8].weight); + len+=sprintf(buf+len," 9 %08x %08x TPE + Rx0\n",g_log_chan[9].default_weight, g_log_chan[9].weight); + len+=sprintf(buf+len," 10 %08x %08x DPLUS + Rx0\n",g_log_chan[10].default_weight, g_log_chan[10].weight); + len+=sprintf(buf+len," 11 %08x %08x DPLUS + Rx0\n",g_log_chan[11].default_weight, g_log_chan[11].weight); */ + return len; +} + +int dma_register_proc_read(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + dev_list *temp_dev; + int len = 0;; + + len += sprintf(buf + len, "amazon dma driver\n"); + len += sprintf(buf + len, "version 1.0\n"); + len += sprintf(buf + len, "devices registered:\n"); + for (temp_dev = g_head_dev; temp_dev; temp_dev = temp_dev->next) { + len += sprintf(buf + len, "%s ", temp_dev->dev->device_name); + } + len += sprintf(buf + len, "\n"); + len += sprintf(buf + len, "CH_ON=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH_ON)); + len += sprintf(buf + len, "CH_RST=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH_RST)); + len += sprintf(buf + len, "CH0_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR)); + len += sprintf(buf + len, "CH1_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH1_ISR)); + len += sprintf(buf + len, "CH2_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH2_ISR)); + len += sprintf(buf + len, "CH3_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH3_ISR)); + len += sprintf(buf + len, "CH4_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH4_ISR)); + len += sprintf(buf + len, "CH5_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH5_ISR)); + len += sprintf(buf + len, "CH6_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH6_ISR)); + len += sprintf(buf + len, "CH7_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH7_ISR)); + len += sprintf(buf + len, "CH8_ISR=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH8_ISR)); + len += + sprintf(buf + len, "CH9_ISR=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH9_ISR)); + len += + sprintf(buf + len, "CH10_ISR=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH10_ISR)); + len += + sprintf(buf + len, "CH11_ISR=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH11_ISR)); + len += + sprintf(buf + len, "LCH0_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK)); + len += + sprintf(buf + len, "LCH1_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH1_MSK)); + len += + sprintf(buf + len, "LCH2_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH2_MSK)); + len += + sprintf(buf + len, "LCH3_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH3_MSK)); + len += + sprintf(buf + len, "LCH4_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH4_MSK)); + len += + sprintf(buf + len, "LCH5_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH5_MSK)); + len += + sprintf(buf + len, "LCH6_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH6_MSK)); + len += + sprintf(buf + len, "LCH7_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH7_MSK)); + len += + sprintf(buf + len, "LCH8_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH8_MSK)); + len += + sprintf(buf + len, "LCH9_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH9_MSK)); + len += + sprintf(buf + len, "LCH10_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH10_MSK)); + len += + sprintf(buf + len, "LCH11_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH11_MSK)); + len += + sprintf(buf + len, "Desc_BA=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_Desc_BA)); + len += + sprintf(buf + len, "LCH0_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH0_DES_LEN)); + len += + sprintf(buf + len, "LCH1_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH1_DES_LEN)); + len += + sprintf(buf + len, "LCH2_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH2_DES_LEN)); + len += + sprintf(buf + len, "LCH3_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH3_DES_LEN)); + len += + sprintf(buf + len, "LCH4_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH4_DES_LEN)); + len += + sprintf(buf + len, "LCH5_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH5_DES_LEN)); + len += + sprintf(buf + len, "LCH6_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH6_DES_LEN)); + len += + sprintf(buf + len, "LCH7_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH7_DES_LEN)); + len += + sprintf(buf + len, "LCH8_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH8_DES_LEN)); + len += + sprintf(buf + len, "LCH9_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH9_DES_LEN)); + len += + sprintf(buf + len, "LCH10_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH10_DES_LEN)); + len += + sprintf(buf + len, "LCH11_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH11_DES_LEN)); + len += + sprintf(buf + len, "LCH1_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH1_DES_OFST)); + len += + sprintf(buf + len, "LCH2_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH2_DES_OFST)); + len += + sprintf(buf + len, "LCH3_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH3_DES_OFST)); + len += + sprintf(buf + len, "LCH4_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH4_DES_OFST)); + len += + sprintf(buf + len, "LCH5_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH5_DES_OFST)); + len += + sprintf(buf + len, "LCH6_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH6_DES_OFST)); + len += + sprintf(buf + len, "LCH7_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH7_DES_OFST)); + len += + sprintf(buf + len, "LCH8_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH8_DES_OFST)); + len += + sprintf(buf + len, "LCH9_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH9_DES_OFST)); + len += + sprintf(buf + len, "LCH10_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH10_DES_OFST)); + len += + sprintf(buf + len, "LCH11_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH11_DES_OFST)); + len += + sprintf(buf + len, "AMAZON_DMA_SW_BL=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_SW_BL)); + len += + sprintf(buf + len, "AMAZON_DMA_TPE_BL=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_TPE_BL)); + len += + sprintf(buf + len, "DPlus2FPI_BL=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_DPlus2FPI_BL)); + len += + sprintf(buf + len, "GRX_BUF_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_GRX_BUF_LEN)); + len += + sprintf(buf + len, "DMA_ECON_REG=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_DMA_ECON_REG)); + len += + sprintf(buf + len, "POLLING_REG=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_POLLING_REG)); + len += + sprintf(buf + len, "CH_WGT=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH_WGT)); + len += + sprintf(buf + len, "TX_WGT=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_TX_WGT)); + len += + sprintf(buf + len, "DPlus2FPI_CLASS=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_DPLus2FPI_CLASS)); + len += + sprintf(buf + len, "COMB_ISR=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_COMB_ISR)); +#ifdef AMAZON_DMA_TPE_AAL5_RECOVERY + len += sprintf(buf + len, "TPE fails:%u\n", total_dma_tpe_reset); // 000004:fchang +#endif + return len; +} + +/* Brief: initialize DMA registers + * Description: + */ +static void dma_chip_init(void) +{ + int i; + for (i = 0; i < CHAN_TOTAL_NUM; i++) { + AMAZON_DMA_REG32(AMAZON_DMA_CH1_DES_OFST + + i * AMAZON_DMA_CH_STEP) = DEFAULT_OFFSET; + } +#ifdef DMA_NO_POLLING + AMAZON_DMA_REG32(AMAZON_DMA_POLLING_REG) = 0; +#else + // enable poll mode and set polling counter + AMAZON_DMA_REG32(AMAZON_DMA_POLLING_REG) = DMA_POLLING_CNT | DMA_POLLING_ENABLE; +#endif + // to enable DMA drop + AMAZON_DMA_REG32(AMAZON_DMA_GRX_BUF_LEN) = 0x10000; +} + +int insert_dev_list(dev_list * dev) +{ + dev_list *temp_dev; + if (g_head_dev == NULL) { + g_head_dev = dev; + g_tail_dev = dev; + dev->prev = NULL; + dev->next = NULL; + } else { + for (temp_dev = g_head_dev; temp_dev; temp_dev = temp_dev->next) { + if (temp_dev->weight < dev->weight) { + if (temp_dev->prev) + temp_dev->prev->next = dev; + + dev->prev = temp_dev->prev; + dev->next = temp_dev; + temp_dev->prev = dev; + if (temp_dev == g_head_dev) + g_head_dev = dev; + break; + } + } + + if (!temp_dev) { + g_tail_dev->next = dev; + dev->prev = g_tail_dev; + dev->next = NULL; + g_tail_dev = dev; + } + + } + + return 1; +} + +u8 *common_buffer_alloc(int len, int *byte_offset, void **opt) +{ + u8 *buffer = (u8 *) kmalloc(len * sizeof(u8), GFP_KERNEL); + *byte_offset = 0; + return buffer; + +} + +int common_buffer_free(u8 * dataptr, void *opt) +{ + if (dataptr) + kfree(dataptr); + return 0; +} + + +int register_dev(struct dma_device_info *dma_dev) +{ + int i, j, temp; + int burst_reg = 0; + u8 *buffer; + void *p = NULL; + int byte_offset = 0; + + struct rx_desc *rx_desc_p; + struct tx_desc *tx_desc_p; + if (strcmp(dma_dev->device_name, "switch1") == 0) { + AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = SWITCH1_RST_MASK; // resest + // channel + // 1st + AMAZON_DMA_REG32(AMAZON_DMA_DMA_ECON_REG) |= 0x3; // endian + // conversion + // for Switch + burst_reg = AMAZON_DMA_SW_BL; + dma_dev->logic_rx_chan_base = switch_rx_chan_base; + dma_dev->logic_tx_chan_base = switch_tx_chan_base; + } + + else if (strcmp(dma_dev->device_name, "switch2") == 0) { + AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = SWITCH2_RST_MASK; // resest + // channel + // 1st + AMAZON_DMA_REG32(AMAZON_DMA_DMA_ECON_REG) |= 0x3; // endian + // conversion + // for Switch + burst_reg = AMAZON_DMA_SW_BL; + dma_dev->logic_rx_chan_base = switch2_rx_chan_base; + dma_dev->logic_tx_chan_base = switch2_tx_chan_base; + + } else if (strcmp(dma_dev->device_name, "TPE") == 0) { + AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = TPE_RST_MASK; // resest + // channel 1st + // + burst_reg = AMAZON_DMA_TPE_BL; + dma_dev->logic_rx_chan_base = TPE_rx_chan_base; + dma_dev->logic_tx_chan_base = TPE_tx_chan_base; + } + + else if (strcmp(dma_dev->device_name, "DPlus") == 0) { + AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = DPlus2FPI_RST_MASK; // resest + // channel + // 1st + dma_dev->logic_rx_chan_base = DPLus2FPI_rx_chan_base; + dma_dev->logic_tx_chan_base = DPLus2FPI_tx_chan_base; + + } + + i = 0; + for (temp = dma_dev->tx_burst_len; temp > 2; temp /= 2) { + i += 1; + } + + + AMAZON_DMA_REG32(burst_reg) = i << 1; + i = 0; + for (temp = dma_dev->rx_burst_len; temp > 2; temp /= 2) { + i += 1; + } + AMAZON_DMA_REG32(burst_reg) += i; + + for (i = 0; i < dma_dev->num_rx_chan; i++) { + + temp = dma_dev->logic_rx_chan_base + i; + g_log_chan[temp].dma_dev = dma_dev; + g_log_chan[temp].weight = dma_dev->rx_chan[i].weight; + g_log_chan[temp].default_weight = dma_dev->rx_chan[i].weight; + g_log_chan[temp].current_desc = 0; + g_log_chan[temp].desc_ofst = DEFAULT_OFFSET; + g_log_chan[temp].desc_len = dma_dev->rx_chan[i].desc_num; + g_log_chan[temp].offset_from_base = temp * DEFAULT_OFFSET; + g_log_chan[temp].packet_size = dma_dev->rx_chan[i].packet_size; + + AMAZON_DMA_REG32(AMAZON_DMA_CH0_DES_LEN + temp * AMAZON_DMA_CH_STEP) = dma_dev->rx_chan[i].desc_num; + // enable interrupt mask + if (temp == 4 || temp == 5) { + AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK + temp * AMAZON_DMA_CH_STEP) = 0x32; + } else { + AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK + temp * AMAZON_DMA_CH_STEP) = 0x36; + } + strcpy(g_log_chan[temp].device_name, dma_dev->device_name); + g_log_chan[temp].burst_len = dma_dev->rx_burst_len; + g_log_chan[temp].control = dma_dev->rx_chan[i].control; + + + /* specify the buffer allocation and free method */ + if (dma_dev->buffer_alloc) + g_log_chan[temp].buffer_alloc = dma_dev->buffer_alloc; + else + g_log_chan[temp].buffer_alloc = common_buffer_alloc; + + if (dma_dev->buffer_free) + g_log_chan[temp].buffer_free = dma_dev->buffer_free; + else + g_log_chan[temp].buffer_free = common_buffer_free; + + if (dma_dev->intr_handler) + g_log_chan[temp].intr_handler = dma_dev->intr_handler; + else + g_log_chan[temp].intr_handler = NULL; + + for (j = 0; j < g_log_chan[temp].desc_len; j++) { + rx_desc_p = (struct rx_desc *) (g_desc_list + g_log_chan[temp].offset_from_base + j); + rx_desc_p->status.word = 0; + rx_desc_p->status.field.data_length = g_log_chan[temp].packet_size; + buffer = (u8 *) g_log_chan[temp].buffer_alloc(g_log_chan[temp].packet_size, &byte_offset, &p); + rx_desc_p->Data_Pointer = (u32) CPHYSADDR((u32) buffer); + rx_desc_p->status.field.byte_offset = byte_offset; + /* fix me, should check if the addresss comply with the burst + lenght requirment */ + g_log_chan[temp].opt[j] = p; + rx_desc_p->status.field.OWN = DMA_OWN; + + } + /* open or close the channel */ + if (g_log_chan[temp].control) + open_channel(temp); + else + close_channel(temp); + } + + for (i = 0; i < dma_dev->num_tx_chan; i++) { + temp = dma_dev->logic_tx_chan_base + i; + g_log_chan[temp].dma_dev = dma_dev; + g_log_chan[temp].weight = dma_dev->tx_chan[i].weight; + g_log_chan[temp].default_weight = dma_dev->tx_chan[i].weight; + g_log_chan[temp].current_desc = 0; + g_log_chan[temp].desc_ofst = DEFAULT_OFFSET; + g_log_chan[temp].desc_len = dma_dev->tx_chan[i].desc_num; + g_log_chan[temp].offset_from_base = temp * DEFAULT_OFFSET; + g_log_chan[temp].packet_size = dma_dev->tx_chan[i].packet_size; + + AMAZON_DMA_REG32(AMAZON_DMA_CH0_DES_LEN + temp * AMAZON_DMA_CH_STEP) = dma_dev->tx_chan[i].desc_num; + // enable interrupt mask +#ifdef NO_TX_INT + AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK + temp * AMAZON_DMA_CH_STEP) = 0x3e; +#else + AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK + temp * AMAZON_DMA_CH_STEP) = 0x36; +#endif + + strcpy(g_log_chan[temp].device_name, dma_dev->device_name); + g_log_chan[temp].burst_len = dma_dev->tx_burst_len; + g_log_chan[temp].control = dma_dev->tx_chan[i].control; + + if (dma_dev->buffer_alloc) + g_log_chan[temp].buffer_alloc = dma_dev->buffer_alloc; + else + g_log_chan[temp].buffer_alloc = common_buffer_alloc; + + if (dma_dev->buffer_free) + g_log_chan[temp].buffer_free = dma_dev->buffer_free; + else + g_log_chan[temp].buffer_free = common_buffer_free; + + if (dma_dev->intr_handler) + g_log_chan[temp].intr_handler = dma_dev->intr_handler; + else + g_log_chan[temp].intr_handler = NULL; + + for (j = 0; j < g_log_chan[temp].desc_len; j++) { + + tx_desc_p = + (struct tx_desc *) (g_desc_list + + g_log_chan[temp].offset_from_base + j); + tx_desc_p->status.word = 0; + tx_desc_p->status.field.data_length = + g_log_chan[temp].packet_size; + tx_desc_p->status.field.OWN = CPU_OWN; + + } + /* workaround DMA pitfall, we never turn on channel if we don't + have proper descriptors */ + if (!g_log_chan[temp].control) { + close_channel(temp); + } + + } + + return 0; +} + +int dma_device_register(struct dma_device_info *dma_dev) +{ + dev_list *temp_dev; + temp_dev = (dev_list *) kmalloc(sizeof(dev_list), GFP_KERNEL); + temp_dev->dev = dma_dev; + temp_dev->weight = dma_dev->weight; + insert_dev_list(temp_dev); + /* check whether this is a known device */ + if ((strcmp(dma_dev->device_name, "switch1") == 0) + || (strcmp(dma_dev->device_name, "TPE") == 0) + || (strcmp(dma_dev->device_name, "switch2") == 0) + || (strcmp(dma_dev->device_name, "DPlus") == 0)) { + register_dev(dma_dev); + } + + return 0; +} + + +int unregister_dev(struct dma_device_info *dma_dev) +{ + int i, j, temp; + u8 *buffer; + struct rx_desc *rx_desc_p; + + for (i = 0; i < dma_dev->num_rx_chan; i++) { + temp = dma_dev->logic_rx_chan_base + i; + close_channel(temp); + for (j = 0; j < g_log_chan[temp].desc_len; j++) { + rx_desc_p = + (struct rx_desc *) (g_desc_list + + g_log_chan[temp].offset_from_base + j); + buffer = (u8 *) __va(rx_desc_p->Data_Pointer); + g_log_chan[temp].buffer_free(buffer, g_log_chan[temp].opt[j]); + } + } + for (i = 0; i < dma_dev->num_tx_chan; i++) { + temp = dma_dev->logic_tx_chan_base + i; + close_channel(temp); + } + return 0; +} + +int dma_device_unregister(struct dma_device_info *dev) +{ + dev_list *temp_dev; + for (temp_dev = g_head_dev; temp_dev; temp_dev = temp_dev->next) { + if (strcmp(dev->device_name, temp_dev->dev->device_name) == 0) { + if ((strcmp(dev->device_name, "switch1") == 0) + || (strcmp(dev->device_name, "TPE") == 0) + || (strcmp(dev->device_name, "switch2") == 0) + || (strcmp(dev->device_name, "DPlus") == 0)) + unregister_dev(dev); + if (temp_dev == g_head_dev) { + g_head_dev = temp_dev->next; + kfree(temp_dev); + } else { + if (temp_dev == g_tail_dev) + g_tail_dev = temp_dev->prev; + if (temp_dev->prev) + temp_dev->prev->next = temp_dev->next; + if (temp_dev->next) + temp_dev->next->prev = temp_dev->prev; + kfree(temp_dev); + } + break; + } + + } + return 0; +} + +void dma_device_update_rx(struct dma_device_info *dma_dev) +{ + int i, temp; + for (i = 0; i < dma_dev->num_rx_chan; i++) { + temp = dma_dev->logic_rx_chan_base + i; + g_log_chan[temp].control = dma_dev->rx_chan[i].control; + + if (g_log_chan[temp].control) + open_channel(temp); + else + close_channel(temp); + } + +} + +void dma_device_update_tx(struct dma_device_info *dma_dev) +{ + int i, temp; + for (i = 0; i < dma_dev->num_tx_chan; i++) { + temp = dma_dev->logic_tx_chan_base + i; + g_log_chan[temp].control = dma_dev->tx_chan[i].control; + if (g_log_chan[temp].control) { + /* we turn on channel when send out the very first packet */ + // open_channel(temp); + } else + close_channel(temp); + } +} + +int dma_device_update(struct dma_device_info *dma_dev) +{ + dma_device_update_rx(dma_dev); + dma_device_update_tx(dma_dev); + return 0; +} + +static int dma_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int dma_release(struct inode *inode, struct file *file) +{ + /* release the resources */ + return 0; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) +static long dma_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +#else +static int dma_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +#endif +{ + int value = 0; + int chan_no = 0; + + switch (cmd) { + case 0: /* get register value */ + break; + case 1: /* return channel weight */ + chan_no = *((int *) arg); + *((int *) arg + 1) = g_log_chan[chan_no].default_weight; + break; + case 2: /* set channel weight */ + chan_no = *((int *) arg); + value = *((int *) arg + 1); + printk("new weight=%08x\n", value); + g_log_chan[chan_no].default_weight = value; + break; + default: + break; + } + return 0; +} + + +static struct file_operations dma_fops = { + owner:THIS_MODULE, + open:dma_open, + release:dma_release, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) + unlocked_ioctl:dma_ioctl, +#else + ioctl:dma_ioctl, +#endif +}; + +static int dma_init(void) +{ + int result = 0; + int i; + printk("initialising dma core\n"); + result = register_chrdev(DMA_MAJOR, "dma-core", &dma_fops); + if (result) { + AMAZON_DMA_EMSG("cannot register device dma-core!\n"); + return result; + } + result = request_irq(AMAZON_DMA_INT, dma_interrupt, IRQF_DISABLED, "dma-core", (void *) &dma_interrupt); + if (result) { + AMAZON_DMA_EMSG("error, cannot get dma_irq!\n"); + free_irq(AMAZON_DMA_INT, (void *) &dma_interrupt); + return -EFAULT; + } + + g_desc_list = (u64 *) KSEG1ADDR(__get_free_page(GFP_DMA)); + + if (g_desc_list == NULL) { + AMAZON_DMA_EMSG("no memory for desriptor\n"); + return -ENOMEM; + } + memset(g_desc_list, 0, PAGE_SIZE); + AMAZON_DMA_REG32(AMAZON_DMA_Desc_BA) = (u32) CPHYSADDR((u32) g_desc_list); + g_amazon_dma_dir = proc_mkdir("amazon_dma", NULL); + create_proc_read_entry("dma_register", 0, g_amazon_dma_dir, dma_register_proc_read, NULL); + create_proc_read_entry("g_desc_list", 0, g_amazon_dma_dir, desc_list_proc_read, NULL); + create_proc_read_entry("channel_weight", 0, g_amazon_dma_dir, channel_weight_proc_read, NULL); + + dma_chip_init(); + for (i = 0; i < (RX_CHAN_NUM + 1); i++) { + rx_chan_list[i] = -1; + } + for (i = 0; i < (TX_CHAN_NUM + 1); i++) { + tx_chan_list[i] = -1; + } + + for (i = 0; i < CHAN_TOTAL_NUM; i++) { + comb_isr_mask[i] = 0x80000000 >> (i); + } + + g_log_chan[CHAN_TOTAL_NUM].weight = 0; + printk("initialising dma core ... done\n"); + + return 0; +} + +arch_initcall(dma_init); + + +void dma_cleanup(void) +{ + dev_list *temp_dev; + + unregister_chrdev(DMA_MAJOR, "dma-core"); + for (temp_dev = g_head_dev; temp_dev; temp_dev = temp_dev->next) { + kfree(temp_dev); + } + free_page(KSEG0ADDR((unsigned long) g_desc_list)); + remove_proc_entry("channel_weight", g_amazon_dma_dir); + remove_proc_entry("dma_list", g_amazon_dma_dir); + remove_proc_entry("dma_register", g_amazon_dma_dir); + remove_proc_entry("amazon_dma", NULL); + /* release the resources */ + free_irq(AMAZON_DMA_INT, (void *) &dma_interrupt); +} + +EXPORT_SYMBOL(dma_device_register); +EXPORT_SYMBOL(dma_device_unregister); +EXPORT_SYMBOL(dma_device_read); +EXPORT_SYMBOL(dma_device_write); +EXPORT_SYMBOL(dma_device_update); +EXPORT_SYMBOL(dma_device_update_rx); + +MODULE_LICENSE("GPL"); diff --git a/target/linux/amazon/files/arch/mips/amazon/dma-core.h b/target/linux/amazon/files/arch/mips/amazon/dma-core.h new file mode 100644 index 000000000..cb3d456c9 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/dma-core.h @@ -0,0 +1,69 @@ +#ifndef DMA_CORE_H +#define DMA_CORE_H + +#define AMAZON_DMA_REG32(reg_num) *((volatile u32*)(reg_num)) +#define AMAZON_DMA_CH_STEP 4 + +#define COMB_ISR_RX_MASK 0xfe000000 +#define COMB_ISR_TX_MASK 0x01f00000 + + +#define DMA_OWN 1 +#define CPU_OWN 0 +#define DMA_MAJOR 250 + +//Descriptors +#define DMA_DESC_OWN_CPU 0x0 +#define DMA_DESC_OWN_DMA 0x80000000 +#define DMA_DESC_CPT_SET 0x40000000 +#define DMA_DESC_SOP_SET 0x20000000 +#define DMA_DESC_EOP_SET 0x10000000 + +#define switch_rx_chan_base 0 +#define switch_tx_chan_base 7 +#define switch2_rx_chan_base 2 +#define switch2_tx_chan_base 8 +#define TPE_rx_chan_base 4 +#define TPE_tx_chan_base 9 +#define DPLus2FPI_rx_chan_base 6 +#define DPLus2FPI_tx_chan_base 11 + +#define RX_CHAN_NUM 7 +#define TX_CHAN_NUM 5 +#define CHAN_TOTAL_NUM (RX_CHAN_NUM+TX_CHAN_NUM) +#define DEFAULT_OFFSET 20 +#define DESCRIPTOR_SIZE 8 + +typedef struct dev_list{ + struct dma_device_info* dev; + int weight; + struct dev_list* prev; + struct dev_list* next; +}dev_list; + +typedef struct channel_info{ + char device_name[16]; + int occupied; + enum attr_t attr; + int current_desc; + int weight; + int default_weight; + int desc_num; + int burst_len; + int desc_len; + int desc_ofst; + int packet_size; + int offset_from_base; + int control; + void* opt[DEFAULT_OFFSET]; + u8* (*buffer_alloc)(int len,int* offset, void** opt); + int (*buffer_free)(u8* dataptr,void* opt); + int (*intr_handler)(struct dma_device_info* info,int status); + + struct dma_device_info* dma_dev; +}channel_info; + + + +#endif + diff --git a/target/linux/amazon/files/arch/mips/amazon/interrupt.c b/target/linux/amazon/files/arch/mips/amazon/interrupt.c new file mode 100644 index 000000000..05ff1ee75 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/interrupt.c @@ -0,0 +1,187 @@ +/* + * Gary Jennejohn (C) 2003 + * Copyright (C) 2007 Felix Fietkau + * Copyright (C) 2007 John Crispin + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Routines for generic manipulation of the interrupts found on the + * AMAZON boards. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static void amazon_disable_irq(struct irq_data *d) +{ + int i; + u32 amazon_ier = AMAZON_ICU_IM0_IER; + unsigned int irq_nr = d->irq; + + if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0) + amazon_writel(amazon_readl(amazon_ier) & (~(AMAZON_DMA_H_MASK)), amazon_ier); + else { + irq_nr -= INT_NUM_IRQ0; + for (i = 0; i <= 4; i++) + { + if (irq_nr <= 31) + amazon_writel(amazon_readl(amazon_ier) & ~(1 << irq_nr ), amazon_ier); + amazon_ier += 0x10; + irq_nr -= 32; + } + } +} + +static void amazon_mask_and_ack_irq(struct irq_data *d) +{ + int i; + u32 amazon_ier = AMAZON_ICU_IM0_IER; + u32 amazon_isr = AMAZON_ICU_IM0_ISR; + unsigned int irq_nr = d->irq; + + if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0){ + amazon_writel(amazon_readl(amazon_ier) & (~(AMAZON_DMA_H_MASK)), amazon_ier); + amazon_writel(AMAZON_DMA_H_MASK, amazon_isr); + } else { + irq_nr -= INT_NUM_IRQ0; + for (i = 0; i <= 4; i++) + { + if (irq_nr <= 31){ + amazon_writel(amazon_readl(amazon_ier) & ~(1 << irq_nr ), amazon_ier); + amazon_writel((1 << irq_nr ), amazon_isr); + } + amazon_ier += 0x10; + amazon_isr += 0x10; + irq_nr -= 32; + } + } +} + +static void amazon_enable_irq(struct irq_data *d) +{ + int i; + u32 amazon_ier = AMAZON_ICU_IM0_IER; + unsigned int irq_nr = d->irq; + + if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0) + amazon_writel(amazon_readl(amazon_ier) | AMAZON_DMA_H_MASK, amazon_ier); + else { + irq_nr -= INT_NUM_IRQ0; + for (i = 0; i <= 4; i++) + { + if (irq_nr <= 31) + amazon_writel(amazon_readl(amazon_ier) | (1 << irq_nr ), amazon_ier); + amazon_ier += 0x10; + irq_nr -= 32; + } + } +} + +static unsigned int amazon_startup_irq(struct irq_data *d) +{ + amazon_enable_irq(d); + return 0; +} + +static struct irq_chip amazon_irq_type = { + .name = "AMAZON", + .irq_startup = amazon_startup_irq, + .irq_enable = amazon_enable_irq, + .irq_disable = amazon_disable_irq, + .irq_unmask = amazon_enable_irq, + .irq_ack = amazon_mask_and_ack_irq, + .irq_mask = amazon_disable_irq, + .irq_mask_ack = amazon_mask_and_ack_irq, +}; + +/* Cascaded interrupts from IM0-4 */ +static inline void amazon_hw_irqdispatch(u8 line) +{ + u32 irq; + + irq = (amazon_readl(AMAZON_ICU_IM_VEC) >> (line * 5)) & AMAZON_ICU_IM0_VEC_MASK; + if (line == 0 && irq <= 11 && irq >= 0) { + //DMA fixed to IM0_IRL0 + irq = 0; + } + do_IRQ(irq + INT_NUM_IRQ0 + (line * 32)); +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; + if (pending & CAUSEF_IP7){ + do_IRQ(MIPS_CPU_TIMER_IRQ); + goto out; + } else { + unsigned int i; + for (i = 0; i <= 4; i++) + { + if(pending & (CAUSEF_IP2 << i)){ + amazon_hw_irqdispatch(i); + goto out; + } + } + } + printk("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status()); +out: + return; +} + +static struct irqaction cascade = { + .handler = no_action, + .flags = IRQF_DISABLED, + .name = "cascade", +}; + +void __init arch_init_irq(void) +{ + int i; + + /* mask all interrupt sources */ + for(i = 0; i <= 4; i++){ + amazon_writel(0, AMAZON_ICU_IM0_IER + (i * 0x10)); + } + + mips_cpu_irq_init(); + + /* set up irq cascade */ + for (i = 2; i <= 6; i++) { + setup_irq(i, &cascade); + } + + for (i = INT_NUM_IRQ0; i <= INT_NUM_IM4_IRL31; i++) + irq_set_chip_and_handler(i, &amazon_irq_type, + handle_level_irq); + + set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5); +} + +void __cpuinit arch_fixup_c0_irqs(void) +{ + /* FIXME: check for CPUID and only do fix for specific chips/versions */ + cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ; + cp0_perfcount_irq = CP0_LEGACY_PERFCNT_IRQ; +} diff --git a/target/linux/amazon/files/arch/mips/amazon/pci.c b/target/linux/amazon/files/arch/mips/amazon/pci.c new file mode 100644 index 000000000..1b2afb9d4 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/pci.c @@ -0,0 +1,279 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 2007 Felix Fietkau + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +/* FIXME: convert nasty volatile register derefs to readl/writel calls */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AMAZON_PCI_REG32( addr ) (*(volatile u32 *)(addr)) +#ifndef AMAZON_PCI_MEM_BASE +#define AMAZON_PCI_MEM_BASE 0xb2000000 +#endif +#define AMAZON_PCI_MEM_SIZE 0x00400000 +#define AMAZON_PCI_IO_BASE 0xb2400000 +#define AMAZON_PCI_IO_SIZE 0x00200000 + +#define AMAZON_PCI_CFG_BUSNUM_SHF 16 +#define AMAZON_PCI_CFG_DEVNUM_SHF 11 +#define AMAZON_PCI_CFG_FUNNUM_SHF 8 + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +static struct resource pci_io_resource = { + .name = "io pci IO space", +#if 1 + .start = AMAZON_PCI_IO_BASE, + .end = AMAZON_PCI_IO_BASE + AMAZON_PCI_IO_SIZE - 1, +#else + .start = 0, + .end = 0x00002000 - 1, +#endif + .flags = IORESOURCE_IO +}; + +static struct resource pci_mem_resource = { + .name = "ext pci memory space", + .start = AMAZON_PCI_MEM_BASE, + .end = AMAZON_PCI_MEM_BASE + AMAZON_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM +}; + +static int amazon_pci_config_access(unsigned char access_type, + struct pci_bus *bus, unsigned int devfn, unsigned int where, u32 *data) +{ + unsigned long flags; + u32 pci_addr; + u32 val; + int ret; + + /* Amazon support slot from 0 to 15 */ + /* devfn 0 & 0x20 is itself */ + if ((bus->number != 0) || (devfn > 0x7f) || (devfn == 0) || (devfn == 0x20)) + return 1; + + local_irq_save(flags); + + pci_addr = AMAZON_PCI_CFG_BASE | + bus->number << AMAZON_PCI_CFG_BUSNUM_SHF | + devfn << AMAZON_PCI_CFG_FUNNUM_SHF | + (where & ~0x3); + + if (access_type == PCI_ACCESS_WRITE) + { +#ifdef CONFIG_SWAP_IO_SPACE + val = swab32(*data); +#endif + ret = put_dbe(val, (u32 *)pci_addr); + } else { + ret = get_dbe(val, (u32 *)pci_addr); +#ifdef CONFIG_SWAP_IO_SPACE + *data = swab32(val); +#else + *data = val; +#endif + } + + amazon_writel(amazon_readl(PCI_MODE) & (~(1<> ((where & 3) << 3)) & 0xff; + else if (size == 2) + *val = (data >> ((where & 3) << 3)) & 0xffff; + else + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + + +static int amazon_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) +{ + u32 data = 0; + + if (size == 4) + { + data = val; + } else { + if (amazon_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (size == 1) + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + else if (size == 2) + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + } + + if (amazon_pci_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops amazon_pci_ops = { + amazon_pci_read, + amazon_pci_write +}; + +static struct pci_controller amazon_pci_controller = { + .pci_ops = &amazon_pci_ops, + .mem_resource = &pci_mem_resource, + .mem_offset = 0x00000000UL, + .io_resource = &pci_io_resource, + .io_offset = 0x00000000UL, +}; + +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + switch (slot) { + case 13: + /* IDSEL = AD29 --> USB Host Controller */ + return INT_NUM_IM2_IRL15; + case 14: + /* IDSEL = AD30 --> mini PCI connector */ + return INT_NUM_IM2_IRL14; + default: + printk("Warning: no IRQ found for PCI device in slot %d, pin %d\n", slot, pin); + return 0; + } +} + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + switch(dev->irq) { + case INT_NUM_IM2_IRL15: + /* + * IDSEL = AD29 --> USB Host Controller + * PCI_INTA/B/C--GPIO Port0.2--EXIN3 + * IN/ALT0:1 ALT1:0 + * PULL UP + */ + (*AMAZON_GPIO_P0_DIR) = (*AMAZON_GPIO_P0_DIR) & 0xfffffffb; + (*AMAZON_GPIO_P0_ALTSEL0) = (*AMAZON_GPIO_P0_ALTSEL0)| 4; + (*AMAZON_GPIO_P0_ALTSEL1) = (*AMAZON_GPIO_P0_ALTSEL1)& 0xfffffffb; + (*AMAZON_GPIO_P0_PUDSEL) = (*AMAZON_GPIO_P0_PUDSEL) | 4; + (*AMAZON_GPIO_P0_PUDEN) = (*AMAZON_GPIO_P0_PUDEN) | 4; + //External Interrupt Node + (*AMAZON_ICU_EXTINTCR) = (*AMAZON_ICU_EXTINTCR)|0x6000; /* Low Level triggered */ + (*AMAZON_ICU_IRNEN) = (*AMAZON_ICU_IRNEN)|0x8; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + break; + case INT_NUM_IM2_IRL14: + /* + * IDSEL = AD30 --> mini PCI connector + * PCI_INTA--GPIO Port0.1--EXIN2 + * IN/ALT0:1 ALT1:0 + * PULL UP + */ + (*AMAZON_GPIO_P0_DIR) = (*AMAZON_GPIO_P0_DIR) & 0xfffffffd; + (*AMAZON_GPIO_P0_ALTSEL0) = (*AMAZON_GPIO_P0_ALTSEL0)| 2; + (*AMAZON_GPIO_P0_ALTSEL1) = (*AMAZON_GPIO_P0_ALTSEL1)& 0xfffffffd; + (*AMAZON_GPIO_P0_PUDSEL) = (*AMAZON_GPIO_P0_PUDSEL) | 2; + (*AMAZON_GPIO_P0_PUDEN) = (*AMAZON_GPIO_P0_PUDEN) | 2; + //External Interrupt Node + (*AMAZON_ICU_EXTINTCR) = (*AMAZON_ICU_EXTINTCR)|0x600; + (*AMAZON_ICU_IRNEN) = (*AMAZON_ICU_IRNEN)|0x4; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + break; + default: + return 1; + } + return 0; +} + +int __init amazon_pci_init(void) +{ + u32 temp_buffer; + +#ifdef CONFIG_SWAP_IO_SPACE + AMAZON_PCI_REG32(IRM) = AMAZON_PCI_REG32(IRM) | (1<<27) | (1<<28); + wmb(); +#endif + + AMAZON_PCI_REG32(CLOCK_CONTROL) = AMAZON_PCI_REG32(CLOCK_CONTROL) | (1< + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void prom_putchar(char c) +{ + /* Wait for FIFO to empty */ + while ((amazon_readl(AMAZON_ASC_FSTAT) >> 8) != 0x00) ; + /* Crude cr/nl handling is better than none */ + if(c == '\n') + amazon_writel('\r', AMAZON_ASC_TBUF); + amazon_writel(c, AMAZON_ASC_TBUF); +} + +void __init prom_init(void) +{ + char **envp = (char **) fw_arg2; + + int memsize = 16; /* assume 16M as default */ + + envp = (char **)KSEG1ADDR((unsigned long)envp); + while (*envp) { + char *e = (char *)KSEG1ADDR(*envp); + + if (!strncmp(e, "memsize=", 8)) { + e += 8; + memsize = simple_strtoul(e, NULL, 10); + } + envp++; + } + memsize *= 1024 * 1024; + + strcpy(&(arcs_cmdline[0]), "console=ttyS0,115200 rootfstype=squashfs,jffs2"); + + add_memory_region(0x00000000, memsize, BOOT_MEM_RAM); +} + +void prom_free_prom_memory(void) +{ +} + +const char *get_system_type(void) +{ + return BOARD_SYSTEM_TYPE; +} diff --git a/target/linux/amazon/files/arch/mips/amazon/setup.c b/target/linux/amazon/files/arch/mips/amazon/setup.c new file mode 100644 index 000000000..ff1a109d4 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/setup.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2004 Peng Liu + * Copyright (C) 2007 John Crispin + * Copyright (C) 2007 Felix Fietkau + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned int r4k_offset; +static unsigned int r4k_cur; + +/* required in arch/mips/kernel/kspd.c */ +unsigned long cpu_khz; + +static void amazon_reboot_setup(void); + +/* the CPU clock rate - lifted from u-boot */ +unsigned int amazon_get_cpu_hz(void) +{ + /*-----------------------------------*/ + /**CGU CPU Clock Reduction Register***/ + /*-----------------------------------*/ + switch(amazon_readl(AMAZON_CGU_CPUCRD) & 0x3){ + case 0: + /*divider ration 1/1, 235 MHz clock */ + return 235000000; + case 1: + /*divider ration 2/3, 235 MHz clock, clock not accurate, here */ + return 150000000; + case 2: + /*divider ration 1/2, 235 MHz clock */ + return 117500000; + default: + /*divider ration 1/4, 235 MHz clock */ + return 58750000; + } +} + +/* the FPI clock rate - lifted from u-boot */ +unsigned int amazon_get_fpi_hz(void) +{ + unsigned int clkCPU; + clkCPU = amazon_get_cpu_hz(); + + /*-------------------------------------*/ + /***CGU Clock Divider Select Register***/ + /*-------------------------------------*/ + switch (amazon_readl(AMAZON_CGU_DIV) & 0x3) + { + case 1: + return clkCPU >> 1; + case 2: + return clkCPU >> 2; + default: + return clkCPU; + /* '11' is reserved */ + } +} +EXPORT_SYMBOL(amazon_get_fpi_hz); + +/* this doesn't really belong here, but it's a convenient location */ +unsigned int amazon_get_cpu_ver(void) +{ + static unsigned int cpu_ver = 0; + if (cpu_ver == 0) + cpu_ver = amazon_readl(AMAZON_MCD_CHIPID) & 0xFFFFF000; + return cpu_ver; +} + +static inline u32 amazon_get_counter_resolution(void) +{ + u32 res; + __asm__ __volatile__( + ".set push\n" + ".set mips32r2\n" + ".set noreorder\n" + "rdhwr %0, $3\n" + "ehb\n" + ".set pop\n" + : "=&r" (res) + : /* no input */ + : "memory"); + instruction_hazard(); + return res; +} + +void __init plat_time_init(void) +{ + mips_hpt_frequency = amazon_get_cpu_hz() / amazon_get_counter_resolution(); + r4k_offset = mips_hpt_frequency / HZ; + printk("mips_hpt_frequency:%d\n", mips_hpt_frequency); + printk("r4k_offset: %08x(%d)\n", r4k_offset, r4k_offset); + + r4k_cur = (read_c0_count() + r4k_offset); + write_c0_compare(r4k_cur); + + /* enable the timer in the PMU */ + amazon_writel(amazon_readl(AMAZON_PMU_PWDCR)| AMAZON_PMU_PWDCR_GPT|AMAZON_PMU_PWDCR_FPI, AMAZON_PMU_PWDCR); + + /* setup the GPTU for timer tick f_fpi == f_gptu*/ + amazon_writel(0x0100, AMAZON_GPTU_CLC); + amazon_writel(0xffff, AMAZON_GPTU_CAPREL); + amazon_writel(0x80C0, AMAZON_GPTU_T6CON); +} + +void __init plat_mem_setup(void) +{ + u32 chipid = 0; + u32 part_no = 0; + + chipid = amazon_readl(AMAZON_MCD_CHIPID); + part_no = AMAZON_MCD_CHIPID_PART_NUMBER_GET(chipid); + + if(part_no == AMAZON_CHIPID_YANGTSE){ + printk("Yangtse Version\n"); + } else if (part_no == AMAZON_CHIPID_STANDARD) { + printk(SYSTEM_MODEL_NAME "\n"); + } else { + printk("unknown version %8x\n",part_no); + } + + amazon_reboot_setup(); + + //stop reset TPE and DFE + amazon_writel(0, AMAZON_RST_REQ); + //clock + amazon_writel(0x3fff, AMAZON_PMU_PWDCR); + //reenable trace capability + part_no = readl(AMAZON_BCU_ECON); + + ioport_resource.start = IOPORT_RESOURCE_START; + ioport_resource.end = IOPORT_RESOURCE_END; + iomem_resource.start = IOMEM_RESOURCE_START; + iomem_resource.end = IOMEM_RESOURCE_END; +} + +static void amazon_machine_restart(char *command) +{ + local_irq_disable(); + amazon_writel(AMAZON_RST_ALL, AMAZON_RST_REQ); + for (;;) ; +} + +static void amazon_machine_halt(void) +{ + printk(KERN_NOTICE "System halted.\n"); + local_irq_disable(); + for (;;) ; +} + +static void amazon_machine_power_off(void) +{ + printk(KERN_NOTICE "Please turn off the power now.\n"); + local_irq_disable(); + for (;;) ; +} + +static void amazon_reboot_setup(void) +{ + _machine_restart = amazon_machine_restart; + _machine_halt = amazon_machine_halt; + pm_power_off = amazon_machine_power_off; +} diff --git a/target/linux/amazon/files/arch/mips/include/asm/mach-amazon/irq.h b/target/linux/amazon/files/arch/mips/include/asm/mach-amazon/irq.h new file mode 100644 index 000000000..e72b7d5c1 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/include/asm/mach-amazon/irq.h @@ -0,0 +1,7 @@ +#ifndef __AMAZON_IRQ_H +#define __AMAZON_IRQ_H + +#define NR_IRQS 256 +#include_next + +#endif diff --git a/target/linux/amazon/files/arch/mips/include/asm/mach-amazon/mangle-port.h b/target/linux/amazon/files/arch/mips/include/asm/mach-amazon/mangle-port.h new file mode 100644 index 000000000..af8c3e939 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/include/asm/mach-amazon/mangle-port.h @@ -0,0 +1,52 @@ +/* + * 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, 2004 Ralf Baechle + */ +#ifndef __ASM_MACH_AMAZON_MANGLE_PORT_H +#define __ASM_MACH_AMAZON_MANGLE_PORT_H + +#define __swizzle_addr_b(port) (port) +#define __swizzle_addr_w(port) ((port) ^ 2) +#define __swizzle_addr_l(port) (port) +#define __swizzle_addr_q(port) (port) + +/* + * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware; + * less sane hardware forces software to fiddle with this... + * + * Regardless, if the host bus endianness mismatches that of PCI/ISA, then + * you can't have the numerical value of data and byte addresses within + * multibyte quantities both preserved at the same time. Hence two + * variations of functions: non-prefixed ones that preserve the value + * and prefixed ones that preserve byte addresses. The latters are + * typically used for moving raw data between a peripheral and memory (cf. + * string I/O functions), hence the "__mem_" prefix. + */ +#if defined(CONFIG_SWAP_IO_SPACE) + +# define ioswabb(a, x) (x) +# define __mem_ioswabb(a, x) (x) +# define ioswabw(a, x) le16_to_cpu(x) +# define __mem_ioswabw(a, x) (x) +# define ioswabl(a, x) le32_to_cpu(x) +# define __mem_ioswabl(a, x) (x) +# define ioswabq(a, x) le64_to_cpu(x) +# define __mem_ioswabq(a, x) (x) + +#else + +# define ioswabb(a, x) (x) +# define __mem_ioswabb(a, x) (x) +# define ioswabw(a, x) (x) +# define __mem_ioswabw(a, x) cpu_to_le16(x) +# define ioswabl(a, x) (x) +# define __mem_ioswabl(a, x) cpu_to_le32(x) +# define ioswabq(a, x) (x) +# define __mem_ioswabq(a, x) cpu_to_le32(x) + +#endif + +#endif /* __ASM_MACH_AMAZON_MANGLE_PORT_H */ diff --git a/target/linux/amazon/files/arch/mips/include/asm/mach-amazon/war.h b/target/linux/amazon/files/arch/mips/include/asm/mach-amazon/war.h new file mode 100644 index 000000000..da42ee5a2 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/include/asm/mach-amazon/war.h @@ -0,0 +1,24 @@ +/* + * 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. + * + */ +#ifndef __ASM_MIPS_MACH_AMAZON_WAR_H +#define __ASM_MIPS_MACH_AMAZON_WAR_H + +#define R4600_V1_INDEX_ICACHEOP_WAR 0 +#define R4600_V1_HIT_CACHEOP_WAR 0 +#define R4600_V2_HIT_CACHEOP_WAR 0 +#define R5432_CP0_INTERRUPT_WAR 0 +#define BCM1250_M3_WAR 0 +#define SIBYTE_1956_WAR 0 +#define MIPS4K_ICACHE_REFILL_WAR 0 +#define MIPS_CACHE_SYNC_WAR 0 +#define TX49XX_ICACHE_INDEX_INV_WAR 0 +#define RM9000_CDEX_SMP_WAR 0 +#define ICACHE_REFILLS_WORKAROUND_WAR 0 +#define R10000_LLSC_WAR 0 +#define MIPS34K_MISSED_ITLB_WAR 0 + +#endif diff --git a/target/linux/amazon/files/drivers/atm/amazon_tpe.c b/target/linux/amazon/files/drivers/atm/amazon_tpe.c new file mode 100644 index 000000000..b50749440 --- /dev/null +++ b/target/linux/amazon/files/drivers/atm/amazon_tpe.c @@ -0,0 +1,3074 @@ +/* + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +//----------------------------------------------------------------------- +/* + * Description: + * Driver for Infineon Amazon TPE + */ +//----------------------------------------------------------------------- +/* Author: peng.liu@infineon.com + * Created: 12-April-2004 + */ +//----------------------------------------------------------------------- +/* History + * Last changed on: 13 Oct. 2004 + * Last changed by: peng.liu@infineon.com + * Last changed on: 28 Jan. 2004 + * Last changed by: peng.liu@infineon.com + * Last changed Reason: + * - AAL5R may send more bytes than expected in MFL (so far, confirmed as 64 bytes) + */ +// 507261:tc.chen 2005/07/26 re-organize code address map to improve performance. +// 507281:tc.chen 2005/07/28 fix f4 segment isssue +/* 511045:linmars 2005/11/04 from Liu.Peng: change NRT_VBR bandwidth calculation based on scr instead of pcr */ + +#ifndef __KERNEL__ +#define __KERNEL__ +#endif +#ifndef EXPORT_SYMTAB +#define EXPORT_SYMTAB +#endif + +/*TPE level loopback, bypass AWARE DFE */ +#undef TPE_LOOPBACK + +/* enable debug options */ +#undef AMAZON_ATM_DEBUG + +/* enable rx error packet analysis */ +#undef AMAZON_ATM_DEBUG_RX + +/* test AAL5 Interrupt */ +#undef AMAZON_TPE_TEST_AAL5_INT + +/* dump packet */ +#undef AMAZON_TPE_DUMP + +/* read ARC register*/ +/* this register is located in side DFE module*/ +#undef AMAZON_TPE_READ_ARC + +/* software controlled reassembly */ +#undef AMAZON_TPE_SCR + +/* recovery from AAL5 bug */ +#undef AMAZON_TPE_AAL5_RECOVERY + +#if defined(AMAZON_TPE_READ_ARC) || defined(AMAZON_TPE_AAL5_RECOVERY) +#define ALPHAEUS_BASE_ADDR 0x31c00 +#define A_CFG_ADDR (ALPHAEUS_BASE_ADDR+0x04) +#define AR_CB0_STATUS_ADDR (ALPHAEUS_BASE_ADDR+0x2c) +#define AR_CB1_STATUS_ADDR (ALPHAEUS_BASE_ADDR+0x30) +#define AT_CELL0_ADDR (ALPHAEUS_BASE_ADDR+0x90) +#define AR_CELL0_ADDR (ALPHAEUS_BASE_ADDR+0x1a0) +#define AR_CD_CNT0_ADDR (ALPHAEUS_BASE_ADDR+0x1c8) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(AMAZON_TPE_READ_ARC) || defined(AMAZON_TPE_AAL5_RECOVERY) +#include +#include +#endif + +#define AMAZON_TPE_EMSG(fmt, args...) printk( KERN_ERR "%s: " fmt,__FUNCTION__, ## args) + +/***************************************** External Functions *******************************************/ +extern unsigned int amazon_get_fpi_hz(void); +extern void mask_and_ack_amazon_irq(unsigned int irq_nr); +extern void amz_push_oam(unsigned char *); + +//amazon_mei.c +#if defined(AMAZON_TPE_READ_ARC) || defined(AMAZON_TPE_AAL5_RECOVERY) +extern MEI_ERROR meiDebugRead(u32 srcaddr, u32 *databuff, u32 databuffsize); +extern MEI_ERROR meiDebugWrite(u32 destaddr, u32 *databuff, u32 databuffsize); +#endif + +/***************************************** Internal Functions *******************************************/ +int amazon_atm_read_procmem(char *buf, char **start, off_t offset,int count, int *eof, void *data); +/***************************************** Global Data *******************************************/ +amazon_atm_dev_t g_atm_dev; //device data +static struct tq_struct swex_start_task; //BH task +static struct tq_struct swex_complete_task; //BH task +#ifdef AMAZON_TPE_SCR +static struct tq_struct a5r_task; //BH task +#endif +static struct dma_device_info g_dma_dev; //for DMA +static struct atm_dev * amazon_atm_devs[AMAZON_ATM_PORT_NUM]; +static struct oam_last_activity g_oam_time_stamp[AMAZON_ATM_MAX_VCC_NUM]; +static u8 g_oam_cell[AMAZON_AAL0_SDU+4]; //for OAM cells +#ifdef AMAZON_CHECK_LINK +static int adsl_link_status; //ADSL link status, 0:down, 1:up +#endif //AMAZON_CHECK_LINK +/***************************************** Module Parameters *************************************/ +// Parameter Definition for module +static int port_enable0 = 1; // Variable for parameter port_enable0 +static int port_enable1 = 0; // Variable for parameter port_enable1 +static int port_max_conn0 = 15; // Variable for parameter port_max_conn0 +static int port_max_conn1 = 0; // Variable for parameter port_max_conn1 +static int port_cell_rate_up0 = 7500; // Variable for parameter port_cell_rate_up0 +static int port_cell_rate_up1 = 7500; // Variable for parameter port_cell_rate_up1 + + +static int qsb_tau = 1; // Variable for parameter qsb_tau +static int qsb_srvm = 0xf; // Variable for parameter qsb_srvm +static int qsb_tstep = 4 ; // Variable for parameter qsb_tstep + +static int cbm_nrt = 3900; // Variable for parameter cbm_nrt +static int cbm_clp0 =3500; // Variable for parameter cbm_clp0 +static int cbm_clp1 =3200; // Variable for parameter cbm_clp1 +static int cbm_free_cell_no = AMAZON_ATM_FREE_CELLS; // Variable for parameter cbm_free_cell_no + +static int a5_fill_pattern = 0x7e; // Variable for parameter a5_fill_pattern '~' +static int a5s_mtu = 0x700; // mtu for tx +static int a5r_mtu = 0x700; // mtu for rx + +static int oam_q_threshold = 64; // oam queue threshold, minium value 64 +static int rx_q_threshold = 1000; // rx queue threshold, minium value 64 +static int tx_q_threshold = 800; // tx queue threshold, minium value 64 + +MODULE_PARM(port_max_conn0, "i"); +MODULE_PARM_DESC(port_max_conn0, "Maximum atm connection for port #0"); +MODULE_PARM(port_max_conn1, "i"); +MODULE_PARM_DESC(port_max_conn1, "Maximum atm connection for port #1"); +MODULE_PARM(port_enable0, "i"); +MODULE_PARM_DESC(port_enable0, "0 -> port disabled, 1->port enabled"); +MODULE_PARM(port_enable1, "i"); +MODULE_PARM_DESC(port_enable1, "0 -> port disabled, 1->port enabled"); +MODULE_PARM(port_cell_rate_up0, "i"); +MODULE_PARM_DESC(port_cell_rate_up0, "ATM port upstream rate in cells/s"); +MODULE_PARM(port_cell_rate_up1, "i"); +MODULE_PARM_DESC(port_cell_rate_up1, "ATM port upstream rate in cells/s"); + +MODULE_PARM(qsb_tau,"i"); +MODULE_PARM_DESC(qsb_tau, "Cell delay variation. value must be > 0"); +MODULE_PARM(qsb_srvm, "i"); +MODULE_PARM_DESC(qsb_srvm, "Maximum burst size"); +MODULE_PARM(qsb_tstep, "i"); +MODULE_PARM_DESC(qsb_tstep, "n*32 cycles per sbs cycles n=1,2,4"); + +MODULE_PARM(cbm_nrt, "i"); +MODULE_PARM_DESC(cbm_nrt, "Non real time threshold for cell buffer"); +MODULE_PARM(cbm_clp0, "i"); +MODULE_PARM_DESC(cbm_clp0, "Threshold for cells with cell loss priority 0"); +MODULE_PARM(cbm_clp1, "i"); +MODULE_PARM_DESC(cbm_clp1, "Threshold for cells with cell loss priority 1"); +MODULE_PARM(cbm_free_cell_no, "i"); +MODULE_PARM_DESC(cbm_free_cell_no, "Number of cells in the cell buffer manager"); + +MODULE_PARM(a5_fill_pattern, "i"); +MODULE_PARM_DESC(a5_fill_pattern, "filling pattern (PAD) for aal5 frames"); +MODULE_PARM(a5s_mtu, "i"); +MODULE_PARM_DESC(a5s_mtu, "max. SDU for upstream"); +MODULE_PARM(a5r_mtu, "i"); +MODULE_PARM_DESC(a5r_mtu, "max. SDU for downstream"); + +MODULE_PARM(oam_q_threshold, "i"); +MODULE_PARM_DESC(oam_q_threshold, "oam queue threshold"); + +MODULE_PARM(rx_q_threshold, "i"); +MODULE_PARM_DESC(rx_q_threshold, "downstream/rx queue threshold"); + +MODULE_PARM(tx_q_threshold, "i"); +MODULE_PARM_DESC(tx_q_threshold, "upstream/tx queue threshold"); + +/***************************************** local functions *************************************/ +/* Brief: valid QID + * Return: 1 if valid + * 0 if not + */ +static inline int valid_qid(int qid) +{ + return ( (qid>0) && (qiddata)) & 15) != 0){ + AMAZON_TPE_DMSG("need to adjust the alignment manually\n"); + skb_reserve(skb, 16 - (((u32) (skb->data)) & 15) ); + } + +} + +/* + * Brief: initialize the device according to the module paramters + * Return: not NULL - ok + * NULL - fails + * Description: arrange load parameters and call the hardware initialization routines + */ +static void atm_init_parameters(amazon_atm_dev_t *dev) +{ + //port setting + dev->ports[0].enable = port_enable0; + dev->ports[0].max_conn = port_max_conn0; + dev->ports[0].tx_max_cr = port_cell_rate_up0; + if (port_enable1){ + dev->ports[1].enable = port_enable1; + dev->ports[1].max_conn = port_max_conn1; + dev->ports[1].tx_max_cr = port_cell_rate_up1; + } + + //aal5 + dev->aal5.padding_byte = a5_fill_pattern; + dev->aal5.tx_max_sdu = a5s_mtu; + dev->aal5.rx_max_sdu = a5r_mtu; + + //cbm + dev->cbm.nrt_thr = cbm_nrt; + dev->cbm.clp0_thr = cbm_clp0; + dev->cbm.clp1_thr = cbm_clp1; + dev->cbm.free_cell_cnt = cbm_free_cell_no; + + //qsb + dev->qsb.tau = qsb_tau; + dev->qsb.tstepc =qsb_tstep; + dev->qsb.sbl = qsb_srvm; + + //allocate on the fly + dev->cbm.mem_addr = NULL; + dev->cbm.qd_addr = NULL; +} + + +/* Brief: Find QID for VCC + * Parameters: vcc - VCC data structure + * Return Value: -EINVAL - VCC not found + * qid - QID for this VCC + * Description: + * This function returns the QID of a given VCC + */ +static int amazon_atm_get_queue(struct atm_vcc* vcc) +{ + int i; + for (i=0;ivpi == vpi) && (vcc->vci == vci)) return i; + } + } + return -EINVAL; +} + +/* Brief: Find QID for VPI + * Parameters: vpi - VPI to found + * Return Value: -EINVAL - VPI not found + * qid - QID for this VPI + * + * Description: + * This function returns the QID for a given VPI. itf and VCI don't matter + */ +static int amazon_atm_find_vpi(u8 vpi) +{ + int i; + for (i=0;ivpi == vpi) return i; + } + } + return -EINVAL; +} + +/* + * Brief: Clears QID entries for VCC + * + * Parameters: vcc - VCC to found + * + * Description: + * This function searches for the given VCC and sets it to NULL if found. + */ +static inline void amazon_atm_clear_vcc(int i) +{ + g_atm_dev.queues[i].vcc = NULL; + g_atm_dev.queues[i].free = 1; +} + + +/* + * Brief: dump skb data + */ +static inline void dump_skb(u32 len, char * data) +{ +#ifdef AMAZON_TPE_DUMP + int i; + for(i=0;ipop != NULL) { + vcc->pop(vcc, skb); + } else { + dev_kfree_skb_any(skb); + } +} +/* + * Brief: release TX skbuff + */ +static inline void amazon_atm_free_tx_skb(struct sk_buff *skb) +{ + struct atm_vcc* vcc = ATM_SKB(skb)->vcc; + if (vcc!=NULL){ + amazon_atm_free_tx_skb_vcc(vcc,skb); + } else { + dev_kfree_skb_any(skb);//fchang:Added + } +} + +/* Brief: divide by 64 and round up + */ +static inline u32 divide_by_64_round_up(int input) +{ + u32 tmp1; + tmp1 = (u32) input; + tmp1 = (tmp1%64)?(tmp1/64 + 1): (tmp1/64); + if (tmp1 == 0) tmp1 = 1; + return tmp1; +} + +/* + * Brief: statistics + */ +#ifdef AMAZON_ATM_DEBUG +static inline void queue_statics(int qid, qs_t idx) +{ + if (valid_qid(qid)){ + g_atm_dev.queues[qid].qs[idx]++; + } +} +#else //not AMAZON_ATM_DEBUG +static inline void queue_statics(int qid, qs_t idx){} +#endif //AMAZON_ATM_DEBUG + + +/* Brief: set dma tx full, i.e. there is no available descriptors + */ +static void inline atm_dma_full(void) +{ + AMAZON_TPE_DMSG("ch0 is full\n"); + atomic_set(&g_atm_dev.dma_tx_free_0,0); +} + +/* + * Brief set dma tx free (at least one descript is available) + */ +inline static void atm_dma_free(void) +{ + AMAZON_TPE_DMSG("ch0 is free\n"); + atomic_set(&g_atm_dev.dma_tx_free_0,1); +} + + +/* Brief: return the status of DMA TX descriptors + * Parameters: TX channel (DMA_TX_CH0, TX_CH1) + * Return: + * 1: there are availabel TX descriptors + * 0: no available + * Description: + * + */ +inline int dma_may_send(int ch) +{ + if (atomic_read(&g_atm_dev.dma_tx_free_0)){ + return 1; + } + return 0; +} + +/******************************* global functions *********************************/ +/* + * Brief: SWIE Cell Extraction Start Routine + * and task routine for swex_complete_task + * Parameters: irq_stat - interrupt status + * + * Description: + * This is the routine for extracting cell. It will schedule itself if the hardware is busy. + * This routine runs in interrupt context + */ +void amazon_atm_swex(void * irq_stat) +{ + u32 ex_stat=0; + u32 addr; + // Read extraction status register + ex_stat = readl(CBM_HWEXSTAT0_ADDR); + + // Check if extraction/insertion is in progress + if ( (ex_stat & CBM_EXSTAT_SCB) || (ex_stat & CBM_EXSTAT_FB) || (test_and_set_bit(SWIE_LOCK, &(g_atm_dev.swie.lock))!=0)) { + AMAZON_TPE_DMSG(" extraction in progress. Will wait\n"); + swex_start_task.data = irq_stat; + queue_task(&swex_start_task, &tq_immediate); + mark_bh(IMMEDIATE_BH); + }else { + // Extract QID + g_atm_dev.swie.qid = (((u32)irq_stat) >> 24); + AMAZON_TPE_DMSG("extracting from qid=%u\n",g_atm_dev.swie.qid); + //read status word + addr = KSEG1ADDR((unsigned long)g_atm_dev.cbm.qd_addr); + addr = readl((addr + g_atm_dev.swie.qid * 0x10 + 4) & 0xFFFFFFC0); + addr = KSEG1ADDR(addr); + g_atm_dev.swie.sw = readl(addr+52)&SWIE_ADDITION_DATA_MASK; + AMAZON_TPE_DMSG("cell addition word: %8x \n", g_atm_dev.swie.sw); + + // Start extraction + AMAZON_WRITE_REGISTER_L(g_atm_dev.swie.qid | SWIE_CBM_PID_SUBADDR, CBM_HWEXPAR0_ADDR); + AMAZON_WRITE_REGISTER_L(SWIE_CBM_SCE0, CBM_HWEXCMD_ADDR); + } +} +#ifdef AMAZON_TPE_SCR +u32 g_a5r_wait=0; +/* + * Brief: AAL5 Packet Extraction Routine and task routine for a5r_task + * Parameters: irq_stat - interrupt status + * + * Description: + * This is the routine for extracting frame. It will schedule itself if the hardware is busy. + * This routine runs in interrupt context + */ +void amazon_atm_a5r(void* qid) +{ + volatile u32 ex_stat=0; + u32 addr; + u32 a5r_wait=0; + + ex_stat = readl(CBM_HWEXSTAT0_ADDR); +#if 0 + // Check if extraction/insertion is in progress + if ( (ex_stat & CBM_EXSTAT_SCB) || (ex_stat & CBM_EXSTAT_FB) ) { + AMAZON_TPE_DMSG(" extraction in progress. Will wait\n"); + a5r_task.data = qid; + queue_task(&a5r_task, &tq_immediate); + mark_bh(IMMEDIATE_BH); + }else { + AMAZON_TPE_DMSG("extracting from qid=%u\n",(u8)qid); + // Start extraction + AMAZON_WRITE_REGISTER_L(((u8)qid) | CBM_HWEXPAR_PN_A5, CBM_HWEXPAR0_ADDR); + AMAZON_WRITE_REGISTER_L(CBM_HWEXCMD_FE0, CBM_HWEXCMD_ADDR); + } +#else + //while ( (ex_stat & CBM_EXSTAT_SCB) || (ex_stat & CBM_EXSTAT_FB) ) { + while ( ex_stat != 0x80){ + a5r_wait++; + ex_stat = readl(CBM_HWEXSTAT0_ADDR); +#if 0 + if (a5r_wait >= 0xffffff){ + a5r_wait=0; + printk("."); + } +#endif + } + if (a5r_wait > g_a5r_wait){ + g_a5r_wait = a5r_wait; + } + AMAZON_WRITE_REGISTER_L(((u8)qid) | CBM_HWEXPAR_PN_A5, CBM_HWEXPAR0_ADDR); + AMAZON_WRITE_REGISTER_L(CBM_HWEXCMD_FE0, CBM_HWEXCMD_ADDR); +#endif +} + +#endif //AMAZON_TPE_SCR + +/* Brief: Handle F4/F5 OAM cell + * Return: + * 0 ok + * <0 fails + */ +static int inline amazon_handle_oam_cell(void *data, u8 vpi, u16 vci,u32 status) +{ + struct atm_vcc* vcc=NULL; + int qid; + if (!status&SWIE_EOAM_MASK){ + AMAZON_TPE_EMSG("unknown cell received, discarded\n"); + goto amazon_handle_oam_cell_err_exit; + }else if (status&SWIE_ECRC10ERROR_MASK){ + AMAZON_TPE_EMSG("CRC-10 Error Status:%8x, discarded\n", status); + goto amazon_handle_oam_cell_err_exit; + }else{ + if(status & (SWIE_EVCI3_MASK |SWIE_EVCI4_MASK)){ + //F4 level (VPI) OAM, Assume duplex + qid = amazon_atm_find_vpi(vpi)+CBM_RX_OFFSET; + }else if (status & (SWIE_EPTI4_MASK|SWIE_EPTI5_MASK)){ + //F5 level (VCI) OAM, Assume duplex + qid = amazon_atm_find_vpivci(vpi,vci)+CBM_RX_OFFSET; + }else{ + qid = -1; + AMAZON_TPE_EMSG("non-F4/F5 OAM cells?, discarded\n"); + goto amazon_handle_oam_cell_err_exit; + } + } + if (valid_qid(qid) && ((vcc = g_atm_dev.queues[qid].vcc)!=NULL)){ + //TODO, should we do this for ALL OAM types? (Actually only User and CC) + g_atm_dev.queues[qid].access_time=xtime; + if (vcc->push_oam){ + (*vcc->push_oam)(vcc,data); + }else{ + amz_push_oam(data); + } + }else{ + AMAZON_TPE_EMSG("no VCC yet\n"); + goto amazon_handle_oam_cell_err_exit; + } + return 0; +amazon_handle_oam_cell_err_exit: + dump_skb(AMAZON_AAL0_SDU,(char *)data); + return -1; +} + +/* Brief: SWIE Cell Extraction Finish Routine + * and task routine for swex_complete_task + * Description: + * 1.Allocate a buffer of type struct sk_buff + * 2.Copy the data from the temporary memory to this buffer + * 3.Push the data to upper layer + * 4.Update the statistical data if necessary + * 5.Release the temporary data + + */ +void amazon_atm_swex_push(void * data) +{ + struct atm_vcc* vcc=NULL; + struct sk_buff* skb=NULL; + struct amazon_atm_cell_header * cell_header; + u32 status; + int qid; + if (!data){ + AMAZON_TPE_EMSG("data is NULL\n"); + return; + } + qid = ((u8*)data)[AMAZON_AAL0_SDU]; + status = ((u32*)data)[ATM_AAL0_SDU/4]; + cell_header = (struct amazon_atm_cell_header *) data; + if (valid_qid(qid) != 1){ + AMAZON_TPE_EMSG("error qid: %u\n",qid); + AMAZON_TPE_EMSG("unknown cells recieved\n"); + }else if (qid == AMAZON_ATM_OAM_Q_ID){ + //OAM or RM or OTHER cell + //Find real connection + +#ifdef IKOS_MINI_BOOT + //for OAM loop back test + dump_skb(56,(char *)data); + //kfree(data); using g_oam_cell + return; +#endif //IKOS_MINI_BOOT +#ifdef TPE_LOOPBACK + amz_push_oam(data); + return; +#endif//TPE_LOOPBACK + int ret = 0; + ret = amazon_handle_oam_cell(data,cell_header->bit.vpi,cell_header->bit.vci,status); + if (ret == 0) + return; + }else{ + //should be normal AAL0 cells + // Get VCC + vcc = g_atm_dev.queues[qid].vcc; + if (vcc != NULL) { + AMAZON_TPE_DMSG("push to upper layer\n"); + skb = dev_alloc_skb(AMAZON_AAL0_SDU); + if (skb != NULL) { + //skb->dev=vcc->dev; + memcpy(skb_put(skb, AMAZON_AAL0_SDU), data, AMAZON_AAL0_SDU); + skb->stamp = xtime; + ATM_SKB(skb)->vcc = vcc; + (*g_atm_dev.queues[qid].push)(vcc,skb,0); + }else{ + AMAZON_TPE_EMSG(" No memory left for incoming AAL0 cell! Cell discarded!\n"); + //inform the upper layer + (*g_atm_dev.queues[qid].push)(vcc,skb,-ENOMEM); + atomic_inc(&vcc->stats->rx_drop); + } + }else{ + AMAZON_TPE_EMSG("invalid qid %u\n",qid); + } + } + //kfree(data); using g_oam_cell +} + +/* + * Brief: Interrupt handler for software cell extraction (done) + * Parameters: irq - CPPN for this interrupt + * data - Device ID for this interrupt + * regs - Register file + * + * Description: + * When a software extraction is finished this interrupt is issued. + * It reads the cell data and sends it to the ATM stack. + */ +void amazon_atm_swex_isr(int irq, void *data, struct pt_regs *regs) +{ + u32 * cell = NULL; + int i; + //ATM_AAL0 SDU + QID + AMAZON_TPE_DMSG("SWIE extraction done\n"); + cell = (u32 *) g_oam_cell; + if (cell != NULL){ + //convert to host byte order from big endian + for(i=0;i>CBM_INTINF0_QID_SHIFT); +#ifdef AMAZON_TPE_SCR + if (irq_stat & CBM_INTINF0_EF){ + amazon_atm_a5r((void*)qid); + } +#endif + // Check if Any Cell Arrived + if (irq_stat & CBM_INTINF0_ACA) { + amazon_atm_swex((void *)irq_stat); + } + //TX AAL5 PDU discard + if (irq_stat & CBM_INTINF0_OPF){ + if ( (qid) < CBM_RX_OFFSET ){ + g_atm_dev.mib_counter.tx_drop++; + } + queue_statics(qid, QS_HW_DROP); + } + if (irq_stat & (CBM_INTINF0_ERR|CBM_INTINF0_Q0E|CBM_INTINF0_Q0I|CBM_INTINF0_RDE)){ + AMAZON_TPE_EMSG("CBM INT status: %8x\n",irq_stat); + if (irq_stat & CBM_INTINF0_ERR){ + AMAZON_TPE_EMSG("CBM Error: FPI Bus Error\n"); + } + if (irq_stat & CBM_INTINF0_Q0E){ + AMAZON_TPE_EMSG("CBM Error: Queue 0 Extract\n"); + } + if (irq_stat & CBM_INTINF0_Q0I){ + AMAZON_TPE_EMSG("CBM Error: Queue 0 Extract\n"); + } + if (irq_stat & CBM_INTINF0_RDE){ + AMAZON_TPE_EMSG("CBM Error: Read Empty Queue %u\n",qid); + dump_qd(qid); + } + } + } + mask_and_ack_amazon_irq(AMAZON_CBM_INT); +} + +/* Brief: check the status word after AAL SDU after reassembly + */ +static inline void check_aal5_error(u8 stw0, u8 stw1, int qid) +{ + if (stw0 & AAL5_STW0_MFL){ + AMAZON_TPE_DMSG("Maximum Frame Length\n"); + g_atm_dev.queues[qid].aal5VccOverSizedSDUs++; + } + if (stw0 & AAL5_STW0_CRC){ + AMAZON_TPE_DMSG("CRC\n"); + g_atm_dev.queues[qid].aal5VccCrcErrors++; + } +#ifdef AMAZON_ATM_DEBUG_RX + AMAZON_TPE_EMSG("qid:%u stw0:%8x stw1:%8x\n",qid,stw0,stw1); +#endif +} + +/* Brief: Process DMA rx data + * Parameters: + dma_dev: pointer to the dma_device_info, provided by us when register the dma device + * Return: no + * Description: DMA interrupt handerl with OoS support. It is called when there is some data in rx direction. + * + */ +//507261:tc.chen void atm_process_dma_rx(struct dma_device_info* dma_dev) +void __system atm_process_dma_rx(struct dma_device_info* dma_dev) +{ + u8 * head=NULL; + u32 length=0; + u8 stw0=0; + u8 stw1=0; + + struct sk_buff * skb=NULL; + struct atm_vcc * vcc=NULL; + int qid=0; +#ifdef AMAZON_ATM_DEBUG_RX + static int dma_rx_dump=0; + static u32 seq=0; + + seq++; + if (dma_rx_dump>0){ + printk("\n=========================[%u]=========================\n",seq); + } +#endif + length=dma_device_read(dma_dev,&head,(void**)&skb); + AMAZON_TPE_DMSG("receive %8p[%u] from DMA\n", head,length); + if (head == NULL||length<=0) { + AMAZON_TPE_DMSG("dma_read null \n"); + goto error_exit; + } + + if (length > (g_atm_dev.aal5.rx_max_sdu+64)){ + AMAZON_TPE_EMSG("received packet too large (%u)\n",length); + goto error_exit; + } + //check AAL5R trail for error and qid + //last byte is qid + length--; + qid = (int) head[length]; + AMAZON_TPE_DMSG("head[%u] qid %u\n",length, qid); + //STW0 is always 4 bytes before qid + length -= 4; + stw0 = head[length]&0xff; + AMAZON_TPE_DMSG("head[%u] stw0 %8x\n",length, stw0); + //position of STW1 depends on the BE bits + length = length-4 + (stw0&AAL5_STW0_BE); + stw1 = head[length]&0xff; + AMAZON_TPE_DMSG("head[%u] stw1 %8x\n",length, stw1); + if ( (stw0 & AAL5_STW0_MASK) || (stw1 & AAL5_STW1_MASK) ){ + //AAL5 Error + check_aal5_error(stw0, stw1,qid); + goto error_exit; + } + //make data pointers consistent + //UU + CPI + length -= 2; + AMAZON_TPE_DMSG("packet length %u\n", length); + + //error: cannot restore the qid + if (valid_qid(qid) != 1){ + AMAZON_TPE_EMSG("received frame in invalid qid %u!\n", qid); + goto error_exit; + } + vcc = g_atm_dev.queues[qid].vcc; + if (vcc == NULL){ + AMAZON_TPE_EMSG("received frame in invalid vcc, qid=%u!\n",qid); + goto error_exit; + } + if (skb == NULL){ + AMAZON_TPE_EMSG("cannot restore skb pointer!\n"); + goto error_exit; + } + skb_put(skb,length); + skb->stamp = xtime; + g_atm_dev.queues[qid].access_time=xtime; + if ((*g_atm_dev.queues[qid].push)(vcc,skb,0)){ + g_atm_dev.mib_counter.rx_drop++; + queue_statics(qid, QS_SW_DROP); + }else{ + g_atm_dev.mib_counter.rx++; + adsl_led_flash();//joelin adsl led + queue_statics(qid, QS_PKT); + AMAZON_TPE_DMSG("push successful!\n"); + } +#ifdef AMAZON_ATM_DEBUG_RX + if (dma_rx_dump>0){ + printk("\nOK packet [dump=%u] length=%u\n",dma_rx_dump,length); + dump_skb(length+7, head); + } + if (dma_rx_dump >0) dma_rx_dump--; +#endif + return ; +error_exit: +#ifdef AMAZON_ATM_DEBUG_RX + if ( (head!=NULL) && (length >0)){ + AMAZON_TPE_EMSG("length=%u\n",length); + dump_skb(length+5, head); + } + dma_rx_dump++; +#endif + g_atm_dev.mib_counter.rx_err++; + queue_statics(qid, QS_ERR); + /* + if (vcc){ + (*g_atm_dev.queues[qid].push)(vcc,skb,1); + } + */ + if (skb != NULL) { + dev_kfree_skb_any(skb); + } + return; +} + +/*Brief: ISR for DMA pseudo interrupt + *Parameter: + dma_dev: pointer to the dma_device_info, provided by us when register the dma device + intr_status: + RCV_INT: rx data available + TX_BUF_FULL_INT: tx descriptor run out of + TRANSMIT_CPT_INT: tx descriptor available again + *Return: + 0 for success??? + */ +//507261:tc.chen int amazon_atm_dma_handler(struct dma_device_info* dma_dev, int intr_status) +int __system amazon_atm_dma_handler(struct dma_device_info* dma_dev, int intr_status) +{ + AMAZON_TPE_DMSG("status:%u\n",intr_status); + switch (intr_status) { + case RCV_INT: + atm_process_dma_rx(dma_dev); + break; + case TX_BUF_FULL_INT: + //TX full: no descriptors + atm_dma_full(); + break; + case TRANSMIT_CPT_INT: + //TX free: at least one descriptor + atm_dma_free(); + break; + default: + AMAZON_TPE_EMSG("unknown status!\n"); + } + return 0; +} + +/*Brief: free buffer for DMA tx + *Parameter: + dataptr: pointers to data buffer + opt: optional parameter, used to convey struct skb pointer, passwd in dma_device_write + *Return: + 0 for success??? + *Description: + called by DMA module to release data buffer after DMA tx transaction + *Error: + cannot restore skb pointer + */ +int amazon_atm_free_tx(u8*dataptr, void* opt) +{ + struct sk_buff *skb; + if (opt){ + AMAZON_TPE_DMSG("free skb%8p\n",opt); + skb = (struct sk_buff *)opt; + amazon_atm_free_tx_skb(skb); + }else{ + AMAZON_TPE_EMSG("BUG: cannot restore skb pointer!\n"); + } + return 0; +} + +/*Brief: allocate buffer & do alignment + */ +inline struct sk_buff * amazon_atm_alloc_buffer(int len) +{ + struct sk_buff *skb; + skb = dev_alloc_skb(len+16); + if (skb){ + //alignment requriements (4x32 bits (16 bytes) boundary) + alloc_align_16(skb); + } + return skb; +} + +/*Brief: allocate buffer for DMA rx + *Parameter: + len: length + opt: optional data to convey the skb pointer, which will be returned to me in interrupt handler, + *Return: + pointer to buffer, NULL means error? + *Description: + must make sure byte alignment + */ + +u8* amazon_atm_alloc_rx(int len, int* offset, void **opt) +{ + struct sk_buff *skb; + *offset = 0; + skb = amazon_atm_alloc_buffer(len); + if (skb){ + AMAZON_TPE_DMSG("alloc skb->data:%8p len:%u\n",skb->data,len); + *(struct sk_buff**)opt = skb; + }else{ + AMAZON_TPE_DMSG("no memory for receiving atm frame!\n"); + return NULL; + } + return skb->data; +} + + + + +/* Brief: Allocate kernel memory for sending a datagram. + * Parameters + * vcc virtual connection + * size data buffer size + * Return: + * NULL fail + * sk_buff a pointer to a sk_buff + * Description: + * This function can allocate our own additional memory for AAL5S inbound + * header (8bytes). We have to replace the protocol default one (alloc_tx in /net/atm/common.c) + * when we open the device. + * byte alignment is done is DMA driver. + */ +struct sk_buff *amazon_atm_alloc_tx(struct atm_vcc *vcc,unsigned int size) +{ + struct sk_buff *skb; + + if (!dma_may_send(DMA_TX_CH0)){ + AMAZON_TPE_EMSG("no DMA descriptor available!\n"); + return NULL; + } + //AAL5 inbound header space + alignment extra buffer + size+=8+AAL5S_INBOUND_HEADER; + + if (atomic_read(&vcc->tx_inuse) && !atm_may_send(vcc,size)) { + AMAZON_TPE_EMSG("Sorry tx_inuse = %u, size = %u, sndbuf = %u\n", + atomic_read(&vcc->tx_inuse),size,vcc->sk->sndbuf); + return NULL; + } + + skb = amazon_atm_alloc_buffer(size); + if (skb == NULL){ + AMAZON_TPE_EMSG("no memory\n"); + return NULL; + } + AMAZON_TPE_DMSG("dev_alloc_skb(%u) = %x\n", skb->len, (u32)skb); + AMAZON_TPE_DMSG("tx_inuse %u += %u\n",atomic_read(&vcc->tx_inuse),skb->truesize); + atomic_add(skb->truesize+ATM_PDU_OVHD,&vcc->tx_inuse); + + //reserve for AAL5 inbound header + skb_reserve(skb,AAL5S_INBOUND_HEADER); + return skb; +} + + +/* Brief: change per queue QSB setting according to vcc qos parameters + * Paramters: + * vcc: atm_vcc pointer + * qid: CBM queue id (1~15) + * Return: + */ +static inline void set_qsb(struct atm_vcc *vcc, struct atm_qos *qos, int qid) +{ + qsb_qptl_t qptl; + qsb_qvpt_t qvpt; + u32 tmp=0; + unsigned int qsb_clk; + + qsb_clk = amazon_get_fpi_hz()>>1; + + AMAZON_TPE_EMSG("Class=%u MAX_PCR=%u PCR=%u MIN_PCR=%u SCR=%u MBS=%u CDV=%u\n" + ,qos->txtp.traffic_class + ,qos->txtp.max_pcr + ,qos->txtp.pcr + ,qos->txtp.min_pcr + ,qos->txtp.scr + ,qos->txtp.mbs + ,qos->txtp.cdv + ); + + // PCR limiter + if (qos->txtp.max_pcr == 0){ + qptl.bit.tprs = 0; /* 0 disables the PCR limiter */ + }else { + // peak cell rate will be slightly lower than requested (maximum rate / pcr)= (qsbclock/2^3 * timestep/4)/pcr + tmp = (( (qsb_clk * g_atm_dev.qsb.tstepc)>>5)/ qos->txtp.max_pcr ) + 1; + // check if an overfow occured + if (tmp > QSB_TP_TS_MAX) { + AMAZON_TPE_EMSG("max_pcr is too small, max_pcr:%u tprs:%u\n",qos->txtp.max_pcr, tmp); + qptl.bit.tprs = QSB_TP_TS_MAX; + }else{ + qptl.bit.tprs = tmp; + } + } + //WFQ + if (qos->txtp.traffic_class == ATM_CBR || qos->txtp.traffic_class ==ATM_VBR_RT){ + // real time queue gets weighted fair queueing bypass + qptl.bit.twfq = 0; + }else if (qos->txtp.traffic_class ==ATM_VBR_NRT ||qos->txtp.traffic_class ==ATM_UBR_PLUS ){ + // wfq calculation here are based on virtual cell rates, to reduce granularity for large rates + // wfq factor is maximum cell rate / garenteed cell rate. + //qptl.bit.twfq = g_atm_dev.qsb.min_cr * QSB_WFQ_NONUBR_MAX / qos->txtp.min_pcr; + if (qos->txtp.min_pcr == 0) { + AMAZON_TPE_EMSG(" MIN_PCR should not be zero\n"); + qptl.bit.twfq = QSB_WFQ_NONUBR_MAX; + }else{ + tmp = QSB_GCR_MIN * QSB_WFQ_NONUBR_MAX / qos->txtp.min_pcr; + if (tmp == 0 ){ + qptl.bit.twfq = 1; + }else if (tmp > QSB_WFQ_NONUBR_MAX){ + AMAZON_TPE_EMSG("min_pcr is too small, min_pcr:%u twfq:%u\n",qos->txtp.min_pcr, tmp); + qptl.bit.twfq = QSB_WFQ_NONUBR_MAX; + }else{ + qptl.bit.twfq = tmp; + } + } + }else if (qos->txtp.traffic_class == ATM_UBR){ + // ubr bypass, twfq set to maximum value + qptl.bit.twfq = QSB_WFQ_UBR_BYPASS; + }else{ + //tx is diabled, treated as UBR + AMAZON_TPE_EMSG(" unsupported traffic class %u \n", qos->txtp.traffic_class); + qos->txtp.traffic_class = ATM_UBR; + qptl.bit.twfq = QSB_WFQ_UBR_BYPASS; + } + + //SCR Leaky Bucket Shaper VBR.0/VBR.1 + if (qos->txtp.traffic_class ==ATM_VBR_RT || qos->txtp.traffic_class ==ATM_VBR_NRT){ + if (qos->txtp.scr == 0){ + //SCR == 0 disable the shaper + qvpt.bit.ts = 0; + qvpt.bit.taus = 0; + }else{ + //CLP + if (vcc->atm_options&ATM_ATMOPT_CLP){ + //CLP1 + qptl.bit.vbr = 1; + }else{ + //CLP0 + qptl.bit.vbr = 0; + } + //TS and TauS + tmp = (( (qsb_clk * g_atm_dev.qsb.tstepc)>>5)/ qos->txtp.scr ) + 1; + if (tmp > QSB_TP_TS_MAX) { + AMAZON_TPE_EMSG("scr is too small, scr:%u ts:%u\n",qos->txtp.scr, tmp); + qvpt.bit.ts = QSB_TP_TS_MAX; + }else{ + qvpt.bit.ts = tmp; + } + tmp = (qos->txtp.mbs - 1)*(qvpt.bit.ts - qptl.bit.tprs)/64; + if (tmp > QSB_TAUS_MAX){ + AMAZON_TPE_EMSG("mbs is too large, mbr:%u taus:%u\n",qos->txtp.mbs, tmp); + qvpt.bit.taus = QSB_TAUS_MAX; + }else if (tmp == 0){ + qvpt.bit.taus = 1; + }else{ + qvpt.bit.taus = tmp; + } + } + }else{ + qvpt.w0 = 0; + } + //write the QSB Queue Parameter Table (QPT) + AMAZON_WRITE_REGISTER_L(QSB_QPT_SET_MASK,QSB_RTM_ADDR); + AMAZON_WRITE_REGISTER_L(qptl.w0, QSB_RTD_ADDR); + AMAZON_WRITE_REGISTER_L((QSB_TABLESEL_QPT<itf; + u32 dma_qos=0; + u8 * qd_addr=NULL; + + tx_config|=CBM_QD_W3_WM_EN|CBM_QD_W3_CLPt; + //RT: check if the connection is a real time connection + if (vcc->qos.txtp.traffic_class == ATM_CBR || vcc->qos.txtp.traffic_class == ATM_VBR_RT){ + tx_config|= CBM_QD_W3_RT; + }else{ + tx_config|= CBM_QD_W3_AAL5; //don't set the AAL5 flag if it is a RT service + } + rx_config = tx_config; + + if(vcc->qos.aal == ATM_AAL5){ + //QoS: DMA QoS according to the traffic class + switch (vcc->qos.txtp.traffic_class){ + case ATM_CBR: dma_qos = CBR_DMA_QOS;break; + case ATM_VBR_RT: dma_qos = VBR_RT_DMA_QOS;break; + case ATM_VBR_NRT: dma_qos = VBR_NRT_DMA_QOS;break; + case ATM_UBR_PLUS: dma_qos = UBR_PLUS_DMA_QOS;break; + case ATM_UBR: dma_qos = UBR_DMA_QOS;break; + } + + //TX: upstream, AAL5(EPD or PPD), NOINT, SBid + tx_config |= CBM_QD_W3_DIR_UP|CBM_QD_W3_INT_NOINT|(itf&CBM_QD_W3_SBID_MASK); + //RX: DMA QoS, downstream, no interrupt, AAL5(EPD, PPD), NO INT, HCR +#ifdef AMAZON_TPE_SCR + rx_config |= dma_qos|CBM_QD_W3_DIR_DOWN|CBM_QD_W3_INT_EOF; +#else + rx_config |= dma_qos|CBM_QD_W3_DIR_DOWN|CBM_QD_W3_INT_NOINT|CBM_QD_W3_HCR; +#endif + }else { + //should be AAL0 + //upstream, NOINT, SBid + tx_config |= CBM_QD_W3_DIR_UP|CBM_QD_W3_INT_NOINT|(itf&CBM_QD_W3_SBID_MASK); + //RX: downstream, ACA interrupt, + rx_config |= CBM_QD_W3_DIR_DOWN|CBM_QD_W3_INT_ACA; + } + + //Threshold: maximum threshold for tx/rx queue, which is adjustable in steps of 64 cells + tx_config |= ( (divide_by_64_round_up(tx_q_threshold)&0xffff)< 1024) + { + AMAZON_TPE_EMSG("timeout\n"); + return -EIO; + } + // write address register, + AMAZON_WRITE_REGISTER_L(idx, HTU_RAMADDR_ADDR); + // configure transmit queue + tmp1 = vpi<<24|vci<<8; + tmp1|= HTU_RAMDAT1_VCON // valid connection the entry is not validated here !!!!!!!!!!!!!!!! + |HTU_RAMDAT1_VCI3 // vci3 -> oam queue + |HTU_RAMDAT1_VCI4 // vci4 -> oam queue + |HTU_RAMDAT1_VCI6 // vci6 -> rm queue + |HTU_RAMDAT1_PTI4 // pti4 -> oam queue + |HTU_RAMDAT1_PTI5; // pti5 -> oam queue + + // ramdat 1 (in params & oam handling) + AMAZON_WRITE_REGISTER_L( tmp1, HTU_RAMDAT1_ADDR); + // ramdat 2 (out params & oam handling) + tmp1 = ((qid+CBM_RX_OFFSET)&HTU_RAMDAT2_QID_MASK) + |HTU_RAMDAT2_PTI6 + |HTU_RAMDAT2_PTI7 + |HTU_RAMDAT2_F4U + |HTU_RAMDAT2_F5U + ; + AMAZON_WRITE_REGISTER_L( tmp1, HTU_RAMDAT2_ADDR); + wmb(); + // write HTU entry + AMAZON_WRITE_REGISTER_L(HTU_RAMCMD_WR, HTU_RAMCMD_ADDR); + return 0; +} +/* + * Brief: add HTU table entry + * Parameter: + * vcc: atm_vcc pointer + * qid: CBM queue id + * Return: + * 0: sucessful + * EIO: HTU table entry cannot be written + */ +inline static int set_htu(struct atm_vcc *vcc, u32 qid) +{ + return set_htu_entry(vcc->vpi, vcc->vci, qid, (qid - CBM_DEFAULT_Q_OFFSET)); +} + +/* + * Brief: allocate a queue + * Return: + * <=0 no available queues + * >0 qid + */ +static int atm_allocate_q(short itf) +{ + int i; + u32 tmp1=0; + int qid=0; + amazon_atm_port_t * dev; + dev = &g_atm_dev.ports[itf]; + //find start queue id for this interface + for (i=0; i< itf; i++) + { + qid+= g_atm_dev.ports[i].max_conn; + } + // apply default queue offset ( oam, free cell queue, others, rm ) + qid += CBM_DEFAULT_Q_OFFSET; + tmp1 = qid; + // search for a free queue + while ( (qidmax_conn) + && ( g_atm_dev.queues[qid].free != 1)) { + qid++;; + } + // if none was found, send failure message and return + if ( tmp1+dev->max_conn == qid) + { + return -EFAULT; + } + return qid; + +} +/* Brief: open a aal5 or aal0 connection + */ +static int atm_open(struct atm_vcc *vcc, push_back_t push) +{ + int err=0; + int qid=0; + amazon_atm_port_t * port = & g_atm_dev.ports[vcc->itf]; + unsigned long flags; + /***************** check bandwidth ******************/ + /* 511045:linmars change ATM_VBR_NRT to use scr instead of pcr */ + if ((vcc->qos.txtp.traffic_class==ATM_CBR&&vcc->qos.txtp.max_pcr>port->tx_rem_cr) + ||(vcc->qos.txtp.traffic_class==ATM_VBR_RT&&vcc->qos.txtp.max_pcr>port->tx_rem_cr) + ||(vcc->qos.txtp.traffic_class==ATM_VBR_NRT&&vcc->qos.txtp.scr>port->tx_rem_cr) + ||(vcc->qos.txtp.traffic_class==ATM_UBR_PLUS&&vcc->qos.txtp.min_pcr>port->tx_rem_cr) + ) { + AMAZON_TPE_EMSG("not enough bandwidth left (%u) cells per seconds \n",port->tx_rem_cr); + return -EINVAL; + } + if ( (qid = amazon_atm_find_vpivci(vcc->vpi, vcc->vci)) >0 ){ + AMAZON_TPE_EMSG("vpi:%u vci:%u is alreay open on queue:%u\n", vcc->vpi, vcc->vci, qid); + return -EADDRINUSE; + } + + /***************** allocate entry queueID for this port *****************/ + if ( (qid=atm_allocate_q(vcc->itf)) <= 0){ + AMAZON_TPE_EMSG("port: %u max:%u qid: %u\n", vcc->itf, port->max_conn, qid); + AMAZON_TPE_EMSG("no availabel connections for this port:%u\n",vcc->itf); + return -EINVAL; + } + /**************QSB parameters and CBM descriptors*************/ + set_qsb(vcc, &vcc->qos, qid); + set_qd(vcc, qid); + mb(); + err=set_htu(vcc,qid); + if (err){ + AMAZON_TPE_EMSG("set htu entry fails %u\n",err); + return err; + } + /************set internal mapping*************/ + local_irq_save(flags); + g_atm_dev.queues[qid].free = 0; + g_atm_dev.queues[qid].vcc = vcc; + g_atm_dev.queues[qid].push = push; + g_atm_dev.queues[qid+CBM_RX_OFFSET].free = 0; + g_atm_dev.queues[qid+CBM_RX_OFFSET].vcc = vcc; + g_atm_dev.queues[qid+CBM_RX_OFFSET].push = push; + /******************reserve bandwidth**********************/ + if (vcc->qos.txtp.traffic_class == ATM_CBR){ + //CBR, real time connection, reserve PCR + port->tx_cur_cr += vcc->qos.txtp.max_pcr; + port->tx_rem_cr -= vcc->qos.txtp.max_pcr; + }else if (vcc->qos.txtp.traffic_class == ATM_VBR_RT){ + //VBR_RT, real time connection, reserve PCR + port->tx_cur_cr += vcc->qos.txtp.max_pcr; + port->tx_rem_cr -= vcc->qos.txtp.max_pcr; + }else if (vcc->qos.txtp.traffic_class == ATM_VBR_NRT){ + //VBR_NRT, reserve SCR + port->tx_cur_cr += vcc->qos.txtp.pcr; + port->tx_rem_cr -= vcc->qos.txtp.pcr; + }else if (vcc->qos.txtp.traffic_class == ATM_UBR_PLUS){ + //UBR_PLUS, reserve MCR + port->tx_cur_cr += vcc->qos.txtp.min_pcr; + port->tx_rem_cr -= vcc->qos.txtp.min_pcr; + } + local_irq_restore(flags); + return err; +} +/* Brief: Open ATM connection + * Parameters: atm_vcc - Pointer to VCC data structure + * vpi - VPI value for new connection + * vci - VCI value for new connection + * + * Return: 0 - sucessful + * -ENOMEM - No memory available + * -EINVAL - No bandwidth/queue/ or unsupported AAL type + * Description: + * This function opens an ATM connection on a specific device/interface + * + */ +int amazon_atm_open(struct atm_vcc *vcc,push_back_t push) +{ + int err=0; + + AMAZON_TPE_DMSG("vpi %u vci %u itf %u aal %u\n" + ,vcc->vpi + ,vcc->vci + ,vcc->itf + ,vcc->qos.aal + ); + + AMAZON_TPE_DMSG("tx cl %u bw %u mtu %u\n" + ,vcc->qos.txtp.traffic_class + ,vcc->qos.txtp.max_pcr + ,vcc->qos.txtp.max_sdu + ); + AMAZON_TPE_DMSG("rx cl %u bw %u mtu %u\n" + ,vcc->qos.rxtp.traffic_class + ,vcc->qos.rxtp.max_pcr + ,vcc->qos.rxtp.max_sdu + ); + if (vcc->qos.aal == ATM_AAL5 || vcc->qos.aal == ATM_AAL0){ + err = atm_open(vcc,push); + }else{ + AMAZON_TPE_EMSG("unsupported aal type %u\n", vcc->qos.aal); + err = -EPROTONOSUPPORT; + }; + if (err == 0 ){ + //replace the default memory allocation function with our own + vcc->alloc_tx = amazon_atm_alloc_tx; + set_bit(ATM_VF_READY,&vcc->flags); + } + return err; +} + +/* Brief: Send ATM OAM cell + * Parameters: atm_vcc - Pointer to VCC data structure + * skb - Pointer to sk_buff structure, that contains the data + * Return: 0 - sucessful + * -ENOMEM - No memory available + * -EINVAL - Not supported + * Description: + * This function sends a cell over and ATM connection + * We always release the skb + * TODO: flags handling (ATM_OF_IMMED, ATM_OF_INRATE) + */ +int amazon_atm_send_oam(struct atm_vcc *vcc, void * cell, int flags) +{ + int err=0; + int qid=0; + struct amazon_atm_cell_header * cell_header; + // Get cell header + cell_header = (struct amazon_atm_cell_header*) cell; + if ((cell_header->bit.pti == ATM_PTI_SEGF5) || (cell_header->bit.pti == ATM_PTI_E2EF5)) { + qid = amazon_atm_find_vpivci( cell_header->bit.vpi, cell_header->bit.vci); + }else if (cell_header->bit.vci == 0x3 || cell_header->bit.vci == 0x4) { + //507281:tc.chen qid = amazon_atm_find_vpi((int) cell_header->bit.vpi); + // 507281:tc.chen start + u8 f4_vpi; + f4_vpi = cell_header->bit.vpi; + qid = amazon_atm_find_vpi(f4_vpi ); + // 507281:tc.chen end + }else{ + //non-OAM cells, always invalid + qid = -EINVAL; + } + if (qid == -EINVAL) { + err = -EINVAL; + AMAZON_TPE_EMSG("not valid AAL0 packet\n"); + }else{ + //send the cell using swie +#ifdef TPE_LOOPBACK + err = amazon_atm_swin(AMAZON_ATM_OAM_Q_ID, cell); +#else + err = amazon_atm_swin(qid, cell); +#endif + } + //kfree(cell); + return err; +} + +/* Brief: Send AAL5 frame through DMA + * Parameters: vpi - virtual path id + * vci - virtual circuit id + * clp - cell loss priority + * qid - CBM queue to be sent to + * skb - packet to be sent + * Return: 0 - sucessful + * -ENOMEM - No memory available + * -EINVAL - Not supported + * Description: + * This function sends a AAL5 frame over and ATM connection + * 1. make sure that the data is aligned to 4x32-bit boundary + * 2. provide the inbound data (CPCS-UU and CPI, not used here) + * 3. set CLPn + * 4. send the frame by DMA + * 5. release the buffer ??? + ** use our own allocation alloc_tx + ** we make sure the alignment and additional memory + *** we always release the skb + + */ +int amazon_atm_dma_tx(u8 vpi, u16 vci, u8 clp, u8 qid, struct sk_buff *skb) +{ + int err=0,need_pop=1; + u32 * data=NULL; + int nwrite=0; + struct sk_buff *skb_tmp; + u32 len=skb->len; + + //AAL5S inbound header 8 bytes + if (skb->len > g_atm_dev.aal5.tx_max_sdu - AAL5S_INBOUND_HEADER) { + AMAZON_TPE_DMSG("tx_max_sdu:%u\n",g_atm_dev.aal5.tx_max_sdu); + AMAZON_TPE_DMSG("skb too large [%u]!\n",skb->len); + err = -EMSGSIZE; + goto atm_dma_tx_error_exit; + } + + //Check the byte alignment requirement and header space + if ( ( ((u32)(skb->data)%16) !=AAL5S_INBOUND_HEADER)|| (skb_headroom(skb)len+16); + if (skb_tmp==NULL){ + err = - ENOMEM; + goto atm_dma_tx_error_exit; + } + alloc_align_16(skb_tmp); + g_atm_dev.aal5.cnt_cpy++; + skb_reserve(skb_tmp,AAL5S_INBOUND_HEADER); + memcpy(skb_put(skb_tmp,skb->len), skb->data, skb->len); + amazon_atm_free_tx_skb(skb); + need_pop=0; + skb = skb_tmp; + } + //Provide AAL5S inbound header + data = (u32 *)skb_push(skb,8); + data[0] = __be32_to_cpu(vpi<<20|vci<<4|clp); + data[1] = __be32_to_cpu(g_atm_dev.aal5.padding_byte<<8|qid); + + len = skb->len; + + //send through DMA + AMAZON_TPE_DMSG("AAL5S header 0 %8x\n", data[0]); + AMAZON_TPE_DMSG("AAL5S header 0 %8x\n", data[1]); + AMAZON_TPE_DMSG("about to call dma_write len: %u\n", len); + nwrite=dma_device_write( &g_dma_dev,skb->data,len,skb); + if (nwrite != len) { + //DMA descriptors full +// AMAZON_TPE_EMSG("AAL5 packet drop due to DMA nwrite:%u skb->len:%u\n", nwrite,len); + AMAZON_TPE_DMSG("AAL5 packet drop due to DMA nwrite:%u skb->len:%u\n", nwrite,len); + err = -EAGAIN; + goto atm_dma_tx_drop_exit; + } + AMAZON_TPE_DMSG("just finish call dma_write\n"); + //release in the "dma done" call-back + return 0; +atm_dma_tx_error_exit: + g_atm_dev.mib_counter.tx_err++; + queue_statics(qid, QS_ERR); + goto atm_dma_tx_exit; + +atm_dma_tx_drop_exit: + g_atm_dev.mib_counter.tx_drop++; + queue_statics(qid, QS_SW_DROP); +atm_dma_tx_exit: + if (need_pop){ + amazon_atm_free_tx_skb(skb); + }else{ + dev_kfree_skb_any(skb); + } + return err; +} + +/* Brief: Send AAL0/AAL5 packet + * Parameters: atm_vcc - Pointer to VCC data structure + * skb - Pointer to sk_buff structure, that contains the data + * Return: 0 - sucessful + * -ENOMEM - No memory available + * -EINVAL - Not supported + * Description: + * See amazon_atm_dma_tx + */ +int amazon_atm_send(struct atm_vcc *vcc,struct sk_buff *skb) +{ + int qid=0; + u8 clp=0; + int err=0; + u32 wm=0; + + if (vcc == NULL || skb == NULL){ + AMAZON_TPE_EMSG("invalid parameter\n"); + return -EINVAL; + } + ATM_SKB(skb)->vcc = vcc; + qid = amazon_atm_get_queue(vcc); + if (valid_qid(qid) != 1) { + AMAZON_TPE_EMSG("invalid vcc!\n"); + err = -EINVAL; + goto atm_send_err_exit; + } + + //Send AAL0 using SWIN + if (vcc->qos.aal == ATM_AAL0){ +#ifdef TPE_LOOPBACK + err=amazon_atm_swin((qid+CBM_RX_OFFSET), skb->data); +#else + err=amazon_atm_swin(qid, skb->data); +#endif + if (err){ + goto atm_send_err_exit; + } + goto atm_send_exit; + } + + //Should be AAl5 + //MIB counter + g_atm_dev.mib_counter.tx++; + adsl_led_flash();//joelin adsl led + queue_statics(qid, QS_PKT); + +#ifdef AMAZON_CHECK_LINK + //check adsl link + if (adsl_link_status == 0){ + //link down + AMAZON_TPE_DMSG("ADSL link down, discarded!\n"); + err=-EFAULT; + goto atm_send_drop_exit; + } +#endif + clp = (vcc->atm_options&ATM_ATMOPT_CLP)?1:0; + //check watermark first + wm = readl(CBM_WMSTAT0_ADDR); + if ( (wm & (1<qos.txtp.traffic_class != ATM_CBR + &&vcc->qos.txtp.traffic_class != ATM_VBR_RT) + &(wm & (CBM_WM_NRT_MASK | (clp&CBM_WM_CLP1_MASK)) ))){ + //wm hit: discard + AMAZON_TPE_DMSG("watermark hit, discarded!\n"); + err=-EFAULT; + goto atm_send_drop_exit; + } +#ifdef TPE_LOOPBACK + return amazon_atm_dma_tx(vcc->vpi, vcc->vci,clp, (qid+CBM_RX_OFFSET),skb); +#else + return amazon_atm_dma_tx(vcc->vpi, vcc->vci,clp, qid,skb); +#endif + +atm_send_exit: + amazon_atm_free_tx_skb_vcc(vcc,skb); + return 0; + +atm_send_drop_exit: + g_atm_dev.mib_counter.tx_drop++; + queue_statics(qid,QS_SW_DROP); +atm_send_err_exit: + amazon_atm_free_tx_skb_vcc(vcc,skb); + return err; +} + +/* Brief: Return ATM port related MIB + * Parameter: interface number + atm_cell_ifEntry_t + */ +int amazon_atm_cell_mib(atm_cell_ifEntry_t* to,u32 itf) +{ + g_atm_dev.mib_counter.htu_unp += readl(HTU_MIBCIUP); + to->ifInUnknownProtos = g_atm_dev.mib_counter.htu_unp; +#ifdef AMAZON_TPE_READ_ARC + u32 reg_val=0; + meiDebugRead((AR_CELL0_ADDR+itf*4),®_val,1); + g_atm_dev.mib_counter.rx_cells += reg_val; + reg_val=0; + meiDebugWrite((AR_CELL0_ADDR+itf*4),®_val,1); + to->ifHCInOctets_h = (g_atm_dev.mib_counter.rx_cells * 53)>>32; + to->ifHCInOctets_l = (g_atm_dev.mib_counter.rx_cells * 53) & 0xffff; + + meiDebugRead((AT_CELL0_ADDR+itf*4),®_val,1); + g_atm_dev.mib_counter.tx_cells += reg_val; + reg_val=0; + meiDebugWrite((AT_CELL0_ADDR+itf*4),®_val,1); + to->ifHCOutOctets_h = (g_atm_dev.mib_counter.tx_cells * 53)>>32; + to->ifHCOutOctets_l = (g_atm_dev.mib_counter.rx_cells * 53) & 0xffff; + + meiDebugRead((AR_CD_CNT0_ADDR+itf*4),®_val,1); + g_atm_dev.mib_counter.rx_err_cells += reg_val; + reg_val=0; + meiDebugWrite((AR_CD_CNT0_ADDR+itf*4),®_val,1); + to->ifInErrors = g_atm_dev.mib_counter.rx_err_cells; + + to->ifOutErrors = 0; +#else + to->ifHCInOctets_h = 0; + to->ifHCInOctets_l = 0; + to->ifHCOutOctets_h = 0; + to->ifHCOutOctets_l = 0; + to->ifInErrors = 0; + to->ifOutErrors = 0; +#endif + return 0; +} + +/* Brief: Return ATM AAL5 related MIB + * Parameter: + atm_aal5_ifEntry_t + */ +int amazon_atm_aal5_mib(atm_aal5_ifEntry_t* to) +{ + u32 reg_l,reg_h; + //AAL5R received Octets from ATM + reg_l = readl(AAL5_RIOL_ADDR); + reg_h = readl(AAL5_RIOM_ADDR); + g_atm_dev.mib_counter.rx_cnt_h +=reg_h; + if (reg_l + g_atm_dev.mib_counter.rx_cnt_l < reg_l){ + g_atm_dev.mib_counter.rx_cnt_h++; + } + + g_atm_dev.mib_counter.rx_cnt_l+= reg_l; + //AAL5S sent Octets to ATM + reg_l = readl(AAL5_SOOL_ADDR); + reg_h = readl(AAL5_SOOM_ADDR); + g_atm_dev.mib_counter.tx_cnt_h +=reg_h; + if (reg_l + g_atm_dev.mib_counter.tx_cnt_l < reg_l){ + g_atm_dev.mib_counter.tx_cnt_h++; + } + g_atm_dev.mib_counter.tx_cnt_l+= reg_l; + + + g_atm_dev.mib_counter.tx_ppd += readl(CBM_AAL5ODIS_ADDR); + g_atm_dev.mib_counter.rx_drop += readl(CBM_AAL5IDIS_ADDR); + + //store + to->ifHCInOctets_h = g_atm_dev.mib_counter.rx_cnt_h; + to->ifHCInOctets_l = g_atm_dev.mib_counter.rx_cnt_l; + to->ifHCOutOctets_h = g_atm_dev.mib_counter.tx_cnt_h; + to->ifHCOutOctets_l = g_atm_dev.mib_counter.tx_cnt_l; + to->ifOutDiscards = g_atm_dev.mib_counter.tx_drop; + to->ifInDiscards = g_atm_dev.mib_counter.rx_drop; + + //Software provided counters + //packets passed to higher layer + to->ifInUcastPkts = g_atm_dev.mib_counter.rx; + //packets passed from higher layer + to->ifOutUcastPkts = g_atm_dev.mib_counter.tx; + //number of wrong downstream packets + to->ifInErrors = g_atm_dev.mib_counter.rx_err; + //number of wrong upstream packets + to->ifOutErros = g_atm_dev.mib_counter.tx_err; + + return 0; +} +/* Brief: Return ATM AAL5 VCC related MIB from internale use + * Parameter: + * qid + * atm_aal5_vcc_t + */ +static int __amazon_atm_vcc_mib(int qid, atm_aal5_vcc_t* to) +{ + //aal5VccCrcErrors + to->aal5VccCrcErrors = g_atm_dev.queues[qid].aal5VccCrcErrors; + to->aal5VccOverSizedSDUs =g_atm_dev.queues[qid].aal5VccOverSizedSDUs; + to->aal5VccSarTimeOuts = 0; //not supported yet + return 0; +} +/* Brief: Return ATM AAL5 VCC related MIB from vpi/vci + * Parameter: atm_vcc + * atm_aal5_vcc_t + */ +int amazon_atm_vcc_mib_x(int vpi, int vci,atm_aal5_vcc_t* to) +{ + int qid=0; + int err=0; + qid = amazon_atm_find_vpivci(vpi, vci); + if (qid >0 ){ + err = __amazon_atm_vcc_mib(qid,to); + }else{ + return -EINVAL; + } + return err; +} + + +/* Brief: Return ATM AAL5 VCC related MIB + * Parameter: atm_vcc + * atm_aal5_vcc_t + */ +int amazon_atm_vcc_mib(struct atm_vcc *vcc,atm_aal5_vcc_t* to) +{ + int qid=0; + int err=0; + qid = amazon_atm_get_queue(vcc); + if (qid >0 ){ + err = __amazon_atm_vcc_mib(qid,to); + }else{ + return -EINVAL; + } + return err; +} + +/* Brief: Close ATM connection + * Parameters: atm_vcc - Pointer to VCC data structure + * Return: no + * Description: + * This function closes the given ATM connection + */ +void amazon_atm_close(struct atm_vcc *vcc){ + int i; + int qid=0; + u32 tmp1; + u8 * qd_addr; + unsigned long flags; + if (vcc == NULL){ + AMAZON_TPE_EMSG("invalid parameter. vcc is null\n"); + return; + } + u32 itf = (u32) vcc->itf; + //release bandwidth + if (vcc->qos.txtp.traffic_class == ATM_CBR){ + g_atm_dev.ports[itf].tx_rem_cr += vcc->qos.txtp.max_pcr; + g_atm_dev.ports[itf].tx_cur_cr -= vcc->qos.txtp.max_pcr; + }else if (vcc->qos.txtp.traffic_class == ATM_VBR_RT){ + g_atm_dev.ports[itf].tx_rem_cr += vcc->qos.txtp.max_pcr; + g_atm_dev.ports[itf].tx_cur_cr -= vcc->qos.txtp.max_pcr; + }else if (vcc->qos.txtp.traffic_class == ATM_VBR_NRT){ + g_atm_dev.ports[itf].tx_rem_cr += vcc->qos.txtp.pcr; + g_atm_dev.ports[itf].tx_cur_cr -= vcc->qos.txtp.pcr; + }else if (vcc->qos.txtp.traffic_class == ATM_UBR_PLUS){ + g_atm_dev.ports[itf].tx_rem_cr += vcc->qos.txtp.min_pcr; + g_atm_dev.ports[itf].tx_cur_cr -= vcc->qos.txtp.min_pcr; + } + + qid = amazon_atm_get_queue(vcc); + if (qid == -EINVAL){ + AMAZON_TPE_EMSG("unknown vcc %u.%u.%u\n", vcc->itf, vcc->vpi, vcc->vci); + return; + } + local_irq_save(flags); + //Disable HTU entry + i=0; + while ((tmp1 = readl(HTU_RAMSTAT_ADDR))!=0 && i < HTU_RAM_ACCESS_MAX) i++; + if (i == HTU_RAM_ACCESS_MAX){ + AMAZON_TPE_EMSG("HTU RAM ACCESS out of time\n"); + } + + // write address register + AMAZON_WRITE_REGISTER_L(qid - CBM_DEFAULT_Q_OFFSET, HTU_RAMADDR_ADDR); + // invalidate the connection + AMAZON_WRITE_REGISTER_L(0, HTU_RAMDAT1_ADDR); + // write command + AMAZON_WRITE_REGISTER_L(HTU_RAMCMD_WR,HTU_RAMCMD_ADDR); + + qd_addr = (u8 *) KSEG1ADDR((unsigned long)g_atm_dev.cbm.qd_addr); +#ifdef AMAZON_ATM_DEBUG + tmp1 = readl(qd_addr+qid*CBM_QD_SIZE+0x8) & 0xffff; + AMAZON_TPE_DMSG("TX queue has %u cells \n", tmp1); + tmp1 = readl( qd_addr+(qid+CBM_RX_OFFSET)*CBM_QD_SIZE+0x08)&0xffff; + AMAZON_TPE_DMSG("RX queue has %u cells \n", tmp1); +#endif + // set threshold of txqueue to 0 + tmp1 = readl(qd_addr+qid*CBM_QD_SIZE+0x0c); + tmp1&= (~ CBM_QD_W3_THRESHOLD_MASK); + AMAZON_WRITE_REGISTER_L(tmp1, (qd_addr+qid*CBM_QD_SIZE+0x0c)); + // set threshold of rxqueue to 0 + tmp1 = readl( qd_addr+(qid+CBM_RX_OFFSET)*CBM_QD_SIZE+0x0c); + tmp1&= (~ CBM_QD_W3_THRESHOLD_MASK); + AMAZON_WRITE_REGISTER_L(tmp1,(qd_addr+(qid+CBM_RX_OFFSET)*CBM_QD_SIZE+0x0c)); + + //clear internal mapping + amazon_atm_clear_vcc(qid); + amazon_atm_clear_vcc(qid+CBM_RX_OFFSET); + + local_irq_restore(flags); +} + + +/* Brief: initialize internal data structure + */ +static void atm_constructor(amazon_atm_dev_t * dev) +{ + int i; + memset(dev,0,sizeof(amazon_atm_dev_t)); + atm_init_parameters(dev); + //internal: queue "free" flag + for(i=1;iqueues[i].vcc=NULL; + dev->queues[i].free = 1; + } + for(i=0;iports[i].tx_rem_cr = dev->ports[i].tx_max_cr; + } + //MIB + atomic_set(&dev->dma_tx_free_0,1); //initially there should be free descriptors +} + +/* Brief: return round up base-2 logarithm + */ +static inline int get_log_2(u32 value) +{ + int i=0,j=1; + while (i<11){ + if (j>=value) break; + j=j<<1; + i++; + } + AMAZON_TPE_DMSG("round up base-2 logarithm of %u is %u\n", value, i); + return i; +} + +/* Brief: TPE hardware initialization + * Parameter: specifiy the configurations of the hardware + */ +static inline int atm_init_hard(amazon_atm_dev_t * dev) +{ + int i; + u32 tmp1, tmp2, tmp3; + u8 * mem_addr=NULL; + u8 * qd_addr=NULL; + //PMU power on the module 1st + *(AMAZON_PMU_PWDCR) = (*AMAZON_PMU_PWDCR) | (AMAZON_PMU_PWDCR_TPE); + //Reset the module + *(AMAZON_RST_REQ) = (* AMAZON_RST_REQ) | (AMAZON_RST_REQ_TPE); + mb(); + mdelay(100); + *(AMAZON_RST_REQ) = (* AMAZON_RST_REQ) & (~(AMAZON_RST_REQ_TPE)); + mb(); + + unsigned long qsb_clk = amazon_get_fpi_hz()>>1; + /*********allocate & arrange memory for CBM *********/ + if (dev->cbm.mem_addr == NULL){ + dev->cbm.allocated = 1; + mem_addr = (u8 *)__get_free_pages(GFP_KERNEL, get_log_2(((CBM_CELL_SIZE * dev->cbm.free_cell_cnt) >>PAGE_SHIFT) + 1)); + if (mem_addr != NULL){ + dev->cbm.mem_addr = mem_addr; + } else { + goto init_no_mem; + } + } + if (dev->cbm.qd_addr == NULL){ +#ifdef CONFIG_USE_VENUS + //to work around a bug, bit15 of QDOFF address should be 1,Aug4, 2004 + //thus, we allocate 64k memory + qd_addr = (u8 *)__get_free_pages(GFP_KERNEL, 4); + if (qd_addr != NULL) { + dev->cbm.qd_addr_free = (u8*) (((unsigned long) qd_addr)); + dev->cbm.qd_addr = (u8*) (((unsigned long) qd_addr) | 0x8000); + }else{ + goto init_no_mem; + } +#else //CONFIG_USE_VENUS + qd_addr = (u8 *)kmalloc( CBM_QD_SIZE * AMAZON_ATM_MAX_QUEUE_NUM, GFP_KERNEL); + if (qd_addr != NULL) { + dev->cbm.qd_addr = qd_addr; + }else { + goto init_no_mem; + } +#endif //CONFIG_USE_VENUS + } +//#ifndef CONFIG_MIPS_UNCACHED + mem_addr = (u8 *)KSEG1ADDR((unsigned long)dev->cbm.mem_addr); + qd_addr = (u8 *)KSEG1ADDR((unsigned long)dev->cbm.qd_addr); +//#endif + //CBM reset cell queue memory, 64 bytes / cell + memset_io(mem_addr, 0, CBM_CELL_SIZE * dev->cbm.free_cell_cnt); + //make a link list, last 4 bytes is pointer + for(i=1;icbm.free_cell_cnt;i++){ + AMAZON_WRITE_REGISTER_L(CPHYSADDR((mem_addr + CBM_CELL_SIZE * i)),(mem_addr + CBM_CELL_SIZE * (i-1) + 0x3c)); + } + //reset queue descriptor + memset_io(qd_addr, 0, CBM_QD_SIZE * AMAZON_ATM_MAX_QUEUE_NUM); + //init word 0-2 of q0 (free cell list) + //address of last cell + AMAZON_WRITE_REGISTER_L(CPHYSADDR((mem_addr + CBM_CELL_SIZE * (dev->cbm.free_cell_cnt-1))), qd_addr); + //address of first cell + AMAZON_WRITE_REGISTER_L(CPHYSADDR((mem_addr)), (qd_addr + 4)); + //no. of free cells + AMAZON_WRITE_REGISTER_L(dev->cbm.free_cell_cnt,(qd_addr + 8)); + //init q descriptor for OAM receiving + AMAZON_WRITE_REGISTER_L((CBM_QD_W3_INT_ACA | (divide_by_64_round_up(oam_q_threshold)&0xff)<< CBM_QD_W3_THRESHOLD_SHIFT), (qd_addr + AMAZON_ATM_OAM_Q_ID * CBM_QD_SIZE + 0x0c)); +// AMAZON_WRITE_REGISTER_L((CBM_QD_W3_INT_ACA | (u32)oam_q_threshold<< CBM_QD_W3_THRESHOLD_SHIFT), (qd_addr + AMAZON_ATM_OAM_Q_ID * CBM_QD_SIZE + 0x0c)); + //config CBM + //set offset address and threshold + AMAZON_WRITE_REGISTER_L(CPHYSADDR(qd_addr), CBM_QDOFF_ADDR); + AMAZON_WRITE_REGISTER_L(((dev->cbm.nrt_thr&CBM_THR_MASK)|CBM_WM_3_1), CBM_NRTTHR_ADDR); + AMAZON_WRITE_REGISTER_L(((dev->cbm.clp0_thr&CBM_THR_MASK)|CBM_WM_3_1), CBM_CLP0THR_ADDR); + AMAZON_WRITE_REGISTER_L(((dev->cbm.clp1_thr&CBM_THR_MASK)|CBM_WM_3_1), CBM_CLP1THR_ADDR); + //config interrupts + AMAZON_WRITE_REGISTER_L( CBM_IMR_MASK & (~(CBM_IMR_ACA|CBM_IMR_Q0E|CBM_IMR_Q0I|CBM_IMR_RDE|CBM_IMR_OPF|CBM_IMR_ERR +#ifdef AMAZON_ATM_DEBUG + |CBM_IMR_DISC|CBM_IMR_QFD|CBM_IMR_NFCA|CBM_IMR_CLP1TR|CBM_IMR_CLP0TR|CBM_IMR_NRTTR|CBM_IMR_QTR +#endif +#ifdef AMAZON_TPE_SCR + |CBM_IMR_EF +#endif + )), CBM_IMR0_ADDR); + AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_CBM_INT, CBM_SRC0_ADDR); + + //HTU + //RAM entry for number of possible connections per interface + tmp1 = dev->ports[0].max_conn?dev->ports[0].max_conn-1:0; + AMAZON_WRITE_REGISTER_L(tmp1, HTU_RX0_ADDR); + for(i=1;iports[i].max_conn; + AMAZON_WRITE_REGISTER_L(tmp1, HTU_RX0_ADDR + 4 * i); + } + dev->cbm.max_q_off = tmp1+1; + //Queue ID for OAM/RM/Other cells + AMAZON_WRITE_REGISTER_L (AMAZON_ATM_OAM_Q_ID, HTU_DESTOAM_ADDR); + AMAZON_WRITE_REGISTER_L( AMAZON_ATM_RM_Q_ID, HTU_DESTRM_ADDR); + AMAZON_WRITE_REGISTER_L( AMAZON_ATM_OTHER_Q_ID, HTU_DESTOTHER_ADDR); + //Timeout + AMAZON_WRITE_REGISTER_L((u32) HTUTIMEOUT, HTU_TIMEOUT_ADDR); +#ifdef AMAZON_ATM_DEBUG + AMAZON_WRITE_REGISTER_L((u32) HTU_ISR_MASK + &(~(HTU_ISR_NE|HTU_ISR_TORD|HTU_ISR_OTOC|HTU_ISR_ONEC|HTU_ISR_PNE|HTU_ISR_PT)), HTU_IMR0_ADDR); + AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS|SRC_SRE_ENABLE|AMAZON_HTU_INT,HTU_SRC0_ADDR); +#endif + //QSB + //global setting, TstepC, SBL, Tau + //Tau + AMAZON_WRITE_REGISTER_L(dev->qsb.tau, QSB_TAU_ADDR); + //SBL + AMAZON_WRITE_REGISTER_L(dev->qsb.sbl, QSB_SBL_ADDR); + //tstep + AMAZON_WRITE_REGISTER_L(dev->qsb.tstepc>>1, QSB_CONFIG_ADDR); + + //port settting + for(i=0;iports[i].enable) && (dev->ports[i].tx_max_cr!=0) ){ + tmp1 = ((qsb_clk * dev->qsb.tstepc) >>1) / dev->ports[i].tx_max_cr; + tmp2 = tmp1 / 64; //integer value of Tsb + tmp3 = tmp1%64 + 1; //fractional part of Tsb + //carry over to integer part (?) + if (tmp3 == 64) { + tmp3 = 0; + tmp2++; + } + if (tmp2 == 0){ + tmp2 = 1; + tmp3 = 1; + } + //1. set mask 2. write value to data transfer register 3. start the transfer + //SCT(FracRate) + AMAZON_WRITE_REGISTER_L(QSB_SET_SCT_MASK, QSB_RTM_ADDR); + AMAZON_WRITE_REGISTER_L(tmp3,QSB_RTD_ADDR); + AMAZON_WRITE_REGISTER_L(((QSB_TABLESEL_SCT<aal5.tx_max_sdu,AAL5_SMFL_ADDR); + AMAZON_WRITE_REGISTER_L(dev->aal5.rx_max_sdu,AAL5_RMFL_ADDR); + AMAZON_WRITE_REGISTER_L(AAL5_SCMD_MODE_POLL // enable polling mode + |AAL5_SCMD_SS + |AAL5_SCMD_AR + ,AAL5_SCMD_ADDR); + //start CBM + AMAZON_WRITE_REGISTER_L(CBM_CFG_START,CBM_CFG_ADDR); + wmb(); + return 0; +init_no_mem: + if (mem_addr != NULL) free_pages((unsigned long)mem_addr,get_log_2(((CBM_CELL_SIZE * dev->cbm.free_cell_cnt) >>PAGE_SHIFT) + 1)); + +#ifdef CONFIG_USE_VENUS + //to work around a bug, bit15 of QDOFF address should be 1 + if (qd_addr != NULL) free_pages((unsigned long)qd_addr,4); +#else //CONFIG_USE_VENUS + if (qd_addr != NULL) kfree(qd_addr); +#endif //CONFIG_USE_VENUS + return -ENOMEM; +} + +/* + * Brief: Create entry in /proc for status information + */ +void atm_create_proc(void) +{ + create_proc_read_entry("amazon_atm", 0,NULL, amazon_atm_read_procmem,(void*)PROC_ATM); + create_proc_read_entry("amazon_atm_mib", 0,NULL, amazon_atm_read_procmem,(void*)PROC_MIB); + create_proc_read_entry("amazon_atm_vcc", 0,NULL, amazon_atm_read_procmem,(void*)PROC_VCC); +#if 0 + create_proc_read_entry("amazon_atm_aal5", 0,NULL, amazon_atm_read_procmem,(void*)PROC_AAL5); + create_proc_read_entry("amazon_atm_cbm", 0,NULL, amazon_atm_read_procmem,(void*)PROC_CBM); + create_proc_read_entry("amazon_atm_htu", 0,NULL, amazon_atm_read_procmem,(void*)PROC_HTU); + create_proc_read_entry("amazon_atm_qsb", 0,NULL, amazon_atm_read_procmem,(void*)PROC_QSB); + create_proc_read_entry("amazon_atm_swie", 0,NULL, amazon_atm_read_procmem,(void*)PROC_SWIE); +#endif +} + +/* + * Brief: Delete entry in /proc for status information + */ +void atm_delete_proc(void) +{ + remove_proc_entry("amazon_atm", NULL); + remove_proc_entry("amazon_atm_mib", NULL); + remove_proc_entry("amazon_atm_vcc", NULL); +#if 0 + remove_proc_entry("amazon_atm_aal5", NULL); + remove_proc_entry("amazon_atm_cbm", NULL); + remove_proc_entry("amazon_atm_htu", NULL); + remove_proc_entry("amazon_atm_qsb", NULL); + remove_proc_entry("amazon_atm_swie", NULL); +#endif +} +/* Brief: Initialize ATM module + * Parameters: no + * Return: &g_atm_dev - sucessful + * NULL - fails: + * 1. invalid parameter + * 2. No memory available + * Description: + * This function configure the TPE components according to the input info, + * -CBM + * -HTU + * -QSB + * -AAL5 + * + */ +amazon_atm_dev_t * amazon_atm_create(void) +{ + int i; + AMAZON_TPE_DMSG("atm_init\n"); + /************initialize global data structure****************/ + atm_constructor(&g_atm_dev); + /***********allocate kernel resources****************/ + //bottom halfs for SWEX + swex_start_task.routine = amazon_atm_swex; + swex_start_task.data = NULL; + swex_complete_task.routine = amazon_atm_swex_push; + swex_complete_task.data = NULL; +#ifdef AMAZON_TPE_SCR + a5r_task.routine = amazon_atm_a5r; + a5r_task.data = NULL; +#endif //AMAZON_TPE_SCR + //SWIN semaphore + sema_init(&(g_atm_dev.swie.in_sem), 1); + //SWIE lock + clear_bit(SWIE_LOCK, &(g_atm_dev.swie.lock)); + //SWIE wait queue + init_waitqueue_head(&(g_atm_dev.swie.sleep)); + atm_create_proc(); + + //register DMA + memset(&g_dma_dev,0,sizeof(struct dma_device_info)); + strcpy(g_dma_dev.device_name,"TPE"); + g_dma_dev.weight=1; + g_dma_dev.num_tx_chan=2; + g_dma_dev.num_rx_chan=2; + g_dma_dev.ack=1; + g_dma_dev.tx_burst_len=4; + g_dma_dev.rx_burst_len=4; + //DMA TX + + for(i=0;i<1;i++){ + g_dma_dev.tx_chan[i].weight=QOS_DEFAULT_WGT; + g_dma_dev.tx_chan[i].desc_num=10; + g_dma_dev.tx_chan[i].packet_size=g_atm_dev.aal5.tx_max_sdu + AAL5S_INBOUND_HEADER; + g_dma_dev.tx_chan[i].control=1; + } + //DMA RX + for(i=0;i<2;i++){ + g_dma_dev.rx_chan[i].weight=QOS_DEFAULT_WGT; + /* BingTao's suggestion, change from 5->10 will prevent packet loss in NO_TX_INT mode */ + g_dma_dev.rx_chan[i].desc_num=10; + g_dma_dev.rx_chan[i].packet_size=(g_atm_dev.aal5.rx_max_sdu + AAL5R_TRAILER_LEN+0x10f)&(~0xf); + g_dma_dev.rx_chan[i].control=1; + } + g_dma_dev.intr_handler=amazon_atm_dma_handler; + g_dma_dev.buffer_alloc=amazon_atm_alloc_rx; + g_dma_dev.buffer_free=amazon_atm_free_tx; + dma_device_register(&g_dma_dev); +/***********intialize the atm hardware ****************/ + if ( atm_init_hard(&g_atm_dev) != 0){ + return NULL; + } + //start CBM + AMAZON_WRITE_REGISTER_L(CBM_CFG_START,CBM_CFG_ADDR); + wmb(); + + //Start HTU + AMAZON_WRITE_REGISTER_L(HTU_CFG_START ,HTU_CFG_ADDR); + wmb(); + + + // Register interrupts for insertion and extraction + request_irq(AMAZON_SWIE_INT, amazon_atm_swie_isr, IRQF_DISABLED, "tpe_swie", NULL); + request_irq(AMAZON_CBM_INT, amazon_atm_cbm_isr, IRQF_DISABLED, "tpe_cbm", NULL); +#ifdef AMAZON_ATM_DEBUG + request_irq(AMAZON_HTU_INT , amazon_atm_htu_isr, IRQF_DISABLED, "tpe_htu", NULL); +#endif +#ifdef AMAZON_TPE_TEST_AAL5_INT + request_irq(AMAZON_AAL5_INT, amazon_atm_aal5_isr, IRQF_DISABLED, "tpe_aal5", NULL); +#endif + return &g_atm_dev; +} + +/* Brief: clean up atm + * Parameters: no + * Return: no + * Description: + * Disable the device. + */ +void amazon_atm_cleanup(void){ + int i; + clear_bit(SWIE_LOCK, &(g_atm_dev.swie.lock)); + wake_up(&g_atm_dev.swie.sleep); + up(&g_atm_dev.swie.in_sem); + // diable SWIE interrupts + AMAZON_WRITE_REGISTER_L(0, SWIE_ISRC_ADDR); + AMAZON_WRITE_REGISTER_L(0, SWIE_ESRC_ADDR); + wmb(); + + // Disable schedulers ( including interrupts )----------------------- + for (i = 0; i < AMAZON_ATM_PORT_NUM; i++); + { + AMAZON_WRITE_REGISTER_L(QSB_SET_SPT_SBVALID_MASK, QSB_RTM_ADDR); + AMAZON_WRITE_REGISTER_L( 0 ,QSB_RTD_ADDR); + AMAZON_WRITE_REGISTER_L( (QSB_TABLESEL_SPT<>PAGE_SHIFT)+1)); +#ifdef CONFIG_USE_VENUS + //to work around a bug, bit15 of QDOFF address should be 1 + free_pages((unsigned long)g_atm_dev.cbm.qd_addr_free,4); +#else //CONFIG_USE_VENUS + kfree(g_atm_dev.cbm.qd_addr); +#endif //CONFIG_USE_VENUS + } + atm_delete_proc(); + // free interrupts for insertion and extraction + dma_device_unregister(&g_dma_dev); + free_irq(AMAZON_SWIE_INT, NULL); + free_irq(AMAZON_CBM_INT, NULL); +#ifdef AMAZON_ATM_DEBUG + free_irq(AMAZON_HTU_INT, NULL); +#endif +#ifdef AMAZON_TPE_TEST_AAL5_INT + free_irq(AMAZON_AAL5_INT, NULL); +#endif + +} + +/************************ ATM network interface ***********************************************/ +/* Brief: getsockopt + */ +int amazon_atm_getsockopt(struct atm_vcc *vcc, int level, int optname, char *optval, int optlen) +{ + int err=0; + atm_aal5_vcc_t mib_vcc; + AMAZON_TPE_DMSG("1\n"); + switch (optname){ + case SO_AMAZON_ATM_MIB_VCC: + AMAZON_TPE_DMSG("2\n"); + err = amazon_atm_vcc_mib(vcc, &mib_vcc); + AMAZON_TPE_DMSG("%u\n",mib_vcc.aal5VccCrcErrors); + err = copy_to_user((void *)optval,&mib_vcc, sizeof(mib_vcc)); + AMAZON_TPE_DMSG("err %u\n",err); + break; + default: + return -EFAULT; + } + return err; +} + +/* Brief: IOCTL + */ + +int amazon_atm_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg) +{ + int err=0; + //MIB + atm_cell_ifEntry_t mib_cell; + atm_aal5_ifEntry_t mib_aal5; + atm_aal5_vcc_x_t mib_vcc; + if (_IOC_TYPE(cmd) != AMAZON_ATM_IOC_MAGIC) return -ENOTTY; + if (_IOC_NR(cmd) > AMAZON_ATM_IOC_MAXNR) return -ENOTTY; + + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd)); + if (err) { + AMAZON_TPE_EMSG("acess verification fails \n"); + return -EFAULT; + } + switch(cmd) { + case AMAZON_ATM_MIB_CELL: + err = amazon_atm_cell_mib(&mib_cell,(u32)arg); + if (err==0){ + err = __copy_to_user((void *)arg,&mib_cell,sizeof(mib_cell)); + }else{ + AMAZON_TPE_EMSG("cannot get MIB ATM_CELL\n"); + } + break; + case AMAZON_ATM_MIB_AAL5: + err = amazon_atm_aal5_mib(&mib_aal5); + if (err==0){ + err=__copy_to_user(arg, &mib_aal5, sizeof(mib_aal5)); + }else{ + AMAZON_TPE_EMSG("cannot get MIB ATM_AAL5\n"); + } + break; + case AMAZON_ATM_MIB_VCC: + err=__copy_from_user(&mib_vcc,arg, sizeof(mib_vcc)); + AMAZON_TPE_DMSG("return of copy_from_user %x\n",err); + err = amazon_atm_vcc_mib_x(mib_vcc.vpi, mib_vcc.vci, &(mib_vcc.mib_vcc)); + if (err==0){ + err=__copy_to_user(arg, &mib_vcc, sizeof(mib_vcc)); + }else{ + AMAZON_TPE_EMSG("cannot get MIB ATM_VCC\n"); + } + + default: + return -ENOTTY; + } + return err; +} +/* Brief: return a link list of OAM related time stamp info + * Parameter: none + * Return: + a link list of "struct oam_last_activity" data + * Description: + Each time, a F4/F5 cell or AAL5 packet is received, the time stamp is updated. + Through this call, u get a list of this time stamp for all active connection. + Please note that u have read-only access. + */ +const struct oam_last_activity* get_oam_time_stamp() +{ + int i,j; + for(i=CBM_DEFAULT_Q_OFFSET+CBM_RX_OFFSET,j=0;ivpi; + g_oam_time_stamp[j].vci = g_atm_dev.queues[i].vcc->vci; + g_oam_time_stamp[j].stamp = g_atm_dev.queues[i].access_time; + g_oam_time_stamp[j].next = NULL; + j++; + } + } + if (j==0) { + return NULL; + }else{ + return g_oam_time_stamp; + } +} + + +/* Brief: call back routine for rx + * Parameter: + * vcc atm_vcc pointer + * skb data if no error + err error flag, 0: no error, 1:error + * Return: + * 0 + * <>0 cannot push up + * Description: + * release the packet if cannot push up + */ +static int amazon_atm_net_push(struct atm_vcc *vcc,struct sk_buff *skb, int err) +{ + if (err){ + if (vcc && vcc->stats) { + atomic_inc(&vcc->stats->rx_err); + } + }else{ + ATM_SKB(skb)->vcc = vcc; + + if (!atm_charge(vcc, skb->truesize)){ + //no space this vcc + AMAZON_TPE_EMSG("no space for this vcc\n"); + dev_kfree_skb_any(skb); + return -ENOMEM; + } + atomic_inc(&vcc->stats->rx); + AMAZON_TPE_DMSG("push to vcc\n"); + vcc->push(vcc,skb); + } + return 0; +} +int amazon_atm_net_send_oam(struct atm_vcc*vcc, void *cell, int flags) +{ + return amazon_atm_send_oam(vcc,cell,flags); +} + +int amazon_atm_net_send(struct atm_vcc *vcc,struct sk_buff *skb) +{ + int err=0; + if (vcc->qos.aal == ATM_AAL0 || vcc->qos.aal == ATM_AAL5) { + err=amazon_atm_send(vcc,skb); + }else{ + //not supported + err = -EPROTONOSUPPORT; + } + if (err){ + atomic_inc(&vcc->stats->tx_err); + }else{ + atomic_inc(&vcc->stats->tx); + } + AMAZON_TPE_DMSG("sent, tx_inuse:%u\n", atomic_read(&vcc->tx_inuse)); + return err; +} + +int amazon_atm_net_open(struct atm_vcc *vcc,short vpi, int vci) +{ + vcc->itf = (int) vcc->dev->dev_data; + vcc->vpi = vpi; + vcc->vci = vci; + return(amazon_atm_open(vcc,amazon_atm_net_push)); +} + +static int amazon_atm_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flgs) +{ + int qid; + + if (vcc == NULL || qos == NULL){ + AMAZON_TPE_EMSG("invalid parameters\n"); + return -EINVAL; + } + qid = amazon_atm_get_queue(vcc); + if (valid_qid(qid) != 1) { + AMAZON_TPE_EMSG("no vcc connection opened\n"); + return -EINVAL; + } + set_qsb(vcc,qos,qid); + return 0; +} + +static struct atmdev_ops amazon_atm_ops = { + open: amazon_atm_net_open, + close: amazon_atm_close, + ioctl: amazon_atm_ioctl, + send: amazon_atm_net_send, + send_oam: amazon_atm_net_send_oam, +// getsockopt: amazon_atm_getsockopt, + change_qos: amazon_atm_change_qos, +// proc_read: amazon_atm_proc_read, + owner: THIS_MODULE, +}; // ATM device callback functions + +/* + * brief "/proc" function + */ +int amazon_atm_read_procmem(char *buf, char **start, off_t offset,int count, int *eof, void *data) +{ + int buf_off=0; /* for buf */ + int i=0,j=0; + int type= (u32)data;//which module + atm_aal5_ifEntry_t mib_aal5; + atm_cell_ifEntry_t mib_cell; + atm_aal5_vcc_t mib_vcc; + switch(type){ + case PROC_MIB: + //MIB counter + amazon_atm_aal5_mib(&mib_aal5); + //TX: + buf_off+=sprintf(buf+buf_off,"\n============= AAL5 Upstream =========\n"); + buf_off+=sprintf(buf+buf_off,"received %u (pkts) from upper layer\n", mib_aal5.ifOutUcastPkts); + buf_off+=sprintf(buf+buf_off,"errors: %u (pkts)\n",mib_aal5.ifOutErros); + buf_off+=sprintf(buf+buf_off,"discards: %u (ptks)\n", mib_aal5.ifOutDiscards); + buf_off+=sprintf(buf+buf_off,"transmitted: %x-%x (bytes) \n", + mib_aal5.ifHCOutOctets_h, mib_aal5.ifHCOutOctets_l); + //RX: + buf_off+=sprintf(buf+buf_off,"\n============= AAL5 Downstream =========\n"); + buf_off+=sprintf(buf+buf_off,"received %x-%x (bytes)\n", + mib_aal5.ifHCInOctets_h,mib_aal5.ifHCInOctets_l); + buf_off+=sprintf(buf+buf_off,"discards: %u (ptks)\n",mib_aal5.ifInDiscards); + buf_off+=sprintf(buf+buf_off,"errors: %u (ptks)\n",mib_aal5.ifInErrors); + buf_off+=sprintf(buf+buf_off,"passed %u (ptks) to upper layer\n",mib_aal5.ifInUcastPkts); + + //Cell level + buf_off+=sprintf(buf+buf_off,"\n============= ATM Cell =========\n"); + amazon_atm_cell_mib(&mib_cell,0); +#ifdef AMAZON_TPE_READ_ARC + buf_off+=sprintf(buf+buf_off,"Port 0: downstream received: %x-%x (bytes)\n",mib_cell.ifHCInOctets_h,mib_cell.ifHCInOctets_l); + buf_off+=sprintf(buf+buf_off,"Port 0: upstream transmitted: %x-%x (bytes)\n",mib_cell.ifHCOutOctets_h,mib_cell.ifHCOutOctets_l); + buf_off+=sprintf(buf+buf_off,"Port 0: downstream errors: %u (cells)\n",mib_cell.ifInErrors); + amazon_atm_cell_mib(&mib_cell,1); + buf_off+=sprintf(buf+buf_off,"Port 1: downstream received: %x-%x (bytes)\n",mib_cell.ifHCInOctets_h,mib_cell.ifHCInOctets_l); + buf_off+=sprintf(buf+buf_off,"Port 1: upstream transmitted: %x-%x (bytes)\n",mib_cell.ifHCOutOctets_h,mib_cell.ifHCOutOctets_l); + buf_off+=sprintf(buf+buf_off,"Port 1: downstream errors: %u (cells)\n",mib_cell.ifInErrors); +#endif + buf_off+=sprintf(buf+buf_off,"HTU discards: %u (cells)\n",mib_cell.ifInUnknownProtos); + + buf_off+=sprintf(buf+buf_off,"\n====== Specials =====\n"); + buf_off+=sprintf(buf+buf_off,"AAL5S PPD: %u (cells)\n",g_atm_dev.mib_counter.tx_ppd); +#ifdef AMAZON_TPE_SCR + buf_off+=sprintf(buf+buf_off,"Reassembly wait: %u \n",g_a5r_wait); +#endif + break; + case PROC_ATM: + //Interface (Port) + buf_off+=sprintf(buf+buf_off,"[Interfaces]\n"); + for(i=0;ivpi + ,g_atm_dev.queues[i].vcc->vci + ,g_atm_dev.queues[i].vcc->itf + ,i + ,(u32)g_atm_dev.queues[i+CBM_RX_OFFSET].access_time.tv_sec + ,(u32)g_atm_dev.queues[i+CBM_RX_OFFSET].access_time.tv_usec + ); + buf_off+=sprintf(buf+buf_off,"\tqos_tx class=%u max_pcr=%u pcr=%u min_pcr=%u scr=%u mbs=%u cdv=%u\n" + ,g_atm_dev.queues[i].vcc->qos.txtp.traffic_class + ,g_atm_dev.queues[i].vcc->qos.txtp.max_pcr + ,g_atm_dev.queues[i].vcc->qos.txtp.pcr + ,g_atm_dev.queues[i].vcc->qos.txtp.min_pcr + ,g_atm_dev.queues[i].vcc->qos.txtp.scr + ,g_atm_dev.queues[i].vcc->qos.txtp.mbs + ,g_atm_dev.queues[i].vcc->qos.txtp.cdv + ); + buf_off+=sprintf(buf+buf_off,"\tqos_rx class=%u max_pcr=%u pcr=%u min_pcr=%u scr=%u mbs=%u cdv=%u\n" + ,g_atm_dev.queues[i].vcc->qos.rxtp.traffic_class + ,g_atm_dev.queues[i].vcc->qos.rxtp.max_pcr + ,g_atm_dev.queues[i].vcc->qos.rxtp.pcr + ,g_atm_dev.queues[i].vcc->qos.rxtp.min_pcr + ,g_atm_dev.queues[i].vcc->qos.rxtp.scr + ,g_atm_dev.queues[i].vcc->qos.rxtp.mbs + ,g_atm_dev.queues[i].vcc->qos.rxtp.cdv + ); + __amazon_atm_vcc_mib((i+CBM_RX_OFFSET),&mib_vcc); + buf_off+=sprintf(buf+buf_off,"\tCRC error=%u\n", mib_vcc.aal5VccCrcErrors); + buf_off+=sprintf(buf+buf_off,"\toversized packet=%u\n", mib_vcc.aal5VccOverSizedSDUs); +#ifdef AMAZON_ATM_DEBUG + if ( valid_qid(i+CBM_RX_OFFSET)){ + buf_off+=sprintf(buf+buf_off,"\tdownstream statics\n" ); + buf_off+=sprintf(buf+buf_off,"\t\tpackets=%u\n",g_atm_dev.queues[i+CBM_RX_OFFSET].qs[QS_PKT]); + buf_off+=sprintf(buf+buf_off,"\t\terr_packets=%u\n",g_atm_dev.queues[i+CBM_RX_OFFSET].qs[QS_ERR] ); + buf_off+=sprintf(buf+buf_off,"\t\tsw_dropped=%u\n",g_atm_dev.queues[i+CBM_RX_OFFSET].qs[QS_SW_DROP] ); + } + + buf_off+=sprintf(buf+buf_off,"\tupstream statics\n" ); + buf_off+=sprintf(buf+buf_off,"\t\tpackets=%u\n",g_atm_dev.queues[i].qs[QS_PKT]); + buf_off+=sprintf(buf+buf_off,"\t\terr_packets=%u\n",g_atm_dev.queues[i].qs[QS_ERR] ); + buf_off+=sprintf(buf+buf_off,"\t\thw_dropped=%u\n",g_atm_dev.queues[i].qs[QS_HW_DROP] ); + buf_off+=sprintf(buf+buf_off,"\t\tsw_dropped=%u\n",g_atm_dev.queues[i].qs[QS_SW_DROP] ); + +#endif + + } + + } + break; + default: + break; + } + if(buf_off>0) *eof = 1; + return buf_off; +} + +#ifdef AMAZON_TPE_AAL5_RECOVERY +extern int (*tpe_reset)(void); +extern int (*tpe_start)(void); +extern int (*tpe_inject)(void); +/* Brief: Reset TPE hardware + * Description + * This is a wordaround for AAL5 bug. It tries to reset TPE. + * take care of software + * setup all previous connection + */ +int amazon_tpe_reset(void) +{ + struct atm_vcc * vcc; + int err=0; + int i; + u8 * qd_addr; + u32 reg_l, reg_h; + unsigned int a_cfg_value=0; + unsigned int a_cfg_old_value=0; + atm_aal5_ifEntry_t mib_aal5; + atm_cell_ifEntry_t mib_cell; + + //make sure all cells transmitting out first + //Segmentation done + amazon_atm_aal5_mib(&mib_aal5); + reg_l = g_atm_dev.mib_counter.tx_cnt_l; + reg_h = g_atm_dev.mib_counter.tx_cnt_h; + while(1){ + mdelay(10); + amazon_atm_aal5_mib(&mib_aal5); + if( (reg_l == g_atm_dev.mib_counter.tx_cnt_l) && (reg_h == g_atm_dev.mib_counter.tx_cnt_h) ){ + break; + } + AMAZON_TPE_DMSG("AAL5 Segmentation still in progress!\n"); + reg_l = g_atm_dev.mib_counter.tx_cnt_l; + reg_h = g_atm_dev.mib_counter.tx_cnt_h; + } + //QSB done + qd_addr = (u8 *) KSEG1ADDR((unsigned long)g_atm_dev.cbm.qd_addr); + for (i=1;i<15;i++){ + while ( (err=readl(qd_addr+i*CBM_QD_SIZE+0x8)&0xffff) !=0 ){ + mdelay(20); + AMAZON_TPE_DMSG("queue %u not empty (%u)\n",i,err); + } + } + //insurance for interfaces between Aware and CARB + mdelay(100); + amazon_atm_cell_mib(&mib_cell,0); + amazon_atm_cell_mib(&mib_cell,1); + amazon_atm_aal5_mib(&mib_aal5); + + mb(); + while ( (AMAZON_READ_REGISTER_L(AR_CELLRDY_BC0) != 0 ) || (AMAZON_READ_REGISTER_L(AR_CELLRDY_BC0) != 0 ) ){ + AMAZON_TPE_EMSG("\nwaiting for AWARE"); + AMAZON_TPE_EMSG(" BC0 %u ", AMAZON_READ_REGISTER_L(AR_CELLRDY_BC0)); + AMAZON_TPE_EMSG(" BC1 %u ", AMAZON_READ_REGISTER_L(AR_CELLRDY_BC1)); + AMAZON_TPE_EMSG("\n"); + mdelay(1); + } + // disable AAI module + meiDebugRead(A_CFG_ADDR,&a_cfg_value,1); + a_cfg_old_value=a_cfg_value; + a_cfg_value &= (~(0x2800)); + meiDebugWrite(A_CFG_ADDR,&a_cfg_value,1); + //clear buffer + a_cfg_value = 0x1; + meiDebugWrite(AR_CB0_STATUS_ADDR,&a_cfg_value,1); + meiDebugWrite(AR_CB1_STATUS_ADDR,&a_cfg_value,1); + + if ( atm_init_hard(&g_atm_dev) != 0){ + return -EIO; + } + sema_init(&(g_atm_dev.swie.in_sem), 1); + //SWIE lock + clear_bit(SWIE_LOCK, &(g_atm_dev.swie.lock)); + //SWIE wait queue + init_waitqueue_head(&(g_atm_dev.swie.sleep)); + + for (i=CBM_DEFAULT_Q_OFFSET;iqos, i); + set_qd(vcc, i); + mb(); + err=set_htu(vcc,i); + if (err){ + AMAZON_TPE_EMSG("set htu entry fails %u\n",err); + } + } + } + meiDebugWrite(A_CFG_ADDR,&a_cfg_old_value,1); +#if 0 + //reset DFE + *(AMAZON_RST_REQ) = (* AMAZON_RST_REQ) | (AMAZON_RST_REQ_DFE); + mb(); + *(AMAZON_RST_REQ) = (* AMAZON_RST_REQ) & (~AMAZON_RST_REQ_DFE); + mb(); +#endif + + return 0; +} + +/* Brief: Send a ATM EoP packet to save DMA channel + */ +int amazon_tpe_inject_debug_cell(void) +{ + //Send a ATM cell to save DMA channel + u8 qid; + unsigned char atm_cell[48]; + qid = 0x11; + AMAZON_TPE_DMSG("qid = %d\n",qid); + memset(atm_cell,0,48); + atm_cell[3] = 0x2; + if ( amazon_atm_swin(qid,atm_cell)) { + AMAZON_TPE_EMSG("cannot insert EoP cell\n"); + return -1; + } + return 0; +} + +/* Brief: start HTU (TPE) + */ + +int amazon_tpe_start(void) +{ + AMAZON_WRITE_REGISTER_L(HTU_CFG_START ,HTU_CFG_ADDR); + wmb(); + return 0; +} +#endif //AMAZON_TPE_AAL5_RECOVERY + +#ifdef AMAZON_CHECK_LINK +extern int (*adsl_link_notify)(int); +/* Brief: notify link status of ADSL link + * Parameters: 0 link down + * 1 link up + * Returns: 0 OK + * Details: called by MEI driver + * should update status and inform upper layer + */ +int amazon_tpe_link_notify(int status) +{ + adsl_link_status = status; + AMAZON_TPE_DMSG("link status %s\n",(status==1)?"Up":"Down"); + if (status == 0){ + //wait until no cells in upstream queues + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(2*HZ); + } + return 0; +} +#endif //ifdef AMAZON_CHECK_LINK + +/* + * Brief: Initialize ATM module + * + * Return Value: ENOMEM - No memory available + * EBUSY - Cannot register atm device + * ERESTARTSYS - Process interrupted by other signal + * 0 - OK, module initialized + * + * Description: + * This function registers an atm device for all UTOPIA devices. + * It also allocates memory for the private device data structures + */ +int __init amazon_atm_net_init(void) +{ + int i; + int err=0; + amazon_atm_dev_t *dev = NULL; + + if ((dev=amazon_atm_create()) != NULL){ + for(i=0;iports[i].enable){ + amazon_atm_devs[i] = NULL; + continue; + } + amazon_atm_devs[i] =atm_dev_register("amazon_atm",&amazon_atm_ops,-1,0UL); + if (amazon_atm_devs[i] == NULL){ + AMAZON_TPE_EMSG("atm_dev_register fails\n"); + err = -EIO; + goto amazon_atm_net_init_exit; + }else{ + AMAZON_TPE_DMSG("registering device %u\n",i); + amazon_atm_devs[i]->ci_range.vpi_bits = 8; + amazon_atm_devs[i]->ci_range.vci_bits = 16; + amazon_atm_devs[i]->link_rate = dev->ports[i].tx_max_cr; + amazon_atm_devs[i]->dev_data = (void *) i; + } + } + + }else{ + err = -ENOMEM; + AMAZON_TPE_EMSG("cannot init atm device\n"); + goto amazon_atm_net_init_exit; + } +#ifdef AMAZON_TPE_AAL5_RECOVERY + tpe_reset = & amazon_tpe_reset; + tpe_start = & amazon_tpe_start; + tpe_inject = & amazon_tpe_inject_debug_cell; +#endif //AMAZON_TPE_AAL5_RECOVERY +#ifdef AMAZON_CHECK_LINK + adsl_link_notify=amazon_tpe_link_notify; +#endif //AMAZON_CHECK_LINK +amazon_atm_net_init_exit: + return err; +} + +void __exit amazon_atm_net_cleanup(void) +{ + int i; + amazon_atm_cleanup(); + for(i=0;i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define SET_BIT(reg, mask) reg |= (mask) +#define CLEAR_BIT(reg, mask) reg &= (~mask) +#define CLEAR_BITS(reg, mask) CLEAR_BIT(reg, mask) +#define SET_BITS(reg, mask) SET_BIT(reg, mask) +#define SET_BITFIELD(reg, mask, off, val) {reg &= (~mask); reg |= (val << off);} + +extern void mask_and_ack_amazon_irq(unsigned int irq_nr); + +#ifdef AMAZON_CHECK_LINK +//amazon_tpe.c +extern int (*adsl_link_notify)(int); +#endif //AMAZON_CHECK_LINK + +// for ARC memory access +#define WHILE_DELAY 20000 +#define AMAZON_DMA_DEBUG_MUTEX + + +//TODO +#undef DFE_LOOPBACK +#define ARC_READY_ACK + +static amazon_mei_mib * current_intvl; +static struct list_head interval_list; +static amazon_mei_mib * mei_mib; + +static int reboot_firsttime=1;//000002:fchang + + //PCM +#define PCM_CHANNEL_NUM 2 //1 rx, 1 tx +static pcm_data_struct pcm_data[PCM_CHANNEL_NUM]__attribute__ ((aligned(4))); //0=tx0, 1=rx0, 2=tx1, 3=rx1 +static u32 pcm_start_addr; +//#define PCM_HRT_TIME_HZ 4000 //?us +#define PCM_ACCESS_DEBUG +static int irqtimes=0; +#undef DATA_LED_ON_MODE +#define ADSL_LED_SUPPORT //joelin for adsl led +#ifdef ADSL_LED_SUPPORT +static int firmware_support_led=0; //joelin version check for adsl led +static int stop_led_module=0; //wakeup and clean led module +static int led_support_check=0; //1.1.2.7.1.1 +#endif //ADSL_LED_SUPPORT +#define IFX_DYING_GASP +#ifdef IFX_DYING_GASP +static wait_queue_head_t wait_queue_dying_gasp; //dying gasp +//struct tq_struct dying_gasp_task; //dying gasp +static wait_queue_head_t wait_queue_uas_poll; //joelin 04/16/2005 +static u16 unavailable_seconds=0; //joelin 04/16/2005 +static meidebug lop_debugwr; //dying gasp +#endif //IFX_DYING_GASP +static int dbg_int=0; +//#define DEBUG_ACCESS_DELAY for(dbg_int=0;dbg_int<100;dbg_int++){;} +#define DEBUG_ACCESS_DELAY +static u8 sampledata[512]; +static int firsttime[PCM_CHANNEL_NUM]={0,1}; +static int num_cmp[PCM_CHANNEL_NUM]={0,0}; +static int pcm_start_loc[PCM_CHANNEL_NUM]={0,0}; + + // for clearEoC +//#define MEI_CLREOC_BUFF_SIZE 512 //double the receive fifo size, bytes +//static u8 clreoc[MEI_CLREOC_BUFF_SIZE]__attribute__ ((aligned(4))); //buffer to hold clearEoC data in bytes +#undef AMAZON_CLEAR_EOC +#ifdef AMAZON_CLEAR_EOC +extern void ifx_push_eoc(struct sk_buff * pkt); +#endif +static int meiResetArc(void); +#define IFX_POP_EOC_DONE 0 +#define IFX_POP_EOC_FAIL -1 +static struct list_head clreoc_list; +static amazon_clreoc_pkt * clreoc_pkt; +#define CLREOC_BUFF_SIZE 12 //number of clreoc commands being buffered +//static int clreoc_wr=0; +//static int clreoc_rd=0; //used to control clreoc circular buffer +static wait_queue_head_t wait_queue_clreoc; +#ifdef ADSL_LED_SUPPORT +static wait_queue_head_t wait_queue_led; //adsl led +static wait_queue_head_t wait_queue_led_polling;// adsl led +struct tq_struct led_task; // adsl led +static DECLARE_TASK_QUEUE(tq_ifx_led); // task +int adsl_led_flash_task(void *ptr); // adsl led +#endif //ADSL_LED_SUPPORT +static void * clreoc_command_pkt=NULL; +static int clreoc_max_tx_len=0; + +// 603221:tc.chen start +#define ME_HDLC_IDLE 0 +#define ME_HDLC_INVALID_MSG 1 +#define ME_HDLC_MSG_QUEUED 2 +#define ME_HDLC_MSG_SENT 3 +#define ME_HDLC_RESP_RCVD 4 +#define ME_HDLC_RESP_TIMEOUT 5 +#define ME_HDLC_RX_BUF_OVERFLOW 6 +#define ME_HDLC_UNRESOLVED 1 +#define ME_HDLC_RESOLVED 2 +// 603221:tc.chen end + +#ifdef LOCK_RETRY +static int reboot_lock=0; +#endif + +static mib_previous_read mib_pread={0,0,0,0,0,0,0,0,0,0,0,0}; +static mib_flags_pretime mib_pflagtime;// initialized when module loaded + + static u32 ATUC_PERF_LOFS=0; + static u32 ATUC_PERF_LOSS=0; + static u32 ATUC_PERF_ESS=0; + static u32 ATUC_PERF_INITS=0; + static u32 ATUR_PERF_LOFS=0; + static u32 ATUR_PERF_LOSS=0; + static u32 ATUR_PERF_LPR=0; + static u32 ATUR_PERF_ESS=0; + static u32 ATUR_CHAN_RECV_BLK=0; + static u32 ATUR_CHAN_TX_BLK=0; + static u32 ATUR_CHAN_CORR_BLK=0; + static u32 ATUR_CHAN_UNCORR_BLK=0; + //RFC-3440 + static u32 ATUC_PERF_STAT_FASTR=0; + static u32 ATUC_PERF_STAT_FAILED_FASTR=0; + static u32 ATUC_PERF_STAT_SESL=0; + static u32 ATUC_PERF_STAT_UASL=0; + static u32 ATUR_PERF_STAT_SESL=0; + static u32 ATUR_PERF_STAT_UASL=0; + + static adslChanPrevTxRate PrevTxRate={0,0}; + static adslPhysCurrStatus CurrStatus={0,0}; + static ChanType chantype={0,0}; + static adslLineAlarmConfProfileEntry AlarmConfProfile={"No Name\0",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; +// 603221:tc.chen start + static adslFarEndPerfStats FarendStatsData; + struct timeval FarendData_acquire_time={0}; + static u32 adsl_mode,adsl_mode_extend; // adsl mode : adsl/ 2/ 2+ + static adslInitStats AdslInitStatsData; +//603221:tc.chen end +static u32 loop_diagnostics_mode=0; +static wait_queue_head_t wait_queue_loop_diagnostic; +#ifdef AMAZON_MEI_MIB_RFC3440 + static adslLineAlarmConfProfileExtEntry AlarmConfProfileExt={"No Name\0",0,0,0,0,0,0}; +#endif + +static int showtime=0; +static int loop_diagnostics_completed=0; +////////////////////////////////////////////////////////////////////////////////// +static int phy_mei_net_init(struct net_device * dev); +static int interleave_mei_net_init(struct net_device * dev); +static int fast_mei_net_init(struct net_device * dev); +static struct net_device_stats * phy_mei_net_get_stats(struct net_device * dev); +static struct net_device_stats * interleave_mei_net_get_stats(struct net_device * dev); +static struct net_device_stats * fast_mei_net_get_stats(struct net_device * dev); + +typedef struct mei_priv{ + struct net_device_stats stats; +}mei_priv; + +static struct net_device phy_mei_net = { init: phy_mei_net_init, name: "MEI_PHY"}; +static struct net_device interleave_mei_net = { init: interleave_mei_net_init, name: "MEI_INTL"}; +static struct net_device fast_mei_net = { init: fast_mei_net_init, name: "MEI_FAST"}; +/////////////////////////////////////////////////////////////////////////////////// + +static int major=AMAZON_MEI_MAJOR; + +static struct semaphore mei_sema; + +// Mei to ARC CMV count, reply count, ARC Indicator count +static int indicator_count=0; +static int cmv_count=0; +static int reply_count=0; +static u16 Recent_indicator[MSG_LENGTH]; + +// Used in interrupt handler as flags +static int arcmsgav=0; +static int cmv_reply=0; +static int cmv_waiting=0; + +#define PROC_ITEMS 8 + +long mei_debug_mode = 0; //509221:tc.chen for adsl firmware debug + +// to wait for arc cmv reply, sleep on wait_queue_arcmsgav; +static wait_queue_head_t wait_queue_arcmsgav; +static wait_queue_head_t wait_queue_codeswap; +static wait_queue_head_t wait_queue_mibdaemon; +static wait_queue_head_t wait_queue_reboot; +static u32 * image_buffer=NULL; // holding adsl firmware image +static u16 RxMessage[MSG_LENGTH]__attribute__ ((aligned(4))); +static u16 TxMessage[MSG_LENGTH]__attribute__ ((aligned(4))); +static u32 * mei_arc_swap_buff=NULL; // holding swap pages +static ARC_IMG_HDR * img_hdr; +static int reboot_flag; + +#ifdef DFE_LOOPBACK +#include "arc_pm.h" +#endif + + +///////////////// net device /////////////////////////////////////////////////// +static int phy_mei_net_init(struct net_device * dev) +{ + //ether_setup(dev); + dev->get_stats = phy_mei_net_get_stats; + dev->ip_ptr = NULL; + dev->type = 94; + +// dev->mtu=12345; + dev->flags=IFF_UP; + + dev->priv = kmalloc(sizeof(struct mei_priv), GFP_KERNEL); + if(dev->priv == NULL) + return -ENOMEM; + memset(dev->priv, 0, sizeof(struct mei_priv)); + return 0; +} + +static int interleave_mei_net_init(struct net_device * dev) +{ + //ether_setup(dev); + dev->get_stats = interleave_mei_net_get_stats; + dev->ip_ptr = NULL; + dev->type = 124; + dev->flags=IFF_UP; + dev->priv = kmalloc(sizeof(struct mei_priv), GFP_KERNEL); + if(dev->priv == NULL) + return -ENOMEM; + memset(dev->priv, 0, sizeof(struct mei_priv)); + return 0; +} + +static int fast_mei_net_init(struct net_device * dev) +{ + //ether_setup(dev); + dev->get_stats = fast_mei_net_get_stats; + dev->ip_ptr = NULL; + dev->type = 125; + dev->flags=IFF_UP; + dev->priv = kmalloc(sizeof(struct mei_priv), GFP_KERNEL); + if(dev->priv == NULL) + return -ENOMEM; + memset(dev->priv, 0, sizeof(struct mei_priv)); + return 0; +} + +static struct net_device_stats * phy_mei_net_get_stats(struct net_device * dev) +{ + struct mei_priv * priv; + priv = (struct mei_priv *)dev->priv; + // update statistics + (priv->stats).rx_packets = ATUR_CHAN_RECV_BLK; + (priv->stats).tx_packets = ATUR_CHAN_TX_BLK; + (priv->stats).rx_errors = ATUR_CHAN_CORR_BLK + ATUR_CHAN_UNCORR_BLK; + (priv->stats).rx_dropped = ATUR_CHAN_UNCORR_BLK; + + return &(priv->stats); +} + +static struct net_device_stats * interleave_mei_net_get_stats(struct net_device * dev) +{ + struct mei_priv * priv; + priv = (struct mei_priv *)dev->priv; + // update statistics + (priv->stats).rx_packets = ATUR_CHAN_RECV_BLK; + (priv->stats).tx_packets = ATUR_CHAN_TX_BLK; + (priv->stats).rx_errors = ATUR_CHAN_CORR_BLK + ATUR_CHAN_UNCORR_BLK; + (priv->stats).rx_dropped = ATUR_CHAN_UNCORR_BLK; + + return &(priv->stats); +} + +static struct net_device_stats * fast_mei_net_get_stats(struct net_device * dev) +{ + struct mei_priv * priv; + priv = (struct mei_priv *)dev->priv; + // update statistics + (priv->stats).rx_packets = ATUR_CHAN_RECV_BLK; + (priv->stats).tx_packets = ATUR_CHAN_TX_BLK; + (priv->stats).rx_errors = ATUR_CHAN_CORR_BLK + ATUR_CHAN_UNCORR_BLK; + (priv->stats).rx_dropped = ATUR_CHAN_UNCORR_BLK; + + return &(priv->stats); +} +///////////////// mei access Rd/Wr methods /////////////////////////////////////////////////// +void meiLongwordWrite(u32 ul_address, u32 ul_data) +{ + *((volatile u32 *)ul_address) = ul_data; + asm("SYNC"); + return; +} // end of "meiLongwordWrite(..." + +void meiLongwordRead(u32 ul_address, u32 *pul_data) +{ + *pul_data = *((volatile u32 *)ul_address); + asm("SYNC"); + return; +} // end of "meiLongwordRead(..." + +MEI_ERROR meiDMAWrite(u32 destaddr, u32 *databuff, u32 databuffsize) +{ + u32 *p = databuff; + u32 temp; + u32 flags; + + if( destaddr & 3) + return MEI_FAILURE; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Set the write transfer address + meiLongwordWrite(MEI_XFR_ADDR, destaddr); + + // Write the data pushed across DMA + while (databuffsize--) + { + temp = *p; + if(databuff==(u32 *)TxMessage) // swap half word + temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16); + meiLongwordWrite(MEI_DATA_XFR, temp); + p++; + } // end of "while(..." + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + return MEI_SUCCESS; + +} // end of "meiDMAWrite(..." + +MEI_ERROR meiDMAWrite_16(u32 destaddr, u32 *databuff, u32 databuffsize) +{ + u32 *p = databuff; + u32 temp; + u32 flags; + + if( destaddr & 3) + return MEI_FAILURE; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Set the write transfer address + meiLongwordWrite(MEI_XFR_ADDR, destaddr); + + // Write the data pushed across DMA + while (databuffsize--) + { + temp = *p; + temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16);//swap half word + meiLongwordWrite(MEI_DATA_XFR, temp); + p++; + } // end of "while(..." + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + return MEI_SUCCESS; + +} // end of "meiDMAWrite_16(..." + +MEI_ERROR meiDMAWrite_8(u32 destaddr, u32 *databuff, u32 databuffsize) +{ + u32 *p = databuff; + u32 temp; + u32 flags; + + if( destaddr & 3) + return MEI_FAILURE; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Set the write transfer address + meiLongwordWrite(MEI_XFR_ADDR, destaddr); + + // Write the data pushed across DMA + while (databuffsize--) + { + temp = *p; + temp = ((temp & 0xff)<<24) + ((temp & 0xff00)<<8)+ ((temp & 0xff0000)>>8)+ ((temp & 0xff000000)>>24);//swap byte + meiLongwordWrite(MEI_DATA_XFR, temp); + p++; + } // end of "while(..." + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + return MEI_SUCCESS; + +} // end of "meiDMAWrite_8(..." + +MEI_ERROR meiDMARead(u32 srcaddr, u32 *databuff, u32 databuffsize) +{ + u32 *p = databuff; + u32 temp; + u32 flags; + + if( srcaddr & 3) + return MEI_FAILURE; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Set the read transfer address + meiLongwordWrite(MEI_XFR_ADDR, srcaddr); + + // Read the data popped across DMA + while (databuffsize--) + { + meiLongwordRead(MEI_DATA_XFR, &temp); + if(databuff==(u32 *)RxMessage) // swap half word + temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16); + *p=temp; + p++; + } // end of "while(..." + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + return MEI_SUCCESS; + +} // end of "meiDMARead(..." + +MEI_ERROR meiDMARead_16(u32 srcaddr, u32 *databuff, u32 databuffsize) +{ + u32 *p = databuff; + u32 temp; + u32 flags; + + if( srcaddr & 3) + return MEI_FAILURE; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Set the read transfer address + meiLongwordWrite(MEI_XFR_ADDR, srcaddr); + + // Read the data popped across DMA + while (databuffsize--) + { + meiLongwordRead(MEI_DATA_XFR, &temp); + temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16); + *p=temp; + p++; + } // end of "while(..." + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + return MEI_SUCCESS; + +} // end of "meiDMARead_16(..." + +MEI_ERROR meiDMARead_8(u32 srcaddr, u32 *databuff, u32 databuffsize) +{ + u32 *p = databuff; + u32 temp; + u32 flags; + + if( srcaddr & 3) + return MEI_FAILURE; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Set the read transfer address + meiLongwordWrite(MEI_XFR_ADDR, srcaddr); + + // Read the data popped across DMA + while (databuffsize--) + { + meiLongwordRead(MEI_DATA_XFR, &temp); + temp = ((temp & 0xff)<<24) + ((temp & 0xff00)<<8)+ ((temp & 0xff0000)>>8)+ ((temp & 0xff000000)>>24);//swap byte + *p=temp; + p++; + } // end of "while(..." + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + return MEI_SUCCESS; + +} // end of "meiDMARead_8(..." + +void meiPollForDbgDone(void) +{ + u32 query = 0; + int i=0; + while (i>8)+ ((temp & 0xff000000)>>24);//swap byte + meiLongwordWrite(MEI_DEBUG_DATA, temp); + DEBUG_ACCESS_DELAY; + meiPollForDbgDone(); + address += 4; + buffer++; + } // end of "for(..." + + // Close the debug port after DMP memory write + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + // Return + return MEI_SUCCESS; + +} // end of "meiDebugWrite_8(..." + +MEI_ERROR meiDebugRead_8(u32 srcaddr, u32 *databuff, u32 databuffsize) +{ + u32 i; + u32 temp = 0x0; + u32 address = 0x0; + u32 *buffer = 0x0; + u32 flags; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Open the debug port before DMP memory read + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP2_MASK); + DEBUG_ACCESS_DELAY; + + // For the requested length, write the address and read the data + address = srcaddr; + buffer = databuff; + for (i=0; i>8)+ ((temp & 0xff000000)>>24);//swap byte + *buffer=temp; + address += 4; + buffer++; + } // end of "for(..." + + // Close the debug port after DMP memory read + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + // Return + return MEI_SUCCESS; + +} // end of "meiDebugRead_8(..." + +MEI_ERROR meiDebugWrite_16(u32 destaddr, u32 *databuff, u32 databuffsize) +{ + u32 i; + u32 temp = 0x0; + u32 address = 0x0; + u32 *buffer = 0x0; + u32 flags; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Open the debug port before DMP memory write + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK); + DEBUG_ACCESS_DELAY; + + // For the requested length, write the address and write the data + address = destaddr; + buffer = databuff; + for (i=0; i < databuffsize; i++) + { + meiLongwordWrite(MEI_DEBUG_WAD, address); + DEBUG_ACCESS_DELAY; + temp=*buffer; + temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16);//swap half word + meiLongwordWrite(MEI_DEBUG_DATA, temp); + DEBUG_ACCESS_DELAY; + meiPollForDbgDone(); + address += 4; + buffer++; + } // end of "for(..." + + // Close the debug port after DMP memory write + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + // Return + return MEI_SUCCESS; + +} // end of "meiDebugWrite_16(..." + +MEI_ERROR meiDebugRead_16(u32 srcaddr, u32 *databuff, u32 databuffsize) +{ + u32 i; + u32 temp = 0x0; + u32 address = 0x0; + u32 *buffer = 0x0; + u32 flags; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Open the debug port before DMP memory read + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP2_MASK); + DEBUG_ACCESS_DELAY; + + // For the requested length, write the address and read the data + address = srcaddr; + buffer = databuff; + for (i=0; i>16);//swap half word + *buffer=temp; + address += 4; + buffer++; + } // end of "for(..." + + // Close the debug port after DMP memory read + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + // Return + return MEI_SUCCESS; + +} // end of "meiDebugRead_16(..." + +MEI_ERROR meiDebugWrite(u32 destaddr, u32 *databuff, u32 databuffsize) +{ + u32 i; + u32 temp = 0x0; + u32 address = 0x0; + u32 *buffer = 0x0; + u32 flags; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Open the debug port before DMP memory write + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK); + DEBUG_ACCESS_DELAY; + + // For the requested length, write the address and write the data + address = destaddr; + buffer = databuff; + for (i=0; i < databuffsize; i++) + { + meiLongwordWrite(MEI_DEBUG_WAD, address); + DEBUG_ACCESS_DELAY; + temp=*buffer; + meiLongwordWrite(MEI_DEBUG_DATA, temp); + DEBUG_ACCESS_DELAY; + meiPollForDbgDone(); + address += 4; + buffer++; + } // end of "for(..." + + // Close the debug port after DMP memory write + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + // Return + return MEI_SUCCESS; + +} // end of "meiDebugWrite(..." + +MEI_ERROR meiDebugRead(u32 srcaddr, u32 *databuff, u32 databuffsize) +{ + u32 i; + u32 temp = 0x0; + u32 address = 0x0; + u32 *buffer = 0x0; + u32 flags; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Open the debug port before DMP memory read + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP2_MASK); + DEBUG_ACCESS_DELAY; + + // For the requested length, write the address and read the data + address = srcaddr; + buffer = databuff; + for (i=0; icount; boot_loop++) + { + if( img_hdr->page[boot_loop].p_size & BOOT_FLAG) + { + page_size = meiGetPage( boot_loop, GET_PROG, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr); + if( page_size > 0) + { + meiDMAWrite(dest_addr, mei_arc_swap_buff, page_size); + } + } + if( img_hdr->page[boot_loop].d_size & BOOT_FLAG) + { + page_size = meiGetPage( boot_loop, GET_DATA, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr); + if( page_size > 0) + { + meiDMAWrite( dest_addr, mei_arc_swap_buff, page_size); + } + } + } +#ifdef AMAZON_MEI_DEBUG_ON +// printk("\n\n pages downloaded"); +#endif + return MEI_SUCCESS; + +} // end of "meiDownloadBootCode(..." + +MEI_ERROR meiRunArc(void) +{ + u32 arc_control_mode = 0x0; + u32 arc_debug_addr = 0x0; + u32 arc_debug_data = 0x0; + + // Switch arc control from JTAG mode to MEI mode- write '1' to bit0 + meiLongwordRead(MEI_CONTROL, &arc_control_mode); + arc_control_mode |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, arc_control_mode); + + // Write arc aux reg access mask (0x0) into debug addr decode reg + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_AUX_MASK); + + // Write arc status aux reg addr (0x0) into debug read addr reg + meiLongwordWrite(MEI_DEBUG_RAD, arc_debug_addr); + meiPollForDbgDone(); + + // Read debug data reg and save content + meiLongwordRead(MEI_DEBUG_DATA, &arc_debug_data); + + // Write arc status aux reg addr (0x0) into debug write addr reg + meiLongwordWrite(MEI_DEBUG_WAD, arc_debug_addr); + + // Write debug data reg with content ANDd with 0xFDFFFFFF (halt bit cleared) + arc_debug_data &= ~(BIT25); + meiLongwordWrite(MEI_DEBUG_DATA, arc_debug_data); + meiPollForDbgDone(); + + // Switch arc control from MEI mode to JTAG mode- write '0' to bit0 + meiLongwordRead(MEI_CONTROL, &arc_control_mode); + arc_control_mode &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, arc_control_mode); + + // Enable mask for arc codeswap interrupts + meiMailboxInterruptsEnable(); + + // Return + return MEI_SUCCESS; + +} // end of "meiActivate(..." + +int meiGetPage( u32 Page, u32 data, u32 MaxSize, u32 *Buffer, u32 *Dest) +{ + u32 size; + u32 i; + u32 *p; + + if( Page > img_hdr->count) + return -2; + + /* + ** Get program or data size, depending on "data" flag + */ + size = (data == GET_DATA) ? img_hdr->page[ Page].d_size : img_hdr->page[ Page].p_size; + + size &= BOOT_FLAG_MASK; // Clear boot bit! + if( size > MaxSize) + return -1; + + if( size == 0) + return 0; + /* + ** Get program or data offset, depending on "data" flag + */ + i = data ? img_hdr->page[ Page].d_offset : img_hdr->page[ Page].p_offset; + + /* + ** Copy data/program to buffer + */ + + i /= 4; // Adjust offset for byte-to-UINT for array operation + + p = (u32 *)img_hdr + i; + for(i = 0; i < size; i++) + Buffer[i] = *p++; + /* + ** Pass back data/program destination address + */ + *Dest = data ? img_hdr->page[Page].d_dest : img_hdr->page[Page].p_dest; + + return size; +} + +MEI_ERROR meiCMV(u16 * request, int reply) // write cmv to arc, if reply needed, wait for reply +{ + MEI_ERROR meierror; + wait_queue_t wait; + + cmv_reply=reply; + + meierror = meiMailboxWrite(request, MSG_LENGTH); + + if(meierror != MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n MailboxWrite Fail."); +#endif + return meierror; + } + else{ + cmv_count++; + } + + if(cmv_reply == NO_REPLY) + return MEI_SUCCESS; + + init_waitqueue_entry(&wait, current); + add_wait_queue(&wait_queue_arcmsgav, &wait); + set_current_state(TASK_INTERRUPTIBLE); +// cmv_waiting=1; + + if(arcmsgav==1){ + set_current_state(TASK_RUNNING); + remove_wait_queue(&wait_queue_arcmsgav, &wait); + } + else{ + schedule_timeout(CMV_TIMEOUT); + remove_wait_queue(&wait_queue_arcmsgav, &wait); + } + if(arcmsgav==0){//CMV_timeout + cmv_waiting=0; + arcmsgav=0; +#ifdef AMAZON_MEI_DEBUG_ON + printk("\nmeiCMV: MEI_MAILBOX_TIMEOUT\n"); +#endif + return MEI_MAILBOX_TIMEOUT; + } + else{ + arcmsgav=0; + reply_count++; + return MEI_SUCCESS; + } +} + +//TODO, for loopback test +#ifdef DFE_LOOPBACK +#define mte_reg_base (0x4800*4+0x20000) + +/* Iridia Registers Address Constants */ +#define MTE_Reg(r) (int)(mte_reg_base + (r*4)) + +#define IT_AMODE MTE_Reg(0x0004) + + +#define OMBOX_BASE 0x15F80 +#define IMBOX_BASE 0x15FC0 + +#define TIMER_DELAY (1024) +#define BC0_BYTES (32) +#define BC1_BYTES (30) +#define NUM_MB (12) +#define TIMEOUT_VALUE 2000 + +void BFMWait (u32 cycle) { + u32 i; + for (i = 0 ; i< cycle ; i++); +} + +void WriteRegLong(u32 addr, u32 data){ + //printk("[%8x] <= %8x \n\n", addr, data); + *((volatile u32 *)(addr)) = data; +} + +u32 ReadRegLong (u32 addr) { + u32 rd_val; + + rd_val = *((volatile u32 *)(addr)); + //printk("[%8x] => %8x \n\n", addr, rd_val); + return rd_val; + +} + +/* This routine writes the mailbox with the data in an input array */ +void WriteMbox(u32 *mboxarray,u32 size) { + u32 i; + + WriteRegLong(MEI_XFR_ADDR,IMBOX_BASE); + for (i=0;if_dentry->d_inode)->i_ino; + char outputbuf[64]; + int count=0; + int i; + u32 version=0; + reg_entry_t* current_reg=NULL; + + for (i=0;iflag == (int *) 8){ + ///proc/mei/version + //format: + //Firmware version: major.minor.sub_version.int_version.rel_state.spl_appl + //Firmware Date Time Code: date/month min:hour + if (*ppos>0) /* Assume reading completed in previous read*/ + return 0; // indicates end of file + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + //if (indicator_count != 1){ + if (indicator_count < 1){ + up(&mei_sema); + return -EAGAIN; + } + //major:bits 0-7 + //minor:bits 8-15 + makeCMV(H2D_CMV_READ, INFO, 54, 0, 1, NULL); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#if 0 +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n WINHOST CMV fail"); +#endif +#endif + up(&mei_sema); + return -EIO; + } + version = RxMessage[4]; + count = sprintf(outputbuf, "%d.%d.",(version)&0xff,(version>>8)&0xff); + + //sub_version:bits 4-7 + //int_version:bits 0-3 + //spl_appl:bits 8-13 + //rel_state:bits 14-15 + makeCMV(H2D_CMV_READ, INFO, 54, 1, 1, NULL); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#if 0 +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n WINHOST CMV fail"); +#endif +#endif + up(&mei_sema); + return -EFAULT; + } + version =RxMessage[4]; + count += sprintf(outputbuf+count, "%d.%d.%d.%d", + (version>>4)&0xf, + version&0xf, + (version>>14)&0x3, + (version>>8)&0x3f); +#ifdef ADSL_LED_SUPPORT +// version check -start for adsl led + if ((((version>>4)&0xf)==2)&&((version&0xf)>=3)&&((version&0xf)<7)) firmware_support_led=1; + else if ((((version>>4)&0xf)==2)&&((version&0xf)>=7)) firmware_support_led=2; + else if (((version>>4)&0xf)>2) firmware_support_led=2; + +//165001:henryhsu:20050906:Modify for adsl firmware version 1.2.1.2.0.1 DATA_LED can't flash. + //else firmware_support_led=0; + else firmware_support_led=2; +//165001 + + +// version check -end +#endif + //Date:bits 0-7 + //Month:bits 8-15 + makeCMV(H2D_CMV_READ, INFO, 55, 0, 1, NULL); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#if 0 +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n WINHOST CMV fail"); +#endif +#endif + up(&mei_sema); + return -EIO; + } + version = RxMessage[4]; + + //Hour:bits 0-7 + //Minute:bits 8-15 + makeCMV(H2D_CMV_READ, INFO, 55, 1, 1, NULL); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#if 0 +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n WINHOST CMV fail"); +#endif +#endif + up(&mei_sema); + return -EFAULT; + } + version += (RxMessage[4]<<16); + count += sprintf(outputbuf+count, " %d/%d %d:%d\n" + ,version&0xff + ,(version>>8)&0xff + ,(version>>25)&0xff + ,(version>>16)&0xff); + + up(&mei_sema); + + *ppos+=count; + }else if(current_reg->flag != (int *)Recent_indicator){ + if (*ppos>0) /* Assume reading completed in previous read*/ + return 0; // indicates end of file + count = sprintf(outputbuf, "0x%08X\n\n", *(current_reg->flag)); + *ppos+=count; + if (count>nbytes) /* Assume output can be read at one time */ + return -EINVAL; + }else{ + if((int)(*ppos)/((int)7)==16) + return 0; // indicate end of the message + count = sprintf(outputbuf, "0x%04X\n\n", *(((u16 *)(current_reg->flag))+ (int)(*ppos)/((int)7))); + *ppos+=count; + } + if (copy_to_user(buf, outputbuf, count)) + return -EFAULT; + return count; +} + +static ssize_t proc_write(struct file * file, const char * buffer, size_t count, loff_t *ppos) +{ + int i_ino = (file->f_dentry->d_inode)->i_ino; + reg_entry_t* current_reg=NULL; + int i; + unsigned long newRegValue; + char *endp; + + for (i=0;iflag == (int *)Recent_indicator)) + return -EINVAL; + + newRegValue = simple_strtoul(buffer,&endp,0); + *(current_reg->flag)=(int)newRegValue; + return (count+endp-buffer); +} +////////////////makeCMV(Opcode, Group, Address, Index, Size, Data), CMV in u16 TxMessage[MSG_LENGTH]/////////////////////////// +void makeCMV(u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data) +{ + memset(TxMessage, 0, MSG_LENGTH*2); + TxMessage[0]= (opcode<<4) + (size&0xf); + TxMessage[1]= (((index==0)?0:1)<<7) + (group&0x7f); + TxMessage[2]= address; + TxMessage[3]= index; + if(opcode == H2D_CMV_WRITE) + memcpy(TxMessage+4, data, size*2); + return; +} + +////////////////makeCMV(Opcode, Group, Address, Index, Size, Data), CMV in u16 TxMessage[MSG_LENGTH]/////////////////////////// +void makeCMV_local(u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data,u16 *CMVMSG) +{ + memset(CMVMSG, 0, MSG_LENGTH*2); + CMVMSG[0]= (opcode<<4) + (size&0xf); + CMVMSG[1]= (((index==0)?0:1)<<7) + (group&0x7f); + CMVMSG[2]= address; + CMVMSG[3]= index; + if(opcode == H2D_CMV_WRITE) + memcpy(CMVMSG+4, data, size*2); + return; +} + +//////////////// Driver Structure ///////////////////////////////////////////////////////////////////////////// +static ssize_t mei_write(struct file *, const char *, size_t, loff_t *); +static int mei_ioctl(struct inode *, struct file *, unsigned int, unsigned long); + +static struct file_operations mei_operations = { + write: mei_write, + ioctl: mei_ioctl, +}; + + +static ssize_t mei_write(struct file * filp, const char * buf, size_t size, loff_t * loff) +{ +// printk("\n\n mei_write entered"); +// image_buffer = (u32 *)kmalloc(size, GFP_KERNEL); + image_buffer = (u32 *)vmalloc(size); +// printk("\n\n image_buffer kmalloc done"); + if(image_buffer == NULL){ +#ifdef AMAZON_MEI_DEBUG_ON +// printk("\n\n kmalloc for firmware image fail"); + printk("\n\n vmalloc for firmware image fail"); +#endif + return -1; + } + copy_from_user((char *)image_buffer, buf, size); +// printk("\n\n copy_from_user done"); + return size; +} + + ////////// ISR GPTU Timer 6 for high resolution timer ///////////// +void amazon_timer6_interrupt_MEI(int irq, void *dev_id, struct pt_regs *regs) +{ + int i,j; + u32 temp; + u16 temp16; + u16 rdindex, wrindex; + u16 num_rd=0; //num of byte can be read + u16 bytes_to_wr=0; + +// printk("\n\nenter timer\n\n"); + irqtimes++; +// printk("\n%d\n",irqtimes); + + +/* +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_8(0x30f20, &temp, 1); +#else + meiDMARead_8(0x30f20, &temp, 1); +#endif + if((temp&0x4000)!=0){ + printk("\nER_ERR"); +#ifdef PCM_ACCESS_DEBUG + meiDebugWrite_8(0x30f20, &temp, 1); +#else + meiDMAWrite_8(0x30f20, &temp, 1); +#endif +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_8(0x30f20, &temp, 1); +#else + meiDMARead_8(0x30f20, &temp, 1); +#endif + if((temp&0x4000)!=0) + printk("\nER_ERR not cleared"); + } +*/ + + for(i=PCM_CHANNEL_NUM-1;i>=0;i--){// start from last channel, which is rx +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_16(pcm_start_addr+i*16+12, &temp, 1); +#else + meiDMARead_16(pcm_start_addr+i*16+12, &temp, 1); +#endif + wrindex = (u16)((temp & 0xffff0000)>>16); +// printk(" %d",wrindex); +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_16(pcm_start_addr+i*16+8, &temp, 1); +#else + meiDMARead_16(pcm_start_addr+i*16+8, &temp, 1); +#endif + rdindex = (u16)(temp & 0xffff); +// printk(" %d",rdindex); + if(rdindex<=wrindex) + num_rd=((wrindex-rdindex)/4)*4; //read multiply of 4 bytes + else + num_rd=((pcm_data[i].len-(rdindex-wrindex))/4)*4; //read multiply of 4 bytes + + if(i%2!=0){//rx channel + pcm_data[i].point=0; + for(j=0;j=pcm_data[i].len) + temp16=(rdindex+j*4) - pcm_data[i].len; + else + temp16=rdindex+j*4; +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16, (u32*)(pcm_data[i].buff+pcm_data[i].point), 1); +#else + meiDMARead_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16, (u32*)(pcm_data[i].buff+pcm_data[i].point), 1); +#endif + // printk(" %8x", *((u32*)(pcm_data[i].buff+pcm_data[i].point))); + /* if(pcm_data[i].point==0){ + if(pcm_data[i].buff[0]==0xA5){// start of loopback data + pcm_data[i].point+=4; + printk("\nstart receive data"); + } + } + else*/ + pcm_data[i].point+=4; + /* if(pcm_data[i].point==PCM_BUFF_SIZE){ //finish rx + pcm_data[i].finish=1; + printk("\nchannel[%d] finished", i); + } */ + } + } + if(firsttime[i]==1){ + for(j=0;j=256) + pcm_start_loc[i]=pcm_start_loc[i]-256; + } + } + + rdindex +=num_rd; + if(rdindex>=pcm_data[i].len) + rdindex=rdindex-pcm_data[i].len; +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_16(pcm_start_addr+i*16+8, &temp, 1); +#else + meiDMARead_16(pcm_start_addr+i*16+8, &temp, 1); +#endif + temp= (temp & 0xffff0000) + rdindex; +#ifdef PCM_ACCESS_DEBUG + meiDebugWrite_16(pcm_start_addr+i*16+8, &temp, 1); // update rdindex +#else + meiDMAWrite_16(pcm_start_addr+i*16+8, &temp, 1); // update rdindex +#endif + + bytes_to_wr = num_rd; + + // if(bytes_to_wr>0){ + // printk(" %d", num_rd); + // printk(" %d", rdindex); +// printk("\n\nrdindex = %d", rdindex); + //} + } + else{ //tx channel + // if((bytes_to_wr + num_rd) < pcm_data[i].len){ + for(j=0;j=pcm_data[i].len) + temp16=(wrindex+j*4) - pcm_data[i].len; + else + temp16=wrindex + j*4; +/* +#ifdef PCM_ACCESS_DEBUG + meiDebugWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i+1].buff+j*4), 1); +#else + meiDMAWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i+1].buff+j*4), 1); +#endif*/ + +#ifdef PCM_ACCESS_DEBUG + meiDebugWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i].buff+pcm_data[i].point), 1); + // meiDebugWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i].buff), 1); +#else + meiDMAWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i].buff+pcm_data[i].point), 1); +#endif + pcm_data[i].point+=4; + if(pcm_data[i].point==PCM_BUFF_SIZE){ + // pcm_data[i].finish=1; + // printk("\nchannel[%d] finished", i); + pcm_data[i].point=0; + } + } + } + wrindex+=bytes_to_wr; + if(wrindex>=pcm_data[i].len) + wrindex=wrindex-pcm_data[i].len; +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_16(pcm_start_addr+i*16+12, &temp, 1); +#else + meiDMARead_16(pcm_start_addr+i*16+12, &temp, 1); +#endif + temp=(temp&0xffff) + (wrindex<<16); +#ifdef PCM_ACCESS_DEBUG + meiDebugWrite_16(pcm_start_addr+i*16+12, &temp, 1); // update wrindex +#else + meiDMAWrite_16(pcm_start_addr+i*16+12, &temp, 1); // update wrindex +#endif + + //if(bytes_to_wr>0){ + // printk(" %d", bytes_to_wr); + // printk(" %d", wrindex); +// printk("\n\nwrindex = %d", wrindex); + //} + // } + } + } + return; +} +//000002:fchang Start +static int meiResetArc(void) +{ + u32 auxreg0; + u32 auxreg5; + int flshcnt=0; + int flshcnt1=0; + int flshcnt2=0; + + meiLongwordWrite(MEI_CONTROL, 1); + meiLongwordWrite(MEI_DEBUG_DEC, 3); + meiLongwordWrite(MEI_DEBUG_WAD, 0x3c); + meiLongwordWrite(MEI_DEBUG_DATA, 0x10); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_DEC, 0x0); + meiLongwordWrite(MEI_DEBUG_WAD, 0x2); + meiLongwordWrite(MEI_DEBUG_DATA, 0x0); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_WAD, 0x3); + meiLongwordWrite(MEI_DEBUG_DATA, 0x0); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_DEC, 0x0); + meiLongwordWrite(MEI_DEBUG_RAD, 0x0); + meiPollForDbgDone(); + meiLongwordRead(MEI_DEBUG_DATA, &auxreg0); + auxreg0 = auxreg0 & 0x03ffffff; + meiLongwordWrite(MEI_DEBUG_WAD, 0x0); + meiLongwordWrite(MEI_DEBUG_DATA, auxreg0); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_WAD, 0x10a); + meiLongwordWrite(MEI_DEBUG_DATA, 0x0); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_DEC, 0x2); + meiLongwordWrite(MEI_DEBUG_WAD, 0xfffc); + meiLongwordWrite(MEI_DEBUG_DATA, 0x1fffffff); + meiPollForDbgDone(); + while(flshcnt<3){ + meiLongwordWrite(MEI_DEBUG_DEC, 0x0); + meiLongwordWrite(MEI_DEBUG_RAD, 0x0); + meiPollForDbgDone(); + meiLongwordRead(MEI_DEBUG_DATA, &auxreg0); + auxreg0 = auxreg0 & 0xff000000; + auxreg0 = auxreg0 | 0x3fff; + meiLongwordWrite(MEI_DEBUG_WAD, 0x0); + meiLongwordWrite(MEI_DEBUG_DATA, auxreg0); + meiPollForDbgDone(); + + meiLongwordWrite(MEI_DEBUG_DEC, 0x0); + meiLongwordWrite(MEI_DEBUG_RAD, 0x5); + meiPollForDbgDone(); + meiLongwordRead(MEI_DEBUG_DATA, &auxreg5); + auxreg5 = auxreg5 | 0x801; + meiLongwordWrite(MEI_DEBUG_WAD, 0x5); + meiLongwordWrite(MEI_DEBUG_DATA, auxreg5); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_RAD, 0x0); + meiPollForDbgDone(); + meiLongwordRead(MEI_DEBUG_DATA, &auxreg0); + auxreg0 = auxreg0 & 0x00ffffff; + if(auxreg0 == 0x4000) + flshcnt = flshcnt+1; + else{ + if(flshcnt == 0) + flshcnt1 = flshcnt1 +1; + else + flshcnt2 = flshcnt2 +1; + } + } + + return 1; +} + +static int meiResetCore(void) +{ + meiLongwordWrite(MEI_CONTROL, 0x1); + meiLongwordWrite(MEI_DEBUG_DEC, 0x2); + meiLongwordWrite(MEI_DEBUG_WAD, 0x31f10); + meiLongwordWrite(MEI_DEBUG_DATA, 0xf); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_WAD, 0x31f10); + meiLongwordWrite(MEI_DEBUG_DATA, 0x0); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_WAD, 0x31f00); + meiLongwordWrite(MEI_DEBUG_DATA, 0x55); + meiPollForDbgDone(); + return 1; +} + +static int meiEnalbeMailboxInt(void) +{ + u32 arc2meiintmsk; + meiLongwordRead(ARC_TO_MEI_INT_MASK, &arc2meiintmsk); + arc2meiintmsk = arc2meiintmsk | 0x1; + meiLongwordWrite(ARC_TO_MEI_INT_MASK, arc2meiintmsk); + meiLongwordWrite(MEI_CONTROL, 0x0); + return 1; +} + + + +//000002:fchang End + +static int mei_ioctl(struct inode * ino, struct file * fil, unsigned int command, unsigned long lon) +{ + int i,k; + u32 boot_loop; + u32 page_size; + u32 dest_addr; + u32 j; + u32 temp; + u32 temp2; + u16 trapsflag=0; + amazon_clreoc_pkt * current_clreoc; + struct timeval time_now; + struct timeval time_fini; + struct list_head * ptr; + amazon_mei_mib * mib_ptr; +// u16 buff[MSG_LENGTH]__attribute__ ((aligned(4))); + structpts pts; + int meierr=MEI_SUCCESS; + u16 data[12]; //used in makeCMV, to pass in payload when CMV set, ignored when CMV read. + meireg regrdwr; + meidebug debugrdwr; + amazon_mei_mib * temp_intvl; + struct sk_buff * eoc_skb; +// 603221:tc.chen start + u16 hdlc_cmd[2]; + u16 hdlc_rx_buffer[32]; + int hdlc_rx_len=0; +// 603221:tc.chen end + + int from_kernel = 0;//joelin + if (ino == (struct inode *)0) from_kernel = 1;//joelin + +// printk("\n switch.command = %i\n", command); + switch(command){ + case GET_ADSL_LINE_CODE: + pts.adslLineTableEntry_pt = (adslLineTableEntry *)kmalloc(sizeof(adslLineTableEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslLineTableEntry_pt, (char *)lon, sizeof(adslLineTableEntry)); + if(IS_FLAG_SET((&(pts.adslLineTableEntry_pt->flags)), LINE_CODE_FLAG)){ + pts.adslLineTableEntry_pt->adslLineCode = 2; + } + copy_to_user((char *)lon, (char *)pts.adslLineTableEntry_pt, sizeof(adslLineTableEntry)); + kfree(pts.adslLineTableEntry_pt); + break; +#ifdef AMAZON_MEI_MIB_RFC3440 + case GET_ADSL_ATUC_LINE_EXT: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + pts.adslLineExtTableEntry_pt = (adslLineExtTableEntry *)kmalloc(sizeof(adslLineExtTableEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslLineExtTableEntry_pt, (char *)lon, sizeof(adslLineExtTableEntry)); + if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CAP_FLAG)){ + ATUC_LINE_TRANS_CAP_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 67 Index 0"); +#endif + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CAP_FLAG); + } + else{ + memcpy((&(pts.adslLineExtTableEntry_pt->adslLineTransAtucCap)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CONFIG_FLAG)){ + ATUC_LINE_TRANS_CONFIG_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 67 Index 0"); +#endif + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CONFIG_FLAG); + } + else{ + memcpy((&(pts.adslLineExtTableEntry_pt->adslLineTransAtucConfig)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_ACTUAL_FLAG)){ + ATUC_LINE_TRANS_ACTUAL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 2 Address 1 Index 0"); +#endif + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_ACTUAL_FLAG); + } + else{ + memcpy((&(pts.adslLineExtTableEntry_pt->adslLineTransAtucActual)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), LINE_GLITE_POWER_STATE_FLAG)){ // not supported currently +/* + LINE_GLITE_POWER_STATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 2 Address 0 Index 0"); +#endif + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), LINE_GLITE_POWER_STATE_FLAG); + } + else{ + memcpy((&(pts.adslLineExtTableEntry_pt->adslLineGlitePowerState)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } +*/ + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), LINE_GLITE_POWER_STATE_FLAG); + } + copy_to_user((char *)lon, (char *)pts.adslLineExtTableEntry_pt, sizeof(adslLineExtTableEntry)); + kfree(pts.adslLineTableEntry_pt); + up(&mei_sema); + break; +#endif + +#ifdef AMAZON_MEI_MIB_RFC3440 + case SET_ADSL_ATUC_LINE_EXT: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + pts.adslLineExtTableEntry_pt = (adslLineExtTableEntry *)kmalloc(sizeof(adslLineExtTableEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslLineExtTableEntry_pt, (char *)lon, sizeof(adslLineExtTableEntry)); + + //only adslLineTransAtucConfig can be set. + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CAP_FLAG); + if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CONFIG_FLAG)){ + memcpy(data,(&(pts.adslLineExtTableEntry_pt->adslLineTransAtucConfig)), 2); + ATUC_LINE_TRANS_CONFIG_FLAG_MAKECMV_WR; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 67 Index 0"); +#endif + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CONFIG_FLAG); + } + } + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_ACTUAL_FLAG); + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), LINE_GLITE_POWER_STATE_FLAG); + + copy_to_user((char *)lon, (char *)pts.adslLineExtTableEntry_pt, sizeof(adslLineExtTableEntry)); + kfree(pts.adslLineTableEntry_pt); + up(&mei_sema); + break; +#endif + + case GET_ADSL_ATUC_PHY: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslAtucPhysEntry_pt = (adslAtucPhysEntry *)kmalloc(sizeof(adslAtucPhysEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslAtucPhysEntry_pt, (char *)lon, sizeof(adslAtucPhysEntry)); + if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_SER_NUM_FLAG)){ + ATUC_PHY_SER_NUM_FLAG_MAKECMV1; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 57 Index 0"); +#endif + CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_SER_NUM_FLAG); + } + else{ + memcpy(pts.adslAtucPhysEntry_pt->serial_no, RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + ATUC_PHY_SER_NUM_FLAG_MAKECMV2; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 57 Index 12"); +#endif + CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_SER_NUM_FLAG); + } + else{ + memcpy((pts.adslAtucPhysEntry_pt->serial_no+24), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_VENDOR_ID_FLAG)){ + ATUC_PHY_VENDOR_ID_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 64 Index 0"); +#endif + CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_VENDOR_ID_FLAG); + } + else{ + memcpy(pts.adslAtucPhysEntry_pt->vendor_id.vendor_id, RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_VER_NUM_FLAG)){ + ATUC_PHY_VER_NUM_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 58 Index 0"); +#endif + CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_VER_NUM_FLAG); + } + else{ + memcpy(pts.adslAtucPhysEntry_pt->version_no, RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_STAT_FLAG)){ + pts.adslAtucPhysEntry_pt->status = CurrStatus.adslAtucCurrStatus; + } + if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_OUT_PWR_FLAG)){ + ATUC_CURR_OUT_PWR_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 68 Index 5"); +#endif + CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_OUT_PWR_FLAG); + } + else{ + memcpy((&(pts.adslAtucPhysEntry_pt->outputPwr)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_ATTR_FLAG)){ + ATUC_CURR_ATTR_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 69 Index 0"); +#endif + CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_ATTR_FLAG); + } + else{ + memcpy((&(pts.adslAtucPhysEntry_pt->attainableRate)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + copy_to_user((char *)lon, (char *)pts.adslAtucPhysEntry_pt, sizeof(adslAtucPhysEntry)); + kfree(pts.adslAtucPhysEntry_pt); + + up(&mei_sema); + break; + case GET_ADSL_ATUR_PHY: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslAturPhysEntry_pt = (adslAturPhysEntry *)kmalloc(sizeof(adslAturPhysEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslAturPhysEntry_pt, (char *)lon, sizeof(adslAturPhysEntry)); + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_SER_NUM_FLAG)){ + ATUR_PHY_SER_NUM_FLAG_MAKECMV1; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 62 Index 0"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_SER_NUM_FLAG); + } + else{ + memcpy(pts.adslAturPhysEntry_pt->serial_no, RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + ATUR_PHY_SER_NUM_FLAG_MAKECMV2; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 62 Index 12"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_SER_NUM_FLAG); + } + else{ + memcpy((pts.adslAturPhysEntry_pt->serial_no+24), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_VENDOR_ID_FLAG)){ + ATUR_PHY_VENDOR_ID_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 65 Index 0"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_VENDOR_ID_FLAG); + } + else{ + memcpy(pts.adslAturPhysEntry_pt->vendor_id.vendor_id, RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_VER_NUM_FLAG)){ + ATUR_PHY_VER_NUM_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 61 Index 0"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_VER_NUM_FLAG); + } + else{ + memcpy(pts.adslAturPhysEntry_pt->version_no, RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_SNRMGN_FLAG)){ + ATUR_SNRMGN_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 68 Index 4"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_SNRMGN_FLAG); + } + else{ + memcpy((&(pts.adslAturPhysEntry_pt->SnrMgn)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_ATTN_FLAG)){ + ATUR_ATTN_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 68 Index 2"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_ATTN_FLAG); + } + else{ + memcpy((&(pts.adslAturPhysEntry_pt->Attn)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_STAT_FLAG)){ + pts.adslAturPhysEntry_pt->status = CurrStatus.adslAturCurrStatus; + } + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_OUT_PWR_FLAG)){ + ATUR_CURR_OUT_PWR_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 69 Index 5"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_OUT_PWR_FLAG); + } + else{ + memcpy((&(pts.adslAturPhysEntry_pt->outputPwr)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_ATTR_FLAG)){ + ATUR_CURR_ATTR_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 68 Index 0"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_ATTR_FLAG); + } + else{ + memcpy((&(pts.adslAturPhysEntry_pt->attainableRate)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + copy_to_user((char *)lon, (char *)pts.adslAturPhysEntry_pt, sizeof(adslAturPhysEntry)); + kfree(pts.adslAturPhysEntry_pt); + + up(&mei_sema); + break; + case GET_ADSL_ATUC_CHAN_INFO: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslAtucChanInfo_pt = (adslAtucChanInfo *)kmalloc(sizeof(adslAtucChanInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAtucChanInfo_pt, (char *)lon, sizeof(adslAtucChanInfo)); + if(IS_FLAG_SET((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_INTLV_DELAY_FLAG)){ + if((chantype.interleave!=1) || (chantype.fast==1)){ + CLR_FLAG((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_INTLV_DELAY_FLAG); + } + else{ + ATUC_CHAN_INTLV_DELAY_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 3 Index 1"); +#endif + CLR_FLAG((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_INTLV_DELAY_FLAG); + } + else{ + memcpy((&(pts.adslAtucChanInfo_pt->interleaveDelay)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + } + if(IS_FLAG_SET((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_CURR_TX_RATE_FLAG)){ + ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 1 Index 0"); +#endif + CLR_FLAG((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_CURR_TX_RATE_FLAG); + } + else{ + pts.adslAtucChanInfo_pt->currTxRate = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + } + if(IS_FLAG_SET((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_PREV_TX_RATE_FLAG)){ + pts.adslAtucChanInfo_pt->prevTxRate = PrevTxRate.adslAtucChanPrevTxRate; + } + copy_to_user((char *)lon, (char *)pts.adslAtucChanInfo_pt, sizeof(adslAtucChanInfo)); + kfree(pts.adslAtucChanInfo_pt); + + up(&mei_sema); + break; + case GET_ADSL_ATUR_CHAN_INFO: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslAturChanInfo_pt = (adslAturChanInfo *)kmalloc(sizeof(adslAturChanInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAturChanInfo_pt, (char *)lon, sizeof(adslAturChanInfo)); + if(IS_FLAG_SET((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_INTLV_DELAY_FLAG)){ + if((chantype.interleave!=1) || (chantype.fast==1)){ + CLR_FLAG((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_INTLV_DELAY_FLAG); + } + else{ + ATUR_CHAN_INTLV_DELAY_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 2 Index 1"); +#endif + CLR_FLAG((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_INTLV_DELAY_FLAG); + } + else{ + memcpy((&(pts.adslAturChanInfo_pt->interleaveDelay)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + } + if(IS_FLAG_SET((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_CURR_TX_RATE_FLAG)){ + ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 0 Index 0"); +#endif + CLR_FLAG((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_CURR_TX_RATE_FLAG); + } + else{ + pts.adslAturChanInfo_pt->currTxRate = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + } + if(IS_FLAG_SET((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_PREV_TX_RATE_FLAG)){ + pts.adslAturChanInfo_pt->prevTxRate = PrevTxRate.adslAturChanPrevTxRate; + } + if(IS_FLAG_SET((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_CRC_BLK_LEN_FLAG)){ + // ? no CMV to update this + CLR_FLAG((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_CRC_BLK_LEN_FLAG); + } + copy_to_user((char *)lon, (char *)pts.adslAturChanInfo_pt, sizeof(adslAturChanInfo)); + kfree(pts.adslAturChanInfo_pt); + + up(&mei_sema); + break; + case GET_ADSL_ATUC_PERF_DATA: + pts.atucPerfDataEntry_pt = (atucPerfDataEntry *)kmalloc(sizeof(atucPerfDataEntry), GFP_KERNEL); + copy_from_user((char *)pts.atucPerfDataEntry_pt, (char *)lon, sizeof(atucPerfDataEntry)); + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_LOFS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfLofs=ATUC_PERF_LOFS; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_LOSS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfLoss=ATUC_PERF_LOSS; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_ESS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfESs=ATUC_PERF_ESS; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_INITS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfInits=ATUC_PERF_INITS; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_VALID_INTVLS_FLAG)){ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==96) + break; + } + pts.atucPerfDataEntry_pt->adslAtucPerfValidIntervals=i; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_INVALID_INTVLS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfInvalidIntervals=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_TIME_ELAPSED_FLAG)){ + do_gettimeofday(&time_now); + pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinTimeElapsed=time_now.tv_sec - (current_intvl->start_time).tv_sec; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_LOFS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinLofs=current_intvl->AtucPerfLof; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_LOSS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinLoss=current_intvl->AtucPerfLos; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_ESS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinESs=current_intvl->AtucPerfEs; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_INIT_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinInits=current_intvl->AtucPerfInit; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_TIME_ELAPSED_FLAG)){ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i+=900; + } + do_gettimeofday(&time_now); + i+=time_now.tv_sec - (current_intvl->start_time).tv_sec; + if(i>=86400) + pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayTimeElapsed=i-86400; + else + pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayTimeElapsed=i; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_LOFS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfLof; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfLof; + pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayLofs=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_LOSS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfLos; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfLos; + pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayLoss=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_ESS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfEs; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfEs; + pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayESs=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_INIT_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfInit; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfInit; + pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayInits=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_MON_SEC_FLAG)){ + i=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + i++; + } + if(i>=96) + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayMoniSecs=86400; + else + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayMoniSecs=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_LOFS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfLof; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayLofs=j; + else + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayLofs=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_LOSS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfLos; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayLoss=j; + else + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayLoss=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_ESS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfEs; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayESs=j; + else + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayESs=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_INITS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfInit; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayInits=j; + else + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayInits=0; + } + + copy_to_user((char *)lon, (char *)pts.atucPerfDataEntry_pt, sizeof(atucPerfDataEntry)); + kfree(pts.atucPerfDataEntry_pt); + break; +#ifdef AMAZON_MEI_MIB_RFC3440 + case GET_ADSL_ATUC_PERF_DATA_EXT: //??? CMV mapping not available + pts.atucPerfDataExtEntry_pt = (atucPerfDataExtEntry *)kmalloc(sizeof(atucPerfDataExtEntry), GFP_KERNEL); + copy_from_user((char *)pts.atucPerfDataExtEntry_pt, (char *)lon, sizeof(atucPerfDataExtEntry)); + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_STAT_FASTR_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfStatFastR=ATUC_PERF_STAT_FASTR; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_STAT_FAILED_FASTR_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfStatFailedFastR=ATUC_PERF_STAT_FAILED_FASTR; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_STAT_SESL_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfStatSesL=ATUC_PERF_STAT_SESL; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_STAT_UASL_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfStatUasL=ATUC_PERF_STAT_UASL; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_15MIN_FASTR_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr15MinFastR=current_intvl->AtucPerfStatFastR; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_15MIN_FAILED_FASTR_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr15MinFailedFastR=current_intvl->AtucPerfStatFailedFastR; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_15MIN_SESL_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr15MinSesL=current_intvl->AtucPerfStatSesL; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_15MIN_UASL_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr15MinUasL=current_intvl->AtucPerfStatUasL; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_1DAY_FASTR_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatFastR; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfStatFastR; + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr1DayFastR=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_1DAY_FAILED_FASTR_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatFailedFastR; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfStatFailedFastR; + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr1DayFailedFastR=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_1DAY_SESL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatSesL; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfStatSesL; + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr1DaySesL=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_1DAY_UASL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatUasL; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfStatUasL; + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr1DayUasL=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_PREV_1DAY_FASTR_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatFastR; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayFastR=j; + else + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayFastR=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_PREV_1DAY_FAILED_FASTR_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatFailedFastR; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayFailedFastR=j; + else + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayFailedFastR=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_PREV_1DAY_SESL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatSesL; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DaySesL=j; + else + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DaySesL=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_PREV_1DAY_UASL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatUasL; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayUasL=j; + else + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayUasL=0; + } + copy_to_user((char *)lon, (char *)pts.atucPerfDataExtEntry_pt, sizeof(atucPerfDataExtEntry)); + kfree(pts.atucPerfDataExtEntry_pt); + break; +#endif + case GET_ADSL_ATUR_PERF_DATA: + pts.aturPerfDataEntry_pt = (aturPerfDataEntry *)kmalloc(sizeof(aturPerfDataEntry), GFP_KERNEL); + copy_from_user((char *)pts.aturPerfDataEntry_pt, (char *)lon, sizeof(aturPerfDataEntry)); + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_LOFS_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfLofs=ATUR_PERF_LOFS; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_LOSS_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfLoss=ATUR_PERF_LOSS; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_LPR_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfLprs=ATUR_PERF_LPR; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_ESS_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfESs=ATUR_PERF_ESS; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_VALID_INTVLS_FLAG)){ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==96) + break; + } + pts.aturPerfDataEntry_pt->adslAturPerfValidIntervals=i; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_INVALID_INTVLS_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfInvalidIntervals=0; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_TIME_ELAPSED_FLAG)){ + do_gettimeofday(&time_now); + pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinTimeElapsed=time_now.tv_sec - (current_intvl->start_time).tv_sec; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_LOFS_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinLofs=current_intvl->AturPerfLof; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_LOSS_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinLoss=current_intvl->AturPerfLos; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_LPR_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinLprs=current_intvl->AturPerfLpr; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_ESS_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinESs=current_intvl->AturPerfEs; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_TIME_ELAPSED_FLAG)){ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i+=900; + } + do_gettimeofday(&time_now); + i+=time_now.tv_sec - (current_intvl->start_time).tv_sec; + if(i>=86400) + pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayTimeElapsed=i-86400; + else + pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayTimeElapsed=i; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_LOFS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfLof; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturPerfLof; + pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayLofs=j; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_LOSS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfLos; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturPerfLos; + pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayLoss=j; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_LPR_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfLpr; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturPerfLpr; + pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayLprs=j; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_ESS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfEs; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturPerfEs; + pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayESs=j; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_MON_SEC_FLAG)){ + i=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + i++; + } + if(i>=96) + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayMoniSecs=86400; + else + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayMoniSecs=0; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_LOFS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfLof; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLofs=j; + else + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLofs=0; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_LOSS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfLos; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLoss=j; + else + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLoss=0; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_LPR_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfLpr; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLprs=j; + else + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLprs=0; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_ESS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfEs; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayESs=j; + else + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayESs=0; + } + + copy_to_user((char *)lon, (char *)pts.aturPerfDataEntry_pt, sizeof(aturPerfDataEntry)); + kfree(pts.aturPerfDataEntry_pt); + break; +#ifdef AMAZON_MEI_MIB_RFC3440 + case GET_ADSL_ATUR_PERF_DATA_EXT: + pts.aturPerfDataExtEntry_pt = (aturPerfDataExtEntry *)kmalloc(sizeof(aturPerfDataExtEntry), GFP_KERNEL); + copy_from_user((char *)pts.aturPerfDataExtEntry_pt, (char *)lon, sizeof(aturPerfDataExtEntry)); + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_STAT_SESL_FLAG)){ + pts.aturPerfDataExtEntry_pt->adslAturPerfStatSesL=ATUR_PERF_STAT_SESL; + } + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_STAT_UASL_FLAG)){ + pts.aturPerfDataExtEntry_pt->adslAturPerfStatUasL=ATUR_PERF_STAT_UASL; + } + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_CURR_15MIN_SESL_FLAG)){ + pts.aturPerfDataExtEntry_pt->adslAturPerfCurr15MinSesL=current_intvl->AturPerfStatSesL; + } + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_CURR_15MIN_UASL_FLAG)){ + pts.aturPerfDataExtEntry_pt->adslAturPerfCurr15MinUasL=current_intvl->AturPerfStatUasL; + } + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_CURR_1DAY_SESL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfStatSesL; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturPerfStatSesL; + pts.aturPerfDataExtEntry_pt->adslAturPerfCurr1DaySesL=j; + } + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_CURR_1DAY_UASL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfStatUasL; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturPerfStatUasL; + pts.aturPerfDataExtEntry_pt->adslAturPerfCurr1DayUasL=j; + } + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_PREV_1DAY_SESL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfStatSesL; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturPerfDataExtEntry_pt->adslAturPerfPrev1DaySesL=j; + else + pts.aturPerfDataExtEntry_pt->adslAturPerfPrev1DaySesL=0; + } + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_PREV_1DAY_UASL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfStatUasL; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturPerfDataExtEntry_pt->adslAturPerfPrev1DayUasL=j; + else + pts.aturPerfDataExtEntry_pt->adslAturPerfPrev1DayUasL=0; + } + copy_to_user((char *)lon, (char *)pts.aturPerfDataExtEntry_pt, sizeof(aturPerfDataExtEntry)); + kfree(pts.aturPerfDataExtEntry_pt); + break; +#endif + case GET_ADSL_ATUC_INTVL_INFO: + pts.adslAtucIntvlInfo_pt = (adslAtucIntvlInfo *)kmalloc(sizeof(adslAtucIntvlInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAtucIntvlInfo_pt, (char *)lon, sizeof(adslAtucIntvlInfo)); + + if(pts.adslAtucIntvlInfo_pt->IntervalNumber <1){ + pts.adslAtucIntvlInfo_pt->intervalLOF = ATUC_PERF_LOFS; + pts.adslAtucIntvlInfo_pt->intervalLOS = ATUC_PERF_LOSS; + pts.adslAtucIntvlInfo_pt->intervalES = ATUC_PERF_ESS; + pts.adslAtucIntvlInfo_pt->intervalInits = ATUC_PERF_INITS; + pts.adslAtucIntvlInfo_pt->intervalValidData = 1; + } + else{ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==pts.adslAtucIntvlInfo_pt->IntervalNumber){ + temp_intvl = list_entry(ptr, amazon_mei_mib, list); + pts.adslAtucIntvlInfo_pt->intervalLOF = temp_intvl->AtucPerfLof; + pts.adslAtucIntvlInfo_pt->intervalLOS = temp_intvl->AtucPerfLos; + pts.adslAtucIntvlInfo_pt->intervalES = temp_intvl->AtucPerfEs; + pts.adslAtucIntvlInfo_pt->intervalInits = temp_intvl->AtucPerfInit; + pts.adslAtucIntvlInfo_pt->intervalValidData = 1; + break; + } + } + if(ptr==&interval_list){ + pts.adslAtucIntvlInfo_pt->intervalValidData = 0; + pts.adslAtucIntvlInfo_pt->flags = 0; + pts.adslAtucIntvlInfo_pt->intervalLOF = 0; + pts.adslAtucIntvlInfo_pt->intervalLOS = 0; + pts.adslAtucIntvlInfo_pt->intervalES = 0; + pts.adslAtucIntvlInfo_pt->intervalInits = 0; + } + } + + copy_to_user((char *)lon, (char *)pts.adslAtucIntvlInfo_pt, sizeof(adslAtucIntvlInfo)); + kfree(pts.adslAtucIntvlInfo_pt); + break; +#ifdef AMAZON_MEI_MIB_RFC3440 + case GET_ADSL_ATUC_INTVL_EXT_INFO: + pts.adslAtucInvtlExtInfo_pt = (adslAtucInvtlExtInfo *)kmalloc(sizeof(adslAtucInvtlExtInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAtucInvtlExtInfo_pt, (char *)lon, sizeof(adslAtucInvtlExtInfo)); + if(pts.adslAtucInvtlExtInfo_pt->IntervalNumber <1){ + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFastR = ATUC_PERF_STAT_FASTR; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFailedFastR = ATUC_PERF_STAT_FAILED_FASTR; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalSesL = ATUC_PERF_STAT_SESL; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalUasL = ATUC_PERF_STAT_UASL; +// pts.adslAtucInvtlExtInfo_pt->intervalValidData = 1; + } + else{ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==pts.adslAtucInvtlExtInfo_pt->IntervalNumber){ + temp_intvl = list_entry(ptr, amazon_mei_mib, list); + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFastR = temp_intvl->AtucPerfStatFastR; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFailedFastR = temp_intvl->AtucPerfStatFailedFastR; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalSesL = temp_intvl->AtucPerfStatSesL; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalUasL = temp_intvl->AtucPerfStatUasL; +// pts.adslAtucInvtlExtInfo_pt->intervalValidData = 1; + break; + } + } + if(ptr==&interval_list){ +// pts.adslAtucInvtlExtInfo_pt->intervalValidData = 0; + pts.adslAtucInvtlExtInfo_pt->flags = 0; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFastR = 0; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFailedFastR = 0; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalSesL = 0; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalUasL = 0; + } + } + copy_to_user((char *)lon, (char *)pts.adslAtucInvtlExtInfo_pt, sizeof(adslAtucInvtlExtInfo)); + kfree(pts.adslAtucInvtlExtInfo_pt); + break; +#endif + case GET_ADSL_ATUR_INTVL_INFO: + pts.adslAturIntvlInfo_pt = (adslAturIntvlInfo *)kmalloc(sizeof(adslAturIntvlInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAturIntvlInfo_pt, (char *)lon, sizeof(adslAturIntvlInfo)); + + if(pts.adslAturIntvlInfo_pt->IntervalNumber <1){ + pts.adslAturIntvlInfo_pt->intervalLOF = ATUR_PERF_LOFS; + pts.adslAturIntvlInfo_pt->intervalLOS = ATUR_PERF_LOSS; + pts.adslAturIntvlInfo_pt->intervalES = ATUR_PERF_ESS; + pts.adslAturIntvlInfo_pt->intervalLPR = ATUR_PERF_LPR; + pts.adslAturIntvlInfo_pt->intervalValidData = 1; + } + else{ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==pts.adslAturIntvlInfo_pt->IntervalNumber){ + temp_intvl = list_entry(ptr, amazon_mei_mib, list); + pts.adslAturIntvlInfo_pt->intervalLOF = temp_intvl->AturPerfLof; + pts.adslAturIntvlInfo_pt->intervalLOS = temp_intvl->AturPerfLos; + pts.adslAturIntvlInfo_pt->intervalES = temp_intvl->AturPerfEs; + pts.adslAturIntvlInfo_pt->intervalLPR = temp_intvl->AturPerfLpr; + pts.adslAturIntvlInfo_pt->intervalValidData = 1; + break; + } + } + if(ptr==&interval_list){ + pts.adslAturIntvlInfo_pt->intervalValidData = 0; + pts.adslAturIntvlInfo_pt->flags = 0; + pts.adslAturIntvlInfo_pt->intervalLOF = 0; + pts.adslAturIntvlInfo_pt->intervalLOS = 0; + pts.adslAturIntvlInfo_pt->intervalES = 0; + pts.adslAturIntvlInfo_pt->intervalLPR = 0; + } + } + + copy_to_user((char *)lon, (char *)pts.adslAturIntvlInfo_pt, sizeof(adslAturIntvlInfo)); + kfree(pts.adslAturIntvlInfo_pt); + break; +#ifdef AMAZON_MEI_MIB_RFC3440 + case GET_ADSL_ATUR_INTVL_EXT_INFO: + pts.adslAturInvtlExtInfo_pt = (adslAturInvtlExtInfo *)kmalloc(sizeof(adslAturInvtlExtInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAturInvtlExtInfo_pt, (char *)lon, sizeof(adslAturInvtlExtInfo)); + + if(pts.adslAturInvtlExtInfo_pt->IntervalNumber <1){ + pts.adslAturInvtlExtInfo_pt->adslAturIntervalSesL = ATUR_PERF_STAT_SESL; + pts.adslAturInvtlExtInfo_pt->adslAturIntervalUasL = ATUR_PERF_STAT_UASL; +// pts.adslAturInvtlExtInfo_pt->intervalValidData = 1; + } + else{ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==pts.adslAturInvtlExtInfo_pt->IntervalNumber){ + temp_intvl = list_entry(ptr, amazon_mei_mib, list); + pts.adslAturInvtlExtInfo_pt->adslAturIntervalSesL = temp_intvl->AturPerfStatSesL; + pts.adslAturInvtlExtInfo_pt->adslAturIntervalUasL = temp_intvl->AturPerfStatUasL; +// pts.adslAturInvtlExtInfo_pt->intervalValidData = 1; + break; + } + } + if(ptr==&interval_list){ +// pts.adslAturInvtlExtInfo_pt->intervalValidData = 0; + pts.adslAturInvtlExtInfo_pt->flags = 0; + pts.adslAturInvtlExtInfo_pt->adslAturIntervalSesL = 0; + pts.adslAturInvtlExtInfo_pt->adslAturIntervalUasL = 0; + } + } + + copy_to_user((char *)lon, (char *)pts.adslAturInvtlExtInfo_pt, sizeof(adslAturInvtlExtInfo)); + kfree(pts.adslAturInvtlExtInfo_pt); + break; +#endif + case GET_ADSL_ATUC_CHAN_PERF_DATA: + pts.atucChannelPerfDataEntry_pt = (atucChannelPerfDataEntry *)kmalloc(sizeof(atucChannelPerfDataEntry), GFP_KERNEL); + copy_from_user((char *)pts.atucChannelPerfDataEntry_pt, (char *)lon, sizeof(atucChannelPerfDataEntry)); + + pts.atucChannelPerfDataEntry_pt->flags = 0; + + copy_to_user((char *)lon, (char *)pts.atucChannelPerfDataEntry_pt, sizeof(atucChannelPerfDataEntry)); + kfree(pts.atucChannelPerfDataEntry_pt); + break; + case GET_ADSL_ATUR_CHAN_PERF_DATA: + pts.aturChannelPerfDataEntry_pt = (aturChannelPerfDataEntry *)kmalloc(sizeof(aturChannelPerfDataEntry), GFP_KERNEL); + copy_from_user((char *)pts.aturChannelPerfDataEntry_pt, (char *)lon, sizeof(aturChannelPerfDataEntry)); + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_RECV_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanReceivedBlks=ATUR_CHAN_RECV_BLK; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_TX_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanTransmittedBlks=ATUR_CHAN_TX_BLK; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_CORR_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanCorrectedBlks=ATUR_CHAN_CORR_BLK; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_UNCORR_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanUncorrectBlks=ATUR_CHAN_UNCORR_BLK; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_VALID_INTVL_FLAG)){ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==96) + break; + } + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfValidIntervals=i; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_INVALID_INTVL_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfInvalidIntervals=0; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_TIME_ELAPSED_FLAG)){ + do_gettimeofday(&time_now); + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinTimeElapsed=time_now.tv_sec - (current_intvl->start_time).tv_sec; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_RECV_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinReceivedBlks=current_intvl->AturChanPerfRxBlk; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_TX_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinTransmittedBlks=current_intvl->AturChanPerfTxBlk; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_CORR_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinCorrectedBlks=current_intvl->AturChanPerfCorrBlk; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_UNCORR_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinUncorrectBlks=current_intvl->AturChanPerfUncorrBlk; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_TIME_ELAPSED_FLAG)){ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i+=900; + } + do_gettimeofday(&time_now); + i+=time_now.tv_sec - (current_intvl->start_time).tv_sec; + if(i>=86400) + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayTimeElapsed=i-86400; + else + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayTimeElapsed=i; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_RECV_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfRxBlk; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturChanPerfRxBlk; + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayReceivedBlks=j; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_TX_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfTxBlk; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturChanPerfTxBlk; + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayTransmittedBlks=j; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_CORR_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfCorrBlk; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturChanPerfCorrBlk; + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayCorrectedBlks=j; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_UNCORR_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfUncorrBlk; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturChanPerfUncorrBlk; + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayUncorrectBlks=j; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_MONI_SEC_FLAG)){ + i=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + i++; + } + if(i>=96) + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayMoniSecs=86400; + else + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayMoniSecs=0; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_RECV_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfRxBlk; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayReceivedBlks=j; + else + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayReceivedBlks=0; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_TRANS_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfTxBlk; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayTransmittedBlks=j; + else + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayTransmittedBlks=0; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_CORR_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfCorrBlk; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayCorrectedBlks=j; + else + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayCorrectedBlks=0; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_UNCORR_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfUncorrBlk; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayUncorrectBlks=j; + else + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayUncorrectBlks=0; + } + + copy_to_user((char *)lon, (char *)pts.aturChannelPerfDataEntry_pt, sizeof(aturChannelPerfDataEntry)); + kfree(pts.aturChannelPerfDataEntry_pt); + break; + case GET_ADSL_ATUC_CHAN_INTVL_INFO: + pts.adslAtucChanIntvlInfo_pt = (adslAtucChanIntvlInfo *)kmalloc(sizeof(adslAtucChanIntvlInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAtucChanIntvlInfo_pt, (char *)lon, sizeof(adslAtucChanIntvlInfo)); + + pts.adslAtucChanIntvlInfo_pt->flags = 0; + + copy_to_user((char *)lon, (char *)pts.adslAtucChanIntvlInfo_pt, sizeof(adslAtucChanIntvlInfo)); + kfree(pts.adslAtucChanIntvlInfo_pt); + break; + case GET_ADSL_ATUR_CHAN_INTVL_INFO: + pts.adslAturChanIntvlInfo_pt = (adslAturChanIntvlInfo *)kmalloc(sizeof(adslAturChanIntvlInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAturChanIntvlInfo_pt, (char *)lon, sizeof(adslAturChanIntvlInfo)); + + if(pts.adslAturChanIntvlInfo_pt->IntervalNumber <1){ + pts.adslAturChanIntvlInfo_pt->chanIntervalRecvdBlks = ATUR_CHAN_RECV_BLK; + pts.adslAturChanIntvlInfo_pt->chanIntervalXmitBlks = ATUR_CHAN_TX_BLK; + pts.adslAturChanIntvlInfo_pt->chanIntervalCorrectedBlks = ATUR_CHAN_CORR_BLK; + pts.adslAturChanIntvlInfo_pt->chanIntervalUncorrectBlks = ATUR_CHAN_UNCORR_BLK; + pts.adslAturChanIntvlInfo_pt->intervalValidData = 1; + } + else{ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==pts.adslAturChanIntvlInfo_pt->IntervalNumber){ + temp_intvl = list_entry(ptr, amazon_mei_mib, list); + pts.adslAturChanIntvlInfo_pt->chanIntervalRecvdBlks = temp_intvl->AturChanPerfRxBlk; + pts.adslAturChanIntvlInfo_pt->chanIntervalXmitBlks = temp_intvl->AturChanPerfTxBlk; + pts.adslAturChanIntvlInfo_pt->chanIntervalCorrectedBlks = temp_intvl->AturChanPerfCorrBlk; + pts.adslAturChanIntvlInfo_pt->chanIntervalUncorrectBlks = temp_intvl->AturChanPerfUncorrBlk; + pts.adslAturChanIntvlInfo_pt->intervalValidData = 1; + break; + } + } + if(ptr==&interval_list){ + pts.adslAturChanIntvlInfo_pt->intervalValidData = 0; + pts.adslAturChanIntvlInfo_pt->flags = 0; + } + } + + copy_to_user((char *)lon, (char *)pts.adslAturChanIntvlInfo_pt, sizeof(adslAturChanIntvlInfo)); + kfree(pts.adslAturChanIntvlInfo_pt); + break; + case GET_ADSL_ALRM_CONF_PROF: + pts.adslLineAlarmConfProfileEntry_pt = (adslLineAlarmConfProfileEntry *)kmalloc(sizeof(adslLineAlarmConfProfileEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslLineAlarmConfProfileEntry_pt, (char *)lon, sizeof(adslLineAlarmConfProfileEntry)); + + strncpy(pts.adslLineAlarmConfProfileEntry_pt->adslLineAlarmConfProfileName, AlarmConfProfile.adslLineAlarmConfProfileName, 32); + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_LOFS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinLofs=AlarmConfProfile.adslAtucThresh15MinLofs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_LOSS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinLoss=AlarmConfProfile.adslAtucThresh15MinLoss; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_ESS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinESs=AlarmConfProfile.adslAtucThresh15MinESs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_FAST_RATEUP_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshFastRateUp=AlarmConfProfile.adslAtucThreshFastRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_INTERLEAVE_RATEUP_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshInterleaveRateUp=AlarmConfProfile.adslAtucThreshInterleaveRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_FAST_RATEDOWN_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshFastRateDown=AlarmConfProfile.adslAtucThreshFastRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_INTERLEAVE_RATEDOWN_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshInterleaveRateDown=AlarmConfProfile.adslAtucThreshInterleaveRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_INIT_FAILURE_TRAP_ENABLE_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucInitFailureTrapEnable=AlarmConfProfile.adslAtucInitFailureTrapEnable; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LOFS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLofs=AlarmConfProfile.adslAturThresh15MinLofs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LOSS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLoss=AlarmConfProfile.adslAturThresh15MinLoss; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LPRS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLprs=AlarmConfProfile.adslAturThresh15MinLprs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_ESS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinESs=AlarmConfProfile.adslAturThresh15MinESs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_FAST_RATEUP_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshFastRateUp=AlarmConfProfile.adslAturThreshFastRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_INTERLEAVE_RATEUP_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshInterleaveRateUp=AlarmConfProfile.adslAturThreshInterleaveRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_FAST_RATEDOWN_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshFastRateDown=AlarmConfProfile.adslAturThreshFastRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_INTERLEAVE_RATEDOWN_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshInterleaveRateDown=AlarmConfProfile.adslAturThreshInterleaveRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), LINE_ALARM_CONF_PROFILE_ROWSTATUS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslLineAlarmConfProfileRowStatus=AlarmConfProfile.adslLineAlarmConfProfileRowStatus; + } + copy_to_user((char *)lon, (char *)pts.adslLineAlarmConfProfileEntry_pt, sizeof(adslLineAlarmConfProfileEntry)); + kfree(pts.adslLineAlarmConfProfileEntry_pt); + break; +#ifdef AMAZON_MEI_MIB_RFC3440 + case GET_ADSL_ALRM_CONF_PROF_EXT: + pts.adslLineAlarmConfProfileExtEntry_pt = (adslLineAlarmConfProfileExtEntry *)kmalloc(sizeof(adslLineAlarmConfProfileExtEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslLineAlarmConfProfileExtEntry_pt, (char *)lon, sizeof(adslLineAlarmConfProfileExtEntry)); + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_FAILED_FASTR_FLAG)){ + pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinFailedFastR=AlarmConfProfileExt.adslAtucThreshold15MinFailedFastR; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_SESL_FLAG)){ + pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinSesL=AlarmConfProfileExt.adslAtucThreshold15MinSesL; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_UASL_FLAG)){ + pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinUasL=AlarmConfProfileExt.adslAtucThreshold15MinUasL; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUR_THRESH_15MIN_SESL_FLAG)){ + pts.adslLineAlarmConfProfileExtEntry_pt->adslAturThreshold15MinSesL=AlarmConfProfileExt.adslAturThreshold15MinSesL; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUR_THRESH_15MIN_UASL_FLAG)){ + pts.adslLineAlarmConfProfileExtEntry_pt->adslAturThreshold15MinUasL=AlarmConfProfileExt.adslAturThreshold15MinUasL; + } + copy_to_user((char *)lon, (char *)pts.adslLineAlarmConfProfileExtEntry_pt, sizeof(adslLineAlarmConfProfileExtEntry)); + kfree(pts.adslLineAlarmConfProfileExtEntry_pt); + break; +#endif + case SET_ADSL_ALRM_CONF_PROF: + pts.adslLineAlarmConfProfileEntry_pt = (adslLineAlarmConfProfileEntry *)kmalloc(sizeof(adslLineAlarmConfProfileEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslLineAlarmConfProfileEntry_pt, (char *)lon, sizeof(adslLineAlarmConfProfileEntry)); + + strncpy(AlarmConfProfile.adslLineAlarmConfProfileName, pts.adslLineAlarmConfProfileEntry_pt->adslLineAlarmConfProfileName, 32); + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_LOFS_FLAG)){ + AlarmConfProfile.adslAtucThresh15MinLofs=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinLofs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_LOSS_FLAG)){ + AlarmConfProfile.adslAtucThresh15MinLoss=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinLoss; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_ESS_FLAG)){ + AlarmConfProfile.adslAtucThresh15MinESs=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinESs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_FAST_RATEUP_FLAG)){ + AlarmConfProfile.adslAtucThreshFastRateUp=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshFastRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_INTERLEAVE_RATEUP_FLAG)){ + AlarmConfProfile.adslAtucThreshInterleaveRateUp=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshInterleaveRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_FAST_RATEDOWN_FLAG)){ + AlarmConfProfile.adslAtucThreshFastRateDown=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshFastRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_INTERLEAVE_RATEDOWN_FLAG)){ + AlarmConfProfile.adslAtucThreshInterleaveRateDown=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshInterleaveRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_INIT_FAILURE_TRAP_ENABLE_FLAG)){ + AlarmConfProfile.adslAtucInitFailureTrapEnable=pts.adslLineAlarmConfProfileEntry_pt->adslAtucInitFailureTrapEnable; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LOFS_FLAG)){ + AlarmConfProfile.adslAturThresh15MinLofs=pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLofs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LOSS_FLAG)){ + AlarmConfProfile.adslAturThresh15MinLoss=pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLoss; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LPRS_FLAG)){ + AlarmConfProfile.adslAturThresh15MinLprs=pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLprs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_ESS_FLAG)){ + AlarmConfProfile.adslAturThresh15MinESs=pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinESs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_FAST_RATEUP_FLAG)){ + AlarmConfProfile.adslAturThreshFastRateUp=pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshFastRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_INTERLEAVE_RATEUP_FLAG)){ + AlarmConfProfile.adslAturThreshInterleaveRateUp=pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshInterleaveRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_FAST_RATEDOWN_FLAG)){ + AlarmConfProfile.adslAturThreshFastRateDown=pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshFastRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_INTERLEAVE_RATEDOWN_FLAG)){ + AlarmConfProfile.adslAturThreshInterleaveRateDown=pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshInterleaveRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), LINE_ALARM_CONF_PROFILE_ROWSTATUS_FLAG)){ + AlarmConfProfile.adslLineAlarmConfProfileRowStatus=pts.adslLineAlarmConfProfileEntry_pt->adslLineAlarmConfProfileRowStatus; + } + copy_to_user((char *)lon, (char *)pts.adslLineAlarmConfProfileEntry_pt, sizeof(adslLineAlarmConfProfileEntry)); + kfree(pts.adslLineAlarmConfProfileEntry_pt); + break; + +#ifdef AMAZON_MEI_MIB_RFC3440 + case SET_ADSL_ALRM_CONF_PROF_EXT: + pts.adslLineAlarmConfProfileExtEntry_pt = (adslLineAlarmConfProfileExtEntry *)kmalloc(sizeof(adslLineAlarmConfProfileExtEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslLineAlarmConfProfileExtEntry_pt, (char *)lon, sizeof(adslLineAlarmConfProfileExtEntry)); + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_FAILED_FASTR_FLAG)){ + AlarmConfProfileExt.adslAtucThreshold15MinFailedFastR=pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinFailedFastR; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_SESL_FLAG)){ + AlarmConfProfileExt.adslAtucThreshold15MinSesL=pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinSesL; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_UASL_FLAG)){ + AlarmConfProfileExt.adslAtucThreshold15MinUasL=pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinUasL; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUR_THRESH_15MIN_SESL_FLAG)){ + AlarmConfProfileExt.adslAturThreshold15MinSesL=pts.adslLineAlarmConfProfileExtEntry_pt->adslAturThreshold15MinSesL; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUR_THRESH_15MIN_UASL_FLAG)){ + AlarmConfProfileExt.adslAturThreshold15MinUasL=pts.adslLineAlarmConfProfileExtEntry_pt->adslAturThreshold15MinUasL; + } + copy_to_user((char *)lon, (char *)pts.adslLineAlarmConfProfileExtEntry_pt, sizeof(adslLineAlarmConfProfileExtEntry)); + kfree(pts.adslLineAlarmConfProfileExtEntry_pt); + break; +#endif + + case ADSL_ATUR_TRAPS: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + trapsflag=0; + if(AlarmConfProfile.adslAtucThresh15MinLofs!=0 && current_intvl->AtucPerfLof>=AlarmConfProfile.adslAtucThresh15MinLofs) + trapsflag|=ATUC_PERF_LOFS_THRESH_FLAG; + if(AlarmConfProfile.adslAtucThresh15MinLoss!=0 && current_intvl->AtucPerfLos>=AlarmConfProfile.adslAtucThresh15MinLoss) + trapsflag|=ATUC_PERF_LOSS_THRESH_FLAG; + if(AlarmConfProfile.adslAtucThresh15MinESs!=0 && current_intvl->AtucPerfEs>=AlarmConfProfile.adslAtucThresh15MinESs) + trapsflag|=ATUC_PERF_ESS_THRESH_FLAG; + if(chantype.fast==1){ + if(AlarmConfProfile.adslAtucThreshFastRateUp!=0 || AlarmConfProfile.adslAtucThreshFastRateDown!=0){ + ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 1 Index 0"); +#endif + } + else{ + temp = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + if((AlarmConfProfile.adslAtucThreshFastRateUp!=0) && (temp>=PrevTxRate.adslAtucChanPrevTxRate+AlarmConfProfile.adslAtucThreshFastRateUp)){ + trapsflag|=ATUC_RATE_CHANGE_FLAG; + PrevTxRate.adslAtucChanPrevTxRate = temp; + } + if((AlarmConfProfile.adslAtucThreshFastRateDown!=0) && (temp<=PrevTxRate.adslAtucChanPrevTxRate-AlarmConfProfile.adslAtucThreshFastRateDown)){ + trapsflag|=ATUC_RATE_CHANGE_FLAG; + PrevTxRate.adslAtucChanPrevTxRate = temp; + } + } + } + } + if(chantype.interleave==1){ + if(AlarmConfProfile.adslAtucThreshInterleaveRateUp!=0 || AlarmConfProfile.adslAtucThreshInterleaveRateDown!=0){ + ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 1 Index 0"); +#endif + } + else{ + temp = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + if((AlarmConfProfile.adslAtucThreshInterleaveRateUp!=0) && (temp>=PrevTxRate.adslAtucChanPrevTxRate+AlarmConfProfile.adslAtucThreshInterleaveRateUp)){ + trapsflag|=ATUC_RATE_CHANGE_FLAG; + PrevTxRate.adslAtucChanPrevTxRate = temp; + } + if((AlarmConfProfile.adslAtucThreshInterleaveRateDown!=0) && (temp<=PrevTxRate.adslAtucChanPrevTxRate-AlarmConfProfile.adslAtucThreshInterleaveRateDown)){ + trapsflag|=ATUC_RATE_CHANGE_FLAG; + PrevTxRate.adslAtucChanPrevTxRate = temp; + } + } + } + } + if(AlarmConfProfile.adslAturThresh15MinLofs!=0 && current_intvl->AturPerfLof>=AlarmConfProfile.adslAturThresh15MinLofs) + trapsflag|=ATUR_PERF_LOFS_THRESH_FLAG; + if(AlarmConfProfile.adslAturThresh15MinLoss!=0 && current_intvl->AturPerfLos>=AlarmConfProfile.adslAturThresh15MinLoss) + trapsflag|=ATUR_PERF_LOSS_THRESH_FLAG; + if(AlarmConfProfile.adslAturThresh15MinLprs!=0 && current_intvl->AturPerfLpr>=AlarmConfProfile.adslAturThresh15MinLprs) + trapsflag|=ATUR_PERF_LPRS_THRESH_FLAG; + if(AlarmConfProfile.adslAturThresh15MinESs!=0 && current_intvl->AturPerfEs>=AlarmConfProfile.adslAturThresh15MinESs) + trapsflag|=ATUR_PERF_ESS_THRESH_FLAG; + if(chantype.fast==1){ + if(AlarmConfProfile.adslAturThreshFastRateUp!=0 || AlarmConfProfile.adslAturThreshFastRateDown!=0){ + ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 0 Index 0"); +#endif + } + else{ + temp = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + if((AlarmConfProfile.adslAturThreshFastRateUp!=0) && (temp>=PrevTxRate.adslAturChanPrevTxRate+AlarmConfProfile.adslAturThreshFastRateUp)){ + trapsflag|=ATUR_RATE_CHANGE_FLAG; + PrevTxRate.adslAturChanPrevTxRate = temp; + } + if((AlarmConfProfile.adslAturThreshFastRateDown!=0) && (temp<=PrevTxRate.adslAturChanPrevTxRate-AlarmConfProfile.adslAturThreshFastRateDown)){ + trapsflag|=ATUR_RATE_CHANGE_FLAG; + PrevTxRate.adslAturChanPrevTxRate = temp; + } + } + } + } + if(chantype.interleave==1){ + if(AlarmConfProfile.adslAturThreshInterleaveRateUp!=0 || AlarmConfProfile.adslAturThreshInterleaveRateDown!=0){ + ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 0 Index 0"); +#endif + } + else{ + temp = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + if((AlarmConfProfile.adslAturThreshInterleaveRateUp!=0) && (temp>=PrevTxRate.adslAturChanPrevTxRate+AlarmConfProfile.adslAturThreshInterleaveRateUp)){ + trapsflag|=ATUR_RATE_CHANGE_FLAG; + PrevTxRate.adslAturChanPrevTxRate = temp; + } + if((AlarmConfProfile.adslAturThreshInterleaveRateDown!=0) && (temp<=PrevTxRate.adslAturChanPrevTxRate-AlarmConfProfile.adslAturThreshInterleaveRateDown)){ + trapsflag|=ATUR_RATE_CHANGE_FLAG; + PrevTxRate.adslAturChanPrevTxRate = temp; + } + } + } + } + copy_to_user((char *)lon, (char *)(&trapsflag), 2); + + up(&mei_sema); + break; + +#ifdef AMAZON_MEI_MIB_RFC3440 + case ADSL_ATUR_EXT_TRAPS: + trapsflag=0; + if(AlarmConfProfileExt.adslAtucThreshold15MinFailedFastR!=0 && current_intvl->AtucPerfStatFailedFastR>=AlarmConfProfileExt.adslAtucThreshold15MinFailedFastR) + trapsflag|=ATUC_15MIN_FAILED_FASTR_TRAP_FLAG; + if(AlarmConfProfileExt.adslAtucThreshold15MinSesL!=0 && current_intvl->AtucPerfStatSesL>=AlarmConfProfileExt.adslAtucThreshold15MinSesL) + trapsflag|=ATUC_15MIN_SESL_TRAP_FLAG; + if(AlarmConfProfileExt.adslAtucThreshold15MinUasL!=0 && current_intvl->AtucPerfStatUasL>=AlarmConfProfileExt.adslAtucThreshold15MinUasL) + trapsflag|=ATUC_15MIN_UASL_TRAP_FLAG; + if(AlarmConfProfileExt.adslAturThreshold15MinSesL!=0 && current_intvl->AturPerfStatSesL>=AlarmConfProfileExt.adslAturThreshold15MinSesL) + trapsflag|=ATUR_15MIN_SESL_TRAP_FLAG; + if(AlarmConfProfileExt.adslAturThreshold15MinUasL!=0 && current_intvl->AturPerfStatUasL>=AlarmConfProfileExt.adslAturThreshold15MinUasL) + trapsflag|=ATUR_15MIN_UASL_TRAP_FLAG; + copy_to_user((char *)lon, (char *)(&trapsflag), 2); + break; +#endif + +// 603221:tc.chen start + case GET_ADSL_LINE_STATUS: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslLineStatusInfo_pt = (adslLineStatusInfo *)kmalloc(sizeof(adslLineStatusInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslLineStatusInfo_pt, (char *)lon, sizeof(adslLineStatusInfo)); + + if(IS_FLAG_SET((&(pts.adslLineStatusInfo_pt->flags)), LINE_STAT_MODEM_STATUS_FLAG)){ + LINE_STAT_MODEM_STATUS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group STAT Address 0 Index 0"); +#endif + pts.adslLineStatusInfo_pt->adslModemStatus = 0; + } + else{ + pts.adslLineStatusInfo_pt->adslModemStatus = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslLineStatusInfo_pt->flags)), LINE_STAT_MODE_SEL_FLAG)){ + LINE_STAT_MODE_SEL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group STAT Address 1 Index 0"); +#endif + pts.adslLineStatusInfo_pt->adslModeSelected = 0; + } + else{ + pts.adslLineStatusInfo_pt->adslModeSelected = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslLineStatusInfo_pt->flags)), LINE_STAT_TRELLCOD_ENABLE_FLAG)){ + LINE_STAT_TRELLCOD_ENABLE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group OPTN Address 2 Index 0"); +#endif + pts.adslLineStatusInfo_pt->adslTrellisCodeEnable = 0; + } + else{ + + pts.adslLineStatusInfo_pt->adslTrellisCodeEnable = (RxMessage[4]>>13)&0x1==0x1?0:1; + } + } + + if(IS_FLAG_SET((&(pts.adslLineStatusInfo_pt->flags)), LINE_STAT_LATENCY_FLAG)){ + LINE_STAT_LATENCY_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group STAT Address 12 Index 0"); +#endif + pts.adslLineStatusInfo_pt->adslLatency = 0; + } + else{ + pts.adslLineStatusInfo_pt->adslLatency = RxMessage[4]; + } + } + + copy_to_user((char *)lon, (char *)pts.adslLineStatusInfo_pt, sizeof(adslLineStatusInfo)); + kfree(pts.adslLineStatusInfo_pt); + + up(&mei_sema); + break; + + + case GET_ADSL_LINE_RATE: + if (showtime!=1) + return -ERESTARTSYS; + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslLineRateInfo_pt = (adslLineRateInfo *)kmalloc(sizeof(adslLineRateInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslLineRateInfo_pt, (char *)lon, sizeof(adslLineRateInfo)); + + if(IS_FLAG_SET((&(pts.adslLineRateInfo_pt->flags)), LINE_RATE_DATA_RATEDS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode + { + if (chantype.interleave) + LINE_RATE_DATA_RATEDS_FLAG_ADSL1_LP0_MAKECMV; + else + LINE_RATE_DATA_RATEDS_FLAG_ADSL1_LP1_MAKECMV; + + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group RATE Address 1 Index 0"); +#endif + pts.adslLineRateInfo_pt->adslDataRateds = 0; + } + else{ + pts.adslLineRateInfo_pt->adslDataRateds = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + }else // adsl 2/2+ + { + unsigned long Mp,Lp,Tp,Rp,Kp,Bpn,DataRate,DataRate_remain; + Mp=Lp=Tp=Rp=Kp=Bpn=DataRate=DataRate_remain=0; + //// up stream data rate + + if (chantype.interleave) + { + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_LP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 25 Index 0"); +#endif + Lp = 0; + }else + Lp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_RP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 23 Index 0"); +#endif + Rp = 0; + }else + Rp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_MP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 24 Index 0"); +#endif + Mp = 0; + }else + Mp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_TP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 26 Index 0"); +#endif + Tp = 0; + }else + Tp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_KP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 28 Index 0"); +#endif + Kp = 0; + }else + { + Kp=RxMessage[4]+ RxMessage[5]+1; + Bpn=RxMessage[4]+ RxMessage[5]; + } + }else + { + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_LP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 25 Index 1"); +#endif + Lp = 0; + }else + Lp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_RP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 23 Index 1"); +#endif + Rp = 0; + }else + Rp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_MP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 24 Index 1"); +#endif + Mp = 0; + }else + Mp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_TP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 26 Index 1"); +#endif + Tp = 0; + }else + Tp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_KP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 28 Index 2"); +#endif + Kp = 0; + }else + { + Kp=RxMessage[4]+ RxMessage[5]+1; + Bpn=RxMessage[4]+ RxMessage[5]; + } + } + DataRate=((Tp*(Bpn+1)-1)*Mp*Lp*4)/(Tp*(Kp*Mp+Rp)); + //DataRate_remain=((((Tp*(Bpn+1)-1)*Mp*Lp*4)%(Tp*(Kp*Mp+Rp)))*1000)/(Tp*(Kp*Mp+Rp)); + //pts.adslLineRateInfo_pt->adslDataRateds = DataRate * 1000 + DataRate_remain; + pts.adslLineRateInfo_pt->adslDataRateds = DataRate; + } + } + + if(IS_FLAG_SET((&(pts.adslLineRateInfo_pt->flags)), LINE_RATE_DATA_RATEUS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode + { + if (chantype.interleave) + LINE_RATE_DATA_RATEUS_FLAG_ADSL1_LP0_MAKECMV; + else + LINE_RATE_DATA_RATEUS_FLAG_ADSL1_LP1_MAKECMV; + + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ + #ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group RATE Address 0 Index 0"); + #endif + pts.adslLineRateInfo_pt->adslDataRateus = 0; + } + else{ + pts.adslLineRateInfo_pt->adslDataRateus = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + }else // adsl 2/2+ + { + unsigned long Mp,Lp,Tp,Rp,Kp,Bpn,DataRate,DataRate_remain; + Mp=Lp=Tp=Rp=Kp=Bpn=DataRate=DataRate_remain=0; + //// down stream data rate + + if (chantype.interleave) + { + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_LP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 14 Index 0"); +#endif + Lp = 0; + }else + Lp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_RP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 12 Index 0"); +#endif + Rp = 0; + }else + Rp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_MP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 13 Index 0"); +#endif + Mp = 0; + }else + Mp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_TP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 15 Index 0"); +#endif + Tp = 0; + }else + Tp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_KP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 17 Index 0"); +#endif + Kp = 0; + }else + { + Kp=RxMessage[4]+ RxMessage[5]+1; + Bpn=RxMessage[4]+ RxMessage[5]; + } + }else + { + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_LP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 14 Index 1"); +#endif + Lp = 0; + }else + Lp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_RP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 12 Index 1"); +#endif + Rp = 0; + }else + Rp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_MP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 13 Index 1"); +#endif + Mp = 0; + }else + Mp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_TP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 15 Index 1"); +#endif + Tp = 0; + }else + Tp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_KP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 17 Index 2"); +#endif + Kp = 0; + }else + { + Kp=RxMessage[4]+ RxMessage[5]+1; + Bpn=RxMessage[4]+ RxMessage[5]; + } + } + DataRate=((Tp*(Bpn+1)-1)*Mp*Lp*4)/(Tp*(Kp*Mp+Rp)); + //DataRate_remain=((((Tp*(Bpn+1)-1)*Mp*Lp*4)%(Tp*(Kp*Mp+Rp)))*1000)/(Tp*(Kp*Mp+Rp)); + //pts.adslLineRateInfo_pt->adslDataRateus = DataRate * 1000 + DataRate_remain; + pts.adslLineRateInfo_pt->adslDataRateus = DataRate; + } + } + + if(IS_FLAG_SET((&(pts.adslLineRateInfo_pt->flags)), LINE_RATE_ATTNDRDS_FLAG)){ + LINE_RATE_ATTNDRDS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 68 Index 4"); +#endif + pts.adslLineRateInfo_pt->adslATTNDRds = 0; + } + else{ + pts.adslLineRateInfo_pt->adslATTNDRds = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + } + + if(IS_FLAG_SET((&(pts.adslLineRateInfo_pt->flags)), LINE_RATE_ATTNDRUS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode + { + LINE_RATE_ATTNDRUS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ + #ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 69 Index 4"); + #endif + pts.adslLineRateInfo_pt->adslATTNDRus = 0; + } + else{ + pts.adslLineRateInfo_pt->adslATTNDRus = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + }else + { + hdlc_cmd[0]=0x0181; + hdlc_cmd[1]=0x24; + up(&mei_sema); + if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + hdlc_rx_len=0; + hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2); + if (hdlc_rx_len <=0) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_RATE_END; + } + pts.adslLineRateInfo_pt->adslATTNDRus = (u32)le16_to_cpu(hdlc_rx_buffer[1])<<16 | (u32)le16_to_cpu(hdlc_rx_buffer[2]); + } + if(down_interruptible(&mei_sema)) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_RATE_END; + } + } + } + copy_to_user((char *)lon, (char *)pts.adslLineRateInfo_pt, sizeof(adslLineRateInfo)); + up(&mei_sema); + +GET_ADSL_LINE_RATE_END: + kfree(pts.adslLineRateInfo_pt); + break; + + case GET_ADSL_LINE_INFO: + if (showtime!=1) + return -ERESTARTSYS; + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslLineInfo_pt = (adslLineInfo *)kmalloc(sizeof(adslLineInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslLineInfo_pt, (char *)lon, sizeof(adslLineInfo)); + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_INTLV_DEPTHDS_FLAG)){ + if (chantype.interleave) + LINE_INFO_INTLV_DEPTHDS_FLAG_LP0_MAKECMV; + else + LINE_INFO_INTLV_DEPTHDS_FLAG_LP1_MAKECMV; + + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 27 Index 0"); +#endif + pts.adslLineInfo_pt->adslInterleaveDepthds = 0; + } + else{ + pts.adslLineInfo_pt->adslInterleaveDepthds = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_INTLV_DEPTHUS_FLAG)){ + if (chantype.interleave) + LINE_INFO_INTLV_DEPTHUS_FLAG_LP0_MAKECMV; + else + LINE_INFO_INTLV_DEPTHUS_FLAG_LP1_MAKECMV; + + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 16 Index 0"); +#endif + pts.adslLineInfo_pt->adslInterleaveDepthus = 0; + } + else{ + pts.adslLineInfo_pt->adslInterleaveDepthus = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_LATNDS_FLAG)){ + LINE_INFO_LATNDS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 68 Index 1"); +#endif + pts.adslLineInfo_pt->adslLATNds = 0; + } + else{ + pts.adslLineInfo_pt->adslLATNds = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_LATNUS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode + { + LINE_INFO_LATNUS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 69 Index 1"); +#endif + pts.adslLineInfo_pt->adslLATNus = 0; + } + else{ + pts.adslLineInfo_pt->adslLATNus = RxMessage[4]; + } + }else + { + hdlc_cmd[0]=0x0181; + hdlc_cmd[1]=0x21; + up(&mei_sema); + if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + hdlc_rx_len=0; + hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2); + if (hdlc_rx_len <=0) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + pts.adslLineInfo_pt->adslLATNus = le16_to_cpu(hdlc_rx_buffer[1]); + } + if(down_interruptible(&mei_sema)) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_SATNDS_FLAG)){ + LINE_INFO_SATNDS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 68 Index 2"); +#endif + pts.adslLineInfo_pt->adslSATNds = 0; + } + else{ + pts.adslLineInfo_pt->adslSATNds = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_SATNUS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode + { + LINE_INFO_SATNUS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 69 Index 2"); +#endif + pts.adslLineInfo_pt->adslSATNus = 0; + } + else{ + pts.adslLineInfo_pt->adslSATNus = RxMessage[4]; + } + }else + { + hdlc_cmd[0]=0x0181; + hdlc_cmd[1]=0x22; + up(&mei_sema); + if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + hdlc_rx_len=0; + hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2); + if (hdlc_rx_len <=0) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + pts.adslLineInfo_pt->adslSATNus = le16_to_cpu(hdlc_rx_buffer[1]); + } + if(down_interruptible(&mei_sema)) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_SNRMNDS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode + { + LINE_INFO_SNRMNDS_FLAG_ADSL1_MAKECMV; + } + else if ((adsl_mode == 0x4000) || (adsl_mode == 0x8000) || adsl_mode_extend > 0) + { + LINE_INFO_SNRMNDS_FLAG_ADSL2PLUS_MAKECMV; + } + else + { + LINE_INFO_SNRMNDS_FLAG_ADSL2_MAKECMV; + } + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 68 Index 3"); +#endif + pts.adslLineInfo_pt->adslSNRMds = 0; + } + else{ + if (adsl_mode>8 || adsl_mode_extend>0) + { + int SNRMds,SNRMds_remain; + SNRMds=RxMessage[4]; + SNRMds_remain=((SNRMds&0xff)*1000)/256; + SNRMds=(SNRMds>>8)&0xff; + if ((SNRMds_remain%100)>=50) SNRMds_remain=(SNRMds_remain/100)+1; + else SNRMds_remain=(SNRMds_remain/100); + pts.adslLineInfo_pt->adslSNRMds = SNRMds*10 + SNRMds_remain; + }else + { + pts.adslLineInfo_pt->adslSNRMds = RxMessage[4]; + } + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_SNRMNUS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend == 0) + { + LINE_INFO_SNRMNUS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 69 Index 3"); +#endif + pts.adslLineInfo_pt->adslSNRMus = 0; + } + else{ + pts.adslLineInfo_pt->adslSNRMus = RxMessage[4]; + } + }else + { + hdlc_cmd[0]=0x0181; + hdlc_cmd[1]=0x23; + up(&mei_sema); + if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + hdlc_rx_len=0; + hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2); + if (hdlc_rx_len <=0) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + pts.adslLineInfo_pt->adslSNRMus = le16_to_cpu(hdlc_rx_buffer[1]); + } + if(down_interruptible(&mei_sema)) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_ACATPDS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend == 0) + { + LINE_INFO_ACATPDS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ + #ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 68 Index 6"); + #endif + pts.adslLineInfo_pt->adslACATPds = 0; + } + else{ + pts.adslLineInfo_pt->adslACATPds = RxMessage[4]; + } + }else + { + hdlc_cmd[0]=0x0181; + hdlc_cmd[1]=0x25; + up(&mei_sema); + if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + hdlc_rx_len=0; + hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2); + if (hdlc_rx_len <=0) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + pts.adslLineInfo_pt->adslACATPds = le16_to_cpu(hdlc_rx_buffer[1]); + } + if(down_interruptible(&mei_sema)) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_ACATPUS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend == 0) + { + LINE_INFO_ACATPUS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 69 Index 6"); +#endif + pts.adslLineInfo_pt->adslACATPus = 0; + } + else{ + pts.adslLineInfo_pt->adslACATPus = RxMessage[4]; + } + }else + { + hdlc_cmd[0]=0x0181; + hdlc_cmd[1]=0x26; + up(&mei_sema); + if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + hdlc_rx_len=0; + hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2); + if (hdlc_rx_len <=0) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + pts.adslLineInfo_pt->adslACATPus = le16_to_cpu(hdlc_rx_buffer[1]); + } + if(down_interruptible(&mei_sema)) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + } + } + + copy_to_user((char *)lon, (char *)pts.adslLineInfo_pt, sizeof(adslLineInfo)); + up(&mei_sema); + +GET_ADSL_LINE_INFO_END: + kfree(pts.adslLineInfo_pt); + break; + + case GET_ADSL_NEAREND_STATS: + if (showtime!=1) + return -ERESTARTSYS; + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslNearEndPerfStats_pt = (adslNearEndPerfStats *)kmalloc(sizeof(adslNearEndPerfStats), GFP_KERNEL); + copy_from_user((char *)pts.adslNearEndPerfStats_pt, (char *)lon, sizeof(adslNearEndPerfStats)); + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_SUPERFRAME_FLAG)){ + NEAREND_PERF_SUPERFRAME_FLAG_LSW_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 20 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslSuperFrames = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslSuperFrames = (u32)(RxMessage[4]); + } + NEAREND_PERF_SUPERFRAME_FLAG_MSW_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 21 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslSuperFrames = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslSuperFrames += (((u32)(RxMessage[4]))<<16); + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOS_FLAG) || + IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOF_FLAG) || + IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LPR_FLAG) || + IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_NCD_FLAG) || + IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LCD_FLAG) ){ + NEAREND_PERF_LOS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 0 Index 0"); +#endif + RxMessage[4] = 0; + } + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOS_FLAG)){ + if( (RxMessage[4]&0x1) == 0x1) + pts.adslNearEndPerfStats_pt->adslneLOS = 1; + else + pts.adslNearEndPerfStats_pt->adslneLOS = 0; + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOF_FLAG)){ + if( (RxMessage[4]&0x2) == 0x2) + pts.adslNearEndPerfStats_pt->adslneLOF = 1; + else + pts.adslNearEndPerfStats_pt->adslneLOF = 0; + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LPR_FLAG)){ + if( (RxMessage[4]&0x4) == 0x4) + pts.adslNearEndPerfStats_pt->adslneLPR = 1; + else + pts.adslNearEndPerfStats_pt->adslneLPR = 0; + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_NCD_FLAG)){ + pts.adslNearEndPerfStats_pt->adslneNCD = (RxMessage[4]>>4)&0x3; + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LCD_FLAG)){ + pts.adslNearEndPerfStats_pt->adslneLCD = (RxMessage[4]>>6)&0x3; + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_CRC_FLAG)){ + if (chantype.interleave) + NEAREND_PERF_CRC_FLAG_LP0_MAKECMV; + else + NEAREND_PERF_CRC_FLAG_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 2 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneCRC = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneCRC = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_RSCORR_FLAG)){ + if (chantype.interleave) + NEAREND_PERF_RSCORR_FLAG_LP0_MAKECMV; + else + NEAREND_PERF_RSCORR_FLAG_LP1_MAKECMV; + + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 3 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneRSCorr = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneRSCorr = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_FECS_FLAG)){ + NEAREND_PERF_FECS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 6 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneFECS = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneFECS = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_ES_FLAG)){ + NEAREND_PERF_ES_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 7 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneES = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneES = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_SES_FLAG)){ + NEAREND_PERF_SES_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 8 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneSES = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneSES = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOSS_FLAG)){ + NEAREND_PERF_LOSS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 9 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneLOSS = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneLOSS = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_UAS_FLAG)){ + NEAREND_PERF_UAS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 10 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneUAS = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneUAS = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_HECERR_FLAG)){ + if (chantype.bearchannel0) + { + NEAREND_PERF_HECERR_FLAG_BC0_MAKECMV; + }else if (chantype.bearchannel1) + { + NEAREND_PERF_HECERR_FLAG_BC1_MAKECMV; + } + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 11 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneHECErrors = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneHECErrors = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + } + + copy_to_user((char *)lon, (char *)pts.adslNearEndPerfStats_pt, sizeof(adslNearEndPerfStats)); + kfree(pts.adslNearEndPerfStats_pt); + + up(&mei_sema); + break; + + case GET_ADSL_FAREND_STATS: + + if (showtime!=1) + return -ERESTARTSYS; + + if (adsl_mode>8 || adsl_mode_extend > 0) + { + do_gettimeofday(&time_now); + if( FarendData_acquire_time.tv_sec==0 || time_now.tv_sec - FarendData_acquire_time.tv_sec>=1) + { + hdlc_cmd[0]=0x105; + + if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],2)!= -EBUSY) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + hdlc_rx_len=0; + hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2); + if (hdlc_rx_len <=0) + { + return -ERESTARTSYS; + } + FarendStatsData.adslfeRSCorr = ((u32)le16_to_cpu(hdlc_rx_buffer[1]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[2]); + FarendStatsData.adslfeCRC = ((u32)le16_to_cpu(hdlc_rx_buffer[3]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[4]); + FarendStatsData.adslfeFECS = ((u32)le16_to_cpu(hdlc_rx_buffer[5]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[6]); + FarendStatsData.adslfeES = ((u32)le16_to_cpu(hdlc_rx_buffer[7]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[8]); + FarendStatsData.adslfeSES = ((u32)le16_to_cpu(hdlc_rx_buffer[9]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[10]); + FarendStatsData.adslfeLOSS = ((u32)le16_to_cpu(hdlc_rx_buffer[11]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[12]); + FarendStatsData.adslfeUAS = ((u32)le16_to_cpu(hdlc_rx_buffer[13]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[14]); + do_gettimeofday(&FarendData_acquire_time); + } + + } + } + + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + pts.adslFarEndPerfStats_pt = (adslFarEndPerfStats *)kmalloc(sizeof(adslFarEndPerfStats), GFP_KERNEL); + copy_from_user((char *)pts.adslFarEndPerfStats_pt, (char *)lon, sizeof(adslFarEndPerfStats)); + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOS_FLAG) || + IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOF_FLAG) || + IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LPR_FLAG) || + IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_NCD_FLAG) || + IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LCD_FLAG) ){ + FAREND_PERF_LOS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 1 Index 0"); +#endif + RxMessage[4] = 0; + } + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOS_FLAG)){ + if((RxMessage[4]&0x1) == 0x1) + pts.adslFarEndPerfStats_pt->adslfeLOS = 1; + else + pts.adslFarEndPerfStats_pt->adslfeLOS = 0; + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOF_FLAG)){ + if((RxMessage[4]&0x2) == 0x2) + pts.adslFarEndPerfStats_pt->adslfeLOF = 1; + else + pts.adslFarEndPerfStats_pt->adslfeLOF = 0; + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LPR_FLAG)){ + if((RxMessage[4]&0x4) == 0x4) + pts.adslFarEndPerfStats_pt->adslfeLPR = 1; + else + pts.adslFarEndPerfStats_pt->adslfeLPR = 0; + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_NCD_FLAG)){ + pts.adslFarEndPerfStats_pt->adslfeNCD = (RxMessage[4]>>4)&0x3; + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LCD_FLAG)){ + pts.adslFarEndPerfStats_pt->adslfeLCD = (RxMessage[4]>>6)&0x3; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_CRC_FLAG)){ + if (adsl_mode<=8 && adsl_mode_extend == 0) + { + if (chantype.interleave) + { + FAREND_PERF_CRC_FLAG_LP0_MAKECMV; + } + else + { + FAREND_PERF_CRC_FLAG_LP1_MAKECMV; + } + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 24 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeCRC = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeCRC = RxMessage[4]; + } + }else + { + pts.adslFarEndPerfStats_pt->adslfeCRC = FarendStatsData.adslfeCRC; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_RSCORR_FLAG)){ + if (adsl_mode<=8 && adsl_mode_extend == 0) + { + if (chantype.interleave) + FAREND_PERF_RSCORR_FLAG_LP0_MAKECMV; + else + FAREND_PERF_RSCORR_FLAG_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 28 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeRSCorr = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeRSCorr = RxMessage[4]; + + } + } + else + { + pts.adslFarEndPerfStats_pt->adslfeRSCorr = FarendStatsData.adslfeRSCorr; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_FECS_FLAG)){ + if (adsl_mode<=8 && adsl_mode_extend == 0) + { + FAREND_PERF_FECS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 32 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeFECS = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeFECS = RxMessage[4]; + } + }else { + pts.adslFarEndPerfStats_pt->adslfeFECS = FarendStatsData.adslfeFECS; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_ES_FLAG)){ + if (adsl_mode<=8 && adsl_mode_extend == 0) + { + FAREND_PERF_ES_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 33 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeES = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeES = RxMessage[4]; + } + }else + { + pts.adslFarEndPerfStats_pt->adslfeES = FarendStatsData.adslfeES; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_SES_FLAG)){ + if (adsl_mode<=8 && adsl_mode_extend == 0) + { + FAREND_PERF_SES_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 34 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeSES = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeSES = RxMessage[4]; + + } + }else + { + pts.adslFarEndPerfStats_pt->adslfeSES = FarendStatsData.adslfeSES; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOSS_FLAG)){ + if (adsl_mode<=8 && adsl_mode_extend == 0) + { + FAREND_PERF_LOSS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeLOSS = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeLOSS = RxMessage[4]; + + } + }else + { + pts.adslFarEndPerfStats_pt->adslfeLOSS = FarendStatsData.adslfeLOSS; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_UAS_FLAG)){ + if (adsl_mode<=8 && adsl_mode_extend == 0) + { + FAREND_PERF_UAS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 36 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeUAS = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeUAS = RxMessage[4]; + + } + }else + { + pts.adslFarEndPerfStats_pt->adslfeUAS = FarendStatsData.adslfeUAS; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_HECERR_FLAG)){ + if (chantype.bearchannel0) + { + FAREND_PERF_HECERR_FLAG_BC0_MAKECMV; + }else if (chantype.bearchannel1) + { + FAREND_PERF_HECERR_FLAG_BC1_MAKECMV; + } + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 37 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeHECErrors = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeHECErrors = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + } + + copy_to_user((char *)lon, (char *)pts.adslFarEndPerfStats_pt, sizeof(adslFarEndPerfStats)); + kfree(pts.adslFarEndPerfStats_pt); + + up(&mei_sema); + + break; +// 603221:tc.chen end + case GET_ADSL_LOOP_DIAGNOSTICS_MODE: + //lon = loop_diagnostics_mode; + copy_to_user((char *)lon, (char *)&loop_diagnostics_mode, sizeof(int)); + break; +//>> SHC + case IS_ADSL_LOOP_DIAGNOSTICS_MODE_COMPLETE: + copy_to_user((char *)lon, (char *)&loop_diagnostics_completed, sizeof(int)); + break; + +//<< end SHC + case LOOP_DIAGNOSTIC_MODE_COMPLETE: + loop_diagnostics_completed = 1; + // read adsl mode + makeCMV(H2D_CMV_READ, STAT, 1, 0, 1, data); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group STAT Address 1 Index 0"); +#endif + } + adsl_mode = RxMessage[4]; + + makeCMV(H2D_CMV_READ, STAT, 17, 0, 1, data); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group STAT Address 1 Index 0"); +#endif + } + adsl_mode_extend = RxMessage[4]; + wake_up_interruptible(&wait_queue_loop_diagnostic); + break; + case SET_ADSL_LOOP_DIAGNOSTICS_MODE: + if (lon != loop_diagnostics_mode) + { + loop_diagnostics_completed = 0; + loop_diagnostics_mode = lon; + + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_REBOOT, NULL); + + } + break; + case GET_ADSL_ATUR_SUBCARRIER_STATS: + if (loop_diagnostics_completed == 0) + { + interruptible_sleep_on_timeout(&wait_queue_loop_diagnostic,300*HZ); + if (loop_diagnostics_completed==0) + { + return -ERESTARTSYS; + } + } + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslATURSubcarrierInfo_pt = (adslATURSubcarrierInfo *)kmalloc(sizeof(adslATURSubcarrierInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslATURSubcarrierInfo_pt, (char *)lon, sizeof(adslATURSubcarrierInfo)); + + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_HLINSC)){ + FAREND_HLINSC_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + pts.adslATURSubcarrierInfo_pt->HLINSCds = 0; + } + else{ + pts.adslATURSubcarrierInfo_pt->HLINSCds = RxMessage[4]; + + } + } + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_HLINPS)){ + int index=0,size=12; + //printk("FAREND_HLINPS\n"); + for (index=0;index<1024;index+=size) + { + if (index+size>=1024) + size = 1024-index; + FAREND_HLINPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + } + else{ + memcpy(&pts.adslATURSubcarrierInfo_pt->HLINpsds[index],&RxMessage[4],size*2); +#if 0 + int msg_idx; + for(msg_idx=0;msg_idxflags)), FAREND_HLOGMT)){ + FAREND_HLOGMT_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + pts.adslATURSubcarrierInfo_pt->HLOGMTds = 0; + } + else{ + pts.adslATURSubcarrierInfo_pt->HLOGMTds = RxMessage[4]; + + } + } + + ///////////////////////////////////////////////////////////////////////// + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_HLOGPS)){ + //printk("FAREND_HLOGPS\n"); + int index=0,size=12; + for (index=0;index<256;index+=size) + { + if (index+size>=256) + size = 256-index; + + FAREND_HLOGPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + } + else{ + if (adsl_mode < 0x4000 && adsl_mode_extend==0)//adsl2 mode + { + memcpy(&pts.adslATURSubcarrierInfo_pt->HLOGpsds[index],&RxMessage[4],size*2); + }else + { + int msg_idx=0; + for (msg_idx=0;msg_idxHLOGpsds[(index+msg_idx)*2+1] = RxMessage[4+msg_idx]; + //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + } + } + } + } + if (adsl_mode >= 0x4000 || adsl_mode_extend >0)//adsl2+ mode + { + pts.adslATURSubcarrierInfo_pt->HLOGpsds[0] = pts.adslATURSubcarrierInfo_pt->HLOGpsds[1]; + for (index=1;index<256;index++) + { + pts.adslATURSubcarrierInfo_pt->HLOGpsds[index*2] = (pts.adslATURSubcarrierInfo_pt->HLOGpsds[(index)*2-1] + pts.adslATURSubcarrierInfo_pt->HLOGpsds[(index)*2+1] +1) >>1; + } + } + } + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_QLNMT)){ + FAREND_QLNMT_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + pts.adslATURSubcarrierInfo_pt->QLNMTds = 0; + } + else{ + pts.adslATURSubcarrierInfo_pt->QLNMTds = RxMessage[4]; + } + } + + ///////////////////////////////////////////////////////////////////////// + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_QLNPS)){ + int index=0,size=12; + //printk("FAREND_QLNPS\n"); + for (index=0;index<128;index+=size) + { + if (index+size>=128) + size = 128-index; + FAREND_QLNPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + } + else{ + int msg_idx=0; + for (msg_idx=0;msg_idxQLNpsds[index],&RxMessage[4],size*2); + if (adsl_mode < 0x4000 && adsl_mode_extend==0)//adsl2 mode + { + pts.adslATURSubcarrierInfo_pt->QLNpsds[(index+msg_idx)*2] = (u16)(RxMessage[4+msg_idx]&0xFF); + pts.adslATURSubcarrierInfo_pt->QLNpsds[(index+msg_idx)*2+1] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF); + }else + { + pts.adslATURSubcarrierInfo_pt->QLNpsds[(index+msg_idx)*4+1] = (u16)(RxMessage[4+msg_idx]&0xFF); + pts.adslATURSubcarrierInfo_pt->QLNpsds[(index+msg_idx)*4+3] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF); + //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + } + } + + + } + } + if (adsl_mode >= 0x4000 || adsl_mode_extend >0)//adsl2+ mode + { + pts.adslATURSubcarrierInfo_pt->QLNpsds[0] = pts.adslATURSubcarrierInfo_pt->QLNpsds[1]; + for (index=1;index<256;index++) + { + pts.adslATURSubcarrierInfo_pt->QLNpsds[index*2] = (pts.adslATURSubcarrierInfo_pt->QLNpsds[(index)*2-1] + pts.adslATURSubcarrierInfo_pt->QLNpsds[(index)*2+1]) >>1; + } + } + } + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_SNRMT)){ + FAREND_SNRMT_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + pts.adslATURSubcarrierInfo_pt->SNRMTds = 0; + } + else{ + pts.adslATURSubcarrierInfo_pt->SNRMTds = RxMessage[4]; + } + } + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_SNRPS)){ + int index=0,size=12; + //printk("FAREND_SNRPS\n"); + for (index=0;index<512;index+=size) + { + if (index+size>=512) + size = 512-index; + FAREND_SNRPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + } + else{ + //memcpy(&pts.adslATURSubcarrierInfo_pt->SNRpsds[index],&RxMessage[4],size*2); + int msg_idx=0; + for (msg_idx=0;msg_idxSNRpsds[index+msg_idx] = (u16)(RxMessage[4+msg_idx]&0xFF); + //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + } + + } + } + } + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_BITPS)){ + int index=0,size=12; + //printk("FAREND_BITPS\n"); + for (index=0;index<256;index+=size) + { + if (index+size>=256) + size = 256-index; + FAREND_BITPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + } + else{ + int msg_idx=0; + for (msg_idx=0;msg_idxBITpsds[(index+msg_idx)*2] = (u16)(RxMessage[4+msg_idx]&0xFF); + pts.adslATURSubcarrierInfo_pt->BITpsds[(index+msg_idx)*2+1] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF); + //printk("index:%d ,cmv_result: %04X, %d\n",index+msg_idx,RxMessage[4+msg_idx],RxMessage[4+msg_idx]); + + } + + } + } + } + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_GAINPS)){ + int index=0,size=12; + //printk("FAREND_GAINPS\n"); + for (index=0;index<512;index+=size) + { + FAREND_GAINPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + } + else{ + /* + int msg_idx=0; + for (msg_idx=0;msg_idxGAINpsds[(index+msg_idx)*2] = RxMessage[4+msg_idx]&0xFF; + pts.adslATURSubcarrierInfo_pt->GAINpsds[(index+msg_idx)*2+1] = (RxMessage[4+msg_idx]>>8)&0xFF; + + } + */ + memcpy(&pts.adslATURSubcarrierInfo_pt->GAINpsds[index],&RxMessage[4],size*2); +#if 0 + int msg_idx=0; + for (msg_idx=0;msg_idxflags)), NEAREND_HLINSC)){ + NEAREND_HLINSC_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 71 Index 2"); +#endif + pts.adslATUCSubcarrierInfo_pt->HLINSCus = 0; + } + else{ + pts.adslATUCSubcarrierInfo_pt->HLINSCus = RxMessage[4]; + + } + } + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_HLINPS)){ + int index=0,size=12; + //printk("NEAREND_HLINPS\n"); + for (index=0;index<128;index+=size) + { + if (index+size>=128) + size = 128-index; + NEAREND_HLINPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 73 Index 0"); +#endif + } + else{ + memcpy(&pts.adslATUCSubcarrierInfo_pt->HLINpsus[index],&RxMessage[4],size*2); +#if 0 + int msg_idx; + for (msg_idx=0;msg_idxflags)), NEAREND_HLOGMT)){ + NEAREND_HLOGMT_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 80 Index 0"); +#endif + pts.adslATUCSubcarrierInfo_pt->HLOGMTus = 0; + } + else{ + pts.adslATUCSubcarrierInfo_pt->HLOGMTus = RxMessage[4]; + + } + } + + ///////////////////////////////////////////////////////////////////////// + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_HLOGPS)){ + int index=0,size=12; + //printk("NEAREND_HLOGPS\n"); + for (index=0;index<64;index+=size) + { + if (index+size>=64) + size = 64-index; + NEAREND_HLOGPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 75 Index 0"); +#endif + } + else{ +#if 0 + if (adsl_mode <0x4000)//adsl /adsl2 mode + { +#endif + memcpy(&pts.adslATUCSubcarrierInfo_pt->HLOGpsus[index],&RxMessage[4],size*2); +#if 0 + }else + { + int msg_idx=0; + for (msg_idx=0;msg_idxHLOGpsus[(index+msg_idx)*2+1] = RxMessage[4+msg_idx]; + pts.adslATUCSubcarrierInfo_pt->HLOGpsus[(index+msg_idx)] = RxMessage[4+msg_idx]; + } + } +#endif + } + } +#if 0 + if (adsl_mode >= 0x4000)//adsl2 mode + { + pts.adslATUCSubcarrierInfo_pt->HLOGpsus[0] = pts.adslATUCSubcarrierInfo_pt->HLOGpsus[1]; + for (index=1;index<64;index++) + { + pts.adslATUCSubcarrierInfo_pt->HLOGpsus[index*2] = (pts.adslATUCSubcarrierInfo_pt->HLOGpsus[(index)*2-1] + pts.adslATUCSubcarrierInfo_pt->HLOGpsus[(index)*2+1]) >>1; + } + } +#endif + } + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_QLNMT)){ + NEAREND_QLNMT_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 80 Index 1"); +#endif + pts.adslATUCSubcarrierInfo_pt->QLNMTus = 0; + } + else{ + pts.adslATUCSubcarrierInfo_pt->QLNMTus = RxMessage[4]; + } + } + + ///////////////////////////////////////////////////////////////////////// + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_QLNPS)){ + int index=0,size=12; + //printk("NEAREND_QLNPS\n"); + for (index=0;index<32;index+=size) + { + if (index+size>=32) + size = 32-index; + NEAREND_QLNPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 77 Index 0"); +#endif + } + else{ + int msg_idx=0; + for (msg_idx=0;msg_idxQLNpsds[index],&RxMessage[4],size*2); + if (adsl_mode == 0x200 || adsl_mode == 0x800 || adsl_mode ==0x2000 || adsl_mode ==0x4000 || (adsl_mode == 0 && (adsl_mode_extend == 0x4 || adsl_mode_extend == 0x2))//ADSL 2 Annex B(0x200)/J(0x800)/M(0x2000) //ADSL 2+ B,J,M + if (adsl_mode < 0x4000 && adsl_mode_extend==0)//adsl2 mode + { + pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index+msg_idx)*4+1] = (u16)(RxMessage[4+msg_idx]&0xFF); + pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index+msg_idx)*4+3] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF); + }else +#endif + { + pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index+msg_idx)*2] = (u16)(RxMessage[4+msg_idx]&0xFF); + pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index+msg_idx)*2+1] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF); + //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + } + } + + + } + } +#if 0 + //if (adsl_mode <0x4000)//Annex I/J/L/M + if (adsl_mode == 0x200 || adsl_mode == 0x800 || adsl_mode ==0x2000 || adsl_mode ==0x4000 || (adsl_mode == 0 && (adsl_mode_extend == 0x4 || adsl_mode_extend == 0x2))//ADSL 2 Annex B(0x200)/J(0x800)/M(0x2000) //ADSL 2+ B,J,M + { + pts.adslATUCSubcarrierInfo_pt->QLNpsus[0] = pts.adslATUCSubcarrierInfo_pt->QLNpsus[1]; + for (index=1;index<64;index++) + { + pts.adslATUCSubcarrierInfo_pt->QLNpsus[index*2] = (pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index)*2-1] + pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index)*2+1]) >>1; + } + } +#endif + } + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_SNRMT)){ + NEAREND_SNRMT_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 80 Index 2"); +#endif + pts.adslATUCSubcarrierInfo_pt->SNRMTus = 0; + } + else{ + pts.adslATUCSubcarrierInfo_pt->SNRMTus = RxMessage[4]; + } + } + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_SNRPS)){ + int index=0,size=12; + //printk("NEAREND_SNRPS\n"); + for (index=0;index<64;index+=size) + { + if (index+size>=64) + size = 64-index; + NEAREND_SNRPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 78 Index 0"); +#endif + } + else{ + //memcpy(&pts.adslATUCSubcarrierInfo_pt->SNRpsus[index],&RxMessage[4],size*2); + int msg_idx=0; + for (msg_idx=0;msg_idxSNRpsus[index+msg_idx] = (u16)(RxMessage[4+msg_idx]&0xFF); + //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + } + + } + } + } + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_BITPS)){ + int index=0,size=12; + //printk("NEAREND_BITPS\n"); + for (index=0;index<32;index+=size) + { + if (index+size>=32) + size = 32-index; + NEAREND_BITPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 22 Index 0"); +#endif + } + else{ + int msg_idx=0; + for (msg_idx=0;msg_idxBITpsus[(index+msg_idx)*2] = (u16)(RxMessage[4+msg_idx]&0xFF); + pts.adslATUCSubcarrierInfo_pt->BITpsus[(index+msg_idx)*2+1] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF); + //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + } + + } + } + } + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_GAINPS)){ + int index=0,size=12; + //printk("NEAREND_GAINPS\n"); + for (index=0;index<64;index+=size) + { + if (index+size>=64) + size = 64-index; + NEAREND_GAINPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 24 Index 0"); +#endif + } + else{ + /* + int msg_idx=0; + for (msg_idx=0;msg_idxGAINpsds[(index+msg_idx)*2] = RxMessage[4+msg_idx]&0xFF; + pts.adslATUCSubcarrierInfo_pt->GAINpsds[(index+msg_idx)*2+1] = (RxMessage[4+msg_idx]>>8)&0xFF; + + } + */ + memcpy(&pts.adslATUCSubcarrierInfo_pt->GAINpsus[index],&RxMessage[4],size*2); +#if 0 + int msg_idx; + for (msg_idx=0;msg_idxACTPSDus = ((int )(j*256 - temp*10*256 + k*10)) /256; + } + // DS + i=0; + j=temp=temp2=0; + NOMPSD_DS_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + i=-1; + } + else{ + j=RxMessage[4]; + } + PCB_DS_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + i=-1; + } + else{ + temp=RxMessage[4]; + } + RMSGI_DS_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + i=-1; + } + else{ + //temp2=RxMessage[4]; + k=(int16_t)RxMessage[4]; + } + if (i==0) + { + pts.adslPowerSpectralDensity_pt->ACTPSDds = ((int )(j*256 - temp*10*256 + k*10)) /256; + } + copy_to_user((char *)lon, (char *)pts.adslPowerSpectralDensity_pt, sizeof(adslPowerSpectralDensity)); + kfree(pts.adslPowerSpectralDensity_pt); + up(&mei_sema); + break; + case AMAZON_MEI_START: + showtime=0; + loop_diagnostics_completed = 0; +#ifdef ARC_READY_ACK +#ifdef LOCK_RETRY + i=0; +lock_retry: + if(down_trylock(&mei_sema)!=0) + { + reboot_lock = 1; + printk("lock fail\n"); + i++; + if (i <=5) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(10); + goto lock_retry; + }else + { + printk("Force to Reboot ADSL!\n"); + up(&mei_sema); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1000); + sema_init(&mei_sema, 1); // semaphore initialization, mutex + } + }else + { + reboot_lock = 1; + } +#else + if(down_interruptible(&mei_sema)) //disable CMV access until ARC ready + { + return -ERESTARTSYS; + } +#endif +#endif + //CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //Warning LED GPIO ON + if(chantype.interleave==1){ + kfree(interleave_mei_net.priv); + unregister_netdev(&interleave_mei_net); + } + else if(chantype.fast==1){ + kfree(fast_mei_net.priv); + unregister_netdev(&fast_mei_net); + } + chantype.interleave=0; + chantype.fast=0; + meiMailboxInterruptsDisable(); //disable all MEI interrupts + if(mei_arc_swap_buff == NULL){ + mei_arc_swap_buff = (u32 *)kmalloc(MAXSWAPSIZE*4, GFP_KERNEL); + if(mei_arc_swap_buff==NULL){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n malloc fail for codeswap buff"); +#endif + meierr=MEI_FAILURE; + } + } + if(meiForceRebootAdslModem() != MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n meiForceRebootAdslModem() error..."); +#endif + meierr=MEI_FAILURE; + } + interruptible_sleep_on(&wait_queue_codeswap); + // reset is called + break; + case AMAZON_MEI_MIB_DAEMON: +#ifdef IFX_SMALL_FOOTPRINT /* [ */ + return -1; +#else /* ][ !IFX_SMALL_FOOTPRINT */ + i=0; + while(1){ + if(istart_time.tv_sec>=900){ + if(current_intvl->list.next!=&interval_list){ + current_intvl = list_entry(current_intvl->list.next, amazon_mei_mib, list); + do_gettimeofday(&(current_intvl->start_time)); + } + else{ + mib_ptr = list_entry(interval_list.next, amazon_mei_mib, list); + list_del(interval_list.next); + memset(mib_ptr, 0, sizeof(amazon_mei_mib)); + list_add_tail(&(mib_ptr->list), &interval_list); + if(current_intvl->list.next==&interval_list) +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nlink list error"); +#endif + current_intvl = list_entry(current_intvl->list.next, amazon_mei_mib, list); + do_gettimeofday(&(current_intvl->start_time)); + } + } + + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; +/* + ATUC_PERF_LO_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 0 Index 0"); +#endif + } + else{ + if(RxMessage[4]&PLAM_LOS_FailureBit){ + current_intvl->AtucPerfLos++; + ATUC_PERF_LOSS++; + CurrStatus.adslAtucCurrStatus = 2; + } + if(RxMessage[4]&PLAM_LOF_FailureBit){ + current_intvl->AtucPerfLof++; + ATUC_PERF_LOFS++; + CurrStatus.adslAtucCurrStatus = 1; + } + if(!(RxMessage[4]&(PLAM_LOS_FailureBit|PLAM_LOF_FailureBit))) + CurrStatus.adslAtucCurrStatus = 0; + } +*/ + ATUC_PERF_ESS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 7 Index 0"); +#endif + } + else{ + temp = RxMessage[4]-mib_pread.ATUC_PERF_ESS; + if(temp>=0){ + current_intvl->AtucPerfEs+=temp; + ATUC_PERF_ESS+=temp; + mib_pread.ATUC_PERF_ESS = RxMessage[4]; + } + else{ + current_intvl->AtucPerfEs+=0xffff-mib_pread.ATUC_PERF_ESS+RxMessage[4]; + ATUC_PERF_ESS+=0xffff-mib_pread.ATUC_PERF_ESS+RxMessage[4]; + mib_pread.ATUC_PERF_ESS = RxMessage[4]; + } + } +/* + ATUR_PERF_LO_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 1 Index 0"); +#endif + } + else{ + if(RxMessage[4]&PLAM_LOS_FailureBit){ + current_intvl->AturPerfLos++; + ATUR_PERF_LOSS++; + CurrStatus.adslAturCurrStatus = 2; + } + if(RxMessage[4]&PLAM_LOF_FailureBit){ + current_intvl->AturPerfLof++; + ATUR_PERF_LOFS++; + CurrStatus.adslAturCurrStatus = 1; + } + if(RxMessage[4]&PLAM_LPR_FailureBit){ + current_intvl->AturPerfLpr++; + ATUR_PERF_LPR++; + CurrStatus.adslAturCurrStatus = 3; + } + if(!(RxMessage[4]&(PLAM_LOS_FailureBit|PLAM_LOF_FailureBit|PLAM_LPR_FailureBit))) + CurrStatus.adslAturCurrStatus = 0; + } +*/ + ATUR_PERF_ESS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 33 Index 0"); +#endif + } + else{ + temp = RxMessage[4]-mib_pread.ATUR_PERF_ESS; + if(temp>=0){ + current_intvl->AturPerfEs+=temp; + ATUR_PERF_ESS+=temp; + mib_pread.ATUR_PERF_ESS = RxMessage[4]; + } + else{ + current_intvl->AturPerfEs+=0xffff-mib_pread.ATUR_PERF_ESS+RxMessage[4]; + ATUR_PERF_ESS+= 0xffff-mib_pread.ATUR_PERF_ESS+RxMessage[4]; + mib_pread.ATUR_PERF_ESS=RxMessage[4]; + } + } + // to update rx/tx blocks + ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_LSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 20 Index 0"); +#endif + } + else{ + temp = RxMessage[4]; + } + ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_MSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 21 Index 0"); +#endif + } + else{ + temp2 = RxMessage[4]; + } + if((temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK)>=0){ + current_intvl->AturChanPerfRxBlk+=temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK; + ATUR_CHAN_RECV_BLK+=temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK; + mib_pread.ATUR_CHAN_RECV_BLK = temp + (temp2<<16); + } + else{ + current_intvl->AturChanPerfRxBlk+=0xffffffff - mib_pread.ATUR_CHAN_RECV_BLK +(temp + (temp2<<16)); + ATUR_CHAN_RECV_BLK+=0xffffffff - mib_pread.ATUR_CHAN_RECV_BLK +(temp + (temp2<<16)); + mib_pread.ATUR_CHAN_RECV_BLK = temp + (temp2<<16); + } + current_intvl->AturChanPerfTxBlk = current_intvl->AturChanPerfRxBlk; + ATUR_CHAN_TX_BLK = ATUR_CHAN_RECV_BLK; +/* + ATUR_CHAN_TX_BLK_FLAG_MAKECMV_LSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS) + printk("\n\nCMV fail, Group 7 Address 20 Index 0"); + else{ + if(RxMessage[4]){ + current_intvl->AturChanPerfTxBlk+=RxMessage[4]; + ATUR_CHAN_TX_BLK+=RxMessage[4]; + } + } + ATUR_CHAN_TX_BLK_FLAG_MAKECMV_MSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS) + printk("\n\nCMV fail, Group 7 Address 21 Index 0"); + else{ + if(RxMessage[4]){ + current_intvl->AturChanPerfTxBlk+=(int)((RxMessage[4])<<16); + ATUR_CHAN_TX_BLK+=(int)((RxMessage[4])<<16); + } + } +*/ + if(chantype.interleave == 1){ + ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_INTL; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 3 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_CORR_BLK_INTL; + if(temp>=0){ + current_intvl->AturChanPerfCorrBlk+=temp; + ATUR_CHAN_CORR_BLK+=temp; + mib_pread.ATUR_CHAN_CORR_BLK_INTL = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfCorrBlk+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_INTL +RxMessage[4]; + ATUR_CHAN_CORR_BLK+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_INTL +RxMessage[4]; + mib_pread.ATUR_CHAN_CORR_BLK_INTL = RxMessage[4]; + } + } + } + else if(chantype.fast == 1){ + ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_FAST; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 3 Index 1"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_CORR_BLK_FAST; + if(temp>=0){ + current_intvl->AturChanPerfCorrBlk+=temp; + ATUR_CHAN_CORR_BLK+=temp; + mib_pread.ATUR_CHAN_CORR_BLK_FAST = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfCorrBlk+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_FAST + RxMessage[4]; + ATUR_CHAN_CORR_BLK+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_FAST + RxMessage[4]; + mib_pread.ATUR_CHAN_CORR_BLK_FAST = RxMessage[4]; + } + } + } + + if(chantype.interleave == 1){ + ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_INTL; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 2 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL; + if(temp>=0){ + current_intvl->AturChanPerfUncorrBlk+=temp; + ATUR_CHAN_UNCORR_BLK+=temp; + mib_pread.ATUR_CHAN_UNCORR_BLK_INTL = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfUncorrBlk+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL + RxMessage[4]; + ATUR_CHAN_UNCORR_BLK+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL + RxMessage[4]; + mib_pread.ATUR_CHAN_UNCORR_BLK_INTL = RxMessage[4]; + } + } + } + else if(chantype.fast == 1){ + ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_FAST; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 2 Index 1"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST; + if(temp>=0){ + current_intvl->AturChanPerfUncorrBlk+=temp; + ATUR_CHAN_UNCORR_BLK+=temp; + mib_pread.ATUR_CHAN_UNCORR_BLK_FAST = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfUncorrBlk+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST + RxMessage[4]; + ATUR_CHAN_UNCORR_BLK+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST + RxMessage[4]; + mib_pread.ATUR_CHAN_UNCORR_BLK_FAST = RxMessage[4]; + } + } + } + + //RFC-3440 + +#ifdef AMAZON_MEI_MIB_RFC3440 + ATUC_PERF_STAT_FASTR_FLAG_MAKECMV; //??? + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 0 Address 0 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_FASTR; + if(temp>=0){ + current_intvl->AtucPerfStatFastR+=temp; + ATUC_PERF_STAT_FASTR+=temp; + mib_pread.ATUC_PERF_STAT_FASTR = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatFastR+=0xffff - mib_pread.ATUC_PERF_STAT_FASTR + RxMessage[4]; + ATUC_PERF_STAT_FASTR+=0xffff - mib_pread.ATUC_PERF_STAT_FASTR + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_FASTR = RxMessage[4]; + } + } + ATUC_PERF_STAT_FAILED_FASTR_FLAG_MAKECMV; //??? + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 0 Address 0 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_FAILED_FASTR; + if(temp>=0){ + current_intvl->AtucPerfStatFailedFastR+=temp; + ATUC_PERF_STAT_FAILED_FASTR+=temp; + mib_pread.ATUC_PERF_STAT_FAILED_FASTR = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatFailedFastR+=0xffff - mib_pread.ATUC_PERF_STAT_FAILED_FASTR + RxMessage[4]; + ATUC_PERF_STAT_FAILED_FASTR+=0xffff - mib_pread.ATUC_PERF_STAT_FAILED_FASTR + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_FAILED_FASTR = RxMessage[4]; + } + } + ATUC_PERF_STAT_SESL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 8 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_SESL; + if(temp>=0){ + current_intvl->AtucPerfStatSesL+=temp; + ATUC_PERF_STAT_SESL+=temp; + mib_pread.ATUC_PERF_STAT_SESL = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatSesL+=0xffff - mib_pread.ATUC_PERF_STAT_SESL + RxMessage[4]; + ATUC_PERF_STAT_SESL+=0xffff - mib_pread.ATUC_PERF_STAT_SESL + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_SESL = RxMessage[4]; + } + } + ATUC_PERF_STAT_UASL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 10 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_UASL; + if(temp>=0){ + current_intvl->AtucPerfStatUasL+=temp; + ATUC_PERF_STAT_UASL+=temp; + mib_pread.ATUC_PERF_STAT_UASL = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatUasL+=0xffff - mib_pread.ATUC_PERF_STAT_UASL + RxMessage[4]; + ATUC_PERF_STAT_UASL+=0xffff - mib_pread.ATUC_PERF_STAT_UASL + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_UASL = RxMessage[4]; + } + } + ATUR_PERF_STAT_SESL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 34 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_PERF_STAT_SESL; + if(temp>=0){ + current_intvl->AtucPerfStatUasL+=temp; + ATUC_PERF_STAT_UASL+=temp; + mib_pread.ATUR_PERF_STAT_SESL = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatUasL+=0xffff - mib_pread.ATUR_PERF_STAT_SESL + RxMessage[4]; + ATUC_PERF_STAT_UASL+=0xffff - mib_pread.ATUR_PERF_STAT_SESL + RxMessage[4]; + mib_pread.ATUR_PERF_STAT_SESL = RxMessage[4]; + } + } + +#endif + up(&mei_sema); + + do_gettimeofday(&time_fini); + i = ((int)((time_fini.tv_sec-time_now.tv_sec)*1000)) + ((int)((time_fini.tv_usec-time_now.tv_usec)/1000)) ; //msec + }//showtime==1 + } + break; +#endif /* ] !IFX_SMALL_FOOTPRINT */ + case AMAZON_MEI_RESET: + case AMAZON_MEI_REBOOT: + case AMAZON_MEI_SHOWTIME: +/* if(mei_arc_swap_buff !=NULL){ + kfree(mei_arc_swap_buff); + mei_arc_swap_buff=NULL; + } + if(image_buffer !=NULL){ +// kfree(image_buffer); + vfree(image_buffer); + image_buffer =NULL; + } +*/ + if(clreoc_command_pkt !=NULL){ + kfree(clreoc_command_pkt); + clreoc_command_pkt =NULL; + } + for(i=0;istart_time)); + ATUC_PERF_LOFS=0; + ATUC_PERF_LOSS=0; + ATUC_PERF_ESS=0; + ATUC_PERF_INITS=0; + ATUR_PERF_LOFS=0; + ATUR_PERF_LOSS=0; + ATUR_PERF_LPR=0; + ATUR_PERF_ESS=0; + ATUR_CHAN_RECV_BLK=0; + ATUR_CHAN_TX_BLK=0; + ATUR_CHAN_CORR_BLK=0; + ATUR_CHAN_UNCORR_BLK=0; + memset((((u8 *)&AlarmConfProfile)+32), 0, 16*4); + AlarmConfProfile.adslLineAlarmConfProfileRowStatus=1; +*/ + PrevTxRate.adslAtucChanPrevTxRate=0; + PrevTxRate.adslAturChanPrevTxRate=0; + CurrStatus.adslAtucCurrStatus=0; + CurrStatus.adslAturCurrStatus=0; + + if((command==AMAZON_MEI_RESET) || (command==AMAZON_MEI_REBOOT)){ +#ifdef AMAZON_CHECK_LINK + if (adsl_link_notify){ + (*adsl_link_notify)(0); + } +#endif + showtime=0; + //CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //Warning LED GPIO ON + // disconnect net_dev + if(chantype.interleave==1){ + kfree(interleave_mei_net.priv); + unregister_netdev(&interleave_mei_net); +// if(unregister_netdev(&interleave_mei_net)!=0) +// printk("\n unregister interleave fail"); + } + else if(chantype.fast==1){ + kfree(fast_mei_net.priv); + unregister_netdev(&fast_mei_net); +// if(unregister_netdev(&fast_mei_net)!=0) +// printk("\n unregister fast fail"); + } + chantype.interleave=0; + chantype.fast=0; +// 603221:tc.chen start + chantype.bearchannel0 = 0; + chantype.bearchannel1 = 0; + adsl_mode = 0; +// 603221:tc.chen end + + while(1){ + + makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, NULL); //maximum allowed tx message length, in bytes + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ + //printk("AdslInitStatsData.FullInitializationCount++\n"); + AdslInitStatsData.FullInitializationCount++; + //printk("AdslInitStatsData.FailedFullInitializationCount++\n"); + AdslInitStatsData.FailedFullInitializationCount++; + //printk("AdslInitStatsData.LINIT_Errors++\n"); + AdslInitStatsData.LINIT_Errors++; + }else + { + //printk("RxMessage=%X\n",RxMessage[4]); + if ( RxMessage[4]!=0x1) + { + //printk("AdslInitStatsData.FullInitializationCount++\n"); + AdslInitStatsData.FullInitializationCount++; + if ( RxMessage[4] != 0x7) + { + //printk("AdslInitStatsData.LINIT_Errors++\n"); + AdslInitStatsData.LINIT_Errors++; + //printk("AdslInitStatsData.FailedFullInitializationCount++\n"); + AdslInitStatsData.FailedFullInitializationCount++; + + } + } + } + + reboot_flag=0; + wake_up_interruptible(&wait_queue_codeswap); //wake up codeswap daemon + + interruptible_sleep_on_timeout(&wait_queue_reboot, 1*HZ); // sleep until arc ready +#ifdef ARC_READY_ACK + if(reboot_flag!=0) + break; + else + { + up(&mei_sema); + printk("\n reboot retry"); + } +#else + break; +#endif + } + } + else{ //AMAZON_MEI_SHOWTIME + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + // clreoc stuff + makeCMV(H2D_CMV_READ, INFO, 83, 0, 1, data); //maximum allowed tx message length, in bytes + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 83 Index 0"); +#endif + } + else{ + clreoc_max_tx_len = (int)RxMessage[4]; + clreoc_command_pkt = kmalloc((clreoc_max_tx_len*CLREOC_BUFF_SIZE), GFP_KERNEL); + if(clreoc_command_pkt == NULL){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("kmalloc error for clreoc_command_pkt\n\n"); +#endif + up(&mei_sema); + return -1; + } + for(i=0;ilen)>0){ + copy_to_user((char *)lon, (char*)(&(current_clreoc->len)), 4); + break; + } + else//wait for eoc data from higher layer + interruptible_sleep_on(&wait_queue_clreoc); + } + break; + case AMAZON_MEI_GET_EOC_DATA: + current_clreoc = list_entry(clreoc_list.next, amazon_clreoc_pkt, list); + if((current_clreoc->len)>0){ + copy_to_user((char*)lon, (char*)(current_clreoc->command), current_clreoc->len); + meierr=1; + list_del(clreoc_list.next); //remove and add to end of list + current_clreoc->len = 0; + list_add_tail(&(current_clreoc->list), &clreoc_list); + } + else + meierr=-1; + break; + case AMAZON_MEI_EOC_SEND: + copy_from_user((char *)(&debugrdwr), (char *)lon, sizeof(debugrdwr)); + eoc_skb = dev_alloc_skb(debugrdwr.iCount*4); + if(eoc_skb==NULL){ + printk("\n\nskb alloc fail"); + break; + } + + eoc_skb->len=debugrdwr.iCount*4; + memcpy(skb_put(eoc_skb, debugrdwr.iCount*4), (char *)debugrdwr.buffer, debugrdwr.iCount*4); + + ifx_push_eoc(eoc_skb); //pass data to higher layer + break; +#endif //#ifdef AMAZON_CLEAR_EOC + case AMAZON_MIB_LO_ATUC: + do_gettimeofday(&time_now); + if(lon&0x1){ + if((time_now.tv_sec-(mib_pflagtime.ATUC_PERF_LOSS_PTIME).tv_sec)>2){ + current_intvl->AtucPerfLos++; + ATUC_PERF_LOSS++; + CurrStatus.adslAtucCurrStatus = 2; + } + (mib_pflagtime.ATUC_PERF_LOSS_PTIME).tv_sec = time_now.tv_sec; + } + if(lon&0x2){ + if((time_now.tv_sec-(mib_pflagtime.ATUC_PERF_LOFS_PTIME).tv_sec)>2){ + current_intvl->AtucPerfLof++; + ATUC_PERF_LOFS++; + CurrStatus.adslAtucCurrStatus = 1; + } + (mib_pflagtime.ATUC_PERF_LOFS_PTIME).tv_sec = time_now.tv_sec; + } + if(!(lon&0x3)) + CurrStatus.adslAtucCurrStatus = 0; + break; + case AMAZON_MIB_LO_ATUR: + do_gettimeofday(&time_now); + if(lon&0x1){ + if((time_now.tv_sec-(mib_pflagtime.ATUR_PERF_LOSS_PTIME).tv_sec)>2){ + current_intvl->AturPerfLos++; + ATUR_PERF_LOSS++; + CurrStatus.adslAturCurrStatus = 2; + } + (mib_pflagtime.ATUR_PERF_LOSS_PTIME).tv_sec = time_now.tv_sec; + } + if(lon&0x2){ + if((time_now.tv_sec-(mib_pflagtime.ATUR_PERF_LOFS_PTIME).tv_sec)>2){ + current_intvl->AturPerfLof++; + ATUR_PERF_LOFS++; + CurrStatus.adslAturCurrStatus = 1; + } + (mib_pflagtime.ATUR_PERF_LOFS_PTIME).tv_sec = time_now.tv_sec; + } + if(lon&0x4){ + if((time_now.tv_sec-(mib_pflagtime.ATUR_PERF_LPR_PTIME).tv_sec)>2){ + current_intvl->AturPerfLpr++; + ATUR_PERF_LPR++; + CurrStatus.adslAturCurrStatus = 3; + } + (mib_pflagtime.ATUR_PERF_LPR_PTIME).tv_sec = time_now.tv_sec; + } + if(!(lon&0x7)) + CurrStatus.adslAturCurrStatus = 0; + break; + case AMAZON_MEI_DOWNLOAD: + // DMA the boot code page(s) +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n start download pages"); +#endif + for( boot_loop = 0; boot_loop < img_hdr->count; boot_loop++){ + if( img_hdr->page[boot_loop].p_size & BOOT_FLAG){ + page_size = meiGetPage( boot_loop, GET_PROG, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr); + if( page_size > 0){ + meiDMAWrite(dest_addr, mei_arc_swap_buff, page_size); + } + } + if( img_hdr->page[boot_loop].d_size & BOOT_FLAG){ + page_size = meiGetPage( boot_loop, GET_DATA, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr); + if( page_size > 0){ + meiDMAWrite( dest_addr, mei_arc_swap_buff, page_size); + } + } + } +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n pages downloaded"); +#endif + break; + //509221:tc.chen start + case AMAZON_MEI_DEBUG_MODE: + mei_debug_mode = lon; + break; + //509221:tc.chen end + } + return meierr; +} + + +////////////////////// Interrupt handler ///////////////////////////////////////////////////// +static void mei_interrupt_arcmsgav(int,void *,struct pt_regs *); +static void mei_interrupt_arcmsgav(int int1, void * void0, struct pt_regs * regs) +{ + u32 scratch; + u32 fetchpage; + u32 size; + u32 dest_addr; + u32 temp; + int i; + + meiDebugRead(ARC_MEI_MAILBOXR, &scratch, 1); + if(scratch & OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK) + { + if(showtime==1){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n Code Swap Request After ShowTime !!!"); +#endif + } + else{ +#ifdef AMAZON_MEI_DEBUG_ON +// printk("\n\n Code Swap Request"); +#endif + fetchpage = scratch & ~OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK; + size = meiGetPage( fetchpage, GET_PROG, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr); + if( size > 0) + { +#ifdef AMAZON_MEI_DEBUG_ON +// printk(" : prom page num %d",fetchpage); +#endif + meiDMAWrite( dest_addr, mei_arc_swap_buff, size); + } + + size = meiGetPage( fetchpage, GET_DATA, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr); + if( size > 0) + { +#ifdef AMAZON_MEI_DEBUG_ON +// printk(" : data page num %d",fetchpage); +#endif + meiDMAWrite( dest_addr, mei_arc_swap_buff, size); + } + } + // Notify arc that mailbox read complete + meiLongwordWrite(ARC_TO_MEI_INT, ARC_TO_MEI_MSGAV); + + // Tell ARC Codeswap is done + meiLongwordWrite(MEI_TO_ARC_INT, MEI_TO_ARC_CS_DONE); + asm("SYNC"); + i=0; + while(i>4)==D2H_AUTONOMOUS_MODEM_READY_MSG){ //check ARC ready message + +#ifdef LOCK_RETRY + if (reboot_lock) + { + reboot_lock = 0; + up(&mei_sema); // allow cmv access + } +#else + up(&mei_sema); // allow cmv access +#endif + reboot_flag=1; +//#ifdef ADSL_LED_SUPPORT +#if 0 + led_support_check=1;//adsl led for 1.1.2.7.1.1 + adsl_led_flash();//adsl led for 1.1.2.7.1.1 +#endif + wake_up_interruptible(&wait_queue_reboot); // wait up ioctl reboot + } +#endif + } + } +// meiLongwordWrite(ARC_TO_MEI_INT, ARC_TO_MEI_MSGAV); + mask_and_ack_amazon_irq(AMAZON_MEI_INT); + return; +} + +// 603221:tc.chen start +////////////////////////hdlc //////////////// + +// get hdlc status +static unsigned int ifx_me_hdlc_status(void) +{ + u16 CMVMSG[MSG_LENGTH]; + int ret; + + if (showtime!=1) + return -ENETRESET; + + makeCMV_local(H2D_CMV_READ, STAT, 14, 0, 1, NULL,CMVMSG); //Get HDLC status + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + return -EIO; + } + return CMVMSG[4]&0x0F; +} + +int ifx_me_is_resloved(int status) +{ + u16 CMVMSG[MSG_LENGTH]; + int ret; + + if (status == ME_HDLC_MSG_QUEUED || status == ME_HDLC_MSG_SENT) + return ME_HDLC_UNRESOLVED; + if (status == ME_HDLC_IDLE) + { + makeCMV_local(H2D_CMV_READ, CNTL, 2, 0, 1, NULL,CMVMSG); //Get ME-HDLC Control + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + return IFX_POP_EOC_FAIL; + } + if (CMVMSG[4]&(1<<0)) + { + return ME_HDLC_UNRESOLVED; + } + + } + return ME_HDLC_RESOLVED; +} + +int _ifx_me_hdlc_send(unsigned char *hdlc_pkt,int len,int max_length) +{ + int ret; + u16 CMVMSG[MSG_LENGTH]; + u16 data=0; + u16 pkt_len=len; + if (pkt_len > max_length) + { + printk("Exceed maximum eoc message length\n"); + return -ENOBUFS; + } + //while(pkt_len > 0) + { + makeCMV_local(H2D_CMV_WRITE, INFO, 81, 0, (pkt_len+1)/2,(u16 *)hdlc_pkt,CMVMSG); //Write clear eoc message to ARC + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + return -EIO; + } + + makeCMV_local(H2D_CMV_WRITE, INFO, 83, 2, 1,&pkt_len,CMVMSG); //Update tx message length + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + return -EIO; + } + + data = (1<<0); + makeCMV_local(H2D_CMV_WRITE, CNTL, 2, 0, 1,&data,CMVMSG); //Start to send + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + return -EIO; + } + return 0; + } +} + +static int ifx_me_hdlc_send(unsigned char *hdlc_pkt,int hdlc_pkt_len) +{ + int hdlc_status=0; + u16 CMVMSG[MSG_LENGTH]; + int max_hdlc_tx_length=0,ret=0,retry=0; + + while(retry<10) + { + hdlc_status = ifx_me_hdlc_status(); + if (ifx_me_is_resloved(hdlc_status)==ME_HDLC_RESOLVED) // arc ready to send HDLC message + { + makeCMV_local(H2D_CMV_READ, INFO, 83, 0, 1, NULL,CMVMSG); //Get Maximum Allowed HDLC Tx Message Length + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + return -EIO; + } + max_hdlc_tx_length = CMVMSG[4]; + ret = _ifx_me_hdlc_send(hdlc_pkt,hdlc_pkt_len,max_hdlc_tx_length); + return ret; + } + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(10); + } + return -EBUSY; +} + +int ifx_mei_hdlc_read(char *hdlc_pkt,int max_hdlc_pkt_len) +{ + u16 CMVMSG[MSG_LENGTH]; + int msg_read_len,ret=0,pkt_len=0,retry = 0; + + while(retry<10) + { + ret = ifx_me_hdlc_status(); + if (ret == ME_HDLC_RESP_RCVD) + { + int current_size=0; + makeCMV_local(H2D_CMV_READ, INFO, 83, 3, 1, NULL,CMVMSG); //Get EoC packet length + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + return -EIO; + } + + pkt_len = CMVMSG[4]; + if (pkt_len > max_hdlc_pkt_len) + { + ret = -ENOMEM; + goto error; + } + while( current_size < pkt_len) + { + if (pkt_len - current_size >(MSG_LENGTH*2-8)) + msg_read_len = (MSG_LENGTH*2-8); + else + msg_read_len = pkt_len - (current_size); + makeCMV_local(H2D_CMV_READ, INFO, 82, 0 + (current_size/2), (msg_read_len+1)/2, NULL,CMVMSG); //Get hdlc packet + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + goto error; + } + memcpy(hdlc_pkt+current_size,&CMVMSG[4],msg_read_len); + current_size +=msg_read_len; + } + ret = current_size; + break; + }else + { + ret = -ENODATA; + } + + retry++; + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(10); + + } + return ret; +error: + + return ret; +} + +////////////////////////hdlc //////////////// +// 603221:tc.chen end + +/////////////////////// clearEoC, int ifx_pop_eoc(sk_buff * pkt) ////////// +int ifx_pop_eoc(struct sk_buff * pkt); +int ifx_pop_eoc(struct sk_buff * pkt) +{ + amazon_clreoc_pkt * current; + if(showtime!=1){ + dev_kfree_skb(pkt); + return IFX_POP_EOC_FAIL; + } + if((pkt->len)>clreoc_max_tx_len){ + dev_kfree_skb(pkt); + return IFX_POP_EOC_FAIL; + } + current = list_entry(clreoc_list.next, amazon_clreoc_pkt, list); + while(1){ + if(current->len==0){ + memcpy(current->command, pkt->data, pkt->len); + current->len=pkt->len; + break; + } + else{ + if((current->list).next==&clreoc_list){ + dev_kfree_skb(pkt); + return IFX_POP_EOC_FAIL; //buffer full + } + current = list_entry((current->list).next,amazon_clreoc_pkt, list); + } + } + wake_up_interruptible(&wait_queue_clreoc); + + dev_kfree_skb(pkt); + return IFX_POP_EOC_DONE; +} +/* this is used in circular fifo mode */ +/* +int ifx_pop_eoc(sk_buff * pkt); +int ifx_pop_eoc(sk_buff * pkt) +{ + int buff_space,i; + if(showtime!=1) + return IFX_POP_EOC_FAIL; + + if(clreoc_wr>=clreoc_rd) + buff_space = (MEI_CLREOC_BUFF_SIZE-1)-(clreoc_wr - clreoc_rd); + else + buff_space = clreoc_rd - clreoc_wr - 1; + if((pkt->len)>buff_space) + return IFX_POP_EOC_FAIL; + + if((clreoc_wr+pkt->len)>MEI_CLREOC_BUFF_SIZE){ + memcpy((clreoc+clreoc_wr), pkt->data, ((clreoc_wr+pkt->len)-MEI_CLREOC_BUFF_SIZE+1)); + memcpy(clreoc, (pkt->data)+((clreoc_wr+pkt->len)-MEI_CLREOC_BUFF_SIZE+1), (pkt->len)-((clreoc_wr+pkt->len)-MEI_CLREOC_BUFF_SIZE+1)); + clreoc_wr=(clreoc_wr+pkt->len)-MEI_CLREOC_BUFF_SIZE; + } + else{ + memcpy((clreoc+clreoc_wr), pkt->data, pkt->len); + if((clreoc_wr+pkt->len)=MEI_CLREOC_BUFF_SIZE) + clreoc_wr=0; + else + clreoc_wr+=pkt->len; + } + wake_up_interruptible(&wait_queue_clreoc); + return IFX_POP_EOC_DONE; +} +*/ + + +//////////////////////////////////////////////////////////////////////////// +//int amazon_mei_init_module (void); +//void amazon_mei_cleanup_module (void); +//int __init init_module (void); +//void __exit cleanup_module (void); + +int __init amazon_mei_init_module(void) +//int __init init_module(void) +{ + struct proc_dir_entry *entry; + int i; + +//dying gasp-start +#ifdef IFX_DYING_GASP + +//000003:fchang Start +#ifdef CONFIG_CPU_AMAZON_E + //GPIO31 :dying gasp event indication + // (1) logic high: dying gasp event is false (default) + // (2) logic low: dying gasp event is true + CLEAR_BIT((*((volatile u32 *)0xB0100B18)), 0x4); + CLEAR_BIT((*((volatile u32 *)0xB0100B1c)), 0x4); + CLEAR_BIT((*((volatile u32 *)0xB0100B20)), 0x4); + SET_BIT((*((volatile u32 *)0xB0100B24)), 0x4); + asm("SYNC"); +#else //000003:fchang End + + //GPIO31 :dying gasp event indication + // (1) logic high: dying gasp event is false (default) + // (2) logic low: dying gasp event is true + CLEAR_BIT((*((volatile u32 *)0xB0100B48)), 0x8000); + CLEAR_BIT((*((volatile u32 *)0xB0100B4C)), 0x8000); + CLEAR_BIT((*((volatile u32 *)0xB0100B50)), 0x8000); + SET_BIT((*((volatile u32 *)0xB0100B54)), 0x8000); +#if 0 +//warning-led-start +//GPIO 22 + SET_BIT ((*((volatile u32 *)0xB0100B48)), 0x40); + CLEAR_BIT((*((volatile u32 *)0xB0100B4C)), 0x40); + CLEAR_BIT((*((volatile u32 *)0xB0100B50)), 0x40); + SET_BIT((*((volatile u32 *)0xB0100B54)), 0x40); + CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //GPIO ON + printk("LED ON ON ON ON ON ON....."); +//warning-led-end +#endif + asm("SYNC"); +#endif //000003:fchang + +#endif //IFX_DYING_GASP +//dying gasp -end + + + reg_entry_t regs_temp[PROC_ITEMS] = // Items being debugged + { + /* { flag, name, description } */ + { &arcmsgav, "arcmsgav", "arc to mei message ", 0 }, + { &cmv_reply, "cmv_reply", "cmv needs reply", 0}, + { &cmv_waiting, "cmv_waiting", "waiting for cmv reply from arc", 0}, + { &indicator_count, "indicator_count", "ARC to MEI indicator count", 0}, + { &cmv_count, "cmv_count", "MEI to ARC CMVs", 0}, + { &reply_count, "reply_count", "ARC to MEI Reply", 0}, + { (int *)Recent_indicator, "Recent_indicator", "most recent indicator", 0}, + { (int *)8, "version", "version of firmware", 0}, + }; + memcpy((char *)regs, (char *)regs_temp, sizeof(regs_temp)); + + + //sema_init(&mei_sema, 0); // semaphore initialization, mutex + sema_init(&mei_sema, 1); // semaphore initialization, mutex + + init_waitqueue_head(&wait_queue_arcmsgav); // for ARCMSGAV + init_waitqueue_head(&wait_queue_codeswap); // for codeswap daemon + init_waitqueue_head(&wait_queue_mibdaemon); // for mib daemon + init_waitqueue_head(&wait_queue_reboot); // for ioctl reboot + init_waitqueue_head(&wait_queue_clreoc); // for clreoc_wr function + init_waitqueue_head(&wait_queue_loop_diagnostic); // for loop diagnostic function +#ifdef ADSL_LED_SUPPORT + init_waitqueue_head(&wait_queue_led); // adsl led for led function + init_waitqueue_head(&wait_queue_led_polling); // adsl led for led function + led_task.routine = adsl_led_flash_task; // adsl led for led function + led_poll_init(); // adsl led for led function +#endif //ADSL_LED_SUPPORT +#ifdef IFX_DYING_GASP + init_waitqueue_head(&wait_queue_dying_gasp); // IFX_DYING_GASP + lop_poll_init(); // IFX_DYING_GASP +#endif //IFX_DYING_GASP + + init_waitqueue_head(&wait_queue_uas_poll);//joelin 04/16/2005 + unavailable_seconds_poll_init();//joelin 04/16/2005 + memset(&mib_pflagtime, 0, (sizeof(mib_flags_pretime))); + + // initialize link list for intervals + mei_mib = (amazon_mei_mib *)kmalloc((sizeof(amazon_mei_mib)*INTERVAL_NUM), GFP_KERNEL); + if(mei_mib == NULL){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("kmalloc error for amazon_mei_mib\n\n"); +#endif + return -1; + } + memset(mei_mib, 0, (sizeof(amazon_mei_mib)*INTERVAL_NUM)); + INIT_LIST_HEAD(&interval_list); + for(i=0;istart_time)); + // initialize clreoc list + clreoc_pkt = (amazon_clreoc_pkt *)kmalloc((sizeof(amazon_clreoc_pkt)*CLREOC_BUFF_SIZE), GFP_KERNEL); + if(clreoc_pkt == NULL){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("kmalloc error for clreoc_pkt\n\n"); +#endif + return -1; + } + memset(clreoc_pkt, 0, (sizeof(amazon_clreoc_pkt)*CLREOC_BUFF_SIZE)); + INIT_LIST_HEAD(&clreoc_list); + for(i=0;ilow_ino; + entry->proc_fops = &proc_operations; + } else { +#ifdef AMAZON_MEI_DEBUG_ON + printk( KERN_ERR + ": can't create /proc/" MEI_DIRNAME + "/%s\n\n", regs[i].name); +#endif + return(-ENOMEM); + } + } + ///////////////////////////////// register net device //////////////////////////// + if(register_netdev(&phy_mei_net)!=0){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n Register phy Device Failed."); +#endif + return -1; + } +/* + if(register_netdev(&interleave_mei_net)!=0){ + printk("\n\n Register interleave Device Failed."); + return -1; + } + if(register_netdev(&fast_mei_net)!=0){ + printk("\n\n Register fast Device Failed."); + return -1; + } +*/ +#ifdef DFE_LOOPBACK + mei_arc_swap_buff = (u32 *)kmalloc(MAXSWAPSIZE*4, GFP_KERNEL); + if (mei_arc_swap_buff){ +#ifdef ARC_READY_ACK + if(down_interruptible(&mei_sema)) //disable CMV access until ARC ready + { + return -ERESTARTSYS; + } +#ifdef LOCK_RETRY + reboot_lock = 1; +#endif +#endif + meiForceRebootAdslModem(); + kfree(mei_arc_swap_buff); + }else{ +#ifdef AMAZON_MEI_DEBUG_ON + printk("cannot load image: no memory\n\n"); +#endif + } +#endif +#ifdef IFX_SMALL_FOOTPRINT + mib_poll_init(); +#endif + return 0; +} + +void __exit amazon_mei_cleanup_module(void) +//void __exit cleanup_module(void) +{ + int i; +#ifdef ADSL_LED_SUPPORT + stop_led_module=1; //wake up and clean led module + led_support_check=0;//joelin , clear task + showtime=0;//joelin,clear task + //CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //Warning LED GPIO ON + firmware_support_led=0;//joelin ,clear task + wake_up_interruptible(&wait_queue_led); //wake up and clean led module + wake_up_interruptible(&wait_queue_led_polling); //wake up and clean led module +#endif + for(i=0;icomm, "kmibpoll"); + sigfillset(&tsk->blocked); + + printk("Inside mib poll loop ...\n"); + i=0; + while(1){ + if(istart_time.tv_sec>=900){ + if(current_intvl->list.next!=&interval_list){ + current_intvl = list_entry(current_intvl->list.next, amazon_mei_mib, list); + do_gettimeofday(&(current_intvl->start_time)); + } + else{ + mib_ptr = list_entry(interval_list.next, amazon_mei_mib, list); + list_del(interval_list.next); + memset(mib_ptr, 0, sizeof(amazon_mei_mib)); + list_add_tail(&(mib_ptr->list), &interval_list); + if(current_intvl->list.next==&interval_list) +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nlink list error"); +#endif + current_intvl = list_entry(current_intvl->list.next, amazon_mei_mib, list); + do_gettimeofday(&(current_intvl->start_time)); + } + } + + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; +/* + ATUC_PERF_LO_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 0 Index 0"); +#endif + } + else{ + if(RxMessage[4]&PLAM_LOS_FailureBit){ + current_intvl->AtucPerfLos++; + ATUC_PERF_LOSS++; + CurrStatus.adslAtucCurrStatus = 2; + } + if(RxMessage[4]&PLAM_LOF_FailureBit){ + current_intvl->AtucPerfLof++; + ATUC_PERF_LOFS++; + CurrStatus.adslAtucCurrStatus = 1; + } + if(!(RxMessage[4]&(PLAM_LOS_FailureBit|PLAM_LOF_FailureBit))) + CurrStatus.adslAtucCurrStatus = 0; + } +*/ + + if(showtime!=1) + goto mib_poll_end; + ATUC_PERF_ESS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 7 Index 0"); +#endif + } + else{ + temp = RxMessage[4]-mib_pread.ATUC_PERF_ESS; + if(temp>=0){ + current_intvl->AtucPerfEs+=temp; + ATUC_PERF_ESS+=temp; + mib_pread.ATUC_PERF_ESS = RxMessage[4]; + } + else{ + current_intvl->AtucPerfEs+=0xffff-mib_pread.ATUC_PERF_ESS+RxMessage[4]; + ATUC_PERF_ESS+=0xffff-mib_pread.ATUC_PERF_ESS+RxMessage[4]; + mib_pread.ATUC_PERF_ESS = RxMessage[4]; + } + } +/* + ATUR_PERF_LO_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 1 Index 0"); +#endif + } + else{ + if(RxMessage[4]&PLAM_LOS_FailureBit){ + current_intvl->AturPerfLos++; + ATUR_PERF_LOSS++; + CurrStatus.adslAturCurrStatus = 2; + } + if(RxMessage[4]&PLAM_LOF_FailureBit){ + current_intvl->AturPerfLof++; + ATUR_PERF_LOFS++; + CurrStatus.adslAturCurrStatus = 1; + } + if(RxMessage[4]&PLAM_LPR_FailureBit){ + current_intvl->AturPerfLpr++; + ATUR_PERF_LPR++; + CurrStatus.adslAturCurrStatus = 3; + } + if(!(RxMessage[4]&(PLAM_LOS_FailureBit|PLAM_LOF_FailureBit|PLAM_LPR_FailureBit))) + CurrStatus.adslAturCurrStatus = 0; + } +*/ + if(showtime!=1) + goto mib_poll_end; + ATUR_PERF_ESS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 33 Index 0"); +#endif + } + else{ + temp = RxMessage[4]-mib_pread.ATUR_PERF_ESS; + if(temp>=0){ + current_intvl->AturPerfEs+=temp; + ATUR_PERF_ESS+=temp; + mib_pread.ATUR_PERF_ESS = RxMessage[4]; + } + else{ + current_intvl->AturPerfEs+=0xffff-mib_pread.ATUR_PERF_ESS+RxMessage[4]; + ATUR_PERF_ESS+= 0xffff-mib_pread.ATUR_PERF_ESS+RxMessage[4]; + mib_pread.ATUR_PERF_ESS=RxMessage[4]; + } + } + if(showtime!=1) + goto mib_poll_end; + // to update rx/tx blocks + ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_LSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 20 Index 0"); +#endif + } + else{ + temp = RxMessage[4]; + } + if(showtime!=1) + goto mib_poll_end; + ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_MSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 21 Index 0"); +#endif + } + else{ + temp2 = RxMessage[4]; + } + if((temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK)>=0){ + current_intvl->AturChanPerfRxBlk+=temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK; + ATUR_CHAN_RECV_BLK+=temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK; + mib_pread.ATUR_CHAN_RECV_BLK = temp + (temp2<<16); + } + else{ + current_intvl->AturChanPerfRxBlk+=0xffffffff - mib_pread.ATUR_CHAN_RECV_BLK +(temp + (temp2<<16)); + ATUR_CHAN_RECV_BLK+=0xffffffff - mib_pread.ATUR_CHAN_RECV_BLK +(temp + (temp2<<16)); + mib_pread.ATUR_CHAN_RECV_BLK = temp + (temp2<<16); + } + current_intvl->AturChanPerfTxBlk = current_intvl->AturChanPerfRxBlk; + ATUR_CHAN_TX_BLK = ATUR_CHAN_RECV_BLK; +/* + ATUR_CHAN_TX_BLK_FLAG_MAKECMV_LSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS) + printk("\n\nCMV fail, Group 7 Address 20 Index 0"); + else{ + if(RxMessage[4]){ + current_intvl->AturChanPerfTxBlk+=RxMessage[4]; + ATUR_CHAN_TX_BLK+=RxMessage[4]; + } + } + ATUR_CHAN_TX_BLK_FLAG_MAKECMV_MSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS) + printk("\n\nCMV fail, Group 7 Address 21 Index 0"); + else{ + if(RxMessage[4]){ + current_intvl->AturChanPerfTxBlk+=(int)((RxMessage[4])<<16); + ATUR_CHAN_TX_BLK+=(int)((RxMessage[4])<<16); + } + } +*/ + if(chantype.interleave == 1){ + if(showtime!=1) + goto mib_poll_end; + ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_INTL; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 3 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_CORR_BLK_INTL; + if(temp>=0){ + current_intvl->AturChanPerfCorrBlk+=temp; + ATUR_CHAN_CORR_BLK+=temp; + mib_pread.ATUR_CHAN_CORR_BLK_INTL = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfCorrBlk+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_INTL +RxMessage[4]; + ATUR_CHAN_CORR_BLK+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_INTL +RxMessage[4]; + mib_pread.ATUR_CHAN_CORR_BLK_INTL = RxMessage[4]; + } + } + } + else if(chantype.fast == 1){ + if(showtime!=1) + goto mib_poll_end; + ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_FAST; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 3 Index 1"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_CORR_BLK_FAST; + if(temp>=0){ + current_intvl->AturChanPerfCorrBlk+=temp; + ATUR_CHAN_CORR_BLK+=temp; + mib_pread.ATUR_CHAN_CORR_BLK_FAST = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfCorrBlk+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_FAST + RxMessage[4]; + ATUR_CHAN_CORR_BLK+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_FAST + RxMessage[4]; + mib_pread.ATUR_CHAN_CORR_BLK_FAST = RxMessage[4]; + } + } + } + + if(chantype.interleave == 1){ + if(showtime!=1) + goto mib_poll_end; + ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_INTL; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 2 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL; + if(temp>=0){ + current_intvl->AturChanPerfUncorrBlk+=temp; + ATUR_CHAN_UNCORR_BLK+=temp; + mib_pread.ATUR_CHAN_UNCORR_BLK_INTL = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfUncorrBlk+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL + RxMessage[4]; + ATUR_CHAN_UNCORR_BLK+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL + RxMessage[4]; + mib_pread.ATUR_CHAN_UNCORR_BLK_INTL = RxMessage[4]; + } + } + } + else if(chantype.fast == 1){ + if(showtime!=1) + goto mib_poll_end; + ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_FAST; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 2 Index 1"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST; + if(temp>=0){ + current_intvl->AturChanPerfUncorrBlk+=temp; + ATUR_CHAN_UNCORR_BLK+=temp; + mib_pread.ATUR_CHAN_UNCORR_BLK_FAST = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfUncorrBlk+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST + RxMessage[4]; + ATUR_CHAN_UNCORR_BLK+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST + RxMessage[4]; + mib_pread.ATUR_CHAN_UNCORR_BLK_FAST = RxMessage[4]; + } + } + } + + //RFC-3440 + +#ifdef AMAZON_MEI_MIB_RFC3440 + if(showtime!=1) + goto mib_poll_end; + ATUC_PERF_STAT_FASTR_FLAG_MAKECMV; //??? + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 0 Address 0 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_FASTR; + if(temp>=0){ + current_intvl->AtucPerfStatFastR+=temp; + ATUC_PERF_STAT_FASTR+=temp; + mib_pread.ATUC_PERF_STAT_FASTR = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatFastR+=0xffff - mib_pread.ATUC_PERF_STAT_FASTR + RxMessage[4]; + ATUC_PERF_STAT_FASTR+=0xffff - mib_pread.ATUC_PERF_STAT_FASTR + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_FASTR = RxMessage[4]; + } + } + if(showtime!=1) + goto mib_poll_end; + ATUC_PERF_STAT_FAILED_FASTR_FLAG_MAKECMV; //??? + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 0 Address 0 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_FAILED_FASTR; + if(temp>=0){ + current_intvl->AtucPerfStatFailedFastR+=temp; + ATUC_PERF_STAT_FAILED_FASTR+=temp; + mib_pread.ATUC_PERF_STAT_FAILED_FASTR = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatFailedFastR+=0xffff - mib_pread.ATUC_PERF_STAT_FAILED_FASTR + RxMessage[4]; + ATUC_PERF_STAT_FAILED_FASTR+=0xffff - mib_pread.ATUC_PERF_STAT_FAILED_FASTR + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_FAILED_FASTR = RxMessage[4]; + } + } + if(showtime!=1) + goto mib_poll_end; + ATUC_PERF_STAT_SESL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 8 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_SESL; + if(temp>=0){ + current_intvl->AtucPerfStatSesL+=temp; + ATUC_PERF_STAT_SESL+=temp; + mib_pread.ATUC_PERF_STAT_SESL = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatSesL+=0xffff - mib_pread.ATUC_PERF_STAT_SESL + RxMessage[4]; + ATUC_PERF_STAT_SESL+=0xffff - mib_pread.ATUC_PERF_STAT_SESL + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_SESL = RxMessage[4]; + } + } + if(showtime!=1) + goto mib_poll_end; + ATUC_PERF_STAT_UASL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 10 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_UASL; + if(temp>=0){ + current_intvl->AtucPerfStatUasL+=temp; + ATUC_PERF_STAT_UASL+=temp; + mib_pread.ATUC_PERF_STAT_UASL = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatUasL+=0xffff - mib_pread.ATUC_PERF_STAT_UASL + RxMessage[4]; + ATUC_PERF_STAT_UASL+=0xffff - mib_pread.ATUC_PERF_STAT_UASL + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_UASL = RxMessage[4]; + } + } + if(showtime!=1) + goto mib_poll_end; + ATUR_PERF_STAT_SESL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 34 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_PERF_STAT_SESL; + if(temp>=0){ + current_intvl->AtucPerfStatUasL+=temp; + ATUC_PERF_STAT_UASL+=temp; + mib_pread.ATUR_PERF_STAT_SESL = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatUasL+=0xffff - mib_pread.ATUR_PERF_STAT_SESL + RxMessage[4]; + ATUC_PERF_STAT_UASL+=0xffff - mib_pread.ATUR_PERF_STAT_SESL + RxMessage[4]; + mib_pread.ATUR_PERF_STAT_SESL = RxMessage[4]; + } + } + +#endif +mib_poll_end: + up(&mei_sema); + + do_gettimeofday(&time_fini); + i = ((int)((time_fini.tv_sec-time_now.tv_sec)*1000)) + ((int)((time_fini.tv_usec-time_now.tv_usec)/1000)) ; //msec + }//showtime==1 + } + +} +int mib_poll_init(void) +{ + printk("Starting mib_poll...\n"); + + kernel_thread(adsl_mib_poll, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); + return 0; +} +#endif //IFX_SMALL_FOOTPRINT +//EXPORT_NO_SYMBOLS; + +#ifdef ADSL_LED_SUPPORT +// adsl led -start +int led_status_on=0,led_need_to_flash=0; +int led_current_flashing=0; +unsigned long led_delay=0; +static int led_poll(void *unused) +{ + stop_led_module=0; //begin polling ... + while(!stop_led_module){ + if ((!led_status_on)&&(!led_need_to_flash)) interruptible_sleep_on_timeout (&wait_queue_led_polling,1000); //10 seconds timeout for waiting wakeup +// else printk("direct running task, no waiting"); + run_task_queue(&tq_ifx_led);//joelin task +// printk("led and LOP polling...\n"); + } + return 0; +} +static int led_poll_init(void) +{ +// printk("Starting adsl led polling...\n"); + +//warning-led-start +// CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //Warning LED GPIO ON +//warning-led-end + + kernel_thread(led_poll, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); + return 0; +} + +int adsl_led_flash(void) +{ + int i; + if (!firmware_support_led) return 0; //joelin version check + + if (led_status_on == 0 && led_need_to_flash == 0) + { + queue_task(&led_task, &tq_ifx_led);//joelin task + wake_up_interruptible(&wait_queue_led_polling); //wake up and clean led module +// printk("queue Task 1...\n"); //joelin test + } + led_need_to_flash=1;//asking to flash led + + return 0; +} + +int adsl_led_flash_task(void *ptr) +{ + + u16 one=1; + u16 zero=0; + u16 data=0x0600; + int kernel_use=1; + u16 CMVMSG[MSG_LENGTH]; +//adsl-led-start for >v1.1.2.7.1.1 +// printk("Task Running...\n"); //joelin test + if ((firmware_support_led==2)&&(led_support_check)) + { + led_support_check=0; + data=0x0600; + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 0, 1, &data,CMVMSG); //configure GPIO9 GPIO10 as outputs + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 2, 1, &data,CMVMSG); //enable writing to bit 9 and bit10 + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + + data=0x0a01; + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 4, 1, &data,CMVMSG); //use GPIO10 for TR68 .Enable and don't invert. + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + +#ifdef DATA_LED_ON_MODE + data=0x0903;//tecom //use GPIO9 for TR68 data led .turn on. +#else + data=0x0900; +#endif + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 5, 1, &data,CMVMSG); //use GPIO9 for TR68 data led .turn off. + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + + } + if (!showtime) {led_need_to_flash=0; return 0;} +//adsl-led-end for >v1.1.2.7.1.1 + + if (led_status_on == 0 || led_need_to_flash == 1) + { + + if (led_current_flashing==0) + { + if (firmware_support_led==1){//>1.1.2.3.1.1 + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 0, 1, &one,CMVMSG); //flash + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &CMVMSG); + } + else if (firmware_support_led==2){//>1.1.2.7.1.1 + data=0x0901;//flash + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 5, 1, &data,CMVMSG); //use GPIO9 for TR68 data led .flash. + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &CMVMSG); + + }//(firmware_support_led==2) + led_current_flashing = 1;//turn on led + } + led_status_on=1; + + do{//do nothing , waiting untill no data traffic + led_need_to_flash=0; + interruptible_sleep_on_timeout(&wait_queue_led, 25); //the time for LED Off , if no data traffic + }while(led_need_to_flash==1); + + }else if (led_status_on == 1 && led_need_to_flash==0) + { + if (led_current_flashing==1) + {//turn off led + if (firmware_support_led==1){//>1.1.2.3.1.1 + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 0, 1, &zero,CMVMSG);//off + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &CMVMSG); + } //>1.1.2.3.1.1 + else if (firmware_support_led==2){//>1.1.2.7.1.1 +#ifdef DATA_LED_ON_MODE + data=0x0903;//tecom //use GPIO9 for TR68 data led .turn on. +#else + data=0x0900;//off +#endif + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 5, 1, &data,CMVMSG); //use GPIO9 for TR68 data led .off. + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &CMVMSG); + + }//(firmware_support_led==2) + led_status_on=0; + led_current_flashing = 0; + } + } + + if (led_status_on == 1 || led_need_to_flash) + {//led flash job on going or led need to flash + queue_task(&led_task, &tq_ifx_led); //joelin task +// printk("queue Task 2...\n"); //joelin test + } + return 0; +} +//joelin adsl led-end +#else +int adsl_led_flash(void) +{ + return 0; +} +#endif //ADSL_LED_SUPPORT +#ifdef IFX_DYING_GASP +static int lop_poll(void *unused) +{ + + while(1) + { + interruptible_sleep_on_timeout(&wait_queue_dying_gasp, 1); +#ifdef CONFIG_CPU_AMAZON_E //000003:fchang + if(showtime&&((*((volatile u32 *)0xB0100B14))&0x4)==0x0) {//000003:fchang +#else //000003:fchang + if(showtime&&((*((volatile u32 *)0xB0100B44))&0x8000)==0x0) { +#endif //CONFIG_CPU_AMAZON_E + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_WRITEDEBUG, &lop_debugwr); + printk("send dying gasp..\n");} + + } + return 0; + } +static int lop_poll_init(void) +{ +// printk("Starting LOP polling...\n"); + kernel_thread(lop_poll, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); + return 0; +} + +#endif //IFX_DYING_GASP + +//joelin 04/16/2005-satrt +static int unavailable_seconds_poll(void *unused) +{ + while(1){ + interruptible_sleep_on_timeout (&wait_queue_uas_poll,100); //1 second timeout for waiting wakeup + if (!showtime) unavailable_seconds++; + } + return 0; +} +static int unavailable_seconds_poll_init(void) +{ + + kernel_thread(unavailable_seconds_poll, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); + return 0; +} + + +//joelin 04/16/2005-end +EXPORT_SYMBOL(meiDebugWrite); +EXPORT_SYMBOL(ifx_pop_eoc); + +MODULE_LICENSE("GPL"); + +module_init(amazon_mei_init_module); +module_exit(amazon_mei_cleanup_module); + diff --git a/target/linux/amazon/files/drivers/char/ifx_ssc.c b/target/linux/amazon/files/drivers/char/ifx_ssc.c new file mode 100644 index 000000000..ea01659a9 --- /dev/null +++ b/target/linux/amazon/files/drivers/char/ifx_ssc.c @@ -0,0 +1,2121 @@ +/************************************************** + * + * drivers/ifx/serial/ifx_ssc.c + * + * Driver for IFX_SSC serial ports + * + * Copyright (C) 2004 Infineon Technologies AG + * Author Michael Schoenenborn (IFX COM TI BT) + * + */ +#define IFX_SSC_DRV_VERSION "0.2.1" +/* + ************************************************** + * + * This driver was originally based on the INCA-IP driver, but due to + * fundamental conceptual drawbacks there has been changed a lot. + * + * Based on INCA-IP driver Copyright (c) 2003 Gary Jennejohn + * Based on the VxWorks drivers Copyright (c) 2002, Infineon Technologies. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +// ### TO DO: general issues: +// - power management +// - interrupt handling (direct/indirect) +// - pin/mux-handling (just overall concept due to project dependency) +// - multiple instances capability +// - slave functionality + +/* + * Include section + */ +#ifndef EXPORT_SYMTAB +#define EXPORT_SYMTAB +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#ifdef SSC_FRAME_INT_ENABLE +#undef SSC_FRAME_INT_ENABLE +#endif + +#define not_yet + +#define SPI_VINETIC + +/* + * Deal with CONFIG_MODVERSIONS + */ +#if CONFIG_MODVERSIONS==1 +# include +#endif + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Michael Schoenenborn"); +MODULE_DESCRIPTION("IFX SSC driver"); +MODULE_SUPPORTED_DEVICE("ifx_ssc"); +MODULE_PARM(maj, "i"); +MODULE_PARM_DESC(maj, "Major device number"); + +/* allow the user to set the major device number */ +static int maj = 0; + + +/* + * This is the per-channel data structure containing pointers, flags + * and variables for the port. This driver supports a maximum of PORT_CNT. + * isp is allocated in ifx_ssc_init() based on the chip version. + */ +static struct ifx_ssc_port *isp; + +/* prototypes for fops */ +static ssize_t ifx_ssc_read(struct file *, char *, size_t, loff_t *); +static ssize_t ifx_ssc_write(struct file *, const char *, size_t, loff_t *); +//static unsigned int ifx_ssc_poll(struct file *, struct poll_table_struct *); +int ifx_ssc_ioctl(struct inode *, struct file *, unsigned int, unsigned long); +int ifx_ssc_open(struct inode *, struct file *); +int ifx_ssc_close(struct inode *, struct file *); + +/* other forward declarations */ +static unsigned int ifx_ssc_get_kernel_clk(struct ifx_ssc_port *info); +static void ifx_ssc_rx_int(int, void *, struct pt_regs *); +static void ifx_ssc_tx_int(int, void *, struct pt_regs *); +static void ifx_ssc_err_int(int, void *, struct pt_regs *); +#ifdef SSC_FRAME_INT_ENABLE +static void ifx_ssc_frm_int(int, void *, struct pt_regs *); +#endif +static void tx_int(struct ifx_ssc_port *); +static int ifx_ssc1_read_proc(char *, char **, off_t, int, int *, void *); +static void ifx_gpio_init(void); +/************************************************************************ + * Function declaration + ************************************************************************/ +//interrupt.c +extern unsigned int amazon_get_fpi_hz(void); +extern void disable_amazon_irq(unsigned int irq_nr); +extern void enable_amazon_irq(unsigned int irq_nr); +extern void mask_and_ack_amazon_irq(unsigned int irq_nr); + + +/*****************************************************************/ +typedef struct { + int (*request)(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, + const char * devname, + void *dev_id); + void (*free)(unsigned int irq, void *dev_id); + void (*enable)(unsigned int irq); + void (*disable)(unsigned int irq); + void (*clear)(unsigned int irq); +} ifx_int_wrapper_t; + +static ifx_int_wrapper_t ifx_int_wrapper = { + request: request_irq, // IM action: enable int + free: free_irq, // IM action: disable int + enable: enable_amazon_irq, + disable: disable_amazon_irq, + clear: mask_and_ack_amazon_irq, + //end: +}; + +/* Fops-struct */ +static struct file_operations ifx_ssc_fops = { + owner: THIS_MODULE, + read: ifx_ssc_read, /* read */ + write: ifx_ssc_write, /* write */ +// poll: ifx_ssc_poll, /* poll */ + ioctl: ifx_ssc_ioctl, /* ioctl */ + open: ifx_ssc_open, /* open */ + release: ifx_ssc_close, /* release */ +}; + + +static inline unsigned int ifx_ssc_get_kernel_clk(struct ifx_ssc_port *info) +{ // ATTENTION: This function assumes that the CLC register is set with the + // appropriate value for RMC. + unsigned int rmc; + + rmc = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CLC) & + IFX_CLC_RUN_DIVIDER_MASK) >> IFX_CLC_RUN_DIVIDER_OFFSET; + if (rmc == 0){ + printk("ifx_ssc_get_kernel_clk rmc==0 \n"); + return (0); + } + return (amazon_get_fpi_hz() / rmc); +} + +#ifndef not_yet +#ifdef IFX_SSC_INT_USE_BH +/* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver + * (also known as the "bottom half"). This can be called any + * number of times for any channel without harm. + */ +static inline void +ifx_ssc_sched_event(struct ifx_ssc_port *info, int event) +{ + info->event |= 1 << event; /* remember what kind of event and who */ + queue_task(&info->tqueue, &tq_cyclades); /* it belongs to */ + mark_bh(CYCLADES_BH); /* then trigger event */ +} /* ifx_ssc_sched_event */ + + +/* + * This routine is used to handle the "bottom half" processing for the + * serial driver, known also the "software interrupt" processing. + * This processing is done at the kernel interrupt level, after the + * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This + * is where time-consuming activities which can not be done in the + * interrupt driver proper are done; the interrupt driver schedules + * them using ifx_ssc_sched_event(), and they get done here. + * + * This is done through one level of indirection--the task queue. + * When a hardware interrupt service routine wants service by the + * driver's bottom half, it enqueues the appropriate tq_struct (one + * per port) to the tq_cyclades work queue and sets a request flag + * via mark_bh for processing that queue. When the time is right, + * do_ifx_ssc_bh is called (because of the mark_bh) and it requests + * that the work queue be processed. + * + * Although this may seem unwieldy, it gives the system a way to + * pass an argument (in this case the pointer to the ifx_ssc_port + * structure) to the bottom half of the driver. Previous kernels + * had to poll every port to see if that port needed servicing. + */ +static void +do_ifx_ssc_bh(void) +{ + run_task_queue(&tq_cyclades); +} /* do_ifx_ssc_bh */ + +static void +do_softint(void *private_) +{ + struct ifx_ssc_port *info = (struct ifx_ssc_port *) private_; + + if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) { + wake_up_interruptible(&info->open_wait); + info->flags &= ~(ASYNC_NORMAL_ACTIVE| + ASYNC_CALLOUT_ACTIVE); + } + if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) { + wake_up_interruptible(&info->open_wait); + } + if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) { + wake_up_interruptible(&info->delta_msr_wait); + } + if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) { + wake_up_interruptible(&tty->write_wait); + } +#ifdef Z_WAKE + if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) { + wake_up_interruptible(&info->shutdown_wait); + } +#endif +} /* do_softint */ +#endif /* IFX_SSC_INT_USE_BH */ +#endif // not_yet + +inline static void +rx_int(struct ifx_ssc_port *info) +{ + int fifo_fill_lev, bytes_in_buf, i; + unsigned long tmp_val; + unsigned long *tmp_ptr; + unsigned int rx_valid_cnt; + /* number of words waiting in the RX FIFO */ + fifo_fill_lev = (READ_PERIPHERAL_REGISTER(info->mapbase + + IFX_SSC_FSTAT) & + IFX_SSC_FSTAT_RECEIVED_WORDS_MASK) >> + IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET; + // Note: There are always 32 bits in a fifo-entry except for the last + // word of a contigous transfer block and except for not in rx-only + // mode and CON.ENBV set. But for this case it should be a convention + // in software which helps: + // In tx or rx/tx mode all transfers from the buffer to the FIFO are + // 32-bit wide, except for the last three bytes, which could be a + // combination of 16- and 8-bit access. + // => The whole block is received as 32-bit words as a contigous stream, + // even if there was a gap in tx which has the fifo run out of data! + // Just the last fifo entry *may* be partially filled (0, 1, 2 or 3 bytes)! + + /* free space in the RX buffer */ + bytes_in_buf = info->rxbuf_end - info->rxbuf_ptr; + // transfer with 32 bits per entry + while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0)) { + tmp_ptr = (unsigned long *)info->rxbuf_ptr; + *tmp_ptr = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RB); + info->rxbuf_ptr += 4; + info->stats.rxBytes += 4; + fifo_fill_lev --; + bytes_in_buf -= 4; + } // while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0)) + // now do the rest as mentioned in STATE.RXBV + while ((bytes_in_buf > 0) && (fifo_fill_lev > 0)) { + rx_valid_cnt = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & + IFX_SSC_STATE_RX_BYTE_VALID_MASK) >> + IFX_SSC_STATE_RX_BYTE_VALID_OFFSET; + if (rx_valid_cnt == 0) break; + if (rx_valid_cnt > bytes_in_buf) { + // ### TO DO: warning message: not block aligned data, other data + // in this entry will be lost + rx_valid_cnt = bytes_in_buf; + } + tmp_val = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RB); + + for (i=0; irxbuf_ptr = (tmp_val >> ( 8 * (rx_valid_cnt - i-1))) & 0xff; +/* + *info->rxbuf_ptr = tmp_val & 0xff; + tmp_val >>= 8; +*/ + bytes_in_buf--; + + + info->rxbuf_ptr++; + } + info->stats.rxBytes += rx_valid_cnt; + } // while ((bytes_in_buf > 0) && (fifo_fill_lev > 0)) + + // check if transfer is complete + if (info->rxbuf_ptr >= info->rxbuf_end) { + ifx_int_wrapper.disable(info->rxirq); + /* wakeup any processes waiting in read() */ + wake_up_interruptible(&info->rwait); + /* and in poll() */ + //wake_up_interruptible(&info->pwait); + } else if ((info->opts.modeRxTx == IFX_SSC_MODE_RX) && + (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) == 0)) { + // if buffer not filled completely and rx request done initiate new transfer +/* + if (info->rxbuf_end - info->rxbuf_ptr < 65536) +*/ + if (info->rxbuf_end - info->rxbuf_ptr < IFX_SSC_RXREQ_BLOCK_SIZE) + WRITE_PERIPHERAL_REGISTER((info->rxbuf_end - info->rxbuf_ptr) << + IFX_SSC_RXREQ_RXCOUNT_OFFSET, + info->mapbase + IFX_SSC_RXREQ); + else + WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, + info->mapbase + IFX_SSC_RXREQ); + } +} // rx_int + +inline static void +tx_int(struct ifx_ssc_port *info) +{ + + int fifo_space, fill, i; + fifo_space = ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_ID) & + IFX_SSC_PERID_TXFS_MASK) >> IFX_SSC_PERID_TXFS_OFFSET) - + ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_FSTAT) & + IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK) >> + IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET); + + if (fifo_space == 0) + return; + + fill = info->txbuf_end - info->txbuf_ptr; + + if (fill > fifo_space * 4) + fill = fifo_space * 4; + + for (i = 0; i < fill / 4; i++) { + // at first 32 bit access + WRITE_PERIPHERAL_REGISTER(*(UINT32 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB); + info->txbuf_ptr += 4; + } + + fifo_space -= fill / 4; + info->stats.txBytes += fill & ~0x3; + fill &= 0x3; + if ((fifo_space > 0) & (fill > 1)) { + // trailing 16 bit access + WRITE_PERIPHERAL_REGISTER_16(*(UINT16 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB); + info->txbuf_ptr += 2; + info->stats.txBytes += 2; + fifo_space --; +/* added by bingtao */ + fill -=2; + } + if ((fifo_space > 0) & (fill > 0)) { + // trailing 8 bit access + WRITE_PERIPHERAL_REGISTER_8(*(UINT8 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB); + info->txbuf_ptr ++; + info->stats.txBytes ++; +/* + fifo_space --; +*/ + } + + // check if transmission complete + if (info->txbuf_ptr >= info->txbuf_end) { + ifx_int_wrapper.disable(info->txirq); + kfree(info->txbuf); + info->txbuf = NULL; + /* wake up any process waiting in poll() */ + //wake_up_interruptible(&info->pwait); + } + +} // tx_int + +static void +ifx_ssc_rx_int(int irq, void *dev_id, struct pt_regs *regs) +{ + struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id; + //WRITE_PERIPHERAL_REGISTER(IFX_SSC_R_BIT, info->mapbase + IFX_SSC_IRN_CR); + rx_int(info); +} + +static void +ifx_ssc_tx_int(int irq, void *dev_id, struct pt_regs *regs) +{ + struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id; + //WRITE_PERIPHERAL_REGISTER(IFX_SSC_T_BIT, info->mapbase + IFX_SSC_IRN_CR); + tx_int(info); +} + +static void +ifx_ssc_err_int(int irq, void *dev_id, struct pt_regs *regs) +{ + struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id; + unsigned int state; + unsigned int write_back = 0; + unsigned long flags; + + + local_irq_save(flags); + state = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE); + + if ((state & IFX_SSC_STATE_RX_UFL) != 0) { + info->stats.rxUnErr++; + write_back |= IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR; + } + if ((state & IFX_SSC_STATE_RX_OFL) != 0) { + info->stats.rxOvErr++; + write_back |= IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR; + } + if ((state & IFX_SSC_STATE_TX_OFL) != 0) { + info->stats.txOvErr++; + write_back |= IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR; + } + if ((state & IFX_SSC_STATE_TX_UFL) != 0) { + info->stats.txUnErr++; + write_back |= IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR; + } +// if ((state & IFX_SSC_STATE_ABORT_ERR) != 0) { +// info->stats.abortErr++; +// write_back |= IFX_SSC_WHBSTATE_CLR_ABORT_ERROR; +// } + if ((state & IFX_SSC_STATE_MODE_ERR) != 0) { + info->stats.modeErr++; + write_back |= IFX_SSC_WHBSTATE_CLR_MODE_ERROR; + } + + if (write_back) + WRITE_PERIPHERAL_REGISTER(write_back, + info->mapbase + IFX_SSC_WHBSTATE); + + local_irq_restore(flags); +} + +#ifdef SSC_FRAME_INT_ENABLE +static void +ifx_ssc_frm_int(int irq, void *dev_id, struct pt_regs *regs) +{ + // ### TO DO: wake up framing wait-queue in conjunction with batch execution +} +#endif + +static void +ifx_ssc_abort(struct ifx_ssc_port *info) +{ + unsigned long flags; + bool enabled; + + local_irq_save(flags); + + // disable all int's + ifx_int_wrapper.disable(info->rxirq); + ifx_int_wrapper.disable(info->txirq); + ifx_int_wrapper.disable(info->errirq); +/* + ifx_int_wrapper.disable(info->frmirq); +*/ + local_irq_restore(flags); + + // disable SSC (also aborts a receive request!) + // ### TO DO: Perhaps it's better to abort after the receiption of a + // complete word. The disable cuts the transmission immediatly and + // releases the chip selects. This could result in unpredictable + // behavior of connected external devices! + enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) + & IFX_SSC_STATE_IS_ENABLED) != 0; + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + + + // flush fifos + WRITE_PERIPHERAL_REGISTER(IFX_SSC_XFCON_FIFO_FLUSH, + info->mapbase + IFX_SSC_TXFCON); + WRITE_PERIPHERAL_REGISTER(IFX_SSC_XFCON_FIFO_FLUSH, + info->mapbase + IFX_SSC_RXFCON); + + // free txbuf + if (info->txbuf != NULL) { + kfree(info->txbuf); + info->txbuf = NULL; + } + + // wakeup read process + if (info->rxbuf != NULL) + wake_up_interruptible(&info->rwait); + + // clear pending int's + ifx_int_wrapper.clear(info->rxirq); + ifx_int_wrapper.clear(info->txirq); + ifx_int_wrapper.clear(info->errirq); +/* + ifx_int_wrapper.clear(info->frmirq); +*/ + + // clear error flags + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ALL_ERROR, + info->mapbase + IFX_SSC_WHBSTATE); + + //printk("IFX SSC%d: Transmission aborted\n", info->port_nr); + // enable SSC + if (enabled) + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + +} // ifx_ssc_abort + + +/* + * This routine is called whenever a port is opened. It enforces + * exclusive opening of a port and enables interrupts, etc. + */ +int +ifx_ssc_open(struct inode *inode, struct file * filp) +{ + struct ifx_ssc_port *info; + int line; + int from_kernel = 0; + + if ((inode == (struct inode *)0) || (inode == (struct inode *)1)) { + from_kernel = 1; + line = (int)inode; + } + else { + line = MINOR(filp->f_dentry->d_inode->i_rdev); + filp->f_op = &ifx_ssc_fops; + } + + /* don't open more minor devices than we can support */ + if (line < 0 || line >= PORT_CNT) + return -ENXIO; + + info = &isp[line]; + + /* exclusive open */ + if (info->port_is_open != 0) + return -EBUSY; + info->port_is_open++; + + ifx_int_wrapper.disable(info->rxirq); + ifx_int_wrapper.disable(info->txirq); + ifx_int_wrapper.disable(info->errirq); +/* + ifx_int_wrapper.disable(info->frmirq); +*/ + + /* Flush and enable TX/RX FIFO */ + WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_TXFIFO_FL << + IFX_SSC_XFCON_ITL_OFFSET) | + IFX_SSC_XFCON_FIFO_FLUSH | + IFX_SSC_XFCON_FIFO_ENABLE, + info->mapbase + IFX_SSC_TXFCON); + WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_RXFIFO_FL << + IFX_SSC_XFCON_ITL_OFFSET) | + IFX_SSC_XFCON_FIFO_FLUSH | + IFX_SSC_XFCON_FIFO_ENABLE, + info->mapbase + IFX_SSC_RXFCON); + + + /* logically flush the software FIFOs */ + info->rxbuf_ptr = 0; + info->txbuf_ptr = 0; + + /* clear all error bits */ + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ALL_ERROR, + info->mapbase + IFX_SSC_WHBSTATE); + + // clear pending interrupts + ifx_int_wrapper.clear(info->rxirq); + ifx_int_wrapper.clear(info->txirq); + ifx_int_wrapper.clear(info->errirq); +/* + ifx_int_wrapper.clear(info->frmirq); +*/ + + // enable SSC + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + + MOD_INC_USE_COUNT; + + return 0; +} /* ifx_ssc_open */ +EXPORT_SYMBOL(ifx_ssc_open); + +/* + * This routine is called when a particular device is closed. + */ +int +ifx_ssc_close(struct inode *inode, struct file *filp) +{ + struct ifx_ssc_port *info; + int idx; + + if ((inode == (struct inode *)0) || (inode == (struct inode *)1)) + idx = (int)inode; + else + idx = MINOR(filp->f_dentry->d_inode->i_rdev); + + if (idx < 0 || idx >= PORT_CNT) + return -ENXIO; + + info = &isp[idx]; + if (!info) + return -ENXIO; + + // disable SSC + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + + // call abort function to disable int's, flush fifos... + ifx_ssc_abort(info); + + info->port_is_open --; + MOD_DEC_USE_COUNT; + + return 0; +} /* ifx_ssc_close */ +EXPORT_SYMBOL(ifx_ssc_close); + +/* added by bingtao */ +/* helper routine to handle reads from the kernel or user-space */ +/* info->rxbuf : never kfree and contains valid data */ +/* should be points to NULL after copying data !!! */ +static ssize_t +ifx_ssc_read_helper_poll(struct ifx_ssc_port *info, char *buf, size_t len, + int from_kernel) +{ + ssize_t ret_val; + unsigned long flags; + + if (info->opts.modeRxTx == IFX_SSC_MODE_TX) + return -EFAULT; + local_irq_save(flags); + info->rxbuf_ptr = info->rxbuf; + info->rxbuf_end = info->rxbuf + len; + local_irq_restore(flags); +/* Vinetic driver always works in IFX_SSC_MODE_RXTX */ +/* TXRX in poll mode */ + while (info->rxbuf_ptr < info->rxbuf_end){ +/* This is the key point, if you don't check this condition + kfree (NULL) will happen + because tx only need write into FIFO, it's much fast than rx + So when rx still waiting , tx already finish and release buf +*/ + if (info->txbuf_ptr < info->txbuf_end) { + tx_int(info); + } + + rx_int(info); + }; + + ret_val = info->rxbuf_ptr - info->rxbuf; + return (ret_val); +} // ifx_ssc_read_helper_poll + +/* helper routine to handle reads from the kernel or user-space */ +/* info->rx_buf : never kfree and contains valid data */ +/* should be points to NULL after copying data !!! */ +static ssize_t +ifx_ssc_read_helper(struct ifx_ssc_port *info, char *buf, size_t len, + int from_kernel) +{ + ssize_t ret_val; + unsigned long flags; + DECLARE_WAITQUEUE(wait, current); + + if (info->opts.modeRxTx == IFX_SSC_MODE_TX) + return -EFAULT; + local_irq_save(flags); + info->rxbuf_ptr = info->rxbuf; + info->rxbuf_end = info->rxbuf + len; + if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) { + if ((info->txbuf == NULL) || + (info->txbuf != info->txbuf_ptr) || + (info->txbuf_end != len + info->txbuf)) { + local_irq_restore(flags); + printk("IFX SSC - %s: write must be called before calling " + "read in combined RX/TX!\n", __FUNCTION__); + return -EFAULT; + } + local_irq_restore(flags); + /* should enable tx, right?*/ + tx_int(info); + if (info->txbuf_ptr < info->txbuf_end){ + ifx_int_wrapper.enable(info->txirq); + } + + ifx_int_wrapper.enable(info->rxirq); + } else { // rx mode + local_irq_restore(flags); + if (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) & + IFX_SSC_RXCNT_TODO_MASK) + return -EBUSY; + ifx_int_wrapper.enable(info->rxirq); + // rx request limited to ' bytes +/* + if (len < 65536) +*/ + if (len < IFX_SSC_RXREQ_BLOCK_SIZE) + WRITE_PERIPHERAL_REGISTER(len << IFX_SSC_RXREQ_RXCOUNT_OFFSET, + info->mapbase + IFX_SSC_RXREQ); + else + WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, + info->mapbase + IFX_SSC_RXREQ); + } + + __add_wait_queue(&info->rwait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + // wakeup done in rx_int + + do { + local_irq_save(flags); + if (info->rxbuf_ptr >= info->rxbuf_end) + break; + local_irq_restore(flags); + +// if (filp->f_flags & O_NONBLOCK) +// { +// N = -EAGAIN; +// goto out; +// } + if (signal_pending(current)) { + ret_val = -ERESTARTSYS; + goto out; + } + schedule(); + } while (1); + + ret_val = info->rxbuf_ptr - info->rxbuf; // should be equal to len + local_irq_restore(flags); + + out: + current->state = TASK_RUNNING; + __remove_wait_queue(&info->rwait, &wait); + return (ret_val); +} // ifx_ssc_read_helper + + +#if 0 +/* helper routine to handle reads from the kernel or user-space */ +/* appropriate in interrupt context */ +static ssize_t +ifx_ssc_read_helper(struct ifx_ssc_port *info, char *buf, size_t len, + int from_kernel) +{ + ssize_t ret_val; + unsigned long flags; + DECLARE_WAITQUEUE(wait, current); + + if (info->opts.modeRxTx == IFX_SSC_MODE_TX) + return -EFAULT; + local_irq_save(flags); + info->rxbuf_ptr = info->rxbuf; + info->rxbuf_end = info->rxbuf + len; + if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) { + if ((info->txbuf == NULL) || + (info->txbuf != info->txbuf_ptr) || + (info->txbuf_end != len + info->txbuf)) { + local_irq_restore(flags); + printk("IFX SSC - %s: write must be called before calling " + "read in combined RX/TX!\n", __FUNCTION__); + return -EFAULT; + } + local_irq_restore(flags); + /* should enable tx, right?*/ + tx_int(info); + if (!in_irq()){ + if (info->txbuf_ptr < info->txbuf_end){ + ifx_int_wrapper.enable(info->txirq); + } + ifx_int_wrapper.enable(info->rxirq); + } + } else { // rx mode + local_irq_restore(flags); + if (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) & + IFX_SSC_RXCNT_TODO_MASK) + return -EBUSY; + if (!in_irq()){ + ifx_int_wrapper.enable(info->rxirq); + } + + if (len < IFX_SSC_RXREQ_BLOCK_SIZE) + WRITE_PERIPHERAL_REGISTER(len << IFX_SSC_RXREQ_RXCOUNT_OFFSET, + info->mapbase + IFX_SSC_RXREQ); + else + WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, + info->mapbase + IFX_SSC_RXREQ); + } + if (in_irq()){ + do { + rx_int(info); + if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) { + tx_int(info); + } + + if (info->rxbuf_ptr >= info->rxbuf_end) + break; + } while (1); + ret_val = info->rxbuf_ptr - info->rxbuf; + }else{ + __add_wait_queue(&info->rwait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + // wakeup done in rx_int + + do { + local_irq_save(flags); + if (info->rxbuf_ptr >= info->rxbuf_end) + break; + local_irq_restore(flags); + + if (signal_pending(current)) { + ret_val = -ERESTARTSYS; + goto out; + } + schedule(); + } while (1); + + ret_val = info->rxbuf_ptr - info->rxbuf; // should be equal to len + local_irq_restore(flags); + + out: + current->state = TASK_RUNNING; + __remove_wait_queue(&info->rwait, &wait); + } + return (ret_val); +} // ifx_ssc_read_helper +#endif + +/* helper routine to handle writes to the kernel or user-space */ +/* info->txbuf has two cases: + * 1) return value < 0 (-EFAULT), not touched at all + * 2) kfree and points to NULL in interrupt routine (but maybe later ) + */ +static ssize_t +ifx_ssc_write_helper(struct ifx_ssc_port *info, const char *buf, + size_t len, int from_kernel) +{ + // check if in tx or tx/rx mode + if (info->opts.modeRxTx == IFX_SSC_MODE_RX) + return -EFAULT; + + info->txbuf_ptr = info->txbuf; + info->txbuf_end = len + info->txbuf; + /* start the transmission (not in rx/tx, see read helper) */ + if (info->opts.modeRxTx == IFX_SSC_MODE_TX) { + tx_int(info); + if (info->txbuf_ptr < info->txbuf_end){ + ifx_int_wrapper.enable(info->txirq); + } + } + //local_irq_restore(flags); + return len; +} + +/* + * kernel interfaces for read and write. + * The caller must set port to: n for SSC with n=m-1 (e.g. n=0 for SSC1) + */ +ssize_t +ifx_ssc_kread(int port, char *kbuf, size_t len) +{ + struct ifx_ssc_port *info; + ssize_t ret_val; + + if (port < 0 || port >= PORT_CNT) + return -ENXIO; + + if (len == 0) + return 0; + + info = &isp[port]; + + // check if reception in progress + if (info->rxbuf != NULL){ + printk("SSC device busy\n"); + return -EBUSY; + } + + info->rxbuf = kbuf; + if (info->rxbuf == NULL){ + printk("SSC device error\n"); + return -EINVAL; + } + +/* changed by bingtao */ + /* change by TaiCheng */ + //if (!in_irq()){ + if (0){ + ret_val = ifx_ssc_read_helper(info, kbuf, len, 1); + }else{ + ret_val = ifx_ssc_read_helper_poll(info, kbuf, len, 1); + }; + info->rxbuf = NULL; + + // ### TO DO: perhaps warn if ret_val != len + ifx_int_wrapper.disable(info->rxirq); + + return (ret_val); +} // ifx_ssc_kread +EXPORT_SYMBOL(ifx_ssc_kread); + +ssize_t +ifx_ssc_kwrite(int port, const char *kbuf, size_t len) +{ + struct ifx_ssc_port *info; + ssize_t ret_val; + + if (port < 0 || port >= PORT_CNT) + return -ENXIO; + + if (len == 0) + return 0; + + info = &isp[port]; + + // check if transmission in progress + if (info->txbuf != NULL) + return -EBUSY; + info->txbuf = (char *)kbuf; + + ret_val = ifx_ssc_write_helper(info, info->txbuf, len, 1); + if (ret_val < 0){ + info->txbuf = NULL; + } + return ret_val; +} +EXPORT_SYMBOL(ifx_ssc_kwrite); + + +/* + * user interfaces to read and write + */ +static ssize_t +ifx_ssc_read(struct file *filp, char *ubuf, size_t len, loff_t *off) +{ + ssize_t ret_val; + int idx; + struct ifx_ssc_port *info; + +/* + if (len == 0) + return (0); +*/ + idx = MINOR(filp->f_dentry->d_inode->i_rdev); + info = &isp[idx]; + + // check if reception in progress + if (info->rxbuf != NULL) + return -EBUSY; + + info->rxbuf = kmalloc(len+ 3, GFP_KERNEL); + if (info->rxbuf == NULL) + return -ENOMEM; + + ret_val = ifx_ssc_read_helper(info, info->rxbuf, len, 0); + // ### TO DO: perhaps warn if ret_val != len + if (copy_to_user((void*)ubuf, info->rxbuf, ret_val) != 0) + ret_val = -EFAULT; + + ifx_int_wrapper.disable(info->rxirq); + + kfree(info->rxbuf); + info->rxbuf = NULL; + return (ret_val); +} // ifx_ssc_read + +/* + * As many bytes as we have free space for are copied from the user + * into txbuf and the actual byte count is returned. The transmission is + * always kicked off by calling the appropriate TX routine. + */ +static ssize_t +ifx_ssc_write(struct file *filp, const char *ubuf, size_t len, loff_t *off) +{ + int idx; + struct ifx_ssc_port *info; + int ret_val; + + if (len == 0) + return (0); + + idx = MINOR(filp->f_dentry->d_inode->i_rdev); + info = &isp[idx]; + + // check if transmission in progress + if (info->txbuf != NULL) + return -EBUSY; + + info->txbuf = kmalloc(len+ 3, GFP_KERNEL); + if (info->txbuf == NULL) + return -ENOMEM; + + ret_val = copy_from_user(info->txbuf, ubuf, len); + if (ret_val == 0) + ret_val = ifx_ssc_write_helper(info, info->txbuf, len, 0); + else + ret_val = -EFAULT; + if (ret_val < 0) { + kfree(info->txbuf); // otherwise will be done in ISR + info->txbuf = NULL; + } + return (ret_val); +} /* ifx_ssc_write */ + + +/* + * ------------------------------------------------------------ + * ifx_ssc_ioctl() and friends + * ------------------------------------------------------------ + */ + +/*----------------------------------------------------------------------------- + FUNC-NAME : ifx_ssc_frm_status_get + LONG-NAME : framing status get + PURPOSE : Get the actual status of the framing. + + PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. + + RESULT : pointer to a structure ifx_ssc_frm_status which holds busy and + count values. + + REMARKS : Returns a register value independent of framing is enabled or + not! Changes structure inside of info, so the return value isn't + needed at all, but could be used for simple access. +-----------------------------------------------------------------------------*/ +static struct ifx_ssc_frm_status * +ifx_ssc_frm_status_get(struct ifx_ssc_port *info) +{ + unsigned long tmp; + + tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFSTAT); + info->frm_status.DataBusy = (tmp & IFX_SSC_SFSTAT_IN_DATA) > 0; + info->frm_status.PauseBusy = (tmp & IFX_SSC_SFSTAT_IN_PAUSE) > 0; + info->frm_status.DataCount = (tmp & IFX_SSC_SFSTAT_DATA_COUNT_MASK) + >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET; + info->frm_status.PauseCount = (tmp & IFX_SSC_SFSTAT_PAUSE_COUNT_MASK) + >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET; + tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON); + info->frm_status.EnIntAfterData = + (tmp & IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE) > 0; + info->frm_status.EnIntAfterPause = + (tmp & IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE) > 0; + return (&info->frm_status); +} // ifx_ssc_frm_status_get + + +/*----------------------------------------------------------------------------- + FUNC-NAME : ifx_ssc_frm_control_get + LONG-NAME : framing control get + PURPOSE : Get the actual control values of the framing. + + PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. + + RESULT : pointer to a structure ifx_ssc_frm_opts which holds control bits + and count reload values. + + REMARKS : Changes structure inside of info, so the return value isn't + needed at all, but could be used for simple access. +-----------------------------------------------------------------------------*/ +static struct ifx_ssc_frm_opts * +ifx_ssc_frm_control_get(struct ifx_ssc_port *info) +{ + unsigned long tmp; + + tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON); + info->frm_opts.FrameEnable = (tmp & IFX_SSC_SFCON_SF_ENABLE) > 0; + info->frm_opts.DataLength = (tmp & IFX_SSC_SFCON_DATA_LENGTH_MASK) + >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET; + info->frm_opts.PauseLength = (tmp & IFX_SSC_SFCON_PAUSE_LENGTH_MASK) + >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET; + info->frm_opts.IdleData = (tmp & IFX_SSC_SFCON_PAUSE_DATA_MASK) + >> IFX_SSC_SFCON_PAUSE_DATA_OFFSET; + info->frm_opts.IdleClock = (tmp & IFX_SSC_SFCON_PAUSE_CLOCK_MASK) + >> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET; + info->frm_opts.StopAfterPause = + (tmp & IFX_SSC_SFCON_STOP_AFTER_PAUSE) > 0; + return (&info->frm_opts); +} // ifx_ssc_frm_control_get + + +/*----------------------------------------------------------------------------- + FUNC-NAME : ifx_ssc_frm_control_set + LONG-NAME : framing control set + PURPOSE : Set the actual control values of the framing. + + PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. + + RESULT : pointer to a structure ifx_ssc_frm_opts which holds control bits + and count reload values. + + REMARKS : +-----------------------------------------------------------------------------*/ +static int +ifx_ssc_frm_control_set(struct ifx_ssc_port *info) +{ + unsigned long tmp; + + // check parameters + if ((info->frm_opts.DataLength > IFX_SSC_SFCON_DATA_LENGTH_MAX) || + (info->frm_opts.DataLength < 1) || + (info->frm_opts.PauseLength > IFX_SSC_SFCON_PAUSE_LENGTH_MAX) || + (info->frm_opts.PauseLength < 1) || + ((info->frm_opts.IdleData & ~(IFX_SSC_SFCON_PAUSE_DATA_MASK >> + IFX_SSC_SFCON_PAUSE_DATA_OFFSET)) != 0 ) || + ((info->frm_opts.IdleClock & ~(IFX_SSC_SFCON_PAUSE_CLOCK_MASK >> + IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET)) != 0 )) + return -EINVAL; + + // read interrupt bits (they're not changed here) + tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON) & + (IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE | + IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE); + + // set all values with respect to it's bit position (for data and pause + // length set N-1) + tmp = (info->frm_opts.DataLength - 1) << IFX_SSC_SFCON_DATA_LENGTH_OFFSET; + tmp |= (info->frm_opts.PauseLength - 1) << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET; + tmp |= info->frm_opts.IdleData << IFX_SSC_SFCON_PAUSE_DATA_OFFSET; + tmp |= info->frm_opts.IdleClock << IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET; + tmp |= info->frm_opts.FrameEnable * IFX_SSC_SFCON_SF_ENABLE; + tmp |= info->frm_opts.StopAfterPause * IFX_SSC_SFCON_STOP_AFTER_PAUSE; + + WRITE_PERIPHERAL_REGISTER(tmp, info->mapbase + IFX_SSC_SFCON); + + return 0; +} // ifx_ssc_frm_control_set + + +/*----------------------------------------------------------------------------- + FUNC-NAME : ifx_ssc_rxtx_mode_set + LONG-NAME : rxtx mode set + PURPOSE : Set the transmission mode. + + PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. + + RESULT : Returns error code + + REMARKS : Assumes that SSC not used (SSC disabled, device not opened yet + or just closed) +-----------------------------------------------------------------------------*/ +static int +ifx_ssc_rxtx_mode_set(struct ifx_ssc_port *info, unsigned int val) +{ + unsigned long tmp; + + // check parameters + if (!(info) || (val & ~(IFX_SSC_MODE_MASK))) + return -EINVAL; + /*check BUSY and RXCNT*/ + if ( READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & IFX_SSC_STATE_BUSY + ||READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) & IFX_SSC_RXCNT_TODO_MASK) + return -EBUSY; + // modify + tmp = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CON) & + ~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF)) | (val); + WRITE_PERIPHERAL_REGISTER(tmp, info->mapbase + IFX_SSC_CON); + info->opts.modeRxTx = val; +/* + printk(KERN_DEBUG "IFX SSC%d: Setting mode to %s%s\n", + info->port_nr, + ((val & IFX_SSC_CON_RX_OFF) == 0) ? "rx ":"", + ((val & IFX_SSC_CON_TX_OFF) == 0) ? "tx":""); +*/ + return 0; +} // ifx_ssc_rxtx_mode_set + +void ifx_gpio_init(void) +{ + u32 temp; +/* set gpio pin p0.10(SPI_DIN) p0.11(SPI_DOUT) p0.12(SPI_CLK) p0.13(SPI_CS2) direction */ + temp = *(AMAZON_GPIO_P0_DIR) ; + temp &= 0xFFFFFBFF; + temp |= 0x3800; + *(AMAZON_GPIO_P0_DIR) = temp; +/* set port 0 alternate select register 0 */ + temp = *(AMAZON_GPIO_P0_ALTSEL0) ; + temp &= 0xFFFFC3FF; + temp |= 0x00001c00; + *(AMAZON_GPIO_P0_ALTSEL0) = temp; + +/* set port 0 alternate select register 1 */ + temp = *(AMAZON_GPIO_P0_ALTSEL1) ; + temp &= 0xFFFFC3FF; + temp |= 0x00002000; + *(AMAZON_GPIO_P0_ALTSEL1) = temp; + +/* set port 0 open drain mode register */ + temp = *(AMAZON_GPIO_P0_OD); + temp |= 0x00003800; /* set output pin normal mode */ + *(AMAZON_GPIO_P0_OD)= temp; +} + +/* + * This routine intializes the SSC appropriately depending + * on slave/master and full-/half-duplex mode. + * It assumes that the SSC is disabled and the fifo's and buffers + * are flushes later on. + */ +static int +ifx_ssc_sethwopts(struct ifx_ssc_port *info) +{ + unsigned long flags, bits; + struct ifx_ssc_hwopts *opts = &info->opts; + + /* sanity checks */ + if ((opts->dataWidth < IFX_SSC_MIN_DATA_WIDTH) || + (opts->dataWidth > IFX_SSC_MAX_DATA_WIDTH)) { + printk("%s: sanity check failed\n", __FUNCTION__); + return -EINVAL; + } + bits = (opts->dataWidth - 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET; + bits |= IFX_SSC_CON_ENABLE_BYTE_VALID; +// if (opts->abortErrDetect) +// bits |= IFX_SSC_CON_ABORT_ERR_CHECK; + if (opts->rxOvErrDetect) + bits |= IFX_SSC_CON_RX_OFL_CHECK; + if (opts->rxUndErrDetect) + bits |= IFX_SSC_CON_RX_UFL_CHECK; + if (opts->txOvErrDetect) + bits |= IFX_SSC_CON_TX_OFL_CHECK; + if (opts->txUndErrDetect) + bits |= IFX_SSC_CON_TX_UFL_CHECK; + if (opts->loopBack) + bits |= IFX_SSC_CON_LOOPBACK_MODE; + if (opts->echoMode) + bits |= IFX_SSC_CON_ECHO_MODE_ON; + if (opts->headingControl) + bits |= IFX_SSC_CON_MSB_FIRST; + if (opts->clockPhase) + bits |= IFX_SSC_CON_LATCH_THEN_SHIFT; + if (opts->clockPolarity) + bits |= IFX_SSC_CON_CLOCK_FALL; + switch (opts->modeRxTx) { + case IFX_SSC_MODE_TX: + bits |= IFX_SSC_CON_RX_OFF; + break; + case IFX_SSC_MODE_RX: + bits |= IFX_SSC_CON_TX_OFF; + break; + } // switch (opts->modeRxT) + local_irq_save(flags); + WRITE_PERIPHERAL_REGISTER(bits, info->mapbase + IFX_SSC_CON); + WRITE_PERIPHERAL_REGISTER((info->opts.gpoCs << IFX_SSC_GPOCON_ISCSB0_POS) | + (info->opts.gpoInv << IFX_SSC_GPOCON_INVOUT0_POS), + info->mapbase + IFX_SSC_GPOCON); + //master mode + if (opts->masterSelect){ + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_MASTER_SELECT,info->mapbase + IFX_SSC_WHBSTATE); + }else{ + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_MASTER_SELECT,info->mapbase + IFX_SSC_WHBSTATE); + } + // init serial framing + WRITE_PERIPHERAL_REGISTER(0, info->mapbase + IFX_SSC_SFCON); + /* set up the port pins */ + //check for general requirements to switch (external) pad/pin characteristics + ifx_gpio_init(); + local_irq_restore(flags); + + return 0; +} // ifx_ssc_sethwopts + +static int +ifx_ssc_set_baud(struct ifx_ssc_port *info, unsigned int baud) +{ + unsigned int ifx_ssc_clock; + unsigned int br; + unsigned long flags; + bool enabled; + + ifx_ssc_clock = ifx_ssc_get_kernel_clk(info); + if (ifx_ssc_clock ==0) + return -EINVAL; + + local_irq_save(flags); + /* have to disable the SSC to set the baudrate */ + enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) + & IFX_SSC_STATE_IS_ENABLED) != 0; + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + + // compute divider + br = ((ifx_ssc_clock >> 1)/baud) - 1; + asm("SYNC"); + if (br > 0xffff || + ((br == 0) && + ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & + IFX_SSC_STATE_IS_MASTER) == 0))){ + local_irq_restore(flags); + printk("%s: illegal baudrate %u\n", __FUNCTION__, baud); + return -EINVAL; + } + WRITE_PERIPHERAL_REGISTER(br, info->mapbase + IFX_SSC_BR); + if (enabled) + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + + local_irq_restore(flags); + return 0; +} // ifx_ssc_set_baud + +static int +ifx_ssc_hwinit(struct ifx_ssc_port *info) +{ + unsigned long flags; + bool enabled; + + /* have to disable the SSC */ + enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) + & IFX_SSC_STATE_IS_ENABLED) != 0; + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + + if (ifx_ssc_sethwopts(info) < 0) + { + printk("%s: setting the hardware options failed\n", + __FUNCTION__); + return -EINVAL; + } + + if (ifx_ssc_set_baud(info, info->baud) < 0) { + printk("%s: setting the baud rate failed\n", __FUNCTION__); + return -EINVAL; + } + local_irq_save(flags); + /* TX FIFO */ + WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_TXFIFO_FL << + IFX_SSC_XFCON_ITL_OFFSET) | + IFX_SSC_XFCON_FIFO_ENABLE, + info->mapbase + IFX_SSC_TXFCON); + /* RX FIFO */ + WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_RXFIFO_FL << + IFX_SSC_XFCON_ITL_OFFSET) | + IFX_SSC_XFCON_FIFO_ENABLE, + info->mapbase + IFX_SSC_RXFCON); + local_irq_restore(flags); + if (enabled) + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + return 0; +} // ifx_ssc_hwinit + +/*----------------------------------------------------------------------------- + FUNC-NAME : ifx_ssc_batch_exec + LONG-NAME : + PURPOSE : + + PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. + + RESULT : Returns error code + + REMARKS : +-----------------------------------------------------------------------------*/ +static int +ifx_ssc_batch_exec(struct ifx_ssc_port *info, struct ifx_ssc_batch_list *batch_anchor) +{ + // ### TO DO: implement user space batch execution + // first, copy the whole linked list from user to kernel space + // save some hardware options + // execute list + // restore hardware options if selected + return -EFAULT; +} // ifx_ssc_batch_exec + + +/* + * This routine allows the driver to implement device- + * specific ioctl's. If the ioctl number passed in cmd is + * not recognized by the driver, it should return ENOIOCTLCMD. + */ +int +ifx_ssc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long data) +{ + struct ifx_ssc_port *info; + int line, ret_val = 0; + unsigned long flags; + unsigned long tmp; + int from_kernel = 0; + + if ((inode == (struct inode *)0) || (inode == (struct inode *)1)) + { + from_kernel = 1; + line = (int)inode; + } + else + line = MINOR(filp->f_dentry->d_inode->i_rdev); + + /* don't use more minor devices than we can support */ + if (line < 0 || line >= PORT_CNT) + return -ENXIO; + + info = &isp[line]; + + switch (cmd) { + case IFX_SSC_STATS_READ: + /* data must be a pointer to a struct ifx_ssc_statistics */ + if (from_kernel) + memcpy((void *)data, (void *)&info->stats, + sizeof(struct ifx_ssc_statistics)); + else + if (copy_to_user((void *)data, + (void *)&info->stats, + sizeof(struct ifx_ssc_statistics))) + ret_val = -EFAULT; + break; + case IFX_SSC_STATS_RESET: + /* just resets the statistics counters */ + memset((void *)&info->stats, 0, sizeof(struct ifx_ssc_statistics)); + break; + case IFX_SSC_BAUD_SET: + /* if the buffers are not empty then the port is */ + /* busy and we shouldn't change things on-the-fly! */ + if (!info->txbuf || !info->rxbuf || + (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) + & IFX_SSC_STATE_BUSY)) { + ret_val = -EBUSY; + break; + } + /* misuse flags */ + if (from_kernel) + flags = *((unsigned long *)data); + else + if (copy_from_user((void *)&flags, + (void *)data, sizeof(flags))) + { + ret_val = -EFAULT; + break; + } + if (flags == 0) + { + ret_val = -EINVAL; + break; + } + if (ifx_ssc_set_baud(info, flags) < 0) + { + ret_val = -EINVAL; + break; + } + info->baud = flags; + break; + case IFX_SSC_BAUD_GET: + if (from_kernel) + *((unsigned int *)data) = info->baud; + else + if (copy_to_user((void *)data, + (void *)&info->baud, + sizeof(unsigned long))) + ret_val = -EFAULT; + break; + case IFX_SSC_RXTX_MODE_SET: + if (from_kernel) + tmp = *((unsigned long *)data); + else + if (copy_from_user((void *)&tmp, + (void *)data, sizeof(tmp))) { + ret_val = -EFAULT; + break; + } + ret_val = ifx_ssc_rxtx_mode_set(info, tmp); + break; + case IFX_SSC_RXTX_MODE_GET: + tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CON) & + (~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF)); + if (from_kernel) + *((unsigned int *)data) = tmp; + else + if (copy_to_user((void *)data, + (void *)&tmp, + sizeof(tmp))) + ret_val = -EFAULT; + break; + + case IFX_SSC_ABORT: + ifx_ssc_abort(info); + break; + + case IFX_SSC_GPO_OUT_SET: + if (from_kernel) + tmp = *((unsigned long *)data); + else + if (copy_from_user((void *)&tmp, + (void *)data, sizeof(tmp))) { + ret_val = -EFAULT; + break; + } + if (tmp > IFX_SSC_MAX_GPO_OUT) + ret_val = -EINVAL; + else + WRITE_PERIPHERAL_REGISTER + (1<<(tmp + IFX_SSC_WHBGPOSTAT_SETOUT0_POS), + info->mapbase + IFX_SSC_WHBGPOSTAT); + break; + case IFX_SSC_GPO_OUT_CLR: + if (from_kernel) + tmp = *((unsigned long *)data); + else + if (copy_from_user((void *)&tmp, + (void *)data, sizeof(tmp))) { + ret_val = -EFAULT; + break; + } + if (tmp > IFX_SSC_MAX_GPO_OUT) + ret_val = -EINVAL; + else { + WRITE_PERIPHERAL_REGISTER + (1<<(tmp + IFX_SSC_WHBGPOSTAT_CLROUT0_POS), + info->mapbase + IFX_SSC_WHBGPOSTAT); + } + break; + case IFX_SSC_GPO_OUT_GET: + tmp = READ_PERIPHERAL_REGISTER + (info->mapbase + IFX_SSC_GPOSTAT); + if (from_kernel) + *((unsigned int *)data) = tmp; + else + if (copy_to_user((void *)data, + (void *)&tmp, + sizeof(tmp))) + ret_val = -EFAULT; + break; + case IFX_SSC_FRM_STATUS_GET: + ifx_ssc_frm_status_get(info); + if (from_kernel) + memcpy((void *)data, (void *)&info->frm_status, + sizeof(struct ifx_ssc_frm_status)); + else + if (copy_to_user((void *)data, + (void *)&info->frm_status, + sizeof(struct ifx_ssc_frm_status))) + ret_val = -EFAULT; + break; + case IFX_SSC_FRM_CONTROL_GET: + ifx_ssc_frm_control_get(info); + if (from_kernel) + memcpy((void *)data, (void *)&info->frm_opts, + sizeof(struct ifx_ssc_frm_opts)); + else + if (copy_to_user((void *)data, + (void *)&info->frm_opts, + sizeof(struct ifx_ssc_frm_opts))) + ret_val = -EFAULT; + break; + case IFX_SSC_FRM_CONTROL_SET: + if (from_kernel) + memcpy((void *)&info->frm_opts, (void *)data, + sizeof(struct ifx_ssc_frm_opts)); + else + if (copy_to_user((void *)&info->frm_opts, + (void *)data, + sizeof(struct ifx_ssc_frm_opts))){ + ret_val = -EFAULT; + break; + } + ret_val = ifx_ssc_frm_control_set(info); + break; + case IFX_SSC_HWOPTS_SET: + /* data must be a pointer to a struct ifx_ssc_hwopts */ + /* if the buffers are not empty then the port is */ + /* busy and we shouldn't change things on-the-fly! */ + if (!info->txbuf || !info->rxbuf || + (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) + & IFX_SSC_STATE_BUSY)) { + ret_val = -EBUSY; + break; + } + if (from_kernel) + memcpy((void *)&info->opts, (void *)data, + sizeof(struct ifx_ssc_hwopts)); + else + if (copy_from_user((void *)&info->opts, + (void *)data, + sizeof(struct ifx_ssc_hwopts))) + { + ret_val = -EFAULT; + break; + } + if (ifx_ssc_hwinit(info) < 0) + { + ret_val = -EIO; + } + break; + case IFX_SSC_HWOPTS_GET: + /* data must be a pointer to a struct ifx_ssc_hwopts */ + if (from_kernel) + memcpy((void *)data, (void *)&info->opts, + sizeof(struct ifx_ssc_hwopts)); + else + if (copy_to_user((void *)data, + (void *)&info->opts, + sizeof(struct ifx_ssc_hwopts))) + ret_val = -EFAULT; + break; + default: + ret_val = -ENOIOCTLCMD; + } + + return ret_val; +} /* ifx_ssc_ioctl */ +EXPORT_SYMBOL(ifx_ssc_ioctl); + +///* the poll routine */ +//static unsigned int +//ifx_ssc_poll(struct file *filp, struct poll_table_struct *pts) +//{ +// int unit = MINOR(filp->f_dentry->d_inode->i_rdev); +// struct ifx_ssc_port *info; +// unsigned int mask = 0; +// int spc; +// +// info = &isp[unit]; +// +// /* add event to the wait queues */ +// /* DO NOT FORGET TO DO A WAKEUP ON THESE !!!! */ +// poll_wait(filp, &info->pwait, pts); +// +// /* are there bytes in the RX SW-FIFO? */ +// if (info->rxrp != info->rxwp) +// mask |= POLLIN | POLLRDNORM; +// +// /* free space in the TX SW-FIFO */ +// spc = info->txrp - info->txwp - 1; +// if (spc < 0) +// spc += TX_BUFSIZE; +//#ifdef IFX_SSC_USEDMA +// /* writing always works, except in the DMA case when all descriptors */ +// /* are used up */ +// if (unit == 1 && info->dma_freecnt == 0) +// spc = 0; +//#endif +// if (spc > 0) +// mask |= POLLOUT | POLLWRNORM; +// +// return (mask); +//} + +static int +ifx_ssc1_read_proc(char *page, char **start, off_t offset, int count, int *eof, void *data) +{ + int off = 0; + unsigned long flags; + + /* don't want any interrupts here */ + save_flags(flags); + cli(); + + + /* print statistics */ + off += sprintf(page+off, "Statistics for Infineon Synchronous Serial Controller SSC1\n"); + off += sprintf(page+off, "RX overflow errors %d\n", isp[0].stats.rxOvErr); + off += sprintf(page+off, "RX underflow errors %d\n", isp[0].stats.rxUnErr); + off += sprintf(page+off, "TX overflow errors %d\n", isp[0].stats.txOvErr); + off += sprintf(page+off, "TX underflow errors %d\n", isp[0].stats.txUnErr); + off += sprintf(page+off, "Abort errors %d\n", isp[0].stats.abortErr); + off += sprintf(page+off, "Mode errors %d\n", isp[0].stats.modeErr); + off += sprintf(page+off, "RX Bytes %d\n", isp[0].stats.rxBytes); + off += sprintf(page+off, "TX Bytes %d\n", isp[0].stats.txBytes); + + restore_flags (flags); /* XXXXX */ + *eof = 1; + return (off); +} + + +/* + * This routine prints out the appropriate serial driver version number + */ +static inline void +show_version(void) +{ +#if 0 + printk("Infineon Technologies Synchronous Serial Controller (SSC) driver\n" + " version %s - built %s %s\n", IFX_SSC_DRV_VERSION, __DATE__, __TIME__); +#endif +} /* show_version */ + + +/* + * Due to the fact that a port can be dynamically switched between slave + * and master mode using an IOCTL the hardware is not initialized here, + * but in ifx_ssc_hwinit() as a result of an IOCTL. + */ +int __init +ifx_ssc_init(void) +{ + struct ifx_ssc_port *info; + int i, nbytes; + unsigned long flags; + int ret_val; + + // ### TO DO: dynamic port count evaluation due to pin multiplexing + + ret_val = -ENOMEM; + nbytes = PORT_CNT * sizeof(struct ifx_ssc_port); + isp = (struct ifx_ssc_port *)kmalloc(nbytes, GFP_KERNEL); + if (isp == NULL) + { + printk("%s: no memory for isp\n", __FUNCTION__); + return (ret_val); + } + memset(isp, 0, nbytes); + + show_version(); + + /* register the device */ + ret_val = -ENXIO; +/* + i = maj; +*/ + if ((i = register_chrdev(maj, "ssc", &ifx_ssc_fops)) < 0) + { + printk("Unable to register major %d for the Infineon SSC\n", maj); + if (maj == 0){ + goto errout; + } + else{ + maj = 0; + if ((i = register_chrdev(maj, "ssc", &ifx_ssc_fops)) < 0) + { + printk("Unable to register major %d for the Infineon SSC\n", maj); + goto errout; + } + } + } + if (maj == 0) maj = i; + //printk("registered major %d for Infineon SSC\n", maj); + + /* set default values in ifx_ssc_port */ + for (i = 0; i < PORT_CNT; i++) { + info = &isp[i]; + info->port_nr = i; + /* default values for the HwOpts */ + info->opts.AbortErrDetect = IFX_SSC_DEF_ABRT_ERR_DETECT; + info->opts.rxOvErrDetect = IFX_SSC_DEF_RO_ERR_DETECT; + info->opts.rxUndErrDetect = IFX_SSC_DEF_RU_ERR_DETECT; + info->opts.txOvErrDetect = IFX_SSC_DEF_TO_ERR_DETECT; + info->opts.txUndErrDetect = IFX_SSC_DEF_TU_ERR_DETECT; + info->opts.loopBack = IFX_SSC_DEF_LOOP_BACK; + info->opts.echoMode = IFX_SSC_DEF_ECHO_MODE; + info->opts.idleValue = IFX_SSC_DEF_IDLE_DATA; + info->opts.clockPolarity = IFX_SSC_DEF_CLOCK_POLARITY; + info->opts.clockPhase = IFX_SSC_DEF_CLOCK_PHASE; + info->opts.headingControl = IFX_SSC_DEF_HEADING_CONTROL; + info->opts.dataWidth = IFX_SSC_DEF_DATA_WIDTH; + info->opts.modeRxTx = IFX_SSC_DEF_MODE_RXTX; + info->opts.gpoCs = IFX_SSC_DEF_GPO_CS; + info->opts.gpoInv = IFX_SSC_DEF_GPO_INV; + info->opts.masterSelect = IFX_SSC_DEF_MASTERSLAVE; + info->baud = IFX_SSC_DEF_BAUDRATE; + info->rxbuf = NULL; + info->txbuf = NULL; + /* values specific to SSC1 */ + if (i == 0) { + info->mapbase = AMAZON_SSC_BASE_ADD_0; + // ### TO DO: power management + + // setting interrupt vectors + info->txirq = IFX_SSC_TIR; + info->rxirq = IFX_SSC_RIR; + info->errirq = IFX_SSC_EIR; +/* + info->frmirq = IFX_SSC_FIR; +*/ + } + /* activate SSC */ + /* CLC.DISS = 0 */ + WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_RMC << IFX_CLC_RUN_DIVIDER_OFFSET, info->mapbase + IFX_SSC_CLC); + +// ### TO DO: multiple instances + + init_waitqueue_head(&info->rwait); + //init_waitqueue_head(&info->pwait); + + local_irq_save(flags); + + // init serial framing register + WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_SFCON, info->mapbase + IFX_SSC_SFCON); + + /* try to get the interrupts */ + // ### TO DO: interrupt handling with multiple instances + ret_val = ifx_int_wrapper.request(info->txirq, ifx_ssc_tx_int, + 0, "ifx_ssc_tx", info); + if (ret_val){ + printk("%s: unable to get irq %d\n", __FUNCTION__, + info->txirq); + local_irq_restore(flags); + goto errout; + } + ret_val = ifx_int_wrapper.request(info->rxirq, ifx_ssc_rx_int, + 0, "ifx_ssc_rx", info); + if (ret_val){ + printk("%s: unable to get irq %d\n", __FUNCTION__, + info->rxirq); + local_irq_restore(flags); + goto irqerr; + } + ret_val = ifx_int_wrapper.request(info->errirq, ifx_ssc_err_int, + 0, "ifx_ssc_err", info); + if (ret_val){ + printk("%s: unable to get irq %d\n", __FUNCTION__, + info->errirq); + local_irq_restore(flags); + goto irqerr; + } +/* + ret_val = ifx_int_wrapper.request(info->frmirq, ifx_ssc_frm_int, + 0, "ifx_ssc_frm", info); + if (ret_val){ + printk("%s: unable to get irq %d\n", __FUNCTION__, + info->frmirq); + local_irq_restore(flags); + goto irqerr; + } + +*/ + WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_IRNEN, info->mapbase + IFX_SSC_IRN_EN); + + local_irq_restore(flags); + } // for (i = 0; i < PORT_CNT; i++) + + /* init the SSCs with default values */ + for (i = 0; i < PORT_CNT; i++) + { + info = &isp[i]; + if (ifx_ssc_hwinit(info) < 0) + { + printk("%s: hardware init failed for port %d\n", + __FUNCTION__, i); + goto irqerr; + } + } + + /* register /proc read handler */ + // ### TO DO: multiple instances + /* for SSC1, which is always present */ + create_proc_read_entry("driver/ssc1", 0, NULL, ifx_ssc1_read_proc, NULL); + return 0; + +irqerr: + // ### TO DO: multiple instances + ifx_int_wrapper.free(isp[0].txirq,&isp[0]); + ifx_int_wrapper.free(isp[0].rxirq,&isp[0]); + ifx_int_wrapper.free(isp[0].errirq,&isp[0]); +/* + ifx_int_wrapper.free(isp[0].frmirq, &isp[0]); +*/ +errout: + /* free up any allocated memory in the error case */ + kfree(isp); + return (ret_val); +} /* ifx_ssc_init */ + + +void +ifx_ssc_cleanup_module(void) +{ + int i; + + /* free up any allocated memory */ + for (i = 0; i < PORT_CNT; i++) + { + /* disable the SSC */ + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE,isp[i].mapbase + IFX_SSC_WHBSTATE); + /* free the interrupts */ + ifx_int_wrapper.free(isp[i].txirq, &isp[i]); + ifx_int_wrapper.free(isp[i].rxirq, &isp[i]); + ifx_int_wrapper.free(isp[i].errirq, &isp[i]); +/* + ifx_int_wrapper.free(isp[i].frmirq, &isp[i]); + + if (isp[i].rxbuf != NULL) + kfree(isp[i].rxbuf); + if (isp[i].txbuf != NULL) + kfree(isp[i].txbuf); +*/ + } + kfree(isp); + /* unregister the device */ + if (unregister_chrdev(maj, "ssc")) + { + printk("Unable to unregister major %d for the SSC\n", maj); + } + /* delete /proc read handler */ + remove_proc_entry("driver/ssc1", NULL); + remove_proc_entry("driver/ssc2", NULL); +} /* ifx_ssc_cleanup_module */ + +module_exit(ifx_ssc_cleanup_module); + +/* Module entry-points */ +module_init(ifx_ssc_init); + +#ifndef MODULE +static int __init +ifx_ssc_set_maj(char *str) +{ + maj = simple_strtol(str, NULL, 0); + return 1; +} +__setup("ssc_maj=", ifx_ssc_set_maj); +#endif /* !MODULE */ + +#define AMAZON_SSC_EMSG(fmt,arg...) printk("%s: "fmt,__FUNCTION__, ##arg) +/* Brief: chip select enable + */ +inline int amazon_ssc_cs_low(u32 pin) +{ + int ret=0; + if ((ret=ifx_ssc_ioctl((struct inode *)0, NULL,IFX_SSC_GPO_OUT_CLR, (unsigned long)&pin))){ + AMAZON_SSC_EMSG("clear CS %d fails\n",pin); + } + wmb(); + return ret; +} +EXPORT_SYMBOL(amazon_ssc_cs_low); +/* Brief: chip select disable + */ +inline int amazon_ssc_cs_high(u32 pin) +{ + int ret=0; + if ((ret=ifx_ssc_ioctl((struct inode *)0, NULL,IFX_SSC_GPO_OUT_SET, (unsigned long)&pin))){ + AMAZON_SSC_EMSG("set CS %d fails\n", pin); + } + wmb(); + return ret; +} +EXPORT_SYMBOL(amazon_ssc_cs_high); +/* Brief: one SSC session + * Parameter: + * tx_buf + * tx_len + * rx_buf + * rx_len + * session_mode: IFX_SSC_MODE_RXTX or IFX_SSC_MODE_TX + * Return: >=0 number of bytes received (if rx_buf != 0) or transmitted + * <0 error code + * Description: + * 0. copy data to internal buffer + * 1. Write command + * 2a. If SSC_SESSION_MODE_TXONLY, read tx_len data + * 2b. If not Read back (tx_len + rx_len) data + * 3. copy internal buffer to rx buf if necessary + */ +static int ssc_session(char * tx_buf, u32 tx_len, char * rx_buf, u32 rx_len) +{ + int ret=0; + + char * ssc_tx_buf=NULL; + char * ssc_rx_buf=NULL; + +// volatile char ssc_tx_buf[128]={0}; +// volatile char ssc_rx_buf[128]={0}; + + int eff_size=0; + u8 mode=0; + + if (tx_buf == NULL && tx_len ==0 && rx_buf == NULL && rx_len == 0){ + AMAZON_SSC_EMSG("invalid parameters\n"); + ret=-EINVAL; + goto ssc_session_exit; + }else if (tx_buf == NULL || tx_len == 0){ + if (rx_buf != NULL && rx_len != 0){ + mode = IFX_SSC_MODE_RX; + }else{ + AMAZON_SSC_EMSG("invalid parameters\n"); + ret=-EINVAL; + goto ssc_session_exit; + } + }else if (rx_buf == NULL || rx_len ==0){ + if (tx_buf != NULL && tx_len != 0){ + mode = IFX_SSC_MODE_TX; + }else{ + AMAZON_SSC_EMSG("invalid parameters\n"); + ret=-EINVAL; + goto ssc_session_exit; + } + }else{ + mode = IFX_SSC_MODE_RXTX; + } + + if (mode == IFX_SSC_MODE_RXTX){ + eff_size = tx_len + rx_len; + }else if (mode == IFX_SSC_MODE_RX){ + eff_size = rx_len; + }else{ + eff_size = tx_len; + } + + //4 bytes alignment, required by driver + /* change by TaiCheng */ + //if (in_irq()){ + if (1){ + ssc_tx_buf = (char*) kmalloc(sizeof(char) * ((eff_size + 3) & (~3)), GFP_ATOMIC); + ssc_rx_buf = (char*) kmalloc(sizeof(char) * ((eff_size + 3) & (~3)), GFP_ATOMIC); + }else{ + ssc_tx_buf = (char*) kmalloc(sizeof(char) * ((eff_size + 3) & (~3)), GFP_KERNEL); + ssc_rx_buf = (char*) kmalloc(sizeof(char) * ((eff_size + 3) & (~3)), GFP_KERNEL); + } + if (ssc_tx_buf == NULL || ssc_rx_buf == NULL){ + AMAZON_SSC_EMSG("no memory for size of %d\n", eff_size); + ret = -ENOMEM; + goto ssc_session_exit; + } + memset((void*)ssc_tx_buf, 0, eff_size); + memset((void*)ssc_rx_buf, 0, eff_size); + + if (tx_len>0){ + memcpy(ssc_tx_buf, tx_buf, tx_len); + } + + ret=ifx_ssc_kwrite(0, ssc_tx_buf, eff_size); + + if (ret > 0) { + ssc_tx_buf = NULL; //should be freed by ifx_ssc_kwrite + } + + if ( ret != eff_size ){ + AMAZON_SSC_EMSG("ifx_ssc_write return %d\n",ret); + goto ssc_session_exit; + } + ret=ifx_ssc_kread(0, ssc_rx_buf,eff_size); + if ( ret != eff_size ){ + AMAZON_SSC_EMSG("ifx_ssc_read return %d\n",ret); + goto ssc_session_exit; + } + + memcpy(rx_buf, ssc_rx_buf+tx_len, rx_len); + + if (mode == IFX_SSC_MODE_TX) { + ret = tx_len; + }else{ + ret = rx_len; + } +ssc_session_exit: + + if (ssc_tx_buf != NULL) kfree(ssc_tx_buf); + if (ssc_rx_buf != NULL) kfree(ssc_rx_buf); + + if (ret<0) { + printk("ssc session fails\n"); + } + return ret; +} +/* Brief: TX-RX session + * Parameter: + * tx_buf + * tx_len + * rx_buf + * rx_len + * Return: >=0 number of bytes received + * <0 error code + * Description: + * 1. TX session + * 2. RX session + */ +int amazon_ssc_txrx(char * tx_buf, u32 tx_len, char * rx_buf, u32 rx_len) +{ + return ssc_session(tx_buf,tx_len,rx_buf,rx_len); +} +EXPORT_SYMBOL(amazon_ssc_txrx); +/* Brief: TX only session + * Parameter: + * tx_buf + * tx_len + * Return: >=0 number of bytes transmitted + * <0 error code + */ +int amazon_ssc_tx(char * tx_buf, u32 tx_len) +{ + return ssc_session(tx_buf,tx_len,NULL,0); +} +EXPORT_SYMBOL(amazon_ssc_tx); +/* Brief: RX only session + * Parameter: + * rx_buf + * rx_len + * Return: >=0 number of bytes received + * <0 error code + */ +int amazon_ssc_rx(char * rx_buf, u32 rx_len) +{ + return ssc_session(NULL,0,rx_buf,rx_len); +} +EXPORT_SYMBOL(amazon_ssc_rx); + diff --git a/target/linux/amazon/files/drivers/mtd/maps/amazon.c b/target/linux/amazon/files/drivers/mtd/maps/amazon.c new file mode 100644 index 000000000..568f7d828 --- /dev/null +++ b/target/linux/amazon/files/drivers/mtd/maps/amazon.c @@ -0,0 +1,204 @@ +/* + * Handle mapping of the flash memory access routines + * on Amazon based devices. + * + * Copyright(C) 2004 peng.liu@infineon.com + * + * This code is GPLed + * + */ +// 000005:fchang 2005/6/2 Modified by Bingtao to double check if the EBU is enabled/disabled +// 506231:tc.chen 2005/06/23 increase firmware partition size form 192KB to 256KB +// 050701:linmars 2005/07/01 fix flash size wrong alignment after increase firmware partition +// 165001:henryhsu 2005/8/18 Remove the support for Intel flash because of 2.1 not enough rootfs partition size +// 165001:henryhsu 2005/9/7 Rolback to support INtel flash +// 509071:tc.chen 2005/09/07 Reduced flash writing time +// 511046:linmars 2005/11/04 change bootloader size from 128 into 64 +// 511241:linmars 2005/11/24 merge TaiChen's IRM patch + +// copyright 2005 infineon + +// copyright 2007 john crispin +// copyright 2007 felix fietkau +// copyright 2009 hauke mehrtens + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define AMAZON_PCI_ARB_CTL_ALT 0xb100205c +#define AMAZON_MTD_REG32( addr ) (*(volatile u32 *)(addr)) + + +static struct map_info amazon_map = { + .name = "AMAZON_FLASH", + .bankwidth = 2, +}; + +static map_word amazon_read16(struct map_info * map, unsigned long ofs) +{ + map_word temp; + ofs ^= 2; + temp.x[0] = *((__u16 *) (map->virt + ofs)); + return temp; +} + +static void amazon_write16(struct map_info *map, map_word d, unsigned long adr) +{ + adr ^= 2; + *((__u16 *) (map->virt + adr)) = d.x[0]; +} + +void amazon_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +{ + u8 *p; + u8 *to_8; + from = (unsigned long) (from + map->virt); + p = (u8 *) from; + to_8 = (u8 *) to; + while(len--){ + *to_8++ = *p++; + } +} + +void amazon_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +{ + u8 *p = (u8*) from; + u8 *to_8; + to += (unsigned long) map->virt; + to_8 = (u8*)to; + while(len--){ + *p++ = *to_8++; + } +} + +#define UBOOT_SIZE 0x40000 + +static struct mtd_partition amazon_partitions[3] = { + { + name:"U-Boot", /* U-Boot firmware */ + offset:0x00000000, + size:UBOOT_SIZE , /* 128k */ + }, + { + name:"kernel", /* firmware */ + offset:UBOOT_SIZE, + size:0x00100000, /* 192K */ + }, + { + name:"rootfs", /* default partition */ + offset:0x00200000, + size:0x00200000, + }, +}; + +unsigned long uImage_size = 0x10000d; + +int find_uImage_size(unsigned long start_offset) +{ + unsigned long magic; + unsigned long temp; + amazon_copy_from(&amazon_map, &magic, start_offset, 4); + if (!(ntohl(magic) == 0x27051956)) { + printk(KERN_INFO "amazon_mtd: invalid magic (0x%08X) of kernel at 0x%08lx \n", ntohl(magic), start_offset); + return 0; + } + amazon_copy_from(&amazon_map, &temp, start_offset + 12, 4); + printk(KERN_INFO "amazon_mtd: kernel size is %ld \n", temp + 0x40); + return temp + 0x40; +} + +static int amazon_mtd_probe(struct platform_device *dev) +{ + unsigned long uimage_size; + struct mtd_info *mymtd = NULL; + struct mtd_partition *parts = NULL; + + *AMAZON_EBU_BUSCON0 = 0x1d7ff; + + amazon_map.read = amazon_read16; + amazon_map.write = amazon_write16; + amazon_map.copy_from = amazon_copy_from; + amazon_map.copy_to = amazon_copy_to; + + amazon_map.phys = dev->resource->start; + amazon_map.size = dev->resource->end - amazon_map.phys + 1; + amazon_map.virt = ioremap_nocache(amazon_map.phys, amazon_map.size); + + if (!amazon_map.virt) { + printk(KERN_WARNING "amazon_mtd: Failed to ioremap!\n"); + return -EIO; + } + + mymtd = (struct mtd_info *) do_map_probe("cfi_probe", &amazon_map); + if (!mymtd) { + iounmap(amazon_map.virt); + printk(KERN_WARNING "amazon_mtd: probing failed\n"); + return -ENXIO; + } + + mymtd->owner = THIS_MODULE; + parts = &amazon_partitions[0]; + + /* Some Samsung devices are containing a 16 MB flash chip with a bigger U-Boot partition. */ + if(mymtd->size == 0x01000000 && mymtd->erasesize == 0x00020000) { + printk(KERN_INFO "amazon_mtd: Found big flash chip!\n"); + amazon_partitions[0].size = 0x60000; + amazon_partitions[1].offset = 0x60000; + uimage_size = find_uImage_size(amazon_partitions[1].offset); + amazon_partitions[1].size = uimage_size; + amazon_partitions[2].offset = 0x60000 + uimage_size; + amazon_partitions[2].size = mymtd->size - amazon_partitions[2].offset - mymtd->erasesize; + } else { + printk(KERN_INFO "amazon_mtd: Found small flash chip!\n"); + uimage_size = find_uImage_size(amazon_partitions[1].offset); + amazon_partitions[1].size = uimage_size; + amazon_partitions[2].offset = UBOOT_SIZE + uimage_size; + amazon_partitions[2].size = mymtd->size - amazon_partitions[2].offset - (2 * mymtd->erasesize); + } + + mtd_device_register(mymtd, parts, 3); + + printk(KERN_INFO "amazon_mtd: added %s flash with %dMB\n", + amazon_map.name, ((int)mymtd->size) >> 20); + return 0; +} + +static struct platform_driver amazon_mtd_driver = { + .probe = amazon_mtd_probe, + .driver = { + .name = "amazon_mtd", + .owner = THIS_MODULE, + }, +}; + +static int __init amazon_mtd_init(void) +{ + int ret = platform_driver_register(&amazon_mtd_driver); + if (ret) + printk(KERN_WARNING "amazon_mtd: error registering platfom driver!\n"); + return ret; +} + +static void __exit amazon_mtd_cleanup(void) +{ + platform_driver_unregister(&amazon_mtd_driver); +} + +module_init(amazon_mtd_init); +module_exit(amazon_mtd_cleanup); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("john crispin blogic@openwrt.org"); +MODULE_DESCRIPTION("MTD map driver for AMAZON boards"); + diff --git a/target/linux/amazon/files/drivers/net/ethernet/admmod.c b/target/linux/amazon/files/drivers/net/ethernet/admmod.c new file mode 100644 index 000000000..a11ee1d39 --- /dev/null +++ b/target/linux/amazon/files/drivers/net/ethernet/admmod.c @@ -0,0 +1,1493 @@ +/****************************************************************************** + Copyright (c) 2004, Infineon Technologies. All rights reserved. + + No Warranty + Because the program is licensed free of charge, there is no warranty for + the program, to the extent permitted by applicable law. Except when + otherwise stated in writing the copyright holders and/or other parties + provide the program "as is" without warranty of any kind, either + expressed or implied, including, but not limited to, the implied + warranties of merchantability and fitness for a particular purpose. The + entire risk as to the quality and performance of the program is with + you. should the program prove defective, you assume the cost of all + necessary servicing, repair or correction. + + In no event unless required by applicable law or agreed to in writing + will any copyright holder, or any other party who may modify and/or + redistribute the program as permitted above, be liable to you for + damages, including any general, special, incidental or consequential + damages arising out of the use or inability to use the program + (including but not limited to loss of data or data being rendered + inaccurate or losses sustained by you or third parties or a failure of + the program to operate with any other programs), even if such holder or + other party has been advised of the possibility of such damages. + ****************************************************************************** + Module : admmod.c + Date : 2004-09-01 + Description : JoeLin + Remarks: + + Revision: + MarsLin, add to support VLAN + + *****************************************************************************/ +//000001.joelin 2005/06/02 add"ADM6996_MDC_MDIO_MODE" define, +// if define ADM6996_MDC_MDIO_MODE==> ADM6996LC and ADM6996I will be in MDIO/MDC(SMI)(16 bit) mode, +// amazon should contrl ADM6996 by MDC/MDIO pin +// if undef ADM6996_MDC_MDIO_MODE==> ADM6996 will be in EEProm(32 bit) mode, +// amazon should contrl ADM6996 by GPIO15,16,17,18 pin +/* 507281:linmars 2005/07/28 support MDIO/EEPROM config mode */ +/* 509201:linmars remove driver testing codes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include + + +unsigned int ifx_sw_conf[ADM_SW_MAX_PORT_NUM+1] = \ + {ADM_SW_PORT0_CONF, ADM_SW_PORT1_CONF, ADM_SW_PORT2_CONF, \ + ADM_SW_PORT3_CONF, ADM_SW_PORT4_CONF, ADM_SW_PORT5_CONF}; +unsigned int ifx_sw_bits[8] = \ + {0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff}; +unsigned int ifx_sw_vlan_port[6] = {0, 2, 4, 6, 7, 8}; +//050613:fchang +/* 507281:linmars start */ +#ifdef CONFIG_SWITCH_ADM6996_MDIO +#define ADM6996_MDC_MDIO_MODE 1 //000001.joelin +#else +#undef ADM6996_MDC_MDIO_MODE +#endif +/* 507281:linmars end */ +#define adm6996i 0 +#define adm6996lc 1 +#define adm6996l 2 +unsigned int adm6996_mode=adm6996i; +/* + initialize GPIO pins. + output mode, low +*/ +void ifx_gpio_init(void) +{ + //GPIO16,17,18 direction:output + //GPIO16,17,18 output 0 + + AMAZON_SW_REG(AMAZON_GPIO_P1_DIR) |= (GPIO_MDIO|GPIO_MDCS|GPIO_MDC); + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT) =AMAZON_SW_REG(AMAZON_GPIO_P1_IN)& ~(GPIO_MDIO|GPIO_MDCS|GPIO_MDC); + +} + +/* read one bit from mdio port */ +int ifx_sw_mdio_readbit(void) +{ + //int val; + + //val = (AMAZON_SW_REG(GPIO_conf0_REG) & GPIO0_INPUT_MASK) >> 8; + //return val; + //GPIO16 + return AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&1; +} + +/* + MDIO mode selection + 1 -> output + 0 -> input + + switch input/output mode of GPIO 0 +*/ +void ifx_mdio_mode(int mode) +{ +// AMAZON_SW_REG(GPIO_conf0_REG) = mode ? GPIO_ENABLEBITS : +// ((GPIO_ENABLEBITS | MDIO_INPUT) & ~MDIO_OUTPUT_EN); + mode?(AMAZON_SW_REG(AMAZON_GPIO_P1_DIR)|=GPIO_MDIO): + (AMAZON_SW_REG(AMAZON_GPIO_P1_DIR)&=~GPIO_MDIO); + /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_DIR); + mode?(r|=GPIO_MDIO):(r&=~GPIO_MDIO); + AMAZON_SW_REG(AMAZON_GPIO_P1_DIR)=r;*/ +} + +void ifx_mdc_hi(void) +{ + //GPIO_SET_HI(GPIO_MDC); + //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)|=GPIO_MDC; + /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT); + r|=GPIO_MDC; + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/ + + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)|GPIO_MDC; +} + +void ifx_mdio_hi(void) +{ + //GPIO_SET_HI(GPIO_MDIO); + //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)|=GPIO_MDIO; + /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT); + r|=GPIO_MDIO; + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/ + + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)|GPIO_MDIO; +} + +void ifx_mdcs_hi(void) +{ + //GPIO_SET_HI(GPIO_MDCS); + //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)|=GPIO_MDCS; + /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT); + r|=GPIO_MDCS; + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/ + + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)|GPIO_MDCS; +} + +void ifx_mdc_lo(void) +{ + //GPIO_SET_LOW(GPIO_MDC); + //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)&=~GPIO_MDC; + /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT); + r&=~GPIO_MDC; + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/ + + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&(~GPIO_MDC); +} + +void ifx_mdio_lo(void) +{ + //GPIO_SET_LOW(GPIO_MDIO); + //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)&=~GPIO_MDIO; + /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT); + r&=~GPIO_MDIO; + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/ + + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&(~GPIO_MDIO); +} + +void ifx_mdcs_lo(void) +{ + //GPIO_SET_LOW(GPIO_MDCS); + //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)&=~GPIO_MDCS; + /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT); + r&=~GPIO_MDCS; + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/ + + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&(~GPIO_MDCS); +} + +/* + mdc pulse + 0 -> 1 -> 0 +*/ +static void ifx_sw_mdc_pulse(void) +{ + ifx_mdc_lo(); + udelay(ADM_SW_MDC_DOWN_DELAY); + ifx_mdc_hi(); + udelay(ADM_SW_MDC_UP_DELAY); + ifx_mdc_lo(); +} + +/* + mdc toggle + 1 -> 0 +*/ +static void ifx_sw_mdc_toggle(void) +{ + ifx_mdc_hi(); + udelay(ADM_SW_MDC_UP_DELAY); + ifx_mdc_lo(); + udelay(ADM_SW_MDC_DOWN_DELAY); +} + +/* + enable eeprom write + For ATC 93C66 type EEPROM; accessing ADM6996 internal EEPROM type registers +*/ +static void ifx_sw_eeprom_write_enable(void) +{ + unsigned int op; + + ifx_mdcs_lo(); + ifx_mdc_lo(); + ifx_mdio_hi(); + udelay(ADM_SW_CS_DELAY); + /* enable chip select */ + ifx_mdcs_hi(); + udelay(ADM_SW_CS_DELAY); + /* start bit */ + ifx_mdio_hi(); + ifx_sw_mdc_pulse(); + + /* eeprom write enable */ + op = ADM_SW_BIT_MASK_4; + while (op) + { + if (op & ADM_SW_EEPROM_WRITE_ENABLE) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + op = ADM_SW_BIT_MASK_1 << (EEPROM_TYPE - 3); + while (op) + { + ifx_mdio_lo(); + ifx_sw_mdc_pulse(); + op >>= 1; + } + /* disable chip select */ + ifx_mdcs_lo(); + udelay(ADM_SW_CS_DELAY); + ifx_sw_mdc_pulse(); +} + +/* + disable eeprom write +*/ +static void ifx_sw_eeprom_write_disable(void) +{ + unsigned int op; + + ifx_mdcs_lo(); + ifx_mdc_lo(); + ifx_mdio_hi(); + udelay(ADM_SW_CS_DELAY); + /* enable chip select */ + ifx_mdcs_hi(); + udelay(ADM_SW_CS_DELAY); + + /* start bit */ + ifx_mdio_hi(); + ifx_sw_mdc_pulse(); + /* eeprom write disable */ + op = ADM_SW_BIT_MASK_4; + while (op) + { + if (op & ADM_SW_EEPROM_WRITE_DISABLE) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + op = ADM_SW_BIT_MASK_1 << (EEPROM_TYPE - 3); + while (op) + { + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + /* disable chip select */ + ifx_mdcs_lo(); + udelay(ADM_SW_CS_DELAY); + ifx_sw_mdc_pulse(); +} + +/* + read registers from ADM6996 + serial registers start at 0x200 (addr bit 9 = 1b) + EEPROM registers -> 16bits; Serial registers -> 32bits +*/ +#ifdef ADM6996_MDC_MDIO_MODE //smi mode//000001.joelin +static int ifx_sw_read_adm6996i_smi(unsigned int addr, unsigned int *dat) +{ + addr=(addr<<16)&0x3ff0000; + AMAZON_SW_REG(AMAZON_SW_MDIO_ACC) =(0xC0000000|addr); + while ((AMAZON_SW_REG(AMAZON_SW_MDIO_ACC))&0x80000000){}; + *dat=((AMAZON_SW_REG(AMAZON_SW_MDIO_ACC))&0x0FFFF); + return 0; +} +#endif + +static int ifx_sw_read_adm6996i(unsigned int addr, unsigned int *dat) +{ + unsigned int op; + + ifx_gpio_init(); + + ifx_mdcs_hi(); + udelay(ADM_SW_CS_DELAY); + + ifx_mdcs_lo(); + ifx_mdc_lo(); + ifx_mdio_lo(); + + udelay(ADM_SW_CS_DELAY); + + /* preamble, 32 bit 1 */ + ifx_mdio_hi(); + op = ADM_SW_BIT_MASK_32; + while (op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* command start (01b) */ + op = ADM_SW_BIT_MASK_2; + while (op) + { + if (op & ADM_SW_SMI_START) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* read command (10b) */ + op = ADM_SW_BIT_MASK_2; + while (op) + { + if (op & ADM_SW_SMI_READ) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* send address A9 ~ A0 */ + op = ADM_SW_BIT_MASK_10; + while (op) + { + if (op & addr) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* turnaround bits */ + op = ADM_SW_BIT_MASK_2; + ifx_mdio_hi(); + while (op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + udelay(ADM_SW_MDC_DOWN_DELAY); + + /* set MDIO pin to input mode */ + ifx_mdio_mode(ADM_SW_MDIO_INPUT); + + /* start read data */ + *dat = 0; +//adm6996i op = ADM_SW_BIT_MASK_32; + op = ADM_SW_BIT_MASK_16;//adm6996i + while (op) + { + *dat <<= 1; + if (ifx_sw_mdio_readbit()) *dat |= 1; + ifx_sw_mdc_toggle(); + + op >>= 1; + } + + /* set MDIO to output mode */ + ifx_mdio_mode(ADM_SW_MDIO_OUTPUT); + + /* dummy clock */ + op = ADM_SW_BIT_MASK_4; + ifx_mdio_lo(); + while(op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + ifx_mdc_lo(); + ifx_mdio_lo(); + ifx_mdcs_hi(); + + /* EEPROM registers */ +//adm6996i if (!(addr & 0x200)) +//adm6996i { +//adm6996i if (addr % 2) +//adm6996i *dat >>= 16; +//adm6996i else +//adm6996i *dat &= 0xffff; +//adm6996i } + + return 0; +} +//adm6996 +static int ifx_sw_read_adm6996l(unsigned int addr, unsigned int *dat) +{ + unsigned int op; + + ifx_gpio_init(); + + ifx_mdcs_hi(); + udelay(ADM_SW_CS_DELAY); + + ifx_mdcs_lo(); + ifx_mdc_lo(); + ifx_mdio_lo(); + + udelay(ADM_SW_CS_DELAY); + + /* preamble, 32 bit 1 */ + ifx_mdio_hi(); + op = ADM_SW_BIT_MASK_32; + while (op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* command start (01b) */ + op = ADM_SW_BIT_MASK_2; + while (op) + { + if (op & ADM_SW_SMI_START) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* read command (10b) */ + op = ADM_SW_BIT_MASK_2; + while (op) + { + if (op & ADM_SW_SMI_READ) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* send address A9 ~ A0 */ + op = ADM_SW_BIT_MASK_10; + while (op) + { + if (op & addr) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* turnaround bits */ + op = ADM_SW_BIT_MASK_2; + ifx_mdio_hi(); + while (op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + udelay(ADM_SW_MDC_DOWN_DELAY); + + /* set MDIO pin to input mode */ + ifx_mdio_mode(ADM_SW_MDIO_INPUT); + + /* start read data */ + *dat = 0; + op = ADM_SW_BIT_MASK_32; + while (op) + { + *dat <<= 1; + if (ifx_sw_mdio_readbit()) *dat |= 1; + ifx_sw_mdc_toggle(); + + op >>= 1; + } + + /* set MDIO to output mode */ + ifx_mdio_mode(ADM_SW_MDIO_OUTPUT); + + /* dummy clock */ + op = ADM_SW_BIT_MASK_4; + ifx_mdio_lo(); + while(op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + ifx_mdc_lo(); + ifx_mdio_lo(); + ifx_mdcs_hi(); + + /* EEPROM registers */ + if (!(addr & 0x200)) + { + if (addr % 2) + *dat >>= 16; + else + *dat &= 0xffff; + } + + return 0; +} + +static int ifx_sw_read(unsigned int addr, unsigned int *dat) +{ +#ifdef ADM6996_MDC_MDIO_MODE //smi mode ////000001.joelin + ifx_sw_read_adm6996i_smi(addr,dat); +#else + if (adm6996_mode==adm6996i) ifx_sw_read_adm6996i(addr,dat); + else ifx_sw_read_adm6996l(addr,dat); +#endif + return 0; + +} + +/* + write register to ADM6996 eeprom registers +*/ +//for adm6996i -start +#ifdef ADM6996_MDC_MDIO_MODE //smi mode //000001.joelin +static int ifx_sw_write_adm6996i_smi(unsigned int addr, unsigned int dat) +{ + + AMAZON_SW_REG(AMAZON_SW_MDIO_ACC) = ((addr<<16)&0x3ff0000)|dat|0x80000000; + while ((AMAZON_SW_REG(AMAZON_SW_MDIO_ACC))&0x80000000){}; + + return 0; + +} +#endif //ADM6996_MDC_MDIO_MODE //000001.joelin + +static int ifx_sw_write_adm6996i(unsigned int addr, unsigned int dat) +{ + unsigned int op; + + ifx_gpio_init(); + + ifx_mdcs_hi(); + udelay(ADM_SW_CS_DELAY); + + ifx_mdcs_lo(); + ifx_mdc_lo(); + ifx_mdio_lo(); + + udelay(ADM_SW_CS_DELAY); + + /* preamble, 32 bit 1 */ + ifx_mdio_hi(); + op = ADM_SW_BIT_MASK_32; + while (op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* command start (01b) */ + op = ADM_SW_BIT_MASK_2; + while (op) + { + if (op & ADM_SW_SMI_START) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* write command (01b) */ + op = ADM_SW_BIT_MASK_2; + while (op) + { + if (op & ADM_SW_SMI_WRITE) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* send address A9 ~ A0 */ + op = ADM_SW_BIT_MASK_10; + while (op) + { + if (op & addr) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* turnaround bits */ + op = ADM_SW_BIT_MASK_2; + ifx_mdio_hi(); + while (op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + udelay(ADM_SW_MDC_DOWN_DELAY); + + /* set MDIO pin to output mode */ + ifx_mdio_mode(ADM_SW_MDIO_OUTPUT); + + + /* start write data */ + op = ADM_SW_BIT_MASK_16; + while (op) + { + if (op & dat) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_toggle(); + op >>= 1; + } + + // /* set MDIO to output mode */ + // ifx_mdio_mode(ADM_SW_MDIO_OUTPUT); + + /* dummy clock */ + op = ADM_SW_BIT_MASK_4; + ifx_mdio_lo(); + while(op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + ifx_mdc_lo(); + ifx_mdio_lo(); + ifx_mdcs_hi(); + + /* EEPROM registers */ +//adm6996i if (!(addr & 0x200)) +//adm6996i { +//adm6996i if (addr % 2) +//adm6996i *dat >>= 16; +//adm6996i else +//adm6996i *dat &= 0xffff; +//adm6996i } + + return 0; +} +//for adm6996i-end +static int ifx_sw_write_adm6996l(unsigned int addr, unsigned int dat) +{ + unsigned int op; + + ifx_gpio_init(); + + /* enable write */ + ifx_sw_eeprom_write_enable(); + + /* chip select */ + ifx_mdcs_hi(); + udelay(ADM_SW_CS_DELAY); + + /* issue write command */ + /* start bit */ + ifx_mdio_hi(); + ifx_sw_mdc_pulse(); + + /* EEPROM write command */ + op = ADM_SW_BIT_MASK_2; + while (op) + { + if (op & ADM_SW_EEPROM_WRITE) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* send address A7 ~ A0 */ + op = ADM_SW_BIT_MASK_1 << (EEPROM_TYPE - 1); + + while (op) + { + if (op & addr) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_toggle(); + op >>= 1; + } + + /* start write data */ + op = ADM_SW_BIT_MASK_16; + while (op) + { + if (op & dat) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_toggle(); + op >>= 1; + } + + /* disable cs & wait 1 clock */ + ifx_mdcs_lo(); + udelay(ADM_SW_CS_DELAY); + ifx_sw_mdc_toggle(); + + ifx_sw_eeprom_write_disable(); + + return 0; +} + +static int ifx_sw_write(unsigned int addr, unsigned int dat) +{ +#ifdef ADM6996_MDC_MDIO_MODE //smi mode ////000001.joelin + ifx_sw_write_adm6996i_smi(addr,dat); +#else //000001.joelin + if (adm6996_mode==adm6996i) ifx_sw_write_adm6996i(addr,dat); + else ifx_sw_write_adm6996l(addr,dat); +#endif //000001.joelin + return 0; +} + +/* + do switch PHY reset +*/ +int ifx_sw_reset(void) +{ + /* reset PHY */ + ifx_sw_write(ADM_SW_PHY_RESET, 0); + + return 0; +} + +/* 509201:linmars start */ +#if 0 +/* + check port status +*/ +int ifx_check_port_status(int port) +{ + unsigned int val; + + if ((port < 0) || (port > ADM_SW_MAX_PORT_NUM)) + { + ifx_printf(("error on port number (%d)!!\n", port)); + return -1; + } + + ifx_sw_read(ifx_sw_conf[port], &val); + if (ifx_sw_conf[port]%2) val >>= 16; + /* only 16bits are effective */ + val &= 0xFFFF; + + ifx_printf(("Port %d status (%.8x): \n", port, val)); + + if (val & ADM_SW_PORT_FLOWCTL) + ifx_printf(("\t802.3x flow control supported!\n")); + else + ifx_printf(("\t802.3x flow control not supported!\n")); + + if (val & ADM_SW_PORT_AN) + ifx_printf(("\tAuto negotiation ON!\n")); + else + ifx_printf(("\tAuto negotiation OFF!\n")); + + if (val & ADM_SW_PORT_100M) + ifx_printf(("\tLink at 100M!\n")); + else + ifx_printf(("\tLink at 10M!\n")); + + if (val & ADM_SW_PORT_FULL) + ifx_printf(("\tFull duplex!\n")); + else + ifx_printf(("\tHalf duplex!\n")); + + if (val & ADM_SW_PORT_DISABLE) + ifx_printf(("\tPort disabled!\n")); + else + ifx_printf(("\tPort enabled!\n")); + + if (val & ADM_SW_PORT_TOS) + ifx_printf(("\tTOS enabled!\n")); + else + ifx_printf(("\tTOS disabled!\n")); + + if (val & ADM_SW_PORT_PPRI) + ifx_printf(("\tPort priority first!\n")); + else + ifx_printf(("\tVLAN or TOS priority first!\n")); + + if (val & ADM_SW_PORT_MDIX) + ifx_printf(("\tAuto MDIX!\n")); + else + ifx_printf(("\tNo auto MDIX\n")); + + ifx_printf(("\tPVID: %d\n", \ + ((val >> ADM_SW_PORT_PVID_SHIFT)&ifx_sw_bits[ADM_SW_PORT_PVID_BITS]))); + + return 0; +} +/* + initialize a VLAN + clear all VLAN bits +*/ +int ifx_sw_vlan_init(int vlanid) +{ + ifx_sw_write(ADM_SW_VLAN0_CONF + vlanid, 0); + + return 0; +} + +/* + add a port to certain vlan +*/ +int ifx_sw_vlan_add(int port, int vlanid) +{ + int reg = 0; + + if ((port < 0) || (port > ADM_SW_MAX_PORT_NUM) || (vlanid < 0) || + (vlanid > ADM_SW_MAX_VLAN_NUM)) + { + ifx_printf(("Port number or VLAN number ERROR!!\n")); + return -1; + } + ifx_sw_read(ADM_SW_VLAN0_CONF + vlanid, ®); + reg |= (1 << ifx_sw_vlan_port[port]); + ifx_sw_write(ADM_SW_VLAN0_CONF + vlanid, reg); + + return 0; +} + +/* + delete a given port from certain vlan +*/ +int ifx_sw_vlan_del(int port, int vlanid) +{ + unsigned int reg = 0; + + if ((port < 0) || (port > ADM_SW_MAX_PORT_NUM) || (vlanid < 0) || (vlanid > ADM_SW_MAX_VLAN_NUM)) + { + ifx_printf(("Port number or VLAN number ERROR!!\n")); + return -1; + } + ifx_sw_read(ADM_SW_VLAN0_CONF + vlanid, ®); + reg &= ~(1 << ifx_sw_vlan_port[port]); + ifx_sw_write(ADM_SW_VLAN0_CONF + vlanid, reg); + + return 0; +} + +/* + default VLAN setting + + port 0~3 as untag port and PVID = 1 + VLAN1: port 0~3 and port 5 (MII) +*/ +static int ifx_sw_init(void) +{ + ifx_printf(("Setting default ADM6996 registers... \n")); + + /* MAC clone, 802.1q based VLAN */ + ifx_sw_write(ADM_SW_VLAN_MODE, 0xff30); + /* auto MDIX, PVID=1, untag */ + ifx_sw_write(ADM_SW_PORT0_CONF, 0x840f); + ifx_sw_write(ADM_SW_PORT1_CONF, 0x840f); + ifx_sw_write(ADM_SW_PORT2_CONF, 0x840f); + ifx_sw_write(ADM_SW_PORT3_CONF, 0x840f); + /* auto MDIX, PVID=2, untag */ + ifx_sw_write(ADM_SW_PORT5_CONF, 0x880f); + /* port 0~3 & 5 as VLAN1 */ + ifx_sw_write(ADM_SW_VLAN0_CONF+1, 0x0155); + + return 0; +} +#endif +/* 509201:linmars end */ + +int adm_open(struct inode *node, struct file *filp) +{ + return 0; +} + +ssize_t adm_read(struct file *filep, char *buf, size_t count, loff_t *ppos) +{ + return count; +} + +ssize_t adm_write(struct file *filep, const char *buf, size_t count, loff_t *ppos) +{ + return count; +} + +/* close */ +int adm_release(struct inode *inode, struct file *filp) +{ + return 0; +} + +/* IOCTL function */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) +static long adm_ioctl(struct file *filp, unsigned int cmd, unsigned long args) +#else +static int adm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long args) +#endif +{ + PREGRW uREGRW; + unsigned int rtval; + unsigned int val; //6996i + unsigned int control[6] ; //6996i + unsigned int status[6] ; //6996i + + PMACENTRY mMACENTRY;//adm6996i + PPROTOCOLFILTER uPROTOCOLFILTER ;///adm6996i + + if (_IOC_TYPE(cmd) != ADM_MAGIC) + { + printk("adm_ioctl: IOC_TYPE(%x) != ADM_MAGIC(%x)! \n", _IOC_TYPE(cmd), ADM_MAGIC); + return (-EINVAL); + } + + if(_IOC_NR(cmd) >= KEY_IOCTL_MAX_KEY) + { + printk(KERN_WARNING "adm_ioctl: IOC_NR(%x) invalid! \n", _IOC_NR(cmd)); + return (-EINVAL); + } + + switch (cmd) + { + case ADM_IOCTL_REGRW: + { + uREGRW = (PREGRW)kmalloc(sizeof(REGRW), GFP_KERNEL); + rtval = copy_from_user(uREGRW, (PREGRW)args, sizeof(REGRW)); + if (rtval != 0) + { + printk("ADM_IOCTL_REGRW: copy from user FAILED!! \n"); + return (-EFAULT); + } + + switch(uREGRW->mode) + { + case REG_READ: + uREGRW->value = 0x12345678;//inl(uREGRW->addr); + copy_to_user((PREGRW)args, uREGRW, sizeof(REGRW)); + break; + case REG_WRITE: + //outl(uREGRW->value, uREGRW->addr); + break; + + default: + printk("No such Register Read/Write function!! \n"); + return (-EFAULT); + } + kfree(uREGRW); + break; + } + + case ADM_SW_IOCTL_REGRW: + { + unsigned int val = 0xff; + + uREGRW = (PREGRW)kmalloc(sizeof(REGRW), GFP_KERNEL); + rtval = copy_from_user(uREGRW, (PREGRW)args, sizeof(REGRW)); + if (rtval != 0) + { + printk("ADM_IOCTL_REGRW: copy from user FAILED!! \n"); + return (-EFAULT); + } + + switch(uREGRW->mode) + { + case REG_READ: + ifx_sw_read(uREGRW->addr, &val); + uREGRW->value = val; + copy_to_user((PREGRW)args, uREGRW, sizeof(REGRW)); + break; + + case REG_WRITE: + ifx_sw_write(uREGRW->addr, uREGRW->value); + break; + default: + printk("No such Register Read/Write function!! \n"); + return (-EFAULT); + } + kfree(uREGRW); + break; + } +/* 509201:linmars start */ +#if 0 + case ADM_SW_IOCTL_PORTSTS: + for (rtval = 0; rtval < ADM_SW_MAX_PORT_NUM+1; rtval++) + ifx_check_port_status(rtval); + break; + case ADM_SW_IOCTL_INIT: + ifx_sw_init(); + break; +#endif +/* 509201:linmars end */ +//adm6996i + case ADM_SW_IOCTL_MACENTRY_ADD: + case ADM_SW_IOCTL_MACENTRY_DEL: + case ADM_SW_IOCTL_MACENTRY_GET_INIT: + case ADM_SW_IOCTL_MACENTRY_GET_MORE: + + + mMACENTRY = (PMACENTRY)kmalloc(sizeof(MACENTRY), GFP_KERNEL); + rtval = copy_from_user(mMACENTRY, (PMACENTRY)args, sizeof(MACENTRY)); + if (rtval != 0) + { + printk("ADM_SW_IOCTL_MACENTRY: copy from user FAILED!! \n"); + return (-EFAULT); + } + control[0]=(mMACENTRY->mac_addr[1]<<8)+mMACENTRY->mac_addr[0] ; + control[1]=(mMACENTRY->mac_addr[3]<<8)+mMACENTRY->mac_addr[2] ; + control[2]=(mMACENTRY->mac_addr[5]<<8)+mMACENTRY->mac_addr[4] ; + control[3]=(mMACENTRY->fid&0xf)+((mMACENTRY->portmap&0x3f)<<4); + if (((mMACENTRY->info_type)&0x01)) control[4]=(mMACENTRY->ctrl.info_ctrl)+0x1000; //static ,info control + else control[4]=((mMACENTRY->ctrl.age_timer)&0xff);//not static ,agetimer + if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT) { + //initial the pointer to the first address + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + control[5]=0x030;//initial the first address + ifx_sw_write(0x11f,control[5]); + + + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + + } //if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT) + if (cmd==ADM_SW_IOCTL_MACENTRY_ADD) control[5]=0x07;//create a new address + else if (cmd==ADM_SW_IOCTL_MACENTRY_DEL) control[5]=0x01f;//erased an existed address + else if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) + control[5]=0x02c;//search by the mac address field + + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + ifx_sw_write(0x11a,control[0]); + ifx_sw_write(0x11b,control[1]); + ifx_sw_write(0x11c,control[2]); + ifx_sw_write(0x11d,control[3]); + ifx_sw_write(0x11e,control[4]); + ifx_sw_write(0x11f,control[5]); + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + val=((val&0x7000)>>12);//result ,status5[14:12] + mMACENTRY->result=val; + + if (!val) { + printk(" Command OK!! \n"); + if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) { + ifx_sw_read(0x120,&(status[0])); + ifx_sw_read(0x121,&(status[1])); + ifx_sw_read(0x122,&(status[2])); + ifx_sw_read(0x123,&(status[3])); + ifx_sw_read(0x124,&(status[4])); + ifx_sw_read(0x125,&(status[5])); + + + mMACENTRY->mac_addr[0]=(status[0]&0x00ff) ; + mMACENTRY->mac_addr[1]=(status[0]&0xff00)>>8 ; + mMACENTRY->mac_addr[2]=(status[1]&0x00ff) ; + mMACENTRY->mac_addr[3]=(status[1]&0xff00)>>8 ; + mMACENTRY->mac_addr[4]=(status[2]&0x00ff) ; + mMACENTRY->mac_addr[5]=(status[2]&0xff00)>>8 ; + mMACENTRY->fid=(status[3]&0xf); + mMACENTRY->portmap=((status[3]>>4)&0x3f); + if (status[5]&0x2) {//static info_ctrl //status5[1]???? + mMACENTRY->ctrl.info_ctrl=(status[4]&0x00ff); + mMACENTRY->info_type=1; + } + else {//not static age_timer + mMACENTRY->ctrl.age_timer=(status[4]&0x00ff); + mMACENTRY->info_type=0; + } +//status5[13]???? mMACENTRY->occupy=(status[5]&0x02)>>1;//status5[1] + mMACENTRY->occupy=(status[5]&0x02000)>>13;//status5[13] ??? + mMACENTRY->bad=(status[5]&0x04)>>2;//status5[2] + }//if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) + + } + else if (val==0x001) + printk(" All Entry Used!! \n"); + else if (val==0x002) + printk(" Entry Not Found!! \n"); + else if (val==0x003) + printk(" Try Next Entry!! \n"); + else if (val==0x005) + printk(" Command Error!! \n"); + else + printk(" UnKnown Error!! \n"); + + copy_to_user((PMACENTRY)args, mMACENTRY,sizeof(MACENTRY)); + + break; + + case ADM_SW_IOCTL_FILTER_ADD: + case ADM_SW_IOCTL_FILTER_DEL: + case ADM_SW_IOCTL_FILTER_GET: + + uPROTOCOLFILTER = (PPROTOCOLFILTER)kmalloc(sizeof(PROTOCOLFILTER), GFP_KERNEL); + rtval = copy_from_user(uPROTOCOLFILTER, (PPROTOCOLFILTER)args, sizeof(PROTOCOLFILTER)); + if (rtval != 0) + { + printk("ADM_SW_IOCTL_FILTER_ADD: copy from user FAILED!! \n"); + return (-EFAULT); + } + + if(cmd==ADM_SW_IOCTL_FILTER_DEL) { //delete filter + uPROTOCOLFILTER->ip_p=00; //delet filter + uPROTOCOLFILTER->action=00; //delete filter + } //delete filter + + ifx_sw_read(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), &val);//rx68~rx6b,protocol filter0~7 + + if (((uPROTOCOLFILTER->protocol_filter_num)%2)==00){ + if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= val&0x00ff;//get filter ip_p + else val=(val&0xff00)|(uPROTOCOLFILTER->ip_p);//set filter ip_p + } + else { + if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= (val>>8);//get filter ip_p + else val=(val&0x00ff)|((uPROTOCOLFILTER->ip_p)<<8);//set filter ip_p + } + if(cmd!=ADM_SW_IOCTL_FILTER_GET) ifx_sw_write(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), val);//write rx68~rx6b,protocol filter0~7 + + ifx_sw_read(0x95, &val); //protocol filter action + if(cmd==ADM_SW_IOCTL_FILTER_GET) { + uPROTOCOLFILTER->action= ((val>>(uPROTOCOLFILTER->protocol_filter_num*2))&0x3);//get filter action + copy_to_user((PPROTOCOLFILTER)args, uPROTOCOLFILTER, sizeof(PROTOCOLFILTER)); + + } + else { + val=(val&(~(0x03<<(uPROTOCOLFILTER->protocol_filter_num*2))))|(((uPROTOCOLFILTER->action)&0x03)<<(uPROTOCOLFILTER->protocol_filter_num*2)); + // printk("%d----\n",val); + ifx_sw_write(0x95, val); //write protocol filter action + } + + break; +//adm6996i + + /* others */ + default: + return -EFAULT; + } + /* end of switch */ + return 0; +} + +/* Santosh: handle IGMP protocol filter ADD/DEL/GET */ +int adm_process_protocol_filter_request (unsigned int cmd, PPROTOCOLFILTER uPROTOCOLFILTER) +{ + unsigned int val; //6996i + + if(cmd==ADM_SW_IOCTL_FILTER_DEL) { //delete filter + uPROTOCOLFILTER->ip_p=00; //delet filter + uPROTOCOLFILTER->action=00; //delete filter + } //delete filter + + ifx_sw_read(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), &val);//rx68~rx6b,protocol filter0~7 + + if (((uPROTOCOLFILTER->protocol_filter_num)%2)==00){ + if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= val&0x00ff;//get filter ip_p + else val=(val&0xff00)|(uPROTOCOLFILTER->ip_p);//set filter ip_p + } + else { + if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= (val>>8);//get filter ip_p + else val=(val&0x00ff)|((uPROTOCOLFILTER->ip_p)<<8);//set filter ip_p + } + if(cmd!=ADM_SW_IOCTL_FILTER_GET) ifx_sw_write(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), val);//write rx68~rx6b,protocol filter0~7 + + ifx_sw_read(0x95, &val); //protocol filter action + if(cmd==ADM_SW_IOCTL_FILTER_GET) { + uPROTOCOLFILTER->action= ((val>>(uPROTOCOLFILTER->protocol_filter_num*2))&0x3);//get filter action + } + else { + val=(val&(~(0x03<<(uPROTOCOLFILTER->protocol_filter_num*2))))|(((uPROTOCOLFILTER->action)&0x03)<<(uPROTOCOLFILTER->protocol_filter_num*2)); + ifx_sw_write(0x95, val); //write protocol filter action + } + + return 0; +} + + +/* Santosh: function for MAC ENTRY ADD/DEL/GET */ + +int adm_process_mac_table_request (unsigned int cmd, PMACENTRY mMACENTRY) +{ + unsigned int val; //6996i + unsigned int control[6] ; //6996i + unsigned int status[6] ; //6996i + + // printk ("adm_process_mac_table_request: enter\n"); + + control[0]=(mMACENTRY->mac_addr[1]<<8)+mMACENTRY->mac_addr[0] ; + control[1]=(mMACENTRY->mac_addr[3]<<8)+mMACENTRY->mac_addr[2] ; + control[2]=(mMACENTRY->mac_addr[5]<<8)+mMACENTRY->mac_addr[4] ; + control[3]=(mMACENTRY->fid&0xf)+((mMACENTRY->portmap&0x3f)<<4); + + if (((mMACENTRY->info_type)&0x01)) control[4]=(mMACENTRY->ctrl.info_ctrl)+0x1000; //static ,info control + else control[4]=((mMACENTRY->ctrl.age_timer)&0xff);//not static ,agetimer + if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT) { + //initial the pointer to the first address + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + control[5]=0x030;//initial the first address + ifx_sw_write(0x11f,control[5]); + + + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + + } //if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT) + if (cmd==ADM_SW_IOCTL_MACENTRY_ADD) control[5]=0x07;//create a new address + else if (cmd==ADM_SW_IOCTL_MACENTRY_DEL) control[5]=0x01f;//erased an existed address + else if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) + control[5]=0x02c;//search by the mac address field + + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + ifx_sw_write(0x11a,control[0]); + ifx_sw_write(0x11b,control[1]); + ifx_sw_write(0x11c,control[2]); + ifx_sw_write(0x11d,control[3]); + ifx_sw_write(0x11e,control[4]); + ifx_sw_write(0x11f,control[5]); + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + val=((val&0x7000)>>12);//result ,status5[14:12] + mMACENTRY->result=val; + + if (!val) { + printk(" Command OK!! \n"); + if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) { + ifx_sw_read(0x120,&(status[0])); + ifx_sw_read(0x121,&(status[1])); + ifx_sw_read(0x122,&(status[2])); + ifx_sw_read(0x123,&(status[3])); + ifx_sw_read(0x124,&(status[4])); + ifx_sw_read(0x125,&(status[5])); + + + mMACENTRY->mac_addr[0]=(status[0]&0x00ff) ; + mMACENTRY->mac_addr[1]=(status[0]&0xff00)>>8 ; + mMACENTRY->mac_addr[2]=(status[1]&0x00ff) ; + mMACENTRY->mac_addr[3]=(status[1]&0xff00)>>8 ; + mMACENTRY->mac_addr[4]=(status[2]&0x00ff) ; + mMACENTRY->mac_addr[5]=(status[2]&0xff00)>>8 ; + mMACENTRY->fid=(status[3]&0xf); + mMACENTRY->portmap=((status[3]>>4)&0x3f); + if (status[5]&0x2) {//static info_ctrl //status5[1]???? + mMACENTRY->ctrl.info_ctrl=(status[4]&0x00ff); + mMACENTRY->info_type=1; + } + else {//not static age_timer + mMACENTRY->ctrl.age_timer=(status[4]&0x00ff); + mMACENTRY->info_type=0; + } +//status5[13]???? mMACENTRY->occupy=(status[5]&0x02)>>1;//status5[1] + mMACENTRY->occupy=(status[5]&0x02000)>>13;//status5[13] ??? + mMACENTRY->bad=(status[5]&0x04)>>2;//status5[2] + }//if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) + + } + else if (val==0x001) + printk(" All Entry Used!! \n"); + else if (val==0x002) + printk(" Entry Not Found!! \n"); + else if (val==0x003) + printk(" Try Next Entry!! \n"); + else if (val==0x005) + printk(" Command Error!! \n"); + else + printk(" UnKnown Error!! \n"); + + // printk ("adm_process_mac_table_request: Exit\n"); + return 0; +} + +/* Santosh: End of function for MAC ENTRY ADD/DEL*/ +struct file_operations adm_ops = +{ + read: adm_read, + write: adm_write, + open: adm_open, + release: adm_release, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) + unlocked_ioctl: adm_ioctl +#else + ioctl: adm_ioctl +#endif +}; + +int adm_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data) +{ + int len = 0; + + len += sprintf(buf+len, " ************ Registers ************ \n"); + *eof = 1; + return len; +} + +int __init init_adm6996_module(void) +{ + unsigned int val = 000; + unsigned int val1 = 000; + + printk("Loading ADM6996 driver... \n"); + + /* if running on adm5120 */ + /* set GPIO 0~2 as adm6996 control pins */ + //outl(0x003f3f00, 0x12000028); + /* enable switch port 5 (MII) as RMII mode (5120MAC <-> 6996MAC) */ + //outl(0x18a, 0x12000030); + /* group adm5120 port 1 ~ 5 as VLAN0, port 5 & 6(CPU) as VLAN1 */ + //outl(0x417e, 0x12000040); + /* end adm5120 fixup */ +#ifdef ADM6996_MDC_MDIO_MODE //smi mode //000001.joelin + register_chrdev(69, "adm6996", &adm_ops); + AMAZON_SW_REG(AMAZON_SW_MDIO_CFG) = 0x27be; + AMAZON_SW_REG(AMAZON_SW_EPHY) = 0xfc; + adm6996_mode=adm6996i; + ifx_sw_read(0xa0, &val); + ifx_sw_read(0xa1, &val1); + val=((val1&0x0f)<<16)|val; + printk ("\nADM6996 SMI Mode-"); + printk ("Chip ID:%5x \n ", val); +#else //000001.joelin + + AMAZON_SW_REG(AMAZON_SW_MDIO_CFG) = 0x2c50; + AMAZON_SW_REG(AMAZON_SW_EPHY) = 0xff; + + AMAZON_SW_REG(AMAZON_GPIO_P1_ALTSEL0) &= ~(GPIO_MDIO|GPIO_MDCS|GPIO_MDC); + AMAZON_SW_REG(AMAZON_GPIO_P1_ALTSEL1) &= ~(GPIO_MDIO|GPIO_MDCS|GPIO_MDC); + AMAZON_SW_REG(AMAZON_GPIO_P1_OD) |= (GPIO_MDIO|GPIO_MDCS|GPIO_MDC); + + ifx_gpio_init(); + register_chrdev(69, "adm6996", &adm_ops); + mdelay(100); + + /* create proc entries */ + // create_proc_read_entry("admide", 0, NULL, admide_proc, NULL); + +//joelin adm6996i support start + adm6996_mode=adm6996i; + ifx_sw_read(0xa0, &val); + adm6996_mode=adm6996l; + ifx_sw_read(0x200, &val1); +// printk ("\n %0x \n",val1); + if ((val&0xfff0)==0x1020) { + printk ("\n ADM6996I .. \n"); + adm6996_mode=adm6996i; + } + else if ((val1&0xffffff00)==0x71000) {//71010 or 71020 + printk ("\n ADM6996LC .. \n"); + adm6996_mode=adm6996lc; + } + else { + printk ("\n ADM6996L .. \n"); + adm6996_mode=adm6996l; + } +#endif //ADM6996_MDC_MDIO_MODE //smi mode //000001.joelin + + if ((adm6996_mode==adm6996lc)||(adm6996_mode==adm6996i)){ +#if 0 /* removed by MarsLin */ + ifx_sw_write(0x29,0xc000); + ifx_sw_write(0x30,0x0985); +#else + ifx_sw_read(0xa0, &val); + if (val == 0x1021) // for both 6996LC and 6996I, only AB version need the patch + ifx_sw_write(0x29, 0x9000); + ifx_sw_write(0x30,0x0985); +#endif + } +//joelin adm6996i support end + return 0; +} + +void __exit cleanup_adm6996_module(void) +{ + printk("Free ADM device driver... \n"); + + unregister_chrdev(69, "adm6996"); + + /* remove proc entries */ + // remove_proc_entry("admide", NULL); +} + +/* MarsLin, add start */ +#if defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT) || defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT_MODULE) + #define SET_BIT(reg, mask) reg |= (mask) + #define CLEAR_BIT(reg, mask) reg &= (~mask) + static int ifx_hw_reset(void) + { + CLEAR_BIT((*AMAZON_GPIO_P0_ALTSEL0),0x2000); + CLEAR_BIT((*AMAZON_GPIO_P0_ALTSEL1),0x2000); + SET_BIT((*AMAZON_GPIO_P0_OD),0x2000); + SET_BIT((*AMAZON_GPIO_P0_DIR), 0x2000); + CLEAR_BIT((*AMAZON_GPIO_P0_OUT), 0x2000); + mdelay(500); + SET_BIT((*AMAZON_GPIO_P0_OUT), 0x2000); + cleanup_adm6996_module(); + return init_adm6996_module(); + } + int (*adm6996_hw_reset)(void) = ifx_hw_reset; + EXPORT_SYMBOL(adm6996_hw_reset); + EXPORT_SYMBOL(adm6996_mode); + int (*adm6996_sw_read)(unsigned int addr, unsigned int *data) = ifx_sw_read; + EXPORT_SYMBOL(adm6996_sw_read); + int (*adm6996_sw_write)(unsigned int addr, unsigned int data) = ifx_sw_write; + EXPORT_SYMBOL(adm6996_sw_write); +#endif +/* MarsLin, add end */ + +/* Santosh: for IGMP proxy/snooping, Begin */ +EXPORT_SYMBOL (adm_process_mac_table_request); +EXPORT_SYMBOL (adm_process_protocol_filter_request); +/* Santosh: for IGMP proxy/snooping, End */ + +MODULE_DESCRIPTION("ADMtek 6996 Driver"); +MODULE_AUTHOR("Joe Lin "); +MODULE_LICENSE("GPL"); + +module_init(init_adm6996_module); +module_exit(cleanup_adm6996_module); + diff --git a/target/linux/amazon/files/drivers/net/ethernet/amazon_sw.c b/target/linux/amazon/files/drivers/net/ethernet/amazon_sw.c new file mode 100644 index 000000000..d18b439ce --- /dev/null +++ b/target/linux/amazon/files/drivers/net/ethernet/amazon_sw.c @@ -0,0 +1,899 @@ +/* + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +//----------------------------------------------------------------------- +/* + * Description: + * Driver for Infineon Amazon 3 port switch + */ +//----------------------------------------------------------------------- +/* Author: Wu Qi Ming[Qi-Ming.Wu@infineon.com] + * Created: 7-April-2004 + */ +//----------------------------------------------------------------------- +/* History + * Changed on: Jun 28, 2004 + * Changed by: peng.liu@infineon.com + * Reason: add hardware flow control (HFC) (CONFIG_NET_HW_FLOWCONTROL) + * + * Changed on: Apr 6, 2005 + * Changed by: mars.lin@infineon.com + * Reason : supoort port identification + */ + + +// copyright 2004-2005 infineon.com + +// copyright 2007 john crispin +// copyright 2007 felix fietkau +// copyright 2009 hauke mehrtens + + +// TODO +// port vlan code from bcrm target... the tawainese code was scrapped due to crappyness +// check all the mmi reg settings and possibly document them better +// verify the ethtool code +// remove the while(1) stuff +// further clean up and rework ... but it works for now +// check the mode[]=bridge stuff +// verify that the ethaddr can be set from u-boot + + +#ifndef __KERNEL__ +#define __KERNEL__ +#endif + + +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) +#define MODVERSIONS +#endif + +#if defined(MODVERSIONS) && !defined(__GENKSYMS__) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// how many mii ports are there ? +#define AMAZON_SW_INT_NO 2 + +#define ETHERNET_PACKET_DMA_BUFFER_SIZE 1536 + +/***************************************** Module Parameters *************************************/ +static char mode[] = "bridge"; +module_param_array(mode, charp, NULL, 0); + +static int timeout = 1 * HZ; +module_param(timeout, int, 0); + +int switch_init(struct net_device *dev); +void switch_tx_timeout(struct net_device *dev); + +static struct net_device *switch_devs[2]; + +int add_mac_table_entry(u64 entry_value) +{ + int i; + u32 data1, data2; + + AMAZON_SW_REG32(AMAZON_SW_ARL_CTL) = ~7; + + for (i = 0; i < 32; i++) { + AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0x80000000 | 0x20 | i; + while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {}; + data1 = AMAZON_SW_REG32(AMAZON_SW_DATA1); + data2 = AMAZON_SW_REG32(AMAZON_SW_DATA2); + if ((data1 & (0x00700000)) != 0x00700000) + continue; + AMAZON_SW_REG32(AMAZON_SW_DATA1) = (u32) (entry_value >> 32); + AMAZON_SW_REG32(AMAZON_SW_DATA2) = (u32) entry_value & 0xffffffff; + AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0xc0000020 | i; + while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {}; + break; + } + AMAZON_SW_REG32(AMAZON_SW_ARL_CTL) |= 7; + if (i >= 32) + return -1; + return OK; +} + +u64 read_mac_table_entry(int index) +{ + u32 data1, data2; + u64 value; + AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0x80000000 | 0x20 | index; + while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {}; + data1 = AMAZON_SW_REG32(AMAZON_SW_DATA1) & 0xffffff; + data2 = AMAZON_SW_REG32(AMAZON_SW_DATA2); + value = (u64) data1 << 32 | (u64) data2; + return value; +} + +int write_mac_table_entry(int index, u64 value) +{ + u32 data1, data2; + data1 = (u32) (value >> 32); + data2 = (u32) value & 0xffffffff; + AMAZON_SW_REG32(AMAZON_SW_DATA1) = data1; + AMAZON_SW_REG32(AMAZON_SW_DATA2) = data2; + AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0xc0000020 | index; + while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {}; + return OK; +} + +u32 get_mdio_reg(int phy_addr, int reg_num) +{ + u32 value; + AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) = (3 << 30) | ((phy_addr & 0x1f) << 21) | ((reg_num & 0x1f) << 16); + while (AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) & (1 << 31)) {}; + value = AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) & 0xffff; + return value; +} + +int set_mdio_reg(int phy_addr, int reg_num, u32 value) +{ + AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) = (2 << 30) | ((phy_addr & 0x1f) << 21) | ((reg_num & 0x1f) << 16) | (value & 0xffff); + while (AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) & (1 << 31)) {}; + return OK; +} + +int auto_negotiate(int phy_addr) +{ + u32 value = 0; + value = get_mdio_reg(phy_addr, MDIO_BASE_CONTROL_REG); + set_mdio_reg(phy_addr, MDIO_BASE_CONTROL_REG, (value | RESTART_AUTO_NEGOTIATION | AUTO_NEGOTIATION_ENABLE | PHY_RESET)); + return OK; +} + +/* + In this version of switch driver, we split the dma channels for the switch. + 2 for port0 and 2 for port1. So that we can do internal bridging if necessary. + In switch mode, packets coming in from port0 or port1 is able to do Destination + address lookup. Packets coming from port0 with destination address of port1 should + not go to pmac again. The switch hardware should be able to do the switch in the hard + ware level. Packets coming from the pmac should not do the DA look up in that the + desination is already known for the kernel. It only needs to go to the correct NIC to + find its way out. + */ +int amazon_sw_chip_init(void) +{ + u32 tmp1; + int i = 0; + + /* Aging tick select: 5mins */ + tmp1 = 0xa0; + if (strcmp(mode, "bridge") == 0) { + // bridge mode, set militarised mode to 1, no learning! + tmp1 |= 0xC00; + } else { + // enable learning for P0 and P1, + tmp1 |= 3; + } + + /* unknown broadcast/multicast/unicast to all ports */ + AMAZON_SW_REG32(AMAZON_SW_UN_DEST) = 0x1ff; + + AMAZON_SW_REG32(AMAZON_SW_ARL_CTL) = tmp1; + + /* OCS:1 set OCS bit, split the two NIC in rx direction EDL:1 (enable DA lookup) */ +#if defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT) || defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT_MODULE) + AMAZON_SW_REG32(AMAZON_SW_P2_PCTL) = 0x700; +#else + AMAZON_SW_REG32(AMAZON_SW_P2_PCTL) = 0x401; +#endif + + /* EPC: 1 split the two NIC in tx direction CRC is generated */ + AMAZON_SW_REG32(AMAZON_SW_P2_CTL) = 0x6; + + // for bi-directional + AMAZON_SW_REG32(AMAZON_SW_P0_WM) = 0x14141412; + AMAZON_SW_REG32(AMAZON_SW_P1_WM) = 0x14141412; + AMAZON_SW_REG32(AMAZON_SW_P2_WM) = 0x28282826; + AMAZON_SW_REG32(AMAZON_SW_GBL_WM) = 0x0; + + AMAZON_SW_REG32(AMAZON_CGU_PLL0SR) = (AMAZON_SW_REG32(AMAZON_CGU_PLL0SR)) | 0x58000000; + // clock for PHY + AMAZON_SW_REG32(AMAZON_CGU_IFCCR) = (AMAZON_SW_REG32(AMAZON_CGU_IFCCR)) | 0x80000004; + // enable power for PHY + AMAZON_SW_REG32(AMAZON_PMU_PWDCR) = (AMAZON_SW_REG32(AMAZON_PMU_PWDCR)) | AMAZON_PMU_PWDCR_EPHY; + // set reverse MII, enable MDIO statemachine + AMAZON_SW_REG32(AMAZON_SW_MDIO_CFG) = 0x800027bf; + while (1) + if (((AMAZON_SW_REG32(AMAZON_SW_MDIO_CFG)) & 0x80000000) == 0) + break; + AMAZON_SW_REG32(AMAZON_SW_EPHY) = 0xff; + + // auto negotiation + AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) = 0x83e08000; + auto_negotiate(0x1f); + + /* enable all ports */ + AMAZON_SW_REG32(AMAZON_SW_PS_CTL) = 0x7; + for (i = 0; i < 32; i++) + write_mac_table_entry(i, 1 << 50); + return 0; +} + +static unsigned char my_ethaddr[MAX_ADDR_LEN]; +/* need to get the ether addr from u-boot */ +static int __init ethaddr_setup(char *line) +{ + char *ep; + int i; + + memset(my_ethaddr, 0, MAX_ADDR_LEN); + for (i = 0; i < 6; i++) { + my_ethaddr[i] = line ? simple_strtoul(line, &ep, 16) : 0; + if (line) + line = (*ep) ? ep + 1 : ep; + } + printk(KERN_INFO "amazon_mii0: mac address %2x-%2x-%2x-%2x-%2x-%2x \n", my_ethaddr[0], my_ethaddr[1], my_ethaddr[2], my_ethaddr[3], my_ethaddr[4], my_ethaddr[5]); + return 0; +} + +__setup("ethaddr=", ethaddr_setup); + +static void open_rx_dma(struct net_device *dev) +{ + struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev); + struct dma_device_info *dma_dev = priv->dma_device; + int i; + + for (i = 0; i < dma_dev->num_rx_chan; i++) + dma_dev->rx_chan[i].control = 1; + dma_device_update_rx(dma_dev); +} + +#ifdef CONFIG_NET_HW_FLOWCONTROL +static void close_rx_dma(struct net_device *dev) +{ + struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev); + struct dma_device_info *dma_dev = priv->dma_device; + int i; + + for (i = 0; i < dma_dev->num_rx_chan; i++) + dma_dev->rx_chan[i].control = 0; + dma_device_update_rx(dma_dev); +} + +void amazon_xon(struct net_device *dev) +{ + unsigned long flag; + local_irq_save(flag); + open_rx_dma(dev); + local_irq_restore(flag); +} +#endif + +int switch_open(struct net_device *dev) +{ + struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev); + if (!strcmp(dev->name, "eth1")) { + priv->mdio_phy_addr = PHY0_ADDR; + } + open_rx_dma(dev); + +#ifdef CONFIG_NET_HW_FLOWCONTROL + if ((priv->fc_bit = netdev_register_fc(dev, amazon_xon)) == 0) { + printk(KERN_WARNING "amazon_mii0: Hardware Flow Control register fails\n"); + } +#endif + + netif_start_queue(dev); + return OK; +} + +int switch_release(struct net_device *dev) +{ + int i; + struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev); + struct dma_device_info *dma_dev = priv->dma_device; + + for (i = 0; i < dma_dev->num_tx_chan; i++) + dma_dev->tx_chan[i].control = 0; + for (i = 0; i < dma_dev->num_rx_chan; i++) + dma_dev->rx_chan[i].control = 0; + + dma_device_update(dma_dev); + +#ifdef CONFIG_NET_HW_FLOWCONTROL + if (priv->fc_bit) { + netdev_unregister_fc(priv->fc_bit); + } +#endif + netif_stop_queue(dev); + + return OK; +} + + +void switch_rx(struct net_device *dev, int len, struct sk_buff *skb) +{ + struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev); +#ifdef CONFIG_NET_HW_FLOWCONTROL + int mit_sel = 0; +#endif + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); + +#ifdef CONFIG_NET_HW_FLOWCONTROL + mit_sel = netif_rx(skb); + switch (mit_sel) { + case NET_RX_SUCCESS: + case NET_RX_CN_LOW: + case NET_RX_CN_MOD: + break; + case NET_RX_CN_HIGH: + break; + case NET_RX_DROP: + if ((priv->fc_bit) + && (!test_and_set_bit(priv->fc_bit, &netdev_fc_xoff))) { + close_rx_dma(dev); + } + break; + } +#else + netif_rx(skb); +#endif + priv->stats.rx_packets++; + priv->stats.rx_bytes += len; + return; +} + +int asmlinkage switch_hw_tx(char *buf, int len, struct net_device *dev) +{ + struct switch_priv *priv = netdev_priv(dev); + struct dma_device_info *dma_dev = priv->dma_device; + + dma_dev->current_tx_chan = 0; + return dma_device_write(dma_dev, buf, len, priv->skb); +} + +int asmlinkage switch_tx(struct sk_buff *skb, struct net_device *dev) +{ + int len; + char *data; + struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev); + + len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; + data = skb->data; + priv->skb = skb; + dev->trans_start = jiffies; + + if (switch_hw_tx(data, len, dev) != len) { + dev_kfree_skb_any(skb); + return OK; + } + + priv->stats.tx_packets++; + priv->stats.tx_bytes += len; + return OK; +} + +void switch_tx_timeout(struct net_device *dev) +{ + struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev); + priv->stats.tx_errors++; + netif_wake_queue(dev); + return; +} + +void negotiate(struct net_device *dev) +{ + struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev); + unsigned short data = get_mdio_reg(priv->mdio_phy_addr, MDIO_ADVERTISMENT_REG); + + data &= ~(MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD | MDIO_ADVERT_10_HD); + + switch (priv->current_speed_selection) { + case 10: + if (priv->current_duplex == full) + data |= MDIO_ADVERT_10_FD; + else if (priv->current_duplex == half) + data |= MDIO_ADVERT_10_HD; + else + data |= MDIO_ADVERT_10_HD | MDIO_ADVERT_10_FD; + break; + + case 100: + if (priv->current_duplex == full) + data |= MDIO_ADVERT_100_FD; + else if (priv->current_duplex == half) + data |= MDIO_ADVERT_100_HD; + else + data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD; + break; + + case 0: /* Auto */ + if (priv->current_duplex == full) + data |= MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD; + else if (priv->current_duplex == half) + data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_10_HD; + else + data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD | MDIO_ADVERT_10_HD; + break; + + default: /* assume autoneg speed and duplex */ + data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD | MDIO_ADVERT_10_HD; + } + + set_mdio_reg(priv->mdio_phy_addr, MDIO_ADVERTISMENT_REG, data); + + /* Renegotiate with link partner */ + + data = get_mdio_reg(priv->mdio_phy_addr, MDIO_BASE_CONTROL_REG); + data |= MDIO_BC_NEGOTIATE; + + set_mdio_reg(priv->mdio_phy_addr, MDIO_BASE_CONTROL_REG, data); + +} + + +void set_duplex(struct net_device *dev, enum duplex new_duplex) +{ + struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev); + if (new_duplex != priv->current_duplex) { + priv->current_duplex = new_duplex; + negotiate(dev); + } +} + +void set_speed(struct net_device *dev, unsigned long speed) +{ + struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev); + priv->current_speed_selection = speed; + negotiate(dev); +} + +static int switch_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr) +{ + struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev); + struct ethtool_cmd ecmd; + + if (copy_from_user(&ecmd, ifr->ifr_data, sizeof(ecmd))) + return -EFAULT; + + switch (ecmd.cmd) { + case ETHTOOL_GSET: + memset((void *) &ecmd, 0, sizeof(ecmd)); + ecmd.supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; + ecmd.port = PORT_TP; + ecmd.transceiver = XCVR_EXTERNAL; + ecmd.phy_address = priv->mdio_phy_addr; + + ecmd.speed = priv->current_speed; + + ecmd.duplex = priv->full_duplex ? DUPLEX_FULL : DUPLEX_HALF; + + ecmd.advertising = ADVERTISED_TP; + if (priv->current_duplex == autoneg && priv->current_speed_selection == 0) + ecmd.advertising |= ADVERTISED_Autoneg; + else { + ecmd.advertising |= ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; + if (priv->current_speed_selection == 10) + ecmd.advertising &= ~(ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full); + else if (priv->current_speed_selection == 100) + ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full); + if (priv->current_duplex == half) + ecmd.advertising &= ~(ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Full); + else if (priv->current_duplex == full) + ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_100baseT_Half); + } + ecmd.autoneg = AUTONEG_ENABLE; + if (copy_to_user(ifr->ifr_data, &ecmd, sizeof(ecmd))) + return -EFAULT; + break; + + case ETHTOOL_SSET: + if (!capable(CAP_NET_ADMIN)) { + return -EPERM; + } + if (ecmd.autoneg == AUTONEG_ENABLE) { + set_duplex(dev, autoneg); + set_speed(dev, 0); + } else { + set_duplex(dev, ecmd.duplex == DUPLEX_HALF ? half : full); + set_speed(dev, ecmd.speed == SPEED_10 ? 10 : 100); + } + break; + + case ETHTOOL_GDRVINFO: + { + struct ethtool_drvinfo info; + memset((void *) &info, 0, sizeof(info)); + strncpy(info.driver, "AMAZONE", sizeof(info.driver) - 1); + strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1); + strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1); + info.regdump_len = 0; + info.eedump_len = 0; + info.testinfo_len = 0; + if (copy_to_user(ifr->ifr_data, &info, sizeof(info))) + return -EFAULT; + } + break; + case ETHTOOL_NWAY_RST: + if (priv->current_duplex == autoneg && priv->current_speed_selection == 0) + negotiate(dev); + break; + default: + return -EOPNOTSUPP; + break; + } + return 0; +} + + + +int mac_table_tools_ioctl(struct net_device *dev, struct mac_table_req *req) +{ + int cmd; + int i; + cmd = req->cmd; + switch (cmd) { + case RESET_MAC_TABLE: + for (i = 0; i < 32; i++) { + write_mac_table_entry(i, 0); + } + break; + case READ_MAC_ENTRY: + req->entry_value = read_mac_table_entry(req->index); + break; + case WRITE_MAC_ENTRY: + write_mac_table_entry(req->index, req->entry_value); + break; + case ADD_MAC_ENTRY: + add_mac_table_entry(req->entry_value); + break; + default: + return -EINVAL; + } + + return 0; +} + + +/* + the ioctl for the switch driver is developed in the conventional way + the control type falls into some basic categories, among them, the + SIOCETHTOOL is the traditional eth interface. VLAN_TOOLS and + MAC_TABLE_TOOLS are designed specifically for amazon chip. User + should be aware of the data structures used in these interfaces. +*/ +int switch_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct data_req *switch_data_req = (struct data_req *) ifr->ifr_data; + struct mac_table_req *switch_mac_table_req; + switch (cmd) { + case SIOCETHTOOL: + switch_ethtool_ioctl(dev, ifr); + break; + case SIOCGMIIPHY: /* Get PHY address */ + break; + case SIOCGMIIREG: /* Read MII register */ + break; + case SIOCSMIIREG: /* Write MII register */ + break; + case SET_ETH_SPEED_10: /* 10 Mbps */ + break; + case SET_ETH_SPEED_100: /* 100 Mbps */ + break; + case SET_ETH_SPEED_AUTO: /* Auto negotiate speed */ + break; + case SET_ETH_DUPLEX_HALF: /* Half duplex. */ + break; + case SET_ETH_DUPLEX_FULL: /* Full duplex. */ + break; + case SET_ETH_DUPLEX_AUTO: /* Autonegotiate duplex */ + break; + case SET_ETH_REG: + AMAZON_SW_REG32(switch_data_req->index) = switch_data_req->value; + break; + case MAC_TABLE_TOOLS: + switch_mac_table_req = (struct mac_table_req *) ifr->ifr_data; + mac_table_tools_ioctl(dev, switch_mac_table_req); + break; + default: + return -EINVAL; + } + + return 0; +} + +struct net_device_stats *switch_stats(struct net_device *dev) +{ + struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev); + return &priv->stats; +} + +int switch_change_mtu(struct net_device *dev, int new_mtu) +{ + if (new_mtu >= 1516) + new_mtu = 1516; + dev->mtu = new_mtu; + return 0; +} + +int switch_hw_receive(struct net_device *dev, struct dma_device_info *dma_dev) +{ + u8 *buf = NULL; + int len = 0; + struct sk_buff *skb = NULL; + + len = dma_device_read(dma_dev, &buf, (void **) &skb); + + if (len >= 0x600) { + printk(KERN_WARNING "amazon_mii0: packet too large %d\n", len); + goto switch_hw_receive_err_exit; + } + + /* remove CRC */ + len -= 4; + if (skb == NULL) { + printk(KERN_WARNING "amazon_mii0: cannot restore pointer\n"); + goto switch_hw_receive_err_exit; + } + if (len > (skb->end - skb->tail)) { + printk(KERN_WARNING "amazon_mii0: BUG, len:%d end:%p tail:%p\n", (len + 4), skb->end, skb->tail); + goto switch_hw_receive_err_exit; + } + skb_put(skb, len); + skb->dev = dev; + switch_rx(dev, len, skb); + return OK; + + switch_hw_receive_err_exit: + if (skb) + dev_kfree_skb_any(skb); + return -EIO; +} + +int dma_intr_handler(struct dma_device_info *dma_dev, int status) +{ + struct net_device *dev; + + dev = dma_dev->priv; + switch (status) { + case RCV_INT: + switch_hw_receive(dev, dma_dev); + break; + case TX_BUF_FULL_INT: + netif_stop_queue(dev); + break; + case TRANSMIT_CPT_INT: + netif_wake_queue(dev); + break; + } + return OK; +} + +/* reserve 2 bytes in front of data pointer*/ +u8 *dma_buffer_alloc(int len, int *byte_offset, void **opt) +{ + u8 *buffer = NULL; + struct sk_buff *skb = NULL; + skb = dev_alloc_skb(ETHERNET_PACKET_DMA_BUFFER_SIZE); + if (skb == NULL) { + return NULL; + } + buffer = (u8 *) (skb->data); + skb_reserve(skb, 2); + *(int *) opt = (int) skb; + *byte_offset = 2; + return buffer; +} + +int dma_buffer_free(u8 * dataptr, void *opt) +{ + struct sk_buff *skb = NULL; + if (opt == NULL) { + kfree(dataptr); + } else { + skb = (struct sk_buff *) opt; + dev_kfree_skb_any(skb); + } + return OK; +} + +int init_dma_device(_dma_device_info * dma_dev, struct net_device *dev) +{ + int i; + int num_tx_chan, num_rx_chan; + if (strcmp(dma_dev->device_name, "switch1") == 0) { + num_tx_chan = 1; + num_rx_chan = 2; + } else { + num_tx_chan = 1; + num_rx_chan = 2; + } + dma_dev->priv = dev; + + dma_dev->weight = 1; + dma_dev->num_tx_chan = num_tx_chan; + dma_dev->num_rx_chan = num_rx_chan; + dma_dev->ack = 1; + dma_dev->tx_burst_len = 4; + dma_dev->rx_burst_len = 4; + for (i = 0; i < dma_dev->num_tx_chan; i++) { + dma_dev->tx_chan[i].weight = QOS_DEFAULT_WGT; + dma_dev->tx_chan[i].desc_num = 10; + dma_dev->tx_chan[i].packet_size = 0; + dma_dev->tx_chan[i].control = 0; + } + for (i = 0; i < num_rx_chan; i++) { + dma_dev->rx_chan[i].weight = QOS_DEFAULT_WGT; + dma_dev->rx_chan[i].desc_num = 10; + dma_dev->rx_chan[i].packet_size = ETHERNET_PACKET_DMA_BUFFER_SIZE; + dma_dev->rx_chan[i].control = 0; + } + dma_dev->intr_handler = dma_intr_handler; + dma_dev->buffer_alloc = dma_buffer_alloc; + dma_dev->buffer_free = dma_buffer_free; + return 0; +} + +int switch_set_mac_address(struct net_device *dev, void *p) +{ + struct sockaddr *addr = p; + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + return OK; +} + +static const struct net_device_ops amazon_mii_ops = { + .ndo_init = switch_init, + .ndo_open = switch_open, + .ndo_stop = switch_release, + .ndo_start_xmit = switch_tx, + .ndo_do_ioctl = switch_ioctl, + .ndo_get_stats = switch_stats, + .ndo_change_mtu = switch_change_mtu, + .ndo_set_mac_address = switch_set_mac_address, + .ndo_tx_timeout = switch_tx_timeout, +}; + +int switch_init(struct net_device *dev) +{ + u64 retval = 0; + int i; + int result; + struct switch_priv *priv; + ether_setup(dev); /* assign some of the fields */ + printk(KERN_INFO "amazon_mii0: %s up using ", dev->name); + dev->watchdog_timeo = timeout; + + priv = netdev_priv(dev); + priv->dma_device = (struct dma_device_info *) kmalloc(sizeof(struct dma_device_info), GFP_KERNEL); + if (priv->num == 0) { + sprintf(priv->dma_device->device_name, "switch1"); + } else if (priv->num == 1) { + sprintf(priv->dma_device->device_name, "switch2"); + } + printk("\"%s\"\n", priv->dma_device->device_name); + init_dma_device(priv->dma_device, dev); + result = dma_device_register(priv->dma_device); + + /* read the mac address from the mac table and put them into the mac table. */ + for (i = 0; i < 6; i++) { + retval += my_ethaddr[i]; + } + /* ethaddr not set in u-boot ? */ + if (retval == 0) { + dev->dev_addr[0] = 0x00; + dev->dev_addr[1] = 0x20; + dev->dev_addr[2] = 0xda; + dev->dev_addr[3] = 0x86; + dev->dev_addr[4] = 0x23; + dev->dev_addr[5] = 0x74 + (unsigned char) priv->num; + } else { + for (i = 0; i < 6; i++) { + dev->dev_addr[i] = my_ethaddr[i]; + } + dev->dev_addr[5] += +(unsigned char) priv->num; + } + return OK; +} + +static int amazon_mii_probe(struct platform_device *dev) +{ + int i = 0, result, device_present = 0; + struct switch_priv *priv; + + for (i = 0; i < AMAZON_SW_INT_NO; i++) { + switch_devs[i] = alloc_etherdev(sizeof(struct switch_priv)); + switch_devs[i]->netdev_ops = &amazon_mii_ops; + strcpy(switch_devs[i]->name, "eth%d"); + priv = (struct switch_priv *) netdev_priv(switch_devs[i]); + priv->num = i; + if ((result = register_netdev(switch_devs[i]))) + printk(KERN_WARNING "amazon_mii0: error %i registering device \"%s\"\n", result, switch_devs[i]->name); + else + device_present++; + } + amazon_sw_chip_init(); + return device_present ? 0 : -ENODEV; +} + +static int amazon_mii_remove(struct platform_device *dev) +{ + int i; + struct switch_priv *priv; + for (i = 0; i < AMAZON_SW_INT_NO; i++) { + priv = netdev_priv(switch_devs[i]); + if (priv->dma_device) { + dma_device_unregister(priv->dma_device); + kfree(priv->dma_device); + } + kfree(netdev_priv(switch_devs[i])); + unregister_netdev(switch_devs[i]); + } + return 0; +} + +static struct platform_driver amazon_mii_driver = { + .probe = amazon_mii_probe, + .remove = amazon_mii_remove, + .driver = { + .name = "amazon_mii0", + .owner = THIS_MODULE, + }, +}; + +static int __init amazon_mii_init(void) +{ + int ret = platform_driver_register(&amazon_mii_driver); + if (ret) + printk(KERN_WARNING "amazon_mii0: Error registering platfom driver!\n"); + return ret; +} + +static void __exit amazon_mii_cleanup(void) +{ + platform_driver_unregister(&amazon_mii_driver); +} + +module_init(amazon_mii_init); +module_exit(amazon_mii_cleanup); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Wu Qi Ming"); +MODULE_DESCRIPTION("ethernet driver for AMAZON boards"); + diff --git a/target/linux/amazon/files/drivers/tty/serial/amazon_asc.c b/target/linux/amazon/files/drivers/tty/serial/amazon_asc.c new file mode 100644 index 000000000..bb2dd7222 --- /dev/null +++ b/target/linux/amazon/files/drivers/tty/serial/amazon_asc.c @@ -0,0 +1,711 @@ +/* + * Driver for AMAZONASC serial ports + * + * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. + * Based on drivers/serial/serial_s3c2400.c + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Copyright (C) 2004 Infineon IFAP DC COM CPE + * Copyright (C) 2007 Felix Fietkau + * Copyright (C) 2007 John Crispin + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define PORT_AMAZONASC 111 + +#include + +#define UART_NR 1 + +#define UART_DUMMY_UER_RX 1 + +#define SERIAL_AMAZONASC_MAJOR TTY_MAJOR +#define CALLOUT_AMAZONASC_MAJOR TTYAUX_MAJOR +#define SERIAL_AMAZONASC_MINOR 64 +#define SERIAL_AMAZONASC_NR UART_NR + +static void amazonasc_tx_chars(struct uart_port *port); +static struct uart_port amazonasc_ports[UART_NR]; +static struct uart_driver amazonasc_reg; +static unsigned int uartclk = 0; + +static void amazonasc_stop_tx(struct uart_port *port) +{ + /* fifo underrun shuts up after firing once */ + return; +} + +static void amazonasc_start_tx(struct uart_port *port) +{ + unsigned long flags; + + local_irq_save(flags); + amazonasc_tx_chars(port); + local_irq_restore(flags); + + return; +} + +static void amazonasc_stop_rx(struct uart_port *port) +{ + /* clear the RX enable bit */ + amazon_writel(ASCWHBCON_CLRREN, AMAZON_ASC_WHBCON); +} + +static void amazonasc_enable_ms(struct uart_port *port) +{ + /* no modem signals */ + return; +} + +#include + +static void +amazonasc_rx_chars(struct uart_port *port) +{ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31)) + struct tty_struct *tty = port->state->port.tty; +#else + struct tty_struct *tty = port->info->port.tty; +#endif + unsigned int ch = 0, rsr = 0, fifocnt; + + fifocnt = amazon_readl(AMAZON_ASC_FSTAT) & ASCFSTAT_RXFFLMASK; + while (fifocnt--) + { + u8 flag = TTY_NORMAL; + ch = amazon_readl(AMAZON_ASC_RBUF); + rsr = (amazon_readl(AMAZON_ASC_CON) & ASCCON_ANY) | UART_DUMMY_UER_RX; + tty_flip_buffer_push(tty); + port->icount.rx++; + + /* + * Note that the error handling code is + * out of the main execution path + */ + if (rsr & ASCCON_ANY) { + if (rsr & ASCCON_PE) { + port->icount.parity++; + amazon_writel_masked(AMAZON_ASC_WHBCON, ASCWHBCON_CLRPE, ASCWHBCON_CLRPE); + } else if (rsr & ASCCON_FE) { + port->icount.frame++; + amazon_writel_masked(AMAZON_ASC_WHBCON, ASCWHBCON_CLRFE, ASCWHBCON_CLRFE); + } + if (rsr & ASCCON_OE) { + port->icount.overrun++; + amazon_writel_masked(AMAZON_ASC_WHBCON, ASCWHBCON_CLROE, ASCWHBCON_CLROE); + } + + rsr &= port->read_status_mask; + + if (rsr & ASCCON_PE) + flag = TTY_PARITY; + else if (rsr & ASCCON_FE) + flag = TTY_FRAME; + } + + if ((rsr & port->ignore_status_mask) == 0) + tty_insert_flip_char(tty, ch, flag); + + if (rsr & ASCCON_OE) + /* + * Overrun is special, since it's reported + * immediately, and doesn't affect the current + * character + */ + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } + if (ch != 0) + tty_flip_buffer_push(tty); + + return; +} + + +static void amazonasc_tx_chars(struct uart_port *port) +{ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31)) + struct circ_buf *xmit = &port->state->xmit; +#else + struct circ_buf *xmit = &port->info->xmit; +#endif + + if (uart_tx_stopped(port)) { + amazonasc_stop_tx(port); + return; + } + + while (((amazon_readl(AMAZON_ASC_FSTAT) & ASCFSTAT_TXFFLMASK) + >> ASCFSTAT_TXFFLOFF) != AMAZONASC_TXFIFO_FULL) + { + if (port->x_char) { + amazon_writel(port->x_char, AMAZON_ASC_TBUF); + port->icount.tx++; + port->x_char = 0; + continue; + } + + if (uart_circ_empty(xmit)) + break; + + amazon_writel(xmit->buf[xmit->tail], AMAZON_ASC_TBUF); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + port->icount.tx++; + } + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); +} + +static irqreturn_t amazonasc_tx_int(int irq, void *port) +{ + amazon_writel(ASC_IRNCR_TIR, AMAZON_ASC_IRNCR1); + amazonasc_start_tx(port); + + /* clear any pending interrupts */ + amazon_writel_masked(AMAZON_ASC_WHBCON, + (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE), + (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE)); + + return IRQ_HANDLED; +} + +static irqreturn_t amazonasc_er_int(int irq, void *port) +{ + /* clear any pending interrupts */ + amazon_writel_masked(AMAZON_ASC_WHBCON, + (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE), + (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE)); + + return IRQ_HANDLED; +} + +static irqreturn_t amazonasc_rx_int(int irq, void *port) +{ + amazon_writel(ASC_IRNCR_RIR, AMAZON_ASC_IRNCR1); + amazonasc_rx_chars((struct uart_port *) port); + return IRQ_HANDLED; +} + +static u_int amazonasc_tx_empty(struct uart_port *port) +{ + int status; + + /* + * FSTAT tells exactly how many bytes are in the FIFO. + * The question is whether we really need to wait for all + * 16 bytes to be transmitted before reporting that the + * transmitter is empty. + */ + status = amazon_readl(AMAZON_ASC_FSTAT) & ASCFSTAT_TXFFLMASK; + return status ? 0 : TIOCSER_TEMT; +} + +static u_int amazonasc_get_mctrl(struct uart_port *port) +{ + /* no modem control signals - the readme says to pretend all are set */ + return TIOCM_CTS|TIOCM_CAR|TIOCM_DSR; +} + +static void amazonasc_set_mctrl(struct uart_port *port, u_int mctrl) +{ + /* no modem control - just return */ + return; +} + +static void amazonasc_break_ctl(struct uart_port *port, int break_state) +{ + /* no way to send a break */ + return; +} + +static int amazonasc_startup(struct uart_port *port) +{ + unsigned int con = 0; + unsigned long flags; + int retval; + + /* this assumes: CON.BRS = CON.FDE = 0 */ + if (uartclk == 0) + uartclk = amazon_get_fpi_hz(); + + amazonasc_ports[0].uartclk = uartclk; + + local_irq_save(flags); + + /* this setup was probably already done in u-boot */ + /* ASC and GPIO Port 1 bits 3 and 4 share the same pins + * P1.3 (RX) in, Alternate 10 + * P1.4 (TX) in, Alternate 10 + */ + amazon_writel_masked(AMAZON_GPIO_P1_DIR, 0x18, 0x10); //P1.4 output, P1.3 input + amazon_writel_masked(AMAZON_GPIO_P1_ALTSEL0, 0x18, 0x18); //ALTSETL0 11 + amazon_writel_masked(AMAZON_GPIO_P1_ALTSEL1, 0x18, 0); //ALTSETL1 00 + amazon_writel_masked(AMAZON_GPIO_P1_OD, 0x18, 0x10); + + /* set up the CLC */ + amazon_writel_masked(AMAZON_ASC_CLC, AMAZON_ASC_CLC_DISS, 0); + amazon_writel_masked(AMAZON_ASC_CLC, ASCCLC_RMCMASK, 1 << ASCCLC_RMCOFFSET); + + /* asynchronous mode */ + con = ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_OEN | ASCCON_PEN; + + /* choose the line - there's only one */ + amazon_writel(0, AMAZON_ASC_PISEL); + amazon_writel(((AMAZONASC_TXFIFO_FL << ASCTXFCON_TXFITLOFF) & ASCTXFCON_TXFITLMASK) | ASCTXFCON_TXFEN | ASCTXFCON_TXFFLU, + AMAZON_ASC_TXFCON); + amazon_writel(((AMAZONASC_RXFIFO_FL << ASCRXFCON_RXFITLOFF) & ASCRXFCON_RXFITLMASK) | ASCRXFCON_RXFEN | ASCRXFCON_RXFFLU, + AMAZON_ASC_RXFCON); + wmb(); + + amazon_writel_masked(AMAZON_ASC_CON, con, con); + + retval = request_irq(AMAZONASC_RIR, amazonasc_rx_int, 0, "asc_rx", port); + if (retval){ + printk("failed to request amazonasc_rx_int\n"); + return retval; + } + retval = request_irq(AMAZONASC_TIR, amazonasc_tx_int, 0, "asc_tx", port); + if (retval){ + printk("failed to request amazonasc_tx_int\n"); + goto err1; + } + + retval = request_irq(AMAZONASC_EIR, amazonasc_er_int, 0, "asc_er", port); + if (retval){ + printk("failed to request amazonasc_er_int\n"); + goto err2; + } + + local_irq_restore(flags); + return 0; + +err2: + free_irq(AMAZONASC_TIR, port); + +err1: + free_irq(AMAZONASC_RIR, port); + local_irq_restore(flags); + return retval; +} + +static void amazonasc_shutdown(struct uart_port *port) +{ + free_irq(AMAZONASC_RIR, port); + free_irq(AMAZONASC_TIR, port); + free_irq(AMAZONASC_EIR, port); + /* + * disable the baudrate generator to disable the ASC + */ + amazon_writel(0, AMAZON_ASC_CON); + + /* flush and then disable the fifos */ + amazon_writel_masked(AMAZON_ASC_RXFCON, ASCRXFCON_RXFFLU, ASCRXFCON_RXFFLU); + amazon_writel_masked(AMAZON_ASC_RXFCON, ASCRXFCON_RXFEN, 0); + amazon_writel_masked(AMAZON_ASC_TXFCON, ASCTXFCON_TXFFLU, ASCTXFCON_TXFFLU); + amazon_writel_masked(AMAZON_ASC_TXFCON, ASCTXFCON_TXFEN, 0); +} + +static void amazonasc_set_termios(struct uart_port *port, struct ktermios *new, struct ktermios *old) +{ + unsigned int cflag; + unsigned int iflag; + unsigned int baud, quot; + unsigned int con = 0; + unsigned long flags; + + cflag = new->c_cflag; + iflag = new->c_iflag; + + /* byte size and parity */ + switch (cflag & CSIZE) { + /* 7 bits are always with parity */ + case CS7: con = ASCCON_M_7ASYNCPAR; break; + /* the ASC only suports 7 and 8 bits */ + case CS5: + case CS6: + default: + if (cflag & PARENB) + con = ASCCON_M_8ASYNCPAR; + else + con = ASCCON_M_8ASYNC; + break; + } + if (cflag & CSTOPB) + con |= ASCCON_STP; + if (cflag & PARENB) { + if (!(cflag & PARODD)) + con &= ~ASCCON_ODD; + else + con |= ASCCON_ODD; + } + + port->read_status_mask = ASCCON_OE; + if (iflag & INPCK) + port->read_status_mask |= ASCCON_FE | ASCCON_PE; + + port->ignore_status_mask = 0; + if (iflag & IGNPAR) + port->ignore_status_mask |= ASCCON_FE | ASCCON_PE; + + if (iflag & IGNBRK) { + /* + * If we're ignoring parity and break indicators, + * ignore overruns too (for real raw support). + */ + if (iflag & IGNPAR) + port->ignore_status_mask |= ASCCON_OE; + } + + /* + * Ignore all characters if CREAD is not set. + */ + if ((cflag & CREAD) == 0) + port->ignore_status_mask |= UART_DUMMY_UER_RX; + + /* set error signals - framing, parity and overrun */ + con |= ASCCON_FEN; + con |= ASCCON_OEN; + con |= ASCCON_PEN; + /* enable the receiver */ + con |= ASCCON_REN; + + /* block the IRQs */ + local_irq_save(flags); + + /* set up CON */ + amazon_writel(con, AMAZON_ASC_CON); + + /* Set baud rate - take a divider of 2 into account */ + baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); + quot = uart_get_divisor(port, baud); + quot = quot/2 - 1; + + /* the next 3 probably already happened when we set CON above */ + /* disable the baudrate generator */ + amazon_writel_masked(AMAZON_ASC_CON, ASCCON_R, 0); + /* make sure the fractional divider is off */ + amazon_writel_masked(AMAZON_ASC_CON, ASCCON_FDE, 0); + /* set up to use divisor of 2 */ + amazon_writel_masked(AMAZON_ASC_CON, ASCCON_BRS, 0); + /* now we can write the new baudrate into the register */ + amazon_writel(quot, AMAZON_ASC_BTR); + /* turn the baudrate generator back on */ + amazon_writel_masked(AMAZON_ASC_CON, ASCCON_R, ASCCON_R); + + local_irq_restore(flags); +} + +static const char *amazonasc_type(struct uart_port *port) +{ + return port->type == PORT_AMAZONASC ? "AMAZONASC" : NULL; +} + +/* + * Release the memory region(s) being used by 'port' + */ +static void amazonasc_release_port(struct uart_port *port) +{ + return; +} + +/* + * Request the memory region(s) being used by 'port' + */ +static int amazonasc_request_port(struct uart_port *port) +{ + return 0; +} + +/* + * Configure/autoconfigure the port. + */ +static void amazonasc_config_port(struct uart_port *port, int flags) +{ + if (flags & UART_CONFIG_TYPE) { + port->type = PORT_AMAZONASC; + amazonasc_request_port(port); + } +} + +/* + * verify the new serial_struct (for TIOCSSERIAL). + */ +static int amazonasc_verify_port(struct uart_port *port, struct serial_struct *ser) +{ + int ret = 0; + if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMAZONASC) + ret = -EINVAL; + if (ser->irq < 0 || ser->irq >= NR_IRQS) + ret = -EINVAL; + if (ser->baud_base < 9600) + ret = -EINVAL; + return ret; +} + +static struct uart_ops amazonasc_pops = { + .tx_empty = amazonasc_tx_empty, + .set_mctrl = amazonasc_set_mctrl, + .get_mctrl = amazonasc_get_mctrl, + .stop_tx = amazonasc_stop_tx, + .start_tx = amazonasc_start_tx, + .stop_rx = amazonasc_stop_rx, + .enable_ms = amazonasc_enable_ms, + .break_ctl = amazonasc_break_ctl, + .startup = amazonasc_startup, + .shutdown = amazonasc_shutdown, + .set_termios = amazonasc_set_termios, + .type = amazonasc_type, + .release_port = amazonasc_release_port, + .request_port = amazonasc_request_port, + .config_port = amazonasc_config_port, + .verify_port = amazonasc_verify_port, +}; + +static struct uart_port amazonasc_ports[UART_NR] = { + { + membase: (void *)AMAZON_ASC, + mapbase: AMAZON_ASC, + iotype: SERIAL_IO_MEM, + irq: AMAZONASC_RIR, /* RIR */ + uartclk: 0, /* filled in dynamically */ + fifosize: 16, + unused: { AMAZONASC_TIR, AMAZONASC_EIR}, /* xmit/error/xmit-buffer-empty IRQ */ + type: PORT_AMAZONASC, + ops: &amazonasc_pops, + flags: ASYNC_BOOT_AUTOCONF, + }, +}; + +static void amazonasc_console_write(struct console *co, const char *s, u_int count) +{ + int i, fifocnt; + unsigned long flags; + local_irq_save(flags); + for (i = 0; i < count;) + { + /* wait until the FIFO is not full */ + do + { + fifocnt = (amazon_readl(AMAZON_ASC_FSTAT) & ASCFSTAT_TXFFLMASK) + >> ASCFSTAT_TXFFLOFF; + } while (fifocnt == AMAZONASC_TXFIFO_FULL); + if (s[i] == '\0') + { + break; + } + if (s[i] == '\n') + { + amazon_writel('\r', AMAZON_ASC_TBUF); + do + { + fifocnt = (amazon_readl(AMAZON_ASC_FSTAT) & + ASCFSTAT_TXFFLMASK) >> ASCFSTAT_TXFFLOFF; + } while (fifocnt == AMAZONASC_TXFIFO_FULL); + } + amazon_writel(s[i], AMAZON_ASC_TBUF); + i++; + } + + local_irq_restore(flags); +} + +static void __init +amazonasc_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits) +{ + u_int lcr_h; + + lcr_h = amazon_readl(AMAZON_ASC_CON); + /* do this only if the ASC is turned on */ + if (lcr_h & ASCCON_R) { + u_int quot, div, fdiv, frac; + + *parity = 'n'; + if ((lcr_h & ASCCON_MODEMASK) == ASCCON_M_7ASYNCPAR || + (lcr_h & ASCCON_MODEMASK) == ASCCON_M_8ASYNCPAR) { + if (lcr_h & ASCCON_ODD) + *parity = 'o'; + else + *parity = 'e'; + } + + if ((lcr_h & ASCCON_MODEMASK) == ASCCON_M_7ASYNCPAR) + *bits = 7; + else + *bits = 8; + + quot = amazon_readl(AMAZON_ASC_BTR) + 1; + + /* this gets hairy if the fractional divider is used */ + if (lcr_h & ASCCON_FDE) + { + div = 1; + fdiv = amazon_readl(AMAZON_ASC_FDV); + if (fdiv == 0) + fdiv = 512; + frac = 512; + } + else + { + div = lcr_h & ASCCON_BRS ? 3 : 2; + fdiv = frac = 1; + } + /* + * This doesn't work exactly because we use integer + * math to calculate baud which results in rounding + * errors when we try to go from quot -> baud !! + * Try to make this work for both the fractional divider + * and the simple divider. Also try to avoid rounding + * errors using integer math. + */ + + *baud = frac * (port->uartclk / (div * 512 * 16 * quot)); + if (*baud > 1100 && *baud < 2400) + *baud = 1200; + if (*baud > 2300 && *baud < 4800) + *baud = 2400; + if (*baud > 4700 && *baud < 9600) + *baud = 4800; + if (*baud > 9500 && *baud < 19200) + *baud = 9600; + if (*baud > 19000 && *baud < 38400) + *baud = 19200; + if (*baud > 38400 && *baud < 57600) + *baud = 38400; + if (*baud > 57600 && *baud < 115200) + *baud = 57600; + if (*baud > 115200 && *baud < 230400) + *baud = 115200; + } +} + +static int __init amazonasc_console_setup(struct console *co, char *options) +{ + struct uart_port *port; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + /* this assumes: CON.BRS = CON.FDE = 0 */ + if (uartclk == 0) + uartclk = amazon_get_fpi_hz(); + co->index = 0; + port = &amazonasc_ports[0]; + amazonasc_ports[0].uartclk = uartclk; + amazonasc_ports[0].type = PORT_AMAZONASC; + + if (options){ + uart_parse_options(options, &baud, &parity, &bits, &flow); + } + + return uart_set_options(port, co, baud, parity, bits, flow); +} + +static struct uart_driver amazonasc_reg; +static struct console amazonasc_console = { + name: "ttyS", + write: amazonasc_console_write, + device: uart_console_device, + setup: amazonasc_console_setup, + flags: CON_PRINTBUFFER, + index: -1, + data: &amazonasc_reg, +}; + +static struct uart_driver amazonasc_reg = { + .owner = THIS_MODULE, + .driver_name = "serial", + .dev_name = "ttyS", + .major = TTY_MAJOR, + .minor = 64, + .nr = UART_NR, + .cons = &amazonasc_console, +}; + +static int amazon_asc_probe(struct platform_device *dev) +{ + unsigned char res; + uart_register_driver(&amazonasc_reg); + res = uart_add_one_port(&amazonasc_reg, &amazonasc_ports[0]); + return res; +} + +static int amazon_asc_remove(struct platform_device *dev) +{ + uart_unregister_driver(&amazonasc_reg); + return 0; +} + +static struct platform_driver amazon_asc_driver = { + .probe = amazon_asc_probe, + .remove = amazon_asc_remove, + .driver = { + .name = "amazon_asc", + .owner = THIS_MODULE, + }, +}; + +static int __init amazon_asc_init(void) +{ + int ret = platform_driver_register(&amazon_asc_driver); + if (ret) + printk(KERN_WARNING "amazon_asc: error registering platfom driver!\n"); + return ret; +} + +static void __exit amazon_asc_cleanup(void) +{ + platform_driver_unregister(&amazon_asc_driver); +} + +module_init(amazon_asc_init); +module_exit(amazon_asc_cleanup); + +MODULE_AUTHOR("Gary Jennejohn, Felix Fietkau, John Crispin"); +MODULE_DESCRIPTION("MIPS AMAZONASC serial port driver"); +MODULE_LICENSE("GPL"); + diff --git a/target/linux/amazon/files/drivers/watchdog/amazon_wdt.c b/target/linux/amazon/files/drivers/watchdog/amazon_wdt.c new file mode 100644 index 000000000..b18296b79 --- /dev/null +++ b/target/linux/amazon/files/drivers/watchdog/amazon_wdt.c @@ -0,0 +1,277 @@ +/* + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Copyright 2004 Wu Qi Ming + * Copyright (C) 2007 John Crispin + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "AMAZON WDT:" + +#undef AMAZON_WDT_DEBUG + +static int amazon_wdt_isopen = 0; + +#ifdef AMAZON_WDT_DEBUG +static struct proc_dir_entry* amazon_wdt_dir; +#endif + +int wdt_enable(int timeout) +{ + u32 hard_psw, ffpi; + int reload_value, divider = 1; + + ffpi = amazon_get_fpi_hz(); + + reload_value = 65536 - timeout * ffpi / 256; + + if (reload_value < 0) { + divider = 0; + reload_value = 65536 - timeout * ffpi / 16384; + } + + if (reload_value < 0){ + printk(KERN_INFO DRV_NAME "timeout too large %d\n", timeout); + return -EINVAL; + } + + printk(KERN_INFO DRV_NAME "timeout:%d reload_value: %8x\n", timeout, reload_value); + + hard_psw = (amazon_readl(AMAZON_WDT_CON0) & 0xffffff01) + + (amazon_readl(AMAZON_WDT_CON1) & 0xc) + 0xf0; + amazon_writel(hard_psw, AMAZON_WDT_CON0); + wmb(); + + amazon_writel((hard_psw & 0xff00) + (reload_value << 16) + 0xf2, AMAZON_WDT_CON0); + wmb(); + + amazon_writel(divider << 2, AMAZON_WDT_CON1); + wmb(); + + hard_psw = (amazon_readl(AMAZON_WDT_CON0) & 0xffffff01) + + (amazon_readl(AMAZON_WDT_CON1) & 0xc) + 0xf0; + amazon_writel(hard_psw, AMAZON_WDT_CON0); + wmb(); + + amazon_writel_masked(AMAZON_WDT_CON0, 0xff, 0xf3); + wmb(); + return 0; +} + +void wdt_disable(void) +{ + u32 hard_psw = 0; + + hard_psw = (amazon_readl(AMAZON_WDT_CON0) & 0xffffff01) + + (amazon_readl(AMAZON_WDT_CON1) & 0xc) + 0xf0; + amazon_writel(hard_psw, AMAZON_WDT_CON0); + wmb(); + + amazon_writel_masked(AMAZON_WDT_CON0, 0xff, 0xf2); + wmb(); + + amazon_writel_masked(AMAZON_WDT_CON1, 0x8, 0x8); + wmb(); + + hard_psw=(amazon_readl(AMAZON_WDT_CON0) & 0xffffff01) + + (amazon_readl(AMAZON_WDT_CON1) & 0xc) + 0xf0; + amazon_writel(hard_psw, AMAZON_WDT_CON0); + wmb(); + + amazon_writel_masked(AMAZON_WDT_CON0, 0xff, 0xf3); + wmb(); + + return; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) +static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +#else +static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +#endif +{ + int result=0; + static int timeout=-1; + + switch(cmd){ + case AMAZON_WDT_IOC_START: + printk(KERN_INFO DRV_NAME "enable watch dog timer!\n"); + if (copy_from_user((void*)&timeout, (void*)arg, sizeof (int))) { + printk(KERN_INFO DRV_NAME "invalid argument\n"); + result=-EINVAL; + } else if ((result = wdt_enable(timeout)) < 0) { + timeout = -1; + } + break; + + case AMAZON_WDT_IOC_STOP: + printk(KERN_INFO DRV_NAME "disable watch dog timer\n"); + timeout = -1; + wdt_disable(); + break; + + case AMAZON_WDT_IOC_PING: + if (timeout < 0) { + result = -EIO; + } else { + result = wdt_enable(timeout); + } + break; + + default: + result=-EINVAL; + break; + } + return result; +} + +static ssize_t wdt_read(struct file *file, char *buf, size_t count, loff_t *offset) +{ + return 0; +} + +static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_t *offset) +{ + return count; +} + +static int wdt_open(struct inode *inode, struct file *file) +{ + if (amazon_wdt_isopen == 1) + return -EBUSY; + + amazon_wdt_isopen = 1; + printk(KERN_INFO DRV_NAME "opened\n"); + return 0; +} + +static int wdt_release(struct inode *inode, struct file *file) +{ + amazon_wdt_isopen = 0; + printk(KERN_INFO DRV_NAME "closed\n"); + return 0; +} + +#ifdef AMAZON_WDT_DEBUG +int wdt_register_proc_read(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + int len=0; + len+=sprintf(buf+len,"NMISR: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_NMISR)); + len+=sprintf(buf+len,"RST_REQ: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_RST_REQ)); + len+=sprintf(buf+len,"RST_SR: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_RST_SR)); + len+=sprintf(buf+len,"WDT_CON0: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_CON0)); + len+=sprintf(buf+len,"WDT_CON1: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_CON1)); + len+=sprintf(buf+len,"WDT_SR: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_SR)); + *eof = 1; + return len; +} +#endif + +static struct file_operations wdt_fops = { + read: wdt_read, + write: wdt_write, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) + unlocked_ioctl: wdt_ioctl, +#else + ioctl: wdt_ioctl, +#endif + open: wdt_open, + release: wdt_release, +}; + +static int amazon_wdt_probe(struct platform_device *dev) +{ + int result = result = register_chrdev(0, "watchdog", &wdt_fops); + + if (result < 0) { + printk(KERN_INFO DRV_NAME "cannot register device\n"); + return result; + } + +#ifdef AMAZON_WDT_DEBUG + amazon_wdt_dir=proc_mkdir("amazon_wdt",NULL); + create_proc_read_entry("wdt_register", 0, amazon_wdt_dir, + wdt_register_proc_read, NULL); +#endif + + amazon_wdt_isopen=0; + printk(KERN_INFO DRV_NAME "driver loaded but inactive\n"); + return 0; +} + +static int amazon_wdt_remove(struct platform_device *dev) +{ + unregister_chrdev(0, "watchdog"); +#ifdef AMAZON_WDT_DEBUG + remove_proc_entry("wdt_register", amazon_wdt_dir); + remove_proc_entry("amazon_wdt", NULL); +#endif + printk(KERN_INFO DRV_NAME "unregistered\n"); + return 0; +} + +static struct platform_driver amazon_wdt_driver = { + .probe = amazon_wdt_probe, + .remove = amazon_wdt_remove, + .driver = { + .name = "amazon_wdt", + .owner = THIS_MODULE, + }, +}; + +static int __init amazon_wdt_init(void) +{ + int ret = platform_driver_register(&amazon_wdt_driver); + if (ret) + printk(KERN_WARNING "amazon_wdt: error registering platfom driver!\n"); + return ret; +} + +static void __exit amazon_wdt_exit(void) +{ + platform_driver_unregister(&amazon_wdt_driver); +} + +module_init(amazon_wdt_init); +module_exit(amazon_wdt_exit); + +MODULE_LICENSE ("GPL"); +MODULE_AUTHOR("Infineon / John Crispin "); +MODULE_DESCRIPTION("AMAZON WDT driver"); + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/adm6996.h b/target/linux/amazon/files/include/asm-mips/amazon/adm6996.h new file mode 100644 index 000000000..77cf4b131 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/adm6996.h @@ -0,0 +1,232 @@ +/****************************************************************************** + Copyright (c) 2004, Infineon Technologies. All rights reserved. + + No Warranty + Because the program is licensed free of charge, there is no warranty for + the program, to the extent permitted by applicable law. Except when + otherwise stated in writing the copyright holders and/or other parties + provide the program "as is" without warranty of any kind, either + expressed or implied, including, but not limited to, the implied + warranties of merchantability and fitness for a particular purpose. The + entire risk as to the quality and performance of the program is with + you. should the program prove defective, you assume the cost of all + necessary servicing, repair or correction. + + In no event unless required by applicable law or agreed to in writing + will any copyright holder, or any other party who may modify and/or + redistribute the program as permitted above, be liable to you for + damages, including any general, special, incidental or consequential + damages arising out of the use or inability to use the program + (including but not limited to loss of data or data being rendered + inaccurate or losses sustained by you or third parties or a failure of + the program to operate with any other programs), even if such holder or + other party has been advised of the possibility of such damages. + ****************************************************************************** + Module : ifx_swdrv.h + Date : 2004-09-01 + Description : JoeLin + Remarks: + + *****************************************************************************/ + +#ifndef _ADM_6996_MODULE_H_ +#define _ADM_6996_MODULE_H_ + +#include + +#define ifx_printf(x) printk x + +/* command codes */ +#define ADM_SW_SMI_READ 0x02 +#define ADM_SW_SMI_WRITE 0x01 +#define ADM_SW_SMI_START 0x01 + +#define ADM_SW_EEPROM_WRITE 0x01 +#define ADM_SW_EEPROM_WRITE_ENABLE 0x03 +#define ADM_SW_EEPROM_WRITE_DISABLE 0x00 +#define EEPROM_TYPE 8 /* for 93C66 */ + +/* bit masks */ +#define ADM_SW_BIT_MASK_1 0x00000001 +#define ADM_SW_BIT_MASK_2 0x00000002 +#define ADM_SW_BIT_MASK_4 0x00000008 +#define ADM_SW_BIT_MASK_10 0x00000200 +#define ADM_SW_BIT_MASK_16 0x00008000 +#define ADM_SW_BIT_MASK_32 0x80000000 + +/* delay timers */ +#define ADM_SW_MDC_DOWN_DELAY 5 +#define ADM_SW_MDC_UP_DELAY 5 +#define ADM_SW_CS_DELAY 5 + +/* MDIO modes */ +#define ADM_SW_MDIO_OUTPUT 1 +#define ADM_SW_MDIO_INPUT 0 + +#define ADM_SW_MAX_PORT_NUM 5 +#define ADM_SW_MAX_VLAN_NUM 15 + +/* registers */ +#define ADM_SW_PORT0_CONF 0x1 +#define ADM_SW_PORT1_CONF 0x3 +#define ADM_SW_PORT2_CONF 0x5 +#define ADM_SW_PORT3_CONF 0x7 +#define ADM_SW_PORT4_CONF 0x8 +#define ADM_SW_PORT5_CONF 0x9 +#define ADM_SW_VLAN_MODE 0x11 +#define ADM_SW_MAC_LOCK 0x12 +#define ADM_SW_VLAN0_CONF 0x13 +#define ADM_SW_PORT0_PVID 0x28 +#define ADM_SW_PORT1_PVID 0x29 +#define ADM_SW_PORT2_PVID 0x2a +#define ADM_SW_PORT34_PVID 0x2b +#define ADM_SW_PORT5_PVID 0x2c +#define ADM_SW_PHY_RESET 0x2f +#define ADM_SW_MISC_CONF 0x30 +#define ADM_SW_BNDWDH_CTL0 0x31 +#define ADM_SW_BNDWDH_CTL1 0x32 +#define ADM_SW_BNDWDH_CTL_ENA 0x33 + +/* port modes */ +#define ADM_SW_PORT_FLOWCTL 0x1 /* 802.3x flow control */ +#define ADM_SW_PORT_AN 0x2 /* auto negotiation */ +#define ADM_SW_PORT_100M 0x4 /* 100M */ +#define ADM_SW_PORT_FULL 0x8 /* full duplex */ +#define ADM_SW_PORT_TAG 0x10 /* output tag on */ +#define ADM_SW_PORT_DISABLE 0x20 /* disable port */ +#define ADM_SW_PORT_TOS 0x40 /* TOS first */ +#define ADM_SW_PORT_PPRI 0x80 /* port based priority first */ +#define ADM_SW_PORT_MDIX 0x8000 /* auto MDIX on */ +#define ADM_SW_PORT_PVID_SHIFT 10 +#define ADM_SW_PORT_PVID_BITS 4 + +/* VLAN */ +#define ADM_SW_VLAN_PORT0 0x1 +#define ADM_SW_VLAN_PORT1 0x2 +#define ADM_SW_VLAN_PORT2 0x10 +#define ADM_SW_VLAN_PORT3 0x40 +#define ADM_SW_VLAN_PORT4 0x80 +#define ADM_SW_VLAN_PORT5 0x100 + + +/* GPIO 012 enabled, output mode */ +#define GPIO_ENABLEBITS 0x000700f8 + +/* + define AMAZON GPIO port to ADM6996 EEPROM interface + MDIO -> EEDI GPIO 16, AMAZON GPIO P1.0, bi-direction + MDC -> EESK GPIO 17, AMAZON GPIO P1.1, output only + MDCS -> EECS GPIO 18, AMAZON GPIO P1.2, output only + EEDO GPIO 15, AMAZON GPIO P0.15, do not need this one! */ + +#define GPIO_MDIO 1 //P1.0 +#define GPIO_MDC 2 //P1.1 +#define GPIO_MDCS 4 //P1.2 + +//joelin #define GPIO_MDIO 0 +//joelin #define GPIO_MDC 5 /* PORT 0 GPIO5 */ +//joelin #define GPIO_MDCS 6 /* PORT 0 GPIO6 */ + + +#define MDIO_INPUT 0x00000001 +#define MDIO_OUTPUT_EN 0x00010000 + + +/* type definitions */ +typedef unsigned char U8; +typedef unsigned short U16; +typedef unsigned int U32; + +typedef struct _REGRW_ +{ + unsigned int addr; + unsigned int value; + unsigned int mode; +}REGRW, *PREGRW; + +//joelin adm6996i +typedef struct _MACENTRY_ +{ + unsigned char mac_addr[6]; + unsigned long fid:4; + unsigned long portmap:6; + union { + unsigned long age_timer:9; + unsigned long info_ctrl:9; + } ctrl; + unsigned long occupy:1; + unsigned long info_type:1; + unsigned long bad:1; + unsigned long result:3;//000:command ok ,001:all entry used,010:Entry Not found ,011:try next entry ,101:command error + + }MACENTRY, *PMACENTRY; +typedef struct _PROTOCOLFILTER_ +{ + int protocol_filter_num;//[0~7] + int ip_p; //Value Compared with Protocol in IP Heade[7:0] + char action:2;//Action for protocol Filter . +//00 = Protocol Portmap is Default Output Ports. +//01 = Protocol Portmap is 6'b0. +//10 = Protocol Portmap is the CPU port if the incoming port +//is not the CPU port. But if the incoming port is the CPU port, then Type Portmap contains Default Output Ports, excluding the CPU port. + }PROTOCOLFILTER, *PPROTOCOLFILTER; + +//joelin adm6996i + +/* Santosh: for IGMP proxy/snooping */ + +//050614:fchang int adm_process_mac_table_request (unsigned int cmd, struct _MACENTRY_ *mac); +//050614:fchang int adm_process_protocol_filter_request (unsigned int cmd, struct _PROTOCOLFILTER_ *filter); + + +/* IOCTL keys */ +#define KEY_IOCTL_ADM_REGRW 0x01 +#define KEY_IOCTL_ADM_SW_REGRW 0x02 +#define KEY_IOCTL_ADM_SW_PORTSTS 0x03 +#define KEY_IOCTL_ADM_SW_INIT 0x04 +//for adm6996i-start +#define KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_ADD 0x05 +#define KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_DEL 0x06 +#define KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_GET_INIT 0x07 +#define KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_GET_MORE 0x08 +#define KEY_IOCTL_ADM_SW_IOCTL_FILTER_ADD 0x09 +#define KEY_IOCTL_ADM_SW_IOCTL_FILTER_DEL 0x0a +#define KEY_IOCTL_ADM_SW_IOCTL_FILTER_GET 0x0b + +//adm6996i #define KEY_IOCTL_MAX_KEY 0x05 +#define KEY_IOCTL_MAX_KEY 0x0c +//for adm6996i-end +/* IOCTL MAGIC */ +#define ADM_MAGIC ('a'|'d'|'m'|'t'|'e'|'k') + +/* IOCTL parameters */ +#define ADM_IOCTL_REGRW _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_REGRW, REGRW) +#define ADM_SW_IOCTL_REGRW _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_REGRW, REGRW) +#define ADM_SW_IOCTL_PORTSTS _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_PORTSTS, NULL) +#define ADM_SW_IOCTL_INIT _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_INIT, NULL) + + +//6996i-stat +#define ADM_SW_IOCTL_MACENTRY_ADD _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_ADD,MACENTRY) +#define ADM_SW_IOCTL_MACENTRY_DEL _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_DEL,MACENTRY) +#define ADM_SW_IOCTL_MACENTRY_GET_INIT _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_GET_INIT,MACENTRY) +#define ADM_SW_IOCTL_MACENTRY_GET_MORE _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_GET_MORE,MACENTRY) +#define ADM_SW_IOCTL_FILTER_ADD _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_FILTER_ADD,PROTOCOLFILTER) +#define ADM_SW_IOCTL_FILTER_DEL _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_FILTER_DEL,PROTOCOLFILTER) +#define ADM_SW_IOCTL_FILTER_GET _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_FILTER_GET,PROTOCOLFILTER) + +//6996i-end + + +#define REG_READ 0x0 +#define REG_WRITE 0x1 + +/* undefine symbol */ +#define AMAZON_SW_REG(reg) *((volatile U32*)(reg)) +//#define GPIO0_INPUT_MASK 0 +//#define GPIO_conf0_REG 0x12345678 +//#define GPIO_SET_HI +//#define GPIO_SET_LOW + +#endif +/* _ADM_6996_MODULE_H_ */ diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon.h new file mode 100644 index 000000000..28af7f59d --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon.h @@ -0,0 +1,1447 @@ +#ifndef AMAZON_H +#define AMAZON_H +/****************************************************************************** + Copyright (c) 2002, Infineon Technologies. All rights reserved. + + No Warranty + Because the program is licensed free of charge, there is no warranty for + the program, to the extent permitted by applicable law. Except when + otherwise stated in writing the copyright holders and/or other parties + provide the program "as is" without warranty of any kind, either + expressed or implied, including, but not limited to, the implied + warranties of merchantability and fitness for a particular purpose. The + entire risk as to the quality and performance of the program is with + you. should the program prove defective, you assume the cost of all + necessary servicing, repair or correction. + + In no event unless required by applicable law or agreed to in writing + will any copyright holder, or any other party who may modify and/or + redistribute the program as permitted above, be liable to you for + damages, including any general, special, incidental or consequential + damages arising out of the use or inability to use the program + (including but not limited to loss of data or data being rendered + inaccurate or losses sustained by you or third parties or a failure of + the program to operate with any other programs), even if such holder or + other party has been advised of the possibility of such damages. +******************************************************************************/ + +#define amazon_readl(a) __raw_readl(((u32*)(a))) +#define amazon_writel(a,b) __raw_writel(a, ((u32*)(b))) +#define amazon_writel_masked(a,b,c) __raw_writel((__raw_readl(((u32*)(a))) & ~b) | (c & b), ((u32*)(a))) + +unsigned int amazon_get_fpi_hz(void); + +#define IOPORT_RESOURCE_START 0x10000000 +#define IOPORT_RESOURCE_END 0xffffffff +#define IOMEM_RESOURCE_START 0x10000000 +#define IOMEM_RESOURCE_END 0xffffffff + +/* check ADSL link status */ +#define AMAZON_CHECK_LINK + +/***********************************************************************/ +/* Module : WDT register address and bits */ +/***********************************************************************/ + +#define AMAZON_WDT (KSEG1+0x10100900) +/***********************************************************************/ + +/***Reset Request Register***/ +#define AMAZON_RST_REQ ((volatile u32*)(AMAZON_WDT+ 0x0010)) +#define AMAZON_RST_REQ_PLL (1 << 31) +#define AMAZON_RST_REQ_PCI_CORE (1 << 13) +#define AMAZON_RST_REQ_TPE (1 << 12) +#define AMAZON_RST_REQ_AFE (1 << 11) +#define AMAZON_RST_REQ_DMA (1 << 9) +#define AMAZON_RST_REQ_SWITCH (1 << 8) +#define AMAZON_RST_REQ_DFE (1 << 7) +#define AMAZON_RST_REQ_PHY (1 << 5) +#define AMAZON_RST_REQ_PCI (1 << 4) +#define AMAZON_RST_REQ_FPI (1 << 2) +#define AMAZON_RST_REQ_CPU (1 << 1) +#define AMAZON_RST_REQ_HRST (1 << 0) +#define AMAZON_RST_ALL (AMAZON_RST_REQ_PLL \ + |AMAZON_RST_REQ_PCI_CORE \ + |AMAZON_RST_REQ_TPE \ + |AMAZON_RST_REQ_AFE \ + |AMAZON_RST_REQ_DMA \ + |AMAZON_RST_REQ_SWITCH \ + |AMAZON_RST_REQ_DFE \ + |AMAZON_RST_REQ_PHY \ + |AMAZON_RST_REQ_PCI \ + |AMAZON_RST_REQ_FPI \ + |AMAZON_RST_REQ_CPU \ + |AMAZON_RST_REQ_HRST) + +/***Reset Status Register Power On***/ +#define AMAZON_RST_SR ((volatile u32*)(AMAZON_WDT+ 0x0014)) + +/***Watchdog Timer Control Register 0***/ +#define AMAZON_WDT_CON0 ((volatile u32*)(AMAZON_WDT+ 0x0020)) + +/***Watchdog Timer Control Register 1***/ +#define AMAZON_WDT_CON1 ((volatile u32*)(AMAZON_WDT+ 0x0024)) +#define AMAZON_WDT_CON1_WDTDR (1 << 3) +#define AMAZON_WDT_CON1_WDTIR (1 << 2) + +/***Watchdog Timer Status Register***/ +#define AMAZON_WDT_SR ((volatile u32*)(AMAZON_WDT+ 0x0028)) +#define AMAZON_WDT_SR_WDTTIM(value) (((( 1 << 16) - 1) & (value)) << 16) +#define AMAZON_WDT_SR_WDTPR (1 << 5) +#define AMAZON_WDT_SR_WDTTO (1 << 4) +#define AMAZON_WDT_SR_WDTDS (1 << 3) +#define AMAZON_WDT_SR_WDTIS (1 << 2) +#define AMAZON_WDT_SR_WDTOE (1 << 1) +#define AMAZON_WDT_SR_WDTAE (1 << 0) + +/***NMI Status Register***/ +#define AMAZON_WDT_NMISR ((volatile u32*)(AMAZON_WDT+ 0x002C)) +#define AMAZON_WDT_NMISR_NMIWDT (1 << 2) +#define AMAZON_WDT_NMISR_NMIPLL (1 << 1) +#define AMAZON_WDT_NMISR_NMIEXT (1 << 0) + +#define AMAZON_WDT_RST_MON ((volatile u32*)(AMAZON_WDT+ 0x0030)) + +/***********************************************************************/ +/* Module : MCD register address and bits */ +/***********************************************************************/ +#define AMAZON_MCD (KSEG1+0x1F106000) + +/***Manufacturer Identification Register***/ +#define AMAZON_MCD_MANID ((volatile u32*)(AMAZON_MCD+ 0x0024)) +#define AMAZON_MCD_MANID_MANUF(value) (((( 1 << 11) - 1) & (value)) << 5) + +/***Chip Identification Register***/ +#define AMAZON_MCD_CHIPID ((volatile u32*)(AMAZON_MCD+ 0x0028)) +#define AMAZON_MCD_CHIPID_VERSION_GET(value) (((value) >> 28) & ((1 << 4) - 1)) +#define AMAZON_MCD_CHIPID_VERSION_SET(value) (((( 1 << 4) - 1) & (value)) << 28) +#define AMAZON_MCD_CHIPID_PART_NUMBER_GET(value) (((value) >> 12) & ((1 << 16) - 1)) +#define AMAZON_MCD_CHIPID_PART_NUMBER_SET(value) (((( 1 << 16) - 1) & (value)) << 12) +#define AMAZON_MCD_CHIPID_MANID_GET(value) (((value) >> 1) & ((1 << 11) - 1)) +#define AMAZON_MCD_CHIPID_MANID_SET(value) (((( 1 << 11) - 1) & (value)) << 1) + +#define AMAZON_CHIPID_STANDARD 0x00EB +#define AMAZON_CHIPID_YANGTSE 0x00ED + +/***Redesign Tracing Identification Register***/ +#define AMAZON_MCD_RTID ((volatile u32*)(AMAZON_MCD+ 0x002C)) +#define AMAZON_MCD_RTID_LC (1 << 15) +#define AMAZON_MCD_RTID_RIX(value) (((( 1 << 3) - 1) & (value)) << 0) + + +/***********************************************************************/ +/* Module : CGU register address and bits */ +/***********************************************************************/ + +#define AMAZON_CGU (KSEG1+0x1F103000) +/***********************************************************************/ + +/***CGU Clock Divider Select Register***/ +#define AMAZON_CGU_DIV (AMAZON_CGU + 0x0000) +/***CGU PLL0 Status Register***/ +#define AMAZON_CGU_PLL0SR (AMAZON_CGU + 0x0004) +/***CGU PLL1 Status Register***/ +#define AMAZON_CGU_PLL1SR (AMAZON_CGU + 0x0008) +/***CGU Interface Clock Control Register***/ +#define AMAZON_CGU_IFCCR (AMAZON_CGU + 0x000c) +/***CGU Oscillator Control Register***/ +#define AMAZON_CGU_OSCCR (AMAZON_CGU + 0x0010) +/***CGU Memory Clock Delay Register***/ +#define AMAZON_CGU_MCDEL (AMAZON_CGU + 0x0014) +/***CGU CPU Clock Reduction Register***/ +#define AMAZON_CGU_CPUCRD (AMAZON_CGU + 0x0018) +/***CGU Test Register**/ +#define AMAZON_CGU_TST (AMAZON_CGU + 0x003c) + +/***********************************************************************/ +/* Module : PMU register address and bits */ +/***********************************************************************/ + +#define AMAZON_PMU AMAZON_CGU +/***********************************************************************/ + + +/***PMU Power Down Control Register***/ +#define AMAZON_PMU_PWDCR ((volatile u32*)(AMAZON_PMU+ 0x001c)) +#define AMAZON_PMU_PWDCR_TPE (1 << 13) +#define AMAZON_PMU_PWDCR_PLL (1 << 12) +#define AMAZON_PMU_PWDCR_XTAL (1 << 11) +#define AMAZON_PMU_PWDCR_EBU (1 << 10) +#define AMAZON_PMU_PWDCR_DFE (1 << 9) +#define AMAZON_PMU_PWDCR_SPI (1 << 8) +#define AMAZON_PMU_PWDCR_UART (1 << 7) +#define AMAZON_PMU_PWDCR_GPT (1 << 6) +#define AMAZON_PMU_PWDCR_DMA (1 << 5) +#define AMAZON_PMU_PWDCR_PCI (1 << 4) +#define AMAZON_PMU_PWDCR_SW (1 << 3) +#define AMAZON_PMU_PWDCR_IOR (1 << 2) +#define AMAZON_PMU_PWDCR_FPI (1 << 1) +#define AMAZON_PMU_PWDCR_EPHY (1 << 0) + +/***PMU Status Register***/ +#define AMAZON_PMU_SR ((volatile u32*)(AMAZON_PMU+ 0x0020)) +#define AMAZON_PMU_SR_TPE (1 << 13) +#define AMAZON_PMU_SR_PLL (1 << 12) +#define AMAZON_PMU_SR_XTAL (1 << 11) +#define AMAZON_PMU_SR_EBU (1 << 10) +#define AMAZON_PMU_SR_DFE (1 << 9) +#define AMAZON_PMU_SR_SPI (1 << 8) +#define AMAZON_PMU_SR_UART (1 << 7) +#define AMAZON_PMU_SR_GPT (1 << 6) +#define AMAZON_PMU_SR_DMA (1 << 5) +#define AMAZON_PMU_SR_PCI (1 << 4) +#define AMAZON_PMU_SR_SW (1 << 3) +#define AMAZON_PMU_SR_IOR (1 << 2) +#define AMAZON_PMU_SR_FPI (1 << 1) +#define AMAZON_PMU_SR_EPHY (1 << 0) + +/***********************************************************************/ +/* Module : BCU register address and bits */ +/***********************************************************************/ + +#define AMAZON_BCU (KSEG1+0x10100000) +/***********************************************************************/ + + +/***BCU Control Register (0010H)***/ +#define AMAZON_BCU_CON ((volatile u32*)(AMAZON_BCU+ 0x0010)) +#define AMAZON_BCU_CON_SPC(value) (((( 1 << 8) - 1) & (value)) << 24) +#define AMAZON_BCU_CON_SPE (1 << 19) +#define AMAZON_BCU_CON_PSE (1 << 18) +#define AMAZON_BCU_CON_DBG (1 << 16) +#define AMAZON_BCU_CON_TOUT(value) (((( 1 << 16) - 1) & (value)) << 0) + +/***BCU Error Control Capture Register (0020H)***/ +#define AMAZON_BCU_ECON ((volatile u32*)(AMAZON_BCU+ 0x0020)) +#define AMAZON_BCU_ECON_TAG(value) (((( 1 << 4) - 1) & (value)) << 24) +#define AMAZON_BCU_ECON_RDN (1 << 23) +#define AMAZON_BCU_ECON_WRN (1 << 22) +#define AMAZON_BCU_ECON_SVM (1 << 21) +#define AMAZON_BCU_ECON_ACK(value) (((( 1 << 2) - 1) & (value)) << 19) +#define AMAZON_BCU_ECON_ABT (1 << 18) +#define AMAZON_BCU_ECON_RDY (1 << 17) +#define AMAZON_BCU_ECON_TOUT (1 << 16) +#define AMAZON_BCU_ECON_ERRCNT(value) (((( 1 << 16) - 1) & (value)) << 0) +#define AMAZON_BCU_ECON_OPC(value) (((( 1 << 4) - 1) & (value)) << 28) + +/***BCU Error Address Capture Register (0024 H)***/ +#define AMAZON_BCU_EADD ((volatile u32*)(AMAZON_BCU+ 0x0024)) +#define AMAZON_BCU_EADD_FPIADR + +/***BCU Error Data Capture Register (0028H)***/ +#define AMAZON_BCU_EDAT ((volatile u32*)(AMAZON_BCU+ 0x0028)) +#define AMAZON_BCU_EDAT_FPIDAT + +/***********************************************************************/ +/* Module : Switch register address and bits */ +/***********************************************************************/ + +#define AMAZON_SWITCH (KSEG1+0x10106000) +/***********************************************************************/ +#define AMAZON_SW_UN_DEST AMAZON_SWITCH+0x00 /*Unknown destination register*/ +#define AMAZON_SW_VLAN_CTRL AMAZON_SWITCH+0x04 /*VLAN control register*/ +#define AMAZON_SW_PS_CTL AMAZON_SWITCH+0x08 /*port status control register*/ +#define AMAZON_SW_COS_CTL AMAZON_SWITCH+0x0c /*Cos control register*/ +#define AMAZON_SW_VLAN_COS AMAZON_SWITCH+0x10 /*VLAN priority cos mapping register*/ +#define AMAZON_SW_DSCP_COS3 AMAZON_SWITCH+0x14 /*DSCP cos mapping register3*/ +#define AMAZON_SW_DSCP_COS2 AMAZON_SWITCH+0x18 /*DSCP cos mapping register2*/ +#define AMAZON_SW_DSCP_COS1 AMAZON_SWITCH+0x1c /*DSCP cos mapping register1*/ +#define AMAZON_SW_DSCP_COS0 AMAZON_SWITCH+0x20 /*DSCP cos mapping register*/ +#define AMAZON_SW_ARL_CTL AMAZON_SWITCH+0x24 /*ARL control register*/ +#define AMAZON_SW_PKT_LEN AMAZON_SWITCH+0x28 /*packet length register*/ +#define AMAZON_SW_CPU_ACTL AMAZON_SWITCH+0x2c /*CPU control register1*/ +#define AMAZON_SW_DATA1 AMAZON_SWITCH+0x30 /*CPU access control register1*/ +#define AMAZON_SW_DATA2 AMAZON_SWITCH+0x34 /*CPU access control register2*/ +#define AMAZON_SW_P2_PCTL AMAZON_SWITCH+0x38 /*Port2 control register*/ +#define AMAZON_SW_P0_TX_CTL AMAZON_SWITCH+0x3c /*port0 TX control register*/ +#define AMAZON_SW_P1_TX_CTL AMAZON_SWITCH+0x40 /*port 1 TX control register*/ +#define AMAZON_SW_P0_WM AMAZON_SWITCH+0x44 /*port 0 watermark control register*/ +#define AMAZON_SW_P1_WM AMAZON_SWITCH+0x48 /*port 1 watermark control register*/ +#define AMAZON_SW_P2_WM AMAZON_SWITCH+0x4c /*port 2 watermark control register*/ +#define AMAZON_SW_GBL_WM AMAZON_SWITCH+0x50 /*Global watermark register*/ +#define AMAZON_SW_PM_CTL AMAZON_SWITCH+0x54 /*PM control register*/ +#define AMAZON_SW_P2_CTL AMAZON_SWITCH+0x58 /*PMAC control register*/ +#define AMAZON_SW_P2_TX_IPG AMAZON_SWITCH+0x5c /*port2 TX IPG control register*/ +#define AMAZON_SW_P2_RX_IPG AMAZON_SWITCH+0x60 /*prot2 RX IPG control register*/ +#define AMAZON_SW_MDIO_ACC AMAZON_SWITCH+0x64 /*MDIO access register*/ +#define AMAZON_SW_EPHY AMAZON_SWITCH+0x68 /*Ethernet PHY register*/ +#define AMAZON_SW_MDIO_CFG AMAZON_SWITCH+0x6c /*MDIO configuration register*/ +#define AMAZON_SW_P0_RCV_DROP_CNT AMAZON_SWITCH+0x70 /*port0 receive drop counter */ +#define AMAZON_SW_P0_RCV_FRAME_ERR_CNT AMAZON_SWITCH+0x74 /*port0 receive frame error conter*/ +#define AMAZON_SW_P0_TX_COLL_CNT AMAZON_SWITCH+0x78 /*port0 transmit collision counter*/ +#define AMAZON_SW_P0_TX_DROP_CNT AMAZON_SWITCH+0x7c /*port1 transmit drop counter*/ +#define AMAZON_SW_P1_RCV_DROP_CNT AMAZON_SWITCH+0x80 /*port1 receive drop counter*/ +#define AMAZON_SW_P1_RCV_FRAME_ERR_CNT AMAZON_SWITCH+0x84 /*port1 receive error counter*/ +#define AMAZON_SW_P1_TX_COLL_CNT AMAZON_SWITCH+0x88 /*port1 transmit collision counter*/ +#define AMAZON_SW_P1_TX_DROP_CNT AMAZON_SWITCH+0x8c /*port1 transmit drop counter*/ + + + +/***********************************************************************/ +/* Module : SSC register address and bits */ +/***********************************************************************/ +#define AMAZON_SSC_BASE_ADD_0 (KSEG1+0x10100800) + +/*165001:henryhsu:20050603:Source add by Bing Tao*/ + +/*configuration/Status Registers in Bus Clock Domain*/ +#define AMAZON_SSC_CLC ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0000)) +#define AMAZON_SSC_ID ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0008)) +#define AMAZON_SSC_CON ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0010)) +#define AMAZON_SSC_STATE ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0014)) +#define AMAZON_SSC_WHBSTATE ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0018)) +#define AMAZON_SSC_TB ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0020)) +#define AMAZON_SSC_RB ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0024)) +#define AMAZON_SSC_FSTAT ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0038)) + +/*Configuration/Status Registers in Kernel Clock Domain*/ +#define AMAZON_SSC_PISEL ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0004)) +#define AMAZON_SSC_RXFCON ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0030)) +#define AMAZON_SSC_TXFCON ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0034)) +#define AMAZON_SSC_BR ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0040)) +#define AMAZON_SSC_BRSTAT ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0044)) +#define AMAZON_SSC_SFCON ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0060)) +#define AMAZON_SSC_SFSTAT ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0064)) +#define AMAZON_SSC_GPOCON ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0070)) +#define AMAZON_SSC_GPOSTAT ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0074)) +#define AMAZON_SSC_WHBGPOSTAT ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0078)) +#define AMAZON_SSC_RXREQ ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0080)) +#define AMAZON_SSC_RXCNT ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0084)) + +/*DMA Registers in Bus Clock Domain*/ +#define AMAZON_SSC_DMA_CON ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x00ec)) + +/*interrupt Node Registers in Bus Clock Domain*/ +#define AMAZON_SSC_IRNEN ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x00F4)) +#define AMAZON_SSC_IRNICR ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x00FC)) +#define AMAZON_SSC_IRNCR ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x00F8)) + +/*165001*/ + +/***********************************************************************/ + + + +/***********************************************************************/ +/* Module : EBU register address and bits */ +/***********************************************************************/ + +#define AMAZON_EBU (KSEG1+0x10105300) +/***********************************************************************/ + + +/***EBU Clock Control Register***/ +#define AMAZON_EBU_CLC ((volatile u32*)(AMAZON_EBU+ 0x0000)) +#define AMAZON_EBU_CLC_DISS (1 << 1) +#define AMAZON_EBU_CLC_DISR (1 << 0) + +/***EBU Global Control Register***/ +#define AMAZON_EBU_CON ((volatile u32*)(AMAZON_EBU+ 0x0010)) +#define AMAZON_EBU_CON_DTACS(value) (((( 1 << 3) - 1) & (value)) << 20) +#define AMAZON_EBU_CON_DTARW(value) (((( 1 << 3) - 1) & (value)) << 16) +#define AMAZON_EBU_CON_TOUTC(value) (((( 1 << 8) - 1) & (value)) << 8) +#define AMAZON_EBU_CON_ARBMODE(value) (((( 1 << 2) - 1) & (value)) << 6) +#define AMAZON_EBU_CON_ARBSYNC (1 << 5) +#define AMAZON_EBU_CON_1 (1 << 3) + +/***EBU Address Select Register 0***/ +#define AMAZON_EBU_ADDSEL0 ((volatile u32*)(AMAZON_EBU+ 0x0020)) +#define AMAZON_EBU_ADDSEL0_BASE(value) (((( 1 << 20) - 1) & (value)) << 12) +#define AMAZON_EBU_ADDSEL0_MASK(value) (((( 1 << 4) - 1) & (value)) << 4) +#define AMAZON_EBU_ADDSEL0_MIRRORE (1 << 1) +#define AMAZON_EBU_ADDSEL0_REGEN (1 << 0) + +/***EBU Address Select Register 1***/ +#define AMAZON_EBU_ADDSEL1 ((volatile u32*)(AMAZON_EBU+ 0x0024)) +#define AMAZON_EBU_ADDSEL1_BASE(value) (((( 1 << 20) - 1) & (value)) << 12) +#define AMAZON_EBU_ADDSEL1_MASK(value) (((( 1 << 4) - 1) & (value)) << 4) +#define AMAZON_EBU_ADDSEL1_MIRRORE (1 << 1) +#define AMAZON_EBU_ADDSEL1_REGEN (1 << 0) + +/***EBU Address Select Register 2***/ +#define AMAZON_EBU_ADDSEL2 ((volatile u32*)(AMAZON_EBU+ 0x0028)) +#define AMAZON_EBU_ADDSEL2_BASE(value) (((( 1 << 20) - 1) & (value)) << 12) +#define AMAZON_EBU_ADDSEL2_MASK(value) (((( 1 << 4) - 1) & (value)) << 4) +#define AMAZON_EBU_ADDSEL2_MIRRORE (1 << 1) +#define AMAZON_EBU_ADDSEL2_REGEN (1 << 0) + +/***EBU Bus Configuration Register 0***/ +#define AMAZON_EBU_BUSCON0 ((volatile u32*)(AMAZON_EBU+ 0x0060)) +#define AMAZON_EBU_BUSCON0_WRDIS (1 << 31) +#define AMAZON_EBU_BUSCON0_ALEC(value) (((( 1 << 2) - 1) & (value)) << 29) +#define AMAZON_EBU_BUSCON0_BCGEN(value) (((( 1 << 2) - 1) & (value)) << 27) +#define AMAZON_EBU_BUSCON0_AGEN(value) (((( 1 << 2) - 1) & (value)) << 24) +#define AMAZON_EBU_BUSCON0_CMULTR(value) (((( 1 << 2) - 1) & (value)) << 22) +#define AMAZON_EBU_BUSCON0_WAIT(value) (((( 1 << 2) - 1) & (value)) << 20) +#define AMAZON_EBU_BUSCON0_WAITINV (1 << 19) +#define AMAZON_EBU_BUSCON0_SETUP (1 << 18) +#define AMAZON_EBU_BUSCON0_PORTW(value) (((( 1 << 2) - 1) & (value)) << 16) +#define AMAZON_EBU_BUSCON0_WAITRDC(value) (((( 1 << 7) - 1) & (value)) << 9) +#define AMAZON_EBU_BUSCON0_WAITWRC(value) (((( 1 << 3) - 1) & (value)) << 6) +#define AMAZON_EBU_BUSCON0_HOLDC(value) (((( 1 << 2) - 1) & (value)) << 4) +#define AMAZON_EBU_BUSCON0_RECOVC(value) (((( 1 << 2) - 1) & (value)) << 2) +#define AMAZON_EBU_BUSCON0_CMULT(value) (((( 1 << 2) - 1) & (value)) << 0) + +/***EBU Bus Configuration Register 1***/ +#define AMAZON_EBU_BUSCON1 ((volatile u32*)(AMAZON_EBU+ 0x0064)) +#define AMAZON_EBU_BUSCON1_WRDIS (1 << 31) +#define AMAZON_EBU_BUSCON1_ALEC(value) (((( 1 << 2) - 1) & (value)) << 29) +#define AMAZON_EBU_BUSCON1_BCGEN(value) (((( 1 << 2) - 1) & (value)) << 27) +#define AMAZON_EBU_BUSCON1_AGEN(value) (((( 1 << 2) - 1) & (value)) << 24) +#define AMAZON_EBU_BUSCON1_CMULTR(value) (((( 1 << 2) - 1) & (value)) << 22) +#define AMAZON_EBU_BUSCON1_WAIT(value) (((( 1 << 2) - 1) & (value)) << 20) +#define AMAZON_EBU_BUSCON1_WAITINV (1 << 19) +#define AMAZON_EBU_BUSCON1_SETUP (1 << 18) +#define AMAZON_EBU_BUSCON1_PORTW(value) (((( 1 << 2) - 1) & (value)) << 16) +#define AMAZON_EBU_BUSCON1_WAITRDC(value) (((( 1 << 7) - 1) & (value)) << 9) +#define AMAZON_EBU_BUSCON1_WAITWRC(value) (((( 1 << 3) - 1) & (value)) << 6) +#define AMAZON_EBU_BUSCON1_HOLDC(value) (((( 1 << 2) - 1) & (value)) << 4) +#define AMAZON_EBU_BUSCON1_RECOVC(value) (((( 1 << 2) - 1) & (value)) << 2) +#define AMAZON_EBU_BUSCON1_CMULT(value) (((( 1 << 2) - 1) & (value)) << 0) + +/***EBU Bus Configuration Register 2***/ +#define AMAZON_EBU_BUSCON2 ((volatile u32*)(AMAZON_EBU+ 0x0068)) +#define AMAZON_EBU_BUSCON2_WRDIS (1 << 31) +#define AMAZON_EBU_BUSCON2_ALEC(value) (((( 1 << 2) - 1) & (value)) << 29) +#define AMAZON_EBU_BUSCON2_BCGEN(value) (((( 1 << 2) - 1) & (value)) << 27) +#define AMAZON_EBU_BUSCON2_AGEN(value) (((( 1 << 2) - 1) & (value)) << 24) +#define AMAZON_EBU_BUSCON2_CMULTR(value) (((( 1 << 2) - 1) & (value)) << 22) +#define AMAZON_EBU_BUSCON2_WAIT(value) (((( 1 << 2) - 1) & (value)) << 20) +#define AMAZON_EBU_BUSCON2_WAITINV (1 << 19) +#define AMAZON_EBU_BUSCON2_SETUP (1 << 18) +#define AMAZON_EBU_BUSCON2_PORTW(value) (((( 1 << 2) - 1) & (value)) << 16) +#define AMAZON_EBU_BUSCON2_WAITRDC(value) (((( 1 << 7) - 1) & (value)) << 9) +#define AMAZON_EBU_BUSCON2_WAITWRC(value) (((( 1 << 3) - 1) & (value)) << 6) +#define AMAZON_EBU_BUSCON2_HOLDC(value) (((( 1 << 2) - 1) & (value)) << 4) +#define AMAZON_EBU_BUSCON2_RECOVC(value) (((( 1 << 2) - 1) & (value)) << 2) +#define AMAZON_EBU_BUSCON2_CMULT(value) (((( 1 << 2) - 1) & (value)) << 0) + +/***********************************************************************/ +/* Module : SDRAM register address and bits */ +/***********************************************************************/ + +#define AMAZON_SDRAM (KSEG1+0x1F800000) +/***********************************************************************/ + + +/***MC Access Error Cause Register***/ +#define AMAZON_SDRAM_MC_ERRCAUSE ((volatile u32*)(AMAZON_SDRAM+ 0x0010)) +#define AMAZON_SDRAM_MC_ERRCAUSE_ERR (1 << 31) +#define AMAZON_SDRAM_MC_ERRCAUSE_PORT(value) (((( 1 << 4) - 1) & (value)) << 16) +#define AMAZON_SDRAM_MC_ERRCAUSE_CAUSE(value) (((( 1 << 2) - 1) & (value)) << 0) +#define AMAZON_SDRAM_MC_ERRCAUSE_Res(value) (((( 1 << NaN) - 1) & (value)) << NaN) + +/***MC Access Error Address Register***/ +#define AMAZON_SDRAM_MC_ERRADDR ((volatile u32*)(AMAZON_SDRAM+ 0x0020)) +#define AMAZON_SDRAM_MC_ERRADDR_ADDR + +/***MC I/O General Purpose Register***/ +#define AMAZON_SDRAM_MC_IOGP ((volatile u32*)(AMAZON_SDRAM+ 0x0100)) +#define AMAZON_SDRAM_MC_IOGP_GPR6(value) (((( 1 << 4) - 1) & (value)) << 28) +#define AMAZON_SDRAM_MC_IOGP_GPR5(value) (((( 1 << 4) - 1) & (value)) << 24) +#define AMAZON_SDRAM_MC_IOGP_GPR4(value) (((( 1 << 4) - 1) & (value)) << 20) +#define AMAZON_SDRAM_MC_IOGP_GPR3(value) (((( 1 << 4) - 1) & (value)) << 16) +#define AMAZON_SDRAM_MC_IOGP_GPR2(value) (((( 1 << 4) - 1) & (value)) << 12) +#define AMAZON_SDRAM_MC_IOGP_CPS (1 << 11) +#define AMAZON_SDRAM_MC_IOGP_CLKDELAY(value) (((( 1 << 3) - 1) & (value)) << 8) +#define AMAZON_SDRAM_MC_IOGP_CLKRAT(value) (((( 1 << 4) - 1) & (value)) << 4) +#define AMAZON_SDRAM_MC_IOGP_RDDEL(value) (((( 1 << 4) - 1) & (value)) << 0) + +/***MC Self Refresh Register***/ +#define AMAZON_SDRAM_MC_SELFRFSH ((volatile u32*)(AMAZON_SDRAM+ 0x01A0)) +#define AMAZON_SDRAM_MC_SELFRFSH_PWDS (1 << 1) +#define AMAZON_SDRAM_MC_SELFRFSH_PWD (1 << 0) +#define AMAZON_SDRAM_MC_SELFRFSH_Res(value) (((( 1 << 30) - 1) & (value)) << 2) + +/***MC Enable Register***/ +#define AMAZON_SDRAM_MC_CTRLENA ((volatile u32*)(AMAZON_SDRAM+ 0x0110)) +#define AMAZON_SDRAM_MC_CTRLENA_ENA (1 << 0) +#define AMAZON_SDRAM_MC_CTRLENA_Res(value) (((( 1 << 31) - 1) & (value)) << 1) + +/***MC Mode Register Setup Code***/ +#define AMAZON_SDRAM_MC_MRSCODE ((volatile u32*)(AMAZON_SDRAM+ 0x0120)) +#define AMAZON_SDRAM_MC_MRSCODE_UMC(value) (((( 1 << 5) - 1) & (value)) << 7) +#define AMAZON_SDRAM_MC_MRSCODE_CL(value) (((( 1 << 3) - 1) & (value)) << 4) +#define AMAZON_SDRAM_MC_MRSCODE_WT (1 << 3) +#define AMAZON_SDRAM_MC_MRSCODE_BL(value) (((( 1 << 3) - 1) & (value)) << 0) + +/***MC Configuration Data-word Width Register***/ +#define AMAZON_SDRAM_MC_CFGDW ((volatile u32*)(AMAZON_SDRAM+ 0x0130)) +#define AMAZON_SDRAM_MC_CFGDW_DW(value) (((( 1 << 4) - 1) & (value)) << 0) +#define AMAZON_SDRAM_MC_CFGDW_Res(value) (((( 1 << 28) - 1) & (value)) << 4) + +/***MC Configuration Physical Bank 0 Register***/ +#define AMAZON_SDRAM_MC_CFGPB0 ((volatile u32*)(AMAZON_SDRAM+ 0x140)) +#define AMAZON_SDRAM_MC_CFGPB0_MCSEN0(value) (((( 1 << 4) - 1) & (value)) << 12) +#define AMAZON_SDRAM_MC_CFGPB0_BANKN0(value) (((( 1 << 4) - 1) & (value)) << 8) +#define AMAZON_SDRAM_MC_CFGPB0_ROWW0(value) (((( 1 << 4) - 1) & (value)) << 4) +#define AMAZON_SDRAM_MC_CFGPB0_COLW0(value) (((( 1 << 4) - 1) & (value)) << 0) +#define AMAZON_SDRAM_MC_CFGPB0_Res(value) (((( 1 << 16) - 1) & (value)) << 16) + +/***MC Latency Register***/ +#define AMAZON_SDRAM_MC_LATENCY ((volatile u32*)(AMAZON_SDRAM+ 0x0180)) +#define AMAZON_SDRAM_MC_LATENCY_TRP(value) (((( 1 << 4) - 1) & (value)) << 16) +#define AMAZON_SDRAM_MC_LATENCY_TRAS(value) (((( 1 << 4) - 1) & (value)) << 12) +#define AMAZON_SDRAM_MC_LATENCY_TRCD(value) (((( 1 << 4) - 1) & (value)) << 8) +#define AMAZON_SDRAM_MC_LATENCY_TDPL(value) (((( 1 << 4) - 1) & (value)) << 4) +#define AMAZON_SDRAM_MC_LATENCY_TDAL(value) (((( 1 << 4) - 1) & (value)) << 0) +#define AMAZON_SDRAM_MC_LATENCY_Res(value) (((( 1 << 12) - 1) & (value)) << 20) + +/***MC Refresh Cycle Time Register***/ +#define AMAZON_SDRAM_MC_TREFRESH ((volatile u32*)(AMAZON_SDRAM+ 0x0190)) +#define AMAZON_SDRAM_MC_TREFRESH_TREF(value) (((( 1 << 13) - 1) & (value)) << 0) +#define AMAZON_SDRAM_MC_TREFRESH_Res(value) (((( 1 << 19) - 1) & (value)) << 13) + +/***********************************************************************/ +/* Module : GPTU register address and bits */ +/***********************************************************************/ + +#define AMAZON_GPTU (KSEG1+0x10100A00) +/***********************************************************************/ + + +/***GPT Clock Control Register***/ +#define AMAZON_GPTU_CLC ((volatile u32*)(AMAZON_GPTU+ 0x0000)) +#define AMAZON_GPTU_CLC_RMC(value) (((( 1 << 8) - 1) & (value)) << 8) +#define AMAZON_GPTU_CLC_DISS (1 << 1) +#define AMAZON_GPTU_CLC_DISR (1 << 0) + +/***GPT Timer 3 Control Register***/ +#define AMAZON_GPTU_T3CON ((volatile u32*)(AMAZON_GPTU+ 0x0014)) +#define AMAZON_GPTU_T3CON_T3RDIR (1 << 15) +#define AMAZON_GPTU_T3CON_T3CHDIR (1 << 14) +#define AMAZON_GPTU_T3CON_T3EDGE (1 << 13) +#define AMAZON_GPTU_T3CON_BPS1(value) (((( 1 << 2) - 1) & (value)) << 11) +#define AMAZON_GPTU_T3CON_T3OTL (1 << 10) +#define AMAZON_GPTU_T3CON_T3UD (1 << 7) +#define AMAZON_GPTU_T3CON_T3R (1 << 6) +#define AMAZON_GPTU_T3CON_T3M(value) (((( 1 << 3) - 1) & (value)) << 3) +#define AMAZON_GPTU_T3CON_T3I(value) (((( 1 << 3) - 1) & (value)) << 0) + +/***GPT Write Hardware Modified Timer 3 Control Register +If set and clear bit are written concurrently with 1, the associated bit is not changed.***/ +#define AMAZON_GPTU_WHBT3CON ((volatile u32*)(AMAZON_GPTU+ 0x004C)) +#define AMAZON_GPTU_WHBT3CON_SETT3CHDIR (1 << 15) +#define AMAZON_GPTU_WHBT3CON_CLRT3CHDIR (1 << 14) +#define AMAZON_GPTU_WHBT3CON_SETT3EDGE (1 << 13) +#define AMAZON_GPTU_WHBT3CON_CLRT3EDGE (1 << 12) +#define AMAZON_GPTU_WHBT3CON_SETT3OTL (1 << 11) +#define AMAZON_GPTU_WHBT3CON_CLRT3OTL (1 << 10) + +/***GPT Timer 2 Control Register***/ +#define AMAZON_GPTU_T2CON ((volatile u32*)(AMAZON_GPTU+ 0x0010)) +#define AMAZON_GPTU_T2CON_TxRDIR (1 << 15) +#define AMAZON_GPTU_T2CON_TxCHDIR (1 << 14) +#define AMAZON_GPTU_T2CON_TxEDGE (1 << 13) +#define AMAZON_GPTU_T2CON_TxIRDIS (1 << 12) +#define AMAZON_GPTU_T2CON_TxRC (1 << 9) +#define AMAZON_GPTU_T2CON_TxUD (1 << 7) +#define AMAZON_GPTU_T2CON_TxR (1 << 6) +#define AMAZON_GPTU_T2CON_TxM(value) (((( 1 << 3) - 1) & (value)) << 3) +#define AMAZON_GPTU_T2CON_TxI(value) (((( 1 << 3) - 1) & (value)) << 0) + +/***GPT Timer 4 Control Register***/ +#define AMAZON_GPTU_T4CON ((volatile u32*)(AMAZON_GPTU+ 0x0018)) +#define AMAZON_GPTU_T4CON_TxRDIR (1 << 15) +#define AMAZON_GPTU_T4CON_TxCHDIR (1 << 14) +#define AMAZON_GPTU_T4CON_TxEDGE (1 << 13) +#define AMAZON_GPTU_T4CON_TxIRDIS (1 << 12) +#define AMAZON_GPTU_T4CON_TxRC (1 << 9) +#define AMAZON_GPTU_T4CON_TxUD (1 << 7) +#define AMAZON_GPTU_T4CON_TxR (1 << 6) +#define AMAZON_GPTU_T4CON_TxM(value) (((( 1 << 3) - 1) & (value)) << 3) +#define AMAZON_GPTU_T4CON_TxI(value) (((( 1 << 3) - 1) & (value)) << 0) + +/***GPT Write HW Modified Timer 2 Control Register If set + and clear bit are written concurrently with 1, the associated bit is not changed.***/ +#define AMAZON_GPTU_WHBT2CON ((volatile u32*)(AMAZON_GPTU+ 0x0048)) +#define AMAZON_GPTU_WHBT2CON_SETTxCHDIR (1 << 15) +#define AMAZON_GPTU_WHBT2CON_CLRTxCHDIR (1 << 14) +#define AMAZON_GPTU_WHBT2CON_SETTxEDGE (1 << 13) +#define AMAZON_GPTU_WHBT2CON_CLRTxEDGE (1 << 12) + +/***GPT Write HW Modified Timer 4 Control Register If set + and clear bit are written concurrently with 1, the associated bit is not changed.***/ +#define AMAZON_GPTU_WHBT4CON ((volatile u32*)(AMAZON_GPTU+ 0x0050)) +#define AMAZON_GPTU_WHBT4CON_SETTxCHDIR (1 << 15) +#define AMAZON_GPTU_WHBT4CON_CLRTxCHDIR (1 << 14) +#define AMAZON_GPTU_WHBT4CON_SETTxEDGE (1 << 13) +#define AMAZON_GPTU_WHBT4CON_CLRTxEDGE (1 << 12) + +/***GPT Capture Reload Register***/ +#define AMAZON_GPTU_CAPREL ((volatile u32*)(AMAZON_GPTU+ 0x0030)) +#define AMAZON_GPTU_CAPREL_CAPREL(value) (((( 1 << 16) - 1) & (value)) << 0) + +/***GPT Timer 2 Register***/ +#define AMAZON_GPTU_T2 ((volatile u32*)(AMAZON_GPTU+ 0x0034)) +#define AMAZON_GPTU_T2_TVAL(value) (((( 1 << 16) - 1) & (value)) << 0) + +/***GPT Timer 3 Register***/ +#define AMAZON_GPTU_T3 ((volatile u32*)(AMAZON_GPTU+ 0x0038)) +#define AMAZON_GPTU_T3_TVAL(value) (((( 1 << 16) - 1) & (value)) << 0) + +/***GPT Timer 4 Register***/ +#define AMAZON_GPTU_T4 ((volatile u32*)(AMAZON_GPTU+ 0x003C)) +#define AMAZON_GPTU_T4_TVAL(value) (((( 1 << 16) - 1) & (value)) << 0) + +/***GPT Timer 5 Register***/ +#define AMAZON_GPTU_T5 ((volatile u32*)(AMAZON_GPTU+ 0x0040)) +#define AMAZON_GPTU_T5_TVAL(value) (((( 1 << 16) - 1) & (value)) << 0) + +/***GPT Timer 6 Register***/ +#define AMAZON_GPTU_T6 ((volatile u32*)(AMAZON_GPTU+ 0x0044)) +#define AMAZON_GPTU_T6_TVAL(value) (((( 1 << 16) - 1) & (value)) << 0) + +/***GPT Timer 6 Control Register***/ +#define AMAZON_GPTU_T6CON ((volatile u32*)(AMAZON_GPTU+ 0x0020)) +#define AMAZON_GPTU_T6CON_T6SR (1 << 15) +#define AMAZON_GPTU_T6CON_T6CLR (1 << 14) +#define AMAZON_GPTU_T6CON_BPS2(value) (((( 1 << 2) - 1) & (value)) << 11) +#define AMAZON_GPTU_T6CON_T6OTL (1 << 10) +#define AMAZON_GPTU_T6CON_T6UD (1 << 7) +#define AMAZON_GPTU_T6CON_T6R (1 << 6) +#define AMAZON_GPTU_T6CON_T6M(value) (((( 1 << 3) - 1) & (value)) << 3) +#define AMAZON_GPTU_T6CON_T6I(value) (((( 1 << 3) - 1) & (value)) << 0) + +/***GPT Write HW Modified Timer 6 Control Register If set + and clear bit are written concurrently with 1, the associated bit is not changed.***/ +#define AMAZON_GPTU_WHBT6CON ((volatile u32*)(AMAZON_GPTU+ 0x0054)) +#define AMAZON_GPTU_WHBT6CON_SETT6OTL (1 << 11) +#define AMAZON_GPTU_WHBT6CON_CLRT6OTL (1 << 10) + +/***GPT Timer 5 Control Register***/ +#define AMAZON_GPTU_T5CON ((volatile u32*)(AMAZON_GPTU+ 0x001C)) +#define AMAZON_GPTU_T5CON_T5SC (1 << 15) +#define AMAZON_GPTU_T5CON_T5CLR (1 << 14) +#define AMAZON_GPTU_T5CON_CI(value) (((( 1 << 2) - 1) & (value)) << 12) +#define AMAZON_GPTU_T5CON_T5CC (1 << 11) +#define AMAZON_GPTU_T5CON_CT3 (1 << 10) +#define AMAZON_GPTU_T5CON_T5RC (1 << 9) +#define AMAZON_GPTU_T5CON_T5UDE (1 << 8) +#define AMAZON_GPTU_T5CON_T5UD (1 << 7) +#define AMAZON_GPTU_T5CON_T5R (1 << 6) +#define AMAZON_GPTU_T5CON_T5M(value) (((( 1 << 3) - 1) & (value)) << 3) +#define AMAZON_GPTU_T5CON_T5I(value) (((( 1 << 3) - 1) & (value)) << 0) + + +/***********************************************************************/ +/* Module : ASC register address and bits */ +/***********************************************************************/ + +#define AMAZON_ASC (KSEG1+0x10100400) +/***********************************************************************/ + + +/***ASC Port Input Select Register***/ +#define AMAZON_ASC_PISEL (AMAZON_ASC+ 0x0004) +#define AMAZON_ASC_PISEL_RIS (1 << 0) + +/***ASC Control Register***/ +#define AMAZON_ASC_CON (AMAZON_ASC+ 0x0010) +#define AMAZON_ASC_CON_R (1 << 15) +#define AMAZON_ASC_CON_LB (1 << 14) +#define AMAZON_ASC_CON_BRS (1 << 13) +#define AMAZON_ASC_CON_ODD (1 << 12) +#define AMAZON_ASC_CON_FDE (1 << 11) +#define AMAZON_ASC_CON_OE (1 << 10) +#define AMAZON_ASC_CON_FE (1 << 9) +#define AMAZON_ASC_CON_PE (1 << 8) +#define AMAZON_ASC_CON_OEN (1 << 7) +#define AMAZON_ASC_CON_FEN (1 << 6) +#define AMAZON_ASC_CON_PENRXDI (1 << 5) +#define AMAZON_ASC_CON_REN (1 << 4) +#define AMAZON_ASC_CON_STP (1 << 3) +#define AMAZON_ASC_CON_M(value) (((( 1 << 3) - 1) & (value)) << 0) + +/***ASC Write Hardware Modified Control Register***/ +#define AMAZON_ASC_WHBCON (AMAZON_ASC+ 0x0050) +#define AMAZON_ASC_WHBCON_SETOE (1 << 13) +#define AMAZON_ASC_WHBCON_SETFE (1 << 12) +#define AMAZON_ASC_WHBCON_SETPE (1 << 11) +#define AMAZON_ASC_WHBCON_CLROE (1 << 10) +#define AMAZON_ASC_WHBCON_CLRFE (1 << 9) +#define AMAZON_ASC_WHBCON_CLRPE (1 << 8) +#define AMAZON_ASC_WHBCON_SETREN (1 << 5) +#define AMAZON_ASC_WHBCON_CLRREN (1 << 4) + +/***ASC Baudrate Timer/Reload Register***/ +#define AMAZON_ASC_BTR (AMAZON_ASC+ 0x0014) +#define AMAZON_ASC_BTR_BR_VALUE(value) (((( 1 << 13) - 1) & (value)) << 0) + +/***ASC Fractional Divider Register***/ +#define AMAZON_ASC_FDV (AMAZON_ASC+ 0x0018) +#define AMAZON_ASC_FDV_FD_VALUE(value) (((( 1 << 9) - 1) & (value)) << 0) + +/***ASC IrDA Pulse Mode/Width Register***/ +#define AMAZON_ASC_PMW (AMAZON_ASC+ 0x001C) +#define AMAZON_ASC_PMW_IRPW (1 << 8) +#define AMAZON_ASC_PMW_PW_VALUE(value) (((( 1 << 8) - 1) & (value)) << 0) + +/***ASC Transmit Buffer Register***/ +#define AMAZON_ASC_TBUF (AMAZON_ASC+ 0x0020) +#define AMAZON_ASC_TBUF_TD_VALUE(value) (((( 1 << 9) - 1) & (value)) << 0) + +/***ASC Receive Buffer Register***/ +#define AMAZON_ASC_RBUF (AMAZON_ASC+ 0x0024) +#define AMAZON_ASC_RBUF_RD_VALUE(value) (((( 1 << 9) - 1) & (value)) << 0) + +/***ASC Autobaud Control Register***/ +#define AMAZON_ASC_ABCON (AMAZON_ASC+ 0x0030) +#define AMAZON_ASC_ABCON_RXINV (1 << 11) +#define AMAZON_ASC_ABCON_TXINV (1 << 10) +#define AMAZON_ASC_ABCON_ABEM(value) (((( 1 << 2) - 1) & (value)) << 8) +#define AMAZON_ASC_ABCON_FCDETEN (1 << 4) +#define AMAZON_ASC_ABCON_ABDETEN (1 << 3) +#define AMAZON_ASC_ABCON_ABSTEN (1 << 2) +#define AMAZON_ASC_ABCON_AUREN (1 << 1) +#define AMAZON_ASC_ABCON_ABEN (1 << 0) + +/***Receive FIFO Control Register***/ +#define AMAZON_ASC_RXFCON (AMAZON_ASC+ 0x0040) +#define AMAZON_ASC_RXFCON_RXFITL(value) (((( 1 << 6) - 1) & (value)) << 8) +#define AMAZON_ASC_RXFCON_RXTMEN (1 << 2) +#define AMAZON_ASC_RXFCON_RXFFLU (1 << 1) +#define AMAZON_ASC_RXFCON_RXFEN (1 << 0) + +/***Transmit FIFO Control Register***/ +#define AMAZON_ASC_TXFCON (AMAZON_ASC+ 0x0044) +#define AMAZON_ASC_TXFCON_TXFITL(value) (((( 1 << 6) - 1) & (value)) << 8) +#define AMAZON_ASC_TXFCON_TXTMEN (1 << 2) +#define AMAZON_ASC_TXFCON_TXFFLU (1 << 1) +#define AMAZON_ASC_TXFCON_TXFEN (1 << 0) + +/***FIFO Status Register***/ +#define AMAZON_ASC_FSTAT (AMAZON_ASC+ 0x0048) +#define AMAZON_ASC_FSTAT_TXFFL(value) (((( 1 << 6) - 1) & (value)) << 8) +#define AMAZON_ASC_FSTAT_RXFFL(value) (((( 1 << 6) - 1) & (value)) << 0) + +/***ASC Write HW Modified Autobaud Control Register***/ +#define AMAZON_ASC_WHBABCON (AMAZON_ASC+ 0x0054) +#define AMAZON_ASC_WHBABCON_SETABEN (1 << 1) +#define AMAZON_ASC_WHBABCON_CLRABEN (1 << 0) + +/***ASC Autobaud Status Register***/ +#define AMAZON_ASC_ABSTAT (AMAZON_ASC+ 0x0034) +#define AMAZON_ASC_ABSTAT_DETWAIT (1 << 4) +#define AMAZON_ASC_ABSTAT_SCCDET (1 << 3) +#define AMAZON_ASC_ABSTAT_SCSDET (1 << 2) +#define AMAZON_ASC_ABSTAT_FCCDET (1 << 1) +#define AMAZON_ASC_ABSTAT_FCSDET (1 << 0) + +/***ASC Write HW Modified Autobaud Status Register***/ +#define AMAZON_ASC_WHBABSTAT (AMAZON_ASC+ 0x0058) +#define AMAZON_ASC_WHBABSTAT_SETDETWAIT (1 << 9) +#define AMAZON_ASC_WHBABSTAT_CLRDETWAIT (1 << 8) +#define AMAZON_ASC_WHBABSTAT_SETSCCDET (1 << 7) +#define AMAZON_ASC_WHBABSTAT_CLRSCCDET (1 << 6) +#define AMAZON_ASC_WHBABSTAT_SETSCSDET (1 << 5) +#define AMAZON_ASC_WHBABSTAT_CLRSCSDET (1 << 4) +#define AMAZON_ASC_WHBABSTAT_SETFCCDET (1 << 3) +#define AMAZON_ASC_WHBABSTAT_CLRFCCDET (1 << 2) +#define AMAZON_ASC_WHBABSTAT_SETFCSDET (1 << 1) +#define AMAZON_ASC_WHBABSTAT_CLRFCSDET (1 << 0) + +/***ASC Clock Control Register***/ +#define AMAZON_ASC_CLC (AMAZON_ASC+ 0x0000) +#define AMAZON_ASC_CLC_RMC(value) (((( 1 << 8) - 1) & (value)) << 8) +#define AMAZON_ASC_CLC_DISS (1 << 1) +#define AMAZON_ASC_CLC_DISR (1 << 0) + +/***ASC IRNCR0 **/ +#define AMAZON_ASC_IRNCR0 (AMAZON_ASC+ 0x00FC) +/***ASC IRNCR1 **/ +#define AMAZON_ASC_IRNCR1 (AMAZON_ASC+ 0x00F8) +#define ASC_IRNCR_TIR 0x1 +#define ASC_IRNCR_RIR 0x2 +#define ASC_IRNCR_EIR 0x4 +/***********************************************************************/ +/* Module : DMA register address and bits */ +/***********************************************************************/ + +#define AMAZON_DMA (KSEG1+0x10103000) +/***********************************************************************/ +#define AMAZON_DMA_CH_ON AMAZON_DMA+0x28 +#define AMAZON_DMA_CH_RST AMAZON_DMA+0x2c +#define AMAZON_DMA_CH0_ISR AMAZON_DMA+0x30 +#define AMAZON_DMA_CH1_ISR AMAZON_DMA+0x34 +#define AMAZON_DMA_CH2_ISR AMAZON_DMA+0x38 +#define AMAZON_DMA_CH3_ISR AMAZON_DMA+0x3c +#define AMAZON_DMA_CH4_ISR AMAZON_DMA+0x40 +#define AMAZON_DMA_CH5_ISR AMAZON_DMA+0x44 +#define AMAZON_DMA_CH6_ISR AMAZON_DMA+0x48 +#define AMAZON_DMA_CH7_ISR AMAZON_DMA+0x4c +#define AMAZON_DMA_CH8_ISR AMAZON_DMA+0x50 +#define AMAZON_DMA_CH9_ISR AMAZON_DMA+0x54 +#define AMAZON_DMA_CH10_ISR AMAZON_DMA+0x58 +#define AMAZON_DMA_CH11_ISR AMAZON_DMA+0x5c +#define AMAZON_DMA_CH0_MSK AMAZON_DMA+0x60 +#define AMAZON_DMA_CH1_MSK AMAZON_DMA+0x64 +#define AMAZON_DMA_CH2_MSK AMAZON_DMA+0x68 +#define AMAZON_DMA_CH3_MSK AMAZON_DMA+0x6c +#define AMAZON_DMA_CH4_MSK AMAZON_DMA+0x70 +#define AMAZON_DMA_CH5_MSK AMAZON_DMA+0x74 +#define AMAZON_DMA_CH6_MSK AMAZON_DMA+0x78 +#define AMAZON_DMA_CH7_MSK AMAZON_DMA+0x7c +#define AMAZON_DMA_CH8_MSK AMAZON_DMA+0x80 +#define AMAZON_DMA_CH9_MSK AMAZON_DMA+0x84 +#define AMAZON_DMA_CH10_MSK AMAZON_DMA+0x88 +#define AMAZON_DMA_CH11_MSK AMAZON_DMA+0x8c +#define AMAZON_DMA_Desc_BA AMAZON_DMA+0x90 +#define AMAZON_DMA_CH0_DES_LEN AMAZON_DMA+0x94 +#define AMAZON_DMA_CH1_DES_LEN AMAZON_DMA+0x98 +#define AMAZON_DMA_CH2_DES_LEN AMAZON_DMA+0x9c +#define AMAZON_DMA_CH3_DES_LEN AMAZON_DMA+0xa0 +#define AMAZON_DMA_CH4_DES_LEN AMAZON_DMA+0xa4 +#define AMAZON_DMA_CH5_DES_LEN AMAZON_DMA+0xa8 +#define AMAZON_DMA_CH6_DES_LEN AMAZON_DMA+0xac +#define AMAZON_DMA_CH7_DES_LEN AMAZON_DMA+0xb0 +#define AMAZON_DMA_CH8_DES_LEN AMAZON_DMA+0xb4 +#define AMAZON_DMA_CH9_DES_LEN AMAZON_DMA+0xb8 +#define AMAZON_DMA_CH10_DES_LEN AMAZON_DMA+0xbc +#define AMAZON_DMA_CH11_DES_LEN AMAZON_DMA+0xc0 +#define AMAZON_DMA_CH1_DES_OFST AMAZON_DMA+0xc4 +#define AMAZON_DMA_CH2_DES_OFST AMAZON_DMA+0xc8 +#define AMAZON_DMA_CH3_DES_OFST AMAZON_DMA+0xcc +#define AMAZON_DMA_CH4_DES_OFST AMAZON_DMA+0xd0 +#define AMAZON_DMA_CH5_DES_OFST AMAZON_DMA+0xd4 +#define AMAZON_DMA_CH6_DES_OFST AMAZON_DMA+0xd8 +#define AMAZON_DMA_CH7_DES_OFST AMAZON_DMA+0xdc +#define AMAZON_DMA_CH8_DES_OFST AMAZON_DMA+0xe0 +#define AMAZON_DMA_CH9_DES_OFST AMAZON_DMA+0xe4 +#define AMAZON_DMA_CH10_DES_OFST AMAZON_DMA+0xe8 +#define AMAZON_DMA_CH11_DES_OFST AMAZON_DMA+0xec +#define AMAZON_DMA_SW_BL AMAZON_DMA+0xf0 +#define AMAZON_DMA_TPE_BL AMAZON_DMA+0xf4 +#define AMAZON_DMA_DPlus2FPI_BL AMAZON_DMA+0xf8 +#define AMAZON_DMA_GRX_BUF_LEN AMAZON_DMA+0xfc +#define AMAZON_DMA_DMA_ECON_REG AMAZON_DMA+0x100 +#define AMAZON_DMA_POLLING_REG AMAZON_DMA+0x104 +#define AMAZON_DMA_CH_WGT AMAZON_DMA+0x108 +#define AMAZON_DMA_TX_WGT AMAZON_DMA+0x10c +#define AMAZON_DMA_DPLus2FPI_CLASS AMAZON_DMA+0x110 +#define AMAZON_DMA_COMB_ISR AMAZON_DMA+0x114 + +//channel reset +#define SWITCH1_RST_MASK 0x83 /* Switch1 channel mask */ +#define SWITCH2_RST_MASK 0x10C /* Switch1 channel mask */ +#define TPE_RST_MASK 0x630 /* TPE channel mask */ +#define DPlus2FPI_RST_MASK 0x840 /* DPlusFPI channel mask */ + +//ISR +#define DMA_ISR_RDERR 0x20 +#define DMA_ISR_CMDCPT 0x10 +#define DMA_ISR_CPT 0x8 +#define DMA_ISR_DURR 0x4 +#define DMA_ISR_EOP 0x2 +#define DMA_DESC_BYTEOFF_SHIFT 23 + +#define DMA_POLLING_ENABLE 0x80000000 +#define DMA_POLLING_CNT 0x50 /*minimum 0x10, max 0xfff0*/ + +/***********************************************************************/ +/* Module : Debug register address and bits */ +/***********************************************************************/ + +#define AMAZON_DEBUG (KSEG1+0x1F106000) +/***********************************************************************/ + + +/***MCD Break System Control Register***/ +#define AMAZON_DEBUG_MCD_BSCR ((volatile u32*)(AMAZON_DEBUG+ 0x0000)) + +/***PMC Performance Counter Control Register0***/ +#define AMAZON_DEBUG_PMC_PCCR0 ((volatile u32*)(AMAZON_DEBUG+ 0x0010)) + +/***PMC Performance Counter Control Register1***/ +#define AMAZON_DEBUG_PMC_PCCR1 ((volatile u32*)(AMAZON_DEBUG+ 0x0014)) + +/***PMC Performance Counter Register0***/ +#define AMAZON_DEBUG_PMC_PCR0 ((volatile u32*)(AMAZON_DEBUG+ 0x0018)) + +/*165001:henryhsu:20050603:Source modified by Bing Tao*/ + +/***PMC Performance Counter Register1***/ +//#define AMAZON_DEBUG_PMC_PCR1 ((volatile u32*)(AMAZON_DEBUG+ 0x0020)) +#define AMAZON_DEBUG_PMC_PCR1 ((volatile u32*)(AMAZON_DEBUG+ 0x001c)) + +/*165001*/ + + + +/***MCD Suspend Mode Control Register***/ +#define AMAZON_DEBUG_MCD_SMCR ((volatile u32*)(AMAZON_DEBUG+ 0x0024)) + +/***********************************************************************/ +/* Module : GPIO register address and bits */ +/***********************************************************************/ + +#define AMAZON_GPIO (KSEG1+0x10100B00) +/***********************************************************************/ + + +/***Port 0 Data Output Register (0010H)***/ +#define AMAZON_GPIO_P0_OUT ((volatile u32*)(AMAZON_GPIO+ 0x0010)) + +/***Port 1 Data Output Register (0040H)***/ +#define AMAZON_GPIO_P1_OUT ((volatile u32*)(AMAZON_GPIO+ 0x0040)) + +/***Port 0 Data Input Register (0014H)***/ +#define AMAZON_GPIO_P0_IN ((volatile u32*)(AMAZON_GPIO+ 0x0014)) + +/***Port 1 Data Input Register (0044H)***/ +#define AMAZON_GPIO_P1_IN ((volatile u32*)(AMAZON_GPIO+ 0x0044)) + +/***Port 0 Direction Register (0018H)***/ +#define AMAZON_GPIO_P0_DIR ((volatile u32*)(AMAZON_GPIO+ 0x0018)) + +/***Port 1 Direction Register (0048H)***/ +#define AMAZON_GPIO_P1_DIR ((volatile u32*)(AMAZON_GPIO+ 0x0048)) + +/***Port 0 Alternate Function Select Register 0 (001C H) ***/ +#define AMAZON_GPIO_P0_ALTSEL0 ((volatile u32*)(AMAZON_GPIO+ 0x001C)) + +/***Port 1 Alternate Function Select Register 0 (004C H) ***/ +#define AMAZON_GPIO_P1_ALTSEL0 ((volatile u32*)(AMAZON_GPIO+ 0x004C)) + +/***Port 0 Alternate Function Select Register 1 (0020 H) ***/ +#define AMAZON_GPIO_P0_ALTSEL1 ((volatile u32*)(AMAZON_GPIO+ 0x0020)) + +/***Port 1 Alternate Function Select Register 0 (0050 H) ***/ +#define AMAZON_GPIO_P1_ALTSEL1 ((volatile u32*)(AMAZON_GPIO+ 0x0050)) + +/***Port 0 Open Drain Control Register (0024H)***/ +#define AMAZON_GPIO_P0_OD ((volatile u32*)(AMAZON_GPIO+ 0x0024)) + +/***Port 1 Open Drain Control Register (0054H)***/ +#define AMAZON_GPIO_P1_OD ((volatile u32*)(AMAZON_GPIO+ 0x0054)) + +/***Port 0 Input Schmitt-Trigger Off Register (0028 H) ***/ +#define AMAZON_GPIO_P0_STOFF ((volatile u32*)(AMAZON_GPIO+ 0x0028)) + +/***Port 1 Input Schmitt-Trigger Off Register (0058 H) ***/ +#define AMAZON_GPIO_P1_STOFF ((volatile u32*)(AMAZON_GPIO+ 0x0058)) + +/***Port 0 Pull Up/Pull Down Select Register (002C H)***/ +#define AMAZON_GPIO_P0_PUDSEL ((volatile u32*)(AMAZON_GPIO+ 0x002C)) + +/***Port 1 Pull Up/Pull Down Select Register (005C H)***/ +#define AMAZON_GPIO_P1_PUDSEL ((volatile u32*)(AMAZON_GPIO+ 0x005C)) + +/***Port 0 Pull Up Device Enable Register (0030 H)***/ +#define AMAZON_GPIO_P0_PUDEN ((volatile u32*)(AMAZON_GPIO+ 0x0030)) + +/***Port 1 Pull Up Device Enable Register (0060 H)***/ +#define AMAZON_GPIO_P1_PUDEN ((volatile u32*)(AMAZON_GPIO+ 0x0060)) + +/***********************************************************************/ +/* Module : BIU register address and bits */ +/***********************************************************************/ + +#define AMAZON_BIU (KSEG1+0x1FA80000) +/***********************************************************************/ + + +/***BIU Identification Register***/ +#define AMAZON_BIU_ID ((volatile u32*)(AMAZON_BIU+ 0x0000)) +#define AMAZON_BIU_ID_ARCH (1 << 16) +#define AMAZON_BIU_ID_ID(value) (((( 1 << 8) - 1) & (value)) << 8) +#define AMAZON_BIU_ID_REV(value) (((( 1 << 8) - 1) & (value)) << 0) + +/***BIU Access Error Cause Register***/ +#define AMAZON_BIU_ERRCAUSE ((volatile u32*)(AMAZON_BIU+ 0x0100)) +#define AMAZON_BIU_ERRCAUSE_ERR (1 << 31) +#define AMAZON_BIU_ERRCAUSE_PORT(value) (((( 1 << 4) - 1) & (value)) << 16) +#define AMAZON_BIU_ERRCAUSE_CAUSE(value) (((( 1 << 2) - 1) & (value)) << 0) + +/***BIU Access Error Address Register***/ +#define AMAZON_BIU_ERRADDR ((volatile u32*)(AMAZON_BIU+ 0x0108)) +#define AMAZON_BIU_ERRADDR_ADDR + +/***********************************************************************/ +/* Module : ICU register address and bits */ +/***********************************************************************/ + +#define AMAZON_ICU (KSEG1+0x1F101000) +/***********************************************************************/ + +/***IM0 Interrupt Status Register***/ +#define AMAZON_ICU_IM0_ISR (AMAZON_ICU + 0x0010) +#define AMAZON_ICU_IM1_ISR (AMAZON_ICU + 0x0020) +#define AMAZON_ICU_IM2_ISR (AMAZON_ICU + 0x0030) +#define AMAZON_ICU_IM3_ISR (AMAZON_ICU + 0x0040) +#define AMAZON_ICU_IM4_ISR (AMAZON_ICU + 0x0050) + +/***IM0 Interrupt Enable Register***/ +#define AMAZON_ICU_IM0_IER (AMAZON_ICU + 0x0014) +#define AMAZON_ICU_IM1_IER (AMAZON_ICU + 0x0024) +#define AMAZON_ICU_IM2_IER (AMAZON_ICU + 0x0034) +#define AMAZON_ICU_IM3_IER (AMAZON_ICU + 0x0044) +#define AMAZON_ICU_IM4_IER (AMAZON_ICU + 0x0054) + +/***IM0 Interrupt Output Status Register***/ +#define AMAZON_ICU_IM0_IOSR (AMAZON_ICU + 0x0018) +#define AMAZON_ICU_IM1_IOSR (AMAZON_ICU + 0x0028) +#define AMAZON_ICU_IM2_IOSR (AMAZON_ICU + 0x0038) +#define AMAZON_ICU_IM3_IOSR (AMAZON_ICU + 0x0048) +#define AMAZON_ICU_IM4_IOSR (AMAZON_ICU + 0x0058) + +/***IM0 Interrupt Request Set Register***/ +#define AMAZON_ICU_IM0_IRSR (AMAZON_ICU + 0x001c) +#define AMAZON_ICU_IM1_IRSR (AMAZON_ICU + 0x002c) +#define AMAZON_ICU_IM2_IRSR (AMAZON_ICU + 0x003c) +#define AMAZON_ICU_IM3_IRSR (AMAZON_ICU + 0x004c) +#define AMAZON_ICU_IM4_IRSR (AMAZON_ICU + 0x005c) + +/***Interrupt Vector Value Register***/ +#define AMAZON_ICU_IM_VEC (AMAZON_ICU + 0x0060) + +/***Interrupt Vector Value Mask***/ +#define AMAZON_ICU_IM0_VEC_MASK 0x0000001f +#define AMAZON_ICU_IM1_VEC_MASK 0x000003e0 +#define AMAZON_ICU_IM2_VEC_MASK 0x00007c00 +#define AMAZON_ICU_IM3_VEC_MASK 0x000f8000 +#define AMAZON_ICU_IM4_VEC_MASK 0x01f00000 + +/***DMA Interrupt Mask Value***/ +#define AMAZON_DMA_H_MASK 0x00000fff + +/***External Interrupt Control Register***/ +#define AMAZON_ICU_EXTINTCR ((volatile u32*)(AMAZON_ICU + 0x0000)) +#define AMAZON_ICU_IRNICR ((volatile u32*)(AMAZON_ICU + 0x0004)) +#define AMAZON_ICU_IRNCR ((volatile u32*)(AMAZON_ICU + 0x0008)) +#define AMAZON_ICU_IRNEN ((volatile u32*)(AMAZON_ICU + 0x000c)) + +/***********************************************************************/ +/* Module : PCI/Card-BUS/PC-Card register address and bits */ +/***********************************************************************/ + +#define AMAZON_PCI (KSEG1+0x10105400) +#define AMAZON_PCI_CFG_BASE (KSEG1+0x11000000) +#define AMAZON_PCI_MEM_BASE (KSEG1+0x12000000) + +#define CLOCK_CONTROL AMAZON_PCI + 0x00000000 +#define ARB_CTRL_bit 1 +#define IDENTIFICATION AMAZON_PCI + 0x00000004 +#define SOFTRESET AMAZON_PCI + 0x00000010 +#define PCI_FPI_ERROR_ADDRESS AMAZON_PCI + 0x00000014 +#define FPI_PCI_ERROR_ADDRESS AMAZON_PCI + 0x00000018 +#define FPI_ERROR_TAG AMAZON_PCI + 0x0000001c +#define IRR AMAZON_PCI + 0x00000020 +#define IRA_IR AMAZON_PCI + 0x00000024 +#define IRM AMAZON_PCI + 0x00000028 +#define DMA_COMPLETE_BIT 0 +#define PCI_POWER_CHANGE_BIT 16 +#define PCI_MASTER0_BROKEN_INT_BIT 24 +#define PCI_MASTER1_BROKEN_INT_BIT 25 +#define PCI_MASTER2_BROKEN_INT_BIT 26 +#define EOI AMAZON_PCI + 0x0000002c +#define PCI_MODE AMAZON_PCI + 0x00000030 +#define PCI_MODE_cfgok_bit 24 +#define DEVICE_VENDOR_ID AMAZON_PCI + 0x00000034 +#define SUBSYSTEM_VENDOR_ID AMAZON_PCI + 0x00000038 +#define POWER_MANAGEMENT AMAZON_PCI + 0x0000003c +#define CLASS_CODE1 AMAZON_PCI + 0x00000040 +#define BAR11_MASK AMAZON_PCI + 0x00000044 +#define BAR12_MASK AMAZON_PCI + 0x00000048 +#define BAR13_MASK AMAZON_PCI + 0x0000004c +#define BAR14_MASK AMAZON_PCI + 0x00000050 +#define BAR15_MASK AMAZON_PCI + 0x00000054 +#define BAR16_MASK AMAZON_PCI + 0x00000058 +#define CARDBUS_CIS_POINTER1 AMAZON_PCI + 0x0000005c +#define SUBSYSTEM_ID1 AMAZON_PCI + 0x00000060 +#define PCI_ADDRESS_MAP_11 AMAZON_PCI + 0x00000064 +#define PCI_ADDRESS_MAP_12 AMAZON_PCI + 0x00000068 +#define PCI_ADDRESS_MAP_13 AMAZON_PCI + 0x0000006c +#define PCI_ADDRESS_MAP_14 AMAZON_PCI + 0x00000070 +#define PCI_ADDRESS_MAP_15 AMAZON_PCI + 0x00000074 +#define PCI_ADDRESS_MAP_16 AMAZON_PCI + 0x00000078 +#define FPI_SEGMENT_ENABLE AMAZON_PCI + 0x0000007c +#define CLASS_CODE2 AMAZON_PCI + 0x00000080 +#define BAR21_MASK AMAZON_PCI + 0x00000084 +#define BAR22_MASK AMAZON_PCI + 0x00000088 +#define BAR23_MASK AMAZON_PCI + 0x0000008c +#define BAR24_MASK AMAZON_PCI + 0x00000090 +#define BAR25_MASK AMAZON_PCI + 0x00000094 +#define BAR26_MASK AMAZON_PCI + 0x00000098 +#define CARDBUS_CIS_POINTER2 AMAZON_PCI + 0x0000009c +#define SUBSYSTEM_ID2 AMAZON_PCI + 0x000000a0 +#define PCI_ADDRESS_MAP_21 AMAZON_PCI + 0x000000a4 +#define PCI_ADDRESS_MAP_22 AMAZON_PCI + 0x000000a8 +#define PCI_ADDRESS_MAP_23 AMAZON_PCI + 0x000000ac +#define PCI_ADDRESS_MAP_24 AMAZON_PCI + 0x000000b0 +#define PCI_ADDRESS_MAP_25 AMAZON_PCI + 0x000000b4 +#define PCI_ADDRESS_MAP_26 AMAZON_PCI + 0x000000b8 +#define FPI_ADDRESS_MASK11LOW AMAZON_PCI + 0x000000bc +#define FPI_ADDRESS_MAP_0 AMAZON_PCI + 0x000000c0 +#define FPI_ADDRESS_MAP_1 AMAZON_PCI + 0x000000c4 +#define FPI_ADDRESS_MAP_2 AMAZON_PCI + 0x000000c8 +#define FPI_ADDRESS_MAP_3 AMAZON_PCI + 0x000000cc +#define FPI_ADDRESS_MAP_4 AMAZON_PCI + 0x000000d0 +#define FPI_ADDRESS_MAP_5 AMAZON_PCI + 0x000000d4 +#define FPI_ADDRESS_MAP_6 AMAZON_PCI + 0x000000d8 +#define FPI_ADDRESS_MAP_7 AMAZON_PCI + 0x000000dc +#define FPI_ADDRESS_MAP_11LOW AMAZON_PCI + 0x000000e0 +#define FPI_ADDRESS_MAP_11HIGH AMAZON_PCI + 0x000000e4 +#define FPI_BURST_LENGTH AMAZON_PCI + 0x000000e8 +#define SET_PCI_SERR AMAZON_PCI + 0x000000ec +#define DMA_FPI_START_ADDR AMAZON_PCI + 0x000000f0 +#define DMA_PCI_START_ADDR AMAZON_PCI + 0x000000f4 +#define DMA_TRANSFER_COUNT AMAZON_PCI + 0x000000f8 +#define DMA_CONTROL_STATUS AMAZON_PCI + 0x000000fc + +#define EXT_PCI1_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x0800 +#define EXT_PCI2_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x1000 +#define EXT_PCI3_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x1800 +#define EXT_PCI4_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x2000 +#define EXT_PCI5_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x2800 +#define EXT_PCI6_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x3000 +#define EXT_PCI7_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x3800 +#define EXT_PCI8_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x4000 +#define EXT_PCI9_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x4800 +#define EXT_PCI10_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x5000 +#define EXT_PCI11_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x5800 +#define EXT_PCI12_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x6000 +#define EXT_PCI13_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x6800 +#define EXT_PCI14_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x7000 +#define EXT_PCI15_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x7800 +#define EXT_CARDBUS_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0XF000 +#define EXT_PCI_BAR1_ADDR 0x10 +#define EXT_PCI_BAR2_ADDR 0x14 +#define EXT_PCI_BAR3_ADDR 0x18 +#define EXT_PCI_BAR4_ADDR 0x1C +#define EXT_PCI_BAR5_ADDR 0x20 +#define EXT_PCI_BAR6_ADDR 0x24 + +#define DEVICE_ID_VECDOR_ID_ADDR AMAZON_PCI_CFG_BASE + 0x0 +#define STATUS_COMMAND_ADDR AMAZON_PCI_CFG_BASE + 0x4 +#define BUS_MASTER_ENABLE_BIT 2 +#define MEM_SPACE_ENABLE_BIT 1 +#define CLASS_CODE_REVISION_ADDR AMAZON_PCI_CFG_BASE + 0x8 +#define BIST_HEADER_TYPE_LATENCY_CAHCE_ADDR AMAZON_PCI_CFG_BASE + 0xC +#define BAR1_ADDR AMAZON_PCI_CFG_BASE + 0x10 +#define BAR2_ADDR AMAZON_PCI_CFG_BASE + 0x14 +#define BAR3_ADDR AMAZON_PCI_CFG_BASE + 0x18 +#define BAR4_ADDR AMAZON_PCI_CFG_BASE + 0x1C +#define BAR3_ADDR AMAZON_PCI_CFG_BASE + 0x18 +#define BAR4_ADDR AMAZON_PCI_CFG_BASE + 0x1C +#define BAR5_ADDR AMAZON_PCI_CFG_BASE + 0x20 +#define BAR6_ADDR AMAZON_PCI_CFG_BASE + 0x24 +#define CARDBUS_CIS_POINTER_ADDR AMAZON_PCI_CFG_BASE + 0x28 +#define SUBSYSTEM_ID_VENDOR_ID_ADDR AMAZON_PCI_CFG_BASE + 0x2C +#define EXPANSION_ROM_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x30 +#define CAPABILITIES_POINTER_ADDR AMAZON_PCI_CFG_BASE + 0x34 +#define RESERVED_0x38 AMAZON_PCI_CFG_BASE + 0x38 +#define MAX_LAT_MIN_GNT_INT_PIN_LINE_ADDR AMAZON_PCI_CFG_BASE + 0x3C +#define POWER_MNGT_NEXT_POINTER_CAP_ID_ADDR AMAZON_PCI_CFG_BASE + 0x40 +#define POWER_MANAGEMENT_CTRL_STATUS_ADDR AMAZON_PCI_CFG_BASE + 0x44 +#define RESERVED_0x48 AMAZON_PCI_CFG_BASE + 0x48 +#define RESERVED_0x4C AMAZON_PCI_CFG_BASE + 0x4C +#define ERROR_ADDR_PCI_FPI_ADDR AMAZON_PCI_CFG_BASE + 0x50 +#define ERROR_ADdR_FPI_PCI_ADDR AMAZON_PCI_CFG_BASE + 0x54 +#define ERROR_TAG_FPI_PCI_ADDR AMAZON_PCI_CFG_BASE + 0x58 +#define PCI_ARB_CTRL_STATUS_ADDR AMAZON_PCI_CFG_BASE + 0x5C +#define INTERNAL_ARB_ENABLE_BIT 0 +#define ARB_SCHEME_BIT 1 +#define PCI_MASTER0_PRIOR_2BITS 2 +#define PCI_MASTER1_PRIOR_2BITS 4 +#define PCI_MASTER2_PRIOR_2BITS 6 +#define PCI_MASTER0_REQ_MASK_2BITS 8 +#define PCI_MASTER1_REQ_MASK_2BITS 10 +#define PCI_MASTER2_REQ_MASK_2BITS 12 +#define PCI_MASTER0_GNT_MASK_2BITS 14 +#define PCI_MASTER1_GNT_MASK_2BITS 16 +#define PCI_MASTER2_GNT_MASK_2BITS 18 +#define FPI_PCI_INT_STATUS_ADDR AMAZON_PCI_CFG_BASE + 0x60 +#define FPI_PCI_INT_ACK_ADDR AMAZON_PCI_CFG_BASE + 0x64 +#define FPI_PCI_INT_MASK_ADDR AMAZON_PCI_CFG_BASE + 0x68 +#define CARDBUS_CTRL_STATUS_ADDR AMAZON_PCI_CFG_BASE + 0x6C +#define CARDBUS_CFRAME_ENABLE 0 + +#define CLOCK_CONTROL_default 0x00000000 +#define CLOCK_CONTROL_mask 0x00000003 + +#define IDENTIFICATION_default 0x0011C002 +#define IDENTIFICATION_mask 0x00000000 + +#define SOFTRESET_default 0x00000000 +// SOFTRESET bit 0 is writable but will be reset to 0 after software reset is over +#define SOFTRESET_mask 0x00000000 + +#define PCI_FPI_ERROR_ADDRESS_default 0xFFFFFFFF +#define PCI_FPI_ERROR_ADDRESS_mask 0x00000000 + +#define FPI_PCI_ERROR_ADDRESS_default 0xFFFFFFFF +#define FPI_PCI_ERROR_ADDRESS_mask 0x00000000 + +#define FPI_ERROR_TAG_default 0x0000000F +#define FPI_ERROR_TAG_mask 0x00000000 + +#define IRR_default 0x00000000 +#define IRR_mask 0x07013b2F + +#define IRA_IR_default 0x00000000 +#define IRA_IR_mask 0x07013b2F + +#define IRM_default 0x00000000 +#define IRM_mask 0xFFFFFFFF + +#define EOI_default 0x00000000 +#define EOI_mask 0x00000000 + +#define PCI_MODE_default 0x01000103 +#define PCI_MODE_mask 0x1107070F + +#define DEVICE_VENDOR_ID_default 0x000C15D1 +#define DEVICE_VENDOR_ID_mask 0xFFFFFFFF + +#define SUBSYSTEM_VENDOR_ID_default 0x000015D1 +#define SUBSYSTEM_VENDOR_ID_mask 0x0000FFFF + +#define POWER_MANAGEMENT_default 0x0000001B +#define POWER_MANAGEMENT_mask 0x0000001F + +#define CLASS_CODE1_default 0x00028000 +#define CLASS_CODE1_mask 0x00FFFFFF + +#define BAR11_MASK_default 0x0FF00008 +#define BAR11_MASK_mask 0x8FF00008 + +#define BAR12_MASK_default 0x80001800 +#define BAR12_MASK_mask 0x80001F08 + +#define BAR13_MASK_default 0x8FF00008 +#define BAR13_MASK_mask 0x8FF00008 + +#define BAR14_MASK_default 0x8F000000 +#define BAR14_MASK_mask 0x8FFFFF08 + +#define BAR15_MASK_default 0x80000000 +#define BAR15_MASK_mask 0x8FFFFF08 + +#define BAR16_MASK_default 0x80000001 +// bit 0 and bit 3 is mutually exclusive +#define BAR16_MASK_mask 0x8FFFFFF9 + +#define CARDBUS_CIS_POINTER1_default 0x00000000 +#define CARDBUS_CIS_POINTER1_mask 0x03FFFFFF + +#define SUBSYSTEM_ID1_default 0x0000000C +#define SUBSYSTEM_ID1_mask 0x0000FFFF + +#define PCI_ADDRESS_MAP_11_default 0x18000000 +#define PCI_ADDRESS_MAP_11_mask 0x7FFFFFF1 + +#define PCI_ADDRESS_MAP_12_default 0x18100000 +#define PCI_ADDRESS_MAP_12_mask 0x7FFFFF01 + +#define PCI_ADDRESS_MAP_13_default 0x18200000 +#define PCI_ADDRESS_MAP_13_mask 0x7FF00001 + +#define PCI_ADDRESS_MAP_14_default 0x70000000 +#define PCI_ADDRESS_MAP_14_mask 0x7FFFFF01 + +#define PCI_ADDRESS_MAP_15_default 0x00000001 +#define PCI_ADDRESS_MAP_15_mask 0x7FFFFF01 + +#define PCI_ADDRESS_MAP_16_default 0x60000000 +#define PCI_ADDRESS_MAP_16_mask 0x7FF00001 + +#define FPI_SEGMENT_ENABLE_default 0x000003FF +#define FPI_SEGMENT_ENABLE_mask 0x000003FF + +#define CLASS_CODE2_default 0x00FF0000 +#define CLASS_CODE2_mask 0x00FFFFFF + +#define BAR21_MASK_default 0x80000008 +#define BAR21_MASK_mask 0x8FFFFFF8 + +#define BAR22_MASK_default 0x80000008 +#define BAR22_MASK_mask 0x80001F08 + +#define BAR23_MASK_default 0x80000008 +#define BAR23_MASK_mask 0x8FF00008 + +#define BAR24_MASK_default 0x8FE00000 +#define BAR24_MASK_mask 0x8FFFFF08 + +#define BAR25_MASK_default 0x8FFFF000 +#define BAR25_MASK_mask 0x8FFFFF08 + +#define BAR26_MASK_default 0x8FFFFFE1 +#define BAR26_MASK_mask 0x8FFFFFF1 + +#define CARDBUS_CIS_POINTER2_default 0x00000000 +#define CARDBUS_CIS_POINTER2_mask 0x03FFFFFF + +#define SUBSYSTEM_ID2_default 0x0000000C +#define SUBSYSTEM_ID2_mask 0x0000FFFF + +#define PCI_ADDRESS_MAP_21_default 0x3FE00000 +#define PCI_ADDRESS_MAP_21_mask 0x7FFFFFF1 + +#define PCI_ADDRESS_MAP_22_default 0x68000000 +#define PCI_ADDRESS_MAP_22_mask 0x7FFFFF01 + +#define PCI_ADDRESS_MAP_23_default 0x20000000 +#define PCI_ADDRESS_MAP_23_mask 0x7FF00001 + +#define PCI_ADDRESS_MAP_24_default 0x70000001 +#define PCI_ADDRESS_MAP_24_mask 0x7FFFFF01 + +#define PCI_ADDRESS_MAP_25_default 0x78000001 +#define PCI_ADDRESS_MAP_25_mask 0x7FFFFF01 + +#define PCI_ADDRESS_MAP_26_default 0x20000000 +#define PCI_ADDRESS_MAP_26_mask 0x7FF00001 + +#define FPI_ADDRESS_MASK11LOW_default 0x00000000 +#define FPI_ADDRESS_MASK11LOW_mask 0x00070000 + +#define FPI_ADDRESS_MAP_0_default 0x00000000 +#define FPI_ADDRESS_MAP_0_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_1_default 0x10000000 +#define FPI_ADDRESS_MAP_1_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_2_default 0x20000000 +#define FPI_ADDRESS_MAP_2_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_3_default 0x30000000 +#define FPI_ADDRESS_MAP_3_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_4_default 0x40000000 +#define FPI_ADDRESS_MAP_4_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_5_default 0x50000000 +#define FPI_ADDRESS_MAP_5_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_6_default 0x60000000 +#define FPI_ADDRESS_MAP_6_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_7_default 0x70000000 +#define FPI_ADDRESS_MAP_7_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_11LOW_default 0xB0000000 +#define FPI_ADDRESS_MAP_11LOW_mask 0xFFFF0000 + +#define FPI_ADDRESS_MAP_11HIGH_default 0xB8000000 +#define FPI_ADDRESS_MAP_11HIGH_mask 0xFFF80000 + +#define FPI_BURST_LENGTH_default 0x00000000 +#define FPI_BURST_LENGTH_mask 0x00000303 + +#define SET_PCI_SERR_default 0x00000000 +#define SET_PCI_SERR_mask 0x00000000 + +#define DMA_FPI_START_ADDRESS_default 0x00000000 +#define DMA_FPI_START_ADDRESS_mask 0xFFFFFFFF + +#define DMA_PCI_START_ADDRESS_default 0x00000000 +#define DMA_PCI_START_ADDRESS_mask 0xFFFFFFFF + +#define DMA_TRANSFER_COUNT_default 0x00000000 +#define DMA_TRANSFER_COUNT_mask 0x0000FFFF + +#define DMA_CONTROL_STATUS_default 0x00000000 +#define DMA_CONTROL_STATUS_mask 0x00000000 // bit 0,1 is writable + +/***********************************************************************/ +#undef IKOS_MINI_BOOT //don't run a full booting +#ifdef CONFIG_USE_IKOS +#define CONFIG_USE_VENUS //Faster, 10M CPU and 192k baudrate +#ifdef CONFIG_USE_VENUS +#define IKOS_CPU_SPEED 10000000 +#else +#define IKOS_CPU_SPEED 180000 //IKOS is slow +#endif +#endif //CONFIG_USE_IKOS + +/* 165001:henryhsu:20050603:Source Modify form Bing Tao */ + +#if defined(CONFIG_NET_WIRELESS_SPURS) || defined(CONFIG_NET_WIRELESS_SPURS_MODULE) +#define EBU_PCI_SOFTWARE_ARBITOR +#endif + +#define AMAZON_B11 +#ifdef AMAZON_B11 +#define SWITCH_BUF_FPI_ADDR (0x10110000) +#define SWITCH_BUF_ADDR (KSEG1+SWITCH_BUF_FPI_ADDR) +#define SWITCH_BUF_SIZE (0x2800) +#define AMAZON_B11_CBM_QD_ADDR (SWITCH_BUF_ADDR+0x0) +#define AMAZON_B11_BOND_CELL_ADDR (SWITCH_BUF_ADDR+0x000) +#endif +#define AMAZON_REFERENCE_BOARD +//for AMAZON ATM bonding application +#ifdef AMAZON_REFERENCE_BOARD +#define GPIO_DETECT_LOW +#else +#undef GPIO_DETECT_LOW +#endif + +/* 165001 */ + +#undef AMAZON_IKOS_DEBUG_MSG +#undef AMAZON_INT_DEBUG_MSG +#undef AMAZON_ATM_DEBUG_MSG +#undef AMAZON_DMA_DEBUG_MSG +#undef AMAZON_SW_DEBUG_MSG +#undef AMAZON_WDT_DEBUG_MSG +#undef AMAZON_MTD_DEBUG_MSG +#undef AMAZON_SSC_DEBUG_MSG +#undef AMAZON_MEI_DEBUG_MSG + +#ifdef AMAZON_IKOS_DEBUG_MSG +#define AMAZON_IKOS_DMSG(fmt,args...) printk("%s:" fmt, __FUNCTION__, ##args) +#else +#define AMAZON_IKOS_DMSG(fmt,args...) +#endif + +#ifdef AMAZON_WDT_DEBUG_MSG +#define AMAZON_WDT_DMSG(fmt, args...) printk( "%s: " fmt, __FUNCTION__ , ##args) +#else +#define AMAZON_WDT_DMSG(fm,args...) +#endif + +#ifdef AMAZON_SSC_DEBUG_MSG +#define AMAZON_SSC_DMSG(fmt, args...) printk( "%s: " fmt, __FUNCTION__ , ##args) +#else +#define AMAZON_SSC_DMSG(fm,args...) +#endif + +#ifdef AMAZON_DMA_DEBUG_MSG +#define AMAZON_DMA_DMSG(fmt, args...) printk( "%s: " fmt, __FUNCTION__ , ##args) +#else +#define AMAZON_DMA_DMSG(fm,args...) +#endif + +#ifdef AMAZON_ATM_DEBUG_MSG +#define AMAZON_TPE_DMSG(fmt, args...) printk( "%s: " fmt, __FUNCTION__ , ##args) +#else //not AMAZON_ATM_DEBUG +#define AMAZON_TPE_DMSG(fmt, args...) +#endif //AMAZON_ATM_DEBUG + +#ifdef AMAZON_SW_DEBUG_MSG +#define AMAZON_SW_DMSG(fmt,args...) printk("%s: " fmt, __FUNCTION__ , ##args) +#else +#define AMAZON_SW_DMSG(fmt,args...) +#endif + +#ifdef AMAZON_MTD_DEBUG_MSG +#define AMAZON_MTD_DMSG(fmt,args...) printk("%s: " fmt, __FUNCTION__ , ##args) +#else +#define AMAZON_MTD_DMSG(fmt,args...) +#endif + +#ifdef AMAZON_INT_DEBUG_MSG +#define AMAZON_INT_DMSG(x...) printk(x) +#else +#define AMAZON_INT_DMSG(x...) +#endif + +#ifdef AMAZON_MEI_DEBUG_MSG +#define AMAZON_MEI_DMSG(fmt,args...) printk("%s:" fmt, __FUNCTION__, ##args) +#else +#define AMAZON_MEI_DMSG(fmt,args...) +#endif + +#endif //AMAZON_H diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_dma.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_dma.h new file mode 100644 index 000000000..63ab5924e --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_dma.h @@ -0,0 +1,148 @@ +#ifndef AMAZON_DMA_H +#define AMAZON_DMA_H + +#define RCV_INT 1 +#define TX_BUF_FULL_INT 2 +#define TRANSMIT_CPT_INT 4 + +#define QOS_DEFAULT_WGT 0x7fffffffUL; + + +enum attr_t{ + TX=0, + RX=1, + RESERVED=2, + DEFAULT=3, + +}; + +#ifdef CONFIG_CPU_LITTLE_ENDIAN +typedef struct rx_desc{ + u32 data_length:16; + volatile u32 reserved:7; + volatile u32 byte_offset:2; + volatile u32 Burst_length_offset:3; + volatile u32 EoP:1; + volatile u32 Res:1; + volatile u32 C:1; + volatile u32 OWN:1; + volatile u32 Data_Pointer; + /*fix me:should be 28 bits here, 32 bits just for host simulatiuon purpose*/ +}_rx_desc; + + +typedef struct tx_desc{ + volatile u32 data_length:16; + volatile u32 reserved1:7; + volatile u32 byte_offset:5; + volatile u32 EoP:1; + volatile u32 SoP:1; + volatile u32 C:1; + volatile u32 OWN:1; + volatile u32 Data_Pointer;//fix me:should be 28 bits here +}_tx_desc; +#else //BIG +typedef struct rx_desc{ + union + { + struct + { + volatile u32 OWN :1; + volatile u32 C :1; + volatile u32 SoP :1; + volatile u32 EoP :1; + volatile u32 Burst_length_offset :3; + volatile u32 byte_offset :2; + volatile u32 reserve :7; + volatile u32 data_length :16; + }field; + + volatile u32 word; + }status; + + volatile u32 Data_Pointer; +}_rx_desc; + + +typedef struct tx_desc{ + union + { + struct + { + volatile u32 OWN :1; + volatile u32 C :1; + volatile u32 SoP :1; + volatile u32 EoP :1; + volatile u32 byte_offset :5; + volatile u32 reserved :7; + volatile u32 data_length :16; + }field; + + volatile u32 word; + }status; + + volatile u32 Data_Pointer; +}_tx_desc; + +#endif //ENDIAN + +struct dma_channel_info{ + /*filled by driver, optional*/ + enum attr_t attr;/*TX or RX*/ + int weight; + int desc_num; + int packet_size; + int control;/*on or off*/ + + int desc_base; + int status; +}; + +typedef struct dma_channel_info _dma_channel_info; + +struct dma_device_info{ + /*variables*/ + /*filled by driver, compulsary*/ + char device_name[15]; + enum attr_t attr;/*default or else*/ + int tx_burst_len; + int rx_burst_len; + + int logic_rx_chan_base; + int logic_tx_chan_base; + u8 on_ch_bit; + /*filled by driver, optional*/ + int weight; + int current_tx_chan; + int current_rx_chan; + int num_tx_chan; + int num_rx_chan; + struct dma_channel_info tx_chan[2]; + struct dma_channel_info rx_chan[4]; + + /*functions, optional*/ + u8* (*buffer_alloc)(int len,int* offset, void** opt); + int (*buffer_free)(u8* dataptr, void* opt); + int (*intr_handler)(struct dma_device_info* info, int status); + /*set by device, clear by dma*/ + int ack; + void * priv; /* used by peripheral driver only */ +}; +typedef struct dma_device_info _dma_device_info; + +int dma_device_register(struct dma_device_info* info); + +int dma_device_unregister(struct dma_device_info* info); + +int dma_device_read(struct dma_device_info* info, u8** dataptr, void** opt); + +int dma_device_write(struct dma_device_info* info, u8* dataptr, int len, void* opt); + +int dma_device_update(struct dma_device_info* info); + +void dma_device_update_rx(struct dma_device_info* dma_dev); + +void dma_device_update_tx(struct dma_device_info* dma_dev); + +void register_handler_sim(int (*handler)(int)); +#endif /* AMAZON_DMA_H */ diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei.h new file mode 100644 index 000000000..6ac8ab310 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei.h @@ -0,0 +1,220 @@ +#ifndef _AMAZON_MEI_H +#define _AMAZON_MEI_H +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "amazon_mei_app.h" + +#define AMAZON_MEI_DEBUG_ON +#define AMAZON_MEI_CMV_EXTRA + +#define AMAZON_MEI_MAJOR 106 + +/* +** Define where in ME Processor's memory map the Stratify chip lives +*/ +#define MEI_SPACE_ACCESS 0xB0100C00 + +#define MAXSWAPSIZE 8 * 1024 //8k *(32bits) +//#define AMAZON_ADSL_IMAGESIZE 16*1024 // 16k * (32bits) + + +// Mailboxes +#define MSG_LENGTH 16 // x16 bits +#define YES_REPLY 1 +#define NO_REPLY 0 + +#define CMV_TIMEOUT 100 //jiffies +#define MIB_INTERVAL 10000 //msec + +/*** Bit definitions ***/ + +#define FALSE 0 +#define TRUE 1 +#define BIT0 1<<0 +#define BIT1 1<<1 +#define BIT2 1<<2 +#define BIT3 1<<3 +#define BIT4 1<<4 +#define BIT5 1<<5 +#define BIT6 1<<6 +#define BIT7 1<<7 +#define BIT8 1<<8 +#define BIT9 1<<9 +#define BIT10 1<<10 +#define BIT11 1<<11 +#define BIT12 1<<12 +#define BIT13 1<<13 +#define BIT14 1<<14 +#define BIT15 1<<15 +#define BIT16 1<<16 +#define BIT17 1<<17 +#define BIT18 1<<18 +#define BIT19 1<<19 +#define BIT20 1<<20 +#define BIT21 1<<21 +#define BIT22 1<<22 +#define BIT23 1<<23 +#define BIT24 1<<24 +#define BIT25 1<<25 +#define BIT26 1<<26 +#define BIT27 1<<27 +#define BIT28 1<<28 +#define BIT29 1<<29 +#define BIT30 1<<30 +#define BIT31 1<<31 + + +/*** Register address offsets, relative to MEI_SPACE_ADDRESS ***/ +#define MEI_DATA_XFR (0x0000 + MEI_SPACE_ACCESS) +#define MEI_VERSION (0x0200 + MEI_SPACE_ACCESS) +#define ARC_GP_STAT (0x0204 + MEI_SPACE_ACCESS) +#define MEI_XFR_ADDR (0x020C + MEI_SPACE_ACCESS) +#define MEI_TO_ARC_INT (0x021C + MEI_SPACE_ACCESS) +#define ARC_TO_MEI_INT (0x0220 + MEI_SPACE_ACCESS) +#define ARC_TO_MEI_INT_MASK (0x0224 + MEI_SPACE_ACCESS) +#define MEI_DEBUG_WAD (0x0228 + MEI_SPACE_ACCESS) +#define MEI_DEBUG_RAD (0x022C + MEI_SPACE_ACCESS) +#define MEI_DEBUG_DATA (0x0230 + MEI_SPACE_ACCESS) +#define MEI_DEBUG_DEC (0x0234 + MEI_SPACE_ACCESS) +#define MEI_CONTROL (0x0238 + MEI_SPACE_ACCESS) +#define AT_CELLRDY_BC0 (0x023C + MEI_SPACE_ACCESS) +#define AT_CELLRDY_BC1 (0x0240 + MEI_SPACE_ACCESS) +#define AR_CELLRDY_BC0 (0x0244 + MEI_SPACE_ACCESS) +#define AR_CELLRDY_BC1 (0x0248 + MEI_SPACE_ACCESS) +#define AAI_ACCESS (0x024C + MEI_SPACE_ACCESS) +#define AAITXCB0 (0x0300 + MEI_SPACE_ACCESS) +#define AAITXCB1 (0x0304 + MEI_SPACE_ACCESS) +#define AAIRXCB0 (0x0308 + MEI_SPACE_ACCESS) +#define AAIRXCB1 (0x030C + MEI_SPACE_ACCESS) + + +// MEI_TO_ARC_INTERRUPT Register definitions +#define MEI_TO_ARC_INT1 BIT3 +#define MEI_TO_ARC_INT0 BIT2 +#define MEI_TO_ARC_CS_DONE BIT1 +#define MEI_TO_ARC_MSGAV BIT0 + +// ARC_TO_MEI_INTERRUPT Register definitions +#define ARC_TO_MEI_INT1 BIT8 +#define ARC_TO_MEI_INT0 BIT7 +#define ARC_TO_MEI_CS_REQ BIT6 +#define ARC_TO_MEI_DBG_DONE BIT5 +#define ARC_TO_MEI_MSGACK BIT4 +#define ARC_TO_MEI_NO_ACCESS BIT3 +#define ARC_TO_MEI_CHECK_AAITX BIT2 +#define ARC_TO_MEI_CHECK_AAIRX BIT1 +#define ARC_TO_MEI_MSGAV BIT0 + +// ARC_TO_MEI_INTERRUPT_MASK Register definitions +#define GP_INT1_EN BIT8 +#define GP_INT0_EN BIT7 +#define CS_REQ_EN BIT6 +#define DBG_DONE_EN BIT5 +#define MSGACK_EN BIT4 +#define NO_ACC_EN BIT3 +#define AAITX_EN BIT2 +#define AAIRX_EN BIT1 +#define MSGAV_EN BIT0 + +// MEI_CONTROL Register definitions +#define INT_LEVEL BIT2 +#define SOFT_RESET BIT1 +#define HOST_MSTR BIT0 + +// MEI_DEBUG_DECODE Register definitions +#define MEI_DEBUG_DEC_MASK (0x3) +#define MEI_DEBUG_DEC_AUX_MASK (0x0) +#define MEI_DEBUG_DEC_DMP1_MASK (0x1) +#define MEI_DEBUG_DEC_DMP2_MASK (0x2) +#define MEI_DEBUG_DEC_CORE_MASK (0x3) + + +// ARC_TO_MEI_MAILBOX[11] is a special location used to indicate +// page swap requests. +#define MEI_TO_ARC_MAILBOX (0x15FC0) +#define MEI_TO_ARC_MAILBOXR (0x15FEC) +#define ARC_TO_MEI_MAILBOX (0x15F90) +#define ARC_MEI_MAILBOXR (0x15FBC) + +// Codeswap request messages are indicated by setting BIT31 +#define OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK (0x80000000) + +/* +** Swap page header +*/ +// Page must be loaded at boot time if size field has BIT31 set +#define BOOT_FLAG (BIT31) +#define BOOT_FLAG_MASK ~BOOT_FLAG + +// Swap page header describes size in 32-bit words, load location, and image offset +// for program and/or data segments +typedef struct _arc_swp_page_hdr +{ + u32 p_offset; // Offset bytes of progseg from beginning of image + u32 p_dest; // Destination addr of progseg on processor + u32 p_size; // Size in 32-bitwords of program segment + u32 d_offset; // Offset bytes of dataseg from beginning of image + u32 d_dest; // Destination addr of dataseg on processor + u32 d_size; // Size in 32-bitwords of data segment +}ARC_SWP_PAGE_HDR; + + +/* +** Swap image header +*/ +#define GET_PROG 0 // Flag used for program mem segment +#define GET_DATA 1 // Flag used for data mem segment + +// Image header contains size of image, checksum for image, and count of +// page headers. Following that are 'count' page headers followed by +// the code and/or data segments to be loaded +typedef struct _arc_img_hdr +{ + u32 size; // Size of binary image in bytes + u32 checksum; // Checksum for image + u32 count; // Count of swp pages in image + ARC_SWP_PAGE_HDR page[1]; // Should be "count" pages - '1' to make compiler happy +}ARC_IMG_HDR; + + + +/* +** Native size for the Stratiphy interface is 32-bits. All reads and writes +** MUST be aligned on 32-bit boundaries. Trickery must be invoked to read word and/or +** byte data. Read routines are provided. Write routines are probably a bad idea, as the +** Arc has unrestrained, unseen access to the same memory, so a read-modify-write cycle +** could very well have unintended results. +*/ +MEI_ERROR meiCMV(u16 *, int); // first arg is CMV to ARC, second to indicate whether need reply + +void meiLongwordWrite(u32 ul_address, u32 ul_data); +void meiLongwordRead(u32 ul_address, u32 *pul_data); + + +MEI_ERROR meiDMAWrite(u32 destaddr, u32 *databuff, u32 databuffsize); +MEI_ERROR meiDebugWrite(u32 destaddr, u32 *databuff, u32 databuffsize); + +MEI_ERROR meiDMARead(u32 srcaddr, u32 *databuff, u32 databuffsize); +MEI_ERROR meiDebugRead(u32 srcaddr, u32 *databuff, u32 databuffsize); + +void meiPollForDbgDone(void); + +void meiMailboxInterruptsDisable(void); +void meiMailboxInterruptsEnable(void); + +MEI_ERROR meiMailboxWrite(u16 *msgsrcbuffer, u16 msgsize); +MEI_ERROR meiMailboxRead(u16 *msgdestbuffer, u16 msgsize); + +int meiGetPage( u32 Page, u32 data, u32 MaxSize, u32 *Buffer, u32 *Dest); + +MEI_ERROR meiHaltArc(void); +MEI_ERROR meiRunArc(void); + +MEI_ERROR meiDownloadBootCode(void); + +MEI_ERROR meiForceRebootAdslModem(void); + +void makeCMV(u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data); + +#endif + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_app.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_app.h new file mode 100644 index 000000000..89700d9d7 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_app.h @@ -0,0 +1,54 @@ +//509221:tc.chen 2005/09/22 Reset DFE added when MEI_TO_ARC_CS_DONE not cleared by ARC and Added AMAZON_MEI_DEBUG_MODE ioctl + +#ifndef _AMAZON_MEI_APP_H +#define _AMAZON_MEI_APP_H + +///////////////////////////////////////////////////////////////////////////////////////////////////// + + // ioctl control +#define AMAZON_MEI_START 300 +#define AMAZON_MEI_REPLY 301 +#define AMAZON_MEI_NOREPLY 302 + +#define AMAZON_MEI_RESET 303 +#define AMAZON_MEI_REBOOT 304 +#define AMAZON_MEI_HALT 305 +#define AMAZON_MEI_CMV_WINHOST 306 +#define AMAZON_MEI_CMV_READ 307 +#define AMAZON_MEI_CMV_WRITE 308 +#define AMAZON_MEI_MIB_DAEMON 309 +#define AMAZON_MEI_SHOWTIME 310 +#define AMAZON_MEI_REMOTE 311 +#define AMAZON_MEI_READDEBUG 312 +#define AMAZON_MEI_WRITEDEBUG 313 +#define AMAZON_MEI_LOP 314 + +#define AMAZON_MEI_PCM_SETUP 315 +#define AMAZON_MEI_PCM_START_TIMER 316 +#define AMAZON_MEI_PCM_STOP_TIMER 317 +#define AMAZON_MEI_PCM_CHECK 318 +#define AMAZON_MEI_GET_EOC_LEN 319 +#define AMAZON_MEI_GET_EOC_DATA 320 +#define AMAZON_MEI_PCM_GETDATA 321 +#define AMAZON_MEI_PCM_GPIO 322 +#define AMAZON_MEI_EOC_SEND 323 +//MIB +#define AMAZON_MIB_LO_ATUC 324 +#define AMAZON_MIB_LO_ATUR 325 +#define AMAZON_MEI_DOWNLOAD 326 + +#define AMAZON_MEI_DEBUG_MODE 327 //509221:tc.chen +#define LOOP_DIAGNOSTIC_MODE_COMPLETE 328 + + +/*** Enums ***/ +typedef enum mei_error +{ + MEI_SUCCESS = 0, + MEI_FAILURE = -1, + MEI_MAILBOX_FULL = -2, + MEI_MAILBOX_EMPTY = -3, + MEI_MAILBOX_TIMEOUT = -4, +}MEI_ERROR; + +#endif diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_app_ioctl.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_app_ioctl.h new file mode 100644 index 000000000..d98f60b17 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_app_ioctl.h @@ -0,0 +1,1169 @@ +// 603221:tc.chen 2006/03/21 added APIs to support the WEB related parameters for ADSL Statistics + +#ifndef __AMAZON_MEI_APP_IOCTL_H +#define __AMAZON_MEI_APP_IOCTL_H + +#ifdef __KERNEL__ +#include "amazon_mei_ioctl.h" +#endif + +/* Interface Name */ +//#define INTERFACE_NAME + +/* adslLineTable constants */ +#define GET_ADSL_LINE_CODE 1 + +/* adslAtucPhysTable constants */ +#define GET_ADSL_ATUC_PHY 4 + +/* adslAturPhysTable constants */ +#define GET_ADSL_ATUR_PHY 10 + +/* adslAtucChanTable constants */ +#define GET_ADSL_ATUC_CHAN_INFO 15 + +/* adslAturChanTable constants */ +#define GET_ADSL_ATUR_CHAN_INFO 18 + +/* adslAtucPerfDataTable constants */ +#define GET_ADSL_ATUC_PERF_DATA 21 + +/* adslAturPerfDataTable constants */ +#define GET_ADSL_ATUR_PERF_DATA 40 + +/* adslAtucIntervalTable constants */ +#define GET_ADSL_ATUC_INTVL_INFO 60 + +/* adslAturIntervalTable constants */ +#define GET_ADSL_ATUR_INTVL_INFO 65 + +/* adslAtucChanPerfDataTable constants */ +#define GET_ADSL_ATUC_CHAN_PERF_DATA 70 + +/* adslAturChanPerfDataTable constants */ +#define GET_ADSL_ATUR_CHAN_PERF_DATA 90 + +/* adslAtucChanIntervalTable constants */ +#define GET_ADSL_ATUC_CHAN_INTVL_INFO 110 + +/* adslAturChanIntervalTable constants */ +#define GET_ADSL_ATUR_CHAN_INTVL_INFO 115 + +/* adslLineAlarmConfProfileTable constants */ +#define GET_ADSL_ALRM_CONF_PROF 120 +#define SET_ADSL_ALRM_CONF_PROF 121 + +/* adslAturTrap constants */ +#define ADSL_ATUR_TRAPS 135 + +////////////////// RFC-3440 ////////////// + +#ifdef AMAZON_MEI_MIB_RFC3440 +/* adslLineExtTable */ +#define GET_ADSL_ATUC_LINE_EXT 201 +#define SET_ADSL_ATUC_LINE_EXT 203 + +/* adslAtucPerfDateExtTable */ +#define GET_ADSL_ATUC_PERF_DATA_EXT 205 + +/* adslAtucIntervalExtTable */ +#define GET_ADSL_ATUC_INTVL_EXT_INFO 221 + +/* adslAturPerfDataExtTable */ +#define GET_ADSL_ATUR_PERF_DATA_EXT 225 + +/* adslAturIntervalExtTable */ +#define GET_ADSL_ATUR_INTVL_EXT_INFO 233 + +/* adslAlarmConfProfileExtTable */ +#define GET_ADSL_ALRM_CONF_PROF_EXT 235 +#define SET_ADSL_ALRM_CONF_PROF_EXT 236 + +/* adslAturExtTrap */ +#define ADSL_ATUR_EXT_TRAPS 240 + +#endif + +// 603221:tc.chen start +/* The following constants are added to support the WEB related ADSL Statistics */ + +/* adslLineStatus constants */ +#define GET_ADSL_LINE_STATUS 245 + +/* adslLineRate constants */ +#define GET_ADSL_LINE_RATE 250 + +/* adslLineInformation constants */ +#define GET_ADSL_LINE_INFO 255 + +/* adslNearEndPerformanceStats constants */ +#define GET_ADSL_NEAREND_STATS 270 + +/* adslFarEndPerformanceStats constants */ +#define GET_ADSL_FAREND_STATS 290 + +// 603221:tc.chen end + +/* Loop diagnostics mode of the ADSL line related constants */ +#define GET_ADSL_LOOP_DIAGNOSTICS_MODE 295 +#define SET_ADSL_LOOP_DIAGNOSTICS_MODE 296 +#define IS_ADSL_LOOP_DIAGNOSTICS_MODE_COMPLETE 299 + +/* Sub-carrier related parameters */ +#define GET_ADSL_ATUC_SUBCARRIER_STATS 297 +#define GET_ADSL_ATUR_SUBCARRIER_STATS 298 +#define GET_ADSL_LINE_INIT_STATS 150 +#define GET_ADSL_POWER_SPECTRAL_DENSITY 151 + + +/////////////////////////////////////////////////////////// +// makeCMV(Opcode, Group, Address, Index, Size, Data) + +/* adslLineCode Flags */ +#define LINE_CODE_FLAG 0x1 /* BIT 0th position */ + +/* adslAtucPhysTable Flags */ +#define ATUC_PHY_SER_NUM_FLAG 0x1 /* BIT 0th position */ +#define ATUC_PHY_SER_NUM_FLAG_MAKECMV1 makeCMV(H2D_CMV_READ, INFO, 57, 0, 12, data) +#define ATUC_PHY_SER_NUM_FLAG_MAKECMV2 makeCMV(H2D_CMV_READ, INFO, 57, 12, 4, data) + +#define ATUC_PHY_VENDOR_ID_FLAG 0x2 /* BIT 1 */ +#define ATUC_PHY_VENDOR_ID_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 64, 0, 4, data) + +#define ATUC_PHY_VER_NUM_FLAG 0x4 /* BIT 2 */ +#define ATUC_PHY_VER_NUM_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 58, 0, 8, data) + +#define ATUC_CURR_STAT_FLAG 0x8 /* BIT 3 */ + +#define ATUC_CURR_OUT_PWR_FLAG 0x10 /* BIT 4 */ +#define ATUC_CURR_OUT_PWR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 5, 1, data) + +#define ATUC_CURR_ATTR_FLAG 0x20 /* BIT 5 */ +#define ATUC_CURR_ATTR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 0, 2, data) + + +/* adslAturPhysTable Flags */ +#define ATUR_PHY_SER_NUM_FLAG 0x1 /* BIT 0th position */ +#define ATUR_PHY_SER_NUM_FLAG_MAKECMV1 makeCMV(H2D_CMV_READ, INFO, 62, 0, 12, data) +#define ATUR_PHY_SER_NUM_FLAG_MAKECMV2 makeCMV(H2D_CMV_READ, INFO, 62, 12, 4, data) + +#define ATUR_PHY_VENDOR_ID_FLAG 0x2 /* BIT 1 */ +#define ATUR_PHY_VENDOR_ID_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 65, 0, 4, data) + +#define ATUR_PHY_VER_NUM_FLAG 0x4 /* BIT 2 */ +#define ATUR_PHY_VER_NUM_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 61, 0, 8, data) + +#define ATUR_SNRMGN_FLAG 0x8 +#define ATUR_SNRMGN_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 4, 1, data) + +#define ATUR_ATTN_FLAG 0x10 +#define ATUR_ATTN_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 2, 1, data) + +#define ATUR_CURR_STAT_FLAG 0x20 /* BIT 3 */ + +#define ATUR_CURR_OUT_PWR_FLAG 0x40 /* BIT 4 */ +#define ATUR_CURR_OUT_PWR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 5, 1, data) + +#define ATUR_CURR_ATTR_FLAG 0x80 /* BIT 5 */ +#define ATUR_CURR_ATTR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 0, 2, data) + +/* adslAtucChanTable Flags */ +#define ATUC_CHAN_INTLV_DELAY_FLAG 0x1 /* BIT 0th position */ +#define ATUC_CHAN_INTLV_DELAY_FLAG_MAKECMV makeCMV(H2D_CMV_READ, RATE, 3, 1, 1, data) + +#define ATUC_CHAN_CURR_TX_RATE_FLAG 0x2 /* BIT 1 */ +#define ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV makeCMV(H2D_CMV_READ, RATE, 1, 0, 2, data) + +#define ATUC_CHAN_PREV_TX_RATE_FLAG 0x4 /* BIT 2 */ + +/* adslAturChanTable Flags */ +#define ATUR_CHAN_INTLV_DELAY_FLAG 0x1 /* BIT 0th position */ +#define ATUR_CHAN_INTLV_DELAY_FLAG_MAKECMV makeCMV(H2D_CMV_READ, RATE, 2, 1, 1, data) + +#define ATUR_CHAN_CURR_TX_RATE_FLAG 0x2 /* BIT 1 */ +#define ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV makeCMV(H2D_CMV_READ, RATE, 0, 0, 2, data) + +#define ATUR_CHAN_PREV_TX_RATE_FLAG 0x4 /* BIT 2 */ + +#define ATUR_CHAN_CRC_BLK_LEN_FLAG 0x8 /* BIT 3 */ + +/* adslAtucPerfDataTable Flags */ +#define ATUC_PERF_LOFS_FLAG 0x1 /* BIT 0th position */ +#define ATUC_PERF_LOSS_FLAG 0x2 /* BIT 1 */ +#define ATUC_PERF_LO_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 0, 0, 1, data) +#define ATUC_PERF_ESS_FLAG 0x4 /* BIT 2 */ +#define ATUC_PERF_ESS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 7, 0, 1, data) +#define ATUC_PERF_INITS_FLAG 0x8 /* BIT 3 */ +#define ATUC_PERF_VALID_INTVLS_FLAG 0x10 /* BIT 4 */ +#define ATUC_PERF_INVALID_INTVLS_FLAG 0x20 /* BIT 5 */ +#define ATUC_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */ +#define ATUC_PERF_CURR_15MIN_LOFS_FLAG 0x80 /* BIT 7 */ +#define ATUC_PERF_CURR_15MIN_LOSS_FLAG 0x100 /* BIT 8 */ +#define ATUC_PERF_CURR_15MIN_ESS_FLAG 0x200 /* BIT 9 */ +#define ATUC_PERF_CURR_15MIN_INIT_FLAG 0x400 /* BIT 10 */ +#define ATUC_PERF_CURR_1DAY_TIME_ELAPSED_FLAG 0x800 /* BIT 11 */ +#define ATUC_PERF_CURR_1DAY_LOFS_FLAG 0x1000 /* BIT 12 */ +#define ATUC_PERF_CURR_1DAY_LOSS_FLAG 0x2000 /* BIT 13 */ +#define ATUC_PERF_CURR_1DAY_ESS_FLAG 0x4000 /* BIT 14 */ +#define ATUC_PERF_CURR_1DAY_INIT_FLAG 0x8000 /* BIT 15 */ +#define ATUC_PERF_PREV_1DAY_MON_SEC_FLAG 0x10000 /* BIT 16 */ +#define ATUC_PERF_PREV_1DAY_LOFS_FLAG 0x20000 /* BIT 17 */ +#define ATUC_PERF_PREV_1DAY_LOSS_FLAG 0x40000 /* BIT 18 */ +#define ATUC_PERF_PREV_1DAY_ESS_FLAG 0x80000 /* BIT 19 */ +#define ATUC_PERF_PREV_1DAY_INITS_FLAG 0x100000 /* BIT 20 */ + +/* adslAturPerfDataTable Flags */ +#define ATUR_PERF_LOFS_FLAG 0x1 /* BIT 0th position */ +#define ATUR_PERF_LOSS_FLAG 0x2 /* BIT 1 */ +#define ATUR_PERF_LPR_FLAG 0x4 /* BIT 2 */ +#define ATUR_PERF_LO_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 1, 0, 1, data) +#define ATUR_PERF_ESS_FLAG 0x8 /* BIT 3 */ +#define ATUR_PERF_ESS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 33, 0, 1, data) +#define ATUR_PERF_VALID_INTVLS_FLAG 0x10 /* BIT 4 */ +#define ATUR_PERF_INVALID_INTVLS_FLAG 0x20 /* BIT 5 */ +#define ATUR_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */ +#define ATUR_PERF_CURR_15MIN_LOFS_FLAG 0x80 /* BIT 7 */ +#define ATUR_PERF_CURR_15MIN_LOSS_FLAG 0x100 /* BIT 8 */ +#define ATUR_PERF_CURR_15MIN_LPR_FLAG 0x200 /* BIT 9 */ +#define ATUR_PERF_CURR_15MIN_ESS_FLAG 0x400 /* BIT 10 */ +#define ATUR_PERF_CURR_1DAY_TIME_ELAPSED_FLAG 0x800 /* BIT 11 */ +#define ATUR_PERF_CURR_1DAY_LOFS_FLAG 0x1000 /* BIT 12 */ +#define ATUR_PERF_CURR_1DAY_LOSS_FLAG 0x2000 /* BIT 13 */ +#define ATUR_PERF_CURR_1DAY_LPR_FLAG 0x4000 /* BIT 14 */ +#define ATUR_PERF_CURR_1DAY_ESS_FLAG 0x8000 /* BIT 15 */ +#define ATUR_PERF_PREV_1DAY_MON_SEC_FLAG 0x10000 /* BIT 16 */ +#define ATUR_PERF_PREV_1DAY_LOFS_FLAG 0x20000 /* BIT 17 */ +#define ATUR_PERF_PREV_1DAY_LOSS_FLAG 0x40000 /* BIT 18 */ +#define ATUR_PERF_PREV_1DAY_LPR_FLAG 0x80000 /* BIT 19 */ +#define ATUR_PERF_PREV_1DAY_ESS_FLAG 0x100000 /* BIT 20 */ + +/* adslAtucIntervalTable Flags */ +#define ATUC_INTVL_LOF_FLAG 0x1 /* BIT 0th position */ +#define ATUC_INTVL_LOS_FLAG 0x2 /* BIT 1 */ +#define ATUC_INTVL_ESS_FLAG 0x4 /* BIT 2 */ +#define ATUC_INTVL_INIT_FLAG 0x8 /* BIT 3 */ +#define ATUC_INTVL_VALID_DATA_FLAG 0x10 /* BIT 4 */ + +/* adslAturIntervalTable Flags */ +#define ATUR_INTVL_LOF_FLAG 0x1 /* BIT 0th position */ +#define ATUR_INTVL_LOS_FLAG 0x2 /* BIT 1 */ +#define ATUR_INTVL_LPR_FLAG 0x4 /* BIT 2 */ +#define ATUR_INTVL_ESS_FLAG 0x8 /* BIT 3 */ +#define ATUR_INTVL_VALID_DATA_FLAG 0x10 /* BIT 4 */ + +/* adslAtucChanPerfDataTable Flags */ +#define ATUC_CHAN_RECV_BLK_FLAG 0x01 /* BIT 0th position */ +#define ATUC_CHAN_TX_BLK_FLAG 0x02 /* BIT 1 */ +#define ATUC_CHAN_CORR_BLK_FLAG 0x04 /* BIT 2 */ +#define ATUC_CHAN_UNCORR_BLK_FLAG 0x08 /* BIT 3 */ +#define ATUC_CHAN_PERF_VALID_INTVL_FLAG 0x10 /* BIT 4 */ +#define ATUC_CHAN_PERF_INVALID_INTVL_FLAG 0x20 /* BIT 5 */ +#define ATUC_CHAN_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */ +#define ATUC_CHAN_PERF_CURR_15MIN_RECV_BLK_FLAG 0x80 /* BIT 7 */ +#define ATUC_CHAN_PERF_CURR_15MIN_TX_BLK_FLAG 0x100 /* BIT 8 */ +#define ATUC_CHAN_PERF_CURR_15MIN_CORR_BLK_FLAG 0x200 /* BIT 9 */ +#define ATUC_CHAN_PERF_CURR_15MIN_UNCORR_BLK_FLAG 0x400 /* BIT 10 */ +#define ATUC_CHAN_PERF_CURR_1DAY_TIME_ELAPSED_FLAG 0x800 /* BIT 11*/ +#define ATUC_CHAN_PERF_CURR_1DAY_RECV_BLK_FLAG 0x1000 /* BIT 12 */ +#define ATUC_CHAN_PERF_CURR_1DAY_TX_BLK_FLAG 0x2000 /* BIT 13 */ +#define ATUC_CHAN_PERF_CURR_1DAY_CORR_BLK_FLAG 0x4000 /* BIT 14 */ +#define ATUC_CHAN_PERF_CURR_1DAY_UNCORR_BLK_FLAG 0x8000 /* BIT 15 */ +#define ATUC_CHAN_PERF_PREV_1DAY_MONI_SEC_FLAG 0x10000 /* BIT 16 */ +#define ATUC_CHAN_PERF_PREV_1DAY_RECV_BLK_FLAG 0x20000 /* BIT 17 */ +#define ATUC_CHAN_PERF_PREV_1DAY_TX_BLK_FLAG 0x40000 /* BIT 18 */ +#define ATUC_CHAN_PERF_PREV_1DAY_CORR_BLK_FLAG 0x80000 /* BIT 19 */ +#define ATUC_CHAN_PERF_PREV_1DAY_UNCORR_BLK_FLAG 0x100000 /* BIT 20 */ + + +/* adslAturChanPerfDataTable Flags */ +#define ATUR_CHAN_RECV_BLK_FLAG 0x01 /* BIT 0th position */ +#define ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_LSW makeCMV(H2D_CMV_READ, PLAM, 20, 0, 1, data) +#define ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_MSW makeCMV(H2D_CMV_READ, PLAM, 21, 0, 1, data) +#define ATUR_CHAN_TX_BLK_FLAG 0x02 /* BIT 1 */ +#define ATUR_CHAN_TX_BLK_FLAG_MAKECMV_LSW makeCMV(H2D_CMV_READ, PLAM, 20, 0, 1, data) +#define ATUR_CHAN_TX_BLK_FLAG_MAKECMV_MSW makeCMV(H2D_CMV_READ, PLAM, 21, 0, 1, data) +#define ATUR_CHAN_CORR_BLK_FLAG 0x04 /* BIT 2 */ +#define ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_INTL makeCMV(H2D_CMV_READ, PLAM, 3, 0, 1, data) +#define ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_FAST makeCMV(H2D_CMV_READ, PLAM, 3, 1, 1, data) +#define ATUR_CHAN_UNCORR_BLK_FLAG 0x08 /* BIT 3 */ +#define ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_INTL makeCMV(H2D_CMV_READ, PLAM, 2, 0, 1, data) +#define ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_FAST makeCMV(H2D_CMV_READ, PLAM, 2, 1, 1, data) +#define ATUR_CHAN_PERF_VALID_INTVL_FLAG 0x10 /* BIT 4 */ +#define ATUR_CHAN_PERF_INVALID_INTVL_FLAG 0x20 /* BIT 5 */ +#define ATUR_CHAN_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */ +#define ATUR_CHAN_PERF_CURR_15MIN_RECV_BLK_FLAG 0x80 /* BIT 7 */ +#define ATUR_CHAN_PERF_CURR_15MIN_TX_BLK_FLAG 0x100 /* BIT 8 */ +#define ATUR_CHAN_PERF_CURR_15MIN_CORR_BLK_FLAG 0x200 /* BIT 9 */ +#define ATUR_CHAN_PERF_CURR_15MIN_UNCORR_BLK_FLAG 0x400 /* BIT 10 */ +#define ATUR_CHAN_PERF_CURR_1DAY_TIME_ELAPSED_FLAG 0x800 /* BIT 11 */ +#define ATUR_CHAN_PERF_CURR_1DAY_RECV_BLK_FLAG 0x1000 /* BIT 12 */ +#define ATUR_CHAN_PERF_CURR_1DAY_TX_BLK_FLAG 0x2000 /* BIT 13 */ +#define ATUR_CHAN_PERF_CURR_1DAY_CORR_BLK_FLAG 0x4000 /* BIT 14 */ +#define ATUR_CHAN_PERF_CURR_1DAY_UNCORR_BLK_FLAG 0x8000 /* BIT 15 */ +#define ATUR_CHAN_PERF_PREV_1DAY_MONI_SEC_FLAG 0x10000 /* BIT 16 */ +#define ATUR_CHAN_PERF_PREV_1DAY_RECV_BLK_FLAG 0x20000 /* BIT 17 */ +#define ATUR_CHAN_PERF_PREV_1DAY_TRANS_BLK_FLAG 0x40000 /* BIT 18 */ +#define ATUR_CHAN_PERF_PREV_1DAY_CORR_BLK_FLAG 0x80000 /* BIT 19 */ +#define ATUR_CHAN_PERF_PREV_1DAY_UNCORR_BLK_FLAG 0x100000 /* BIT 20 */ + +/* adslAtucChanIntervalTable Flags */ +#define ATUC_CHAN_INTVL_NUM_FLAG 0x1 /* BIT 0th position */ +#define ATUC_CHAN_INTVL_RECV_BLK_FLAG 0x2 /* BIT 1 */ +#define ATUC_CHAN_INTVL_TX_BLK_FLAG 0x4 /* BIT 2 */ +#define ATUC_CHAN_INTVL_CORR_BLK_FLAG 0x8 /* BIT 3 */ +#define ATUC_CHAN_INTVL_UNCORR_BLK_FLAG 0x10 /* BIT 4 */ +#define ATUC_CHAN_INTVL_VALID_DATA_FLAG 0x20 /* BIT 5 */ + +/* adslAturChanIntervalTable Flags */ +#define ATUR_CHAN_INTVL_NUM_FLAG 0x1 /* BIT 0th Position */ +#define ATUR_CHAN_INTVL_RECV_BLK_FLAG 0x2 /* BIT 1 */ +#define ATUR_CHAN_INTVL_TX_BLK_FLAG 0x4 /* BIT 2 */ +#define ATUR_CHAN_INTVL_CORR_BLK_FLAG 0x8 /* BIT 3 */ +#define ATUR_CHAN_INTVL_UNCORR_BLK_FLAG 0x10 /* BIT 4 */ +#define ATUR_CHAN_INTVL_VALID_DATA_FLAG 0x20 /* BIT 5 */ + +/* adslLineAlarmConfProfileTable Flags */ +#define ATUC_THRESH_15MIN_LOFS_FLAG 0x01 /* BIT 0th position */ +#define ATUC_THRESH_15MIN_LOSS_FLAG 0x02 /* BIT 1 */ +#define ATUC_THRESH_15MIN_ESS_FLAG 0x04 /* BIT 2 */ +#define ATUC_THRESH_FAST_RATEUP_FLAG 0x08 /* BIT 3 */ +#define ATUC_THRESH_INTERLEAVE_RATEUP_FLAG 0x10 /* BIT 4 */ +#define ATUC_THRESH_FAST_RATEDOWN_FLAG 0x20 /* BIT 5 */ +#define ATUC_THRESH_INTERLEAVE_RATEDOWN_FLAG 0x40 /* BIT 6 */ +#define ATUC_INIT_FAILURE_TRAP_ENABLE_FLAG 0x80 /* BIT 7 */ +#define ATUR_THRESH_15MIN_LOFS_FLAG 0x100 /* BIT 8 */ +#define ATUR_THRESH_15MIN_LOSS_FLAG 0x200 /* BIT 9 */ +#define ATUR_THRESH_15MIN_LPRS_FLAG 0x400 /* BIT 10 */ +#define ATUR_THRESH_15MIN_ESS_FLAG 0x800 /* BIT 11 */ +#define ATUR_THRESH_FAST_RATEUP_FLAG 0x1000 /* BIT 12 */ +#define ATUR_THRESH_INTERLEAVE_RATEUP_FLAG 0x2000 /* BIT 13 */ +#define ATUR_THRESH_FAST_RATEDOWN_FLAG 0x4000 /* BIT 14 */ +#define ATUR_THRESH_INTERLEAVE_RATEDOWN_FLAG 0x8000 /* BIT 15 */ +#define LINE_ALARM_CONF_PROFILE_ROWSTATUS_FLAG 0x10000 /* BIT 16 */ + + +/* adslAturTraps Flags */ +#define ATUC_PERF_LOFS_THRESH_FLAG 0x1 /* BIT 0th position */ +#define ATUC_PERF_LOSS_THRESH_FLAG 0x2 /* BIT 1 */ +#define ATUC_PERF_ESS_THRESH_FLAG 0x4 /* BIT 2 */ +#define ATUC_RATE_CHANGE_FLAG 0x8 /* BIT 3 */ +#define ATUR_PERF_LOFS_THRESH_FLAG 0x10 /* BIT 4 */ +#define ATUR_PERF_LOSS_THRESH_FLAG 0x20 /* BIT 5 */ +#define ATUR_PERF_LPRS_THRESH_FLAG 0x40 /* BIT 6 */ +#define ATUR_PERF_ESS_THRESH_FLAG 0x80 /* BIT 7 */ +#define ATUR_RATE_CHANGE_FLAG 0x100 /* BIT 8 */ + +//RFC- 3440 FLAG DEFINITIONS + +#ifdef AMAZON_MEI_MIB_RFC3440 +/* adslLineExtTable flags */ +#define ATUC_LINE_TRANS_CAP_FLAG 0x1 /* BIT 0th position */ +#define ATUC_LINE_TRANS_CAP_FLAG_MAKECMV makeCMV(H2D_CMV_READ,INFO, 67, 0, 1, data) +#define ATUC_LINE_TRANS_CONFIG_FLAG 0x2 /* BIT 1 */ +#define ATUC_LINE_TRANS_CONFIG_FLAG_MAKECMV makeCMV(H2D_CMV_READ,INFO, 67, 0, 1, data) +#define ATUC_LINE_TRANS_CONFIG_FLAG_MAKECMV_WR makeCMV(H2D_CMV_WRITE,INFO, 67, 0, 1, data) +#define ATUC_LINE_TRANS_ACTUAL_FLAG 0x4 /* BIT 2 */ +#define ATUC_LINE_TRANS_ACTUAL_FLAG_MAKECMV makeCMV(H2D_CMV_READ,STAT, 1, 0, 1, data) +#define LINE_GLITE_POWER_STATE_FLAG 0x8 /* BIT 3 */ +#define LINE_GLITE_POWER_STATE_FLAG_MAKECMV makeCMV(H2D_CMV_READ,STAT, 0, 0, 1, data) + +/* adslAtucPerfDataExtTable flags */ +#define ATUC_PERF_STAT_FASTR_FLAG 0x1 /* BIT 0th position */ +#define ATUC_PERF_STAT_FASTR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, data) +#define ATUC_PERF_STAT_FAILED_FASTR_FLAG 0x2 /* BIT 1 */ +#define ATUC_PERF_STAT_FAILED_FASTR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, data) +#define ATUC_PERF_STAT_SESL_FLAG 0X4 /* BIT 2 */ +#define ATUC_PERF_STAT_SESL_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 8, 0, 1, data) +#define ATUC_PERF_STAT_UASL_FLAG 0X8 /* BIT 3 */ +#define ATUC_PERF_STAT_UASL_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 10, 0, 1, data) +#define ATUC_PERF_CURR_15MIN_FASTR_FLAG 0X10 /* BIT 4 */ +#define ATUC_PERF_CURR_15MIN_FAILED_FASTR_FLAG 0X20 /* BIT 5 */ +#define ATUC_PERF_CURR_15MIN_SESL_FLAG 0X40 /* BIT 6 */ +#define ATUC_PERF_CURR_15MIN_UASL_FLAG 0X80 /* BIT 7 */ +#define ATUC_PERF_CURR_1DAY_FASTR_FLAG 0X100 /* BIT 8 */ +#define ATUC_PERF_CURR_1DAY_FAILED_FASTR_FLAG 0X200 /* BIT 9 */ +#define ATUC_PERF_CURR_1DAY_SESL_FLAG 0X400 /* BIT 10 */ +#define ATUC_PERF_CURR_1DAY_UASL_FLAG 0X800 /* BIT 11 */ +#define ATUC_PERF_PREV_1DAY_FASTR_FLAG 0X1000 /* BIT 12 */ +#define ATUC_PERF_PREV_1DAY_FAILED_FASTR_FLAG 0X2000 /* BIT 13 */ +#define ATUC_PERF_PREV_1DAY_SESL_FLAG 0X4000 /* BIT 14 */ +#define ATUC_PERF_PREV_1DAY_UASL_FLAG 0X8000 /* BIT 15 */ + +/* adslAturPerfDataExtTable */ +#define ATUR_PERF_STAT_SESL_FLAG 0X1 /* BIT 0th position */ +#define ATUR_PERF_STAT_SESL_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 34, 0, 1, data) +#define ATUR_PERF_STAT_UASL_FLAG 0X2 /* BIT 1 */ +#define ATUR_PERF_STAT_UASL_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 36, 0, 1, data) +#define ATUR_PERF_CURR_15MIN_SESL_FLAG 0X4 /* BIT 2 */ +#define ATUR_PERF_CURR_15MIN_UASL_FLAG 0X8 /* BIT 3 */ +#define ATUR_PERF_CURR_1DAY_SESL_FLAG 0X10 /* BIT 4 */ +#define ATUR_PERF_CURR_1DAY_UASL_FLAG 0X20 /* BIT 5 */ +#define ATUR_PERF_PREV_1DAY_SESL_FLAG 0X40 /* BIT 6 */ +#define ATUR_PERF_PREV_1DAY_UASL_FLAG 0X80 /* BIT 7 */ + +/* adslAutcIntervalExtTable flags */ +#define ATUC_INTERVAL_FASTR_FLAG 0x1 /* Bit 0 */ +#define ATUC_INTERVAL_FAILED_FASTR_FLAG 0x2 /* Bit 1 */ +#define ATUC_INTERVAL_SESL_FLAG 0x4 /* Bit 2 */ +#define ATUC_INTERVAL_UASL_FLAG 0x8 /* Bit 3 */ + +/* adslAturIntervalExtTable */ +#define ATUR_INTERVAL_SESL_FLAG 0X1 /* BIT 0th position */ +#define ATUR_INTERVAL_UASL_FLAG 0X2 /* BIT 1 */ + +/* adslAlarmConfProfileExtTable */ +#define ATUC_THRESH_15MIN_FAILED_FASTR_FLAG 0X1/* BIT 0th position */ +#define ATUC_THRESH_15MIN_SESL_FLAG 0X2 /* BIT 1 */ +#define ATUC_THRESH_15MIN_UASL_FLAG 0X4 /* BIT 2 */ +#define ATUR_THRESH_15MIN_SESL_FLAG 0X8 /* BIT 3 */ +#define ATUR_THRESH_15MIN_UASL_FLAG 0X10 /* BIT 4 */ + +/* adslAturExtTraps */ +#define ATUC_15MIN_FAILED_FASTR_TRAP_FLAG 0X1 /* BIT 0th position */ +#define ATUC_15MIN_SESL_TRAP_FLAG 0X2 /* BIT 1 */ +#define ATUC_15MIN_UASL_TRAP_FLAG 0X4 /* BIT 2 */ +#define ATUR_15MIN_SESL_TRAP_FLAG 0X8 /* BIT 3 */ +#define ATUR_15MIN_UASL_TRAP_FLAG 0X10 /* BIT 4 */ + +// 603221:tc.chen start +/* adslLineStatus Flags */ +#define LINE_STAT_MODEM_STATUS_FLAG 0x1 /* BIT 0th position */ +#define LINE_STAT_MODEM_STATUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, data) +#define LINE_STAT_MODE_SEL_FLAG 0x2 /* BIT 1 */ +#define LINE_STAT_MODE_SEL_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 1, 0, 1, data) +#define LINE_STAT_TRELLCOD_ENABLE_FLAG 0x4 /* BIT 2 */ +#define LINE_STAT_TRELLCOD_ENABLE_FLAG_MAKECMV makeCMV(H2D_CMV_READ, OPTN, 2, 0, 1, data) +#define LINE_STAT_LATENCY_FLAG 0x8 /* BIT 3 */ +#define LINE_STAT_LATENCY_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 12, 0, 1, data) + +/* adslLineRate Flags */ +#define LINE_RATE_DATA_RATEDS_FLAG 0x1 /* BIT 0th position */ +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL1_LP0_MAKECMV makeCMV(H2D_CMV_READ, RATE, 1, 0, 2, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL1_LP1_MAKECMV makeCMV(H2D_CMV_READ, RATE, 1, 2, 2, data) + + +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_RP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 12, 0, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_MP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 13, 0, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_LP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 14, 0, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_TP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 15, 0, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_KP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 17, 0, 2, data) + +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_RP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 12, 1, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_MP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 13, 1, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_LP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 14, 1, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_TP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 15, 1, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_KP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 17, 2, 2, data) + +#define LINE_RATE_DATA_RATEUS_FLAG 0x2 /* BIT 1 */ +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL1_LP0_MAKECMV makeCMV(H2D_CMV_READ, RATE, 0, 0, 2, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL1_LP1_MAKECMV makeCMV(H2D_CMV_READ, RATE, 0, 2, 2, data) + + +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_RP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 23, 0, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_MP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 24, 0, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_LP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 25, 0, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_TP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 26, 0, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_KP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 28, 0, 2, data) + +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_RP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 23, 1, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_MP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 24, 1, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_LP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 25, 1, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_TP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 26, 1, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_KP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 28, 2, 2, data) + +#define LINE_RATE_ATTNDRDS_FLAG 0x4 /* BIT 2 */ +#define LINE_RATE_ATTNDRDS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 4, 2, data) + +#define LINE_RATE_ATTNDRUS_FLAG 0x8 /* BIT 3 */ +#define LINE_RATE_ATTNDRUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 4, 2, data) + +/* adslLineInformation Flags */ +#define LINE_INFO_INTLV_DEPTHDS_FLAG 0x1 /* BIT 0th position */ +#define LINE_INFO_INTLV_DEPTHDS_FLAG_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 27, 0, 1, data) +#define LINE_INFO_INTLV_DEPTHDS_FLAG_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 27, 1, 1, data) +#define LINE_INFO_INTLV_DEPTHUS_FLAG 0x2 /* BIT 1 */ +#define LINE_INFO_INTLV_DEPTHUS_FLAG_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 16, 0, 1, data) +#define LINE_INFO_INTLV_DEPTHUS_FLAG_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 16, 1, 1, data) +#define LINE_INFO_LATNDS_FLAG 0x4 /* BIT 2 */ +#define LINE_INFO_LATNDS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 1, 1, data) +#define LINE_INFO_LATNUS_FLAG 0x8 /* BIT 3 */ +#define LINE_INFO_LATNUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 1, 1, data) +#define LINE_INFO_SATNDS_FLAG 0x10 /* BIT 4 */ +#define LINE_INFO_SATNDS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 2, 1, data) +#define LINE_INFO_SATNUS_FLAG 0x20 /* BIT 5 */ +#define LINE_INFO_SATNUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 2, 1, data) +#define LINE_INFO_SNRMNDS_FLAG 0x40 /* BIT 6 */ +#define LINE_INFO_SNRMNDS_FLAG_ADSL1_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 3, 1, data) +#define LINE_INFO_SNRMNDS_FLAG_ADSL2_MAKECMV makeCMV(H2D_CMV_READ, RATE, 3, 0, 1, data) +#define LINE_INFO_SNRMNDS_FLAG_ADSL2PLUS_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 46, 0, 1, data) +#define LINE_INFO_SNRMNUS_FLAG 0x80 /* BIT 7 */ +#define LINE_INFO_SNRMNUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 3, 1, data) +#define LINE_INFO_ACATPDS_FLAG 0x100 /* BIT 8 */ +#define LINE_INFO_ACATPDS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 6, 1, data) +#define LINE_INFO_ACATPUS_FLAG 0x200 /* BIT 9 */ +#define LINE_INFO_ACATPUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 6, 1, data) + +/* adslNearEndPerformanceStats Flags */ +#define NEAREND_PERF_SUPERFRAME_FLAG_LSW_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 20, 0, 1, data) +#define NEAREND_PERF_SUPERFRAME_FLAG_MSW_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 21, 0, 1, data) +#define NEAREND_PERF_SUPERFRAME_FLAG 0x1 /* BIT 0th position */ +#define NEAREND_PERF_LOS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 0, 0, 1, data) +#define NEAREND_PERF_LOS_FLAG 0x2 /* BIT 1 */ +#define NEAREND_PERF_LOF_FLAG 0x4 /* BIT 2 */ +#define NEAREND_PERF_LPR_FLAG 0x8 /* BIT 3 */ +#define NEAREND_PERF_NCD_FLAG 0x10 /* BIT 4 */ +#define NEAREND_PERF_LCD_FLAG 0x20 /* BIT 5 */ +#define NEAREND_PERF_CRC_FLAG 0x40 /* BIT 6 */ +#define NEAREND_PERF_CRC_FLAG_LP0_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 2, 0, 1, data) +#define NEAREND_PERF_CRC_FLAG_LP1_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 2, 1, 1, data) +#define NEAREND_PERF_RSCORR_FLAG_LP0_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 3, 0, 1, data) +#define NEAREND_PERF_RSCORR_FLAG_LP1_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 3, 1, 1, data) +#define NEAREND_PERF_RSCORR_FLAG 0x80 /* BIT 7 */ +#define NEAREND_PERF_FECS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 6, 0, 1, data) +#define NEAREND_PERF_FECS_FLAG 0x100 /* BIT 8 */ +#define NEAREND_PERF_ES_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 7, 0, 1, data) +#define NEAREND_PERF_ES_FLAG 0x200 /* BIT 9 */ +#define NEAREND_PERF_SES_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 8, 0, 1, data) +#define NEAREND_PERF_SES_FLAG 0x400 /* BIT 10 */ +#define NEAREND_PERF_LOSS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 9, 0, 1, data) +#define NEAREND_PERF_LOSS_FLAG 0x800 /* BIT 11 */ +#define NEAREND_PERF_UAS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 10, 0, 1, data) +#define NEAREND_PERF_UAS_FLAG 0x1000 /* BIT 12 */ +#define NEAREND_PERF_HECERR_FLAG_BC0_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 11, 0, 2, data) +#define NEAREND_PERF_HECERR_FLAG_BC1_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 11, 2, 2, data) +#define NEAREND_PERF_HECERR_FLAG 0x2000 /* BIT 13 */ + +/* adslFarEndPerformanceStats Flags */ +#define FAREND_PERF_LOS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 1, 0, 1, data) +#define FAREND_PERF_LOS_FLAG 0x1 /* BIT 0th position */ +#define FAREND_PERF_LOF_FLAG 0x2 /* BIT 1 */ +#define FAREND_PERF_LPR_FLAG 0x4 /* BIT 2 */ +#define FAREND_PERF_NCD_FLAG 0x8 /* BIT 3 */ +#define FAREND_PERF_LCD_FLAG 0x10 /* BIT 4 */ +#define FAREND_PERF_CRC_FLAG_LP0_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 24, 0, 1, data) +#define FAREND_PERF_CRC_FLAG_LP1_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 24, 1, 1, data) +#define FAREND_PERF_CRC_FLAG 0x20 /* BIT 5 */ +#define FAREND_PERF_RSCORR_FLAG_LP0_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 28, 0, 1, data) +#define FAREND_PERF_RSCORR_FLAG_LP1_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 28, 1, 1, data) +#define FAREND_PERF_RSCORR_FLAG 0x40 /* BIT 6 */ +#define FAREND_PERF_FECS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 32, 0, 1, data) +#define FAREND_PERF_FECS_FLAG 0x80 /* BIT 7 */ +#define FAREND_PERF_ES_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 33, 0, 1, data) +#define FAREND_PERF_ES_FLAG 0x100 /* BIT 8 */ +#define FAREND_PERF_SES_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 34, 0, 1, data) +#define FAREND_PERF_SES_FLAG 0x200 /* BIT 9 */ +#define FAREND_PERF_LOSS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 35, 0, 1, data) +#define FAREND_PERF_LOSS_FLAG 0x400 /* BIT 10 */ +#define FAREND_PERF_UAS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 36, 0, 1, data) +#define FAREND_PERF_UAS_FLAG 0x800 /* BIT 11 */ +#define FAREND_PERF_HECERR_FLAG_BC0_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 37, 0, 2, data) +#define FAREND_PERF_HECERR_FLAG_BC1_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 37, 2, 2, data) +#define FAREND_PERF_HECERR_FLAG 0x1000 /* BIT 12 */ +// 603221:tc.chen end +/* TR-69 related additional parameters - defines */ +/* Defines for struct adslATURSubcarrierInfo */ +#define NEAREND_HLINSC 0x1 +#define NEAREND_HLINSC_MAKECMV(mode) makeCMV(mode, INFO, 71, 2, 1, data) +#define NEAREND_HLINPS 0x2 +#define NEAREND_HLINPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 73, idx, size, data) +#define NEAREND_HLOGMT 0x4 +#define NEAREND_HLOGMT_MAKECMV(mode) makeCMV(mode, INFO, 80, 0, 1, data) +#define NEAREND_HLOGPS 0x8 +#define NEAREND_HLOGPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 75, idx, size, data) +#define NEAREND_QLNMT 0x10 +#define NEAREND_QLNMT_MAKECMV(mode) makeCMV(mode, INFO, 80, 1, 1, data) +#define NEAREND_QLNPS 0x20 +#define NEAREND_QLNPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 77, idx, size, data) +#define NEAREND_SNRMT 0x40 +#define NEAREND_SNRMT_MAKECMV(mode) makeCMV(mode, INFO, 80, 2, 1, data) +#define NEAREND_SNRPS 0x80 +#define NEAREND_SNRPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 78, idx, size, data) +#define NEAREND_BITPS 0x100 +#define NEAREND_BITPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 22, idx, size, data) +#define NEAREND_GAINPS 0x200 +#define NEAREND_GAINPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 24, idx, size, data) + +/* Defines for struct adslATUCSubcarrierInfo */ +#define FAREND_HLINSC 0x1 +#define FAREND_HLINSC_MAKECMV(mode) makeCMV(mode, INFO, 70, 0, 1, data) +#define FAREND_HLINPS 0x2 +#define FAREND_HLINPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 72, idx, size, data) +#define FAREND_HLOGMT 0x4 +#define FAREND_HLOGMT_MAKECMV(mode) makeCMV(mode, INFO, 79, 0, 1, data) +#define FAREND_HLOGPS 0x8 +#define FAREND_HLOGPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 74, idx, size, data) +#define FAREND_QLNMT 0x10 +#define FAREND_QLNMT_MAKECMV(mode) makeCMV(mode, INFO, 79, 1, 1, data) +#define FAREND_QLNPS 0x20 +#define FAREND_QLNPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 76, idx, size, data) +#define FAREND_SNRMT 0x40 +#define FAREND_SNRMT_MAKECMV(mode) makeCMV(mode, INFO, 79, 2, 1, data) +#define FAREND_SNRPS 0x80 +#define FAREND_SNRPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 10, idx, size, data) +#define FAREND_BITPS 0x100 +#define FAREND_BITPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 23, idx, size, data) +#define FAREND_GAINPS 0x200 +#define FAREND_GAINPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 25, idx, size, data) + + +// GET_ADSL_POWER_SPECTRAL_DENSITY +#define NOMPSD_US_MAKECMV makeCMV(H2D_CMV_READ, INFO, 102, 0, 1, data) +#define NOMPSD_DS_MAKECMV makeCMV(H2D_CMV_READ, INFO, 102, 1, 1, data) +#define PCB_US_MAKECMV makeCMV(H2D_CMV_READ, INFO, 102, 6, 1, data) +#define PCB_DS_MAKECMV makeCMV(H2D_CMV_READ, INFO, 102, 7, 1, data) +#define RMSGI_US_MAKECMV makeCMV(H2D_CMV_READ, INFO, 102, 10, 1, data) +#define RMSGI_DS_MAKECMV makeCMV(H2D_CMV_READ, INFO, 102, 11, 1, data) + + +#endif +/////////////////////////////////////////////////Macro Definitions ? FLAG Setting & Testing + +#define SET_FLAG(flags, flag_val) ((*flags) = ((*flags) | flag_val)) +// -- This macro sets the flags with the flag_val. Here flags is passed as a pointer + +#define IS_FLAG_SET(flags, test_flag) (((*flags) & (test_flag)) == (test_flag)? test_flag:0) +// -- This macro verifies whether test_flag has been set in flags. Here flags is passed as a pointer + + +#define CLR_FLAG(flags, flag_bit) ((*flags) = (*flags) & (~flag_bit)) +// -- This macro resets the specified flag_bit in the flags. Here flags is passed as a pointer + + +////////////////////////////////////////////////DATA STRUCTURES ORGANIZATION + +//Here are the data structures used for accessing mib parameters. The ioctl call includes the third parameter as a void pointer. This parameter has to be type-casted in the driver code to the corresponding structure depending upon the command type. For Ex: consider the ioctl used to get the adslLineCode type, ioctl(fd,GET_ADSL_LINE_CODE,void *struct_adslLineTableEntry). In the driver code we check on the type of the command, i.e GET_ADSL_LINE_CODE and type-cast the void pointer to struct adslLineTableEntry type. + // +#define u32 unsigned int +#define u16 unsigned short +#define s16 short +#define u8 unsigned char + + +typedef u32 AdslPerfTimeElapsed; +typedef u32 AdslPerfPrevDayCount; +typedef u32 PerfCurrentCount; +typedef u32 PerfIntervalCount; +typedef u32 AdslPerfCurrDayCount; + + +//ioctl(int fd, GET_ADSL_LINE_CODE, void *struct_adslLineTableEntry) + +typedef struct adslLineTableEntry { + int ifIndex; + int adslLineCode; + u8 flags; +} adslLineTableEntry; + +#ifdef AMAZON_MEI_MIB_RFC3440 +typedef struct adslLineExtTableEntry { + int ifIndex; + u16 adslLineTransAtucCap; + u16 adslLineTransAtucConfig; + u16 adslLineTransAtucActual; + int adslLineGlitePowerState; + u32 flags; +}adslLineExtTableEntry; +#endif +//ioctl(int fd, GET_ADSL_ATUC_PHY, void *struct_adslAtucPhysEntry) + +typedef struct adslVendorId { + u16 country_code; + u_char provider_id[4]; /* Ascii characters */ + u_char revision_info[2]; +}adslVendorId; + + +typedef struct adslAtucPhysEntry { + int ifIndex; + char serial_no[32]; + union { + char vendor_id[16]; + adslVendorId vendor_info; + } vendor_id; + + char version_no[16]; + u32 status; + int outputPwr; + u32 attainableRate; + u8 flags; +} adslAtucPhysEntry; + + +//ioctl(int fd, GET_ADSL_ATUR_PHY, void *struct_adslAturPhysEntry) + +typedef struct adslAturPhysEntry { + int ifIndex; + char serial_no[32]; + union { + char vendor_id[16]; + adslVendorId vendor_info; + } vendor_id; + char version_no[16]; + int SnrMgn; + u32 Attn; + u32 status; + int outputPwr; + u32 attainableRate; + u8 flags; +} adslAturPhysEntry; + + +//ioctl(int fd, GET_ADSL_ATUC_CHAN_INFO, void *struct_adslAtucChanInfo) + +typedef struct adslAtucChanInfo { + int ifIndex; + u32 interleaveDelay; + u32 currTxRate; + u32 prevTxRate; + u8 flags; +} adslAtucChanInfo; + + +//ioctl(int fd, GET_ADSL_ATUR_CHAN_INFO, void *struct_adslAturChanInfo) + +typedef struct adslAturChanInfo { + int ifIndex; + u32 interleaveDelay; + u32 currTxRate; + u32 prevTxRate; + u32 crcBlkLen; + u8 flags; +} adslAturChanInfo; + + +//ioctl(int fd, GET_ADSL_ATUC_PERF_DATA, void *struct_atucPerfDataEntry) + +typedef struct atucPerfDataEntry +{ + int ifIndex; + u32 adslAtucPerfLofs; + u32 adslAtucPerfLoss; + u32 adslAtucPerfESs; + u32 adslAtucPerfInits; + int adslAtucPerfValidIntervals; + int adslAtucPerfInvalidIntervals; + AdslPerfTimeElapsed adslAtucPerfCurr15MinTimeElapsed; + PerfCurrentCount adslAtucPerfCurr15MinLofs; + PerfCurrentCount adslAtucPerfCurr15MinLoss; + PerfCurrentCount adslAtucPerfCurr15MinESs; + PerfCurrentCount adslAtucPerfCurr15MinInits; + AdslPerfTimeElapsed adslAtucPerfCurr1DayTimeElapsed; + AdslPerfCurrDayCount adslAtucPerfCurr1DayLofs; + AdslPerfCurrDayCount adslAtucPerfCurr1DayLoss; + AdslPerfCurrDayCount adslAtucPerfCurr1DayESs; + AdslPerfCurrDayCount adslAtucPerfCurr1DayInits; + int adslAtucPerfPrev1DayMoniSecs; + AdslPerfPrevDayCount adslAtucPerfPrev1DayLofs; + AdslPerfPrevDayCount adslAtucPerfPrev1DayLoss; + AdslPerfPrevDayCount adslAtucPerfPrev1DayESs; + AdslPerfPrevDayCount adslAtucPerfPrev1DayInits; + u32 flags; +} atucPerfDataEntry; + +#ifdef AMAZON_MEI_MIB_RFC3440 +typedef struct atucPerfDataExtEntry + { + int ifIndex; + u32 adslAtucPerfStatFastR; + u32 adslAtucPerfStatFailedFastR; + u32 adslAtucPerfStatSesL; + u32 adslAtucPerfStatUasL; + u32 adslAtucPerfCurr15MinFastR; + u32 adslAtucPerfCurr15MinFailedFastR; + u32 adslAtucPerfCurr15MinSesL; + u32 adslAtucPerfCurr15MinUasL; + u32 adslAtucPerfCurr1DayFastR; + u32 adslAtucPerfCurr1DayFailedFastR; + u32 adslAtucPerfCurr1DaySesL; + u32 adslAtucPerfCurr1DayUasL; + u32 adslAtucPerfPrev1DayFastR; + u32 adslAtucPerfPrev1DayFailedFastR; + u32 adslAtucPerfPrev1DaySesL; + u32 adslAtucPerfPrev1DayUasL; + u32 flags; +} atucPerfDataExtEntry; + +#endif +//ioctl(int fd, GET_ADSL_ATUR_PERF_DATA, void *struct_aturPerfDataEntry) + +typedef struct aturPerfDataEntry +{ + int ifIndex; + u32 adslAturPerfLofs; + u32 adslAturPerfLoss; + u32 adslAturPerfLprs; + u32 adslAturPerfESs; + int adslAturPerfValidIntervals; + int adslAturPerfInvalidIntervals; + AdslPerfTimeElapsed adslAturPerfCurr15MinTimeElapsed; + PerfCurrentCount adslAturPerfCurr15MinLofs; + PerfCurrentCount adslAturPerfCurr15MinLoss; + PerfCurrentCount adslAturPerfCurr15MinLprs; + PerfCurrentCount adslAturPerfCurr15MinESs; + AdslPerfTimeElapsed adslAturPerfCurr1DayTimeElapsed; + AdslPerfCurrDayCount adslAturPerfCurr1DayLofs; + AdslPerfCurrDayCount adslAturPerfCurr1DayLoss; + AdslPerfCurrDayCount adslAturPerfCurr1DayLprs; + AdslPerfCurrDayCount adslAturPerfCurr1DayESs; + int adslAturPerfPrev1DayMoniSecs; + AdslPerfPrevDayCount adslAturPerfPrev1DayLofs; + AdslPerfPrevDayCount adslAturPerfPrev1DayLoss; + AdslPerfPrevDayCount adslAturPerfPrev1DayLprs; + AdslPerfPrevDayCount adslAturPerfPrev1DayESs; + u32 flags; +} aturPerfDataEntry; + +#ifdef AMAZON_MEI_MIB_RFC3440 +typedef struct aturPerfDataExtEntry + { + int ifIndex; + u32 adslAturPerfStatSesL; + u32 adslAturPerfStatUasL; + u32 adslAturPerfCurr15MinSesL; + u32 adslAturPerfCurr15MinUasL; + u32 adslAturPerfCurr1DaySesL; + u32 adslAturPerfCurr1DayUasL; + u32 adslAturPerfPrev1DaySesL; + u32 adslAturPerfPrev1DayUasL; + u32 flags; +} aturPerfDataExtEntry; +#endif +//ioctl(int fd, GET_ADSL_ATUC_INTVL_INFO, void *struct_adslAtucInvtInfo) + +typedef struct adslAtucIntvlInfo { + int ifIndex; + int IntervalNumber; + PerfIntervalCount intervalLOF; + PerfIntervalCount intervalLOS; + PerfIntervalCount intervalES; + PerfIntervalCount intervalInits; + int intervalValidData; + u8 flags; +} adslAtucIntvlInfo; + +#ifdef AMAZON_MEI_MIB_RFC3440 +typedef struct adslAtucInvtlExtInfo + { + int ifIndex; + int IntervalNumber; + u32 adslAtucIntervalFastR; + u32 adslAtucIntervalFailedFastR; + u32 adslAtucIntervalSesL; + u32 adslAtucIntervalUasL; + u32 flags; +} adslAtucInvtlExtInfo; +#endif +//ioctl(int fd, GET_ADSL_ATUR_INTVL_INFO, void *struct_adslAturInvtlInfo) + +typedef struct adslAturIntvlInfo { + int ifIndex; + int IntervalNumber; + PerfIntervalCount intervalLOF; + PerfIntervalCount intervalLOS; + PerfIntervalCount intervalLPR; + PerfIntervalCount intervalES; + int intervalValidData; + u8 flags; +} adslAturIntvlInfo; + +#ifdef AMAZON_MEI_MIB_RFC3440 +typedef struct adslAturInvtlExtInfo + { + int ifIndex; + int IntervalNumber; + u32 adslAturIntervalSesL; + u32 adslAturIntervalUasL; + u32 flags; +} adslAturInvtlExtInfo; +#endif +//ioctl(int fd, GET_ADSL_ATUC_CHAN_PERF_DATA, void *struct_atucChannelPerfDataEntry) + +typedef struct atucChannelPerfDataEntry +{ + int ifIndex; + u32 adslAtucChanReceivedBlks; + u32 adslAtucChanTransmittedBlks; + u32 adslAtucChanCorrectedBlks; + u32 adslAtucChanUncorrectBlks; + int adslAtucChanPerfValidIntervals; + int adslAtucChanPerfInvalidIntervals; + AdslPerfTimeElapsed adslAtucChanPerfCurr15MinTimeElapsed; + PerfCurrentCount adslAtucChanPerfCurr15MinReceivedBlks; + PerfCurrentCount adslAtucChanPerfCurr15MinTransmittedBlks; + PerfCurrentCount adslAtucChanPerfCurr15MinCorrectedBlks; + PerfCurrentCount adslAtucChanPerfCurr15MinUncorrectBlks; + AdslPerfTimeElapsed adslAtucChanPerfCurr1DayTimeElapsed; + AdslPerfCurrDayCount adslAtucChanPerfCurr1DayReceivedBlks; + AdslPerfCurrDayCount adslAtucChanPerfCurr1DayTransmittedBlks; + AdslPerfCurrDayCount adslAtucChanPerfCurr1DayCorrectedBlks; + AdslPerfCurrDayCount adslAtucChanPerfCurr1DayUncorrectBlks; + int adslAtucChanPerfPrev1DayMoniSecs; + AdslPerfPrevDayCount adslAtucChanPerfPrev1DayReceivedBlks; + AdslPerfPrevDayCount adslAtucChanPerfPrev1DayTransmittedBlks; + AdslPerfPrevDayCount adslAtucChanPerfPrev1DayCorrectedBlks; + AdslPerfPrevDayCount adslAtucChanPerfPrev1DayUncorrectBlks; + u32 flags; +}atucChannelPerfDataEntry; + + +//ioctl(int fd, GET_ADSL_ATUR_CHAN_PERF_DATA, void *struct_aturChannelPerfDataEntry) + +typedef struct aturChannelPerfDataEntry +{ + int ifIndex; + u32 adslAturChanReceivedBlks; + u32 adslAturChanTransmittedBlks; + u32 adslAturChanCorrectedBlks; + u32 adslAturChanUncorrectBlks; + int adslAturChanPerfValidIntervals; + int adslAturChanPerfInvalidIntervals; + AdslPerfTimeElapsed adslAturChanPerfCurr15MinTimeElapsed; + PerfCurrentCount adslAturChanPerfCurr15MinReceivedBlks; + PerfCurrentCount adslAturChanPerfCurr15MinTransmittedBlks; + PerfCurrentCount adslAturChanPerfCurr15MinCorrectedBlks; + PerfCurrentCount adslAturChanPerfCurr15MinUncorrectBlks; + AdslPerfTimeElapsed adslAturChanPerfCurr1DayTimeElapsed; + AdslPerfCurrDayCount adslAturChanPerfCurr1DayReceivedBlks; + AdslPerfCurrDayCount adslAturChanPerfCurr1DayTransmittedBlks; + AdslPerfCurrDayCount adslAturChanPerfCurr1DayCorrectedBlks; + AdslPerfCurrDayCount adslAturChanPerfCurr1DayUncorrectBlks; + int adslAturChanPerfPrev1DayMoniSecs; + AdslPerfPrevDayCount adslAturChanPerfPrev1DayReceivedBlks; + AdslPerfPrevDayCount adslAturChanPerfPrev1DayTransmittedBlks; + AdslPerfPrevDayCount adslAturChanPerfPrev1DayCorrectedBlks; + AdslPerfPrevDayCount adslAturChanPerfPrev1DayUncorrectBlks; + u32 flags; +} aturChannelPerfDataEntry; + + +//ioctl(int fd, GET_ADSL_ATUC_CHAN_INTVL_INFO, void *struct_adslAtucChanIntvlInfo) + +typedef struct adslAtucChanIntvlInfo { + int ifIndex; + int IntervalNumber; + PerfIntervalCount chanIntervalRecvdBlks; + PerfIntervalCount chanIntervalXmitBlks; + PerfIntervalCount chanIntervalCorrectedBlks; + PerfIntervalCount chanIntervalUncorrectBlks; + int intervalValidData; + u8 flags; +} adslAtucChanIntvlInfo; + + +//ioctl(int fd, GET_ADSL_ATUR_CHAN_INTVL_INFO, void *struct_adslAturChanIntvlInfo) + +typedef struct adslAturChanIntvlInfo { + int ifIndex; + int IntervalNumber; + PerfIntervalCount chanIntervalRecvdBlks; + PerfIntervalCount chanIntervalXmitBlks; + PerfIntervalCount chanIntervalCorrectedBlks; + PerfIntervalCount chanIntervalUncorrectBlks; + int intervalValidData; + u8 flags; +} adslAturChanIntvlInfo; + + +//ioctl(int fd, GET_ADSL_ALRM_CONF_PROF, void *struct_adslLineAlarmConfProfileEntry) +//ioctl(int fd, SET_ADSL_ALRM_CONF_PROF, void *struct_adslLineAlarmConfProfileEntry) + +typedef struct adslLineAlarmConfProfileEntry + { + unsigned char adslLineAlarmConfProfileName[32]; + int adslAtucThresh15MinLofs; + int adslAtucThresh15MinLoss; + int adslAtucThresh15MinESs; + u32 adslAtucThreshFastRateUp; + u32 adslAtucThreshInterleaveRateUp; + u32 adslAtucThreshFastRateDown; + u32 adslAtucThreshInterleaveRateDown; + int adslAtucInitFailureTrapEnable; + int adslAturThresh15MinLofs; + int adslAturThresh15MinLoss; + int adslAturThresh15MinLprs; + int adslAturThresh15MinESs; + u32 adslAturThreshFastRateUp; + u32 adslAturThreshInterleaveRateUp; + u32 adslAturThreshFastRateDown; + u32 adslAturThreshInterleaveRateDown; + int adslLineAlarmConfProfileRowStatus; + u32 flags; +} adslLineAlarmConfProfileEntry; + +#ifdef AMAZON_MEI_MIB_RFC3440 +typedef struct adslLineAlarmConfProfileExtEntry + { + u8 adslLineAlarmConfProfileExtName[32]; + u32 adslAtucThreshold15MinFailedFastR; + u32 adslAtucThreshold15MinSesL; + u32 adslAtucThreshold15MinUasL; + u32 adslAturThreshold15MinSesL; + u32 adslAturThreshold15MinUasL; + u32 flags; +} adslLineAlarmConfProfileExtEntry; +#endif +//TRAPS + +// 603221:tc.chen start +/* The following Data Sturctures are added to support the WEB related parameters for ADSL Statistics */ +typedef struct adslLineStatus + { + int adslModemStatus; + u32 adslModeSelected; + int adslAtucThresh15MinESs; + int adslTrellisCodeEnable; + int adslLatency; + u8 flags; + } adslLineStatusInfo; + +typedef struct adslLineRate + { + u32 adslDataRateds; + u32 adslDataRateus; + u32 adslATTNDRds; + u32 adslATTNDRus; + u8 flags; + } adslLineRateInfo; + +typedef struct adslLineInfo + { + u32 adslInterleaveDepthds; + u32 adslInterleaveDepthus; + u32 adslLATNds; + u32 adslLATNus; + u32 adslSATNds; + u32 adslSATNus; + int adslSNRMds; + int adslSNRMus; + int adslACATPds; + int adslACATPus; + u32 flags; + } adslLineInfo; + +typedef struct adslNearEndPerfStats + { + u32 adslSuperFrames; + u32 adslneLOS; + u32 adslneLOF; + u32 adslneLPR; + u32 adslneNCD; + u32 adslneLCD; + u32 adslneCRC; + u32 adslneRSCorr; + u32 adslneFECS; + u32 adslneES; + u32 adslneSES; + u32 adslneLOSS; + u32 adslneUAS; + u32 adslneHECErrors; + u32 flags; + } adslNearEndPerfStats; + +typedef struct adslFarEndPerfStats + { + u32 adslfeLOS; + u32 adslfeLOF; + u32 adslfeLPR; + u32 adslfeNCD; + u32 adslfeLCD; + u32 adslfeCRC; + u32 adslfeRSCorr; + u32 adslfeFECS; + u32 adslfeES; + u32 adslfeSES; + u32 adslfeLOSS; + u32 adslfeUAS; + u32 adslfeHECErrors; + u32 flags; + } adslFarEndPerfStats; +// 603221:tc.chen end + +/* The number of tones (and hence indexes) is dependent on the ADSL mode - G.992.1, G.992.2, G.992.3, * G.992.4 and G.992.5 */ +typedef struct adslATURSubcarrierInfo { + int ifindex; + u16 HLINSCds; + u16 HLINpsds[1024];/* Even index = real part; Odd Index + = imaginary part for each tone */ + u16 HLOGMTds; + u16 HLOGpsds[512]; + u16 QLNMTds; + u16 QLNpsds[512]; + u16 SNRMTds; + u16 SNRpsds[512]; + u16 BITpsds[512]; + u16 GAINpsds[512]; + u16 flags; +}adslATURSubcarrierInfo; + +typedef struct adslATUCSubcarrierInfo { + int ifindex; + u16 HLINSCus; + u16 HLINpsus[128];/* Even index = real part; Odd Index + = imaginary part for each tone */ + u16 HLOGMTus; + u16 HLOGpsus[64]; + u16 QLNMTus; + u16 QLNpsus[64]; + u16 SNRMTus; + u16 SNRpsus[64]; + u16 BITpsus[64]; + u16 GAINpsus[64]; + u16 flags; +}adslATUCSubcarrierInfo; + +#ifndef u_int16 +#define u_int16 u16 +#endif + +typedef struct adslInitStats { + u_int16 FullInitializationCount; + u_int16 FailedFullInitializationCount; + u_int16 LINIT_Errors; + u_int16 Init_Timeouts; +}adslInitStats; + +typedef struct adslPowerSpectralDensity { + int ACTPSDds; + int ACTPSDus; +}adslPowerSpectralDensity; + + +//ioctl(int fd, ADSL_ATUR_TRAPS, void *uint16_flags) +typedef union structpts { + adslLineTableEntry * adslLineTableEntry_pt; + adslAtucPhysEntry * adslAtucPhysEntry_pt; + adslAturPhysEntry * adslAturPhysEntry_pt; + adslAtucChanInfo * adslAtucChanInfo_pt; + adslAturChanInfo * adslAturChanInfo_pt; + atucPerfDataEntry * atucPerfDataEntry_pt; + aturPerfDataEntry * aturPerfDataEntry_pt; + adslAtucIntvlInfo * adslAtucIntvlInfo_pt; + adslAturIntvlInfo * adslAturIntvlInfo_pt; + atucChannelPerfDataEntry * atucChannelPerfDataEntry_pt; + aturChannelPerfDataEntry * aturChannelPerfDataEntry_pt; + adslAtucChanIntvlInfo * adslAtucChanIntvlInfo_pt; + adslAturChanIntvlInfo * adslAturChanIntvlInfo_pt; + adslLineAlarmConfProfileEntry * adslLineAlarmConfProfileEntry_pt; + // RFC 3440 + + #ifdef AMAZON_MEI_MIB_RFC3440 + adslLineExtTableEntry * adslLineExtTableEntry_pt; + atucPerfDataExtEntry * atucPerfDataExtEntry_pt; + adslAtucInvtlExtInfo * adslAtucInvtlExtInfo_pt; + aturPerfDataExtEntry * aturPerfDataExtEntry_pt; + adslAturInvtlExtInfo * adslAturInvtlExtInfo_pt; + adslLineAlarmConfProfileExtEntry * adslLineAlarmConfProfileExtEntry_pt; + #endif +// 603221:tc.chen start + adslLineStatusInfo * adslLineStatusInfo_pt; + adslLineRateInfo * adslLineRateInfo_pt; + adslLineInfo * adslLineInfo_pt; + adslNearEndPerfStats * adslNearEndPerfStats_pt; + adslFarEndPerfStats * adslFarEndPerfStats_pt; +// 603221:tc.chen end + adslATUCSubcarrierInfo * adslATUCSubcarrierInfo_pt; + adslATURSubcarrierInfo * adslATURSubcarrierInfo_pt; + adslPowerSpectralDensity * adslPowerSpectralDensity_pt; +}structpts; + +#endif /* ] __AMAZON_MEI_APP_IOCTL_H */ diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_ioctl.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_ioctl.h new file mode 100644 index 000000000..02a150eac --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_ioctl.h @@ -0,0 +1,757 @@ +//509221:tc.chen 2005/09/22 Reset DFE added when MEI_TO_ARC_CS_DONE not cleared by ARC and Added AMAZON_MEI_DEBUG_MODE ioctl +#ifndef _AMAZON_MEI_IOCTL_H +#define _AMAZON_MEI_IOCTL_H + +///////////////////////////////////////////////////////////////////////////////////////////////////// +#define PCM_BUFF_SIZE 1024 //bytes +// interrupt numbers + +#ifndef _AMAZON_ADSL_APP + +typedef struct pcm_data_struct{ + u16 S; + u16 temp; + u16 LSW; + u16 MSW; + u16 len; + u16 rdindex; + u16 wrindex; + u16 flow; + + int finish; + u8 buff[PCM_BUFF_SIZE]; + int point; +}pcm_data_struct; + +typedef struct amazon_clreoc_pkt{ + struct list_head list; + u8 * command; //point to clreoc command data + int len; //command length +}amazon_clreoc_pkt; + +// Number of intervals +#define INTERVAL_NUM 192 //two days +typedef struct amazon_mei_mib{ + struct list_head list; + struct timeval start_time; //start of current interval + + int AtucPerfLof; + int AtucPerfLos; + int AtucPerfEs; + int AtucPerfInit; + + int AturPerfLof; + int AturPerfLos; + int AturPerfLpr; + int AturPerfEs; + + int AturChanPerfRxBlk; + int AturChanPerfTxBlk; + int AturChanPerfCorrBlk; + int AturChanPerfUncorrBlk; + + //RFC-3440 + int AtucPerfStatFastR; + int AtucPerfStatFailedFastR; + int AtucPerfStatSesL; + int AtucPerfStatUasL; + int AturPerfStatSesL; + int AturPerfStatUasL; +}amazon_mei_mib; + +typedef struct adslChanPrevTxRate{ + u32 adslAtucChanPrevTxRate; + u32 adslAturChanPrevTxRate; +}adslChanPrevTxRate; + +typedef struct adslPhysCurrStatus{ + u32 adslAtucCurrStatus; + u32 adslAturCurrStatus; +}adslPhysCurrStatus; + +typedef struct ChanType{ + int interleave; + int fast; +// 603221:tc.chen start + int bearchannel0; + int bearchannel1; +// 603221:tc.chen end +}ChanType; + +typedef struct mib_previous_read{ + u16 ATUC_PERF_ESS; + u16 ATUR_PERF_ESS; + u32 ATUR_CHAN_RECV_BLK; + u16 ATUR_CHAN_CORR_BLK_INTL; + u16 ATUR_CHAN_CORR_BLK_FAST; + u16 ATUR_CHAN_UNCORR_BLK_INTL; + u16 ATUR_CHAN_UNCORR_BLK_FAST; + u16 ATUC_PERF_STAT_FASTR; + u16 ATUC_PERF_STAT_FAILED_FASTR; + u16 ATUC_PERF_STAT_SESL; + u16 ATUC_PERF_STAT_UASL; + u16 ATUR_PERF_STAT_SESL; +}mib_previous_read; + +typedef struct mib_flags_pretime{ + struct timeval ATUC_PERF_LOSS_PTIME; + struct timeval ATUC_PERF_LOFS_PTIME; + struct timeval ATUR_PERF_LOSS_PTIME; + struct timeval ATUR_PERF_LOFS_PTIME; + struct timeval ATUR_PERF_LPR_PTIME; +}mib_flags_pretime; + + // cmv message structures +#define MP_PAYLOAD_SIZE 12 +typedef struct mpmessage{ + u16 iFunction; + u16 iGroup; + u16 iAddress; + u16 iIndex; + u16 iPayload[MP_PAYLOAD_SIZE]; +}MPMessage; +#endif + + +typedef struct meireg{ + u32 iAddress; + u32 iData; +}meireg; + +#define MEIDEBUG_BUFFER_SIZES 50 +typedef struct meidebug{ + u32 iAddress; + u32 iCount; + u32 buffer[MEIDEBUG_BUFFER_SIZES]; +}meidebug; + +//============================================================================== +// Group definitions +//============================================================================== +#define OPTN 5 +#define CNFG 8 +#define CNTL 1 +#define STAT 2 +#define RATE 6 +#define PLAM 7 +#define INFO 3 +#define TEST 4 +//============================================================================== +// Opcode definitions +//============================================================================== +#define H2D_CMV_READ 0x00 +#define H2D_CMV_WRITE 0x04 +#define H2D_CMV_INDICATE_REPLY 0x10 +#define H2D_ERROR_OPCODE_UNKNOWN 0x20 +#define H2D_ERROR_CMV_UNKNOWN 0x30 + +#define D2H_CMV_READ_REPLY 0x01 +#define D2H_CMV_WRITE_REPLY 0x05 +#define D2H_CMV_INDICATE 0x11 +#define D2H_ERROR_OPCODE_UNKNOWN 0x21 +#define D2H_ERROR_CMV_UNKNOWN 0x31 +#define D2H_ERROR_CMV_READ_NOT_AVAILABLE 0x41 +#define D2H_ERROR_CMV_WRITE_ONLY 0x51 +#define D2H_ERROR_CMV_READ_ONLY 0x61 + +#define H2D_DEBUG_READ_DM 0x02 +#define H2D_DEBUG_READ_PM 0x06 +#define H2D_DEBUG_WRITE_DM 0x0a +#define H2D_DEBUG_WRITE_PM 0x0e + +#define D2H_DEBUG_READ_DM_REPLY 0x03 +#define D2H_DEBUG_READ_FM_REPLY 0x07 +#define D2H_DEBUG_WRITE_DM_REPLY 0x0b +#define D2H_DEBUG_WRITE_FM_REPLY 0x0f +#define D2H_ERROR_ADDR_UNKNOWN 0x33 + +#define D2H_AUTONOMOUS_MODEM_READY_MSG 0xf1 +//============================================================================== +// INFO register address field definitions +//============================================================================== + +#define INFO_TxState 0 +#define INFO_RxState 1 +#define INFO_TxNextState 2 +#define INFO_RxNextState 3 +#define INFO_TxStateJumpFrom 4 +#define INFO_RxStateJumpFrom 5 + +#define INFO_ReverbSnrBuf 8 +#define INFO_ReverbEchoSnrBuf 9 +#define INFO_MedleySnrBuf 10 +#define INFO_RxShowtimeSnrBuf 11 +#define INFO_DECdelay 12 +#define INFO_DECExponent 13 +#define INFO_DECTaps 14 +#define INFO_AECdelay 15 +#define INFO_AECExponent 16 +#define INFO_AECTaps 17 +#define INFO_TDQExponent 18 +#define INFO_TDQTaps 19 +#define INFO_FDQExponent 20 +#define INFO_FDQTaps 21 +#define INFO_USBat 22 +#define INFO_DSBat 23 +#define INFO_USFineGains 24 +#define INFO_DSFineGains 25 +#define INFO_BitloadFirstChannel 26 +#define INFO_BitloadLastChannel 27 +#define INFO_PollEOCData 28 // CO specific +#define INFO_CSNRMargin 29 // CO specific +#define INFO_RCMsgs1 30 +#define INFO_RMsgs1 31 +#define INFO_RMsgRA 32 +#define INFO_RCMsgRA 33 +#define INFO_RMsg2 34 +#define INFO_RCMsg2 35 +#define INFO_BitLoadOK 36 +#define INFO_RCRates1 37 +#define INFO_RRates1Tab 38 +#define INFO_RMsgs1Tab 39 +#define INFO_RMsgRATab 40 +#define INFO_RRatesRA 41 +#define INFO_RCRatesRA 42 +#define INFO_RRates2 43 +#define INFO_RCRates2 44 +#define INFO_PackedRMsg2 45 +#define INFO_RxBitSwapFlag 46 +#define INFO_TxBitSwapFlag 47 +#define INFO_ShowtimeSNRUpdateCount 48 +#define INFO_ShowtimeFDQUpdateCount 49 +#define INFO_ShowtimeDECUpdateCount 50 +#define INFO_CopyRxBuffer 51 +#define INFO_RxToneBuf 52 +#define INFO_TxToneBuf 53 +#define INFO_Version 54 +#define INFO_TimeStamp 55 +#define INFO_feVendorID 56 +#define INFO_feSerialNum 57 +#define INFO_feVersionNum 58 +#define INFO_BulkMemory 59 //Points to start of bulk memory +#define INFO_neVendorID 60 +#define INFO_neVersionNum 61 +#define INFO_neSerialNum 62 + +//============================================================================== +// RATE register address field definitions +//============================================================================== + + +#define RATE_UsRate 0 +#define RATE_DsRate 1 + + +//============================================================================== +// PLAM (Physical Layer Management) register address field definitions +// (See G997.1 for reference) +//============================================================================== + + + // /// + // Failure Flags /// + // /// + +#define PLAM_NearEndFailureFlags 0 +#define PLAM_FarEndFailureFlags 1 + + // /// + // Near End Failure Flags Bit Definitions /// + // /// + +// ADSL Failures /// +#define PLAM_LOS_FailureBit 0x0001 +#define PLAM_LOF_FailureBit 0x0002 +#define PLAM_LPR_FailureBit 0x0004 +#define PLAM_RFI_FailureBit 0x0008 + +// ATM Failures /// +#define PLAM_NCD_LP0_FailureBit 0x0010 +#define PLAM_NCD_LP1_FailureBit 0x0020 +#define PLAM_LCD_LP0_FailureBit 0x0040 +#define PLAM_LCD_LP1_FailureBit 0x0080 + +#define PLAM_NCD_BC0_FailureBit 0x0100 +#define PLAM_NCD_BC1_FailureBit 0x0200 +#define PLAM_LCD_BC0_FailureBit 0x0400 +#define PLAM_LCD_BC1_FailureBit 0x0800 + // /// + // Performance Counts /// + // /// + +#define PLAM_NearEndCrcCnt 2 +#define PLAM_CorrectedRSErrors 3 + +#define PLAM_NearEndECSCnt 6 +#define PLAM_NearEndESCnt 7 +#define PLAM_NearEndSESCnt 8 +#define PLAM_NearEndLOSSCnt 9 +#define PLAM_NearEndUASLCnt 10 + +#define PLAM_NearEndHECErrCnt 11 + +#define PLAM_NearEndHECTotCnt 16 +#define PLAM_NearEndCellTotCnt 18 +#define PLAM_NearEndSfCntLSW 20 +#define PLAM_NearEndSfCntMSW 21 + +#define PLAM_FarEndFebeCnt 24 + +#define PLAM_FarEndFecCnt 28 + +#define PLAM_FarEndFECSCnt 32 +#define PLAM_FarEndESCnt 33 +#define PLAM_FarEndSESCnt 34 +#define PLAM_FarEndLOSSCnt 35 +#define PLAM_FarEndUASLCnt 36 + +#define PLAM_FarEndHECErrCnt 37 + +#define PLAM_FarEndHECTotCnt 41 + +#define PLAM_FarEndCellTotCnt 43 + +#define PLAM_LineAttn 45 +#define PLAM_SNRMargin 46 + + +//============================================================================== +// CNTL register address and bit field definitions +//============================================================================== + + +#define CNTL_ModemControl 0 + +#define CNTL_ModemReset 0x0 +#define CNTL_ModemStart 0x2 + + +//============================================================================== +// STAT register address and bit field definitions +//============================================================================== + +#define STAT_MacroState 0 +#define STAT_Mode 1 +#define STAT_DMTFramingMode 2 +#define STAT_SleepState 3 +#define STAT_Misc 4 +#define STAT_FailureState 5 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // STAT_OLRStatus provides status of OLR + //16-bit STAT_OLRStatus_DS + // [1:0] : OLR status 00=IDLE, 01=OLR_IN_PROGRESS, 10=OLR_Completed, 11=OLR_Aborted + // [3:2]: Reserved + // [5:4]: OLR_Type (1:bitswap; 2: DRR; 3: SRA) + // [7:6]: Reserved + // [10:8]: >0=Request. 0=not. For DS, # of request transmissions/retransmissions (3 bits). + // [11]: 1=Receive Response, 0=not + // [15:12]: Reserved + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// +#define STAT_OLRStatus_DS 6 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // STAT_OLRStatus provides status of OLR + // 16-bit STAT_OLRStatus_US CMV + // [1:0] : OLR status 00=IDLE, 01=OLR_IN_PROGRESS, 10=OLR_Completed, 11=OLR_Aborted + // [3:2]: Reserved + // [5:4]: OLR_Type (1:bitswap; 2: DRR; 3: SRA) + // [7:6]: Reserved + // [8]: 1=Request Received. 0=not. + // [10:9]: Reserved + // [11]: 1=Response Sent, 0=not + // [15:12]: Reserved + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/// +#define STAT_OLRStatus_US 7 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // STAT_PMStatus provides status of PM + // 16-bit STAT_PMStatus CMV + // [1:0] : PM Status 00=IDLE, 01=PM_IN_PROGRESS, 10=PM_Completed, 11=PM_Aborted + // [2] : 0=ATU_R initiated PM; 1 = ATU_C initiated PM + // [3]: Reserved + // [5:4]: PM_Type (1:Simple Request; 2: L2 request; 3: L2 trim) + // [7:6]: Reserved + // [10:8]: >0=Request. 0=not. # of request transmissions/retransmissions (3 bits). + // [11]: 1=Response, 0=not + // [15:12]: Reserved + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// +#define STAT_PMStatus 8 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // 16-bit STAT_OLRError_DS, STAT_OLRError_US, STAT_PMError + // [3:0]: OLR/PM response reason code + // [7:4]: OLR/PM Internal error code + // [15:8]: OLR/PM Reserved for future + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// +#define STAT_OLRError_DS 9 +#define STAT_OLRError_US 10 +#define STAT_PMError 11 + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// STAT_MacroState +// MacroState reflects the high level state of the modem + +#define STAT_InitState 0x0000 +#define STAT_ReadyState 0x0001 +#define STAT_FailState 0x0002 +#define STAT_IdleState 0x0003 +#define STAT_QuietState 0x0004 +#define STAT_GhsState 0x0005 +#define STAT_FullInitState 0x0006 +#define STAT_ShowTimeState 0x0007 +#define STAT_FastRetrainState 0x0008 +#define STAT_LoopDiagMode 0x0009 +#define STAT_ShortInit 0x000A // Bis short initialization /// + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// STAT_Mode +// ConfigurationMode indicates the mode of the current ADSL Link. In general, a modem may use +// G.Hs or some other mechanism to negotiate the specific mode of operation. +// The OPTN_modeControl CMV is used to select a set of desired modes. +// The STAT_Mode CMV indicates which mode was actually selected. + +#define STAT_ConfigMode_T1413 0x0001 +#define STAT_ConfigMode_G992_2_AB 0x0002 +#define STAT_ConfigMode_G992_1_A 0x0004 +#define STAT_ConfigMode_G992_1_B 0x0008 +#define STAT_ConfigMode_G992_1_C 0x0010 +#define STAT_ConfigMode_G992_2_C 0x0020 + +#define STAT_ConfigMode_G992_3_A 0x0100 +#define STAT_ConfigMode_G992_3_B 0x0200 +#define STAT_ConfigMode_G992_3_I 0x0400 +#define STAT_ConfigMode_G992_3_J 0x0800 +#define STAT_ConfigMode_G992_3_L 0x1000 + +#define STAT_ConfigMode_G992_4_A 0x2000 +#define STAT_ConfigMode_G992_4_I 0x4000 + +#define STAT_ConfigMode_G992_5 0x8000 + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// STAT_DMTFramingMode +// FramingMode indicates the DMT framing mde negotiated during initialization. The framing mode +// status is not applicable in BIS mode and its value is undefined +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define STAT_FramingModeMask 0x0003 + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// STAT_Misc +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define STAT_OverlappedSpectrum 0x0008 +#define STAT_TCM 0x0010 +#define STAT_TDQ_at_1104 0x0020 +#define STAT_T1413_Signal_Detected 0x0040 +#define STAT_AnnexL_US_Mask1_PSD 0x1000 //indicate we actually selected G992.3 AnnexL US PSD mask1 +#define STAT_AnnexL_US_Mask2_PSD 0x2000 //indicate we actually selected G992.3 AnnexL US PSD mask2 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// STAT_FailureState +// when the MacroSTate indicates the fail state, FailureState provides a failure code +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +#define E_CODE_NO_ERROR 0 +#define E_CODE_BAT_TX 1 // TX BAT table is incorrect */ +#define E_CODE_BAT_RX 2 // RX BAT table is incorrect */ +#define E_CODE_PROFILE 3 // profile is not selected in fast retrain */ +#define E_CODE_TX_AOC_FIFO_OVERFLOW 4 +#define E_CODE_TRUNCATE_FR 5 //Fast Retrain truncated due to no stored profiles*/ +#define E_CODE_BITLOAD 6 // bit loading fails */ +#define E_CODE_ST_ERROR 7 // showtime CRC error */ +#define E_CODE_RESERVED 8 // using parameters reserved by the ITU-T */ +#define E_CODE_C_TONES 9 // detected C_TONES */ +#define E_CODE_CODESWAP_ERR 10 // codeswap not finished in time */ +#define E_CODE_FIFO_OVERFLOW 11 // we have run out of fifo space */ +#define E_CODE_C_BG_DECODE_ERR 12 // error in decoding C-BG message */ +#define E_CODE_C_RATES2_DECODE_ERR 13 // error in decoding C-MSGS2 and C-RATES2 */ +#define E_CODE_RCMedleyRx_C_SEGUE2_Failure 14 // Timeout after RCMedleyRx waiting for C_SEGUE2 */ +#define E_CODE_RReverbRATx_C_SEGUE2_Failure 15 // Timeout after RReverbRATx waiting for C_SEGUE2 */ +#define E_CODE_RReverb3Tx_C_SEGUE1_Failure 16 // Timeout after RReverb3Tx waiting for C_SEGUE1 */ +#define E_CODE_RCCRC2Rx_C_RATES1_DECOD_ERR 17 // Received CRC not equal to computed CRC */ +#define E_CODE_RCCRC1Rx_C_RATES1_DECOD_ERR 18 // Received CRC not equal to computed CRC */ +#define E_CODE_RReverb5Tx_C_SEGUE2_Failure 19 // Timeout after RReverb5Tx waiting for C_SEGUE2 */ +#define E_CODE_RReverb6Tx_C_SEGUE3_Failure 20 // Timeout after RReverb6Tx waiting for C_SEGUE3 */ +#define E_CODE_RSegue5Tx_C_SEGUE3_Failure 21 // Timeout after RSegue5Tx waiting for C_SEGUE3 */ +#define E_CODE_RCReverb5Rx_C_SEGUE_Failure 22 // Timeout after RCReverb5Rx waiting for C_SEGUE */ +#define E_CODE_RCReverbRARx_C_SEGUE2_Failure 23 // Timeout after RCReverbRARx waiting for C_SEGUE2 */ +#define E_CODE_RCCRC4Rx_CMSGS2_DECOD_ERR 24 // Received CRC not equal to computed CRC */ +#define E_CODE_RCCRC5Rx_C_BG_DECOD_ERR 25 // Received CRC not equal to computed CRC */ +#define E_CODE_RCCRC3Rx_DECOD_ERR 26 // Received CRC not equal to computed CRC */ +#define E_CODE_RCPilot3_DEC_PATH_DEL_TIMEOUT 27 // DEC Path Delay timeout */ +#define E_CODE_RCPilot3_DEC_TRAINING_TIMEOUT 28 // DEC Training timeout */ +#define E_CODE_RCReverb3Rx_C_SEGUE1_Failure 29 // Timeout after RCReverb3Rx waiting for C_SEGUE1 */ +#define E_CODE_RCReverb2Rx_SignalEnd_Failure 30 // Timeout waiting for the end of RCReverb2Rx signal */ +#define E_CODE_RQuiet2_SignalEnd_Failure 31 // Timeout waiting for the end of RQuiet2 signal */ +#define E_CODE_RCReverbFR1Rx_Failure 32 // Timeout waiting for the end of RCReverbFR1Rx signal */ +#define E_CODE_RCPilotFR1Rx_SignalEnd_Failure 33 // Timeout waiting for the end of RCPilotFR1Rx signal */ +#define E_CODE_RCReverbFR2Rx_C_Segue_Failure 34 // Timeout after RCReverbFR2Rx waiting for C_SEGUE */ +#define E_CODE_RCReverbFR5Rx_SignalEnd_TIMEOUT 35 // Timeout waiting for the end of RCReverbFR5Rx signal */ +#define E_CODE_RCReverbFR6Rx_C_SEGUE_Failure 36 // Timeout after RCReverbFR6Rx waiting for C_SEGUE */ +#define E_CODE_RCReverbFR8Rx_C_SEGUE_FR4_Failure 37 // Timeout after RCReverbFR8Rx waiting for C_SEGUE_FR4 */ +#define E_CODE_RCReverbFR8Rx_No_PROFILE 38 // Timeout since no profile was selected */ +#define E_CODE_RCReverbFR8Rx_SignalEnd_TIMEOUT 39 // Timeout waiting for the end of RCReverbFR8Rx signal */ +#define E_CODE_RCCRCFR1_DECOD_ERR 40 // Received CRC not equal to computed CRC */ +#define E_CODE_RCRecovRx_SingnalEnd_TIMEOUT 41 // Timeout waiting for the end of RCRecovRx signal */ +#define E_CODE_RSegueFR5Tx_TX_Not_Ready_TIMEOUT 42 // Timeout after RSegueFR5Tx waiting for C_SEGUE2 */ +#define E_CODE_RRecovTx_SignalEnd_TIMEOUT 43 // Timeout waiting for the end of RRecovTx signal */ +#define E_CODE_RCMedleyFRRx_C_SEGUE2_Failure 44 // Timeout after RCMedleyFRRx waiting for C_SEGUE2 */ +#define E_CODE_CONFIGURATION_PARAMETERS_ERROR 45 // one of the configuration parameters do not meet the standard */ +#define E_CODE_BAD_MEM_ACCESS 46 +#define E_CODE_BAD_INSTRUCTION_ACCESS 47 +#define E_CODE_TX_EOC_FIFO_OVERFLOW 48 +#define E_CODE_RX_EOC_FIFO_OVERFLOW 49 +#define E_CODE_GHS_CD_FLAG_TIME_OUT 50 // Timeout when transmitting Flag in handshake cleardown */ + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//STAT_OLRStatus: +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define STAT_OLRPM_IDLE 0x0000 +#define STAT_OLRPM_IN_PROGRESS 0x0001 +#define STAT_OLRPM_COMPLETE 0x0002 +#define STAT_OLRPM_ABORTED 0x0003 +#define STAT_OLRPM_RESPONSE 0x0800 + +#define STAT_OLR_BITSWAP 0x0010 +#define STAT_OLR_DRR 0x0020 +#define STAT_OLR_SRA 0x0030 + +//STAT_PMStatus_US: +#define STAT_PM_CO_REQ 0x0004 +#define STAT_PM_SIMPLE_REQ 0x0010 +#define STAT_PM_L2_REQ 0x0020 +#define STAT_PM_L2_TRIM_REQ 0x0030 + +// STAT_OLRError_DS, STAT_OLRError_US +//4 bit response reason code: +#define RESP_BUSY 0x01 +#define RESP_INVALID_PARAMETERS 0x02 +#define RESP_NOT_ENABLED 0x03 +#define RESP_NOT_SUPPORTED 0x04 + +//4 bit internal error code (common for OLR and PM) +#define REQ_INVALID_BiGi 0x10 +#define REQ_INVALID_Lp 0x20 +#define REQ_INVALID_Bpn 0x30 +#define REQ_INVALID_FRAMING_CONSTRAINT 0x40 +#define REQ_NOT_IN_L0_STATE 0x50 +#define REQ_NOT_IN_L2_STATE 0x60 +#define REQ_INVALID_PCB 0x70 +#define REQ_VIOLATES_MARGIN 0x80 + +//STAT_PMError +//4 bit response reason code: +#define RESP_STATE_NOT_DESIRED 0x03 +#define RESP_INFEASIBLE_PARAMETERS 0x04 + + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// OPTN register address and bit field definitions +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define OPTN_ModeControl 0 +#define OPTN_DMTLnkCtl 1 +// Reserved 2 +#define OPTN_GhsControl 3 +// Reserved 4 +#define OPTN_PwrManControl 5 +#define OPTN_AnnexControl 6 +#define OPTN_ModeControl1 7 +// Reserved 8 +#define OPTN_StateMachineCtrl 9 +// Reserved 10 +// Reserved 11 +#define OPTN_BisLinkControl 12 +#define OPTN_ATMAddrConfig 13 +#define OPTN_ATMNumCellConfig 14 + +// Mode control defines the allowable operating modes of an ADSL link. In general, a modem may /// +// use G.Hs or some other mechanism to negotiate the specific mode of operation. /// +// The OPTN_ModeControl CMV is used to select a set of desired modes /// +// The STAT_ModeControl CMV indicates which mode was actually selected /// + +// OPTN_ModeControl +#define OPTN_ConfigMode_T1413 0x0001 +#define OPTN_ConfigMode_G992_2_AB 0x0002 +#define OPTN_ConfigMode_G992_1_A 0x0004 +#define OPTN_ConfigMode_G992_1_B 0x0008 +#define OPTN_ConfigMode_G992_1_C 0x0010 +#define OPTN_ConfigMode_G992_2_C 0x0020 + +#define OPTN_ConfigMode_G992_3_A 0x0100 +#define OPTN_ConfigMode_G992_3_B 0x0200 +#define OPTN_ConfigMode_G992_3_I 0x0400 +#define OPTN_ConfigMode_G992_3_J 0x0800 +#define OPTN_ConfigMode_G992_3_L 0x1000 + +#define OPTN_ConfigMode_G992_4_A 0x2000 +#define OPTN_ConfigMode_G992_4_I 0x4000 + +#define OPTN_ConfigMode_G992_5 0x8000 + +// OPTN_PwrManControl +#define OPTN_PwrManWakeUpGhs 0x1 +#define OPTN_PwrManWakeUpFR 0x2 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// OPTN_DMT Link Control +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define OPTN_DMT_DualLatency_Dis 0x200 +#define OPTN_DMT_S_Dis 0x100 +#define OPTN_DMT_FRAMINGMODE 0x1 +#define OPTN_DMT_FRAMINGMODE_MASK 0x7 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// OPTN_BIS Link Control +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define OPTN_BisLinkContrl_LineProbeDis 0x1 +#define OPTN_BisLinkContrl_DSBlackBitsEn 0x2 +#define OPTN_BisLinkContrl_DiagnosticModeEn 0x4 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// OPTN_GhsControl +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// for OPTN_GhsControl, we will assign 16bit word as follows +// bit 0~3: set the control over which start(initial) message CPE will send: +// +// BIT: 2 1 0 +// 0 0 1 CLR +// 0 1 0 MR +// 0 1 1 MS +// 1 0 0 MP +// +// // bit 4~6: set the control over which message will be sent when we get at lease one CL/CLR exchange +// BIT: 5 4 +// 0 1 MS +// 1 0 MR +// 1 1 MP +// +// // bit 15: RT initiated G.hs sample sessions one through eight. Session one is default. +// BIT: 15 +// 1 means session one +// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define OPTN_GHS_ST_GHS 0x8000 +#define OPTN_GHS_INIT_MASK 0x000F +#define OPTN_GHS_RESP_MASK 0x00F0 + +#define OPTN_RTInitTxMsg_CLR 0x0001 +#define OPTN_RTInitTxMsg_MR 0x0002 +#define OPTN_RTInitTxMsg_MS 0x0003 +#define OPTN_RTInitTxMsg_MP 0x0004 + +#define OPTN_RTRespTxMsg_MS 0x0010 +#define OPTN_RTRespTxMsg_MR 0x0020 +#define OPTN_RTRespTxMsg_MP 0x0030 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// OPTN_AnnexControl +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +// G.992.3 Annex A/L1/L2 US PSD Mask preferred + +#define OPTN_G992_3_AnnexA_PreferredModeMask 0x3000 +#define OPTN_G992_3_AnnexA_PreferredModeA 0x0000 // default AnnexA PSD mask /// +#define OPTN_G992_3_AnnexA_PreferredModeL1 0x1000 // AnnexL wide spectrum upstream PSD mask /// +#define OPTN_G992_3_AnnexA_PreferredModeL2 0x2000 // AnnexL narrow spectrum upstream PSD mask /// + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//OPTN_ATMAddrConfig +// Bits 4:0 are Utopia address for BC1 +// Bits 9:5 are Utopia address for BC0 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define OPTN_UTPADDR_BC1 0x001F +#define OPTN_UTPADDR_BC0 0x03E0 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//OPTN_ATMNumCellConfig +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define OPTN_BC1_NUM_CELL_PAGES 0x000F // Bits 0:3 /// +#define OPTN_BC0_NUM_CELL_PAGES 0x00F0 // Bits 4:7 /// + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CNFG register address field /// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////// +// these cmvs are used by bis handshake /// +/////////////////////////////////////////// + +// Each of the CNFG_TPS entries points to a structure of type (TPS_TC_BearerChannel_t) +#define CNFG_TPS_TC_DS0 0 +#define CNFG_TPS_TC_DS1 1 +#define CNFG_TPS_TC_US0 2 +#define CNFG_TPS_TC_US1 3 + +#define CNFG_HDLC_Overhead_Requirements 4 + +// Each of the CNFG_PMS entries points to a structure of type (PMS_TC_LatencyPath_t) +#define CNFG_PMS_TC_DS0 5 +#define CNFG_PMS_TC_DS1 6 +#define CNFG_PMS_TC_US0 7 +#define CNFG_PMS_TC_US1 8 + +// CNFG_PMD_PARAMETERS points to a structure of type (PMD_params_t) +#define CNFG_PMD_PARAMETERS 9 + +//////////////////////////////////////////////////////////// +// these cmvs are used by bis training and showtime code /// +//////////////////////////////////////////////////////////// + +//////////////// +// Tx Config /// +//////////////// +#define CNFG_tx_Cnfg_Nbc 10 +#define CNFG_tx_Cnfg_Nlp 11 +#define CNFG_tx_Cnfg_Rp 12 +#define CNFG_tx_Cnfg_Mp 13 +#define CNFG_tx_Cnfg_Lp 14 +#define CNFG_tx_Cnfg_Tp 15 +#define CNFG_tx_Cnfg_Dp 16 +#define CNFG_tx_Cnfg_Bpn 17 +#define CNFG_tx_Cnfg_FramingMode 18 +#define CNFG_tx_Cnfg_MSGLp 19 +#define CNFG_tx_Cnfg_MSGc 20 + + +//////////////// +// Rx Config /// +//////////////// +#define CNFG_rx_Cnfg_Nbc 21 +#define CNFG_rx_Cnfg_Nlp 22 +#define CNFG_rx_Cnfg_Rp 23 +#define CNFG_rx_Cnfg_Mp 24 +#define CNFG_rx_Cnfg_Lp 25 +#define CNFG_rx_Cnfg_Tp 26 +#define CNFG_rx_Cnfg_Dp 27 +#define CNFG_rx_Cnfg_Bpn 28 +#define CNFG_rx_Cnfg_FramingMode 29 +#define CNFG_rx_Cnfg_MSGLp 30 +#define CNFG_rx_Cnfg_MSGc 31 + +#define CNFG_tx_Cnfg_BCnToLPp 32 +#define CNFG_rx_Cnfg_BCnToLPp 33 + + + +#endif + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_sw.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_sw.h new file mode 100644 index 000000000..13273813a --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_sw.h @@ -0,0 +1,177 @@ +#ifndef AMAZON_SW_H +#define AMAZON_SW_H +#define SET_ETH_SPEED_AUTO SIOCDEVPRIVATE +#define SET_ETH_SPEED_10 SIOCDEVPRIVATE+1 +#define SET_ETH_SPEED_100 SIOCDEVPRIVATE+2 +#define SET_ETH_DUPLEX_AUTO SIOCDEVPRIVATE+3 +#define SET_ETH_DUPLEX_HALF SIOCDEVPRIVATE+4 +#define SET_ETH_DUPLEX_FULL SIOCDEVPRIVATE+5 +#define SET_ETH_REG SIOCDEVPRIVATE+6 +#define VLAN_TOOLS SIOCDEVPRIVATE+7 +#define MAC_TABLE_TOOLS SIOCDEVPRIVATE+8 + + +/*===mac table commands==*/ +#define RESET_MAC_TABLE 0 +#define READ_MAC_ENTRY 1 +#define WRITE_MAC_ENTRY 2 +#define ADD_MAC_ENTRY 3 + +/*====vlan commands===*/ + +#define CHANGE_VLAN_CTRL 0 +#define READ_VLAN_ENTRY 1 +#define UPDATE_VLAN_ENTRY 2 +#define CLEAR_VLAN_ENTRY 3 +#define RESET_VLAN_TABLE 4 +#define ADD_VLAN_ENTRY 5 + +/* +** MDIO constants. +*/ + +#define MDIO_BASE_STATUS_REG 0x1 +#define MDIO_BASE_CONTROL_REG 0x0 +#define MDIO_PHY_ID_HIGH_REG 0x2 +#define MDIO_PHY_ID_LOW_REG 0x3 +#define MDIO_BC_NEGOTIATE 0x0200 +#define MDIO_BC_FULL_DUPLEX_MASK 0x0100 +#define MDIO_BC_AUTO_NEG_MASK 0x1000 +#define MDIO_BC_SPEED_SELECT_MASK 0x2000 +#define MDIO_STATUS_100_FD 0x4000 +#define MDIO_STATUS_100_HD 0x2000 +#define MDIO_STATUS_10_FD 0x1000 +#define MDIO_STATUS_10_HD 0x0800 +#define MDIO_STATUS_SPEED_DUPLEX_MASK 0x7800 +#define MDIO_ADVERTISMENT_REG 0x4 +#define MDIO_ADVERT_100_FD 0x100 +#define MDIO_ADVERT_100_HD 0x080 +#define MDIO_ADVERT_10_FD 0x040 +#define MDIO_ADVERT_10_HD 0x020 +#define MDIO_LINK_UP_MASK 0x4 +#define MDIO_START 0x1 +#define MDIO_READ 0x2 +#define MDIO_WRITE 0x1 +#define MDIO_PREAMBLE 0xfffffffful + +#define PHY_RESET 0x8000 +#define AUTO_NEGOTIATION_ENABLE 0X1000 +#define AUTO_NEGOTIATION_COMPLETE 0x20 +#define RESTART_AUTO_NEGOTIATION 0X200 + + +#define PHY0_ADDR 0 +#define PHY1_ADDR 1 +#define P1M 0 + +#define AMAZON_SW_REG32(reg_num) *((volatile u32*)(reg_num)) + +#define OK 0; + +#ifdef CONFIG_CPU_LITTLE_ENDIAN +typedef struct mac_table_entry{ + u64 mac_address:48; + u64 p0:1; + u64 p1:1; + u64 p2:1; + u64 cr:1; + u64 ma_st:3; + u64 res:9; +}_mac_table_entry; + +typedef struct IFX_Switch_VLanTableEntry{ + u32 vlan_id:12; + u32 mp0:1; + u32 mp1:1; + u32 mp2:1; + u32 v:1; + u32 res:16; +}_IFX_Switch_VLanTableEntry; + +typedef struct mac_table_req{ + int cmd; + int index; + u32 data; + u64 entry_value; +}_mac_table_req; + +#else //not CONFIG_CPU_LITTLE_ENDIAN +typedef struct mac_table_entry{ + u64 mac_address:48; + u64 p0:1; + u64 p1:1; + u64 p2:1; + u64 cr:1; + u64 ma_st:3; + u64 res:9; +}_mac_table_entry; + +typedef struct IFX_Switch_VLanTableEntry{ + u32 vlan_id:12; + u32 mp0:1; + u32 mp1:1; + u32 mp2:1; + u32 v:1; + u32 res:16; +}_IFX_Switch_VLanTableEntry; + + +typedef struct mac_table_req{ + int cmd; + int index; + u32 data; + u64 entry_value; +}_mac_table_req; + +#endif //CONFIG_CPU_LITTLE_ENDIAN + + + +typedef struct vlan_req{ + int cmd; + int index; + u32 data; + u32 entry_value; +}_vlan_req; + +typedef struct data_req{ + int index; + u32 value; +}_data_req; + +enum duplex +{ + half, + full, + autoneg +}; + +struct switch_priv { + struct net_device_stats stats; + int rx_packetlen; + u8 *rx_packetdata; + int rx_status; + int tx_packetlen; +#ifdef CONFIG_NET_HW_FLOWCONTROL + int fc_bit; +#endif //CONFIG_NET_HW_FLOWCONTROL + u8 *tx_packetdata; + int tx_status; + struct dma_device_info *dma_device; + struct sk_buff *skb; + spinlock_t lock; + int mdio_phy_addr; + int current_speed; + int current_speed_selection; + int rx_queue_len; + int full_duplex; + enum duplex current_duplex; + int num; +}; + +#endif //AMAZON_SW_H + + + + + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_tpe.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_tpe.h new file mode 100644 index 000000000..a64e6f9f8 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_tpe.h @@ -0,0 +1,258 @@ +#ifndef AMAZON_TPE_H +#define AMAZON_TPE_H +#include +#include +#include +#include + +#ifdef CONFIG_IFX_ATM_MIB +/* For ATM-MIB lists */ +#include +#endif +#include + +/* CBM Queue arranagement + * Q0: free cells pool + * Q1~ Q15: upstream queues + * Q16: QAM downstream + * Q17~Q31: downstream queues + */ +#define AMAZON_ATM_MAX_QUEUE_NUM 32 +#define AMAZON_ATM_PORT_NUM 2 +#define AMAZON_ATM_FREE_CELLS 4000 +#define AMAZON_ATM_MAX_VCC_NUM (AMAZON_ATM_MAX_QUEUE_NUM/2 - 1) +#define AMAZON_AAL0_SDU (ATM_AAL0_SDU+4) //one more word for status +#define CBM_RX_OFFSET 16 //offset from the same q for tx +#define AMAZON_ATM_OAM_Q_ID 16 +#define AMAZON_ATM_RM_Q_ID 16 +#define AMAZON_ATM_OTHER_Q_ID 16 +#define CBM_DEFAULT_Q_OFFSET 1 +#define HTUTIMEOUT 0xffff//timeoutofhtutocbm +#define QSB_WFQ_NONUBR_MAX 0x3f00 +#define QSB_WFQ_UBR_BYPASS 0x3fff +#define QSB_TP_TS_MAX 65472 +#define QSB_TAUS_MAX 64512 +#define QSB_GCR_MIN 18 +#define HTU_RAM_ACCESS_MAX 1024//maxium time for HTU RAM access + +#define SWIE_LOCK 1 +#define PROC_ATM 1 +#define PROC_MIB 2 +#define PROC_VCC 3 +#define PROC_AAL5 4 +#define PROC_CBM 5 +#define PROC_HTU 6 +#define PROC_QSB 7 +#define PROC_SWIE 8 + +/***************** internal data structure ********************/ +typedef int (*push_back_t)(struct atm_vcc *vcc,struct sk_buff *skb,int err) ; +/* Device private data */ +typedef struct{ + u8 padding_byte; + u32 tx_max_sdu; + u32 rx_max_sdu; + u32 cnt_cpy; //no. of packets that need a copy due to alignment +}amazon_aal5_dev_t; + +typedef struct{ + u32 max_q_off; //maxium queues used in real scenario + u32 nrt_thr; + u32 clp0_thr; + u32 clp1_thr; + u32 free_cell_cnt; +#ifdef CONFIG_USE_VENUS + u8 * qd_addr_free; //to work around a bug, bit15 of QDOFF address should be 1 +#endif + u8 * qd_addr; + u8 * mem_addr; + u8 allocated; +}amazon_cbm_dev_t; + +typedef struct{ + +}amazon_htu_dev_t; + +typedef struct{ + u32 tau; //cell delay variation due to concurrency(?) + u32 tstepc; //time step, all legal values are 1,2,4 + u32 sbl; //scheduler burse length (for PHY) +}amazon_qsb_dev_t; + +typedef struct{ + u32 qid; //QID of the current extraction queue + struct semaphore in_sem; // Software-Insertion semaphore + volatile long lock; //lock that avoids race contions between SWIN and SWEX + wait_queue_head_t sleep; //wait queue for SWIE and SWEX + u32 sw; //status word +}amazon_swie_dev_t; + +//AAL5 MIB Counter +typedef struct{ + u32 tx,rx; //number AAL5 CPCS PDU from/to higher-layer + u32 tx_err,rx_err; //ifInErrors and ifOutErros + u32 tx_drop,rx_drop; //discarded received packets due to mm shortage + u32 htu_unp; //number of unknown received cells + u32 rx_cnt_h; //number of octets received, high 32 bits + u32 rx_cnt_l; //number of octets received, low 32 bits + u32 tx_cnt_h; //number of octets transmitted, high 32 bits + u32 tx_cnt_l; //number of octets transmitted, low 32 bits + u32 tx_ppd; //number of cells for AAL5 upstream PPD discards + u64 rx_cells; //number of cells for downstream + u64 tx_cells; //number of cells for upstream + u32 rx_err_cells; //number of cells dropped due to uncorrectable HEC errors +}amazon_mib_counter_t; + + + +typedef enum {QS_PKT,QS_LEN,QS_ERR,QS_HW_DROP,QS_SW_DROP,QS_MAX} qs_t; +//queue statics no. of packet received / sent +//queue statics no. of bytes received / sent +//queue statics no. of packets with error +//queue statics no. of packets dropped by hw +//queue statics no. of packets dropped by sw + +typedef struct{ + push_back_t push; //call back function + struct atm_vcc * vcc; //opened vcc + struct timeval access_time; //time when last F4/F5 user cells arrive + int free; //whether this queue is occupied, 0: occupied, 1: free + u32 aal5VccCrcErrors; //MIB counter + u32 aal5VccOverSizedSDUs; //MIB counter + +#if defined(AMAZON_ATM_DEBUG) || defined (CONFIG_IFX_ATM_MIB) + u32 qs[QS_MAX]; +#endif +}amazon_atm_queue_t; + + +typedef struct{ + int enable; //enable / disable + u32 max_conn; //maximum number of connections per port + u32 tx_max_cr; //Remaining cellrate for this device for tx direction + u32 tx_rem_cr; //Remaining cellrate for this device for tx direction + u32 tx_cur_cr; //Current cellrate for this device for tx direction +}amazon_atm_port_t; + +typedef struct{ + amazon_aal5_dev_t aal5; + amazon_cbm_dev_t cbm; + amazon_htu_dev_t htu; + amazon_qsb_dev_t qsb; + amazon_swie_dev_t swie; + amazon_mib_counter_t mib_counter; + amazon_atm_queue_t queues[AMAZON_ATM_MAX_QUEUE_NUM]; + amazon_atm_port_t ports[AMAZON_ATM_PORT_NUM]; + atomic_t dma_tx_free_0;//TX_CH0 has availabe descriptors +} amazon_atm_dev_t; + +struct oam_last_activity{ + u8 vpi; //vpi for this connection + u16 vci; //vci for t his connection + struct timeval stamp; //time when last F4/F5 user cells arrive + struct oam_last_activity * next;//for link list purpose +}; + +typedef union{ +#ifdef CONFIG_CPU_LITTLE_ENDIAN + struct{ + u32 tprs :16; + u32 twfq :14; + u32 vbr :1; + u32 reserved :1; + }bit; + u32 w0; +#else + struct{ + u32 reserved :1; + u32 vbr :1; + u32 twfq :14; + u32 tprs :16; + }bit; + u32 w0; +#endif + +}qsb_qptl_t; + +typedef union{ +#ifdef CONFIG_CPU_LITTLE_ENDIAN + struct{ + u32 ts :16; + u32 taus :16; + }bit; + u32 w0; +#else + struct{ + u32 taus :16; + u32 ts :16; + }bit; + u32 w0; +#endif +}qsb_qvpt_t; + + + +struct amazon_atm_cell_header { +#ifdef CONFIG_CPU_LITTLE_ENDIAN + struct{ + u32 clp :1; // Cell Loss Priority + u32 pti :3; // Payload Type Identifier + u32 vci :16; // Virtual Channel Identifier + u32 vpi :8; // Vitual Path Identifier + u32 gfc :4; // Generic Flow Control + }bit; +#else + struct{ + u32 gfc :4; // Generic Flow Control + u32 vpi :8; // Vitual Path Identifier + u32 vci :16; // Virtual Channel Identifier + u32 pti :3; // Payload Type Identifier + u32 clp :1; // Cell Loss Priority + }bit; +#endif +}; + + +/************************ Function Declarations **************************/ +amazon_atm_dev_t * amazon_atm_create(void); +int amazon_atm_open(struct atm_vcc *vcc,push_back_t); +int amazon_atm_send(struct atm_vcc *vcc,struct sk_buff *skb); +int amazon_atm_send_oam(struct atm_vcc *vcc,void *cell, int flags); +void amazon_atm_close(struct atm_vcc *vcc); +void amazon_atm_cleanup(void); +const struct oam_last_activity* get_oam_time_stamp(void); + +//mib-related +int amazon_atm_cell_mib(atm_cell_ifEntry_t * to,u32 itf); +int amazon_atm_aal5_mib(atm_aal5_ifEntry_t * to); +int amazon_atm_vcc_mib(struct atm_vcc *vcc,atm_aal5_vcc_t * to); +int amazon_atm_vcc_mib_x(int vpi, int vci,atm_aal5_vcc_t* to); + +#define AMAZON_WRITE_REGISTER_L(data,addr) do{ *((volatile u32*)(addr)) = (u32)(data); wmb();} while (0) +#define AMAZON_READ_REGISTER_L(addr) (*((volatile u32*)(addr))) +/******************************* ioctl stuff****************************************/ +#define NUM(dev) (MINOR(dev) & 0xf) +/* + * Ioctl definitions + */ +/* Use 'o' as magic number */ +#define AMAZON_ATM_IOC_MAGIC 'o' +/* MIB_CELL: get atm cell level mib counter + * MIB_AAL5: get aal5 mib counter + * MIB_VCC: get vcc mib counter + */ +typedef struct{ + int vpi; + int vci; + atm_aal5_vcc_t mib_vcc; +}atm_aal5_vcc_x_t; +#define AMAZON_ATM_MIB_CELL _IOWR(AMAZON_ATM_IOC_MAGIC, 0, atm_cell_ifEntry_t) +#define AMAZON_ATM_MIB_AAL5 _IOWR(AMAZON_ATM_IOC_MAGIC, 1, atm_aal5_ifEntry_t) +#define AMAZON_ATM_MIB_VCC _IOWR(AMAZON_ATM_IOC_MAGIC, 2, atm_aal5_vcc_x_t) +#define AMAZON_ATM_IOC_MAXNR 3 + +//sockopt +#define SO_AMAZON_ATM_MIB_VCC __SO_ENCODE(SOL_ATM,5,atm_aal5_vcc_t) + +#endif // AMAZON_TPE_H + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_wdt.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_wdt.h new file mode 100644 index 000000000..775dabccf --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_wdt.h @@ -0,0 +1,23 @@ +#ifndef AMAZON_WDT_H +#define AMAZON_WDT_H +#ifdef __KERNEL__ +typedef struct wdt_dev{ + char name[16]; + int major; + int minor; + + int full; + char buff[10]; +}wdt_dev; +#define AMAZON_WDT_REG32(addr) (*((volatile u32*)(addr))) +#endif //__KERNEL__ + +//AMAZON_WDT_IOC_START: start the WDT timer (must provide a initial timeout value) +//AMAZON_WDT_IOC_STOP: stop the WDT +//AMAZON_WDT_IOC_PING: reload the timer to initial value (must happend after a AMAZON_WDT_IOC_START) +#define AMAZON_WDT_IOC_MAGIC 0xc0 +#define AMAZON_WDT_IOC_START _IOW( AMAZON_WDT_IOC_MAGIC,0, int) +#define AMAZON_WDT_IOC_STOP _IO( AMAZON_WDT_IOC_MAGIC,1) +#define AMAZON_WDT_IOC_PING _IO( AMAZON_WDT_IOC_MAGIC,2) + +#endif //AMAZON_WDT_H diff --git a/target/linux/amazon/files/include/asm-mips/amazon/atm_defines.h b/target/linux/amazon/files/include/asm-mips/amazon/atm_defines.h new file mode 100644 index 000000000..8adda2005 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/atm_defines.h @@ -0,0 +1,540 @@ +#ifndef ATM_DEFINES_H +#define ATM_DEFINES_H + +//Registers Base Address +#define IO_BASE_ADDR 0xA0000000 +#define AAL5_BASE_ADDRESS 0x10104400+IO_BASE_ADDR +#define CBM_BASE_ADDRESS 0x10104000+IO_BASE_ADDR +#define HTU_BASE_ADDRESS 0x10105100+IO_BASE_ADDR +#define QSB_BASE_ADDRESS 0x10105000+IO_BASE_ADDR +#define SWIE_BASE_ADDRESS 0x10105200+IO_BASE_ADDR + +//AAL5 Registers +#define AAL5_SISR0_ADDR AAL5_BASE_ADDRESS+0x20 +#define AAL5_SIMR0_ADDR AAL5_BASE_ADDRESS+0x24 +#define AAL5_SISR1_ADDR AAL5_BASE_ADDRESS+0x28 +#define AAL5_SIMR1_ADDR AAL5_BASE_ADDRESS+0x2C +#define AAL5_SMFL_ADDR AAL5_BASE_ADDRESS+0x30 +#define AAL5_SATMHD_ADDR AAL5_BASE_ADDRESS+0x34 +#define AAL5_SCON_ADDR AAL5_BASE_ADDRESS+0x38 +#define AAL5_SCMD_ADDR AAL5_BASE_ADDRESS+0x3C +#define AAL5_RISR0_ADDR AAL5_BASE_ADDRESS+0x40 +#define AAL5_RIMR0_ADDR AAL5_BASE_ADDRESS+0x44 +#define AAL5_RISR1_ADDR AAL5_BASE_ADDRESS+0x48 +#define AAL5_RIMR1_ADDR AAL5_BASE_ADDRESS+0x4C +#define AAL5_RMFL_ADDR AAL5_BASE_ADDRESS+0x50 +#define AAL5_RINTINF0_ADDR AAL5_BASE_ADDRESS+0x54 +#define AAL5_RINTINF1_ADDR AAL5_BASE_ADDRESS+0x58 +#define AAL5_RES5C_ADDR AAL5_BASE_ADDRESS+0x5C +#define AAL5_RIOL_ADDR AAL5_BASE_ADDRESS+0x60 +#define AAL5_RIOM_ADDR AAL5_BASE_ADDRESS+0x64 +#define AAL5_SOOL_ADDR AAL5_BASE_ADDRESS+0x68 +#define AAL5_SOOM_ADDR AAL5_BASE_ADDRESS+0x6C +#define AAL5_RES70_ADDR AAL5_BASE_ADDRESS+0x70 +#define AAL5_RES74_ADDR AAL5_BASE_ADDRESS+0x74 +#define AAL5_RES78_ADDR AAL5_BASE_ADDRESS+0x78 +#define AAL5_RES7C_ADDR AAL5_BASE_ADDRESS+0x7C +#define AAL5_RES80_ADDR AAL5_BASE_ADDRESS+0x80 +#define AAL5_RES84_ADDR AAL5_BASE_ADDRESS+0x84 +#define AAL5_RES88_ADDR AAL5_BASE_ADDRESS+0x88 +#define AAL5_RES8C_ADDR AAL5_BASE_ADDRESS+0x8C +#define AAL5_RES90_ADDR AAL5_BASE_ADDRESS+0x90 +#define AAL5_RES94_ADDR AAL5_BASE_ADDRESS+0x94 +#define AAL5_RES98_ADDR AAL5_BASE_ADDRESS+0x98 +#define AAL5_RES9C_ADDR AAL5_BASE_ADDRESS+0x9C +#define AAL5_RESA0_ADDR AAL5_BASE_ADDRESS+0xA0 +#define AAL5_RESA4_ADDR AAL5_BASE_ADDRESS+0xA4 +#define AAL5_RESA8_ADDR AAL5_BASE_ADDRESS+0xA8 +#define AAL5_RESAC_ADDR AAL5_BASE_ADDRESS+0xAC +#define AAL5_RESB0_ADDR AAL5_BASE_ADDRESS+0xB0 +#define AAL5_RESB4_ADDR AAL5_BASE_ADDRESS+0xB4 +#define AAL5_RESB8_ADDR AAL5_BASE_ADDRESS+0xB8 +#define AAL5_RESBC_ADDR AAL5_BASE_ADDRESS+0xBC +#define AAL5_RESC0_ADDR AAL5_BASE_ADDRESS+0xC0 +#define AAL5_RESC4_ADDR AAL5_BASE_ADDRESS+0xC4 +#define AAL5_RESC8_ADDR AAL5_BASE_ADDRESS+0xC8 +#define AAL5_RESCC_ADDR AAL5_BASE_ADDRESS+0xCC +#define AAL5_RESD0_ADDR AAL5_BASE_ADDRESS+0xD0 +#define AAL5_RESD4_ADDR AAL5_BASE_ADDRESS+0xD4 +#define AAL5_RESD8_ADDR AAL5_BASE_ADDRESS+0xD8 +#define AAL5_RESDC_ADDR AAL5_BASE_ADDRESS+0xDC +#define AAL5_RESE0_ADDR AAL5_BASE_ADDRESS+0xE0 +#define AAL5_RESE4_ADDR AAL5_BASE_ADDRESS+0xE4 +#define AAL5_RESE8_ADDR AAL5_BASE_ADDRESS+0xE8 +#define AAL5_RESEC_ADDR AAL5_BASE_ADDRESS+0xEC +#define AAL5_SSRC0_ADDR AAL5_BASE_ADDRESS+0xF0 +#define AAL5_SSRC1_ADDR AAL5_BASE_ADDRESS+0xF4 +#define AAL5_RSRC0_ADDR AAL5_BASE_ADDRESS+0xF8 +#define AAL5_RSRC1_ADDR AAL5_BASE_ADDRESS+0xFC + +#define AAL5S_ISR_QID_MASK 0xFF000000 +#define AAL5S_ISR_SAB 0x00000100 +#define AAL5S_ISR_SE 0x00000080 +#define AAL5S_ISR_MFLE 0x00000040 +#define AAL5S_ISR_SBE0 0x00000020 +#define AAL5S_ISR_SEG0 0x00000010 +#define AAL5S_ISR_TAB 0x00000004 + +#define AAL5_SIMR_MASK 0x000001c7 +#define AAL5_SIMR_SAB 0x00000100 +#define AAL5_SIMR_SE 0x00000080 +#define AAL5_SIMR_MFLE 0x00000040 +#define AAL5_SIMR_TAB 0x00000004 +#define AAL5_SIMR_SBE0 0x00000002 +#define AAL5_SIMR_SEG0 0x00000001 + +#define AAL5_SCMD_SEQCOUNT_MASK 0x0000ff00 +#define AAL5_SCMD_MODE_POLL 0x00000008 +#define AAL5_SCMD_MODE_COUNT 0x00000000 +#define AAL5_SCMD_AS 0x00000004 +#define AAL5_SCMD_SS 0x00000002 +#define AAL5_SCMD_AR 0x00000001 + +#define AAL5R_ISR_CID_MASK 0xFF000000//ConnectionID +#define AAL5R_ISR_DBC_MASK 0x00FF0000//DiscardedByteCounter +#define AAL5R_ISR_END 0x00002000//End +#define AAL5R_ISR_ICID 0x00001000//InvalidConnectionID +#define AAL5R_ISR_CLP 0x00000800//CellLossPriority +#define AAL5R_ISR_CGST 0x00000400//Congestion +#define AAL5R_ISR_UUE 0x00000200//CPCSUUError +#define AAL5R_ISR_CPIE 0x00000100//CPIError +#define AAL5R_ISR_FE 0x00000080//FrameEnd +#define AAL5R_ISR_MFLE 0x00000040//MaximumFrameLengthExceeded +#define AAL5R_ISR_DBCE 0x00000020//DiscardedByteCounterExceeded +#define AAL5R_ISR_CRC 0x00000010//CRCError +#define AAL5R_ISR_ILEN 0x00000008//InvalidLength +#define AAL5R_ISR_RAB 0x00000004//ReceiveAbort + +#define AAL5_RIMR1_MASK 0x00003ffc +#define AAL5_RIMR1_END 0x00002000//End +#define AAL5_RIMR1_ICID 0x00001000//InvalidConnectionID +#define AAL5_RIMR1_CLP 0x00000800//CellLossPriority +#define AAL5_RIMR1_CGST 0x00000400//Congestion +#define AAL5_RIMR1_UUE 0x00000200//CPCSUUError +#define AAL5_RIMR1_CPIE 0x00000100//CPIError +#define AAL5_RIMR1_FE 0x00000080//FrameEnd +#define AAL5_RIMR1_MFLE 0x00000040//MaximumFrameLengthExceeded +#define AAL5_RIMR1_DBCE 0x00000020//DiscardedByteCounterExceeded +#define AAL5_RIMR1_CRC 0x00000010//CRCError +#define AAL5_RIMR1_ILEN 0x00000008//InvalidLength +#define AAL5_RIMR1_RAB 0x00000004//ReceiveAbort + +//AAL5 Reassambly Errors +#define AAL5_STW1_MASK 0x33//Error mask +#define AAL5_STW0_MASK 0x5c//Error mask +#define AAL5_STW0_BE 0x3//padding bytes mask +#define AAL5_STW1_CBM 0x20//Transfer from CBM to A5R abnormally ended +#define AAL5_STW1_CH 0x10//Invalid Channel number error +#define AAL5_STW1_CLP 0x8//CLP value of cells in packet is 1 +#define AAL5_STW1_CG 0x4//Cell in packet expired congestion +#define AAL5_STW1_UU 0x2//CPCS-UU value error +#define AAL5_STW1_CPI 0x1//CPI value error +#define AAL5_STW0_FE 0x80//Frame end +#define AAL5_STW0_MFL 0x40//Maximum frame length error +#define AAL5_STW0_CRC 0x10//CRC error +#define AAL5_STW0_IL 0x8//Invalid length +#define AAL5_STW0_RA 0x4//Received abort + + + +//CBM Registers +#define CBM_NRTTHR_ADDR CBM_BASE_ADDRESS+0x10//NonRealTimeThreshold +#define CBM_CLP0THR_ADDR CBM_BASE_ADDRESS+0x14//CLP0Threshold +#define CBM_CLP1THR_ADDR CBM_BASE_ADDRESS+0x18//CLP1Threshold +#define CBM_QDOFF_ADDR CBM_BASE_ADDRESS+0x1C//QueueDescriptorOffset +#define CBM_CFG_ADDR CBM_BASE_ADDRESS+0x20//Configuration +#define CBM_HWEXPAR0_ADDR CBM_BASE_ADDRESS+0x24//HWExtractParameter0 +#define CBM_RES28_ADDR CBM_BASE_ADDRESS+0x28 +#define CBM_WMSTAT0_ADDR CBM_BASE_ADDRESS+0x2C +#define CBM_HWEXCMD_ADDR CBM_BASE_ADDRESS+0x30//HWExtractCommand0 +#define CBM_RES34_ADDR CBM_BASE_ADDRESS+0x34 +#define CBM_HWEXSTAT0_ADDR CBM_BASE_ADDRESS+0x38//HWExtractStatus0 +#define CBM_RES3C_ADDR CBM_BASE_ADDRESS+0x3C +#define CBM_RES40_ADDR CBM_BASE_ADDRESS+0x40 +#define CBM_CNT_ADDR CBM_BASE_ADDRESS+0x44//CellCount +#define CBM_RES48_ADDR CBM_BASE_ADDRESS+0x48 +#define CBM_LFR_ADDR CBM_BASE_ADDRESS+0x4C//PointertolastCellinfreeCellQueue +#define CBM_FFR_ADDR CBM_BASE_ADDRESS+0x50//PointertofirstCellinfreeCellQueue +#define CBM_RES54_ADDR CBM_BASE_ADDRESS+0x54 +#define CBM_RES58_ADDR CBM_BASE_ADDRESS+0x58 +#define CBM_RES5C_ADDR CBM_BASE_ADDRESS+0x5C +#define CBM_RES60_ADDR CBM_BASE_ADDRESS+0x60 +#define CBM_RES64_ADDR CBM_BASE_ADDRESS+0x64 +#define CBM_RES68_ADDR CBM_BASE_ADDRESS+0x68 +#define CBM_RES6C_ADDR CBM_BASE_ADDRESS+0x6C +#define CBM_RES70_ADDR CBM_BASE_ADDRESS+0x70 +#define CBM_RES74_ADDR CBM_BASE_ADDRESS+0x74 +#define CBM_RES78_ADDR CBM_BASE_ADDRESS+0x78 +#define CBM_RES7C_ADDR CBM_BASE_ADDRESS+0x7C +#define CBM_RES80_ADDR CBM_BASE_ADDRESS+0x80 +#define CBM_RES84_ADDR CBM_BASE_ADDRESS+0x84 +#define CBM_RES88_ADDR CBM_BASE_ADDRESS+0x88 +#define CBM_RES8C_ADDR CBM_BASE_ADDRESS+0x8C +#define CBM_RES90_ADDR CBM_BASE_ADDRESS+0x90 +#define CBM_RES94_ADDR CBM_BASE_ADDRESS+0x94 +#define CBM_RES98_ADDR CBM_BASE_ADDRESS+0x98 +#define CBM_RES9C_ADDR CBM_BASE_ADDRESS+0x9C +#define CBM_RESA0_ADDR CBM_BASE_ADDRESS+0xA0 +#define CBM_RESA4_ADDR CBM_BASE_ADDRESS+0xA4 +#define CBM_RESA8_ADDR CBM_BASE_ADDRESS+0xA8 +#define CBM_RESAC_ADDR CBM_BASE_ADDRESS+0xAC +#define CBM_RESB0_ADDR CBM_BASE_ADDRESS+0xB0 +#define CBM_RESB4_ADDR CBM_BASE_ADDRESS+0xB4 +#define CBM_RESB8_ADDR CBM_BASE_ADDRESS+0xB8 +#define CBM_RESBC_ADDR CBM_BASE_ADDRESS+0xBC +#define CBM_INTINF0_ADDR CBM_BASE_ADDRESS+0xC0//InterruptInfo0 +#define CBM_INTCMD_ADDR CBM_BASE_ADDRESS+0xC4//InterruptCommand0 +#define CBM_IMR0_ADDR CBM_BASE_ADDRESS+0xC8//InterruptMask +#define CBM_SRC0_ADDR CBM_BASE_ADDRESS+0xCC//ServiceRequestControl +#define CBM_RESD0_ADDR CBM_BASE_ADDRESS+0xD0 +#define CBM_RESD4_ADDR CBM_BASE_ADDRESS+0xD4 +#define CBM_RESD8_ADDR CBM_BASE_ADDRESS+0xD8 +#define CBM_RESDC_ADDR CBM_BASE_ADDRESS+0xDC +#define CBM_RESE0_ADDR CBM_BASE_ADDRESS+0xE0 +#define CBM_AAL5IDIS_ADDR CBM_BASE_ADDRESS+0xE4//MIB-No.EPDdiscardedpacketsupstream +#define CBM_AAL5ODIS_ADDR CBM_BASE_ADDRESS+0xE8//MIB-No.PPDdiscardedpacketsupstream +#define CBM_RESEC_ADDR CBM_BASE_ADDRESS+0xEC +#define CBM_RESF0_ADDR CBM_BASE_ADDRESS+0xF0 +#define CBM_RESF4_ADDR CBM_BASE_ADDRESS+0xF4 +#define CBM_RESF8_ADDR CBM_BASE_ADDRESS+0xF8 +#define CBM_RESFC_ADDR CBM_BASE_ADDRESS+0xFC + +//CBMCFG +#define CBM_CFG_INTLCK0EN 0x00000008 +#define CBM_CFG_INT0HLT 0x00000004 +#define CBM_CFG_START 0x00000001 + +#define CBM_HWEXPAR_PN_A5 0x00002000 +#define CBM_HWEXPAR_PN_CM 0x00000000 +#define CBM_HWEXPAR_SUBADD_PORTMASK 0x00000070 +#define CBM_HWEXPAR_SUBADD_ADU 0x00000000 +#define CBM_HWEXPAR_SUBADD_AAL2 0x00000080 +#define CBM_HWEXPAR_SUBADD_SWIE 0x00000100 + +#define CBM_HWEXCMD_SFE2 0x00000100 +#define CBM_HWEXCMD_FE2 0x00000080 +#define CBM_HWEXCMD_SCE2 0x00000040 +#define CBM_HWEXCMD_SFE1 0x00000020 +#define CBM_HWEXCMD_FE1 0x00000010 +#define CBM_HWEXCMD_SCE1 0x00000008 +#define CBM_HWEXCMD_SFE0 0x00000004 +#define CBM_HWEXCMD_FE0 0x00000002 +#define CBM_HWEXCMD_SCE0 0x00000001 + +#define CBM_INTINF0_QID_MASK 0xFF000000 +#define CBM_INTINF0_ORIGIN_MASK 0x00F00000 +#define CBM_INTINF0_EF 0x00004000 +#define CBM_INTINF0_ACA 0x00002000 +#define CBM_INTINF0_ERR 0x00001000 +#define CBM_INTINF0_DISC 0x00000800 +#define CBM_INTINF0_QSBV 0x00000400 +#define CBM_INTINF0_Q0E 0x00000200 +#define CBM_INTINF0_Q0I 0x00000100 +#define CBM_INTINF0_RDE 0x00000080 +#define CBM_INTINF0_OPF 0x00000040 +#define CBM_INTINF0_NFCA 0x00000020 +#define CBM_INTINF0_CLP1TR 0x00000010 +#define CBM_INTINF0_CLP0TR 0x00000008 +#define CBM_INTINF0_NRTTR 0x00000004 +#define CBM_INTINF0_QFD 0x00000002 +#define CBM_INTINF0_QTR 0x00000001 +#define CBM_INTINF0_QID_SHIFT 24 +//CBM QD Word 3 +#define CBM_QD_W3_QOS_0 0x00000000 +#define CBM_QD_W3_QOS_1 0x40000000 +#define CBM_QD_W3_QOS_2 0x80000000 +#define CBM_QD_W3_QOS_3 0xc0000000 + +#define CBM_QD_W3_DIR_UP 0x20000000 +#define CBM_QD_W3_DIR_DOWN 0x00000000 + +#define CBM_QD_W3_CLPt 0x10000000 +#define CBM_QD_W3_RT 0x08000000 +#define CBM_QD_W3_AAL5 0x04000000 + +#define CBM_QD_W3_INT_NOINT 0x00000000 +#define CBM_QD_W3_INT_ACA 0x01000000 +#define CBM_QD_W3_INT_EOF 0x02000000 +#define CBM_QD_W3_INT_BOTH 0x03000000 + +#define CBM_QD_W3_THRESHOLD_MASK 0x00ff0000 +#define CBM_QD_W3_WM_EN 0x00000010 +#define CBM_QD_W3_HCR 0x00000008 +#define CBM_QD_W3_SBID_MASK 0x00000001 + +#define CBM_QD_W3_THRESHOLD_SHIFT 16 + +//WATER MARK STATUS +#define CBM_WM_NRT_MASK 0x00040000 +#define CBM_WM_CLP0_MASK 0x00020000 +#define CBM_WM_CLP1_MASK 0x00010000 + +//CBMNRTTHR, CBMCLP0THR, CBMCLP0THR +#define CBM_NRT_WM_NONE 0x00000000//no water mark +#define CBM_WM_3_1 0x00010000//3/4 to set, 1/4 to release +#define CBM_WM_3_2 0x00020000//3/4 to set, 2/4 to release +#define CBM_WM_2_1 0x00030000//2/4 to set, 1/4 to release +#define CBM_THR_MASK 0x0000FFFF + +#define CBM_IMR_MASK 0x0000fbff +#define CBM_IMR_reserved 0xFFFF0400 +#define CBM_IMR_RFULL 0x00008000//EndofFrame +#define CBM_IMR_EF 0x00004000//EndofFrame +#define CBM_IMR_ACA 0x00002000//AnyCellArrived +#define CBM_IMR_ERR 0x00001000//FPI Error +#define CBM_IMR_DISC 0x00000800//Discard +#define CBM_IMR_reserved1 0x00000400//reserved +#define CBM_IMR_Q0E 0x00000200//Queue0Extract +#define CBM_IMR_Q0I 0x00000100//Queue0Insert +#define CBM_IMR_RDE 0x00000080//ReadEmptyQueue +#define CBM_IMR_OPF 0x00000040//OncePerFrame +#define CBM_IMR_NFCA 0x00000020//NoFreeCellAvailable +#define CBM_IMR_CLP1TR 0x00000010//CLP1ThresholdReached +#define CBM_IMR_CLP0TR 0x00000008//CLP0ThresholdReached +#define CBM_IMR_NRTTR 0x00000004//NonRealTimeThresholdReached +#define CBM_IMR_QFD 0x00000002//QueueFrameDiscard +#define CBM_IMR_QTR 0x00000001//QueueThresholdReached + +#define CBM_EXSTAT_FB 0x00000010 +#define CBM_EXSTAT_SCB 0x00000008 +#define CBM_EXSTAT_Q0 0x00000004 +#define CBM_EXSTAT_RDE 0x00000002 +#define CBM_EXSTAT_QV 0x00000001 + +//HTU Registers +#define HTU_RX0_ADDR HTU_BASE_ADDRESS+0x10 +#define HTU_RX1_ADDR HTU_BASE_ADDRESS+0x14 +#define HTU_RES18_ADDR HTU_BASE_ADDRESS+0x18 +#define HTU_RES1C_ADDR HTU_BASE_ADDRESS+0x1C +#define HTU_RES20_ADDR HTU_BASE_ADDRESS+0x20 +#define HTU_RES24_ADDR HTU_BASE_ADDRESS+0x24 +#define HTU_RES28_ADDR HTU_BASE_ADDRESS+0x28 +#define HTU_RES2C_ADDR HTU_BASE_ADDRESS+0x2C +#define HTU_PCF0PAT_ADDR HTU_BASE_ADDRESS+0x30 +#define HTU_PCF1PAT_ADDR HTU_BASE_ADDRESS+0x34 +#define HTU_RES38_ADDR HTU_BASE_ADDRESS+0x38 +#define HTU_RES3C_ADDR HTU_BASE_ADDRESS+0x3C +#define HTU_RES40_ADDR HTU_BASE_ADDRESS+0x40 +#define HTU_RES44_ADDR HTU_BASE_ADDRESS+0x44 +#define HTU_RES48_ADDR HTU_BASE_ADDRESS+0x48 +#define HTU_RES4C_ADDR HTU_BASE_ADDRESS+0x4C +#define HTU_PCF0MASK_ADDR HTU_BASE_ADDRESS+0x50 +#define HTU_PCF1MASK_ADDR HTU_BASE_ADDRESS+0x54 +#define HTU_RES58_ADDR HTU_BASE_ADDRESS+0x58 +#define HTU_RES5C_ADDR HTU_BASE_ADDRESS+0x5C +#define HTU_RES60_ADDR HTU_BASE_ADDRESS+0x60 +#define HTU_RES64_ADDR HTU_BASE_ADDRESS+0x64 +#define HTU_RES68_ADDR HTU_BASE_ADDRESS+0x68 +#define HTU_RES6C_ADDR HTU_BASE_ADDRESS+0x6C +#define HTU_TIMEOUT_ADDR HTU_BASE_ADDRESS+0x70 +#define HTU_DESTOAM_ADDR HTU_BASE_ADDRESS+0x74 +#define HTU_DESTRM_ADDR HTU_BASE_ADDRESS+0x78 +#define HTU_DESTOTHER_ADDR HTU_BASE_ADDRESS+0x7C +#define HTU_CFG_ADDR HTU_BASE_ADDRESS+0x80 +#define HTU_RES84_ADDR HTU_BASE_ADDRESS+0x84 +#define HTU_RES88_ADDR HTU_BASE_ADDRESS+0x88 +#define HTU_RES8C_ADDR HTU_BASE_ADDRESS+0x8C +#define HTU_INFNOENTRY_ADDR HTU_BASE_ADDRESS+0x90 +#define HTU_INFTIMEOUT_ADDR HTU_BASE_ADDRESS+0x94 +#define HTU_RES98_STAT HTU_BASE_ADDRESS+0x98 +#define HTU_RES9C_ADDR HTU_BASE_ADDRESS+0x9C +#define HTU_MIBCIUP HTU_BASE_ADDRESS+0xA0//MIB Counter In Unknown Protoc Register +#define HTU_CNTTIMEOUT_ADDR HTU_BASE_ADDRESS+0xA4 +#define HTU_RESA8_ADDR HTU_BASE_ADDRESS+0xA8 +#define HTU_RESAC_ADDR HTU_BASE_ADDRESS+0xAC +#define HTU_RAMADDR_ADDR HTU_BASE_ADDRESS+0xB0 +#define HTU_RAMCMD_ADDR HTU_BASE_ADDRESS+0xB4 +#define HTU_RAMSTAT_ADDR HTU_BASE_ADDRESS+0xB8 +#define HTU_RESBC_ADDR HTU_BASE_ADDRESS+0xBC +#define HTU_RAMDAT1_ADDR HTU_BASE_ADDRESS+0xC0 +#define HTU_RAMDAT2_ADDR HTU_BASE_ADDRESS+0xC4 +#define HTU_RESCC_ADDR HTU_BASE_ADDRESS+0xCC +#define HTU_RESD0_ADDR HTU_BASE_ADDRESS+0xD0 +#define HTU_RESD4_ADDR HTU_BASE_ADDRESS+0xD4 +#define HTU_RESD8_ADDR HTU_BASE_ADDRESS+0xD8 +#define HTU_RESDC_ADDR HTU_BASE_ADDRESS+0xDC +#define HTU_RESE0_ADDR HTU_BASE_ADDRESS+0xE0 +#define HTU_RESE4_ADDR HTU_BASE_ADDRESS+0xE4 +#define HTU_IMR0_ADDR HTU_BASE_ADDRESS+0xE8 +#define HTU_RESEC_ADDR HTU_BASE_ADDRESS+0xEC +#define HTU_ISR0_ADDR HTU_BASE_ADDRESS+0xF0 +#define HTU_RESF4_ADDR HTU_BASE_ADDRESS+0xF4 +#define HTU_SRC0_ADDR HTU_BASE_ADDRESS+0xF8 +#define HTU_RESFC_ADDR HTU_BASE_ADDRESS+0xFC + +//HTU_CFG +#define HTU_CFG_START 0x00000001 + +#define HTU_RAMCMD_RMW 0x00000004 +#define HTU_RAMCMD_RD 0x00000002 +#define HTU_RAMCMD_WR 0x00000001 + +#define HTU_RAMDAT1_VCON 0x00000080//validconnection +#define HTU_RAMDAT1_VCT 0x00000040//vcivalueistransparent +#define HTU_RAMDAT1_QIDS 0x00000020//qid selects a cell in cbm +#define HTU_RAMDAT1_VCI3 0x00000010//vci3->oamqueue +#define HTU_RAMDAT1_VCI4 0x00000008//vci4->oamqueue +#define HTU_RAMDAT1_VCI6 0x00000004//vci6->rmqueue +#define HTU_RAMDAT1_PTI4 0x00000002//pti4->oamqueue +#define HTU_RAMDAT1_PTI5 0x00000001//pti5->oamqueue + +#define HTU_RAMDAT2_PTI6 0x00000800 +#define HTU_RAMDAT2_PTI7 0x00000400 +#define HTU_RAMDAT2_F4U 0x00000200 +#define HTU_RAMDAT2_F5U 0x00000100 +#define HTU_RAMDAT2_QID_MASK 0x000000ff + +#define HTU_ISR_NE 0x00000001 +#define HTU_ISR_TORD 0x00000002 +#define HTU_ISR_IT 0x00000008 +#define HTU_ISR_OTOC 0x00000010 +#define HTU_ISR_ONEC 0x00000020 +#define HTU_ISR_PNE 0x00000040 +#define HTU_ISR_PT 0x00000080 +#define HTU_ISR_MASK 0x000000ff + + +//QSB Registers +#define QSB_BIP0_ADDR QSB_BASE_ADDRESS+0x00 +#define QSB_BIP1_ADDR QSB_BASE_ADDRESS+0x04 +#define QSB_BIP2_ADDR QSB_BASE_ADDRESS+0x08 +#define QSB_BIP3_ADDR QSB_BASE_ADDRESS+0x0C +#define QSB_RSVP_ADDR QSB_BASE_ADDRESS+0x10 +#define QSB_TNOW_ADDR QSB_BASE_ADDRESS+0x14 +#define QSB_TNOWCYC_ADDR QSB_BASE_ADDRESS+0x18 +#define QSB_TAU_ADDR QSB_BASE_ADDRESS+0x1C +#define QSB_L1BRS_ADDR QSB_BASE_ADDRESS+0x20 +#define QSB_SBL_ADDR QSB_BASE_ADDRESS+0x24 +#define QSB_CONFIG_ADDR QSB_BASE_ADDRESS+0x28 +#define QSB_RTM_ADDR QSB_BASE_ADDRESS+0x2C +#define QSB_RTD_ADDR QSB_BASE_ADDRESS+0x30 +#define QSB_RAMAC_ADDR QSB_BASE_ADDRESS+0x34 +#define QSB_ISR_ADDR QSB_BASE_ADDRESS+0x38 +#define QSB_IMR_ADDR QSB_BASE_ADDRESS+0x3C +#define QSB_SRC_ADDR QSB_BASE_ADDRESS+0x40 + +#define QSB_TABLESEL_QVPT 8 +#define QSB_TABLESEL_QPT 1 +#define QSB_TABLESEL_SCT 2 +#define QSB_TABLESEL_SPT 3 +#define QSB_TABLESEL_CALENDARWFQ 4/*notusedbyFW*/ +#define QSB_TABLESEL_L2WFQ 5/*notusedbyFW*/ +#define QSB_TABLESEL_CALENDARRS 6/*notusedbyFW*/ +#define QSB_TABLESEL_L2BITMAPRS 7/*notusedbyFW*/ +#define QSB_TABLESEL_SHIFT 24 +#define QSB_TWFQ_MASK 0x3FFF0000 +#define QSB_TPRS_MASK 0x0000FFFF +#define QSB_SBID_MASK 0xF +#define QSB_TWFQ_SHIFT 16 +#define QSB_SCDRATE_MASK 0x00007FFF +#define QSB_SBVALID_MASK 0x80000000 + +#define QSB_ISR_WFQLE 0x00000001 +#define QSB_ISR_WFQBE 0x00000002 +#define QSB_ISR_RSLE 0x00000004 +#define QSB_ISR_RSBE 0x00000008 +#define QSB_ISR_MUXOV 0x00000010 +#define QSB_ISR_CDVOV 0x00000020 +#define QSB_ISR_PARAMI 0x00000040 +#define QSB_ISR_SLOSS 0x00000080 +#define QSB_ISR_IIPS 0x00000100 + +#define QSB_IMR_WFQLE 0x00000001 +#define QSB_IMR_WFQBE 0x00000002 +#define QSB_IMR_RSLE 0x00000004 +#define QSB_IMR_RSBE 0x00000008 +#define QSB_IMR_MUXOV 0x00000010 +#define QSB_IMR_CDVOV 0x00000020 +#define QSB_IMR_PARAMI 0x00000040 +#define QSB_IMR_SLOSS 0x00000080 +#define QSB_IMR_IIPS 0x00000100 + +#define QSB_READ 0x0 +#define QSB_WRITE 0x80000000 +#define QSB_READ_ALL 0xFFFFFFFF + +#if 1 //some bug with QSB access mask +#define QSB_QPT_SET_MASK 0x0 +#define QSB_QVPT_SET_MASK 0x0 +#define QSB_SET_SCT_MASK 0x0 +#define QSB_SET_SPT_MASK 0x0 +#define QSB_SET_SPT_SBVALID_MASK 0x7FFFFFFF +#else //some bug with QSB access mask +#define QSB_QPT_SET_MASK 0x80000000 +#define QSB_QVPT_SET_MASK 0x0 +#define QSB_SET_SCT_MASK 0xFFFFFFE0 +#define QSB_SET_SPT_MASK 0x7FF8C000 +#define QSB_SET_SPT_SBVALID_MASK 0x7FFFFFFF +#endif //some bug with QSB access mask + +#define QSB_SPT_SBVALID 0x80000000 + +#define QSB_RAMAC_REG_LOW 0x0 +#define QSB_RAMAC_REG_HIGH 0x00010000 + +#define SRC_SRE_ENABLE 0x1000 +#define SRC_CLRR 0x4000 //request clear bit + + + +//SWIE Registers +#define SWIE_IQID_ADDR SWIE_BASE_ADDRESS+0x0c//SWIEInsertQueueDescriptor +#define SWIE_ICMD_ADDR SWIE_BASE_ADDRESS+0x10//SWIEInsertCommand +#define SWIE_ISTAT_ADDR SWIE_BASE_ADDRESS+0x14//SWIEInsertStatus +#define SWIE_ESTAT_ADDR SWIE_BASE_ADDRESS+0x18//SWIEExtractStatus +#define SWIE_ISRC_ADDR SWIE_BASE_ADDRESS+0x74//SWIEInsertServiceRequestControl +#define SWIE_ESRC_ADDR SWIE_BASE_ADDRESS+0x78//SWIEExtractServiceRequestControl +#define SWIE_ICELL_ADDR SWIE_BASE_ADDRESS+0x80//SWIEInsertCell(0x80-0xb4) +#define SWIE_ECELL_ADDR SWIE_BASE_ADDRESS+0xc0//SWIEExtractCell(0xc0-0xf4) + +#define SWIE_ISTAT_DONE 0x1 +#define SWIE_ESTAT_DONE 0x1 +#define SWIE_ICMD_START 0x00000001//Startcommandforinsertion +#define SWIE_CBM_SCE0 CBM_HWEXCMD_SCE0//CBMcommandforSingle-Cell-Extract +#define SWIE_CBM_PID_SUBADDR 0x00001000//CBMPortIDandSubAddressforUTOPIA + +//Extracted cell format +//52bytes AAL0 PDU + "Input cell additional data"(14bits) +#define SWIE_ADDITION_DATA_MASK 0x7fff +#define SWIE_EPORT_MASK 0x7000//Source ID (000 AUB0, 001 AUB1) +#define SWIE_EF4USER_MASK 0x800 +#define SWIE_EF5USER_MASK 0x400 +#define SWIE_EOAM_MASK 0x200 +#define SWIE_EAUU_MASK 0x100 +#define SWIE_EVCI3_MASK 0x80 +#define SWIE_EVCI4_MASK 0x40 +#define SWIE_EVCI6_MASK 0x20 +#define SWIE_EPTI4_MASK 0x10 +#define SWIE_EPTI5_MASK 0x8 +#define SWIE_EPTI6_MASK 0x4 +#define SWIE_EPTI7_MASK 0x2 +#define SWIE_ECRC10ERROR_MASK 0x1 + +#define CBM_CELL_SIZE 0x40 +#define CBM_QD_SIZE 0x10 +#define AAL5R_TRAILER_LEN 12 +#define AAL5S_INBOUND_HEADER 8 + +//constants +//TODO: to be finalized by system guys +//DMA QOS defined by ATM QoS Service type +#define DMA_RX_CH0 0 +#define DMA_RX_CH1 1 +#define DMA_TX_CH0 0 +#define DMA_TX_CH1 1 +#define CBR_DMA_QOS CBM_QD_W3_QOS_0 +#define VBR_RT_DMA_QOS CBM_QD_W3_QOS_0 +#define VBR_NRT_DMA_QOS CBM_QD_W3_QOS_0 +#define UBR_PLUS_DMA_QOS CBM_QD_W3_QOS_0 +#define UBR_DMA_QOS CBM_QD_W3_QOS_0 + +#define SRC_TOS_MIPS 0 +#define AAL5R_SRPN 0x00000006//a5rneedshigherprioritythanDR +#define AAL5S_SRPN 0x00000005 +#define CBM_MIPS_SRPN 0x00000004 +#define QSB_SRPN 0x00000023 +#define HTU_SRPN1 0x00000022 +#define HTU_SRPN0 0x00000021 + +#endif //ATM_DEFINES_H + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/atm_mib.h b/target/linux/amazon/files/include/asm-mips/amazon/atm_mib.h new file mode 100644 index 000000000..f86334258 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/atm_mib.h @@ -0,0 +1,142 @@ +#ifndef AMAZON_ATM_MIB_H +#define AMAZON_ATM_MIB_H + +#ifdef CONFIG_IFX_ATM_MIB +#include +#ifdef __KERNEL__ +#include +#endif +#endif /* CONFIG_IFX_ATM_MIB */ + +#ifndef __KERNEL__ +#include +typedef unsigned int __u32; +#endif + +typedef struct{ + __u32 ifHCInOctets_h; + __u32 ifHCInOctets_l; + __u32 ifHCOutOctets_h; + __u32 ifHCOutOctets_l; + __u32 ifInErrors; + __u32 ifInUnknownProtos; + __u32 ifOutErrors; +}atm_cell_ifEntry_t; + +typedef struct{ + __u32 ifHCInOctets_h; + __u32 ifHCInOctets_l; + __u32 ifHCOutOctets_h; + __u32 ifHCOutOctets_l; + __u32 ifInUcastPkts; + __u32 ifOutUcastPkts; + __u32 ifInErrors; + __u32 ifInDiscards; + __u32 ifOutErros; + __u32 ifOutDiscards; +}atm_aal5_ifEntry_t; + +typedef struct{ + __u32 aal5VccCrcErrors; + __u32 aal5VccSarTimeOuts;//no timer support yet + __u32 aal5VccOverSizedSDUs; +}atm_aal5_vcc_t; + +#if defined(CONFIG_IFX_ATM_MIB) || defined(IFX_CONFIG_SNMP_ATM_MIB) +/* ATM-MIB data structures */ +typedef struct atmIfConfEntry { + int ifIndex; + int atmInterfaceMaxVpcs; + int atmInterfaceMaxVccs; + int atmInterfaceConfVpcs; + int atmInterfaceConfVccs; + int atmInterfaceMaxActiveVpiBits; + int atmInterfaceMaxActiveVciBits; + int atmInterfaceIlmiVpi; + int atmInterfaceIlmiVci; + int atmInterfaceAddressType; + char atmInterfaceAdminAddress[40]; + unsigned long atmInterfaceMyNeighborIpAddress; + char atmInterfaceMyNeighborIfName[20]; + int atmInterfaceCurrentMaxVpiBits; + int atmInterfaceCurrentMaxVciBits; + char atmInterfaceSubscrAddress[40]; + int flags; +}atmIfConfEntry; + +typedef struct atmTrafficDescParamEntry { + /* Following three parameters are used to update VCC QoS values */ + int ifIndex; + short atmVclvpi; + int atmVclvci; + + unsigned int atmTrafficParamIndex; + unsigned char traffic_class; + int max_pcr; + /* Subramani: Added min_pcr */ + int min_pcr; + int cdv; + int scr; + int mbs; + int atmTrafficRowStatus; + int atmTrafficFrameDiscard; + struct list_head vpivci_head; + struct list_head list; +}atmTrafficDescParamEntry; + + +typedef struct atmVclEntry { + int ifIndex; + short atmVclvpi; + int atmVclvci; + char vpivci[20]; + int atmVclAdminStatus; + int atmVclOperStatus; + unsigned long atmVclLastChange; + struct atmTrafficDescParamEntry *atmVclRxTrafficPtr; + struct atmTrafficDescParamEntry *atmVclTxTrafficPtr; + unsigned char atmVccAalType; + unsigned int atmVccAal5TxSduSize; + unsigned int atmVccAal5RxSduSize; + int atmVccAal5Encap; + int atmVclRowStatus; + int atmVclCastType; + int atmVclConnKind; + struct list_head list; + int flags; +}atmVclEntry; + + +typedef union union_atmptrs { + struct atmIfConfEntry *atmIfConfEntry_ptr; + struct atmTrafficDescParamEntry *atmTrafficDescParamEntry_ptr; + struct atmVclEntry *atmVclEntry_ptr; +}union_atmptrs; + +/* ATM Character device major number */ +#define ATM_MEI_MAJOR 107 + +/* Protocol Constants */ +#define IFX_PROTO_RAW 0 +#define IFX_PROTO_BR2684 1 +#define IFX_PROTO_PPPOATM 2 +#define IFX_PROTO_CLIP 3 + +/* IOCTL Command Set for ATM-MIB */ +#define GET_ATM_IF_CONF_DATA 0x0AB0 +#define SET_ATM_IF_CONF_DATA 0x0AB1 + +#define SET_ATM_QOS_DATA 0x0BC0 + +#define GET_ATM_VCL_DATA 0x0CD0 +#define SET_ATM_VCL_DATA 0x0CD1 + +#define FIND_VCC_IN_KERNEL 0x0DE0 + +/* User defined flags for VCL Table */ +#define ATMVCCAAL5CPCSTRANSMITSDUSIZE 9 +#define ATMVCCAAL5CPCSRECEIVESDUSIZE 10 + +#endif /* CONFIG_IFX_ATM_MIB || IFX_CONFIG_SNMP_ATM_MIB */ + +#endif //AMAZON_ATM_MIB_H diff --git a/target/linux/amazon/files/include/asm-mips/amazon/ifx_peripheral_definitions.h b/target/linux/amazon/files/include/asm-mips/amazon/ifx_peripheral_definitions.h new file mode 100644 index 000000000..65f14e405 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/ifx_peripheral_definitions.h @@ -0,0 +1,96 @@ +//************************************************************************* +//* Summary of definitions which are used in each peripheral * +//************************************************************************* + +#ifndef peripheral_definitions_h +#define peripheral_definitions_h + +typedef unsigned char UINT8; +typedef signed char INT8; +typedef unsigned short UINT16; +typedef signed short INT16; +typedef unsigned int UINT32; +typedef signed int INT32; +typedef unsigned long long UINT64; +typedef signed long long INT64; + +#define REG8( addr ) (*(volatile UINT8 *) (addr)) +#define REG16( addr ) (*(volatile UINT16 *)(addr)) +#define REG32( addr ) (*(volatile UINT32 *)(addr)) +#define REG64( addr ) (*(volatile UINT64 *)(addr)) + +/* define routine to set FPI access in Supervisor Mode */ +#define IFX_SUPERVISOR_ON() REG32(FB0_CFG) = 0x01 +/* Supervisor mode ends, following functions will be done in User mode */ +#define IFX_SUPERVISOR_OFF() REG32(FB0_CFG) = 0x00 +/* Supervisor mode ends, following functions will be done in User mode */ +#define IFX_SUPERVISOR_MODE() REG32(FB0_CFG) +/* Supervisor mode ends, following functions will be done in User mode */ +#define IFX_SUPERVISOR_SET(svm) REG32(FB0_CFG) = svm +/* enable all Interrupts in IIU */ +//#define IFX_ENABLE_IRQ(irq_mask, im_base) REG32(im_base | IIU_MASK) = irq_mask +///* get all high priority interrupt bits in IIU */ +//#define IFX_GET_IRQ_MASKED(im_base) REG32(im_base | IIU_IRMASKED) +///* signal ends of interrupt to IIU */ +//#define IFX_CLEAR_DIRECT_IRQ(irq_bit, im_base) REG32(im_base | IIU_IR) = irq_bit +///* force IIU interrupt register */ +//#define IFX_FORCE_IIU_REGISTER(data, im_base) REG32(im_base | IIU_IRDEBUG) = data +///* get all bits of interrupt register */ +//#define IFX_GET_IRQ_UNMASKED(im_base) REG32(im_base | IIU_IR) +/* insert a NOP instruction */ +#define NOP _nop() +/* CPU goes to power down mode until interrupt occurs */ +#define IFX_CPU_SLEEP _sleep() +/* enable all interrupts to CPU */ +#define IFX_CPU_ENABLE_ALL_INTERRUPT sys_enable_int() +/* get all low priority interrupt bits in peripheral */ +#define IFX_GET_LOW_PRIO_IRQ(int_reg) REG32(int_reg) +/* clear low priority interrupt bit in peripheral */ +#define IFX_CLEAR_LOW_PRIO_IRQ(irq_bit, int_reg) REG32(int_reg) = irq_bit +/* write FPI bus */ +#define WRITE_FPI_BYTE(data, addr) REG8(addr) = data +#define WRITE_FPI_16BIT(data, addr) REG16(addr) = data +#define WRITE_FPI_32BIT(data, addr) REG32(addr) = data +/* read FPI bus */ +#define READ_FPI_BYTE(addr) REG8(addr) +#define READ_FPI_16BIT(addr) REG16(addr) +#define READ_FPI_32BIT(addr) REG32(addr) +/* write peripheral register */ +#define WRITE_PERIPHERAL_REGISTER(data, addr) REG32(addr) = data + +#ifdef CONFIG_CPU_LITTLE_ENDIAN +#define WRITE_PERIPHERAL_REGISTER_16(data, addr) REG16(addr) = data +#define WRITE_PERIPHERAL_REGISTER_8(data, addr) REG8(addr) = data +#else //not CONFIG_CPU_LITTLE_ENDIAN +#define WRITE_PERIPHERAL_REGISTER_16(data, addr) REG16(addr+2) = data +#define WRITE_PERIPHERAL_REGISTER_8(data, addr) REG8(addr+3) = data +#endif //CONFIG_CPU_LITTLE_ENDIAN + +/* read peripheral register */ +#define READ_PERIPHERAL_REGISTER(addr) REG32(addr) + +/* read/modify(or)/write peripheral register */ +#define RMW_OR_PERIPHERAL_REGISTER(data, addr) REG32(addr) = REG32(addr) | data +/* read/modify(and)/write peripheral register */ +#define RMW_AND_PERIPHERAL_REGISTER(data, addr) REG32(addr) = REG32(addr) & (UINT32)data + +/* CPU-independent mnemonic constants */ +/* CLC register bits */ +#define IFX_CLC_ENABLE 0x00000000 +#define IFX_CLC_DISABLE 0x00000001 +#define IFX_CLC_DISABLE_STATUS 0x00000002 +#define IFX_CLC_SUSPEND_ENABLE 0x00000004 +#define IFX_CLC_CLOCK_OFF_DISABLE 0x00000008 +#define IFX_CLC_OVERWRITE_SPEN_FSOE 0x00000010 +#define IFX_CLC_FAST_CLOCK_SWITCH_OFF 0x00000020 +#define IFX_CLC_RUN_DIVIDER_MASK 0x0000FF00 +#define IFX_CLC_RUN_DIVIDER_OFFSET 8 +#define IFX_CLC_SLEEP_DIVIDER_MASK 0x00FF0000 +#define IFX_CLC_SLEEP_DIVIDER_OFFSET 16 +#define IFX_CLC_SPECIFIC_DIVIDER_MASK 0x00FF0000 +#define IFX_CLC_SPECIFIC_DIVIDER_OFFSET 24 + +/* number of cycles to wait for interrupt service routine to be called */ +#define WAIT_CYCLES 50 + +#endif /* PERIPHERAL_DEFINITIONS_H not yet defined */ diff --git a/target/linux/amazon/files/include/asm-mips/amazon/ifx_ssc.h b/target/linux/amazon/files/include/asm-mips/amazon/ifx_ssc.h new file mode 100644 index 000000000..e5d73ad4e --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/ifx_ssc.h @@ -0,0 +1,263 @@ +/* + * ifx_ssc.h defines some data sructures used in ifx_ssc.c + * + * Copyright (C) 2004 Michael Schoenenborn (IFX COM TI BT) + * + * + */ + +#ifndef __IFX_SSC_H +#define __IFX_SSC_H +#ifdef __KERNEL__ +#include +#endif //__KERNEL__ + +#define PORT_CNT 1 // assume default value + +/* symbolic constants to be used in SSC routines */ + +// ### TO DO: bad performance +#define IFX_SSC_TXFIFO_ITL 1 +#define IFX_SSC_RXFIFO_ITL 1 + + + +struct ifx_ssc_statistics{ + unsigned int abortErr; /* abort error */ + unsigned int modeErr; /* master/slave mode error */ + unsigned int txOvErr; /* TX Overflow error */ + unsigned int txUnErr; /* TX Underrun error */ + unsigned int rxOvErr; /* RX Overflow error */ + unsigned int rxUnErr; /* RX Underrun error */ + unsigned int rxBytes; + unsigned int txBytes; +}; + + +struct ifx_ssc_hwopts { + unsigned int AbortErrDetect :1; /* Abort Error detection (in slave mode) */ + unsigned int rxOvErrDetect :1; /* Receive Overflow Error detection */ + unsigned int rxUndErrDetect :1; /* Receive Underflow Error detection */ + unsigned int txOvErrDetect :1; /* Transmit Overflow Error detection */ + unsigned int txUndErrDetect :1; /* Transmit Underflow Error detection */ + unsigned int echoMode :1; /* Echo mode */ + unsigned int loopBack :1; /* Loopback mode */ + unsigned int idleValue :1; /* Idle value */ + unsigned int clockPolarity :1; /* Idle clock is high or low */ + unsigned int clockPhase :1; /* Tx on trailing or leading edge*/ + unsigned int headingControl :1; /* LSB first or MSB first */ + unsigned int dataWidth :6; /* from 2 up to 32 bits */ + unsigned int masterSelect :1; /* Master or Slave mode */ + unsigned int modeRxTx :2; /* rx/tx mode */ + unsigned int gpoCs :8; /* choose outputs to use for chip select */ + unsigned int gpoInv :8; /* invert GPO outputs */ +}; + + +struct ifx_ssc_frm_opts { + bool FrameEnable; // SFCON.SFEN + unsigned int DataLength; // SFCON.DLEN + unsigned int PauseLength; // SFCON.PLEN + unsigned int IdleData; // SFCON.IDAT + unsigned int IdleClock; // SFCON.ICLK + bool StopAfterPause; // SFCON.STOP +}; + +struct ifx_ssc_frm_status { + bool DataBusy; // SFSTAT.DBSY + bool PauseBusy; // SFSTAT.PBSY + unsigned int DataCount; // SFSTAT.DCNT + unsigned int PauseCount; // SFSTAT.PCNT + bool EnIntAfterData; // SFCON.IBEN + bool EnIntAfterPause;// SFCON.IAEN +}; + +typedef struct { + char *buf; + size_t len; +} ifx_ssc_buf_item_t; + + +// data structures for batch execution +typedef union { + struct { + bool save_options; + } init; + ifx_ssc_buf_item_t read; + ifx_ssc_buf_item_t write; + ifx_ssc_buf_item_t rd_wr; + unsigned int set_baudrate; + struct ifx_ssc_frm_opts set_frm; + unsigned int set_gpo; + struct ifx_ssc_hwopts set_hwopts; +}ifx_ssc_batch_cmd_param; + +struct ifx_ssc_batch_list { + unsigned int cmd; + ifx_ssc_batch_cmd_param cmd_param; + struct ifx_ssc_batch_list *next; +}; + +#ifdef __KERNEL__ +#define IFX_SSC_IS_MASTER(p) ((p)->opts.masterSelect == SSC_MASTER_MODE) + + +struct ifx_ssc_port{ + unsigned long mapbase; + struct ifx_ssc_hwopts opts; + struct ifx_ssc_statistics stats; + struct ifx_ssc_frm_status frm_status; + struct ifx_ssc_frm_opts frm_opts; + /* wait queue for ifx_ssc_read() */ + wait_queue_head_t rwait, pwait; + int port_nr; + char port_is_open; /* exclusive open - boolean */ +// int no_of_bits; /* number of _valid_ bits */ +// int elem_size; /* shift for element (no of bytes)*/ + /* buffer and pointers to the read/write position */ + char *rxbuf; /* buffer for RX */ + char *rxbuf_end; /* buffer end pointer for RX */ + volatile char *rxbuf_ptr; /* buffer write pointer for RX */ + char *txbuf; /* buffer for TX */ + char *txbuf_end; /* buffer end pointer for TX */ + volatile char *txbuf_ptr; /* buffer read pointer for TX */ + unsigned int baud; + /* each channel has its own interrupts */ + /* (transmit/receive/error/frame) */ + unsigned int txirq, rxirq, errirq, frmirq; +}; +/* default values for SSC configuration */ +// values of CON +#define IFX_SSC_DEF_IDLE_DATA 1 /* enable */ +#define IFX_SSC_DEF_BYTE_VALID_CTL 1 /* enable */ +#define IFX_SSC_DEF_DATA_WIDTH 32 /* bits */ +#define IFX_SSC_DEF_ABRT_ERR_DETECT 0 /* disable */ +#define IFX_SSC_DEF_RO_ERR_DETECT 1 /* enable */ +#define IFX_SSC_DEF_RU_ERR_DETECT 0 /* disable */ +#define IFX_SSC_DEF_TO_ERR_DETECT 0 /* disable */ +#define IFX_SSC_DEF_TU_ERR_DETECT 0 /* disable */ +#define IFX_SSC_DEF_LOOP_BACK 0 /* disable */ +#define IFX_SSC_DEF_ECHO_MODE 0 /* disable */ +#define IFX_SSC_DEF_CLOCK_POLARITY 0 /* low */ +#define IFX_SSC_DEF_CLOCK_PHASE 1 /* 0: shift on leading edge, latch on trailling edge, 1, otherwise */ +#define IFX_SSC_DEF_HEADING_CONTROL IFX_SSC_MSB_FIRST +#define IFX_SSC_DEF_MODE_RXTX IFX_SSC_MODE_RXTX +// other values +#define IFX_SSC_DEF_MASTERSLAVE IFX_SSC_MASTER_MODE /* master */ +#define IFX_SSC_DEF_BAUDRATE 1000000 +#define IFX_SSC_DEF_RMC 0x10 + +#define IFX_SSC_DEF_TXFIFO_FL 8 +#define IFX_SSC_DEF_RXFIFO_FL 1 + +#if 1 //TODO +#define IFX_SSC_DEF_GPO_CS 2 /* no chip select */ +#define IFX_SSC_DEF_GPO_INV 0 /* no chip select */ +#else +#error "what is ur Chip Select???" +#endif +#define IFX_SSC_DEF_SFCON 0 /* no serial framing */ +#if 0 +#define IFX_SSC_DEF_IRNEN IFX_SSC_T_BIT | /* enable all int's */\ + IFX_SSC_R_BIT | IFX_SSC_E_BIT | IFX_SSC_F_BIT +#endif +#define IFX_SSC_DEF_IRNEN IFX_SSC_T_BIT | /* enable all int's */\ + IFX_SSC_R_BIT | IFX_SSC_E_BIT +#endif /* __KERNEL__ */ + +// batch execution commands +#define IFX_SSC_BATCH_CMD_INIT 1 +#define IFX_SSC_BATCH_CMD_READ 2 +#define IFX_SSC_BATCH_CMD_WRITE 3 +#define IFX_SSC_BATCH_CMD_RD_WR 4 +#define IFX_SSC_BATCH_CMD_SET_BAUDRATE 5 +#define IFX_SSC_BATCH_CMD_SET_HWOPTS 6 +#define IFX_SSC_BATCH_CMD_SET_FRM 7 +#define IFX_SSC_BATCH_CMD_SET_GPO 8 +#define IFX_SSC_BATCH_CMD_FIFO_FLUSH 9 +//#define IFX_SSC_BATCH_CMD_ +//#define IFX_SSC_BATCH_CMD_ +#define IFX_SSC_BATCH_CMD_END_EXEC 0 + +/* Macros to configure SSC hardware */ +/* headingControl: */ +#define IFX_SSC_LSB_FIRST 0 +#define IFX_SSC_MSB_FIRST 1 +/* dataWidth: */ +#define IFX_SSC_MIN_DATA_WIDTH 2 +#define IFX_SSC_MAX_DATA_WIDTH 32 +/* master/slave mode select */ +#define IFX_SSC_MASTER_MODE 1 +#define IFX_SSC_SLAVE_MODE 0 +/* rx/tx mode */ +// ### TO DO: !!! ATTENTION! Hardware dependency => move to ifx_ssc_defines.h +#define IFX_SSC_MODE_RXTX 0 +#define IFX_SSC_MODE_RX 1 +#define IFX_SSC_MODE_TX 2 +#define IFX_SSC_MODE_OFF 3 +#define IFX_SSC_MODE_MASK IFX_SSC_MODE_RX | IFX_SSC_MODE_TX + +/* GPO values */ +#define IFX_SSC_MAX_GPO_OUT 7 + +#define IFX_SSC_RXREQ_BLOCK_SIZE 32768 + +/***********************/ +/* defines for ioctl's */ +/***********************/ +#define IFX_SSC_IOCTL_MAGIC 'S' +/* read out the statistics */ +#define IFX_SSC_STATS_READ _IOR(IFX_SSC_IOCTL_MAGIC, 1, struct ifx_ssc_statistics) +/* clear the statistics */ +#define IFX_SSC_STATS_RESET _IO(IFX_SSC_IOCTL_MAGIC, 2) +/* set the baudrate */ +#define IFX_SSC_BAUD_SET _IOW(IFX_SSC_IOCTL_MAGIC, 3, unsigned int) +/* get the current baudrate */ +#define IFX_SSC_BAUD_GET _IOR(IFX_SSC_IOCTL_MAGIC, 4, unsigned int) +/* set hardware options */ +#define IFX_SSC_HWOPTS_SET _IOW(IFX_SSC_IOCTL_MAGIC, 5, struct ifx_ssc_hwopts) +/* get the current hardware options */ +#define IFX_SSC_HWOPTS_GET _IOR(IFX_SSC_IOCTL_MAGIC, 6, struct ifx_ssc_hwopts) +/* set transmission mode */ +#define IFX_SSC_RXTX_MODE_SET _IOW(IFX_SSC_IOCTL_MAGIC, 7, unsigned int) +/* get the current transmission mode */ +#define IFX_SSC_RXTX_MODE_GET _IOR(IFX_SSC_IOCTL_MAGIC, 8, unsigned int) +/* abort transmission */ +#define IFX_SSC_ABORT _IO(IFX_SSC_IOCTL_MAGIC, 9) +#define IFX_SSC_FIFO_FLUSH _IO(IFX_SSC_IOCTL_MAGIC, 9) + +/* set general purpose outputs */ +#define IFX_SSC_GPO_OUT_SET _IOW(IFX_SSC_IOCTL_MAGIC, 32, unsigned int) +/* clear general purpose outputs */ +#define IFX_SSC_GPO_OUT_CLR _IOW(IFX_SSC_IOCTL_MAGIC, 33, unsigned int) +/* get general purpose outputs */ +#define IFX_SSC_GPO_OUT_GET _IOR(IFX_SSC_IOCTL_MAGIC, 34, unsigned int) + +/*** serial framing ***/ +/* get status of serial framing */ +#define IFX_SSC_FRM_STATUS_GET _IOR(IFX_SSC_IOCTL_MAGIC, 48, struct ifx_ssc_frm_status) +/* get counter reload values and control bits */ +#define IFX_SSC_FRM_CONTROL_GET _IOR(IFX_SSC_IOCTL_MAGIC, 49, struct ifx_ssc_frm_opts) +/* set counter reload values and control bits */ +#define IFX_SSC_FRM_CONTROL_SET _IOW(IFX_SSC_IOCTL_MAGIC, 50, struct ifx_ssc_frm_opts) + + +/*** batch execution ***/ +/* do batch execution */ +#define IFX_SSC_BATCH_EXEC _IOW(IFX_SSC_IOCTL_MAGIC, 64, struct ifx_ssc_batch_list) + + +#ifdef __KERNEL__ +// routines from ifx_ssc.c +// ### TO DO +/* kernel interface for read and write */ +ssize_t ifx_ssc_kread(int, char *, size_t); +ssize_t ifx_ssc_kwrite(int, const char *, size_t); + +#ifdef CONFIG_IFX_VP_KERNEL_TEST +void ifx_ssc_tc(void); +#endif // CONFIG_IFX_VP_KERNEL_TEST + +#endif //__KERNEL__ +#endif // __IFX_SSC_H + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/ifx_ssc_defines.h b/target/linux/amazon/files/include/asm-mips/amazon/ifx_ssc_defines.h new file mode 100644 index 000000000..46157dcbd --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/ifx_ssc_defines.h @@ -0,0 +1,552 @@ +#ifndef IFX_SSC_DEFINES_H +#define IFX_SSC_DEFINES_H + +#include "ifx_peripheral_definitions.h" + +/* maximum SSC FIFO size */ +#define IFX_SSC_MAX_FIFO_SIZE 32 + +/* register map of SSC */ + +/* address of the Clock Control Register of the SSC */ +#define IFX_SSC_CLC 0x00000000 +/* IFX_SSC_CLC register is significant in bits 23 downto 8 and in bits 5, 3, 2, 0 + bit 1 is hardware modified*/ +#define IFX_SSC_CLC_readmask 0x00FFFFEF +#define IFX_SSC_CLC_writemask 0x00FFFF3D +#define IFX_SSC_CLC_hwmask 0x00000002 +#define IFX_SSC_CLC_dontcare (IFX_SSC_CLC_readmask & IFX_SSC_CLC_writemask & ~IFX_SSC_CLC_hwmask) + +/* address of Port Input Select Register of the SSC */ +#define IFX_SSC_PISEL 0x00000004 +/* IFX_SSC_PISEL register is significant in lowest three bits only */ +#define IFX_SSC_PISEL_readmask 0x00000007 +#define IFX_SSC_PISEL_writemask 0x00000007 +#define IFX_SSC_PISEL_hwmask 0x00000000 +#define IFX_SSC_PISEL_dontcare (IFX_SSC_PISEL_readmask & IFX_SSC_PISEL_writemask & ~IFX_SSC_PISEL_hwmask) + +/* address of Identification Register of the SSC */ +#define IFX_SSC_ID 0x00000008 +/* IFX_SSC_ID register is significant in no bit */ +#define IFX_SSC_ID_readmask 0x0000FF3F +#define IFX_SSC_ID_writemask 0x00000000 +#define IFX_SSC_ID_hwmask 0x00000000 +#define IFX_SSC_ID_dontcare (IFX_SSC_ID_readmask & IFX_SSC_ID_writemask & ~IFX_SSC_ID_hwmask) + +/* address of the Control Register of the SSC */ +#define IFX_SSC_CON 0x00000010 +/* IFX_SSC_CON register is significant in bits 23:22, 20:16 and 12:0 */ +#define IFX_SSC_CON_readmask 0x01DF1FFF +#define IFX_SSC_CON_writemask 0x01DF1FFF +#define IFX_SSC_CON_hwmask 0x00000000 +#define IFX_SSC_CON_dontcare (IFX_SSC_CON_readmask & IFX_SSC_CON_writemask & ~IFX_SSC_CON_hwmask) + + +/* address of the Status Register of the SSC */ +#define IFX_SSC_STATE 0x00000014 +/* IFX_SSC_STATE register is readable in bits 30:28, 26:24, 20:16, 12:7 and 2:0 + all bits except 1:0 are hardware modified */ +#define IFX_SSC_STATE_readmask 0x771F3F87 +#define IFX_SSC_STATE_writemask 0x00000000 +#define IFX_SSC_STATE_hwmask 0x771F3F84 +#define IFX_SSC_STATE_dontcare (IFX_SSC_STATE_readmask & IFX_SSC_STATE_writemask & ~IFX_SSC_STATE_hwmask) + +/* address of the Write Hardware Modified Control Register Bits of the SSC */ +#define IFX_SSC_WHBSTATE 0x00000018 +/* IFX_SSC_WHBSTATE register is write only */ +#define IFX_SSC_WHBSTATE_readmask 0x00000000 +#define IFX_SSC_WHBSTATE_writemask 0x0000FFFF +#define IFX_SSC_WHBSTATE_hwmask 0x00000000 +#define IFX_SSC_WHBSTATE_dontcare (IFX_SSC_WHBSTATE_readmask & IFX_SSC_WHBSTATE_writemask & ~IFX_SSC_WHBSTATE_hwmask) + +/* address of the Baudrate Timer Reload Register of the SSC */ +#define IFX_SSC_BR 0x00000040 +/* IFX_SSC_BR register is significant in bit 15 downto 0*/ +#define IFX_SSC_BR_readmask 0x0000FFFF +#define IFX_SSC_BR_writemask 0x0000FFFF +#define IFX_SSC_BR_hwmask 0x00000000 +#define IFX_SSC_BR_dontcare (IFX_SSC_BR_readmask & IFX_SSC_BR_writemask & ~IFX_SSC_BR_hwmask) + +/* address of the Baudrate Timer Status Register of the SSC */ +#define IFX_SSC_BRSTAT 0x00000044 +/* IFX_SSC_BRSTAT register is significant in bit 15 downto 0*/ +#define IFX_SSC_BRSTAT_readmask 0x0000FFFF +#define IFX_SSC_BRSTAT_writemask 0x00000000 +#define IFX_SSC_BRSTAT_hwmask 0x0000FFFF +#define IFX_SSC_BRSTAT_dontcare (IFX_SSC_BRSTAT_readmask & IFX_SSC_BRSTAT_writemask & ~IFX_SSC_BRSTAT_hwmask) + +/* address of the Transmitter Buffer Register of the SSC */ +#define IFX_SSC_TB 0x00000020 +/* IFX_SSC_TB register is significant in bit 31 downto 0*/ +#define IFX_SSC_TB_readmask 0xFFFFFFFF +#define IFX_SSC_TB_writemask 0xFFFFFFFF +#define IFX_SSC_TB_hwmask 0x00000000 +#define IFX_SSC_TB_dontcare (IFX_SSC_TB_readmask & IFX_SSC_TB_writemask & ~IFX_SSC_TB_hwmask) + +/* address of the Reciver Buffer Register of the SSC */ +#define IFX_SSC_RB 0x00000024 +/* IFX_SSC_RB register is significant in no bits*/ +#define IFX_SSC_RB_readmask 0xFFFFFFFF +#define IFX_SSC_RB_writemask 0x00000000 +#define IFX_SSC_RB_hwmask 0xFFFFFFFF +#define IFX_SSC_RB_dontcare (IFX_SSC_RB_readmask & IFX_SSC_RB_writemask & ~IFX_SSC_RB_hwmask) + +/* address of the Receive FIFO Control Register of the SSC */ +#define IFX_SSC_RXFCON 0x00000030 +/* IFX_SSC_RXFCON register is significant in bit 13 downto 8 and bit 1 downto 0 */ +#define IFX_SSC_RXFCON_readmask 0x00003F03 +#define IFX_SSC_RXFCON_writemask 0x00003F03 +#define IFX_SSC_RXFCON_hwmask 0x00000000 +#define IFX_SSC_RXFCON_dontcare (IFX_SSC_RXFCON_readmask & IFX_SSC_RXFCON_writemask & ~IFX_SSC_RXFCON_hwmask) + +/* address of the Transmit FIFO Control Register of the SSC */ +#define IFX_SSC_TXFCON 0x00000034 +/* IFX_SSC_TXFCON register is significant in bit 13 downto 8 and bit 1 downto 0 */ +#define IFX_SSC_TXFCON_readmask 0x00003F03 +#define IFX_SSC_TXFCON_writemask 0x00003F03 +#define IFX_SSC_TXFCON_hwmask 0x00000000 +#define IFX_SSC_TXFCON_dontcare (IFX_SSC_TXFCON_readmask & IFX_SSC_TXFCON_writemask & ~IFX_SSC_TXFCON_hwmask) + +/* address of the FIFO Status Register of the SSC */ +#define IFX_SSC_FSTAT 0x00000038 +/* IFX_SSC_FSTAT register is significant in no bit*/ +#define IFX_SSC_FSTAT_readmask 0x00003F3F +#define IFX_SSC_FSTAT_writemask 0x00000000 +#define IFX_SSC_FSTAT_hwmask 0x00003F3F +#define IFX_SSC_FSTAT_dontcare (IFX_SSC_FSTAT_readmask & IFX_SSC_FSTAT_writemask & ~IFX_SSC_FSTAT_hwmask) + +/* address of the Data Frame Control register of the SSC */ +#define IFX_SSC_SFCON 0x00000060 +#define IFX_SSC_SFCON_readmask 0xFFDFFFFD +#define IFX_SSC_SFCON_writemask 0xFFDFFFFD +#define IFX_SSC_SFCON_hwmask 0x00000000 +#define IFX_SSC_SFCON_dontcare (IFX_SSC_SFCON_readmask & IFX_SSC_SFCON_writemask & ~IFX_SSC_SFCON_hwmask) + +/* address of the Data Frame Status register of the SSC */ +#define IFX_SSC_SFSTAT 0x00000064 +#define IFX_SSC_SFSTAT_readmask 0xFFC0FFF3 +#define IFX_SSC_SFSTAT_writemask 0x00000000 +#define IFX_SSC_SFSTAT_hwmask 0xFFC0FFF3 +#define IFX_SSC_SFSTAT_dontcare (IFX_SSC_SFSTAT_readmask & IFX_SSC_SFSTAT_writemask & ~IFX_SSC_SFSTAT_hwmask) + +/* address of the General Purpose Output Control register of the SSC */ +#define IFX_SSC_GPOCON 0x00000070 +#define IFX_SSC_GPOCON_readmask 0x0000FFFF +#define IFX_SSC_GPOCON_writemask 0x0000FFFF +#define IFX_SSC_GPOCON_hwmask 0x00000000 +#define IFX_SSC_GPOCON_dontcare (IFX_SSC_GPOCON_readmask & IFX_SSC_GPOCON_writemask & ~IFX_SSC_GPOCON_hwmask) + +/* address of the General Purpose Output Status register of the SSC */ +#define IFX_SSC_GPOSTAT 0x00000074 +#define IFX_SSC_GPOSTAT_readmask 0x000000FF +#define IFX_SSC_GPOSTAT_writemask 0x00000000 +#define IFX_SSC_GPOSTAT_hwmask 0x00000000 +#define IFX_SSC_GPOSTAT_dontcare (IFX_SSC_GPOSTAT_readmask & IFX_SSC_GPOSTAT_writemask & ~IFX_SSC_GPOSTAT_hwmask) + +/* address of the Force GPO Status register of the SSC */ +#define IFX_SSC_WHBGPOSTAT 0x00000078 +#define IFX_SSC_WHBGPOSTAT_readmask 0x00000000 +#define IFX_SSC_WHBGPOSTAT_writemask 0x0000FFFF +#define IFX_SSC_WHBGPOSTAT_hwmask 0x00000000 +#define IFX_SSC_WHBGPOSTAT_dontcare (IFX_SSC_WHBGPOSTAT_readmask & IFX_SSC_WHBGPOSTAT_writemask & ~IFX_SSC_WHBGPOSTAT_hwmask) + +/* address of the Receive Request Register of the SSC */ +#define IFX_SSC_RXREQ 0x00000080 +#define IFX_SSC_RXREQ_readmask 0x0000FFFF +#define IFX_SSC_RXREQ_writemask 0x0000FFFF +#define IFX_SSC_RXREQ_hwmask 0x00000000 +#define IFX_SSC_RXREQ_dontcare (IFX_SSC_RXREQ_readmask & IFX_SSC_RXREQ_writemask & ~IFX_SSC_RXREQ_hwmask) + +/* address of the Receive Count Register of the SSC */ +#define IFX_SSC_RXCNT 0x00000084 +#define IFX_SSC_RXCNT_readmask 0x0000FFFF +#define IFX_SSC_RXCNT_writemask 0x00000000 +#define IFX_SSC_RXCNT_hwmask 0x0000FFFF +#define IFX_SSC_RXCNT_dontcare (IFX_SSC_RXCNT_readmask & IFX_SSC_RXCNT_writemask & ~IFX_SSC_RXCNT_hwmask) + +/* address of the DMA Configuration Register of the SSC */ +#define IFX_SSC_DMACON 0x000000EC +#define IFX_SSC_DMACON_readmask 0x0000FFFF +#define IFX_SSC_DMACON_writemask 0x00000000 +#define IFX_SSC_DMACON_hwmask 0x0000FFFF +#define IFX_SSC_DMACON_dontcare (IFX_SSC_DMACON_readmask & IFX_SSC_DMACON_writemask & ~IFX_SSC_DMACON_hwmask) + +//------------------------------------------------------ +// interrupt register for enabling interrupts, mask register of irq_reg +#define IFX_SSC_IRN_EN 0xF4 +// read/write +#define IFX_SSC_IRN_EN_readmask 0x0000000F +#define IFX_SSC_IRN_EN_writemask 0x0000000F +#define IFX_SSC_IRN_EN_hwmask 0x00000000 +#define IFX_SSC_IRN_EN_dontcare (IFX_SSC_IRN_EN_readmask & IFX_SSC_IRN_EN_writemask & ~IFX_SSC_IRN_EN_hwmask) + +// interrupt register for accessing interrupts +#define IFX_SSC_IRN_CR 0xF8 +// read/write +#define IFX_SSC_IRN_CR_readmask 0x0000000F +#define IFX_SSC_IRN_CR_writemask 0x0000000F +#define IFX_SSC_IRN_CR_hwmask 0x0000000F +#define IFX_SSC_IRN_CR_dontcare (IFX_SSC_IRN_CR_readmask & IFX_SSC_IRN_CR_writemask & ~IFX_SSC_IRN_CR_hwmask) + +// interrupt register for stimulating interrupts +#define IFX_SSC_IRN_ICR 0xFC +// read/write +#define IFX_SSC_IRN_ICR_readmask 0x0000000F +#define IFX_SSC_IRN_ICR_writemask 0x0000000F +#define IFX_SSC_IRN_ICR_hwmask 0x00000000 +#define IFX_SSC_IRN_ICR_dontcare (IFX_SSC_IRN_ICR_readmask & IFX_SSC_IRN_ICR_writemask & ~IFX_SSC_IRN_ICR_hwmask) + +//--------------------------------------------------------------------- +// Number of IRQs and bitposition of IRQ +#define IFX_SSC_NUM_IRQ 4 +#define IFX_SSC_T_BIT 0x00000001 +#define IFX_SSC_R_BIT 0x00000002 +#define IFX_SSC_E_BIT 0x00000004 +#define IFX_SSC_F_BIT 0x00000008 + +/* bit masks for SSC registers */ + +/* ID register */ +#define IFX_SSC_PERID_REV_MASK 0x0000001F +#define IFX_SSC_PERID_CFG_MASK 0x00000020 +#define IFX_SSC_PERID_ID_MASK 0x0000FF00 +#define IFX_SSC_PERID_REV_OFFSET 0 +#define IFX_SSC_PERID_CFG_OFFSET 5 +#define IFX_SSC_PERID_ID_OFFSET 8 +#define IFX_SSC_PERID_ID 0x45 +#define IFX_SSC_PERID_DMA_ON 0x00000020 +#define IFX_SSC_PERID_RXFS_MASK 0x003F0000 +#define IFX_SSC_PERID_RXFS_OFFSET 16 +#define IFX_SSC_PERID_TXFS_MASK 0x3F000000 +#define IFX_SSC_PERID_TXFS_OFFSET 24 + +/* PISEL register */ +#define IFX_SSC_PISEL_MASTER_IN_A 0x0000 +#define IFX_SSC_PISEL_MASTER_IN_B 0x0001 +#define IFX_SSC_PISEL_SLAVE_IN_A 0x0000 +#define IFX_SSC_PISEL_SLAVE_IN_B 0x0002 +#define IFX_SSC_PISEL_CLOCK_IN_A 0x0000 +#define IFX_SSC_PISEL_CLOCK_IN_B 0x0004 + + +/* IFX_SSC_CON register */ +#define IFX_SSC_CON_ECHO_MODE_ON 0x01000000 +#define IFX_SSC_CON_ECHO_MODE_OFF 0x00000000 +#define IFX_SSC_CON_IDLE_HIGH 0x00800000 +#define IFX_SSC_CON_IDLE_LOW 0x00000000 +#define IFX_SSC_CON_ENABLE_BYTE_VALID 0x00400000 +#define IFX_SSC_CON_DISABLE_BYTE_VALID 0x00000000 +#define IFX_SSC_CON_DATA_WIDTH_OFFSET 16 +#define IFX_SSC_CON_DATA_WIDTH_MASK 0x001F0000 +#define IFX_SSC_ENCODE_DATA_WIDTH(width) (((width - 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET) & IFX_SSC_CON_DATA_WIDTH_MASK) + +#define IFX_SSC_CON_RESET_ON_BAUDERR 0x00002000 +#define IFX_SSC_CON_GO_ON_ON_BAUDERR 0x00000000 + +#define IFX_SSC_CON_RX_UFL_CHECK 0x00001000 +#define IFX_SSC_CON_RX_UFL_IGNORE 0x00000000 +#define IFX_SSC_CON_TX_UFL_CHECK 0x00000800 +#define IFX_SSC_CON_TX_UFL_IGNORE 0x00000000 +#define IFX_SSC_CON_ABORT_ERR_CHECK 0x00000400 +#define IFX_SSC_CON_ABORT_ERR_IGNORE 0x00000000 +#define IFX_SSC_CON_RX_OFL_CHECK 0x00000200 +#define IFX_SSC_CON_RX_OFL_IGNORE 0x00000000 +#define IFX_SSC_CON_TX_OFL_CHECK 0x00000100 +#define IFX_SSC_CON_TX_OFL_IGNORE 0x00000000 +#define IFX_SSC_CON_ALL_ERR_CHECK 0x00001F00 +#define IFX_SSC_CON_ALL_ERR_IGNORE 0x00000000 + +#define IFX_SSC_CON_LOOPBACK_MODE 0x00000080 +#define IFX_SSC_CON_NO_LOOPBACK 0x00000000 +#define IFX_SSC_CON_HALF_DUPLEX 0x00000080 +#define IFX_SSC_CON_FULL_DUPLEX 0x00000000 +#define IFX_SSC_CON_CLOCK_FALL 0x00000040 +#define IFX_SSC_CON_CLOCK_RISE 0x00000000 +#define IFX_SSC_CON_SHIFT_THEN_LATCH 0x00000000 +#define IFX_SSC_CON_LATCH_THEN_SHIFT 0x00000020 +#define IFX_SSC_CON_MSB_FIRST 0x00000010 +#define IFX_SSC_CON_LSB_FIRST 0x00000000 +#define IFX_SSC_CON_ENABLE_CSB 0x00000008 +#define IFX_SSC_CON_DISABLE_CSB 0x00000000 +#define IFX_SSC_CON_INVERT_CSB 0x00000004 +#define IFX_SSC_CON_TRUE_CSB 0x00000000 +#define IFX_SSC_CON_RX_OFF 0x00000002 +#define IFX_SSC_CON_RX_ON 0x00000000 +#define IFX_SSC_CON_TX_OFF 0x00000001 +#define IFX_SSC_CON_TX_ON 0x00000000 + + +/* IFX_SSC_STATE register */ +#define IFX_SSC_STATE_RX_BYTE_VALID_OFFSET 28 +#define IFX_SSC_STATE_RX_BYTE_VALID_MASK 0x70000000 +#define IFX_SSC_DECODE_RX_BYTE_VALID(con_state) ((con_state & IFX_SSC_STATE_RX_BYTE_VALID_MASK) >> IFX_SSC_STATE_RX_BYTE_VALID_OFFSET) +#define IFX_SSC_STATE_TX_BYTE_VALID_OFFSET 24 +#define IFX_SSC_STATE_TX_BYTE_VALID_MASK 0x07000000 +#define IFX_SSC_DECODE_TX_BYTE_VALID(con_state) ((con_state & IFX_SSC_STATE_TX_BYTE_VALID_MASK) >> IFX_SSC_STATE_TX_BYTE_VALID_OFFSET) +#define IFX_SSC_STATE_BIT_COUNT_OFFSET 16 +#define IFX_SSC_STATE_BIT_COUNT_MASK 0x001F0000 +#define IFX_SSC_DECODE_DATA_WIDTH(con_state) (((con_state & IFX_SSC_STATE_BIT_COUNT_MASK) >> IFX_SSC_STATE_BIT_COUNT_OFFSET) + 1) +#define IFX_SSC_STATE_BUSY 0x00002000 +#define IFX_SSC_STATE_RX_UFL 0x00001000 +#define IFX_SSC_STATE_TX_UFL 0x00000800 +#define IFX_SSC_STATE_ABORT_ERR 0x00000400 +#define IFX_SSC_STATE_RX_OFL 0x00000200 +#define IFX_SSC_STATE_TX_OFL 0x00000100 +#define IFX_SSC_STATE_MODE_ERR 0x00000080 +#define IFX_SSC_STATE_SLAVE_IS_SELECTED 0x00000004 +#define IFX_SSC_STATE_IS_MASTER 0x00000002 +#define IFX_SSC_STATE_IS_ENABLED 0x00000001 + +/* WHBSTATE register */ +#define IFX_SSC_WHBSTATE_DISABLE_SSC 0x0001 +#define IFX_SSC_WHBSTATE_CONFIGURATION_MODE 0x0001 +#define IFX_SSC_WHBSTATE_CLR_ENABLE 0x0001 + +#define IFX_SSC_WHBSTATE_ENABLE_SSC 0x0002 +#define IFX_SSC_WHBSTATE_RUN_MODE 0x0002 +#define IFX_SSC_WHBSTATE_SET_ENABLE 0x0002 + +#define IFX_SSC_WHBSTATE_SLAVE_MODE 0x0004 +#define IFX_SSC_WHBSTATE_CLR_MASTER_SELECT 0x0004 + +#define IFX_SSC_WHBSTATE_MASTER_MODE 0x0008 +#define IFX_SSC_WHBSTATE_SET_MASTER_SELECT 0x0008 + +#define IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR 0x0010 +#define IFX_SSC_WHBSTATE_SET_RX_UFL_ERROR 0x0020 + +#define IFX_SSC_WHBSTATE_CLR_MODE_ERROR 0x0040 +#define IFX_SSC_WHBSTATE_SET_MODE_ERROR 0x0080 + +#define IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR 0x0100 +#define IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR 0x0200 +#define IFX_SSC_WHBSTATE_CLR_ABORT_ERROR 0x0400 +#define IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR 0x0800 +#define IFX_SSC_WHBSTATE_SET_TX_OFL_ERROR 0x1000 +#define IFX_SSC_WHBSTATE_SET_RX_OFL_ERROR 0x2000 +#define IFX_SSC_WHBSTATE_SET_ABORT_ERROR 0x4000 +#define IFX_SSC_WHBSTATE_SET_TX_UFL_ERROR 0x8000 +#define IFX_SSC_WHBSTATE_CLR_ALL_ERROR 0x0F50 +#define IFX_SSC_WHBSTATE_SET_ALL_ERROR 0xF0A0 + +/* BR register */ +#define IFX_SSC_BR_BAUDRATE_OFFSET 0 +#define IFX_SSC_BR_BAUDRATE_MASK 0xFFFF + +/* BR_STAT register */ +#define IFX_SSC_BRSTAT_BAUDTIMER_OFFSET 0 +#define IFX_SSC_BRSTAT_BAUDTIMER_MASK 0xFFFF + +/* TB register */ +#define IFX_SSC_TB_DATA_OFFSET 0 +#define IFX_SSC_TB_DATA_MASK 0xFFFFFFFF + +/* RB register */ +#define IFX_SSC_RB_DATA_OFFSET 0 +#define IFX_SSC_RB_DATA_MASK 0xFFFFFFFF + + +/* RXFCON and TXFCON registers */ +#define IFX_SSC_XFCON_FIFO_DISABLE 0x0000 +#define IFX_SSC_XFCON_FIFO_ENABLE 0x0001 +#define IFX_SSC_XFCON_FIFO_FLUSH 0x0002 +#define IFX_SSC_XFCON_ITL_MASK 0x00003F00 +#define IFX_SSC_XFCON_ITL_OFFSET 8 + +/* FSTAT register */ +#define IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET 0 +#define IFX_SSC_FSTAT_RECEIVED_WORDS_MASK 0x003F +#define IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET 8 +#define IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK 0x3F00 + +/* GPOCON register */ +#define IFX_SSC_GPOCON_INVOUT0_POS 0 +#define IFX_SSC_GPOCON_INV_OUT0 0x00000001 +#define IFX_SSC_GPOCON_TRUE_OUT0 0x00000000 +#define IFX_SSC_GPOCON_INVOUT1_POS 1 +#define IFX_SSC_GPOCON_INV_OUT1 0x00000002 +#define IFX_SSC_GPOCON_TRUE_OUT1 0x00000000 +#define IFX_SSC_GPOCON_INVOUT2_POS 2 +#define IFX_SSC_GPOCON_INV_OUT2 0x00000003 +#define IFX_SSC_GPOCON_TRUE_OUT2 0x00000000 +#define IFX_SSC_GPOCON_INVOUT3_POS 3 +#define IFX_SSC_GPOCON_INV_OUT3 0x00000008 +#define IFX_SSC_GPOCON_TRUE_OUT3 0x00000000 +#define IFX_SSC_GPOCON_INVOUT4_POS 4 +#define IFX_SSC_GPOCON_INV_OUT4 0x00000010 +#define IFX_SSC_GPOCON_TRUE_OUT4 0x00000000 +#define IFX_SSC_GPOCON_INVOUT5_POS 5 +#define IFX_SSC_GPOCON_INV_OUT5 0x00000020 +#define IFX_SSC_GPOCON_TRUE_OUT5 0x00000000 +#define IFX_SSC_GPOCON_INVOUT6_POS 6 +#define IFX_SSC_GPOCON_INV_OUT6 0x00000040 +#define IFX_SSC_GPOCON_TRUE_OUT6 0x00000000 +#define IFX_SSC_GPOCON_INVOUT7_POS 7 +#define IFX_SSC_GPOCON_INV_OUT7 0x00000080 +#define IFX_SSC_GPOCON_TRUE_OUT7 0x00000000 +#define IFX_SSC_GPOCON_INV_OUT_ALL 0x000000FF +#define IFX_SSC_GPOCON_TRUE_OUT_ALL 0x00000000 + +#define IFX_SSC_GPOCON_ISCSB0_POS 8 +#define IFX_SSC_GPOCON_IS_CSB0 0x00000100 +#define IFX_SSC_GPOCON_IS_GPO0 0x00000000 +#define IFX_SSC_GPOCON_ISCSB1_POS 9 +#define IFX_SSC_GPOCON_IS_CSB1 0x00000200 +#define IFX_SSC_GPOCON_IS_GPO1 0x00000000 +#define IFX_SSC_GPOCON_ISCSB2_POS 10 +#define IFX_SSC_GPOCON_IS_CSB2 0x00000400 +#define IFX_SSC_GPOCON_IS_GPO2 0x00000000 +#define IFX_SSC_GPOCON_ISCSB3_POS 11 +#define IFX_SSC_GPOCON_IS_CSB3 0x00000800 +#define IFX_SSC_GPOCON_IS_GPO3 0x00000000 +#define IFX_SSC_GPOCON_ISCSB4_POS 12 +#define IFX_SSC_GPOCON_IS_CSB4 0x00001000 +#define IFX_SSC_GPOCON_IS_GPO4 0x00000000 +#define IFX_SSC_GPOCON_ISCSB5_POS 13 +#define IFX_SSC_GPOCON_IS_CSB5 0x00002000 +#define IFX_SSC_GPOCON_IS_GPO5 0x00000000 +#define IFX_SSC_GPOCON_ISCSB6_POS 14 +#define IFX_SSC_GPOCON_IS_CSB6 0x00004000 +#define IFX_SSC_GPOCON_IS_GPO6 0x00000000 +#define IFX_SSC_GPOCON_ISCSB7_POS 15 +#define IFX_SSC_GPOCON_IS_CSB7 0x00008000 +#define IFX_SSC_GPOCON_IS_GPO7 0x00000000 +#define IFX_SSC_GPOCON_IS_CSB_ALL 0x0000FF00 +#define IFX_SSC_GPOCON_IS_GPO_ALL 0x00000000 + +/* GPOSTAT register */ +#define IFX_SSC_GPOSTAT_OUT0 0x00000001 +#define IFX_SSC_GPOSTAT_OUT1 0x00000002 +#define IFX_SSC_GPOSTAT_OUT2 0x00000004 +#define IFX_SSC_GPOSTAT_OUT3 0x00000008 +#define IFX_SSC_GPOSTAT_OUT4 0x00000010 +#define IFX_SSC_GPOSTAT_OUT5 0x00000020 +#define IFX_SSC_GPOSTAT_OUT6 0x00000040 +#define IFX_SSC_GPOSTAT_OUT7 0x00000080 +#define IFX_SSC_GPOSTAT_OUT_ALL 0x000000FF + +/* WHBGPOSTAT register */ +#define IFX_SSC_WHBGPOSTAT_CLROUT0_POS 0 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT0 0x00000001 +#define IFX_SSC_WHBGPOSTAT_CLROUT1_POS 1 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT1 0x00000002 +#define IFX_SSC_WHBGPOSTAT_CLROUT2_POS 2 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT2 0x00000004 +#define IFX_SSC_WHBGPOSTAT_CLROUT3_POS 3 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT3 0x00000008 +#define IFX_SSC_WHBGPOSTAT_CLROUT4_POS 4 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT4 0x00000010 +#define IFX_SSC_WHBGPOSTAT_CLROUT5_POS 5 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT5 0x00000020 +#define IFX_SSC_WHBGPOSTAT_CLROUT6_POS 6 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT6 0x00000040 +#define IFX_SSC_WHBGPOSTAT_CLROUT7_POS 7 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT7 0x00000080 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT_ALL 0x000000FF + +#define IFX_SSC_WHBGPOSTAT_OUT0_POS 0 +#define IFX_SSC_WHBGPOSTAT_OUT1_POS 1 +#define IFX_SSC_WHBGPOSTAT_OUT2_POS 2 +#define IFX_SSC_WHBGPOSTAT_OUT3_POS 3 +#define IFX_SSC_WHBGPOSTAT_OUT4_POS 4 +#define IFX_SSC_WHBGPOSTAT_OUT5_POS 5 +#define IFX_SSC_WHBGPOSTAT_OUT6_POS 6 +#define IFX_SSC_WHBGPOSTAT_OUT7_POS 7 + + +#define IFX_SSC_WHBGPOSTAT_SETOUT0_POS 8 +#define IFX_SSC_WHBGPOSTAT_SET_OUT0 0x00000100 +#define IFX_SSC_WHBGPOSTAT_SETOUT1_POS 9 +#define IFX_SSC_WHBGPOSTAT_SET_OUT1 0x00000200 +#define IFX_SSC_WHBGPOSTAT_SETOUT2_POS 10 +#define IFX_SSC_WHBGPOSTAT_SET_OUT2 0x00000400 +#define IFX_SSC_WHBGPOSTAT_SETOUT3_POS 11 +#define IFX_SSC_WHBGPOSTAT_SET_OUT3 0x00000800 +#define IFX_SSC_WHBGPOSTAT_SETOUT4_POS 12 +#define IFX_SSC_WHBGPOSTAT_SET_OUT4 0x00001000 +#define IFX_SSC_WHBGPOSTAT_SETOUT5_POS 13 +#define IFX_SSC_WHBGPOSTAT_SET_OUT5 0x00002000 +#define IFX_SSC_WHBGPOSTAT_SETOUT6_POS 14 +#define IFX_SSC_WHBGPOSTAT_SET_OUT6 0x00004000 +#define IFX_SSC_WHBGPOSTAT_SETOUT7_POS 15 +#define IFX_SSC_WHBGPOSTAT_SET_OUT7 0x00008000 +#define IFX_SSC_WHBGPOSTAT_SET_OUT_ALL 0x0000FF00 + +/* SFCON register */ +#define IFX_SSC_SFCON_SF_ENABLE 0x00000001 +#define IFX_SSC_SFCON_SF_DISABLE 0x00000000 +#define IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE 0x00000004 +#define IFX_SSC_SFCON_FIR_DISABLE_BEFORE_PAUSE 0x00000000 +#define IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE 0x00000008 +#define IFX_SSC_SFCON_FIR_DISABLE_AFTER_PAUSE 0x00000000 +#define IFX_SSC_SFCON_DATA_LENGTH_MASK 0x0000FFF0 +#define IFX_SSC_SFCON_DATA_LENGTH_OFFSET 4 +#define IFX_SSC_SFCON_PAUSE_DATA_MASK 0x00030000 +#define IFX_SSC_SFCON_PAUSE_DATA_OFFSET 16 +#define IFX_SSC_SFCON_PAUSE_DATA_0 0x00000000 +#define IFX_SSC_SFCON_PAUSE_DATA_1 0x00010000 +#define IFX_SSC_SFCON_PAUSE_DATA_IDLE 0x00020000 +#define IFX_SSC_SFCON_PAUSE_CLOCK_MASK 0x000C0000 +#define IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET 18 +#define IFX_SSC_SFCON_PAUSE_CLOCK_0 0x00000000 +#define IFX_SSC_SFCON_PAUSE_CLOCK_1 0x00040000 +#define IFX_SSC_SFCON_PAUSE_CLOCK_IDLE 0x00080000 +#define IFX_SSC_SFCON_PAUSE_CLOCK_RUN 0x000C0000 +#define IFX_SSC_SFCON_STOP_AFTER_PAUSE 0x00100000 +#define IFX_SSC_SFCON_CONTINUE_AFTER_PAUSE 0x00000000 +#define IFX_SSC_SFCON_PAUSE_LENGTH_MASK 0xFFC00000 +#define IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET 22 +#define IFX_SSC_SFCON_DATA_LENGTH_MAX 4096 +#define IFX_SSC_SFCON_PAUSE_LENGTH_MAX 1024 + +#define IFX_SSC_SFCON_EXTRACT_DATA_LENGTH(sfcon) ((sfcon & IFX_SSC_SFCON_DATA_LENGTH_MASK) >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET) +#define IFX_SSC_SFCON_EXTRACT_PAUSE_LENGTH(sfcon) ((sfcon & IFX_SSC_SFCON_PAUSE_LENGTH_MASK) >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET) +#define IFX_SSC_SFCON_SET_DATA_LENGTH(value) ((value << IFX_SSC_SFCON_DATA_LENGTH_OFFSET) & IFX_SSC_SFCON_DATA_LENGTH_MASK) +#define IFX_SSC_SFCON_SET_PAUSE_LENGTH(value) ((value << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET) & IFX_SSC_SFCON_PAUSE_LENGTH_MASK) + +/* SFSTAT register */ +#define IFX_SSC_SFSTAT_IN_DATA 0x00000001 +#define IFX_SSC_SFSTAT_IN_PAUSE 0x00000002 +#define IFX_SSC_SFSTAT_DATA_COUNT_MASK 0x0000FFF0 +#define IFX_SSC_SFSTAT_DATA_COUNT_OFFSET 4 +#define IFX_SSC_SFSTAT_PAUSE_COUNT_MASK 0xFFF00000 +#define IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET 20 + +#define IFX_SSC_SFSTAT_EXTRACT_DATA_COUNT(sfstat) ((sfstat & IFX_SSC_SFSTAT_DATA_COUNT_MASK) >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET) +#define IFX_SSC_SFSTAT_EXTRACT_PAUSE_COUNT(sfstat) ((sfstat & IFX_SSC_SFSTAT_PAUSE_COUNT_MASK) >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET) + +/* RXREQ register */ +#define IFX_SSC_RXREQ_RXCOUNT_MASK 0x0000FFFF +#define IFX_SSC_RXREQ_RXCOUNT_OFFSET 0 + +/* RXCNT register */ +#define IFX_SSC_RXCNT_TODO_MASK 0x0000FFFF +#define IFX_SSC_RXCNT_TODO_OFFSET 0 + +/* DMACON register */ +#define IFX_SSC_DMACON_RXON 0x00000001 +#define IFX_SSC_DMACON_RXOFF 0x00000000 +#define IFX_SSC_DMACON_TXON 0x00000002 +#define IFX_SSC_DMACON_TXOFF 0x00000000 +#define IFX_SSC_DMACON_DMAON 0x00000003 +#define IFX_SSC_DMACON_DMAOFF 0x00000000 +#define IFX_SSC_DMACON_CLASS_MASK 0x0000000C +#define IFX_SSC_DMACON_CLASS_OFFSET 2 + +/* register access macros */ +#define ifx_ssc_fstat_received_words(status) (status & 0x003F) +#define ifx_ssc_fstat_words_to_transmit(status) ((status & 0x3F00) >> 8) + +#define ifx_ssc_change_status(data, addr) WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_WHBSTATE)) +#define ifx_ssc_set_config(data, addr) WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_CON)) +#define ifx_ssc_get_config(addr) READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_CON)) +#define ifx_ssc_get_status(addr) READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_STATE)) +#define ifx_ssc_receive(addr) READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_RB)) +#define ifx_ssc_transmit(data, addr) WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_TB)) +#define ifx_ssc_fifo_status(addr) READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_FSTAT)) +#define ifx_ssc_set_baudrate(data, addr) WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_BR)) + +#define ifx_ssc_extract_rx_fifo_size(id) ((id & IFX_SSC_PERID_RXFS_MASK) >> IFX_SSC_PERID_RXFS_OFFSET) +#define ifx_ssc_extract_tx_fifo_size(id) ((id & IFX_SSC_PERID_TXFS_MASK) >> IFX_SSC_PERID_TXFS_OFFSET) + +#endif diff --git a/target/linux/amazon/files/include/asm-mips/amazon/irq.h b/target/linux/amazon/files/include/asm-mips/amazon/irq.h new file mode 100644 index 000000000..c575dd64b --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/irq.h @@ -0,0 +1,200 @@ +/* irq.h - AMAZON interrupts */ + +#ifndef __AMAZON_IRQ +#define __AMAZON_IRQ + +/************************************************************************ + * Interrupt information +*************************************************************************/ + +/* these vectors are to handle the interrupts from the internal AMAZON + interrupt controller. THe INT_NUM values are really just indices into + an array and are set up so that we can use the INT_NUM as a shift + to calculate a mask value. */ +#define INT_NUM_IRQ0 8 +#define INT_NUM_IM0_IRL0 (INT_NUM_IRQ0 + 0) +#define INT_NUM_IM0_IRL1 (INT_NUM_IRQ0 + 1) +#define INT_NUM_IM0_IRL2 (INT_NUM_IRQ0 + 2) +#define INT_NUM_IM0_IRL3 (INT_NUM_IRQ0 + 3) +#define INT_NUM_IM0_IRL4 (INT_NUM_IRQ0 + 4) +#define INT_NUM_IM0_IRL5 (INT_NUM_IRQ0 + 5) +#define INT_NUM_IM0_IRL6 (INT_NUM_IRQ0 + 6) +#define INT_NUM_IM0_IRL7 (INT_NUM_IRQ0 + 7) +#define INT_NUM_IM0_IRL8 (INT_NUM_IRQ0 + 8) +#define INT_NUM_IM0_IRL9 (INT_NUM_IRQ0 + 9) +#define INT_NUM_IM0_IRL10 (INT_NUM_IRQ0 + 10) +#define INT_NUM_IM0_IRL11 (INT_NUM_IRQ0 + 11) +#define INT_NUM_IM0_IRL12 (INT_NUM_IRQ0 + 12) +#define INT_NUM_IM0_IRL13 (INT_NUM_IRQ0 + 13) +#define INT_NUM_IM0_IRL14 (INT_NUM_IRQ0 + 14) +#define INT_NUM_IM0_IRL15 (INT_NUM_IRQ0 + 15) +#define INT_NUM_IM0_IRL16 (INT_NUM_IRQ0 + 16) +#define INT_NUM_IM0_IRL17 (INT_NUM_IRQ0 + 17) +#define INT_NUM_IM0_IRL18 (INT_NUM_IRQ0 + 18) +#define INT_NUM_IM0_IRL19 (INT_NUM_IRQ0 + 19) +#define INT_NUM_IM0_IRL20 (INT_NUM_IRQ0 + 20) +#define INT_NUM_IM0_IRL21 (INT_NUM_IRQ0 + 21) +#define INT_NUM_IM0_IRL22 (INT_NUM_IRQ0 + 22) +#define INT_NUM_IM0_IRL23 (INT_NUM_IRQ0 + 23) +#define INT_NUM_IM0_IRL24 (INT_NUM_IRQ0 + 24) +#define INT_NUM_IM0_IRL25 (INT_NUM_IRQ0 + 25) +#define INT_NUM_IM0_IRL26 (INT_NUM_IRQ0 + 26) +#define INT_NUM_IM0_IRL27 (INT_NUM_IRQ0 + 27) +#define INT_NUM_IM0_IRL28 (INT_NUM_IRQ0 + 28) +#define INT_NUM_IM0_IRL29 (INT_NUM_IRQ0 + 29) +#define INT_NUM_IM0_IRL30 (INT_NUM_IRQ0 + 30) +#define INT_NUM_IM0_IRL31 (INT_NUM_IRQ0 + 31) + +#define INT_NUM_IM1_IRL0 (INT_NUM_IRQ0 + 32) +#define INT_NUM_IM1_IRL1 (INT_NUM_IM1_IRL0 + 1) +#define INT_NUM_IM1_IRL2 (INT_NUM_IM1_IRL0 + 2) +#define INT_NUM_IM1_IRL3 (INT_NUM_IM1_IRL0 + 3) +#define INT_NUM_IM1_IRL4 (INT_NUM_IM1_IRL0 + 4) +#define INT_NUM_IM1_IRL5 (INT_NUM_IM1_IRL0 + 5) +#define INT_NUM_IM1_IRL6 (INT_NUM_IM1_IRL0 + 6) +#define INT_NUM_IM1_IRL7 (INT_NUM_IM1_IRL0 + 7) +#define INT_NUM_IM1_IRL8 (INT_NUM_IM1_IRL0 + 8) +#define INT_NUM_IM1_IRL9 (INT_NUM_IM1_IRL0 + 9) +#define INT_NUM_IM1_IRL10 (INT_NUM_IM1_IRL0 + 10) +#define INT_NUM_IM1_IRL11 (INT_NUM_IM1_IRL0 + 11) +#define INT_NUM_IM1_IRL12 (INT_NUM_IM1_IRL0 + 12) +#define INT_NUM_IM1_IRL13 (INT_NUM_IM1_IRL0 + 13) +#define INT_NUM_IM1_IRL14 (INT_NUM_IM1_IRL0 + 14) +#define INT_NUM_IM1_IRL15 (INT_NUM_IM1_IRL0 + 15) +#define INT_NUM_IM1_IRL16 (INT_NUM_IM1_IRL0 + 16) +#define INT_NUM_IM1_IRL17 (INT_NUM_IM1_IRL0 + 17) +#define INT_NUM_IM1_IRL18 (INT_NUM_IM1_IRL0 + 18) +#define INT_NUM_IM1_IRL19 (INT_NUM_IM1_IRL0 + 19) +#define INT_NUM_IM1_IRL20 (INT_NUM_IM1_IRL0 + 20) +#define INT_NUM_IM1_IRL21 (INT_NUM_IM1_IRL0 + 21) +#define INT_NUM_IM1_IRL22 (INT_NUM_IM1_IRL0 + 22) +#define INT_NUM_IM1_IRL23 (INT_NUM_IM1_IRL0 + 23) +#define INT_NUM_IM1_IRL24 (INT_NUM_IM1_IRL0 + 24) +#define INT_NUM_IM1_IRL25 (INT_NUM_IM1_IRL0 + 25) +#define INT_NUM_IM1_IRL26 (INT_NUM_IM1_IRL0 + 26) +#define INT_NUM_IM1_IRL27 (INT_NUM_IM1_IRL0 + 27) +#define INT_NUM_IM1_IRL28 (INT_NUM_IM1_IRL0 + 28) +#define INT_NUM_IM1_IRL29 (INT_NUM_IM1_IRL0 + 29) +#define INT_NUM_IM1_IRL30 (INT_NUM_IM1_IRL0 + 30) +#define INT_NUM_IM1_IRL31 (INT_NUM_IM1_IRL0 + 31) + +#define INT_NUM_IM2_IRL0 (INT_NUM_IRQ0 + 64) +#define INT_NUM_IM2_IRL1 (INT_NUM_IM2_IRL0 + 1) +#define INT_NUM_IM2_IRL2 (INT_NUM_IM2_IRL0 + 2) +#define INT_NUM_IM2_IRL3 (INT_NUM_IM2_IRL0 + 3) +#define INT_NUM_IM2_IRL4 (INT_NUM_IM2_IRL0 + 4) +#define INT_NUM_IM2_IRL5 (INT_NUM_IM2_IRL0 + 5) +#define INT_NUM_IM2_IRL6 (INT_NUM_IM2_IRL0 + 6) +#define INT_NUM_IM2_IRL7 (INT_NUM_IM2_IRL0 + 7) +#define INT_NUM_IM2_IRL8 (INT_NUM_IM2_IRL0 + 8) +#define INT_NUM_IM2_IRL9 (INT_NUM_IM2_IRL0 + 9) +#define INT_NUM_IM2_IRL10 (INT_NUM_IM2_IRL0 + 10) +#define INT_NUM_IM2_IRL11 (INT_NUM_IM2_IRL0 + 11) +#define INT_NUM_IM2_IRL12 (INT_NUM_IM2_IRL0 + 12) +#define INT_NUM_IM2_IRL13 (INT_NUM_IM2_IRL0 + 13) +#define INT_NUM_IM2_IRL14 (INT_NUM_IM2_IRL0 + 14) +#define INT_NUM_IM2_IRL15 (INT_NUM_IM2_IRL0 + 15) +#define INT_NUM_IM2_IRL16 (INT_NUM_IM2_IRL0 + 16) +#define INT_NUM_IM2_IRL17 (INT_NUM_IM2_IRL0 + 17) +#define INT_NUM_IM2_IRL18 (INT_NUM_IM2_IRL0 + 18) +#define INT_NUM_IM2_IRL19 (INT_NUM_IM2_IRL0 + 19) +#define INT_NUM_IM2_IRL20 (INT_NUM_IM2_IRL0 + 20) +#define INT_NUM_IM2_IRL21 (INT_NUM_IM2_IRL0 + 21) +#define INT_NUM_IM2_IRL22 (INT_NUM_IM2_IRL0 + 22) +#define INT_NUM_IM2_IRL23 (INT_NUM_IM2_IRL0 + 23) +#define INT_NUM_IM2_IRL24 (INT_NUM_IM2_IRL0 + 24) +#define INT_NUM_IM2_IRL25 (INT_NUM_IM2_IRL0 + 25) +#define INT_NUM_IM2_IRL26 (INT_NUM_IM2_IRL0 + 26) +#define INT_NUM_IM2_IRL27 (INT_NUM_IM2_IRL0 + 27) +#define INT_NUM_IM2_IRL28 (INT_NUM_IM2_IRL0 + 28) +#define INT_NUM_IM2_IRL29 (INT_NUM_IM2_IRL0 + 29) +#define INT_NUM_IM2_IRL30 (INT_NUM_IM2_IRL0 + 30) +#define INT_NUM_IM2_IRL31 (INT_NUM_IM2_IRL0 + 31) + +#define INT_NUM_IM3_IRL0 (INT_NUM_IRQ0 + 96) +#define INT_NUM_IM3_IRL1 (INT_NUM_IM3_IRL0 + 1) +#define INT_NUM_IM3_IRL2 (INT_NUM_IM3_IRL0 + 2) +#define INT_NUM_IM3_IRL3 (INT_NUM_IM3_IRL0 + 3) +#define INT_NUM_IM3_IRL4 (INT_NUM_IM3_IRL0 + 4) +#define INT_NUM_IM3_IRL5 (INT_NUM_IM3_IRL0 + 5) +#define INT_NUM_IM3_IRL6 (INT_NUM_IM3_IRL0 + 6) +#define INT_NUM_IM3_IRL7 (INT_NUM_IM3_IRL0 + 7) +#define INT_NUM_IM3_IRL8 (INT_NUM_IM3_IRL0 + 8) +#define INT_NUM_IM3_IRL9 (INT_NUM_IM3_IRL0 + 9) +#define INT_NUM_IM3_IRL10 (INT_NUM_IM3_IRL0 + 10) +#define INT_NUM_IM3_IRL11 (INT_NUM_IM3_IRL0 + 11) +#define INT_NUM_IM3_IRL12 (INT_NUM_IM3_IRL0 + 12) +#define INT_NUM_IM3_IRL13 (INT_NUM_IM3_IRL0 + 13) +#define INT_NUM_IM3_IRL14 (INT_NUM_IM3_IRL0 + 14) +#define INT_NUM_IM3_IRL15 (INT_NUM_IM3_IRL0 + 15) +#define INT_NUM_IM3_IRL16 (INT_NUM_IM3_IRL0 + 16) +#define INT_NUM_IM3_IRL17 (INT_NUM_IM3_IRL0 + 17) +#define INT_NUM_IM3_IRL18 (INT_NUM_IM3_IRL0 + 18) +#define INT_NUM_IM3_IRL19 (INT_NUM_IM3_IRL0 + 19) +#define INT_NUM_IM3_IRL20 (INT_NUM_IM3_IRL0 + 20) +#define INT_NUM_IM3_IRL21 (INT_NUM_IM3_IRL0 + 21) +#define INT_NUM_IM3_IRL22 (INT_NUM_IM3_IRL0 + 22) +#define INT_NUM_IM3_IRL23 (INT_NUM_IM3_IRL0 + 23) +#define INT_NUM_IM3_IRL24 (INT_NUM_IM3_IRL0 + 24) +#define INT_NUM_IM3_IRL25 (INT_NUM_IM3_IRL0 + 25) +#define INT_NUM_IM3_IRL26 (INT_NUM_IM3_IRL0 + 26) +#define INT_NUM_IM3_IRL27 (INT_NUM_IM3_IRL0 + 27) +#define INT_NUM_IM3_IRL28 (INT_NUM_IM3_IRL0 + 28) +#define INT_NUM_IM3_IRL29 (INT_NUM_IM3_IRL0 + 29) +#define INT_NUM_IM3_IRL30 (INT_NUM_IM3_IRL0 + 30) +#define INT_NUM_IM3_IRL31 (INT_NUM_IM3_IRL0 + 31) + +#define INT_NUM_IM4_IRL0 (INT_NUM_IRQ0 + 128) +#define INT_NUM_IM4_IRL1 (INT_NUM_IM4_IRL0 + 1) +#define INT_NUM_IM4_IRL2 (INT_NUM_IM4_IRL0 + 2) +#define INT_NUM_IM4_IRL3 (INT_NUM_IM4_IRL0 + 3) +#define INT_NUM_IM4_IRL4 (INT_NUM_IM4_IRL0 + 4) +#define INT_NUM_IM4_IRL5 (INT_NUM_IM4_IRL0 + 5) +#define INT_NUM_IM4_IRL6 (INT_NUM_IM4_IRL0 + 6) +#define INT_NUM_IM4_IRL7 (INT_NUM_IM4_IRL0 + 7) +#define INT_NUM_IM4_IRL8 (INT_NUM_IM4_IRL0 + 8) +#define INT_NUM_IM4_IRL9 (INT_NUM_IM4_IRL0 + 9) +#define INT_NUM_IM4_IRL10 (INT_NUM_IM4_IRL0 + 10) +#define INT_NUM_IM4_IRL11 (INT_NUM_IM4_IRL0 + 11) +#define INT_NUM_IM4_IRL12 (INT_NUM_IM4_IRL0 + 12) +#define INT_NUM_IM4_IRL13 (INT_NUM_IM4_IRL0 + 13) +#define INT_NUM_IM4_IRL14 (INT_NUM_IM4_IRL0 + 14) +#define INT_NUM_IM4_IRL15 (INT_NUM_IM4_IRL0 + 15) +#define INT_NUM_IM4_IRL16 (INT_NUM_IM4_IRL0 + 16) +#define INT_NUM_IM4_IRL17 (INT_NUM_IM4_IRL0 + 17) +#define INT_NUM_IM4_IRL18 (INT_NUM_IM4_IRL0 + 18) +#define INT_NUM_IM4_IRL19 (INT_NUM_IM4_IRL0 + 19) +#define INT_NUM_IM4_IRL20 (INT_NUM_IM4_IRL0 + 20) +#define INT_NUM_IM4_IRL21 (INT_NUM_IM4_IRL0 + 21) +#define INT_NUM_IM4_IRL22 (INT_NUM_IM4_IRL0 + 22) +#define INT_NUM_IM4_IRL23 (INT_NUM_IM4_IRL0 + 23) +#define INT_NUM_IM4_IRL24 (INT_NUM_IM4_IRL0 + 24) +#define INT_NUM_IM4_IRL25 (INT_NUM_IM4_IRL0 + 25) +#define INT_NUM_IM4_IRL26 (INT_NUM_IM4_IRL0 + 26) +#define INT_NUM_IM4_IRL27 (INT_NUM_IM4_IRL0 + 27) +#define INT_NUM_IM4_IRL28 (INT_NUM_IM4_IRL0 + 28) +#define INT_NUM_IM4_IRL29 (INT_NUM_IM4_IRL0 + 29) +#define INT_NUM_IM4_IRL30 (INT_NUM_IM4_IRL0 + 30) +#define INT_NUM_IM4_IRL31 (INT_NUM_IM4_IRL0 + 31) + +/****** Interrupt Assigments ***********/ +#define AMAZON_DMA_INT INT_NUM_IM0_IRL0 +#define IFX_SSC_TIR INT_NUM_IM0_IRL29 +#define IFX_SSC_RIR INT_NUM_IM0_IRL30 +#define IFX_SSC_EIR INT_NUM_IM0_IRL31 + +#define AMAZON_MEI_INT INT_NUM_IM2_IRL8 + +#define AMAZONASC_TIR INT_NUM_IM4_IRL15/* TX interrupt */ +#define AMAZONASC_RIR INT_NUM_IM4_IRL16/* RX interrupt */ +#define AMAZONASC_EIR INT_NUM_IM4_IRL17/* ERROR interrupt */ + +#define AMAZON_TIMER6_INT INT_NUM_IM1_IRL23 + +#define AMAZON_SWIE_INT INT_NUM_IM3_IRL8 +#define AMAZON_CBM_INT INT_NUM_IM3_IRL9 +#define AMAZON_AAL5_INT INT_NUM_IM3_IRL10 +#define AMAZON_HTU_INT INT_NUM_IM3_IRL11 +#define AMAZON_QSB_INT INT_NUM_IM3_IRL12 +#define MIPS_CPU_TIMER_IRQ 7 +#endif /* __AMAZON_IRQ */ diff --git a/target/linux/amazon/files/include/asm-mips/amazon/model.h b/target/linux/amazon/files/include/asm-mips/amazon/model.h new file mode 100644 index 000000000..4e43ab5f1 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/model.h @@ -0,0 +1,29 @@ +#ifndef AMAZON_MODEL_H +#define AMAZON_MODEL_H +/****************************************************************************** + Copyright (c) 2002, Infineon Technologies. All rights reserved. + + No Warranty + Because the program is licensed free of charge, there is no warranty for + the program, to the extent permitted by applicable law. Except when + otherwise stated in writing the copyright holders and/or other parties + provide the program "as is" without warranty of any kind, either + expressed or implied, including, but not limited to, the implied + warranties of merchantability and fitness for a particular purpose. The + entire risk as to the quality and performance of the program is with + you. should the program prove defective, you assume the cost of all + necessary servicing, repair or correction. + + In no event unless required by applicable law or agreed to in writing + will any copyright holder, or any other party who may modify and/or + redistribute the program as permitted above, be liable to you for + damages, including any general, special, incidental or consequential + damages arising out of the use or inability to use the program + (including but not limited to loss of data or data being rendered + inaccurate or losses sustained by you or third parties or a failure of + the program to operate with any other programs), even if such holder or + other party has been advised of the possibility of such damages. +******************************************************************************/ +#define BOARD_SYSTEM_TYPE "AMAZON" +#define SYSTEM_MODEL_NAME "Amazon Gateway Package 3.2 Version" +#endif diff --git a/target/linux/amazon/files/include/asm-mips/amazon/port.h b/target/linux/amazon/files/include/asm-mips/amazon/port.h new file mode 100644 index 000000000..21825794c --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/port.h @@ -0,0 +1,72 @@ +/* + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * port.h + * + * Global Amazon port driver header file + * + */ + +/* Modification history */ +/* 21Jun2004 btxu Generate from Inca_IP project */ + + +#ifndef PORT_H +#define PORT_H + +struct amazon_port_ioctl_parm { + int port; + int pin; + int value; +}; +#define AMAZON_PORT_IOC_MAGIC 0xbf +#define AMAZON_PORT_IOCOD _IOW( AMAZON_PORT_IOC_MAGIC,0,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCPUDSEL _IOW( AMAZON_PORT_IOC_MAGIC,1,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCPUDEN _IOW( AMAZON_PORT_IOC_MAGIC,2,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCSTOFF _IOW( AMAZON_PORT_IOC_MAGIC,3,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCDIR _IOW( AMAZON_PORT_IOC_MAGIC,4,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCOUTPUT _IOW( AMAZON_PORT_IOC_MAGIC,5,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCINPUT _IOWR(AMAZON_PORT_IOC_MAGIC,6,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCALTSEL0 _IOW( AMAZON_PORT_IOC_MAGIC,7,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCALTSEL1 _IOW( AMAZON_PORT_IOC_MAGIC,8,struct amazon_port_ioctl_parm) + +int amazon_port_reserve_pin(int port, int pin, int module_id); +int amazon_port_free_pin(int port, int pin, int module_id); +int amazon_port_set_open_drain(int port, int pin, int module_id); +int amazon_port_clear_open_drain(int port, int pin, int module_id); +int amazon_port_set_pudsel(int port, int pin, int module_id); +int amazon_port_clear_pudsel(int port, int pin, int module_id); +int amazon_port_set_puden(int port, int pin, int module_id); +int amazon_port_clear_puden(int port, int pin, int module_id); +int amazon_port_set_stoff(int port, int pin, int module_id); +int amazon_port_clear_stoff(int port, int pin, int module_id); +int amazon_port_set_dir_out(int port, int pin, int module_id); +int amazon_port_set_dir_in(int port, int pin, int module_id); +int amazon_port_set_output(int port, int pin, int module_id); +int amazon_port_clear_output(int port, int pin, int module_id); +int amazon_port_get_input(int port, int pin, int module_id); + +int amazon_port_set_altsel0(int port, int pin, int module_id); +int amazon_port_clear_altsel0(int port, int pin, int module_id); +int amazon_port_set_altsel1(int port, int pin, int module_id); +int amazon_port_clear_altsel1(int port, int pin, int module_id); + + +#endif /* PORT_H */ + + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/serial.h b/target/linux/amazon/files/include/asm-mips/amazon/serial.h new file mode 100644 index 000000000..3ff3efc28 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/serial.h @@ -0,0 +1,146 @@ +/* incaAscSio.h - (AMAZON) ASC UART tty driver header */ + +#ifndef __AMAZON_ASC_H +#define __AMAZON_ASC_H + +/* channel operating modes */ +#define ASCOPT_CSIZE 0x00000003 +#define ASCOPT_CS7 0x00000001 +#define ASCOPT_CS8 0x00000002 +#define ASCOPT_PARENB 0x00000004 +#define ASCOPT_STOPB 0x00000008 +#define ASCOPT_PARODD 0x00000010 +#define ASCOPT_CREAD 0x00000020 + +#define ASC_OPTIONS (ASCOPT_CREAD | ASCOPT_CS8) + +/* ASC input select (0 or 1) */ +#define CONSOLE_TTY 0 + +/* use fractional divider for baudrate settings */ +#define AMAZONASC_USE_FDV + +#ifdef AMAZONASC_USE_FDV + #define AMAZONASC_FDV_LOW_BAUDRATE 71 +#ifdef CONFIG_USE_IKOS + #define AMAZONASC_FDV_HIGH_BAUDRATE 443 +#else + #define AMAZONASC_FDV_HIGH_BAUDRATE 498 +#endif //CONFIG_USE_IKOS +#endif /*AMAZONASC_USE_FDV*/ + + +#define AMAZONASC_TXFIFO_FL 1 +#define AMAZONASC_RXFIFO_FL 1 +#define AMAZONASC_TXFIFO_FULL 16 + +/* interrupt lines masks for the ASC device interrupts*/ +/* change these macroses if it's necessary */ +#define AMAZONASC_IRQ_LINE_ALL 0x000F0000 /* all IRQs */ + +#define AMAZONASC_IRQ_LINE_TIR 0x00010000 /* TIR - Tx */ +#define AMAZONASC_IRQ_LINE_RIR 0x00020000 /* RIR - Rx */ +#define AMAZONASC_IRQ_LINE_EIR 0x00040000 /* EIR - Err */ +#define AMAZONASC_IRQ_LINE_TBIR 0x00080000 /* TBIR - Tx Buf*/ + +/* CLC register's bits and bitfields */ +#define ASCCLC_DISR 0x00000001 +#define ASCCLC_DISS 0x00000002 +#define ASCCLC_RMCMASK 0x0000FF00 +#define ASCCLC_RMCOFFSET 8 + +/* CON register's bits and bitfields */ +#define ASCCON_MODEMASK 0x0007 + #define ASCCON_M_8SYNC 0x0 + #define ASCCON_M_8ASYNC 0x1 + #define ASCCON_M_8IRDAASYNC 0x2 + #define ASCCON_M_7ASYNCPAR 0x3 + #define ASCCON_M_9ASYNC 0x4 + #define ASCCON_M_8WAKEUPASYNC 0x5 + #define ASCCON_M_8ASYNCPAR 0x7 +#define ASCCON_STP 0x0008 +#define ASCCON_REN 0x0010 +#define ASCCON_PEN 0x0020 +#define ASCCON_FEN 0x0040 +#define ASCCON_OEN 0x0080 +#define ASCCON_PE 0x0100 +#define ASCCON_FE 0x0200 +#define ASCCON_OE 0x0400 +#define ASCCON_FDE 0x0800 +#define ASCCON_ODD 0x1000 +#define ASCCON_BRS 0x2000 +#define ASCCON_LB 0x4000 +#define ASCCON_R 0x8000 +#define ASCCON_ANY (ASCCON_PE|ASCCON_FE|ASCCON_OE) + +/* WHBCON register's bits and bitfields */ +#define ASCWHBCON_CLRREN 0x0010 +#define ASCWHBCON_SETREN 0x0020 +#define ASCWHBCON_CLRPE 0x0100 +#define ASCWHBCON_CLRFE 0x0200 +#define ASCWHBCON_CLROE 0x0400 +#define ASCWHBCON_SETPE 0x0800 +#define ASCWHBCON_SETFE 0x1000 +#define ASCWHBCON_SETOE 0x2000 + +/* ABCON register's bits and bitfields */ +#define ASCABCON_ABEN 0x0001 +#define ASCABCON_AUREN 0x0002 +#define ASCABCON_ABSTEN 0x0004 +#define ASCABCON_ABDETEN 0x0008 +#define ASCABCON_FCDETEN 0x0010 +#define ASCABCON_EMMASK 0x0300 + #define ASCABCON_EMOFF 8 + #define ASCABCON_EM_DISAB 0x0 + #define ASCABCON_EM_DURAB 0x1 + #define ASCABCON_EM_ALWAYS 0x2 +#define ASCABCON_TXINV 0x0400 +#define ASCABCON_RXINV 0x0800 + +/* FDV register mask, offset and bitfields*/ +#define ASCFDV_VALUE_MASK 0x000001FF + +/* WHBABCON register's bits and bitfields */ +#define ASCWHBABCON_SETABEN 0x0001 +#define ASCWHBABCON_CLRABEN 0x0002 + +/* ABSTAT register's bits and bitfields */ +#define ASCABSTAT_FCSDET 0x0001 +#define ASCABSTAT_FCCDET 0x0002 +#define ASCABSTAT_SCSDET 0x0004 +#define ASCABSTAT_SCCDET 0x0008 +#define ASCABSTAT_DETWAIT 0x0010 + +/* WHBABSTAT register's bits and bitfields */ +#define ASCWHBABSTAT_CLRFCSDET 0x0001 +#define ASCWHBABSTAT_SETFCSDET 0x0002 +#define ASCWHBABSTAT_CLRFCCDET 0x0004 +#define ASCWHBABSTAT_SETFCCDET 0x0008 +#define ASCWHBABSTAT_CLRSCSDET 0x0010 +#define ASCWHBABSTAT_SETSCSDET 0x0020 +#define ASCWHBABSTAT_SETSCCDET 0x0040 +#define ASCWHBABSTAT_CLRSCCDET 0x0080 +#define ASCWHBABSTAT_CLRDETWAIT 0x0100 +#define ASCWHBABSTAT_SETDETWAIT 0x0200 + +/* TXFCON register's bits and bitfields */ +#define ASCTXFCON_TXFEN 0x0001 +#define ASCTXFCON_TXFFLU 0x0002 +#define ASCTXFCON_TXTMEN 0x0004 +#define ASCTXFCON_TXFITLMASK 0x3F00 +#define ASCTXFCON_TXFITLOFF 8 + +/* RXFCON register's bits and bitfields */ +#define ASCRXFCON_RXFEN 0x0001 +#define ASCRXFCON_RXFFLU 0x0002 +#define ASCRXFCON_RXTMEN 0x0004 +#define ASCRXFCON_RXFITLMASK 0x3F00 +#define ASCRXFCON_RXFITLOFF 8 + +/* FSTAT register's bits and bitfields */ +#define ASCFSTAT_RXFFLMASK 0x003F +#define ASCFSTAT_TXFFLMASK 0x3F00 +#define ASCFSTAT_TXFFLOFF 8 + +#endif /* __AMAZON_ASC_H */ + diff --git a/target/linux/amazon/image/Makefile b/target/linux/amazon/image/Makefile new file mode 100644 index 000000000..08f3ba531 --- /dev/null +++ b/target/linux/amazon/image/Makefile @@ -0,0 +1,30 @@ +# +# Copyright (C) 2006-2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/image.mk + +define Image/BuildKernel + $(STAGING_DIR_HOST)/bin/lzma e $(KDIR)/vmlinux $(KDIR)/vmlinux.lzma + mkimage -A mips -O linux -T kernel -C lzma -a 0x80002000 -e \ + 0x80002000 \ + -n 'MIPS OpenWrt Linux-$(LINUX_VERSION)' \ + -d $(KDIR)/vmlinux.lzma $(KDIR)/uImage + + cp $(KDIR)/uImage $(BIN_DIR)/$(IMG_PREFIX)-uImage +endef + +define Image/Build/squashfs + $(call prepare_generic_squashfs,$(BIN_DIR)/$(IMG_PREFIX)-$(1).image) +endef + +define Image/Build + cat $(KDIR)/uImage $(KDIR)/root.$(1) > $(BIN_DIR)/$(IMG_PREFIX)-$(1).image + $(call Image/Build/$(1),$(1)) +endef + + +$(eval $(call BuildImage)) diff --git a/target/linux/amazon/patches-3.3/000-mips-bad-intctl.patch b/target/linux/amazon/patches-3.3/000-mips-bad-intctl.patch new file mode 100644 index 000000000..0aa37780a --- /dev/null +++ b/target/linux/amazon/patches-3.3/000-mips-bad-intctl.patch @@ -0,0 +1,33 @@ +--- a/arch/mips/kernel/traps.c ++++ b/arch/mips/kernel/traps.c +@@ -1593,7 +1593,16 @@ void __cpuinit per_cpu_trap_init(void) + if (cpu_has_mips_r2) { + cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP; + cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7; ++ if (!cp0_compare_irq) ++ cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ; ++ + cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7; ++ if (!cp0_perfcount_irq) ++ cp0_perfcount_irq = CP0_LEGACY_PERFCNT_IRQ; ++ ++ if (arch_fixup_c0_irqs) ++ arch_fixup_c0_irqs(); ++ + if (cp0_perfcount_irq == cp0_compare_irq) + cp0_perfcount_irq = -1; + } else { +--- a/arch/mips/include/asm/irq.h ++++ b/arch/mips/include/asm/irq.h +@@ -139,9 +139,11 @@ extern void free_irqno(unsigned int irq) + * IE7. Since R2 their number has to be read from the c0_intctl register. + */ + #define CP0_LEGACY_COMPARE_IRQ 7 ++#define CP0_LEGACY_PERFCNT_IRQ 7 + + extern int cp0_compare_irq; + extern int cp0_compare_irq_shift; + extern int cp0_perfcount_irq; ++extern void __weak arch_fixup_c0_irqs(void); + + #endif /* _ASM_IRQ_H */ diff --git a/target/linux/amazon/patches-3.3/010-mips_clocksource_init_war.patch b/target/linux/amazon/patches-3.3/010-mips_clocksource_init_war.patch new file mode 100644 index 000000000..7078b3743 --- /dev/null +++ b/target/linux/amazon/patches-3.3/010-mips_clocksource_init_war.patch @@ -0,0 +1,33 @@ +--- a/arch/mips/kernel/cevt-r4k.c ++++ b/arch/mips/kernel/cevt-r4k.c +@@ -23,6 +23,22 @@ + + #ifndef CONFIG_MIPS_MT_SMTC + ++/* ++ * Compare interrupt can be routed and latched outside the core, ++ * so a single execution hazard barrier may not be enough to give ++ * it time to clear as seen in the Cause register. 4 time the ++ * pipeline depth seems reasonably conservative, and empirically ++ * works better in configurations with high CPU/bus clock ratios. ++ */ ++ ++#define compare_change_hazard() \ ++ do { \ ++ irq_disable_hazard(); \ ++ irq_disable_hazard(); \ ++ irq_disable_hazard(); \ ++ irq_disable_hazard(); \ ++ } while (0) ++ + static int mips_next_event(unsigned long delta, + struct clock_event_device *evt) + { +@@ -32,6 +48,7 @@ static int mips_next_event(unsigned long + cnt = read_c0_count(); + cnt += delta; + write_c0_compare(cnt); ++ compare_change_hazard(); + res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0; + return res; + } diff --git a/target/linux/amazon/patches-3.3/017-wdt-driver.patch b/target/linux/amazon/patches-3.3/017-wdt-driver.patch new file mode 100644 index 000000000..005ee710a --- /dev/null +++ b/target/linux/amazon/patches-3.3/017-wdt-driver.patch @@ -0,0 +1,10 @@ +--- a/drivers/watchdog/Makefile ++++ b/drivers/watchdog/Makefile +@@ -132,6 +132,7 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o + obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o + octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o + obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o ++obj-$(CONFIG_AMAZON_WDT) += amazon_wdt.o + + # PARISC Architecture + diff --git a/target/linux/amazon/patches-3.3/100-board.patch b/target/linux/amazon/patches-3.3/100-board.patch new file mode 100644 index 000000000..b74305273 --- /dev/null +++ b/target/linux/amazon/patches-3.3/100-board.patch @@ -0,0 +1,53 @@ +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -120,6 +120,22 @@ config BCM63XX + help + Support for BCM63XX based boards + ++config AMAZON ++ bool "Amazon support (EXPERIMENTAL)" ++ depends on EXPERIMENTAL ++ select DMA_NONCOHERENT ++ select IRQ_CPU ++ select CEVT_R4K ++ select CSRC_R4K ++ select SYS_HAS_CPU_MIPS32_R1 ++ select SYS_HAS_CPU_MIPS32_R2 ++ select HAVE_STD_PC_SERIAL_PORT ++ select SYS_SUPPORTS_BIG_ENDIAN ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_HAS_EARLY_PRINTK ++ select HW_HAS_PCI ++ select SWAP_IO_SPACE ++ + config MIPS_COBALT + bool "Cobalt Server" + select CEVT_R4K +@@ -813,6 +829,7 @@ config NLM_XLP_BOARD + + endchoice + ++source "arch/mips/amazon/Kconfig" + source "arch/mips/alchemy/Kconfig" + source "arch/mips/ath79/Kconfig" + source "arch/mips/bcm47xx/Kconfig" +--- a/arch/mips/Kbuild.platforms ++++ b/arch/mips/Kbuild.platforms +@@ -6,6 +6,7 @@ platforms += ath79 + platforms += bcm47xx + platforms += bcm63xx + platforms += cavium-octeon ++platforms += amazon + platforms += cobalt + platforms += dec + platforms += emma +--- /dev/null ++++ b/arch/mips/amazon/Platform +@@ -0,0 +1,7 @@ ++# ++# Infineon AMAZON boards ++# ++platform-$(CONFIG_AMAZON) += amazon/ ++cflags-$(CONFIG_AMAZON) += \ ++ -I$(srctree)/arch/mips/include/asm/mach-amazon ++load-$(CONFIG_AMAZON) := 0xffffffff80002000 diff --git a/target/linux/amazon/patches-3.3/130-mtd_drivers.patch b/target/linux/amazon/patches-3.3/130-mtd_drivers.patch new file mode 100644 index 000000000..6ce28e3fd --- /dev/null +++ b/target/linux/amazon/patches-3.3/130-mtd_drivers.patch @@ -0,0 +1,7 @@ +--- a/drivers/mtd/maps/Makefile ++++ b/drivers/mtd/maps/Makefile +@@ -57,3 +57,4 @@ obj-$(CONFIG_MTD_VMU) += vmu-flash.o + obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o + obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o + obj-$(CONFIG_MTD_LANTIQ) += lantiq-flash.o ++obj-$(CONFIG_AMAZON_MTD) += amazon.o diff --git a/target/linux/amazon/patches-3.3/140-net_drivers.patch b/target/linux/amazon/patches-3.3/140-net_drivers.patch new file mode 100644 index 000000000..9c840e67f --- /dev/null +++ b/target/linux/amazon/patches-3.3/140-net_drivers.patch @@ -0,0 +1,9 @@ +--- a/drivers/net/ethernet/Makefile ++++ b/drivers/net/ethernet/Makefile +@@ -74,3 +74,6 @@ obj-$(CONFIG_NET_VENDOR_TUNDRA) += tundr + obj-$(CONFIG_NET_VENDOR_VIA) += via/ + obj-$(CONFIG_NET_VENDOR_XILINX) += xilinx/ + obj-$(CONFIG_NET_VENDOR_XIRCOM) += xircom/ ++ ++obj-$(CONFIG_AMAZON_NET_SW) += amazon_sw.o ++obj-$(CONFIG_ADM6996_SUPPORT) += admmod.o diff --git a/target/linux/amazon/patches-3.3/150-serial_driver.patch b/target/linux/amazon/patches-3.3/150-serial_driver.patch new file mode 100644 index 000000000..c6e7f39bd --- /dev/null +++ b/target/linux/amazon/patches-3.3/150-serial_driver.patch @@ -0,0 +1,7 @@ +--- a/drivers/tty/serial/Makefile ++++ b/drivers/tty/serial/Makefile +@@ -78,3 +78,4 @@ obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o + obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o + obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o + obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o ++obj-$(CONFIG_AMAZON_ASC_UART) += amazon_asc.o diff --git a/target/linux/amazon/patches-3.3/160-cfi-swap.patch b/target/linux/amazon/patches-3.3/160-cfi-swap.patch new file mode 100644 index 000000000..4a0009e43 --- /dev/null +++ b/target/linux/amazon/patches-3.3/160-cfi-swap.patch @@ -0,0 +1,56 @@ +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -1152,6 +1152,9 @@ static int __xipram do_write_oneword(str + int retry_cnt = 0; + + adr += chip->start; ++#ifdef CONFIG_AMAZON ++ adr ^= 2; ++#endif + + mutex_lock(&chip->mutex); + ret = get_chip(map, chip, adr, FL_WRITING); +@@ -1420,7 +1423,11 @@ static int __xipram do_write_buffer(stru + z = 0; + while(z < words * map_bankwidth(map)) { + datum = map_word_load(map, buf); ++#ifdef CONFIG_AMAZON ++ map_write(map, datum, (adr + z) ^ 0x2); ++#else + map_write(map, datum, adr + z); ++#endif + + z += map_bankwidth(map); + buf += map_bankwidth(map); +@@ -1665,6 +1672,9 @@ static int __xipram do_erase_oneblock(st + int ret = 0; + + adr += chip->start; ++#ifdef CONFIG_AMAZON ++ adr ^= 2; ++#endif + + mutex_lock(&chip->mutex); + ret = get_chip(map, chip, adr, FL_ERASING); +@@ -1793,6 +1803,10 @@ static int do_atmel_lock(struct map_info + struct cfi_private *cfi = map->fldrv_priv; + int ret; + ++#ifdef CONFIG_AMAZON ++ adr ^= 2; ++#endif ++ + mutex_lock(&chip->mutex); + ret = get_chip(map, chip, adr + chip->start, FL_LOCKING); + if (ret) +@@ -1828,6 +1842,10 @@ static int do_atmel_unlock(struct map_in + struct cfi_private *cfi = map->fldrv_priv; + int ret; + ++#ifdef CONFIG_AMAZON ++ adr ^= 2; ++#endif ++ + mutex_lock(&chip->mutex); + ret = get_chip(map, chip, adr + chip->start, FL_UNLOCKING); + if (ret) diff --git a/target/linux/ar7/Makefile b/target/linux/ar7/Makefile new file mode 100644 index 000000000..a712d6d20 --- /dev/null +++ b/target/linux/ar7/Makefile @@ -0,0 +1,26 @@ +# +# Copyright (C) 2006-2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +ARCH:=mipsel +BOARD:=ar7 +BOARDNAME:=TI AR7 +FEATURES:=squashfs jffs2 atm +MAINTAINER:=Florian Fainelli + +LINUX_VERSION:=3.3.8 + +include $(INCLUDE_DIR)/target.mk + +DEFAULT_PACKAGES+= kmod-pppoa ppp-mod-pppoa linux-atm atm-tools br2684ctl \ + kmod-acx-mac80211 swconfig hostapd + +define Target/Description + Build firmware images for TI AR7 based routers. +endef + +$(eval $(call BuildTarget)) diff --git a/target/linux/ar7/base-files.mk b/target/linux/ar7/base-files.mk new file mode 100644 index 000000000..f21a604b8 --- /dev/null +++ b/target/linux/ar7/base-files.mk @@ -0,0 +1,11 @@ +define Build/Compile + $(call Build/Compile/Default) + $(TARGET_CC) -o $(PKG_BUILD_DIR)/adam2patcher $(PLATFORM_DIR)/src/adam2patcher.c +endef + +define Package/base-files/install-target + mkdir -p $(1)/sbin + $(CP) $(PKG_BUILD_DIR)/adam2patcher $(1)/sbin +endef + + diff --git a/target/linux/ar7/base-files/etc/config/network b/target/linux/ar7/base-files/etc/config/network new file mode 100644 index 000000000..9ba0e6d29 --- /dev/null +++ b/target/linux/ar7/base-files/etc/config/network @@ -0,0 +1,42 @@ +# Copyright (C) 2006 OpenWrt.org + +config interface loopback + option ifname lo + option proto static + option ipaddr 127.0.0.1 + option netmask 255.0.0.0 + +config interface lan + option type bridge + option ifname "eth0 eth1" + option proto static + option ipaddr 192.168.1.1 + option netmask 255.255.255.0 + option nat 1 + +## Example for ATM bridging. +## Useful for PPPoE or IP over ATM. Will create 'nas${unit}' +# +# config atm-bridge +# option unit 0 +# option encaps llc +# option vpi 8 +# option vci 35 +# option payload bridged # some ISPs need this set to 'routed' + + +# config interface wan +## PPPoE: +# option ifname nas0 +# option proto pppoe + +## PPPoA: +# option ifname atm0 +# option proto pppoa +# option encaps llc +# option vpi 8 +# option vci 35 + +## Both: +# option username "my_username" +# option password "my_password" diff --git a/target/linux/ar7/base-files/etc/diag.sh b/target/linux/ar7/base-files/etc/diag.sh new file mode 100644 index 000000000..b8e4dc874 --- /dev/null +++ b/target/linux/ar7/base-files/etc/diag.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# Copyright (C) 2007 OpenWrt.org + +# This setup gives us 4.5 distinguishable states: +# +# Solid OFF: Bootloader running, or kernel hung (timer task stalled) +# Solid ON: Kernel hung (timer task stalled) +# 5Hz blink: preinit +# 10Hz blink: failsafe +# Heartbeat: normal operation + +set_state() { + case "$1" in + preinit) + [ -d /sys/class/leds/status ] && { + echo timer >/sys/class/leds/status/trigger + echo 100 >/sys/class/leds/status/delay_on + echo 100 >/sys/class/leds/status/delay_off + } + ;; + failsafe) + [ -d /sys/class/leds/status ] && { + echo timer >/sys/class/leds/status/trigger + echo 50 >/sys/class/leds/status/delay_on + echo 50 >/sys/class/leds/status/delay_off + } + ;; + done) + [ -d /sys/class/leds/status ] && { + echo heartbeat >/sys/class/leds/status/trigger + } + ;; + esac +} diff --git a/target/linux/ar7/base-files/etc/init.d/adam2 b/target/linux/ar7/base-files/etc/init.d/adam2 new file mode 100755 index 000000000..6b786270e --- /dev/null +++ b/target/linux/ar7/base-files/etc/init.d/adam2 @@ -0,0 +1,13 @@ +#!/bin/sh /etc/rc.common +# ADAM2 patcher for Netgear DG834 and compatible +# Copyright (C) 2006 OpenWrt.org + +START=00 +start() { + MD5="$(md5sum /dev/mtdblock0 | awk '{print $1}')" + [ "$MD5" = "0530bfdf00ec155f4182afd70da028c1" ] && { + mtd unlock adam2 + /sbin/adam2patcher /dev/mtdblock0 + } + rm -f /etc/rc.d/S${START}adam2 /etc/init.d/adam2 /sbin/adam2patcher >&- 2>&- +} diff --git a/target/linux/ar7/base-files/etc/uci-defaults/network b/target/linux/ar7/base-files/etc/uci-defaults/network new file mode 100644 index 000000000..2d35c56b1 --- /dev/null +++ b/target/linux/ar7/base-files/etc/uci-defaults/network @@ -0,0 +1,30 @@ +#!/bin/sh +if [ -e "/sys/bus/mdio_bus/drivers/IC+ IP175A/1:00" -o \ + -e "/sys/bus/mdio_bus/drivers/IC+ IP17xx/1:00" ] && \ + [ -x /sbin/swconfig ]; +then + uci batch < + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "ar7_gpio" +#define LONGNAME "TI AR7 GPIOs Driver" + +MODULE_AUTHOR("Nicolas Thill "); +MODULE_DESCRIPTION(LONGNAME); +MODULE_LICENSE("GPL"); + +static int ar7_gpio_major; + +static ssize_t ar7_gpio_write(struct file *file, const char __user *buf, + size_t len, loff_t *ppos) +{ + int pin = iminor(file->f_dentry->d_inode); + size_t i; + + for (i = 0; i < len; ++i) { + char c; + if (get_user(c, buf + i)) + return -EFAULT; + switch (c) { + case '0': + gpio_set_value(pin, 0); + break; + case '1': + gpio_set_value(pin, 1); + break; + case 'd': + case 'D': + ar7_gpio_disable(pin); + break; + case 'e': + case 'E': + ar7_gpio_enable(pin); + break; + case 'i': + case 'I': + case '<': + gpio_direction_input(pin); + break; + case 'o': + case 'O': + case '>': + gpio_direction_output(pin, 0); + break; + default: + return -EINVAL; + } + } + + return len; +} + +static ssize_t ar7_gpio_read(struct file *file, char __user *buf, + size_t len, loff_t *ppos) +{ + int pin = iminor(file->f_dentry->d_inode); + int value; + + value = gpio_get_value(pin); + if (put_user(value ? '1' : '0', buf)) + return -EFAULT; + + return 1; +} + +static int ar7_gpio_open(struct inode *inode, struct file *file) +{ + int m = iminor(inode); + + if (m >= (ar7_is_titan() ? TITAN_GPIO_MAX : AR7_GPIO_MAX)) + return -EINVAL; + + return nonseekable_open(inode, file); +} + +static int ar7_gpio_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations ar7_gpio_fops = { + .owner = THIS_MODULE, + .write = ar7_gpio_write, + .read = ar7_gpio_read, + .open = ar7_gpio_open, + .release = ar7_gpio_release, + .llseek = no_llseek, +}; + +static struct platform_device *ar7_gpio_device; + +static int __init ar7_gpio_char_init(void) +{ + int rc; + + ar7_gpio_device = platform_device_alloc(DRVNAME, -1); + if (!ar7_gpio_device) + return -ENOMEM; + + rc = platform_device_add(ar7_gpio_device); + if (rc < 0) + goto out_put; + + rc = register_chrdev(ar7_gpio_major, DRVNAME, &ar7_gpio_fops); + if (rc < 0) + goto out_put; + + ar7_gpio_major = rc; + + rc = 0; + + goto out; + +out_put: + platform_device_put(ar7_gpio_device); +out: + return rc; +} + +static void __exit ar7_gpio_char_exit(void) +{ + unregister_chrdev(ar7_gpio_major, DRVNAME); + platform_device_unregister(ar7_gpio_device); +} + +module_init(ar7_gpio_char_init); +module_exit(ar7_gpio_char_exit); diff --git a/target/linux/ar7/files/drivers/mtd/titanpart.c b/target/linux/ar7/files/drivers/mtd/titanpart.c new file mode 100644 index 000000000..74f8251a2 --- /dev/null +++ b/target/linux/ar7/files/drivers/mtd/titanpart.c @@ -0,0 +1,234 @@ +#include +#include + +#include +#include +#include +#include +#include + +#define IMAGE_A_SIZE 0X3c0000 +#define WRTP_PARTS 14 +#define NSP_IMG_MAGIC_NUMBER le32_to_cpu(0x4D544443) +#define NSP_IMG_SECTION_TYPE_KERNEL (0x01) +#define NSP_IMG_SECTION_TYPE_FILESYSTEM_ROOT (0x02) +#define NSP_IMG_SECTION_TYPE_FILESYSTEM (0x03) +#define MAX_NUM_PARTITIONS 14 + +static int part_count=0; +static struct mtd_partition titan_parts[WRTP_PARTS]; + + +struct nsp_img_hdr_head +{ + unsigned int magic; /* Magic number to identify this image header */ + unsigned int boot_offset; /* Offset from start of header to kernel code. */ + unsigned int flags; /* Image flags. */ + unsigned int hdr_version; /* Version of this header. */ + unsigned int hdr_size; /* The complete size of all portions of the header */ + unsigned int prod_id; /* This product id */ + unsigned int rel_id; /* Which release this is */ + unsigned int version; /* name-MMM.nnn.ooo-rxx => 0xMMnnooxx. See comment + below */ + unsigned int image_size; /* Image size (including header) */ + unsigned int info_offset; /* Offset from start of header to info block */ + unsigned int sect_info_offset; /* Offset from start of header to section desc */ + unsigned int chksum_offset; /* Offset from start of header to chksum block */ + unsigned int pad1; +}; + +struct nsp_img_hdr_section_info +{ + unsigned int num_sects; /* Number of section (and section desc blocks) in this image */ + unsigned int sect_size; /* Size of a SINGLE section_desc block */ + unsigned int sections_offset; /* Offset to from start of header to the start of the section blocks */ +}; + +/* There will be one of more of the following stuctures in the image header. Each + section will have one of these blocks. */ +struct nsp_img_hdr_sections +{ + unsigned int offset; /* Offset of section from start of NSP_IMG_HDR_HEAD */ + unsigned int total_size; /* Size of section (including pad size.) */ + unsigned int raw_size; /* Size of section only */ + unsigned int flags; /* Section flags */ + unsigned int chksum; /* Section checksum */ + unsigned int type; /* Section type. What kind of info does this section describe */ + char name[16]; /* Reference name for this section. */ +}; + + + + + +static int titan_parse_env_address(char *env_name, unsigned int *flash_base, + unsigned int *flash_end) +{ + char image_name[30]; + char *env_ptr; + char *base_ptr; + char *end_ptr; + char * string_ptr; + /* Get the image variable */ + env_ptr = prom_getenv(env_name); + if(!env_ptr){ + printk("titan: invalid env name, %s.\n", env_name); + return -1; /* Error, no image variable */ + } + strncpy(image_name, env_ptr, 30); + image_name[29]=0; + string_ptr = image_name; + /* Extract the start and stop addresses of the partition */ + base_ptr = strsep(&string_ptr, ","); + end_ptr = strsep(&string_ptr, ","); + if ((base_ptr == NULL) || (end_ptr == NULL)) { + printk("titan: Couldn't tokenize %s start,end.\n", image_name); + return -1; + } + + *flash_base = (unsigned int) simple_strtol(base_ptr, NULL, 0); + *flash_end = (unsigned int) simple_strtol(end_ptr, NULL, 0); + if((!*flash_base) || (!*flash_end)) { + printk("titan: Unable to convert :%s: :%s: into start,end values.\n", + env_name, image_name); + return -1; + } + *flash_base &= 0x0fffffff; + *flash_end &= 0x0fffffff; + return 0; +} + + + +static int titan_get_single_image(char *bootcfg_name, unsigned int *flash_base, + unsigned int *flash_end) +{ + char *env_ptr; + char *base_ptr; + char *end_ptr; + char image_name[30]; + char * string_ptr; + + if(!bootcfg_name || !flash_base || !flash_end) + return -1; + + env_ptr = prom_getenv(bootcfg_name); + if(!env_ptr){ + printk("titan: %s variable not found.\n", bootcfg_name); + return -1; /* Error, no bootcfg variable */ + } + + string_ptr = image_name; + /* Save off the image name */ + strncpy(image_name, env_ptr, 30); + image_name[29]=0; + + end_ptr=strsep(&string_ptr, "\""); + base_ptr=strsep(&string_ptr, "\""); /* Loose the last " */ + if(!end_ptr || !base_ptr){ + printk("titan: invalid bootcfg format, %s.\n", image_name); + return -1; /* Error, invalid bootcfg variable */ + } + + /* Now, parse the addresses */ + return titan_parse_env_address(base_ptr, flash_base, flash_end); +} + + + +static void titan_add_partition(char * env_name, unsigned int flash_base, unsigned int flash_end) +{ + titan_parts[part_count].name = env_name; + titan_parts[part_count].offset = flash_base; + titan_parts[part_count].size = flash_end-flash_base; + titan_parts[part_count].mask_flags = (strcmp(env_name, "bootloader")==0|| + strcmp(env_name, "boot_env")==0 || + strcmp(env_name, "full_image")==0 )?MTD_WRITEABLE:0; + part_count++; + +} +int create_titan_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + unsigned long origin) +{ + struct nsp_img_hdr_head hdr; + struct nsp_img_hdr_section_info sect_info; + struct nsp_img_hdr_sections section; + unsigned int flash_base, flash_end; + unsigned int start, end; + char *name; + int i; + int total_sects=0; + size_t len; + + /* Get the bootcfg env variable first */ + if(titan_get_single_image("BOOTCFG", &flash_base, &flash_end)) { + /* Error, fallback */ + return -1; + } + + /* Get access to the header, and do some validation checks */ + //hdr=(struct nsp_img_hdr_head*)flash_base; + master->read(master, flash_base, sizeof(struct nsp_img_hdr_head), &len, (uint8_t *)&hdr); + if(hdr.magic != NSP_IMG_MAGIC_NUMBER) + return -1; /* Not a single image */ + + master->read(master, flash_base + hdr.sect_info_offset, sizeof(struct nsp_img_hdr_section_info), &len, (uint8_t *)§_info); + + /* Look for the root fs, and add it first. This way we KNOW where the rootfs is */ + for(i=0; i< sect_info.num_sects && iread(master, flash_base + sect_info.sections_offset + (i * sect_info.sect_size) , sizeof(struct nsp_img_hdr_sections), &len, (uint8_t *)§ion); + /* Add only the root partition */ + if(section.type != NSP_IMG_SECTION_TYPE_FILESYSTEM_ROOT){ + continue; + } + start=flash_base + section.offset; + end=start + section.total_size; + titan_add_partition("root", start, end); + total_sects++; + + } + + for(i=0; i< sect_info.num_sects && iread(master, flash_base + sect_info.sections_offset + (i * sect_info.sect_size) , sizeof(struct nsp_img_hdr_sections), &len, (uint8_t *)§ion); + + name=section.name; + if(section.type == NSP_IMG_SECTION_TYPE_FILESYSTEM_ROOT) + { + name = "rootfs"; + start=flash_base + section.offset; + end=flash_end; + titan_add_partition(name, start, end); + total_sects++; + } + else if(section.type == NSP_IMG_SECTION_TYPE_KERNEL) + { + name = "kernel"; + start=flash_base + section.offset; + end=start + section.total_size; + titan_add_partition(name, start, end); + total_sects++; + } + + } + + /* Next, lets add the single image */ + titan_add_partition("primary_image", flash_base, flash_end); + total_sects++; + + + titan_add_partition("full_image", 0, master->size); + total_sects++; + + if (!titan_parse_env_address("BOOTLOADER", &start, &end)){ + titan_add_partition("bootloader", start, end); + total_sects++; + } + if (!titan_parse_env_address("boot_env", &start, &end)){ + titan_add_partition("boot_env", start, end); + total_sects++; + } + *pparts = titan_parts; + return total_sects; +} diff --git a/target/linux/ar7/image/Makefile b/target/linux/ar7/image/Makefile new file mode 100644 index 000000000..d27c2e888 --- /dev/null +++ b/target/linux/ar7/image/Makefile @@ -0,0 +1,109 @@ +# +# Copyright (C) 2006-2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/image.mk + +DROP_SECTIONS:=.reginfo .mdebug .comment .note .pdr .options .MIPS.options +OBJCOPY_SREC:=$(TARGET_CROSS)objcopy -S -O srec $(addprefix --remove-section=,$(DROP_SECTIONS)) + +LOADADDR:=0x94600000 +KERNEL_ENTRY:=0x94100000 +RAMSTART:=0x94000000 +RAMSIZE:=0x00100000 + +EVA_LOADADDR := 0x94100000 + +LOADER_MAKEOPTS= \ + KDIR=$(KDIR) \ + LOADADDR=$(LOADADDR) \ + KERNEL_ENTRY=$(KERNEL_ENTRY) \ + RAMSTART=$(RAMSTART) \ + RAMSIZE=$(RAMSIZE) + +CFLAGS := -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ + -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic \ + -pipe -mlong-calls -fno-common \ + -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap \ + -DLOADADDR=$(LOADADDR) + +define Build/Clean + $(MAKE) -C $(GENERIC_PLATFORM_DIR)/image/lzma-loader $(LOADER_MAKEOPTS) clean +endef + +define Image/Prepare + cat $(KDIR)/vmlinux | $(STAGING_DIR_HOST)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma + + $(MAKE) -C $(GENERIC_PLATFORM_DIR)/image/lzma-loader \ + $(LOADER_MAKEOPTS) \ + clean compile + $(OBJCOPY_SREC) $(KDIR)/loader.elf $(KDIR)/loader.srec + srec2bin $(KDIR)/loader.srec $(KDIR)/loader.bin +endef + +define align/jffs2-64k +bs=65536 conv=sync +endef + +define align/jffs2-128k +bs=131072 conv=sync +endef + +define align/squashfs +bs=65536 conv=sync +endef + +define Image/Build/CyberTAN + (dd if=/dev/zero bs=16 count=1; cat $(BIN_DIR)/$(IMG_PREFIX)-$(1).bin) | \ + $(STAGING_DIR_HOST)/bin/addpattern -p $(3) -o $(BIN_DIR)/openwrt-$(2)-$(4)-code.bin +endef + +define Image/Build/Titan + $(STAGING_DIR_HOST)/bin/mktitanimg -o $(BIN_DIR)/openwrt-$(2)-$(4)-code.bin -i $(KDIR)/loader.bin $(KDIR)/root.$(1) -a 0x10000 0x10000 -h 2 -p 0x4C575943 -s 0x0b010000 + $(STAGING_DIR_HOST)/bin/mktitanimg -o $(BIN_DIR)/openwrt-$(2)-na-$(4)-code.bin -i $(KDIR)/loader.bin $(KDIR)/root.$(1) -a 0x10000 0x10000 -h 2 -p 0x4D575943 -s 0x0b010000 +endef + + +#define Image/Build/sErCoMm +# cat sercomm/adam2.bin "$(BIN_DIR)/$(IMG_PREFIX)-$(1).bin" > "$(KDIR)/dgfw.tmp" +# dd if=sercomm/$(2) of="$(KDIR)/dgfw.tmp" bs=$$$$((0x3e0000 - 80)) seek=1 conv=notrunc +# $(STAGING_DIR_HOST)/bin/dgfirmware -f -w "$(BIN_DIR)/openwrt-$(2)-$(3).img" "$(KDIR)/dgfw.tmp" +# rm -f "$(KDIR)/dgfw.tmp" +#endef + +define Image/Build/EVA + $(STAGING_DIR_HOST)/bin/lzma2eva $(EVA_LOADADDR) 0x$${shell $(TARGET_CROSS)nm $(KDIR)/linux-*/vmlinux | grep -w kernel_entry | cut -d' ' -f1} $(KDIR)/vmlinux.lzma $(KDIR)/loader.eva + dd if=$(KDIR)/loader.eva $(call align/$(1)) > $(BIN_DIR)/openwrt-$(2)-$(KERNEL)-$(1).bin + cat $(KDIR)/root.$(1) >> $(BIN_DIR)/openwrt-$(2)-$(KERNEL)-$(1).bin + $(call prepare_generic_squashfs,$(BIN_DIR)/openwrt-$(2)-$(KERNEL)-$(1).bin) +endef + +define Image/Build + dd if=$(KDIR)/loader.bin $(call align/$(1)) > $(BIN_DIR)/$(IMG_PREFIX)-$(1).bin + cat $(KDIR)/root.$(1) >> $(BIN_DIR)/$(IMG_PREFIX)-$(1).bin + $(call prepare_generic_squashfs,$(BIN_DIR)/$(IMG_PREFIX)-$(1).bin) + $(call Image/Build/CyberTAN,$(1),AG1B,AG1B,$(1)) + $(call Image/Build/CyberTAN,$(1),AG1A,AG1A,$(1)) + $(call Image/Build/CyberTAN,$(1),WA21,WA21,$(1)) + $(call Image/Build/CyberTAN,$(1),WA22,WA22,$(1)) + $(call Image/Build/CyberTAN,$(1),WAG2,WAG2,$(1)) + $(call Image/Build/CyberTAN,$(1),AG310,AV2A -b -r 1.0,$(1)) + $(call Image/Build/CyberTAN,$(1),AG241v2,AG3A -b -r 2.0,$(1)) + $(call Image/Build/CyberTAN,$(1),AG241v2b,AG3B -b -r 2.0,$(1)) + $(call Image/Build/CyberTAN,$(1),AG241v1,AG3A -b,$(1)) + $(call Image/Build/CyberTAN,$(1),WAG54GP2v1,ATWL -b,$(1)) + $(call Image/Build/CyberTAN,$(1),WAG54GP2v2,CTWL -b,$(1)) + $(call Image/Build/CyberTAN,$(1),WA31,WA31 -b,$(1)) + $(call Image/Build/CyberTAN,$(1),WA32,WA32 -b,$(1)) + $(call Image/Build/CyberTAN,$(1),WA7A,WA7A -b,$(1)) + $(call Image/Build/CyberTAN,$(1),WA7B,WA7B -b,$(1)) +# $(call Image/Build/sErCoMm,$(1),dg834,$(1)) +# $(call Image/Build/sErCoMm,$(1),jdr454wb,$(1)) + $(call Image/Build/EVA,$(1),EVA) + $(call Image/Build/Titan,$(1),Titan,Titan,$(1)) +endef + +$(eval $(call BuildImage)) diff --git a/target/linux/ar7/patches-3.3/110-flash.patch b/target/linux/ar7/patches-3.3/110-flash.patch new file mode 100644 index 000000000..58ce7eaa4 --- /dev/null +++ b/target/linux/ar7/patches-3.3/110-flash.patch @@ -0,0 +1,22 @@ +--- a/drivers/mtd/maps/physmap.c ++++ b/drivers/mtd/maps/physmap.c +@@ -78,7 +78,7 @@ static const char *rom_probe_types[] = { + "map_rom", + NULL }; + static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", "afs", +- NULL }; ++ "ar7part", NULL }; + + static int physmap_flash_probe(struct platform_device *dev) + { +--- a/drivers/mtd/Makefile ++++ b/drivers/mtd/Makefile +@@ -10,7 +10,7 @@ obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o + obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o + obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o + obj-$(CONFIG_MTD_AFS_PARTS) += afs.o +-obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o ++obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o titanpart.o + obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o + obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o + diff --git a/target/linux/ar7/patches-3.3/120-gpio_chrdev.patch b/target/linux/ar7/patches-3.3/120-gpio_chrdev.patch new file mode 100644 index 000000000..006cef4d5 --- /dev/null +++ b/target/linux/ar7/patches-3.3/120-gpio_chrdev.patch @@ -0,0 +1,28 @@ +--- a/drivers/char/Kconfig ++++ b/drivers/char/Kconfig +@@ -478,6 +478,15 @@ config MWAVE + 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 +--- a/drivers/char/Makefile ++++ b/drivers/char/Makefile +@@ -44,6 +44,7 @@ obj-$(CONFIG_HW_RANDOM) += hw_random/ + 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 --git a/target/linux/ar7/patches-3.3/160-vlynq_try_remote_first.patch b/target/linux/ar7/patches-3.3/160-vlynq_try_remote_first.patch new file mode 100644 index 000000000..437bc89d9 --- /dev/null +++ b/target/linux/ar7/patches-3.3/160-vlynq_try_remote_first.patch @@ -0,0 +1,20 @@ +--- a/drivers/vlynq/vlynq.c ++++ b/drivers/vlynq/vlynq.c +@@ -514,9 +514,14 @@ static int __vlynq_enable_device(struct + !__vlynq_try_external(dev)) + return 0; + } else { +- if (!__vlynq_try_external(dev) || +- !__vlynq_try_local(dev) || +- !__vlynq_try_remote(dev)) ++ /* XXX: I don't really know what difference it makes, if the order ++ * of the following calls is changed, but at least in this order ++ * my fritzbox doesn't hang at startup as in ++ * https://dev.openwrt.org/ticket/7324 ++ */ ++ if (!__vlynq_try_remote(dev) || ++ !__vlynq_try_local(dev) || ++ !__vlynq_try_external(dev)) + return 0; + } + break; diff --git a/target/linux/ar7/patches-3.3/500-serial_kludge.patch b/target/linux/ar7/patches-3.3/500-serial_kludge.patch new file mode 100644 index 000000000..5c19cf22b --- /dev/null +++ b/target/linux/ar7/patches-3.3/500-serial_kludge.patch @@ -0,0 +1,28 @@ +--- a/drivers/tty/serial/8250/8250.c ++++ b/drivers/tty/serial/8250/8250.c +@@ -290,6 +290,13 @@ static const struct serial8250_config ua + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR, + }, ++ [PORT_AR7] = { ++ .name = "TI-AR7", ++ .fifo_size = 16, ++ .tx_loadsz = 16, ++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, ++ .flags = UART_CAP_FIFO | UART_CAP_AFE, ++ }, + }; + + #if defined(CONFIG_MIPS_ALCHEMY) +@@ -2798,7 +2805,11 @@ static void serial8250_console_putchar(s + struct uart_8250_port *up = + container_of(port, struct uart_8250_port, port); + ++#ifdef CONFIG_AR7 ++ wait_for_xmitr(up, BOTH_EMPTY); ++#else + wait_for_xmitr(up, UART_LSR_THRE); ++#endif + serial_out(up, UART_TX, ch); + } + diff --git a/target/linux/ar7/patches-3.3/920-ar7part.patch b/target/linux/ar7/patches-3.3/920-ar7part.patch new file mode 100644 index 000000000..9cbc53786 --- /dev/null +++ b/target/linux/ar7/patches-3.3/920-ar7part.patch @@ -0,0 +1,56 @@ +--- a/drivers/mtd/ar7part.c ++++ b/drivers/mtd/ar7part.c +@@ -29,11 +29,14 @@ + #include + #include + ++#include ++ + #define AR7_PARTS 4 + #define ROOT_OFFSET 0xe0000 + + #define LOADER_MAGIC1 le32_to_cpu(0xfeedfa42) + #define LOADER_MAGIC2 le32_to_cpu(0xfeed1281) ++#define LOADER_MAGIC3 le32_to_cpu(0x434d4d4c) + + #ifndef SQUASHFS_MAGIC + #define SQUASHFS_MAGIC 0x73717368 +@@ -45,6 +48,10 @@ struct ar7_bin_rec { + unsigned int address; + }; + ++int create_titan_partitions(struct mtd_info *master, ++ struct mtd_partition **pparts, ++ struct mtd_part_parser_data *data); ++ + static int create_mtd_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +@@ -58,6 +65,16 @@ static int create_mtd_partitions(struct + int retries = 10; + struct mtd_partition *ar7_parts; + ++ const char *prod_id ; ++ prod_id = prom_getenv("ProductID"); ++ if(prod_id && ++ (strcmp(prod_id, "CYWL")==0 || ++ strcmp(prod_id, "CYWM")==0 || ++ strcmp(prod_id, "CYLM")==0 || ++ strcmp(prod_id, "CYLL")==0)){ ++ return create_titan_partitions(master, pparts, data); ++ } ++ + ar7_parts = kzalloc(sizeof(*ar7_parts) * AR7_PARTS, GFP_KERNEL); + if (!ar7_parts) + return -ENOMEM; +--- a/drivers/mtd/titanpart.c ++++ b/drivers/mtd/titanpart.c +@@ -149,7 +149,7 @@ static void titan_add_partition(char * e + } + int create_titan_partitions(struct mtd_info *master, + struct mtd_partition **pparts, +- unsigned long origin) ++ struct mtd_part_parser_data *data) + { + struct nsp_img_hdr_head hdr; + struct nsp_img_hdr_section_info sect_info; diff --git a/target/linux/ar7/patches-3.3/950-cpmac_titan.patch b/target/linux/ar7/patches-3.3/950-cpmac_titan.patch new file mode 100644 index 000000000..a829e4e8c --- /dev/null +++ b/target/linux/ar7/patches-3.3/950-cpmac_titan.patch @@ -0,0 +1,52 @@ +--- a/drivers/net/ethernet/ti/cpmac.c ++++ b/drivers/net/ethernet/ti/cpmac.c +@@ -1159,6 +1159,8 @@ static int __devinit cpmac_probe(struct + goto fail; + } + ++ ar7_device_reset(pdata->reset_bit); ++ + dev->irq = platform_get_irq_byname(pdev, "irq"); + + dev->netdev_ops = &cpmac_netdev_ops; +@@ -1237,7 +1239,7 @@ int __devinit cpmac_init(void) + cpmac_mii->reset = cpmac_mdio_reset; + cpmac_mii->irq = mii_irqs; + +- cpmac_mii->priv = ioremap(AR7_REGS_MDIO, 256); ++ cpmac_mii->priv = ioremap(ar7_is_titan() ? TITAN_REGS_MDIO : AR7_REGS_MDIO, 256); + + if (!cpmac_mii->priv) { + printk(KERN_ERR "Can't ioremap mdio registers\n"); +@@ -1248,10 +1250,16 @@ int __devinit cpmac_init(void) + #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); ++ ++ if (!ar7_is_titan()) { ++ ar7_device_reset(AR7_RESET_BIT_CPMAC_LO); ++ ar7_device_reset(AR7_RESET_BIT_CPMAC_HI); ++ } + ar7_device_reset(AR7_RESET_BIT_EPHY); + ++ if (ar7_is_titan()) ++ ar7_device_reset(TITAN_RESET_BIT_EPHY1); ++ + cpmac_mii->reset(cpmac_mii); + + for (i = 0; i < 300; i++) { +@@ -1268,7 +1276,11 @@ int __devinit cpmac_init(void) + mask = 0; + } + +- cpmac_mii->phy_mask = ~(mask | 0x80000000); ++ if (ar7_is_titan()) ++ cpmac_mii->phy_mask = ~(mask | 0x80000000 | 0x40000000); ++ else ++ cpmac_mii->phy_mask = ~(mask | 0x80000000); ++ + snprintf(cpmac_mii->id, MII_BUS_ID_SIZE, "cpmac-1"); + + res = mdiobus_register(cpmac_mii); diff --git a/target/linux/ar7/patches-3.3/972-cpmac_fixup.patch b/target/linux/ar7/patches-3.3/972-cpmac_fixup.patch new file mode 100644 index 000000000..b1eb081c9 --- /dev/null +++ b/target/linux/ar7/patches-3.3/972-cpmac_fixup.patch @@ -0,0 +1,218 @@ +--- a/arch/mips/ar7/platform.c ++++ b/arch/mips/ar7/platform.c +@@ -33,7 +33,6 @@ + #include + #include + #include +-#include + #include + #include + +@@ -248,12 +247,6 @@ static struct resource cpmac_high_res[] + }, + }; + +-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, +@@ -680,26 +673,18 @@ static int __init ar7_register_devices(v + } + + if (ar7_has_high_cpmac()) { +- res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status); +- if (!res) { +- cpmac_get_mac(1, cpmac_high_data.dev_addr); +- +- res = platform_device_register(&cpmac_high); +- if (res) +- pr_warning("unable to register cpmac-high: %d\n", res); +- } else +- pr_warning("unable to add cpmac-high phy: %d\n", res); +- } else +- cpmac_low_data.phy_mask = 0xffffffff; ++ cpmac_get_mac(1, cpmac_high_data.dev_addr); + +- res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status); +- if (!res) { +- cpmac_get_mac(0, cpmac_low_data.dev_addr); +- res = platform_device_register(&cpmac_low); ++ res = platform_device_register(&cpmac_high); + if (res) +- pr_warning("unable to register cpmac-low: %d\n", res); ++ pr_warning("unable to register cpmac-high: %d\n", res); + } else +- pr_warning("unable to add cpmac-low phy: %d\n", res); ++ cpmac_low_data.phy_mask = 0xffffffff; ++ ++ cpmac_get_mac(0, cpmac_low_data.dev_addr); ++ res = platform_device_register(&cpmac_low); ++ if (res) ++ pr_warning("unable to register cpmac-low: %d\n", res); + + detect_leds(); + res = platform_device_register(&ar7_gpio_leds); +@@ -712,8 +697,10 @@ static int __init ar7_register_devices(v + + /* Register watchdog only if enabled in hardware */ + bootcr = ioremap_nocache(AR7_REGS_DCL, 4); +- val = readl(bootcr); +- iounmap(bootcr); ++ if (bootcr) { ++ val = readl(bootcr); ++ iounmap(bootcr); ++ } + if (val & AR7_WDT_HW_ENA) { + if (ar7_has_high_vlynq()) + ar7_wdt_res.start = UR8_REGS_WDT; +--- a/arch/mips/include/asm/mach-ar7/ar7.h ++++ b/arch/mips/include/asm/mach-ar7/ar7.h +@@ -42,6 +42,7 @@ + #define AR7_REGS_PINSEL (AR7_REGS_BASE + 0x160C) + #define AR7_REGS_VLYNQ0 (AR7_REGS_BASE + 0x1800) + #define AR7_REGS_DCL (AR7_REGS_BASE + 0x1a00) ++#define AR7_REGS_MII (AR7_REGS_BASE + 0x1a08) + #define AR7_REGS_VLYNQ1 (AR7_REGS_BASE + 0x1c00) + #define AR7_REGS_MDIO (AR7_REGS_BASE + 0x1e00) + #define AR7_REGS_IRQ (AR7_REGS_BASE + 0x2400) +--- a/drivers/net/ethernet/ti/cpmac.c ++++ b/drivers/net/ethernet/ti/cpmac.c +@@ -35,7 +35,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -48,14 +47,11 @@ 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 */ ++/* Next is 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.2" + /* frame size + 802.1q tag + FCS size */ +@@ -674,9 +670,8 @@ static void cpmac_hw_start(struct net_de + 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_MAC_ADDR_HI, be32_to_cpu(*(u32 *) ++ dev->dev_addr)); + 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); +@@ -1108,8 +1103,6 @@ static const struct net_device_ops cpmac + .ndo_set_mac_address = eth_mac_addr, + }; + +-static int external_switch; +- + static int __devinit cpmac_probe(struct platform_device *pdev) + { + int rc, phy_id; +@@ -1121,25 +1114,18 @@ static int __devinit cpmac_probe(struct + + pdata = pdev->dev.platform_data; + +- if (external_switch || dumb_switch) { +- strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); /* fixed phys bus */ +- phy_id = pdev->id; +- } else { +- 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; +- strncpy(mdio_bus_id, cpmac_mii->id, MII_BUS_ID_SIZE); +- break; +- } ++ 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; ++ strncpy(mdio_bus_id, cpmac_mii->id, MII_BUS_ID_SIZE); ++ break; + } + + if (phy_id == PHY_MAX_ADDR) { +- dev_err(&pdev->dev, "no PHY present, falling back " +- "to switch on MDIO bus 0\n"); +- strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); /* fixed phys bus */ +- phy_id = pdev->id; ++ printk(KERN_ERR "cpmac: No PHY present\n"); ++ return -ENXIO; + } + + dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES); +@@ -1228,6 +1214,7 @@ int __devinit cpmac_init(void) + { + u32 mask; + int i, res; ++ void __iomem *mii_reg; + + cpmac_mii = mdiobus_alloc(); + if (cpmac_mii == NULL) +@@ -1251,14 +1238,14 @@ int __devinit cpmac_init(void) + ar7_gpio_disable(26); + ar7_gpio_disable(27); + +- if (!ar7_is_titan()) { ++ if (ar7_is_titan()) { ++ ar7_device_reset(AR7_RESET_BIT_EPHY); ++ ar7_device_reset(TITAN_RESET_BIT_EPHY1); ++ } else { ++ ar7_device_reset(AR7_RESET_BIT_EPHY); + ar7_device_reset(AR7_RESET_BIT_CPMAC_LO); + ar7_device_reset(AR7_RESET_BIT_CPMAC_HI); + } +- ar7_device_reset(AR7_RESET_BIT_EPHY); +- +- if (ar7_is_titan()) +- ar7_device_reset(TITAN_RESET_BIT_EPHY1); + + cpmac_mii->reset(cpmac_mii); + +@@ -1270,10 +1257,22 @@ int __devinit cpmac_init(void) + msleep(10); + } + +- mask &= 0x7fffffff; ++ mask &= ar7_is_titan()? ~(0x80000000 | 0x40000000) : ~(0x80000000); + if (mask & (mask - 1)) { +- external_switch = 1; +- mask = 0; ++ if (!ar7_has_high_cpmac()) { ++ if (ar7_is_titan()) { ++ ar7_device_disable(AR7_RESET_BIT_EPHY); ++ ar7_device_disable(TITAN_RESET_BIT_EPHY1); ++ } else ++ ar7_device_disable(AR7_RESET_BIT_EPHY); ++ ++ //Titan remap might be different ++ mii_reg = ioremap(AR7_REGS_MII, 4); ++ if (mii_reg) { ++ writel(readl(mii_reg) | 1, mii_reg); ++ iounmap(mii_reg); ++ } ++ } + } + + if (ar7_is_titan()) diff --git a/target/linux/ar7/profiles/100-Annex-A.mk b/target/linux/ar7/profiles/100-Annex-A.mk new file mode 100644 index 000000000..3d74b5d7d --- /dev/null +++ b/target/linux/ar7/profiles/100-Annex-A.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Annex-A + NAME:=Annex-A DSL firmware (default) + PACKAGES:=kmod-sangam-atm-annex-a +endef + +define Profile/Annex-A/Description + Package set compatible with Annex-A DSL lines (most countries). +endef +$(eval $(call Profile,Annex-A)) + diff --git a/target/linux/ar7/profiles/110-Annex-B.mk b/target/linux/ar7/profiles/110-Annex-B.mk new file mode 100644 index 000000000..66692e796 --- /dev/null +++ b/target/linux/ar7/profiles/110-Annex-B.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Annex-B + NAME:=Annex-B DSL firmware + PACKAGES:=kmod-sangam-atm-annex-b +endef + +define Profile/Annex-B/Description + Package set compatible with Annex-B DSL lines (Germany). +endef +$(eval $(call Profile,Annex-B)) + diff --git a/target/linux/ar7/profiles/200-Texas.mk b/target/linux/ar7/profiles/200-Texas.mk new file mode 100644 index 000000000..7d868bdb0 --- /dev/null +++ b/target/linux/ar7/profiles/200-Texas.mk @@ -0,0 +1,18 @@ +# +# Copyright (C) 2006-2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Texas + NAME:=Texas Instruments WiFi (mac80211) + PACKAGES:=kmod-acx-mac80211 +endef + +define Profile/Texas/Description + Package set compatible with hardware using Texas Instruments WiFi cards + using the mac80211 driver. +endef +$(eval $(call Profile,Texas)) + diff --git a/target/linux/ar7/profiles/210-None.mk b/target/linux/ar7/profiles/210-None.mk new file mode 100644 index 000000000..2fcfacde9 --- /dev/null +++ b/target/linux/ar7/profiles/210-None.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/None + NAME:=No WiFi + PACKAGES:= +endef + +define Profile/None/Description + Package set without WiFi support +endef +$(eval $(call Profile,None)) + diff --git a/target/linux/ar7/src/adam2patcher.c b/target/linux/ar7/src/adam2patcher.c new file mode 100644 index 000000000..25a78074a --- /dev/null +++ b/target/linux/ar7/src/adam2patcher.c @@ -0,0 +1,59 @@ +/* + * patcher.c - ADAM2 patcher for Netgear DG834 (and compatible) + * + * Copyright (C) 2006 Felix Fietkau + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int main(int argc, char **argv) +{ + int fd; + char *ptr; + uint32_t *i; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + + if (((fd = open(argv[1], O_RDWR)) < 0) + || ((ptr = mmap(0, 128 * 1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == (void *) (-1))) { + fprintf(stderr, "Can't open file\n"); + exit(1); + } + + i = (uint32_t *) &ptr[0x3944]; + if (*i == 0x0c000944) { + fprintf(stderr, "Unpatched ADAM2 detected. Patching... "); + *i = 0x00000000; + msync(i, sizeof(*i), MS_SYNC|MS_INVALIDATE); + fprintf(stderr, "done!\n"); + } else if (*i == 0x00000000) { + fprintf(stderr, "Patched ADAM2 detected.\n"); + } else { + fprintf(stderr, "Unknown ADAM2 detected. Can't patch!\n"); + } + + close(fd); +} diff --git a/target/linux/ar71xx/Makefile b/target/linux/ar71xx/Makefile new file mode 100644 index 000000000..f86399381 --- /dev/null +++ b/target/linux/ar71xx/Makefile @@ -0,0 +1,29 @@ +# +# Copyright (C) 2008-2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +ARCH:=mips +BOARD:=ar71xx +BOARDNAME:=Atheros AR7xxx/AR9xxx +FEATURES:=squashfs jffs2 targz +CFLAGS:=-Os -pipe -mips32r2 -mtune=mips32r2 -fno-caller-saves +SUBTARGETS:=generic nand + +LINUX_VERSION:=3.3.8 + +include $(INCLUDE_DIR)/target.mk + +DEFAULT_PACKAGES += \ + kmod-leds-gpio kmod-gpio-button-hotplug kmod-wdt-ath79 swconfig \ + kmod-ledtrig-default-on kmod-ledtrig-timer kmod-ledtrig-netdev \ + kmod-ath9k wpad-mini uboot-envtools + +define Target/Description + Build firmware images for Atheros AR7xxx/AR9xxx based boards. +endef + +$(eval $(call BuildTarget)) diff --git a/target/linux/ar71xx/base-files.mk b/target/linux/ar71xx/base-files.mk new file mode 100644 index 000000000..d6682bd38 --- /dev/null +++ b/target/linux/ar71xx/base-files.mk @@ -0,0 +1,5 @@ +define Package/base-files/install-target + rm -f $(1)/etc/config/network +endef + + diff --git a/target/linux/ar71xx/base-files/etc/defconfig/wndr3700/network b/target/linux/ar71xx/base-files/etc/defconfig/wndr3700/network new file mode 100644 index 000000000..69d7dc712 --- /dev/null +++ b/target/linux/ar71xx/base-files/etc/defconfig/wndr3700/network @@ -0,0 +1,69 @@ +config interface loopback + option ifname lo + option proto static + option ipaddr 127.0.0.1 + option netmask 255.0.0.0 + +config interface lan + option ifname eth0.1 + option type bridge + option proto static + option ipaddr 192.168.1.1 + option netmask 255.255.255.0 + +config interface wan + option ifname eth1 + option proto dhcp + +config switch + option name rtl8366s + option reset 1 + option enable_vlan 1 + # Blinkrate: 0=43ms; 1=84ms; 2=120ms; 3=170ms; 4=340ms; 5=670ms + option blinkrate 2 + +config switch_vlan + option device rtl8366s + option vlan 1 + option ports "0 1 2 3 5t" + +config switch_port + # Port 1 controls the GREEN configuration of LEDs for + # the switch and the section does not correspond to a real + # switch port. + # + # 0=LED off; 1=Collision/FDX; 2=Link/activity; 3=1000 Mb/s; + # 4=100 Mb/s; 5=10 Mb/s; 6=1000 Mb/s+activity; 7=100 Mb/s+activity; + # 8=10 Mb/s+activity; 9=10/100 Mb/s+activity; 10: Fiber; + # 11: Fault; 12: Link/activity(tx); 13: Link/activity(rx); + # 14: Link (master); 15: separate register + + option device rtl8366s + option port 1 + option led 6 + +config switch_port + # Port 2 controls the ORANGE configuration of LEDs for + # the switch and the section does not correspond to a real + # switch port. + # + # See the key above for switch port 1 for the meaning of the + # 'led' setting below. + + option device rtl8366s + option port 2 + option led 9 + +config switch_port + # Port 5 controls the configuration of the WAN LED and the + # section does not correspond to a real switch port. + # + # To toggle the use of green or orange LEDs for the WAN port, + # see the LED setting for wndr3700:green:wan in /etc/config/system. + # + # See the key above for switch port 1 for the meaning of the + # 'led' setting below. + + option device rtl8366s + option port 5 + option led 2 diff --git a/target/linux/ar71xx/base-files/etc/diag.sh b/target/linux/ar71xx/base-files/etc/diag.sh new file mode 100755 index 000000000..c3f97345c --- /dev/null +++ b/target/linux/ar71xx/base-files/etc/diag.sh @@ -0,0 +1,196 @@ +#!/bin/sh +# +# Copyright (C) 2009 OpenWrt.org +# +# + +. /lib/ar71xx.sh + +status_led="" + +led_set_attr() { + [ -f "/sys/class/leds/$1/$2" ] && echo "$3" > "/sys/class/leds/$1/$2" +} + +status_led_set_timer() { + led_set_attr $status_led "trigger" "timer" + led_set_attr $status_led "delay_on" "$1" + led_set_attr $status_led "delay_off" "$2" +} + +status_led_on() { + led_set_attr $status_led "trigger" "none" + led_set_attr $status_led "brightness" 255 +} + +status_led_off() { + led_set_attr $status_led "trigger" "none" + led_set_attr $status_led "brightness" 0 +} + +get_status_led() { + case $(ar71xx_board_name) in + alfa-nx) + status_led="alfa:green:led_8" + ;; + all0305) + status_led="eap7660d:green:ds4" + ;; + ap136) + status_led="ap136:green:status" + ;; + ap81) + status_led="ap81:green:status" + ;; + ap83) + status_led="ap83:green:power" + ;; + ap96) + status_led="ap96:green:led2" + ;; + aw-nr580) + status_led="aw-nr580:green:ready" + ;; + bullet-m | rocket-m | nano-m | nanostation-m) + status_led="ubnt:green:link4" + ;; + db120) + status_led="db120:green:status" + ;; + dir-600-a1 |\ + dir-615-e4) + status_led="d-link:green:power" + ;; + dir-615-c1) + status_led="d-link:green:status" + ;; + dir-825-b1) + status_led="d-link:orange:power" + ;; + eap7660d) + status_led="eap7660d:green:ds4" + ;; + hornet-ub) + status_led="alfa:blue:wps" + ;; + ja76pf | \ + ja76pf2) + status_led="jjplus:green:led1" + ;; + ls-sr71) + status_led="ubnt:green:d22" + ;; + mzk-w04nu | \ + mzk-w300nh) + status_led="planex:green:status" + ;; + nbg460n_550n_550nh) + status_led="nbg460n:green:power" + ;; + om2p | \ + om2p-lc) + status_led="om2p:blue:power" + ;; + pb44) + status_led="pb44:amber:jump1" + ;; + rb-411 | rb-411u | rb-433 | rb-433u | rb-450 | rb-450g | rb-493) + status_led="rb4xx:yellow:user" + ;; + rb-750) + status_led="rb750:green:act" + ;; + routerstation | routerstation-pro) + status_led="ubnt:green:rf" + ;; + rw2458n) + status_led="rw2458n:green:d3" + ;; + tew-632brp) + status_led="tew-632brp:green:status" + ;; + tew-673gru) + status_led="trendnet:blue:wps" + ;; + tew-712br) + status_led="trendnet:green:power" + ;; + tl-mr3020) + status_led="tp-link:green:wps" + ;; + tl-mr3220 | \ + tl-mr3420 | \ + tl-wa901nd | \ + tl-wa901nd-v2 | \ + tl-wr1041n-v2 | \ + tl-wr1043nd | \ + tl-wr741nd | \ + tl-wr741nd-v4 | \ + tl-wr841n-v1 | \ + tl-wr841n-v7 | \ + tl-wr841n-v8 | \ + tl-wr941nd) + status_led="tp-link:green:system" + ;; + tl-wdr4300 | \ + tl-wr703n) + status_led="tp-link:blue:system" + ;; + tl-wr2543n) + status_led="tp-link:green:wps" + ;; + unifi) + status_led="ubnt:green:dome" + ;; + whr-g301n | \ + whr-hp-g300n | \ + whr-hp-gn | \ + wzr-hp-g300nh) + status_led="buffalo:green:router" + ;; + wlae-ag300n) + status_led="buffalo:green:status" + ;; + wzr-hp-ag300h | \ + wzr-hp-g300nh2) + status_led="buffalo:red:diag" + ;; + wndr3700) + status_led="wndr3700:green:power" + ;; + wnr2000) + status_led="wnr2000:green:power" + ;; + wp543) + status_led="wp543:green:diag" + ;; + wrt400n) + status_led="wrt400n:blue:wps" + ;; + wrt160nl) + status_led="wrt160nl:blue:wps" + ;; + zcn-1523h-2 | zcn-1523h-5) + status_led="zcn-1523h:amber:init" + ;; + esac; +} + +set_state() { + get_status_led + + case "$1" in + preinit) + insmod leds-gpio + insmod ledtrig-default-on + insmod ledtrig-timer + status_led_set_timer 200 200 + ;; + failsafe) + status_led_set_timer 50 50 + ;; + done) + status_led_on + ;; + esac +} diff --git a/target/linux/ar71xx/base-files/etc/hotplug.d/net/10-ar922x-led-fix b/target/linux/ar71xx/base-files/etc/hotplug.d/net/10-ar922x-led-fix new file mode 100644 index 000000000..102415009 --- /dev/null +++ b/target/linux/ar71xx/base-files/etc/hotplug.d/net/10-ar922x-led-fix @@ -0,0 +1,51 @@ +#!/bin/sh + +# For AR9220 and AR9223, GPIO JTAG must explicit be disabled +# before LEDs start working. Do this when wifi device is +# detected. + +# +# $DEVPATH is not valid for some boards (including WZR-HP-AG300H). +# Manipulate the $DEVPATH to reach the corresponding phyN. +# + +devdir=`dirname $DEVPATH` +devdir=`dirname $devdir` +phydir=/sys$devdir/ieee80211 +phyname=`cat $phydir/phy*/name` + +if [ -z $phyname -o $ACTION != "add" ]; then exit 0; fi + +# +# ar922x_disable_gpio_jtag(): +# +# Emulate +# REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); +# for AR9220 and AR9223. +# + +ar922x_disable_gpio_jtag() +{ + local regidx=0x4054 + + [ -f /sys/kernel/debug/ieee80211/$1/ath9k/regidx ] && { + echo $regidx > /sys/kernel/debug/ieee80211/$1/ath9k/regidx + regval=`cat /sys/kernel/debug/ieee80211/$1/ath9k/regval` + regval=$((regval | 0x20000)) + echo regval $regval + echo $regval > /sys/kernel/debug/ieee80211/$1/ath9k/regval + } +} + +if [ $phyname -a $ACTION = "add" ]; then + + . /lib/ar71xx.sh + + case $(ar71xx_board_name) in + wzr-hp-ag300h) + ar922x_disable_gpio_jtag $phyname + ;; + esac; +fi + +exit 0 diff --git a/target/linux/ar71xx/base-files/etc/init.d/defconfig b/target/linux/ar71xx/base-files/etc/init.d/defconfig new file mode 100755 index 000000000..364fa4a6a --- /dev/null +++ b/target/linux/ar71xx/base-files/etc/init.d/defconfig @@ -0,0 +1,20 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (C) 2009 OpenWrt.org +# + +START=05 + +start() { + . /lib/ar71xx.sh + + local board=$(ar71xx_board_name) + + [ ! -d /etc/defconfig/$board ] && return 0 + + for f in $( ls /etc/defconfig/$board ); do + if [ ! -e /etc/config/$f ]; then + cp /etc/defconfig/$board/$f /etc/config/ + fi + done +} diff --git a/target/linux/ar71xx/base-files/etc/inittab b/target/linux/ar71xx/base-files/etc/inittab new file mode 100644 index 000000000..17f829f6d --- /dev/null +++ b/target/linux/ar71xx/base-files/etc/inittab @@ -0,0 +1,2 @@ +::sysinit:/etc/init.d/rcS S boot +::shutdown:/etc/init.d/rcS K shutdown diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/inittab-console-fixup b/target/linux/ar71xx/base-files/etc/uci-defaults/inittab-console-fixup new file mode 100755 index 000000000..4098b37a7 --- /dev/null +++ b/target/linux/ar71xx/base-files/etc/uci-defaults/inittab-console-fixup @@ -0,0 +1,27 @@ +#!/bin/sh +# +# Copyright (C) 2011 OpenWrt.org +# + +enable_console_login() { + local cons=$1 + local initline="$cons::askfirst:/bin/ash --login" + + grep -qs "^$initline" /etc/inittab || { + echo "$initline" >> /etc/inittab + sync + kill -HUP 1 + } +} + +inittab_console_fixup() { + for cons in ttyS0 ttyATH0; do + grep -qs "console=$cons" /proc/cmdline && { + enable_console_login $cons + } + done +} + +inittab_console_fixup + +exit 0 diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/leds b/target/linux/ar71xx/base-files/etc/uci-defaults/leds new file mode 100755 index 000000000..cb4b68299 --- /dev/null +++ b/target/linux/ar71xx/base-files/etc/uci-defaults/leds @@ -0,0 +1,209 @@ +#!/bin/sh +# +# Copyright (C) 2011 OpenWrt.org +# + +. /lib/functions/uci-defaults.sh +. /lib/ar71xx.sh + +board=$(ar71xx_board_name) + +case "$board" in +alfa-nx) + ucidef_set_led_netdev "wan" "WAN" "alfa:green:led_2" "eth0" + ucidef_set_led_netdev "lan" "LAN" "alfa:green:led_3" "eth1" + ;; + +all0258n) + ucidef_set_rssimon "wlan0" "40000" "1" + ucidef_set_led_rssi "rssilow" "RSSILOW" "all0258n:red:rssilow" "wlan0" "1" "40" "0" "6" + ucidef_set_led_rssi "rssimedium" "RSSIMEDIUM" "all0258n:yellow:rssimedium" "wlan0" "30" "80" "-29" "5" + ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "all0258n:green:rssihigh" "wlan0" "70" "100" "-69" "8" + ;; + +all0315n) + ucidef_set_rssimon "wlan0" "40000" "1" + ucidef_set_led_rssi "rssilow" "RSSILOW" "all0315n:red:rssilow" "wlan0" "1" "40" "0" "6" + ucidef_set_led_rssi "rssimedium" "RSSIMEDIUM" "all0315n:yellow:rssimedium" "wlan0" "30" "80" "-29" "5" + ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "all0315n:green:rssihigh" "wlan0" "70" "100" "-69" "8" + ;; + +ap113) + ucidef_set_led_usbdev "usb" "USB" "ap113:green:usb" "1-1" + ;; + +db120) + ucidef_set_led_usbdev "usb" "USB" "db120:green:usb" "1-1" + ;; + +rb750) + ucidef_set_led_default "act" "act" "rb750:green:act" "1" + ucidef_set_led_netdev "port1" "port1" "rb750:green:port1" "eth1" + ucidef_set_led_switch "port2" "port2" "rb750:green:port2" "switch0" "0x10" + ucidef_set_led_switch "port3" "port3" "rb750:green:port3" "switch0" "0x08" + ucidef_set_led_switch "port4" "port4" "rb750:green:port4" "switch0" "0x04" + ucidef_set_led_switch "port5" "port5" "rb750:green:port5" "switch0" "0x02" + ;; + +dir-600-a1|\ +dir-615-e4) + ucidef_set_led_netdev "wan" "WAN" "d-link:green:wan" "eth1" + ucidef_set_led_switch "lan1" "LAN1" "d-link:green:lan1" "switch0" "0x02" + ucidef_set_led_switch "lan2" "LAN2" "d-link:green:lan2" "switch0" "0x04" + ucidef_set_led_switch "lan3" "LAN3" "d-link:green:lan3" "switch0" "0x08" + ucidef_set_led_switch "lan4" "LAN4" "d-link:green:lan4" "switch0" "0x10" + ;; + +dir-825-b1) + ucidef_set_led_usbdev "usb" "USB" "d-link:blue:usb" "1-1" + ;; + +hornet-ub) + ucidef_set_led_netdev "lan" "LAN" "alfa:blue:lan" "eth0" + ucidef_set_led_netdev "wan" "WAN" "alfa:blue:wan" "eth1" + ucidef_set_led_wlan "wlan" "WLAN" "alfa:blue:wlan" "phy0tpt" + ucidef_set_led_usbdev "usb" "USB" "alfa:blue:usb" "1-1" + ;; + +mzk-w04u) + ucidef_set_led_usbdev "usb" "USB" "planex:green:usb" "1-1" + ;; + +mzk-w300nh) + ucidef_set_led_wlan "wlan" "WLAN" "planex:green:wlan" "phy0tpt" + ;; + +nbg460n_550n_550nh) + ucidef_set_led_wlan "wlan" "WLAN" "nbg460n:green:wlan" "phy0tpt" + ;; + +om2p | \ +om2p-lc) + ucidef_set_led_netdev "port1" "port1" "om2p:blue:wan" "eth0" + ucidef_set_led_netdev "port2" "port2" "om2p:blue:lan" "eth1" + ;; + +tew-712br) + ucidef_set_led_netdev "wan" "WAN" "trendnet:green:wan" "eth1" + ucidef_set_led_switch "lan1" "LAN1" "trendnet:green:lan1" "switch0" "0x02" + ucidef_set_led_switch "lan2" "LAN2" "trendnet:green:lan2" "switch0" "0x04" + ucidef_set_led_switch "lan3" "LAN3" "trendnet:green:lan3" "switch0" "0x08" + ucidef_set_led_switch "lan4" "LAN4" "trendnet:green:lan4" "switch0" "0x10" + ucidef_set_led_wlan "wlan" "WLAN" "trendnet:green:wlan" "phy0tpt" + ;; + +tl-mr11u | \ +tl-mr3020 | \ +tl-mr3040) + ucidef_set_led_usbdev "usb" "USB" "tp-link:green:3g" "1-1" + ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" + ucidef_set_led_netdev "lan" "LAN" "tp-link:green:lan" "eth0" + ;; + +tl-mr3220 | \ +tl-mr3420 ) + ucidef_set_led_usbdev "usb" "USB" "tp-link:green:3g" "1-1" + ;; + +tl-wa901nd) + ucidef_set_led_netdev "lan" "LAN" "tp-link:green:lan" "eth0" + ;; + +tl-wa901nd-v2) + ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" + ;; + +tl-wdr4300) + ucidef_set_led_usbdev "usb1" "USB1" "tp-link:green:usb1" "1-1.1" + ucidef_set_led_usbdev "usb2" "USB2" "tp-link:green:usb2" "1-1.2" + ucidef_set_led_wlan "wlan2g" "WLAN2G" "tp-link:blue:wlan2g" "phy0tpt" + ;; + +tl-wr741nd) + ucidef_set_led_netdev "wan" "WAN" "tp-link:green:wan" "eth1" + ucidef_set_led_switch "lan1" "LAN1" "tp-link:green:lan1" "switch0" "0x02" + ucidef_set_led_switch "lan2" "LAN2" "tp-link:green:lan2" "switch0" "0x04" + ucidef_set_led_switch "lan3" "LAN3" "tp-link:green:lan3" "switch0" "0x08" + ucidef_set_led_switch "lan4" "LAN4" "tp-link:green:lan4" "switch0" "0x10" + ;; + +tl-wr741nd-v4) + ucidef_set_led_netdev "wan" "WAN" "tp-link:green:wan" "eth1" + ucidef_set_led_switch "lan1" "LAN1" "tp-link:green:lan1" "switch0" "0x04" + ucidef_set_led_switch "lan2" "LAN2" "tp-link:green:lan2" "switch0" "0x08" + ucidef_set_led_switch "lan3" "LAN3" "tp-link:green:lan3" "switch0" "0x10" + ucidef_set_led_switch "lan4" "LAN4" "tp-link:green:lan4" "switch0" "0x02" + ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" + ;; + +tl-wr841n-v8) + ucidef_set_led_netdev "wan" "WAN" "tp-link:green:wan" "eth0" + ucidef_set_led_switch "lan1" "LAN1" "tp-link:green:lan1" "switch0" "0x04" + ucidef_set_led_switch "lan2" "LAN2" "tp-link:green:lan2" "switch0" "0x08" + ucidef_set_led_switch "lan3" "LAN3" "tp-link:green:lan3" "switch0" "0x10" + ucidef_set_led_switch "lan4" "LAN4" "tp-link:green:lan4" "switch0" "0x02" + ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" + ;; + +tl-wr941nd | \ +tl-wr1041n-v2) + ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" + ;; + +tl-wr1043nd) + ucidef_set_led_usbdev "usb" "USB" "tp-link:green:usb" "1-1" + ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" + ;; + +tl-wr2543n) + ucidef_set_led_usbdev "usb" "USB" "tp-link:green:usb" "1-1" + ;; + +wrt160nl) + ucidef_set_led_wlan "wlan" "WLAN" "wrt160nl:blue:wlan" "phy0tpt" + ;; + +wndr3700) + ucidef_set_led_default "wan" "WAN LED (green)" "wndr3700:green:wan" "0" + ucidef_set_led_usbdev "usb" "USB" "wndr3700:green:usb" "1-1" + ;; + +whr-g301n |\ +whr-hp-g300n |\ +whr-hp-gn) + ucidef_set_led_netdev "wan" "WAN" "buffalo:green:wan" "eth1" + ucidef_set_led_switch "lan1" "LAN1" "buffalo:green:lan1" "switch0" "0x02" + ucidef_set_led_switch "lan2" "LAN2" "buffalo:green:lan2" "switch0" "0x04" + ucidef_set_led_switch "lan3" "LAN3" "buffalo:green:lan3" "switch0" "0x08" + ucidef_set_led_switch "lan4" "LAN4" "buffalo:green:lan4" "switch0" "0x10" + ;; + +wlae-ag300n) + ucidef_set_led_netdev "wireless" "WIRELESS" "buffalo:green:wireless" "wlan0" + ;; + +wzr-hp-ag300h) + ucidef_set_led_default "diag" "DIAG" "buffalo:red:diag" "0" + ucidef_set_led_netdev "router" "ROUTER" "buffalo:green:router" "eth1" + ucidef_set_led_usbdev "usb" "USB" "buffalo:green:usb" "1-1" + ;; + +wzr-hp-g300nh) + ucidef_set_led_wlan "wlan" "Wireless" "buffalo:green:wireless" "phy0tpt" + ucidef_set_led_netdev "router" "Router" "buffalo:green:router" "eth1" + ucidef_set_led_usbdev "usb" "USB" "buffalo:blue:usb" "1-1" + ;; + +zcn-1523h-2) + ucidef_set_led_netdev "lan1" "lan1" "zcn-1523h:green:lan1" "eth0" + ;; + +zcn-1523h-5) + ucidef_set_led_netdev "lan1" "lan1" "zcn-1523h:green:lan1" "eth0" + ucidef_set_led_netdev "lan2" "lan2" "zcn-1523h:green:lan2" "eth1" + ;; +esac + +ucidef_commit_leds + +exit 0 diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/network b/target/linux/ar71xx/base-files/etc/uci-defaults/network new file mode 100755 index 000000000..cd9e997d8 --- /dev/null +++ b/target/linux/ar71xx/base-files/etc/uci-defaults/network @@ -0,0 +1,215 @@ +#!/bin/sh +# +# Copyright (C) 2011 OpenWrt.org +# + +[ -e /etc/config/network ] && exit 0 + +touch /etc/config/network + +. /lib/functions/uci-defaults.sh +. /lib/ar71xx.sh + +ucidef_set_interface_loopback + +board=$(ar71xx_board_name) + +case "$board" in +all0315n |\ +all0258n |\ +ja76pf2) + ucidef_set_interface_lan "eth0 eth1" + ;; + +db120 |\ +rb-2011l | \ +rb-2011uas-2hnd) + ucidef_set_interfaces_lan_wan "eth0.1 eth1" "eth0.2" + ucidef_add_switch "eth0" "1" "1" + ucidef_add_switch_vlan "eth0" "1" "0t 2 3 4 5" + ucidef_add_switch_vlan "eth0" "2" "0t 1" + ucidef_add_switch "eth1" "1" "1" + ucidef_add_switch_vlan "eth1" "1" "0 1 2 3 4 5" + ;; + +dir-825-b1|\ +tew-673gru) + ucidef_set_interfaces_lan_wan "eth0.1" "eth1" + ucidef_add_switch "rtl8366s" "1" "1" + ucidef_add_switch_vlan "rtl8366s" "1" "0 1 2 3 5t" + ;; + +nbg460n_550n_550nh) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_switch "rtl8366s" "1" "1" + ucidef_add_switch_vlan "rtl8366s" "0" "0 1 2 3 5" + ;; + +rb-433 |\ +rb-433u) + ucidef_set_interfaces_lan_wan "eth1" "eth0" + ucidef_add_switch "switch0" "1" "1" + ucidef_add_switch_vlan "switch0" "1" "1 2 5" + ;; + +rb-450) + ucidef_set_interfaces_lan_wan "eth1" "eth0" + ucidef_add_switch "eth1" "1" "1" + ucidef_add_switch_vlan "eth1" "1" "0 1 2 3 5" + ;; + +rb-450g |\ +routerstation-pro) + ucidef_set_interfaces_lan_wan "eth1" "eth0" + ucidef_add_switch "switch0" "1" "1" + ucidef_add_switch_vlan "switch0" "1" "0 1 2 3 4" + ;; + +ap136 |\ +rb-750gl |\ +rb-751g |\ +wzr-hp-g450h) + ucidef_set_interfaces_lan_wan "eth0.1" "eth0.2" + ucidef_add_switch "switch0" "1" "1" + ucidef_add_switch_vlan "switch0" "1" "0t 2 3 4 5" + ucidef_add_switch_vlan "switch0" "2" "0t 1" + ;; + +rb-493g) + ucidef_set_interfaces_lan_wan "eth0 eth1.1" "eth1.2" + ucidef_add_switch "switch0" "1" "1" + ucidef_add_switch_vlan "switch0" "1" "0 1 2 3 4" + ucidef_add_switch "switch1" "1" "1" + ucidef_add_switch_vlan "switch1" "1" "0t 1 2 3 4" + ucidef_add_switch_vlan "switch1" "2" "0t 5" + ;; + +wzr-hp-g300nh2 |\ +pb92 |\ +ap113) + ucidef_set_interfaces_lan_wan "eth0.1" "eth0.2" + ucidef_add_switch "eth0" "1" "1" + ucidef_add_switch_vlan "eth0" "1" "0t 1 3 4 5" + ucidef_add_switch_vlan "eth0" "2" "0t 2" + ;; + +tl-wdr4300|\ +tl-wr1041n-v2) + ucidef_set_interfaces_lan_wan "eth0.1" "eth0.2" + ucidef_add_switch "eth0" "1" "1" + ucidef_add_switch_vlan "eth0" "1" "0t 2 3 4 5" + ucidef_add_switch_vlan "eth0" "2" "0t 1" + ;; + +tl-wr1043nd) + ucidef_set_interfaces_lan_wan "eth0.1" "eth0.2" + ucidef_add_switch "rtl8366rb" "1" "1" + ucidef_add_switch_vlan "rtl8366rb" "1" "1 2 3 4 5t" + ucidef_add_switch_vlan "rtl8366rb" "2" "0 5t" + ;; + +tl-wr2543n) + ucidef_set_interfaces_lan_wan "eth0.1" "eth0.2" + ucidef_add_switch "switch0" "1" "1" + ucidef_add_switch_vlan "switch0" "1" "1 2 3 4 9t" + ucidef_add_switch_vlan "switch0" "2" "0 9t" + ;; + +tl-wr841n-v1|\ +tl-wr941nd) + ucidef_set_interface_raw "eth" "eth0" + ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan" + ;; + +tl-wr841n-v8) + ucidef_set_interfaces_lan_wan "eth1" "eth0" + ucidef_add_switch "switch0" "1" "1" + ucidef_add_switch_vlan "switch0" "1" "0 1 2 3 4" + ;; + +wrt160nl) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_switch "eth0" "1" "1" + ucidef_add_switch_vlan "eth0" "1" "0 1 2 3 4 5" + ;; + +wzr-hp-g300nh) + ucidef_set_interfaces_lan_wan "eth0.1" "eth1" + ucidef_add_switch "switch0" "1" "1" + ucidef_add_switch_vlan "switch0" "1" "0 1 2 3 5t" + ;; + +all0305 |\ +aw-nr580 |\ +bullet-m |\ +eap7660d |\ +ew-dorin |\ +rb-411 |\ +tl-mr11u |\ +tl-mr3020 |\ +tl-mr3040 |\ +tl-wa901nd |\ +tl-wa901nd-v2 |\ +tl-wr703n |\ +wp543) + ucidef_set_interface_lan "eth0" + ;; + +alfa-ap96 |\ +alfa-nx |\ +ap83 |\ +jwap003 |\ +pb42 |\ +pb44 |\ +routerstation|\ +wpe72) + ucidef_set_interfaces_lan_wan "eth1" "eth0" + ;; + +ap121 |\ +ap121-mini |\ +ap96 |\ +airrouter |\ +dir-600-a1 |\ +dir-615-c1 |\ +dir-615-e4 |\ +ja76pf |\ +rb-750 |\ +rb-751 |\ +tew-632brp |\ +tew-712br |\ +tl-mr3220 |\ +tl-mr3420 |\ +tl-wr741nd |\ +tl-wr741nd-v4 |\ +tl-wr841n-v7 |\ +whr-g301n |\ +whr-hp-g300n |\ +whr-hp-gn |\ +wzr-hp-ag300h) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_switch "eth0" "1" "1" + ucidef_add_switch_vlan "eth0" "1" "0 1 2 3 4" + ;; + +wzr-hp-g450h) + ucidef_set_interfaces_lan_wan "eth0.1" "eth0.2" + ucidef_add_switch "eth0" "1" "1" + ucidef_add_switch_vlan "eth0" "1" "0t 2 3 4 5" + ucidef_add_switch_vlan "eth0" "2" "0t 1" + ;; + +ew-dorin-router) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ucidef_add_switch "eth0" "1" "1" + ucidef_add_switch_vlan "eth0" "1" "0 2 3" + ;; + +*) + ucidef_set_interfaces_lan_wan "eth0" "eth1" + ;; +esac + +uci commit network + +exit 0 diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/vlan-migration b/target/linux/ar71xx/base-files/etc/uci-defaults/vlan-migration new file mode 100755 index 000000000..bea9493c8 --- /dev/null +++ b/target/linux/ar71xx/base-files/etc/uci-defaults/vlan-migration @@ -0,0 +1,13 @@ +#!/bin/sh +# +# Copyright (C) 2010 OpenWrt.org +# + +local dev="$(uci -q get network.@switch_vlan[0].device)" +local vlan="$(uci -q get network.@switch_vlan[0].vlan)" + +if [ "$dev" = "rtl8366s" ] && [ "$vlan" = 0 ]; then + logger -t vlan-migration "VLAN 0 is invalid for RTL8366s, changing to 1" + uci set network.@switch_vlan[0].vlan=1 + uci commit network +fi diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/wrt160nl b/target/linux/ar71xx/base-files/etc/uci-defaults/wrt160nl new file mode 100755 index 000000000..dce28dde9 --- /dev/null +++ b/target/linux/ar71xx/base-files/etc/uci-defaults/wrt160nl @@ -0,0 +1,16 @@ +#!/bin/sh +# +# Copyright (C) 2010 OpenWrt.org +# + +. /lib/ar71xx.sh + +board=$(ar71xx_board_name) + +wrt160nl_fixtrx() { + mtd -o 32 fixtrx firmware +} + +if [ "${board}" == "wrt160nl" ]; then + wrt160nl_fixtrx +fi diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh new file mode 100755 index 000000000..f3c32555f --- /dev/null +++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh @@ -0,0 +1,455 @@ +#!/bin/sh +# +# Copyright (C) 2009-2011 OpenWrt.org +# + +AR71XX_BOARD_NAME= +AR71XX_MODEL= + +ar71xx_get_mtd_offset_size_format() { + local mtd="$1" + local offset="$2" + local size="$3" + local format="$4" + local dev + + dev=$(find_mtd_part $mtd) + [ -z "$dev" ] && return + + dd if=$dev bs=1 skip=$offset count=$size 2>/dev/null | hexdump -v -e "1/1 \"$format\"" +} + +ar71xx_get_mtd_part_magic() { + local mtd="$1" + ar71xx_get_mtd_offset_size_format "$mtd" 0 4 %02x +} + +wndr3700_board_detect() { + local machine="$1" + local magic + local name + + name="wndr3700" + + magic="$(ar71xx_get_mtd_part_magic firmware)" + case $magic in + "33373030") + machine="NETGEAR WNDR3700" + ;; + "33373031") + local model + model=$(ar71xx_get_mtd_offset_size_format art 56 10 %c) + if [ -z "$model" ] || [ "$model" = $'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' ]; then + machine="NETGEAR WNDR3700v2" + elif [ -z "$model" ] || [ "$model" = $'\xff\xff\xff\xff\xff\xff\xff\xff\xffN' ]; then + machine="NETGEAR WNDRMAC" + else + machine="NETGEAR $model" + fi + ;; + esac + + AR71XX_BOARD_NAME="$name" + AR71XX_MODEL="$machine" +} + +tplink_get_hwid() { + local part + + part=$(find_mtd_part firmware) + [ -z "$part" ] && return 1 + + dd if=$part bs=4 count=1 skip=16 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' +} + +tplink_board_detect() { + local model="$1" + local hwid + local hwver + + hwid=$(tplink_get_hwid) + hwver=${hwid:6:2} + hwver="v${hwver#0}" + + case "$hwid" in + "070300"*) + model="TP-Link TL-WR703N" + ;; + "070100"*) + model="TP-Link TL-WA701N/ND" + ;; + "074000"*) + model="TP-Link TL-WR740N/ND" + ;; + "074100"*) + model="TP-Link TL-WR741N/ND" + ;; + "074300"*) + model="TP-Link TL-WR743N/ND" + ;; + "084100"*) + model="TP-Link TL-WR841N/ND" + ;; + "084200"*) + model="TP-Link TL-WR842N/ND" + ;; + "090100"*) + model="TP-Link TL-WA901N/ND" + ;; + "094100"*) + model="TP-Link TL-WR941N/ND" + ;; + "104100"*) + model="TP-Link TL-WR1041N/ND" + ;; + "104300"*) + model="TP-Link TL-WR1043N/ND" + ;; + "254300"*) + model="TP-Link TL-WR2543N/ND" + ;; + "110101"*) + model="TP-Link TL-MR11U" + ;; + "302000"*) + model="TP-Link TL-MR3020" + ;; + "304000"*) + model="TP-Link TL-MR3040" + ;; + "322000"*) + model="TP-Link TL-MR3220" + ;; + "342000"*) + model="TP-Link TL-MR3420" + ;; + "360000"*) + model="TP-Link TL-WDR3600" + ;; + "430000"*) + model="TP-Link TL-WDR4300" + ;; + "431000"*) + model="TP-Link TL-WDR4310" + ;; + *) + hwver="" + ;; + esac + + AR71XX_MODEL="$model $hwver" +} + +ar71xx_board_detect() { + local machine + local name + + machine=$(awk 'BEGIN{FS="[ \t]+:[ \t]"} /machine/ {print $2}' /proc/cpuinfo) + + case "$machine" in + *"AirRouter") + name="airrouter" + ;; + *"ALFA Network AP96") + name="alfa-ap96" + ;; + *"ALFA Network N2/N5") + name="alfa-nx" + ;; + *ALL0258N) + name="all0258n" + ;; + *ALL0305) + name="all0305" + ;; + *ALL0315N) + name="all0315n" + ;; + *AP113) + name="ap113" + ;; + *AP121) + name="ap121" + ;; + *AP121-MINI) + name="ap121-mini" + ;; + *"AP136 reference board") + name="ap136" + ;; + *AP81) + name="ap81" + ;; + *AP83) + name="ap83" + ;; + *"Atheros AP96") + name="ap96" + ;; + *AW-NR580) + name="aw-nr580" + ;; + *"DB120 reference board") + name="db120" + ;; + *"DIR-600 rev. A1") + name="dir-600-a1" + ;; + *"DIR-615 rev. E4") + name="dir-615-e4" + ;; + *"DIR-825 rev. B1") + name="dir-825-b1" + ;; + *EAP7660D) + name="eap7660d" + ;; + *JA76PF) + name="ja76pf" + ;; + *JA76PF2) + name="ja76pf2" + ;; + *"Bullet M") + name="bullet-m" + ;; + *"Nanostation M") + name="nanostation-m" + ;; + *JWAP003) + name="jwap003" + ;; + *"Hornet-UB") + name="hornet-ub" + ;; + *LS-SR71) + name="ls-sr71" + ;; + *MZK-W04NU) + name="mzk-w04nu" + ;; + *MZK-W300NH) + name="mzk-w300nh" + ;; + *"NBG460N/550N/550NH") + name="nbg460n_550n_550nh" + ;; + *OM2P) + name="om2p" + ;; + *"OM2P LC") + name="om2p-lc" + ;; + *PB42) + name="pb42" + ;; + *"PB44 reference board") + name="pb44" + ;; + *PB92) + name="pb92" + ;; + *"RouterBOARD 411/A/AH") + name="rb-411" + ;; + *"RouterBOARD 411U") + name="rb-411u" + ;; + *"RouterBOARD 433/AH") + name="rb-433" + ;; + *"RouterBOARD 433UAH") + name="rb-433u" + ;; + *"RouterBOARD 450") + name="rb-450" + ;; + *"RouterBOARD 450G") + name="rb-450g" + ;; + *"RouterBOARD 493/AH") + name="rb-493" + ;; + *"RouterBOARD 493G") + name="rb-493g" + ;; + *"RouterBOARD 750") + name="rb-750" + ;; + *"RouterBOARD 750GL") + name="rb-750gl" + ;; + *"RouterBOARD 751") + name="rb-751" + ;; + *"RouterBOARD 751G") + name="rb-751g" + ;; + *"RouterBOARD 2011L") + name="rb-2011l" + ;; + *"RouterBOARD 2011UAS-2HnD") + name="rb-2011uas-2hnd" + ;; + *"Rocket M") + name="rocket-m" + ;; + *RouterStation) + name="routerstation" + ;; + *"RouterStation Pro") + name="routerstation-pro" + ;; + *RW2458N) + name="rw2458n" + ;; + *TEW-632BRP) + name="tew-632brp" + ;; + *TEW-673GRU) + name="tew-673gru" + ;; + *TEW-712BR) + name="tew-712br" + ;; + *"TL-WR1041N v2") + name="tl-wr1041n-v2" + ;; + *TL-WR1043ND) + name="tl-wr1043nd" + ;; + *TL-WR2543N*) + name="tl-wr2543n" + ;; + *"DIR-615 rev. C1") + name="dir-615-c1" + ;; + *TL-MR3020) + name="tl-mr3020" + ;; + *TL-MR3040) + name="tl-mr3040" + ;; + *TL-MR3220) + name="tl-mr3220" + ;; + *TL-MR3420) + name="tl-mr3420" + ;; + *TL-WA901ND) + name="tl-wa901nd" + ;; + *"TL-WA901ND v2") + name="tl-wa901nd-v2" + ;; + *"TL-WDR3600/4300/4310") + name="tl-wdr4300" + ;; + *TL-WR741ND) + name="tl-wr741nd" + ;; + *"TL-WR741ND v4") + name="tl-wr741nd-v4" + ;; + *"TL-WR841N v1") + name="tl-wr841n-v1" + ;; + *"TL-WR841N/ND v7") + name="tl-wr841n-v7" + ;; + *"TL-WR841N/ND v8") + name="tl-wr841n-v8" + ;; + *TL-WR941ND) + name="tl-wr941nd" + ;; + *"TL-WR703N v1") + name="tl-wr703n" + ;; + *"TL-MR11U") + name="tl-mr11u" + ;; + *UniFi) + name="unifi" + ;; + *WHR-G301N) + name="whr-g301n" + ;; + *WHR-HP-GN) + name="whr-hp-gn" + ;; + *WLAE-AG300N) + name="wlae-ag300n" + ;; + *WP543) + name="wp543" + ;; + *WPE72) + name="wpe72" + ;; + *"WNDR3700/WNDR3800/WNDRMAC") + wndr3700_board_detect "$machine" + ;; + *WNR2000) + name="wnr2000" + ;; + *WRT160NL) + name="wrt160nl" + ;; + *WRT400N) + name="wrt400n" + ;; + *WZR-HP-AG300H) + name="wzr-hp-ag300h" + ;; + *WZR-HP-G300NH) + name="wzr-hp-g300nh" + ;; + *WZR-HP-G450H) + name="wzr-hp-g450h" + ;; + *WZR-HP-G300NH2) + name="wzr-hp-g300nh2" + ;; + *WHR-HP-G300N) + name="whr-hp-g300n" + ;; + *ZCN-1523H-2) + name="zcn-1523h-2" + ;; + *ZCN-1523H-5) + name="zcn-1523h-5" + ;; + *EmbWir-Dorin) + name="ew-dorin" + ;; + *EmbWir-Dorin-Router) + name="ew-dorin-router" + ;; + esac + + case "$machine" in + *TL-WR* | *TL-WA* | *TL-MR*) + tplink_board_detect "$machine" + ;; + esac + + [ -z "$name" ] && name="unknown" + + [ -z "$AR71XX_BOARD_NAME" ] && AR71XX_BOARD_NAME="$name" + [ -z "$AR71XX_MODEL" ] && AR71XX_MODEL="$machine" + + [ -e "/tmp/sysinfo/" ] || mkdir -p "/tmp/sysinfo/" + + echo "$AR71XX_BOARD_NAME" > /tmp/sysinfo/board_name + echo "$AR71XX_MODEL" > /tmp/sysinfo/model +} + +ar71xx_board_name() { + local name + + [ -f /tmp/sysinfo/board_name ] && name=$(cat /tmp/sysinfo/board_name) + [ -z "$name" ] && name="unknown" + + echo "$name" +} diff --git a/target/linux/ar71xx/base-files/lib/preinit/03_preinit_do_ar71xx.sh b/target/linux/ar71xx/base-files/lib/preinit/03_preinit_do_ar71xx.sh new file mode 100644 index 000000000..ff5407a0d --- /dev/null +++ b/target/linux/ar71xx/base-files/lib/preinit/03_preinit_do_ar71xx.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +do_ar71xx() { + . /lib/ar71xx.sh + + ar71xx_board_detect +} + +boot_hook_add preinit_main do_ar71xx diff --git a/target/linux/ar71xx/base-files/lib/preinit/05_enable_reset_button_ar71xx b/target/linux/ar71xx/base-files/lib/preinit/05_enable_reset_button_ar71xx new file mode 100644 index 000000000..317c8d15a --- /dev/null +++ b/target/linux/ar71xx/base-files/lib/preinit/05_enable_reset_button_ar71xx @@ -0,0 +1,13 @@ +# +# Copyright (C) 2009 OpenWrt.org +# + +. /lib/ar71xx.sh + + +preinit_enable_reset_button() { + insmod gpio-button-hotplug +} + +boot_hook_add preinit_main preinit_enable_reset_button + diff --git a/target/linux/ar71xx/base-files/lib/preinit/05_set_iface_mac_ar71xx b/target/linux/ar71xx/base-files/lib/preinit/05_set_iface_mac_ar71xx new file mode 100644 index 000000000..f8bb7b76c --- /dev/null +++ b/target/linux/ar71xx/base-files/lib/preinit/05_set_iface_mac_ar71xx @@ -0,0 +1,39 @@ +# +# Copyright (C) 2009 OpenWrt.org +# + +. /lib/ar71xx.sh + +fetch_mac_from_mtd() { + local mtd_part=$1 + local lan_env=$2 + local wan_env=$3 + local mtd mac + + mtd=$(grep $mtd_part /proc/mtd | cut -d: -f1) + [ -z $mtd ] && return + + mac=$(grep $lan_env /dev/$mtd | cut -d= -f2) + [ ! -z $mac ] && ifconfig eth0 hw ether $mac 2>/dev/null + + mac=$(grep $wan_env /dev/$mtd | cut -d= -f2) + [ ! -z $mac ] && ifconfig eth1 hw ether $mac 2>/dev/null +} + +preinit_set_mac_address() { + case $(ar71xx_board_name) in + tew-632brp) + fetch_mac_from_mtd config lan_mac wan_mac + ;; + dir-615-c1) + fetch_mac_from_mtd config lan_mac wan_mac + echo 1 > /sys/class/leds/dir-615-c1:green:wancpu/brightness + ;; + wrt160nl) + fetch_mac_from_mtd nvram lan_hwaddr wan_hwaddr + ;; + esac +} + +boot_hook_add preinit_main preinit_set_mac_address + diff --git a/target/linux/ar71xx/base-files/lib/preinit/05_set_preinit_iface_ar71xx b/target/linux/ar71xx/base-files/lib/preinit/05_set_preinit_iface_ar71xx new file mode 100644 index 000000000..8611dce81 --- /dev/null +++ b/target/linux/ar71xx/base-files/lib/preinit/05_set_preinit_iface_ar71xx @@ -0,0 +1,16 @@ +#!/bin/sh + +# +# Copyright (C) 2009 OpenWrt.org +# + +. /lib/ar71xx.sh + +set_preinit_iface() { + ifname=eth0 +} + +boot_hook_add preinit_main set_preinit_iface + + + diff --git a/target/linux/ar71xx/base-files/lib/upgrade/allnet.sh b/target/linux/ar71xx/base-files/lib/upgrade/allnet.sh new file mode 100644 index 000000000..9a375ff19 --- /dev/null +++ b/target/linux/ar71xx/base-files/lib/upgrade/allnet.sh @@ -0,0 +1,160 @@ +# The U-Boot loader of the some Allnet devices requires image sizes and +# checksums to be provided in the U-Boot environment. +# In case the check fails during boot, a failsafe-system is started to provide +# a minimal web-interface for flashing a new firmware. + +# make sure we got uboot-envtools and fw_env.config copied over to the ramfs +platform_add_ramfs_ubootenv() { + [ -e /usr/sbin/fw_printenv ] && install_bin /usr/sbin/fw_printenv /usr/sbin/fw_setenv + [ -e /etc/fw_env.config ] && install_file /etc/fw_env.config +} +append sysupgrade_pre_upgrade platform_add_ramfs_ubootenv + +# determine size of the main firmware partition +platform_get_firmware_size() { + local dev size erasesize name + while read dev size erasesize name; do + name=${name#'"'}; name=${name%'"'} + case "$name" in + firmware) + printf "%d" "0x$size" + break + ;; + esac + done < /proc/mtd +} + +# get the first 4 bytes (magic) of a given file starting at offset in hex format +get_magic_long_at() { + dd if="$1" skip=$(( $CI_BLKSZ / 4 * $2 )) bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' +} + +get_filesize() { + wc -c "$1" | while read image_size _n ; do echo $image_size ; break; done +} + +# scan through the update image pages until matching a magic +platform_get_offset() { + offsetcount=0 + magiclong="x" + if [ -n "$3" ]; then + offsetcount=$3 + fi + while magiclong=$( get_magic_long_at "$1" "$offsetcount" ) && [ -n "$magiclong" ]; do + case "$magiclong" in + "2705"*) + # U-Boot image magic + if [ "$2" = "uImage" ]; then + echo $offsetcount + return + fi + ;; + "68737173"|"73717368") + # SquashFS + if [ "$2" = "rootfs" ]; then + echo $offsetcount + return + fi + ;; + "deadc0de"|"19852003") + # JFFS2 empty page + if [ "$2" = "rootfs-data" ]; then + echo $offsetcount + return + fi + ;; + esac + offsetcount=$(( $offsetcount + 1 )) + done +} + +platform_check_image_allnet() { + local fw_printenv=/usr/sbin/fw_printenv + [ ! -n "$fw_printenv" -o ! -x "$fw_printenv" ] && { + echo "Please install uboot-envtools!" + return 1 + } + + [ ! -r "/etc/fw_env.config" ] && { + echo "/etc/fw_env.config is missing" + return 1 + } + + local image_size=$( get_filesize "$1" ) + local firmware_size=$( platform_get_firmware_size ) + [ $image_size -ge $firmware_size ] && + { + echo "upgrade image is too big (${image_size}b > ${firmware_size}b)" + } + + local vmlinux_blockoffset=$( platform_get_offset "$1" uImage ) + [ -z $vmlinux_blockoffset ] && { + echo "vmlinux-uImage not found" + return 1 + } + + local rootfs_blockoffset=$( platform_get_offset "$1" rootfs "$vmlinux_blockoffset" ) + [ -z $rootfs_blockoffset ] && { + echo "missing rootfs" + return 1 + } + + local data_blockoffset=$( platform_get_offset "$1" rootfs-data "$rootfs_blockoffset" ) + [ -z $data_blockoffset ] && { + echo "rootfs doesn't have JFFS2 end marker" + return 1 + } + + return 0 +} + +platform_do_upgrade_allnet() { + local firmware_base_addr=$( printf "%d" "$1" ) + local vmlinux_blockoffset=$( platform_get_offset "$2" uImage ) + if [ ! -n "$vmlinux_blockoffset" ]; then + echo "can't determine uImage offset" + return 1 + fi + local rootfs_blockoffset=$( platform_get_offset "$2" rootfs $(( $vmlinux_blockoffset + 1 )) ) + local vmlinux_offset=$(( $vmlinux_blockoffset * $CI_BLKSZ )) + local vmlinux_addr=$(( $firmware_base_addr + $vmlinux_offset )) + local vmlinux_hexaddr=0x$( printf "%08x" "$vmlinux_addr" ) + if [ ! -n "$rootfs_blockoffset" ]; then + echo "can't determine rootfs offset" + return 1 + fi + local rootfs_offset=$(( $rootfs_blockoffset * $CI_BLKSZ )) + local rootfs_addr=$(( $firmware_base_addr + $rootfs_offset )) + local rootfs_hexaddr=0x$( printf "%08x" "$rootfs_addr" ) + local vmlinux_blockcount=$(( $rootfs_blockoffset - $vmlinux_blockoffset )) + local vmlinux_size=$(( $rootfs_offset - $vmlinux_offset )) + local vmlinux_hexsize=0x$( printf "%08x" "$vmlinux_size" ) + local data_blockoffset=$( platform_get_offset "$2" rootfs-data $(( $rootfs_blockoffset + 1 )) ) + if [ ! -n "$data_blockoffset" ]; then + echo "can't determine rootfs size" + return 1 + fi + local data_offset=$(( $data_blockoffset * $CI_BLKSZ )) + local rootfs_blockcount=$(( $data_blockoffset - $rootfs_blockoffset )) + local rootfs_size=$(( $data_offset - $rootfs_offset )) + local rootfs_hexsize=0x$( printf "%08x" "$rootfs_size" ) + + local rootfs_md5=$( dd if="$2" bs=$CI_BLKSZ skip=$rootfs_blockoffset count=$rootfs_blockcount 2>/dev/null | md5sum -); rootfs_md5="${rootfs_md5%% *}" + local vmlinux_md5=$( dd if="$2" bs=$CI_BLKSZ skip=$vmlinux_blockoffset count=$vmlinux_blockcount 2>/dev/null | md5sum -); vmlinux_md5="${vmlinux_md5%% *}" + # this needs a recent version of uboot-envtools! + cat >/tmp/fw_env_upgrade </dev/null | hexdump -v -n 4 -e '1/1 "%02x"' +} + +dir825b_is_caldata_valid() { + local mtddev=$1 + local magic + + magic=$(get_magic_at $mtddev 4096) + [ "$magic" != "a55a" ] && return 0 + + magic=$(get_magic_at $mtddev 20480) + [ "$magic" != "a55a" ] && return 0 + + return 1 +} + +dir825b_copy_caldata() { + local cal_src=$1 + local cal_dst=$2 + local mtd_src + local mtd_dst + local md5_src + local md5_dst + + mtd_src=$(find_mtd_part $cal_src) + [ -z "$mtd_src" ] && { + echo "no $cal_src partition found" + return 1 + } + + mtd_dst=$(find_mtd_part $cal_dst) + [ -z "$mtd_dst" ] && { + echo "no $cal_dst partition found" + return 1 + } + + dir825b_is_caldata_valid "$mtd_src" && { + echo "no valid calibration data found in $cal_src" + return 1 + } + + dir825b_is_caldata_valid "$mtd_dst" && { + echo "Copying calibration data from $cal_src to $cal_dst..." + dd if="$mtd_src" 2>/dev/null | mtd -q -q write - "$cal_dst" + } + + md5_src=$(md5sum "$mtd_src") && md5_src="${md5_src%% *}" + md5_dst=$(md5sum "$mtd_dst") && md5_dst="${md5_dst%% *}" + + [ "$md5_src" != "$md5_dst" ] && { + echo "calibration data mismatch $cal_src:$md5_src $cal_dst:$md5_dst" + return 1 + } + + return 0 +} + +dir825b_do_upgrade_combined() { + local fw_part=$1 + local fw_file=$2 + local fw_mtd=$(find_mtd_part $fw_part) + local fw_length=0x$(dd if="$fw_file" bs=2 skip=1 count=4 2>/dev/null) + local fw_blocks=$(($fw_length / 65536)) + + if [ -n "$fw_mtd" ] && [ ${fw_blocks:-0} -gt 0 ]; then + local append="" + [ -f "$CONF_TAR" -a "$SAVE_CONFIG" -eq 1 ] && append="-j $CONF_TAR" + + sync + dd if="$fw_file" bs=64k skip=1 count=$fw_blocks 2>/dev/null | \ + mtd $append write - "$fw_part" + fi +} + +dir825b_check_image() { + local magic="$(get_magic_long "$1")" + local fw_mtd=$(find_mtd_part "firmware_orig") + + case "$magic" in + "27051956") + ;; + "43493030") + local md5_img=$(dd if="$1" bs=2 skip=9 count=16 2>/dev/null) + local md5_chk=$(dd if="$1" bs=64k skip=1 2>/dev/null | md5sum -); md5_chk="${md5_chk%% *}" + local fw_len=$(dd if="$1" bs=2 skip=1 count=4 2>/dev/null) + local fw_part_len=$(get_mtd_part_size "firmware") + + if [ -z "$fw_mtd" ]; then + ask_bool 0 "Do you have a backup of the caldata partition?" || { + echo "Warning, please make sure that you have a backup of the caldata partition." + echo "Once you have that, use 'sysupgrade -i' for upgrading to the 'fat' firmware." + return 1 + } + fi + + if [ -z "$md5_img" -o -z "$md5_chk" ]; then + echo "Unable to get image checksums. Maybe you are using a streamed image?" + return 1 + fi + + if [ "$md5_img" != "$md5_chk" ]; then + echo "Invalid image. Contents do not match checksum (image:$md5_img calculated:$md5_chk)" + return 1 + fi + + fw_len=$((0x$fw_len)) + fw_part_len=${fw_part_len:-0} + + if [ $fw_part_len -lt $fw_len ]; then + echo "The upgrade image is too big (size:$fw_len available:$fw_part_len)" + return 1 + fi + ;; + *) + echo "Unsupported image format." + return 1 + ;; + esac + + return 0 +} + +platform_do_upgrade_dir825b() { + local magic="$(get_magic_long "$1")" + local fw_mtd=$(find_mtd_part "firmware_orig") + + case "$magic" in + "27051956") + if [ -n "$fw_mtd" ]; then + # restore calibration data before downgrading to + # the normal image + dir825b_copy_caldata "caldata" "caldata_orig" || { + echo "unable to restore calibration data" + exit 1 + } + PART_NAME="firmware_orig" + else + PART_NAME="firmware" + fi + default_do_upgrade "$ARGV" + ;; + "43493030") + if [ -z "$fw_mtd" ]; then + # backup calibration data before upgrading to the + # fat image + dir825b_copy_caldata "caldata" "caldata_copy" || { + echo "unable to backup calibration data" + exit 1 + } + fi + dir825b_do_upgrade_combined "firmware" "$ARGV" + ;; + esac +} diff --git a/target/linux/ar71xx/base-files/lib/upgrade/om2p.sh b/target/linux/ar71xx/base-files/lib/upgrade/om2p.sh new file mode 100644 index 000000000..d9a8bbb7f --- /dev/null +++ b/target/linux/ar71xx/base-files/lib/upgrade/om2p.sh @@ -0,0 +1,169 @@ +# The U-Boot loader of the OM2P requires image sizes and checksums to be +# provided in the U-Boot environment. +# The OM2P comes with 2 main partitions - while one is active sysupgrade +# will flash the other. The boot order is changed to boot the newly +# flashed partition. If the new partition can't be booted due to upgrade +# failures the previously used partition is loaded. + +trim() +{ + echo $1 +} + +cfg_value_get() +{ + local cfg=$1 cfg_opt + local section=$2 our_section=0 + local param=$3 our_param= + + for cfg_opt in $cfg + do + [ "$cfg_opt" = "[$section]" ] && our_section=1 && continue + [ "$our_section" = "1" ] || continue + + our_param=$(echo ${cfg_opt%%=*}) + [ "$param" = "$our_param" ] && echo ${cfg_opt##*=} && break + done +} + +# make sure we got uboot-envtools and fw_env.config copied over to the ramfs +platform_add_ramfs_ubootenv() +{ + [ -e /usr/sbin/fw_printenv ] && install_bin /usr/sbin/fw_printenv /usr/sbin/fw_setenv + [ -e /etc/fw_env.config ] && install_file /etc/fw_env.config +} +append sysupgrade_pre_upgrade platform_add_ramfs_ubootenv + +platform_check_image_om2p() +{ + local img_magic=$1 + local img_path=$2 + local fw_printenv=/usr/sbin/fw_printenv + local img_board_target= img_num_files= i=0 + local cfg_name= kernel_name= rootfs_name= + + case "$img_magic" in + # Combined Extended Image v1 + 43453031) + img_board_target=$(trim $(dd if="$img_path" bs=4 skip=1 count=8 2>/dev/null)) + img_num_files=$(trim $(dd if="$img_path" bs=2 skip=18 count=1 2>/dev/null)) + ;; + *) + echo "Invalid image ($img_magic). Use combined extended images on this platform" + return 1 + ;; + esac + + case "$img_board_target" in + OM2P) + ;; + *) + echo "Invalid board target ($img_board_target). Use the correct image for this platform" + return 1 + ;; + esac + + [ $img_num_files -ne 3 ] && { + echo "Invalid number of embedded images ($img_num_files). Use the correct image for this platform" + return 1 + } + + cfg_name=$(trim $(dd if="$img_path" bs=2 skip=19 count=16 2>/dev/null)) + + [ "$cfg_name" != "fwupgrade.cfg" ] && { + echo "Invalid embedded config file ($cfg_name). Use the correct image for this platform" + return 1 + } + + kernel_name=$(trim $(dd if="$img_path" bs=2 skip=55 count=16 2>/dev/null)) + + [ "$kernel_name" != "kernel" ] && { + echo "Invalid embedded kernel file ($kernel_name). Use the correct image for this platform" + return 1 + } + + rootfs_name=$(trim $(dd if="$img_path" bs=2 skip=91 count=16 2>/dev/null)) + + [ "$rootfs_name" != "rootfs" ] && { + echo "Invalid embedded kernel file ($rootfs_name). Use the correct image for this platform" + return 1 + } + + [ ! -x "$fw_printenv" ] && { + echo "Please install uboot-envtools!" + return 1 + } + + [ ! -r "/etc/fw_env.config" ] && { + echo "/etc/fw_env.config is missing" + return 1 + } + + return 0 +} + +platform_do_upgrade_om2p() +{ + local img_path=$1 + local kernel_start_addr= kernel_size= kernel_md5= + local rootfs_size= rootfs_checksize= rootfs_md5= + local kernel_bsize= total_size=7340032 + local data_offset=$((64 * 1024)) block_size=$((256 * 1024)) offset= + local uboot_env_upgrade="/tmp/fw_env_upgrade" + local cfg_size= kernel_size= rootfs_size= + local append="" + + [ -f "$CONF_TAR" -a "$SAVE_CONFIG" -eq 1 ] && append="-j $CONF_TAR" + + cfg_size=$(dd if="$img_path" bs=2 skip=35 count=4 2>/dev/null) + kernel_size=$(dd if="$img_path" bs=2 skip=71 count=4 2>/dev/null) + rootfs_size=$(dd if="$img_path" bs=2 skip=107 count=4 2>/dev/null) + + cfg_content=$(dd if="$img_path" bs=1 skip=$data_offset count=$(echo $((0x$cfg_size))) 2>/dev/null) + + kernel_md5=$(cfg_value_get "$cfg_content" "vmlinux" "md5sum") + rootfs_md5=$(cfg_value_get "$cfg_content" "rootfs" "md5sum") + rootfs_checksize=$(cfg_value_get "$cfg_content" "rootfs" "checksize") + + if [ "$((0x$kernel_size % $block_size))" = "0" ] + then + kernel_bsize=$(echo $((0x$kernel_size))) + else + kernel_bsize=$((0x$kernel_size + ($block_size - (0x$kernel_size % $block_size)))) + fi + + mtd -q erase inactive + + offset=$(echo $(($data_offset + 0x$cfg_size + 0x$kernel_size))) + dd if="$img_path" bs=1 skip=$offset count=$(echo $((0x$rootfs_size))) 2>&- | mtd -n -p $kernel_bsize $append write - "inactive" + + offset=$(echo $(($data_offset + 0x$cfg_size))) + dd if="$img_path" bs=1 skip=$offset count=$(echo $((0x$kernel_size))) 2>&- | mtd -n write - "inactive" + + rm $uboot_env_upgrade 2>&- + + if [ "$(grep 'mtd3:.*inactive' /proc/mtd)" ] + then + printf "kernel_size_1 %u\n" $(($kernel_bsize / 1024)) >> $uboot_env_upgrade + printf "rootfs_size_1 %u\n" $((($total_size - $kernel_bsize) / 1024)) >> $uboot_env_upgrade + printf "bootseq 1,2\n" >> $uboot_env_upgrade + kernel_start_addr=0x9f1c0000 + else + printf "kernel_size_2 %u\n" $(($kernel_bsize / 1024)) >> $uboot_env_upgrade + printf "rootfs_size_2 %u\n" $((($total_size - $kernel_bsize) / 1024)) >> $uboot_env_upgrade + printf "bootseq 2,1\n" >> $uboot_env_upgrade + kernel_start_addr=0x9f8c0000 + fi + + printf "vmlinux_start_addr %s\n" $kernel_start_addr >> $uboot_env_upgrade + printf "vmlinux_size 0x%s\n" $kernel_size >> $uboot_env_upgrade + printf "vmlinux_checksum %s\n" $kernel_md5 >> $uboot_env_upgrade + printf "rootfs_start_addr 0x%x\n" $(($kernel_start_addr + $kernel_bsize)) >> $uboot_env_upgrade + printf "rootfs_size %s\n" $rootfs_checksize >> $uboot_env_upgrade + printf "rootfs_checksum %s\n" $rootfs_md5 >> $uboot_env_upgrade + + fw_setenv -s $uboot_env_upgrade || { + echo "failed to update U-Boot environment" + return 1 + } +} diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh new file mode 100755 index 000000000..8ec958d79 --- /dev/null +++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh @@ -0,0 +1,269 @@ +# +# Copyright (C) 2011 OpenWrt.org +# + +. /lib/ar71xx.sh + +PART_NAME=firmware +RAMFS_COPY_DATA=/lib/ar71xx.sh + +CI_BLKSZ=65536 +CI_LDADR=0x80060000 + +platform_find_partitions() { + local first dev size erasesize name + while read dev size erasesize name; do + name=${name#'"'}; name=${name%'"'} + case "$name" in + vmlinux.bin.l7|vmlinux|kernel|linux|rootfs|filesystem) + if [ -z "$first" ]; then + first="$name" + else + echo "$erasesize:$first:$name" + break + fi + ;; + esac + done < /proc/mtd +} + +platform_find_kernelpart() { + local part + for part in "${1%:*}" "${1#*:}"; do + case "$part" in + vmlinux.bin.l7|vmlinux|kernel|linux) + echo "$part" + break + ;; + esac + done +} + +platform_do_upgrade_combined() { + local partitions=$(platform_find_partitions) + local kernelpart=$(platform_find_kernelpart "${partitions#*:}") + local erase_size=$((0x${partitions%%:*})); partitions="${partitions#*:}" + local kern_length=0x$(dd if="$1" bs=2 skip=1 count=4 2>/dev/null) + local kern_blocks=$(($kern_length / $CI_BLKSZ)) + local root_blocks=$((0x$(dd if="$1" bs=2 skip=5 count=4 2>/dev/null) / $CI_BLKSZ)) + + if [ -n "$partitions" ] && [ -n "$kernelpart" ] && \ + [ ${kern_blocks:-0} -gt 0 ] && \ + [ ${root_blocks:-0} -gt ${kern_blocks:-0} ] && \ + [ ${erase_size:-0} -gt 0 ]; + then + local append="" + [ -f "$CONF_TAR" -a "$SAVE_CONFIG" -eq 1 ] && append="-j $CONF_TAR" + + ( dd if="$1" bs=$CI_BLKSZ skip=1 count=$kern_blocks 2>/dev/null; \ + dd if="$1" bs=$CI_BLKSZ skip=$((1+$kern_blocks)) count=$root_blocks 2>/dev/null ) | \ + mtd -r $append -F$kernelpart:$kern_length:$CI_LDADR,rootfs write - $partitions + fi +} + +tplink_get_image_hwid() { + get_image "$@" | dd bs=4 count=1 skip=16 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' +} + +platform_check_image() { + local board=$(ar71xx_board_name) + local magic="$(get_magic_word "$1")" + local magic_long="$(get_magic_long "$1")" + + [ "$ARGC" -gt 1 ] && return 1 + + case "$board" in + all0315n | \ + all0258n ) + platform_check_image_allnet "$1" && return 0 + return 1 + ;; + alfa-ap96 | \ + alfa-nx | \ + ap113 | \ + ap121 | \ + ap121-mini | \ + ap136 | \ + ap96 | \ + db120 | \ + hornet-ub | \ + zcn-1523h-2 | \ + zcn-1523h-5) + [ "$magic_long" != "68737173" -a "$magic_long" != "19852003" ] && { + echo "Invalid image type." + return 1 + } + return 0 + ;; + ap81 | \ + ap83 | \ + dir-600-a1 | \ + dir-615-c1 | \ + dir-615-e4 | \ + ew-dorin | \ + ew-dorin-router | \ + mzk-w04nu | \ + mzk-w300nh | \ + tew-632brp | \ + tew-712br | \ + wrt400n | \ + airrouter | \ + bullet-m | \ + nanostation-m | \ + rocket-m | \ + rw2458n | \ + wzr-hp-g300nh2 | \ + wzr-hp-g300nh | \ + wzr-hp-g450h | \ + wzr-hp-ag300h | \ + whr-g301n | \ + whr-hp-g300n | \ + whr-hp-gn | \ + wlae-ag300n | \ + nbg460n_550n_550nh | \ + unifi ) + [ "$magic" != "2705" ] && { + echo "Invalid image type." + return 1 + } + return 0 + ;; + + dir-825-b1 | \ + tew-673gru) + dir825b_check_image "$1" && return 0 + ;; + + om2p | \ + om2p-lc) + platform_check_image_om2p "$magic_long" "$1" && return 0 + return 1 + ;; + tl-mr11u | \ + tl-mr3020 | \ + tl-mr3040 | \ + tl-mr3220 | \ + tl-mr3420 | \ + tl-wa901nd | \ + tl-wa901nd-v2 | \ + tl-wdr4300 | \ + tl-wr703n | \ + tl-wr741nd | \ + tl-wr741nd-v4 | \ + tl-wr841n-v1 | \ + tl-wr841n-v7 | \ + tl-wr841n-v8 | \ + tl-wr941nd | \ + tl-wr1041n-v2 | \ + tl-wr1043nd | \ + tl-wr2543n) + [ "$magic" != "0100" ] && { + echo "Invalid image type." + return 1 + } + + local hwid + local imageid + + hwid=$(tplink_get_hwid) + imageid=$(tplink_get_image_hwid "$1") + + [ "$hwid" != "$imageid" ] && { + echo "Invalid image, hardware ID mismatch, hw:$hwid image:$imageid." + return 1 + } + + return 0 + ;; + wndr3700) + local hw_magic + + hw_magic="$(ar71xx_get_mtd_part_magic firmware)" + [ "$magic_long" != "$hw_magic" ] && { + echo "Invalid image, hardware ID mismatch, hw:$hw_magic image:$magic_long." + return 1 + } + return 0 + ;; + wrt160nl) + [ "$magic" != "4e4c" ] && { + echo "Invalid image type." + return 1 + } + return 0 + ;; + routerstation | \ + routerstation-pro | \ + ls-sr71 | \ + pb42 | \ + pb44 | \ + all0305 | \ + eap7660d | \ + ja76pf | \ + ja76pf2) + [ "$magic" != "4349" ] && { + echo "Invalid image. Use *-sysupgrade.bin files on this board" + return 1 + } + + local md5_img=$(dd if="$1" bs=2 skip=9 count=16 2>/dev/null) + local md5_chk=$(dd if="$1" bs=$CI_BLKSZ skip=1 2>/dev/null | md5sum -); md5_chk="${md5_chk%% *}" + + if [ -n "$md5_img" -a -n "$md5_chk" ] && [ "$md5_img" = "$md5_chk" ]; then + return 0 + else + echo "Invalid image. Contents do not match checksum (image:$md5_img calculated:$md5_chk)" + return 1 + fi + return 0 + ;; + esac + + echo "Sysupgrade is not yet supported on $board." + return 1 +} + +platform_do_upgrade() { + local board=$(ar71xx_board_name) + + case "$board" in + routerstation | \ + routerstation-pro | \ + ls-sr71 | \ + all0305 | \ + eap7660d | \ + pb42 | \ + pb44 | \ + ja76pf | \ + ja76pf2) + platform_do_upgrade_combined "$ARGV" + ;; + all0258n ) + platform_do_upgrade_allnet "0x9f050000" "$ARGV" + ;; + all0315n ) + platform_do_upgrade_allnet "0x9f080000" "$ARGV" + ;; + dir-825-b1 |\ + tew-673gru) + platform_do_upgrade_dir825b "$ARGV" + ;; + om2p | \ + om2p-lc) + platform_do_upgrade_om2p "$ARGV" + ;; + *) + default_do_upgrade "$ARGV" + ;; + esac +} + +disable_watchdog() { + killall watchdog + ( ps | grep -v 'grep' | grep '/dev/watchdog' ) && { + echo 'Could not disable watchdog' + return 1 + } +} + +append sysupgrade_pre_upgrade disable_watchdog diff --git a/target/linux/ar71xx/base-files/sbin/wget2nand b/target/linux/ar71xx/base-files/sbin/wget2nand new file mode 100755 index 000000000..9cd6e7c40 --- /dev/null +++ b/target/linux/ar71xx/base-files/sbin/wget2nand @@ -0,0 +1,85 @@ +#!/bin/sh +# wget2nand +# This script can be used to download a TGZ file from your build system which +# contains the files to be installed on the NAND flash on your RB1xx card. +# The one parameter is the URL of the TGZ file to be downloaded. +# Licence GPL V2 +# Author david.goodenough@linkchoose.co.uk +# Based on cf2nand from RB532 support +. /etc/functions.sh + +wget2nand_dir=/tmp/wget2nand +mnt_kernel=$wget2nand_dir/mnt_kernel +mnt_rootfs=$wget2nand_dir/mnt_rootfs +src_rootfs=$wget2nand_dir/rootfs.tgz +src_kernel=$wget2nand_dir/kernel + +[ -d "$wget2nand_dir" ] && { + echo "$wget2nand_dir already exists" + exit 1 +} + +# need to find the wget server from the command line +url=$1 +[ -z "$url" ] && { + echo "No URL specified for image TGZ" + echo "Usage : $0 URL" + exit 1 +} + +url_kernel=$url/openwrt-ar71xx-nand-vmlinux.elf +url_rootfs=$url/openwrt-ar71xx-nand-rootfs.tar.gz + +mtd_kernel="$(find_mtd_part 'kernel')" +mtd_rootfs="$(find_mtd_part 'rootfs')" +[ -z "$mtd_kernel" -o -z "$mtd_rootfs" ] && { + echo "Cannot find NAND Flash partitions" + exit 1 +} + +mkdir "$wget2nand_dir" +wget $url_kernel -O "$src_kernel" || { + echo "Unable to download $url_kernel" + exit 1 +} + +wget $url_rootfs -O "$src_rootfs" || { + echo "Unable to download $url_rootfs" + exit 1 +} + +echo "Erasing filesystem..." +mtd erase kernel 2>/dev/null >/dev/null +mtd erase rootfs 2>/dev/null >/dev/null + +echo "Mounting $mtd_rootfs as new root and $mtd_kernel as kernel partition" + +mkdir "$mnt_kernel" +mkdir "$mnt_rootfs" +mount -t yaffs2 "$mtd_kernel" "$mnt_kernel" +mount -t yaffs2 "$mtd_rootfs" "$mnt_rootfs" + +echo "Copying kernel..." +cp $src_kernel $mnt_kernel/kernel || { + echo "Error occured while copying the kernel" + exit 1 +} +chmod +x $mnt_kernel/kernel + +echo "Preparing filesystem..." +( cd "$mnt_rootfs"; tar xvz -f "$src_rootfs" ) + +# make sure everything is written before we unmount the partitions +echo "chmod ugo+x /" > $mnt_rootfs/etc/uci-defaults/set_root_permission +sync +ls $mnt_kernel >/dev/null +ls $mnt_rootfs >/dev/null + +echo "Cleaning up..." +# unmount the partitions and remove the directories into which they were mounted +umount $mnt_kernel +umount $mnt_rootfs +rm -rf $wget2nand_dir + +# all done +echo "Image written, you can now reboot. Remember to change the boot source to Boot from Nand" diff --git a/target/linux/ar71xx/config-3.3 b/target/linux/ar71xx/config-3.3 new file mode 100644 index 000000000..ec12afdfd --- /dev/null +++ b/target/linux/ar71xx/config-3.3 @@ -0,0 +1,233 @@ +CONFIG_AG71XX=y +CONFIG_AG71XX_AR8216_SUPPORT=y +# CONFIG_AG71XX_DEBUG is not set +# CONFIG_AG71XX_DEBUG_FS is not set +CONFIG_AR8216_PHY=y +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +CONFIG_ARCH_DISCARD_MEMBLOCK=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ATH79=y +CONFIG_ATH79_DEV_AP9X_PCI=y +CONFIG_ATH79_DEV_DSA=y +CONFIG_ATH79_DEV_ETH=y +CONFIG_ATH79_DEV_GPIO_BUTTONS=y +CONFIG_ATH79_DEV_LEDS_GPIO=y +CONFIG_ATH79_DEV_M25P80=y +CONFIG_ATH79_DEV_NFC=y +CONFIG_ATH79_DEV_SPI=y +CONFIG_ATH79_DEV_USB=y +CONFIG_ATH79_DEV_WMAC=y +CONFIG_ATH79_MACH_ALFA_AP96=y +CONFIG_ATH79_MACH_ALFA_NX=y +CONFIG_ATH79_MACH_ALL0258N=y +CONFIG_ATH79_MACH_ALL0315N=y +CONFIG_ATH79_MACH_AP113=y +CONFIG_ATH79_MACH_AP121=y +CONFIG_ATH79_MACH_AP136=y +CONFIG_ATH79_MACH_AP81=y +CONFIG_ATH79_MACH_AP83=y +CONFIG_ATH79_MACH_AP96=y +CONFIG_ATH79_MACH_AW_NR580=y +CONFIG_ATH79_MACH_DB120=y +CONFIG_ATH79_MACH_DIR_600_A1=y +CONFIG_ATH79_MACH_DIR_615_C1=y +CONFIG_ATH79_MACH_DIR_825_B1=y +CONFIG_ATH79_MACH_EAP7660D=y +CONFIG_ATH79_MACH_EW_DORIN=y +CONFIG_ATH79_MACH_HORNET_UB=y +CONFIG_ATH79_MACH_JA76PF=y +CONFIG_ATH79_MACH_JWAP003=y +CONFIG_ATH79_MACH_MZK_W04NU=y +CONFIG_ATH79_MACH_MZK_W300NH=y +CONFIG_ATH79_MACH_NBG460N=y +CONFIG_ATH79_MACH_OM2P=y +CONFIG_ATH79_MACH_PB42=y +CONFIG_ATH79_MACH_PB44=y +CONFIG_ATH79_MACH_PB92=y +CONFIG_ATH79_MACH_RB2011=y +CONFIG_ATH79_MACH_RB4XX=y +CONFIG_ATH79_MACH_RB750=y +CONFIG_ATH79_MACH_RW2458N=y +CONFIG_ATH79_MACH_TEW_632BRP=y +CONFIG_ATH79_MACH_TEW_673GRU=y +CONFIG_ATH79_MACH_TEW_712BR=y +CONFIG_ATH79_MACH_TL_MR11U=y +CONFIG_ATH79_MACH_TL_MR3020=y +CONFIG_ATH79_MACH_TL_MR3X20=y +CONFIG_ATH79_MACH_TL_WA901ND=y +CONFIG_ATH79_MACH_TL_WA901ND_V2=y +CONFIG_ATH79_MACH_TL_WDR4300=y +CONFIG_ATH79_MACH_TL_WR1041N_V2=y +CONFIG_ATH79_MACH_TL_WR1043ND=y +CONFIG_ATH79_MACH_TL_WR2543N=y +CONFIG_ATH79_MACH_TL_WR703N=y +CONFIG_ATH79_MACH_TL_WR741ND=y +CONFIG_ATH79_MACH_TL_WR741ND_V4=y +CONFIG_ATH79_MACH_TL_WR841N_V1=y +CONFIG_ATH79_MACH_TL_WR841N_V8=y +CONFIG_ATH79_MACH_TL_WR941ND=y +CONFIG_ATH79_MACH_UBNT=y +CONFIG_ATH79_MACH_UBNT_XM=y +CONFIG_ATH79_MACH_WHR_HP_G300N=y +CONFIG_ATH79_MACH_WLAE_AG300N=y +CONFIG_ATH79_MACH_WNDR3700=y +CONFIG_ATH79_MACH_WNR2000=y +CONFIG_ATH79_MACH_WP543=y +CONFIG_ATH79_MACH_WPE72=y +CONFIG_ATH79_MACH_WRT160NL=y +CONFIG_ATH79_MACH_WRT400N=y +CONFIG_ATH79_MACH_WZR_HP_AG300H=y +CONFIG_ATH79_MACH_WZR_HP_G300NH=y +CONFIG_ATH79_MACH_WZR_HP_G300NH2=y +CONFIG_ATH79_MACH_WZR_HP_G450H=y +CONFIG_ATH79_MACH_ZCN_1523H=y +CONFIG_ATH79_NVRAM=y +CONFIG_ATH79_PCI_ATH9K_FIXUP=y +CONFIG_ATH79_ROUTERBOOT=y +# CONFIG_ATH79_WDT is not set +CONFIG_BCMA_POSSIBLE=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_CEVT_R4K=y +CONFIG_CEVT_R4K_LIB=y +CONFIG_CMDLINE="rootfstype=squashfs,yaffs,jffs2 noinitrd" +CONFIG_CMDLINE_BOOL=y +# CONFIG_CMDLINE_OVERRIDE is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPS32_R2=y +CONFIG_CPU_MIPSR2=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CSRC_R4K=y +CONFIG_CSRC_R4K_LIB=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_EARLY_PRINTK=y +CONFIG_ETHERNET_PACKET_MANGLE=y +CONFIG_GENERIC_ATOMIC64=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_NXP_74HC153=y +CONFIG_GPIO_PCF857X=y +CONFIG_GPIO_SYSFS=y +CONFIG_HARDWARE_WATCHPOINTS=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_GENERIC_HARDIRQS=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_WORK=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HW_HAS_PCI=y +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_GPIO=y +CONFIG_IMAGE_CMDLINE_HACK=y +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_SOURCE="../../root" +CONFIG_IP17XX_PHY=y +CONFIG_IRQ_CPU=y +CONFIG_IRQ_FORCED_THREADING=y +# CONFIG_LEDS_RB750 is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set +# CONFIG_LEDS_TRIGGER_NETDEV is not set +# CONFIG_LEDS_TRIGGER_TIMER is not set +# CONFIG_LEDS_WNDR3700_USB is not set +# CONFIG_M25PXX_USE_FAST_READ is not set +CONFIG_MARVELL_PHY=y +CONFIG_MDIO_BOARDINFO=y +CONFIG_MICREL_PHY=y +CONFIG_MIPS=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +CONFIG_MIPS_MACHINE=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_M25P80=y +CONFIG_MTD_MYLOADER_PARTS=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-2 +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_TPLINK_PARTS=y +CONFIG_MTD_WRT160NL_PARTS=y +CONFIG_MYLOADER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_MV88E6060=y +CONFIG_NET_DSA_MV88E6063=y +CONFIG_NET_DSA_TAG_TRAILER=y +CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PCI=y +CONFIG_PCI_AR724X=y +CONFIG_PCI_DISABLE_COMMON_QUIRKS=y +CONFIG_PCI_DOMAINS=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PHYLIB=y +# CONFIG_PREEMPT_RCU is not set +CONFIG_RLE_DECOMPRESS=y +CONFIG_RTL8306_PHY=y +CONFIG_RTL8366RB_PHY=y +CONFIG_RTL8366S_PHY=y +CONFIG_RTL8366_SMI=y +CONFIG_RTL8367_PHY=y +# CONFIG_SCSI_DMA is not set +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=1 +CONFIG_SERIAL_AR933X=y +CONFIG_SERIAL_AR933X_CONSOLE=y +CONFIG_SERIAL_AR933X_NR_UARTS=2 +# CONFIG_SLAB is not set +CONFIG_SLUB=y +CONFIG_SOC_AR71XX=y +CONFIG_SOC_AR724X=y +CONFIG_SOC_AR913X=y +CONFIG_SOC_AR933X=y +CONFIG_SOC_AR934X=y +CONFIG_SOC_QCA955X=y +CONFIG_SPI=y +CONFIG_SPI_AP83=y +CONFIG_SPI_ATH79=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_MASTER=y +# CONFIG_SPI_RB4XX is not set +# CONFIG_SPI_RB4XX_CPLD is not set +# CONFIG_SPI_VSC7385 is not set +CONFIG_SWCONFIG=y +CONFIG_SWCONFIG_LEDS=y +CONFIG_SYS_HAS_CPU_MIPS32_R2=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_USB_ARCH_HAS_XHCI=y +CONFIG_USB_SUPPORT=y +CONFIG_XZ_DEC=y +CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c new file mode 100644 index 000000000..c08e43808 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.c @@ -0,0 +1,153 @@ +/* + * Atheros AP9X reference board PCI initialization + * + * Copyright (C) 2009-2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include + +#include + +#include "dev-ap9x-pci.h" +#include "pci-ath9k-fixup.h" +#include "pci.h" + +static struct ath9k_platform_data ap9x_wmac0_data = { + .led_pin = -1, +}; +static struct ath9k_platform_data ap9x_wmac1_data = { + .led_pin = -1, +}; +static char ap9x_wmac0_mac[6]; +static char ap9x_wmac1_mac[6]; + +__init void ap9x_pci_setup_wmac_led_pin(unsigned wmac, int pin) +{ + switch (wmac) { + case 0: + ap9x_wmac0_data.led_pin = pin; + break; + case 1: + ap9x_wmac1_data.led_pin = pin; + break; + } +} + +__init struct ath9k_platform_data *ap9x_pci_get_wmac_data(unsigned wmac) +{ + switch (wmac) { + case 0: + return &ap9x_wmac0_data; + + case 1: + return &ap9x_wmac1_data; + } + + return NULL; +} + +__init void ap9x_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 val) +{ + switch (wmac) { + case 0: + ap9x_wmac0_data.gpio_mask = mask; + ap9x_wmac0_data.gpio_val = val; + break; + case 1: + ap9x_wmac1_data.gpio_mask = mask; + ap9x_wmac1_data.gpio_val = val; + break; + } +} + +__init void ap9x_pci_setup_wmac_leds(unsigned wmac, struct gpio_led *leds, + int num_leds) +{ + switch (wmac) { + case 0: + ap9x_wmac0_data.leds = leds; + ap9x_wmac0_data.num_leds = num_leds; + break; + case 1: + ap9x_wmac1_data.leds = leds; + ap9x_wmac1_data.num_leds = num_leds; + break; + } +} + +static int ap91_pci_plat_dev_init(struct pci_dev *dev) +{ + switch (PCI_SLOT(dev->devfn)) { + case 0: + dev->dev.platform_data = &ap9x_wmac0_data; + break; + } + + return 0; +} + +__init void ap91_pci_init(u8 *cal_data, u8 *mac_addr) +{ + if (cal_data) + memcpy(ap9x_wmac0_data.eeprom_data, cal_data, + sizeof(ap9x_wmac0_data.eeprom_data)); + + if (mac_addr) { + memcpy(ap9x_wmac0_mac, mac_addr, sizeof(ap9x_wmac0_mac)); + ap9x_wmac0_data.macaddr = ap9x_wmac0_mac; + } + + ath79_pci_set_plat_dev_init(ap91_pci_plat_dev_init); + ath79_register_pci(); + + pci_enable_ath9k_fixup(0, ap9x_wmac0_data.eeprom_data); +} + +static int ap94_pci_plat_dev_init(struct pci_dev *dev) +{ + switch (PCI_SLOT(dev->devfn)) { + case 17: + dev->dev.platform_data = &ap9x_wmac0_data; + break; + + case 18: + dev->dev.platform_data = &ap9x_wmac1_data; + break; + } + + return 0; +} + +__init void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, + u8 *cal_data1, u8 *mac_addr1) +{ + if (cal_data0) + memcpy(ap9x_wmac0_data.eeprom_data, cal_data0, + sizeof(ap9x_wmac0_data.eeprom_data)); + + if (cal_data1) + memcpy(ap9x_wmac1_data.eeprom_data, cal_data1, + sizeof(ap9x_wmac1_data.eeprom_data)); + + if (mac_addr0) { + memcpy(ap9x_wmac0_mac, mac_addr0, sizeof(ap9x_wmac0_mac)); + ap9x_wmac0_data.macaddr = ap9x_wmac0_mac; + } + + if (mac_addr1) { + memcpy(ap9x_wmac1_mac, mac_addr1, sizeof(ap9x_wmac1_mac)); + ap9x_wmac1_data.macaddr = ap9x_wmac1_mac; + } + + ath79_pci_set_plat_dev_init(ap94_pci_plat_dev_init); + ath79_register_pci(); + + pci_enable_ath9k_fixup(17, ap9x_wmac0_data.eeprom_data); + pci_enable_ath9k_fixup(18, ap9x_wmac1_data.eeprom_data); +} diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h b/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h new file mode 100644 index 000000000..d56f7136b --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-ap9x-pci.h @@ -0,0 +1,46 @@ +/* + * Atheros AP9X reference board PCI initialization + * + * Copyright (C) 2009-2012 Gabor Juhos + * + * This program 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. + */ + +#ifndef _ATH79_DEV_AP9X_PCI_H +#define _ATH79_DEV_AP9X_PCI_H + +struct gpio_led; +struct ath9k_platform_data; + +#if defined(CONFIG_ATH79_DEV_AP9X_PCI) +void ap9x_pci_setup_wmac_led_pin(unsigned wmac, int pin); +void ap9x_pci_setup_wmac_gpio(unsigned wmac, u32 mask, u32 val); +void ap9x_pci_setup_wmac_leds(unsigned wmac, struct gpio_led *leds, + int num_leds); +struct ath9k_platform_data *ap9x_pci_get_wmac_data(unsigned wmac); + +void ap91_pci_init(u8 *cal_data, u8 *mac_addr); +void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, + u8 *cal_data1, u8 *mac_addr1); + +#else +static inline void ap9x_pci_setup_wmac_led_pin(unsigned wmac, int pin) {} +static inline void ap9x_pci_setup_wmac_gpio(unsigned wmac, + u32 mask, u32 val) {} +static inline void ap9x_pci_setup_wmac_leds(unsigned wmac, + struct gpio_led *leds, + int num_leds) {} +static inline struct ath9k_platform_data *ap9x_pci_get_wmac_data(unsigned wmac) +{ + return NULL; +} + +static inline void ap91_pci_init(u8 *cal_data, u8 *mac_addr) {} +static inline void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, + u8 *cal_data1, u8 *mac_addr1) {} +#endif + +#endif /* _ATH79_DEV_AP9X_PCI_H */ + diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.c new file mode 100644 index 000000000..176414738 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.c @@ -0,0 +1,36 @@ +/* + * Atheros AR71xx DSA switch device support + * + * Copyright (C) 2008-2012 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#include +#include + +#include + +#include "dev-dsa.h" + +static struct platform_device ar71xx_dsa_switch_device = { + .name = "dsa", + .id = 0, +}; + +void __init ath79_register_dsa(struct device *netdev, + struct device *miidev, + struct dsa_platform_data *d) +{ + int i; + + d->netdev = netdev; + for (i = 0; i < d->nr_chips; i++) + d->chip[i].mii_bus = miidev; + + ar71xx_dsa_switch_device.dev.platform_data = d; + platform_device_register(&ar71xx_dsa_switch_device); +} diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.h b/target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.h new file mode 100644 index 000000000..3730202e8 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-dsa.h @@ -0,0 +1,21 @@ +/* + * Atheros AR71xx DSA switch device support + * + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#ifndef _ATH79_DEV_DSA_H +#define _ATH79_DEV_DSA_H + +#include + +void ath79_register_dsa(struct device *netdev, + struct device *miidev, + struct dsa_platform_data *d); + +#endif /* _ATH79_DEV_DSA_H */ diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c new file mode 100644 index 000000000..4487958bc --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c @@ -0,0 +1,1029 @@ +/* + * Atheros AR71xx SoC platform devices + * + * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2008-2012 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * Parts of this file are based on Atheros 2.6.15 BSP + * Parts of this file are based on Atheros 2.6.31 BSP + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "common.h" +#include "dev-eth.h" + +unsigned char ath79_mac_base[ETH_ALEN] __initdata; + +static struct resource ath79_mdio0_resources[] = { + { + .name = "mdio_base", + .flags = IORESOURCE_MEM, + .start = AR71XX_GE0_BASE, + .end = AR71XX_GE0_BASE + 0x200 - 1, + } +}; + +static struct ag71xx_mdio_platform_data ath79_mdio0_data; + +struct platform_device ath79_mdio0_device = { + .name = "ag71xx-mdio", + .id = 0, + .resource = ath79_mdio0_resources, + .num_resources = ARRAY_SIZE(ath79_mdio0_resources), + .dev = { + .platform_data = &ath79_mdio0_data, + }, +}; + +static struct resource ath79_mdio1_resources[] = { + { + .name = "mdio_base", + .flags = IORESOURCE_MEM, + .start = AR71XX_GE1_BASE, + .end = AR71XX_GE1_BASE + 0x200 - 1, + } +}; + +static struct ag71xx_mdio_platform_data ath79_mdio1_data; + +struct platform_device ath79_mdio1_device = { + .name = "ag71xx-mdio", + .id = 1, + .resource = ath79_mdio1_resources, + .num_resources = ARRAY_SIZE(ath79_mdio1_resources), + .dev = { + .platform_data = &ath79_mdio1_data, + }, +}; + +static void ath79_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift) +{ + void __iomem *base; + u32 t; + + base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); + + t = __raw_readl(base + cfg_reg); + t &= ~(3 << shift); + t |= (2 << shift); + __raw_writel(t, base + cfg_reg); + udelay(100); + + __raw_writel(pll_val, base + pll_reg); + + t |= (3 << shift); + __raw_writel(t, base + cfg_reg); + udelay(100); + + t &= ~(3 << shift); + __raw_writel(t, base + cfg_reg); + udelay(100); + + printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n", + (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg)); + + iounmap(base); +} + +static void __init ath79_mii_ctrl_set_if(unsigned int reg, + unsigned int mii_if) +{ + void __iomem *base; + u32 t; + + base = ioremap(AR71XX_MII_BASE, AR71XX_MII_SIZE); + + t = __raw_readl(base + reg); + t &= ~(AR71XX_MII_CTRL_IF_MASK); + t |= (mii_if & AR71XX_MII_CTRL_IF_MASK); + __raw_writel(t, base + reg); + + iounmap(base); +} + +static void ath79_mii_ctrl_set_speed(unsigned int reg, unsigned int speed) +{ + void __iomem *base; + unsigned int mii_speed; + u32 t; + + switch (speed) { + case SPEED_10: + mii_speed = AR71XX_MII_CTRL_SPEED_10; + break; + case SPEED_100: + mii_speed = AR71XX_MII_CTRL_SPEED_100; + break; + case SPEED_1000: + mii_speed = AR71XX_MII_CTRL_SPEED_1000; + break; + default: + BUG(); + } + + base = ioremap(AR71XX_MII_BASE, AR71XX_MII_SIZE); + + t = __raw_readl(base + reg); + t &= ~(AR71XX_MII_CTRL_SPEED_MASK << AR71XX_MII_CTRL_SPEED_SHIFT); + t |= mii_speed << AR71XX_MII_CTRL_SPEED_SHIFT; + __raw_writel(t, base + reg); + + iounmap(base); +} + +static unsigned long ar934x_get_mdio_ref_clock(void) +{ + void __iomem *base; + unsigned long ret; + u32 t; + + base = ioremap(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); + + ret = 0; + t = __raw_readl(base + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG); + if (t & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL) { + ret = 100 * 1000 * 1000; + } else { + struct clk *clk; + + clk = clk_get(NULL, "ref"); + if (!IS_ERR(clk)) + ret = clk_get_rate(clk); + } + + iounmap(base); + + return ret; +} + +void __init ath79_register_mdio(unsigned int id, u32 phy_mask) +{ + struct platform_device *mdio_dev; + struct ag71xx_mdio_platform_data *mdio_data; + unsigned int max_id; + + if (ath79_soc == ATH79_SOC_AR9341 || + ath79_soc == ATH79_SOC_AR9342 || + ath79_soc == ATH79_SOC_AR9344 || + ath79_soc == ATH79_SOC_QCA9558) + max_id = 1; + else + max_id = 0; + + if (id > max_id) { + printk(KERN_ERR "ar71xx: invalid MDIO id %u\n", id); + return; + } + + switch (ath79_soc) { + case ATH79_SOC_AR7241: + case ATH79_SOC_AR9330: + case ATH79_SOC_AR9331: + mdio_dev = &ath79_mdio1_device; + mdio_data = &ath79_mdio1_data; + break; + + case ATH79_SOC_AR9341: + case ATH79_SOC_AR9342: + case ATH79_SOC_AR9344: + case ATH79_SOC_QCA9558: + if (id == 0) { + mdio_dev = &ath79_mdio0_device; + mdio_data = &ath79_mdio0_data; + } else { + mdio_dev = &ath79_mdio1_device; + mdio_data = &ath79_mdio1_data; + } + break; + + case ATH79_SOC_AR7242: + ath79_set_pll(AR71XX_PLL_REG_SEC_CONFIG, + AR7242_PLL_REG_ETH0_INT_CLOCK, 0x62000000, + AR71XX_ETH0_PLL_SHIFT); + /* fall through */ + default: + mdio_dev = &ath79_mdio0_device; + mdio_data = &ath79_mdio0_data; + break; + } + + mdio_data->phy_mask = phy_mask; + + switch (ath79_soc) { + case ATH79_SOC_AR7240: + mdio_data->is_ar7240 = 1; + /* fall through */ + case ATH79_SOC_AR7241: + mdio_data->builtin_switch = 1; + break; + + case ATH79_SOC_AR9330: + mdio_data->is_ar9330 = 1; + /* fall through */ + case ATH79_SOC_AR9331: + mdio_data->builtin_switch = 1; + break; + + case ATH79_SOC_AR9341: + case ATH79_SOC_AR9342: + case ATH79_SOC_AR9344: + if (id == 1) { + mdio_data->builtin_switch = 1; + mdio_data->ref_clock = ar934x_get_mdio_ref_clock(); + mdio_data->mdio_clock = 6250000; + } + mdio_data->is_ar934x = 1; + break; + case ATH79_SOC_QCA9558: + if (id == 1) + mdio_data->builtin_switch = 1; + mdio_data->is_ar934x = 1; + break; + + default: + break; + } + + platform_device_register(mdio_dev); +} + +struct ath79_eth_pll_data ath79_eth0_pll_data; +struct ath79_eth_pll_data ath79_eth1_pll_data; + +static u32 ath79_get_eth_pll(unsigned int mac, int speed) +{ + struct ath79_eth_pll_data *pll_data; + u32 pll_val; + + switch (mac) { + case 0: + pll_data = &ath79_eth0_pll_data; + break; + case 1: + pll_data = &ath79_eth1_pll_data; + break; + default: + BUG(); + } + + switch (speed) { + case SPEED_10: + pll_val = pll_data->pll_10; + break; + case SPEED_100: + pll_val = pll_data->pll_100; + break; + case SPEED_1000: + pll_val = pll_data->pll_1000; + break; + default: + BUG(); + } + + return pll_val; +} + +static void ath79_set_speed_ge0(int speed) +{ + u32 val = ath79_get_eth_pll(0, speed); + + ath79_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK, + val, AR71XX_ETH0_PLL_SHIFT); + ath79_mii_ctrl_set_speed(AR71XX_MII_REG_MII0_CTRL, speed); +} + +static void ath79_set_speed_ge1(int speed) +{ + u32 val = ath79_get_eth_pll(1, speed); + + ath79_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK, + val, AR71XX_ETH1_PLL_SHIFT); + ath79_mii_ctrl_set_speed(AR71XX_MII_REG_MII1_CTRL, speed); +} + +static void ar7242_set_speed_ge0(int speed) +{ + u32 val = ath79_get_eth_pll(0, speed); + void __iomem *base; + + base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); + __raw_writel(val, base + AR7242_PLL_REG_ETH0_INT_CLOCK); + iounmap(base); +} + +static void ar91xx_set_speed_ge0(int speed) +{ + u32 val = ath79_get_eth_pll(0, speed); + + ath79_set_pll(AR913X_PLL_REG_ETH_CONFIG, AR913X_PLL_REG_ETH0_INT_CLOCK, + val, AR913X_ETH0_PLL_SHIFT); + ath79_mii_ctrl_set_speed(AR71XX_MII_REG_MII0_CTRL, speed); +} + +static void ar91xx_set_speed_ge1(int speed) +{ + u32 val = ath79_get_eth_pll(1, speed); + + ath79_set_pll(AR913X_PLL_REG_ETH_CONFIG, AR913X_PLL_REG_ETH1_INT_CLOCK, + val, AR913X_ETH1_PLL_SHIFT); + ath79_mii_ctrl_set_speed(AR71XX_MII_REG_MII1_CTRL, speed); +} + +static void ar934x_set_speed_ge0(int speed) +{ + void __iomem *base; + u32 val = ath79_get_eth_pll(0, speed); + + base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); + __raw_writel(val, base + AR934X_PLL_ETH_XMII_CONTROL_REG); + iounmap(base); +} + +static void ath79_set_speed_dummy(int speed) +{ +} + +static void ath79_ddr_no_flush(void) +{ +} + +static void ath79_ddr_flush_ge0(void) +{ + ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_GE0); +} + +static void ath79_ddr_flush_ge1(void) +{ + ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_GE1); +} + +static void ar724x_ddr_flush_ge0(void) +{ + ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_GE0); +} + +static void ar724x_ddr_flush_ge1(void) +{ + ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_GE1); +} + +static void ar91xx_ddr_flush_ge0(void) +{ + ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_GE0); +} + +static void ar91xx_ddr_flush_ge1(void) +{ + ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_GE1); +} + +static void ar933x_ddr_flush_ge0(void) +{ + ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_GE0); +} + +static void ar933x_ddr_flush_ge1(void) +{ + ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_GE1); +} + +static struct resource ath79_eth0_resources[] = { + { + .name = "mac_base", + .flags = IORESOURCE_MEM, + .start = AR71XX_GE0_BASE, + .end = AR71XX_GE0_BASE + 0x200 - 1, + }, { + .name = "mac_irq", + .flags = IORESOURCE_IRQ, + .start = ATH79_CPU_IRQ_GE0, + .end = ATH79_CPU_IRQ_GE0, + }, +}; + +struct ag71xx_platform_data ath79_eth0_data = { + .reset_bit = AR71XX_RESET_GE0_MAC, +}; + +struct platform_device ath79_eth0_device = { + .name = "ag71xx", + .id = 0, + .resource = ath79_eth0_resources, + .num_resources = ARRAY_SIZE(ath79_eth0_resources), + .dev = { + .platform_data = &ath79_eth0_data, + }, +}; + +static struct resource ath79_eth1_resources[] = { + { + .name = "mac_base", + .flags = IORESOURCE_MEM, + .start = AR71XX_GE1_BASE, + .end = AR71XX_GE1_BASE + 0x200 - 1, + }, { + .name = "mac_irq", + .flags = IORESOURCE_IRQ, + .start = ATH79_CPU_IRQ_GE1, + .end = ATH79_CPU_IRQ_GE1, + }, +}; + +struct ag71xx_platform_data ath79_eth1_data = { + .reset_bit = AR71XX_RESET_GE1_MAC, +}; + +struct platform_device ath79_eth1_device = { + .name = "ag71xx", + .id = 1, + .resource = ath79_eth1_resources, + .num_resources = ARRAY_SIZE(ath79_eth1_resources), + .dev = { + .platform_data = &ath79_eth1_data, + }, +}; + +struct ag71xx_switch_platform_data ath79_switch_data; + +#define AR71XX_PLL_VAL_1000 0x00110000 +#define AR71XX_PLL_VAL_100 0x00001099 +#define AR71XX_PLL_VAL_10 0x00991099 + +#define AR724X_PLL_VAL_1000 0x00110000 +#define AR724X_PLL_VAL_100 0x00001099 +#define AR724X_PLL_VAL_10 0x00991099 + +#define AR7242_PLL_VAL_1000 0x16000000 +#define AR7242_PLL_VAL_100 0x00000101 +#define AR7242_PLL_VAL_10 0x00001616 + +#define AR913X_PLL_VAL_1000 0x1a000000 +#define AR913X_PLL_VAL_100 0x13000a44 +#define AR913X_PLL_VAL_10 0x00441099 + +#define AR933X_PLL_VAL_1000 0x00110000 +#define AR933X_PLL_VAL_100 0x00001099 +#define AR933X_PLL_VAL_10 0x00991099 + +#define AR934X_PLL_VAL_1000 0x16000000 +#define AR934X_PLL_VAL_100 0x00000101 +#define AR934X_PLL_VAL_10 0x00001616 + +static void __init ath79_init_eth_pll_data(unsigned int id) +{ + struct ath79_eth_pll_data *pll_data; + u32 pll_10, pll_100, pll_1000; + + switch (id) { + case 0: + pll_data = &ath79_eth0_pll_data; + break; + case 1: + pll_data = &ath79_eth1_pll_data; + break; + default: + BUG(); + } + + switch (ath79_soc) { + case ATH79_SOC_AR7130: + case ATH79_SOC_AR7141: + case ATH79_SOC_AR7161: + pll_10 = AR71XX_PLL_VAL_10; + pll_100 = AR71XX_PLL_VAL_100; + pll_1000 = AR71XX_PLL_VAL_1000; + break; + + case ATH79_SOC_AR7240: + case ATH79_SOC_AR7241: + pll_10 = AR724X_PLL_VAL_10; + pll_100 = AR724X_PLL_VAL_100; + pll_1000 = AR724X_PLL_VAL_1000; + break; + + case ATH79_SOC_AR7242: + pll_10 = AR7242_PLL_VAL_10; + pll_100 = AR7242_PLL_VAL_100; + pll_1000 = AR7242_PLL_VAL_1000; + break; + + case ATH79_SOC_AR9130: + case ATH79_SOC_AR9132: + pll_10 = AR913X_PLL_VAL_10; + pll_100 = AR913X_PLL_VAL_100; + pll_1000 = AR913X_PLL_VAL_1000; + break; + + case ATH79_SOC_AR9330: + case ATH79_SOC_AR9331: + pll_10 = AR933X_PLL_VAL_10; + pll_100 = AR933X_PLL_VAL_100; + pll_1000 = AR933X_PLL_VAL_1000; + break; + + case ATH79_SOC_AR9341: + case ATH79_SOC_AR9342: + case ATH79_SOC_AR9344: + case ATH79_SOC_QCA9558: + pll_10 = AR934X_PLL_VAL_10; + pll_100 = AR934X_PLL_VAL_100; + pll_1000 = AR934X_PLL_VAL_1000; + break; + + default: + BUG(); + } + + if (!pll_data->pll_10) + pll_data->pll_10 = pll_10; + + if (!pll_data->pll_100) + pll_data->pll_100 = pll_100; + + if (!pll_data->pll_1000) + pll_data->pll_1000 = pll_1000; +} + +static int __init ath79_setup_phy_if_mode(unsigned int id, + struct ag71xx_platform_data *pdata) +{ + unsigned int mii_if; + + switch (id) { + case 0: + switch (ath79_soc) { + case ATH79_SOC_AR7130: + case ATH79_SOC_AR7141: + case ATH79_SOC_AR7161: + case ATH79_SOC_AR9130: + case ATH79_SOC_AR9132: + switch (pdata->phy_if_mode) { + case PHY_INTERFACE_MODE_MII: + mii_if = AR71XX_MII0_CTRL_IF_MII; + break; + case PHY_INTERFACE_MODE_GMII: + mii_if = AR71XX_MII0_CTRL_IF_GMII; + break; + case PHY_INTERFACE_MODE_RGMII: + mii_if = AR71XX_MII0_CTRL_IF_RGMII; + break; + case PHY_INTERFACE_MODE_RMII: + mii_if = AR71XX_MII0_CTRL_IF_RMII; + break; + default: + return -EINVAL; + } + ath79_mii_ctrl_set_if(AR71XX_MII_REG_MII0_CTRL, mii_if); + break; + + case ATH79_SOC_AR7240: + case ATH79_SOC_AR7241: + case ATH79_SOC_AR9330: + case ATH79_SOC_AR9331: + pdata->phy_if_mode = PHY_INTERFACE_MODE_MII; + break; + + case ATH79_SOC_AR7242: + /* FIXME */ + + case ATH79_SOC_AR9341: + case ATH79_SOC_AR9342: + case ATH79_SOC_AR9344: + case ATH79_SOC_QCA9558: + switch (pdata->phy_if_mode) { + case PHY_INTERFACE_MODE_MII: + case PHY_INTERFACE_MODE_GMII: + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RMII: + break; + default: + return -EINVAL; + } + break; + + default: + BUG(); + } + break; + case 1: + switch (ath79_soc) { + case ATH79_SOC_AR7130: + case ATH79_SOC_AR7141: + case ATH79_SOC_AR7161: + case ATH79_SOC_AR9130: + case ATH79_SOC_AR9132: + switch (pdata->phy_if_mode) { + case PHY_INTERFACE_MODE_RMII: + mii_if = AR71XX_MII1_CTRL_IF_RMII; + break; + case PHY_INTERFACE_MODE_RGMII: + mii_if = AR71XX_MII1_CTRL_IF_RGMII; + break; + default: + return -EINVAL; + } + ath79_mii_ctrl_set_if(AR71XX_MII_REG_MII1_CTRL, mii_if); + break; + + case ATH79_SOC_AR7240: + case ATH79_SOC_AR7241: + case ATH79_SOC_AR9330: + case ATH79_SOC_AR9331: + pdata->phy_if_mode = PHY_INTERFACE_MODE_GMII; + break; + + case ATH79_SOC_AR7242: + /* FIXME */ + + case ATH79_SOC_AR9341: + case ATH79_SOC_AR9342: + case ATH79_SOC_AR9344: + case ATH79_SOC_QCA9558: + switch (pdata->phy_if_mode) { + case PHY_INTERFACE_MODE_MII: + case PHY_INTERFACE_MODE_GMII: + break; + default: + return -EINVAL; + } + break; + + default: + BUG(); + } + break; + } + + return 0; +} + +void __init ath79_setup_ar933x_phy4_switch(bool mac, bool mdio) +{ + void __iomem *base; + u32 t; + + base = ioremap(AR933X_GMAC_BASE, AR933X_GMAC_SIZE); + + t = __raw_readl(base + AR933X_GMAC_REG_ETH_CFG); + t &= ~(AR933X_ETH_CFG_SW_PHY_SWAP | AR933X_ETH_CFG_SW_PHY_ADDR_SWAP); + if (mac) + t |= AR933X_ETH_CFG_SW_PHY_SWAP; + if (mdio) + t |= AR933X_ETH_CFG_SW_PHY_ADDR_SWAP; + __raw_writel(t, base + AR933X_GMAC_REG_ETH_CFG); + + iounmap(base); +} + +static int ath79_eth_instance __initdata; +void __init ath79_register_eth(unsigned int id) +{ + struct platform_device *pdev; + struct ag71xx_platform_data *pdata; + int err; + + if (id > 1) { + printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id); + return; + } + + ath79_init_eth_pll_data(id); + + if (id == 0) + pdev = &ath79_eth0_device; + else + pdev = &ath79_eth1_device; + + pdata = pdev->dev.platform_data; + + err = ath79_setup_phy_if_mode(id, pdata); + if (err) { + printk(KERN_ERR + "ar71xx: invalid PHY interface mode for GE%u\n", id); + return; + } + + switch (ath79_soc) { + case ATH79_SOC_AR7130: + if (id == 0) { + pdata->ddr_flush = ath79_ddr_flush_ge0; + pdata->set_speed = ath79_set_speed_ge0; + } else { + pdata->ddr_flush = ath79_ddr_flush_ge1; + pdata->set_speed = ath79_set_speed_ge1; + } + break; + + case ATH79_SOC_AR7141: + case ATH79_SOC_AR7161: + if (id == 0) { + pdata->ddr_flush = ath79_ddr_flush_ge0; + pdata->set_speed = ath79_set_speed_ge0; + } else { + pdata->ddr_flush = ath79_ddr_flush_ge1; + pdata->set_speed = ath79_set_speed_ge1; + } + pdata->has_gbit = 1; + break; + + case ATH79_SOC_AR7242: + if (id == 0) { + pdata->reset_bit |= AR724X_RESET_GE0_MDIO | + AR71XX_RESET_GE0_PHY; + pdata->ddr_flush = ar724x_ddr_flush_ge0; + pdata->set_speed = ar7242_set_speed_ge0; + } else { + pdata->reset_bit |= AR724X_RESET_GE1_MDIO | + AR71XX_RESET_GE1_PHY; + pdata->ddr_flush = ar724x_ddr_flush_ge1; + pdata->set_speed = ath79_set_speed_dummy; + } + pdata->has_gbit = 1; + pdata->is_ar724x = 1; + + if (!pdata->fifo_cfg1) + pdata->fifo_cfg1 = 0x0010ffff; + if (!pdata->fifo_cfg2) + pdata->fifo_cfg2 = 0x015500aa; + if (!pdata->fifo_cfg3) + pdata->fifo_cfg3 = 0x01f00140; + break; + + case ATH79_SOC_AR7241: + if (id == 0) + pdata->reset_bit |= AR724X_RESET_GE0_MDIO; + else + pdata->reset_bit |= AR724X_RESET_GE1_MDIO; + /* fall through */ + case ATH79_SOC_AR7240: + if (id == 0) { + pdata->reset_bit |= AR71XX_RESET_GE0_PHY; + pdata->ddr_flush = ar724x_ddr_flush_ge0; + pdata->set_speed = ath79_set_speed_dummy; + + pdata->phy_mask = BIT(4); + } else { + pdata->reset_bit |= AR71XX_RESET_GE1_PHY; + pdata->ddr_flush = ar724x_ddr_flush_ge1; + pdata->set_speed = ath79_set_speed_dummy; + + pdata->speed = SPEED_1000; + pdata->duplex = DUPLEX_FULL; + pdata->switch_data = &ath79_switch_data; + + ath79_switch_data.phy_poll_mask |= BIT(4); + } + pdata->has_gbit = 1; + pdata->is_ar724x = 1; + if (ath79_soc == ATH79_SOC_AR7240) + pdata->is_ar7240 = 1; + + if (!pdata->fifo_cfg1) + pdata->fifo_cfg1 = 0x0010ffff; + if (!pdata->fifo_cfg2) + pdata->fifo_cfg2 = 0x015500aa; + if (!pdata->fifo_cfg3) + pdata->fifo_cfg3 = 0x01f00140; + break; + + case ATH79_SOC_AR9130: + if (id == 0) { + pdata->ddr_flush = ar91xx_ddr_flush_ge0; + pdata->set_speed = ar91xx_set_speed_ge0; + } else { + pdata->ddr_flush = ar91xx_ddr_flush_ge1; + pdata->set_speed = ar91xx_set_speed_ge1; + } + pdata->is_ar91xx = 1; + break; + + case ATH79_SOC_AR9132: + if (id == 0) { + pdata->ddr_flush = ar91xx_ddr_flush_ge0; + pdata->set_speed = ar91xx_set_speed_ge0; + } else { + pdata->ddr_flush = ar91xx_ddr_flush_ge1; + pdata->set_speed = ar91xx_set_speed_ge1; + } + pdata->is_ar91xx = 1; + pdata->has_gbit = 1; + break; + + case ATH79_SOC_AR9330: + case ATH79_SOC_AR9331: + if (id == 0) { + pdata->reset_bit = AR933X_RESET_GE0_MAC | + AR933X_RESET_GE0_MDIO; + pdata->ddr_flush = ar933x_ddr_flush_ge0; + pdata->set_speed = ath79_set_speed_dummy; + + pdata->phy_mask = BIT(4); + } else { + pdata->reset_bit = AR933X_RESET_GE1_MAC | + AR933X_RESET_GE1_MDIO; + pdata->ddr_flush = ar933x_ddr_flush_ge1; + pdata->set_speed = ath79_set_speed_dummy; + + pdata->speed = SPEED_1000; + pdata->duplex = DUPLEX_FULL; + pdata->switch_data = &ath79_switch_data; + + ath79_switch_data.phy_poll_mask |= BIT(4); + } + + pdata->has_gbit = 1; + pdata->is_ar724x = 1; + + if (!pdata->fifo_cfg1) + pdata->fifo_cfg1 = 0x0010ffff; + if (!pdata->fifo_cfg2) + pdata->fifo_cfg2 = 0x015500aa; + if (!pdata->fifo_cfg3) + pdata->fifo_cfg3 = 0x01f00140; + break; + + case ATH79_SOC_AR9341: + case ATH79_SOC_AR9342: + case ATH79_SOC_AR9344: + case ATH79_SOC_QCA9558: + if (id == 0) { + pdata->reset_bit = AR934X_RESET_GE0_MAC | + AR934X_RESET_GE0_MDIO; + pdata->set_speed = ar934x_set_speed_ge0; + } else { + pdata->reset_bit = AR934X_RESET_GE1_MAC | + AR934X_RESET_GE1_MDIO; + pdata->set_speed = ath79_set_speed_dummy; + + pdata->switch_data = &ath79_switch_data; + + /* reset the built-in switch */ + ath79_device_reset_set(AR934X_RESET_ETH_SWITCH); + ath79_device_reset_clear(AR934X_RESET_ETH_SWITCH); + } + + pdata->ddr_flush = ath79_ddr_no_flush; + pdata->has_gbit = 1; + pdata->is_ar724x = 1; + + if (!pdata->fifo_cfg1) + pdata->fifo_cfg1 = 0x0010ffff; + if (!pdata->fifo_cfg2) + pdata->fifo_cfg2 = 0x015500aa; + if (!pdata->fifo_cfg3) + pdata->fifo_cfg3 = 0x01f00140; + break; + + default: + BUG(); + } + + switch (pdata->phy_if_mode) { + case PHY_INTERFACE_MODE_GMII: + case PHY_INTERFACE_MODE_RGMII: + if (!pdata->has_gbit) { + printk(KERN_ERR "ar71xx: no gbit available on eth%d\n", + id); + return; + } + /* fallthrough */ + default: + break; + } + + if (!is_valid_ether_addr(pdata->mac_addr)) { + random_ether_addr(pdata->mac_addr); + printk(KERN_DEBUG + "ar71xx: using random MAC address for eth%d\n", + ath79_eth_instance); + } + + if (pdata->mii_bus_dev == NULL) { + switch (ath79_soc) { + case ATH79_SOC_AR9341: + case ATH79_SOC_AR9342: + case ATH79_SOC_AR9344: + case ATH79_SOC_QCA9558: + if (id == 0) + pdata->mii_bus_dev = &ath79_mdio0_device.dev; + else + pdata->mii_bus_dev = &ath79_mdio1_device.dev; + break; + + case ATH79_SOC_AR7241: + case ATH79_SOC_AR9330: + case ATH79_SOC_AR9331: + pdata->mii_bus_dev = &ath79_mdio1_device.dev; + break; + + default: + pdata->mii_bus_dev = &ath79_mdio0_device.dev; + break; + } + } + + /* Reset the device */ + ath79_device_reset_set(pdata->reset_bit); + mdelay(100); + + ath79_device_reset_clear(pdata->reset_bit); + mdelay(100); + + platform_device_register(pdev); + ath79_eth_instance++; +} + +void __init ath79_set_mac_base(unsigned char *mac) +{ + memcpy(ath79_mac_base, mac, ETH_ALEN); +} + +void __init ath79_parse_mac_addr(char *mac_str) +{ + u8 tmp[ETH_ALEN]; + int t; + + t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", + &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); + + if (t != ETH_ALEN) + t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx", + &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); + + if (t == ETH_ALEN) + ath79_set_mac_base(tmp); + else + printk(KERN_DEBUG "ar71xx: failed to parse mac address " + "\"%s\"\n", mac_str); +} + +static int __init ath79_ethaddr_setup(char *str) +{ + ath79_parse_mac_addr(str); + return 1; +} +__setup("ethaddr=", ath79_ethaddr_setup); + +static int __init ath79_kmac_setup(char *str) +{ + ath79_parse_mac_addr(str); + return 1; +} +__setup("kmac=", ath79_kmac_setup); + +void __init ath79_init_mac(unsigned char *dst, const unsigned char *src, + int offset) +{ + int t; + + if (!dst) + return; + + if (!src || !is_valid_ether_addr(src)) { + memset(dst, '\0', ETH_ALEN); + return; + } + + t = (((u32) src[3]) << 16) + (((u32) src[4]) << 8) + ((u32) src[5]); + t += offset; + + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = (t >> 16) & 0xff; + dst[4] = (t >> 8) & 0xff; + dst[5] = t & 0xff; +} + +void __init ath79_init_local_mac(unsigned char *dst, const unsigned char *src) +{ + int i; + + if (!dst) + return; + + if (!src || !is_valid_ether_addr(src)) { + memset(dst, '\0', ETH_ALEN); + return; + } + + for (i = 0; i < ETH_ALEN; i++) + dst[i] = src[i]; + dst[0] |= 0x02; +} diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.h b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.h new file mode 100644 index 000000000..d4f27d9cf --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.h @@ -0,0 +1,48 @@ +/* + * Atheros AR71xx SoC device definitions + * + * Copyright (C) 2008-2012 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#ifndef _ATH79_DEV_ETH_H +#define _ATH79_DEV_ETH_H + +#include + +struct platform_device; + +extern unsigned char ath79_mac_base[] __initdata; +void ath79_parse_mac_addr(char *mac_str); +void ath79_init_mac(unsigned char *dst, const unsigned char *src, + int offset); +void ath79_init_local_mac(unsigned char *dst, const unsigned char *src); + +struct ath79_eth_pll_data { + u32 pll_10; + u32 pll_100; + u32 pll_1000; +}; + +extern struct ath79_eth_pll_data ath79_eth0_pll_data; +extern struct ath79_eth_pll_data ath79_eth1_pll_data; + +extern struct ag71xx_platform_data ath79_eth0_data; +extern struct ag71xx_platform_data ath79_eth1_data; +extern struct platform_device ath79_eth0_device; +extern struct platform_device ath79_eth1_device; +void ath79_register_eth(unsigned int id); + +extern struct ag71xx_switch_platform_data ath79_switch_data; + +extern struct platform_device ath79_mdio0_device; +extern struct platform_device ath79_mdio1_device; +void ath79_register_mdio(unsigned int id, u32 phy_mask); + +void ath79_setup_ar933x_phy4_switch(bool mac, bool mdio); + +#endif /* _ATH79_DEV_ETH_H */ diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c new file mode 100644 index 000000000..66115b1c4 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2009-2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include + +#include "dev-spi.h" +#include "dev-m25p80.h" + +static struct ath79_spi_controller_data ath79_spi0_cdata = +{ + .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, + .cs_line = 0, +}; + +static struct ath79_spi_controller_data ath79_spi1_cdata = +{ + .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, + .cs_line = 1, +}; + +static struct spi_board_info ath79_spi_info[] = { + { + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 25000000, + .modalias = "m25p80", + .controller_data = &ath79_spi0_cdata, + }, + { + .bus_num = 0, + .chip_select = 1, + .max_speed_hz = 25000000, + .modalias = "m25p80", + .controller_data = &ath79_spi1_cdata, + } +}; + +static struct ath79_spi_platform_data ath79_spi_data; + +void __init ath79_register_m25p80(struct flash_platform_data *pdata) +{ + ath79_spi_data.bus_num = 0; + ath79_spi_data.num_chipselect = 1; + ath79_spi0_cdata.is_flash = true; + ath79_spi_info[0].platform_data = pdata; + ath79_register_spi(&ath79_spi_data, ath79_spi_info, 1); +} + +static struct flash_platform_data *multi_pdata; + +static struct mtd_info *concat_devs[2] = { NULL, NULL }; +static struct work_struct mtd_concat_work; + +static void mtd_concat_add_work(struct work_struct *work) +{ + struct mtd_info *mtd; + + mtd = mtd_concat_create(concat_devs, ARRAY_SIZE(concat_devs), "flash"); + + mtd_device_register(mtd, multi_pdata->parts, multi_pdata->nr_parts); +} + +static void mtd_concat_add(struct mtd_info *mtd) +{ + static bool registered = false; + + if (registered) + return; + + if (!strcmp(mtd->name, "spi0.0")) + concat_devs[0] = mtd; + else if (!strcmp(mtd->name, "spi0.1")) + concat_devs[1] = mtd; + else + return; + + if (!concat_devs[0] || !concat_devs[1]) + return; + + registered = true; + INIT_WORK(&mtd_concat_work, mtd_concat_add_work); + schedule_work(&mtd_concat_work); +} + +static void mtd_concat_remove(struct mtd_info *mtd) +{ +} + +static void add_mtd_concat_notifier(void) +{ + static struct mtd_notifier not = { + .add = mtd_concat_add, + .remove = mtd_concat_remove, + }; + + register_mtd_user(¬); +} + + +void __init ath79_register_m25p80_multi(struct flash_platform_data *pdata) +{ + multi_pdata = pdata; + add_mtd_concat_notifier(); + ath79_spi_data.bus_num = 0; + ath79_spi_data.num_chipselect = 2; + ath79_register_spi(&ath79_spi_data, ath79_spi_info, 2); +} diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.h b/target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.h new file mode 100644 index 000000000..637b41a7d --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2009-2012 Gabor Juhos + * + * This program 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. + */ + +#ifndef _ATH79_DEV_M25P80_H +#define _ATH79_DEV_M25P80_H + +#include + +void ath79_register_m25p80(struct flash_platform_data *pdata) __init; +void ath79_register_m25p80_multi(struct flash_platform_data *pdata) __init; + +#endif /* _ATH79_DEV_M25P80_H */ diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.c new file mode 100644 index 000000000..f330395fe --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.c @@ -0,0 +1,95 @@ +/* + * Atheros AR934X SoCs built-in NAND flash controller support + * + * Copyright (C) 2011-2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "dev-nfc.h" + +static struct resource ath79_nfc_resources[2]; +static u64 ar934x_nfc_dmamask = DMA_BIT_MASK(32); +static struct ar934x_nfc_platform_data ath79_nfc_data; + +static struct platform_device ath79_nfc_device = { + .name = AR934X_NFC_DRIVER_NAME, + .id = -1, + .resource = ath79_nfc_resources, + .num_resources = ARRAY_SIZE(ath79_nfc_resources), + .dev = { + .dma_mask = &ar934x_nfc_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &ath79_nfc_data, + }, +}; + +static void ar934x_nfc_hw_reset(bool active) +{ + if (active) { + ath79_device_reset_set(AR934X_RESET_NANDF); + udelay(100); + + ath79_device_reset_set(AR934X_RESET_ETH_SWITCH_ANALOG); + udelay(250); + } else { + ath79_device_reset_clear(AR934X_RESET_ETH_SWITCH_ANALOG); + udelay(250); + + ath79_device_reset_clear(AR934X_RESET_NANDF); + udelay(100); + } +} + +static void ar934x_nfc_setup(void) +{ + ath79_nfc_resources[0].start = AR934X_NFC_BASE; + ath79_nfc_resources[0].end = AR934X_NFC_BASE + AR934X_NFC_SIZE - 1; + ath79_nfc_resources[0].flags = IORESOURCE_MEM; + + ath79_nfc_resources[1].start = ATH79_MISC_IRQ(21); + ath79_nfc_resources[1].end = ATH79_MISC_IRQ(21); + ath79_nfc_resources[1].flags = IORESOURCE_IRQ; + + ath79_nfc_data.hw_reset = ar934x_nfc_hw_reset; + + platform_device_register(&ath79_nfc_device); +} + +void __init ath79_nfc_set_select_chip(void (*f)(int chip_no)) +{ + ath79_nfc_data.select_chip = f; +} + +void __init ath79_nfc_set_scan_fixup(int (*f)(struct mtd_info *mtd)) +{ + ath79_nfc_data.scan_fixup = f; +} + +void __init ath79_nfc_set_parts(struct mtd_partition *parts, int nr_parts) +{ + ath79_nfc_data.parts = parts; + ath79_nfc_data.nr_parts = nr_parts; +} + +void __init ath79_register_nfc(void) +{ + if (soc_is_ar934x()) + ar934x_nfc_setup(); + else + BUG(); +} diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.h b/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.h new file mode 100644 index 000000000..1fc4b807b --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-nfc.h @@ -0,0 +1,27 @@ +/* + * Atheros AR934X SoCs built-in NAND Flash Controller support + * + * Copyright (C) 2011-2012 Gabor Juhos + * + * This program 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. + */ + +#ifndef _ATH79_DEV_NFC_H +#define _ATH79_DEV_NFC_H + +#ifdef CONFIG_ATH79_DEV_NFC +void ath79_nfc_set_parts(struct mtd_partition *parts, int nr_parts); +void ath79_nfc_set_select_chip(void (*f)(int chip_no)); +void ath79_nfc_set_scan_fixup(int (*f)(struct mtd_info *mtd)); +void ath79_register_nfc(void); +#else +static inline void ath79_nfc_set_parts(struct mtd_partition *parts, + int nr_parts) {} +static inline void ath79_nfc_set_select_chip(void (*f)(int chip_no)) {} +static inline void ath79_nfc_set_scan_fixup(int (*f)(struct mtd_info *mtd)) {} +static inline void ath79_register_nfc(void) {} +#endif + +#endif /* _ATH79_DEV_NFC_H */ diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-ap96.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-ap96.c new file mode 100644 index 000000000..15abb081f --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-ap96.c @@ -0,0 +1,154 @@ +/* + * ALFA Network AP96 board support + * + * Copyright (C) 2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "common.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-spi.h" +#include "dev-usb.h" +#include "machtypes.h" +#include "pci.h" + +#define ALFA_AP96_GPIO_PCIE_RESET 2 +#define ALFA_AP96_GPIO_SIM_DETECT 3 +#define ALFA_AP96_GPIO_MICROSD_CD 4 +#define ALFA_AP96_GPIO_PCIE_W_DISABLE 5 + +#define ALFA_AP96_GPIO_BUTTON_RESET 11 + +#define ALFA_AP96_KEYS_POLL_INTERVAL 20 /* msecs */ +#define ALFA_AP96_KEYS_DEBOUNCE_INTERVAL (3 * ALFA_AP96_KEYS_POLL_INTERVAL) + +static struct gpio_keys_button alfa_ap96_gpio_keys[] __initdata = { + { + .desc = "Reset button", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = ALFA_AP96_KEYS_DEBOUNCE_INTERVAL, + .gpio = ALFA_AP96_GPIO_BUTTON_RESET, + .active_low = 1, + } +}; + +static int alfa_ap96_mmc_get_cd(struct device *dev) +{ + return !gpio_get_value(ALFA_AP96_GPIO_MICROSD_CD); +} + +static struct mmc_spi_platform_data alfa_ap96_mmc_data = { + .get_cd = alfa_ap96_mmc_get_cd, + .caps = MMC_CAP_NEEDS_POLL, + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, +}; + +static struct ath79_spi_controller_data ap96_spi0_cdata = { + .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, + .cs_line = 0, + .is_flash = true, +}; + +static struct ath79_spi_controller_data ap96_spi1_cdata = { + .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, + .cs_line = 1, +}; + +static struct ath79_spi_controller_data ap96_spi2_cdata = { + .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, + .cs_line = 2, +}; + +static struct spi_board_info alfa_ap96_spi_info[] = { + { + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 25000000, + .modalias = "m25p80", + .controller_data = &ap96_spi0_cdata + }, { + .bus_num = 0, + .chip_select = 1, + .max_speed_hz = 25000000, + .modalias = "mmc_spi", + .platform_data = &alfa_ap96_mmc_data, + .controller_data = &ap96_spi1_cdata + }, { + .bus_num = 0, + .chip_select = 2, + .max_speed_hz = 6250000, + .modalias = "rtc-pcf2123", + .controller_data = &ap96_spi2_cdata + }, +}; + +static struct ath79_spi_platform_data alfa_ap96_spi_data = { + .bus_num = 0, + .num_chipselect = 3, +}; + +static void __init alfa_ap96_gpio_setup(void) +{ + ath79_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN | + AR71XX_GPIO_FUNC_SPI_CS2_EN); + + gpio_request(ALFA_AP96_GPIO_MICROSD_CD, "microSD CD"); + gpio_direction_input(ALFA_AP96_GPIO_MICROSD_CD); + gpio_request(ALFA_AP96_GPIO_PCIE_RESET, "PCIe reset"); + gpio_direction_output(ALFA_AP96_GPIO_PCIE_RESET, 1); + gpio_request(ALFA_AP96_GPIO_PCIE_W_DISABLE, "PCIe write disable"); + gpio_direction_output(ALFA_AP96_GPIO_PCIE_W_DISABLE, 1); +} + +#define ALFA_AP96_WAN_PHYMASK BIT(4) +#define ALFA_AP96_LAN_PHYMASK BIT(5) +#define ALFA_AP96_MDIO_PHYMASK (ALFA_AP96_LAN_PHYMASK | ALFA_AP96_WAN_PHYMASK) + +static void __init alfa_ap96_init(void) +{ + alfa_ap96_gpio_setup(); + + ath79_register_mdio(0, ~ALFA_AP96_MDIO_PHYMASK); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.phy_mask = ALFA_AP96_WAN_PHYMASK; + ath79_eth1_pll_data.pll_1000 = 0x110000; + + ath79_register_eth(0); + + ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth1_data.phy_mask = ALFA_AP96_LAN_PHYMASK; + ath79_eth1_pll_data.pll_1000 = 0x110000; + + ath79_register_eth(1); + + ath79_register_pci(); + ath79_register_spi(&alfa_ap96_spi_data, alfa_ap96_spi_info, + ARRAY_SIZE(alfa_ap96_spi_info)); + + ath79_register_gpio_keys_polled(-1, ALFA_AP96_KEYS_POLL_INTERVAL, + ARRAY_SIZE(alfa_ap96_gpio_keys), + alfa_ap96_gpio_keys); + ath79_register_usb(); +} + +MIPS_MACHINE(ATH79_MACH_ALFA_AP96, "ALFA-AP96", "ALFA Network AP96", + alfa_ap96_init); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-nx.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-nx.c new file mode 100644 index 000000000..a515f4f54 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-alfa-nx.c @@ -0,0 +1,113 @@ +/* + * ALFA Network N2/N5 board support + * + * Copyright (C) 2011-2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include + +#include "common.h" +#include "dev-eth.h" +#include "dev-ap9x-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "machtypes.h" + +#define ALFA_NX_GPIO_LED_2 17 +#define ALFA_NX_GPIO_LED_3 16 +#define ALFA_NX_GPIO_LED_5 12 +#define ALFA_NX_GPIO_LED_6 8 +#define ALFA_NX_GPIO_LED_7 6 +#define ALFA_NX_GPIO_LED_8 7 + +#define ALFA_NX_GPIO_BTN_RESET 11 + +#define ALFA_NX_KEYS_POLL_INTERVAL 20 /* msecs */ +#define ALFA_NX_KEYS_DEBOUNCE_INTERVAL (3 * ALFA_NX_KEYS_POLL_INTERVAL) + +#define ALFA_NX_MAC0_OFFSET 0 +#define ALFA_NX_MAC1_OFFSET 6 +#define ALFA_NX_CALDATA_OFFSET 0x1000 + +static struct gpio_keys_button alfa_nx_gpio_keys[] __initdata = { + { + .desc = "Reset button", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = ALFA_NX_KEYS_DEBOUNCE_INTERVAL, + .gpio = ALFA_NX_GPIO_BTN_RESET, + .active_low = 1, + } +}; + +static struct gpio_led alfa_nx_leds_gpio[] __initdata = { + { + .name = "alfa:green:led_2", + .gpio = ALFA_NX_GPIO_LED_2, + .active_low = 1, + }, { + .name = "alfa:green:led_3", + .gpio = ALFA_NX_GPIO_LED_3, + .active_low = 1, + }, { + .name = "alfa:red:led_5", + .gpio = ALFA_NX_GPIO_LED_5, + .active_low = 1, + }, { + .name = "alfa:amber:led_6", + .gpio = ALFA_NX_GPIO_LED_6, + .active_low = 1, + }, { + .name = "alfa:green:led_7", + .gpio = ALFA_NX_GPIO_LED_7, + .active_low = 1, + }, { + .name = "alfa:green:led_8", + .gpio = ALFA_NX_GPIO_LED_8, + .active_low = 1, + } +}; + +static void __init alfa_nx_setup(void) +{ + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + + ath79_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE, + AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + + ath79_register_m25p80(NULL); + + ath79_register_leds_gpio(0, ARRAY_SIZE(alfa_nx_leds_gpio), + alfa_nx_leds_gpio); + + ath79_register_gpio_keys_polled(-1, ALFA_NX_KEYS_POLL_INTERVAL, + ARRAY_SIZE(alfa_nx_gpio_keys), + alfa_nx_gpio_keys); + + ath79_register_mdio(0, 0x0); + + ath79_init_mac(ath79_eth0_data.mac_addr, + art + ALFA_NX_MAC0_OFFSET, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, + art + ALFA_NX_MAC1_OFFSET, 0); + + /* WAN port */ + ath79_register_eth(0); + /* LAN port */ + ath79_register_eth(1); + + ap91_pci_init(art + ALFA_NX_CALDATA_OFFSET, NULL); +} + +MIPS_MACHINE(ATH79_MACH_ALFA_NX, "ALFA-NX", "ALFA Network N2/N5", + alfa_nx_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-all0258n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-all0258n.c new file mode 100644 index 000000000..2495bcba7 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-all0258n.c @@ -0,0 +1,88 @@ +/* + * Allnet ALL0258N support + * + * Copyright (C) 2011 Daniel Golle + * + * This program 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. + */ + +#include + +#include "dev-eth.h" +#include "dev-ap9x-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "machtypes.h" + +/* found via /sys/gpio/... try and error */ +#define ALL0258N_GPIO_BTN_RESET 1 +#define ALL0258N_GPIO_LED_RSSIHIGH 13 +#define ALL0258N_GPIO_LED_RSSIMEDIUM 15 +#define ALL0258N_GPIO_LED_RSSILOW 14 + +/* defaults taken from others machs */ +#define ALL0258N_KEYS_POLL_INTERVAL 20 /* msecs */ +#define ALL0258N_KEYS_DEBOUNCE_INTERVAL (3 * ALL0258N_KEYS_POLL_INTERVAL) + +/* showed up in the original firmware's bootlog */ +#define ALL0258N_SEC_PHYMASK BIT(3) + +static struct gpio_led all0258n_leds_gpio[] __initdata = { + { + .name = "all0258n:green:rssihigh", + .gpio = ALL0258N_GPIO_LED_RSSIHIGH, + .active_low = 1, + }, { + .name = "all0258n:yellow:rssimedium", + .gpio = ALL0258N_GPIO_LED_RSSIMEDIUM, + .active_low = 1, + }, { + .name = "all0258n:red:rssilow", + .gpio = ALL0258N_GPIO_LED_RSSILOW, + .active_low = 1, + } +}; + +static struct gpio_keys_button all0258n_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = ALL0258N_KEYS_DEBOUNCE_INTERVAL, + .gpio = ALL0258N_GPIO_BTN_RESET, + .active_low = 1, + } +}; + +static void __init all0258n_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f7f0000); + u8 *ee = (u8 *) KSEG1ADDR(0x1f7f1000); + + ath79_register_m25p80(NULL); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(all0258n_leds_gpio), + all0258n_leds_gpio); + + ath79_register_gpio_keys_polled(-1, ALL0258N_KEYS_POLL_INTERVAL, + ARRAY_SIZE(all0258n_gpio_keys), + all0258n_gpio_keys); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); + + ath79_eth1_data.phy_mask = ALL0258N_SEC_PHYMASK; + + ath79_register_mdio(0, 0x0); + + ath79_register_eth(0); + ath79_register_eth(1); + + ap91_pci_init(ee, mac); +} + +MIPS_MACHINE(ATH79_MACH_ALL0258N, "ALL0258N", "Allnet ALL0258N", + all0258n_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-all0315n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-all0315n.c new file mode 100644 index 000000000..387ee7f9e --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-all0315n.c @@ -0,0 +1,85 @@ +/* + * Allnet ALL0315N support + * + * Copyright (C) 2012 Daniel Golle + * + * + * This program 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. + */ + +#include +#include + +#include "common.h" +#include "dev-eth.h" +#include "dev-ap9x-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-m25p80.h" +#include "dev-leds-gpio.h" +#include "machtypes.h" +#include "pci.h" + +#define ALL0315N_GPIO_BTN_RESET 0 +#define ALL0315N_GPIO_LED_RSSIHIGH 14 +#define ALL0315N_GPIO_LED_RSSIMEDIUM 15 +#define ALL0315N_GPIO_LED_RSSILOW 16 + +#define ALL0315N_KEYS_POLL_INTERVAL 20 /* msecs */ +#define ALL0315N_KEYS_DEBOUNCE_INTERVAL (3 * ALL0315N_KEYS_POLL_INTERVAL) + +static struct gpio_led all0315n_leds_gpio[] __initdata = { + { + .name = "all0315n:green:rssihigh", + .gpio = ALL0315N_GPIO_LED_RSSIHIGH, + .active_low = 1, + }, { + .name = "all0315n:yellow:rssimedium", + .gpio = ALL0315N_GPIO_LED_RSSIMEDIUM, + .active_low = 1, + }, { + .name = "all0315n:red:rssilow", + .gpio = ALL0315N_GPIO_LED_RSSILOW, + .active_low = 1, + } +}; + +static struct gpio_keys_button all0315n_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = ALL0315N_KEYS_DEBOUNCE_INTERVAL, + .gpio = ALL0315N_GPIO_BTN_RESET, + .active_low = 1, + } +}; + +static void __init all0315n_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1ffc0000); + u8 *ee = (u8 *) KSEG1ADDR(0x1ffc1000); + + ath79_register_m25p80(NULL); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.phy_mask = BIT(0); + + ath79_register_mdio(0, 0x0); + ath79_register_eth(0); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(all0315n_leds_gpio), + all0315n_leds_gpio); + + ath79_register_gpio_keys_polled(-1, ALL0315N_KEYS_POLL_INTERVAL, + ARRAY_SIZE(all0315n_gpio_keys), + all0315n_gpio_keys); + + ap9x_pci_setup_wmac_led_pin(0, 1); + ap91_pci_init(ee, NULL); +} + +MIPS_MACHINE(ATH79_MACH_ALL0315N, "ALL0315N", "Allnet ALL0315N", + all0315n_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ap113.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap113.c new file mode 100644 index 000000000..9b38faa47 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap113.c @@ -0,0 +1,84 @@ +/* + * Atheros AP113 board support + * + * Copyright (C) 2011 Florian Fainelli + * + * This program 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. + */ + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "pci.h" +#include "dev-usb.h" +#include "machtypes.h" + +#define AP113_GPIO_LED_USB 0 +#define AP113_GPIO_LED_STATUS 1 +#define AP113_GPIO_LED_ST 11 + +#define AP113_GPIO_BTN_JUMPSTART 12 + +#define AP113_KEYS_POLL_INTERVAL 20 /* msecs */ +#define AP113_KEYS_DEBOUNCE_INTERVAL (3 * AP113_KEYS_POLL_INTERVAL) + +static struct gpio_led ap113_leds_gpio[] __initdata = { + { + .name = "ap113:green:usb", + .gpio = AP113_GPIO_LED_USB, + .active_low = 1, + }, + { + .name = "ap113:green:status", + .gpio = AP113_GPIO_LED_STATUS, + .active_low = 1, + }, + { + .name = "ap113:green:st", + .gpio = AP113_GPIO_LED_ST, + .active_low = 1, + } +}; + +static struct gpio_keys_button ap113_gpio_keys[] __initdata = { + { + .desc = "jumpstart button", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = AP113_KEYS_DEBOUNCE_INTERVAL, + .gpio = AP113_GPIO_BTN_JUMPSTART, + .active_low = 1, + }, +}; + +static void __init ap113_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); + + ath79_register_m25p80(NULL); + + ath79_register_mdio(0, ~BIT(0)); + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_eth0_data.phy_mask = BIT(0); + + ath79_register_eth(0); + + ath79_register_gpio_keys_polled(-1, AP113_KEYS_POLL_INTERVAL, + ARRAY_SIZE(ap113_gpio_keys), + ap113_gpio_keys); + ath79_register_leds_gpio(-1, ARRAY_SIZE(ap113_leds_gpio), + ap113_leds_gpio); + + ath79_register_pci(); + + ath79_register_usb(); +} + +MIPS_MACHINE(ATH79_MACH_AP113, "AP113", "Atheros AP113", + ap113_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ap83.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap83.c new file mode 100644 index 000000000..8519a9d9a --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap83.c @@ -0,0 +1,275 @@ +/* + * Atheros AP83 board support + * + * Copyright (C) 2008-2012 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-usb.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define AP83_GPIO_LED_WLAN 6 +#define AP83_GPIO_LED_POWER 14 +#define AP83_GPIO_LED_JUMPSTART 15 +#define AP83_GPIO_BTN_JUMPSTART 12 +#define AP83_GPIO_BTN_RESET 21 + +#define AP83_050_GPIO_VSC7385_CS 1 +#define AP83_050_GPIO_VSC7385_MISO 3 +#define AP83_050_GPIO_VSC7385_MOSI 16 +#define AP83_050_GPIO_VSC7385_SCK 17 + +#define AP83_KEYS_POLL_INTERVAL 20 /* msecs */ +#define AP83_KEYS_DEBOUNCE_INTERVAL (3 * AP83_KEYS_POLL_INTERVAL) + +static struct mtd_partition ap83_flash_partitions[] = { + { + .name = "u-boot", + .offset = 0, + .size = 0x040000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "u-boot-env", + .offset = 0x040000, + .size = 0x020000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "kernel", + .offset = 0x060000, + .size = 0x140000, + }, { + .name = "rootfs", + .offset = 0x1a0000, + .size = 0x650000, + }, { + .name = "art", + .offset = 0x7f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "firmware", + .offset = 0x060000, + .size = 0x790000, + } +}; + +static struct physmap_flash_data ap83_flash_data = { + .width = 2, + .parts = ap83_flash_partitions, + .nr_parts = ARRAY_SIZE(ap83_flash_partitions), +}; + +static struct resource ap83_flash_resources[] = { + [0] = { + .start = AR71XX_SPI_BASE, + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device ap83_flash_device = { + .name = "ar91xx-flash", + .id = -1, + .resource = ap83_flash_resources, + .num_resources = ARRAY_SIZE(ap83_flash_resources), + .dev = { + .platform_data = &ap83_flash_data, + } +}; + +static struct gpio_led ap83_leds_gpio[] __initdata = { + { + .name = "ap83:green:jumpstart", + .gpio = AP83_GPIO_LED_JUMPSTART, + .active_low = 0, + }, { + .name = "ap83:green:power", + .gpio = AP83_GPIO_LED_POWER, + .active_low = 0, + }, { + .name = "ap83:green:wlan", + .gpio = AP83_GPIO_LED_WLAN, + .active_low = 0, + }, +}; + +static struct gpio_keys_button ap83_gpio_keys[] __initdata = { + { + .desc = "soft_reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = AP83_KEYS_DEBOUNCE_INTERVAL, + .gpio = AP83_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "jumpstart", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = AP83_KEYS_DEBOUNCE_INTERVAL, + .gpio = AP83_GPIO_BTN_JUMPSTART, + .active_low = 1, + } +}; + +static struct resource ap83_040_spi_resources[] = { + [0] = { + .start = AR71XX_SPI_BASE, + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device ap83_040_spi_device = { + .name = "ap83-spi", + .id = 0, + .resource = ap83_040_spi_resources, + .num_resources = ARRAY_SIZE(ap83_040_spi_resources), +}; + +static struct spi_gpio_platform_data ap83_050_spi_data = { + .miso = AP83_050_GPIO_VSC7385_MISO, + .mosi = AP83_050_GPIO_VSC7385_MOSI, + .sck = AP83_050_GPIO_VSC7385_SCK, + .num_chipselect = 1, +}; + +static struct platform_device ap83_050_spi_device = { + .name = "spi_gpio", + .id = 0, + .dev = { + .platform_data = &ap83_050_spi_data, + } +}; + +static void ap83_vsc7385_reset(void) +{ + ath79_device_reset_set(AR71XX_RESET_GE1_PHY); + udelay(10); + ath79_device_reset_clear(AR71XX_RESET_GE1_PHY); + mdelay(50); +} + +static struct vsc7385_platform_data ap83_vsc7385_data = { + .reset = ap83_vsc7385_reset, + .ucode_name = "vsc7385_ucode_ap83.bin", + .mac_cfg = { + .tx_ipg = 6, + .bit2 = 0, + .clk_sel = 3, + }, +}; + +static struct spi_board_info ap83_spi_info[] = { + { + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 25000000, + .modalias = "spi-vsc7385", + .platform_data = &ap83_vsc7385_data, + .controller_data = (void *) AP83_050_GPIO_VSC7385_CS, + } +}; + +static void __init ap83_generic_setup(void) +{ + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_register_mdio(0, 0xfffffffe); + + ath79_init_mac(ath79_eth0_data.mac_addr, eeprom, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.phy_mask = 0x1; + + ath79_register_eth(0); + + ath79_init_mac(ath79_eth1_data.mac_addr, eeprom, 1); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth1_data.speed = SPEED_1000; + ath79_eth1_data.duplex = DUPLEX_FULL; + + ath79_eth1_pll_data.pll_1000 = 0x1f000000; + + ath79_register_eth(1); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(ap83_leds_gpio), + ap83_leds_gpio); + + ath79_register_gpio_keys_polled(-1, AP83_KEYS_POLL_INTERVAL, + ARRAY_SIZE(ap83_gpio_keys), + ap83_gpio_keys); + + ath79_register_usb(); + + ath79_register_wmac(eeprom, NULL); + + platform_device_register(&ap83_flash_device); + + spi_register_board_info(ap83_spi_info, ARRAY_SIZE(ap83_spi_info)); +} + +static void ap83_040_flash_lock(struct platform_device *pdev) +{ + ath79_flash_acquire(); +} + +static void ap83_040_flash_unlock(struct platform_device *pdev) +{ + ath79_flash_release(); +} + +static void __init ap83_040_setup(void) +{ + ap83_flash_data.lock = ap83_040_flash_lock; + ap83_flash_data.unlock = ap83_040_flash_unlock; + ap83_generic_setup(); + platform_device_register(&ap83_040_spi_device); +} + +static void __init ap83_050_setup(void) +{ + ap83_generic_setup(); + platform_device_register(&ap83_050_spi_device); +} + +static void __init ap83_setup(void) +{ + u8 *board_id = (u8 *) KSEG1ADDR(0x1fff1244); + unsigned int board_version; + + board_version = (unsigned int)(board_id[0] - '0'); + board_version += ((unsigned int)(board_id[1] - '0')) * 10; + + switch (board_version) { + case 40: + ap83_040_setup(); + break; + case 50: + ap83_050_setup(); + break; + default: + printk(KERN_WARNING "AP83-%03u board is not yet supported\n", + board_version); + } +} + +MIPS_MACHINE(ATH79_MACH_AP83, "AP83", "Atheros AP83", ap83_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ap96.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap96.c new file mode 100644 index 000000000..35120d3e2 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ap96.c @@ -0,0 +1,142 @@ +/* + * Atheros AP96 board support + * + * Copyright (C) 2009 Marco Porsch + * Copyright (C) 2009-2012 Gabor Juhos + * Copyright (C) 2010 Atheros Communications + * + * This program 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. + */ + +#include +#include + +#include + +#include "dev-ap9x-pci.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" + +#define AP96_GPIO_LED_12_GREEN 0 +#define AP96_GPIO_LED_3_GREEN 1 +#define AP96_GPIO_LED_2_GREEN 2 +#define AP96_GPIO_LED_WPS_GREEN 4 +#define AP96_GPIO_LED_5_GREEN 5 +#define AP96_GPIO_LED_4_ORANGE 6 + +/* Reset button - next to the power connector */ +#define AP96_GPIO_BTN_RESET 3 +/* WPS button - next to a led on right */ +#define AP96_GPIO_BTN_WPS 8 + +#define AP96_KEYS_POLL_INTERVAL 20 /* msecs */ +#define AP96_KEYS_DEBOUNCE_INTERVAL (3 * AP96_KEYS_POLL_INTERVAL) + +#define AP96_WMAC0_MAC_OFFSET 0x120c +#define AP96_WMAC1_MAC_OFFSET 0x520c +#define AP96_CALDATA0_OFFSET 0x1000 +#define AP96_CALDATA1_OFFSET 0x5000 + +/* + * AP96 has 12 unlabeled leds in the front; these are numbered from 1 to 12 + * below (from left to right on the board). Led 1 seems to be on whenever the + * board is powered. Led 11 shows LAN link activity actity. Led 3 is orange; + * others are green. + * + * In addition, there is one led next to a button on the right side for WPS. + */ +static struct gpio_led ap96_leds_gpio[] __initdata = { + { + .name = "ap96:green:led2", + .gpio = AP96_GPIO_LED_2_GREEN, + .active_low = 1, + }, { + .name = "ap96:green:led3", + .gpio = AP96_GPIO_LED_3_GREEN, + .active_low = 1, + }, { + .name = "ap96:orange:led4", + .gpio = AP96_GPIO_LED_4_ORANGE, + .active_low = 1, + }, { + .name = "ap96:green:led5", + .gpio = AP96_GPIO_LED_5_GREEN, + .active_low = 1, + }, { + .name = "ap96:green:led12", + .gpio = AP96_GPIO_LED_12_GREEN, + .active_low = 1, + }, { /* next to a button on right */ + .name = "ap96:green:wps", + .gpio = AP96_GPIO_LED_WPS_GREEN, + .active_low = 1, + } +}; + +static struct gpio_keys_button ap96_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = AP96_KEYS_DEBOUNCE_INTERVAL, + .gpio = AP96_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = AP96_KEYS_DEBOUNCE_INTERVAL, + .gpio = AP96_GPIO_BTN_WPS, + .active_low = 1, + } +}; + +#define AP96_WAN_PHYMASK 0x10 +#define AP96_LAN_PHYMASK 0x0f + +static void __init ap96_setup(void) +{ + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + + ath79_register_mdio(0, ~(AP96_WAN_PHYMASK | AP96_LAN_PHYMASK)); + + ath79_init_mac(ath79_eth0_data.mac_addr, art, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.phy_mask = AP96_LAN_PHYMASK; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + + ath79_register_eth(0); + + ath79_init_mac(ath79_eth1_data.mac_addr, art, 1); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth1_data.phy_mask = AP96_WAN_PHYMASK; + + ath79_eth1_pll_data.pll_1000 = 0x1f000000; + + ath79_register_eth(1); + + ath79_register_usb(); + + ath79_register_m25p80(NULL); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(ap96_leds_gpio), + ap96_leds_gpio); + + ath79_register_gpio_keys_polled(-1, AP96_KEYS_POLL_INTERVAL, + ARRAY_SIZE(ap96_gpio_keys), + ap96_gpio_keys); + + ap94_pci_init(art + AP96_CALDATA0_OFFSET, + art + AP96_WMAC0_MAC_OFFSET, + art + AP96_CALDATA1_OFFSET, + art + AP96_WMAC1_MAC_OFFSET); +} + +MIPS_MACHINE(ATH79_MACH_AP96, "AP96", "Atheros AP96", ap96_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-aw-nr580.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-aw-nr580.c new file mode 100644 index 000000000..281129b78 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-aw-nr580.c @@ -0,0 +1,107 @@ +/* + * AzureWave AW-NR580 board support + * + * Copyright (C) 2008-2012 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#include + +#include "dev-eth.h" +#include "dev-m25p80.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "machtypes.h" +#include "pci.h" + +#define AW_NR580_GPIO_LED_READY_RED 0 +#define AW_NR580_GPIO_LED_WLAN 1 +#define AW_NR580_GPIO_LED_READY_GREEN 2 +#define AW_NR580_GPIO_LED_WPS_GREEN 4 +#define AW_NR580_GPIO_LED_WPS_AMBER 5 + +#define AW_NR580_GPIO_BTN_WPS 3 +#define AW_NR580_GPIO_BTN_RESET 11 + +#define AW_NR580_KEYS_POLL_INTERVAL 20 /* msecs */ +#define AW_NR580_KEYS_DEBOUNCE_INTERVAL (3 * AW_NR580_KEYS_POLL_INTERVAL) + +static struct gpio_led aw_nr580_leds_gpio[] __initdata = { + { + .name = "aw-nr580:red:ready", + .gpio = AW_NR580_GPIO_LED_READY_RED, + .active_low = 0, + }, { + .name = "aw-nr580:green:ready", + .gpio = AW_NR580_GPIO_LED_READY_GREEN, + .active_low = 0, + }, { + .name = "aw-nr580:green:wps", + .gpio = AW_NR580_GPIO_LED_WPS_GREEN, + .active_low = 0, + }, { + .name = "aw-nr580:amber:wps", + .gpio = AW_NR580_GPIO_LED_WPS_AMBER, + .active_low = 0, + }, { + .name = "aw-nr580:green:wlan", + .gpio = AW_NR580_GPIO_LED_WLAN, + .active_low = 0, + } +}; + +static struct gpio_keys_button aw_nr580_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = AW_NR580_KEYS_DEBOUNCE_INTERVAL, + .gpio = AW_NR580_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = AW_NR580_KEYS_DEBOUNCE_INTERVAL, + .gpio = AW_NR580_GPIO_BTN_WPS, + .active_low = 1, + } +}; + +static const char *aw_nr580_part_probes[] = { + "RedBoot", + NULL, +}; + +static struct flash_platform_data aw_nr580_flash_data = { + .part_probes = aw_nr580_part_probes, +}; + +static void __init aw_nr580_setup(void) +{ + ath79_register_mdio(0, 0x0); + + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; + ath79_eth0_data.speed = SPEED_100; + ath79_eth0_data.duplex = DUPLEX_FULL; + + ath79_register_eth(0); + + ath79_register_pci(); + + ath79_register_m25p80(&aw_nr580_flash_data); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(aw_nr580_leds_gpio), + aw_nr580_leds_gpio); + + ath79_register_gpio_keys_polled(-1, AW_NR580_KEYS_POLL_INTERVAL, + ARRAY_SIZE(aw_nr580_gpio_keys), + aw_nr580_gpio_keys); +} + +MIPS_MACHINE(ATH79_MACH_AW_NR580, "AW-NR580", "AzureWave AW-NR580", + aw_nr580_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-600-a1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-600-a1.c new file mode 100644 index 000000000..c0fa9008c --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-600-a1.c @@ -0,0 +1,151 @@ +/* + * D-Link DIR-600 rev. A1 board support + * + * Copyright (C) 2010-2012 Gabor Juhos + * Copyright (C) 2012 Vadim Girlin + * + * This program 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. + */ + +#include +#include + +#include "common.h" +#include "dev-ap9x-pci.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "machtypes.h" +#include "nvram.h" + +#define DIR_600_A1_GPIO_LED_WPS 0 +#define DIR_600_A1_GPIO_LED_POWER_AMBER 1 +#define DIR_600_A1_GPIO_LED_POWER_GREEN 6 +#define DIR_600_A1_GPIO_LED_LAN1 13 +#define DIR_600_A1_GPIO_LED_LAN2 14 +#define DIR_600_A1_GPIO_LED_LAN3 15 +#define DIR_600_A1_GPIO_LED_LAN4 16 +#define DIR_600_A1_GPIO_LED_WAN_AMBER 7 +#define DIR_600_A1_GPIO_LED_WAN_GREEN 17 + +#define DIR_600_A1_GPIO_BTN_RESET 8 +#define DIR_600_A1_GPIO_BTN_WPS 12 + +#define DIR_600_A1_KEYS_POLL_INTERVAL 20 /* msecs */ +#define DIR_600_A1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_600_A1_KEYS_POLL_INTERVAL) + +#define DIR_600_A1_NVRAM_ADDR 0x1f030000 +#define DIR_600_A1_NVRAM_SIZE 0x10000 + +static struct gpio_led dir_600_a1_leds_gpio[] __initdata = { + { + .name = "d-link:green:power", + .gpio = DIR_600_A1_GPIO_LED_POWER_GREEN, + }, { + .name = "d-link:amber:power", + .gpio = DIR_600_A1_GPIO_LED_POWER_AMBER, + }, { + .name = "d-link:amber:wan", + .gpio = DIR_600_A1_GPIO_LED_WAN_AMBER, + }, { + .name = "d-link:green:wan", + .gpio = DIR_600_A1_GPIO_LED_WAN_GREEN, + .active_low = 1, + }, { + .name = "d-link:green:lan1", + .gpio = DIR_600_A1_GPIO_LED_LAN1, + .active_low = 1, + }, { + .name = "d-link:green:lan2", + .gpio = DIR_600_A1_GPIO_LED_LAN2, + .active_low = 1, + }, { + .name = "d-link:green:lan3", + .gpio = DIR_600_A1_GPIO_LED_LAN3, + .active_low = 1, + }, { + .name = "d-link:green:lan4", + .gpio = DIR_600_A1_GPIO_LED_LAN4, + .active_low = 1, + }, { + .name = "d-link:blue:wps", + .gpio = DIR_600_A1_GPIO_LED_WPS, + .active_low = 1, + } +}; + +static struct gpio_keys_button dir_600_a1_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = DIR_600_A1_KEYS_DEBOUNCE_INTERVAL, + .gpio = DIR_600_A1_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = DIR_600_A1_KEYS_DEBOUNCE_INTERVAL, + .gpio = DIR_600_A1_GPIO_BTN_WPS, + .active_low = 1, + } +}; + +static void __init dir_600_a1_setup(void) +{ + const char *nvram = (char *) KSEG1ADDR(DIR_600_A1_NVRAM_ADDR); + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + u8 mac_buff[6]; + u8 *mac = NULL; + + if (ath79_nvram_parse_mac_addr(nvram, DIR_600_A1_NVRAM_SIZE, + "lan_mac=", mac_buff) == 0) { + ath79_init_mac(ath79_eth0_data.mac_addr, mac_buff, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, mac_buff, 1); + mac = mac_buff; + } + + ath79_register_m25p80(NULL); + + ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(dir_600_a1_leds_gpio), + dir_600_a1_leds_gpio); + + ath79_register_gpio_keys_polled(-1, DIR_600_A1_KEYS_POLL_INTERVAL, + ARRAY_SIZE(dir_600_a1_gpio_keys), + dir_600_a1_gpio_keys); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); + + ath79_register_mdio(0, 0x0); + + /* LAN ports */ + ath79_register_eth(1); + + /* WAN port */ + ath79_register_eth(0); + + ap91_pci_init(ee, mac); +} + +MIPS_MACHINE(ATH79_MACH_DIR_600_A1, "DIR-600-A1", "D-Link DIR-600 rev. A1", + dir_600_a1_setup); + +static void __init dir_615_e4_setup(void) +{ + dir_600_a1_setup(); + ap9x_pci_setup_wmac_led_pin(0, 1); +} + +MIPS_MACHINE(ATH79_MACH_DIR_615_E4, "DIR-615-E4", "D-Link DIR-615 rev. E4", + dir_615_e4_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-c1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-c1.c new file mode 100644 index 000000000..425be301e --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-c1.c @@ -0,0 +1,133 @@ +/* + * D-Link DIR-615 rev C1 board support + * + * Copyright (C) 2008-2012 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-wmac.h" +#include "machtypes.h" +#include "nvram.h" + +#define DIR_615C1_GPIO_LED_ORANGE_STATUS 1 /* ORANGE:STATUS:TRICOLOR */ +#define DIR_615C1_GPIO_LED_BLUE_WPS 3 /* BLUE:WPS */ +#define DIR_615C1_GPIO_LED_GREEN_WAN 4 /* GREEN:WAN:TRICOLOR */ +#define DIR_615C1_GPIO_LED_GREEN_WANCPU 5 /* GREEN:WAN:CPU:TRICOLOR */ +#define DIR_615C1_GPIO_LED_GREEN_WLAN 6 /* GREEN:WLAN */ +#define DIR_615C1_GPIO_LED_GREEN_STATUS 14 /* GREEN:STATUS:TRICOLOR */ +#define DIR_615C1_GPIO_LED_ORANGE_WAN 15 /* ORANGE:WAN:TRICOLOR */ + +/* buttons may need refinement */ + +#define DIR_615C1_GPIO_BTN_WPS 12 +#define DIR_615C1_GPIO_BTN_RESET 21 + +#define DIR_615C1_KEYS_POLL_INTERVAL 20 /* msecs */ +#define DIR_615C1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_615C1_KEYS_POLL_INTERVAL) + +#define DIR_615C1_CONFIG_ADDR 0x1f020000 +#define DIR_615C1_CONFIG_SIZE 0x10000 + +static struct gpio_led dir_615c1_leds_gpio[] __initdata = { + { + .name = "d-link:orange:status", + .gpio = DIR_615C1_GPIO_LED_ORANGE_STATUS, + .active_low = 1, + }, { + .name = "d-link:blue:wps", + .gpio = DIR_615C1_GPIO_LED_BLUE_WPS, + .active_low = 1, + }, { + .name = "d-link:green:wan", + .gpio = DIR_615C1_GPIO_LED_GREEN_WAN, + .active_low = 1, + }, { + .name = "d-link:green:wancpu", + .gpio = DIR_615C1_GPIO_LED_GREEN_WANCPU, + .active_low = 1, + }, { + .name = "d-link:green:wlan", + .gpio = DIR_615C1_GPIO_LED_GREEN_WLAN, + .active_low = 1, + }, { + .name = "d-link:green:status", + .gpio = DIR_615C1_GPIO_LED_GREEN_STATUS, + .active_low = 1, + }, { + .name = "d-link:orange:wan", + .gpio = DIR_615C1_GPIO_LED_ORANGE_WAN, + .active_low = 1, + } + +}; + +static struct gpio_keys_button dir_615c1_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = DIR_615C1_KEYS_DEBOUNCE_INTERVAL, + .gpio = DIR_615C1_GPIO_BTN_RESET, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = DIR_615C1_KEYS_DEBOUNCE_INTERVAL, + .gpio = DIR_615C1_GPIO_BTN_WPS, + } +}; + +#define DIR_615C1_LAN_PHYMASK BIT(0) +#define DIR_615C1_WAN_PHYMASK BIT(4) +#define DIR_615C1_MDIO_MASK (~(DIR_615C1_LAN_PHYMASK | \ + DIR_615C1_WAN_PHYMASK)) + +static void __init dir_615c1_setup(void) +{ + const char *config = (char *) KSEG1ADDR(DIR_615C1_CONFIG_ADDR); + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + u8 mac[6]; + u8 *wlan_mac = NULL; + + if (ath79_nvram_parse_mac_addr(config, DIR_615C1_CONFIG_SIZE, + "lan_mac=", mac) == 0) { + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); + wlan_mac = mac; + } + + ath79_register_mdio(0, DIR_615C1_MDIO_MASK); + + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth0_data.phy_mask = DIR_615C1_LAN_PHYMASK; + + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth1_data.phy_mask = DIR_615C1_WAN_PHYMASK; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_m25p80(NULL); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(dir_615c1_leds_gpio), + dir_615c1_leds_gpio); + + ath79_register_gpio_keys_polled(-1, DIR_615C1_KEYS_POLL_INTERVAL, + ARRAY_SIZE(dir_615c1_gpio_keys), + dir_615c1_gpio_keys); + + ath79_register_wmac(eeprom, wlan_mac); +} + +MIPS_MACHINE(ATH79_MACH_DIR_615_C1, "DIR-615-C1", "D-Link DIR-615 rev. C1", + dir_615c1_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-825-b1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-825-b1.c new file mode 100644 index 000000000..476cbd98e --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-825-b1.c @@ -0,0 +1,200 @@ +/* + * D-Link DIR-825 rev. B1 board support + * + * Copyright (C) 2009-2011 Lukas Kuna, Evkanet, s.r.o. + * + * based on mach-wndr3700.c + * + * This program 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. + */ + +#include +#include +#include + +#include + +#include "dev-eth.h" +#include "dev-ap9x-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" + +#define DIR825B1_GPIO_LED_BLUE_USB 0 +#define DIR825B1_GPIO_LED_ORANGE_POWER 1 +#define DIR825B1_GPIO_LED_BLUE_POWER 2 +#define DIR825B1_GPIO_LED_BLUE_WPS 4 +#define DIR825B1_GPIO_LED_ORANGE_PLANET 6 +#define DIR825B1_GPIO_LED_BLUE_PLANET 11 + +#define DIR825B1_GPIO_BTN_RESET 3 +#define DIR825B1_GPIO_BTN_WPS 8 + +#define DIR825B1_GPIO_RTL8366_SDA 5 +#define DIR825B1_GPIO_RTL8366_SCK 7 + +#define DIR825B1_KEYS_POLL_INTERVAL 20 /* msecs */ +#define DIR825B1_KEYS_DEBOUNCE_INTERVAL (3 * DIR825B1_KEYS_POLL_INTERVAL) + +#define DIR825B1_CAL0_OFFSET 0x1000 +#define DIR825B1_CAL1_OFFSET 0x5000 +#define DIR825B1_MAC0_OFFSET 0xffa0 +#define DIR825B1_MAC1_OFFSET 0xffb4 + +#define DIR825B1_CAL_LOCATION_0 0x1f660000 +#define DIR825B1_CAL_LOCATION_1 0x1f7f0000 + +static struct gpio_led dir825b1_leds_gpio[] __initdata = { + { + .name = "d-link:blue:usb", + .gpio = DIR825B1_GPIO_LED_BLUE_USB, + .active_low = 1, + }, { + .name = "d-link:orange:power", + .gpio = DIR825B1_GPIO_LED_ORANGE_POWER, + .active_low = 1, + }, { + .name = "d-link:blue:power", + .gpio = DIR825B1_GPIO_LED_BLUE_POWER, + .active_low = 1, + }, { + .name = "d-link:blue:wps", + .gpio = DIR825B1_GPIO_LED_BLUE_WPS, + .active_low = 1, + }, { + .name = "d-link:orange:planet", + .gpio = DIR825B1_GPIO_LED_ORANGE_PLANET, + .active_low = 1, + }, { + .name = "d-link:blue:planet", + .gpio = DIR825B1_GPIO_LED_BLUE_PLANET, + .active_low = 1, + } +}; + +static struct gpio_keys_button dir825b1_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = DIR825B1_KEYS_DEBOUNCE_INTERVAL, + .gpio = DIR825B1_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = DIR825B1_KEYS_DEBOUNCE_INTERVAL, + .gpio = DIR825B1_GPIO_BTN_WPS, + .active_low = 1, + } +}; + +static struct rtl8366_initval dir825b1_rtl8366s_initvals[] = { + { .reg = 0x06, .val = 0x0108 }, +}; + +static struct rtl8366_platform_data dir825b1_rtl8366s_data = { + .gpio_sda = DIR825B1_GPIO_RTL8366_SDA, + .gpio_sck = DIR825B1_GPIO_RTL8366_SCK, + .num_initvals = ARRAY_SIZE(dir825b1_rtl8366s_initvals), + .initvals = dir825b1_rtl8366s_initvals, +}; + +static struct platform_device dir825b1_rtl8366s_device = { + .name = RTL8366S_DRIVER_NAME, + .id = -1, + .dev = { + .platform_data = &dir825b1_rtl8366s_data, + } +}; + +static void dir825b1_read_ascii_mac(u8 *dest, u8 *src) +{ + int ret; + + ret = sscanf(src, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", + &dest[0], &dest[1], &dest[2], + &dest[3], &dest[4], &dest[5]); + + if (ret != ETH_ALEN) + memset(dest, 0, ETH_ALEN); +} + +static bool __init dir825b1_is_caldata_valid(u8 *p) +{ + u16 *magic0, *magic1; + + magic0 = (u16 *)(p + DIR825B1_CAL0_OFFSET); + magic1 = (u16 *)(p + DIR825B1_CAL1_OFFSET); + + return (*magic0 == 0xa55a && *magic1 == 0xa55a); +} + +static void __init dir825b1_wlan_init(void) +{ + u8 *caldata; + u8 mac1[ETH_ALEN], mac2[ETH_ALEN]; + + caldata = (u8 *) KSEG1ADDR(DIR825B1_CAL_LOCATION_0); + if (!dir825b1_is_caldata_valid(caldata)) { + caldata = (u8 *)KSEG1ADDR(DIR825B1_CAL_LOCATION_1); + if (!dir825b1_is_caldata_valid(caldata)) { + pr_err("no calibration data found\n"); + return; + } + } + + dir825b1_read_ascii_mac(mac1, caldata + DIR825B1_MAC0_OFFSET); + dir825b1_read_ascii_mac(mac2, caldata + DIR825B1_MAC1_OFFSET); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 2); + ath79_init_mac(ath79_eth1_data.mac_addr, mac1, 3); + + ap9x_pci_setup_wmac_led_pin(0, 5); + ap9x_pci_setup_wmac_led_pin(1, 5); + + ap94_pci_init(caldata + DIR825B1_CAL0_OFFSET, mac1, + caldata + DIR825B1_CAL1_OFFSET, mac2); +} + +static void __init dir825b1_setup(void) +{ + dir825b1_wlan_init(); + + ath79_register_mdio(0, 0x0); + + ath79_eth0_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev; + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_eth0_pll_data.pll_1000 = 0x11110000; + + ath79_eth1_data.mii_bus_dev = &dir825b1_rtl8366s_device.dev; + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth1_data.phy_mask = 0x10; + ath79_eth1_pll_data.pll_1000 = 0x11110000; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_m25p80(NULL); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(dir825b1_leds_gpio), + dir825b1_leds_gpio); + + ath79_register_gpio_keys_polled(-1, DIR825B1_KEYS_POLL_INTERVAL, + ARRAY_SIZE(dir825b1_gpio_keys), + dir825b1_gpio_keys); + + ath79_register_usb(); + + platform_device_register(&dir825b1_rtl8366s_device); +} + +MIPS_MACHINE(ATH79_MACH_DIR_825_B1, "DIR-825-B1", "D-Link DIR-825 rev. B1", + dir825b1_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-eap7660d.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-eap7660d.c new file mode 100644 index 000000000..787e6275d --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-eap7660d.c @@ -0,0 +1,181 @@ +/* + * Senao EAP7660D board support + * + * Copyright (C) 2010 Daniel Golle + * Copyright (C) 2008 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#include +#include +#include + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "machtypes.h" +#include "pci.h" + +#define EAP7660D_KEYS_POLL_INTERVAL 20 /* msecs */ +#define EAP7660D_KEYS_DEBOUNCE_INTERVAL (3 * EAP7660D_KEYS_POLL_INTERVAL) + +#define EAP7660D_GPIO_DS4 7 +#define EAP7660D_GPIO_DS5 2 +#define EAP7660D_GPIO_DS7 0 +#define EAP7660D_GPIO_DS8 4 +#define EAP7660D_GPIO_SW1 3 +#define EAP7660D_GPIO_SW3 8 +#define EAP7660D_PHYMASK BIT(20) +#define EAP7660D_BOARDCONFIG 0x1F7F0000 +#define EAP7660D_GBIC_MAC_OFFSET 0x1000 +#define EAP7660D_WMAC0_MAC_OFFSET 0x1010 +#define EAP7660D_WMAC1_MAC_OFFSET 0x1016 +#define EAP7660D_WMAC0_CALDATA_OFFSET 0x2000 +#define EAP7660D_WMAC1_CALDATA_OFFSET 0x3000 + +#ifdef CONFIG_PCI +static struct ath5k_platform_data eap7660d_wmac0_data; +static struct ath5k_platform_data eap7660d_wmac1_data; +static char eap7660d_wmac0_mac[6]; +static char eap7660d_wmac1_mac[6]; +static u16 eap7660d_wmac0_eeprom[ATH5K_PLAT_EEP_MAX_WORDS]; +static u16 eap7660d_wmac1_eeprom[ATH5K_PLAT_EEP_MAX_WORDS]; + +static int eap7660d_pci_plat_dev_init(struct pci_dev *dev) +{ + switch (PCI_SLOT(dev->devfn)) { + case 17: + dev->dev.platform_data = &eap7660d_wmac0_data; + break; + + case 18: + dev->dev.platform_data = &eap7660d_wmac1_data; + break; + } + + return 0; +} + +void __init eap7660d_pci_init(u8 *cal_data0, u8 *mac_addr0, + u8 *cal_data1, u8 *mac_addr1) +{ + if (cal_data0 && *cal_data0 == 0xa55a) { + memcpy(eap7660d_wmac0_eeprom, cal_data0, + ATH5K_PLAT_EEP_MAX_WORDS); + eap7660d_wmac0_data.eeprom_data = eap7660d_wmac0_eeprom; + } + + if (cal_data1 && *cal_data1 == 0xa55a) { + memcpy(eap7660d_wmac1_eeprom, cal_data1, + ATH5K_PLAT_EEP_MAX_WORDS); + eap7660d_wmac1_data.eeprom_data = eap7660d_wmac1_eeprom; + } + + if (mac_addr0) { + memcpy(eap7660d_wmac0_mac, mac_addr0, + sizeof(eap7660d_wmac0_mac)); + eap7660d_wmac0_data.macaddr = eap7660d_wmac0_mac; + } + + if (mac_addr1) { + memcpy(eap7660d_wmac1_mac, mac_addr1, + sizeof(eap7660d_wmac1_mac)); + eap7660d_wmac1_data.macaddr = eap7660d_wmac1_mac; + } + + ath79_pci_set_plat_dev_init(eap7660d_pci_plat_dev_init); + ath79_register_pci(); +} +#else +static inline void eap7660d_pci_init(u8 *cal_data0, u8 *mac_addr0, + u8 *cal_data1, u8 *mac_addr1) +{ +} +#endif /* CONFIG_PCI */ + +static struct gpio_led eap7660d_leds_gpio[] __initdata = { + { + .name = "eap7660d:green:ds8", + .gpio = EAP7660D_GPIO_DS8, + .active_low = 0, + }, + { + .name = "eap7660d:green:ds5", + .gpio = EAP7660D_GPIO_DS5, + .active_low = 0, + }, + { + .name = "eap7660d:green:ds7", + .gpio = EAP7660D_GPIO_DS7, + .active_low = 0, + }, + { + .name = "eap7660d:green:ds4", + .gpio = EAP7660D_GPIO_DS4, + .active_low = 0, + } +}; + +static struct gpio_keys_button eap7660d_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = EAP7660D_KEYS_DEBOUNCE_INTERVAL, + .gpio = EAP7660D_GPIO_SW1, + .active_low = 1, + }, + { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = EAP7660D_KEYS_DEBOUNCE_INTERVAL, + .gpio = EAP7660D_GPIO_SW3, + .active_low = 1, + } +}; + +static const char *eap7660d_part_probes[] = { + "RedBoot", + NULL, +}; + +static struct flash_platform_data eap7660d_flash_data = { + .part_probes = eap7660d_part_probes, +}; + +static void __init eap7660d_setup(void) +{ + u8 *boardconfig = (u8 *) KSEG1ADDR(EAP7660D_BOARDCONFIG); + + ath79_register_mdio(0, ~EAP7660D_PHYMASK); + + ath79_init_mac(ath79_eth0_data.mac_addr, + boardconfig + EAP7660D_GBIC_MAC_OFFSET, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.phy_mask = EAP7660D_PHYMASK; + ath79_register_eth(0); + ath79_register_m25p80(&eap7660d_flash_data); + ath79_register_leds_gpio(-1, ARRAY_SIZE(eap7660d_leds_gpio), + eap7660d_leds_gpio); + ath79_register_gpio_keys_polled(-1, EAP7660D_KEYS_POLL_INTERVAL, + ARRAY_SIZE(eap7660d_gpio_keys), + eap7660d_gpio_keys); + eap7660d_pci_init(boardconfig + EAP7660D_WMAC0_CALDATA_OFFSET, + boardconfig + EAP7660D_WMAC0_MAC_OFFSET, + boardconfig + EAP7660D_WMAC1_CALDATA_OFFSET, + boardconfig + EAP7660D_WMAC1_MAC_OFFSET); +}; + +MIPS_MACHINE(ATH79_MACH_EAP7660D, "EAP7660D", "Senao EAP7660D", + eap7660d_setup); + +MIPS_MACHINE(ATH79_MACH_ALL0305, "ALL0305", "Allnet ALL0305", + eap7660d_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ew-dorin.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ew-dorin.c new file mode 100644 index 000000000..47ed51b5d --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ew-dorin.c @@ -0,0 +1,144 @@ +/* + * EW Dorin board support + * (based on Atheros Ref. Design AP121) + * Copyright (C) 2011-2012 Gabor Juhos + * Copyright (C) 2012 Embedded Wireless GmbH www.80211.de + * + * This program 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. + */ + +#include +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-spi.h" +#include "dev-usb.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define DORIN_KEYS_POLL_INTERVAL 20 /* msecs */ +#define DORIN_KEYS_DEBOUNCE_INTERVAL (3 * DORIN_KEYS_POLL_INTERVAL) + +#define DORIN_CALDATA_OFFSET 0x1000 +#define DORIN_WMAC_MAC_OFFSET 0x1002 + +#define DORIN_GPIO_LED_21 21 +#define DORIN_GPIO_LED_22 22 + +#define DORIN_GPIO_BTN_JUMPSTART 11 +#define DORIN_GPIO_BTN_RESET 6 + +static struct gpio_led dorin_leds_gpio[] __initdata = { + { + .name = "dorin:green:led21", + .gpio = DORIN_GPIO_LED_21, + .active_low = 1, + }, + { + .name = "dorin:green:led22", + .gpio = DORIN_GPIO_LED_22, + .active_low = 1, + }, +}; + +static struct gpio_keys_button dorin_gpio_keys[] __initdata = { + { + .desc = "jumpstart button", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = DORIN_KEYS_DEBOUNCE_INTERVAL, + .gpio = DORIN_GPIO_BTN_JUMPSTART, + .active_low = 1, + }, + { + .desc = "reset button", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = DORIN_KEYS_DEBOUNCE_INTERVAL, + .gpio = DORIN_GPIO_BTN_RESET, + .active_low = 0, + } +}; + +static void __init ew_dorin_setup(void) +{ + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + static u8 mac[6]; + + ath79_register_m25p80(NULL); + + ath79_register_usb(); + + if (ar93xx_wmac_read_mac_address(mac)) { + ath79_register_wmac(NULL, NULL); + } else { + ath79_register_wmac(art + DORIN_CALDATA_OFFSET, + art + DORIN_WMAC_MAC_OFFSET); + memcpy(mac, art + DORIN_WMAC_MAC_OFFSET, sizeof(mac)); + } + + mac[3] |= 0x40; + ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); + + ath79_register_mdio(0, 0x0); + + /* LAN ports */ + ath79_register_eth(1); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(dorin_leds_gpio), + dorin_leds_gpio); + ath79_register_gpio_keys_polled(-1, DORIN_KEYS_POLL_INTERVAL, + ARRAY_SIZE(dorin_gpio_keys), + dorin_gpio_keys); +} + +MIPS_MACHINE(ATH79_MACH_EW_DORIN, "EW-DORIN", "EmbWir-Dorin", + ew_dorin_setup); + + +static void __init ew_dorin_router_setup(void) +{ + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + static u8 mac[6]; + + ath79_register_m25p80(NULL); + + ath79_register_usb(); + + if (ar93xx_wmac_read_mac_address(mac)) { + ath79_register_wmac(NULL, NULL); + } else { + ath79_register_wmac(art + DORIN_CALDATA_OFFSET, + art + DORIN_WMAC_MAC_OFFSET); + memcpy(mac, art + DORIN_WMAC_MAC_OFFSET, sizeof(mac)); + } + + mac[3] |= 0x40; + ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); + + mac[3] &= 0x3F; + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_setup_ar933x_phy4_switch(true, true); + + ath79_register_mdio(0, 0x0); + + /* LAN ports */ + ath79_register_eth(1); + + /* WAN port */ + ath79_register_eth(0); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(dorin_leds_gpio), + dorin_leds_gpio); + ath79_register_gpio_keys_polled(-1, DORIN_KEYS_POLL_INTERVAL, + ARRAY_SIZE(dorin_gpio_keys), + dorin_gpio_keys); +} + +MIPS_MACHINE(ATH79_MACH_EW_DORIN_ROUTER, "EW-DORIN-ROUTER", + "EmbWir-Dorin-Router", ew_dorin_router_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-hornet-ub.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-hornet-ub.c new file mode 100644 index 000000000..f8870e711 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-hornet-ub.c @@ -0,0 +1,136 @@ +/* + * ALFA NETWORKS Hornet-UB board support + * + * Copyright (C) 2011-2012 Gabor Juhos + * + * This program 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. + */ + +#include + +#include +#include + +#include "common.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define HORNET_UB_GPIO_LED_WLAN 0 +#define HORNET_UB_GPIO_LED_USB 1 +#define HORNET_UB_GPIO_LED_LAN 13 +#define HORNET_UB_GPIO_LED_WAN 17 +#define HORNET_UB_GPIO_LED_WPS 27 + +#define HORNET_UB_GPIO_BTN_RESET 11 +#define HORNET_UB_GPIO_BTN_WPS 12 + +#define HORNET_UB_GPIO_USB_POWER 26 + +#define HORNET_UB_KEYS_POLL_INTERVAL 20 /* msecs */ +#define HORNET_UB_KEYS_DEBOUNCE_INTERVAL (3 * HORNET_UB_KEYS_POLL_INTERVAL) + +#define HORNET_UB_MAC0_OFFSET 0x0000 +#define HORNET_UB_MAC1_OFFSET 0x0006 +#define HORNET_UB_CALDATA_OFFSET 0x1000 + +static struct gpio_led hornet_ub_leds_gpio[] __initdata = { + { + .name = "alfa:blue:lan", + .gpio = HORNET_UB_GPIO_LED_LAN, + .active_low = 0, + }, + { + .name = "alfa:blue:usb", + .gpio = HORNET_UB_GPIO_LED_USB, + .active_low = 0, + }, + { + .name = "alfa:blue:wan", + .gpio = HORNET_UB_GPIO_LED_WAN, + .active_low = 1, + }, + { + .name = "alfa:blue:wlan", + .gpio = HORNET_UB_GPIO_LED_WLAN, + .active_low = 0, + }, + { + .name = "alfa:blue:wps", + .gpio = HORNET_UB_GPIO_LED_WPS, + .active_low = 1, + }, +}; + +static struct gpio_keys_button hornet_ub_gpio_keys[] __initdata = { + { + .desc = "WPS button", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = HORNET_UB_KEYS_DEBOUNCE_INTERVAL, + .gpio = HORNET_UB_GPIO_BTN_WPS, + .active_low = 1, + }, + { + .desc = "Reset button", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = HORNET_UB_KEYS_DEBOUNCE_INTERVAL, + .gpio = HORNET_UB_GPIO_BTN_RESET, + .active_low = 0, + } +}; + +static void __init hornet_ub_gpio_setup(void) +{ + u32 t; + + ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + + t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); + t |= AR933X_BOOTSTRAP_MDIO_GPIO_EN; + ath79_reset_wr(AR933X_RESET_REG_BOOTSTRAP, t); + + ath79_set_usb_power_gpio(HORNET_UB_GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH, + "USB power"); +} + +static void __init hornet_ub_setup(void) +{ + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + + hornet_ub_gpio_setup(); + + ath79_register_m25p80(NULL); + ath79_register_leds_gpio(-1, ARRAY_SIZE(hornet_ub_leds_gpio), + hornet_ub_leds_gpio); + ath79_register_gpio_keys_polled(-1, HORNET_UB_KEYS_POLL_INTERVAL, + ARRAY_SIZE(hornet_ub_gpio_keys), + hornet_ub_gpio_keys); + + ath79_init_mac(ath79_eth1_data.mac_addr, + art + HORNET_UB_MAC0_OFFSET, 0); + ath79_init_mac(ath79_eth0_data.mac_addr, + art + HORNET_UB_MAC1_OFFSET, 0); + + ath79_register_mdio(0, 0x0); + + ath79_register_eth(1); + ath79_register_eth(0); + + ath79_register_wmac(art + HORNET_UB_CALDATA_OFFSET, NULL); + ath79_register_usb(); +} + +MIPS_MACHINE(ATH79_MACH_HORNET_UB, "HORNET-UB", "ALFA NETWORKS Hornet-UB", + hornet_ub_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ja76pf.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ja76pf.c new file mode 100644 index 000000000..d1fe0f8a2 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ja76pf.c @@ -0,0 +1,190 @@ +/* + * jjPlus JA76PF board support + */ + +#include +#include +#include + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" +#include "pci.h" + +#define JA76PF_KEYS_POLL_INTERVAL 20 /* msecs */ +#define JA76PF_KEYS_DEBOUNCE_INTERVAL (3 * JA76PF_KEYS_POLL_INTERVAL) + +#define JA76PF_GPIO_I2C_SCL 0 +#define JA76PF_GPIO_I2C_SDA 1 +#define JA76PF_GPIO_LED_1 5 +#define JA76PF_GPIO_LED_2 4 +#define JA76PF_GPIO_LED_3 3 +#define JA76PF_GPIO_BTN_RESET 11 + +static struct gpio_led ja76pf_leds_gpio[] __initdata = { + { + .name = "jjplus:green:led1", + .gpio = JA76PF_GPIO_LED_1, + .active_low = 1, + }, { + .name = "jjplus:green:led2", + .gpio = JA76PF_GPIO_LED_2, + .active_low = 1, + }, { + .name = "jjplus:green:led3", + .gpio = JA76PF_GPIO_LED_3, + .active_low = 1, + } +}; + +static struct gpio_keys_button ja76pf_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = JA76PF_KEYS_DEBOUNCE_INTERVAL, + .gpio = JA76PF_GPIO_BTN_RESET, + .active_low = 1, + } +}; + +static struct i2c_gpio_platform_data ja76pf_i2c_gpio_data = { + .sda_pin = JA76PF_GPIO_I2C_SDA, + .scl_pin = JA76PF_GPIO_I2C_SCL, +}; + +static struct platform_device ja76pf_i2c_gpio_device = { + .name = "i2c-gpio", + .id = 0, + .dev = { + .platform_data = &ja76pf_i2c_gpio_data, + } +}; + +static const char *ja76pf_part_probes[] = { + "RedBoot", + NULL, +}; + +static struct flash_platform_data ja76pf_flash_data = { + .part_probes = ja76pf_part_probes, +}; + +#define JA76PF_WAN_PHYMASK (1 << 4) +#define JA76PF_LAN_PHYMASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 < 3)) +#define JA76PF_MDIO_PHYMASK (JA76PF_LAN_PHYMASK | JA76PF_WAN_PHYMASK) + +static void __init ja76pf_init(void) +{ + ath79_register_m25p80(&ja76pf_flash_data); + + ath79_register_mdio(0, ~JA76PF_MDIO_PHYMASK); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.phy_mask = JA76PF_LAN_PHYMASK; + + ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth1_data.phy_mask = JA76PF_WAN_PHYMASK; + ath79_eth1_data.speed = SPEED_1000; + ath79_eth1_data.duplex = DUPLEX_FULL; + + ath79_register_eth(0); + ath79_register_eth(1); + + platform_device_register(&ja76pf_i2c_gpio_device); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(ja76pf_leds_gpio), + ja76pf_leds_gpio); + + ath79_register_gpio_keys_polled(-1, JA76PF_KEYS_POLL_INTERVAL, + ARRAY_SIZE(ja76pf_gpio_keys), + ja76pf_gpio_keys); + + ath79_register_usb(); + ath79_register_pci(); +} + +MIPS_MACHINE(ATH79_MACH_JA76PF, "JA76PF", "jjPlus JA76PF", ja76pf_init); + +#define JA76PF2_GPIO_LED_D2 5 +#define JA76PF2_GPIO_LED_D3 4 +#define JA76PF2_GPIO_LED_D4 3 +#define JA76PF2_GPIO_BTN_RESET 7 +#define JA76PF2_GPIO_BTN_WPS 8 + +static struct gpio_led ja76pf2_leds_gpio[] __initdata = { + { + .name = "jjplus:green:led1", + .gpio = JA76PF2_GPIO_LED_D2, + .active_low = 1, + }, { + .name = "jjplus:green:led2", + .gpio = JA76PF2_GPIO_LED_D3, + .active_low = 0, + }, { + .name = "jjplus:green:led3", + .gpio = JA76PF2_GPIO_LED_D4, + .active_low = 0, + } +}; + +static struct gpio_keys_button ja76pf2_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = JA76PF_KEYS_DEBOUNCE_INTERVAL, + .gpio = JA76PF2_GPIO_BTN_RESET, + .active_low = 1, + }, + { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = JA76PF_KEYS_DEBOUNCE_INTERVAL, + .gpio = JA76PF2_GPIO_BTN_WPS, + .active_low = 1, + }, +}; + +#define JA76PF2_LAN_PHYMASK BIT(0) +#define JA76PF2_WAN_PHYMASK BIT(4) +#define JA76PF2_MDIO_PHYMASK (JA76PF2_LAN_PHYMASK | JA76PF2_WAN_PHYMASK) + +static void __init ja76pf2_init(void) +{ + ath79_register_m25p80(&ja76pf_flash_data); + + ath79_register_mdio(0, ~JA76PF2_MDIO_PHYMASK); + + /* MAC0 is connected to the CPU port of the AR8316 switch */ + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.phy_mask = BIT(0); + + /* MAC1 is connected to the PHY4 of the AR8316 switch */ + ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth1_data.phy_mask = BIT(4); + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(ja76pf2_leds_gpio), + ja76pf2_leds_gpio); + + ath79_register_gpio_keys_polled(-1, JA76PF_KEYS_POLL_INTERVAL, + ARRAY_SIZE(ja76pf2_gpio_keys), + ja76pf2_gpio_keys); + + ath79_register_pci(); +} + +MIPS_MACHINE(ATH79_MACH_JA76PF2, "JA76PF2", "jjPlus JA76PF2", ja76pf2_init); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-jwap003.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-jwap003.c new file mode 100644 index 000000000..a3c93ccd9 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-jwap003.c @@ -0,0 +1,95 @@ +/* + * jjPlus JWAP003 board support + * + */ + +#include +#include +#include + +#include + +#include "dev-eth.h" +#include "dev-m25p80.h" +#include "dev-gpio-buttons.h" +#include "dev-usb.h" +#include "machtypes.h" +#include "pci.h" + +#define JWAP003_KEYS_POLL_INTERVAL 20 /* msecs */ +#define JWAP003_KEYS_DEBOUNCE_INTERVAL (3 * JWAP003_KEYS_POLL_INTERVAL) + +#define JWAP003_GPIO_WPS 11 +#define JWAP003_GPIO_I2C_SCL 0 +#define JWAP003_GPIO_I2C_SDA 1 + +static struct gpio_keys_button jwap003_gpio_keys[] __initdata = { + { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = JWAP003_KEYS_DEBOUNCE_INTERVAL, + .gpio = JWAP003_GPIO_WPS, + .active_low = 1, + } +}; + +static struct i2c_gpio_platform_data jwap003_i2c_gpio_data = { + .sda_pin = JWAP003_GPIO_I2C_SDA, + .scl_pin = JWAP003_GPIO_I2C_SCL, +}; + +static struct platform_device jwap003_i2c_gpio_device = { + .name = "i2c-gpio", + .id = 0, + .dev = { + .platform_data = &jwap003_i2c_gpio_data, + } +}; + +static const char *jwap003_part_probes[] = { + "RedBoot", + NULL, +}; + +static struct flash_platform_data jwap003_flash_data = { + .part_probes = jwap003_part_probes, +}; + +#define JWAP003_WAN_PHYMASK BIT(0) +#define JWAP003_LAN_PHYMASK BIT(4) + +static void __init jwap003_init(void) +{ + ath79_register_m25p80(&jwap003_flash_data); + + ath79_register_mdio(0, 0x0); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth0_data.phy_mask = JWAP003_WAN_PHYMASK; + ath79_eth0_data.speed = SPEED_100; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_eth0_data.has_ar8216 = 1; + + ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth1_data.phy_mask = JWAP003_LAN_PHYMASK; + ath79_eth1_data.speed = SPEED_100; + ath79_eth1_data.duplex = DUPLEX_FULL; + + ath79_register_eth(0); + ath79_register_eth(1); + + platform_device_register(&jwap003_i2c_gpio_device); + + ath79_register_usb(); + + ath79_register_gpio_keys_polled(-1, JWAP003_KEYS_POLL_INTERVAL, + ARRAY_SIZE(jwap003_gpio_keys), + jwap003_gpio_keys); + + ath79_register_pci(); +} + +MIPS_MACHINE(ATH79_MACH_JWAP003, "JWAP003", "jjPlus JWAP003", jwap003_init); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w04nu.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w04nu.c new file mode 100644 index 000000000..c2460ce33 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w04nu.c @@ -0,0 +1,124 @@ +/* + * Planex MZK-W04NU board support + * + * Copyright (C) 2009-2012 Gabor Juhos + * + * This program 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. + */ + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define MZK_W04NU_GPIO_LED_USB 0 +#define MZK_W04NU_GPIO_LED_STATUS 1 +#define MZK_W04NU_GPIO_LED_WPS 3 +#define MZK_W04NU_GPIO_LED_WLAN 6 +#define MZK_W04NU_GPIO_LED_AP 15 +#define MZK_W04NU_GPIO_LED_ROUTER 16 + +#define MZK_W04NU_GPIO_BTN_APROUTER 5 +#define MZK_W04NU_GPIO_BTN_WPS 12 +#define MZK_W04NU_GPIO_BTN_RESET 21 + +#define MZK_W04NU_KEYS_POLL_INTERVAL 20 /* msecs */ +#define MZK_W04NU_KEYS_DEBOUNCE_INTERVAL (3 * MZK_W04NU_KEYS_POLL_INTERVAL) + +static struct gpio_led mzk_w04nu_leds_gpio[] __initdata = { + { + .name = "planex:green:status", + .gpio = MZK_W04NU_GPIO_LED_STATUS, + .active_low = 1, + }, { + .name = "planex:blue:wps", + .gpio = MZK_W04NU_GPIO_LED_WPS, + .active_low = 1, + }, { + .name = "planex:green:wlan", + .gpio = MZK_W04NU_GPIO_LED_WLAN, + .active_low = 1, + }, { + .name = "planex:green:usb", + .gpio = MZK_W04NU_GPIO_LED_USB, + .active_low = 1, + }, { + .name = "planex:green:ap", + .gpio = MZK_W04NU_GPIO_LED_AP, + .active_low = 1, + }, { + .name = "planex:green:router", + .gpio = MZK_W04NU_GPIO_LED_ROUTER, + .active_low = 1, + } +}; + +static struct gpio_keys_button mzk_w04nu_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, + .gpio = MZK_W04NU_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, + .gpio = MZK_W04NU_GPIO_BTN_WPS, + .active_low = 1, + }, { + .desc = "aprouter", + .type = EV_KEY, + .code = BTN_2, + .debounce_interval = MZK_W04NU_KEYS_DEBOUNCE_INTERVAL, + .gpio = MZK_W04NU_GPIO_BTN_APROUTER, + .active_low = 0, + } +}; + +#define MZK_W04NU_WAN_PHYMASK BIT(4) +#define MZK_W04NU_MDIO_MASK (~MZK_W04NU_WAN_PHYMASK) + +static void __init mzk_w04nu_setup(void) +{ + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_register_mdio(0, MZK_W04NU_MDIO_MASK); + + ath79_init_mac(ath79_eth0_data.mac_addr, eeprom, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth0_data.speed = SPEED_100; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_eth0_data.has_ar8216 = 1; + + ath79_init_mac(ath79_eth1_data.mac_addr, eeprom, 1); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth1_data.phy_mask = MZK_W04NU_WAN_PHYMASK; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_m25p80(NULL); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(mzk_w04nu_leds_gpio), + mzk_w04nu_leds_gpio); + + ath79_register_gpio_keys_polled(-1, MZK_W04NU_KEYS_POLL_INTERVAL, + ARRAY_SIZE(mzk_w04nu_gpio_keys), + mzk_w04nu_gpio_keys); + ath79_register_usb(); + + ath79_register_wmac(eeprom, NULL); +} + +MIPS_MACHINE(ATH79_MACH_MZK_W04NU, "MZK-W04NU", "Planex MZK-W04NU", + mzk_w04nu_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w300nh.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w300nh.c new file mode 100644 index 000000000..8c4036528 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mzk-w300nh.c @@ -0,0 +1,115 @@ +/* + * Planex MZK-W300NH board support + * + * Copyright (C) 2008-2012 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define MZK_W300NH_GPIO_LED_STATUS 1 +#define MZK_W300NH_GPIO_LED_WPS 3 +#define MZK_W300NH_GPIO_LED_WLAN 6 +#define MZK_W300NH_GPIO_LED_AP_GREEN 15 +#define MZK_W300NH_GPIO_LED_AP_AMBER 16 + +#define MZK_W300NH_GPIO_BTN_APROUTER 5 +#define MZK_W300NH_GPIO_BTN_WPS 12 +#define MZK_W300NH_GPIO_BTN_RESET 21 + +#define MZK_W300NH_KEYS_POLL_INTERVAL 20 /* msecs */ +#define MZK_W300NH_KEYS_DEBOUNCE_INTERVAL (3 * MZK_W300NH_KEYS_POLL_INTERVAL) + +static struct gpio_led mzk_w300nh_leds_gpio[] __initdata = { + { + .name = "planex:green:status", + .gpio = MZK_W300NH_GPIO_LED_STATUS, + .active_low = 1, + }, { + .name = "planex:blue:wps", + .gpio = MZK_W300NH_GPIO_LED_WPS, + .active_low = 1, + }, { + .name = "planex:green:wlan", + .gpio = MZK_W300NH_GPIO_LED_WLAN, + .active_low = 1, + }, { + .name = "planex:green:aprouter", + .gpio = MZK_W300NH_GPIO_LED_AP_GREEN, + }, { + .name = "planex:amber:aprouter", + .gpio = MZK_W300NH_GPIO_LED_AP_AMBER, + } +}; + +static struct gpio_keys_button mzk_w300nh_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, + .gpio = MZK_W300NH_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, + .gpio = MZK_W300NH_GPIO_BTN_WPS, + .active_low = 1, + }, { + .desc = "aprouter", + .type = EV_KEY, + .code = BTN_2, + .debounce_interval = MZK_W300NH_KEYS_DEBOUNCE_INTERVAL, + .gpio = MZK_W300NH_GPIO_BTN_APROUTER, + .active_low = 0, + } +}; + +#define MZK_W300NH_WAN_PHYMASK BIT(4) +#define MZK_W300NH_MDIO_MASK (~MZK_W300NH_WAN_PHYMASK) + +static void __init mzk_w300nh_setup(void) +{ + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_register_mdio(0, MZK_W300NH_MDIO_MASK); + + ath79_init_mac(ath79_eth0_data.mac_addr, eeprom, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth0_data.speed = SPEED_100; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_eth0_data.has_ar8216 = 1; + + ath79_init_mac(ath79_eth1_data.mac_addr, eeprom, 1); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth1_data.phy_mask = MZK_W300NH_WAN_PHYMASK; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_m25p80(NULL); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(mzk_w300nh_leds_gpio), + mzk_w300nh_leds_gpio); + + ath79_register_gpio_keys_polled(-1, MZK_W300NH_KEYS_POLL_INTERVAL, + ARRAY_SIZE(mzk_w300nh_gpio_keys), + mzk_w300nh_gpio_keys); + ath79_register_wmac(eeprom, NULL); +} + +MIPS_MACHINE(ATH79_MACH_MZK_W300NH, "MZK-W300NH", "Planex MZK-W300NH", + mzk_w300nh_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-nbg460n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-nbg460n.c new file mode 100644 index 000000000..8aa7331d4 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-nbg460n.c @@ -0,0 +1,220 @@ +/* + * Zyxel NBG 460N/550N/550NH board support + * + * Copyright (C) 2010 Michael Kurz + * + * based on mach-tl-wr1043nd.c + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-wmac.h" +#include "machtypes.h" + +/* LEDs */ +#define NBG460N_GPIO_LED_WPS 3 +#define NBG460N_GPIO_LED_WAN 6 +#define NBG460N_GPIO_LED_POWER 14 +#define NBG460N_GPIO_LED_WLAN 15 + +/* Buttons */ +#define NBG460N_GPIO_BTN_WPS 12 +#define NBG460N_GPIO_BTN_RESET 21 + +#define NBG460N_KEYS_POLL_INTERVAL 20 /* msecs */ +#define NBG460N_KEYS_DEBOUNCE_INTERVAL (3 * NBG460N_KEYS_POLL_INTERVAL) + +/* RTC chip PCF8563 I2C interface */ +#define NBG460N_GPIO_PCF8563_SDA 8 +#define NBG460N_GPIO_PCF8563_SCK 7 + +/* Switch configuration I2C interface */ +#define NBG460N_GPIO_RTL8366_SDA 16 +#define NBG460N_GPIO_RTL8366_SCK 18 + +static struct mtd_partition nbg460n_partitions[] = { + { + .name = "Bootbase", + .offset = 0, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "U-Boot Config", + .offset = 0x010000, + .size = 0x030000, + }, { + .name = "U-Boot", + .offset = 0x040000, + .size = 0x030000, + }, { + .name = "linux", + .offset = 0x070000, + .size = 0x0e0000, + }, { + .name = "rootfs", + .offset = 0x150000, + .size = 0x2a0000, + }, { + .name = "CalibData", + .offset = 0x3f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "firmware", + .offset = 0x070000, + .size = 0x380000, + } +}; + +static struct flash_platform_data nbg460n_flash_data = { + .parts = nbg460n_partitions, + .nr_parts = ARRAY_SIZE(nbg460n_partitions), +}; + +static struct gpio_led nbg460n_leds_gpio[] __initdata = { + { + .name = "nbg460n:green:power", + .gpio = NBG460N_GPIO_LED_POWER, + .active_low = 0, + .default_trigger = "default-on", + }, { + .name = "nbg460n:green:wps", + .gpio = NBG460N_GPIO_LED_WPS, + .active_low = 0, + }, { + .name = "nbg460n:green:wlan", + .gpio = NBG460N_GPIO_LED_WLAN, + .active_low = 0, + }, { + /* Not really for controlling the LED, + when set low the LED blinks uncontrollable */ + .name = "nbg460n:green:wan", + .gpio = NBG460N_GPIO_LED_WAN, + .active_low = 0, + } +}; + +static struct gpio_keys_button nbg460n_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = NBG460N_KEYS_DEBOUNCE_INTERVAL, + .gpio = NBG460N_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = NBG460N_KEYS_DEBOUNCE_INTERVAL, + .gpio = NBG460N_GPIO_BTN_WPS, + .active_low = 1, + } +}; + +static struct i2c_gpio_platform_data nbg460n_i2c_device_platdata = { + .sda_pin = NBG460N_GPIO_PCF8563_SDA, + .scl_pin = NBG460N_GPIO_PCF8563_SCK, + .udelay = 10, +}; + +static struct platform_device nbg460n_i2c_device = { + .name = "i2c-gpio", + .id = -1, + .num_resources = 0, + .resource = NULL, + .dev = { + .platform_data = &nbg460n_i2c_device_platdata, + }, +}; + +static struct i2c_board_info nbg460n_i2c_devs[] __initdata = { + { + I2C_BOARD_INFO("pcf8563", 0x51), + }, +}; + +static void __devinit nbg460n_i2c_init(void) +{ + /* The gpio interface */ + platform_device_register(&nbg460n_i2c_device); + /* I2C devices */ + i2c_register_board_info(0, nbg460n_i2c_devs, + ARRAY_SIZE(nbg460n_i2c_devs)); +} + + +static struct rtl8366_platform_data nbg460n_rtl8366s_data = { + .gpio_sda = NBG460N_GPIO_RTL8366_SDA, + .gpio_sck = NBG460N_GPIO_RTL8366_SCK, +}; + +static struct platform_device nbg460n_rtl8366s_device = { + .name = RTL8366S_DRIVER_NAME, + .id = -1, + .dev = { + .platform_data = &nbg460n_rtl8366s_data, + } +}; + +static void __init nbg460n_setup(void) +{ + /* end of bootloader sector contains mac address */ + u8 *mac = (u8 *) KSEG1ADDR(0x1fc0fff8); + /* last sector contains wlan calib data */ + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + + /* LAN Port */ + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_eth0_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev; + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + + /* WAN Port */ + ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); + ath79_eth1_data.mii_bus_dev = &nbg460n_rtl8366s_device.dev; + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth1_data.phy_mask = 0x10; + + ath79_register_eth(0); + ath79_register_eth(1); + + /* register the switch phy */ + platform_device_register(&nbg460n_rtl8366s_device); + + /* register flash */ + ath79_register_m25p80(&nbg460n_flash_data); + + ath79_register_wmac(eeprom, mac); + + /* register RTC chip */ + nbg460n_i2c_init(); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(nbg460n_leds_gpio), + nbg460n_leds_gpio); + + ath79_register_gpio_keys_polled(-1, NBG460N_KEYS_POLL_INTERVAL, + ARRAY_SIZE(nbg460n_gpio_keys), + nbg460n_gpio_keys); +} + +MIPS_MACHINE(ATH79_MACH_NBG460N, "NBG460N", "Zyxel NBG460N/550N/550NH", + nbg460n_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-om2p.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-om2p.c new file mode 100644 index 000000000..faeb49a51 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-om2p.c @@ -0,0 +1,176 @@ +/* + * OpenMesh OM2P support + * + * Copyright (C) 2011 Marek Lindner + * + * This program 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. + */ + +#include +#include +#include +#include + +#include +#include + +#include "common.h" +#include "dev-ap9x-pci.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define OM2P_GPIO_LED_POWER 0 +#define OM2P_GPIO_LED_GREEN 13 +#define OM2P_GPIO_LED_RED 14 +#define OM2P_GPIO_LED_YELLOW 15 +#define OM2P_GPIO_LED_LAN 16 +#define OM2P_GPIO_LED_WAN 17 +#define OM2P_GPIO_BTN_RESET 11 + +#define OM2P_KEYS_POLL_INTERVAL 20 /* msecs */ +#define OM2P_KEYS_DEBOUNCE_INTERVAL (3 * OM2P_KEYS_POLL_INTERVAL) + +#define OM2P_WAN_PHYMASK BIT(4) + +#define OM2P_LC_GPIO_LED_POWER 1 +#define OM2P_LC_GPIO_LED_GREEN 15 +#define OM2P_LC_GPIO_LED_RED 16 +#define OM2P_LC_GPIO_LED_YELLOW 0 +#define OM2P_LC_GPIO_LED_LAN 13 +#define OM2P_LC_GPIO_LED_WAN 17 +#define OM2P_LC_GPIO_BTN_RESET 12 + +static struct flash_platform_data om2p_flash_data = { + .type = "s25sl12800", + .name = "ar7240-nor0", +}; + +static struct gpio_led om2p_leds_gpio[] __initdata = { + { + .name = "om2p:blue:power", + .gpio = OM2P_GPIO_LED_POWER, + .active_low = 1, + }, { + .name = "om2p:red:wifi", + .gpio = OM2P_GPIO_LED_RED, + .active_low = 1, + }, { + .name = "om2p:yellow:wifi", + .gpio = OM2P_GPIO_LED_YELLOW, + .active_low = 1, + }, { + .name = "om2p:green:wifi", + .gpio = OM2P_GPIO_LED_GREEN, + .active_low = 1, + }, { + .name = "om2p:blue:lan", + .gpio = OM2P_GPIO_LED_LAN, + .active_low = 1, + }, { + .name = "om2p:blue:wan", + .gpio = OM2P_GPIO_LED_WAN, + .active_low = 1, + } +}; + +static struct gpio_keys_button om2p_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = OM2P_KEYS_DEBOUNCE_INTERVAL, + .gpio = OM2P_GPIO_BTN_RESET, + .active_low = 1, + } +}; + +static void __init om2p_setup(void) +{ + u8 *mac1 = (u8 *)KSEG1ADDR(0x1ffc0000); + u8 *mac2 = (u8 *)KSEG1ADDR(0x1ffc0000 + ETH_ALEN); + u8 *ee = (u8 *)KSEG1ADDR(0x1ffc1000); + + ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + + ath79_register_m25p80(&om2p_flash_data); + + ath79_register_mdio(0, ~OM2P_WAN_PHYMASK); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0); + + ath79_register_eth(0); + ath79_register_eth(1); + + ap91_pci_init(ee, NULL); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(om2p_leds_gpio), + om2p_leds_gpio); + + ath79_register_gpio_keys_polled(-1, OM2P_KEYS_POLL_INTERVAL, + ARRAY_SIZE(om2p_gpio_keys), + om2p_gpio_keys); +} + +MIPS_MACHINE(ATH79_MACH_OM2P, "OM2P", "OpenMesh OM2P", om2p_setup); + + +static struct flash_platform_data om2p_lc_flash_data = { + .type = "s25sl12800", +}; + +static void __init om2p_lc_setup(void) +{ + u8 *mac1 = (u8 *)KSEG1ADDR(0x1ffc0000); + u8 *mac2 = (u8 *)KSEG1ADDR(0x1ffc0000 + ETH_ALEN); + u8 *art = (u8 *)KSEG1ADDR(0x1ffc1000); + u32 t; + + ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + + t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); + t |= AR933X_BOOTSTRAP_MDIO_GPIO_EN; + ath79_reset_wr(AR933X_RESET_REG_BOOTSTRAP, t); + + ath79_register_m25p80(&om2p_lc_flash_data); + + om2p_leds_gpio[0].gpio = OM2P_LC_GPIO_LED_POWER; + om2p_leds_gpio[1].gpio = OM2P_LC_GPIO_LED_RED; + om2p_leds_gpio[2].gpio = OM2P_LC_GPIO_LED_YELLOW; + om2p_leds_gpio[3].gpio = OM2P_LC_GPIO_LED_GREEN; + om2p_leds_gpio[4].gpio = OM2P_LC_GPIO_LED_LAN; + om2p_leds_gpio[5].gpio = OM2P_LC_GPIO_LED_WAN; + ath79_register_leds_gpio(-1, ARRAY_SIZE(om2p_leds_gpio), + om2p_leds_gpio); + + om2p_gpio_keys[0].gpio = OM2P_LC_GPIO_BTN_RESET; + ath79_register_gpio_keys_polled(-1, OM2P_KEYS_POLL_INTERVAL, + ARRAY_SIZE(om2p_gpio_keys), + om2p_gpio_keys); + + ath79_init_mac(ath79_eth1_data.mac_addr, mac1, 0); + ath79_init_mac(ath79_eth0_data.mac_addr, mac2, 0); + + ath79_register_mdio(0, 0x0); + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_wmac(art, NULL); +} + +MIPS_MACHINE(ATH79_MACH_OM2P_LC, "OM2P-LC", "OpenMesh OM2P LC", om2p_lc_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-pb42.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-pb42.c new file mode 100644 index 000000000..3a350e90a --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-pb42.c @@ -0,0 +1,83 @@ +/* + * Atheros PB42 board support + * + * Copyright (C) 2008-2012 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" +#include "pci.h" + +#define PB42_KEYS_POLL_INTERVAL 20 /* msecs */ +#define PB42_KEYS_DEBOUNCE_INTERVAL (3 * PB42_KEYS_POLL_INTERVAL) + +#define PB42_GPIO_BTN_SW4 8 +#define PB42_GPIO_BTN_SW5 3 + +static struct gpio_keys_button pb42_gpio_keys[] __initdata = { + { + .desc = "sw4", + .type = EV_KEY, + .code = BTN_0, + .debounce_interval = PB42_KEYS_DEBOUNCE_INTERVAL, + .gpio = PB42_GPIO_BTN_SW4, + .active_low = 1, + }, { + .desc = "sw5", + .type = EV_KEY, + .code = BTN_1, + .debounce_interval = PB42_KEYS_DEBOUNCE_INTERVAL, + .gpio = PB42_GPIO_BTN_SW5, + .active_low = 1, + } +}; + +static const char *pb42_part_probes[] = { + "RedBoot", + NULL, +}; + +static struct flash_platform_data pb42_flash_data = { + .part_probes = pb42_part_probes, +}; + +#define PB42_WAN_PHYMASK BIT(20) +#define PB42_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19)) +#define PB42_MDIO_PHYMASK (PB42_LAN_PHYMASK | PB42_WAN_PHYMASK) + +static void __init pb42_init(void) +{ + ath79_register_m25p80(&pb42_flash_data); + + ath79_register_mdio(0, ~PB42_MDIO_PHYMASK); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; + ath79_eth0_data.phy_mask = PB42_WAN_PHYMASK; + + ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth1_data.speed = SPEED_100; + ath79_eth1_data.duplex = DUPLEX_FULL; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_gpio_keys_polled(-1, PB42_KEYS_POLL_INTERVAL, + ARRAY_SIZE(pb42_gpio_keys), + pb42_gpio_keys); + + ath79_register_pci(); +} + +MIPS_MACHINE(ATH79_MACH_PB42, "PB42", "Atheros PB42", pb42_init); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-pb92.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-pb92.c new file mode 100644 index 000000000..76715a517 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-pb92.c @@ -0,0 +1,70 @@ +/* + * Atheros PB92 board support + * + * Copyright (C) 2010 Felix Fietkau + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" +#include "pci.h" + +#define PB92_KEYS_POLL_INTERVAL 20 /* msecs */ +#define PB92_KEYS_DEBOUNCE_INTERVAL (3 * PB92_KEYS_POLL_INTERVAL) + +#define PB92_GPIO_BTN_SW4 8 +#define PB92_GPIO_BTN_SW5 3 + +static struct gpio_keys_button pb92_gpio_keys[] __initdata = { + { + .desc = "sw4", + .type = EV_KEY, + .code = BTN_0, + .debounce_interval = PB92_KEYS_DEBOUNCE_INTERVAL, + .gpio = PB92_GPIO_BTN_SW4, + .active_low = 1, + }, { + .desc = "sw5", + .type = EV_KEY, + .code = BTN_1, + .debounce_interval = PB92_KEYS_DEBOUNCE_INTERVAL, + .gpio = PB92_GPIO_BTN_SW5, + .active_low = 1, + } +}; + +static void __init pb92_init(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); + + ath79_register_m25p80(NULL); + + ath79_register_mdio(0, ~BIT(0)); + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_eth0_data.phy_mask = BIT(0); + + ath79_register_eth(0); + + ath79_register_gpio_keys_polled(-1, PB92_KEYS_POLL_INTERVAL, + ARRAY_SIZE(pb92_gpio_keys), + pb92_gpio_keys); + + ath79_register_usb(); + + ath79_register_pci(); +} + +MIPS_MACHINE(ATH79_MACH_PB92, "PB92", "Atheros PB92", pb92_init); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rb2011.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb2011.c new file mode 100644 index 000000000..ecdd7ea2e --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb2011.c @@ -0,0 +1,271 @@ +/* + * MikroTik RouterBOARD 2011 support + * + * Copyright (C) 2012 Stijn Tintel + * Copyright (C) 2012 Gabor Juhos + * + * This program 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 pr_fmt(fmt) "rb2011: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "common.h" +#include "dev-eth.h" +#include "dev-m25p80.h" +#include "dev-nfc.h" +#include "dev-wmac.h" +#include "machtypes.h" +#include "routerboot.h" + +#define RB2011_GPIO_NAND_NCE 14 + +#define RB_ROUTERBOOT_OFFSET 0x0000 +#define RB_ROUTERBOOT_SIZE 0xb000 +#define RB_HARD_CFG_OFFSET 0xb000 +#define RB_HARD_CFG_SIZE 0x1000 +#define RB_BIOS_OFFSET 0xd000 +#define RB_BIOS_SIZE 0x2000 +#define RB_SOFT_CFG_OFFSET 0xf000 +#define RB_SOFT_CFG_SIZE 0x1000 + +#define RB_ART_SIZE 0x10000 + +static struct mtd_partition rb2011_spi_partitions[] = { + { + .name = "routerboot", + .offset = RB_ROUTERBOOT_OFFSET, + .size = RB_ROUTERBOOT_SIZE, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "hard_config", + .offset = RB_HARD_CFG_OFFSET, + .size = RB_HARD_CFG_SIZE, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "bios", + .offset = RB_BIOS_OFFSET, + .size = RB_BIOS_SIZE, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "soft_config", + .offset = RB_SOFT_CFG_OFFSET, + .size = RB_SOFT_CFG_SIZE, + } +}; + +static struct mtd_partition rb2011_nand_partitions[] = { + { + .name = "booter", + .offset = 0, + .size = (256 * 1024), + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "kernel", + .offset = (256 * 1024), + .size = (4 * 1024 * 1024) - (256 * 1024), + }, + { + .name = "rootfs", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct flash_platform_data rb2011_spi_flash_data = { + .parts = rb2011_spi_partitions, + .nr_parts = ARRAY_SIZE(rb2011_spi_partitions), +}; + +static struct ar8327_pad_cfg rb2011_ar8327_pad0_cfg = { + .mode = AR8327_PAD_MAC_RGMII, + .txclk_delay_en = true, + .rxclk_delay_en = true, + .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, + .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, +}; + +static struct ar8327_platform_data rb2011_ar8327_data = { + .pad0_cfg = &rb2011_ar8327_pad0_cfg, + .cpuport_cfg = { + .force_link = 1, + .speed = AR8327_PORT_SPEED_1000, + .duplex = 1, + .txpause = 1, + .rxpause = 1, + } +}; + +static struct mdio_board_info rb2011_mdio0_info[] = { + { + .bus_id = "ag71xx-mdio.0", + .phy_addr = 0, + .platform_data = &rb2011_ar8327_data, + }, +}; + +static void __init rb2011_gmac_setup(void) +{ + void __iomem *base; + u32 t; + + base = ioremap(AR934X_GMAC_BASE, AR934X_GMAC_SIZE); + + t = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); + t &= ~(AR934X_ETH_CFG_RGMII_GMAC0 | AR934X_ETH_CFG_MII_GMAC0 | + AR934X_ETH_CFG_GMII_GMAC0 | AR934X_ETH_CFG_SW_ONLY_MODE); + t |= AR934X_ETH_CFG_RGMII_GMAC0 | AR934X_ETH_CFG_SW_ONLY_MODE; + + __raw_writel(t, base + AR934X_GMAC_REG_ETH_CFG); + + iounmap(base); +} + +static void __init rb2011_wlan_init(void) +{ + u8 *hard_cfg = (u8 *) KSEG1ADDR(0x1f000000 + RB_HARD_CFG_OFFSET); + u16 tag_len; + u8 *tag; + char *art_buf; + u8 wlan_mac[ETH_ALEN]; + int err; + + err = routerboot_find_tag(hard_cfg, RB_HARD_CFG_SIZE, RB_ID_WLAN_DATA, + &tag, &tag_len); + if (err) { + pr_err("no calibration data found\n"); + return; + } + + art_buf = kmalloc(RB_ART_SIZE, GFP_KERNEL); + if (art_buf == NULL) { + pr_err("no memory for calibration data\n"); + return; + } + + err = rle_decode((char *) tag, tag_len, art_buf, RB_ART_SIZE, + NULL, NULL); + if (err) { + pr_err("unable to decode calibration data\n"); + goto free; + } + + ath79_init_mac(wlan_mac, ath79_mac_base, 11); + ath79_register_wmac(art_buf + 0x1000, wlan_mac); + +free: + kfree(art_buf); +} + +static void rb2011_nand_select_chip(int chip_no) +{ + switch (chip_no) { + case 0: + gpio_set_value(RB2011_GPIO_NAND_NCE, 0); + break; + default: + gpio_set_value(RB2011_GPIO_NAND_NCE, 1); + break; + } + ndelay(500); +} + +static struct nand_ecclayout rb2011_nand_ecclayout = { + .eccbytes = 6, + .eccpos = { 8, 9, 10, 13, 14, 15 }, + .oobavail = 9, + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } +}; + +static int rb2011_nand_scan_fixup(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + + if (mtd->writesize == 512) { + /* + * Use the OLD Yaffs-1 OOB layout, otherwise RouterBoot + * will not be able to find the kernel that we load. + */ + chip->ecc.layout = &rb2011_nand_ecclayout; + } + + return 0; +} + +static void __init rb2011_nand_init(void) +{ + ath79_nfc_set_scan_fixup(rb2011_nand_scan_fixup); + ath79_nfc_set_parts(rb2011_nand_partitions, + ARRAY_SIZE(rb2011_nand_partitions)); + ath79_nfc_set_select_chip(rb2011_nand_select_chip); + ath79_register_nfc(); +} + +static void __init rb2011_gpio_init(void) +{ + gpio_request_one(RB2011_GPIO_NAND_NCE, GPIOF_OUT_INIT_HIGH, "NAND nCE"); +} + +static void __init rb2011_setup(void) +{ + rb2011_gpio_init(); + + ath79_register_m25p80(&rb2011_spi_flash_data); + rb2011_nand_init(); + + rb2011_gmac_setup(); + + ath79_register_mdio(1, 0x0); + ath79_register_mdio(0, 0x0); + + mdiobus_register_board_info(rb2011_mdio0_info, + ARRAY_SIZE(rb2011_mdio0_info)); + + /* GMAC0 is connected to an ar8327 switch */ + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.phy_mask = BIT(0); + ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; + ath79_eth0_pll_data.pll_1000 = 0x06000000; + + ath79_register_eth(0); + + /* GMAC1 is connected to the internal switch */ + ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 5); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; + ath79_eth1_data.speed = SPEED_1000; + ath79_eth1_data.duplex = DUPLEX_FULL; + + ath79_register_eth(1); +} + +MIPS_MACHINE(ATH79_MACH_RB_2011L, "2011L", "MikroTik RouterBOARD 2011L", + rb2011_setup); + +static void __init rb2011g_setup(void) +{ + rb2011_setup(); + rb2011_wlan_init(); +} + +MIPS_MACHINE(ATH79_MACH_RB_2011G, "2011G", "MikroTik RouterBOARD 2011UAS-2HnD", + rb2011g_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rb4xx.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb4xx.c new file mode 100644 index 000000000..1604a5c56 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb4xx.c @@ -0,0 +1,405 @@ +/* + * MikroTik RouterBOARD 4xx series support + * + * Copyright (C) 2008-2012 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "common.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-usb.h" +#include "machtypes.h" +#include "pci.h" + +#define RB4XX_GPIO_USER_LED 4 +#define RB4XX_GPIO_RESET_SWITCH 7 + +#define RB4XX_GPIO_CPLD_BASE 32 +#define RB4XX_GPIO_CPLD_LED1 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED1) +#define RB4XX_GPIO_CPLD_LED2 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED2) +#define RB4XX_GPIO_CPLD_LED3 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED3) +#define RB4XX_GPIO_CPLD_LED4 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED4) +#define RB4XX_GPIO_CPLD_LED5 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED5) + +#define RB4XX_KEYS_POLL_INTERVAL 20 /* msecs */ +#define RB4XX_KEYS_DEBOUNCE_INTERVAL (3 * RB4XX_KEYS_POLL_INTERVAL) + +static struct gpio_led rb4xx_leds_gpio[] __initdata = { + { + .name = "rb4xx:yellow:user", + .gpio = RB4XX_GPIO_USER_LED, + .active_low = 0, + }, { + .name = "rb4xx:green:led1", + .gpio = RB4XX_GPIO_CPLD_LED1, + .active_low = 1, + }, { + .name = "rb4xx:green:led2", + .gpio = RB4XX_GPIO_CPLD_LED2, + .active_low = 1, + }, { + .name = "rb4xx:green:led3", + .gpio = RB4XX_GPIO_CPLD_LED3, + .active_low = 1, + }, { + .name = "rb4xx:green:led4", + .gpio = RB4XX_GPIO_CPLD_LED4, + .active_low = 1, + }, { + .name = "rb4xx:green:led5", + .gpio = RB4XX_GPIO_CPLD_LED5, + .active_low = 0, + }, +}; + +static struct gpio_keys_button rb4xx_gpio_keys[] __initdata = { + { + .desc = "reset_switch", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = RB4XX_KEYS_DEBOUNCE_INTERVAL, + .gpio = RB4XX_GPIO_RESET_SWITCH, + .active_low = 1, + } +}; + +static struct platform_device rb4xx_nand_device = { + .name = "rb4xx-nand", + .id = -1, +}; + +static struct ath79_pci_irq rb4xx_pci_irqs[] __initdata = { + { + .slot = 17, + .pin = 1, + .irq = ATH79_PCI_IRQ(2), + }, { + .slot = 18, + .pin = 1, + .irq = ATH79_PCI_IRQ(0), + }, { + .slot = 18, + .pin = 2, + .irq = ATH79_PCI_IRQ(1), + }, { + .slot = 19, + .pin = 1, + .irq = ATH79_PCI_IRQ(1), + }, { + .slot = 19, + .pin = 1, + .irq = ATH79_PCI_IRQ(2), + } +}; + +static struct mtd_partition rb4xx_partitions[] = { + { + .name = "routerboot", + .offset = 0, + .size = 0x0b000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "hard_config", + .offset = 0x0b000, + .size = 0x01000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "bios", + .offset = 0x0d000, + .size = 0x02000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "soft_config", + .offset = 0x0f000, + .size = 0x01000, + } +}; + +static struct flash_platform_data rb4xx_flash_data = { + .type = "pm25lv512", + .parts = rb4xx_partitions, + .nr_parts = ARRAY_SIZE(rb4xx_partitions), +}; + +static struct rb4xx_cpld_platform_data rb4xx_cpld_data = { + .gpio_base = RB4XX_GPIO_CPLD_BASE, +}; + +static struct mmc_spi_platform_data rb4xx_mmc_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, +}; + +static struct spi_board_info rb4xx_spi_info[] = { + { + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 25000000, + .modalias = "m25p80", + .platform_data = &rb4xx_flash_data, + }, { + .bus_num = 0, + .chip_select = 1, + .max_speed_hz = 25000000, + .modalias = "spi-rb4xx-cpld", + .platform_data = &rb4xx_cpld_data, + } +}; + +static struct spi_board_info rb4xx_microsd_info[] = { + { + .bus_num = 0, + .chip_select = 2, + .max_speed_hz = 25000000, + .modalias = "mmc_spi", + .platform_data = &rb4xx_mmc_data, + } +}; + + +static struct resource rb4xx_spi_resources[] = { + { + .start = AR71XX_SPI_BASE, + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device rb4xx_spi_device = { + .name = "rb4xx-spi", + .id = -1, + .resource = rb4xx_spi_resources, + .num_resources = ARRAY_SIZE(rb4xx_spi_resources), +}; + +static void __init rb4xx_generic_setup(void) +{ + ath79_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN | + AR71XX_GPIO_FUNC_SPI_CS2_EN); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(rb4xx_leds_gpio), + rb4xx_leds_gpio); + + ath79_register_gpio_keys_polled(-1, RB4XX_KEYS_POLL_INTERVAL, + ARRAY_SIZE(rb4xx_gpio_keys), + rb4xx_gpio_keys); + + spi_register_board_info(rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info)); + platform_device_register(&rb4xx_spi_device); + platform_device_register(&rb4xx_nand_device); +} + +static void __init rb411_setup(void) +{ + rb4xx_generic_setup(); + spi_register_board_info(rb4xx_microsd_info, + ARRAY_SIZE(rb4xx_microsd_info)); + + ath79_register_mdio(0, 0xfffffffc); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; + ath79_eth0_data.phy_mask = 0x00000003; + + ath79_register_eth(0); + + ath79_pci_set_irq_map(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); + ath79_register_pci(); +} + +MIPS_MACHINE(ATH79_MACH_RB_411, "411", "MikroTik RouterBOARD 411/A/AH", + rb411_setup); + +static void __init rb411u_setup(void) +{ + rb411_setup(); + ath79_register_usb(); +} + +MIPS_MACHINE(ATH79_MACH_RB_411U, "411U", "MikroTik RouterBOARD 411U", + rb411u_setup); + +#define RB433_LAN_PHYMASK BIT(0) +#define RB433_WAN_PHYMASK BIT(4) +#define RB433_MDIO_PHYMASK (RB433_LAN_PHYMASK | RB433_WAN_PHYMASK) + +static void __init rb433_setup(void) +{ + rb4xx_generic_setup(); + spi_register_board_info(rb4xx_microsd_info, + ARRAY_SIZE(rb4xx_microsd_info)); + + ath79_register_mdio(0, ~RB433_MDIO_PHYMASK); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 1); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; + ath79_eth0_data.phy_mask = RB433_LAN_PHYMASK; + + ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 0); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth1_data.phy_mask = RB433_WAN_PHYMASK; + + ath79_register_eth(1); + ath79_register_eth(0); + + ath79_pci_set_irq_map(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); + ath79_register_pci(); +} + +MIPS_MACHINE(ATH79_MACH_RB_433, "433", "MikroTik RouterBOARD 433/AH", + rb433_setup); + +static void __init rb433u_setup(void) +{ + rb433_setup(); + ath79_register_usb(); +} + +MIPS_MACHINE(ATH79_MACH_RB_433U, "433U", "MikroTik RouterBOARD 433UAH", + rb433u_setup); + +#define RB450_LAN_PHYMASK BIT(0) +#define RB450_WAN_PHYMASK BIT(4) +#define RB450_MDIO_PHYMASK (RB450_LAN_PHYMASK | RB450_WAN_PHYMASK) + +static void __init rb450_generic_setup(int gige) +{ + rb4xx_generic_setup(); + ath79_register_mdio(0, ~RB450_MDIO_PHYMASK); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 1); + ath79_eth0_data.phy_if_mode = (gige) ? + PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_MII; + ath79_eth0_data.phy_mask = RB450_LAN_PHYMASK; + + ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 0); + ath79_eth1_data.phy_if_mode = (gige) ? + PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_RMII; + ath79_eth1_data.phy_mask = RB450_WAN_PHYMASK; + + ath79_register_eth(1); + ath79_register_eth(0); +} + +static void __init rb450_setup(void) +{ + rb450_generic_setup(0); +} + +MIPS_MACHINE(ATH79_MACH_RB_450, "450", "MikroTik RouterBOARD 450", + rb450_setup); + +static void __init rb450g_setup(void) +{ + rb450_generic_setup(1); + spi_register_board_info(rb4xx_microsd_info, + ARRAY_SIZE(rb4xx_microsd_info)); +} + +MIPS_MACHINE(ATH79_MACH_RB_450G, "450G", "MikroTik RouterBOARD 450G", + rb450g_setup); + +static void __init rb493_setup(void) +{ + rb4xx_generic_setup(); + + ath79_register_mdio(0, 0x3fffff00); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; + ath79_eth0_data.speed = SPEED_100; + ath79_eth0_data.duplex = DUPLEX_FULL; + + ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth1_data.phy_mask = 0x00000001; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_pci_set_irq_map(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); + ath79_register_pci(); +} + +MIPS_MACHINE(ATH79_MACH_RB_493, "493", "MikroTik RouterBOARD 493/AH", + rb493_setup); + +#define RB493G_GPIO_MDIO_MDC 7 +#define RB493G_GPIO_MDIO_DATA 8 + +#define RB493G_MDIO_PHYMASK BIT(0) + +static struct mdio_gpio_platform_data rb493g_mdio_data = { + .mdc = RB493G_GPIO_MDIO_MDC, + .mdio = RB493G_GPIO_MDIO_DATA, + + .phy_mask = ~RB493G_MDIO_PHYMASK, +}; + +static struct platform_device rb493g_mdio_device = { + .name = "mdio-gpio", + .id = -1, + .dev = { + .platform_data = &rb493g_mdio_data, + }, +}; + +static void __init rb493g_setup(void) +{ + ath79_gpio_function_enable(AR71XX_GPIO_FUNC_SPI_CS1_EN | + AR71XX_GPIO_FUNC_SPI_CS2_EN); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(rb4xx_leds_gpio), + rb4xx_leds_gpio); + + spi_register_board_info(rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info)); + platform_device_register(&rb4xx_spi_device); + platform_device_register(&rb4xx_nand_device); + + ath79_register_mdio(0, ~RB493G_MDIO_PHYMASK); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.phy_mask = RB493G_MDIO_PHYMASK; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + + ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth1_data.mii_bus_dev = &rb493g_mdio_device.dev; + ath79_eth1_data.phy_mask = RB493G_MDIO_PHYMASK; + ath79_eth1_data.speed = SPEED_1000; + ath79_eth1_data.duplex = DUPLEX_FULL; + + platform_device_register(&rb493g_mdio_device); + + ath79_register_eth(1); + ath79_register_eth(0); + + ath79_register_usb(); + + ath79_pci_set_irq_map(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs); + ath79_register_pci(); +} + +MIPS_MACHINE(ATH79_MACH_RB_493G, "493G", "MikroTik RouterBOARD 493G", + rb493g_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rb750.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb750.c new file mode 100644 index 000000000..bee8bdf9c --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rb750.c @@ -0,0 +1,337 @@ +/* + * MikroTik RouterBOARD 750/750GL support + * + * Copyright (C) 2010-2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "common.h" +#include "dev-ap9x-pci.h" +#include "dev-usb.h" +#include "dev-eth.h" +#include "machtypes.h" +#include "routerboot.h" + +static struct rb750_led_data rb750_leds[] = { + { + .name = "rb750:green:act", + .mask = RB750_LED_ACT, + .active_low = 1, + }, { + .name = "rb750:green:port1", + .mask = RB750_LED_PORT5, + .active_low = 1, + }, { + .name = "rb750:green:port2", + .mask = RB750_LED_PORT4, + .active_low = 1, + }, { + .name = "rb750:green:port3", + .mask = RB750_LED_PORT3, + .active_low = 1, + }, { + .name = "rb750:green:port4", + .mask = RB750_LED_PORT2, + .active_low = 1, + }, { + .name = "rb750:green:port5", + .mask = RB750_LED_PORT1, + .active_low = 1, + } +}; + +static struct rb750_led_data rb750gr3_leds[] = { + { + .name = "rb750:green:act", + .mask = RB7XX_LED_ACT, + .active_low = 1, + }, +}; + +static struct rb750_led_platform_data rb750_leds_data; +static struct platform_device rb750_leds_device = { + .name = "leds-rb750", + .dev = { + .platform_data = &rb750_leds_data, + } +}; + +static struct rb7xx_nand_platform_data rb750_nand_data; +static struct platform_device rb750_nand_device = { + .name = "rb750-nand", + .id = -1, + .dev = { + .platform_data = &rb750_nand_data, + } +}; + +static void rb750_latch_change(u32 mask_clr, u32 mask_set) +{ + static DEFINE_SPINLOCK(lock); + static u32 latch_set = RB750_LED_BITS | RB750_LVC573_LE; + static u32 latch_oe; + static u32 latch_clr; + unsigned long flags; + u32 t; + + spin_lock_irqsave(&lock, flags); + + if ((mask_clr & BIT(31)) != 0 && + (latch_set & RB750_LVC573_LE) == 0) { + goto unlock; + } + + latch_set = (latch_set | mask_set) & ~mask_clr; + latch_clr = (latch_clr | mask_clr) & ~mask_set; + + if (latch_oe == 0) + latch_oe = __raw_readl(ath79_gpio_base + AR71XX_GPIO_REG_OE); + + if (likely(latch_set & RB750_LVC573_LE)) { + void __iomem *base = ath79_gpio_base; + + t = __raw_readl(base + AR71XX_GPIO_REG_OE); + t |= mask_clr | latch_oe | mask_set; + + __raw_writel(t, base + AR71XX_GPIO_REG_OE); + __raw_writel(latch_clr, base + AR71XX_GPIO_REG_CLEAR); + __raw_writel(latch_set, base + AR71XX_GPIO_REG_SET); + } else if (mask_clr & RB750_LVC573_LE) { + void __iomem *base = ath79_gpio_base; + + latch_oe = __raw_readl(base + AR71XX_GPIO_REG_OE); + __raw_writel(RB750_LVC573_LE, base + AR71XX_GPIO_REG_CLEAR); + /* flush write */ + __raw_readl(base + AR71XX_GPIO_REG_CLEAR); + } + +unlock: + spin_unlock_irqrestore(&lock, flags); +} + +static void rb750_nand_enable_pins(void) +{ + rb750_latch_change(RB750_LVC573_LE, 0); + ath79_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE, + AR724X_GPIO_FUNC_SPI_EN); +} + +static void rb750_nand_disable_pins(void) +{ + ath79_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN, + AR724X_GPIO_FUNC_JTAG_DISABLE); + rb750_latch_change(0, RB750_LVC573_LE); +} + +static void __init rb750_setup(void) +{ + ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); + + ath79_register_mdio(0, 0x0); + + /* LAN ports */ + ath79_register_eth(1); + + /* WAN port */ + ath79_register_eth(0); + + rb750_leds_data.num_leds = ARRAY_SIZE(rb750_leds); + rb750_leds_data.leds = rb750_leds; + rb750_leds_data.latch_change = rb750_latch_change; + platform_device_register(&rb750_leds_device); + + rb750_nand_data.nce_line = RB750_NAND_NCE; + rb750_nand_data.enable_pins = rb750_nand_enable_pins; + rb750_nand_data.disable_pins = rb750_nand_disable_pins; + rb750_nand_data.latch_change = rb750_latch_change; + platform_device_register(&rb750_nand_device); +} + +MIPS_MACHINE(ATH79_MACH_RB_750, "750i", "MikroTik RouterBOARD 750", + rb750_setup); + +static struct ar8327_pad_cfg rb750gr3_ar8327_pad0_cfg = { + .mode = AR8327_PAD_MAC_RGMII, + .txclk_delay_en = true, + .rxclk_delay_en = true, + .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, + .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, +}; + +static struct ar8327_platform_data rb750gr3_ar8327_data = { + .pad0_cfg = &rb750gr3_ar8327_pad0_cfg, + .cpuport_cfg = { + .force_link = 1, + .speed = AR8327_PORT_SPEED_100, + .duplex = 1, + .txpause = 1, + .rxpause = 1, + } +}; + +static struct mdio_board_info rb750g3_mdio_info[] = { + { + .bus_id = "ag71xx-mdio.0", + .phy_addr = 0, + .platform_data = &rb750gr3_ar8327_data, + }, +}; + +static void rb750gr3_nand_enable_pins(void) +{ + ath79_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE, + AR724X_GPIO_FUNC_SPI_EN | + AR724X_GPIO_FUNC_SPI_CS_EN2); +} + +static void rb750gr3_nand_disable_pins(void) +{ + ath79_gpio_function_setup(AR724X_GPIO_FUNC_SPI_EN | + AR724X_GPIO_FUNC_SPI_CS_EN2, + AR724X_GPIO_FUNC_JTAG_DISABLE); +} + +static void rb750gr3_latch_change(u32 mask_clr, u32 mask_set) +{ + static DEFINE_SPINLOCK(lock); + static u32 latch_set = RB7XX_LED_ACT; + static u32 latch_clr; + void __iomem *base = ath79_gpio_base; + unsigned long flags; + u32 t; + + spin_lock_irqsave(&lock, flags); + + latch_set = (latch_set | mask_set) & ~mask_clr; + latch_clr = (latch_clr | mask_clr) & ~mask_set; + + mask_set = latch_set & (RB7XX_USB_POWERON | RB7XX_MONITOR); + mask_clr = latch_clr & (RB7XX_USB_POWERON | RB7XX_MONITOR); + + if ((latch_set ^ RB7XX_LED_ACT) & RB7XX_LED_ACT) { + /* enable output mode */ + t = __raw_readl(base + AR71XX_GPIO_REG_OE); + t |= RB7XX_LED_ACT; + __raw_writel(t, base + AR71XX_GPIO_REG_OE); + + mask_clr |= RB7XX_LED_ACT; + } else { + /* disable output mode */ + t = __raw_readl(base + AR71XX_GPIO_REG_OE); + t &= ~RB7XX_LED_ACT; + __raw_writel(t, base + AR71XX_GPIO_REG_OE); + } + + __raw_writel(mask_set, base + AR71XX_GPIO_REG_SET); + __raw_writel(mask_clr, base + AR71XX_GPIO_REG_CLEAR); + + spin_unlock_irqrestore(&lock, flags); +} + +static void __init rb750gr3_setup(void) +{ + ath79_register_mdio(0, 0x0); + mdiobus_register_board_info(rb750g3_mdio_info, + ARRAY_SIZE(rb750g3_mdio_info)); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.phy_mask = BIT(0); + + ath79_register_eth(0); + + rb750_leds_data.num_leds = ARRAY_SIZE(rb750gr3_leds); + rb750_leds_data.leds = rb750gr3_leds; + rb750_leds_data.latch_change = rb750gr3_latch_change; + platform_device_register(&rb750_leds_device); + + rb750_nand_data.nce_line = RB7XX_NAND_NCE; + rb750_nand_data.enable_pins = rb750gr3_nand_enable_pins; + rb750_nand_data.disable_pins = rb750gr3_nand_disable_pins; + rb750_nand_data.latch_change = rb750gr3_latch_change; + platform_device_register(&rb750_nand_device); +} + +MIPS_MACHINE(ATH79_MACH_RB_750G_R3, "750Gr3", "MikroTik RouterBOARD 750GL", + rb750gr3_setup); + +#define RB751_HARDCONFIG 0x1f00b000 +#define RB751_HARDCONFIG_SIZE 0x1000 +#define RB751_MAC_ADDRESS_OFFSET 0xE80 + +static void __init rb751_wlan_setup(void) +{ + u8 *hardconfig = (u8 *) KSEG1ADDR(RB751_HARDCONFIG); + struct ath9k_platform_data *wmac_data; + u16 tag_len; + u8 *tag; + int err; + + wmac_data = ap9x_pci_get_wmac_data(0); + if (!wmac_data) { + pr_err("rb75x: unable to get address of wlan data\n"); + return; + } + + ap9x_pci_setup_wmac_led_pin(0, 9); + + err = routerboot_find_tag(hardconfig, RB751_HARDCONFIG_SIZE, + RB_ID_WLAN_DATA, &tag, &tag_len); + if (err) { + pr_err("rb75x: no calibration data found\n"); + return; + } + + err = rle_decode(tag, tag_len, (unsigned char *) wmac_data->eeprom_data, + sizeof(wmac_data->eeprom_data), NULL, NULL); + if (err) { + pr_err("rb75x: unable to decode wlan eeprom data\n"); + return; + } + + ap91_pci_init(NULL, hardconfig + RB751_MAC_ADDRESS_OFFSET); +} + +static void __init rb751_setup(void) +{ + rb750_setup(); + ath79_register_usb(); + rb751_wlan_setup(); +} + +MIPS_MACHINE(ATH79_MACH_RB_751, "751", "MikroTik RouterBOARD 751", + rb751_setup); + +static void __init rb751g_setup(void) +{ + rb750gr3_setup(); + ath79_register_usb(); + rb751_wlan_setup(); +} + +MIPS_MACHINE(ATH79_MACH_RB_751G, "751g", "MikroTik RouterBOARD 751G", + rb751g_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-rw2458n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-rw2458n.c new file mode 100644 index 000000000..28d9de4f3 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-rw2458n.c @@ -0,0 +1,100 @@ +/* + * Redwave RW2458N support + * + * Copyright (C) 2011-2012 Cezary Jackiewicz + * + * This program 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. + */ + +#include + +#include "dev-eth.h" +#include "dev-ap9x-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" + +#define RW2458N_GPIO_LED_D3 1 +#define RW2458N_GPIO_LED_D4 0 +#define RW2458N_GPIO_LED_D5 11 +#define RW2458N_GPIO_LED_D6 7 +#define RW2458N_GPIO_BTN_RESET 12 + +#define RW2458N_KEYS_POLL_INTERVAL 20 /* msecs */ +#define RW2458N_KEYS_DEBOUNCE_INTERVAL (3 * RW2458N_KEYS_POLL_INTERVAL) + +static struct gpio_keys_button rw2458n_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = RW2458N_KEYS_DEBOUNCE_INTERVAL, + .gpio = RW2458N_GPIO_BTN_RESET, + .active_low = 1, + } +}; + +#define RW2458N_WAN_PHYMASK BIT(4) + +static struct gpio_led rw2458n_leds_gpio[] __initdata = { + { + .name = "rw2458n:green:d3", + .gpio = RW2458N_GPIO_LED_D3, + .active_low = 1, + }, { + .name = "rw2458n:green:d4", + .gpio = RW2458N_GPIO_LED_D4, + .active_low = 1, + }, { + .name = "rw2458n:green:d5", + .gpio = RW2458N_GPIO_LED_D5, + .active_low = 1, + }, { + .name = "rw2458n:green:d6", + .gpio = RW2458N_GPIO_LED_D6, + .active_low = 1, + } +}; + +static const char *rw2458n_part_probes[] = { + "RedBoot", + NULL, +}; + +static struct flash_platform_data rw2458n_flash_data = { + .part_probes = rw2458n_part_probes, +}; + +static void __init rw2458n_setup(void) +{ + u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000); + u8 *mac2 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN); + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_register_m25p80(&rw2458n_flash_data); + + ath79_register_mdio(0, ~RW2458N_WAN_PHYMASK); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0); + + ath79_register_eth(0); + ath79_register_eth(1); + + ap91_pci_init(ee, NULL); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(rw2458n_leds_gpio), + rw2458n_leds_gpio); + + ath79_register_gpio_keys_polled(-1, RW2458N_KEYS_POLL_INTERVAL, + ARRAY_SIZE(rw2458n_gpio_keys), + rw2458n_gpio_keys); + ath79_register_usb(); +} + +MIPS_MACHINE(ATH79_MACH_RW2458N, "RW2458N", "Redwave RW2458N", + rw2458n_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-632brp.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-632brp.c new file mode 100644 index 000000000..b76d4a7a0 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-632brp.c @@ -0,0 +1,109 @@ +/* + * TrendNET TEW-632BRP board support + * + * Copyright (C) 2008-2012 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-wmac.h" +#include "machtypes.h" +#include "nvram.h" + +#define TEW_632BRP_GPIO_LED_STATUS 1 +#define TEW_632BRP_GPIO_LED_WPS 3 +#define TEW_632BRP_GPIO_LED_WLAN 6 +#define TEW_632BRP_GPIO_BTN_WPS 12 +#define TEW_632BRP_GPIO_BTN_RESET 21 + +#define TEW_632BRP_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TEW_632BRP_KEYS_DEBOUNCE_INTERVAL (3 * TEW_632BRP_KEYS_POLL_INTERVAL) + +#define TEW_632BRP_CONFIG_ADDR 0x1f020000 +#define TEW_632BRP_CONFIG_SIZE 0x10000 + +static struct gpio_led tew_632brp_leds_gpio[] __initdata = { + { + .name = "tew-632brp:green:status", + .gpio = TEW_632BRP_GPIO_LED_STATUS, + .active_low = 1, + }, { + .name = "tew-632brp:blue:wps", + .gpio = TEW_632BRP_GPIO_LED_WPS, + .active_low = 1, + }, { + .name = "tew-632brp:green:wlan", + .gpio = TEW_632BRP_GPIO_LED_WLAN, + .active_low = 1, + } +}; + +static struct gpio_keys_button tew_632brp_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TEW_632BRP_KEYS_DEBOUNCE_INTERVAL, + .gpio = TEW_632BRP_GPIO_BTN_RESET, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = TEW_632BRP_KEYS_DEBOUNCE_INTERVAL, + .gpio = TEW_632BRP_GPIO_BTN_WPS, + } +}; + +#define TEW_632BRP_LAN_PHYMASK BIT(0) +#define TEW_632BRP_WAN_PHYMASK BIT(4) +#define TEW_632BRP_MDIO_MASK (~(TEW_632BRP_LAN_PHYMASK | \ + TEW_632BRP_WAN_PHYMASK)) + +static void __init tew_632brp_setup(void) +{ + const char *config = (char *) KSEG1ADDR(TEW_632BRP_CONFIG_ADDR); + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + u8 mac[6]; + u8 *wlan_mac = NULL; + + if (ath79_nvram_parse_mac_addr(config, TEW_632BRP_CONFIG_SIZE, + "lan_mac=", mac) == 0) { + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); + wlan_mac = mac; + } + + ath79_register_mdio(0, TEW_632BRP_MDIO_MASK); + + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth0_data.phy_mask = TEW_632BRP_LAN_PHYMASK; + + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth1_data.phy_mask = TEW_632BRP_WAN_PHYMASK; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_m25p80(NULL); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tew_632brp_leds_gpio), + tew_632brp_leds_gpio); + + ath79_register_gpio_keys_polled(-1, TEW_632BRP_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tew_632brp_gpio_keys), + tew_632brp_gpio_keys); + + ath79_register_wmac(eeprom, wlan_mac); +} + +MIPS_MACHINE(ATH79_MACH_TEW_632BRP, "TEW-632BRP", "TRENDnet TEW-632BRP", + tew_632brp_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-673gru.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-673gru.c new file mode 100644 index 000000000..207384f99 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-673gru.c @@ -0,0 +1,210 @@ +/* + * TRENDnet TEW-673GRU board support + * + * Copyright (C) 2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include +#include +#include + +#include + +#include "dev-ap9x-pci.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" + +#define TEW673GRU_GPIO_LCD_SCK 0 +#define TEW673GRU_GPIO_LCD_MOSI 1 +#define TEW673GRU_GPIO_LCD_MISO 2 +#define TEW673GRU_GPIO_LCD_CS 6 + +#define TEW673GRU_GPIO_LED_WPS 9 + +#define TEW673GRU_GPIO_BTN_RESET 3 +#define TEW673GRU_GPIO_BTN_WPS 8 + +#define TEW673GRU_GPIO_RTL8366_SDA 5 +#define TEW673GRU_GPIO_RTL8366_SCK 7 + +#define TEW673GRU_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TEW673GRU_KEYS_DEBOUNCE_INTERVAL (3 * TEW673GRU_KEYS_POLL_INTERVAL) + +#define TEW673GRU_CAL0_OFFSET 0x1000 +#define TEW673GRU_CAL1_OFFSET 0x5000 +#define TEW673GRU_MAC0_OFFSET 0xffa0 +#define TEW673GRU_MAC1_OFFSET 0xffb4 + +#define TEW673GRU_CAL_LOCATION_0 0x1f660000 +#define TEW673GRU_CAL_LOCATION_1 0x1f7f0000 + +static struct gpio_led tew673gru_leds_gpio[] __initdata = { + { + .name = "trendnet:blue:wps", + .gpio = TEW673GRU_GPIO_LED_WPS, + .active_low = 1, + } +}; + +static struct gpio_keys_button tew673gru_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TEW673GRU_KEYS_DEBOUNCE_INTERVAL, + .gpio = TEW673GRU_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = TEW673GRU_KEYS_DEBOUNCE_INTERVAL, + .gpio = TEW673GRU_GPIO_BTN_WPS, + .active_low = 1, + } +}; + +static struct rtl8366_initval tew673gru_rtl8366s_initvals[] = { + { .reg = 0x06, .val = 0x0108 }, +}; + +static struct rtl8366_platform_data tew673gru_rtl8366s_data = { + .gpio_sda = TEW673GRU_GPIO_RTL8366_SDA, + .gpio_sck = TEW673GRU_GPIO_RTL8366_SCK, + .num_initvals = ARRAY_SIZE(tew673gru_rtl8366s_initvals), + .initvals = tew673gru_rtl8366s_initvals, +}; + +static struct platform_device tew673gru_rtl8366s_device = { + .name = RTL8366S_DRIVER_NAME, + .id = -1, + .dev = { + .platform_data = &tew673gru_rtl8366s_data, + } +}; + +static struct spi_board_info tew673gru_spi_info[] = { + { + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 400000, + .modalias = "spidev", + .mode = SPI_MODE_2, + .controller_data = (void *) TEW673GRU_GPIO_LCD_CS, + }, +}; + +static struct spi_gpio_platform_data tew673gru_spi_data = { + .sck = TEW673GRU_GPIO_LCD_SCK, + .miso = TEW673GRU_GPIO_LCD_MISO, + .mosi = TEW673GRU_GPIO_LCD_MOSI, + .num_chipselect = 1, +}; + +static struct platform_device tew673gru_spi_device = { + .name = "spi_gpio", + .id = 1, + .dev = { + .platform_data = &tew673gru_spi_data, + }, +}; + +static void tew673gru_read_ascii_mac(u8 *dest, u8 *src) +{ + int ret; + + ret = sscanf(src, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", + &dest[0], &dest[1], &dest[2], + &dest[3], &dest[4], &dest[5]); + + if (ret != ETH_ALEN) + memset(dest, 0, ETH_ALEN); +} + +static bool __init tew673gru_is_caldata_valid(u8 *p) +{ + u16 *magic0, *magic1; + + magic0 = (u16 *)(p + TEW673GRU_CAL0_OFFSET); + magic1 = (u16 *)(p + TEW673GRU_CAL1_OFFSET); + + return (*magic0 == 0xa55a && *magic1 == 0xa55a); +} + +static void __init tew673gru_wlan_init(void) +{ + u8 mac1[ETH_ALEN], mac2[ETH_ALEN]; + u8 *caldata; + + caldata = (u8 *) KSEG1ADDR(TEW673GRU_CAL_LOCATION_0); + if (!tew673gru_is_caldata_valid(caldata)) { + caldata = (u8 *)KSEG1ADDR(TEW673GRU_CAL_LOCATION_1); + if (!tew673gru_is_caldata_valid(caldata)) { + pr_err("no calibration data found\n"); + return; + } + } + + tew673gru_read_ascii_mac(mac1, caldata + TEW673GRU_MAC0_OFFSET); + tew673gru_read_ascii_mac(mac2, caldata + TEW673GRU_MAC1_OFFSET); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 2); + ath79_init_mac(ath79_eth1_data.mac_addr, mac1, 3); + + ap9x_pci_setup_wmac_led_pin(0, 5); + ap9x_pci_setup_wmac_led_pin(1, 5); + + ap94_pci_init(caldata + TEW673GRU_CAL0_OFFSET, mac1, + caldata + TEW673GRU_CAL1_OFFSET, mac2); +} + +static void __init tew673gru_setup(void) +{ + tew673gru_wlan_init(); + + ath79_register_mdio(0, 0x0); + + ath79_eth0_data.mii_bus_dev = &tew673gru_rtl8366s_device.dev; + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_eth0_pll_data.pll_1000 = 0x11110000; + + ath79_eth1_data.mii_bus_dev = &tew673gru_rtl8366s_device.dev; + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth1_data.phy_mask = 0x10; + ath79_eth1_pll_data.pll_1000 = 0x11110000; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_m25p80(NULL); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tew673gru_leds_gpio), + tew673gru_leds_gpio); + + ath79_register_gpio_keys_polled(-1, TEW673GRU_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tew673gru_gpio_keys), + tew673gru_gpio_keys); + + ath79_register_usb(); + + platform_device_register(&tew673gru_rtl8366s_device); + + spi_register_board_info(tew673gru_spi_info, + ARRAY_SIZE(tew673gru_spi_info)); + platform_device_register(&tew673gru_spi_device); +} + +MIPS_MACHINE(ATH79_MACH_TEW_673GRU, "TEW-673GRU", "TRENDnet TEW-673GRU", + tew673gru_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-712br.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-712br.c new file mode 100644 index 000000000..b0bc51bfe --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tew-712br.c @@ -0,0 +1,163 @@ +/* + * TRENDnet TEW-712BR board support + * + * Copyright (C) 2012 Gabor Juhos + * + * This program 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. + */ + +#include + +#include +#include + +#include "common.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define TEW_712BR_GPIO_BTN_WPS 11 +#define TEW_712BR_GPIO_BTN_RESET 12 + +#define TEW_712BR_GPIO_LED_LAN1 13 +#define TEW_712BR_GPIO_LED_LAN2 14 +#define TEW_712BR_GPIO_LED_LAN3 15 +#define TEW_712BR_GPIO_LED_LAN4 16 +#define TEW_712BR_GPIO_LED_POWER_GREEN 20 +#define TEW_712BR_GPIO_LED_POWER_ORANGE 27 +#define TEW_712BR_GPIO_LED_WAN_GREEN 17 +#define TEW_712BR_GPIO_LED_WAN_ORANGE 23 +#define TEW_712BR_GPIO_LED_WLAN 0 +#define TEW_712BR_GPIO_LED_WPS 26 + +#define TEW_712BR_GPIO_WAN_LED_ENABLE 1 + +#define TEW_712BR_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TEW_712BR_KEYS_DEBOUNCE_INTERVAL (3 * TEW_712BR_KEYS_POLL_INTERVAL) + +#define TEW_712BR_ART_ADDRESS 0x1f010000 +#define TEW_712BR_CALDATA_OFFSET 0x1000 +#define TEW_712BR_LAN_MAC_ADDRESS 0x1f020004 +#define TEW_712BR_WAN_MAC_ADDRESS 0x1f020016 + +static struct gpio_led tew_712br_leds_gpio[] __initdata = { + { + .name = "trendnet:green:lan1", + .gpio = TEW_712BR_GPIO_LED_LAN1, + .active_low = 0, + }, { + .name = "trendnet:green:lan2", + .gpio = TEW_712BR_GPIO_LED_LAN2, + .active_low = 0, + }, { + .name = "trendnet:green:lan3", + .gpio = TEW_712BR_GPIO_LED_LAN3, + .active_low = 0, + }, { + .name = "trendnet:green:lan4", + .gpio = TEW_712BR_GPIO_LED_LAN4, + .active_low = 0, + }, { + .name = "trendnet:blue:wps", + .gpio = TEW_712BR_GPIO_LED_WPS, + .active_low = 1, + }, { + .name = "trendnet:green:power", + .gpio = TEW_712BR_GPIO_LED_POWER_GREEN, + .active_low = 0, + }, { + .name = "trendnet:orange:power", + .gpio = TEW_712BR_GPIO_LED_POWER_ORANGE, + .active_low = 0, + }, { + .name = "trendnet:green:wan", + .gpio = TEW_712BR_GPIO_LED_WAN_GREEN, + .active_low = 1, + }, { + .name = "trendnet:orange:wan", + .gpio = TEW_712BR_GPIO_LED_WAN_ORANGE, + .active_low = 0, + }, { + .name = "trendnet:green:wlan", + .gpio = TEW_712BR_GPIO_LED_WLAN, + .active_low = 0, + }, +}; + +static struct gpio_keys_button tew_712br_gpio_keys[] __initdata = { + { + .desc = "Reset button", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TEW_712BR_KEYS_DEBOUNCE_INTERVAL, + .gpio = TEW_712BR_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "WPS button", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = TEW_712BR_KEYS_DEBOUNCE_INTERVAL, + .gpio = TEW_712BR_GPIO_BTN_WPS, + .active_low = 1, + } +}; + +static void __init tew_712br_read_ascii_mac(u8 *dest, unsigned int src_addr) +{ + int ret; + u8 *src = (u8 *)KSEG1ADDR(src_addr); + + ret = sscanf(src, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", + &dest[0], &dest[1], &dest[2], + &dest[3], &dest[4], &dest[5]); + + if (ret != ETH_ALEN) + memset(dest, 0, ETH_ALEN); +} + +static void __init tew_712br_setup(void) +{ + u8 *art = (u8 *) KSEG1ADDR(TEW_712BR_ART_ADDRESS); + u8 lan_mac[ETH_ALEN]; + u8 wan_mac[ETH_ALEN]; + + ath79_setup_ar933x_phy4_switch(false, false); + + ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + + gpio_request_one(TEW_712BR_GPIO_WAN_LED_ENABLE, + GPIOF_OUT_INIT_LOW, "WAN LED enable"); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tew_712br_leds_gpio), + tew_712br_leds_gpio); + + ath79_register_gpio_keys_polled(1, TEW_712BR_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tew_712br_gpio_keys), + tew_712br_gpio_keys); + + ath79_register_m25p80(NULL); + + tew_712br_read_ascii_mac(lan_mac, TEW_712BR_LAN_MAC_ADDRESS); + tew_712br_read_ascii_mac(wan_mac, TEW_712BR_WAN_MAC_ADDRESS); + + ath79_init_mac(ath79_eth0_data.mac_addr, wan_mac, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, lan_mac, 0); + + ath79_register_mdio(0, 0x0); + ath79_register_eth(1); + ath79_register_eth(0); + + ath79_register_wmac(art + TEW_712BR_CALDATA_OFFSET, wan_mac); +} + +MIPS_MACHINE(ATH79_MACH_TEW_712BR, "TEW-712BR", + "TRENDnet TEW-712BR", tew_712br_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr11u.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr11u.c new file mode 100644 index 000000000..6b2820711 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr11u.c @@ -0,0 +1,130 @@ +/* + * TP-LINK TL-MR11U/TL-MR3040 board support + * + * Copyright (C) 2011 dongyuqi <729650915@qq.com> + * Copyright (C) 2011-2012 Gabor Juhos + * + * This program 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. + */ + +#include + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define TL_MR11U_GPIO_LED_3G 27 +#define TL_MR11U_GPIO_LED_WLAN 26 +#define TL_MR11U_GPIO_LED_LAN 17 + +#define TL_MR11U_GPIO_BTN_WPS 20 +#define TL_MR11U_GPIO_BTN_RESET 11 + +#define TL_MR11U_GPIO_USB_POWER 8 +#define TL_MR3040_GPIO_USB_POWER 18 + +#define TL_MR11U_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TL_MR11U_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR11U_KEYS_POLL_INTERVAL) + +static const char *tl_mr11u_part_probes[] = { + "tp-link", + NULL, +}; + +static struct flash_platform_data tl_mr11u_flash_data = { + .part_probes = tl_mr11u_part_probes, +}; + +static struct gpio_led tl_mr11u_leds_gpio[] __initdata = { + { + .name = "tp-link:green:3g", + .gpio = TL_MR11U_GPIO_LED_3G, + .active_low = 1, + }, + { + .name = "tp-link:green:wlan", + .gpio = TL_MR11U_GPIO_LED_WLAN, + .active_low = 1, + }, + { + .name = "tp-link:green:lan", + .gpio = TL_MR11U_GPIO_LED_LAN, + .active_low = 1, + } +}; + +static struct gpio_keys_button tl_mr11u_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TL_MR11U_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_MR11U_GPIO_BTN_RESET, + .active_low = 0, + }, + { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = TL_MR11U_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_MR11U_GPIO_BTN_WPS, + .active_low = 0, + }, +}; + +static void __init common_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_setup_ar933x_phy4_switch(false, true); + + ath79_register_m25p80(&tl_mr11u_flash_data); + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_mr11u_leds_gpio), + tl_mr11u_leds_gpio); + + ath79_register_usb(); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + + ath79_register_mdio(0, 0x0); + ath79_register_eth(0); + ath79_eth0_data.phy_mask = BIT(0); + + ath79_register_wmac(ee, mac); +} + +static void __init tl_mr11u_setup(void) +{ + common_setup(); + + ath79_register_gpio_keys_polled(-1, TL_MR11U_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tl_mr11u_gpio_keys), + tl_mr11u_gpio_keys); + ath79_set_usb_power_gpio(TL_MR11U_GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH, + "USB power"); +} + +MIPS_MACHINE(ATH79_MACH_TL_MR11U, "TL-MR11U", "TP-LINK TL-MR11U", + tl_mr11u_setup); + +static void __init tl_mr3040_setup(void) +{ + common_setup(); + + ath79_register_gpio_keys_polled(-1, TL_MR11U_KEYS_POLL_INTERVAL, + 1, tl_mr11u_gpio_keys); + ath79_set_usb_power_gpio(TL_MR3040_GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH, + "USB power"); +} + +MIPS_MACHINE(ATH79_MACH_TL_MR3040, "TL-MR3040", "TP-LINK TL-MR3040", + tl_mr3040_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3020.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3020.c new file mode 100644 index 000000000..8f37d7a87 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3020.c @@ -0,0 +1,125 @@ +/* + * TP-LINK TL-MR3020 board support + * + * Copyright (C) 2011 dongyuqi <729650915@qq.com> + * Copyright (C) 2011-2012 Gabor Juhos + * + * This program 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. + */ + +#include + +#include +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define TL_MR3020_GPIO_LED_3G 27 +#define TL_MR3020_GPIO_LED_WLAN 0 +#define TL_MR3020_GPIO_LED_LAN 17 +#define TL_MR3020_GPIO_LED_WPS 26 + +#define TL_MR3020_GPIO_BTN_WPS 11 +#define TL_MR3020_GPIO_BTN_SW1 18 +#define TL_MR3020_GPIO_BTN_SW2 20 + +#define TL_MR3020_GPIO_USB_POWER 8 + +#define TL_MR3020_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TL_MR3020_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR3020_KEYS_POLL_INTERVAL) + +static const char *tl_mr3020_part_probes[] = { + "tp-link", + NULL, +}; + +static struct flash_platform_data tl_mr3020_flash_data = { + .part_probes = tl_mr3020_part_probes, +}; + +static struct gpio_led tl_mr3020_leds_gpio[] __initdata = { + { + .name = "tp-link:green:3g", + .gpio = TL_MR3020_GPIO_LED_3G, + .active_low = 1, + }, + { + .name = "tp-link:green:wlan", + .gpio = TL_MR3020_GPIO_LED_WLAN, + .active_low = 0, + }, + { + .name = "tp-link:green:lan", + .gpio = TL_MR3020_GPIO_LED_LAN, + .active_low = 1, + }, + { + .name = "tp-link:green:wps", + .gpio = TL_MR3020_GPIO_LED_WPS, + .active_low = 1, + }, +}; + +static struct gpio_keys_button tl_mr3020_gpio_keys[] __initdata = { + { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = TL_MR3020_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_MR3020_GPIO_BTN_WPS, + .active_low = 0, + }, + { + .desc = "sw1", + .type = EV_KEY, + .code = BTN_0, + .debounce_interval = TL_MR3020_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_MR3020_GPIO_BTN_SW1, + .active_low = 0, + }, + { + .desc = "sw2", + .type = EV_KEY, + .code = BTN_1, + .debounce_interval = TL_MR3020_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_MR3020_GPIO_BTN_SW2, + .active_low = 0, + } +}; + +static void __init tl_mr3020_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_setup_ar933x_phy4_switch(false, true); + + ath79_register_m25p80(&tl_mr3020_flash_data); + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_mr3020_leds_gpio), + tl_mr3020_leds_gpio); + ath79_register_gpio_keys_polled(-1, TL_MR3020_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tl_mr3020_gpio_keys), + tl_mr3020_gpio_keys); + + ath79_set_usb_power_gpio(TL_MR3020_GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH, + "USB power"); + ath79_register_usb(); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + + ath79_register_mdio(0, 0x0); + ath79_register_eth(0); + ath79_eth0_data.phy_mask = BIT(0); + ath79_register_wmac(ee, mac); +} + +MIPS_MACHINE(ATH79_MACH_TL_MR3020, "TL-MR3020", "TP-LINK TL-MR3020", + tl_mr3020_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c new file mode 100644 index 000000000..b35f09f8a --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c @@ -0,0 +1,146 @@ +/* + * TP-LINK TL-MR3220/3420 board support + * + * Copyright (C) 2010-2012 Gabor Juhos + * + * This program 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. + */ + +#include + +#include + +#include "dev-eth.h" +#include "dev-ap9x-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" + +#define TL_MR3X20_GPIO_LED_QSS 0 +#define TL_MR3X20_GPIO_LED_SYSTEM 1 +#define TL_MR3X20_GPIO_LED_3G 8 + +#define TL_MR3X20_GPIO_BTN_RESET 11 +#define TL_MR3X20_GPIO_BTN_QSS 12 + +#define TL_MR3X20_GPIO_USB_POWER 6 + +#define TL_MR3X20_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TL_MR3X20_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR3X20_KEYS_POLL_INTERVAL) + +static const char *tl_mr3x20_part_probes[] = { + "tp-link", + NULL, +}; + +static struct flash_platform_data tl_mr3x20_flash_data = { + .part_probes = tl_mr3x20_part_probes, +}; + +static struct gpio_led tl_mr3x20_leds_gpio[] __initdata = { + { + .name = "tp-link:green:system", + .gpio = TL_MR3X20_GPIO_LED_SYSTEM, + .active_low = 1, + }, { + .name = "tp-link:green:qss", + .gpio = TL_MR3X20_GPIO_LED_QSS, + .active_low = 1, + }, { + .name = "tp-link:green:3g", + .gpio = TL_MR3X20_GPIO_LED_3G, + .active_low = 1, + } +}; + +static struct gpio_keys_button tl_mr3x20_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TL_MR3X20_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_MR3X20_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "qss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = TL_MR3X20_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_MR3X20_GPIO_BTN_QSS, + .active_low = 1, + } +}; + +static void __init tl_ap99_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_register_m25p80(&tl_mr3x20_flash_data); + + ath79_register_gpio_keys_polled(-1, TL_MR3X20_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tl_mr3x20_gpio_keys), + tl_mr3x20_gpio_keys); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); + ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); + + ath79_register_mdio(0, 0x0); + + /* LAN ports */ + ath79_register_eth(1); + /* WAN port */ + ath79_register_eth(0); + + ap91_pci_init(ee, mac); +} + +static void __init tl_mr3x20_usb_setup(void) +{ + /* enable power for the USB port */ + ath79_set_usb_power_gpio(TL_MR3X20_GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH, + "USB power"); + ath79_register_usb(); +} + +static void __init tl_mr3220_setup(void) +{ + tl_ap99_setup(); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_mr3x20_leds_gpio), + tl_mr3x20_leds_gpio); + ap9x_pci_setup_wmac_led_pin(0, 1); + tl_mr3x20_usb_setup(); +} + +MIPS_MACHINE(ATH79_MACH_TL_MR3220, "TL-MR3220", "TP-LINK TL-MR3220", + tl_mr3220_setup); + +static void __init tl_mr3420_setup(void) +{ + tl_ap99_setup(); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_mr3x20_leds_gpio), + tl_mr3x20_leds_gpio); + ap9x_pci_setup_wmac_led_pin(0, 0); + tl_mr3x20_usb_setup(); +} + +MIPS_MACHINE(ATH79_MACH_TL_MR3420, "TL-MR3420", "TP-LINK TL-MR3420", + tl_mr3420_setup); + +static void __init tl_wr841n_v7_setup(void) +{ + tl_ap99_setup(); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_mr3x20_leds_gpio) - 1, + tl_mr3x20_leds_gpio); + ap9x_pci_setup_wmac_led_pin(0, 0); +} + +MIPS_MACHINE(ATH79_MACH_TL_WR841N_V7, "TL-WR841N-v7", + "TP-LINK TL-WR841N/ND v7", tl_wr841n_v7_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd-v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd-v2.c new file mode 100644 index 000000000..b4fb2a9f9 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd-v2.c @@ -0,0 +1,104 @@ +/* + * TP-LINK TL-WA901N/ND v2 board support + * + * Copyright (C) 2009-2012 Gabor Juhos + * Copyright (C) 2010 Pieter Hollants + * Copyright (C) 2011 Jonathan Bennett + * + * This program 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. + */ + +#include +#include + +#include "dev-eth.h" +#include "dev-m25p80.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define TL_WA901ND_V2_GPIO_LED_QSS 4 +#define TL_WA901ND_V2_GPIO_LED_SYSTEM 2 +#define TL_WA901ND_V2_GPIO_LED_WLAN 9 + +#define TL_WA901ND_V2_GPIO_BTN_RESET 3 +#define TL_WA901ND_V2_GPIO_BTN_QSS 7 + +#define TL_WA901ND_V2_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL \ + (3 * TL_WA901ND_V2_KEYS_POLL_INTERVAL) + +static const char *tl_wa901nd_v2_part_probes[] = { + "tp-link", + NULL, +}; + +static struct flash_platform_data tl_wa901nd_v2_flash_data = { + .part_probes = tl_wa901nd_v2_part_probes, +}; + +static struct gpio_led tl_wa901nd_v2_leds_gpio[] __initdata = { + { + .name = "tp-link:green:system", + .gpio = TL_WA901ND_V2_GPIO_LED_SYSTEM, + .active_low = 1, + }, { + .name = "tp-link:green:qss", + .gpio = TL_WA901ND_V2_GPIO_LED_QSS, + }, { + .name = "tp-link:green:wlan", + .gpio = TL_WA901ND_V2_GPIO_LED_WLAN, + .active_low = 1, + } +}; + +static struct gpio_keys_button tl_wa901nd_v2_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WA901ND_V2_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "qss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = TL_WA901ND_V2_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WA901ND_V2_GPIO_BTN_QSS, + .active_low = 1, + } +}; + +static void __init tl_wa901nd_v2_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; + ath79_eth0_data.phy_mask = 0x00001000; + ath79_register_mdio(0, 0x0); + + ath79_eth0_data.reset_bit = AR71XX_RESET_GE0_MAC | + AR71XX_RESET_GE0_PHY; + ath79_register_eth(0); + + ath79_register_m25p80(&tl_wa901nd_v2_flash_data); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa901nd_v2_leds_gpio), + tl_wa901nd_v2_leds_gpio); + + ath79_register_gpio_keys_polled(-1, TL_WA901ND_V2_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tl_wa901nd_v2_gpio_keys), + tl_wa901nd_v2_gpio_keys); + + ath79_register_wmac(eeprom, mac); +} + +MIPS_MACHINE(ATH79_MACH_TL_WA901ND_V2, "TL-WA901ND-v2", + "TP-LINK TL-WA901ND v2", tl_wa901nd_v2_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd.c new file mode 100644 index 000000000..2f4e0c047 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wa901nd.c @@ -0,0 +1,109 @@ +/* + * TP-LINK TL-WA901N/ND v1 board support + * + * Copyright (C) 2009-2012 Gabor Juhos + * Copyright (C) 2010 Pieter Hollants + * + * This program 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. + */ + +#include +#include + +#include "common.h" +#include "dev-ap9x-pci.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "machtypes.h" + +#define TL_WA901ND_GPIO_LED_QSS 0 +#define TL_WA901ND_GPIO_LED_SYSTEM 1 +#define TL_WA901ND_GPIO_LED_LAN 13 + +#define TL_WA901ND_GPIO_BTN_RESET 11 +#define TL_WA901ND_GPIO_BTN_QSS 12 + +#define TL_WA901ND_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TL_WA901ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WA901ND_KEYS_POLL_INTERVAL) + +static const char *tl_wa901nd_part_probes[] = { + "tp-link", + NULL, +}; + +static struct flash_platform_data tl_wa901nd_flash_data = { + .part_probes = tl_wa901nd_part_probes, +}; + +static struct gpio_led tl_wa901nd_leds_gpio[] __initdata = { + { + .name = "tp-link:green:lan", + .gpio = TL_WA901ND_GPIO_LED_LAN, + .active_low = 1, + }, { + .name = "tp-link:green:system", + .gpio = TL_WA901ND_GPIO_LED_SYSTEM, + .active_low = 1, + }, { + .name = "tp-link:green:qss", + .gpio = TL_WA901ND_GPIO_LED_QSS, + .active_low = 1, + } +}; + +static struct gpio_keys_button tl_wa901nd_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = BTN_0, + .debounce_interval = TL_WA901ND_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WA901ND_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "qss", + .type = EV_KEY, + .code = BTN_1, + .debounce_interval = TL_WA901ND_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WA901ND_GPIO_BTN_QSS, + .active_low = 1, + } +}; + +static void __init tl_wa901nd_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + + /* + * ath79_eth0 would be the WAN port, but is not connected on + * the TL-WA901ND. ath79_eth1 connects to the internal switch chip, + * however we have a single LAN port only. + */ + ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); + ath79_register_mdio(0, 0x0); + ath79_register_eth(1); + + ath79_register_m25p80(&tl_wa901nd_flash_data); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wa901nd_leds_gpio), + tl_wa901nd_leds_gpio); + + ath79_register_gpio_keys_polled(-1, TL_WA901ND_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tl_wa901nd_gpio_keys), + tl_wa901nd_gpio_keys); + + ap91_pci_init(ee, mac); +} + +MIPS_MACHINE(ATH79_MACH_TL_WA901ND, "TL-WA901ND", "TP-LINK TL-WA901ND", + tl_wa901nd_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr4300.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr4300.c new file mode 100644 index 000000000..331de5680 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr4300.c @@ -0,0 +1,204 @@ +/* + * TP-LINK TL-WDR4300 board support + * + * Copyright (C) 2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "dev-ap9x-pci.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-spi.h" +#include "dev-usb.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define WDR4300_GPIO_LED_USB1 11 +#define WDR4300_GPIO_LED_USB2 12 +#define WDR4300_GPIO_LED_WLAN2G 13 +#define WDR4300_GPIO_LED_SYSTEM 14 +#define WDR4300_GPIO_LED_QSS 15 + +#define WDR4300_GPIO_BTN_WPS 16 +#define WDR4300_GPIO_BTN_RFKILL 17 + +#define WDR4300_GPIO_USB1_POWER 22 +#define WDR4300_GPIO_USB2_POWER 21 + +#define WDR4300_KEYS_POLL_INTERVAL 20 /* msecs */ +#define WDR4300_KEYS_DEBOUNCE_INTERVAL (3 * WDR4300_KEYS_POLL_INTERVAL) + +#define WDR4300_MAC0_OFFSET 0 +#define WDR4300_MAC1_OFFSET 6 +#define WDR4300_WMAC_CALDATA_OFFSET 0x1000 +#define WDR4300_PCIE_CALDATA_OFFSET 0x5000 + +static const char *wdr4300_part_probes[] = { + "tp-link", + NULL, +}; + +static struct flash_platform_data wdr4300_flash_data = { + .part_probes = wdr4300_part_probes, +}; + +static struct gpio_led wdr4300_leds_gpio[] __initdata = { + { + .name = "tp-link:blue:qss", + .gpio = WDR4300_GPIO_LED_QSS, + .active_low = 1, + }, + { + .name = "tp-link:blue:system", + .gpio = WDR4300_GPIO_LED_SYSTEM, + .active_low = 1, + }, + { + .name = "tp-link:green:usb1", + .gpio = WDR4300_GPIO_LED_USB1, + .active_low = 1, + }, + { + .name = "tp-link:green:usb2", + .gpio = WDR4300_GPIO_LED_USB2, + .active_low = 1, + }, + { + .name = "tp-link:blue:wlan2g", + .gpio = WDR4300_GPIO_LED_WLAN2G, + .active_low = 1, + }, +}; + +static struct gpio_keys_button wdr4300_gpio_keys[] __initdata = { + { + .desc = "QSS button", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = WDR4300_KEYS_DEBOUNCE_INTERVAL, + .gpio = WDR4300_GPIO_BTN_WPS, + .active_low = 1, + }, + { + .desc = "RFKILL switch", + .type = EV_SW, + .code = KEY_RFKILL, + .debounce_interval = WDR4300_KEYS_DEBOUNCE_INTERVAL, + .gpio = WDR4300_GPIO_BTN_RFKILL, + }, +}; + +static struct ar8327_pad_cfg wdr4300_ar8327_pad0_cfg = { + .mode = AR8327_PAD_MAC_RGMII, + .txclk_delay_en = true, + .rxclk_delay_en = true, + .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, + .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, +}; + +static struct ar8327_led_cfg wdr4300_ar8327_led_cfg = { + .led_ctrl0 = 0xc737c737, + .led_ctrl1 = 0x00000000, + .led_ctrl2 = 0x00000000, + .led_ctrl3 = 0x0030c300, + .open_drain = false, +}; + +static struct ar8327_platform_data wdr4300_ar8327_data = { + .pad0_cfg = &wdr4300_ar8327_pad0_cfg, + .cpuport_cfg = { + .force_link = 1, + .speed = AR8327_PORT_SPEED_1000, + .duplex = 1, + .txpause = 1, + .rxpause = 1, + }, + .led_cfg = &wdr4300_ar8327_led_cfg, +}; + +static struct mdio_board_info wdr4300_mdio0_info[] = { + { + .bus_id = "ag71xx-mdio.0", + .phy_addr = 0, + .platform_data = &wdr4300_ar8327_data, + }, +}; + +static void __init wdr4300_gmac_setup(void) +{ + void __iomem *base; + u32 t; + + base = ioremap(AR934X_GMAC_BASE, AR934X_GMAC_SIZE); + + t = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); + t &= ~(AR934X_ETH_CFG_RGMII_GMAC0 | AR934X_ETH_CFG_MII_GMAC0 | + AR934X_ETH_CFG_GMII_GMAC0 | AR934X_ETH_CFG_SW_ONLY_MODE); + t |= AR934X_ETH_CFG_RGMII_GMAC0; + + __raw_writel(t, base + AR934X_GMAC_REG_ETH_CFG); + + iounmap(base); +} + +static void __init wdr4300_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + u8 tmpmac[ETH_ALEN]; + + ath79_register_m25p80(&wdr4300_flash_data); + ath79_register_leds_gpio(-1, ARRAY_SIZE(wdr4300_leds_gpio), + wdr4300_leds_gpio); + ath79_register_gpio_keys_polled(-1, WDR4300_KEYS_POLL_INTERVAL, + ARRAY_SIZE(wdr4300_gpio_keys), + wdr4300_gpio_keys); + + ath79_init_mac(tmpmac, mac, -1); + ath79_register_wmac(art + WDR4300_WMAC_CALDATA_OFFSET, tmpmac); + + ath79_init_mac(tmpmac, mac, 0); + ap9x_pci_setup_wmac_led_pin(0, 0); + ap91_pci_init(art + WDR4300_PCIE_CALDATA_OFFSET, tmpmac); + + wdr4300_gmac_setup(); + + mdiobus_register_board_info(wdr4300_mdio0_info, + ARRAY_SIZE(wdr4300_mdio0_info)); + + ath79_register_mdio(0, 0x0); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, -2); + + /* GMAC0 is connected to an AR8327N switch */ + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.phy_mask = BIT(0); + ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; + ath79_eth0_pll_data.pll_1000 = 0x06000000; + ath79_register_eth(0); + + ath79_set_usb_power_gpio(WDR4300_GPIO_USB1_POWER, GPIOF_OUT_INIT_HIGH, + "USB1 power"); + ath79_set_usb_power_gpio(WDR4300_GPIO_USB2_POWER, GPIOF_OUT_INIT_HIGH, + "USB2 power"); + ath79_register_usb(); +} + +MIPS_MACHINE(ATH79_MACH_TL_WDR4300, "TL-WDR4300", + "TP-LINK TL-WDR3600/4300/4310", + wdr4300_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1041n-v2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1041n-v2.c new file mode 100644 index 000000000..ed5b2b0e6 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1041n-v2.c @@ -0,0 +1,154 @@ +/* + * TP-LINK TL-WR1041 v2 board support + * + * Copyright (C) 2010-2012 Gabor Juhos + * Copyright (C) 2011-2012 Anan Huang + * + * This program 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. + */ + +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "dev-ap9x-pci.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-spi.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define TL_WR1041NV2_GPIO_BTN_RESET 14 +#define TL_WR1041NV2_GPIO_LED_WPS 13 +#define TL_WR1041NV2_GPIO_LED_WLAN 11 + +#define TL_WR1041NV2_GPIO_LED_SYSTEM 12 + +#define TL_WR1041NV2_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TL_WR1041NV2_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR1041NV2_KEYS_POLL_INTERVAL) + +#define TL_WR1041NV2_PCIE_CALDATA_OFFSET 0x5000 + +static const char *tl_wr1041nv2_part_probes[] = { + "tp-link", + NULL, +}; + +static struct flash_platform_data tl_wr1041nv2_flash_data = { + .part_probes = tl_wr1041nv2_part_probes, +}; + +static struct gpio_led tl_wr1041nv2_leds_gpio[] __initdata = { + { + .name = "tp-link:green:system", + .gpio = TL_WR1041NV2_GPIO_LED_SYSTEM, + .active_low = 1, + }, { + .name = "tp-link:green:wps", + .gpio = TL_WR1041NV2_GPIO_LED_WPS, + .active_low = 1, + }, { + .name = "tp-link:green:wlan", + .gpio = TL_WR1041NV2_GPIO_LED_WLAN, + .active_low = 1, + } +}; + +static struct gpio_keys_button tl_wr1041nv2_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TL_WR1041NV2_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR1041NV2_GPIO_BTN_RESET, + .active_low = 1, + } +}; + +static struct ar8327_pad_cfg db120_ar8327_pad0_cfg = { + .mode = AR8327_PAD_MAC_RGMII, + .txclk_delay_en = true, + .rxclk_delay_en = true, + .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, + .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, +}; + +static struct ar8327_platform_data db120_ar8327_data = { + .pad0_cfg = &db120_ar8327_pad0_cfg, + .cpuport_cfg = { + .force_link = 1, + .speed = AR8327_PORT_SPEED_1000, + .duplex = 1, + .txpause = 1, + .rxpause = 1, + } +}; + +static struct mdio_board_info db120_mdio0_info[] = { + { + .bus_id = "ag71xx-mdio.0", + .phy_addr = 0, + .platform_data = &db120_ar8327_data, + }, +}; + +static void __init db120_gmac_setup(void) +{ + void __iomem *base; + u32 t; + + base = ioremap(AR934X_GMAC_BASE, AR934X_GMAC_SIZE); + + t = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); + t &= ~(AR934X_ETH_CFG_RGMII_GMAC0 | AR934X_ETH_CFG_MII_GMAC0 | + AR934X_ETH_CFG_GMII_GMAC0 | AR934X_ETH_CFG_SW_ONLY_MODE); + t |= AR934X_ETH_CFG_RGMII_GMAC0 | AR934X_ETH_CFG_SW_ONLY_MODE; + + __raw_writel(t, base + AR934X_GMAC_REG_ETH_CFG); + + iounmap(base); +} + +static void __init tl_wr1041nv2_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_register_m25p80(&tl_wr1041nv2_flash_data); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr1041nv2_leds_gpio), + tl_wr1041nv2_leds_gpio); + ath79_register_gpio_keys_polled(-1, TL_WR1041NV2_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tl_wr1041nv2_gpio_keys), + tl_wr1041nv2_gpio_keys); + ath79_register_wmac(ee, mac); + + db120_gmac_setup(); + + ath79_register_mdio(1, 0x0); + ath79_register_mdio(0, 0x0); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); + + mdiobus_register_board_info(db120_mdio0_info, + ARRAY_SIZE(db120_mdio0_info)); + + /* GMAC0 is connected to an AR8327 switch */ + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.phy_mask = BIT(0); + ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; + ath79_eth0_pll_data.pll_1000 = 0x06000000; + ath79_register_eth(0); +} + +MIPS_MACHINE(ATH79_MACH_TL_WR1041N_V2, "TL-WR1041N-v2", + "TP-LINK TL-WR1041N v2", tl_wr1041nv2_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd.c new file mode 100644 index 000000000..61aeb52d0 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr1043nd.c @@ -0,0 +1,141 @@ +/* + * TP-LINK TL-WR1043N/ND board support + * + * Copyright (C) 2009-2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include + +#include +#include + +#include "dev-eth.h" +#include "dev-m25p80.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-usb.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define TL_WR1043ND_GPIO_LED_USB 1 +#define TL_WR1043ND_GPIO_LED_SYSTEM 2 +#define TL_WR1043ND_GPIO_LED_QSS 5 +#define TL_WR1043ND_GPIO_LED_WLAN 9 + +#define TL_WR1043ND_GPIO_BTN_RESET 3 +#define TL_WR1043ND_GPIO_BTN_QSS 7 + +#define TL_WR1043ND_GPIO_RTL8366_SDA 18 +#define TL_WR1043ND_GPIO_RTL8366_SCK 19 + +#define TL_WR1043ND_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR1043ND_KEYS_POLL_INTERVAL) + +static const char *tl_wr1043nd_part_probes[] = { + "tp-link", + NULL, +}; + +static struct flash_platform_data tl_wr1043nd_flash_data = { + .part_probes = tl_wr1043nd_part_probes, +}; + +static struct gpio_led tl_wr1043nd_leds_gpio[] __initdata = { + { + .name = "tp-link:green:usb", + .gpio = TL_WR1043ND_GPIO_LED_USB, + .active_low = 1, + }, { + .name = "tp-link:green:system", + .gpio = TL_WR1043ND_GPIO_LED_SYSTEM, + .active_low = 1, + }, { + .name = "tp-link:green:qss", + .gpio = TL_WR1043ND_GPIO_LED_QSS, + .active_low = 0, + }, { + .name = "tp-link:green:wlan", + .gpio = TL_WR1043ND_GPIO_LED_WLAN, + .active_low = 1, + } +}; + +static struct gpio_keys_button tl_wr1043nd_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR1043ND_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "qss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = TL_WR1043ND_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR1043ND_GPIO_BTN_QSS, + .active_low = 1, + } +}; + +static void tl_wr1043nd_rtl8366rb_hw_reset(bool active) +{ + if (active) + ath79_device_reset_set(AR71XX_RESET_GE0_PHY); + else + ath79_device_reset_clear(AR71XX_RESET_GE0_PHY); +} + +static struct rtl8366_platform_data tl_wr1043nd_rtl8366rb_data = { + .gpio_sda = TL_WR1043ND_GPIO_RTL8366_SDA, + .gpio_sck = TL_WR1043ND_GPIO_RTL8366_SCK, + .hw_reset = tl_wr1043nd_rtl8366rb_hw_reset, +}; + +static struct platform_device tl_wr1043nd_rtl8366rb_device = { + .name = RTL8366RB_DRIVER_NAME, + .id = -1, + .dev = { + .platform_data = &tl_wr1043nd_rtl8366rb_data, + } +}; + +static void __init tl_wr1043nd_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + + tl_wr1043nd_rtl8366rb_hw_reset(true); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_eth0_data.mii_bus_dev = &tl_wr1043nd_rtl8366rb_device.dev; + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_eth0_pll_data.pll_1000 = 0x1a000000; + + ath79_register_eth(0); + + ath79_register_usb(); + + ath79_register_m25p80(&tl_wr1043nd_flash_data); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr1043nd_leds_gpio), + tl_wr1043nd_leds_gpio); + + platform_device_register(&tl_wr1043nd_rtl8366rb_device); + + ath79_register_gpio_keys_polled(-1, TL_WR1043ND_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tl_wr1043nd_gpio_keys), + tl_wr1043nd_gpio_keys); + + ath79_register_wmac(eeprom, mac); +} + +MIPS_MACHINE(ATH79_MACH_TL_WR1043ND, "TL-WR1043ND", "TP-LINK TL-WR1043ND", + tl_wr1043nd_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr2543n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr2543n.c new file mode 100644 index 000000000..8f6db5eda --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr2543n.c @@ -0,0 +1,156 @@ +/* + * TP-LINK TL-WR2543N/ND board support + * + * Copyright (C) 2011-2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include + +#include + +#include "dev-eth.h" +#include "dev-ap9x-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" + +#define TL_WR2543N_GPIO_LED_WPS 0 +#define TL_WR2543N_GPIO_LED_USB 8 + +/* The WLAN LEDs use GPIOs on the discrete AR9380 wmac */ +#define TL_WR2543N_GPIO_WMAC_LED_WLAN2G 0 +#define TL_WR2543N_GPIO_WMAC_LED_WLAN5G 1 + +#define TL_WR2543N_GPIO_BTN_RESET 11 +#define TL_WR2543N_GPIO_BTN_WPS 12 + +#define TL_WR2543N_GPIO_RTL8367_SDA 1 +#define TL_WR2543N_GPIO_RTL8367_SCK 6 + +#define TL_WR2543N_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TL_WR2543N_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR2543N_KEYS_POLL_INTERVAL) + +static const char *tl_wr2543n_part_probes[] = { + "tp-link", + NULL, +}; + +static struct flash_platform_data tl_wr2543n_flash_data = { + .part_probes = tl_wr2543n_part_probes, +}; + +static struct gpio_led tl_wr2543n_leds_gpio[] __initdata = { + { + .name = "tp-link:green:usb", + .gpio = TL_WR2543N_GPIO_LED_USB, + .active_low = 1, + }, { + .name = "tp-link:green:wps", + .gpio = TL_WR2543N_GPIO_LED_WPS, + .active_low = 1, + } +}; + +static struct gpio_led tl_wr2543n_wmac_leds_gpio[] = { + { + .name = "tp-link:green:wlan5g", + .gpio = TL_WR2543N_GPIO_WMAC_LED_WLAN5G, + .active_low = 1, + }, +}; + +static struct gpio_keys_button tl_wr2543n_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TL_WR2543N_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR2543N_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = TL_WR2543N_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR2543N_GPIO_BTN_WPS, + .active_low = 1, + } +}; + +static struct rtl8367_extif_config tl_wr2543n_rtl8367_extif0_cfg = { + .mode = RTL8367_EXTIF_MODE_RGMII, + .txdelay = 1, + .rxdelay = 0, + .ability = { + .force_mode = 1, + .txpause = 1, + .rxpause = 1, + .link = 1, + .duplex = 1, + .speed = RTL8367_PORT_SPEED_1000, + }, +}; + +static struct rtl8367_platform_data tl_wr2543n_rtl8367_data = { + .gpio_sda = TL_WR2543N_GPIO_RTL8367_SDA, + .gpio_sck = TL_WR2543N_GPIO_RTL8367_SCK, + .extif0_cfg = &tl_wr2543n_rtl8367_extif0_cfg, +}; + +static struct platform_device tl_wr2543n_rtl8367_device = { + .name = RTL8367_DRIVER_NAME, + .id = -1, + .dev = { + .platform_data = &tl_wr2543n_rtl8367_data, + } +}; + +static void __init tl_wr2543n_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_register_m25p80(&tl_wr2543n_flash_data); + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr2543n_leds_gpio), + tl_wr2543n_leds_gpio); + ath79_register_gpio_keys_polled(-1, TL_WR2543N_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tl_wr2543n_gpio_keys), + tl_wr2543n_gpio_keys); + ath79_register_usb(); + + /* + * The ath9k driver uses this pin for its default led device, which is + * named ath9k-phy0, and reflects activity on either the 2 GHz or 5 GHz + * bands. This pin is connected to the WR2543's 2GHz WLAN LED. + */ + ap9x_pci_setup_wmac_led_pin(0, TL_WR2543N_GPIO_WMAC_LED_WLAN2G); + + /* + * We also have the driver set up an led device for the WR2543's + * separate 5 GHz WLAN LED in case the user wants it. + */ + ap9x_pci_setup_wmac_leds(0, tl_wr2543n_wmac_leds_gpio, + ARRAY_SIZE(tl_wr2543n_wmac_leds_gpio)); + ap91_pci_init(eeprom, mac); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, -1); + ath79_eth0_data.mii_bus_dev = &tl_wr2543n_rtl8367_device.dev; + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_eth0_pll_data.pll_1000 = 0x1a000000; + + ath79_register_eth(0); + + platform_device_register(&tl_wr2543n_rtl8367_device); +} + +MIPS_MACHINE(ATH79_MACH_TL_WR2543N, "TL-WR2543N", "TP-LINK TL-WR2543N/ND", + tl_wr2543n_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr703n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr703n.c new file mode 100644 index 000000000..f60f96245 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr703n.c @@ -0,0 +1,85 @@ +/* + * TP-LINK TL-WR703N board support + * + * Copyright (C) 2011 dongyuqi <729650915@qq.com> + * Copyright (C) 2011-2012 Gabor Juhos + * + * This program 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. + */ + +#include + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define TL_WR703N_GPIO_LED_SYSTEM 27 +#define TL_WR703N_GPIO_BTN_RESET 11 + +#define TL_WR703N_GPIO_USB_POWER 8 + +#define TL_WR703N_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TL_WR703N_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR703N_KEYS_POLL_INTERVAL) + +static const char *tl_wr703n_part_probes[] = { + "tp-link", + NULL, +}; + +static struct flash_platform_data tl_wr703n_flash_data = { + .part_probes = tl_wr703n_part_probes, +}; + +static struct gpio_led tl_wr703n_leds_gpio[] __initdata = { + { + .name = "tp-link:blue:system", + .gpio = TL_WR703N_GPIO_LED_SYSTEM, + .active_low = 1, + }, +}; + +static struct gpio_keys_button tl_wr703n_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TL_WR703N_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR703N_GPIO_BTN_RESET, + .active_low = 0, + } +}; + +static void __init tl_wr703n_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_register_m25p80(&tl_wr703n_flash_data); + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr703n_leds_gpio), + tl_wr703n_leds_gpio); + ath79_register_gpio_keys_polled(-1, TL_WR703N_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tl_wr703n_gpio_keys), + tl_wr703n_gpio_keys); + + ath79_set_usb_power_gpio(TL_WR703N_GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH, + "USB power"); + ath79_register_usb(); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + + ath79_register_mdio(0, 0x0); + ath79_register_eth(0); + + ath79_register_wmac(ee, mac); +} + +MIPS_MACHINE(ATH79_MACH_TL_WR703N, "TL-WR703N", "TP-LINK TL-WR703N v1", + tl_wr703n_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd-v4.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd-v4.c new file mode 100644 index 000000000..0d758913f --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd-v4.c @@ -0,0 +1,135 @@ +/* + * TP-LINK TL-WR741ND v4 board support + * + * Copyright (C) 2011-2012 Gabor Juhos + * + * This program 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. + */ + +#include + +#include +#include + +#include "common.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define TL_WR741NDV4_GPIO_BTN_RESET 11 +#define TL_WR741NDV4_GPIO_BTN_WPS 26 + +#define TL_WR741NDV4_GPIO_LED_WLAN 0 +#define TL_WR741NDV4_GPIO_LED_QSS 1 +#define TL_WR741NDV4_GPIO_LED_WAN 13 +#define TL_WR741NDV4_GPIO_LED_LAN1 14 +#define TL_WR741NDV4_GPIO_LED_LAN2 15 +#define TL_WR741NDV4_GPIO_LED_LAN3 16 +#define TL_WR741NDV4_GPIO_LED_LAN4 17 + +#define TL_WR741NDV4_GPIO_LED_SYSTEM 27 + +#define TL_WR741NDV4_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TL_WR741NDV4_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR741NDV4_KEYS_POLL_INTERVAL) + +static const char *tl_wr741ndv4_part_probes[] = { + "tp-link", + NULL, +}; + +static struct flash_platform_data tl_wr741ndv4_flash_data = { + .part_probes = tl_wr741ndv4_part_probes, +}; + +static struct gpio_led tl_wr741ndv4_leds_gpio[] __initdata = { + { + .name = "tp-link:green:lan1", + .gpio = TL_WR741NDV4_GPIO_LED_LAN1, + .active_low = 0, + }, { + .name = "tp-link:green:lan2", + .gpio = TL_WR741NDV4_GPIO_LED_LAN2, + .active_low = 0, + }, { + .name = "tp-link:green:lan3", + .gpio = TL_WR741NDV4_GPIO_LED_LAN3, + .active_low = 0, + }, { + .name = "tp-link:green:lan4", + .gpio = TL_WR741NDV4_GPIO_LED_LAN4, + .active_low = 1, + }, { + .name = "tp-link:green:qss", + .gpio = TL_WR741NDV4_GPIO_LED_QSS, + .active_low = 0, + }, { + .name = "tp-link:green:system", + .gpio = TL_WR741NDV4_GPIO_LED_SYSTEM, + .active_low = 1, + }, { + .name = "tp-link:green:wan", + .gpio = TL_WR741NDV4_GPIO_LED_WAN, + .active_low = 0, + }, { + .name = "tp-link:green:wlan", + .gpio = TL_WR741NDV4_GPIO_LED_WLAN, + .active_low = 0, + }, +}; + +static struct gpio_keys_button tl_wr741ndv4_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TL_WR741NDV4_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR741NDV4_GPIO_BTN_RESET, + .active_low = 0, + }, { + .desc = "WPS", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = TL_WR741NDV4_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR741NDV4_GPIO_BTN_WPS, + .active_low = 0, + } +}; + +static void __init tl_wr741ndv4_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_setup_ar933x_phy4_switch(true, true); + + ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN | + AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr741ndv4_leds_gpio), + tl_wr741ndv4_leds_gpio); + + ath79_register_gpio_keys_polled(1, TL_WR741NDV4_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tl_wr741ndv4_gpio_keys), + tl_wr741ndv4_gpio_keys); + + ath79_register_m25p80(&tl_wr741ndv4_flash_data); + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); + ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); + + ath79_register_mdio(0, 0x0); + ath79_register_eth(1); + ath79_register_eth(0); + + ath79_register_wmac(ee, mac); +} + +MIPS_MACHINE(ATH79_MACH_TL_WR741ND_V4, "TL-WR741ND-v4", + "TP-LINK TL-WR741ND v4", tl_wr741ndv4_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd.c new file mode 100644 index 000000000..5931654bb --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr741nd.c @@ -0,0 +1,130 @@ +/* + * TP-LINK TL-WR741ND board support + * + * Copyright (C) 2009-2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include + +#include "common.h" +#include "dev-ap9x-pci.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "machtypes.h" + +#define TL_WR741ND_GPIO_LED_QSS 0 +#define TL_WR741ND_GPIO_LED_SYSTEM 1 +#define TL_WR741ND_GPIO_LED_LAN1 13 +#define TL_WR741ND_GPIO_LED_LAN2 14 +#define TL_WR741ND_GPIO_LED_LAN3 15 +#define TL_WR741ND_GPIO_LED_LAN4 16 +#define TL_WR741ND_GPIO_LED_WAN 17 + +#define TL_WR741ND_GPIO_BTN_RESET 11 +#define TL_WR741ND_GPIO_BTN_QSS 12 + +#define TL_WR741ND_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TL_WR741ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR741ND_KEYS_POLL_INTERVAL) + +static const char *tl_wr741nd_part_probes[] = { + "tp-link", + NULL, +}; + +static struct flash_platform_data tl_wr741nd_flash_data = { + .part_probes = tl_wr741nd_part_probes, +}; + +static struct gpio_led tl_wr741nd_leds_gpio[] __initdata = { + { + .name = "tp-link:green:lan1", + .gpio = TL_WR741ND_GPIO_LED_LAN1, + .active_low = 1, + }, { + .name = "tp-link:green:lan2", + .gpio = TL_WR741ND_GPIO_LED_LAN2, + .active_low = 1, + }, { + .name = "tp-link:green:lan3", + .gpio = TL_WR741ND_GPIO_LED_LAN3, + .active_low = 1, + }, { + .name = "tp-link:green:lan4", + .gpio = TL_WR741ND_GPIO_LED_LAN4, + .active_low = 1, + }, { + .name = "tp-link:green:qss", + .gpio = TL_WR741ND_GPIO_LED_QSS, + .active_low = 1, + }, { + .name = "tp-link:green:system", + .gpio = TL_WR741ND_GPIO_LED_SYSTEM, + .active_low = 1, + }, { + .name = "tp-link:green:wan", + .gpio = TL_WR741ND_GPIO_LED_WAN, + .active_low = 1, + }, +}; + +static struct gpio_keys_button tl_wr741nd_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TL_WR741ND_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR741ND_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "qss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = TL_WR741ND_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR741ND_GPIO_BTN_QSS, + .active_low = 1, + } +}; + +static void __init tl_wr741nd_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_register_m25p80(&tl_wr741nd_flash_data); + + ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr741nd_leds_gpio), + tl_wr741nd_leds_gpio); + + ath79_register_gpio_keys_polled(-1, TL_WR741ND_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tl_wr741nd_gpio_keys), + tl_wr741nd_gpio_keys); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); + ath79_init_mac(ath79_eth1_data.mac_addr, mac, -1); + + ath79_register_mdio(0, 0x0); + + /* LAN ports */ + ath79_register_eth(1); + + /* WAN port */ + ath79_register_eth(0); + + ap9x_pci_setup_wmac_led_pin(0, 1); + ap91_pci_init(ee, mac); +} +MIPS_MACHINE(ATH79_MACH_TL_WR741ND, "TL-WR741ND", "TP-LINK TL-WR741ND", + tl_wr741nd_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v8.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v8.c new file mode 100644 index 000000000..db4d1052a --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v8.c @@ -0,0 +1,159 @@ +/* + * TP-LINK TL-WR841N/ND v8 board support + * + * Copyright (C) 2012 Gabor Juhos + * + * This program 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. + */ + +#include + +#include +#include + +#include "common.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define TL_WR841NV8_GPIO_LED_WLAN 13 +#define TL_WR841NV8_GPIO_LED_QSS 15 +#define TL_WR841NV8_GPIO_LED_WAN 18 +#define TL_WR841NV8_GPIO_LED_LAN1 19 +#define TL_WR841NV8_GPIO_LED_LAN2 20 +#define TL_WR841NV8_GPIO_LED_LAN3 21 +#define TL_WR841NV8_GPIO_LED_LAN4 12 +#define TL_WR841NV8_GPIO_LED_SYSTEM 14 + +#define TL_WR841NV8_GPIO_BTN_RESET 17 +#define TL_WR841NV8_GPIO_SW_RFKILL 16 + +#define TL_WR841NV8_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TL_WR841NV8_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR841NV8_KEYS_POLL_INTERVAL) + +static const char *tl_wr841n_v8_part_probes[] = { + "tp-link", + NULL, +}; + +static struct flash_platform_data tl_wr841n_v8_flash_data = { + .part_probes = tl_wr841n_v8_part_probes, +}; + +static struct gpio_led tl_wr841n_v8_leds_gpio[] __initdata = { + { + .name = "tp-link:green:lan1", + .gpio = TL_WR841NV8_GPIO_LED_LAN1, + .active_low = 1, + }, { + .name = "tp-link:green:lan2", + .gpio = TL_WR841NV8_GPIO_LED_LAN2, + .active_low = 1, + }, { + .name = "tp-link:green:lan3", + .gpio = TL_WR841NV8_GPIO_LED_LAN3, + .active_low = 1, + }, { + .name = "tp-link:green:lan4", + .gpio = TL_WR841NV8_GPIO_LED_LAN4, + .active_low = 1, + }, { + .name = "tp-link:green:qss", + .gpio = TL_WR841NV8_GPIO_LED_QSS, + .active_low = 1, + }, { + .name = "tp-link:green:system", + .gpio = TL_WR841NV8_GPIO_LED_SYSTEM, + .active_low = 1, + }, { + .name = "tp-link:green:wan", + .gpio = TL_WR841NV8_GPIO_LED_WAN, + .active_low = 1, + }, { + .name = "tp-link:green:wlan", + .gpio = TL_WR841NV8_GPIO_LED_WLAN, + .active_low = 1, + }, +}; + +static struct gpio_keys_button tl_wr841n_v8_gpio_keys[] __initdata = { + { + .desc = "Reset button", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TL_WR841NV8_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR841NV8_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "RFKILL switch", + .type = EV_SW, + .code = KEY_RFKILL, + .debounce_interval = TL_WR841NV8_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR841NV8_GPIO_SW_RFKILL, + .active_low = 0, + } +}; + +static void __init tl_wr841n_v8_gmac_setup(void) +{ + void __iomem *base; + u32 t; + + base = ioremap(AR934X_GMAC_BASE, AR934X_GMAC_SIZE); + + t = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); + + t &= ~(AR934X_ETH_CFG_RGMII_GMAC0 | AR934X_ETH_CFG_MII_GMAC0 | + AR934X_ETH_CFG_GMII_GMAC0 | AR934X_ETH_CFG_SW_ONLY_MODE | + AR934X_ETH_CFG_SW_PHY_SWAP); + + t |= AR934X_ETH_CFG_SW_PHY_SWAP; + __raw_writel(t, base + AR934X_GMAC_REG_ETH_CFG); + t = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); + + iounmap(base); +} + +static void __init tl_wr841n_v8_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v8_leds_gpio), + tl_wr841n_v8_leds_gpio); + + ath79_register_gpio_keys_polled(1, TL_WR841NV8_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tl_wr841n_v8_gpio_keys), + tl_wr841n_v8_gpio_keys); + + ath79_register_m25p80(&tl_wr841n_v8_flash_data); + + tl_wr841n_v8_gmac_setup(); + + ath79_register_mdio(1, 0x0); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, -1); + ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); + + /* GMAC0 is connected to the PHY0 of the internal switch */ + ath79_switch_data.phy4_mii_en = 1; + ath79_switch_data.phy_poll_mask = BIT(0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; + ath79_eth0_data.phy_mask = BIT(0); + ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; + ath79_register_eth(0); + + /* GMAC1 is connected to the internal switch */ + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; + ath79_register_eth(1); + + ath79_register_wmac(ee, mac); +} + +MIPS_MACHINE(ATH79_MACH_TL_WR841N_V8, "TL-WR841N-v8", "TP-LINK TL-WR841N/ND v8", + tl_wr841n_v8_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n.c new file mode 100644 index 000000000..11f853f05 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n.c @@ -0,0 +1,140 @@ +/* + * TP-LINK TL-WR841N/ND v1 board support + * + * Copyright (C) 2009-2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include + +#include + +#include "dev-dsa.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "machtypes.h" +#include "pci.h" + +#define TL_WR841ND_V1_GPIO_LED_SYSTEM 2 +#define TL_WR841ND_V1_GPIO_LED_QSS_GREEN 4 +#define TL_WR841ND_V1_GPIO_LED_QSS_RED 5 + +#define TL_WR841ND_V1_GPIO_BTN_RESET 3 +#define TL_WR841ND_V1_GPIO_BTN_QSS 7 + +#define TL_WR841ND_V1_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL \ + (3 * TL_WR841ND_V1_KEYS_POLL_INTERVAL) + +static struct mtd_partition tl_wr841n_v1_partitions[] = { + { + .name = "redboot", + .offset = 0, + .size = 0x020000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "kernel", + .offset = 0x020000, + .size = 0x140000, + }, { + .name = "rootfs", + .offset = 0x160000, + .size = 0x280000, + }, { + .name = "config", + .offset = 0x3e0000, + .size = 0x020000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "firmware", + .offset = 0x020000, + .size = 0x3c0000, + } +}; + +static struct flash_platform_data tl_wr841n_v1_flash_data = { + .parts = tl_wr841n_v1_partitions, + .nr_parts = ARRAY_SIZE(tl_wr841n_v1_partitions), +}; + +static struct gpio_led tl_wr841n_v1_leds_gpio[] __initdata = { + { + .name = "tp-link:green:system", + .gpio = TL_WR841ND_V1_GPIO_LED_SYSTEM, + .active_low = 1, + }, { + .name = "tp-link:red:qss", + .gpio = TL_WR841ND_V1_GPIO_LED_QSS_RED, + }, { + .name = "tp-link:green:qss", + .gpio = TL_WR841ND_V1_GPIO_LED_QSS_GREEN, + } +}; + +static struct gpio_keys_button tl_wr841n_v1_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR841ND_V1_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "qss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = TL_WR841ND_V1_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR841ND_V1_GPIO_BTN_QSS, + .active_low = 1, + } +}; + +static struct dsa_chip_data tl_wr841n_v1_dsa_chip = { + .port_names[0] = "wan", + .port_names[1] = "lan1", + .port_names[2] = "lan2", + .port_names[3] = "lan3", + .port_names[4] = "lan4", + .port_names[5] = "cpu", +}; + +static struct dsa_platform_data tl_wr841n_v1_dsa_data = { + .nr_chips = 1, + .chip = &tl_wr841n_v1_dsa_chip, +}; + +static void __init tl_wr841n_v1_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + + ath79_register_mdio(0, 0x0); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth0_data.speed = SPEED_100; + ath79_eth0_data.duplex = DUPLEX_FULL; + + ath79_register_eth(0); + ath79_register_dsa(&ath79_eth0_device.dev, &ath79_mdio0_device.dev, + &tl_wr841n_v1_dsa_data); + + ath79_register_m25p80(&tl_wr841n_v1_flash_data); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr841n_v1_leds_gpio), + tl_wr841n_v1_leds_gpio); + + ath79_register_gpio_keys_polled(-1, TL_WR841ND_V1_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tl_wr841n_v1_gpio_keys), + tl_wr841n_v1_gpio_keys); + ath79_register_pci(); +} + +MIPS_MACHINE(ATH79_MACH_TL_WR841N_V1, "TL-WR841N-v1.5", "TP-LINK TL-WR841N v1", + tl_wr841n_v1_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr941nd.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr941nd.c new file mode 100644 index 000000000..1ddeec730 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr941nd.c @@ -0,0 +1,121 @@ +/* + * TP-LINK TL-WR941ND board support + * + * Copyright (C) 2009-2012 Gabor Juhos + * + * This program 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. + */ + +#include + +#include + +#include "dev-dsa.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define TL_WR941ND_GPIO_LED_SYSTEM 2 +#define TL_WR941ND_GPIO_LED_QSS_RED 4 +#define TL_WR941ND_GPIO_LED_QSS_GREEN 5 +#define TL_WR941ND_GPIO_LED_WLAN 9 + +#define TL_WR941ND_GPIO_BTN_RESET 3 +#define TL_WR941ND_GPIO_BTN_QSS 7 + +#define TL_WR941ND_KEYS_POLL_INTERVAL 20 /* msecs */ +#define TL_WR941ND_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR941ND_KEYS_POLL_INTERVAL) + +static const char *tl_wr941nd_part_probes[] = { + "tp-link", + NULL, +}; + +static struct flash_platform_data tl_wr941nd_flash_data = { + .part_probes = tl_wr941nd_part_probes, +}; + +static struct gpio_led tl_wr941nd_leds_gpio[] __initdata = { + { + .name = "tp-link:green:system", + .gpio = TL_WR941ND_GPIO_LED_SYSTEM, + .active_low = 1, + }, { + .name = "tp-link:red:qss", + .gpio = TL_WR941ND_GPIO_LED_QSS_RED, + }, { + .name = "tp-link:green:qss", + .gpio = TL_WR941ND_GPIO_LED_QSS_GREEN, + }, { + .name = "tp-link:green:wlan", + .gpio = TL_WR941ND_GPIO_LED_WLAN, + .active_low = 1, + } +}; + +static struct gpio_keys_button tl_wr941nd_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = TL_WR941ND_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR941ND_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "qss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = TL_WR941ND_KEYS_DEBOUNCE_INTERVAL, + .gpio = TL_WR941ND_GPIO_BTN_QSS, + .active_low = 1, + } +}; + +static struct dsa_chip_data tl_wr941nd_dsa_chip = { + .port_names[0] = "wan", + .port_names[1] = "lan1", + .port_names[2] = "lan2", + .port_names[3] = "lan3", + .port_names[4] = "lan4", + .port_names[5] = "cpu", +}; + +static struct dsa_platform_data tl_wr941nd_dsa_data = { + .nr_chips = 1, + .chip = &tl_wr941nd_dsa_chip, +}; + +static void __init tl_wr941nd_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_register_mdio(0, 0x0); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth0_data.speed = SPEED_100; + ath79_eth0_data.duplex = DUPLEX_FULL; + + ath79_register_eth(0); + ath79_register_dsa(&ath79_eth0_device.dev, &ath79_mdio0_device.dev, + &tl_wr941nd_dsa_data); + + ath79_register_m25p80(&tl_wr941nd_flash_data); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_leds_gpio), + tl_wr941nd_leds_gpio); + + ath79_register_gpio_keys_polled(-1, TL_WR941ND_KEYS_POLL_INTERVAL, + ARRAY_SIZE(tl_wr941nd_gpio_keys), + tl_wr941nd_gpio_keys); + ath79_register_wmac(eeprom, mac); +} + +MIPS_MACHINE(ATH79_MACH_TL_WR941ND, "TL-WR941ND", "TP-LINK TL-WR941ND", + tl_wr941nd_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt.c new file mode 100644 index 000000000..e49ac23fd --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-ubnt.c @@ -0,0 +1,205 @@ +/* + * Ubiquiti RouterStation support + * + * Copyright (C) 2008-2012 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * Copyright (C) 2008 Ubiquiti + * + * This program 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. + */ + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" +#include "pci.h" + +#define UBNT_RS_GPIO_LED_RF 2 +#define UBNT_RS_GPIO_SW4 8 + +#define UBNT_LS_SR71_GPIO_LED_D25 0 +#define UBNT_LS_SR71_GPIO_LED_D26 1 +#define UBNT_LS_SR71_GPIO_LED_D24 2 +#define UBNT_LS_SR71_GPIO_LED_D23 4 +#define UBNT_LS_SR71_GPIO_LED_D22 5 +#define UBNT_LS_SR71_GPIO_LED_D27 6 +#define UBNT_LS_SR71_GPIO_LED_D28 7 + +#define UBNT_KEYS_POLL_INTERVAL 20 /* msecs */ +#define UBNT_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_KEYS_POLL_INTERVAL) + +static struct gpio_led ubnt_rs_leds_gpio[] __initdata = { + { + .name = "ubnt:green:rf", + .gpio = UBNT_RS_GPIO_LED_RF, + .active_low = 0, + } +}; + +static struct gpio_led ubnt_ls_sr71_leds_gpio[] __initdata = { + { + .name = "ubnt:green:d22", + .gpio = UBNT_LS_SR71_GPIO_LED_D22, + .active_low = 0, + }, { + .name = "ubnt:green:d23", + .gpio = UBNT_LS_SR71_GPIO_LED_D23, + .active_low = 0, + }, { + .name = "ubnt:green:d24", + .gpio = UBNT_LS_SR71_GPIO_LED_D24, + .active_low = 0, + }, { + .name = "ubnt:red:d25", + .gpio = UBNT_LS_SR71_GPIO_LED_D25, + .active_low = 0, + }, { + .name = "ubnt:red:d26", + .gpio = UBNT_LS_SR71_GPIO_LED_D26, + .active_low = 0, + }, { + .name = "ubnt:green:d27", + .gpio = UBNT_LS_SR71_GPIO_LED_D27, + .active_low = 0, + }, { + .name = "ubnt:green:d28", + .gpio = UBNT_LS_SR71_GPIO_LED_D28, + .active_low = 0, + } +}; + +static struct gpio_keys_button ubnt_gpio_keys[] __initdata = { + { + .desc = "sw4", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = UBNT_KEYS_DEBOUNCE_INTERVAL, + .gpio = UBNT_RS_GPIO_SW4, + .active_low = 1, + } +}; + +static const char *ubnt_part_probes[] = { + "RedBoot", + NULL, +}; + +static struct flash_platform_data ubnt_flash_data = { + .part_probes = ubnt_part_probes, +}; + +static void __init ubnt_generic_setup(void) +{ + ath79_register_m25p80(&ubnt_flash_data); + + ath79_register_gpio_keys_polled(-1, UBNT_KEYS_POLL_INTERVAL, + ARRAY_SIZE(ubnt_gpio_keys), + ubnt_gpio_keys); + ath79_register_pci(); +} + +#define UBNT_RS_WAN_PHYMASK BIT(20) +#define UBNT_RS_LAN_PHYMASK (BIT(16) | BIT(17) | BIT(18) | BIT(19)) + +static void __init ubnt_rs_setup(void) +{ + ubnt_generic_setup(); + + ath79_register_mdio(0, ~(UBNT_RS_WAN_PHYMASK | UBNT_RS_LAN_PHYMASK)); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; + ath79_eth0_data.phy_mask = UBNT_RS_WAN_PHYMASK; + + /* + * There is Secondary MAC address duplicate problem with some + * UBNT HW batches. Do not increase Secondary MAC address by 1 + * but do workaround with 'Locally Administrated' bit. + */ + ath79_init_local_mac(ath79_eth1_data.mac_addr, ath79_mac_base); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth1_data.speed = SPEED_100; + ath79_eth1_data.duplex = DUPLEX_FULL; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_usb(); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio), + ubnt_rs_leds_gpio); +} + +MIPS_MACHINE(ATH79_MACH_UBNT_RS, "UBNT-RS", "Ubiquiti RouterStation", + ubnt_rs_setup); + +#define UBNT_RSPRO_WAN_PHYMASK BIT(4) +#define UBNT_RSPRO_LAN_PHYMASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) + +static void __init ubnt_rspro_setup(void) +{ + ubnt_generic_setup(); + + ath79_register_mdio(0, ~(UBNT_RSPRO_WAN_PHYMASK | + UBNT_RSPRO_LAN_PHYMASK)); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.phy_mask = UBNT_RSPRO_WAN_PHYMASK; + + /* + * There is Secondary MAC address duplicate problem with some + * UBNT HW batches. Do not increase Secondary MAC address by 1 + * but do workaround with 'Locally Administrated' bit. + */ + ath79_init_local_mac(ath79_eth1_data.mac_addr, ath79_mac_base); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth1_data.phy_mask = UBNT_RSPRO_LAN_PHYMASK; + ath79_eth1_data.speed = SPEED_1000; + ath79_eth1_data.duplex = DUPLEX_FULL; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_usb(); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio), + ubnt_rs_leds_gpio); +} + +MIPS_MACHINE(ATH79_MACH_UBNT_RSPRO, "UBNT-RSPRO", "Ubiquiti RouterStation Pro", + ubnt_rspro_setup); + +static void __init ubnt_lsx_setup(void) +{ + ubnt_generic_setup(); +} + +MIPS_MACHINE(ATH79_MACH_UBNT_LSX, "UBNT-LSX", "Ubiquiti LSX", ubnt_lsx_setup); + +#define UBNT_LSSR71_PHY_MASK BIT(1) + +static void __init ubnt_lssr71_setup(void) +{ + ubnt_generic_setup(); + + ath79_register_mdio(0, ~UBNT_LSSR71_PHY_MASK); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; + ath79_eth0_data.phy_mask = UBNT_LSSR71_PHY_MASK; + + ath79_register_eth(0); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_ls_sr71_leds_gpio), + ubnt_ls_sr71_leds_gpio); +} + +MIPS_MACHINE(ATH79_MACH_UBNT_LSSR71, "UBNT-LS-SR71", "Ubiquiti LS-SR71", + ubnt_lssr71_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-whr-hp-g300n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-whr-hp-g300n.c new file mode 100644 index 000000000..48f49ad0f --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-whr-hp-g300n.c @@ -0,0 +1,155 @@ +/* + * Buffalo WHR-HP-G300N board support + * + * based on ... + * + * TP-LINK TL-WR741ND board support + * + * Copyright (C) 2009-2010 Gabor Juhos + * + * This program 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. + */ + +#include +#include + +#include "common.h" +#include "dev-ap9x-pci.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "machtypes.h" + +#define WHRHPG300N_GPIO_LED_SECURITY 0 +#define WHRHPG300N_GPIO_LED_DIAG 1 +#define WHRHPG300N_GPIO_LED_ROUTER 6 + +#define WHRHPG300N_GPIO_BTN_ROUTER_ON 7 +#define WHRHPG300N_GPIO_BTN_ROUTER_AUTO 8 +#define WHRHPG300N_GPIO_BTN_RESET 11 +#define WHRHPG300N_GPIO_BTN_AOSS 12 +#define WHRHPG300N_GPIO_LED_LAN1 13 +#define WHRHPG300N_GPIO_LED_LAN2 14 +#define WHRHPG300N_GPIO_LED_LAN3 15 +#define WHRHPG300N_GPIO_LED_LAN4 16 +#define WHRHPG300N_GPIO_LED_WAN 17 + +#define WHRHPG300N_KEYS_POLL_INTERVAL 20 /* msecs */ +#define WHRHPG300N_KEYS_DEBOUNCE_INTERVAL (3 * WHRHPG300N_KEYS_POLL_INTERVAL) + +#define WHRHPG300N_MAC_OFFSET 0x20c + +static struct gpio_led whrhpg300n_leds_gpio[] __initdata = { + { + .name = "buffalo:orange:security", + .gpio = WHRHPG300N_GPIO_LED_SECURITY, + .active_low = 1, + }, { + .name = "buffalo:red:diag", + .gpio = WHRHPG300N_GPIO_LED_DIAG, + .active_low = 1, + }, { + .name = "buffalo:green:router", + .gpio = WHRHPG300N_GPIO_LED_ROUTER, + .active_low = 1, + }, { + .name = "buffalo:green:wan", + .gpio = WHRHPG300N_GPIO_LED_WAN, + .active_low = 1, + }, { + .name = "buffalo:green:lan1", + .gpio = WHRHPG300N_GPIO_LED_LAN1, + .active_low = 1, + }, { + .name = "buffalo:green:lan2", + .gpio = WHRHPG300N_GPIO_LED_LAN2, + .active_low = 1, + }, { + .name = "buffalo:green:lan3", + .gpio = WHRHPG300N_GPIO_LED_LAN3, + .active_low = 1, + }, { + .name = "buffalo:green:lan4", + .gpio = WHRHPG300N_GPIO_LED_LAN4, + .active_low = 1, + } +}; + +static struct gpio_keys_button whrhpg300n_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = WHRHPG300N_KEYS_DEBOUNCE_INTERVAL, + .gpio = WHRHPG300N_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "aoss/wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .gpio = WHRHPG300N_GPIO_BTN_AOSS, + .debounce_interval = WHRHPG300N_KEYS_DEBOUNCE_INTERVAL, + .active_low = 1, + }, { + .desc = "router_on", + .type = EV_KEY, + .code = BTN_2, + .gpio = WHRHPG300N_GPIO_BTN_ROUTER_ON, + .debounce_interval = WHRHPG300N_KEYS_DEBOUNCE_INTERVAL, + .active_low = 1, + }, { + .desc = "router_auto", + .type = EV_KEY, + .code = BTN_3, + .gpio = WHRHPG300N_GPIO_BTN_ROUTER_AUTO, + .debounce_interval = WHRHPG300N_KEYS_DEBOUNCE_INTERVAL, + .active_low = 1, + } +}; + +static void __init whrhpg300n_setup(void) +{ + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + u8 *mac = (u8 *) KSEG1ADDR(ee + WHRHPG300N_MAC_OFFSET); + + ath79_register_m25p80(NULL); + + ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(whrhpg300n_leds_gpio), + whrhpg300n_leds_gpio); + + ath79_register_gpio_keys_polled(-1, WHRHPG300N_KEYS_POLL_INTERVAL, + ARRAY_SIZE(whrhpg300n_gpio_keys), + whrhpg300n_gpio_keys); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); + + ath79_register_mdio(0, 0x0); + + /* LAN ports */ + ath79_register_eth(1); + /* WAN port */ + ath79_register_eth(0); + + ap9x_pci_setup_wmac_led_pin(0, 1); + + ap91_pci_init(ee, mac); +} + +MIPS_MACHINE(ATH79_MACH_WHR_HP_G300N, "WHR-HP-G300N", "Buffalo WHR-HP-G300N", + whrhpg300n_setup); + +MIPS_MACHINE(ATH79_MACH_WHR_G301N, "WHR-G301N", "Buffalo WHR-G301N", + whrhpg300n_setup); + +MIPS_MACHINE(ATH79_MACH_WHR_HP_GN, "WHR-HP-GN", "Buffalo WHR-HP-GN", + whrhpg300n_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wlae-ag300n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wlae-ag300n.c new file mode 100644 index 000000000..11006fd1b --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wlae-ag300n.c @@ -0,0 +1,114 @@ +/* + * Buffalo WLAE-AG300N board support + */ + +#include +#include +#include + +#include + +#include "dev-eth.h" +#include "dev-ap9x-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" + +#define WLAEAG300N_MAC_OFFSET 0x20c +#define WLAEAG300N_KEYS_POLL_INTERVAL 20 /* msecs */ +#define WLAEAG300N_KEYS_DEBOUNCE_INTERVAL (3 * WLAEAG300N_KEYS_POLL_INTERVAL) + + +static struct gpio_led wlaeag300n_leds_gpio[] __initdata = { + /* + * Note: Writing 1 into GPIO 13 will power down the device. + */ + { + .name = "buffalo:green:wireless", + .gpio = 14, + .active_low = 1, + }, { + .name = "buffalo:red:wireless", + .gpio = 15, + .active_low = 1, + }, { + .name = "buffalo:green:status", + .gpio = 16, + .active_low = 1, + }, { + .name = "buffalo:red:status", + .gpio = 17, + .active_low = 1, + } +}; + + +static struct gpio_keys_button wlaeag300n_gpio_keys[] __initdata = { + { + .desc = "function", + .type = EV_KEY, + .code = KEY_MODE, + .debounce_interval = WLAEAG300N_KEYS_DEBOUNCE_INTERVAL, + .gpio = 0, + .active_low = 1, + }, { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = WLAEAG300N_KEYS_DEBOUNCE_INTERVAL, + .gpio = 1, + .active_low = 1, + }, { + .desc = "power", + .type = EV_KEY, + .code = KEY_POWER, + .debounce_interval = WLAEAG300N_KEYS_DEBOUNCE_INTERVAL, + .gpio = 11, + .active_low = 1, + }, { + .desc = "aoss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = WLAEAG300N_KEYS_DEBOUNCE_INTERVAL, + .gpio = 12, + .active_low = 1, + } +}; + +static void __init wlaeag300n_setup(void) +{ + u8 *eeprom1 = (u8 *) KSEG1ADDR(0x1fff1000); + u8 *mac1 = eeprom1 + WLAEAG300N_MAC_OFFSET; + + ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, mac1, 1); + + ath79_register_mdio(0, ~(BIT(0) | BIT(4))); + + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_eth0_data.phy_mask = BIT(0); + + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth1_data.phy_mask = BIT(4); + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(wlaeag300n_leds_gpio), + wlaeag300n_leds_gpio); + + ath79_register_gpio_keys_polled(-1, WLAEAG300N_KEYS_POLL_INTERVAL, + ARRAY_SIZE(wlaeag300n_gpio_keys), + wlaeag300n_gpio_keys); + + ath79_register_m25p80(NULL); + + ap91_pci_init(eeprom1, mac1); +} + +MIPS_MACHINE(ATH79_MACH_WLAE_AG300N, "WLAE-AG300N", + "Buffalo WLAE-AG300N", wlaeag300n_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wndr3700.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wndr3700.c new file mode 100644 index 000000000..fccf1c663 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wndr3700.c @@ -0,0 +1,172 @@ +/* + * Netgear WNDR3700 board support + * + * Copyright (C) 2009 Marco Porsch + * Copyright (C) 2009-2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include +#include +#include + +#include + +#include "dev-ap9x-pci.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" + +#define WNDR3700_GPIO_LED_WPS_ORANGE 0 +#define WNDR3700_GPIO_LED_POWER_ORANGE 1 +#define WNDR3700_GPIO_LED_POWER_GREEN 2 +#define WNDR3700_GPIO_LED_WPS_GREEN 4 +#define WNDR3700_GPIO_LED_WAN_GREEN 6 + +#define WNDR3700_GPIO_BTN_WPS 3 +#define WNDR3700_GPIO_BTN_RESET 8 +#define WNDR3700_GPIO_BTN_WIFI 11 + +#define WNDR3700_GPIO_RTL8366_SDA 5 +#define WNDR3700_GPIO_RTL8366_SCK 7 + +#define WNDR3700_KEYS_POLL_INTERVAL 20 /* msecs */ +#define WNDR3700_KEYS_DEBOUNCE_INTERVAL (3 * WNDR3700_KEYS_POLL_INTERVAL) + +#define WNDR3700_ETH0_MAC_OFFSET 0 +#define WNDR3700_ETH1_MAC_OFFSET 0x6 + +#define WNDR3700_WMAC0_MAC_OFFSET 0 +#define WNDR3700_WMAC1_MAC_OFFSET 0xc +#define WNDR3700_CALDATA0_OFFSET 0x1000 +#define WNDR3700_CALDATA1_OFFSET 0x5000 + +static struct gpio_led wndr3700_leds_gpio[] __initdata = { + { + .name = "wndr3700:green:power", + .gpio = WNDR3700_GPIO_LED_POWER_GREEN, + .active_low = 1, + }, { + .name = "wndr3700:orange:power", + .gpio = WNDR3700_GPIO_LED_POWER_ORANGE, + .active_low = 1, + }, { + .name = "wndr3700:green:wps", + .gpio = WNDR3700_GPIO_LED_WPS_GREEN, + .active_low = 1, + }, { + .name = "wndr3700:orange:wps", + .gpio = WNDR3700_GPIO_LED_WPS_ORANGE, + .active_low = 1, + }, { + .name = "wndr3700:green:wan", + .gpio = WNDR3700_GPIO_LED_WAN_GREEN, + .active_low = 1, + } +}; + +static struct gpio_keys_button wndr3700_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, + .gpio = WNDR3700_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, + .gpio = WNDR3700_GPIO_BTN_WPS, + .active_low = 1, + }, { + .desc = "wifi", + .type = EV_KEY, + .code = BTN_2, + .debounce_interval = WNDR3700_KEYS_DEBOUNCE_INTERVAL, + .gpio = WNDR3700_GPIO_BTN_WIFI, + .active_low = 1, + } +}; + +static struct rtl8366_platform_data wndr3700_rtl8366s_data = { + .gpio_sda = WNDR3700_GPIO_RTL8366_SDA, + .gpio_sck = WNDR3700_GPIO_RTL8366_SCK, +}; + +static struct platform_device wndr3700_rtl8366s_device = { + .name = RTL8366S_DRIVER_NAME, + .id = -1, + .dev = { + .platform_data = &wndr3700_rtl8366s_data, + } +}; + +static void __init wndr3700_setup(void) +{ + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + + /* + * The eth0 and wmac0 interfaces share the same MAC address which + * can lead to problems if operated unbridged. Set the locally + * administered bit on the eth0 MAC to make it unique. + */ + ath79_init_local_mac(ath79_eth0_data.mac_addr, + art + WNDR3700_ETH0_MAC_OFFSET); + ath79_eth0_pll_data.pll_1000 = 0x11110000; + ath79_eth0_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev; + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + + ath79_init_mac(ath79_eth1_data.mac_addr, + art + WNDR3700_ETH1_MAC_OFFSET, 0); + ath79_eth1_pll_data.pll_1000 = 0x11110000; + ath79_eth1_data.mii_bus_dev = &wndr3700_rtl8366s_device.dev; + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth1_data.phy_mask = 0x10; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_usb(); + + ath79_register_m25p80(NULL); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(wndr3700_leds_gpio), + wndr3700_leds_gpio); + + ath79_register_gpio_keys_polled(-1, WNDR3700_KEYS_POLL_INTERVAL, + ARRAY_SIZE(wndr3700_gpio_keys), + wndr3700_gpio_keys); + + platform_device_register(&wndr3700_rtl8366s_device); + platform_device_register_simple("wndr3700-led-usb", -1, NULL, 0); + + ap9x_pci_setup_wmac_led_pin(0, 5); + ap9x_pci_setup_wmac_led_pin(1, 5); + + /* 2.4 GHz uses the first fixed antenna group (1, 0, 1, 0) */ + ap9x_pci_setup_wmac_gpio(0, (0xf << 6), (0xa << 6)); + + /* 5 GHz uses the second fixed antenna group (0, 1, 1, 0) */ + ap9x_pci_setup_wmac_gpio(1, (0xf << 6), (0x6 << 6)); + + ap94_pci_init(art + WNDR3700_CALDATA0_OFFSET, + art + WNDR3700_WMAC0_MAC_OFFSET, + art + WNDR3700_CALDATA1_OFFSET, + art + WNDR3700_WMAC1_MAC_OFFSET); +} + +MIPS_MACHINE(ATH79_MACH_WNDR3700, "WNDR3700", + "NETGEAR WNDR3700/WNDR3800/WNDRMAC", + wndr3700_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000.c new file mode 100644 index 000000000..bd86db386 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2000.c @@ -0,0 +1,145 @@ +/* + * NETGEAR WNR2000 board support + * + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * Copyright (C) 2008-2009 Andy Boyett + * + * This program 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. + */ + +#include +#include + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define WNR2000_GPIO_LED_PWR_GREEN 14 +#define WNR2000_GPIO_LED_PWR_AMBER 7 +#define WNR2000_GPIO_LED_WPS 4 +#define WNR2000_GPIO_LED_WLAN 6 +#define WNR2000_GPIO_BTN_RESET 21 +#define WNR2000_GPIO_BTN_WPS 8 + +#define WNR2000_KEYS_POLL_INTERVAL 20 /* msecs */ +#define WNR2000_KEYS_DEBOUNCE_INTERVAL (3 * WNR2000_KEYS_POLL_INTERVAL) + +static struct mtd_partition wnr2000_partitions[] = { + { + .name = "u-boot", + .offset = 0, + .size = 0x040000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "u-boot-env", + .offset = 0x040000, + .size = 0x010000, + }, { + .name = "rootfs", + .offset = 0x050000, + .size = 0x240000, + }, { + .name = "user-config", + .offset = 0x290000, + .size = 0x010000, + }, { + .name = "uImage", + .offset = 0x2a0000, + .size = 0x120000, + }, { + .name = "language_table", + .offset = 0x3c0000, + .size = 0x020000, + }, { + .name = "rootfs_checksum", + .offset = 0x3e0000, + .size = 0x010000, + }, { + .name = "art", + .offset = 0x3f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + } +}; + +static struct flash_platform_data wnr2000_flash_data = { + .parts = wnr2000_partitions, + .nr_parts = ARRAY_SIZE(wnr2000_partitions), +}; + +static struct gpio_led wnr2000_leds_gpio[] __initdata = { + { + .name = "wnr2000:green:power", + .gpio = WNR2000_GPIO_LED_PWR_GREEN, + .active_low = 1, + }, { + .name = "wnr2000:amber:power", + .gpio = WNR2000_GPIO_LED_PWR_AMBER, + .active_low = 1, + }, { + .name = "wnr2000:green:wps", + .gpio = WNR2000_GPIO_LED_WPS, + .active_low = 1, + }, { + .name = "wnr2000:blue:wlan", + .gpio = WNR2000_GPIO_LED_WLAN, + .active_low = 1, + } +}; + +static struct gpio_keys_button wnr2000_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = WNR2000_KEYS_DEBOUNCE_INTERVAL, + .gpio = WNR2000_GPIO_BTN_RESET, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = WNR2000_KEYS_DEBOUNCE_INTERVAL, + .gpio = WNR2000_GPIO_BTN_WPS, + } +}; + +static void __init wnr2000_setup(void) +{ + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_register_mdio(0, 0x0); + + ath79_init_mac(ath79_eth0_data.mac_addr, eeprom, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth0_data.speed = SPEED_100; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_eth0_data.has_ar8216 = 1; + + ath79_init_mac(ath79_eth1_data.mac_addr, eeprom, 1); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth1_data.phy_mask = 0x10; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_m25p80(&wnr2000_flash_data); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(wnr2000_leds_gpio), + wnr2000_leds_gpio); + + ath79_register_gpio_keys_polled(-1, WNR2000_KEYS_POLL_INTERVAL, + ARRAY_SIZE(wnr2000_gpio_keys), + wnr2000_gpio_keys); + + ath79_register_wmac(eeprom, NULL); +} + +MIPS_MACHINE(ATH79_MACH_WNR2000, "WNR2000", "NETGEAR WNR2000", wnr2000_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wp543.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wp543.c new file mode 100644 index 000000000..148cd7c7f --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wp543.c @@ -0,0 +1,107 @@ +/* + * Compex WP543/WPJ543 board support + * + * Copyright (C) 2008-2012 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#include +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" +#include "pci.h" + +#define WP543_GPIO_SW6 2 +#define WP543_GPIO_LED_1 3 +#define WP543_GPIO_LED_2 4 +#define WP543_GPIO_LED_WLAN 5 +#define WP543_GPIO_LED_CONN 6 +#define WP543_GPIO_LED_DIAG 7 +#define WP543_GPIO_SW4 8 + +#define WP543_KEYS_POLL_INTERVAL 20 /* msecs */ +#define WP543_KEYS_DEBOUNCE_INTERVAL (3 * WP543_KEYS_POLL_INTERVAL) + +static struct gpio_led wp543_leds_gpio[] __initdata = { + { + .name = "wp543:green:led1", + .gpio = WP543_GPIO_LED_1, + .active_low = 1, + }, { + .name = "wp543:green:led2", + .gpio = WP543_GPIO_LED_2, + .active_low = 1, + }, { + .name = "wp543:green:wlan", + .gpio = WP543_GPIO_LED_WLAN, + .active_low = 1, + }, { + .name = "wp543:green:conn", + .gpio = WP543_GPIO_LED_CONN, + .active_low = 1, + }, { + .name = "wp543:green:diag", + .gpio = WP543_GPIO_LED_DIAG, + .active_low = 1, + } +}; + +static struct gpio_keys_button wp543_gpio_keys[] __initdata = { + { + .desc = "sw6", + .type = EV_KEY, + .code = BTN_0, + .debounce_interval = WP543_KEYS_DEBOUNCE_INTERVAL, + .gpio = WP543_GPIO_SW6, + }, { + .desc = "sw4", + .type = EV_KEY, + .code = BTN_1, + .debounce_interval = WP543_KEYS_DEBOUNCE_INTERVAL, + .gpio = WP543_GPIO_SW4, + } +}; + +static const char *wp543_part_probes[] = { + "MyLoader", + NULL, +}; + +static struct flash_platform_data wp543_flash_data = { + .part_probes = wp543_part_probes, +}; + +static void __init wp543_setup(void) +{ + ath79_register_m25p80(&wp543_flash_data); + + ath79_register_mdio(0, 0xfffffff0); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; + ath79_eth0_data.phy_mask = 0x0f; + ath79_eth0_data.reset_bit = AR71XX_RESET_GE0_MAC | + AR71XX_RESET_GE0_PHY; + ath79_register_eth(0); + + ath79_register_usb(); + ath79_register_pci(); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(wp543_leds_gpio), + wp543_leds_gpio); + + ath79_register_gpio_keys_polled(-1, WP543_KEYS_POLL_INTERVAL, + ARRAY_SIZE(wp543_gpio_keys), + wp543_gpio_keys); +} + +MIPS_MACHINE(ATH79_MACH_WP543, "WP543", "Compex WP543", wp543_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wpe72.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wpe72.c new file mode 100644 index 000000000..114d6233c --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wpe72.c @@ -0,0 +1,96 @@ +/* + * Compex WPE72 board support + * + * Copyright (C) 2012 Johnathan Boyce + * + * This program 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. + */ + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" +#include "pci.h" + +#define WPE72_GPIO_RESET 12 +#define WPE72_GPIO_LED_DIAG 13 +#define WPE72_GPIO_LED_1 14 +#define WPE72_GPIO_LED_2 15 +#define WPE72_GPIO_LED_3 16 +#define WPE72_GPIO_LED_4 17 + +#define WPE72_KEYS_POLL_INTERVAL 20 /* msecs */ +#define WPE72_KEYS_DEBOUNCE_INTERVAL (3 * WPE72_KEYS_POLL_INTERVAL) + +static struct gpio_led wpe72_leds_gpio[] __initdata = { + { + .name = "wpe72:green:led1", + .gpio = WPE72_GPIO_LED_1, + .active_low = 1, + }, { + .name = "wpe72:green:led2", + .gpio = WPE72_GPIO_LED_2, + .active_low = 1, + }, { + .name = "wpe72:green:led3", + .gpio = WPE72_GPIO_LED_3, + .active_low = 1, + }, { + .name = "wpe72:green:led4", + .gpio = WPE72_GPIO_LED_4, + .active_low = 1, + }, { + .name = "wpe72:green:diag", + .gpio = WPE72_GPIO_LED_DIAG, + .active_low = 1, + } +}; + +static struct gpio_keys_button wpe72_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = WPE72_KEYS_DEBOUNCE_INTERVAL, + .gpio = WPE72_GPIO_RESET, + } +}; + +static const char *wpe72_part_probes[] = { + "MyLoader", + NULL, +}; + +static struct flash_platform_data wpe72_flash_data = { + .part_probes = wpe72_part_probes, +}; + +static void __init wpe72_setup(void) +{ + ath79_register_m25p80(&wpe72_flash_data); + ath79_register_mdio(0, 0x0); + + ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_usb(); + ath79_register_pci(); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(wpe72_leds_gpio), + wpe72_leds_gpio); + + ath79_register_gpio_keys_polled(-1, WPE72_KEYS_POLL_INTERVAL, + ARRAY_SIZE(wpe72_gpio_keys), + wpe72_gpio_keys); +} + +MIPS_MACHINE(ATH79_MACH_WPE72, "WPE72", "Compex WPE72", wpe72_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wrt160nl.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wrt160nl.c new file mode 100644 index 000000000..21aefe00a --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wrt160nl.c @@ -0,0 +1,126 @@ +/* + * Linksys WRT160NL board support + * + * Copyright (C) 2009-2012 Gabor Juhos + * + * This program 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. + */ + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "dev-wmac.h" +#include "nvram.h" +#include "machtypes.h" + +#define WRT160NL_GPIO_LED_POWER 14 +#define WRT160NL_GPIO_LED_WPS_AMBER 9 +#define WRT160NL_GPIO_LED_WPS_BLUE 8 +#define WRT160NL_GPIO_LED_WLAN 6 + +#define WRT160NL_GPIO_BTN_WPS 7 +#define WRT160NL_GPIO_BTN_RESET 21 + +#define WRT160NL_KEYS_POLL_INTERVAL 20 /* msecs */ +#define WRT160NL_KEYS_DEBOUNCE_INTERVAL (3 * WRT160NL_KEYS_POLL_INTERVAL) + +#define WRT160NL_NVRAM_ADDR 0x1f7e0000 +#define WRT160NL_NVRAM_SIZE 0x10000 + +static const char *wrt160nl_part_probes[] = { + "wrt160nl", + NULL, +}; + +static struct flash_platform_data wrt160nl_flash_data = { + .part_probes = wrt160nl_part_probes, +}; + +static struct gpio_led wrt160nl_leds_gpio[] __initdata = { + { + .name = "wrt160nl:blue:power", + .gpio = WRT160NL_GPIO_LED_POWER, + .active_low = 1, + .default_trigger = "default-on", + }, { + .name = "wrt160nl:amber:wps", + .gpio = WRT160NL_GPIO_LED_WPS_AMBER, + .active_low = 1, + }, { + .name = "wrt160nl:blue:wps", + .gpio = WRT160NL_GPIO_LED_WPS_BLUE, + .active_low = 1, + }, { + .name = "wrt160nl:blue:wlan", + .gpio = WRT160NL_GPIO_LED_WLAN, + .active_low = 1, + } +}; + +static struct gpio_keys_button wrt160nl_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = WRT160NL_KEYS_DEBOUNCE_INTERVAL, + .gpio = WRT160NL_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wps", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = WRT160NL_KEYS_DEBOUNCE_INTERVAL, + .gpio = WRT160NL_GPIO_BTN_WPS, + .active_low = 1, + } +}; + +static void __init wrt160nl_setup(void) +{ + const char *nvram = (char *) KSEG1ADDR(WRT160NL_NVRAM_ADDR); + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + u8 mac[6]; + + if (ath79_nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE, + "lan_hwaddr=", mac) == 0) { + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); + } + + ath79_register_mdio(0, 0x0); + + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth0_data.phy_mask = 0x01; + + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth1_data.phy_mask = 0x10; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_m25p80(&wrt160nl_flash_data); + + ath79_register_usb(); + + if (ath79_nvram_parse_mac_addr(nvram, WRT160NL_NVRAM_SIZE, + "wl0_hwaddr=", mac) == 0) + ath79_register_wmac(eeprom, mac); + else + ath79_register_wmac(eeprom, NULL); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(wrt160nl_leds_gpio), + wrt160nl_leds_gpio); + + ath79_register_gpio_keys_polled(-1, WRT160NL_KEYS_POLL_INTERVAL, + ARRAY_SIZE(wrt160nl_gpio_keys), + wrt160nl_gpio_keys); +} + +MIPS_MACHINE(ATH79_MACH_WRT160NL, "WRT160NL", "Linksys WRT160NL", + wrt160nl_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wrt400n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wrt400n.c new file mode 100644 index 000000000..6c4c1cb0d --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wrt400n.c @@ -0,0 +1,161 @@ +/* + * Linksys WRT400N board support + * + * Copyright (C) 2009-2012 Gabor Juhos + * Copyright (C) 2009 Imre Kaloz + * + * This program 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. + */ + +#include +#include + +#include + +#include "dev-ap9x-pci.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "machtypes.h" + +#define WRT400N_GPIO_LED_POWER 1 +#define WRT400N_GPIO_LED_WPS_BLUE 4 +#define WRT400N_GPIO_LED_WPS_AMBER 5 +#define WRT400N_GPIO_LED_WLAN 6 + +#define WRT400N_GPIO_BTN_RESET 8 +#define WRT400N_GPIO_BTN_WLSEC 3 + +#define WRT400N_KEYS_POLL_INTERVAL 20 /* msecs */ +#define WRT400N_KEYS_DEBOUNE_INTERVAL (3 * WRT400N_KEYS_POLL_INTERVAL) + +#define WRT400N_MAC_ADDR_OFFSET 0x120c +#define WRT400N_CALDATA0_OFFSET 0x1000 +#define WRT400N_CALDATA1_OFFSET 0x5000 + +static struct mtd_partition wrt400n_partitions[] = { + { + .name = "uboot", + .offset = 0, + .size = 0x030000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "env", + .offset = 0x030000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "linux", + .offset = 0x040000, + .size = 0x140000, + }, { + .name = "rootfs", + .offset = 0x180000, + .size = 0x630000, + }, { + .name = "nvram", + .offset = 0x7b0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "factory", + .offset = 0x7c0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "language", + .offset = 0x7d0000, + .size = 0x020000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "caldata", + .offset = 0x7f0000, + .size = 0x010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "firmware", + .offset = 0x040000, + .size = 0x770000, + } +}; + +static struct flash_platform_data wrt400n_flash_data = { + .parts = wrt400n_partitions, + .nr_parts = ARRAY_SIZE(wrt400n_partitions), +}; + +static struct gpio_led wrt400n_leds_gpio[] __initdata = { + { + .name = "wrt400n:blue:wps", + .gpio = WRT400N_GPIO_LED_WPS_BLUE, + .active_low = 1, + }, { + .name = "wrt400n:amber:wps", + .gpio = WRT400N_GPIO_LED_WPS_AMBER, + .active_low = 1, + }, { + .name = "wrt400n:blue:wlan", + .gpio = WRT400N_GPIO_LED_WLAN, + .active_low = 1, + }, { + .name = "wrt400n:blue:power", + .gpio = WRT400N_GPIO_LED_POWER, + .active_low = 0, + .default_trigger = "default-on", + } +}; + +static struct gpio_keys_button wrt400n_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = WRT400N_KEYS_DEBOUNE_INTERVAL, + .gpio = WRT400N_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "wlsec", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = WRT400N_KEYS_DEBOUNE_INTERVAL, + .gpio = WRT400N_GPIO_BTN_WLSEC, + .active_low = 1, + } +}; + +static void __init wrt400n_setup(void) +{ + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + u8 *mac = art + WRT400N_MAC_ADDR_OFFSET; + + ath79_register_mdio(0, 0x0); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 1); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth0_data.speed = SPEED_100; + ath79_eth0_data.duplex = DUPLEX_FULL; + + ath79_init_mac(ath79_eth1_data.mac_addr, mac, 2); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth1_data.phy_mask = 0x10; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_m25p80(&wrt400n_flash_data); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(wrt400n_leds_gpio), + wrt400n_leds_gpio); + + ath79_register_gpio_keys_polled(-1, WRT400N_KEYS_POLL_INTERVAL, + ARRAY_SIZE(wrt400n_gpio_keys), + wrt400n_gpio_keys); + + ap94_pci_init(art + WRT400N_CALDATA0_OFFSET, NULL, + art + WRT400N_CALDATA1_OFFSET, NULL); +} + +MIPS_MACHINE(ATH79_MACH_WRT400N, "WRT400N", "Linksys WRT400N", wrt400n_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-ag300h.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-ag300h.c new file mode 100644 index 000000000..868514c95 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-ag300h.c @@ -0,0 +1,213 @@ +/* + * Buffalo WZR-HP-AG300H board support + * + * Copyright (C) 2011 Felix Fietkau + * + * This program 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. + */ + +#include +#include +#include + +#include + +#include "dev-eth.h" +#include "dev-ap9x-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" + +#define WZRHPAG300H_MAC_OFFSET 0x20c +#define WZRHPAG300H_KEYS_POLL_INTERVAL 20 /* msecs */ +#define WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPAG300H_KEYS_POLL_INTERVAL) + +static struct mtd_partition wzrhpag300h_flash_partitions[] = { + { + .name = "u-boot", + .offset = 0, + .size = 0x0040000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "u-boot-env", + .offset = 0x0040000, + .size = 0x0010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "art", + .offset = 0x0050000, + .size = 0x0010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "kernel", + .offset = 0x0060000, + .size = 0x0100000, + }, { + .name = "rootfs", + .offset = 0x0160000, + .size = 0x1e90000, + }, { + .name = "user_property", + .offset = 0x1ff0000, + .size = 0x0010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "firmware", + .offset = 0x0060000, + .size = 0x1f90000, + } +}; + +static struct flash_platform_data wzrhpag300h_flash_data = { + .parts = wzrhpag300h_flash_partitions, + .nr_parts = ARRAY_SIZE(wzrhpag300h_flash_partitions), +}; + +static struct gpio_led wzrhpag300h_leds_gpio[] __initdata = { + { + .name = "buffalo:red:diag", + .gpio = 1, + .active_low = 1, + }, +}; + +static struct gpio_led wzrhpag300h_wmac0_leds_gpio[] = { + { + .name = "buffalo:amber:band2g", + .gpio = 1, + .active_low = 1, + }, + { + .name = "buffalo:green:usb", + .gpio = 3, + .active_low = 1, + }, + { + .name = "buffalo:green:band2g", + .gpio = 5, + .active_low = 1, + }, +}; + +static struct gpio_led wzrhpag300h_wmac1_leds_gpio[] = { + { + .name = "buffalo:green:band5g", + .gpio = 1, + .active_low = 1, + }, + { + .name = "buffalo:green:router", + .gpio = 3, + .active_low = 1, + }, + { + .name = "buffalo:blue:movie_engine", + .gpio = 4, + .active_low = 1, + }, + { + .name = "buffalo:amber:band5g", + .gpio = 5, + .active_low = 1, + }, +}; + +static struct gpio_keys_button wzrhpag300h_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, + .gpio = 11, + .active_low = 1, + }, { + .desc = "usb", + .type = EV_KEY, + .code = BTN_2, + .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, + .gpio = 3, + .active_low = 1, + }, { + .desc = "aoss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, + .gpio = 5, + .active_low = 1, + }, { + .desc = "router_auto", + .type = EV_KEY, + .code = BTN_6, + .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, + .gpio = 6, + .active_low = 1, + }, { + .desc = "router_off", + .type = EV_KEY, + .code = BTN_5, + .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, + .gpio = 7, + .active_low = 1, + }, { + .desc = "movie_engine", + .type = EV_KEY, + .code = BTN_7, + .debounce_interval = WZRHPAG300H_KEYS_DEBOUNCE_INTERVAL, + .gpio = 8, + .active_low = 1, + } +}; + +static void __init wzrhpag300h_setup(void) +{ + u8 *eeprom1 = (u8 *) KSEG1ADDR(0x1f051000); + u8 *eeprom2 = (u8 *) KSEG1ADDR(0x1f055000); + u8 *mac1 = eeprom1 + WZRHPAG300H_MAC_OFFSET; + u8 *mac2 = eeprom2 + WZRHPAG300H_MAC_OFFSET; + + ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 1); + + ath79_register_mdio(0, ~(BIT(0) | BIT(4))); + + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_eth0_data.phy_mask = BIT(0); + + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth1_data.phy_mask = BIT(4); + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_set_usb_power_gpio(2, GPIOF_OUT_INIT_HIGH, "USB power"); + ath79_register_usb(); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(wzrhpag300h_leds_gpio), + wzrhpag300h_leds_gpio); + + ath79_register_gpio_keys_polled(-1, WZRHPAG300H_KEYS_POLL_INTERVAL, + ARRAY_SIZE(wzrhpag300h_gpio_keys), + wzrhpag300h_gpio_keys); + + ath79_register_m25p80_multi(&wzrhpag300h_flash_data); + + ap94_pci_init(eeprom1, mac1, eeprom2, mac2); + + ap9x_pci_setup_wmac_led_pin(0, 1); + ap9x_pci_setup_wmac_led_pin(1, 5); + + ap9x_pci_setup_wmac_leds(0, wzrhpag300h_wmac0_leds_gpio, + ARRAY_SIZE(wzrhpag300h_wmac0_leds_gpio)); + ap9x_pci_setup_wmac_leds(1, wzrhpag300h_wmac1_leds_gpio, + ARRAY_SIZE(wzrhpag300h_wmac1_leds_gpio)); +} + +MIPS_MACHINE(ATH79_MACH_WZR_HP_AG300H, "WZR-HP-AG300H", + "Buffalo WZR-HP-AG300H", wzrhpag300h_setup); + diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh.c new file mode 100644 index 000000000..94f352ace --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh.c @@ -0,0 +1,287 @@ +/* + * Buffalo WZR-HP-G300NH board support + * + * Copyright (C) 2010-2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-usb.h" +#include "dev-wmac.h" +#include "machtypes.h" + +#define WZRHPG300NH_GPIO_LED_USB 0 +#define WZRHPG300NH_GPIO_LED_DIAG 1 +#define WZRHPG300NH_GPIO_LED_WIRELESS 6 +#define WZRHPG300NH_GPIO_LED_SECURITY 17 +#define WZRHPG300NH_GPIO_LED_ROUTER 18 + +#define WZRHPG300NH_GPIO_RTL8366_SDA 19 +#define WZRHPG300NH_GPIO_RTL8366_SCK 20 + +#define WZRHPG300NH_GPIO_74HC153_S0 9 +#define WZRHPG300NH_GPIO_74HC153_S1 11 +#define WZRHPG300NH_GPIO_74HC153_1Y 12 +#define WZRHPG300NH_GPIO_74HC153_2Y 14 + +#define WZRHPG300NH_GPIO_EXP_BASE 32 +#define WZRHPG300NH_GPIO_BTN_AOSS (WZRHPG300NH_GPIO_EXP_BASE + 0) +#define WZRHPG300NH_GPIO_BTN_RESET (WZRHPG300NH_GPIO_EXP_BASE + 1) +#define WZRHPG300NH_GPIO_BTN_ROUTER_ON (WZRHPG300NH_GPIO_EXP_BASE + 2) +#define WZRHPG300NH_GPIO_BTN_QOS_ON (WZRHPG300NH_GPIO_EXP_BASE + 3) +#define WZRHPG300NH_GPIO_BTN_USB (WZRHPG300NH_GPIO_EXP_BASE + 5) +#define WZRHPG300NH_GPIO_BTN_ROUTER_AUTO (WZRHPG300NH_GPIO_EXP_BASE + 6) +#define WZRHPG300NH_GPIO_BTN_QOS_OFF (WZRHPG300NH_GPIO_EXP_BASE + 7) + +#define WZRHPG300NH_KEYS_POLL_INTERVAL 20 /* msecs */ +#define WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPG300NH_KEYS_POLL_INTERVAL) + +#define WZRHPG300NH_MAC_OFFSET 0x20c + +static struct mtd_partition wzrhpg300nh_flash_partitions[] = { + { + .name = "u-boot", + .offset = 0, + .size = 0x0040000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "u-boot-env", + .offset = 0x0040000, + .size = 0x0020000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "kernel", + .offset = 0x0060000, + .size = 0x0100000, + }, { + .name = "rootfs", + .offset = 0x0160000, + .size = 0x1e60000, + }, { + .name = "user_property", + .offset = 0x1fc0000, + .size = 0x0020000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "art", + .offset = 0x1fe0000, + .size = 0x0020000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "firmware", + .offset = 0x0060000, + .size = 0x1f60000, + } +}; + +static struct physmap_flash_data wzrhpg300nh_flash_data = { + .width = 2, + .parts = wzrhpg300nh_flash_partitions, + .nr_parts = ARRAY_SIZE(wzrhpg300nh_flash_partitions), +}; + +#define WZRHPG300NH_FLASH_BASE 0x1e000000 +#define WZRHPG300NH_FLASH_SIZE (32 * 1024 * 1024) + +static struct resource wzrhpg300nh_flash_resources[] = { + [0] = { + .start = WZRHPG300NH_FLASH_BASE, + .end = WZRHPG300NH_FLASH_BASE + WZRHPG300NH_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device wzrhpg300nh_flash_device = { + .name = "physmap-flash", + .id = -1, + .resource = wzrhpg300nh_flash_resources, + .num_resources = ARRAY_SIZE(wzrhpg300nh_flash_resources), + .dev = { + .platform_data = &wzrhpg300nh_flash_data, + } +}; + +static struct gpio_led wzrhpg300nh_leds_gpio[] __initdata = { + { + .name = "buffalo:orange:security", + .gpio = WZRHPG300NH_GPIO_LED_SECURITY, + .active_low = 1, + }, { + .name = "buffalo:green:wireless", + .gpio = WZRHPG300NH_GPIO_LED_WIRELESS, + .active_low = 1, + }, { + .name = "buffalo:green:router", + .gpio = WZRHPG300NH_GPIO_LED_ROUTER, + .active_low = 1, + }, { + .name = "buffalo:red:diag", + .gpio = WZRHPG300NH_GPIO_LED_DIAG, + .active_low = 1, + }, { + .name = "buffalo:blue:usb", + .gpio = WZRHPG300NH_GPIO_LED_USB, + .active_low = 1, + } +}; + +static struct gpio_keys_button wzrhpg300nh_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, + .gpio = WZRHPG300NH_GPIO_BTN_RESET, + .active_low = 1, + }, { + .desc = "aoss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, + .gpio = WZRHPG300NH_GPIO_BTN_AOSS, + .active_low = 1, + }, { + .desc = "usb", + .type = EV_KEY, + .code = BTN_2, + .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, + .gpio = WZRHPG300NH_GPIO_BTN_USB, + .active_low = 1, + }, { + .desc = "qos_on", + .type = EV_KEY, + .code = BTN_3, + .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, + .gpio = WZRHPG300NH_GPIO_BTN_QOS_ON, + .active_low = 0, + }, { + .desc = "qos_off", + .type = EV_KEY, + .code = BTN_4, + .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, + .gpio = WZRHPG300NH_GPIO_BTN_QOS_OFF, + .active_low = 0, + }, { + .desc = "router_on", + .type = EV_KEY, + .code = BTN_5, + .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, + .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_ON, + .active_low = 0, + }, { + .desc = "router_auto", + .type = EV_KEY, + .code = BTN_6, + .debounce_interval = WZRHPG300NH_KEYS_DEBOUNCE_INTERVAL, + .gpio = WZRHPG300NH_GPIO_BTN_ROUTER_AUTO, + .active_low = 0, + } +}; + +static struct nxp_74hc153_platform_data wzrhpg300nh_74hc153_data = { + .gpio_base = WZRHPG300NH_GPIO_EXP_BASE, + .gpio_pin_s0 = WZRHPG300NH_GPIO_74HC153_S0, + .gpio_pin_s1 = WZRHPG300NH_GPIO_74HC153_S1, + .gpio_pin_1y = WZRHPG300NH_GPIO_74HC153_1Y, + .gpio_pin_2y = WZRHPG300NH_GPIO_74HC153_2Y, +}; + +static struct platform_device wzrhpg300nh_74hc153_device = { + .name = NXP_74HC153_DRIVER_NAME, + .id = -1, + .dev = { + .platform_data = &wzrhpg300nh_74hc153_data, + } +}; + +static struct rtl8366_platform_data wzrhpg300nh_rtl8366_data = { + .gpio_sda = WZRHPG300NH_GPIO_RTL8366_SDA, + .gpio_sck = WZRHPG300NH_GPIO_RTL8366_SCK, +}; + +static struct platform_device wzrhpg300nh_rtl8366s_device = { + .name = RTL8366S_DRIVER_NAME, + .id = -1, + .dev = { + .platform_data = &wzrhpg300nh_rtl8366_data, + } +}; + +static struct platform_device wzrhpg300nh_rtl8366rb_device = { + .name = RTL8366RB_DRIVER_NAME, + .id = -1, + .dev = { + .platform_data = &wzrhpg300nh_rtl8366_data, + } +}; + +static void __init wzrhpg300nh_setup(void) +{ + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); + u8 *mac = eeprom + WZRHPG300NH_MAC_OFFSET; + bool hasrtl8366rb = false; + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); + + if (rtl8366_smi_detect(&wzrhpg300nh_rtl8366_data) == RTL8366_TYPE_RB) + hasrtl8366rb = true; + + if (hasrtl8366rb) { + ath79_eth0_pll_data.pll_1000 = 0x1f000000; + ath79_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366rb_device.dev; + ath79_eth1_pll_data.pll_1000 = 0x100; + ath79_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366rb_device.dev; + } else { + ath79_eth0_pll_data.pll_1000 = 0x1e000100; + ath79_eth0_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev; + ath79_eth1_pll_data.pll_1000 = 0x1e000100; + ath79_eth1_data.mii_bus_dev = &wzrhpg300nh_rtl8366s_device.dev; + } + + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth1_data.phy_mask = 0x10; + + ath79_register_eth(0); + ath79_register_eth(1); + + ath79_register_usb(); + ath79_register_wmac(eeprom, NULL); + + platform_device_register(&wzrhpg300nh_74hc153_device); + platform_device_register(&wzrhpg300nh_flash_device); + + if (hasrtl8366rb) + platform_device_register(&wzrhpg300nh_rtl8366rb_device); + else + platform_device_register(&wzrhpg300nh_rtl8366s_device); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(wzrhpg300nh_leds_gpio), + wzrhpg300nh_leds_gpio); + + ath79_register_gpio_keys_polled(-1, WZRHPG300NH_KEYS_POLL_INTERVAL, + ARRAY_SIZE(wzrhpg300nh_gpio_keys), + wzrhpg300nh_gpio_keys); + +} + +MIPS_MACHINE(ATH79_MACH_WZR_HP_G300NH, "WZR-HP-G300NH", + "Buffalo WZR-HP-G300NH", wzrhpg300nh_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh2.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh2.c new file mode 100644 index 000000000..6c850cee5 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g300nh2.c @@ -0,0 +1,177 @@ +/* + * Buffalo WZR-HP-G300NH2 board support + * + * Copyright (C) 2011 Felix Fietkau + * Copyright (C) 2011 Mark Deneen + * + * This program 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. + */ + +#include +#include +#include + +#include + +#include "dev-ap9x-pci.h" +#include "dev-eth.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-m25p80.h" +#include "dev-usb.h" +#include "machtypes.h" + +#define WZRHPG300NH2_MAC_OFFSET 0x20c +#define WZRHPG300NH2_KEYS_POLL_INTERVAL 20 /* msecs */ +#define WZRHPG300NH2_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPG300NH2_KEYS_POLL_INTERVAL) + +static struct mtd_partition wzrhpg300nh2_flash_partitions[] = { + { + .name = "u-boot", + .offset = 0, + .size = 0x0040000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "u-boot-env", + .offset = 0x0040000, + .size = 0x0010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "art", + .offset = 0x0050000, + .size = 0x0010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "kernel", + .offset = 0x0060000, + .size = 0x0100000, + }, { + .name = "rootfs", + .offset = 0x0160000, + .size = 0x1e90000, + }, { + .name = "user_property", + .offset = 0x1ff0000, + .size = 0x0010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "firmware", + .offset = 0x0060000, + .size = 0x1f90000, + } +}; + +static struct flash_platform_data wzrhpg300nh2_flash_data = { + .parts = wzrhpg300nh2_flash_partitions, + .nr_parts = ARRAY_SIZE(wzrhpg300nh2_flash_partitions), +}; + +static struct gpio_led wzrhpg300nh2_leds_gpio[] __initdata = { + { + .name = "buffalo:red:diag", + .gpio = 16, + .active_low = 1, + }, +}; + +static struct gpio_led wzrhpg300nh2_wmac_leds_gpio[] = { + { + .name = "buffalo:blue:usb", + .gpio = 4, + .active_low = 1, + }, + { + .name = "buffalo:orange:security", + .gpio = 6, + .active_low = 1, + }, + { + .name = "buffalo:green:router", + .gpio = 7, + .active_low = 1, + }, + { + .name = "buffalo:blue:movie_engine_on", + .gpio = 8, + .active_low = 1, + }, + { + .name = "buffalo:blue:movie_engine_off", + .gpio = 9, + .active_low = 1, + }, +}; + +/* The AOSS button is wmac gpio 12 */ +static struct gpio_keys_button wzrhpg300nh2_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = WZRHPG300NH2_KEYS_DEBOUNCE_INTERVAL, + .gpio = 1, + .active_low = 1, + }, { + .desc = "usb", + .type = EV_KEY, + .code = BTN_2, + .debounce_interval = WZRHPG300NH2_KEYS_DEBOUNCE_INTERVAL, + .gpio = 7, + .active_low = 1, + }, { + .desc = "qos", + .type = EV_KEY, + .code = BTN_3, + .debounce_interval = WZRHPG300NH2_KEYS_DEBOUNCE_INTERVAL, + .gpio = 11, + .active_low = 0, + }, { + .desc = "router_on", + .type = EV_KEY, + .code = BTN_5, + .debounce_interval = WZRHPG300NH2_KEYS_DEBOUNCE_INTERVAL, + .gpio = 8, + .active_low = 0, + }, +}; + +static void __init wzrhpg300nh2_setup(void) +{ + + u8 *eeprom = (u8 *) KSEG1ADDR(0x1f051000); + u8 *mac0 = eeprom + WZRHPG300NH2_MAC_OFFSET; + /* There is an eth1 but it is not connected to the switch */ + + ath79_register_m25p80_multi(&wzrhpg300nh2_flash_data); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac0, 0); + ath79_register_mdio(0, ~(BIT(0))); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac0, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_eth0_data.phy_mask = BIT(0); + + ath79_register_eth(0); + + /* gpio13 is usb power. Turn it on. */ + ath79_set_usb_power_gpio(13, GPIOF_OUT_INIT_HIGH, "USB power"); + ath79_register_usb(); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(wzrhpg300nh2_leds_gpio), + wzrhpg300nh2_leds_gpio); + ath79_register_gpio_keys_polled(-1, WZRHPG300NH2_KEYS_POLL_INTERVAL, + ARRAY_SIZE(wzrhpg300nh2_gpio_keys), + wzrhpg300nh2_gpio_keys); + ap9x_pci_setup_wmac_led_pin(0, 5); + ap9x_pci_setup_wmac_leds(0, wzrhpg300nh2_wmac_leds_gpio, + ARRAY_SIZE(wzrhpg300nh2_wmac_leds_gpio)); + + ap91_pci_init(eeprom, mac0); +} + +MIPS_MACHINE(ATH79_MACH_WZR_HP_G300NH2, "WZR-HP-G300NH2", + "Buffalo WZR-HP-G300NH2", wzrhpg300nh2_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g450h.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g450h.c new file mode 100644 index 000000000..b5292db54 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wzr-hp-g450h.c @@ -0,0 +1,169 @@ +/* + * Buffalo WZR-HP-G450G board support + * + * Copyright (C) 2011 Felix Fietkau + * Copyright (C) 2008-2012 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#include +#include +#include + +#include + +#include "dev-eth.h" +#include "dev-m25p80.h" +#include "dev-ap9x-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "dev-usb.h" +#include "machtypes.h" + +#define WZRHPG450H_KEYS_POLL_INTERVAL 20 /* msecs */ +#define WZRHPG450H_KEYS_DEBOUNCE_INTERVAL (3 * WZRHPG450H_KEYS_POLL_INTERVAL) + +static struct mtd_partition wzrhpg450h_partitions[] = { + { + .name = "u-boot", + .offset = 0, + .size = 0x0040000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "u-boot-env", + .offset = 0x0040000, + .size = 0x0010000, + }, { + .name = "ART", + .offset = 0x0050000, + .size = 0x0010000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "uImage", + .offset = 0x0060000, + .size = 0x0100000, + }, { + .name = "rootfs", + .offset = 0x0160000, + .size = 0x1e80000, + }, { + .name = "user_property", + .offset = 0x1fe0000, + .size = 0x0020000, + }, { + .name = "firmware", + .offset = 0x0060000, + .size = 0x1f80000, + } +}; + +static struct flash_platform_data wzrhpg450h_flash_data = { + .parts = wzrhpg450h_partitions, + .nr_parts = ARRAY_SIZE(wzrhpg450h_partitions), +}; + +static struct gpio_led wzrhpg450h_leds_gpio[] __initdata = { + { + .name = "buffalo:red:diag", + .gpio = 14, + .active_low = 1, + }, + { + .name = "buffalo:orange:security", + .gpio = 13, + .active_low = 1, + }, +}; + + +static struct gpio_led wzrhpg450h_wmac_leds_gpio[] = { + { + .name = "buffalo:blue:movie_engine", + .gpio = 13, + .active_low = 1, + }, + { + .name = "buffalo:green:router", + .gpio = 14, + .active_low = 1, + }, +}; + +static struct gpio_keys_button wzrhpg450h_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = WZRHPG450H_KEYS_DEBOUNCE_INTERVAL, + .gpio = 6, + .active_low = 1, + }, { + .desc = "usb", + .type = EV_KEY, + .code = BTN_2, + .debounce_interval = WZRHPG450H_KEYS_DEBOUNCE_INTERVAL, + .gpio = 1, + .active_low = 1, + }, { + .desc = "aoss", + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .debounce_interval = WZRHPG450H_KEYS_DEBOUNCE_INTERVAL, + .gpio = 8, + .active_low = 1, + }, { + .desc = "movie_engine", + .type = EV_KEY, + .code = BTN_6, + .debounce_interval = WZRHPG450H_KEYS_DEBOUNCE_INTERVAL, + .gpio = 7, + .active_low = 0, + }, { + .desc = "router_off", + .type = EV_KEY, + .code = BTN_5, + .debounce_interval = WZRHPG450H_KEYS_DEBOUNCE_INTERVAL, + .gpio = 12, + .active_low = 0, + } +}; + + +static void __init wzrhpg450h_init(void) +{ + u8 *ee = (u8 *) KSEG1ADDR(0x1f051000); + u8 *mac = (u8 *) ee + 2; + + ath79_register_m25p80_multi(&wzrhpg450h_flash_data); + + ath79_register_mdio(0, ~BIT(0)); + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; + ath79_eth0_data.speed = SPEED_1000; + ath79_eth0_data.duplex = DUPLEX_FULL; + ath79_eth0_data.phy_mask = BIT(0); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(wzrhpg450h_leds_gpio), + wzrhpg450h_leds_gpio); + + ath79_register_gpio_keys_polled(-1, WZRHPG450H_KEYS_POLL_INTERVAL, + ARRAY_SIZE(wzrhpg450h_gpio_keys), + wzrhpg450h_gpio_keys); + + ath79_register_eth(0); + + ath79_set_usb_power_gpio(16, GPIOF_OUT_INIT_HIGH, "USB power"); + ath79_register_usb(); + + ap91_pci_init(ee, NULL); + ap9x_pci_setup_wmac_led_pin(0, 15); + ap9x_pci_setup_wmac_leds(0, wzrhpg450h_wmac_leds_gpio, + ARRAY_SIZE(wzrhpg450h_wmac_leds_gpio)); +} + +MIPS_MACHINE(ATH79_MACH_WZR_HP_G450H, "WZR-HP-G450H", "Buffalo WZR-HP-G450H", + wzrhpg450h_init); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-zcn-1523h.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-zcn-1523h.c new file mode 100644 index 000000000..3a6fe21ed --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-zcn-1523h.c @@ -0,0 +1,157 @@ +/* + * Zcomax ZCN-1523H-2-8/5-16 board support + * + * Copyright (C) 2010-2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include + +#include "common.h" +#include "dev-eth.h" +#include "dev-m25p80.h" +#include "dev-ap9x-pci.h" +#include "dev-gpio-buttons.h" +#include "dev-leds-gpio.h" +#include "machtypes.h" + +#define ZCN_1523H_GPIO_BTN_RESET 0 +#define ZCN_1523H_GPIO_LED_INIT 11 +#define ZCN_1523H_GPIO_LED_LAN1 17 + +#define ZCN_1523H_2_GPIO_LED_WEAK 13 +#define ZCN_1523H_2_GPIO_LED_MEDIUM 14 +#define ZCN_1523H_2_GPIO_LED_STRONG 15 + +#define ZCN_1523H_5_GPIO_LED_UNKNOWN 1 +#define ZCN_1523H_5_GPIO_LED_LAN2 13 +#define ZCN_1523H_5_GPIO_LED_WEAK 14 +#define ZCN_1523H_5_GPIO_LED_MEDIUM 15 +#define ZCN_1523H_5_GPIO_LED_STRONG 16 + +#define ZCN_1523H_KEYS_POLL_INTERVAL 20 /* msecs */ +#define ZCN_1523H_KEYS_DEBOUNCE_INTERVAL (3 * ZCN_1523H_KEYS_POLL_INTERVAL) + +static struct gpio_keys_button zcn_1523h_gpio_keys[] __initdata = { + { + .desc = "reset", + .type = EV_KEY, + .code = KEY_RESTART, + .debounce_interval = ZCN_1523H_KEYS_DEBOUNCE_INTERVAL, + .gpio = ZCN_1523H_GPIO_BTN_RESET, + .active_low = 1, + } +}; + +static struct gpio_led zcn_1523h_leds_gpio[] __initdata = { + { + .name = "zcn-1523h:amber:init", + .gpio = ZCN_1523H_GPIO_LED_INIT, + .active_low = 1, + }, { + .name = "zcn-1523h:green:lan1", + .gpio = ZCN_1523H_GPIO_LED_LAN1, + .active_low = 1, + } +}; + +static struct gpio_led zcn_1523h_2_leds_gpio[] __initdata = { + { + .name = "zcn-1523h:red:weak", + .gpio = ZCN_1523H_2_GPIO_LED_WEAK, + .active_low = 1, + }, { + .name = "zcn-1523h:amber:medium", + .gpio = ZCN_1523H_2_GPIO_LED_MEDIUM, + .active_low = 1, + }, { + .name = "zcn-1523h:green:strong", + .gpio = ZCN_1523H_2_GPIO_LED_STRONG, + .active_low = 1, + } +}; + +static struct gpio_led zcn_1523h_5_leds_gpio[] __initdata = { + { + .name = "zcn-1523h:red:weak", + .gpio = ZCN_1523H_5_GPIO_LED_WEAK, + .active_low = 1, + }, { + .name = "zcn-1523h:amber:medium", + .gpio = ZCN_1523H_5_GPIO_LED_MEDIUM, + .active_low = 1, + }, { + .name = "zcn-1523h:green:strong", + .gpio = ZCN_1523H_5_GPIO_LED_STRONG, + .active_low = 1, + }, { + .name = "zcn-1523h:green:lan2", + .gpio = ZCN_1523H_5_GPIO_LED_LAN2, + .active_low = 1, + }, { + .name = "zcn-1523h:amber:unknown", + .gpio = ZCN_1523H_5_GPIO_LED_UNKNOWN, + } +}; + +static void __init zcn_1523h_generic_setup(void) +{ + u8 *mac = (u8 *) KSEG1ADDR(0x1f7e0004); + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); + + ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | + AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); + + ath79_register_m25p80(NULL); + + ath79_register_leds_gpio(0, ARRAY_SIZE(zcn_1523h_leds_gpio), + zcn_1523h_leds_gpio); + + ath79_register_gpio_keys_polled(-1, ZCN_1523H_KEYS_POLL_INTERVAL, + ARRAY_SIZE(zcn_1523h_gpio_keys), + zcn_1523h_gpio_keys); + + ap91_pci_init(ee, mac); + + ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); + ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); + + ath79_register_mdio(0, 0x0); + + /* LAN1 port */ + ath79_register_eth(0); +} + +static void __init zcn_1523h_2_setup(void) +{ + zcn_1523h_generic_setup(); + ap9x_pci_setup_wmac_gpio(0, BIT(9), 0); + + ath79_register_leds_gpio(1, ARRAY_SIZE(zcn_1523h_2_leds_gpio), + zcn_1523h_2_leds_gpio); +} + +MIPS_MACHINE(ATH79_MACH_ZCN_1523H_2, "ZCN-1523H-2", "Zcomax ZCN-1523H-2", + zcn_1523h_2_setup); + +static void __init zcn_1523h_5_setup(void) +{ + zcn_1523h_generic_setup(); + ap9x_pci_setup_wmac_gpio(0, BIT(8), 0); + + ath79_register_leds_gpio(1, ARRAY_SIZE(zcn_1523h_5_leds_gpio), + zcn_1523h_5_leds_gpio); + + /* LAN2 port */ + ath79_register_eth(1); +} + +MIPS_MACHINE(ATH79_MACH_ZCN_1523H_5, "ZCN-1523H-5", "Zcomax ZCN-1523H-5", + zcn_1523h_5_setup); diff --git a/target/linux/ar71xx/files/arch/mips/ath79/nvram.c b/target/linux/ar71xx/files/arch/mips/ath79/nvram.c new file mode 100644 index 000000000..43911b8ac --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/nvram.c @@ -0,0 +1,75 @@ +/* + * Atheros AR71xx minimal nvram support + * + * Copyright (C) 2009 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include +#include +#include + +#include "nvram.h" + +char *ath79_nvram_find_var(const char *name, const char *buf, unsigned buf_len) +{ + unsigned len = strlen(name); + char *cur, *last; + + if (buf_len == 0 || len == 0) + return NULL; + + if (buf_len < len) + return NULL; + + if (len == 1) + return memchr(buf, (int) *name, buf_len); + + last = (char *) buf + buf_len - len; + for (cur = (char *) buf; cur <= last; cur++) + if (cur[0] == name[0] && memcmp(cur, name, len) == 0) + return cur + len; + + return NULL; +} + +int ath79_nvram_parse_mac_addr(const char *nvram, unsigned nvram_len, + const char *name, char *mac) +{ + char *buf; + char *mac_str; + int ret; + int t; + + buf = vmalloc(nvram_len); + if (!buf) + return -ENOMEM; + + memcpy(buf, nvram, nvram_len); + buf[nvram_len - 1] = '\0'; + + mac_str = ath79_nvram_find_var(name, buf, nvram_len); + if (!mac_str) { + ret = -EINVAL; + goto free; + } + + t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", + &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); + + if (t != 6) { + ret = -EINVAL; + goto free; + } + + ret = 0; + +free: + vfree(buf); + return ret; +} diff --git a/target/linux/ar71xx/files/arch/mips/ath79/nvram.h b/target/linux/ar71xx/files/arch/mips/ath79/nvram.h new file mode 100644 index 000000000..75151d4a3 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/nvram.h @@ -0,0 +1,19 @@ +/* + * Atheros AR71xx minimal nvram support + * + * Copyright (C) 2009 Gabor Juhos + * + * This program 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. + */ + +#ifndef _ATH79_NVRAM_H +#define _ATH79_NVRAM_H + +char *ath79_nvram_find_var(const char *name, const char *buf, + unsigned buf_len); +int ath79_nvram_parse_mac_addr(const char *nvram, unsigned nvram_len, + const char *name, char *mac); + +#endif /* _ATH79_NVRAM_H */ diff --git a/target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.c b/target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.c new file mode 100644 index 000000000..fcca1d2ea --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.c @@ -0,0 +1,123 @@ +/* + * Atheros AP94 reference board PCI initialization + * + * Copyright (C) 2009-2010 Gabor Juhos + * + * This program 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. + */ + +#include +#include + +#include +#include + +struct ath9k_fixup { + u16 *cal_data; + unsigned slot; +}; + +static int ath9k_num_fixups; +static struct ath9k_fixup ath9k_fixups[2]; + +static void ath9k_pci_fixup(struct pci_dev *dev) +{ + void __iomem *mem; + u16 *cal_data = NULL; + u16 cmd; + u32 bar0; + u32 val; + unsigned i; + + for (i = 0; i < ath9k_num_fixups; i++) { + if (ath9k_fixups[i].cal_data == NULL) + continue; + + if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn)) + continue; + + cal_data = ath9k_fixups[i].cal_data; + break; + } + + if (cal_data == NULL) + return; + + if (*cal_data != 0xa55a) { + pr_err("pci %s: invalid calibration data\n", pci_name(dev)); + return; + } + + pr_info("pci %s: fixup device configuration\n", pci_name(dev)); + + mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000); + if (!mem) { + pr_err("pci %s: ioremap error\n", pci_name(dev)); + return; + } + + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); + + switch (ath79_soc) { + case ATH79_SOC_AR7161: + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, + AR71XX_PCI_MEM_BASE); + break; + case ATH79_SOC_AR7240: + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff); + break; + + case ATH79_SOC_AR7241: + case ATH79_SOC_AR7242: + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x1000ffff); + break; + + default: + BUG(); + } + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pci_write_config_word(dev, PCI_COMMAND, cmd); + + /* set pointer to first reg address */ + cal_data += 3; + while (*cal_data != 0xffff) { + u32 reg; + reg = *cal_data++; + val = *cal_data++; + val |= (*cal_data++) << 16; + + __raw_writel(val, mem + reg); + udelay(100); + } + + pci_read_config_dword(dev, PCI_VENDOR_ID, &val); + dev->vendor = val & 0xffff; + dev->device = (val >> 16) & 0xffff; + + pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); + dev->revision = val & 0xff; + dev->class = val >> 8; /* upper 3 bytes */ + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); + pci_write_config_word(dev, PCI_COMMAND, cmd); + + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0); + + iounmap(mem); +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup); + +void __init pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) +{ + if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups)) + return; + + ath9k_fixups[ath9k_num_fixups].slot = slot; + ath9k_fixups[ath9k_num_fixups].cal_data = cal_data; + ath9k_num_fixups++; +} diff --git a/target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.h b/target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.h new file mode 100644 index 000000000..5794941f0 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.h @@ -0,0 +1,6 @@ +#ifndef _PCI_ATH9K_FIXUP +#define _PCI_ATH9K_FIXUP + +void pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) __init; + +#endif /* _PCI_ATH9K_FIXUP */ diff --git a/target/linux/ar71xx/files/arch/mips/ath79/routerboot.c b/target/linux/ar71xx/files/arch/mips/ath79/routerboot.c new file mode 100644 index 000000000..3c6f9aaeb --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/routerboot.c @@ -0,0 +1,100 @@ +/* + * RouterBoot helper routines + * + * Copyright (C) 2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include + +#include "routerboot.h" + +static u32 get_u32(void *buf) +{ + u8 *p = buf; + + return ((u32) p[3] + ((u32) p[2] << 8) + ((u32) p[1] << 16) + + ((u32) p[0] << 24)); +} + +static u16 get_u16(void *buf) +{ + u8 *p = buf; + + return (u16) p[1] + ((u16) p[0] << 8); +} + +__init int +routerboot_find_tag(u8 *buf, unsigned int buflen, u16 tag_id, + u8 **tag_data, u16 *tag_len) +{ + uint32_t magic; + int ret; + + if (buflen < 4) + return -EINVAL; + + magic = get_u32(buf); + switch (magic) { + case RB_MAGIC_HARD: + /* skip magic value */ + buf += 4; + buflen -= 4; + break; + + case RB_MAGIC_SOFT: + if (buflen < 8) + return -EINVAL; + + /* skip magic and CRC value */ + buf += 8; + buflen -= 8; + + break; + + default: + return -EINVAL; + } + + ret = -ENOENT; + while (buflen > 2) { + u16 id; + u16 len; + + len = get_u16(buf); + buf += 2; + buflen -= 2; + + if (buflen < 2) + break; + + id = get_u16(buf); + buf += 2; + buflen -= 2; + + if (id == RB_ID_TERMINATOR) + break; + + if (buflen < len) + break; + + if (id == tag_id) { + if (tag_len) + *tag_len = len; + if (tag_data) + *tag_data = buf; + ret = 0; + break; + } + + buf += len; + buflen -= len; + } + + return ret; +} diff --git a/target/linux/ar71xx/files/arch/mips/ath79/routerboot.h b/target/linux/ar71xx/files/arch/mips/ath79/routerboot.h new file mode 100644 index 000000000..9a4dde59e --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/routerboot.h @@ -0,0 +1,26 @@ +/* + * RouterBoot definitions + * + * Copyright (C) 2012 Gabor Juhos + * + * This program 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. + */ + +#ifndef _ATH79_ROUTERBOOT_H_ +#define _ATH79_ROUTERBOOT_H_ + +#ifdef CONFIG_ATH79_ROUTERBOOT +int routerboot_find_tag(u8 *buf, unsigned int buflen, u16 tag_id, + u8 **tag_data, u16 *tag_len); +#else +static inline int +routerboot_find_tag(u8 *buf, unsigned int buflen, u16 tag_id, + u8 **tag_data, u16 *tag_len) +{ + return -ENOENT; +} +#endif + +#endif /* _ATH79_ROUTERBOOT_H_ */ diff --git a/target/linux/ar71xx/files/arch/mips/include/asm/fw/myloader/myloader.h b/target/linux/ar71xx/files/arch/mips/include/asm/fw/myloader/myloader.h new file mode 100644 index 000000000..8a99d566d --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/include/asm/fw/myloader/myloader.h @@ -0,0 +1,34 @@ +/* + * Compex's MyLoader specific definitions + * + * Copyright (C) 2006-2008 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _ASM_MIPS_FW_MYLOADER_H +#define _ASM_MIPS_FW_MYLOADER_H + +#include + +struct myloader_info { + uint32_t vid; + uint32_t did; + uint32_t svid; + uint32_t sdid; + uint8_t macs[MYLO_ETHADDR_COUNT][6]; +}; + +#ifdef CONFIG_MYLOADER +extern struct myloader_info *myloader_get_info(void) __init; +#else +static inline struct myloader_info *myloader_get_info(void) +{ + return NULL; +} +#endif /* CONFIG_MYLOADER */ + +#endif /* _ASM_MIPS_FW_MYLOADER_H */ diff --git a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h new file mode 100644 index 000000000..656a6ef86 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h @@ -0,0 +1,60 @@ +/* + * Atheros AR71xx SoC specific platform data definitions + * + * Copyright (C) 2008-2012 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This program 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. + */ + +#ifndef __ASM_MACH_ATH79_PLATFORM_H +#define __ASM_MACH_ATH79_PLATFORM_H + +#include +#include +#include +#include + +struct ag71xx_switch_platform_data { + u8 phy4_mii_en:1; + u8 phy_poll_mask; +}; + +struct ag71xx_platform_data { + phy_interface_t phy_if_mode; + u32 phy_mask; + int speed; + int duplex; + u32 reset_bit; + u8 mac_addr[ETH_ALEN]; + struct device *mii_bus_dev; + + u8 has_gbit:1; + u8 is_ar91xx:1; + u8 is_ar7240:1; + u8 is_ar724x:1; + u8 has_ar8216:1; + + struct ag71xx_switch_platform_data *switch_data; + + void (*ddr_flush)(void); + void (*set_speed)(int speed); + + u32 fifo_cfg1; + u32 fifo_cfg2; + u32 fifo_cfg3; +}; + +struct ag71xx_mdio_platform_data { + u32 phy_mask; + u8 builtin_switch:1; + u8 is_ar7240:1; + u8 is_ar9330:1; + u8 is_ar934x:1; + unsigned long mdio_clock; + unsigned long ref_clock; +}; + +#endif /* __ASM_MACH_ATH79_PLATFORM_H */ diff --git a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/mach-rb750.h b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/mach-rb750.h new file mode 100644 index 000000000..50d5a2097 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/mach-rb750.h @@ -0,0 +1,84 @@ +/* + * MikroTik RouterBOARD 750 definitions + * + * Copyright (C) 2010-2012 Gabor Juhos + * + * This program 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. + */ +#ifndef _MACH_RB750_H +#define _MACH_RB750_H + +#include + +#define RB750_GPIO_LVC573_LE 0 /* Latch enable on LVC573 */ +#define RB750_GPIO_NAND_IO0 1 /* NAND I/O 0 */ +#define RB750_GPIO_NAND_IO1 2 /* NAND I/O 1 */ +#define RB750_GPIO_NAND_IO2 3 /* NAND I/O 2 */ +#define RB750_GPIO_NAND_IO3 4 /* NAND I/O 3 */ +#define RB750_GPIO_NAND_IO4 5 /* NAND I/O 4 */ +#define RB750_GPIO_NAND_IO5 6 /* NAND I/O 5 */ +#define RB750_GPIO_NAND_IO6 7 /* NAND I/O 6 */ +#define RB750_GPIO_NAND_IO7 8 /* NAND I/O 7 */ +#define RB750_GPIO_NAND_NCE 11 /* NAND Chip Enable (active low) */ +#define RB750_GPIO_NAND_RDY 12 /* NAND Ready */ +#define RB750_GPIO_NAND_CLE 14 /* NAND Command Latch Enable */ +#define RB750_GPIO_NAND_ALE 15 /* NAND Address Latch Enable */ +#define RB750_GPIO_NAND_NRE 16 /* NAND Read Enable (active low) */ +#define RB750_GPIO_NAND_NWE 17 /* NAND Write Enable (active low) */ + +#define RB750_GPIO_BTN_RESET 1 +#define RB750_GPIO_SPI_CS0 2 +#define RB750_GPIO_LED_ACT 12 +#define RB750_GPIO_LED_PORT1 13 +#define RB750_GPIO_LED_PORT2 14 +#define RB750_GPIO_LED_PORT3 15 +#define RB750_GPIO_LED_PORT4 16 +#define RB750_GPIO_LED_PORT5 17 + +#define RB750_LED_ACT BIT(RB750_GPIO_LED_ACT) +#define RB750_LED_PORT1 BIT(RB750_GPIO_LED_PORT1) +#define RB750_LED_PORT2 BIT(RB750_GPIO_LED_PORT2) +#define RB750_LED_PORT3 BIT(RB750_GPIO_LED_PORT3) +#define RB750_LED_PORT4 BIT(RB750_GPIO_LED_PORT4) +#define RB750_LED_PORT5 BIT(RB750_GPIO_LED_PORT5) +#define RB750_NAND_NCE BIT(RB750_GPIO_NAND_NCE) + +#define RB750_LVC573_LE BIT(RB750_GPIO_LVC573_LE) + +#define RB750_LED_BITS (RB750_LED_PORT1 | RB750_LED_PORT2 | RB750_LED_PORT3 | \ + RB750_LED_PORT4 | RB750_LED_PORT5 | RB750_LED_ACT) + +#define RB7XX_GPIO_NAND_NCE 0 +#define RB7XX_GPIO_MON 9 +#define RB7XX_GPIO_LED_ACT 11 +#define RB7XX_GPIO_USB_POWERON 13 + +#define RB7XX_NAND_NCE BIT(RB7XX_GPIO_NAND_NCE) +#define RB7XX_LED_ACT BIT(RB7XX_GPIO_LED_ACT) +#define RB7XX_MONITOR BIT(RB7XX_GPIO_MON) +#define RB7XX_USB_POWERON BIT(RB7XX_GPIO_USB_POWERON) + +struct rb750_led_data { + char *name; + char *default_trigger; + u32 mask; + int active_low; +}; + +struct rb750_led_platform_data { + int num_leds; + struct rb750_led_data *leds; + void (*latch_change)(u32 clear, u32 set); +}; + +struct rb7xx_nand_platform_data { + u32 nce_line; + + void (*enable_pins)(void); + void (*disable_pins)(void); + void (*latch_change)(u32, u32); +}; + +#endif /* _MACH_RB750_H */ \ No newline at end of file diff --git a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/rb4xx_cpld.h b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/rb4xx_cpld.h new file mode 100644 index 000000000..5b17e94b6 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/rb4xx_cpld.h @@ -0,0 +1,48 @@ +/* + * SPI driver definitions for the CPLD chip on the Mikrotik RB4xx boards + * + * Copyright (C) 2010 Gabor Juhos + * + * This file was based on the patches for Linux 2.6.27.39 published by + * MikroTik for their RouterBoard 4xx series devices. + * + * This program 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 CPLD_GPIO_nLED1 0 +#define CPLD_GPIO_nLED2 1 +#define CPLD_GPIO_nLED3 2 +#define CPLD_GPIO_nLED4 3 +#define CPLD_GPIO_FAN 4 +#define CPLD_GPIO_ALE 5 +#define CPLD_GPIO_CLE 6 +#define CPLD_GPIO_nCE 7 +#define CPLD_GPIO_nLED5 8 + +#define CPLD_NUM_GPIOS 9 + +#define CPLD_CFG_nLED1 BIT(CPLD_GPIO_nLED1) +#define CPLD_CFG_nLED2 BIT(CPLD_GPIO_nLED2) +#define CPLD_CFG_nLED3 BIT(CPLD_GPIO_nLED3) +#define CPLD_CFG_nLED4 BIT(CPLD_GPIO_nLED4) +#define CPLD_CFG_FAN BIT(CPLD_GPIO_FAN) +#define CPLD_CFG_ALE BIT(CPLD_GPIO_ALE) +#define CPLD_CFG_CLE BIT(CPLD_GPIO_CLE) +#define CPLD_CFG_nCE BIT(CPLD_GPIO_nCE) +#define CPLD_CFG_nLED5 BIT(CPLD_GPIO_nLED5) + +struct rb4xx_cpld_platform_data { + unsigned gpio_base; +}; + +extern int rb4xx_cpld_change_cfg(unsigned mask, unsigned value); +extern int rb4xx_cpld_read(unsigned char *rx_buf, + const unsigned char *verify_buf, + unsigned cnt); +extern int rb4xx_cpld_read_from(unsigned addr, + unsigned char *rx_buf, + const unsigned char *verify_buf, + unsigned cnt); +extern int rb4xx_cpld_write(const unsigned char *buf, unsigned count); diff --git a/target/linux/ar71xx/files/drivers/gpio/gpio-nxp-74hc153.c b/target/linux/ar71xx/files/drivers/gpio/gpio-nxp-74hc153.c new file mode 100644 index 000000000..a5fec5ca7 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/gpio/gpio-nxp-74hc153.c @@ -0,0 +1,247 @@ +/* + * NXP 74HC153 - Dual 4-input multiplexer GPIO driver + * + * Copyright (C) 2010 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include + +#define NXP_74HC153_NUM_GPIOS 8 +#define NXP_74HC153_S0_MASK 0x1 +#define NXP_74HC153_S1_MASK 0x2 +#define NXP_74HC153_BANK_MASK 0x4 + +struct nxp_74hc153_chip { + struct device *parent; + struct gpio_chip gpio_chip; + struct mutex lock; +}; + +static struct nxp_74hc153_chip *gpio_to_nxp(struct gpio_chip *gc) +{ + return container_of(gc, struct nxp_74hc153_chip, gpio_chip); +} + +static int nxp_74hc153_direction_input(struct gpio_chip *gc, unsigned offset) +{ + return 0; +} + +static int nxp_74hc153_direction_output(struct gpio_chip *gc, + unsigned offset, int val) +{ + return -EINVAL; +} + +static int nxp_74hc153_get_value(struct gpio_chip *gc, unsigned offset) +{ + struct nxp_74hc153_chip *nxp; + struct nxp_74hc153_platform_data *pdata; + unsigned s0; + unsigned s1; + unsigned pin; + int ret; + + nxp = gpio_to_nxp(gc); + pdata = nxp->parent->platform_data; + + s0 = !!(offset & NXP_74HC153_S0_MASK); + s1 = !!(offset & NXP_74HC153_S1_MASK); + pin = (offset & NXP_74HC153_BANK_MASK) ? pdata->gpio_pin_2y + : pdata->gpio_pin_1y; + + mutex_lock(&nxp->lock); + gpio_set_value(pdata->gpio_pin_s0, s0); + gpio_set_value(pdata->gpio_pin_s1, s1); + ret = gpio_get_value(pin); + mutex_unlock(&nxp->lock); + + return ret; +} + +static void nxp_74hc153_set_value(struct gpio_chip *gc, + unsigned offset, int val) +{ + /* not supported */ +} + +static int __devinit nxp_74hc153_probe(struct platform_device *pdev) +{ + struct nxp_74hc153_platform_data *pdata; + struct nxp_74hc153_chip *nxp; + struct gpio_chip *gc; + int err; + + pdata = pdev->dev.platform_data; + if (pdata == NULL) { + dev_dbg(&pdev->dev, "no platform data specified\n"); + return -EINVAL; + } + + nxp = kzalloc(sizeof(struct nxp_74hc153_chip), GFP_KERNEL); + if (nxp == NULL) { + dev_err(&pdev->dev, "no memory for private data\n"); + return -ENOMEM; + } + + err = gpio_request(pdata->gpio_pin_s0, dev_name(&pdev->dev)); + if (err) { + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", + pdata->gpio_pin_s0, err); + goto err_free_nxp; + } + + err = gpio_request(pdata->gpio_pin_s1, dev_name(&pdev->dev)); + if (err) { + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", + pdata->gpio_pin_s1, err); + goto err_free_s0; + } + + err = gpio_request(pdata->gpio_pin_1y, dev_name(&pdev->dev)); + if (err) { + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", + pdata->gpio_pin_1y, err); + goto err_free_s1; + } + + err = gpio_request(pdata->gpio_pin_2y, dev_name(&pdev->dev)); + if (err) { + dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", + pdata->gpio_pin_2y, err); + goto err_free_1y; + } + + err = gpio_direction_output(pdata->gpio_pin_s0, 0); + if (err) { + dev_err(&pdev->dev, + "unable to set direction of gpio %u, err=%d\n", + pdata->gpio_pin_s0, err); + goto err_free_2y; + } + + err = gpio_direction_output(pdata->gpio_pin_s1, 0); + if (err) { + dev_err(&pdev->dev, + "unable to set direction of gpio %u, err=%d\n", + pdata->gpio_pin_s1, err); + goto err_free_2y; + } + + err = gpio_direction_input(pdata->gpio_pin_1y); + if (err) { + dev_err(&pdev->dev, + "unable to set direction of gpio %u, err=%d\n", + pdata->gpio_pin_1y, err); + goto err_free_2y; + } + + err = gpio_direction_input(pdata->gpio_pin_2y); + if (err) { + dev_err(&pdev->dev, + "unable to set direction of gpio %u, err=%d\n", + pdata->gpio_pin_2y, err); + goto err_free_2y; + } + + nxp->parent = &pdev->dev; + mutex_init(&nxp->lock); + + gc = &nxp->gpio_chip; + + gc->direction_input = nxp_74hc153_direction_input; + gc->direction_output = nxp_74hc153_direction_output; + gc->get = nxp_74hc153_get_value; + gc->set = nxp_74hc153_set_value; + gc->can_sleep = 1; + + gc->base = pdata->gpio_base; + gc->ngpio = NXP_74HC153_NUM_GPIOS; + gc->label = dev_name(nxp->parent); + gc->dev = nxp->parent; + gc->owner = THIS_MODULE; + + err = gpiochip_add(&nxp->gpio_chip); + if (err) { + dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err); + goto err_free_2y; + } + + platform_set_drvdata(pdev, nxp); + return 0; + +err_free_2y: + gpio_free(pdata->gpio_pin_2y); +err_free_1y: + gpio_free(pdata->gpio_pin_1y); +err_free_s1: + gpio_free(pdata->gpio_pin_s1); +err_free_s0: + gpio_free(pdata->gpio_pin_s0); +err_free_nxp: + kfree(nxp); + return err; +} + +static int nxp_74hc153_remove(struct platform_device *pdev) +{ + struct nxp_74hc153_chip *nxp = platform_get_drvdata(pdev); + struct nxp_74hc153_platform_data *pdata = pdev->dev.platform_data; + + if (nxp) { + int err; + + err = gpiochip_remove(&nxp->gpio_chip); + if (err) { + dev_err(&pdev->dev, + "unable to remove gpio chip, err=%d\n", + err); + return err; + } + + gpio_free(pdata->gpio_pin_2y); + gpio_free(pdata->gpio_pin_1y); + gpio_free(pdata->gpio_pin_s1); + gpio_free(pdata->gpio_pin_s0); + + kfree(nxp); + platform_set_drvdata(pdev, NULL); + } + + return 0; +} + +static struct platform_driver nxp_74hc153_driver = { + .probe = nxp_74hc153_probe, + .remove = __devexit_p(nxp_74hc153_remove), + .driver = { + .name = NXP_74HC153_DRIVER_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init nxp_74hc153_init(void) +{ + return platform_driver_register(&nxp_74hc153_driver); +} +subsys_initcall(nxp_74hc153_init); + +static void __exit nxp_74hc153_exit(void) +{ + platform_driver_unregister(&nxp_74hc153_driver); +} +module_exit(nxp_74hc153_exit); + +MODULE_AUTHOR("Gabor Juhos "); +MODULE_DESCRIPTION("GPIO expander driver for NXP 74HC153"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" NXP_74HC153_DRIVER_NAME); diff --git a/target/linux/ar71xx/files/drivers/leds/leds-rb750.c b/target/linux/ar71xx/files/drivers/leds/leds-rb750.c new file mode 100644 index 000000000..483e4fc96 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/leds/leds-rb750.c @@ -0,0 +1,144 @@ +/* + * LED driver for the RouterBOARD 750 + * + * Copyright (C) 2010 Gabor Juhos + * + * This program 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. + * + */ +#include +#include +#include +#include +#include +#include + +#include + +#define DRV_NAME "leds-rb750" + +struct rb750_led_dev { + struct led_classdev cdev; + u32 mask; + int active_low; + void (*latch_change)(u32 clear, u32 set); +}; + +struct rb750_led_drvdata { + struct rb750_led_dev *led_devs; + int num_leds; +}; + +static inline struct rb750_led_dev *to_rbled(struct led_classdev *led_cdev) +{ + return (struct rb750_led_dev *)container_of(led_cdev, + struct rb750_led_dev, cdev); +} + +static void rb750_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct rb750_led_dev *rbled = to_rbled(led_cdev); + int level; + + level = (value == LED_OFF) ? 0 : 1; + level ^= rbled->active_low; + + if (level) + rbled->latch_change(0, rbled->mask); + else + rbled->latch_change(rbled->mask, 0); +} + +static int __devinit rb750_led_probe(struct platform_device *pdev) +{ + struct rb750_led_platform_data *pdata; + struct rb750_led_drvdata *drvdata; + int ret = 0; + int i; + + pdata = pdev->dev.platform_data; + if (!pdata) + return -EINVAL; + + drvdata = kzalloc(sizeof(struct rb750_led_drvdata) + + sizeof(struct rb750_led_dev) * pdata->num_leds, + GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->num_leds = pdata->num_leds; + drvdata->led_devs = (struct rb750_led_dev *) &drvdata[1]; + + for (i = 0; i < drvdata->num_leds; i++) { + struct rb750_led_dev *rbled = &drvdata->led_devs[i]; + struct rb750_led_data *led_data = &pdata->leds[i]; + + rbled->cdev.name = led_data->name; + rbled->cdev.default_trigger = led_data->default_trigger; + rbled->cdev.brightness_set = rb750_led_brightness_set; + rbled->cdev.brightness = LED_OFF; + + rbled->mask = led_data->mask; + rbled->active_low = !!led_data->active_low; + rbled->latch_change = pdata->latch_change; + + ret = led_classdev_register(&pdev->dev, &rbled->cdev); + if (ret) + goto err; + } + + platform_set_drvdata(pdev, drvdata); + return 0; + +err: + for (i = i - 1; i >= 0; i--) + led_classdev_unregister(&drvdata->led_devs[i].cdev); + + kfree(drvdata); + return ret; +} + +static int __devexit rb750_led_remove(struct platform_device *pdev) +{ + struct rb750_led_drvdata *drvdata; + int i; + + drvdata = platform_get_drvdata(pdev); + for (i = 0; i < drvdata->num_leds; i++) + led_classdev_unregister(&drvdata->led_devs[i].cdev); + + kfree(drvdata); + return 0; +} + +static struct platform_driver rb750_led_driver = { + .probe = rb750_led_probe, + .remove = __devexit_p(rb750_led_remove), + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +MODULE_ALIAS("platform:leds-rb750"); + +static int __init rb750_led_init(void) +{ + return platform_driver_register(&rb750_led_driver); +} + +static void __exit rb750_led_exit(void) +{ + platform_driver_unregister(&rb750_led_driver); +} + +module_init(rb750_led_init); +module_exit(rb750_led_exit); + +MODULE_DESCRIPTION(DRV_NAME); +MODULE_DESCRIPTION("LED driver for the RouterBOARD 750"); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_LICENSE("GPL v2"); diff --git a/target/linux/ar71xx/files/drivers/leds/leds-wndr3700-usb.c b/target/linux/ar71xx/files/drivers/leds/leds-wndr3700-usb.c new file mode 100644 index 000000000..42f5b70bd --- /dev/null +++ b/target/linux/ar71xx/files/drivers/leds/leds-wndr3700-usb.c @@ -0,0 +1,76 @@ +/* + * USB LED driver for the NETGEAR WNDR3700 + * + * Copyright (C) 2009 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include + +#include +#include + +#define DRIVER_NAME "wndr3700-led-usb" + +static void wndr3700_usb_led_set(struct led_classdev *cdev, + enum led_brightness brightness) +{ + if (brightness) + ath79_device_reset_clear(AR71XX_RESET_GE1_PHY); + else + ath79_device_reset_set(AR71XX_RESET_GE1_PHY); +} + +static enum led_brightness wndr3700_usb_led_get(struct led_classdev *cdev) +{ + return ath79_device_reset_get(AR71XX_RESET_GE1_PHY) ? LED_OFF : LED_FULL; +} + +static struct led_classdev wndr3700_usb_led = { + .name = "wndr3700:green:usb", + .brightness_set = wndr3700_usb_led_set, + .brightness_get = wndr3700_usb_led_get, +}; + +static int __devinit wndr3700_usb_led_probe(struct platform_device *pdev) +{ + return led_classdev_register(&pdev->dev, &wndr3700_usb_led); +} + +static int __devexit wndr3700_usb_led_remove(struct platform_device *pdev) +{ + led_classdev_unregister(&wndr3700_usb_led); + return 0; +} + +static struct platform_driver wndr3700_usb_led_driver = { + .probe = wndr3700_usb_led_probe, + .remove = __devexit_p(wndr3700_usb_led_remove), + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init wndr3700_usb_led_init(void) +{ + return platform_driver_register(&wndr3700_usb_led_driver); +} + +static void __exit wndr3700_usb_led_exit(void) +{ + platform_driver_unregister(&wndr3700_usb_led_driver); +} + +module_init(wndr3700_usb_led_init); +module_exit(wndr3700_usb_led_exit); + +MODULE_DESCRIPTION("USB LED driver for the NETGEAR WNDR3700"); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/target/linux/ar71xx/files/drivers/mtd/nand/ar934x_nfc.c b/target/linux/ar71xx/files/drivers/mtd/nand/ar934x_nfc.c new file mode 100644 index 000000000..9bc9b125f --- /dev/null +++ b/target/linux/ar71xx/files/drivers/mtd/nand/ar934x_nfc.c @@ -0,0 +1,1151 @@ +/* + * Driver for the built-in NAND controller of the Atheros AR934x SoCs + * + * Copyright (C) 2011-2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define AR934X_NFC_REG_CMD 0x00 +#define AR934X_NFC_REG_CTRL 0x04 +#define AR934X_NFC_REG_STATUS 0x08 +#define AR934X_NFC_REG_INT_MASK 0x0c +#define AR934X_NFC_REG_INT_STATUS 0x10 +#define AR934X_NFC_REG_ECC_CTRL 0x14 +#define AR934X_NFC_REG_ECC_OFFSET 0x18 +#define AR934X_NFC_REG_ADDR0_0 0x1c +#define AR934X_NFC_REG_ADDR0_1 0x24 +#define AR934X_NFC_REG_ADDR1_0 0x20 +#define AR934X_NFC_REG_ADDR1_1 0x28 +#define AR934X_NFC_REG_SPARE_SIZE 0x30 +#define AR934X_NFC_REG_PROTECT 0x38 +#define AR934X_NFC_REG_LOOKUP_EN 0x40 +#define AR934X_NFC_REG_LOOKUP(_x) (0x44 + (_i) * 4) +#define AR934X_NFC_REG_DMA_ADDR 0x64 +#define AR934X_NFC_REG_DMA_COUNT 0x68 +#define AR934X_NFC_REG_DMA_CTRL 0x6c +#define AR934X_NFC_REG_MEM_CTRL 0x80 +#define AR934X_NFC_REG_DATA_SIZE 0x84 +#define AR934X_NFC_REG_READ_STATUS 0x88 +#define AR934X_NFC_REG_TIME_SEQ 0x8c +#define AR934X_NFC_REG_TIMINGS_ASYN 0x90 +#define AR934X_NFC_REG_TIMINGS_SYN 0x94 +#define AR934X_NFC_REG_FIFO_DATA 0x98 +#define AR934X_NFC_REG_TIME_MODE 0x9c +#define AR934X_NFC_REG_DMA_ADDR_OFFS 0xa0 +#define AR934X_NFC_REG_FIFO_INIT 0xb0 +#define AR934X_NFC_REG_GEN_SEQ_CTRL 0xb4 + +#define AR934X_NFC_CMD_CMD_SEQ_S 0 +#define AR934X_NFC_CMD_CMD_SEQ_M 0x3f +#define AR934X_NFC_CMD_SEQ_1C 0x00 +#define AR934X_NFC_CMD_SEQ_ERASE 0x0e +#define AR934X_NFC_CMD_SEQ_12 0x0c +#define AR934X_NFC_CMD_SEQ_1C1AXR 0x21 +#define AR934X_NFC_CMD_SEQ_S 0x24 +#define AR934X_NFC_CMD_SEQ_1C3AXR 0x27 +#define AR934X_NFC_CMD_SEQ_1C5A1CXR 0x2a +#define AR934X_NFC_CMD_SEQ_18 0x32 +#define AR934X_NFC_CMD_INPUT_SEL_SIU 0 +#define AR934X_NFC_CMD_INPUT_SEL_DMA BIT(6) +#define AR934X_NFC_CMD_ADDR_SEL_0 0 +#define AR934X_NFC_CMD_ADDR_SEL_1 BIT(7) +#define AR934X_NFC_CMD_CMD0_S 8 +#define AR934X_NFC_CMD_CMD0_M 0xff +#define AR934X_NFC_CMD_CMD1_S 16 +#define AR934X_NFC_CMD_CMD1_M 0xff +#define AR934X_NFC_CMD_CMD2_S 24 +#define AR934X_NFC_CMD_CMD2_M 0xff + +#define AR934X_NFC_CTRL_ADDR_CYCLE0_M 0x7 +#define AR934X_NFC_CTRL_ADDR_CYCLE0_S 0 +#define AR934X_NFC_CTRL_SPARE_EN BIT(3) +#define AR934X_NFC_CTRL_INT_EN BIT(4) +#define AR934X_NFC_CTRL_ECC_EN BIT(5) +#define AR934X_NFC_CTRL_BLOCK_SIZE_S 6 +#define AR934X_NFC_CTRL_BLOCK_SIZE_M 0x3 +#define AR934X_NFC_CTRL_BLOCK_SIZE_32 0 +#define AR934X_NFC_CTRL_BLOCK_SIZE_64 1 +#define AR934X_NFC_CTRL_BLOCK_SIZE_128 2 +#define AR934X_NFC_CTRL_BLOCK_SIZE_256 3 +#define AR934X_NFC_CTRL_PAGE_SIZE_S 8 +#define AR934X_NFC_CTRL_PAGE_SIZE_M 0x7 +#define AR934X_NFC_CTRL_PAGE_SIZE_256 0 +#define AR934X_NFC_CTRL_PAGE_SIZE_512 1 +#define AR934X_NFC_CTRL_PAGE_SIZE_1024 2 +#define AR934X_NFC_CTRL_PAGE_SIZE_2048 3 +#define AR934X_NFC_CTRL_PAGE_SIZE_4096 4 +#define AR934X_NFC_CTRL_PAGE_SIZE_8192 5 +#define AR934X_NFC_CTRL_PAGE_SIZE_16384 6 +#define AR934X_NFC_CTRL_CUSTOM_SIZE_EN BIT(11) +#define AR934X_NFC_CTRL_IO_WIDTH_8BITS 0 +#define AR934X_NFC_CTRL_IO_WIDTH_16BITS BIT(12) +#define AR934X_NFC_CTRL_LOOKUP_EN BIT(13) +#define AR934X_NFC_CTRL_PROT_EN BIT(14) +#define AR934X_NFC_CTRL_WORK_MODE_ASYNC 0 +#define AR934X_NFC_CTRL_WORK_MODE_SYNC BIT(15) +#define AR934X_NFC_CTRL_ADDR0_AUTO_INC BIT(16) +#define AR934X_NFC_CTRL_ADDR1_AUTO_INC BIT(17) +#define AR934X_NFC_CTRL_ADDR_CYCLE1_M 0x7 +#define AR934X_NFC_CTRL_ADDR_CYCLE1_S 18 +#define AR934X_NFC_CTRL_SMALL_PAGE BIT(21) + +#define AR934X_NFC_DMA_CTRL_DMA_START BIT(7) +#define AR934X_NFC_DMA_CTRL_DMA_DIR_WRITE 0 +#define AR934X_NFC_DMA_CTRL_DMA_DIR_READ BIT(6) +#define AR934X_NFC_DMA_CTRL_DMA_MODE_SG BIT(5) +#define AR934X_NFC_DMA_CTRL_DMA_BURST_S 2 +#define AR934X_NFC_DMA_CTRL_DMA_BURST_0 0 +#define AR934X_NFC_DMA_CTRL_DMA_BURST_1 1 +#define AR934X_NFC_DMA_CTRL_DMA_BURST_2 2 +#define AR934X_NFC_DMA_CTRL_DMA_BURST_3 3 +#define AR934X_NFC_DMA_CTRL_DMA_BURST_4 4 +#define AR934X_NFC_DMA_CTRL_DMA_BURST_5 5 +#define AR934X_NFC_DMA_CTRL_ERR_FLAG BIT(1) +#define AR934X_NFC_DMA_CTRL_DMA_READY BIT(0) + +#define AR934X_NFC_INT_DEV_RDY(_x) BIT(4 + (_x)) +#define AR934X_NFC_INT_CMD_END BIT(1) + +/* default timing values */ +#define AR934X_NFC_TIME_SEQ_DEFAULT 0x7fff +#define AR934X_NFC_TIMINGS_ASYN_DEFAULT 0x22 +#define AR934X_NFC_TIMINGS_SYN_DEFAULT 0xf + +#define AR934X_NFC_ID_BUF_SIZE 8 +#define AR934X_NFC_DEV_READY_TIMEOUT 25 /* msecs */ +#define AR934X_NFC_DMA_READY_TIMEOUT 25 /* msecs */ +#define AR934X_NFC_DONE_TIMEOUT 1000 +#define AR934X_NFC_DMA_RETRIES 20 + +#define AR934X_NFC_USE_IRQ true +#define AR934X_NFC_IRQ_MASK AR934X_NFC_INT_DEV_RDY(0) + +#define AR934X_NFC_GENSEQ_SMALL_PAGE_READ 0x30043 + +#undef AR934X_NFC_DEBUG_DATA +#undef AR934X_NFC_DEBUG + +struct ar934x_nfc; + +static inline __attribute__ ((format (printf, 2, 3))) +void _nfc_dbg(struct ar934x_nfc *nfc, const char *fmt, ...) +{ +} + +#ifdef AR934X_NFC_DEBUG +#define nfc_dbg(_nfc, fmt, ...) \ + dev_info((_nfc)->parent, fmt, ##__VA_ARGS__) +#else +#define nfc_dbg(_nfc, fmt, ...) \ + _nfc_dbg((_nfc), fmt, ##__VA_ARGS__) +#endif /* AR934X_NFC_DEBUG */ + +#ifdef AR934X_NFC_DEBUG_DATA +static void +nfc_debug_data(const char *label, void *data, int len) +{ + print_hex_dump(KERN_WARNING, label, DUMP_PREFIX_OFFSET, 16, 1, + data, len, 0); +} +#else +static inline void +nfc_debug_data(const char *label, void *data, int len) {} +#endif /* AR934X_NFC_DEBUG_DATA */ + +struct ar934x_nfc { + struct mtd_info mtd; + struct nand_chip nand_chip; + struct device *parent; + void __iomem *base; + void (*select_chip)(int chip_no); + int irq; + wait_queue_head_t irq_waitq; + + bool spurious_irq_expected; + u32 irq_status; + + u32 ctrl_reg; + bool small_page; + unsigned int addr_count0; + unsigned int addr_count1; + + u8 *buf; + dma_addr_t buf_dma; + unsigned int buf_size; + int buf_index; + + int erase1_page_addr; + + int rndout_page_addr; + int rndout_read_cmd; + + int seqin_page_addr; + int seqin_column; + int seqin_read_cmd; +}; + +static void ar934x_nfc_restart(struct ar934x_nfc *nfc); + +static inline void +ar934x_nfc_wr(struct ar934x_nfc *nfc, unsigned reg, u32 val) +{ + __raw_writel(val, nfc->base + reg); +} + +static inline u32 +ar934x_nfc_rr(struct ar934x_nfc *nfc, unsigned reg) +{ + return __raw_readl(nfc->base + reg); +} + +static inline struct ar934x_nfc_platform_data * +ar934x_nfc_get_platform_data(struct ar934x_nfc *nfc) +{ + return nfc->parent->platform_data; +} + +static inline struct +ar934x_nfc *mtd_to_ar934x_nfc(struct mtd_info *mtd) +{ + return container_of(mtd, struct ar934x_nfc, mtd); +} + +static inline bool ar934x_nfc_use_irq(struct ar934x_nfc *nfc) +{ + return AR934X_NFC_USE_IRQ; +} + +static inline void ar934x_nfc_write_cmd_reg(struct ar934x_nfc *nfc, u32 cmd_reg) +{ + wmb(); + + ar934x_nfc_wr(nfc, AR934X_NFC_REG_CMD, cmd_reg); + /* flush write */ + ar934x_nfc_rr(nfc, AR934X_NFC_REG_CMD); +} + +static bool +__ar934x_nfc_dev_ready(struct ar934x_nfc *nfc) +{ + u32 status; + + status = ar934x_nfc_rr(nfc, AR934X_NFC_REG_STATUS); + return (status & 0xff) == 0xff; +} + +static inline bool +__ar934x_nfc_is_dma_ready(struct ar934x_nfc *nfc) +{ + u32 status; + + status = ar934x_nfc_rr(nfc, AR934X_NFC_REG_DMA_CTRL); + return (status & AR934X_NFC_DMA_CTRL_DMA_READY) != 0; +} + +static int +ar934x_nfc_wait_dev_ready(struct ar934x_nfc *nfc) +{ + unsigned long timeout; + + timeout = jiffies + msecs_to_jiffies(AR934X_NFC_DEV_READY_TIMEOUT); + do { + if (__ar934x_nfc_dev_ready(nfc)) + return 0; + } while time_before(jiffies, timeout); + + nfc_dbg(nfc, "timeout waiting for device ready, status:%08x int:%08x\n", + ar934x_nfc_rr(nfc, AR934X_NFC_REG_STATUS), + ar934x_nfc_rr(nfc, AR934X_NFC_REG_INT_STATUS)); + return -ETIMEDOUT; +} + +static int +ar934x_nfc_wait_dma_ready(struct ar934x_nfc *nfc) +{ + unsigned long timeout; + + timeout = jiffies + msecs_to_jiffies(AR934X_NFC_DMA_READY_TIMEOUT); + do { + if (__ar934x_nfc_is_dma_ready(nfc)) + return 0; + } while time_before(jiffies, timeout); + + nfc_dbg(nfc, "timeout waiting for DMA ready, dma_ctrl:%08x\n", + ar934x_nfc_rr(nfc, AR934X_NFC_REG_DMA_CTRL)); + return -ETIMEDOUT; +} + +static int +ar934x_nfc_wait_irq(struct ar934x_nfc *nfc) +{ + long timeout; + int ret; + + timeout = wait_event_timeout(nfc->irq_waitq, + (nfc->irq_status & AR934X_NFC_IRQ_MASK) != 0, + msecs_to_jiffies(AR934X_NFC_DEV_READY_TIMEOUT)); + + ret = 0; + if (!timeout) { + ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_MASK, 0); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_STATUS, 0); + /* flush write */ + ar934x_nfc_rr(nfc, AR934X_NFC_REG_INT_STATUS); + + nfc_dbg(nfc, + "timeout waiting for interrupt, status:%08x\n", + nfc->irq_status); + ret = -ETIMEDOUT; + } + + nfc->irq_status = 0; + return ret; +} + +static int +ar934x_nfc_wait_done(struct ar934x_nfc *nfc) +{ + int ret; + + if (ar934x_nfc_use_irq(nfc)) + ret = ar934x_nfc_wait_irq(nfc); + else + ret = ar934x_nfc_wait_dev_ready(nfc); + + if (ret) + return ret; + + return ar934x_nfc_wait_dma_ready(nfc); +} + +static int +ar934x_nfc_alloc_buf(struct ar934x_nfc *nfc, unsigned size) +{ + nfc->buf = dma_alloc_coherent(nfc->parent, size, + &nfc->buf_dma, GFP_KERNEL); + if (nfc->buf == NULL) { + dev_err(nfc->parent, "no memory for DMA buffer\n"); + return -ENOMEM; + } + + nfc->buf_size = size; + nfc_dbg(nfc, "buf:%p size:%u\n", nfc->buf, nfc->buf_size); + + return 0; +} + +static void +ar934x_nfc_free_buf(struct ar934x_nfc *nfc) +{ + dma_free_coherent(nfc->parent, nfc->buf_size, nfc->buf, nfc->buf_dma); +} + +static void +ar934x_nfc_get_addr(struct ar934x_nfc *nfc, int column, int page_addr, + u32 *addr0, u32 *addr1) +{ + u32 a0, a1; + + a0 = 0; + a1 = 0; + + if (column == -1) { + /* ERASE1 */ + a0 = (page_addr & 0xffff) << 16; + a1 = (page_addr >> 16) & 0xf; + } else if (page_addr != -1) { + /* SEQIN, READ0, etc.. */ + + /* TODO: handle 16bit bus width */ + if (nfc->small_page) { + a0 = column & 0xff; + a0 |= (page_addr & 0xff) << 8; + a0 |= ((page_addr >> 8) & 0xff) << 16; + a0 |= ((page_addr >> 16) & 0xff) << 24; + } else { + a0 = column & 0x0FFF; + a0 |= (page_addr & 0xffff) << 16; + + if (nfc->addr_count0 > 4) + a1 = (page_addr >> 16) & 0xf; + } + } + + *addr0 = a0; + *addr1 = a1; +} + +static void +ar934x_nfc_send_cmd(struct ar934x_nfc *nfc, unsigned command) +{ + u32 cmd_reg; + + cmd_reg = AR934X_NFC_CMD_INPUT_SEL_SIU | AR934X_NFC_CMD_ADDR_SEL_0 | + AR934X_NFC_CMD_SEQ_1C; + cmd_reg |= (command & AR934X_NFC_CMD_CMD0_M) << AR934X_NFC_CMD_CMD0_S; + + ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_STATUS, 0); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_CTRL, nfc->ctrl_reg); + + ar934x_nfc_write_cmd_reg(nfc, cmd_reg); + ar934x_nfc_wait_dev_ready(nfc); +} + +static void +ar934x_nfc_do_rw_command(struct ar934x_nfc *nfc, int column, int page_addr, + int len, u32 cmd_reg, u32 ctrl_reg, bool write) +{ + u32 addr0, addr1; + u32 dma_ctrl; + int dir; + int err; + int retries = 0; + + WARN_ON(len & 3); + + if (WARN_ON(len > nfc->buf_size)) + dev_err(nfc->parent, "len=%d > buf_size=%d", len, nfc->buf_size); + + if (write) { + dma_ctrl = AR934X_NFC_DMA_CTRL_DMA_DIR_WRITE; + dir = DMA_TO_DEVICE; + } else { + dma_ctrl = AR934X_NFC_DMA_CTRL_DMA_DIR_READ; + dir = DMA_FROM_DEVICE; + } + + ar934x_nfc_get_addr(nfc, column, page_addr, &addr0, &addr1); + + dma_ctrl |= AR934X_NFC_DMA_CTRL_DMA_START | + (AR934X_NFC_DMA_CTRL_DMA_BURST_3 << + AR934X_NFC_DMA_CTRL_DMA_BURST_S); + + cmd_reg |= AR934X_NFC_CMD_INPUT_SEL_DMA | AR934X_NFC_CMD_ADDR_SEL_0; + ctrl_reg |= AR934X_NFC_CTRL_INT_EN; + + nfc_dbg(nfc, "%s a0:%08x a1:%08x len:%x cmd:%08x dma:%08x ctrl:%08x\n", + (write) ? "write" : "read", + addr0, addr1, len, cmd_reg, dma_ctrl, ctrl_reg); + +retry: + ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_STATUS, 0); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_ADDR0_0, addr0); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_ADDR0_1, addr1); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_DMA_ADDR, nfc->buf_dma); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_DMA_COUNT, len); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_DATA_SIZE, len); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_CTRL, ctrl_reg); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_DMA_CTRL, dma_ctrl); + + if (ar934x_nfc_use_irq(nfc)) { + ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_MASK, AR934X_NFC_IRQ_MASK); + /* flush write */ + ar934x_nfc_rr(nfc, AR934X_NFC_REG_INT_MASK); + } + + ar934x_nfc_write_cmd_reg(nfc, cmd_reg); + err = ar934x_nfc_wait_done(nfc); + if (err) { + dev_dbg(nfc->parent, "%s operation stuck at page %d\n", + (write) ? "write" : "read", page_addr); + + ar934x_nfc_restart(nfc); + if (retries++ < AR934X_NFC_DMA_RETRIES) + goto retry; + + dev_err(nfc->parent, "%s operation failed on page %d\n", + (write) ? "write" : "read", page_addr); + } +} + +static void +ar934x_nfc_send_readid(struct ar934x_nfc *nfc, unsigned command) +{ + u32 cmd_reg; + + nfc_dbg(nfc, "readid, cmd:%02x\n", command); + + cmd_reg = AR934X_NFC_CMD_SEQ_1C1AXR; + cmd_reg |= (command & AR934X_NFC_CMD_CMD0_M) << AR934X_NFC_CMD_CMD0_S; + + ar934x_nfc_do_rw_command(nfc, -1, -1, AR934X_NFC_ID_BUF_SIZE, cmd_reg, + nfc->ctrl_reg, false); + + nfc_debug_data("[id] ", nfc->buf, AR934X_NFC_ID_BUF_SIZE); +} + +static void +ar934x_nfc_send_read(struct ar934x_nfc *nfc, unsigned command, int column, + int page_addr, int len) +{ + u32 cmd_reg; + + nfc_dbg(nfc, "read, column=%d page=%d len=%d\n", + column, page_addr, len); + + cmd_reg = (command & AR934X_NFC_CMD_CMD0_M) << AR934X_NFC_CMD_CMD0_S; + + if (nfc->small_page) { + cmd_reg |= AR934X_NFC_CMD_SEQ_18; + } else { + cmd_reg |= NAND_CMD_READSTART << AR934X_NFC_CMD_CMD1_S; + cmd_reg |= AR934X_NFC_CMD_SEQ_1C5A1CXR; + } + + ar934x_nfc_do_rw_command(nfc, column, page_addr, len, + cmd_reg, nfc->ctrl_reg, false); + + nfc_debug_data("[data] ", nfc->buf, len); +} + +static void +ar934x_nfc_send_erase(struct ar934x_nfc *nfc, unsigned command, int column, + int page_addr) +{ + u32 addr0, addr1; + u32 ctrl_reg; + u32 cmd_reg; + + ar934x_nfc_get_addr(nfc, column, page_addr, &addr0, &addr1); + + ctrl_reg = nfc->ctrl_reg; + if (nfc->small_page) { + /* override number of address cycles for the erase command */ + ctrl_reg &= ~(AR934X_NFC_CTRL_ADDR_CYCLE0_M << + AR934X_NFC_CTRL_ADDR_CYCLE0_S); + ctrl_reg &= ~(AR934X_NFC_CTRL_ADDR_CYCLE1_M << + AR934X_NFC_CTRL_ADDR_CYCLE1_S); + ctrl_reg &= ~(AR934X_NFC_CTRL_SMALL_PAGE); + ctrl_reg |= (nfc->addr_count0 + 1) << + AR934X_NFC_CTRL_ADDR_CYCLE0_S; + } + + cmd_reg = NAND_CMD_ERASE1 << AR934X_NFC_CMD_CMD0_S; + cmd_reg |= command << AR934X_NFC_CMD_CMD1_S; + cmd_reg |= AR934X_NFC_CMD_SEQ_ERASE; + + nfc_dbg(nfc, "erase page %d, a0:%08x a1:%08x cmd:%08x ctrl:%08x\n", + page_addr, addr0, addr1, cmd_reg, ctrl_reg); + + ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_STATUS, 0); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_CTRL, ctrl_reg); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_ADDR0_0, addr0); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_ADDR0_1, addr1); + + ar934x_nfc_write_cmd_reg(nfc, cmd_reg); + ar934x_nfc_wait_dev_ready(nfc); +} + +static void +ar934x_nfc_send_write(struct ar934x_nfc *nfc, unsigned command, int column, + int page_addr, int len) +{ + u32 cmd_reg; + + nfc_dbg(nfc, "write, column=%d page=%d len=%d\n", + column, page_addr, len); + + nfc_debug_data("[data] ", nfc->buf, len); + + cmd_reg = NAND_CMD_SEQIN << AR934X_NFC_CMD_CMD0_S; + cmd_reg |= command << AR934X_NFC_CMD_CMD1_S; + cmd_reg |= AR934X_NFC_CMD_SEQ_12; + + ar934x_nfc_do_rw_command(nfc, column, page_addr, len, + cmd_reg, nfc->ctrl_reg, true); +} + +static void +ar934x_nfc_read_status(struct ar934x_nfc *nfc) +{ + u32 cmd_reg; + u32 status; + + cmd_reg = NAND_CMD_STATUS << AR934X_NFC_CMD_CMD0_S; + cmd_reg |= AR934X_NFC_CMD_SEQ_S; + + ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_STATUS, 0); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_CTRL, nfc->ctrl_reg); + + ar934x_nfc_write_cmd_reg(nfc, cmd_reg); + ar934x_nfc_wait_dev_ready(nfc); + + status = ar934x_nfc_rr(nfc, AR934X_NFC_REG_READ_STATUS); + + nfc_dbg(nfc, "read status, cmd:%08x status:%02x\n", + cmd_reg, (status & 0xff)); + + nfc->buf[0 ^ 3] = status; +} + +static void +ar934x_nfc_cmdfunc(struct mtd_info *mtd, unsigned int command, int column, + int page_addr) +{ + struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); + + if (command != NAND_CMD_PAGEPROG) + nfc->buf_index = 0; + + switch (command) { + case NAND_CMD_RESET: + ar934x_nfc_send_cmd(nfc, command); + break; + + case NAND_CMD_READID: + ar934x_nfc_send_readid(nfc, command); + break; + + case NAND_CMD_READ0: + case NAND_CMD_READ1: + if (nfc->small_page) { + ar934x_nfc_send_read(nfc, command, column, page_addr, + mtd->writesize + mtd->oobsize); + } else { + ar934x_nfc_send_read(nfc, command, 0, page_addr, + mtd->writesize + mtd->oobsize); + nfc->buf_index = column; + nfc->rndout_page_addr = page_addr; + nfc->rndout_read_cmd = command; + } + break; + + case NAND_CMD_READOOB: + if (nfc->small_page) + ar934x_nfc_send_read(nfc, NAND_CMD_READOOB, + column, page_addr, + mtd->oobsize); + else + ar934x_nfc_send_read(nfc, NAND_CMD_READ0, + mtd->writesize, page_addr, + mtd->oobsize); + break; + + case NAND_CMD_RNDOUT: + if (WARN_ON(nfc->small_page)) + break; + + /* emulate subpage read */ + ar934x_nfc_send_read(nfc, nfc->rndout_read_cmd, 0, + nfc->rndout_page_addr, + mtd->writesize + mtd->oobsize); + nfc->buf_index = column; + break; + + case NAND_CMD_ERASE1: + nfc->erase1_page_addr = page_addr; + break; + + case NAND_CMD_ERASE2: + ar934x_nfc_send_erase(nfc, command, -1, nfc->erase1_page_addr); + break; + + case NAND_CMD_STATUS: + ar934x_nfc_read_status(nfc); + break; + + case NAND_CMD_SEQIN: + if (nfc->small_page) { + /* output read command */ + if (column >= mtd->writesize) { + column -= mtd->writesize; + nfc->seqin_read_cmd = NAND_CMD_READOOB; + } else if (column < 256) { + nfc->seqin_read_cmd = NAND_CMD_READ0; + } else { + column -= 256; + nfc->seqin_read_cmd = NAND_CMD_READ1; + } + } else { + nfc->seqin_read_cmd = NAND_CMD_READ0; + } + nfc->seqin_column = column; + nfc->seqin_page_addr = page_addr; + break; + + case NAND_CMD_PAGEPROG: + if (nfc->small_page) + ar934x_nfc_send_cmd(nfc, nfc->seqin_read_cmd); + + ar934x_nfc_send_write(nfc, command, nfc->seqin_column, + nfc->seqin_page_addr, + nfc->buf_index); + break; + + default: + dev_err(nfc->parent, + "unsupported command: %x, column:%d page_addr=%d\n", + command, column, page_addr); + break; + } +} + +static int +ar934x_nfc_dev_ready(struct mtd_info *mtd) +{ + struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); + + return __ar934x_nfc_dev_ready(nfc); +} + +static void +ar934x_nfc_select_chip(struct mtd_info *mtd, int chip_no) +{ + struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); + + if (nfc->select_chip) + nfc->select_chip(chip_no); +} + +static u8 +ar934x_nfc_read_byte(struct mtd_info *mtd) +{ + struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); + unsigned int buf_index; + u8 data; + + WARN_ON(nfc->buf_index >= nfc->buf_size); + + buf_index = nfc->buf_index ^ 3; + data = nfc->buf[buf_index]; + nfc->buf_index++; + + return data; +} + +static void +ar934x_nfc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) +{ + struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); + int i; + + WARN_ON(nfc->buf_index + len > nfc->buf_size); + + for (i = 0; i < len; i++) { + nfc->buf[nfc->buf_index ^ 3] = buf[i]; + nfc->buf_index++; + } +} + +static void +ar934x_nfc_read_buf(struct mtd_info *mtd, u8 *buf, int len) +{ + struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); + int buf_index; + int i; + + WARN_ON(nfc->buf_index + len > nfc->buf_size); + + buf_index = nfc->buf_index; + + for (i = 0; i < len; i++) { + buf[i] = nfc->buf[buf_index ^ 3]; + buf_index++; + } + + nfc->buf_index = buf_index; +} + +static int +ar934x_nfc_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) +{ + int i; + + for (i = 0; i < len; i++) + if (buf[i] != ar934x_nfc_read_byte(mtd)) + return -EFAULT; + + return 0; +} + +static void +ar934x_nfc_hw_init(struct ar934x_nfc *nfc) +{ + struct ar934x_nfc_platform_data *pdata; + + pdata = ar934x_nfc_get_platform_data(nfc); + if (pdata->hw_reset) { + pdata->hw_reset(true); + pdata->hw_reset(false); + } + + /* + * setup timings + * TODO: make it configurable via platform data + */ + ar934x_nfc_wr(nfc, AR934X_NFC_REG_TIME_SEQ, + AR934X_NFC_TIME_SEQ_DEFAULT); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_TIMINGS_ASYN, + AR934X_NFC_TIMINGS_ASYN_DEFAULT); + ar934x_nfc_wr(nfc, AR934X_NFC_REG_TIMINGS_SYN, + AR934X_NFC_TIMINGS_SYN_DEFAULT); + + /* disable WP on all chips, and select chip 0 */ + ar934x_nfc_wr(nfc, AR934X_NFC_REG_MEM_CTRL, 0xff00); + + ar934x_nfc_wr(nfc, AR934X_NFC_REG_DMA_ADDR_OFFS, 0); + + /* initialize Control register */ + nfc->ctrl_reg = AR934X_NFC_CTRL_CUSTOM_SIZE_EN; + ar934x_nfc_wr(nfc, AR934X_NFC_REG_CTRL, nfc->ctrl_reg); + + if (nfc->small_page) { + /* Setup generic sequence register for small page reads. */ + ar934x_nfc_wr(nfc, AR934X_NFC_REG_GEN_SEQ_CTRL, + AR934X_NFC_GENSEQ_SMALL_PAGE_READ); + } +} + +static void +ar934x_nfc_restart(struct ar934x_nfc *nfc) +{ + u32 ctrl_reg; + + if (nfc->select_chip) + nfc->select_chip(-1); + + ctrl_reg = nfc->ctrl_reg; + ar934x_nfc_hw_init(nfc); + nfc->ctrl_reg = ctrl_reg; + + if (nfc->select_chip) + nfc->select_chip(0); + + ar934x_nfc_send_cmd(nfc, NAND_CMD_RESET); +} + +static irqreturn_t +ar934x_nfc_irq_handler(int irq, void *data) +{ + struct ar934x_nfc *nfc = data; + u32 status; + + status = ar934x_nfc_rr(nfc, AR934X_NFC_REG_INT_STATUS); + + ar934x_nfc_wr(nfc, AR934X_NFC_REG_INT_STATUS, 0); + /* flush write */ + ar934x_nfc_rr(nfc, AR934X_NFC_REG_INT_STATUS); + + status &= ar934x_nfc_rr(nfc, AR934X_NFC_REG_INT_MASK); + if (status) { + nfc_dbg(nfc, "got IRQ, status:%08x\n", status); + + nfc->irq_status = status; + nfc->spurious_irq_expected = true; + wake_up(&nfc->irq_waitq); + } else { + if (nfc->spurious_irq_expected) { + nfc->spurious_irq_expected = false; + } else { + dev_warn(nfc->parent, "spurious interrupt\n"); + } + } + + return IRQ_HANDLED; +} + +static int __devinit +ar934x_nfc_init_tail(struct mtd_info *mtd) +{ + struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd); + struct nand_chip *chip = &nfc->nand_chip; + u32 ctrl; + u32 t; + int err; + + switch (mtd->oobsize) { + case 16: + case 64: + case 128: + ar934x_nfc_wr(nfc, AR934X_NFC_REG_SPARE_SIZE, mtd->oobsize); + break; + + default: + dev_err(nfc->parent, "unsupported OOB size: %d bytes\n", + mtd->oobsize); + return -ENXIO; + } + + ctrl = AR934X_NFC_CTRL_CUSTOM_SIZE_EN; + + switch (mtd->erasesize / mtd->writesize) { + case 32: + t = AR934X_NFC_CTRL_BLOCK_SIZE_32; + break; + + case 64: + t = AR934X_NFC_CTRL_BLOCK_SIZE_64; + break; + + case 128: + t = AR934X_NFC_CTRL_BLOCK_SIZE_128; + break; + + case 256: + t = AR934X_NFC_CTRL_BLOCK_SIZE_256; + break; + + default: + dev_err(nfc->parent, "unsupported block size: %u\n", + mtd->erasesize / mtd->writesize); + return -ENXIO; + } + + ctrl |= t << AR934X_NFC_CTRL_BLOCK_SIZE_S; + + switch (mtd->writesize) { + case 256: + nfc->small_page = 1; + t = AR934X_NFC_CTRL_PAGE_SIZE_256; + break; + + case 512: + nfc->small_page = 1; + t = AR934X_NFC_CTRL_PAGE_SIZE_512; + break; + + case 1024: + t = AR934X_NFC_CTRL_PAGE_SIZE_1024; + break; + + case 2048: + t = AR934X_NFC_CTRL_PAGE_SIZE_2048; + break; + + case 4096: + t = AR934X_NFC_CTRL_PAGE_SIZE_4096; + break; + + case 8192: + t = AR934X_NFC_CTRL_PAGE_SIZE_8192; + break; + + case 16384: + t = AR934X_NFC_CTRL_PAGE_SIZE_16384; + break; + + default: + dev_err(nfc->parent, "unsupported write size: %d bytes\n", + mtd->writesize); + return -ENXIO; + } + + ctrl |= t << AR934X_NFC_CTRL_PAGE_SIZE_S; + + if (nfc->small_page) { + ctrl |= AR934X_NFC_CTRL_SMALL_PAGE; + + if (chip->chipsize > (32 << 20)) { + nfc->addr_count0 = 4; + nfc->addr_count1 = 3; + } else if (chip->chipsize > (2 << 16)) { + nfc->addr_count0 = 3; + nfc->addr_count1 = 2; + } else { + nfc->addr_count0 = 2; + nfc->addr_count1 = 1; + } + } else { + if (chip->chipsize > (128 << 20)) { + nfc->addr_count0 = 5; + nfc->addr_count1 = 3; + } else if (chip->chipsize > (8 << 16)) { + nfc->addr_count0 = 4; + nfc->addr_count1 = 2; + } else { + nfc->addr_count0 = 3; + nfc->addr_count1 = 1; + } + } + + ctrl |= nfc->addr_count0 << AR934X_NFC_CTRL_ADDR_CYCLE0_S; + ctrl |= nfc->addr_count1 << AR934X_NFC_CTRL_ADDR_CYCLE1_S; + + nfc->ctrl_reg = ctrl; + ar934x_nfc_wr(nfc, AR934X_NFC_REG_CTRL, nfc->ctrl_reg); + + ar934x_nfc_free_buf(nfc); + err = ar934x_nfc_alloc_buf(nfc, mtd->writesize + mtd->oobsize); + + return err; +} + +static int __devinit +ar934x_nfc_probe(struct platform_device *pdev) +{ + static const char *part_probes[] = { "cmdlinepart", NULL, }; + struct ar934x_nfc_platform_data *pdata; + struct ar934x_nfc *nfc; + struct resource *res; + struct mtd_info *mtd; + struct nand_chip *nand; + struct mtd_part_parser_data ppdata; + int ret; + + pdata = pdev->dev.platform_data; + if (pdata == NULL) { + dev_err(&pdev->dev, "no platform data defined\n"); + return -EINVAL; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "failed to get I/O memory\n"); + return -EINVAL; + } + + nfc = kzalloc(sizeof(struct ar934x_nfc), GFP_KERNEL); + if (!nfc) { + dev_err(&pdev->dev, "failed to allocate driver data\n"); + return -ENOMEM; + } + + nfc->base = ioremap(res->start, resource_size(res)); + if (nfc->base == NULL) { + dev_err(&pdev->dev, "failed to remap I/O memory\n"); + ret = -ENXIO; + goto err_free_nand; + } + + nfc->irq = platform_get_irq(pdev, 0); + if (nfc->irq < 0) { + dev_err(&pdev->dev, "no IRQ resource specified\n"); + ret = -EINVAL; + goto err_unmap; + } + + init_waitqueue_head(&nfc->irq_waitq); + ret = request_irq(nfc->irq, ar934x_nfc_irq_handler, IRQF_DISABLED, + dev_name(&pdev->dev), nfc); + if (ret) { + dev_err(&pdev->dev, "requast_irq failed, err:%d\n", ret); + goto err_unmap; + } + + nfc->parent = &pdev->dev; + nfc->select_chip = pdata->select_chip; + + nand = &nfc->nand_chip; + mtd = &nfc->mtd; + + mtd->priv = nand; + mtd->owner = THIS_MODULE; + if (pdata->name) + mtd->name = pdata->name; + else + mtd->name = dev_name(&pdev->dev); + + nand->options = NAND_NO_AUTOINCR; + nand->chip_delay = 25; + nand->ecc.mode = NAND_ECC_SOFT; + + nand->dev_ready = ar934x_nfc_dev_ready; + nand->cmdfunc = ar934x_nfc_cmdfunc; + nand->read_byte = ar934x_nfc_read_byte; + nand->write_buf = ar934x_nfc_write_buf; + nand->read_buf = ar934x_nfc_read_buf; + nand->verify_buf = ar934x_nfc_verify_buf; + nand->select_chip = ar934x_nfc_select_chip; + + ret = ar934x_nfc_alloc_buf(nfc, AR934X_NFC_ID_BUF_SIZE); + if (ret) + goto err_free_irq; + + platform_set_drvdata(pdev, nfc); + + ar934x_nfc_hw_init(nfc); + + ret = nand_scan_ident(mtd, 1, NULL); + if (ret) { + dev_err(&pdev->dev, "nand_scan_ident failed, err:%d\n", ret); + goto err_free_buf; + } + + ret = ar934x_nfc_init_tail(mtd); + if (ret) { + dev_err(&pdev->dev, "init tail failed, err:%d\n", ret); + goto err_free_buf; + } + + if (pdata->scan_fixup) { + ret = pdata->scan_fixup(mtd); + if (ret) + goto err_free_buf; + } + + ret = nand_scan_tail(mtd); + if (ret) { + dev_err(&pdev->dev, "scan tail failed, err:%d\n", ret); + goto err_free_buf; + } + + memset(&ppdata, '\0', sizeof(ppdata)); + ret = mtd_device_parse_register(mtd, part_probes, &ppdata, + pdata->parts, pdata->nr_parts); + if (ret) { + dev_err(&pdev->dev, "unable to register mtd, err:%d\n", ret); + goto err_free_buf; + } + + return 0; + +err_free_buf: + ar934x_nfc_free_buf(nfc); +err_free_irq: + free_irq(nfc->irq, nfc); +err_unmap: + iounmap(nfc->base); +err_free_nand: + kfree(nfc); + platform_set_drvdata(pdev, NULL); + return ret; +} + +static int __devexit +ar934x_nfc_remove(struct platform_device *pdev) +{ + struct ar934x_nfc *nfc; + + nfc = platform_get_drvdata(pdev); + if (nfc) { + nand_release(&nfc->mtd); + ar934x_nfc_free_buf(nfc); + free_irq(nfc->irq, nfc); + iounmap(nfc->base); + kfree(nfc); + } + + return 0; +} + +static struct platform_driver ar934x_nfc_driver = { + .probe = ar934x_nfc_probe, + .remove = __devexit_p(ar934x_nfc_remove), + .driver = { + .name = AR934X_NFC_DRIVER_NAME, + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(ar934x_nfc_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_DESCRIPTION("Atheros AR934x NAND Flash Controller driver"); +MODULE_ALIAS("platform:" AR934X_NFC_DRIVER_NAME); diff --git a/target/linux/ar71xx/files/drivers/mtd/nand/rb4xx_nand.c b/target/linux/ar71xx/files/drivers/mtd/nand/rb4xx_nand.c new file mode 100644 index 000000000..1cb8f8240 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/mtd/nand/rb4xx_nand.c @@ -0,0 +1,309 @@ +/* + * NAND flash driver for the MikroTik RouterBoard 4xx series + * + * Copyright (C) 2008-2011 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This file was based on the driver for Linux 2.6.22 published by + * MikroTik for their RouterBoard 4xx series devices. + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DRV_NAME "rb4xx-nand" +#define DRV_VERSION "0.2.0" +#define DRV_DESC "NAND flash driver for RouterBoard 4xx series" + +#define RB4XX_NAND_GPIO_READY 5 +#define RB4XX_NAND_GPIO_ALE 37 +#define RB4XX_NAND_GPIO_CLE 38 +#define RB4XX_NAND_GPIO_NCE 39 + +struct rb4xx_nand_info { + struct nand_chip chip; + struct mtd_info mtd; +}; + +/* + * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader + * will not be able to find the kernel that we load. + */ +static struct nand_ecclayout rb4xx_nand_ecclayout = { + .eccbytes = 6, + .eccpos = { 8, 9, 10, 13, 14, 15 }, + .oobavail = 9, + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } +}; + +static struct mtd_partition rb4xx_nand_partitions[] = { + { + .name = "booter", + .offset = 0, + .size = (256 * 1024), + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "kernel", + .offset = (256 * 1024), + .size = (6 * 1024 * 1024) - (256 * 1024), + }, + { + .name = "rootfs", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static int rb4xx_nand_dev_ready(struct mtd_info *mtd) +{ + return gpio_get_value_cansleep(RB4XX_NAND_GPIO_READY); +} + +static void rb4xx_nand_write_cmd(unsigned char cmd) +{ + unsigned char data = cmd; + int err; + + err = rb4xx_cpld_write(&data, 1); + if (err) + pr_err("rb4xx_nand: write cmd failed, err=%d\n", err); +} + +static void rb4xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + if (ctrl & NAND_CTRL_CHANGE) { + gpio_set_value_cansleep(RB4XX_NAND_GPIO_CLE, + (ctrl & NAND_CLE) ? 1 : 0); + gpio_set_value_cansleep(RB4XX_NAND_GPIO_ALE, + (ctrl & NAND_ALE) ? 1 : 0); + gpio_set_value_cansleep(RB4XX_NAND_GPIO_NCE, + (ctrl & NAND_NCE) ? 0 : 1); + } + + if (cmd != NAND_CMD_NONE) + rb4xx_nand_write_cmd(cmd); +} + +static unsigned char rb4xx_nand_read_byte(struct mtd_info *mtd) +{ + unsigned char data = 0; + int err; + + err = rb4xx_cpld_read(&data, NULL, 1); + if (err) { + pr_err("rb4xx_nand: read data failed, err=%d\n", err); + data = 0xff; + } + + return data; +} + +static void rb4xx_nand_write_buf(struct mtd_info *mtd, const unsigned char *buf, + int len) +{ + int err; + + err = rb4xx_cpld_write(buf, len); + if (err) + pr_err("rb4xx_nand: write buf failed, err=%d\n", err); +} + +static void rb4xx_nand_read_buf(struct mtd_info *mtd, unsigned char *buf, + int len) +{ + int err; + + err = rb4xx_cpld_read(buf, NULL, len); + if (err) + pr_err("rb4xx_nand: read buf failed, err=%d\n", err); +} + +static int __devinit rb4xx_nand_probe(struct platform_device *pdev) +{ + struct rb4xx_nand_info *info; + int ret; + + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); + + ret = gpio_request(RB4XX_NAND_GPIO_READY, "NAND RDY"); + if (ret) { + dev_err(&pdev->dev, "unable to request gpio %d\n", + RB4XX_NAND_GPIO_READY); + goto err; + } + + ret = gpio_direction_input(RB4XX_NAND_GPIO_READY); + if (ret) { + dev_err(&pdev->dev, "unable to set input mode on gpio %d\n", + RB4XX_NAND_GPIO_READY); + goto err_free_gpio_ready; + } + + ret = gpio_request(RB4XX_NAND_GPIO_ALE, "NAND ALE"); + if (ret) { + dev_err(&pdev->dev, "unable to request gpio %d\n", + RB4XX_NAND_GPIO_ALE); + goto err_free_gpio_ready; + } + + ret = gpio_direction_output(RB4XX_NAND_GPIO_ALE, 0); + if (ret) { + dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", + RB4XX_NAND_GPIO_ALE); + goto err_free_gpio_ale; + } + + ret = gpio_request(RB4XX_NAND_GPIO_CLE, "NAND CLE"); + if (ret) { + dev_err(&pdev->dev, "unable to request gpio %d\n", + RB4XX_NAND_GPIO_CLE); + goto err_free_gpio_ale; + } + + ret = gpio_direction_output(RB4XX_NAND_GPIO_CLE, 0); + if (ret) { + dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", + RB4XX_NAND_GPIO_CLE); + goto err_free_gpio_cle; + } + + ret = gpio_request(RB4XX_NAND_GPIO_NCE, "NAND NCE"); + if (ret) { + dev_err(&pdev->dev, "unable to request gpio %d\n", + RB4XX_NAND_GPIO_NCE); + goto err_free_gpio_cle; + } + + ret = gpio_direction_output(RB4XX_NAND_GPIO_NCE, 1); + if (ret) { + dev_err(&pdev->dev, "unable to set output mode on gpio %d\n", + RB4XX_NAND_GPIO_ALE); + goto err_free_gpio_nce; + } + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) { + dev_err(&pdev->dev, "rb4xx-nand: no memory for private data\n"); + ret = -ENOMEM; + goto err_free_gpio_nce; + } + + info->chip.priv = &info; + info->mtd.priv = &info->chip; + info->mtd.owner = THIS_MODULE; + + info->chip.cmd_ctrl = rb4xx_nand_cmd_ctrl; + info->chip.dev_ready = rb4xx_nand_dev_ready; + info->chip.read_byte = rb4xx_nand_read_byte; + info->chip.write_buf = rb4xx_nand_write_buf; + info->chip.read_buf = rb4xx_nand_read_buf; +#if 0 + info->chip.verify_buf = rb4xx_nand_verify_buf; +#endif + + info->chip.chip_delay = 25; + info->chip.ecc.mode = NAND_ECC_SOFT; + info->chip.options |= NAND_NO_AUTOINCR; + + platform_set_drvdata(pdev, info); + + ret = nand_scan_ident(&info->mtd, 1, NULL); + if (ret) { + ret = -ENXIO; + goto err_free_info; + } + + if (info->mtd.writesize == 512) + info->chip.ecc.layout = &rb4xx_nand_ecclayout; + + ret = nand_scan_tail(&info->mtd); + if (ret) { + return -ENXIO; + goto err_set_drvdata; + } + + mtd_device_register(&info->mtd, rb4xx_nand_partitions, + ARRAY_SIZE(rb4xx_nand_partitions)); + if (ret) + goto err_release_nand; + + return 0; + +err_release_nand: + nand_release(&info->mtd); +err_set_drvdata: + platform_set_drvdata(pdev, NULL); +err_free_info: + kfree(info); +err_free_gpio_nce: + gpio_free(RB4XX_NAND_GPIO_NCE); +err_free_gpio_cle: + gpio_free(RB4XX_NAND_GPIO_CLE); +err_free_gpio_ale: + gpio_free(RB4XX_NAND_GPIO_ALE); +err_free_gpio_ready: + gpio_free(RB4XX_NAND_GPIO_READY); +err: + return ret; +} + +static int __devexit rb4xx_nand_remove(struct platform_device *pdev) +{ + struct rb4xx_nand_info *info = platform_get_drvdata(pdev); + + nand_release(&info->mtd); + platform_set_drvdata(pdev, NULL); + kfree(info); + gpio_free(RB4XX_NAND_GPIO_NCE); + gpio_free(RB4XX_NAND_GPIO_CLE); + gpio_free(RB4XX_NAND_GPIO_ALE); + gpio_free(RB4XX_NAND_GPIO_READY); + + return 0; +} + +static struct platform_driver rb4xx_nand_driver = { + .probe = rb4xx_nand_probe, + .remove = __devexit_p(rb4xx_nand_remove), + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init rb4xx_nand_init(void) +{ + return platform_driver_register(&rb4xx_nand_driver); +} + +static void __exit rb4xx_nand_exit(void) +{ + platform_driver_unregister(&rb4xx_nand_driver); +} + +module_init(rb4xx_nand_init); +module_exit(rb4xx_nand_exit); + +MODULE_DESCRIPTION(DRV_DESC); +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_AUTHOR("Imre Kaloz "); +MODULE_LICENSE("GPL v2"); diff --git a/target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c b/target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c new file mode 100644 index 000000000..251e18220 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/mtd/nand/rb750_nand.c @@ -0,0 +1,367 @@ +/* + * NAND flash driver for the MikroTik RouterBOARD 750 + * + * Copyright (C) 2010-2012 Gabor Juhos + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define DRV_NAME "rb750-nand" +#define DRV_VERSION "0.1.0" +#define DRV_DESC "NAND flash driver for the RouterBOARD 750" + +#define RB750_NAND_IO0 BIT(RB750_GPIO_NAND_IO0) +#define RB750_NAND_ALE BIT(RB750_GPIO_NAND_ALE) +#define RB750_NAND_CLE BIT(RB750_GPIO_NAND_CLE) +#define RB750_NAND_NRE BIT(RB750_GPIO_NAND_NRE) +#define RB750_NAND_NWE BIT(RB750_GPIO_NAND_NWE) +#define RB750_NAND_RDY BIT(RB750_GPIO_NAND_RDY) + +#define RB750_NAND_DATA_SHIFT 1 +#define RB750_NAND_DATA_BITS (0xff << RB750_NAND_DATA_SHIFT) +#define RB750_NAND_INPUT_BITS (RB750_NAND_DATA_BITS | RB750_NAND_RDY) +#define RB750_NAND_OUTPUT_BITS (RB750_NAND_ALE | RB750_NAND_CLE | \ + RB750_NAND_NRE | RB750_NAND_NWE) + +struct rb750_nand_info { + struct nand_chip chip; + struct mtd_info mtd; + struct rb7xx_nand_platform_data *pdata; +}; + +static inline struct rb750_nand_info *mtd_to_rbinfo(struct mtd_info *mtd) +{ + return container_of(mtd, struct rb750_nand_info, mtd); +} + +/* + * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader + * will not be able to find the kernel that we load. + */ +static struct nand_ecclayout rb750_nand_ecclayout = { + .eccbytes = 6, + .eccpos = { 8, 9, 10, 13, 14, 15 }, + .oobavail = 9, + .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } +}; + +static struct mtd_partition rb750_nand_partitions[] = { + { + .name = "booter", + .offset = 0, + .size = (256 * 1024), + .mask_flags = MTD_WRITEABLE, + }, { + .name = "kernel", + .offset = (256 * 1024), + .size = (4 * 1024 * 1024) - (256 * 1024), + }, { + .name = "rootfs", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +static void rb750_nand_write(const u8 *buf, unsigned len) +{ + void __iomem *base = ath79_gpio_base; + u32 out; + u32 t; + unsigned i; + + /* set data lines to output mode */ + t = __raw_readl(base + AR71XX_GPIO_REG_OE); + __raw_writel(t | RB750_NAND_DATA_BITS, base + AR71XX_GPIO_REG_OE); + + out = __raw_readl(base + AR71XX_GPIO_REG_OUT); + out &= ~(RB750_NAND_DATA_BITS | RB750_NAND_NWE); + for (i = 0; i != len; i++) { + u32 data; + + data = buf[i]; + data <<= RB750_NAND_DATA_SHIFT; + data |= out; + __raw_writel(data, base + AR71XX_GPIO_REG_OUT); + + __raw_writel(data | RB750_NAND_NWE, base + AR71XX_GPIO_REG_OUT); + /* flush write */ + __raw_readl(base + AR71XX_GPIO_REG_OUT); + } + + /* set data lines to input mode */ + t = __raw_readl(base + AR71XX_GPIO_REG_OE); + __raw_writel(t & ~RB750_NAND_DATA_BITS, base + AR71XX_GPIO_REG_OE); + /* flush write */ + __raw_readl(base + AR71XX_GPIO_REG_OE); +} + +static int rb750_nand_read_verify(u8 *read_buf, unsigned len, + const u8 *verify_buf) +{ + void __iomem *base = ath79_gpio_base; + unsigned i; + + for (i = 0; i < len; i++) { + u8 data; + + /* activate RE line */ + __raw_writel(RB750_NAND_NRE, base + AR71XX_GPIO_REG_CLEAR); + /* flush write */ + __raw_readl(base + AR71XX_GPIO_REG_CLEAR); + + /* read input lines */ + data = __raw_readl(base + AR71XX_GPIO_REG_IN) >> + RB750_NAND_DATA_SHIFT; + + /* deactivate RE line */ + __raw_writel(RB750_NAND_NRE, base + AR71XX_GPIO_REG_SET); + + if (read_buf) + read_buf[i] = data; + else if (verify_buf && verify_buf[i] != data) + return -EFAULT; + } + + return 0; +} + +static void rb750_nand_select_chip(struct mtd_info *mtd, int chip) +{ + struct rb750_nand_info *rbinfo = mtd_to_rbinfo(mtd); + void __iomem *base = ath79_gpio_base; + u32 t; + + if (chip >= 0) { + rbinfo->pdata->enable_pins(); + + /* set input mode for data lines */ + t = __raw_readl(base + AR71XX_GPIO_REG_OE); + __raw_writel(t & ~RB750_NAND_INPUT_BITS, + base + AR71XX_GPIO_REG_OE); + + /* deactivate RE and WE lines */ + __raw_writel(RB750_NAND_NRE | RB750_NAND_NWE, + base + AR71XX_GPIO_REG_SET); + /* flush write */ + (void) __raw_readl(base + AR71XX_GPIO_REG_SET); + + /* activate CE line */ + __raw_writel(rbinfo->pdata->nce_line, + base + AR71XX_GPIO_REG_CLEAR); + } else { + /* deactivate CE line */ + __raw_writel(rbinfo->pdata->nce_line, + base + AR71XX_GPIO_REG_SET); + /* flush write */ + (void) __raw_readl(base + AR71XX_GPIO_REG_SET); + + t = __raw_readl(base + AR71XX_GPIO_REG_OE); + __raw_writel(t | RB750_NAND_IO0 | RB750_NAND_RDY, + base + AR71XX_GPIO_REG_OE); + + rbinfo->pdata->disable_pins(); + } +} + +static int rb750_nand_dev_ready(struct mtd_info *mtd) +{ + void __iomem *base = ath79_gpio_base; + + return !!(__raw_readl(base + AR71XX_GPIO_REG_IN) & RB750_NAND_RDY); +} + +static void rb750_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, + unsigned int ctrl) +{ + if (ctrl & NAND_CTRL_CHANGE) { + void __iomem *base = ath79_gpio_base; + u32 t; + + t = __raw_readl(base + AR71XX_GPIO_REG_OUT); + + t &= ~(RB750_NAND_CLE | RB750_NAND_ALE); + t |= (ctrl & NAND_CLE) ? RB750_NAND_CLE : 0; + t |= (ctrl & NAND_ALE) ? RB750_NAND_ALE : 0; + + __raw_writel(t, base + AR71XX_GPIO_REG_OUT); + /* flush write */ + __raw_readl(base + AR71XX_GPIO_REG_OUT); + } + + if (cmd != NAND_CMD_NONE) { + u8 t = cmd; + rb750_nand_write(&t, 1); + } +} + +static u8 rb750_nand_read_byte(struct mtd_info *mtd) +{ + u8 data = 0; + rb750_nand_read_verify(&data, 1, NULL); + return data; +} + +static void rb750_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len) +{ + rb750_nand_read_verify(buf, len, NULL); +} + +static void rb750_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len) +{ + rb750_nand_write(buf, len); +} + +static int rb750_nand_verify_buf(struct mtd_info *mtd, const u8 *buf, int len) +{ + return rb750_nand_read_verify(NULL, len, buf); +} + +static void __init rb750_nand_gpio_init(struct rb750_nand_info *info) +{ + void __iomem *base = ath79_gpio_base; + u32 out; + u32 t; + + out = __raw_readl(base + AR71XX_GPIO_REG_OUT); + + /* setup output levels */ + __raw_writel(RB750_NAND_NCE | RB750_NAND_NRE | RB750_NAND_NWE, + base + AR71XX_GPIO_REG_SET); + + __raw_writel(RB750_NAND_ALE | RB750_NAND_CLE, + base + AR71XX_GPIO_REG_CLEAR); + + /* setup input lines */ + t = __raw_readl(base + AR71XX_GPIO_REG_OE); + __raw_writel(t & ~(RB750_NAND_INPUT_BITS), base + AR71XX_GPIO_REG_OE); + + /* setup output lines */ + t = __raw_readl(base + AR71XX_GPIO_REG_OE); + t |= RB750_NAND_OUTPUT_BITS; + t |= info->pdata->nce_line; + __raw_writel(t, base + AR71XX_GPIO_REG_OE); + + info->pdata->latch_change(~out & RB750_NAND_IO0, out & RB750_NAND_IO0); +} + +static int __devinit rb750_nand_probe(struct platform_device *pdev) +{ + struct rb750_nand_info *info; + struct rb7xx_nand_platform_data *pdata; + int ret; + + printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); + + pdata = pdev->dev.platform_data; + if (!pdata) + return -EINVAL; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->chip.priv = &info; + info->mtd.priv = &info->chip; + info->mtd.owner = THIS_MODULE; + + info->chip.select_chip = rb750_nand_select_chip; + info->chip.cmd_ctrl = rb750_nand_cmd_ctrl; + info->chip.dev_ready = rb750_nand_dev_ready; + info->chip.read_byte = rb750_nand_read_byte; + info->chip.write_buf = rb750_nand_write_buf; + info->chip.read_buf = rb750_nand_read_buf; + info->chip.verify_buf = rb750_nand_verify_buf; + + info->chip.chip_delay = 25; + info->chip.ecc.mode = NAND_ECC_SOFT; + info->chip.options |= NAND_NO_AUTOINCR; + + info->pdata = pdata; + + platform_set_drvdata(pdev, info); + + rb750_nand_gpio_init(info); + + ret = nand_scan_ident(&info->mtd, 1, NULL); + if (ret) { + ret = -ENXIO; + goto err_free_info; + } + + if (info->mtd.writesize == 512) + info->chip.ecc.layout = &rb750_nand_ecclayout; + + ret = nand_scan_tail(&info->mtd); + if (ret) { + return -ENXIO; + goto err_set_drvdata; + } + + ret = mtd_device_register(&info->mtd, rb750_nand_partitions, + ARRAY_SIZE(rb750_nand_partitions)); + if (ret) + goto err_release_nand; + + return 0; + +err_release_nand: + nand_release(&info->mtd); +err_set_drvdata: + platform_set_drvdata(pdev, NULL); +err_free_info: + kfree(info); + return ret; +} + +static int __devexit rb750_nand_remove(struct platform_device *pdev) +{ + struct rb750_nand_info *info = platform_get_drvdata(pdev); + + nand_release(&info->mtd); + platform_set_drvdata(pdev, NULL); + kfree(info); + + return 0; +} + +static struct platform_driver rb750_nand_driver = { + .probe = rb750_nand_probe, + .remove = __devexit_p(rb750_nand_remove), + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init rb750_nand_init(void) +{ + return platform_driver_register(&rb750_nand_driver); +} + +static void __exit rb750_nand_exit(void) +{ + platform_driver_unregister(&rb750_nand_driver); +} + +module_init(rb750_nand_init); +module_exit(rb750_nand_exit); + +MODULE_DESCRIPTION(DRV_DESC); +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_LICENSE("GPL v2"); diff --git a/target/linux/ar71xx/files/drivers/mtd/tplinkpart.c b/target/linux/ar71xx/files/drivers/mtd/tplinkpart.c new file mode 100644 index 000000000..674df6602 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/mtd/tplinkpart.c @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2011 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define TPLINK_NUM_PARTS 5 +#define TPLINK_HEADER_V1 0x01000000 +#define MD5SUM_LEN 16 + +#define TPLINK_ART_LEN 0x10000 +#define TPLINK_KERNEL_OFFS 0x20000 + +struct tplink_fw_header { + uint32_t version; /* header version */ + char vendor_name[24]; + char fw_version[36]; + uint32_t hw_id; /* hardware id */ + uint32_t hw_rev; /* hardware revision */ + uint32_t unk1; + uint8_t md5sum1[MD5SUM_LEN]; + uint32_t unk2; + uint8_t md5sum2[MD5SUM_LEN]; + uint32_t unk3; + uint32_t kernel_la; /* kernel load address */ + uint32_t kernel_ep; /* kernel entry point */ + uint32_t fw_length; /* total length of the firmware */ + uint32_t kernel_ofs; /* kernel data offset */ + uint32_t kernel_len; /* kernel data length */ + uint32_t rootfs_ofs; /* rootfs data offset */ + uint32_t rootfs_len; /* rootfs data length */ + uint32_t boot_ofs; /* bootloader data offset */ + uint32_t boot_len; /* bootloader data length */ + uint8_t pad[360]; +} __attribute__ ((packed)); + +static struct tplink_fw_header * +tplink_read_header(struct mtd_info *mtd, size_t offset) +{ + struct tplink_fw_header *header; + size_t header_len; + size_t retlen; + int ret; + u32 t; + + header = vmalloc(sizeof(*header)); + if (!header) + goto err; + + header_len = sizeof(struct tplink_fw_header); + ret = mtd->read(mtd, offset, header_len, &retlen, + (unsigned char *) header); + if (ret) + goto err_free_header; + + if (retlen != header_len) + goto err_free_header; + + /* sanity checks */ + t = be32_to_cpu(header->version); + if (t != TPLINK_HEADER_V1) + goto err_free_header; + + t = be32_to_cpu(header->kernel_ofs); + if (t != header_len) + goto err_free_header; + + return header; + +err_free_header: + vfree(header); +err: + return NULL; +} + +static int tplink_check_rootfs_magic(struct mtd_info *mtd, size_t offset) +{ + u32 magic; + size_t retlen; + int ret; + + ret = mtd->read(mtd, offset, sizeof(magic), &retlen, + (unsigned char *) &magic); + if (ret) + return ret; + + if (retlen != sizeof(magic)) + return -EIO; + + if (le32_to_cpu(magic) != SQUASHFS_MAGIC && + magic != 0x19852003) + return -EINVAL; + + return 0; +} + +static int tplink_parse_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +{ + struct mtd_partition *parts; + struct tplink_fw_header *header; + int nr_parts; + size_t offset; + size_t art_offset; + size_t rootfs_offset; + size_t squashfs_offset; + int ret; + + nr_parts = TPLINK_NUM_PARTS; + parts = kzalloc(nr_parts * sizeof(struct mtd_partition), GFP_KERNEL); + if (!parts) { + ret = -ENOMEM; + goto err; + } + + offset = TPLINK_KERNEL_OFFS; + + header = tplink_read_header(master, offset); + if (!header) { + pr_notice("%s: no TP-Link header found\n", master->name); + ret = -ENODEV; + goto err_free_parts; + } + + squashfs_offset = offset + sizeof(struct tplink_fw_header) + + be32_to_cpu(header->kernel_len); + + ret = tplink_check_rootfs_magic(master, squashfs_offset); + if (ret == 0) + rootfs_offset = squashfs_offset; + else + rootfs_offset = offset + be32_to_cpu(header->rootfs_ofs); + + art_offset = master->size - TPLINK_ART_LEN; + + parts[0].name = "u-boot"; + parts[0].offset = 0; + parts[0].size = offset; + parts[0].mask_flags = MTD_WRITEABLE; + + parts[1].name = "kernel"; + parts[1].offset = offset; + parts[1].size = rootfs_offset - offset; + + parts[2].name = "rootfs"; + parts[2].offset = rootfs_offset; + parts[2].size = art_offset - rootfs_offset; + + parts[3].name = "art"; + parts[3].offset = art_offset; + parts[3].size = TPLINK_ART_LEN; + parts[3].mask_flags = MTD_WRITEABLE; + + parts[4].name = "firmware"; + parts[4].offset = offset; + parts[4].size = art_offset - offset; + + vfree(header); + + *pparts = parts; + return nr_parts; + +err_free_parts: + kfree(parts); +err: + *pparts = NULL; + return ret; +} + +static struct mtd_part_parser tplink_parser = { + .owner = THIS_MODULE, + .parse_fn = tplink_parse_partitions, + .name = "tp-link", +}; + +static int __init tplink_parser_init(void) +{ + return register_mtd_parser(&tplink_parser); +} + +module_init(tplink_parser_init); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gabor Juhos "); diff --git a/target/linux/ar71xx/files/drivers/mtd/wrt160nl_part.c b/target/linux/ar71xx/files/drivers/mtd/wrt160nl_part.c new file mode 100644 index 000000000..72927f6f2 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/mtd/wrt160nl_part.c @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2009 Christian Daniel + * Copyright (C) 2009 Gabor Juhos + * + * 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 + * + * TRX flash partition table. + * Based on ar7 map by Felix Fietkau + * + */ + +#include +#include +#include +#include + +#include +#include + +struct cybertan_header { + char magic[4]; + u8 res1[4]; + char fw_date[3]; + char fw_ver[3]; + char id[4]; + char hw_ver; + char unused; + u8 flags[2]; + u8 res2[10]; +}; + +#define TRX_PARTS 6 +#define TRX_MAGIC 0x30524448 +#define TRX_MAX_OFFSET 3 + +struct trx_header { + uint32_t magic; /* "HDR0" */ + uint32_t len; /* Length of file including header */ + uint32_t crc32; /* 32-bit CRC from flag_version to end of file */ + uint32_t flag_version; /* 0:15 flags, 16:31 version */ + uint32_t offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ +}; + +#define IH_MAGIC 0x27051956 /* Image Magic Number */ +#define IH_NMLEN 32 /* Image Name Length */ + +struct uimage_header { + uint32_t ih_magic; /* Image Header Magic Number */ + uint32_t ih_hcrc; /* Image Header CRC Checksum */ + uint32_t ih_time; /* Image Creation Timestamp */ + uint32_t ih_size; /* Image Data Size */ + uint32_t ih_load; /* Data» Load Address */ + uint32_t ih_ep; /* Entry Point Address */ + uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ + uint8_t ih_comp; /* Compression Type */ + uint8_t ih_name[IH_NMLEN]; /* Image Name */ +}; + +struct wrt160nl_header { + struct cybertan_header cybertan; + struct trx_header trx; + struct uimage_header uimage; +} __attribute__ ((packed)); + +#define WRT160NL_UBOOT_LEN 0x40000 +#define WRT160NL_ART_LEN 0x10000 +#define WRT160NL_NVRAM_LEN 0x10000 + +static int wrt160nl_parse_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +{ + struct wrt160nl_header *header; + struct trx_header *theader; + struct uimage_header *uheader; + struct mtd_partition *trx_parts; + size_t retlen; + unsigned int kernel_len; + unsigned int uboot_len; + unsigned int nvram_len; + unsigned int art_len; + int ret; + + uboot_len = max_t(unsigned int, master->erasesize, WRT160NL_UBOOT_LEN); + nvram_len = max_t(unsigned int, master->erasesize, WRT160NL_NVRAM_LEN); + art_len = max_t(unsigned int, master->erasesize, WRT160NL_ART_LEN); + + trx_parts = kzalloc(TRX_PARTS * sizeof(struct mtd_partition), + GFP_KERNEL); + if (!trx_parts) { + ret = -ENOMEM; + goto out; + } + + header = vmalloc(sizeof(*header)); + if (!header) { + return -ENOMEM; + goto free_parts; + } + + ret = master->read(master, uboot_len, sizeof(*header), + &retlen, (void *) header); + if (ret) + goto free_hdr; + + if (retlen != sizeof(*header)) { + ret = -EIO; + goto free_hdr; + } + + if (strncmp(header->cybertan.magic, "NL16", 4) != 0) { + printk(KERN_NOTICE "%s: no WRT160NL signature found\n", + master->name); + goto free_hdr; + } + + theader = &header->trx; + if (le32_to_cpu(theader->magic) != TRX_MAGIC) { + printk(KERN_NOTICE "%s: no TRX header found\n", master->name); + goto free_hdr; + } + + uheader = &header->uimage; + if (uheader->ih_magic != IH_MAGIC) { + printk(KERN_NOTICE "%s: no uImage found\n", master->name); + goto free_hdr; + } + + kernel_len = le32_to_cpu(theader->offsets[1]) + + sizeof(struct cybertan_header); + + trx_parts[0].name = "u-boot"; + trx_parts[0].offset = 0; + trx_parts[0].size = uboot_len; + trx_parts[0].mask_flags = MTD_WRITEABLE; + + trx_parts[1].name = "kernel"; + trx_parts[1].offset = trx_parts[0].offset + trx_parts[0].size; + trx_parts[1].size = kernel_len; + trx_parts[1].mask_flags = 0; + + trx_parts[2].name = "rootfs"; + trx_parts[2].offset = trx_parts[1].offset + trx_parts[1].size; + trx_parts[2].size = master->size - uboot_len - nvram_len - art_len - + trx_parts[1].size; + trx_parts[2].mask_flags = 0; + + trx_parts[3].name = "nvram"; + trx_parts[3].offset = master->size - nvram_len - art_len; + trx_parts[3].size = nvram_len; + trx_parts[3].mask_flags = MTD_WRITEABLE; + + trx_parts[4].name = "art"; + trx_parts[4].offset = master->size - art_len; + trx_parts[4].size = art_len; + trx_parts[4].mask_flags = MTD_WRITEABLE; + + trx_parts[5].name = "firmware"; + trx_parts[5].offset = uboot_len; + trx_parts[5].size = master->size - uboot_len - nvram_len - art_len; + trx_parts[5].mask_flags = 0; + + vfree(header); + + *pparts = trx_parts; + return TRX_PARTS; + +free_hdr: + vfree(header); +free_parts: + kfree(trx_parts); +out: + return ret; +} + +static struct mtd_part_parser wrt160nl_parser = { + .owner = THIS_MODULE, + .parse_fn = wrt160nl_parse_partitions, + .name = "wrt160nl", +}; + +static int __init wrt160nl_parser_init(void) +{ + return register_mtd_parser(&wrt160nl_parser); +} + +module_init(wrt160nl_parser_init); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Christian Daniel "); diff --git a/target/linux/ar71xx/files/drivers/net/dsa/mv88e6063.c b/target/linux/ar71xx/files/drivers/net/dsa/mv88e6063.c new file mode 100644 index 000000000..b41eb5481 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/net/dsa/mv88e6063.c @@ -0,0 +1,294 @@ +/* + * net/dsa/mv88e6063.c - Driver for Marvell 88e6063 switch chips + * Copyright (c) 2009 Gabor Juhos + * + * This driver was base on: net/dsa/mv88e6060.c + * net/dsa/mv88e6063.c - Driver for Marvell 88e6060 switch chips + * Copyright (c) 2008-2009 Marvell Semiconductor + * + * 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. + */ + +#include +#include +#include +#include + +#define REG_BASE 0x10 +#define REG_PHY(p) (REG_BASE + (p)) +#define REG_PORT(p) (REG_BASE + 8 + (p)) +#define REG_GLOBAL (REG_BASE + 0x0f) +#define NUM_PORTS 7 + +static int reg_read(struct dsa_switch *ds, int addr, int reg) +{ + return mdiobus_read(ds->master_mii_bus, addr, reg); +} + +#define REG_READ(addr, reg) \ + ({ \ + int __ret; \ + \ + __ret = reg_read(ds, addr, reg); \ + if (__ret < 0) \ + return __ret; \ + __ret; \ + }) + + +static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val) +{ + return mdiobus_write(ds->master_mii_bus, addr, reg, val); +} + +#define REG_WRITE(addr, reg, val) \ + ({ \ + int __ret; \ + \ + __ret = reg_write(ds, addr, reg, val); \ + if (__ret < 0) \ + return __ret; \ + }) + +static char *mv88e6063_probe(struct mii_bus *bus, int sw_addr) +{ + int ret; + + ret = mdiobus_read(bus, REG_PORT(0), 0x03); + if (ret >= 0) { + ret &= 0xfff0; + if (ret == 0x1530) + return "Marvell 88E6063"; + } + + return NULL; +} + +static int mv88e6063_switch_reset(struct dsa_switch *ds) +{ + int i; + int ret; + + /* + * Set all ports to the disabled state. + */ + for (i = 0; i < NUM_PORTS; i++) { + ret = REG_READ(REG_PORT(i), 0x04); + REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc); + } + + /* + * Wait for transmit queues to drain. + */ + msleep(2); + + /* + * Reset the switch. + */ + REG_WRITE(REG_GLOBAL, 0x0a, 0xa130); + + /* + * Wait up to one second for reset to complete. + */ + for (i = 0; i < 1000; i++) { + ret = REG_READ(REG_GLOBAL, 0x00); + if ((ret & 0x8000) == 0x0000) + break; + + msleep(1); + } + if (i == 1000) + return -ETIMEDOUT; + + return 0; +} + +static int mv88e6063_setup_global(struct dsa_switch *ds) +{ + /* + * Disable discarding of frames with excessive collisions, + * set the maximum frame size to 1536 bytes, and mask all + * interrupt sources. + */ + REG_WRITE(REG_GLOBAL, 0x04, 0x0800); + + /* + * Enable automatic address learning, set the address + * database size to 1024 entries, and set the default aging + * time to 5 minutes. + */ + REG_WRITE(REG_GLOBAL, 0x0a, 0x2130); + + return 0; +} + +static int mv88e6063_setup_port(struct dsa_switch *ds, int p) +{ + int addr = REG_PORT(p); + + /* + * Do not force flow control, disable Ingress and Egress + * Header tagging, disable VLAN tunneling, and set the port + * state to Forwarding. Additionally, if this is the CPU + * port, enable Ingress and Egress Trailer tagging mode. + */ + REG_WRITE(addr, 0x04, dsa_is_cpu_port(ds, p) ? 0x4103 : 0x0003); + + /* + * Port based VLAN map: give each port its own address + * database, allow the CPU port to talk to each of the 'real' + * ports, and allow each of the 'real' ports to only talk to + * the CPU port. + */ + REG_WRITE(addr, 0x06, + ((p & 0xf) << 12) | + (dsa_is_cpu_port(ds, p) ? + ds->phys_port_mask : + (1 << ds->dst->cpu_port))); + + /* + * Port Association Vector: when learning source addresses + * of packets, add the address to the address database using + * a port bitmap that has only the bit for this port set and + * the other bits clear. + */ + REG_WRITE(addr, 0x0b, 1 << p); + + return 0; +} + +static int mv88e6063_setup(struct dsa_switch *ds) +{ + int i; + int ret; + + ret = mv88e6063_switch_reset(ds); + if (ret < 0) + return ret; + + /* @@@ initialise atu */ + + ret = mv88e6063_setup_global(ds); + if (ret < 0) + return ret; + + for (i = 0; i < NUM_PORTS; i++) { + ret = mv88e6063_setup_port(ds, i); + if (ret < 0) + return ret; + } + + return 0; +} + +static int mv88e6063_set_addr(struct dsa_switch *ds, u8 *addr) +{ + REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]); + REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]); + REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]); + + return 0; +} + +static int mv88e6063_port_to_phy_addr(int port) +{ + if (port >= 0 && port <= NUM_PORTS) + return REG_PHY(port); + return -1; +} + +static int mv88e6063_phy_read(struct dsa_switch *ds, int port, int regnum) +{ + int addr; + + addr = mv88e6063_port_to_phy_addr(port); + if (addr == -1) + return 0xffff; + + return reg_read(ds, addr, regnum); +} + +static int +mv88e6063_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) +{ + int addr; + + addr = mv88e6063_port_to_phy_addr(port); + if (addr == -1) + return 0xffff; + + return reg_write(ds, addr, regnum, val); +} + +static void mv88e6063_poll_link(struct dsa_switch *ds) +{ + int i; + + for (i = 0; i < DSA_MAX_PORTS; i++) { + struct net_device *dev; + int uninitialized_var(port_status); + int link; + int speed; + int duplex; + int fc; + + dev = ds->ports[i]; + if (dev == NULL) + continue; + + link = 0; + if (dev->flags & IFF_UP) { + port_status = reg_read(ds, REG_PORT(i), 0x00); + if (port_status < 0) + continue; + + link = !!(port_status & 0x1000); + } + + if (!link) { + if (netif_carrier_ok(dev)) { + printk(KERN_INFO "%s: link down\n", dev->name); + netif_carrier_off(dev); + } + continue; + } + + speed = (port_status & 0x0100) ? 100 : 10; + duplex = (port_status & 0x0200) ? 1 : 0; + fc = ((port_status & 0xc000) == 0xc000) ? 1 : 0; + + if (!netif_carrier_ok(dev)) { + printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, " + "flow control %sabled\n", dev->name, + speed, duplex ? "full" : "half", + fc ? "en" : "dis"); + netif_carrier_on(dev); + } + } +} + +static struct dsa_switch_driver mv88e6063_switch_driver = { + .tag_protocol = htons(ETH_P_TRAILER), + .probe = mv88e6063_probe, + .setup = mv88e6063_setup, + .set_addr = mv88e6063_set_addr, + .phy_read = mv88e6063_phy_read, + .phy_write = mv88e6063_phy_write, + .poll_link = mv88e6063_poll_link, +}; + +static int __init mv88e6063_init(void) +{ + register_switch_driver(&mv88e6063_switch_driver); + return 0; +} +module_init(mv88e6063_init); + +static void __exit mv88e6063_cleanup(void) +{ + unregister_switch_driver(&mv88e6063_switch_driver); +} +module_exit(mv88e6063_cleanup); diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Kconfig b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Kconfig new file mode 100644 index 000000000..42d544f73 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Kconfig @@ -0,0 +1,33 @@ +config AG71XX + tristate "Atheros AR7XXX/AR9XXX built-in ethernet mac support" + depends on ATH79 + select PHYLIB + help + If you wish to compile a kernel for AR7XXX/91XXX and enable + ethernet support, then you should always answer Y to this. + +if AG71XX + +config AG71XX_DEBUG + bool "Atheros AR71xx built-in ethernet driver debugging" + default n + help + Atheros AR71xx built-in ethernet driver debugging messages. + +config AG71XX_DEBUG_FS + bool "Atheros AR71xx built-in ethernet driver debugfs support" + depends on DEBUG_FS + default n + help + Say Y, if you need access to various statistics provided by + the ag71xx driver. + +config AG71XX_AR8216_SUPPORT + bool "special support for the Atheros AR8216 switch" + default n + default y if ATH79_MACH_WNR2000 || ATH79_MACH_MZK_W04NU + help + Say 'y' here if you want to enable special support for the + Atheros AR8216 switch found on some boards. + +endif diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Makefile b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Makefile new file mode 100644 index 000000000..b3ec4084c --- /dev/null +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/Makefile @@ -0,0 +1,15 @@ +# +# Makefile for the Atheros AR71xx built-in ethernet macs +# + +ag71xx-y += ag71xx_main.o +ag71xx-y += ag71xx_ethtool.o +ag71xx-y += ag71xx_phy.o +ag71xx-y += ag71xx_mdio.o +ag71xx-y += ag71xx_ar7240.o + +ag71xx-$(CONFIG_AG71XX_DEBUG_FS) += ag71xx_debugfs.o +ag71xx-$(CONFIG_AG71XX_AR8216_SUPPORT) += ag71xx_ar8216.o + +obj-$(CONFIG_AG71XX) += ag71xx.o + diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h new file mode 100644 index 000000000..b9d95adaf --- /dev/null +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h @@ -0,0 +1,477 @@ +/* + * Atheros AR71xx built-in ethernet mac driver + * + * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * Based on Atheros' AG7100 driver + * + * This program 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. + */ + +#ifndef __AG71XX_H +#define __AG71XX_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#define AG71XX_DRV_NAME "ag71xx" +#define AG71XX_DRV_VERSION "0.5.35" + +#define AG71XX_NAPI_WEIGHT 64 +#define AG71XX_OOM_REFILL (1 + HZ/10) + +#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE) +#define AG71XX_INT_TX (AG71XX_INT_TX_PS) +#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF) + +#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX) +#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL) + +#define AG71XX_TX_MTU_LEN 1540 +#define AG71XX_RX_PKT_SIZE \ + (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) +#define AG71XX_RX_BUF_SIZE (AG71XX_RX_PKT_SIZE + NET_SKB_PAD + NET_IP_ALIGN) + +#define AG71XX_TX_RING_SIZE_DEFAULT 64 +#define AG71XX_RX_RING_SIZE_DEFAULT 128 + +#define AG71XX_TX_RING_SIZE_MAX 256 +#define AG71XX_RX_RING_SIZE_MAX 256 + +#ifdef CONFIG_AG71XX_DEBUG +#define DBG(fmt, args...) pr_debug(fmt, ## args) +#else +#define DBG(fmt, args...) do {} while (0) +#endif + +#define ag71xx_assert(_cond) \ +do { \ + if (_cond) \ + break; \ + printk("%s,%d: assertion failed\n", __FILE__, __LINE__); \ + BUG(); \ +} while (0) + +struct ag71xx_desc { + u32 data; + u32 ctrl; +#define DESC_EMPTY BIT(31) +#define DESC_MORE BIT(24) +#define DESC_PKTLEN_M 0xfff + u32 next; + u32 pad; +} __attribute__((aligned(4))); + +struct ag71xx_buf { + union { + struct sk_buff *skb; + void *rx_buf; + }; + struct ag71xx_desc *desc; + dma_addr_t dma_addr; + unsigned long timestamp; +}; + +struct ag71xx_ring { + struct ag71xx_buf *buf; + u8 *descs_cpu; + dma_addr_t descs_dma; + unsigned int desc_size; + unsigned int curr; + unsigned int dirty; + unsigned int size; +}; + +struct ag71xx_mdio { + struct mii_bus *mii_bus; + int mii_irq[PHY_MAX_ADDR]; + void __iomem *mdio_base; + struct ag71xx_mdio_platform_data *pdata; +}; + +struct ag71xx_int_stats { + unsigned long rx_pr; + unsigned long rx_be; + unsigned long rx_of; + unsigned long tx_ps; + unsigned long tx_be; + unsigned long tx_ur; + unsigned long total; +}; + +struct ag71xx_napi_stats { + unsigned long napi_calls; + unsigned long rx_count; + unsigned long rx_packets; + unsigned long rx_packets_max; + unsigned long tx_count; + unsigned long tx_packets; + unsigned long tx_packets_max; + + unsigned long rx[AG71XX_NAPI_WEIGHT + 1]; + unsigned long tx[AG71XX_NAPI_WEIGHT + 1]; +}; + +struct ag71xx_debug { + struct dentry *debugfs_dir; + + struct ag71xx_int_stats int_stats; + struct ag71xx_napi_stats napi_stats; +}; + +struct ag71xx { + void __iomem *mac_base; + + spinlock_t lock; + struct platform_device *pdev; + struct net_device *dev; + struct napi_struct napi; + u32 msg_enable; + + struct ag71xx_desc *stop_desc; + dma_addr_t stop_desc_dma; + + struct ag71xx_ring rx_ring; + struct ag71xx_ring tx_ring; + + struct mii_bus *mii_bus; + struct phy_device *phy_dev; + void *phy_priv; + + unsigned int link; + unsigned int speed; + int duplex; + + struct work_struct restart_work; + struct delayed_work link_work; + struct timer_list oom_timer; + +#ifdef CONFIG_AG71XX_DEBUG_FS + struct ag71xx_debug debug; +#endif +}; + +extern struct ethtool_ops ag71xx_ethtool_ops; +void ag71xx_link_adjust(struct ag71xx *ag); + +int ag71xx_mdio_driver_init(void) __init; +void ag71xx_mdio_driver_exit(void); + +int ag71xx_phy_connect(struct ag71xx *ag); +void ag71xx_phy_disconnect(struct ag71xx *ag); +void ag71xx_phy_start(struct ag71xx *ag); +void ag71xx_phy_stop(struct ag71xx *ag); + +static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag) +{ + return ag->pdev->dev.platform_data; +} + +static inline int ag71xx_desc_empty(struct ag71xx_desc *desc) +{ + return (desc->ctrl & DESC_EMPTY) != 0; +} + +static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc) +{ + return desc->ctrl & DESC_PKTLEN_M; +} + +/* Register offsets */ +#define AG71XX_REG_MAC_CFG1 0x0000 +#define AG71XX_REG_MAC_CFG2 0x0004 +#define AG71XX_REG_MAC_IPG 0x0008 +#define AG71XX_REG_MAC_HDX 0x000c +#define AG71XX_REG_MAC_MFL 0x0010 +#define AG71XX_REG_MII_CFG 0x0020 +#define AG71XX_REG_MII_CMD 0x0024 +#define AG71XX_REG_MII_ADDR 0x0028 +#define AG71XX_REG_MII_CTRL 0x002c +#define AG71XX_REG_MII_STATUS 0x0030 +#define AG71XX_REG_MII_IND 0x0034 +#define AG71XX_REG_MAC_IFCTL 0x0038 +#define AG71XX_REG_MAC_ADDR1 0x0040 +#define AG71XX_REG_MAC_ADDR2 0x0044 +#define AG71XX_REG_FIFO_CFG0 0x0048 +#define AG71XX_REG_FIFO_CFG1 0x004c +#define AG71XX_REG_FIFO_CFG2 0x0050 +#define AG71XX_REG_FIFO_CFG3 0x0054 +#define AG71XX_REG_FIFO_CFG4 0x0058 +#define AG71XX_REG_FIFO_CFG5 0x005c +#define AG71XX_REG_FIFO_RAM0 0x0060 +#define AG71XX_REG_FIFO_RAM1 0x0064 +#define AG71XX_REG_FIFO_RAM2 0x0068 +#define AG71XX_REG_FIFO_RAM3 0x006c +#define AG71XX_REG_FIFO_RAM4 0x0070 +#define AG71XX_REG_FIFO_RAM5 0x0074 +#define AG71XX_REG_FIFO_RAM6 0x0078 +#define AG71XX_REG_FIFO_RAM7 0x007c + +#define AG71XX_REG_TX_CTRL 0x0180 +#define AG71XX_REG_TX_DESC 0x0184 +#define AG71XX_REG_TX_STATUS 0x0188 +#define AG71XX_REG_RX_CTRL 0x018c +#define AG71XX_REG_RX_DESC 0x0190 +#define AG71XX_REG_RX_STATUS 0x0194 +#define AG71XX_REG_INT_ENABLE 0x0198 +#define AG71XX_REG_INT_STATUS 0x019c + +#define AG71XX_REG_FIFO_DEPTH 0x01a8 +#define AG71XX_REG_RX_SM 0x01b0 +#define AG71XX_REG_TX_SM 0x01b4 + +#define MAC_CFG1_TXE BIT(0) /* Tx Enable */ +#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */ +#define MAC_CFG1_RXE BIT(2) /* Rx Enable */ +#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */ +#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */ +#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */ +#define MAC_CFG1_LB BIT(8) /* Loopback mode */ +#define MAC_CFG1_SR BIT(31) /* Soft Reset */ + +#define MAC_CFG2_FDX BIT(0) +#define MAC_CFG2_CRC_EN BIT(1) +#define MAC_CFG2_PAD_CRC_EN BIT(2) +#define MAC_CFG2_LEN_CHECK BIT(4) +#define MAC_CFG2_HUGE_FRAME_EN BIT(5) +#define MAC_CFG2_IF_1000 BIT(9) +#define MAC_CFG2_IF_10_100 BIT(8) + +#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */ +#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */ +#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */ +#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */ +#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */ +#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \ + | FIFO_CFG0_TXS | FIFO_CFG0_TXF) + +#define FIFO_CFG0_ENABLE_SHIFT 8 + +#define FIFO_CFG4_DE BIT(0) /* Drop Event */ +#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */ +#define FIFO_CFG4_FC BIT(2) /* False Carrier */ +#define FIFO_CFG4_CE BIT(3) /* Code Error */ +#define FIFO_CFG4_CR BIT(4) /* CRC error */ +#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */ +#define FIFO_CFG4_LO BIT(6) /* Length out of range */ +#define FIFO_CFG4_OK BIT(7) /* Packet is OK */ +#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */ +#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */ +#define FIFO_CFG4_DR BIT(10) /* Dribble */ +#define FIFO_CFG4_LE BIT(11) /* Long Event */ +#define FIFO_CFG4_CF BIT(12) /* Control Frame */ +#define FIFO_CFG4_PF BIT(13) /* Pause Frame */ +#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */ +#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */ +#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */ +#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */ + +#define FIFO_CFG5_DE BIT(0) /* Drop Event */ +#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */ +#define FIFO_CFG5_FC BIT(2) /* False Carrier */ +#define FIFO_CFG5_CE BIT(3) /* Code Error */ +#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */ +#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */ +#define FIFO_CFG5_OK BIT(6) /* Packet is OK */ +#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */ +#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */ +#define FIFO_CFG5_DR BIT(9) /* Dribble */ +#define FIFO_CFG5_CF BIT(10) /* Control Frame */ +#define FIFO_CFG5_PF BIT(11) /* Pause Frame */ +#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */ +#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */ +#define FIFO_CFG5_LE BIT(14) /* Long Event */ +#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */ +#define FIFO_CFG5_16 BIT(16) /* unknown */ +#define FIFO_CFG5_17 BIT(17) /* unknown */ +#define FIFO_CFG5_SF BIT(18) /* Short Frame */ +#define FIFO_CFG5_BM BIT(19) /* Byte Mode */ + +#define AG71XX_INT_TX_PS BIT(0) +#define AG71XX_INT_TX_UR BIT(1) +#define AG71XX_INT_TX_BE BIT(3) +#define AG71XX_INT_RX_PR BIT(4) +#define AG71XX_INT_RX_OF BIT(6) +#define AG71XX_INT_RX_BE BIT(7) + +#define MAC_IFCTL_SPEED BIT(16) + +#define MII_CFG_CLK_DIV_4 0 +#define MII_CFG_CLK_DIV_6 2 +#define MII_CFG_CLK_DIV_8 3 +#define MII_CFG_CLK_DIV_10 4 +#define MII_CFG_CLK_DIV_14 5 +#define MII_CFG_CLK_DIV_20 6 +#define MII_CFG_CLK_DIV_28 7 +#define MII_CFG_CLK_DIV_34 8 +#define MII_CFG_CLK_DIV_42 9 +#define MII_CFG_CLK_DIV_50 10 +#define MII_CFG_CLK_DIV_58 11 +#define MII_CFG_CLK_DIV_66 12 +#define MII_CFG_CLK_DIV_74 13 +#define MII_CFG_CLK_DIV_82 14 +#define MII_CFG_CLK_DIV_98 15 +#define MII_CFG_RESET BIT(31) + +#define MII_CMD_WRITE 0x0 +#define MII_CMD_READ 0x1 +#define MII_ADDR_SHIFT 8 +#define MII_IND_BUSY BIT(0) +#define MII_IND_INVALID BIT(2) + +#define TX_CTRL_TXE BIT(0) /* Tx Enable */ + +#define TX_STATUS_PS BIT(0) /* Packet Sent */ +#define TX_STATUS_UR BIT(1) /* Tx Underrun */ +#define TX_STATUS_BE BIT(3) /* Bus Error */ + +#define RX_CTRL_RXE BIT(0) /* Rx Enable */ + +#define RX_STATUS_PR BIT(0) /* Packet Received */ +#define RX_STATUS_OF BIT(2) /* Rx Overflow */ +#define RX_STATUS_BE BIT(3) /* Bus Error */ + +static inline void ag71xx_check_reg_offset(struct ag71xx *ag, unsigned reg) +{ + switch (reg) { + case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: + case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_TX_SM: + case AG71XX_REG_MII_CFG: + break; + + default: + BUG(); + } +} + +static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) +{ + ag71xx_check_reg_offset(ag, reg); + + __raw_writel(value, ag->mac_base + reg); + /* flush write */ + (void) __raw_readl(ag->mac_base + reg); +} + +static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg) +{ + ag71xx_check_reg_offset(ag, reg); + + return __raw_readl(ag->mac_base + reg); +} + +static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask) +{ + void __iomem *r; + + ag71xx_check_reg_offset(ag, reg); + + r = ag->mac_base + reg; + __raw_writel(__raw_readl(r) | mask, r); + /* flush write */ + (void)__raw_readl(r); +} + +static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask) +{ + void __iomem *r; + + ag71xx_check_reg_offset(ag, reg); + + r = ag->mac_base + reg; + __raw_writel(__raw_readl(r) & ~mask, r); + /* flush write */ + (void) __raw_readl(r); +} + +static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints) +{ + ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints); +} + +static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints) +{ + ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints); +} + +#ifdef CONFIG_AG71XX_AR8216_SUPPORT +void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb); +int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, + int pktlen); +static inline int ag71xx_has_ar8216(struct ag71xx *ag) +{ + return ag71xx_get_pdata(ag)->has_ar8216; +} +#else +static inline void ag71xx_add_ar8216_header(struct ag71xx *ag, + struct sk_buff *skb) +{ +} + +static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag, + struct sk_buff *skb, + int pktlen) +{ + return 0; +} +static inline int ag71xx_has_ar8216(struct ag71xx *ag) +{ + return 0; +} +#endif + +#ifdef CONFIG_AG71XX_DEBUG_FS +int ag71xx_debugfs_root_init(void); +void ag71xx_debugfs_root_exit(void); +int ag71xx_debugfs_init(struct ag71xx *ag); +void ag71xx_debugfs_exit(struct ag71xx *ag); +void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status); +void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx); +#else +static inline int ag71xx_debugfs_root_init(void) { return 0; } +static inline void ag71xx_debugfs_root_exit(void) {} +static inline int ag71xx_debugfs_init(struct ag71xx *ag) { return 0; } +static inline void ag71xx_debugfs_exit(struct ag71xx *ag) {} +static inline void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, + u32 status) {} +static inline void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, + int rx, int tx) {} +#endif /* CONFIG_AG71XX_DEBUG_FS */ + +void ag71xx_ar7240_start(struct ag71xx *ag); +void ag71xx_ar7240_stop(struct ag71xx *ag); +int ag71xx_ar7240_init(struct ag71xx *ag); +void ag71xx_ar7240_cleanup(struct ag71xx *ag); + +int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg); +void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val); + +u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr, + unsigned reg_addr); +int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr, + unsigned reg_addr, u16 reg_val); + +#endif /* _AG71XX_H */ diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c new file mode 100644 index 000000000..49f077520 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c @@ -0,0 +1,1193 @@ +/* + * Driver for the built-in ethernet switch of the Atheros AR7240 SoC + * Copyright (c) 2010 Gabor Juhos + * Copyright (c) 2010 Felix Fietkau + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "ag71xx.h" + +#define BITM(_count) (BIT(_count) - 1) +#define BITS(_shift, _count) (BITM(_count) << _shift) + +#define AR7240_REG_MASK_CTRL 0x00 +#define AR7240_MASK_CTRL_REVISION_M BITM(8) +#define AR7240_MASK_CTRL_VERSION_M BITM(8) +#define AR7240_MASK_CTRL_VERSION_S 8 +#define AR7240_MASK_CTRL_VERSION_AR7240 0x01 +#define AR7240_MASK_CTRL_VERSION_AR934X 0x02 +#define AR7240_MASK_CTRL_SOFT_RESET BIT(31) + +#define AR7240_REG_MAC_ADDR0 0x20 +#define AR7240_REG_MAC_ADDR1 0x24 + +#define AR7240_REG_FLOOD_MASK 0x2c +#define AR7240_FLOOD_MASK_BROAD_TO_CPU BIT(26) + +#define AR7240_REG_GLOBAL_CTRL 0x30 +#define AR7240_GLOBAL_CTRL_MTU_M BITM(12) + +#define AR7240_REG_VTU 0x0040 +#define AR7240_VTU_OP BITM(3) +#define AR7240_VTU_OP_NOOP 0x0 +#define AR7240_VTU_OP_FLUSH 0x1 +#define AR7240_VTU_OP_LOAD 0x2 +#define AR7240_VTU_OP_PURGE 0x3 +#define AR7240_VTU_OP_REMOVE_PORT 0x4 +#define AR7240_VTU_ACTIVE BIT(3) +#define AR7240_VTU_FULL BIT(4) +#define AR7240_VTU_PORT BITS(8, 4) +#define AR7240_VTU_PORT_S 8 +#define AR7240_VTU_VID BITS(16, 12) +#define AR7240_VTU_VID_S 16 +#define AR7240_VTU_PRIO BITS(28, 3) +#define AR7240_VTU_PRIO_S 28 +#define AR7240_VTU_PRIO_EN BIT(31) + +#define AR7240_REG_VTU_DATA 0x0044 +#define AR7240_VTUDATA_MEMBER BITS(0, 10) +#define AR7240_VTUDATA_VALID BIT(11) + +#define AR7240_REG_ATU 0x50 +#define AR7240_ATU_FLUSH_ALL 0x1 + +#define AR7240_REG_AT_CTRL 0x5c +#define AR7240_AT_CTRL_AGE_TIME BITS(0, 15) +#define AR7240_AT_CTRL_AGE_EN BIT(17) +#define AR7240_AT_CTRL_LEARN_CHANGE BIT(18) +#define AR7240_AT_CTRL_RESERVED BIT(19) +#define AR7240_AT_CTRL_ARP_EN BIT(20) + +#define AR7240_REG_TAG_PRIORITY 0x70 + +#define AR7240_REG_SERVICE_TAG 0x74 +#define AR7240_SERVICE_TAG_M BITM(16) + +#define AR7240_REG_CPU_PORT 0x78 +#define AR7240_MIRROR_PORT_S 4 +#define AR7240_CPU_PORT_EN BIT(8) + +#define AR7240_REG_MIB_FUNCTION0 0x80 +#define AR7240_MIB_TIMER_M BITM(16) +#define AR7240_MIB_AT_HALF_EN BIT(16) +#define AR7240_MIB_BUSY BIT(17) +#define AR7240_MIB_FUNC_S 24 +#define AR7240_MIB_FUNC_M BITM(3) +#define AR7240_MIB_FUNC_NO_OP 0x0 +#define AR7240_MIB_FUNC_FLUSH 0x1 +#define AR7240_MIB_FUNC_CAPTURE 0x3 + +#define AR7240_REG_MDIO_CTRL 0x98 +#define AR7240_MDIO_CTRL_DATA_M BITM(16) +#define AR7240_MDIO_CTRL_REG_ADDR_S 16 +#define AR7240_MDIO_CTRL_PHY_ADDR_S 21 +#define AR7240_MDIO_CTRL_CMD_WRITE 0 +#define AR7240_MDIO_CTRL_CMD_READ BIT(27) +#define AR7240_MDIO_CTRL_MASTER_EN BIT(30) +#define AR7240_MDIO_CTRL_BUSY BIT(31) + +#define AR7240_REG_PORT_BASE(_port) (0x100 + (_port) * 0x100) + +#define AR7240_REG_PORT_STATUS(_port) (AR7240_REG_PORT_BASE((_port)) + 0x00) +#define AR7240_PORT_STATUS_SPEED_S 0 +#define AR7240_PORT_STATUS_SPEED_M BITM(2) +#define AR7240_PORT_STATUS_SPEED_10 0 +#define AR7240_PORT_STATUS_SPEED_100 1 +#define AR7240_PORT_STATUS_SPEED_1000 2 +#define AR7240_PORT_STATUS_TXMAC BIT(2) +#define AR7240_PORT_STATUS_RXMAC BIT(3) +#define AR7240_PORT_STATUS_TXFLOW BIT(4) +#define AR7240_PORT_STATUS_RXFLOW BIT(5) +#define AR7240_PORT_STATUS_DUPLEX BIT(6) +#define AR7240_PORT_STATUS_LINK_UP BIT(8) +#define AR7240_PORT_STATUS_LINK_AUTO BIT(9) +#define AR7240_PORT_STATUS_LINK_PAUSE BIT(10) + +#define AR7240_REG_PORT_CTRL(_port) (AR7240_REG_PORT_BASE((_port)) + 0x04) +#define AR7240_PORT_CTRL_STATE_M BITM(3) +#define AR7240_PORT_CTRL_STATE_DISABLED 0 +#define AR7240_PORT_CTRL_STATE_BLOCK 1 +#define AR7240_PORT_CTRL_STATE_LISTEN 2 +#define AR7240_PORT_CTRL_STATE_LEARN 3 +#define AR7240_PORT_CTRL_STATE_FORWARD 4 +#define AR7240_PORT_CTRL_LEARN_LOCK BIT(7) +#define AR7240_PORT_CTRL_VLAN_MODE_S 8 +#define AR7240_PORT_CTRL_VLAN_MODE_KEEP 0 +#define AR7240_PORT_CTRL_VLAN_MODE_STRIP 1 +#define AR7240_PORT_CTRL_VLAN_MODE_ADD 2 +#define AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG 3 +#define AR7240_PORT_CTRL_IGMP_SNOOP BIT(10) +#define AR7240_PORT_CTRL_HEADER BIT(11) +#define AR7240_PORT_CTRL_MAC_LOOP BIT(12) +#define AR7240_PORT_CTRL_SINGLE_VLAN BIT(13) +#define AR7240_PORT_CTRL_LEARN BIT(14) +#define AR7240_PORT_CTRL_DOUBLE_TAG BIT(15) +#define AR7240_PORT_CTRL_MIRROR_TX BIT(16) +#define AR7240_PORT_CTRL_MIRROR_RX BIT(17) + +#define AR7240_REG_PORT_VLAN(_port) (AR7240_REG_PORT_BASE((_port)) + 0x08) + +#define AR7240_PORT_VLAN_DEFAULT_ID_S 0 +#define AR7240_PORT_VLAN_DEST_PORTS_S 16 +#define AR7240_PORT_VLAN_MODE_S 30 +#define AR7240_PORT_VLAN_MODE_PORT_ONLY 0 +#define AR7240_PORT_VLAN_MODE_PORT_FALLBACK 1 +#define AR7240_PORT_VLAN_MODE_VLAN_ONLY 2 +#define AR7240_PORT_VLAN_MODE_SECURE 3 + + +#define AR7240_REG_STATS_BASE(_port) (0x20000 + (_port) * 0x100) + +#define AR7240_STATS_RXBROAD 0x00 +#define AR7240_STATS_RXPAUSE 0x04 +#define AR7240_STATS_RXMULTI 0x08 +#define AR7240_STATS_RXFCSERR 0x0c +#define AR7240_STATS_RXALIGNERR 0x10 +#define AR7240_STATS_RXRUNT 0x14 +#define AR7240_STATS_RXFRAGMENT 0x18 +#define AR7240_STATS_RX64BYTE 0x1c +#define AR7240_STATS_RX128BYTE 0x20 +#define AR7240_STATS_RX256BYTE 0x24 +#define AR7240_STATS_RX512BYTE 0x28 +#define AR7240_STATS_RX1024BYTE 0x2c +#define AR7240_STATS_RX1518BYTE 0x30 +#define AR7240_STATS_RXMAXBYTE 0x34 +#define AR7240_STATS_RXTOOLONG 0x38 +#define AR7240_STATS_RXGOODBYTE 0x3c +#define AR7240_STATS_RXBADBYTE 0x44 +#define AR7240_STATS_RXOVERFLOW 0x4c +#define AR7240_STATS_FILTERED 0x50 +#define AR7240_STATS_TXBROAD 0x54 +#define AR7240_STATS_TXPAUSE 0x58 +#define AR7240_STATS_TXMULTI 0x5c +#define AR7240_STATS_TXUNDERRUN 0x60 +#define AR7240_STATS_TX64BYTE 0x64 +#define AR7240_STATS_TX128BYTE 0x68 +#define AR7240_STATS_TX256BYTE 0x6c +#define AR7240_STATS_TX512BYTE 0x70 +#define AR7240_STATS_TX1024BYTE 0x74 +#define AR7240_STATS_TX1518BYTE 0x78 +#define AR7240_STATS_TXMAXBYTE 0x7c +#define AR7240_STATS_TXOVERSIZE 0x80 +#define AR7240_STATS_TXBYTE 0x84 +#define AR7240_STATS_TXCOLLISION 0x8c +#define AR7240_STATS_TXABORTCOL 0x90 +#define AR7240_STATS_TXMULTICOL 0x94 +#define AR7240_STATS_TXSINGLECOL 0x98 +#define AR7240_STATS_TXEXCDEFER 0x9c +#define AR7240_STATS_TXDEFER 0xa0 +#define AR7240_STATS_TXLATECOL 0xa4 + +#define AR7240_PORT_CPU 0 +#define AR7240_NUM_PORTS 6 +#define AR7240_NUM_PHYS 5 + +#define AR7240_PHY_ID1 0x004d +#define AR7240_PHY_ID2 0xd041 + +#define AR934X_PHY_ID1 0x004d +#define AR934X_PHY_ID2 0xd042 + +#define AR7240_MAX_VLANS 16 + +#define AR934X_REG_OPER_MODE0 0x04 +#define AR934X_OPER_MODE0_MAC_GMII_EN BIT(6) +#define AR934X_OPER_MODE0_PHY_MII_EN BIT(10) + +#define AR934X_REG_OPER_MODE1 0x08 +#define AR934X_REG_OPER_MODE1_PHY4_MII_EN BIT(28) + +#define AR934X_REG_FLOOD_MASK 0x2c +#define AR934X_FLOOD_MASK_BC_DP(_p) BIT(25 + (_p)) + +#define AR934X_REG_QM_CTRL 0x3c +#define AR934X_QM_CTRL_ARP_EN BIT(15) + +#define AR934X_REG_AT_CTRL 0x5c +#define AR934X_AT_CTRL_AGE_TIME BITS(0, 15) +#define AR934X_AT_CTRL_AGE_EN BIT(17) +#define AR934X_AT_CTRL_LEARN_CHANGE BIT(18) + +#define AR934X_MIB_ENABLE BIT(30) + +#define AR934X_REG_PORT_BASE(_port) (0x100 + (_port) * 0x100) + +#define AR934X_REG_PORT_VLAN1(_port) (AR934X_REG_PORT_BASE((_port)) + 0x08) +#define AR934X_PORT_VLAN1_DEFAULT_SVID_S 0 +#define AR934X_PORT_VLAN1_FORCE_DEFAULT_VID_EN BIT(12) +#define AR934X_PORT_VLAN1_PORT_TLS_MODE BIT(13) +#define AR934X_PORT_VLAN1_PORT_VLAN_PROP_EN BIT(14) +#define AR934X_PORT_VLAN1_PORT_CLONE_EN BIT(15) +#define AR934X_PORT_VLAN1_DEFAULT_CVID_S 16 +#define AR934X_PORT_VLAN1_FORCE_PORT_VLAN_EN BIT(28) +#define AR934X_PORT_VLAN1_ING_PORT_PRI_S 29 + +#define AR934X_REG_PORT_VLAN2(_port) (AR934X_REG_PORT_BASE((_port)) + 0x0c) +#define AR934X_PORT_VLAN2_PORT_VID_MEM_S 16 +#define AR934X_PORT_VLAN2_8021Q_MODE_S 30 +#define AR934X_PORT_VLAN2_8021Q_MODE_PORT_ONLY 0 +#define AR934X_PORT_VLAN2_8021Q_MODE_PORT_FALLBACK 1 +#define AR934X_PORT_VLAN2_8021Q_MODE_VLAN_ONLY 2 +#define AR934X_PORT_VLAN2_8021Q_MODE_SECURE 3 + +#define sw_to_ar7240(_dev) container_of(_dev, struct ar7240sw, swdev) + +struct ar7240sw_port_stat { + unsigned long rx_broadcast; + unsigned long rx_pause; + unsigned long rx_multicast; + unsigned long rx_fcs_error; + unsigned long rx_align_error; + unsigned long rx_runt; + unsigned long rx_fragments; + unsigned long rx_64byte; + unsigned long rx_128byte; + unsigned long rx_256byte; + unsigned long rx_512byte; + unsigned long rx_1024byte; + unsigned long rx_1518byte; + unsigned long rx_maxbyte; + unsigned long rx_toolong; + unsigned long rx_good_byte; + unsigned long rx_bad_byte; + unsigned long rx_overflow; + unsigned long filtered; + + unsigned long tx_broadcast; + unsigned long tx_pause; + unsigned long tx_multicast; + unsigned long tx_underrun; + unsigned long tx_64byte; + unsigned long tx_128byte; + unsigned long tx_256byte; + unsigned long tx_512byte; + unsigned long tx_1024byte; + unsigned long tx_1518byte; + unsigned long tx_maxbyte; + unsigned long tx_oversize; + unsigned long tx_byte; + unsigned long tx_collision; + unsigned long tx_abortcol; + unsigned long tx_multicol; + unsigned long tx_singlecol; + unsigned long tx_excdefer; + unsigned long tx_defer; + unsigned long tx_xlatecol; +}; + +struct ar7240sw { + struct mii_bus *mii_bus; + struct ag71xx_switch_platform_data *swdata; + struct switch_dev swdev; + int num_ports; + u8 ver; + bool vlan; + u16 vlan_id[AR7240_MAX_VLANS]; + u8 vlan_table[AR7240_MAX_VLANS]; + u8 vlan_tagged; + u16 pvid[AR7240_NUM_PORTS]; + char buf[80]; + + rwlock_t stats_lock; + struct ar7240sw_port_stat port_stats[AR7240_NUM_PORTS]; +}; + +struct ar7240sw_hw_stat { + char string[ETH_GSTRING_LEN]; + int sizeof_stat; + int reg; +}; + +static DEFINE_MUTEX(reg_mutex); + +static inline int sw_is_ar7240(struct ar7240sw *as) +{ + return as->ver == AR7240_MASK_CTRL_VERSION_AR7240; +} + +static inline int sw_is_ar934x(struct ar7240sw *as) +{ + return as->ver == AR7240_MASK_CTRL_VERSION_AR934X; +} + +static inline u32 ar7240sw_port_mask(struct ar7240sw *as, int port) +{ + return BIT(port); +} + +static inline u32 ar7240sw_port_mask_all(struct ar7240sw *as) +{ + return BIT(as->swdev.ports) - 1; +} + +static inline u32 ar7240sw_port_mask_but(struct ar7240sw *as, int port) +{ + return ar7240sw_port_mask_all(as) & ~BIT(port); +} + +static inline u16 mk_phy_addr(u32 reg) +{ + return 0x17 & ((reg >> 4) | 0x10); +} + +static inline u16 mk_phy_reg(u32 reg) +{ + return (reg << 1) & 0x1e; +} + +static inline u16 mk_high_addr(u32 reg) +{ + return (reg >> 7) & 0x1ff; +} + +static u32 __ar7240sw_reg_read(struct mii_bus *mii, u32 reg) +{ + unsigned long flags; + u16 phy_addr; + u16 phy_reg; + u32 hi, lo; + + reg = (reg & 0xfffffffc) >> 2; + phy_addr = mk_phy_addr(reg); + phy_reg = mk_phy_reg(reg); + + local_irq_save(flags); + ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); + lo = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg); + hi = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg + 1); + local_irq_restore(flags); + + return (hi << 16) | lo; +} + +static void __ar7240sw_reg_write(struct mii_bus *mii, u32 reg, u32 val) +{ + unsigned long flags; + u16 phy_addr; + u16 phy_reg; + + reg = (reg & 0xfffffffc) >> 2; + phy_addr = mk_phy_addr(reg); + phy_reg = mk_phy_reg(reg); + + local_irq_save(flags); + ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg)); + ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg + 1, (val >> 16)); + ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg, (val & 0xffff)); + local_irq_restore(flags); +} + +static u32 ar7240sw_reg_read(struct mii_bus *mii, u32 reg_addr) +{ + u32 ret; + + mutex_lock(®_mutex); + ret = __ar7240sw_reg_read(mii, reg_addr); + mutex_unlock(®_mutex); + + return ret; +} + +static void ar7240sw_reg_write(struct mii_bus *mii, u32 reg_addr, u32 reg_val) +{ + mutex_lock(®_mutex); + __ar7240sw_reg_write(mii, reg_addr, reg_val); + mutex_unlock(®_mutex); +} + +static u32 ar7240sw_reg_rmw(struct mii_bus *mii, u32 reg, u32 mask, u32 val) +{ + u32 t; + + mutex_lock(®_mutex); + t = __ar7240sw_reg_read(mii, reg); + t &= ~mask; + t |= val; + __ar7240sw_reg_write(mii, reg, t); + mutex_unlock(®_mutex); + + return t; +} + +static void ar7240sw_reg_set(struct mii_bus *mii, u32 reg, u32 val) +{ + u32 t; + + mutex_lock(®_mutex); + t = __ar7240sw_reg_read(mii, reg); + t |= val; + __ar7240sw_reg_write(mii, reg, t); + mutex_unlock(®_mutex); +} + +static int __ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val, + unsigned timeout) +{ + int i; + + for (i = 0; i < timeout; i++) { + u32 t; + + t = __ar7240sw_reg_read(mii, reg); + if ((t & mask) == val) + return 0; + + msleep(1); + } + + return -ETIMEDOUT; +} + +static int ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val, + unsigned timeout) +{ + int ret; + + mutex_lock(®_mutex); + ret = __ar7240sw_reg_wait(mii, reg, mask, val, timeout); + mutex_unlock(®_mutex); + return ret; +} + +u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr, + unsigned reg_addr) +{ + u32 t, val = 0xffff; + int err; + + if (phy_addr >= AR7240_NUM_PHYS) + return 0xffff; + + mutex_lock(®_mutex); + t = (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) | + (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) | + AR7240_MDIO_CTRL_MASTER_EN | + AR7240_MDIO_CTRL_BUSY | + AR7240_MDIO_CTRL_CMD_READ; + + __ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t); + err = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL, + AR7240_MDIO_CTRL_BUSY, 0, 5); + if (!err) + val = __ar7240sw_reg_read(mii, AR7240_REG_MDIO_CTRL); + mutex_unlock(®_mutex); + + return val & AR7240_MDIO_CTRL_DATA_M; +} + +int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr, + unsigned reg_addr, u16 reg_val) +{ + u32 t; + int ret; + + if (phy_addr >= AR7240_NUM_PHYS) + return -EINVAL; + + mutex_lock(®_mutex); + t = (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) | + (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) | + AR7240_MDIO_CTRL_MASTER_EN | + AR7240_MDIO_CTRL_BUSY | + AR7240_MDIO_CTRL_CMD_WRITE | + reg_val; + + __ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t); + ret = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL, + AR7240_MDIO_CTRL_BUSY, 0, 5); + mutex_unlock(®_mutex); + + return ret; +} + +static int ar7240sw_capture_stats(struct ar7240sw *as) +{ + struct mii_bus *mii = as->mii_bus; + int port; + int ret; + + write_lock(&as->stats_lock); + + /* Capture the hardware statistics for all ports */ + ar7240sw_reg_rmw(mii, AR7240_REG_MIB_FUNCTION0, + (AR7240_MIB_FUNC_M << AR7240_MIB_FUNC_S), + (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S)); + + /* Wait for the capturing to complete. */ + ret = ar7240sw_reg_wait(mii, AR7240_REG_MIB_FUNCTION0, + AR7240_MIB_BUSY, 0, 10); + + if (ret) + goto unlock; + + for (port = 0; port < AR7240_NUM_PORTS; port++) { + unsigned int base; + struct ar7240sw_port_stat *stats; + + base = AR7240_REG_STATS_BASE(port); + stats = &as->port_stats[port]; + +#define READ_STAT(_r) ar7240sw_reg_read(mii, base + AR7240_STATS_ ## _r) + + stats->rx_good_byte += READ_STAT(RXGOODBYTE); + stats->tx_byte += READ_STAT(TXBYTE); + +#undef READ_STAT + } + + ret = 0; + +unlock: + write_unlock(&as->stats_lock); + return ret; +} + +static void ar7240sw_disable_port(struct ar7240sw *as, unsigned port) +{ + ar7240sw_reg_write(as->mii_bus, AR7240_REG_PORT_CTRL(port), + AR7240_PORT_CTRL_STATE_DISABLED); +} + +static void ar7240sw_setup(struct ar7240sw *as) +{ + struct mii_bus *mii = as->mii_bus; + + /* Enable CPU port, and disable mirror port */ + ar7240sw_reg_write(mii, AR7240_REG_CPU_PORT, + AR7240_CPU_PORT_EN | + (15 << AR7240_MIRROR_PORT_S)); + + /* Setup TAG priority mapping */ + ar7240sw_reg_write(mii, AR7240_REG_TAG_PRIORITY, 0xfa50); + + if (sw_is_ar934x(as)) { + /* Enable aging, MAC replacing */ + ar7240sw_reg_write(mii, AR934X_REG_AT_CTRL, + 0x2b /* 5 min age time */ | + AR934X_AT_CTRL_AGE_EN | + AR934X_AT_CTRL_LEARN_CHANGE); + /* Enable ARP frame acknowledge */ + ar7240sw_reg_set(mii, AR934X_REG_QM_CTRL, + AR934X_QM_CTRL_ARP_EN); + /* Enable Broadcast frames transmitted to the CPU */ + ar7240sw_reg_set(mii, AR934X_REG_FLOOD_MASK, + AR934X_FLOOD_MASK_BC_DP(0)); + + /* Enable MIB counters */ + ar7240sw_reg_set(mii, AR7240_REG_MIB_FUNCTION0, + AR934X_MIB_ENABLE); + + } else { + /* Enable ARP frame acknowledge, aging, MAC replacing */ + ar7240sw_reg_write(mii, AR7240_REG_AT_CTRL, + AR7240_AT_CTRL_RESERVED | + 0x2b /* 5 min age time */ | + AR7240_AT_CTRL_AGE_EN | + AR7240_AT_CTRL_ARP_EN | + AR7240_AT_CTRL_LEARN_CHANGE); + /* Enable Broadcast frames transmitted to the CPU */ + ar7240sw_reg_set(mii, AR7240_REG_FLOOD_MASK, + AR7240_FLOOD_MASK_BROAD_TO_CPU); + } + + /* setup MTU */ + ar7240sw_reg_rmw(mii, AR7240_REG_GLOBAL_CTRL, AR7240_GLOBAL_CTRL_MTU_M, + 1536); + + /* setup Service TAG */ + ar7240sw_reg_rmw(mii, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M, 0); +} + +static int ar7240sw_reset(struct ar7240sw *as) +{ + struct mii_bus *mii = as->mii_bus; + int ret; + int i; + + /* Set all ports to disabled state. */ + for (i = 0; i < AR7240_NUM_PORTS; i++) + ar7240sw_disable_port(as, i); + + /* Wait for transmit queues to drain. */ + msleep(2); + + /* Reset the switch. */ + ar7240sw_reg_write(mii, AR7240_REG_MASK_CTRL, + AR7240_MASK_CTRL_SOFT_RESET); + + ret = ar7240sw_reg_wait(mii, AR7240_REG_MASK_CTRL, + AR7240_MASK_CTRL_SOFT_RESET, 0, 1000); + + /* setup PHYs */ + for (i = 0; i < AR7240_NUM_PHYS; i++) { + ar7240sw_phy_write(mii, i, MII_ADVERTISE, + ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | + ADVERTISE_PAUSE_ASYM); + ar7240sw_phy_write(mii, i, MII_BMCR, + BMCR_RESET | BMCR_ANENABLE); + } + msleep(1000); + + ar7240sw_setup(as); + return ret; +} + +static void ar7240sw_setup_port(struct ar7240sw *as, unsigned port, u8 portmask) +{ + struct mii_bus *mii = as->mii_bus; + u32 ctrl; + u32 vid, mode; + + ctrl = AR7240_PORT_CTRL_STATE_FORWARD | AR7240_PORT_CTRL_LEARN | + AR7240_PORT_CTRL_SINGLE_VLAN; + + if (port == AR7240_PORT_CPU) { + ar7240sw_reg_write(mii, AR7240_REG_PORT_STATUS(port), + AR7240_PORT_STATUS_SPEED_1000 | + AR7240_PORT_STATUS_TXFLOW | + AR7240_PORT_STATUS_RXFLOW | + AR7240_PORT_STATUS_TXMAC | + AR7240_PORT_STATUS_RXMAC | + AR7240_PORT_STATUS_DUPLEX); + } else { + ar7240sw_reg_write(mii, AR7240_REG_PORT_STATUS(port), + AR7240_PORT_STATUS_LINK_AUTO); + } + + /* Set the default VID for this port */ + if (as->vlan) { + vid = as->vlan_id[as->pvid[port]]; + mode = AR7240_PORT_VLAN_MODE_SECURE; + } else { + vid = port; + mode = AR7240_PORT_VLAN_MODE_PORT_ONLY; + } + + if (as->vlan) { + if (as->vlan_tagged & BIT(port)) + ctrl |= AR7240_PORT_CTRL_VLAN_MODE_ADD << + AR7240_PORT_CTRL_VLAN_MODE_S; + else + ctrl |= AR7240_PORT_CTRL_VLAN_MODE_STRIP << + AR7240_PORT_CTRL_VLAN_MODE_S; + } else { + ctrl |= AR7240_PORT_CTRL_VLAN_MODE_KEEP << + AR7240_PORT_CTRL_VLAN_MODE_S; + } + + if (!portmask) { + if (port == AR7240_PORT_CPU) + portmask = ar7240sw_port_mask_but(as, AR7240_PORT_CPU); + else + portmask = ar7240sw_port_mask(as, AR7240_PORT_CPU); + } + + /* allow the port to talk to all other ports, but exclude its + * own ID to prevent frames from being reflected back to the + * port that they came from */ + portmask &= ar7240sw_port_mask_but(as, port); + + ar7240sw_reg_write(mii, AR7240_REG_PORT_CTRL(port), ctrl); + if (sw_is_ar934x(as)) { + u32 vlan1, vlan2; + + vlan1 = (vid << AR934X_PORT_VLAN1_DEFAULT_CVID_S); + vlan2 = (portmask << AR934X_PORT_VLAN2_PORT_VID_MEM_S) | + (mode << AR934X_PORT_VLAN2_8021Q_MODE_S); + ar7240sw_reg_write(mii, AR934X_REG_PORT_VLAN1(port), vlan1); + ar7240sw_reg_write(mii, AR934X_REG_PORT_VLAN2(port), vlan2); + } else { + u32 vlan; + + vlan = vid | (mode << AR7240_PORT_VLAN_MODE_S) | + (portmask << AR7240_PORT_VLAN_DEST_PORTS_S); + + ar7240sw_reg_write(mii, AR7240_REG_PORT_VLAN(port), vlan); + } +} + +static int ar7240_set_addr(struct ar7240sw *as, u8 *addr) +{ + struct mii_bus *mii = as->mii_bus; + u32 t; + + t = (addr[4] << 8) | addr[5]; + ar7240sw_reg_write(mii, AR7240_REG_MAC_ADDR0, t); + + t = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3]; + ar7240sw_reg_write(mii, AR7240_REG_MAC_ADDR1, t); + + return 0; +} + +static int +ar7240_set_vid(struct switch_dev *dev, const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + as->vlan_id[val->port_vlan] = val->value.i; + return 0; +} + +static int +ar7240_get_vid(struct switch_dev *dev, const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + val->value.i = as->vlan_id[val->port_vlan]; + return 0; +} + +static int +ar7240_set_pvid(struct switch_dev *dev, int port, int vlan) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + + /* make sure no invalid PVIDs get set */ + + if (vlan >= dev->vlans) + return -EINVAL; + + as->pvid[port] = vlan; + return 0; +} + +static int +ar7240_get_pvid(struct switch_dev *dev, int port, int *vlan) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + *vlan = as->pvid[port]; + return 0; +} + +static int +ar7240_get_ports(struct switch_dev *dev, struct switch_val *val) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + u8 ports = as->vlan_table[val->port_vlan]; + int i; + + val->len = 0; + for (i = 0; i < as->swdev.ports; i++) { + struct switch_port *p; + + if (!(ports & (1 << i))) + continue; + + p = &val->value.ports[val->len++]; + p->id = i; + if (as->vlan_tagged & (1 << i)) + p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); + else + p->flags = 0; + } + return 0; +} + +static int +ar7240_set_ports(struct switch_dev *dev, struct switch_val *val) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + u8 *vt = &as->vlan_table[val->port_vlan]; + int i, j; + + *vt = 0; + for (i = 0; i < val->len; i++) { + struct switch_port *p = &val->value.ports[i]; + + if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) + as->vlan_tagged |= (1 << p->id); + else { + as->vlan_tagged &= ~(1 << p->id); + as->pvid[p->id] = val->port_vlan; + + /* make sure that an untagged port does not + * appear in other vlans */ + for (j = 0; j < AR7240_MAX_VLANS; j++) { + if (j == val->port_vlan) + continue; + as->vlan_table[j] &= ~(1 << p->id); + } + } + + *vt |= 1 << p->id; + } + return 0; +} + +static int +ar7240_set_vlan(struct switch_dev *dev, const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + as->vlan = !!val->value.i; + return 0; +} + +static int +ar7240_get_vlan(struct switch_dev *dev, const struct switch_attr *attr, + struct switch_val *val) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + val->value.i = as->vlan; + return 0; +} + +static void +ar7240_vtu_op(struct ar7240sw *as, u32 op, u32 val) +{ + struct mii_bus *mii = as->mii_bus; + + if (ar7240sw_reg_wait(mii, AR7240_REG_VTU, AR7240_VTU_ACTIVE, 0, 5)) + return; + + if ((op & AR7240_VTU_OP) == AR7240_VTU_OP_LOAD) { + val &= AR7240_VTUDATA_MEMBER; + val |= AR7240_VTUDATA_VALID; + ar7240sw_reg_write(mii, AR7240_REG_VTU_DATA, val); + } + op |= AR7240_VTU_ACTIVE; + ar7240sw_reg_write(mii, AR7240_REG_VTU, op); +} + +static int +ar7240_hw_apply(struct switch_dev *dev) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + u8 portmask[AR7240_NUM_PORTS]; + int i, j; + + /* flush all vlan translation unit entries */ + ar7240_vtu_op(as, AR7240_VTU_OP_FLUSH, 0); + + memset(portmask, 0, sizeof(portmask)); + if (as->vlan) { + /* calculate the port destination masks and load vlans + * into the vlan translation unit */ + for (j = 0; j < AR7240_MAX_VLANS; j++) { + u8 vp = as->vlan_table[j]; + + if (!vp) + continue; + + for (i = 0; i < as->swdev.ports; i++) { + u8 mask = (1 << i); + if (vp & mask) + portmask[i] |= vp & ~mask; + } + + ar7240_vtu_op(as, + AR7240_VTU_OP_LOAD | + (as->vlan_id[j] << AR7240_VTU_VID_S), + as->vlan_table[j]); + } + } else { + /* vlan disabled: + * isolate all ports, but connect them to the cpu port */ + for (i = 0; i < as->swdev.ports; i++) { + if (i == AR7240_PORT_CPU) + continue; + + portmask[i] = 1 << AR7240_PORT_CPU; + portmask[AR7240_PORT_CPU] |= (1 << i); + } + } + + /* update the port destination mask registers and tag settings */ + for (i = 0; i < as->swdev.ports; i++) + ar7240sw_setup_port(as, i, portmask[i]); + + return 0; +} + +static int +ar7240_reset_switch(struct switch_dev *dev) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + ar7240sw_reset(as); + return 0; +} + +static int +ar7240_get_port_link(struct switch_dev *dev, int port, + struct switch_port_link *link) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + struct mii_bus *mii = as->mii_bus; + u32 status; + + if (port > AR7240_NUM_PORTS) + return -EINVAL; + + status = ar7240sw_reg_read(mii, AR7240_REG_PORT_STATUS(port)); + link->aneg = !!(status & AR7240_PORT_STATUS_LINK_AUTO); + if (link->aneg) { + link->link = !!(status & AR7240_PORT_STATUS_LINK_UP); + if (!link->link) + return 0; + } else { + link->link = true; + } + + link->duplex = !!(status & AR7240_PORT_STATUS_DUPLEX); + link->tx_flow = !!(status & AR7240_PORT_STATUS_TXFLOW); + link->rx_flow = !!(status & AR7240_PORT_STATUS_RXFLOW); + switch (status & AR7240_PORT_STATUS_SPEED_M) { + case AR7240_PORT_STATUS_SPEED_10: + link->speed = SWITCH_PORT_SPEED_10; + break; + case AR7240_PORT_STATUS_SPEED_100: + link->speed = SWITCH_PORT_SPEED_100; + break; + case AR7240_PORT_STATUS_SPEED_1000: + link->speed = SWITCH_PORT_SPEED_1000; + break; + } + + return 0; +} + +static int +ar7240_get_port_stats(struct switch_dev *dev, int port, + struct switch_port_stats *stats) +{ + struct ar7240sw *as = sw_to_ar7240(dev); + + if (port > AR7240_NUM_PORTS) + return -EINVAL; + + ar7240sw_capture_stats(as); + + read_lock(&as->stats_lock); + stats->rx_bytes = as->port_stats[port].rx_good_byte; + stats->tx_bytes = as->port_stats[port].tx_byte; + read_unlock(&as->stats_lock); + + return 0; +} + +static struct switch_attr ar7240_globals[] = { + { + .type = SWITCH_TYPE_INT, + .name = "enable_vlan", + .description = "Enable VLAN mode", + .set = ar7240_set_vlan, + .get = ar7240_get_vlan, + .max = 1 + }, +}; + +static struct switch_attr ar7240_port[] = { +}; + +static struct switch_attr ar7240_vlan[] = { + { + .type = SWITCH_TYPE_INT, + .name = "vid", + .description = "VLAN ID", + .set = ar7240_set_vid, + .get = ar7240_get_vid, + .max = 4094, + }, +}; + +static const struct switch_dev_ops ar7240_ops = { + .attr_global = { + .attr = ar7240_globals, + .n_attr = ARRAY_SIZE(ar7240_globals), + }, + .attr_port = { + .attr = ar7240_port, + .n_attr = ARRAY_SIZE(ar7240_port), + }, + .attr_vlan = { + .attr = ar7240_vlan, + .n_attr = ARRAY_SIZE(ar7240_vlan), + }, + .get_port_pvid = ar7240_get_pvid, + .set_port_pvid = ar7240_set_pvid, + .get_vlan_ports = ar7240_get_ports, + .set_vlan_ports = ar7240_set_ports, + .apply_config = ar7240_hw_apply, + .reset_switch = ar7240_reset_switch, + .get_port_link = ar7240_get_port_link, + .get_port_stats = ar7240_get_port_stats, +}; + +static struct ar7240sw *ar7240_probe(struct ag71xx *ag) +{ + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + struct mii_bus *mii = ag->mii_bus; + struct ar7240sw *as; + struct switch_dev *swdev; + u32 ctrl; + u16 phy_id1; + u16 phy_id2; + int i; + + phy_id1 = ar7240sw_phy_read(mii, 0, MII_PHYSID1); + phy_id2 = ar7240sw_phy_read(mii, 0, MII_PHYSID2); + if ((phy_id1 != AR7240_PHY_ID1 || phy_id2 != AR7240_PHY_ID2) && + (phy_id1 != AR934X_PHY_ID1 || phy_id2 != AR934X_PHY_ID2)) { + pr_err("%s: unknown phy id '%04x:%04x'\n", + ag->dev->name, phy_id1, phy_id2); + return NULL; + } + + as = kzalloc(sizeof(*as), GFP_KERNEL); + if (!as) + return NULL; + + as->mii_bus = mii; + as->swdata = pdata->switch_data; + + swdev = &as->swdev; + + ctrl = ar7240sw_reg_read(mii, AR7240_REG_MASK_CTRL); + as->ver = (ctrl >> AR7240_MASK_CTRL_VERSION_S) & + AR7240_MASK_CTRL_VERSION_M; + + if (sw_is_ar7240(as)) { + swdev->name = "AR7240/AR9330 built-in switch"; + swdev->ports = AR7240_NUM_PORTS - 1; + } else if (sw_is_ar934x(as)) { + swdev->name = "AR934X built-in switch"; + + if (pdata->phy_if_mode == PHY_INTERFACE_MODE_GMII) { + ar7240sw_reg_set(mii, AR934X_REG_OPER_MODE0, + AR934X_OPER_MODE0_MAC_GMII_EN); + } else if (pdata->phy_if_mode == PHY_INTERFACE_MODE_MII) { + ar7240sw_reg_set(mii, AR934X_REG_OPER_MODE0, + AR934X_OPER_MODE0_PHY_MII_EN); + } else { + pr_err("%s: invalid PHY interface mode\n", + ag->dev->name); + goto err_free; + } + + if (as->swdata->phy4_mii_en) { + ar7240sw_reg_set(mii, AR934X_REG_OPER_MODE1, + AR934X_REG_OPER_MODE1_PHY4_MII_EN); + swdev->ports = AR7240_NUM_PORTS - 1; + } else { + swdev->ports = AR7240_NUM_PORTS; + } + } else { + pr_err("%s: unsupported chip, ctrl=%08x\n", + ag->dev->name, ctrl); + goto err_free; + } + + swdev->cpu_port = AR7240_PORT_CPU; + swdev->vlans = AR7240_MAX_VLANS; + swdev->ops = &ar7240_ops; + + if (register_switch(&as->swdev, ag->dev) < 0) + goto err_free; + + pr_info("%s: Found an %s\n", ag->dev->name, swdev->name); + + /* initialize defaults */ + for (i = 0; i < AR7240_MAX_VLANS; i++) + as->vlan_id[i] = i; + + as->vlan_table[0] = ar7240sw_port_mask_all(as); + + return as; + +err_free: + kfree(as); + return NULL; +} + +static void link_function(struct work_struct *work) { + struct ag71xx *ag = container_of(work, struct ag71xx, link_work.work); + struct ar7240sw *as = ag->phy_priv; + unsigned long flags; + u8 mask; + int i; + int status = 0; + + mask = ~as->swdata->phy_poll_mask; + for (i = 0; i < AR7240_NUM_PHYS; i++) { + int link; + + if (!(mask & BIT(i))) + continue; + + link = ar7240sw_phy_read(ag->mii_bus, i, MII_BMSR); + if (link & BMSR_LSTATUS) { + status = 1; + break; + } + } + + spin_lock_irqsave(&ag->lock, flags); + if (status != ag->link) { + ag->link = status; + ag71xx_link_adjust(ag); + } + spin_unlock_irqrestore(&ag->lock, flags); + + schedule_delayed_work(&ag->link_work, HZ / 2); +} + +void ag71xx_ar7240_start(struct ag71xx *ag) +{ + struct ar7240sw *as = ag->phy_priv; + + ar7240sw_reset(as); + + ag->speed = SPEED_1000; + ag->duplex = 1; + + ar7240_set_addr(as, ag->dev->dev_addr); + ar7240_hw_apply(&as->swdev); + + schedule_delayed_work(&ag->link_work, HZ / 10); +} + +void ag71xx_ar7240_stop(struct ag71xx *ag) +{ + cancel_delayed_work_sync(&ag->link_work); +} + +int __devinit ag71xx_ar7240_init(struct ag71xx *ag) +{ + struct ar7240sw *as; + + as = ar7240_probe(ag); + if (!as) + return -ENODEV; + + ag->phy_priv = as; + ar7240sw_reset(as); + + rwlock_init(&as->stats_lock); + INIT_DELAYED_WORK(&ag->link_work, link_function); + + return 0; +} + +void ag71xx_ar7240_cleanup(struct ag71xx *ag) +{ + struct ar7240sw *as = ag->phy_priv; + + if (!as) + return; + + unregister_switch(&as->swdev); + kfree(as); + ag->phy_priv = NULL; +} diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar8216.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar8216.c new file mode 100644 index 000000000..7ec43b722 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar8216.c @@ -0,0 +1,44 @@ +/* + * Atheros AR71xx built-in ethernet mac driver + * Special support for the Atheros ar8216 switch chip + * + * Copyright (C) 2009-2010 Gabor Juhos + * + * Based on Atheros' AG7100 driver + * + * This program 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. + */ + +#include "ag71xx.h" + +#define AR8216_PACKET_TYPE_MASK 0xf +#define AR8216_PACKET_TYPE_NORMAL 0 + +#define AR8216_HEADER_LEN 2 + +void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb) +{ + skb_push(skb, AR8216_HEADER_LEN); + skb->data[0] = 0x10; + skb->data[1] = 0x80; +} + +int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb, + int pktlen) +{ + u8 type; + + type = skb->data[1] & AR8216_PACKET_TYPE_MASK; + switch (type) { + case AR8216_PACKET_TYPE_NORMAL: + break; + + default: + return -EINVAL; + } + + skb_pull(skb, AR8216_HEADER_LEN); + return 0; +} diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c new file mode 100644 index 000000000..65f2be198 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c @@ -0,0 +1,280 @@ +/* + * Atheros AR71xx built-in ethernet mac driver + * + * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * Based on Atheros' AG7100 driver + * + * This program 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. + */ + +#include + +#include "ag71xx.h" + +static struct dentry *ag71xx_debugfs_root; + +static int ag71xx_debugfs_generic_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status) +{ + if (status) + ag->debug.int_stats.total++; + if (status & AG71XX_INT_TX_PS) + ag->debug.int_stats.tx_ps++; + if (status & AG71XX_INT_TX_UR) + ag->debug.int_stats.tx_ur++; + if (status & AG71XX_INT_TX_BE) + ag->debug.int_stats.tx_be++; + if (status & AG71XX_INT_RX_PR) + ag->debug.int_stats.rx_pr++; + if (status & AG71XX_INT_RX_OF) + ag->debug.int_stats.rx_of++; + if (status & AG71XX_INT_RX_BE) + ag->debug.int_stats.rx_be++; +} + +static ssize_t read_file_int_stats(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ +#define PR_INT_STAT(_label, _field) \ + len += snprintf(buf + len, sizeof(buf) - len, \ + "%20s: %10lu\n", _label, ag->debug.int_stats._field); + + struct ag71xx *ag = file->private_data; + char buf[256]; + unsigned int len = 0; + + PR_INT_STAT("TX Packet Sent", tx_ps); + PR_INT_STAT("TX Underrun", tx_ur); + PR_INT_STAT("TX Bus Error", tx_be); + PR_INT_STAT("RX Packet Received", rx_pr); + PR_INT_STAT("RX Overflow", rx_of); + PR_INT_STAT("RX Bus Error", rx_be); + len += snprintf(buf + len, sizeof(buf) - len, "\n"); + PR_INT_STAT("Total", total); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +#undef PR_INT_STAT +} + +static const struct file_operations ag71xx_fops_int_stats = { + .open = ag71xx_debugfs_generic_open, + .read = read_file_int_stats, + .owner = THIS_MODULE +}; + +void ag71xx_debugfs_update_napi_stats(struct ag71xx *ag, int rx, int tx) +{ + struct ag71xx_napi_stats *stats = &ag->debug.napi_stats; + + if (rx) { + stats->rx_count++; + stats->rx_packets += rx; + if (rx <= AG71XX_NAPI_WEIGHT) + stats->rx[rx]++; + if (rx > stats->rx_packets_max) + stats->rx_packets_max = rx; + } + + if (tx) { + stats->tx_count++; + stats->tx_packets += tx; + if (tx <= AG71XX_NAPI_WEIGHT) + stats->tx[tx]++; + if (tx > stats->tx_packets_max) + stats->tx_packets_max = tx; + } +} + +static ssize_t read_file_napi_stats(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ag71xx *ag = file->private_data; + struct ag71xx_napi_stats *stats = &ag->debug.napi_stats; + char *buf; + unsigned int buflen; + unsigned int len = 0; + unsigned long rx_avg = 0; + unsigned long tx_avg = 0; + int ret; + int i; + + buflen = 2048; + buf = kmalloc(buflen, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + if (stats->rx_count) + rx_avg = stats->rx_packets / stats->rx_count; + + if (stats->tx_count) + tx_avg = stats->tx_packets / stats->tx_count; + + len += snprintf(buf + len, buflen - len, "%3s %10s %10s\n", + "len", "rx", "tx"); + + for (i = 1; i <= AG71XX_NAPI_WEIGHT; i++) + len += snprintf(buf + len, buflen - len, + "%3d: %10lu %10lu\n", + i, stats->rx[i], stats->tx[i]); + + len += snprintf(buf + len, buflen - len, "\n"); + + len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", + "sum", stats->rx_count, stats->tx_count); + len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", + "avg", rx_avg, tx_avg); + len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", + "max", stats->rx_packets_max, stats->tx_packets_max); + len += snprintf(buf + len, buflen - len, "%3s: %10lu %10lu\n", + "pkt", stats->rx_packets, stats->tx_packets); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); + kfree(buf); + + return ret; +} + +static const struct file_operations ag71xx_fops_napi_stats = { + .open = ag71xx_debugfs_generic_open, + .read = read_file_napi_stats, + .owner = THIS_MODULE +}; + +#define DESC_PRINT_LEN 64 + +static ssize_t read_file_ring(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos, + struct ag71xx *ag, + struct ag71xx_ring *ring, + unsigned desc_reg) +{ + char *buf; + unsigned int buflen; + unsigned int len = 0; + unsigned long flags; + ssize_t ret; + int curr; + int dirty; + u32 desc_hw; + int i; + + buflen = (ring->size * DESC_PRINT_LEN); + buf = kmalloc(buflen, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + len += snprintf(buf + len, buflen - len, + "Idx ... %-8s %-8s %-8s %-8s . %-10s\n", + "desc", "next", "data", "ctrl", "timestamp"); + + spin_lock_irqsave(&ag->lock, flags); + + curr = (ring->curr % ring->size); + dirty = (ring->dirty % ring->size); + desc_hw = ag71xx_rr(ag, desc_reg); + for (i = 0; i < ring->size; i++) { + struct ag71xx_buf *ab = &ring->buf[i]; + u32 desc_dma = ((u32) ring->descs_dma) + i * ring->desc_size; + + len += snprintf(buf + len, buflen - len, + "%3d %c%c%c %08x %08x %08x %08x %c %10lu\n", + i, + (i == curr) ? 'C' : ' ', + (i == dirty) ? 'D' : ' ', + (desc_hw == desc_dma) ? 'H' : ' ', + desc_dma, + ab->desc->next, + ab->desc->data, + ab->desc->ctrl, + (ab->desc->ctrl & DESC_EMPTY) ? 'E' : '*', + ab->timestamp); + } + + spin_unlock_irqrestore(&ag->lock, flags); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); + kfree(buf); + + return ret; +} + +static ssize_t read_file_tx_ring(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ag71xx *ag = file->private_data; + + return read_file_ring(file, user_buf, count, ppos, ag, &ag->tx_ring, + AG71XX_REG_TX_DESC); +} + +static const struct file_operations ag71xx_fops_tx_ring = { + .open = ag71xx_debugfs_generic_open, + .read = read_file_tx_ring, + .owner = THIS_MODULE +}; + +static ssize_t read_file_rx_ring(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ag71xx *ag = file->private_data; + + return read_file_ring(file, user_buf, count, ppos, ag, &ag->rx_ring, + AG71XX_REG_RX_DESC); +} + +static const struct file_operations ag71xx_fops_rx_ring = { + .open = ag71xx_debugfs_generic_open, + .read = read_file_rx_ring, + .owner = THIS_MODULE +}; + +void ag71xx_debugfs_exit(struct ag71xx *ag) +{ + debugfs_remove_recursive(ag->debug.debugfs_dir); +} + +int ag71xx_debugfs_init(struct ag71xx *ag) +{ + ag->debug.debugfs_dir = debugfs_create_dir(ag->dev->name, + ag71xx_debugfs_root); + if (!ag->debug.debugfs_dir) + return -ENOMEM; + + debugfs_create_file("int_stats", S_IRUGO, ag->debug.debugfs_dir, + ag, &ag71xx_fops_int_stats); + debugfs_create_file("napi_stats", S_IRUGO, ag->debug.debugfs_dir, + ag, &ag71xx_fops_napi_stats); + debugfs_create_file("tx_ring", S_IRUGO, ag->debug.debugfs_dir, + ag, &ag71xx_fops_tx_ring); + debugfs_create_file("rx_ring", S_IRUGO, ag->debug.debugfs_dir, + ag, &ag71xx_fops_rx_ring); + + return 0; +} + +int ag71xx_debugfs_root_init(void) +{ + if (ag71xx_debugfs_root) + return -EBUSY; + + ag71xx_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); + if (!ag71xx_debugfs_root) + return -ENOENT; + + return 0; +} + +void ag71xx_debugfs_root_exit(void) +{ + debugfs_remove(ag71xx_debugfs_root); + ag71xx_debugfs_root = NULL; +} diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ethtool.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ethtool.c new file mode 100644 index 000000000..498fbed1f --- /dev/null +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ethtool.c @@ -0,0 +1,124 @@ +/* + * Atheros AR71xx built-in ethernet mac driver + * + * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * Based on Atheros' AG7100 driver + * + * This program 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. + */ + +#include "ag71xx.h" + +static int ag71xx_ethtool_get_settings(struct net_device *dev, + struct ethtool_cmd *cmd) +{ + struct ag71xx *ag = netdev_priv(dev); + struct phy_device *phydev = ag->phy_dev; + + if (!phydev) + return -ENODEV; + + return phy_ethtool_gset(phydev, cmd); +} + +static int ag71xx_ethtool_set_settings(struct net_device *dev, + struct ethtool_cmd *cmd) +{ + struct ag71xx *ag = netdev_priv(dev); + struct phy_device *phydev = ag->phy_dev; + + if (!phydev) + return -ENODEV; + + return phy_ethtool_sset(phydev, cmd); +} + +static void ag71xx_ethtool_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + struct ag71xx *ag = netdev_priv(dev); + + strcpy(info->driver, ag->pdev->dev.driver->name); + strcpy(info->version, AG71XX_DRV_VERSION); + strcpy(info->bus_info, dev_name(&ag->pdev->dev)); +} + +static u32 ag71xx_ethtool_get_msglevel(struct net_device *dev) +{ + struct ag71xx *ag = netdev_priv(dev); + + return ag->msg_enable; +} + +static void ag71xx_ethtool_set_msglevel(struct net_device *dev, u32 msg_level) +{ + struct ag71xx *ag = netdev_priv(dev); + + ag->msg_enable = msg_level; +} + +static void ag71xx_ethtool_get_ringparam(struct net_device *dev, + struct ethtool_ringparam *er) +{ + struct ag71xx *ag = netdev_priv(dev); + + er->tx_max_pending = AG71XX_TX_RING_SIZE_MAX; + er->rx_max_pending = AG71XX_RX_RING_SIZE_MAX; + er->rx_mini_max_pending = 0; + er->rx_jumbo_max_pending = 0; + + er->tx_pending = ag->tx_ring.size; + er->rx_pending = ag->rx_ring.size; + er->rx_mini_pending = 0; + er->rx_jumbo_pending = 0; +} + +static int ag71xx_ethtool_set_ringparam(struct net_device *dev, + struct ethtool_ringparam *er) +{ + struct ag71xx *ag = netdev_priv(dev); + unsigned tx_size; + unsigned rx_size; + int err; + + if (er->rx_mini_pending != 0|| + er->rx_jumbo_pending != 0 || + er->rx_pending == 0 || + er->tx_pending == 0) + return -EINVAL; + + tx_size = er->tx_pending < AG71XX_TX_RING_SIZE_MAX ? + er->tx_pending : AG71XX_TX_RING_SIZE_MAX; + + rx_size = er->rx_pending < AG71XX_RX_RING_SIZE_MAX ? + er->rx_pending : AG71XX_RX_RING_SIZE_MAX; + + if (netif_running(dev)) { + err = dev->netdev_ops->ndo_stop(dev); + if (err) + return err; + } + + ag->tx_ring.size = tx_size; + ag->rx_ring.size = rx_size; + + if (netif_running(dev)) + err = dev->netdev_ops->ndo_open(dev); + + return err; +} + +struct ethtool_ops ag71xx_ethtool_ops = { + .set_settings = ag71xx_ethtool_set_settings, + .get_settings = ag71xx_ethtool_get_settings, + .get_drvinfo = ag71xx_ethtool_get_drvinfo, + .get_msglevel = ag71xx_ethtool_get_msglevel, + .set_msglevel = ag71xx_ethtool_set_msglevel, + .get_ringparam = ag71xx_ethtool_get_ringparam, + .set_ringparam = ag71xx_ethtool_set_ringparam, + .get_link = ethtool_op_get_link, +}; diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c new file mode 100644 index 000000000..fb99d2728 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c @@ -0,0 +1,1258 @@ +/* + * Atheros AR71xx built-in ethernet mac driver + * + * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * Based on Atheros' AG7100 driver + * + * This program 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. + */ + +#include "ag71xx.h" + +#define AG71XX_DEFAULT_MSG_ENABLE \ + (NETIF_MSG_DRV \ + | NETIF_MSG_PROBE \ + | NETIF_MSG_LINK \ + | NETIF_MSG_TIMER \ + | NETIF_MSG_IFDOWN \ + | NETIF_MSG_IFUP \ + | NETIF_MSG_RX_ERR \ + | NETIF_MSG_TX_ERR) + +static int ag71xx_msg_level = -1; + +module_param_named(msg_level, ag71xx_msg_level, int, 0); +MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)"); + +static void ag71xx_dump_dma_regs(struct ag71xx *ag) +{ + DBG("%s: dma_tx_ctrl=%08x, dma_tx_desc=%08x, dma_tx_status=%08x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_TX_CTRL), + ag71xx_rr(ag, AG71XX_REG_TX_DESC), + ag71xx_rr(ag, AG71XX_REG_TX_STATUS)); + + DBG("%s: dma_rx_ctrl=%08x, dma_rx_desc=%08x, dma_rx_status=%08x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_RX_CTRL), + ag71xx_rr(ag, AG71XX_REG_RX_DESC), + ag71xx_rr(ag, AG71XX_REG_RX_STATUS)); +} + +static void ag71xx_dump_regs(struct ag71xx *ag) +{ + DBG("%s: mac_cfg1=%08x, mac_cfg2=%08x, ipg=%08x, hdx=%08x, mfl=%08x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_MAC_CFG1), + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), + ag71xx_rr(ag, AG71XX_REG_MAC_IPG), + ag71xx_rr(ag, AG71XX_REG_MAC_HDX), + ag71xx_rr(ag, AG71XX_REG_MAC_MFL)); + DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), + ag71xx_rr(ag, AG71XX_REG_MAC_ADDR1), + ag71xx_rr(ag, AG71XX_REG_MAC_ADDR2)); + DBG("%s: fifo_cfg0=%08x, fifo_cfg1=%08x, fifo_cfg2=%08x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); + DBG("%s: fifo_cfg3=%08x, fifo_cfg4=%08x, fifo_cfg5=%08x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); +} + +static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr) +{ + DBG("%s: %s intr=%08x %s%s%s%s%s%s\n", + ag->dev->name, label, intr, + (intr & AG71XX_INT_TX_PS) ? "TXPS " : "", + (intr & AG71XX_INT_TX_UR) ? "TXUR " : "", + (intr & AG71XX_INT_TX_BE) ? "TXBE " : "", + (intr & AG71XX_INT_RX_PR) ? "RXPR " : "", + (intr & AG71XX_INT_RX_OF) ? "RXOF " : "", + (intr & AG71XX_INT_RX_BE) ? "RXBE " : ""); +} + +static void ag71xx_ring_free(struct ag71xx_ring *ring) +{ + kfree(ring->buf); + + if (ring->descs_cpu) + dma_free_coherent(NULL, ring->size * ring->desc_size, + ring->descs_cpu, ring->descs_dma); +} + +static int ag71xx_ring_alloc(struct ag71xx_ring *ring) +{ + int err; + int i; + + ring->desc_size = sizeof(struct ag71xx_desc); + if (ring->desc_size % cache_line_size()) { + DBG("ag71xx: ring %p, desc size %u rounded to %u\n", + ring, ring->desc_size, + roundup(ring->desc_size, cache_line_size())); + ring->desc_size = roundup(ring->desc_size, cache_line_size()); + } + + ring->descs_cpu = dma_alloc_coherent(NULL, ring->size * ring->desc_size, + &ring->descs_dma, GFP_ATOMIC); + if (!ring->descs_cpu) { + err = -ENOMEM; + goto err; + } + + + ring->buf = kzalloc(ring->size * sizeof(*ring->buf), GFP_KERNEL); + if (!ring->buf) { + err = -ENOMEM; + goto err; + } + + for (i = 0; i < ring->size; i++) { + int idx = i * ring->desc_size; + ring->buf[i].desc = (struct ag71xx_desc *)&ring->descs_cpu[idx]; + DBG("ag71xx: ring %p, desc %d at %p\n", + ring, i, ring->buf[i].desc); + } + + return 0; + +err: + return err; +} + +static void ag71xx_ring_tx_clean(struct ag71xx *ag) +{ + struct ag71xx_ring *ring = &ag->tx_ring; + struct net_device *dev = ag->dev; + u32 bytes_compl = 0, pkts_compl = 0; + + while (ring->curr != ring->dirty) { + u32 i = ring->dirty % ring->size; + + if (!ag71xx_desc_empty(ring->buf[i].desc)) { + ring->buf[i].desc->ctrl = 0; + dev->stats.tx_errors++; + } + + if (ring->buf[i].skb) { + bytes_compl += ring->buf[i].skb->len; + pkts_compl++; + dev_kfree_skb_any(ring->buf[i].skb); + } + ring->buf[i].skb = NULL; + ring->dirty++; + } + + /* flush descriptors */ + wmb(); + + netdev_completed_queue(dev, pkts_compl, bytes_compl); +} + +static void ag71xx_ring_tx_init(struct ag71xx *ag) +{ + struct ag71xx_ring *ring = &ag->tx_ring; + int i; + + for (i = 0; i < ring->size; i++) { + ring->buf[i].desc->next = (u32) (ring->descs_dma + + ring->desc_size * ((i + 1) % ring->size)); + + ring->buf[i].desc->ctrl = DESC_EMPTY; + ring->buf[i].skb = NULL; + } + + /* flush descriptors */ + wmb(); + + ring->curr = 0; + ring->dirty = 0; + netdev_reset_queue(ag->dev); +} + +static void ag71xx_ring_rx_clean(struct ag71xx *ag) +{ + struct ag71xx_ring *ring = &ag->rx_ring; + int i; + + if (!ring->buf) + return; + + for (i = 0; i < ring->size; i++) + if (ring->buf[i].rx_buf) { + dma_unmap_single(&ag->dev->dev, ring->buf[i].dma_addr, + AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); + kfree(ring->buf[i].rx_buf); + } +} + +static int ag71xx_buffer_offset(struct ag71xx *ag) +{ + int offset = NET_SKB_PAD; + + /* + * On AR71xx/AR91xx packets must be 4-byte aligned. + * + * When using builtin AR8216 support, hardware adds a 2-byte header, + * so we don't need any extra alignment in that case. + */ + if (!ag71xx_get_pdata(ag)->is_ar724x || ag71xx_has_ar8216(ag)) + return offset; + + return offset + NET_IP_ALIGN; +} + +static bool ag71xx_fill_rx_buf(struct ag71xx *ag, struct ag71xx_buf *buf, + int offset) +{ + void *data; + + data = kmalloc(AG71XX_RX_BUF_SIZE + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)), + GFP_ATOMIC); + if (!data) + return false; + + buf->rx_buf = data; + buf->dma_addr = dma_map_single(&ag->dev->dev, data, + AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); + buf->desc->data = (u32) buf->dma_addr + offset; + return true; +} + +static int ag71xx_ring_rx_init(struct ag71xx *ag) +{ + struct ag71xx_ring *ring = &ag->rx_ring; + unsigned int i; + int ret; + int offset = ag71xx_buffer_offset(ag); + + ret = 0; + for (i = 0; i < ring->size; i++) { + ring->buf[i].desc->next = (u32) (ring->descs_dma + + ring->desc_size * ((i + 1) % ring->size)); + + DBG("ag71xx: RX desc at %p, next is %08x\n", + ring->buf[i].desc, + ring->buf[i].desc->next); + } + + for (i = 0; i < ring->size; i++) { + if (!ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) { + ret = -ENOMEM; + break; + } + + ring->buf[i].desc->ctrl = DESC_EMPTY; + } + + /* flush descriptors */ + wmb(); + + ring->curr = 0; + ring->dirty = 0; + + return ret; +} + +static int ag71xx_ring_rx_refill(struct ag71xx *ag) +{ + struct ag71xx_ring *ring = &ag->rx_ring; + unsigned int count; + int offset = ag71xx_buffer_offset(ag); + + count = 0; + for (; ring->curr - ring->dirty > 0; ring->dirty++) { + unsigned int i; + + i = ring->dirty % ring->size; + + if (!ring->buf[i].rx_buf && + !ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) + break; + + ring->buf[i].desc->ctrl = DESC_EMPTY; + count++; + } + + /* flush descriptors */ + wmb(); + + DBG("%s: %u rx descriptors refilled\n", ag->dev->name, count); + + return count; +} + +static int ag71xx_rings_init(struct ag71xx *ag) +{ + int ret; + + ret = ag71xx_ring_alloc(&ag->tx_ring); + if (ret) + return ret; + + ag71xx_ring_tx_init(ag); + + ret = ag71xx_ring_alloc(&ag->rx_ring); + if (ret) + return ret; + + ret = ag71xx_ring_rx_init(ag); + return ret; +} + +static void ag71xx_rings_cleanup(struct ag71xx *ag) +{ + ag71xx_ring_rx_clean(ag); + ag71xx_ring_free(&ag->rx_ring); + + ag71xx_ring_tx_clean(ag); + netdev_reset_queue(ag->dev); + ag71xx_ring_free(&ag->tx_ring); +} + +static unsigned char *ag71xx_speed_str(struct ag71xx *ag) +{ + switch (ag->speed) { + case SPEED_1000: + return "1000"; + case SPEED_100: + return "100"; + case SPEED_10: + return "10"; + } + + return "?"; +} + +static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) +{ + u32 t; + + t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16) + | (((u32) mac[3]) << 8) | ((u32) mac[2]); + + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t); + + t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16); + ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t); +} + +static void ag71xx_dma_reset(struct ag71xx *ag) +{ + u32 val; + int i; + + ag71xx_dump_dma_regs(ag); + + /* stop RX and TX */ + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); + + /* + * give the hardware some time to really stop all rx/tx activity + * clearing the descriptors too early causes random memory corruption + */ + mdelay(1); + + /* clear descriptor addresses */ + ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->stop_desc_dma); + ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->stop_desc_dma); + + /* clear pending RX/TX interrupts */ + for (i = 0; i < 256; i++) { + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); + } + + /* clear pending errors */ + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF); + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR); + + val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); + if (val) + pr_alert("%s: unable to clear DMA Rx status: %08x\n", + ag->dev->name, val); + + val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); + + /* mask out reserved bits */ + val &= ~0xff000000; + + if (val) + pr_alert("%s: unable to clear DMA Tx status: %08x\n", + ag->dev->name, val); + + ag71xx_dump_dma_regs(ag); +} + +#define MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \ + MAC_CFG1_SRX | MAC_CFG1_STX) + +#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT) + +#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \ + FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \ + FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \ + FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \ + FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \ + FIFO_CFG4_VT) + +#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \ + FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \ + FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \ + FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \ + FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \ + FIFO_CFG5_17 | FIFO_CFG5_SF) + +static void ag71xx_hw_stop(struct ag71xx *ag) +{ + /* disable all interrupts and stop the rx/tx engine */ + ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0); + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); +} + +static void ag71xx_hw_setup(struct ag71xx *ag) +{ + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + + /* setup MAC configuration registers */ + ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_INIT); + + ag71xx_sb(ag, AG71XX_REG_MAC_CFG2, + MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK); + + /* setup max frame length */ + ag71xx_wr(ag, AG71XX_REG_MAC_MFL, AG71XX_TX_MTU_LEN); + + /* setup FIFO configuration registers */ + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT); + if (pdata->is_ar724x) { + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, pdata->fifo_cfg1); + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, pdata->fifo_cfg2); + } else { + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000); + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff); + } + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT); + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT); +} + +static void ag71xx_hw_init(struct ag71xx *ag) +{ + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + u32 reset_mask = pdata->reset_bit; + + ag71xx_hw_stop(ag); + + if (pdata->is_ar724x) { + u32 reset_phy = reset_mask; + + reset_phy &= AR71XX_RESET_GE0_PHY | AR71XX_RESET_GE1_PHY; + reset_mask &= ~(AR71XX_RESET_GE0_PHY | AR71XX_RESET_GE1_PHY); + + ath79_device_reset_set(reset_phy); + mdelay(50); + ath79_device_reset_clear(reset_phy); + mdelay(200); + } + + ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR); + udelay(20); + + ath79_device_reset_set(reset_mask); + mdelay(100); + ath79_device_reset_clear(reset_mask); + mdelay(200); + + ag71xx_hw_setup(ag); + + ag71xx_dma_reset(ag); +} + +static void ag71xx_fast_reset(struct ag71xx *ag) +{ + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + struct net_device *dev = ag->dev; + u32 reset_mask = pdata->reset_bit; + u32 rx_ds, tx_ds; + u32 mii_reg; + + reset_mask &= AR71XX_RESET_GE0_MAC | AR71XX_RESET_GE1_MAC; + + mii_reg = ag71xx_rr(ag, AG71XX_REG_MII_CFG); + rx_ds = ag71xx_rr(ag, AG71XX_REG_RX_DESC); + tx_ds = ag71xx_rr(ag, AG71XX_REG_TX_DESC); + + ath79_device_reset_set(reset_mask); + udelay(10); + ath79_device_reset_clear(reset_mask); + udelay(10); + + ag71xx_dma_reset(ag); + ag71xx_hw_setup(ag); + + ag71xx_wr(ag, AG71XX_REG_RX_DESC, rx_ds); + ag71xx_wr(ag, AG71XX_REG_TX_DESC, tx_ds); + ag71xx_wr(ag, AG71XX_REG_MII_CFG, mii_reg); + + ag71xx_hw_set_macaddr(ag, dev->dev_addr); +} + +static void ag71xx_hw_start(struct ag71xx *ag) +{ + /* start RX engine */ + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); + + /* enable interrupts */ + ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT); +} + +void ag71xx_link_adjust(struct ag71xx *ag) +{ + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + u32 cfg2; + u32 ifctl; + u32 fifo5; + + if (!ag->link) { + ag71xx_hw_stop(ag); + netif_carrier_off(ag->dev); + if (netif_msg_link(ag)) + pr_info("%s: link down\n", ag->dev->name); + return; + } + + if (pdata->is_ar724x) + ag71xx_fast_reset(ag); + + cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2); + cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX); + cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0; + + ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL); + ifctl &= ~(MAC_IFCTL_SPEED); + + fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5); + fifo5 &= ~FIFO_CFG5_BM; + + switch (ag->speed) { + case SPEED_1000: + cfg2 |= MAC_CFG2_IF_1000; + fifo5 |= FIFO_CFG5_BM; + break; + case SPEED_100: + cfg2 |= MAC_CFG2_IF_10_100; + ifctl |= MAC_IFCTL_SPEED; + break; + case SPEED_10: + cfg2 |= MAC_CFG2_IF_10_100; + break; + default: + BUG(); + return; + } + + if (pdata->is_ar91xx) + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff); + else if (pdata->is_ar724x) + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, pdata->fifo_cfg3); + else + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x008001ff); + + if (pdata->set_speed) + pdata->set_speed(ag->speed); + + ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2); + ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5); + ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); + ag71xx_hw_start(ag); + + netif_carrier_on(ag->dev); + if (netif_msg_link(ag)) + pr_info("%s: link up (%sMbps/%s duplex)\n", + ag->dev->name, + ag71xx_speed_str(ag), + (DUPLEX_FULL == ag->duplex) ? "Full" : "Half"); + + DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); + + DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); + + DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL)); +} + +static int ag71xx_open(struct net_device *dev) +{ + struct ag71xx *ag = netdev_priv(dev); + int ret; + + ret = ag71xx_rings_init(ag); + if (ret) + goto err; + + napi_enable(&ag->napi); + + netif_carrier_off(dev); + ag71xx_phy_start(ag); + + ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma); + ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->rx_ring.descs_dma); + + ag71xx_hw_set_macaddr(ag, dev->dev_addr); + + netif_start_queue(dev); + + return 0; + +err: + ag71xx_rings_cleanup(ag); + return ret; +} + +static int ag71xx_stop(struct net_device *dev) +{ + struct ag71xx *ag = netdev_priv(dev); + unsigned long flags; + + netif_carrier_off(dev); + ag71xx_phy_stop(ag); + + spin_lock_irqsave(&ag->lock, flags); + + netif_stop_queue(dev); + + ag71xx_hw_stop(ag); + ag71xx_dma_reset(ag); + + napi_disable(&ag->napi); + del_timer_sync(&ag->oom_timer); + + spin_unlock_irqrestore(&ag->lock, flags); + + ag71xx_rings_cleanup(ag); + + return 0; +} + +static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct ag71xx *ag = netdev_priv(dev); + struct ag71xx_ring *ring = &ag->tx_ring; + struct ag71xx_desc *desc; + dma_addr_t dma_addr; + int i; + + i = ring->curr % ring->size; + desc = ring->buf[i].desc; + + if (!ag71xx_desc_empty(desc)) + goto err_drop; + + if (ag71xx_has_ar8216(ag)) + ag71xx_add_ar8216_header(ag, skb); + + if (skb->len <= 0) { + DBG("%s: packet len is too small\n", ag->dev->name); + goto err_drop; + } + + dma_addr = dma_map_single(&dev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + + netdev_sent_queue(dev, skb->len); + ring->buf[i].skb = skb; + ring->buf[i].timestamp = jiffies; + + /* setup descriptor fields */ + desc->data = (u32) dma_addr; + desc->ctrl = (skb->len & DESC_PKTLEN_M); + + /* flush descriptor */ + wmb(); + + ring->curr++; + if (ring->curr == (ring->dirty + ring->size)) { + DBG("%s: tx queue full\n", ag->dev->name); + netif_stop_queue(dev); + } + + DBG("%s: packet injected into TX queue\n", ag->dev->name); + + /* enable TX engine */ + ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE); + + return NETDEV_TX_OK; + +err_drop: + dev->stats.tx_dropped++; + + dev_kfree_skb(skb); + return NETDEV_TX_OK; +} + +static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct ag71xx *ag = netdev_priv(dev); + int ret; + + switch (cmd) { + case SIOCETHTOOL: + if (ag->phy_dev == NULL) + break; + + spin_lock_irq(&ag->lock); + ret = phy_ethtool_ioctl(ag->phy_dev, (void *) ifr->ifr_data); + spin_unlock_irq(&ag->lock); + return ret; + + 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; + + case SIOCGMIIPHY: + case SIOCGMIIREG: + case SIOCSMIIREG: + if (ag->phy_dev == NULL) + break; + + return phy_mii_ioctl(ag->phy_dev, ifr, cmd); + + default: + break; + } + + return -EOPNOTSUPP; +} + +static void ag71xx_oom_timer_handler(unsigned long data) +{ + struct net_device *dev = (struct net_device *) data; + struct ag71xx *ag = netdev_priv(dev); + + napi_schedule(&ag->napi); +} + +static void ag71xx_tx_timeout(struct net_device *dev) +{ + struct ag71xx *ag = netdev_priv(dev); + + if (netif_msg_tx_err(ag)) + pr_info("%s: tx timeout\n", ag->dev->name); + + schedule_work(&ag->restart_work); +} + +static void ag71xx_restart_work_func(struct work_struct *work) +{ + struct ag71xx *ag = container_of(work, struct ag71xx, restart_work); + + if (ag71xx_get_pdata(ag)->is_ar724x) { + ag->link = 0; + ag71xx_link_adjust(ag); + return; + } + + ag71xx_stop(ag->dev); + ag71xx_open(ag->dev); +} + +static bool ag71xx_check_dma_stuck(struct ag71xx *ag, unsigned long timestamp) +{ + u32 rx_sm, tx_sm, rx_fd; + + if (likely(time_before(jiffies, timestamp + HZ/10))) + return false; + + if (!netif_carrier_ok(ag->dev)) + return false; + + rx_sm = ag71xx_rr(ag, AG71XX_REG_RX_SM); + if ((rx_sm & 0x7) == 0x3 && ((rx_sm >> 4) & 0x7) == 0x6) + return true; + + tx_sm = ag71xx_rr(ag, AG71XX_REG_TX_SM); + rx_fd = ag71xx_rr(ag, AG71XX_REG_FIFO_DEPTH); + if (((tx_sm >> 4) & 0x7) == 0 && ((rx_sm & 0x7) == 0) && + ((rx_sm >> 4) & 0x7) == 0 && rx_fd == 0) + return true; + + return false; +} + +static int ag71xx_tx_packets(struct ag71xx *ag) +{ + struct ag71xx_ring *ring = &ag->tx_ring; + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + int sent = 0; + int bytes_compl = 0; + + DBG("%s: processing TX ring\n", ag->dev->name); + + while (ring->dirty != ring->curr) { + unsigned int i = ring->dirty % ring->size; + struct ag71xx_desc *desc = ring->buf[i].desc; + struct sk_buff *skb = ring->buf[i].skb; + + if (!ag71xx_desc_empty(desc)) { + if (pdata->is_ar7240 && + ag71xx_check_dma_stuck(ag, ring->buf[i].timestamp)) + schedule_work(&ag->restart_work); + break; + } + + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); + + bytes_compl += skb->len; + ag->dev->stats.tx_bytes += skb->len; + ag->dev->stats.tx_packets++; + + dev_kfree_skb_any(skb); + ring->buf[i].skb = NULL; + + ring->dirty++; + sent++; + } + + DBG("%s: %d packets sent out\n", ag->dev->name, sent); + + netdev_completed_queue(ag->dev, sent, bytes_compl); + if ((ring->curr - ring->dirty) < (ring->size * 3) / 4) + netif_wake_queue(ag->dev); + + return sent; +} + +static int ag71xx_rx_packets(struct ag71xx *ag, int limit) +{ + struct net_device *dev = ag->dev; + struct ag71xx_ring *ring = &ag->rx_ring; + int offset = ag71xx_buffer_offset(ag); + int done = 0; + + DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n", + dev->name, limit, ring->curr, ring->dirty); + + while (done < limit) { + unsigned int i = ring->curr % ring->size; + struct ag71xx_desc *desc = ring->buf[i].desc; + struct sk_buff *skb; + int pktlen; + int err = 0; + + if (ag71xx_desc_empty(desc)) + break; + + if ((ring->dirty + ring->size) == ring->curr) { + ag71xx_assert(0); + break; + } + + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); + + pktlen = ag71xx_desc_pktlen(desc); + pktlen -= ETH_FCS_LEN; + + dma_unmap_single(&dev->dev, ring->buf[i].dma_addr, + AG71XX_RX_BUF_SIZE, DMA_FROM_DEVICE); + + dev->last_rx = jiffies; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pktlen; + + skb = build_skb(ring->buf[i].rx_buf); + if (!skb) { + kfree(ring->buf[i].rx_buf); + goto next; + } + + skb_reserve(skb, offset); + skb_put(skb, pktlen); + + if (ag71xx_has_ar8216(ag)) + err = ag71xx_remove_ar8216_header(ag, skb, pktlen); + + if (err) { + dev->stats.rx_dropped++; + kfree_skb(skb); + } else { + skb->dev = dev; + skb->ip_summed = CHECKSUM_NONE; + skb->protocol = eth_type_trans(skb, dev); + netif_receive_skb(skb); + } + +next: + ring->buf[i].rx_buf = NULL; + done++; + + ring->curr++; + } + + ag71xx_ring_rx_refill(ag); + + DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n", + dev->name, ring->curr, ring->dirty, done); + + return done; +} + +static int ag71xx_poll(struct napi_struct *napi, int limit) +{ + struct ag71xx *ag = container_of(napi, struct ag71xx, napi); + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + struct net_device *dev = ag->dev; + struct ag71xx_ring *rx_ring; + unsigned long flags; + u32 status; + int tx_done; + int rx_done; + + pdata->ddr_flush(); + tx_done = ag71xx_tx_packets(ag); + + DBG("%s: processing RX ring\n", dev->name); + rx_done = ag71xx_rx_packets(ag, limit); + + ag71xx_debugfs_update_napi_stats(ag, rx_done, tx_done); + + rx_ring = &ag->rx_ring; + if (rx_ring->buf[rx_ring->dirty % rx_ring->size].rx_buf == NULL) + goto oom; + + status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); + if (unlikely(status & RX_STATUS_OF)) { + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF); + dev->stats.rx_fifo_errors++; + + /* restart RX */ + ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); + } + + if (rx_done < limit) { + if (status & RX_STATUS_PR) + goto more; + + status = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); + if (status & TX_STATUS_PS) + goto more; + + DBG("%s: disable polling mode, rx=%d, tx=%d,limit=%d\n", + dev->name, rx_done, tx_done, limit); + + napi_complete(napi); + + /* enable interrupts */ + spin_lock_irqsave(&ag->lock, flags); + ag71xx_int_enable(ag, AG71XX_INT_POLL); + spin_unlock_irqrestore(&ag->lock, flags); + return rx_done; + } + +more: + DBG("%s: stay in polling mode, rx=%d, tx=%d, limit=%d\n", + dev->name, rx_done, tx_done, limit); + return rx_done; + +oom: + if (netif_msg_rx_err(ag)) + pr_info("%s: out of memory\n", dev->name); + + mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL); + napi_complete(napi); + return 0; +} + +static irqreturn_t ag71xx_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct ag71xx *ag = netdev_priv(dev); + u32 status; + + status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS); + ag71xx_dump_intr(ag, "raw", status); + + if (unlikely(!status)) + return IRQ_NONE; + + if (unlikely(status & AG71XX_INT_ERR)) { + if (status & AG71XX_INT_TX_BE) { + ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE); + dev_err(&dev->dev, "TX BUS error\n"); + } + if (status & AG71XX_INT_RX_BE) { + ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE); + dev_err(&dev->dev, "RX BUS error\n"); + } + } + + if (likely(status & AG71XX_INT_POLL)) { + ag71xx_int_disable(ag, AG71XX_INT_POLL); + DBG("%s: enable polling mode\n", dev->name); + napi_schedule(&ag->napi); + } + + ag71xx_debugfs_update_int_stats(ag, status); + + return IRQ_HANDLED; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +/* + * Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. + */ +static void ag71xx_netpoll(struct net_device *dev) +{ + disable_irq(dev->irq); + ag71xx_interrupt(dev->irq, dev); + enable_irq(dev->irq); +} +#endif + +static const struct net_device_ops ag71xx_netdev_ops = { + .ndo_open = ag71xx_open, + .ndo_stop = ag71xx_stop, + .ndo_start_xmit = ag71xx_hard_start_xmit, + .ndo_do_ioctl = ag71xx_do_ioctl, + .ndo_tx_timeout = ag71xx_tx_timeout, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = ag71xx_netpoll, +#endif +}; + +static int __devinit ag71xx_probe(struct platform_device *pdev) +{ + struct net_device *dev; + struct resource *res; + struct ag71xx *ag; + struct ag71xx_platform_data *pdata; + int err; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "no platform data specified\n"); + err = -ENXIO; + goto err_out; + } + + if (pdata->mii_bus_dev == NULL) { + dev_err(&pdev->dev, "no MII bus device specified\n"); + err = -EINVAL; + goto err_out; + } + + dev = alloc_etherdev(sizeof(*ag)); + if (!dev) { + dev_err(&pdev->dev, "alloc_etherdev failed\n"); + err = -ENOMEM; + goto err_out; + } + + SET_NETDEV_DEV(dev, &pdev->dev); + + ag = netdev_priv(dev); + ag->pdev = pdev; + ag->dev = dev; + ag->msg_enable = netif_msg_init(ag71xx_msg_level, + AG71XX_DEFAULT_MSG_ENABLE); + spin_lock_init(&ag->lock); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base"); + if (!res) { + dev_err(&pdev->dev, "no mac_base resource found\n"); + err = -ENXIO; + goto err_out; + } + + ag->mac_base = ioremap_nocache(res->start, res->end - res->start + 1); + if (!ag->mac_base) { + dev_err(&pdev->dev, "unable to ioremap mac_base\n"); + err = -ENOMEM; + goto err_free_dev; + } + + dev->irq = platform_get_irq(pdev, 0); + err = request_irq(dev->irq, ag71xx_interrupt, + IRQF_DISABLED, + dev->name, dev); + if (err) { + dev_err(&pdev->dev, "unable to request IRQ %d\n", dev->irq); + goto err_unmap_base; + } + + dev->base_addr = (unsigned long)ag->mac_base; + dev->netdev_ops = &ag71xx_netdev_ops; + dev->ethtool_ops = &ag71xx_ethtool_ops; + + INIT_WORK(&ag->restart_work, ag71xx_restart_work_func); + + init_timer(&ag->oom_timer); + ag->oom_timer.data = (unsigned long) dev; + ag->oom_timer.function = ag71xx_oom_timer_handler; + + ag->tx_ring.size = AG71XX_TX_RING_SIZE_DEFAULT; + ag->rx_ring.size = AG71XX_RX_RING_SIZE_DEFAULT; + + ag->stop_desc = dma_alloc_coherent(NULL, + sizeof(struct ag71xx_desc), &ag->stop_desc_dma, GFP_KERNEL); + + if (!ag->stop_desc) + goto err_free_irq; + + ag->stop_desc->data = 0; + ag->stop_desc->ctrl = 0; + ag->stop_desc->next = (u32) ag->stop_desc_dma; + + memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN); + + netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT); + + err = register_netdev(dev); + if (err) { + dev_err(&pdev->dev, "unable to register net device\n"); + goto err_free_desc; + } + + pr_info("%s: Atheros AG71xx at 0x%08lx, irq %d\n", + dev->name, dev->base_addr, dev->irq); + + ag71xx_dump_regs(ag); + + ag71xx_hw_init(ag); + + ag71xx_dump_regs(ag); + + err = ag71xx_phy_connect(ag); + if (err) + goto err_unregister_netdev; + + err = ag71xx_debugfs_init(ag); + if (err) + goto err_phy_disconnect; + + platform_set_drvdata(pdev, dev); + + return 0; + +err_phy_disconnect: + ag71xx_phy_disconnect(ag); +err_unregister_netdev: + unregister_netdev(dev); +err_free_desc: + dma_free_coherent(NULL, sizeof(struct ag71xx_desc), ag->stop_desc, + ag->stop_desc_dma); +err_free_irq: + free_irq(dev->irq, dev); +err_unmap_base: + iounmap(ag->mac_base); +err_free_dev: + kfree(dev); +err_out: + platform_set_drvdata(pdev, NULL); + return err; +} + +static int __devexit ag71xx_remove(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + + if (dev) { + struct ag71xx *ag = netdev_priv(dev); + + ag71xx_debugfs_exit(ag); + ag71xx_phy_disconnect(ag); + unregister_netdev(dev); + free_irq(dev->irq, dev); + iounmap(ag->mac_base); + kfree(dev); + platform_set_drvdata(pdev, NULL); + } + + return 0; +} + +static struct platform_driver ag71xx_driver = { + .probe = ag71xx_probe, + .remove = __exit_p(ag71xx_remove), + .driver = { + .name = AG71XX_DRV_NAME, + } +}; + +static int __init ag71xx_module_init(void) +{ + int ret; + + ret = ag71xx_debugfs_root_init(); + if (ret) + goto err_out; + + ret = ag71xx_mdio_driver_init(); + if (ret) + goto err_debugfs_exit; + + ret = platform_driver_register(&ag71xx_driver); + if (ret) + goto err_mdio_exit; + + return 0; + +err_mdio_exit: + ag71xx_mdio_driver_exit(); +err_debugfs_exit: + ag71xx_debugfs_root_exit(); +err_out: + return ret; +} + +static void __exit ag71xx_module_exit(void) +{ + platform_driver_unregister(&ag71xx_driver); + ag71xx_mdio_driver_exit(); + ag71xx_debugfs_root_exit(); +} + +module_init(ag71xx_module_init); +module_exit(ag71xx_module_exit); + +MODULE_VERSION(AG71XX_DRV_VERSION); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_AUTHOR("Imre Kaloz "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" AG71XX_DRV_NAME); diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c new file mode 100644 index 000000000..e123505c7 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c @@ -0,0 +1,315 @@ +/* + * Atheros AR71xx built-in ethernet mac driver + * + * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * Based on Atheros' AG7100 driver + * + * This program 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. + */ + +#include "ag71xx.h" + +#define AG71XX_MDIO_RETRY 1000 +#define AG71XX_MDIO_DELAY 5 + +static inline void ag71xx_mdio_wr(struct ag71xx_mdio *am, unsigned reg, + u32 value) +{ + void __iomem *r; + + r = am->mdio_base + reg; + __raw_writel(value, r); + + /* flush write */ + (void) __raw_readl(r); +} + +static inline u32 ag71xx_mdio_rr(struct ag71xx_mdio *am, unsigned reg) +{ + return __raw_readl(am->mdio_base + reg); +} + +static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am) +{ + DBG("%s: mii_cfg=%08x, mii_cmd=%08x, mii_addr=%08x\n", + am->mii_bus->name, + ag71xx_mdio_rr(am, AG71XX_REG_MII_CFG), + ag71xx_mdio_rr(am, AG71XX_REG_MII_CMD), + ag71xx_mdio_rr(am, AG71XX_REG_MII_ADDR)); + DBG("%s: mii_ctrl=%08x, mii_status=%08x, mii_ind=%08x\n", + am->mii_bus->name, + ag71xx_mdio_rr(am, AG71XX_REG_MII_CTRL), + ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS), + ag71xx_mdio_rr(am, AG71XX_REG_MII_IND)); +} + +static int ag71xx_mdio_wait_busy(struct ag71xx_mdio *am) +{ + int i; + + for (i = 0; i < AG71XX_MDIO_RETRY; i++) { + u32 busy; + + udelay(AG71XX_MDIO_DELAY); + + busy = ag71xx_mdio_rr(am, AG71XX_REG_MII_IND); + if (!busy) + return 0; + + udelay(AG71XX_MDIO_DELAY); + } + + pr_err("%s: MDIO operation timed out\n", am->mii_bus->name); + + return -ETIMEDOUT; +} + +int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg) +{ + int err; + int ret; + + err = ag71xx_mdio_wait_busy(am); + if (err) + return 0xffff; + + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); + ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_READ); + + err = ag71xx_mdio_wait_busy(am); + if (err) + return 0xffff; + + ret = ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS) & 0xffff; + ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); + + DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret); + + return ret; +} + +void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val) +{ + DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val); + + ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, + ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); + ag71xx_mdio_wr(am, AG71XX_REG_MII_CTRL, val); + + ag71xx_mdio_wait_busy(am); +} + +static const u32 ar71xx_mdio_div_table[] = { + 4, 4, 6, 8, 10, 14, 20, 28, +}; + +static const u32 ar7240_mdio_div_table[] = { + 2, 2, 4, 6, 8, 12, 18, 26, 32, 40, 48, 56, 62, 70, 78, 96, +}; + +static const u32 ar933x_mdio_div_table[] = { + 4, 4, 6, 8, 10, 14, 20, 28, 34, 42, 50, 58, 66, 74, 82, 98, +}; + +static int ag71xx_mdio_get_divider(struct ag71xx_mdio *am, u32 *div) +{ + unsigned long ref_clock, mdio_clock; + const u32 *table; + int ndivs; + int i; + + ref_clock = am->pdata->ref_clock; + mdio_clock = am->pdata->mdio_clock; + + if (!ref_clock || !mdio_clock) + return -EINVAL; + + if (am->pdata->is_ar9330 || am->pdata->is_ar934x) { + table = ar933x_mdio_div_table; + ndivs = ARRAY_SIZE(ar933x_mdio_div_table); + } else if (am->pdata->is_ar7240) { + table = ar7240_mdio_div_table; + ndivs = ARRAY_SIZE(ar7240_mdio_div_table); + } else { + table = ar71xx_mdio_div_table; + ndivs = ARRAY_SIZE(ar71xx_mdio_div_table); + } + + for (i = 0; i < ndivs; i++) { + unsigned long t; + + t = ref_clock / table[i]; + if (t <= mdio_clock) { + *div = i; + return 0; + } + } + + dev_err(&am->mii_bus->dev, "no divider found for %lu/%lu\n", + ref_clock, mdio_clock); + return -ENOENT; +} + +static int ag71xx_mdio_reset(struct mii_bus *bus) +{ + struct ag71xx_mdio *am = bus->priv; + u32 t; + int err; + + err = ag71xx_mdio_get_divider(am, &t); + if (err) { + /* fallback */ + if (am->pdata->is_ar7240) + t = MII_CFG_CLK_DIV_6; + else if (am->pdata->builtin_switch && !am->pdata->is_ar934x) + t = MII_CFG_CLK_DIV_10; + else if (!am->pdata->builtin_switch && am->pdata->is_ar934x) + t = MII_CFG_CLK_DIV_58; + else + t = MII_CFG_CLK_DIV_28; + } + + ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t | MII_CFG_RESET); + udelay(100); + + ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t); + udelay(100); + + return 0; +} + +static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg) +{ + struct ag71xx_mdio *am = bus->priv; + + if (am->pdata->builtin_switch) + return ar7240sw_phy_read(bus, addr, reg); + else + return ag71xx_mdio_mii_read(am, addr, reg); +} + +static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val) +{ + struct ag71xx_mdio *am = bus->priv; + + if (am->pdata->builtin_switch) + ar7240sw_phy_write(bus, addr, reg, val); + else + ag71xx_mdio_mii_write(am, addr, reg, val); + return 0; +} + +static int __devinit ag71xx_mdio_probe(struct platform_device *pdev) +{ + struct ag71xx_mdio_platform_data *pdata; + struct ag71xx_mdio *am; + struct resource *res; + int i; + int err; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "no platform data specified\n"); + return -EINVAL; + } + + am = kzalloc(sizeof(*am), GFP_KERNEL); + if (!am) { + err = -ENOMEM; + goto err_out; + } + + am->pdata = pdata; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "no iomem resource found\n"); + err = -ENXIO; + goto err_out; + } + + am->mdio_base = ioremap_nocache(res->start, res->end - res->start + 1); + if (!am->mdio_base) { + dev_err(&pdev->dev, "unable to ioremap registers\n"); + err = -ENOMEM; + goto err_free_mdio; + } + + am->mii_bus = mdiobus_alloc(); + if (am->mii_bus == NULL) { + err = -ENOMEM; + goto err_iounmap; + } + + am->mii_bus->name = "ag71xx_mdio"; + am->mii_bus->read = ag71xx_mdio_read; + am->mii_bus->write = ag71xx_mdio_write; + am->mii_bus->reset = ag71xx_mdio_reset; + am->mii_bus->irq = am->mii_irq; + am->mii_bus->priv = am; + am->mii_bus->parent = &pdev->dev; + snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev)); + am->mii_bus->phy_mask = pdata->phy_mask; + + for (i = 0; i < PHY_MAX_ADDR; i++) + am->mii_irq[i] = PHY_POLL; + + ag71xx_mdio_wr(am, AG71XX_REG_MAC_CFG1, 0); + + err = mdiobus_register(am->mii_bus); + if (err) + goto err_free_bus; + + ag71xx_mdio_dump_regs(am); + + platform_set_drvdata(pdev, am); + return 0; + +err_free_bus: + mdiobus_free(am->mii_bus); +err_iounmap: + iounmap(am->mdio_base); +err_free_mdio: + kfree(am); +err_out: + return err; +} + +static int __devexit ag71xx_mdio_remove(struct platform_device *pdev) +{ + struct ag71xx_mdio *am = platform_get_drvdata(pdev); + + if (am) { + mdiobus_unregister(am->mii_bus); + mdiobus_free(am->mii_bus); + iounmap(am->mdio_base); + kfree(am); + platform_set_drvdata(pdev, NULL); + } + + return 0; +} + +static struct platform_driver ag71xx_mdio_driver = { + .probe = ag71xx_mdio_probe, + .remove = __exit_p(ag71xx_mdio_remove), + .driver = { + .name = "ag71xx-mdio", + } +}; + +int __init ag71xx_mdio_driver_init(void) +{ + return platform_driver_register(&ag71xx_mdio_driver); +} + +void ag71xx_mdio_driver_exit(void) +{ + platform_driver_unregister(&ag71xx_mdio_driver); +} diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_phy.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_phy.c new file mode 100644 index 000000000..ebdbc5b9a --- /dev/null +++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_phy.c @@ -0,0 +1,235 @@ +/* + * Atheros AR71xx built-in ethernet mac driver + * + * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * Based on Atheros' AG7100 driver + * + * This program 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. + */ + +#include "ag71xx.h" + +static void ag71xx_phy_link_adjust(struct net_device *dev) +{ + struct ag71xx *ag = netdev_priv(dev); + struct phy_device *phydev = ag->phy_dev; + unsigned long flags; + int status_change = 0; + + spin_lock_irqsave(&ag->lock, flags); + + if (phydev->link) { + if (ag->duplex != phydev->duplex + || ag->speed != phydev->speed) { + status_change = 1; + } + } + + if (phydev->link != ag->link) + status_change = 1; + + ag->link = phydev->link; + ag->duplex = phydev->duplex; + ag->speed = phydev->speed; + + if (status_change) + ag71xx_link_adjust(ag); + + spin_unlock_irqrestore(&ag->lock, flags); +} + +void ag71xx_phy_start(struct ag71xx *ag) +{ + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + + if (ag->phy_dev) { + phy_start(ag->phy_dev); + } else if (pdata->switch_data) { + ag71xx_ar7240_start(ag); + } else { + ag->link = 1; + ag71xx_link_adjust(ag); + } +} + +void ag71xx_phy_stop(struct ag71xx *ag) +{ + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + unsigned long flags; + + if (ag->phy_dev) + phy_stop(ag->phy_dev); + else if (pdata->switch_data) + ag71xx_ar7240_stop(ag); + + spin_lock_irqsave(&ag->lock, flags); + if (ag->link) { + ag->link = 0; + ag71xx_link_adjust(ag); + } + spin_unlock_irqrestore(&ag->lock, flags); +} + +static int ag71xx_phy_connect_fixed(struct ag71xx *ag) +{ + struct net_device *dev = ag->dev; + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + int ret = 0; + + /* use fixed settings */ + switch (pdata->speed) { + case SPEED_10: + case SPEED_100: + case SPEED_1000: + break; + default: + netdev_err(dev, "invalid speed specified\n"); + ret = -EINVAL; + break; + } + + netdev_dbg(dev, "using fixed link parameters\n"); + + ag->duplex = pdata->duplex; + ag->speed = pdata->speed; + + return ret; +} + +static int ag71xx_phy_connect_multi(struct ag71xx *ag) +{ + struct net_device *dev = ag->dev; + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + struct phy_device *phydev = NULL; + int phy_addr; + int ret = 0; + + for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { + if (!(pdata->phy_mask & (1 << phy_addr))) + continue; + + if (ag->mii_bus->phy_map[phy_addr] == NULL) + continue; + + DBG("%s: PHY found at %s, uid=%08x\n", + dev->name, + dev_name(&ag->mii_bus->phy_map[phy_addr]->dev), + ag->mii_bus->phy_map[phy_addr]->phy_id); + + if (phydev == NULL) + phydev = ag->mii_bus->phy_map[phy_addr]; + } + + if (!phydev) { + netdev_err(dev, "no PHY found with phy_mask=%08x\n", + pdata->phy_mask); + return -ENODEV; + } + + ag->phy_dev = phy_connect(dev, dev_name(&phydev->dev), + &ag71xx_phy_link_adjust, 0, + pdata->phy_if_mode); + + if (IS_ERR(ag->phy_dev)) { + netdev_err(dev, "could not connect to PHY at %s\n", + dev_name(&phydev->dev)); + return PTR_ERR(ag->phy_dev); + } + + /* mask with MAC supported features */ + if (pdata->has_gbit) + phydev->supported &= PHY_GBIT_FEATURES; + else + phydev->supported &= PHY_BASIC_FEATURES; + + phydev->advertising = phydev->supported; + + netdev_info(dev, "connected to PHY at %s [uid=%08x, driver=%s]\n", + dev_name(&phydev->dev), phydev->phy_id, phydev->drv->name); + + ag->link = 0; + ag->speed = 0; + ag->duplex = -1; + + return ret; +} + +static int dev_is_class(struct device *dev, void *class) +{ + if (dev->class != NULL && !strcmp(dev->class->name, class)) + return 1; + + return 0; +} + +static struct device *dev_find_class(struct device *parent, char *class) +{ + if (dev_is_class(parent, class)) { + get_device(parent); + return parent; + } + + return device_find_child(parent, class, dev_is_class); +} + +static struct mii_bus *dev_to_mii_bus(struct device *dev) +{ + struct device *d; + + d = dev_find_class(dev, "mdio_bus"); + if (d != NULL) { + struct mii_bus *bus; + + bus = to_mii_bus(d); + put_device(d); + + return bus; + } + + return NULL; +} + +int __devinit ag71xx_phy_connect(struct ag71xx *ag) +{ + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + + if (pdata->mii_bus_dev == NULL || + pdata->mii_bus_dev->bus == NULL ) + return ag71xx_phy_connect_fixed(ag); + + ag->mii_bus = dev_to_mii_bus(pdata->mii_bus_dev); + if (ag->mii_bus == NULL) { + netdev_err(ag->dev, "unable to find MII bus on device '%s'\n", + dev_name(pdata->mii_bus_dev)); + return -ENODEV; + } + + /* Reset the mdio bus explicitly */ + if (ag->mii_bus->reset) { + mutex_lock(&ag->mii_bus->mdio_lock); + ag->mii_bus->reset(ag->mii_bus); + mutex_unlock(&ag->mii_bus->mdio_lock); + } + + if (pdata->switch_data) + return ag71xx_ar7240_init(ag); + + if (pdata->phy_mask) + return ag71xx_phy_connect_multi(ag); + + return ag71xx_phy_connect_fixed(ag); +} + +void ag71xx_phy_disconnect(struct ag71xx *ag) +{ + struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); + + if (pdata->switch_data) + ag71xx_ar7240_cleanup(ag); + else if (ag->phy_dev) + phy_disconnect(ag->phy_dev); +} diff --git a/target/linux/ar71xx/files/drivers/spi/spi-ap83.c b/target/linux/ar71xx/files/drivers/spi/spi-ap83.c new file mode 100644 index 000000000..33843a6da --- /dev/null +++ b/target/linux/ar71xx/files/drivers/spi/spi-ap83.c @@ -0,0 +1,283 @@ +/* + * Atheros AP83 board specific SPI Controller driver + * + * Copyright (C) 2009 Gabor Juhos + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRV_DESC "Atheros AP83 board SPI Controller driver" +#define DRV_VERSION "0.1.0" +#define DRV_NAME "ap83-spi" + +#define AP83_SPI_CLK_HIGH (1 << 23) +#define AP83_SPI_CLK_LOW 0 +#define AP83_SPI_MOSI_HIGH (1 << 22) +#define AP83_SPI_MOSI_LOW 0 + +#define AP83_SPI_GPIO_CS 1 +#define AP83_SPI_GPIO_MISO 3 + +struct ap83_spi { + struct spi_bitbang bitbang; + void __iomem *base; + u32 addr; + + struct platform_device *pdev; +}; + +static inline u32 ap83_spi_rr(struct ap83_spi *sp, u32 reg) +{ + return __raw_readl(sp->base + reg); +} + +static inline struct ap83_spi *spidev_to_sp(struct spi_device *spi) +{ + return spi_master_get_devdata(spi->master); +} + +static inline void setsck(struct spi_device *spi, int val) +{ + struct ap83_spi *sp = spidev_to_sp(spi); + + if (val) + sp->addr |= AP83_SPI_CLK_HIGH; + else + sp->addr &= ~AP83_SPI_CLK_HIGH; + + dev_dbg(&spi->dev, "addr=%08x, SCK set to %s\n", + sp->addr, (val) ? "HIGH" : "LOW"); + + ap83_spi_rr(sp, sp->addr); +} + +static inline void setmosi(struct spi_device *spi, int val) +{ + struct ap83_spi *sp = spidev_to_sp(spi); + + if (val) + sp->addr |= AP83_SPI_MOSI_HIGH; + else + sp->addr &= ~AP83_SPI_MOSI_HIGH; + + dev_dbg(&spi->dev, "addr=%08x, MOSI set to %s\n", + sp->addr, (val) ? "HIGH" : "LOW"); + + ap83_spi_rr(sp, sp->addr); +} + +static inline u32 getmiso(struct spi_device *spi) +{ + u32 ret; + + ret = gpio_get_value(AP83_SPI_GPIO_MISO) ? 1 : 0; + dev_dbg(&spi->dev, "get MISO: %d\n", ret); + + return ret; +} + +static inline void do_spidelay(struct spi_device *spi, unsigned nsecs) +{ + ndelay(nsecs); +} + +static void ap83_spi_chipselect(struct spi_device *spi, int on) +{ + struct ap83_spi *sp = spidev_to_sp(spi); + + dev_dbg(&spi->dev, "set CS to %d\n", (on) ? 0 : 1); + + if (on) { + ath79_flash_acquire(); + + sp->addr = 0; + ap83_spi_rr(sp, sp->addr); + + gpio_set_value(AP83_SPI_GPIO_CS, 0); + } else { + gpio_set_value(AP83_SPI_GPIO_CS, 1); + ath79_flash_release(); + } +} + +#define spidelay(nsecs) \ + do { \ + /* Steal the spi_device pointer from our caller. \ + * The bitbang-API should probably get fixed here... */ \ + do_spidelay(spi, nsecs); \ + } while (0) + +#define EXPAND_BITBANG_TXRX +#include +#include "spi-bitbang-txrx.h" + +static u32 ap83_spi_txrx_mode0(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits) +{ + dev_dbg(&spi->dev, "TXRX0 word=%08x, bits=%u\n", word, bits); + return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); +} + +static u32 ap83_spi_txrx_mode1(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits) +{ + dev_dbg(&spi->dev, "TXRX1 word=%08x, bits=%u\n", word, bits); + return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits); +} + +static u32 ap83_spi_txrx_mode2(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits) +{ + dev_dbg(&spi->dev, "TXRX2 word=%08x, bits=%u\n", word, bits); + return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits); +} + +static u32 ap83_spi_txrx_mode3(struct spi_device *spi, + unsigned nsecs, u32 word, u8 bits) +{ + dev_dbg(&spi->dev, "TXRX3 word=%08x, bits=%u\n", word, bits); + return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits); +} + +static int ap83_spi_probe(struct platform_device *pdev) +{ + struct spi_master *master; + struct ap83_spi *sp; + struct ap83_spi_platform_data *pdata; + struct resource *r; + int ret; + + ret = gpio_request(AP83_SPI_GPIO_MISO, "spi-miso"); + if (ret) { + dev_err(&pdev->dev, "gpio request failed for MISO\n"); + return ret; + } + + ret = gpio_request(AP83_SPI_GPIO_CS, "spi-cs"); + if (ret) { + dev_err(&pdev->dev, "gpio request failed for CS\n"); + goto err_free_miso; + } + + ret = gpio_direction_input(AP83_SPI_GPIO_MISO); + if (ret) { + dev_err(&pdev->dev, "unable to set direction of MISO\n"); + goto err_free_cs; + } + + ret = gpio_direction_output(AP83_SPI_GPIO_CS, 0); + if (ret) { + dev_err(&pdev->dev, "unable to set direction of CS\n"); + goto err_free_cs; + } + + master = spi_alloc_master(&pdev->dev, sizeof(*sp)); + if (master == NULL) { + dev_err(&pdev->dev, "failed to allocate spi master\n"); + return -ENOMEM; + } + + sp = spi_master_get_devdata(master); + platform_set_drvdata(pdev, sp); + + pdata = pdev->dev.platform_data; + + sp->bitbang.master = spi_master_get(master); + sp->bitbang.chipselect = ap83_spi_chipselect; + sp->bitbang.txrx_word[SPI_MODE_0] = ap83_spi_txrx_mode0; + sp->bitbang.txrx_word[SPI_MODE_1] = ap83_spi_txrx_mode1; + sp->bitbang.txrx_word[SPI_MODE_2] = ap83_spi_txrx_mode2; + sp->bitbang.txrx_word[SPI_MODE_3] = ap83_spi_txrx_mode3; + + sp->bitbang.master->bus_num = pdev->id; + sp->bitbang.master->num_chipselect = 1; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (r == NULL) { + ret = -ENOENT; + goto err_spi_put; + } + + sp->base = ioremap_nocache(r->start, r->end - r->start + 1); + if (!sp->base) { + ret = -ENXIO; + goto err_spi_put; + } + + ret = spi_bitbang_start(&sp->bitbang); + if (!ret) + goto err_unmap; + + dev_info(&pdev->dev, "AP83 SPI adapter at %08x\n", r->start); + + return 0; + +err_unmap: + iounmap(sp->base); +err_spi_put: + platform_set_drvdata(pdev, NULL); + spi_master_put(sp->bitbang.master); + +err_free_cs: + gpio_free(AP83_SPI_GPIO_CS); +err_free_miso: + gpio_free(AP83_SPI_GPIO_MISO); + return ret; +} + +static int ap83_spi_remove(struct platform_device *pdev) +{ + struct ap83_spi *sp = platform_get_drvdata(pdev); + + spi_bitbang_stop(&sp->bitbang); + iounmap(sp->base); + platform_set_drvdata(pdev, NULL); + spi_master_put(sp->bitbang.master); + + return 0; +} + +static struct platform_driver ap83_spi_drv = { + .probe = ap83_spi_probe, + .remove = ap83_spi_remove, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init ap83_spi_init(void) +{ + return platform_driver_register(&ap83_spi_drv); +} +module_init(ap83_spi_init); + +static void __exit ap83_spi_exit(void) +{ + platform_driver_unregister(&ap83_spi_drv); +} +module_exit(ap83_spi_exit); + +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DESCRIPTION(DRV_DESC); +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_LICENSE("GPL v2"); diff --git a/target/linux/ar71xx/files/drivers/spi/spi-rb4xx-cpld.c b/target/linux/ar71xx/files/drivers/spi/spi-rb4xx-cpld.c new file mode 100644 index 000000000..4e8ce3105 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/spi/spi-rb4xx-cpld.c @@ -0,0 +1,441 @@ +/* + * SPI driver for the CPLD chip on the Mikrotik RB4xx boards + * + * Copyright (C) 2010 Gabor Juhos + * + * This file was based on the patches for Linux 2.6.27.39 published by + * MikroTik for their RouterBoard 4xx series devices. + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRV_NAME "spi-rb4xx-cpld" +#define DRV_DESC "RB4xx CPLD driver" +#define DRV_VERSION "0.1.0" + +#define CPLD_CMD_WRITE_NAND 0x08 /* send cmd, n x send data, send indle */ +#define CPLD_CMD_WRITE_CFG 0x09 /* send cmd, n x send cfg */ +#define CPLD_CMD_READ_NAND 0x0a /* send cmd, send idle, n x read data */ +#define CPLD_CMD_READ_FAST 0x0b /* send cmd, 4 x idle, n x read data */ +#define CPLD_CMD_LED5_ON 0x0c /* send cmd */ +#define CPLD_CMD_LED5_OFF 0x0d /* send cmd */ + +struct rb4xx_cpld { + struct spi_device *spi; + struct mutex lock; + struct gpio_chip chip; + unsigned int config; +}; + +static struct rb4xx_cpld *rb4xx_cpld; + +static inline struct rb4xx_cpld *gpio_to_cpld(struct gpio_chip *chip) +{ + return container_of(chip, struct rb4xx_cpld, chip); +} + +static int rb4xx_cpld_write_cmd(struct rb4xx_cpld *cpld, unsigned char cmd) +{ + struct spi_transfer t[1]; + struct spi_message m; + unsigned char tx_buf[1]; + int err; + + spi_message_init(&m); + memset(&t, 0, sizeof(t)); + + t[0].tx_buf = tx_buf; + t[0].len = sizeof(tx_buf); + spi_message_add_tail(&t[0], &m); + + tx_buf[0] = cmd; + + err = spi_sync(cpld->spi, &m); + return err; +} + +static int rb4xx_cpld_write_cfg(struct rb4xx_cpld *cpld, unsigned char config) +{ + struct spi_transfer t[1]; + struct spi_message m; + unsigned char cmd[2]; + int err; + + spi_message_init(&m); + memset(&t, 0, sizeof(t)); + + t[0].tx_buf = cmd; + t[0].len = sizeof(cmd); + spi_message_add_tail(&t[0], &m); + + cmd[0] = CPLD_CMD_WRITE_CFG; + cmd[1] = config; + + err = spi_sync(cpld->spi, &m); + return err; +} + +static int __rb4xx_cpld_change_cfg(struct rb4xx_cpld *cpld, unsigned mask, + unsigned value) +{ + unsigned int config; + int err; + + config = cpld->config & ~mask; + config |= value; + + if ((cpld->config ^ config) & 0xff) { + err = rb4xx_cpld_write_cfg(cpld, config); + if (err) + return err; + } + + if ((cpld->config ^ config) & CPLD_CFG_nLED5) { + err = rb4xx_cpld_write_cmd(cpld, (value) ? CPLD_CMD_LED5_ON : + CPLD_CMD_LED5_OFF); + if (err) + return err; + } + + cpld->config = config; + return 0; +} + +int rb4xx_cpld_change_cfg(unsigned mask, unsigned value) +{ + int ret; + + if (rb4xx_cpld == NULL) + return -ENODEV; + + mutex_lock(&rb4xx_cpld->lock); + ret = __rb4xx_cpld_change_cfg(rb4xx_cpld, mask, value); + mutex_unlock(&rb4xx_cpld->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(rb4xx_cpld_change_cfg); + +int rb4xx_cpld_read_from(unsigned addr, unsigned char *rx_buf, + const unsigned char *verify_buf, unsigned count) +{ + const unsigned char cmd[5] = { + CPLD_CMD_READ_FAST, + (addr >> 16) & 0xff, + (addr >> 8) & 0xff, + addr & 0xff, + 0 + }; + struct spi_transfer t[2] = { + { + .tx_buf = &cmd, + .len = 5, + }, + { + .tx_buf = verify_buf, + .rx_buf = rx_buf, + .len = count, + .verify = (verify_buf != NULL), + }, + }; + struct spi_message m; + + if (rb4xx_cpld == NULL) + return -ENODEV; + + spi_message_init(&m); + m.fast_read = 1; + spi_message_add_tail(&t[0], &m); + spi_message_add_tail(&t[1], &m); + return spi_sync(rb4xx_cpld->spi, &m); +} +EXPORT_SYMBOL_GPL(rb4xx_cpld_read_from); + +#if 0 +int rb4xx_cpld_read(unsigned char *buf, unsigned char *verify_buf, + unsigned count) +{ + struct spi_transfer t[2]; + struct spi_message m; + unsigned char cmd[2]; + + if (rb4xx_cpld == NULL) + return -ENODEV; + + spi_message_init(&m); + memset(&t, 0, sizeof(t)); + + /* send command */ + t[0].tx_buf = cmd; + t[0].len = sizeof(cmd); + spi_message_add_tail(&t[0], &m); + + cmd[0] = CPLD_CMD_READ_NAND; + cmd[1] = 0; + + /* read data */ + t[1].rx_buf = buf; + t[1].len = count; + spi_message_add_tail(&t[1], &m); + + return spi_sync(rb4xx_cpld->spi, &m); +} +#else +int rb4xx_cpld_read(unsigned char *rx_buf, const unsigned char *verify_buf, + unsigned count) +{ + static const unsigned char cmd[2] = { CPLD_CMD_READ_NAND, 0 }; + struct spi_transfer t[2] = { + { + .tx_buf = &cmd, + .len = 2, + }, { + .tx_buf = verify_buf, + .rx_buf = rx_buf, + .len = count, + .verify = (verify_buf != NULL), + }, + }; + struct spi_message m; + + if (rb4xx_cpld == NULL) + return -ENODEV; + + spi_message_init(&m); + spi_message_add_tail(&t[0], &m); + spi_message_add_tail(&t[1], &m); + return spi_sync(rb4xx_cpld->spi, &m); +} +#endif +EXPORT_SYMBOL_GPL(rb4xx_cpld_read); + +int rb4xx_cpld_write(const unsigned char *buf, unsigned count) +{ +#if 0 + struct spi_transfer t[3]; + struct spi_message m; + unsigned char cmd[1]; + + if (rb4xx_cpld == NULL) + return -ENODEV; + + memset(&t, 0, sizeof(t)); + spi_message_init(&m); + + /* send command */ + t[0].tx_buf = cmd; + t[0].len = sizeof(cmd); + spi_message_add_tail(&t[0], &m); + + cmd[0] = CPLD_CMD_WRITE_NAND; + + /* write data */ + t[1].tx_buf = buf; + t[1].len = count; + spi_message_add_tail(&t[1], &m); + + /* send idle */ + t[2].len = 1; + spi_message_add_tail(&t[2], &m); + + return spi_sync(rb4xx_cpld->spi, &m); +#else + static const unsigned char cmd = CPLD_CMD_WRITE_NAND; + struct spi_transfer t[3] = { + { + .tx_buf = &cmd, + .len = 1, + }, { + .tx_buf = buf, + .len = count, + .fast_write = 1, + }, { + .len = 1, + .fast_write = 1, + }, + }; + struct spi_message m; + + if (rb4xx_cpld == NULL) + return -ENODEV; + + spi_message_init(&m); + spi_message_add_tail(&t[0], &m); + spi_message_add_tail(&t[1], &m); + spi_message_add_tail(&t[2], &m); + return spi_sync(rb4xx_cpld->spi, &m); +#endif +} +EXPORT_SYMBOL_GPL(rb4xx_cpld_write); + +static int rb4xx_cpld_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct rb4xx_cpld *cpld = gpio_to_cpld(chip); + int ret; + + mutex_lock(&cpld->lock); + ret = (cpld->config >> offset) & 1; + mutex_unlock(&cpld->lock); + + return ret; +} + +static void rb4xx_cpld_gpio_set(struct gpio_chip *chip, unsigned offset, + int value) +{ + struct rb4xx_cpld *cpld = gpio_to_cpld(chip); + + mutex_lock(&cpld->lock); + __rb4xx_cpld_change_cfg(cpld, (1 << offset), !!value << offset); + mutex_unlock(&cpld->lock); +} + +static int rb4xx_cpld_gpio_direction_input(struct gpio_chip *chip, + unsigned offset) +{ + return -EOPNOTSUPP; +} + +static int rb4xx_cpld_gpio_direction_output(struct gpio_chip *chip, + unsigned offset, + int value) +{ + struct rb4xx_cpld *cpld = gpio_to_cpld(chip); + int ret; + + mutex_lock(&cpld->lock); + ret = __rb4xx_cpld_change_cfg(cpld, (1 << offset), !!value << offset); + mutex_unlock(&cpld->lock); + + return ret; +} + +static int rb4xx_cpld_gpio_init(struct rb4xx_cpld *cpld, unsigned int base) +{ + int err; + + /* init config */ + cpld->config = CPLD_CFG_nLED1 | CPLD_CFG_nLED2 | CPLD_CFG_nLED3 | + CPLD_CFG_nLED4 | CPLD_CFG_nCE; + rb4xx_cpld_write_cfg(cpld, cpld->config); + + /* setup GPIO chip */ + cpld->chip.label = DRV_NAME; + + cpld->chip.get = rb4xx_cpld_gpio_get; + cpld->chip.set = rb4xx_cpld_gpio_set; + cpld->chip.direction_input = rb4xx_cpld_gpio_direction_input; + cpld->chip.direction_output = rb4xx_cpld_gpio_direction_output; + + cpld->chip.base = base; + cpld->chip.ngpio = CPLD_NUM_GPIOS; + cpld->chip.can_sleep = 1; + cpld->chip.dev = &cpld->spi->dev; + cpld->chip.owner = THIS_MODULE; + + err = gpiochip_add(&cpld->chip); + if (err) + dev_err(&cpld->spi->dev, "adding GPIO chip failed, err=%d\n", + err); + + return err; +} + +static int __devinit rb4xx_cpld_probe(struct spi_device *spi) +{ + struct rb4xx_cpld *cpld; + struct rb4xx_cpld_platform_data *pdata; + int err; + + pdata = spi->dev.platform_data; + if (!pdata) { + dev_dbg(&spi->dev, "no platform data\n"); + return -EINVAL; + } + + cpld = kzalloc(sizeof(*cpld), GFP_KERNEL); + if (!cpld) { + dev_err(&spi->dev, "no memory for private data\n"); + return -ENOMEM; + } + + mutex_init(&cpld->lock); + cpld->spi = spi_dev_get(spi); + dev_set_drvdata(&spi->dev, cpld); + + spi->mode = SPI_MODE_0; + spi->bits_per_word = 8; + err = spi_setup(spi); + if (err) { + dev_err(&spi->dev, "spi_setup failed, err=%d\n", err); + goto err_drvdata; + } + + err = rb4xx_cpld_gpio_init(cpld, pdata->gpio_base); + if (err) + goto err_drvdata; + + rb4xx_cpld = cpld; + + return 0; + +err_drvdata: + dev_set_drvdata(&spi->dev, NULL); + kfree(cpld); + + return err; +} + +static int __devexit rb4xx_cpld_remove(struct spi_device *spi) +{ + struct rb4xx_cpld *cpld; + + rb4xx_cpld = NULL; + cpld = dev_get_drvdata(&spi->dev); + dev_set_drvdata(&spi->dev, NULL); + kfree(cpld); + + return 0; +} + +static struct spi_driver rb4xx_cpld_driver = { + .driver = { + .name = DRV_NAME, + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = rb4xx_cpld_probe, + .remove = __devexit_p(rb4xx_cpld_remove), +}; + +static int __init rb4xx_cpld_init(void) +{ + return spi_register_driver(&rb4xx_cpld_driver); +} +module_init(rb4xx_cpld_init); + +static void __exit rb4xx_cpld_exit(void) +{ + spi_unregister_driver(&rb4xx_cpld_driver); +} +module_exit(rb4xx_cpld_exit); + +MODULE_DESCRIPTION(DRV_DESC); +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_LICENSE("GPL v2"); diff --git a/target/linux/ar71xx/files/drivers/spi/spi-rb4xx.c b/target/linux/ar71xx/files/drivers/spi/spi-rb4xx.c new file mode 100644 index 000000000..56260ffc9 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/spi/spi-rb4xx.c @@ -0,0 +1,507 @@ +/* + * SPI controller driver for the Mikrotik RB4xx boards + * + * Copyright (C) 2010 Gabor Juhos + * + * This file was based on the patches for Linux 2.6.27.39 published by + * MikroTik for their RouterBoard 4xx series devices. + * + * This program 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DRV_NAME "rb4xx-spi" +#define DRV_DESC "Mikrotik RB4xx SPI controller driver" +#define DRV_VERSION "0.1.0" + +#define SPI_CTRL_FASTEST 0x40 +#define SPI_FLASH_HZ 33333334 +#define SPI_CPLD_HZ 33333334 + +#define CPLD_CMD_READ_FAST 0x0b + +#undef RB4XX_SPI_DEBUG + +struct rb4xx_spi { + void __iomem *base; + struct spi_master *master; + + unsigned spi_ctrl_flash; + unsigned spi_ctrl_fread; + + struct clk *ahb_clk; + unsigned long ahb_freq; + + spinlock_t lock; + struct list_head queue; + int busy:1; + int cs_wait; +}; + +static unsigned spi_clk_low = AR71XX_SPI_IOC_CS1; + +#ifdef RB4XX_SPI_DEBUG +static inline void do_spi_delay(void) +{ + ndelay(20000); +} +#else +static inline void do_spi_delay(void) { } +#endif + +static inline void do_spi_init(struct spi_device *spi) +{ + unsigned cs = AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1; + + if (!(spi->mode & SPI_CS_HIGH)) + cs ^= (spi->chip_select == 2) ? AR71XX_SPI_IOC_CS1 : + AR71XX_SPI_IOC_CS0; + + spi_clk_low = cs; +} + +static inline void do_spi_finish(void __iomem *base) +{ + do_spi_delay(); + __raw_writel(AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1, + base + AR71XX_SPI_REG_IOC); +} + +static inline void do_spi_clk(void __iomem *base, int bit) +{ + unsigned bval = spi_clk_low | ((bit & 1) ? AR71XX_SPI_IOC_DO : 0); + + do_spi_delay(); + __raw_writel(bval, base + AR71XX_SPI_REG_IOC); + do_spi_delay(); + __raw_writel(bval | AR71XX_SPI_IOC_CLK, base + AR71XX_SPI_REG_IOC); +} + +static void do_spi_byte(void __iomem *base, unsigned char byte) +{ + do_spi_clk(base, byte >> 7); + do_spi_clk(base, byte >> 6); + do_spi_clk(base, byte >> 5); + do_spi_clk(base, byte >> 4); + do_spi_clk(base, byte >> 3); + do_spi_clk(base, byte >> 2); + do_spi_clk(base, byte >> 1); + do_spi_clk(base, byte); + + pr_debug("spi_byte sent 0x%02x got 0x%02x\n", + (unsigned)byte, + (unsigned char)__raw_readl(base + AR71XX_SPI_REG_RDS)); +} + +static inline void do_spi_clk_fast(void __iomem *base, unsigned bit1, + unsigned bit2) +{ + unsigned bval = (spi_clk_low | + ((bit1 & 1) ? AR71XX_SPI_IOC_DO : 0) | + ((bit2 & 1) ? AR71XX_SPI_IOC_CS2 : 0)); + do_spi_delay(); + __raw_writel(bval, base + AR71XX_SPI_REG_IOC); + do_spi_delay(); + __raw_writel(bval | AR71XX_SPI_IOC_CLK, base + AR71XX_SPI_REG_IOC); +} + +static void do_spi_byte_fast(void __iomem *base, unsigned char byte) +{ + do_spi_clk_fast(base, byte >> 7, byte >> 6); + do_spi_clk_fast(base, byte >> 5, byte >> 4); + do_spi_clk_fast(base, byte >> 3, byte >> 2); + do_spi_clk_fast(base, byte >> 1, byte >> 0); + + pr_debug("spi_byte_fast sent 0x%02x got 0x%02x\n", + (unsigned)byte, + (unsigned char) __raw_readl(base + AR71XX_SPI_REG_RDS)); +} + +static int rb4xx_spi_txrx(void __iomem *base, struct spi_transfer *t) +{ + const unsigned char *rxv_ptr = NULL; + const unsigned char *tx_ptr = t->tx_buf; + unsigned char *rx_ptr = t->rx_buf; + unsigned i; + + pr_debug("spi_txrx len %u tx %u rx %u\n", + t->len, + (t->tx_buf ? 1 : 0), + (t->rx_buf ? 1 : 0)); + + if (t->verify) { + rxv_ptr = tx_ptr; + tx_ptr = NULL; + } + + for (i = 0; i < t->len; ++i) { + unsigned char sdata = tx_ptr ? tx_ptr[i] : 0; + + if (t->fast_write) + do_spi_byte_fast(base, sdata); + else + do_spi_byte(base, sdata); + + if (rx_ptr) { + rx_ptr[i] = __raw_readl(base + AR71XX_SPI_REG_RDS) & 0xff; + } else if (rxv_ptr) { + unsigned char c = __raw_readl(base + AR71XX_SPI_REG_RDS); + if (rxv_ptr[i] != c) + return i; + } + } + + return i; +} + +static int rb4xx_spi_read_fast(struct rb4xx_spi *rbspi, + struct spi_message *m) +{ + struct spi_transfer *t; + const unsigned char *tx_ptr; + unsigned addr; + void __iomem *base = rbspi->base; + + /* check for exactly two transfers */ + if (list_empty(&m->transfers) || + list_is_last(m->transfers.next, &m->transfers) || + !list_is_last(m->transfers.next->next, &m->transfers)) { + return -1; + } + + /* first transfer contains command and address */ + t = list_entry(m->transfers.next, + struct spi_transfer, transfer_list); + + if (t->len != 5 || t->tx_buf == NULL) + return -1; + + tx_ptr = t->tx_buf; + if (tx_ptr[0] != CPLD_CMD_READ_FAST) + return -1; + + addr = tx_ptr[1]; + addr = tx_ptr[2] | (addr << 8); + addr = tx_ptr[3] | (addr << 8); + addr += (unsigned) base; + + m->actual_length += t->len; + + /* second transfer contains data itself */ + t = list_entry(m->transfers.next->next, + struct spi_transfer, transfer_list); + + if (t->tx_buf && !t->verify) + return -1; + + __raw_writel(AR71XX_SPI_FS_GPIO, base + AR71XX_SPI_REG_FS); + __raw_writel(rbspi->spi_ctrl_fread, base + AR71XX_SPI_REG_CTRL); + __raw_writel(0, base + AR71XX_SPI_REG_FS); + + if (t->rx_buf) { + memcpy(t->rx_buf, (const void *)addr, t->len); + } else if (t->tx_buf) { + unsigned char buf[t->len]; + memcpy(buf, (const void *)addr, t->len); + if (memcmp(t->tx_buf, buf, t->len) != 0) + m->status = -EMSGSIZE; + } + m->actual_length += t->len; + + if (rbspi->spi_ctrl_flash != rbspi->spi_ctrl_fread) { + __raw_writel(AR71XX_SPI_FS_GPIO, base + AR71XX_SPI_REG_FS); + __raw_writel(rbspi->spi_ctrl_flash, base + AR71XX_SPI_REG_CTRL); + __raw_writel(0, base + AR71XX_SPI_REG_FS); + } + + return 0; +} + +static int rb4xx_spi_msg(struct rb4xx_spi *rbspi, struct spi_message *m) +{ + struct spi_transfer *t = NULL; + void __iomem *base = rbspi->base; + + m->status = 0; + if (list_empty(&m->transfers)) + return -1; + + if (m->fast_read) + if (rb4xx_spi_read_fast(rbspi, m) == 0) + return -1; + + __raw_writel(AR71XX_SPI_FS_GPIO, base + AR71XX_SPI_REG_FS); + __raw_writel(SPI_CTRL_FASTEST, base + AR71XX_SPI_REG_CTRL); + do_spi_init(m->spi); + + list_for_each_entry(t, &m->transfers, transfer_list) { + int len; + + len = rb4xx_spi_txrx(base, t); + if (len != t->len) { + m->status = -EMSGSIZE; + break; + } + m->actual_length += len; + + if (t->cs_change) { + if (list_is_last(&t->transfer_list, &m->transfers)) { + /* wait for continuation */ + return m->spi->chip_select; + } + do_spi_finish(base); + ndelay(100); + } + } + + do_spi_finish(base); + __raw_writel(rbspi->spi_ctrl_flash, base + AR71XX_SPI_REG_CTRL); + __raw_writel(0, base + AR71XX_SPI_REG_FS); + return -1; +} + +static void rb4xx_spi_process_queue_locked(struct rb4xx_spi *rbspi, + unsigned long *flags) +{ + int cs = rbspi->cs_wait; + + rbspi->busy = 1; + while (!list_empty(&rbspi->queue)) { + struct spi_message *m; + + list_for_each_entry(m, &rbspi->queue, queue) + if (cs < 0 || cs == m->spi->chip_select) + break; + + if (&m->queue == &rbspi->queue) + break; + + list_del_init(&m->queue); + spin_unlock_irqrestore(&rbspi->lock, *flags); + + cs = rb4xx_spi_msg(rbspi, m); + m->complete(m->context); + + spin_lock_irqsave(&rbspi->lock, *flags); + } + + rbspi->cs_wait = cs; + rbspi->busy = 0; + + if (cs >= 0) { + /* TODO: add timer to unlock cs after 1s inactivity */ + } +} + +static int rb4xx_spi_transfer(struct spi_device *spi, + struct spi_message *m) +{ + struct rb4xx_spi *rbspi = spi_master_get_devdata(spi->master); + unsigned long flags; + + m->actual_length = 0; + m->status = -EINPROGRESS; + + spin_lock_irqsave(&rbspi->lock, flags); + list_add_tail(&m->queue, &rbspi->queue); + if (rbspi->busy || + (rbspi->cs_wait >= 0 && rbspi->cs_wait != m->spi->chip_select)) { + /* job will be done later */ + spin_unlock_irqrestore(&rbspi->lock, flags); + return 0; + } + + /* process job in current context */ + rb4xx_spi_process_queue_locked(rbspi, &flags); + spin_unlock_irqrestore(&rbspi->lock, flags); + + return 0; +} + +static int rb4xx_spi_setup(struct spi_device *spi) +{ + struct rb4xx_spi *rbspi = spi_master_get_devdata(spi->master); + unsigned long flags; + + if (spi->mode & ~(SPI_CS_HIGH)) { + dev_err(&spi->dev, "mode %x not supported\n", + (unsigned) spi->mode); + return -EINVAL; + } + + if (spi->bits_per_word != 8 && spi->bits_per_word != 0) { + dev_err(&spi->dev, "bits_per_word %u not supported\n", + (unsigned) spi->bits_per_word); + return -EINVAL; + } + + spin_lock_irqsave(&rbspi->lock, flags); + if (rbspi->cs_wait == spi->chip_select && !rbspi->busy) { + rbspi->cs_wait = -1; + rb4xx_spi_process_queue_locked(rbspi, &flags); + } + spin_unlock_irqrestore(&rbspi->lock, flags); + + return 0; +} + +static unsigned get_spi_ctrl(struct rb4xx_spi *rbspi, unsigned hz_max, + const char *name) +{ + unsigned div; + + div = (rbspi->ahb_freq - 1) / (2 * hz_max); + + /* + * CPU has a bug at (div == 0) - first bit read is random + */ + if (div == 0) + ++div; + + if (name) { + unsigned ahb_khz = (rbspi->ahb_freq + 500) / 1000; + unsigned div_real = 2 * (div + 1); + pr_debug("rb4xx: %s SPI clock %u kHz (AHB %u kHz / %u)\n", + name, + ahb_khz / div_real, + ahb_khz, div_real); + } + + return SPI_CTRL_FASTEST + div; +} + +static int rb4xx_spi_probe(struct platform_device *pdev) +{ + struct spi_master *master; + struct rb4xx_spi *rbspi; + struct resource *r; + int err = 0; + + master = spi_alloc_master(&pdev->dev, sizeof(*rbspi)); + if (master == NULL) { + dev_err(&pdev->dev, "no memory for spi_master\n"); + err = -ENOMEM; + goto err_out; + } + + master->bus_num = 0; + master->num_chipselect = 3; + master->setup = rb4xx_spi_setup; + master->transfer = rb4xx_spi_transfer; + + rbspi = spi_master_get_devdata(master); + + rbspi->ahb_clk = clk_get(&pdev->dev, "ahb"); + if (IS_ERR(rbspi->ahb_clk)) { + err = PTR_ERR(rbspi->ahb_clk); + goto err_put_master; + } + + err = clk_enable(rbspi->ahb_clk); + if (err) + goto err_clk_put; + + rbspi->ahb_freq = clk_get_rate(rbspi->ahb_clk); + if (!rbspi->ahb_freq) { + err = -EINVAL; + goto err_clk_disable; + } + + platform_set_drvdata(pdev, rbspi); + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (r == NULL) { + err = -ENOENT; + goto err_clk_disable; + } + + rbspi->base = ioremap(r->start, r->end - r->start + 1); + if (!rbspi->base) { + err = -ENXIO; + goto err_clk_disable; + } + + rbspi->master = master; + rbspi->spi_ctrl_flash = get_spi_ctrl(rbspi, SPI_FLASH_HZ, "FLASH"); + rbspi->spi_ctrl_fread = get_spi_ctrl(rbspi, SPI_CPLD_HZ, "CPLD"); + rbspi->cs_wait = -1; + + spin_lock_init(&rbspi->lock); + INIT_LIST_HEAD(&rbspi->queue); + + err = spi_register_master(master); + if (err) { + dev_err(&pdev->dev, "failed to register SPI master\n"); + goto err_iounmap; + } + + return 0; + +err_iounmap: + iounmap(rbspi->base); +err_clk_disable: + clk_disable(rbspi->ahb_clk); +err_clk_put: + clk_put(rbspi->ahb_clk); +err_put_master: + platform_set_drvdata(pdev, NULL); + spi_master_put(master); +err_out: + return err; +} + +static int rb4xx_spi_remove(struct platform_device *pdev) +{ + struct rb4xx_spi *rbspi = platform_get_drvdata(pdev); + + iounmap(rbspi->base); + clk_disable(rbspi->ahb_clk); + clk_put(rbspi->ahb_clk); + platform_set_drvdata(pdev, NULL); + spi_master_put(rbspi->master); + + return 0; +} + +static struct platform_driver rb4xx_spi_drv = { + .probe = rb4xx_spi_probe, + .remove = rb4xx_spi_remove, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init rb4xx_spi_init(void) +{ + return platform_driver_register(&rb4xx_spi_drv); +} +subsys_initcall(rb4xx_spi_init); + +static void __exit rb4xx_spi_exit(void) +{ + platform_driver_unregister(&rb4xx_spi_drv); +} + +module_exit(rb4xx_spi_exit); + +MODULE_DESCRIPTION(DRV_DESC); +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_LICENSE("GPL v2"); diff --git a/target/linux/ar71xx/files/drivers/spi/spi-vsc7385.c b/target/linux/ar71xx/files/drivers/spi/spi-vsc7385.c new file mode 100644 index 000000000..9340df268 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/spi/spi-vsc7385.c @@ -0,0 +1,621 @@ +/* + * SPI driver for the Vitesse VSC7385 ethernet switch + * + * Copyright (C) 2009 Gabor Juhos + * + * Parts of this file are based on Atheros' 2.6.15 BSP + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "spi-vsc7385" +#define DRV_DESC "Vitesse VSC7385 Gbit ethernet switch driver" +#define DRV_VERSION "0.1.0" + +#define VSC73XX_BLOCK_MAC 0x1 +#define VSC73XX_BLOCK_2 0x2 +#define VSC73XX_BLOCK_MII 0x3 +#define VSC73XX_BLOCK_4 0x4 +#define VSC73XX_BLOCK_5 0x5 +#define VSC73XX_BLOCK_SYSTEM 0x7 + +#define VSC73XX_SUBBLOCK_PORT_0 0 +#define VSC73XX_SUBBLOCK_PORT_1 1 +#define VSC73XX_SUBBLOCK_PORT_2 2 +#define VSC73XX_SUBBLOCK_PORT_3 3 +#define VSC73XX_SUBBLOCK_PORT_4 4 +#define VSC73XX_SUBBLOCK_PORT_MAC 6 + +/* MAC Block registers */ +#define VSC73XX_MAC_CFG 0x0 +#define VSC73XX_ADVPORTM 0x19 +#define VSC73XX_RXOCT 0x50 +#define VSC73XX_TXOCT 0x51 +#define VSC73XX_C_RX0 0x52 +#define VSC73XX_C_RX1 0x53 +#define VSC73XX_C_RX2 0x54 +#define VSC73XX_C_TX0 0x55 +#define VSC73XX_C_TX1 0x56 +#define VSC73XX_C_TX2 0x57 +#define VSC73XX_C_CFG 0x58 + +/* MAC_CFG register bits */ +#define VSC73XX_MAC_CFG_WEXC_DIS (1 << 31) +#define VSC73XX_MAC_CFG_PORT_RST (1 << 29) +#define VSC73XX_MAC_CFG_TX_EN (1 << 28) +#define VSC73XX_MAC_CFG_SEED_LOAD (1 << 27) +#define VSC73XX_MAC_CFG_FDX (1 << 18) +#define VSC73XX_MAC_CFG_GIGE (1 << 17) +#define VSC73XX_MAC_CFG_RX_EN (1 << 16) +#define VSC73XX_MAC_CFG_VLAN_DBLAWR (1 << 15) +#define VSC73XX_MAC_CFG_VLAN_AWR (1 << 14) +#define VSC73XX_MAC_CFG_100_BASE_T (1 << 13) +#define VSC73XX_MAC_CFG_TX_IPG(x) (((x) & 0x1f) << 6) +#define VSC73XX_MAC_CFG_MAC_RX_RST (1 << 5) +#define VSC73XX_MAC_CFG_MAC_TX_RST (1 << 4) +#define VSC73XX_MAC_CFG_BIT2 (1 << 2) +#define VSC73XX_MAC_CFG_CLK_SEL(x) ((x) & 0x3) + +/* ADVPORTM register bits */ +#define VSC73XX_ADVPORTM_IFG_PPM (1 << 7) +#define VSC73XX_ADVPORTM_EXC_COL_CONT (1 << 6) +#define VSC73XX_ADVPORTM_EXT_PORT (1 << 5) +#define VSC73XX_ADVPORTM_INV_GTX (1 << 4) +#define VSC73XX_ADVPORTM_ENA_GTX (1 << 3) +#define VSC73XX_ADVPORTM_DDR_MODE (1 << 2) +#define VSC73XX_ADVPORTM_IO_LOOPBACK (1 << 1) +#define VSC73XX_ADVPORTM_HOST_LOOPBACK (1 << 0) + +/* MII Block registers */ +#define VSC73XX_MII_STAT 0x0 +#define VSC73XX_MII_CMD 0x1 +#define VSC73XX_MII_DATA 0x2 + +/* System Block registers */ +#define VSC73XX_ICPU_SIPAD 0x01 +#define VSC73XX_ICPU_CLOCK_DELAY 0x05 +#define VSC73XX_ICPU_CTRL 0x10 +#define VSC73XX_ICPU_ADDR 0x11 +#define VSC73XX_ICPU_SRAM 0x12 +#define VSC73XX_ICPU_MBOX_VAL 0x15 +#define VSC73XX_ICPU_MBOX_SET 0x16 +#define VSC73XX_ICPU_MBOX_CLR 0x17 +#define VSC73XX_ICPU_CHIPID 0x18 +#define VSC73XX_ICPU_GPIO 0x34 + +#define VSC73XX_ICPU_CTRL_CLK_DIV (1 << 8) +#define VSC73XX_ICPU_CTRL_SRST_HOLD (1 << 7) +#define VSC73XX_ICPU_CTRL_BOOT_EN (1 << 3) +#define VSC73XX_ICPU_CTRL_EXT_ACC_EN (1 << 2) +#define VSC73XX_ICPU_CTRL_CLK_EN (1 << 1) +#define VSC73XX_ICPU_CTRL_SRST (1 << 0) + +#define VSC73XX_ICPU_CHIPID_ID_SHIFT 12 +#define VSC73XX_ICPU_CHIPID_ID_MASK 0xffff +#define VSC73XX_ICPU_CHIPID_REV_SHIFT 28 +#define VSC73XX_ICPU_CHIPID_REV_MASK 0xf +#define VSC73XX_ICPU_CHIPID_ID_7385 0x7385 +#define VSC73XX_ICPU_CHIPID_ID_7395 0x7395 + +#define VSC73XX_CMD_MODE_READ 0 +#define VSC73XX_CMD_MODE_WRITE 1 +#define VSC73XX_CMD_MODE_SHIFT 4 +#define VSC73XX_CMD_BLOCK_SHIFT 5 +#define VSC73XX_CMD_BLOCK_MASK 0x7 +#define VSC73XX_CMD_SUBBLOCK_MASK 0xf + +#define VSC7385_CLOCK_DELAY ((3 << 4) | 3) +#define VSC7385_CLOCK_DELAY_MASK ((3 << 4) | 3) + +#define VSC73XX_ICPU_CTRL_STOP (VSC73XX_ICPU_CTRL_SRST_HOLD | \ + VSC73XX_ICPU_CTRL_BOOT_EN | \ + VSC73XX_ICPU_CTRL_EXT_ACC_EN) + +#define VSC73XX_ICPU_CTRL_START (VSC73XX_ICPU_CTRL_CLK_DIV | \ + VSC73XX_ICPU_CTRL_BOOT_EN | \ + VSC73XX_ICPU_CTRL_CLK_EN | \ + VSC73XX_ICPU_CTRL_SRST) + +#define VSC7385_ADVPORTM_MASK (VSC73XX_ADVPORTM_IFG_PPM | \ + VSC73XX_ADVPORTM_EXC_COL_CONT | \ + VSC73XX_ADVPORTM_EXT_PORT | \ + VSC73XX_ADVPORTM_INV_GTX | \ + VSC73XX_ADVPORTM_ENA_GTX | \ + VSC73XX_ADVPORTM_DDR_MODE | \ + VSC73XX_ADVPORTM_IO_LOOPBACK | \ + VSC73XX_ADVPORTM_HOST_LOOPBACK) + +#define VSC7385_ADVPORTM_INIT (VSC73XX_ADVPORTM_EXT_PORT | \ + VSC73XX_ADVPORTM_ENA_GTX | \ + VSC73XX_ADVPORTM_DDR_MODE) + +#define VSC7385_MAC_CFG_RESET (VSC73XX_MAC_CFG_PORT_RST | \ + VSC73XX_MAC_CFG_MAC_RX_RST | \ + VSC73XX_MAC_CFG_MAC_TX_RST) + +#define VSC73XX_MAC_CFG_INIT (VSC73XX_MAC_CFG_TX_EN | \ + VSC73XX_MAC_CFG_FDX | \ + VSC73XX_MAC_CFG_GIGE | \ + VSC73XX_MAC_CFG_RX_EN) + +#define VSC73XX_RESET_DELAY 100 + +struct vsc7385 { + struct spi_device *spi; + struct mutex lock; + struct vsc7385_platform_data *pdata; +}; + +static int vsc7385_is_addr_valid(u8 block, u8 subblock) +{ + switch (block) { + case VSC73XX_BLOCK_MAC: + switch (subblock) { + case 0 ... 4: + case 6: + return 1; + } + break; + + case VSC73XX_BLOCK_2: + case VSC73XX_BLOCK_SYSTEM: + switch (subblock) { + case 0: + return 1; + } + break; + + case VSC73XX_BLOCK_MII: + case VSC73XX_BLOCK_4: + case VSC73XX_BLOCK_5: + switch (subblock) { + case 0 ... 1: + return 1; + } + break; + } + + return 0; +} + +static inline u8 vsc7385_make_addr(u8 mode, u8 block, u8 subblock) +{ + u8 ret; + + ret = (block & VSC73XX_CMD_BLOCK_MASK) << VSC73XX_CMD_BLOCK_SHIFT; + ret |= (mode & 1) << VSC73XX_CMD_MODE_SHIFT; + ret |= subblock & VSC73XX_CMD_SUBBLOCK_MASK; + + return ret; +} + +static int vsc7385_read(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg, + u32 *value) +{ + u8 cmd[4]; + u8 buf[4]; + struct spi_transfer t[2]; + struct spi_message m; + int err; + + if (!vsc7385_is_addr_valid(block, subblock)) + return -EINVAL; + + spi_message_init(&m); + + memset(&t, 0, sizeof(t)); + + t[0].tx_buf = cmd; + t[0].len = sizeof(cmd); + spi_message_add_tail(&t[0], &m); + + t[1].rx_buf = buf; + t[1].len = sizeof(buf); + spi_message_add_tail(&t[1], &m); + + cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_READ, block, subblock); + cmd[1] = reg; + cmd[2] = 0; + cmd[3] = 0; + + mutex_lock(&vsc->lock); + err = spi_sync(vsc->spi, &m); + mutex_unlock(&vsc->lock); + + if (err) + return err; + + *value = (((u32) buf[0]) << 24) | (((u32) buf[1]) << 16) | + (((u32) buf[2]) << 8) | ((u32) buf[3]); + + return 0; +} + + +static int vsc7385_write(struct vsc7385 *vsc, u8 block, u8 subblock, u8 reg, + u32 value) +{ + u8 cmd[2]; + u8 buf[4]; + struct spi_transfer t[2]; + struct spi_message m; + int err; + + if (!vsc7385_is_addr_valid(block, subblock)) + return -EINVAL; + + spi_message_init(&m); + + memset(&t, 0, sizeof(t)); + + t[0].tx_buf = cmd; + t[0].len = sizeof(cmd); + spi_message_add_tail(&t[0], &m); + + t[1].tx_buf = buf; + t[1].len = sizeof(buf); + spi_message_add_tail(&t[1], &m); + + cmd[0] = vsc7385_make_addr(VSC73XX_CMD_MODE_WRITE, block, subblock); + cmd[1] = reg; + + buf[0] = (value >> 24) & 0xff; + buf[1] = (value >> 16) & 0xff; + buf[2] = (value >> 8) & 0xff; + buf[3] = value & 0xff; + + mutex_lock(&vsc->lock); + err = spi_sync(vsc->spi, &m); + mutex_unlock(&vsc->lock); + + return err; +} + +static inline int vsc7385_write_verify(struct vsc7385 *vsc, u8 block, + u8 subblock, u8 reg, u32 value, + u32 read_mask, u32 read_val) +{ + struct spi_device *spi = vsc->spi; + u32 t; + int err; + + err = vsc7385_write(vsc, block, subblock, reg, value); + if (err) + return err; + + err = vsc7385_read(vsc, block, subblock, reg, &t); + if (err) + return err; + + if ((t & read_mask) != read_val) { + dev_err(&spi->dev, "register write error\n"); + return -EIO; + } + + return 0; +} + +static inline int vsc7385_set_clock_delay(struct vsc7385 *vsc, u32 val) +{ + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, + VSC73XX_ICPU_CLOCK_DELAY, val); +} + +static inline int vsc7385_get_clock_delay(struct vsc7385 *vsc, u32 *val) +{ + return vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, + VSC73XX_ICPU_CLOCK_DELAY, val); +} + +static inline int vsc7385_icpu_stop(struct vsc7385 *vsc) +{ + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL, + VSC73XX_ICPU_CTRL_STOP); +} + +static inline int vsc7385_icpu_start(struct vsc7385 *vsc) +{ + return vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_CTRL, + VSC73XX_ICPU_CTRL_START); +} + +static inline int vsc7385_icpu_reset(struct vsc7385 *vsc) +{ + int rc; + + rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_ICPU_ADDR, + 0x0000); + if (rc) + dev_err(&vsc->spi->dev, + "could not reset microcode, err=%d\n", rc); + + return rc; +} + +static int vsc7385_upload_ucode(struct vsc7385 *vsc) +{ + struct spi_device *spi = vsc->spi; + const struct firmware *firmware; + char *ucode_name; + unsigned char *dp; + unsigned int curVal; + int i; + int diffs; + int rc; + + ucode_name = (vsc->pdata->ucode_name) ? vsc->pdata->ucode_name + : "vsc7385_ucode.bin"; + rc = request_firmware(&firmware, ucode_name, &spi->dev); + if (rc) { + dev_err(&spi->dev, "request_firmware failed, err=%d\n", + rc); + return rc; + } + + rc = vsc7385_icpu_stop(vsc); + if (rc) + goto out; + + rc = vsc7385_icpu_reset(vsc); + if (rc) + goto out; + + dev_info(&spi->dev, "uploading microcode...\n"); + + dp = (unsigned char *) firmware->data; + for (i = 0; i < firmware->size; i++) { + rc = vsc7385_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, + VSC73XX_ICPU_SRAM, *dp++); + if (rc) { + dev_err(&spi->dev, "could not load microcode, err=%d\n", + rc); + goto out; + } + } + + rc = vsc7385_icpu_reset(vsc); + if (rc) + goto out; + + dev_info(&spi->dev, "verifying microcode...\n"); + + dp = (unsigned char *) firmware->data; + diffs = 0; + for (i = 0; i < firmware->size; i++) { + rc = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, + VSC73XX_ICPU_SRAM, &curVal); + if (rc) { + dev_err(&spi->dev, "could not read microcode %d\n", + rc); + goto out; + } + + if (curVal > 0xff) { + dev_err(&spi->dev, "bad val read: %04x : %02x %02x\n", + i, *dp, curVal); + rc = -EIO; + goto out; + } + + if ((curVal & 0xff) != *dp) { + diffs++; + dev_err(&spi->dev, "verify error: %04x : %02x %02x\n", + i, *dp, curVal); + + if (diffs > 4) + break; + } + dp++; + } + + if (diffs) { + dev_err(&spi->dev, "microcode verification failed\n"); + rc = -EIO; + goto out; + } + + dev_info(&spi->dev, "microcode uploaded\n"); + + rc = vsc7385_icpu_start(vsc); + +out: + release_firmware(firmware); + return rc; +} + +static int vsc7385_setup(struct vsc7385 *vsc) +{ + struct vsc7385_platform_data *pdata = vsc->pdata; + u32 t; + int err; + + err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_SYSTEM, 0, + VSC73XX_ICPU_CLOCK_DELAY, + VSC7385_CLOCK_DELAY, + VSC7385_CLOCK_DELAY_MASK, + VSC7385_CLOCK_DELAY); + if (err) + goto err; + + err = vsc7385_write_verify(vsc, VSC73XX_BLOCK_MAC, + VSC73XX_SUBBLOCK_PORT_MAC, VSC73XX_ADVPORTM, + VSC7385_ADVPORTM_INIT, + VSC7385_ADVPORTM_MASK, + VSC7385_ADVPORTM_INIT); + if (err) + goto err; + + err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC, + VSC73XX_MAC_CFG, VSC7385_MAC_CFG_RESET); + if (err) + goto err; + + t = VSC73XX_MAC_CFG_INIT; + t |= VSC73XX_MAC_CFG_TX_IPG(pdata->mac_cfg.tx_ipg); + t |= VSC73XX_MAC_CFG_CLK_SEL(pdata->mac_cfg.clk_sel); + if (pdata->mac_cfg.bit2) + t |= VSC73XX_MAC_CFG_BIT2; + + err = vsc7385_write(vsc, VSC73XX_BLOCK_MAC, VSC73XX_SUBBLOCK_PORT_MAC, + VSC73XX_MAC_CFG, t); + if (err) + goto err; + + return 0; + +err: + return err; +} + +static int vsc7385_detect(struct vsc7385 *vsc) +{ + struct spi_device *spi = vsc->spi; + u32 t; + u32 id; + u32 rev; + int err; + + err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, + VSC73XX_ICPU_MBOX_VAL, &t); + if (err) { + dev_err(&spi->dev, "unable to read mailbox, err=%d\n", err); + return err; + } + + if (t == 0xffffffff) { + dev_dbg(&spi->dev, "assert chip reset\n"); + if (vsc->pdata->reset) + vsc->pdata->reset(); + + } + + err = vsc7385_read(vsc, VSC73XX_BLOCK_SYSTEM, 0, + VSC73XX_ICPU_CHIPID, &t); + if (err) { + dev_err(&spi->dev, "unable to read chip id, err=%d\n", err); + return err; + } + + id = (t >> VSC73XX_ICPU_CHIPID_ID_SHIFT) & VSC73XX_ICPU_CHIPID_ID_MASK; + switch (id) { + case VSC73XX_ICPU_CHIPID_ID_7385: + case VSC73XX_ICPU_CHIPID_ID_7395: + break; + default: + dev_err(&spi->dev, "unsupported chip, id=%04x\n", id); + return -ENODEV; + } + + rev = (t >> VSC73XX_ICPU_CHIPID_REV_SHIFT) & + VSC73XX_ICPU_CHIPID_REV_MASK; + dev_info(&spi->dev, "VSC%04X (rev. %d) switch found\n", id, rev); + + return 0; +} + +static int __devinit vsc7385_probe(struct spi_device *spi) +{ + struct vsc7385 *vsc; + struct vsc7385_platform_data *pdata; + int err; + + printk(KERN_INFO DRV_DESC " version " DRV_VERSION"\n"); + + pdata = spi->dev.platform_data; + if (!pdata) { + dev_err(&spi->dev, "no platform data specified\n"); + return -ENODEV; + } + + vsc = kzalloc(sizeof(*vsc), GFP_KERNEL); + if (!vsc) { + dev_err(&spi->dev, "no memory for private data\n"); + return -ENOMEM; + } + + mutex_init(&vsc->lock); + vsc->pdata = pdata; + vsc->spi = spi_dev_get(spi); + dev_set_drvdata(&spi->dev, vsc); + + spi->mode = SPI_MODE_0; + spi->bits_per_word = 8; + err = spi_setup(spi); + if (err) { + dev_err(&spi->dev, "spi_setup failed, err=%d\n", err); + goto err_drvdata; + } + + err = vsc7385_detect(vsc); + if (err) { + dev_err(&spi->dev, "no chip found, err=%d\n", err); + goto err_drvdata; + } + + err = vsc7385_upload_ucode(vsc); + if (err) + goto err_drvdata; + + err = vsc7385_setup(vsc); + if (err) + goto err_drvdata; + + return 0; + +err_drvdata: + dev_set_drvdata(&spi->dev, NULL); + kfree(vsc); + return err; +} + +static int __devexit vsc7385_remove(struct spi_device *spi) +{ + struct vsc7385_data *vsc; + + vsc = dev_get_drvdata(&spi->dev); + dev_set_drvdata(&spi->dev, NULL); + kfree(vsc); + + return 0; +} + +static struct spi_driver vsc7385_driver = { + .driver = { + .name = DRV_NAME, + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = vsc7385_probe, + .remove = __devexit_p(vsc7385_remove), +}; + +static int __init vsc7385_init(void) +{ + return spi_register_driver(&vsc7385_driver); +} +module_init(vsc7385_init); + +static void __exit vsc7385_exit(void) +{ + spi_unregister_driver(&vsc7385_driver); +} +module_exit(vsc7385_exit); + +MODULE_DESCRIPTION(DRV_DESC); +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_LICENSE("GPL v2"); + diff --git a/target/linux/ar71xx/files/include/linux/nxp_74hc153.h b/target/linux/ar71xx/files/include/linux/nxp_74hc153.h new file mode 100644 index 000000000..20b8845e5 --- /dev/null +++ b/target/linux/ar71xx/files/include/linux/nxp_74hc153.h @@ -0,0 +1,24 @@ +/* + * NXP 74HC153 - Dual 4-input multiplexer defines + * + * Copyright (C) 2010 Gabor Juhos + * + * This program 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. + */ + +#ifndef _NXP_74HC153_H +#define _NXP_74HC153_H + +#define NXP_74HC153_DRIVER_NAME "nxp-74hc153" + +struct nxp_74hc153_platform_data { + unsigned gpio_base; + unsigned gpio_pin_s0; + unsigned gpio_pin_s1; + unsigned gpio_pin_1y; + unsigned gpio_pin_2y; +}; + +#endif /* _NXP_74HC153_H */ diff --git a/target/linux/ar71xx/files/include/linux/platform/ar934x_nfc.h b/target/linux/ar71xx/files/include/linux/platform/ar934x_nfc.h new file mode 100644 index 000000000..3e4c6d988 --- /dev/null +++ b/target/linux/ar71xx/files/include/linux/platform/ar934x_nfc.h @@ -0,0 +1,30 @@ +/* + * Platform data definition for the built-in NAND controller of the + * Atheros AR934x SoCs + * + * Copyright (C) 2011-2012 Gabor Juhos + * + * This program 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. + */ + +#ifndef _AR934X_NFC_PLATFORM_H +#define _AR934X_NFC_PLATFORM_H + +#define AR934X_NFC_DRIVER_NAME "ar934x-nfc" + +struct mtd_info; +struct mtd_partition; + +struct ar934x_nfc_platform_data { + const char *name; + struct mtd_partition *parts; + int nr_parts; + + void (*hw_reset)(bool active); + void (*select_chip)(int chip_no); + int (*scan_fixup)(struct mtd_info *mtd); +}; + +#endif /* _AR934X_NFC_PLATFORM_H */ diff --git a/target/linux/ar71xx/files/include/linux/spi/vsc7385.h b/target/linux/ar71xx/files/include/linux/spi/vsc7385.h new file mode 100644 index 000000000..1072ad794 --- /dev/null +++ b/target/linux/ar71xx/files/include/linux/spi/vsc7385.h @@ -0,0 +1,19 @@ +/* + * Platform data definition for the Vitesse VSC7385 ethernet switch driver + * + * Copyright (C) 2009 Gabor Juhos + * + * This program 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. + */ + +struct vsc7385_platform_data { + void (*reset)(void); + char *ucode_name; + struct { + u32 tx_ipg:5; + u32 bit2:1; + u32 clk_sel:3; + } mac_cfg; +}; diff --git a/target/linux/ar71xx/files/net/dsa/mv88e6063.c b/target/linux/ar71xx/files/net/dsa/mv88e6063.c new file mode 100644 index 000000000..5638a9fe9 --- /dev/null +++ b/target/linux/ar71xx/files/net/dsa/mv88e6063.c @@ -0,0 +1,294 @@ +/* + * net/dsa/mv88e6063.c - Driver for Marvell 88e6063 switch chips + * Copyright (c) 2009 Gabor Juhos + * + * This driver was base on: net/dsa/mv88e6060.c + * net/dsa/mv88e6063.c - Driver for Marvell 88e6060 switch chips + * Copyright (c) 2008-2009 Marvell Semiconductor + * + * 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. + */ + +#include +#include +#include +#include "dsa_priv.h" + +#define REG_BASE 0x10 +#define REG_PHY(p) (REG_BASE + (p)) +#define REG_PORT(p) (REG_BASE + 8 + (p)) +#define REG_GLOBAL (REG_BASE + 0x0f) +#define NUM_PORTS 7 + +static int reg_read(struct dsa_switch *ds, int addr, int reg) +{ + return mdiobus_read(ds->master_mii_bus, addr, reg); +} + +#define REG_READ(addr, reg) \ + ({ \ + int __ret; \ + \ + __ret = reg_read(ds, addr, reg); \ + if (__ret < 0) \ + return __ret; \ + __ret; \ + }) + + +static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val) +{ + return mdiobus_write(ds->master_mii_bus, addr, reg, val); +} + +#define REG_WRITE(addr, reg, val) \ + ({ \ + int __ret; \ + \ + __ret = reg_write(ds, addr, reg, val); \ + if (__ret < 0) \ + return __ret; \ + }) + +static char *mv88e6063_probe(struct mii_bus *bus, int sw_addr) +{ + int ret; + + ret = mdiobus_read(bus, REG_PORT(0), 0x03); + if (ret >= 0) { + ret &= 0xfff0; + if (ret == 0x1530) + return "Marvell 88E6063"; + } + + return NULL; +} + +static int mv88e6063_switch_reset(struct dsa_switch *ds) +{ + int i; + int ret; + + /* + * Set all ports to the disabled state. + */ + for (i = 0; i < NUM_PORTS; i++) { + ret = REG_READ(REG_PORT(i), 0x04); + REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc); + } + + /* + * Wait for transmit queues to drain. + */ + msleep(2); + + /* + * Reset the switch. + */ + REG_WRITE(REG_GLOBAL, 0x0a, 0xa130); + + /* + * Wait up to one second for reset to complete. + */ + for (i = 0; i < 1000; i++) { + ret = REG_READ(REG_GLOBAL, 0x00); + if ((ret & 0x8000) == 0x0000) + break; + + msleep(1); + } + if (i == 1000) + return -ETIMEDOUT; + + return 0; +} + +static int mv88e6063_setup_global(struct dsa_switch *ds) +{ + /* + * Disable discarding of frames with excessive collisions, + * set the maximum frame size to 1536 bytes, and mask all + * interrupt sources. + */ + REG_WRITE(REG_GLOBAL, 0x04, 0x0800); + + /* + * Enable automatic address learning, set the address + * database size to 1024 entries, and set the default aging + * time to 5 minutes. + */ + REG_WRITE(REG_GLOBAL, 0x0a, 0x2130); + + return 0; +} + +static int mv88e6063_setup_port(struct dsa_switch *ds, int p) +{ + int addr = REG_PORT(p); + + /* + * Do not force flow control, disable Ingress and Egress + * Header tagging, disable VLAN tunneling, and set the port + * state to Forwarding. Additionally, if this is the CPU + * port, enable Ingress and Egress Trailer tagging mode. + */ + REG_WRITE(addr, 0x04, dsa_is_cpu_port(ds, p) ? 0x4103 : 0x0003); + + /* + * Port based VLAN map: give each port its own address + * database, allow the CPU port to talk to each of the 'real' + * ports, and allow each of the 'real' ports to only talk to + * the CPU port. + */ + REG_WRITE(addr, 0x06, + ((p & 0xf) << 12) | + (dsa_is_cpu_port(ds, p) ? + ds->phys_port_mask : + (1 << ds->dst->cpu_port))); + + /* + * Port Association Vector: when learning source addresses + * of packets, add the address to the address database using + * a port bitmap that has only the bit for this port set and + * the other bits clear. + */ + REG_WRITE(addr, 0x0b, 1 << p); + + return 0; +} + +static int mv88e6063_setup(struct dsa_switch *ds) +{ + int i; + int ret; + + ret = mv88e6063_switch_reset(ds); + if (ret < 0) + return ret; + + /* @@@ initialise atu */ + + ret = mv88e6063_setup_global(ds); + if (ret < 0) + return ret; + + for (i = 0; i < NUM_PORTS; i++) { + ret = mv88e6063_setup_port(ds, i); + if (ret < 0) + return ret; + } + + return 0; +} + +static int mv88e6063_set_addr(struct dsa_switch *ds, u8 *addr) +{ + REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]); + REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]); + REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]); + + return 0; +} + +static int mv88e6063_port_to_phy_addr(int port) +{ + if (port >= 0 && port <= NUM_PORTS) + return REG_PHY(port); + return -1; +} + +static int mv88e6063_phy_read(struct dsa_switch *ds, int port, int regnum) +{ + int addr; + + addr = mv88e6063_port_to_phy_addr(port); + if (addr == -1) + return 0xffff; + + return reg_read(ds, addr, regnum); +} + +static int +mv88e6063_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) +{ + int addr; + + addr = mv88e6063_port_to_phy_addr(port); + if (addr == -1) + return 0xffff; + + return reg_write(ds, addr, regnum, val); +} + +static void mv88e6063_poll_link(struct dsa_switch *ds) +{ + int i; + + for (i = 0; i < DSA_MAX_PORTS; i++) { + struct net_device *dev; + int uninitialized_var(port_status); + int link; + int speed; + int duplex; + int fc; + + dev = ds->ports[i]; + if (dev == NULL) + continue; + + link = 0; + if (dev->flags & IFF_UP) { + port_status = reg_read(ds, REG_PORT(i), 0x00); + if (port_status < 0) + continue; + + link = !!(port_status & 0x1000); + } + + if (!link) { + if (netif_carrier_ok(dev)) { + printk(KERN_INFO "%s: link down\n", dev->name); + netif_carrier_off(dev); + } + continue; + } + + speed = (port_status & 0x0100) ? 100 : 10; + duplex = (port_status & 0x0200) ? 1 : 0; + fc = ((port_status & 0xc000) == 0xc000) ? 1 : 0; + + if (!netif_carrier_ok(dev)) { + printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, " + "flow control %sabled\n", dev->name, + speed, duplex ? "full" : "half", + fc ? "en" : "dis"); + netif_carrier_on(dev); + } + } +} + +static struct dsa_switch_driver mv88e6063_switch_driver = { + .tag_protocol = htons(ETH_P_TRAILER), + .probe = mv88e6063_probe, + .setup = mv88e6063_setup, + .set_addr = mv88e6063_set_addr, + .phy_read = mv88e6063_phy_read, + .phy_write = mv88e6063_phy_write, + .poll_link = mv88e6063_poll_link, +}; + +static int __init mv88e6063_init(void) +{ + register_switch_driver(&mv88e6063_switch_driver); + return 0; +} +module_init(mv88e6063_init); + +static void __exit mv88e6063_cleanup(void) +{ + unregister_switch_driver(&mv88e6063_switch_driver); +} +module_exit(mv88e6063_cleanup); diff --git a/target/linux/ar71xx/generic/config-default b/target/linux/ar71xx/generic/config-default new file mode 100644 index 000000000..45169689e --- /dev/null +++ b/target/linux/ar71xx/generic/config-default @@ -0,0 +1 @@ +CONFIG_CMDLINE="rootfstype=squashfs,jffs2 noinitrd" diff --git a/target/linux/ar71xx/generic/profiles/00-default.mk b/target/linux/ar71xx/generic/profiles/00-default.mk new file mode 100644 index 000000000..36c4aa61b --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/00-default.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Default + NAME:=Default Profile (all drivers) + PACKAGES:= \ + kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/Default/Description + Default package set compatible with most boards. +endef +$(eval $(call Profile,Default)) diff --git a/target/linux/ar71xx/generic/profiles/01-minimal.mk b/target/linux/ar71xx/generic/profiles/01-minimal.mk new file mode 100644 index 000000000..dfaa3b0b3 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/01-minimal.mk @@ -0,0 +1,16 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Minimal + NAME:=Minimal Profile (no drivers) + PACKAGES:=-kmod-ath9k -wpad-mini +endef + +define Profile/Minimal/Description + Minimal package set compatible with most boards. +endef +$(eval $(call Profile,Minimal)) diff --git a/target/linux/ar71xx/generic/profiles/02-ath5k.mk b/target/linux/ar71xx/generic/profiles/02-ath5k.mk new file mode 100644 index 000000000..78203497f --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/02-ath5k.mk @@ -0,0 +1,16 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/ath5k + NAME:=Atheros 802.11abg WiFi (ath5k) + PACKAGES:=kmod-ath5k -kmod-ath9k +endef + +define Profile/ath5k/Description + Package set compatible with hardware using Atheros 802.11abg cards. +endef +$(eval $(call Profile,ath5k)) diff --git a/target/linux/ar71xx/generic/profiles/alfa.mk b/target/linux/ar71xx/generic/profiles/alfa.mk new file mode 100644 index 000000000..06baf240c --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/alfa.mk @@ -0,0 +1,42 @@ +# +# Copyright (C) 2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/ALFAAP96 + NAME:=ALFA Network AP96 board + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-rtc-pcf2123 +endef + +define Profile/ALFAAP96/Description + Package set optimized for the ALFA Network AP96 board. +endef + +$(eval $(call Profile,ALFAAP96)) + + +define Profile/HORNETUB + NAME:=ALFA Network Hornet-UB board + PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/HORNETUB/Description + Package set optimized for the ALFA Network Hornet-UB board. +endef + +$(eval $(call Profile,HORNETUB)) + + +define Profile/ALFANX + NAME:=ALFA Network N2/N5 board + PACKAGES:= +endef + +define Profile/ALFANX/Description + Package set optimized for the ALFA Network N2/N5 boards. +endef + +$(eval $(call Profile,ALFANX)) + diff --git a/target/linux/ar71xx/generic/profiles/allnet.mk b/target/linux/ar71xx/generic/profiles/allnet.mk new file mode 100644 index 000000000..07ca96444 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/allnet.mk @@ -0,0 +1,39 @@ +# +# Copyright (C) 20012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/ALL0305 + NAME:=Allnet ALL0305 + PACKAGES:=fconfig kmod-ath5k -kmod-ath9k +endef + +define Profile/ALL0305/Description + Package set optimized for the Allnet ALL0305. +endef + +$(eval $(call Profile,ALL0305)) + +define Profile/ALL0258N + NAME:=Allnet ALL0258N + PACKAGES:=uboot-envtools rssileds +endef + +define Profile/ALL0258N/Description + Package set optimized for the Allnet ALL0258N. +endef + +$(eval $(call Profile,ALL0258N)) + +define Profile/ALL0315N + NAME:=Allnet ALL0315N + PACKAGES:=uboot-envtools rssileds +endef + +define Profile/ALL0315N/Description + Package set optimized for the Allnet ALL0315N. +endef + +$(eval $(call Profile,ALL0315N)) diff --git a/target/linux/ar71xx/generic/profiles/atheros.mk b/target/linux/ar71xx/generic/profiles/atheros.mk new file mode 100644 index 000000000..8e79f4cd5 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/atheros.mk @@ -0,0 +1,129 @@ +# +# Copyright (C) 2009-2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/AP113 + NAME:=Atheros AP113 reference board + PACKAGES:=kmod-usb-core kmod-usb2 +endef + +define Profile/AP113/description + Package set optimized for the Atheros AP113 reference board. +endef + +$(eval $(call Profile,AP113)) + +define Profile/AP121 + NAME:=Atheros AP121 reference board + PACKAGES:=kmod-usb-core kmod-usb2 +endef + +define Profile/AP121/Description + Package set optimized for the Atheros AP121 reference board. +endef + +$(eval $(call Profile,AP121)) + +define Profile/AP121MINI + NAME:=Atheros AP121-MINI reference board + PACKAGES:= +endef + +define Profile/AP121MINI/Description + Package set optimized for the Atheros AP121-MINI reference board. +endef + +$(eval $(call Profile,AP121MINI)) + +define Profile/AP136 + NAME:=Atheros AP136 reference board + PACKAGES:=kmod-usb-core kmod-usb2 kmod-usb-storage +endef + +define Profile/AP136/Description + Package set optimized for the Atheros AP136 reference board. +endef + +$(eval $(call Profile,AP136)) + +define Profile/AP81 + NAME:=Atheros AP81 reference board + PACKAGES:=kmod-usb-core kmod-usb2 +endef + +define Profile/AP81/Description + Package set optimized for the Atheros AP81 reference board. +endef + +$(eval $(call Profile,AP81)) + +define Profile/AP83 + NAME:=Atheros AP83 reference board + PACKAGES:=kmod-usb-core kmod-usb2 \ + vsc7385-ucode-ap83 vsc7395-ucode-ap83 +endef + +define Profile/AP83/Description + Package set optimized for the Atheros AP83 reference board. +endef + +$(eval $(call Profile,AP83)) + +define Profile/AP96 + NAME:=Atheros AP96 reference board + PACKAGES:=kmod-usb-core kmod-usb2 +endef + +define Profile/AP96/Description + Package set optimized for the Atheros AP96 reference board. +endef + +$(eval $(call Profile,AP96)) + +define Profile/DB120 + NAME:=Atheros DB120 reference board + PACKAGES:=kmod-usb-core kmod-usb2 kmod-usb-storage +endef + +define Profile/DB120/Description + Package set optimized for the Atheros DB120 reference board. +endef + +$(eval $(call Profile,DB120)) + +define Profile/PB42 + NAME:=Atheros PB42 reference board + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-usb2 +endef + +define Profile/PB42/Description + Package set optimized for the Atheros PB42 reference board. +endef + +$(eval $(call Profile,PB42)) + +define Profile/PB44 + NAME:=Atheros PB44 reference board + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-usb2 \ + vsc7385-ucode-pb44 vsc7395-ucode-pb44 +endef + +define Profile/PB44/Description + Package set optimized for the Atheros PB44 reference board. +endef + +$(eval $(call Profile,PB44)) + +define Profile/PB92 + NAME:=Atheros PB92 reference board + PACKAGES:=kmod-usb-core kmod-usb2 +endef + +define Profile/PB92/Description + Package set optimized for the Atheros PB92 reference board. +endef + +$(eval $(call Profile,PB92)) diff --git a/target/linux/ar71xx/generic/profiles/atlantis.mk b/target/linux/ar71xx/generic/profiles/atlantis.mk new file mode 100644 index 000000000..073d8d1f8 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/atlantis.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/A02RBW300N + NAME:=Atlantis-Land A02-RB-W300N + PACKAGES:= +endef + +define Profile/A02RBW300N/Description + Package set optimized for the Atlantis-Land A02-RB-W300N. +endef + +$(eval $(call Profile,A02RBW300N)) diff --git a/target/linux/ar71xx/generic/profiles/buffalo.mk b/target/linux/ar71xx/generic/profiles/buffalo.mk new file mode 100644 index 000000000..887be2657 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/buffalo.mk @@ -0,0 +1,96 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/WZRHPG300NH + NAME:=Buffalo WZR-HP-G300NH + PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/WZRHPG300NH/Description + Package set optimized for the Buffalo WZR-HP-G300NH and WZR-HP-G301NH +endef + +$(eval $(call Profile,WZRHPG300NH)) + +define Profile/WZRHPG300NH2 + NAME:=Buffalo WZR-HP-G300NH2 + PACKAGES:=kmod-ath9k wpad-mini kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/WZRHPG300NH/Description + Package set optimized for the Buffalo WZR-HP-G300NH2 +endef + +$(eval $(call Profile,WZRHPG300NH2)) + +define Profile/WZRHPAG300H + NAME:=Buffalo WZR-HP-AG300H + PACKAGES:=kmod-usb-ohci kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/WZRHPAG300H/Description + Package set optimized for the Buffalo WZR-HP-AG300H +endef + +$(eval $(call Profile,WZRHPAG300H)) + +define Profile/WZRHPG450H + NAME:=Buffalo WZR-HP-G450H + PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/WZRHPG450H/Description + Package set optimized for the Buffalo WZR-HP-G450H +endef + +$(eval $(call Profile,WZRHPG450H)) + +define Profile/WHRG301N + NAME:=Buffalo WHR-G301N + PACKAGES:= +endef + +define Profile/WHRG301N/Description + Package set optimized for the Buffalo WHR-G301N. +endef + +$(eval $(call Profile,WHRG301N)) + + +define Profile/WHRHPG300N + NAME:=Buffalo WHR-HP-G300N + PACKAGES:= +endef + +define Profile/WHRHPG300N/Description + Package set optimized for the Buffalo WHR-HP-G300N +endef + +$(eval $(call Profile,WHRHPG300N)) + + +define Profile/WHRHPGN + NAME:=Buffalo WHR-HP-GN + PACKAGES:= +endef + +define Profile/WHRHPGN/Description + Package set optimized for the Buffalo WHR-HP-GN. +endef + +$(eval $(call Profile,WHRHPGN)) + +define Profile/WLAEAG300N + NAME:=Buffalo WLAE-AG300N + PACKAGES:=kmod-ledtrig-netdev +endef + +define Profile/WLAEAG300N/Description + Package set optimized for the Buffalo WLAE-AG300N +endef + +$(eval $(call Profile,WLAEAG300N)) diff --git a/target/linux/ar71xx/generic/profiles/compex.mk b/target/linux/ar71xx/generic/profiles/compex.mk new file mode 100644 index 000000000..349147381 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/compex.mk @@ -0,0 +1,28 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/WP543 + NAME:=Compex WP543/WPJ543 + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-usb2 +endef + +define Profile/WP543/Description + Package set optimized for the Compex WP543/WPJ543 boards. +endef + +$(eval $(call Profile,WP543)) + +define Profile/WPE72 + NAME:=Compex WPE72/WPE72NX + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-usb2 +endef + +define Profile/WPE72/Description + Package set optimized for the Compex WPE72 boards including Compex WPE72NX Indoor Access Point. +endef + +$(eval $(call Profile,WPE72)) diff --git a/target/linux/ar71xx/generic/profiles/d-link.mk b/target/linux/ar71xx/generic/profiles/d-link.mk new file mode 100644 index 000000000..98fe00fc2 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/d-link.mk @@ -0,0 +1,63 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/DIR600A1 + NAME:=D-Link DIR-600 rev. A1 + PACKAGES:= +endef + +define Profile/DIR600A1/Description + Package set optimized for the D-Link DIR-600 rev. A1. +endef + +$(eval $(call Profile,DIR600A1)) + +define Profile/DIR601A1 + NAME:=D-Link DIR-601 rev. A1 + PACKAGES:= +endef + +define Profile/DIR601A1/Description + Package set optimized for the D-Link DIR-601 rev. A1. +endef + +$(eval $(call Profile,DIR601A1)) + +define Profile/DIR615C1 + NAME:=D-Link DIR-615 rev. C1 + PACKAGES:= +endef + +define Profile/DIR615C1/Description + Package set optimized for the D-Link DIR-615 rev. C1. +endef + +$(eval $(call Profile,DIR615C1)) + + +define Profile/DIR615E4 + NAME:=D-Link DIR-615 rev. E4 + PACKAGES:= +endef + +define Profile/DIR615E4/Description + Package set optimized for the D-Link DIR-615 rev. E4. +endef + +$(eval $(call Profile,DIR615E4)) + + +define Profile/DIR825B1 + NAME:=D-Link DIR-825 rev. B1 + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/DIR825B1/Description + Package set optimized for the D-Link DIR-825 rev. B1. +endef + +$(eval $(call Profile,DIR825B1)) diff --git a/target/linux/ar71xx/generic/profiles/ew.mk b/target/linux/ar71xx/generic/profiles/ew.mk new file mode 100644 index 000000000..b4e15e322 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/ew.mk @@ -0,0 +1,20 @@ +# +# Copyright (C) 2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/EWDORIN + NAME:=Embedded Wireless Dorin Platform + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-ledtrig-usbdev kmod-usb-storage \ + kmod-fs-vfat kmod-fs-msdos kmod-fs-ntfs kmod-fs-ext4 \ + kmod-nls-cp437 kmod-nls-cp850 kmod-nls-cp852 kmod-nls-iso8859-1 kmod-nls-utf8 +endef + +define Profile/EWDORIN/Description + Package set optimized for the Dorin Platform. +endef + +$(eval $(call Profile,EWDORIN)) + diff --git a/target/linux/ar71xx/generic/profiles/jjplus.mk b/target/linux/ar71xx/generic/profiles/jjplus.mk new file mode 100644 index 000000000..3f97dbf02 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/jjplus.mk @@ -0,0 +1,39 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/JA76PF + NAME:=jjPlus JA76PF + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-hwmon-core kmod-i2c-core kmod-hwmon-lm75 +endef + +define Profile/JA76PF/Description + Package set optimized for the jjPlus JA76PF board. +endef + +$(eval $(call Profile,JA76PF)) + +define Profile/JA76PF2 + NAME:=jjPlus JA76PF2 + PACKAGES:= +endef + +define Profile/JA76PF2/Description + Package set optimized for the jjPlus JA76PF2 board. +endef + +$(eval $(call Profile,JA76PF2)) + +define Profile/JWAP003 + NAME:=jjPlus JWAP0003 + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-usb2 +endef + +define Profile/JWAP003/Description + Package set optimized for the jjPlus JWAP003 board. +endef + +$(eval $(call Profile,JWAP003)) diff --git a/target/linux/ar71xx/generic/profiles/linksys.mk b/target/linux/ar71xx/generic/profiles/linksys.mk new file mode 100644 index 000000000..bedf3a3d4 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/linksys.mk @@ -0,0 +1,27 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/WRT160NL + NAME:=Linksys WRT160NL + PACKAGES:=kmod-usb-core kmod-usb2 +endef + +define Profile/WRT160NL/Description + Package set optimized for the Linksys WRT160NL. +endef + +define Profile/WRT400N + NAME:=Linksys WRT400N + PACKAGES:= +endef + +define Profile/WRT400N/Description + Package set optimized for the Linksys WRT400N. +endef + +$(eval $(call Profile,WRT160NL)) +$(eval $(call Profile,WRT400N)) diff --git a/target/linux/ar71xx/generic/profiles/netgear.mk b/target/linux/ar71xx/generic/profiles/netgear.mk new file mode 100644 index 000000000..fe136234f --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/netgear.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/WNDR3700 + NAME:=NETGEAR WNDR3700/WNDR3800/WNDRMAC + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-ledtrig-usbdev kmod-leds-wndr3700-usb +endef + +define Profile/WNDR3700/Description + Package set optimized for the NETGEAR WNDR3700/WNDR3800/WNDRMAC +endef + +$(eval $(call Profile,WNDR3700)) diff --git a/target/linux/ar71xx/generic/profiles/openmesh.mk b/target/linux/ar71xx/generic/profiles/openmesh.mk new file mode 100644 index 000000000..88e37ee56 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/openmesh.mk @@ -0,0 +1,18 @@ +# +# Copyright (C) 2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/OM2P + NAME:=OpenMesh OM2P/OM2P-LC + PACKAGES:=kmod-ath9k om-watchdog +endef + +define Profile/OM2P/Description + Package set optimized for the OpenMesh OM2P/OM2P-LC. +endef + +$(eval $(call Profile,OM2P)) + diff --git a/target/linux/ar71xx/generic/profiles/planex.mk b/target/linux/ar71xx/generic/profiles/planex.mk new file mode 100644 index 000000000..3d192ba74 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/planex.mk @@ -0,0 +1,28 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/MZKW04NU + NAME:=Planex MZK-W04NU + PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/MZKW04NU/Description + Package set optimized for the Planex MZK-W04NU. +endef + +$(eval $(call Profile,MZKW04NU)) + +define Profile/MZKW300NH + NAME:=Planex MZK-W300NH + PACKAGES:= +endef + +define Profile/MZKW300NH/Description + Package set optimized for the Planex MZK-W300NH. +endef + +$(eval $(call Profile,MZKW300NH)) diff --git a/target/linux/ar71xx/generic/profiles/redwave.mk b/target/linux/ar71xx/generic/profiles/redwave.mk new file mode 100644 index 000000000..069dd8f7b --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/redwave.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/RW2458N + NAME:=Redwave RW2458N + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-ath9k wpad-mini +endef + +define Profile/RW2458N/Description + Package set optimized for the Redwave RW2458N board. +endef + +$(eval $(call Profile,RW2458N)) diff --git a/target/linux/ar71xx/generic/profiles/tp-link.mk b/target/linux/ar71xx/generic/profiles/tp-link.mk new file mode 100644 index 000000000..056a91703 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/tp-link.mk @@ -0,0 +1,204 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/TLMR11U + NAME:=TP-LINK TL-MR11U + PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/TLMR11U/Description + Package set optimized for the TP-LINK TL-MR11U. +endef +$(eval $(call Profile,TLMR11U)) + + +define Profile/TLMR3020 + NAME:=TP-LINK TL-MR3020 + PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/TLMR3020/Description + Package set optimized for the TP-LINK TL-MR3020. +endef +$(eval $(call Profile,TLMR3020)) + + +define Profile/TLMR3040 + NAME:=TP-LINK TL-MR3040 + PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/TLMR3040/Description + Package set optimized for the TP-LINK TL-MR3040. +endef +$(eval $(call Profile,TLMR3040)) + + +define Profile/TLMR3220 + NAME:=TP-LINK TL-MR3220 + PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/TLMR3220/Description + Package set optimized for the TP-LINK TL-MR3220. +endef +$(eval $(call Profile,TLMR3220)) + + +define Profile/TLMR3420 + NAME:=TP-LINK TL-MR3420 + PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/TLMR3420/Description + Package set optimized for the TP-LINK TL-MR3420. +endef +$(eval $(call Profile,TLMR3420)) + + +define Profile/TLWR703 + NAME:=TP-LINK TL-WR703N + PACKAGES:=kmod-usb-core kmod-usb2 +endef + + +define Profile/TLWR703/Description + Package set optimized for the TP-LINK TL-WR703N. +endef +$(eval $(call Profile,TLWR703)) + + +define Profile/TLWA701 + NAME:=TP-LINK TL-WA701N/ND + PACKAGES:= +endef + +define Profile/TLWA701/Description + Package set optimized for the TP-LINK TL-WA701N/ND. +endef +$(eval $(call Profile,TLWA701)) + + +define Profile/TLWA901 + NAME:=TP-LINK TL-WA901N/ND + PACKAGES:= +endef + +define Profile/TLWA901/Description + Package set optimized for the TP-LINK TL-WA901N/ND. +endef +$(eval $(call Profile,TLWA901)) + + +define Profile/TLWDR4300 + NAME:=TP-LINK TL-WDR3600/4300/4310 + PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/TLWDR4300/Description + Package set optimized for the TP-LINK TL-WDR3600/4300/4310. +endef +$(eval $(call Profile,TLWDR4300)) + + +define Profile/TLWR740 + NAME:=TP-LINK TL-WR740N/ND + PACKAGES:= +endef + +define Profile/TLWR740/Description + Package set optimized for the TP-LINK TL-WR740N/ND. +endef +$(eval $(call Profile,TLWR740)) + + +define Profile/TLWR741 + NAME:=TP-LINK TL-WR741N/ND + PACKAGES:= +endef + +define Profile/TLWR741/Description + Package set optimized for the TP-LINK TL-WR741N/ND. +endef +$(eval $(call Profile,TLWR741)) + + +define Profile/TLWR743 + NAME:=TP-LINK TL-WR743N/ND + PACKAGES:= +endef + +define Profile/TLWR743/Description + Package set optimized for the TP-LINK TL-WR743N/ND. +endef +$(eval $(call Profile,TLWR743)) + + +define Profile/TLWR841 + NAME:=TP-LINK TL-WR841N/ND + PACKAGES:= +endef + +define Profile/TLWR841/Description + Package set optimized for the TP-LINK TL-WR841N/ND. +endef +$(eval $(call Profile,TLWR841)) + + +define Profile/TLWR842 + NAME:=TP-LINK TL-WR842N/ND + PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/TLWR842/Description + Package set optimized for the TP-LINK TL-WR842N/ND. +endef +$(eval $(call Profile,TLWR842)) + + +define Profile/TLWR941 + NAME:=TP-LINK TL-WR941N/ND + PACKAGES:= +endef + +define Profile/TLWR941/Description + Package set optimized for the TP-LINK TL-WR941N/ND. +endef +$(eval $(call Profile,TLWR941)) + + +define Profile/TLWR1041 + NAME:=TP-LINK TL-WR1041N + PACKAGES:= +endef + +define Profile/TLWR1041/Description + Package set optimized for the TP-LINK TL-WR1041N/ND. +endef +$(eval $(call Profile,TLWR1041)) + + +define Profile/TLWR1043 + NAME:=TP-LINK TL-WR1043N/ND + PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/TLWR1043/Description + Package set optimized for the TP-LINK TL-WR1043N/ND. +endef +$(eval $(call Profile,TLWR1043)) + + +define Profile/TLWR2543 + NAME:=TP-LINK TL-WR2543N/ND + PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev +endef + +define Profile/TLWR2543/Description + Package set optimized for the TP-LINK TL-WR2543N/ND. +endef +$(eval $(call Profile,TLWR2543)) diff --git a/target/linux/ar71xx/generic/profiles/trendnet.mk b/target/linux/ar71xx/generic/profiles/trendnet.mk new file mode 100644 index 000000000..c6fe9cf79 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/trendnet.mk @@ -0,0 +1,51 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/TEW632BRP + NAME:=TRENDNet TEW-632BRP + PACKAGES:= +endef + +define Profile/TEW632BRP/Description + Package set optimized for the TRENDNet TEW-632BRP. +endef + +$(eval $(call Profile,TEW632BRP)) + +define Profile/TEW652BRP + NAME:=TRENDNet TEW-652BRP + PACKAGES:= +endef + +define Profile/TEW652BRP/Description + Package set optimized for the TRENDNet TEW-652BRP. +endef + +$(eval $(call Profile,TEW652BRP)) + +define Profile/TEW673GRU + NAME:=TRENDNet TEW-673GRU + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-usb2 +endef + +define Profile/TEW673GRU/Description + Package set optimized for the TRENDNet TEW-673GRU. +endef + +$(eval $(call Profile,TEW673GRU)) + +define Profile/TEW712BR + NAME:=TRENDNet TEW-712BR + PACKAGES:= +endef + +define Profile/TEW712BR/Description + Package set optimized for the TRENDNet TEW-712BR. +endef + +$(eval $(call Profile,TEW712BR)) + diff --git a/target/linux/ar71xx/generic/profiles/ubnt.mk b/target/linux/ar71xx/generic/profiles/ubnt.mk new file mode 100644 index 000000000..668171b8e --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/ubnt.mk @@ -0,0 +1,50 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/UBNTRS + NAME:=Ubiquiti RouterStation + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-usb2 +endef + +define Profile/UBNTRS/Description + Package set optimized for the Ubiquiti RouterStation. +endef + +$(eval $(call Profile,UBNTRS)) + +define Profile/UBNTRSPRO + NAME:=Ubiquiti RouterStation Pro + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-usb2 +endef + +define Profile/UBNTRSPRO/Description + Package set optimized for the Ubiquiti RouterStation Pro. +endef + +$(eval $(call Profile,UBNTRSPRO)) + +define Profile/UBNTUNIFI + NAME:=Ubiquiti UniFi AP + PACKAGES:= +endef + +define Profile/UBNTUNIFI/Description + Package set optimized for the Ubiquiti UniFi AP. +endef + +$(eval $(call Profile,UBNTUNIFI)) + +define Profile/UBNT + NAME:=Ubiquiti Products + PACKAGES:=kmod-usb-core kmod-usb-ohci kmod-usb2 +endef + +define Profile/UBNT/Description + Build images for all Ubiquiti products (including LS-SR71, RouterStation and RouterStation Pro) +endef + +$(eval $(call Profile,UBNT)) diff --git a/target/linux/ar71xx/generic/profiles/zcomax.mk b/target/linux/ar71xx/generic/profiles/zcomax.mk new file mode 100644 index 000000000..b9ab77e80 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/zcomax.mk @@ -0,0 +1,28 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/ZCN1523H28 + NAME:=Zcomax ZCN-1523H-2-8 + PACKAGES:= +endef + +define Profile/ZCN1523H28/Description + Package set optimized for the Zcomax ZCN-1523H-2-8 board. +endef + +$(eval $(call Profile,ZCN1523H28)) + +define Profile/ZCN1523H516 + NAME:=Zcomax ZCN-1523H-5-16 + PACKAGES:= +endef + +define Profile/ZCN1523H516/Description + Package set optimized for the Zcomax ZCN-1523H-5-16 board. +endef + +$(eval $(call Profile,ZCN1523H516)) diff --git a/target/linux/ar71xx/generic/profiles/zyxel.mk b/target/linux/ar71xx/generic/profiles/zyxel.mk new file mode 100644 index 000000000..66258bdb8 --- /dev/null +++ b/target/linux/ar71xx/generic/profiles/zyxel.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/NBG_460N_550N_550NH + NAME:=Zyxel NBG 460N/550N/550NH + PACKAGES:=kmod-rtc-pcf8563 +endef + +define Profile/NBG_460N_550N_550NH/Description + Package set optimized for the Zyxel NBG 460N/550N/550NH Routers. +endef + +$(eval $(call Profile,NBG_460N_550N_550NH)) diff --git a/target/linux/ar71xx/generic/target.mk b/target/linux/ar71xx/generic/target.mk new file mode 100644 index 000000000..c08f92962 --- /dev/null +++ b/target/linux/ar71xx/generic/target.mk @@ -0,0 +1,7 @@ +BOARDNAME:=Generic + +define Target/Description + Build firmware images for generic Atheros AR71xx/AR913x/AR934x based boards. +endef + + diff --git a/target/linux/ar71xx/image/Makefile b/target/linux/ar71xx/image/Makefile new file mode 100644 index 000000000..569bdc9ef --- /dev/null +++ b/target/linux/ar71xx/image/Makefile @@ -0,0 +1,901 @@ +# +# Copyright (C) 2008-2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/image.mk + +JFFS2_BLOCKSIZE = 64k 128k 256k + +define imgname +$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(patsubst jffs2-%,jffs2,$(patsubst squashfs-%,squashfs,$(1))) +endef + +define rootfs_align +$(patsubst %-256k,0x40000,$(patsubst %-128k,0x20000,$(patsubst %-64k,0x10000,$(patsubst squashfs-%,0x4,$(1))))) +endef + +define sysupname +$(call imgname,$(1),$(2))-sysupgrade.bin +endef + +define factoryname +$(call imgname,$(1),$(2))-factory.bin +endef + +COMMA:=, + +define mkcmdline +$(if $(1),board=$(1) )$(if $(2),console=$(2)$(COMMA)$(3)) +endef + +SINGLE_PROFILES:= + +define SingleProfile + define Image/Build/Profile/$(3) + $$(call Image/Build/Template/$(2)/$$(1),$(1),$(4),$$(call mkcmdline,$(5),$(6),$(7)),$(8),$(9),$(10),$(11),$(12)) + endef + SINGLE_PROFILES += $(3) +endef + +define MultiProfile + define Image/Build/Profile/$(1) + $(foreach p,$(2), + $$(call Image/Build/Profile/$p,$$(1)) + ) + endef +endef + +LOADER_MAKE := $(NO_TRACE_MAKE) -C lzma-loader KDIR=$(KDIR) + +KDIR_TMP:=$(KDIR)/tmp +VMLINUX:=$(BIN_DIR)/$(IMG_PREFIX)-vmlinux +UIMAGE:=$(BIN_DIR)/$(IMG_PREFIX)-uImage +fs_squash:=squashfs-only +fs_64k:=64k +fs_64kraw:=64kraw +fs_128k:=128k +fs_256k:=256k +ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y) + fs_squash:=initramfs + fs_64k:=initramfs + fs_64kraw:=initramfs + fs_128k:=initramfs + fs_256k:=initramfs + VMLINUX:=$(BIN_DIR)/$(IMG_PREFIX)-vmlinux-initramfs + UIMAGE:=$(BIN_DIR)/$(IMG_PREFIX)-uImage-initramfs +endif + +define CompressLzma + $(STAGING_DIR_HOST)/bin/lzma e $(1) -lc1 -lp2 -pb2 $(2) +endef + +define PatchKernelLzma + cp $(KDIR)/vmlinux $(KDIR_TMP)/vmlinux-$(1) + $(STAGING_DIR_HOST)/bin/patch-cmdline $(KDIR_TMP)/vmlinux-$(1) "$(strip $(2))" + $(call CompressLzma,$(KDIR_TMP)/vmlinux-$(1),$(KDIR_TMP)/vmlinux-$(1).bin.lzma) +endef + +define PatchKernelGzip + cp $(KDIR)/vmlinux $(KDIR_TMP)/vmlinux-$(1) + $(STAGING_DIR_HOST)/bin/patch-cmdline $(KDIR_TMP)/vmlinux-$(1) "$(strip $(2))" + gzip -9 -c $(KDIR_TMP)/vmlinux-$(1) > $(KDIR_TMP)/vmlinux-$(1).bin.gz +endef + +define MkuImage + mkimage -A mips -O linux -T kernel -a 0x80060000 -C $(1) $(2) \ + -e 0x80060000 -n 'MIPS OpenWrt Linux-$(LINUX_VERSION)' \ + -d $(3) $(4) +endef + +define MkuImageLzma + $(call PatchKernelLzma,$(1),$(2)) + $(call MkuImage,lzma,,$(KDIR_TMP)/vmlinux-$(1).bin.lzma,$(KDIR_TMP)/vmlinux-$(1).uImage) +endef + +define MkuImageLzma/initramfs + $(call PatchKernelLzma,$(1),$(2)) + $(call MkuImage,lzma,,$(KDIR_TMP)/vmlinux-$(1).bin.lzma,$(call imgname,initramfs,$(1))-uImage.bin) +endef + +define MkuImageGzip + $(call PatchKernelGzip,$(1),$(2)) + $(call MkuImage,gzip,,$(KDIR_TMP)/vmlinux-$(1).bin.gz,$(KDIR_TMP)/vmlinux-$(1).uImage) +endef + +define MkuImageGzip/initramfs + $(call PatchKernelGzip,$(1),$(2)) + $(call MkuImage,gzip,,$(KDIR_TMP)/vmlinux-$(1).bin.gz,$(call imgname,initramfs,$(1))-uImage.bin) +endef + +define MkuImageOKLI + $(call MkuImage,lzma,-M 0x4f4b4c49,$(KDIR)/vmlinux.bin.lzma,$(KDIR_TMP)/vmlinux-$(1).okli) +endef + +define CatFiles + if [ `stat -c%s "$(1)"` -gt $(2) ]; then \ + echo "Warning: $(1) is too big"; \ + else if [ `stat -c%s $(3)` -gt $(4) ]; then \ + echo "Warning: $(3) is too big"; \ + else \ + ( dd if=$(1) bs=$(2) conv=sync; dd if=$(3) ) > $(5); \ + fi; fi +endef + +define Sysupgrade/KR + $(call CatFiles,$(2),$(3),$(KDIR)/root.$(1),$(4),$(call sysupname,$(1),$(5))) +endef + +define Sysupgrade/KRuImage + $(call CatFiles,$(KDIR_TMP)/vmlinux-$(2).uImage,$(3),$(KDIR)/root.$(1),$(4),$(call sysupname,$(1),$(2))) +endef + +define Sysupgrade/RKuImage + $(call CatFiles,$(KDIR)/root.$(1),$(4),$(KDIR_TMP)/vmlinux-$(2).uImage,$(3),$(call sysupname,$(1),$(2))) +endef + +define Image/BuildLoader + -rm -rf $(KDIR)/lzma-loader + $(LOADER_MAKE) LOADER=loader-$(1).$(2) KERNEL_CMDLINE="$(3)"\ + LZMA_TEXT_START=0x80a00000 LOADADDR=0x80060000 \ + LOADER_DATA="$(KDIR)/vmlinux.bin.lzma" BOARD="$(1)" \ + compile loader.$(2) +endef + +define Image/BuildLoaderAlone + -rm -rf $(KDIR)/lzma-loader + $(LOADER_MAKE) LOADER=loader-$(1).$(2) KERNEL_CMDLINE="$(3)" \ + LZMA_TEXT_START=0x80a00000 LOADADDR=0x80060000 \ + BOARD="$(1)" FLASH_OFFS=$(4) FLASH_MAX=$(5) \ + compile loader.$(2) +endef + +define Build/Clean + $(LOADER_MAKE) clean +endef + + +alfa_ap96_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,256k(u-boot-env)ro,13312k(rootfs),2048k(kernel),512k(caldata)ro,15360k@0x80000(firmware) +alfa_mtdlayout_8M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6144k(rootfs),1600k(kernel),64k(nvram),64k(art)ro,7744k@0x50000(firmware) +all0258n_mtdlayout=mtdparts=spi0.0:256k(u-boot),64k(u-boot-env),1024k(kernel),5248k(rootfs),1536k(failsafe),64k(art),6272k@0x50000(firmware) +all0315n_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,256k(u-boot-env),1024k(kernel),12544k(rootfs),2048k(failsafe),256k(art)ro,13568k@0x80000(firmware) +ap96_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(u-boot-env)ro,6144k(rootfs),1728k(kernel),64k(art)ro,7872k@0x40000(firmware) +ap113_mtd_layout=mtdparts=spi0.0:64k(u-boot),3008k(rootfs),896k(uImage),64k(NVRAM),64k(ART),3904k@0x10000(firmware) +ap121_mtdlayout_2M=mtdparts=spi0.0:64k(u-boot)ro,1216k(rootfs),704k(kernel),64k(art)ro,1920k@0x10000(firmware) +ap121_mtdlayout_4M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,2752k(rootfs),896k(kernel),64k(nvram),64k(art)ro,3648k@0x50000(firmware) +ap136_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6336k(rootfs),1408k(kernel),64k(mib0),64k(art)ro,7744k@0x50000(firmware) +cameo7240_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(nvram)ro,960k(kernel),2752k(rootfs),64k(mac)ro,64k(art)ro,3712k@0x40000(firmware) +cameo913x_mtdlayout=mtdparts=spi0.0:128k(u-boot)ro,64k(config)ro,960k(kernel),2880k(rootfs),64k(art)ro,3840k@0x30000(firmware) +cameo933x_mtdlayout=mtdparts=spi0.0:64k(u-boot)ro,64k(art)ro,64k(mac)ro,64k(nvram)ro,192k(language)ro,896k(kernel),2752k(rootfs),3648k@0x70000(firmware) +db120_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6336k(rootfs),1408k(kernel),64k(nvram),64k(art)ro,7744k@0x50000(firmware) +dir825b1_mtdlayout=mtdparts=spi0.0:256k(uboot)ro,64k(config)ro,1024k(kernel),5184k(rootfs),64k(caldata)ro,1600k(unknown)ro,6208k@0x50000(firmware),64k@0x7f0000(caldata_copy) +dir825b1_mtdlayout_fat=mtdparts=spi0.0:256k(uboot)ro,64k(config)ro,1024k(kernel),6784k(rootfs),64k(caldata)ro,7808k@0x50000(firmware),64k@0x660000(caldata_orig),6208k@0x50000(firmware_orig) +ew-dorin_mtdlayout_4M=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env),1024k(kernel),2688k(rootfs),64k(art),3712k@0x50000(firmware) +pb92_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,2752k(rootfs),896k(kernel),64k(nvram),64k(art)ro,3648k@0x50000(firmware) +planex_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,960k(kernel),6784k(rootfs),128k(art)ro,7744k@0x50000(firmware) +ubntxm_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,1024k(kernel),6528k(rootfs),256k(cfg)ro,64k(EEPROM)ro,7552k@0x50000(firmware) +whrhpg300n_mtdlayout=mtdparts=spi0.0:248k(u-boot)ro,8k(u-boot-env)ro,960k(kernel),2816k(rootfs),64k(art)ro,3712k@0x40000(firmware) +wndr3700_mtdlayout=mtdparts=spi0.0:320k(u-boot)ro,128k(u-boot-env)ro,1024k(kernel),6656k(rootfs),64k(art)ro,7680k@0x70000(firmware) +wndr3700v2_mtdlayout=mtdparts=spi0.0:320k(u-boot)ro,128k(u-boot-env)ro,1024k(kernel),14848k(rootfs),64k(art)ro,15872k@0x70000(firmware) +zcn1523h_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6208k(rootfs),1472k(kernel),64k(configure)ro,64k(mfg)ro,64k(art)ro,7680k@0x50000(firmware) + +define Image/BuildKernel + cp $(KDIR)/vmlinux.elf $(VMLINUX).elf + cp $(KDIR)/vmlinux $(VMLINUX).bin + dd if=$(KDIR)/vmlinux.bin.lzma of=$(VMLINUX).lzma bs=65536 conv=sync + dd if=$(KDIR)/vmlinux.bin.gz of=$(VMLINUX).gz bs=65536 conv=sync + $(call MkuImage,gzip,,$(KDIR)/vmlinux.bin.gz,$(UIMAGE)-gzip.bin) + $(call MkuImage,lzma,,$(KDIR)/vmlinux.bin.lzma,$(UIMAGE)-lzma.bin) + -mkdir -p $(KDIR_TMP) + $(call Image/Build/Initramfs) +endef + +define Image/Build/WRT400N + $(call MkuImageLzma,$(2),$(3)) + $(call Sysupgrade/KRuImage,$(1),$(2),1310720,6488064) + if [ -e "$(call sysupname,$(1),$(2))" ]; then \ + wrt400n $(KDIR_TMP)/vmlinux-$(2).uImage $(KDIR)/root.$(1) $(call factoryname,$(1),$(2)); \ + fi +endef + +define Image/Build/DIR825B1 + $(call MkuImageLzma,$(2),$(3) $(dir825b1_mtdlayout)) + $(call Sysupgrade/KRuImage,$(1),$(2),1048576,5308416) + if [ -e "$(call sysupname,$(1),$(2))" ]; then \ + ( \ + dd if=$(call sysupname,$(1),$(2)); \ + echo -n "$(4)"; \ + ) > $(call imgname,$(1),$(2))-backup-loader.bin; \ + if [ `stat -c%s $(call sysupname,$(1),$(2))` -gt 4194304 ]; then \ + echo "Warning: $(call sysupname,$(1),$(2)) is too big"; \ + else \ + ( \ + dd if=$(call sysupname,$(1),$(2)) bs=4096k conv=sync; \ + echo -n "$(5)"; \ + ) > $(call factoryname,$(1),$(2)); \ + fi; \ + fi + $(call MkuImageLzma,$(2)-fat,$(3) $(dir825b1_mtdlayout_fat)) + $(call CatFiles,$(KDIR_TMP)/vmlinux-$(2)-fat.uImage,1048576,$(KDIR)/root.$(1),6946816,$(KDIR_TMP)/$(2)-fat.bin) + if [ -e "$(KDIR_TMP)/$(2)-fat.bin" ]; then \ + echo -n "" > $(KDIR_TMP)/$(2)-fat.dummy; \ + sh $(TOPDIR)/scripts/combined-image.sh \ + "$(KDIR_TMP)/$(2)-fat.bin" \ + "$(KDIR_TMP)/$(2)-fat.dummy" \ + $(call sysupname,$(1),$(2)-fat); \ + fi +endef + +define Image/Build/WZRHPG30XNH + $(call MkuImageLzma,$(2),$(3)) + $(call Sysupgrade/KRuImage,$(1),$(2),1048576,31850496) + if [ -e "$(call sysupname,$(1),$(2))" ]; then \ + ( \ + echo -n -e "# Airstation Public Fmt1\x00\x00\x00\x00\x00\x00\x00\x00"; \ + dd if=$(call sysupname,$(1),$(2)); \ + ) > $(call imgname,$(1),$(2))-tftp.bin; \ + buffalo-enc -p $(4) -v 1.99 \ + -i $(call sysupname,$(1),$(2)) \ + -o $(KDIR_TMP)/$(2).enc; \ + buffalo-tag -b $(4) -p $(4) -a ath -v 1.99 -m 1.01 -l mlang8 \ + -w 3 -c 0x80041000 -d 0x801e8000 -f 1 -r M_ \ + -i $(KDIR_TMP)/$(2).enc \ + -o $(call factoryname,$(1),$(2)); \ + fi +endef + +define Image/Build/WHRHPG300N + $(call MkuImageLzma,$(2),$(3) $(4)) + $(call Sysupgrade/KRuImage,$(1),$(2),983040,2883584) + if [ -e "$(call sysupname,$(1),$(2))" ]; then \ + ( \ + echo -n -e "# Airstation Public Fmt1\x00\x00\x00\x00\x00\x00\x00\x00"; \ + dd if=$(call sysupname,$(1),$(2)); \ + ) > $(call imgname,$(1),$(2))-tftp.bin; \ + buffalo-enc -p $(5) -v 1.99 \ + -i $(call sysupname,$(1),$(2)) \ + -o $(KDIR_TMP)/$(2).enc; \ + buffalo-tag -b $(5) -p $(5) -a ath -v 1.99 -m 1.01 -l mlang8 \ + -w 3 -c 0x80041000 -d 0x801e8000 -f 1 -r M_ \ + -i $(KDIR_TMP)/$(2).enc \ + -o $(call factoryname,$(1),$(2)); \ + fi +endef + +define Image/Build/WHRHPG300N/initramfs + $(call MkuImageLzma/initramfs,$(2),$(3) $(4)) +endef + +define Image/Build/Cameo + $(call MkuImageLzma,$(2),$(3) $(4)) + $(call Sysupgrade/KRuImage,$(1),$(2),$(5),$(6)) + if [ -e "$(call sysupname,$(1),$(2))" ]; then \ + ( \ + dd if=$(KDIR_TMP)/vmlinux-$(2).uImage bs=$(5) conv=sync; \ + dd if=$(KDIR)/root.$(1) bs=$(6) conv=sync; \ + echo -n $(7); \ + ) > $(call factoryname,$(1),$(2)); \ + fi +endef + +define Image/Build/CameoHornet + $(call MkuImageLzma,$(2),$(3) $(4)) + $(call Sysupgrade/KRuImage,$(1),$(2),$(5),$(6)) + if [ -e "$(call sysupname,$(1),$(2))" ]; then \ + mkcameofw -M HORNET -R "DEF" -S $(7) -V "1.99" \ + -K $(5) -I $$$$(($(5)+$(6))) \ + -k $(KDIR_TMP)/vmlinux-$(2).uImage \ + -r $(BIN_DIR)/$(IMG_PREFIX)-root.$(1) \ + -o $(call factoryname,$(1),$(2)); \ + fi +endef + +define Image/Build/Cameo913x + $(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo913x_mtdlayout),983040,2949120,$(4)) +endef + +define Image/Build/Cameo913x/initramfs + $(call MkuImageLzma/initramfs,$(2),$(3) $(cameo913x_mtdlayout)) +endef + +define Image/Build/Cameo7240 + $(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo7240_mtdlayout),983040,2818048,$(4)) +endef + +define Image/Build/Cameo7240/initramfs + $(call MkuImageLzma/initramfs,$(2),$(3) $(cameo7240_mtdlayout)) +endef + +define Image/Build/Cameo933x + $(call Image/Build/CameoHornet,$(1),$(2),$(3),$(cameo933x_mtdlayout),917504,2818048,$(4)) +endef + +define Image/Build/Cameo933x/initramfs + $(call MkuImageLzma/initramfs,$(2),$(3) $(cameo933x_mtdlayout)) +endef + +define Image/Build/Ath + $(call Sysupgrade/$(7),$(1),$(2),$(5),$(6)) + if [ -e "$(call sysupname,$(1),$(2))" ]; then \ + dd if=$(KDIR_TMP)/vmlinux-$(2).uImage \ + of=$(call imgname,kernel,$(2)).bin bs=64k conv=sync; \ + dd if=$(KDIR)/root.$(1) \ + of=$(call imgname,$(1),$(2)-rootfs).bin bs=128k conv=sync; \ + fi +endef + +define Image/Build/AthGzip + $(call MkuImageGzip,$(2),$(3) $(4)) + $(call Image/Build/Ath,$(1),$(2),$(3),$(4),$(5),$(6),$(7)) +endef + +define Image/Build/AthGzip/initramfs + $(call MkuImageGzip/initramfs,$(2),$(3) $(4)) +endef + +define Image/Build/AthLzma + $(call MkuImageLzma,$(2),$(3) $(4)) + $(call Image/Build/Ath,$(1),$(2),$(3),$(4),$(5),$(6),$(7)) +endef + +define Image/Build/AthLzma/initramfs + $(call MkuImageLzma/initramfs,$(2),$(3) $(4)) +endef + +define Image/Build/PB4X + $(call PatchKernelLzma,$(2),$(3)) + dd if=$(KDIR_TMP)/vmlinux-$(2).bin.lzma \ + of=$(call imgname,kernel,$(2)).bin bs=64k conv=sync + dd if=$(KDIR)/root.$(1) \ + of=$(call imgname,$(1),$(2)-rootfs).bin bs=128k conv=sync + -sh $(TOPDIR)/scripts/combined-image.sh \ + "$(call imgname,kernel,$(2)).bin" \ + "$(call imgname,$(1),$(2)-rootfs).bin" \ + $(call sysupname,$(1),$(2)) +endef + + +define Image/Build/MyLoader + $(call PatchKernelLzma,$(2),$(3)) + -$(STAGING_DIR_HOST)/bin/mkmylofw -B $(2) -s $(4) \ + -p0x030000:0xe0000:al:0x80060000:kernel:$(KDIR_TMP)/vmlinux-$(2).bin.lzma \ + -p0x110000:0:::rootfs:$(KDIR)/root.$(1) \ + $(call imgname,$(1),$(2))-$(5)-factory.img +endef + +define Image/Build/UBNTXM + $(call MkuImageLzma,$(2),$(3) $(ubntxm_mtdlayout)) + $(call Sysupgrade/KRuImage,$(1),$(2),1048576,6684672) + dd if=$(KDIR_TMP)/vmlinux-$(2).uImage of=$(KDIR_TMP)/vmlinux-$(2).uImage.bin bs=1024k conv=sync + -$(STAGING_DIR_HOST)/bin/mkfwimage \ + -B $(4) -v $(5).$(6).v6.0.0-OpenWrt-$(REVISION) \ + -k $(KDIR_TMP)/vmlinux-$(2).uImage.bin \ + -r $(BIN_DIR)/$(IMG_PREFIX)-root.$(1) \ + -o $(call factoryname,$(1),$(2)) +endef + +define Image/Build/UBNT + $(call PatchKernelLzma,$(2),$(3)) + dd if=$(KDIR_TMP)/vmlinux-$(2).bin.lzma of=$(KDIR_TMP)/vmlinux-$(2).lzma bs=64k conv=sync + -$(STAGING_DIR_HOST)/bin/mkfwimage \ + -B $(4) -v $(5).$(6).OpenWrt.$(REVISION) \ + -k $(KDIR_TMP)/vmlinux-$(2).lzma \ + -r $(BIN_DIR)/$(IMG_PREFIX)-root.$(1) \ + -o $(call factoryname,$(1),$(2)) + -sh $(TOPDIR)/scripts/combined-image.sh \ + "$(KDIR_TMP)/vmlinux-$(2).lzma" \ + "$(BIN_DIR)/$(IMG_PREFIX)-root.$(1)" \ + $(call sysupname,$(1),$(2)) +endef + +define Image/Build/Planex/loader + $(call Image/BuildLoaderAlone,$(1),gz,$(2) $(planex_mtdlayout),0x52000,0) +endef + +define Image/Build/Planex + [ -e "$(KDIR)/loader-$(2).gz" ] + $(call MkuImage,gzip,,$(KDIR)/loader-$(2).gz,$(KDIR_TMP)/vmlinux-$(2).uImage) + $(call MkuImageOKLI,$(2)) + ( \ + dd if=$(KDIR_TMP)/vmlinux-$(2).uImage bs=8k count=1 conv=sync; \ + dd if=$(KDIR_TMP)/vmlinux-$(2).okli; \ + ) > $(KDIR_TMP)/kernel-$(2).bin + $(call Sysupgrade/KR,$(1),$(KDIR_TMP)/kernel-$(2).bin,983040,6815744,$(2)) + if [ -e "$(call sysupname,$(1),$(2))" ]; then \ + $(STAGING_DIR_HOST)/bin/mkplanexfw \ + -B $(2) \ + -v 2.00.00 \ + -i $(call sysupname,$(1),$(2)) \ + -o $(call factoryname,$(1),$(2)); \ + fi +endef + +define Image/Build/ALFA + $(call MkuImageLzma,$(2),$(3) $(4)) + $(call Sysupgrade/RKuImage,$(1),$(2),$(5),$(6)) + if [ -e "$(call sysupname,$(1),$(2))" ]; then \ + rm -rf $(KDIR)/$(1); \ + mkdir -p $(KDIR)/$(1); \ + cd $(KDIR)/$(1); \ + cp $(KDIR_TMP)/vmlinux-$(2).uImage $(KDIR)/$(1)/$(7); \ + cp $(KDIR)/root.$(1) $(KDIR)/$(1)/$(8); \ + $(TAR) zcf $(call factoryname,$(1),$(2)) -C $(KDIR)/$(1) $(7) $(8); \ + ( \ + echo WRM7222C | dd bs=32 count=1 conv=sync; \ + echo -ne '\xfe'; \ + ) >> $(call factoryname,$(1),$(2)); \ + fi +endef + +define Image/Build/ALFA/initramfs + $(call MkuImageLzma/initramfs,$(2),$(3) $(4)) +endef + +define Image/Build/TPLINKOLD/loader + $(call Image/BuildLoaderAlone,$(1),gz,$(2),0x22000,0) +endef + +define Image/Build/TPLINKOLD + [ -e "$(KDIR)/loader-$(2).gz" ] + $(call MkuImageOKLI,$(2)) + ( \ + dd if=$(KDIR)/loader-$(2).gz bs=7680 count=1 conv=sync; \ + dd if=$(KDIR_TMP)/vmlinux-$(2).okli conv=sync; \ + ) > $(KDIR_TMP)/kernel-$(2).bin + -$(STAGING_DIR_HOST)/bin/mktplinkfw \ + -H $(4) -W $(5) -F $(6) -N OpenWrt -V $(REVISION)\ + -k $(KDIR_TMP)/kernel-$(2).bin \ + -r $(KDIR)/root.$(1) \ + -o $(call factoryname,$(1),$(2)) + -$(STAGING_DIR_HOST)/bin/mktplinkfw \ + -H $(4) -W $(5) -F $(6) -N OpenWrt -V $(REVISION) -s\ + -k $(KDIR_TMP)/kernel-$(2).bin \ + -r $(KDIR)/root.$(1) \ + -o $(call sysupname,$(1),$(2)) +endef + +define Image/Build/TPLINKOLD/initramfs + $(call Image/BuildLoader,$(2),gz,$(3),0x80060000) + -$(STAGING_DIR_HOST)/bin/mktplinkfw -c \ + -H $(4) -W $(5) -F $(6) -N OpenWrt -V $(REVISION) -s\ + -k $(KDIR)/loader-$(2).gz \ + -o $(call imgname,$(1),$(2))-uImage.bin +endef + +define Image/Build/TPLINK/loader + $(call Image/BuildLoaderAlone,$(1),gz,$(2),0x22000,0) +endef + +define Image/Build/TPLINK + [ -e "$(KDIR)/loader-$(2).gz" ] + $(call MkuImageOKLI,$(2)) + ( \ + dd if=$(KDIR)/loader-$(2).gz bs=7680 count=1 conv=sync; \ + dd if=$(KDIR_TMP)/vmlinux-$(2).okli conv=sync; \ + ) > $(KDIR_TMP)/kernel-$(2).bin + -$(STAGING_DIR_HOST)/bin/mktplinkfw \ + -H $(4) -W $(5) -F $(6) -N OpenWrt -V $(REVISION)\ + -k $(KDIR_TMP)/kernel-$(2).bin \ + -r $(KDIR)/root.$(1) \ + -a $(call rootfs_align,$(1)) -j \ + -o $(call factoryname,$(1),$(2)) + -$(STAGING_DIR_HOST)/bin/mktplinkfw \ + -H $(4) -W $(5) -F $(6) -N OpenWrt -V $(REVISION) -s\ + -k $(KDIR_TMP)/kernel-$(2).bin \ + -r $(KDIR)/root.$(1) \ + -a $(call rootfs_align,$(1)) -j \ + -o $(call sysupname,$(1),$(2)) +endef + +define Image/Build/TPLINK/initramfs + $(call Image/BuildLoader,$(2),gz,$(3),0x80060000) + -$(STAGING_DIR_HOST)/bin/mktplinkfw -c \ + -H $(4) -W $(5) -F $(6) -N OpenWrt -V $(REVISION) -s\ + -k $(KDIR)/loader-$(2).gz \ + -o $(call imgname,$(1),$(2))-uImage.bin +endef + +define Image/Build/TPLINK-LZMA + $(call PatchKernelLzma,$(2),$(3)) + -$(STAGING_DIR_HOST)/bin/mktplinkfw \ + -H $(4) -W $(5) -F $(6) -N OpenWrt -V $(REVISION) $(7) \ + -k $(KDIR_TMP)/vmlinux-$(2).bin.lzma \ + -r $(KDIR)/root.$(1) \ + -a $(call rootfs_align,$(1)) -j \ + -o $(call factoryname,$(1),$(2)) + -$(STAGING_DIR_HOST)/bin/mktplinkfw \ + -H $(4) -W $(5) -F $(6) -N OpenWrt -V $(REVISION) $(7) -s \ + -k $(KDIR_TMP)/vmlinux-$(2).bin.lzma \ + -r $(KDIR)/root.$(1) \ + -a $(call rootfs_align,$(1)) -j \ + -o $(call sysupname,$(1),$(2)) +endef + +define Image/Build/TPLINK-LZMA/initramfs + $(call PatchKernelLzma,$(2),$(3)) + -$(STAGING_DIR_HOST)/bin/mktplinkfw -c \ + -H $(4) -W $(5) -F $(6) -N OpenWrt -V $(REVISION) $(7) -s \ + -k $(KDIR_TMP)/vmlinux-$(2).bin.lzma \ + -o $(call imgname,$(1),$(2))-uImage.bin +endef + +define Image/Build/CyberTAN + $(call MkuImageGzip,$(2),$(3)) + $(STAGING_DIR_HOST)/bin/trx -o $(KDIR)/image.tmp -f $(KDIR_TMP)/vmlinux-$(2).uImage \ + -x 32 -a 0x10000 -x -32 -f $(KDIR)/root.$(1) + -$(STAGING_DIR_HOST)/bin/addpattern -B $(2) -v v$(4) \ + -i $(KDIR)/image.tmp \ + -o $(call sysupname,$(1),$(2)) + -$(STAGING_DIR_HOST)/bin/addpattern -B $(2) -v v$(4) -g \ + -i $(KDIR)/image.tmp \ + -o $(call factoryname,$(1),$(2)) + rm $(KDIR)/image.tmp +endef + +define Image/Build/Netgear/Build_uImage + $(call MkuImageLzma,$(1),$(2) $(3)) + -rm -rf $(KDIR)/$(1) + mkdir -p $(KDIR)/$(1)/image + $(STAGING_DIR_HOST)/bin/wndr3700 \ + $(KDIR_TMP)/vmlinux-$(1).uImage \ + $(KDIR)/$(1)/image/uImage \ + $(4) + $(STAGING_DIR_HOST)/bin/mksquashfs-lzma \ + $(KDIR)/$(1) $(KDIR_TMP)/vmlinux-$(1).uImage.squashfs.tmp \ + -nopad -noappend -root-owned -be + -rm -rf $(KDIR)/$(1) + mkimage -A mips -O linux -T filesystem -C none \ + -a 0xbf070000 -e 0xbf070000 \ + -n 'MIPS OpenWrt Linux-$(LINUX_VERSION)' \ + -d $(KDIR_TMP)/vmlinux-$(1).uImage.squashfs.tmp \ + $(KDIR_TMP)/vmlinux-$(1).uImage.squashfs.tmp2 + $(STAGING_DIR_HOST)/bin/wndr3700 \ + $(KDIR_TMP)/vmlinux-$(1).uImage.squashfs.tmp2 \ + $(KDIR_TMP)/vmlinux-$(1).uImage.squashfs \ + $(4) + -rm -f $(KDIR_TMP)/vmlinux-$(1).uImage.squashfs.tmp* +endef + +define Image/Build/Netgear/Estimate_uImage + $(call Image/Build/Netgear/Build_uImage,$(1)_est,$(2),$(3),$(4)) + ( \ + set -e; \ + kk=`echo '$(3)' | sed -e 's/.*[:,]\([0-9]*\)k(kernel).*/\1/'`; \ + rk=`echo '$(3)' | sed -e 's/.*[:,]\([0-9]*\)k(rootfs).*/\1/'`; \ + let 'tk = kk + rk'; \ + s=`stat -c'%s' '$(KDIR_TMP)/vmlinux-$(1)_est.uImage.squashfs'`; \ + c=`echo '$(3)' | wc -c`; \ + let 'kk = (((s + c) / (64 * 1024) + 1) * 64)'; \ + let 'rk = tk - kk'; \ + echo '$(3)' | sed -e "s/[0-9]*k(kernel)/$$$${kk}k(kernel)/" \ + -e "s/[0-9]*k(rootfs)/$$$${rk}k(rootfs)/" > \ + '$(KDIR_TMP)/$(1)_mtdparts'; \ + let 'k = kk * 1024'; \ + echo "$$$${k}" > '$(KDIR_TMP)/$(1)_kernel_maxsize'; \ + let 'r = rk * 1024'; \ + echo "$$$${r}" > '$(KDIR_TMP)/$(1)_rootfs_maxsize'; \ + ) + -rm -f $(KDIR_TMP)/vmlinux-$(1)_est \ + $(KDIR_TMP)/vmlinux-$(1)_est.bin.lzma \ + $(KDIR_TMP)/vmlinux-$(1)_est.uImage \ + $(KDIR_TMP)/vmlinux-$(1)_est.uImage.squashfs +endef + +define Image/Build/Netgear + $(call Image/Build/Netgear/Estimate_uImage,$(2),$(3),$(4),$(5)) + $(call Image/Build/Netgear/Build_uImage,$(2),$(3),`cat $(KDIR_TMP)/$(2)_mtdparts`,$(5)) + if [ `stat -c%s '$(KDIR_TMP)/vmlinux-$(2).uImage.squashfs'` -gt \ + `cat '$(KDIR_TMP)/$(2)_kernel_maxsize'` ]; then \ + echo "$(KDIR_TMP)/vmlinux-$(2).uImage.squashfs is too big" >& 2; \ + else if [ `stat -c%s '$(KDIR)/root.$(1)'` -gt \ + `cat '$(KDIR_TMP)/$(2)_rootfs_maxsize'` ]; then \ + echo "$(KDIR)/root.$(1) is too big" >& 2; \ + else \ + ( \ + set -e; \ + dd if=$(KDIR_TMP)/vmlinux-$(2).uImage.squashfs \ + bs=`cat '$(KDIR_TMP)/$(2)_kernel_maxsize'` conv=sync; \ + dd if=$(KDIR)/root.$(1) bs=64k; \ + ) > $(call sysupname,$(1),$(2)); \ + for r in $(7) ; do \ + [ -n "$$$$r" ] && dashr="-$$$$r" || dashr= ; \ + $(STAGING_DIR_HOST)/bin/mkdniimg \ + -B $(6) -v OpenWrt.$(REVISION) -r "$$$$r" $(8) \ + -i $(call sysupname,$(1),$(2)) \ + -o $(call imgname,$(1),$(2))-factory$$$$dashr.img; \ + done; \ + fi; fi +endef + +define Image/Build/Netgear/initramfs + $(call MkuImageLzma,$(2),$(3) $(4)) + $(STAGING_DIR_HOST)/bin/wndr3700 \ + $(KDIR_TMP)/vmlinux-$(2).uImage \ + $(call imgname,$(1),$(2))-uImage.bin \ + $(5) +endef + +ifdef CONFIG_PACKAGE_uboot-ar71xx-nbg460n_550n_550nh + define Image/Build/ZyXEL + $(call MkuImageLzma,$(2),$(3)) + $(call Sysupgrade/KRuImage,$(1),$(2),917504,2752512) + if [ -e "$(call sysupname,$(1),$(2))" ]; then \ + if [ ! -f $(BIN_DIR)/$(IMG_PREFIX)-$(2)-u-boot.bin ]; then \ + echo "Warning: $(IMG_PREFIX)-$(2)-u-boot.bin not found"; \ + else \ + $(STAGING_DIR_HOST)/bin/mkzynfw \ + -B $(4) \ + -b $(BIN_DIR)/$(IMG_PREFIX)-$(2)-u-boot.bin \ + -r $(call sysupname,$(1),$(2)):0x10000 \ + -o $(call factoryname,$(1),$(2)); \ + fi; fi + endef +endif + +define Image/Build/OpenMesh + $(call MkuImageLzma,$(2)) + -sh $(TOPDIR)/scripts/om2p-fwupgradecfg-gen.sh \ + "$(BUILD_DIR)/om2p-fwupgrade.cfg" \ + "$(KDIR_TMP)/vmlinux-$(2).uImage" \ + "$(KDIR)/root.$(1)" + -sh $(TOPDIR)/scripts/combined-ext-image.sh \ + "$(3)" "$(call factoryname,$(1),$(2))" \ + "$(BUILD_DIR)/om2p-fwupgrade.cfg" "fwupgrade.cfg" \ + "$(KDIR_TMP)/vmlinux-$(2).uImage" "kernel" \ + "$(KDIR)/root.$(1)" "rootfs" +endef + +define Image/Build/Zcomax + $(call MkuImageLzma,$(2),$(3)) + $(call Sysupgrade/RKuImage,$(1),$(2),1507328,6356992) + if [ -e "$(call sysupname,$(1),$(2))" ]; then \ + $(STAGING_DIR_HOST)/bin/mkzcfw \ + -B $(2) \ + -k $(KDIR_TMP)/vmlinux-$(2).uImage \ + -r $(BIN_DIR)/$(IMG_PREFIX)-root.$(1) \ + -o $(call imgname,$(1),$(2))-factory.img; \ + fi +endef + +define Image/Build/Zcomax/initramfs + $(call MkuImageLzma/initramfs,$(2),$(3)) +endef + +define Image/Build/Template/initramfs/initramfs + $(call Image/Build/$(1)/initramfs,initramfs,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/all/squashfs + $(call Image/Build/$(1),squashfs,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/all/jffs2-64k + $(call Image/Build/$(1),jffs2-64k,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/all/jffs2-128k + $(call Image/Build/$(1),jffs2-128k,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/all/jffs2-256k + $(call Image/Build/$(1),jffs2-256k,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/squashfs-only/loader + $(call Image/Build/$(1)/loader,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/squashfs-only/squashfs + $(call Image/Build/$(1),squashfs,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/64k/loader + $(call Image/Build/$(1)/loader,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/64k/squashfs + $(call Image/Build/$(1),squashfs-64k,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/64k/jffs2-64k + $(call Image/Build/$(1),jffs2-64k,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/64kraw/loader + $(call Image/Build/$(1)/loader,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/64kraw/squashfs + $(call Image/Build/$(1),squashfs-raw,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/64kraw/jffs2-64k + $(call Image/Build/$(1),jffs2-64k,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/128k/squashfs + $(call Image/Build/$(1),squashfs,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/128k/jffs2-128k + $(call Image/Build/$(1),jffs2-128k,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/256k/squashfs + $(call Image/Build/$(1),squashfs,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +define Image/Build/Template/256k/jffs2-256k + $(call Image/Build/$(1),jffs2-256k,$(2),$(3),$(4),$(5),$(6),$(7),$(8)) +endef + +$(eval $(call SingleProfile,ALFA,$(fs_64k),ALFANX,alfa-nx,ALFA-NX,ttyS0,115200,$$(alfa_mtdlayout_8M),1638400,6291456,vmlinux.gz.uImage,pb9x-2.6.31-jffs2)) +$(eval $(call SingleProfile,ALFA,$(fs_64k),HORNETUB,hornet-ub,HORNET-UB,ttyATH0,115200,$$(alfa_mtdlayout_8M),1638400,6291456,kernel_image,rootfs_image)) + +$(eval $(call SingleProfile,AthGzip,$(fs_64k),AP81,ap81,AP81,ttyS0,115200,,1310720,6619136,KRuImage)) +$(eval $(call SingleProfile,AthGzip,$(fs_64k),AP83,ap83,AP83,ttyS0,115200,,1310720,6619136,KRuImage)) +$(eval $(call SingleProfile,AthGzip,$(fs_64k),AP96,ap96,AP96,ttyS0,115200,$$(ap96_mtdlayout),1769472,6291456,RKuImage)) + +$(eval $(call SingleProfile,AthLzma,$(fs_64k),ALFAAP96,alfa-ap96,ALFA-AP96,ttyS0,115200,$$(alfa_ap96_mtdlayout),2097152,13631488,RKuImage)) +$(eval $(call SingleProfile,AthLzma,$(fs_64k),ALL0258N,all0258n,ALL0258N,ttyS0,115200,$$(all0258n_mtdlayout),1048576,5373952,KRuImage)) +$(eval $(call SingleProfile,AthLzma,$(fs_256k),ALL0315N,all0315n,ALL0315N,ttyS0,115200,$$(all0315n_mtdlayout),1048576,12845056,KRuImage)) +$(eval $(call SingleProfile,AthLzma,$(fs_64k),AP113,ap113,AP113,ttyS0,115200,$$(ap113_mtd_layout),917504,3080192,RK)) +$(eval $(call SingleProfile,AthLzma,$(fs_64k),AP121_2M,ap121-2M,AP121,ttyATH0,115200,$$(ap121_mtdlayout_2M),720896,1245184,RKuImage)) +$(eval $(call SingleProfile,AthLzma,$(fs_64k),AP121_4M,ap121-4M,AP121,ttyATH0,115200,$$(ap121_mtdlayout_4M),917504,2818048,RKuImage)) +$(eval $(call SingleProfile,AthLzma,$(fs_64k),AP121MINI,ap121-mini,AP121-MINI,ttyATH0,115200,$$(ap121_mtdlayout_4M),917504,2818048,RKuImage)) +$(eval $(call SingleProfile,AthLzma,$(fs_64k),AP136,ap136,AP136,ttyS0,115200,$$(ap136_mtdlayout),1441792,6488064,RKuImage)) +$(eval $(call SingleProfile,AthLzma,$(fs_64k),DB120,db120,DB120,ttyS0,115200,$$(db120_mtdlayout),1441792,6488064,RKuImage)) +$(eval $(call SingleProfile,AthLzma,$(fs_64k),EWDORINAP,ew-dorin,EW-DORIN,ttyATH0,115200,$$(ew-dorin_mtdlayout_4M),1048576,2752512,KRuImage)) +$(eval $(call SingleProfile,AthLzma,$(fs_64k),EWDORINRT,ew-dorin-router,EW-DORIN-ROUTER,ttyATH0,115200,$$(ew-dorin_mtdlayout_4M),1048576,2752512,KRuImage)) +$(eval $(call SingleProfile,AthLzma,$(fs_64k),PB92,pb92,PB92,ttyS0,115200,$$(pb92_mtdlayout),917504,2818048,KRuImage)) + +$(eval $(call SingleProfile,Cameo7240,$(fs_64k),DIR600A1,dir-600-a1,DIR-600-A1,ttyS0,115200,"AP91-AR7240-RT-090223-00")) +$(eval $(call SingleProfile,Cameo7240,$(fs_64k),DIR601A1,dir-601-a1,DIR-600-A1,ttyS0,115200,"AP91-AR7240-RT-090223-02")) +$(eval $(call SingleProfile,Cameo7240,$(fs_64k),DIR615E4,dir-615-e4,DIR-615-E4,ttyS0,115200,"AP99-AR7240-RT-091105-05")) +$(eval $(call SingleProfile,Cameo7240,$(fs_64k),FR54RTR,fr-54rtr,DIR-600-A1,ttyS0,115200,"AP91-AR7240-RT-090223-01")) + +$(eval $(call SingleProfile,Cameo913x,$(fs_squash),A02RBW300N,a02-rb-w300n,TEW-632BRP,ttyS0,115200,"AP81-AR9130-RT-070614-03")) +$(eval $(call SingleProfile,Cameo913x,$(fs_squash),DIR615C1,dir-615-c1,DIR-615-C1,ttyS0,115200,"AP81-AR9130-RT-070614-02")) +$(eval $(call SingleProfile,Cameo913x,$(fs_squash),TEW632BRP,tew-632brp,TEW-632BRP,ttyS0,115200,"AP81-AR9130-RT-070614-00")) +$(eval $(call SingleProfile,Cameo913x,$(fs_squash),TEW652BRP_FW,tew-652brp,TEW-632BRP,ttyS0,115200,"AP81-AR9130-RT-080609-05")) +$(eval $(call SingleProfile,Cameo913x,$(fs_squash),TEW652BRP_RECOVERY,tew-652brp-recovery,TEW-632BRP,ttyS0,115200,"AP81-AR9130-RT-070614-02")) + +$(eval $(call SingleProfile,Cameo933x,$(fs_squash),TEW712BR,tew-712br,TEW-712BR,ttyATH0,115200,"HORNET-RT-TEW712BR-3")) + +$(eval $(call SingleProfile,CyberTAN,$(fs_64k),WRT160NL,wrt160nl,WRT160NL,ttyS0,115200,1.00.01)) + +$(eval $(call SingleProfile,DIR825B1,$(fs_64k),DIR825B1,dir-825-b1,DIR-825-B1,ttyS0,115200,01AP94-AR7161-RT-080619-00,00AP94-AR7161-RT-080619-00)) +$(eval $(call SingleProfile,DIR825B1,$(fs_64k),TEW673GRU,tew-673gru,TEW-673GRU,ttyS0,115200,01AP94-AR7161-RT-080619-01,00AP94-AR7161-RT-080619-01)) + +$(eval $(call SingleProfile,MyLoader,$(fs_64k),WP543_2M,wp543,,ttyS0,115200,0x200000,2M)) +$(eval $(call SingleProfile,MyLoader,$(fs_64k),WP543_4M,wp543,,ttyS0,115200,0x400000,4M)) +$(eval $(call SingleProfile,MyLoader,$(fs_64k),WP543_8M,wp543,,ttyS0,115200,0x800000,8M)) +$(eval $(call SingleProfile,MyLoader,$(fs_64k),WP543_16M,wp543,,ttyS0,115200,0x1000000,16M)) +$(eval $(call SingleProfile,MyLoader,$(fs_64k),WPE72,wpe72,,ttyS0,115200,0x800000,8M)) + +$(eval $(call SingleProfile,Netgear,$(fs_64k),WNDR3700V1,wndr3700,WNDR3700,ttyS0,115200,$$(wndr3700_mtdlayout),3700,WNDR3700,"" NA,)) +$(eval $(call SingleProfile,Netgear,$(fs_64k),WNDR3700V2,wndr3700v2,WNDR3700,ttyS0,115200,$$(wndr3700v2_mtdlayout),3701,WNDR3700v2,"",-H 29763654+16+64)) +$(eval $(call SingleProfile,Netgear,$(fs_64k),WNDR3800,wndr3800,WNDR3700,ttyS0,115200,$$(wndr3700v2_mtdlayout),3701,WNDR3800,"",-H 29763654+16+128)) +$(eval $(call SingleProfile,Netgear,$(fs_64k),WNDRMAC,wndrmac,WNDR3700,ttyS0,115200,$$(wndr3700v2_mtdlayout),3701,WNDRMAC,"",-H 29763654+16+64)) +$(eval $(call SingleProfile,Netgear,$(fs_64k),WNDRMACV2,wndrmacv2,WNDR3700,ttyS0,115200,$$(wndr3700v2_mtdlayout),3701,WNDRMACv2,"",-H 29763654+16+128)) + +$(eval $(call SingleProfile,OpenMesh,$(fs_squash),OM2P,om2p,OM2P)) + +$(eval $(call SingleProfile,PB4X,$(fs_128k),ALL0305,all0305,ALL0305,ttyS0,115200)) +$(eval $(call SingleProfile,PB4X,$(fs_128k),EAP7660D,eap7660d,EAP7660D,ttyS0,115200)) +$(eval $(call SingleProfile,PB4X,$(fs_64k),JA76PF,ja76pf,JA76PF,ttyS0,115200)) +$(eval $(call SingleProfile,PB4X,$(fs_64k),JA76PF2,ja76pf2,JA76PF2,ttyS0,115200)) +$(eval $(call SingleProfile,PB4X,$(fs_64k),JWAP003,jwap003,JWAP003,ttyS0,115200)) +$(eval $(call SingleProfile,PB4X,$(fs_64k),PB42,pb42,PB42,ttyS0,115200)) +$(eval $(call SingleProfile,PB4X,$(fs_64k),PB44,pb44,PB44,ttyS0,115200)) + +$(eval $(call SingleProfile,Planex,$(fs_64k),MZKW04NU,mzk-w04nu,MZK-W04NU,ttyS0,115200)) +$(eval $(call SingleProfile,Planex,$(fs_64k),MZKW300NH,mzk-w300nh,MZK-W300NH,ttyS0,115200)) + +$(eval $(call SingleProfile,TPLINKOLD,$(fs_squash),TLWR841NV15,tl-wr841nd-v1.5,TL-WR841N-v1.5,ttyS0,115200,0x08410002,2,4M)) + +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLMR3220,tl-mr3220-v1,TL-MR3220,ttyS0,115200,0x32200001,1,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLMR3420,tl-mr3420-v1,TL-MR3420,ttyS0,115200,0x34200001,1,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWA701,tl-wa701n-v1,TL-WA901ND,ttyS0,115200,0x07010001,1,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWA901NV1,tl-wa901nd-v1,TL-WA901ND,ttyS0,115200,0x09010001,1,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWA901NV2,tl-wa901nd-v2,TL-WA901ND-v2,ttyS0,115200,0x09010002,1,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR740NV1,tl-wr740n-v1,TL-WR741ND,ttyS0,115200,0x07400001,1,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR740NV3,tl-wr740n-v3,TL-WR741ND,ttyS0,115200,0x07400003,1,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR741NV1,tl-wr741nd-v1,TL-WR741ND,ttyS0,115200,0x07410001,1,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR741NV2,tl-wr741nd-v2,TL-WR741ND,ttyS0,115200,0x07410001,1,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR743,tl-wr743nd-v1,TL-WR741ND,ttyS0,115200,0x07430001,1,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR841NV3,tl-wr841nd-v3,TL-WR941ND,ttyS0,115200,0x08410003,3,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR841NV5,tl-wr841nd-v5,TL-WR741ND,ttyS0,115200,0x08410005,1,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR841NV7,tl-wr841nd-v7,TL-WR841N-v7,ttyS0,115200,0x08410007,1,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR842,tl-wr842n-v1,TL-MR3420,ttyS0,115200,0x08420001,1,8M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR941NV2,tl-wr941nd-v2,TL-WR941ND,ttyS0,115200,0x09410002,2,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR941NV3,tl-wr941nd-v3,TL-WR941ND,ttyS0,115200,0x09410002,2,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR941NV4,tl-wr941nd-v4,TL-WR741ND,ttyS0,115200,0x09410004,1,4M)) +$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR1043,tl-wr1043nd-v1,TL-WR1043ND,ttyS0,115200,0x10430001,1,8M)) + +$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLMR11U,tl-mr11u-v1,TL-MR11U,ttyATH0,115200,0x00110101,1,4Mlzma)) +$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLMR3020,tl-mr3020-v1,TL-MR3020,ttyATH0,115200,0x30200001,1,4Mlzma)) +$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLMR3040,tl-mr3040-v1,TL-MR3040,ttyATH0,115200,0x30400001,1,4Mlzma)) +$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLWR703,tl-wr703n-v1,TL-WR703N,ttyATH0,115200,0x07030101,1,4Mlzma)) +$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLWR740NV4,tl-wr740n-v4,TL-WR741ND-v4,ttyATH0,115200,0x07400004,1,4Mlzma)) +$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLWR741NV4,tl-wr741nd-v4,TL-WR741ND-v4,ttyATH0,115200,0x07410004,1,4Mlzma)) +$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLWR841NV8,tl-wr841n-v8,TL-WR841N-v8,ttyS0,115200,0x08410008,1,4Mlzma)) +$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLWR1041,tl-wr1041n-v2,TL-WR1041N-v2,ttyS0,115200,0x10410002,1,4Mlzma)) +$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLWR2543,tl-wr2543-v1,TL-WR2543N,ttyS0,115200,0x25430001,1,8Mlzma,-v 3.13.99)) +$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLWDR3600V1,tl-wdr3600-v1,TL-WDR4300,ttyS0,115200,0x36000001,1,8Mlzma)) +$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLWDR4300V1,tl-wdr4300-v1,TL-WDR4300,ttyS0,115200,0x43000001,1,8Mlzma)) +$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLWDR4310V1,tl-wdr4310-v1,TL-WDR4300,ttyS0,115200,0x43100001,1,8Mlzma)) + +$(eval $(call SingleProfile,UBNT,$(fs_64k),UBNTRS,ubnt-rs,UBNT-RS,ttyS0,115200,RS,RSx,ar7100)) +$(eval $(call SingleProfile,UBNT,$(fs_64k),UBNTRSPRO,ubnt-rspro,UBNT-RSPRO,ttyS0,115200,RSPRO,RSPRO,ar7100pro)) +$(eval $(call SingleProfile,UBNT,$(fs_64k),UBNTLSSR71,ubnt-ls-sr71,UBNT-LS-SR71,ttyS0,115200,LS-SR71,LS-SR71,ar7100)) + +$(eval $(call SingleProfile,UBNTXM,$(fs_64k),RW2458N,rw2458n,RW2458N,ttyS0,115200,XM,XM,ar7240)) +$(eval $(call SingleProfile,UBNTXM,$(fs_64k),UBNTAIRROUTER,ubnt-airrouter,UBNT-AR,ttyS0,115200,XM,XM,ar7240)) +$(eval $(call SingleProfile,UBNTXM,$(fs_64k),UBNTBULLETM,ubnt-bullet-m,UBNT-BM,ttyS0,115200,XM,XM,ar7240)) +$(eval $(call SingleProfile,UBNTXM,$(fs_64k),UBNTROCKETM,ubnt-rocket-m,UBNT-RM,ttyS0,115200,XM,XM,ar7240)) +$(eval $(call SingleProfile,UBNTXM,$(fs_64k),UBNTNANOM,ubnt-nano-m,UBNT-NM,ttyS0,115200,XM,XM,ar7240)) +$(eval $(call SingleProfile,UBNTXM,$(fs_64k),UBNTUNIFI,ubnt-unifi,UBNT-UF,ttyS0,115200,XM,XM,ar7240)) + +$(eval $(call SingleProfile,WHRHPG300N,$(fs_64k),WHRG301N,whr-g301n,WHR-G301N,ttyS0,115200,$$(whrhpg300n_mtdlayout),WHR-G301N)) +$(eval $(call SingleProfile,WHRHPG300N,$(fs_64k),WHRHPG300N,whr-hp-g300n,WHR-HP-G300N,ttyS0,115200,$$(whrhpg300n_mtdlayout),WHR-HP-G300N)) +$(eval $(call SingleProfile,WHRHPG300N,$(fs_64k),WHRHPGN,whr-hp-gn,WHR-HP-GN,ttyS0,115200,$$(whrhpg300n_mtdlayout),WHR-HP-GN)) +$(eval $(call SingleProfile,WHRHPG300N,$(fs_64k),WLAEAG300N,wlae-ag300n,WLAE-AG300N,ttyS0,115200,$$(whrhpg300n_mtdlayout),WLAE-AG300N)) + +$(eval $(call SingleProfile,WRT400N,$(fs_64k),WRT400N,wrt400n,WRT400N,ttyS0,115200)) + +$(eval $(call SingleProfile,WZRHPG30XNH,$(fs_128k),WZRHPG300NH,wzr-hp-g300nh,WZR-HP-G300NH,ttyS0,115200,WZR-HP-G300NH)) +$(eval $(call SingleProfile,WZRHPG30XNH,$(fs_64k),WZRHPG300NH2,wzr-hp-g300nh2,WZR-HP-G300NH2,ttyS0,115200,WZR-HP-G300NH2)) +$(eval $(call SingleProfile,WZRHPG30XNH,$(fs_64k),WZRHPAG300H,wzr-hp-ag300h,WZR-HP-AG300H,ttyS0,115200,WZR-HP-AG300H)) +$(eval $(call SingleProfile,WZRHPG30XNH,$(fs_64k),WZRHPG450H,wzr-hp-g450h,WZR-HP-G450H,ttyS0,115200,WZR-HP-AG450H)) + +$(eval $(call SingleProfile,Zcomax,$(fs_64k),ZCN1523H28,zcn-1523h-2-8,ZCN-1523H-2,ttyS0,115200,$$(zcn1523h_mtdlayout))) +$(eval $(call SingleProfile,Zcomax,$(fs_64k),ZCN1523H516,zcn-1523h-5-16,ZCN-1523H-5,ttyS0,115200,$$(zcn1523h_mtdlayout))) + +$(eval $(call SingleProfile,ZyXEL,$(fs_64k),NBG_460N_550N_550NH,nbg460n_550n_550nh,NBG460N,ttyS0,115200,NBG-460N)) + + +$(eval $(call MultiProfile,AP121,AP121_2M AP121_4M)) +$(eval $(call MultiProfile,EWDORIN, EWDORINAP EWDORINRT)) +$(eval $(call MultiProfile,TEW652BRP,TEW652BRP_FW TEW652BRP_RECOVERY)) +$(eval $(call MultiProfile,TLWA901,TLWA901NV1 TLWA901NV2)) +$(eval $(call MultiProfile,TLWR740,TLWR740NV1 TLWR740NV3 TLWR740NV4)) +$(eval $(call MultiProfile,TLWR741,TLWR741NV1 TLWR741NV2 TLWR741NV4)) +$(eval $(call MultiProfile,TLWR841,TLWR841NV15 TLWR841NV3 TLWR841NV5 TLWR841NV7 TLWR841NV8)) +$(eval $(call MultiProfile,TLWR941,TLWR941NV2 TLWR941NV3 TLWR941NV4)) +$(eval $(call MultiProfile,TLWDR4300,TLWDR3600V1 TLWDR4300V1 TLWDR4310V1)) +$(eval $(call MultiProfile,UBNT,UBNTAIRROUTER UBNTRS UBNTRSPRO UBNTLSSR71 UBNTBULLETM UBNTROCKETM UBNTNANOM UBNTUNIFI)) +$(eval $(call MultiProfile,WNDR3700,WNDR3700V1 WNDR3700V2 WNDR3800 WNDRMAC WNDRMACV2)) +$(eval $(call MultiProfile,WP543,WP543_2M WP543_4M WP543_8M WP543_16M)) + +$(eval $(call MultiProfile,Default,$(SINGLE_PROFILES))) +$(eval $(call MultiProfile,Minimal,$(SINGLE_PROFILES))) +$(eval $(call MultiProfile,Madwifi,EAP7660D UBNTRS UBNTRSPRO UBNTLSSR71 WP543)) + +define Image/Build/squashfs + cp $(KDIR)/root.squashfs $(KDIR)/root.squashfs-raw + cp $(KDIR)/root.squashfs $(KDIR)/root.squashfs-64k + $(STAGING_DIR_HOST)/bin/padjffs2 $(KDIR)/root.squashfs-64k 64 + cp $(KDIR)/root.squashfs-64k $(BIN_DIR)/$(IMG_PREFIX)-root.squashfs-64k + $(call prepare_generic_squashfs,$(KDIR)/root.squashfs) +endef + +define Image/Build/Initramfs + $(call Image/Build/Profile/$(PROFILE),initramfs) +endef + +define Image/Prepare + gzip -9 -c $(KDIR)/vmlinux > $(KDIR)/vmlinux.bin.gz + $(call CompressLzma,$(KDIR)/vmlinux,$(KDIR)/vmlinux.bin.lzma) + $(call Image/Build/Profile/$(if $(CONFIG_IB),Default,$(PROFILE)),loader) +endef + +define Image/Build + $(call Image/Build/$(1)) + dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-root.$(1) bs=128k conv=sync + $(call Image/Build/Profile/$(PROFILE),$(1)) +endef + +$(eval $(call BuildImage)) diff --git a/target/linux/ar71xx/image/lzma-loader/Makefile b/target/linux/ar71xx/image/lzma-loader/Makefile new file mode 100644 index 000000000..2e0b9111f --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/Makefile @@ -0,0 +1,64 @@ +# +# Copyright (C) 2011 OpenWrt.org +# Copyright (C) 2011 Gabor Juhos +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +LZMA_TEXT_START := 0x80a00000 +LOADER := loader.bin +LOADER_NAME := $(basename $(notdir $(LOADER))) +LOADER_DATA := +TARGET_DIR := +FLASH_OFFS := +FLASH_MAX := +BOARD := + +ifeq ($(TARGET_DIR),) +TARGET_DIR := $(KDIR) +endif + +LOADER_BIN := $(TARGET_DIR)/$(LOADER_NAME).bin +LOADER_GZ := $(TARGET_DIR)/$(LOADER_NAME).gz +LOADER_ELF := $(TARGET_DIR)/$(LOADER_NAME).elf + +PKG_NAME := lzma-loader +PKG_BUILD_DIR := $(KDIR)/$(PKG_NAME) + +.PHONY : loader-compile loader.bin loader.elf loader.gz + +$(PKG_BUILD_DIR)/.prepared: + mkdir $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ + touch $@ + +loader-compile: $(PKG_BUILD_DIR)/.prepared + $(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE="$(TARGET_CROSS)" \ + LZMA_TEXT_START=$(LZMA_TEXT_START) \ + LOADER_DATA=$(LOADER_DATA) \ + FLASH_OFFS=$(FLASH_OFFS) \ + FLASH_MAX=$(FLASH_MAX) \ + BOARD="$(BOARD)" \ + clean all + +loader.gz: $(PKG_BUILD_DIR)/loader.bin + gzip -nc9 $< > $(LOADER_GZ) + +loader.elf: $(PKG_BUILD_DIR)/loader.elf + $(CP) $< $(LOADER_ELF) + +loader.bin: $(PKG_BUILD_DIR)/loader.bin + $(CP) $< $(LOADER_BIN) + +download: +prepare: $(PKG_BUILD_DIR)/.prepared +compile: loader-compile + +install: + +clean: + rm -rf $(PKG_BUILD_DIR) + diff --git a/target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.c b/target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.c new file mode 100644 index 000000000..cb8345377 --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.c @@ -0,0 +1,584 @@ +/* + LzmaDecode.c + LZMA Decoder (optimized for Speed version) + + LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this Code, expressly permits you to + statically or dynamically link your Code (or bind by name) to the + interfaces of this file without subjecting your linked Code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#include "LzmaDecode.h" + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_READ_BYTE (*Buffer++) + +#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ + { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} + +#ifdef _LZMA_IN_CB + +#define RC_TEST { if (Buffer == BufferLim) \ + { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \ + BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }} + +#define RC_INIT Buffer = BufferLim = 0; RC_INIT2 + +#else + +#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } + +#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 + +#endif + +#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } + +#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) +#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; +#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; + +#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ + { UpdateBit0(p); mi <<= 1; A0; } else \ + { UpdateBit1(p); mi = (mi + mi) + 1; A1; } + +#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) + +#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ + { int i = numLevels; res = 1; \ + do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ + res -= (1 << numLevels); } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) +{ + unsigned char prop0; + if (size < LZMA_PROPERTIES_SIZE) + return LZMA_RESULT_DATA_ERROR; + prop0 = propsData[0]; + if (prop0 >= (9 * 5 * 5)) + return LZMA_RESULT_DATA_ERROR; + { + for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); + for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); + propsRes->lc = prop0; + /* + unsigned char remainder = (unsigned char)(prop0 / 9); + propsRes->lc = prop0 % 9; + propsRes->pb = remainder / 5; + propsRes->lp = remainder % 5; + */ + } + + #ifdef _LZMA_OUT_READ + { + int i; + propsRes->DictionarySize = 0; + for (i = 0; i < 4; i++) + propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); + if (propsRes->DictionarySize == 0) + propsRes->DictionarySize = 1; + } + #endif + return LZMA_RESULT_OK; +} + +#define kLzmaStreamWasFinishedId (-1) + +int LzmaDecode(CLzmaDecoderState *vs, + #ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback, + #else + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + #endif + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) +{ + CProb *p = vs->Probs; + SizeT nowPos = 0; + Byte previousByte = 0; + UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; + UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; + int lc = vs->Properties.lc; + + #ifdef _LZMA_OUT_READ + + UInt32 Range = vs->Range; + UInt32 Code = vs->Code; + #ifdef _LZMA_IN_CB + const Byte *Buffer = vs->Buffer; + const Byte *BufferLim = vs->BufferLim; + #else + const Byte *Buffer = inStream; + const Byte *BufferLim = inStream + inSize; + #endif + int state = vs->State; + UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; + int len = vs->RemainLen; + UInt32 globalPos = vs->GlobalPos; + UInt32 distanceLimit = vs->DistanceLimit; + + Byte *dictionary = vs->Dictionary; + UInt32 dictionarySize = vs->Properties.DictionarySize; + UInt32 dictionaryPos = vs->DictionaryPos; + + Byte tempDictionary[4]; + + #ifndef _LZMA_IN_CB + *inSizeProcessed = 0; + #endif + *outSizeProcessed = 0; + if (len == kLzmaStreamWasFinishedId) + return LZMA_RESULT_OK; + + if (dictionarySize == 0) + { + dictionary = tempDictionary; + dictionarySize = 1; + tempDictionary[0] = vs->TempDictionary[0]; + } + + if (len == kLzmaNeedInitId) + { + { + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + UInt32 i; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + rep0 = rep1 = rep2 = rep3 = 1; + state = 0; + globalPos = 0; + distanceLimit = 0; + dictionaryPos = 0; + dictionary[dictionarySize - 1] = 0; + #ifdef _LZMA_IN_CB + RC_INIT; + #else + RC_INIT(inStream, inSize); + #endif + } + len = 0; + } + while(len != 0 && nowPos < outSize) + { + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + len--; + } + if (dictionaryPos == 0) + previousByte = dictionary[dictionarySize - 1]; + else + previousByte = dictionary[dictionaryPos - 1]; + + #else /* if !_LZMA_OUT_READ */ + + int state = 0; + UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; + int len = 0; + const Byte *Buffer; + const Byte *BufferLim; + UInt32 Range; + UInt32 Code; + + #ifndef _LZMA_IN_CB + *inSizeProcessed = 0; + #endif + *outSizeProcessed = 0; + + { + UInt32 i; + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + } + + #ifdef _LZMA_IN_CB + RC_INIT; + #else + RC_INIT(inStream, inSize); + #endif + + #endif /* _LZMA_OUT_READ */ + + while(nowPos < outSize) + { + CProb *prob; + UInt32 bound; + int posState = (int)( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & posStateMask); + + prob = p + IsMatch + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + int symbol = 1; + UpdateBit0(prob) + prob = p + Literal + (LZMA_LIT_SIZE * + ((( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & literalPosMask) << lc) + (previousByte >> (8 - lc)))); + + if (state >= kNumLitStates) + { + int matchByte; + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + matchByte = dictionary[pos]; + #else + matchByte = outStream[nowPos - rep0]; + #endif + do + { + int bit; + CProb *probLit; + matchByte <<= 1; + bit = (matchByte & 0x100); + probLit = prob + 0x100 + bit + symbol; + RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) + } + while (symbol < 0x100); + } + while (symbol < 0x100) + { + CProb *probLit = prob + symbol; + RC_GET_BIT(probLit, symbol) + } + previousByte = (Byte)symbol; + + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + if (distanceLimit < dictionarySize) + distanceLimit++; + + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #endif + if (state < 4) state = 0; + else if (state < 10) state -= 3; + else state -= 6; + } + else + { + UpdateBit1(prob); + prob = p + IsRep + state; + IfBit0(prob) + { + UpdateBit0(prob); + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + state = state < kNumLitStates ? 0 : 3; + prob = p + LenCoder; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG0 + state; + IfBit0(prob) + { + UpdateBit0(prob); + prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + #ifdef _LZMA_OUT_READ + UInt32 pos; + #endif + UpdateBit0(prob); + + #ifdef _LZMA_OUT_READ + if (distanceLimit == 0) + #else + if (nowPos == 0) + #endif + return LZMA_RESULT_DATA_ERROR; + + state = state < kNumLitStates ? 9 : 11; + #ifdef _LZMA_OUT_READ + pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + if (distanceLimit < dictionarySize) + distanceLimit++; + #endif + + continue; + } + else + { + UpdateBit1(prob); + } + } + else + { + UInt32 distance; + UpdateBit1(prob); + prob = p + IsRepG1 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep1; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG2 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep2; + } + else + { + UpdateBit1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = p + RepLenCoder; + } + { + int numBits, offset; + CProb *probLen = prob + LenChoice; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + numBits = kLenNumLowBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenChoice2; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + numBits = kLenNumMidBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + numBits = kLenNumHighBits; + } + } + RangeDecoderBitTreeDecode(probLen, numBits, len); + len += offset; + } + + if (state < 4) + { + int posSlot; + state += kNumLitStates; + prob = p + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + rep0 = (2 | ((UInt32)posSlot & 1)); + if (posSlot < kEndPosModelIndex) + { + rep0 <<= numDirectBits; + prob = p + SpecPos + rep0 - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + RC_NORMALIZE + Range >>= 1; + rep0 <<= 1; + if (Code >= Range) + { + Code -= Range; + rep0 |= 1; + } + } + while (--numDirectBits != 0); + prob = p + Align; + rep0 <<= kNumAlignBits; + numDirectBits = kNumAlignBits; + } + { + int i = 1; + int mi = 1; + do + { + CProb *prob3 = prob + mi; + RC_GET_BIT2(prob3, mi, ; , rep0 |= i); + i <<= 1; + } + while(--numDirectBits != 0); + } + } + else + rep0 = posSlot; + if (++rep0 == (UInt32)(0)) + { + /* it's for stream version */ + len = kLzmaStreamWasFinishedId; + break; + } + } + + len += kMatchMinLen; + #ifdef _LZMA_OUT_READ + if (rep0 > distanceLimit) + #else + if (rep0 > nowPos) + #endif + return LZMA_RESULT_DATA_ERROR; + + #ifdef _LZMA_OUT_READ + if (dictionarySize - distanceLimit > (UInt32)len) + distanceLimit += len; + else + distanceLimit = dictionarySize; + #endif + + do + { + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + len--; + outStream[nowPos++] = previousByte; + } + while(len != 0 && nowPos < outSize); + } + } + RC_NORMALIZE; + + #ifdef _LZMA_OUT_READ + vs->Range = Range; + vs->Code = Code; + vs->DictionaryPos = dictionaryPos; + vs->GlobalPos = globalPos + (UInt32)nowPos; + vs->DistanceLimit = distanceLimit; + vs->Reps[0] = rep0; + vs->Reps[1] = rep1; + vs->Reps[2] = rep2; + vs->Reps[3] = rep3; + vs->State = state; + vs->RemainLen = len; + vs->TempDictionary[0] = tempDictionary[0]; + #endif + + #ifdef _LZMA_IN_CB + vs->Buffer = Buffer; + vs->BufferLim = BufferLim; + #else + *inSizeProcessed = (SizeT)(Buffer - inStream); + #endif + *outSizeProcessed = nowPos; + return LZMA_RESULT_OK; +} diff --git a/target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.h b/target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.h new file mode 100644 index 000000000..2870eeb9c --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/LzmaDecode.h @@ -0,0 +1,113 @@ +/* + LzmaDecode.h + LZMA Decoder interface + + LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to the + interfaces of this file without subjecting your linked code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#ifndef __LZMADECODE_H +#define __LZMADECODE_H + +#include "LzmaTypes.h" + +/* #define _LZMA_IN_CB */ +/* Use callback for input data */ + +/* #define _LZMA_OUT_READ */ +/* Use read function for output data */ + +/* #define _LZMA_PROB32 */ +/* It can increase speed on some 32-bit CPUs, + but memory usage will be doubled in that case */ + +/* #define _LZMA_LOC_OPT */ +/* Enable local speed optimizations inside code */ + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb UInt16 +#endif + +#define LZMA_RESULT_OK 0 +#define LZMA_RESULT_DATA_ERROR 1 + +#ifdef _LZMA_IN_CB +typedef struct _ILzmaInCallback +{ + int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize); +} ILzmaInCallback; +#endif + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LZMA_PROPERTIES_SIZE 5 + +typedef struct _CLzmaProperties +{ + int lc; + int lp; + int pb; + #ifdef _LZMA_OUT_READ + UInt32 DictionarySize; + #endif +}CLzmaProperties; + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); + +#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) + +#define kLzmaNeedInitId (-2) + +typedef struct _CLzmaDecoderState +{ + CLzmaProperties Properties; + CProb *Probs; + + #ifdef _LZMA_IN_CB + const unsigned char *Buffer; + const unsigned char *BufferLim; + #endif + + #ifdef _LZMA_OUT_READ + unsigned char *Dictionary; + UInt32 Range; + UInt32 Code; + UInt32 DictionaryPos; + UInt32 GlobalPos; + UInt32 DistanceLimit; + UInt32 Reps[4]; + int State; + int RemainLen; + unsigned char TempDictionary[4]; + #endif +} CLzmaDecoderState; + +#ifdef _LZMA_OUT_READ +#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; } +#endif + +int LzmaDecode(CLzmaDecoderState *vs, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback, + #else + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + #endif + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); + +#endif diff --git a/target/linux/ar71xx/image/lzma-loader/src/LzmaTypes.h b/target/linux/ar71xx/image/lzma-loader/src/LzmaTypes.h new file mode 100644 index 000000000..9c2729075 --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/LzmaTypes.h @@ -0,0 +1,45 @@ +/* +LzmaTypes.h + +Types for LZMA Decoder + +This file written and distributed to public domain by Igor Pavlov. +This file is part of LZMA SDK 4.40 (2006-05-01) +*/ + +#ifndef __LZMATYPES_H +#define __LZMATYPES_H + +#ifndef _7ZIP_BYTE_DEFINED +#define _7ZIP_BYTE_DEFINED +typedef unsigned char Byte; +#endif + +#ifndef _7ZIP_UINT16_DEFINED +#define _7ZIP_UINT16_DEFINED +typedef unsigned short UInt16; +#endif + +#ifndef _7ZIP_UINT32_DEFINED +#define _7ZIP_UINT32_DEFINED +#ifdef _LZMA_UINT32_IS_ULONG +typedef unsigned long UInt32; +#else +typedef unsigned int UInt32; +#endif +#endif + +/* #define _LZMA_NO_SYSTEM_SIZE_T */ +/* You can use it, if you don't want */ + +#ifndef _7ZIP_SIZET_DEFINED +#define _7ZIP_SIZET_DEFINED +#ifdef _LZMA_NO_SYSTEM_SIZE_T +typedef UInt32 SizeT; +#else +#include +typedef size_t SizeT; +#endif +#endif + +#endif diff --git a/target/linux/ar71xx/image/lzma-loader/src/Makefile b/target/linux/ar71xx/image/lzma-loader/src/Makefile new file mode 100644 index 000000000..3e6839c7c --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/Makefile @@ -0,0 +1,99 @@ +# +# Makefile for the LZMA compressed kernel loader for +# Atheros AR7XXX/AR9XXX based boards +# +# Copyright (C) 2011 Gabor Juhos +# +# Some parts of this file was based on the OpenWrt specific lzma-loader +# for the BCM47xx and ADM5120 based boards: +# Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) +# Copyright (C) 2005 Mineharu Takahara +# Copyright (C) 2005 by Oleg I. Vdovikin +# +# This program 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. +# + +LOADADDR := +LZMA_TEXT_START := 0x80a00000 +LOADER_DATA := +BOARD := +FLASH_OFFS := +FLASH_MAX := + +CC := $(CROSS_COMPILE)gcc +LD := $(CROSS_COMPILE)ld +OBJCOPY := $(CROSS_COMPILE)objcopy +OBJDUMP := $(CROSS_COMPILE)objdump + +BIN_FLAGS := -O binary -R .reginfo -R .note -R .comment -R .mdebug -S + +CFLAGS = -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ + -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 \ + -mno-abicalls -fno-pic -ffunction-sections -pipe -mlong-calls \ + -fno-common -ffreestanding -fhonour-copts \ + -mabi=32 -march=mips32r2 \ + -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap +CFLAGS += -D_LZMA_PROB32 + +ASFLAGS = $(CFLAGS) -D__ASSEMBLY__ + +LDFLAGS = -static --gc-sections -no-warn-mismatch +LDFLAGS += -e startup -T loader.lds -Ttext $(LZMA_TEXT_START) + +O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32) + +OBJECTS := head.o loader.o cache.o board.o printf.o LzmaDecode.o + +ifneq ($(strip $(LOADER_DATA)),) +OBJECTS += data.o +CFLAGS += -DLZMA_WRAPPER=1 -DLOADADDR=$(LOADADDR) +endif + +ifneq ($(strip $(KERNEL_CMDLINE)),) +CFLAGS += -DCONFIG_KERNEL_CMDLINE='"$(KERNEL_CMDLINE)"' +endif + +ifneq ($(strip $(FLASH_OFFS)),) +CFLAGS += -DCONFIG_FLASH_OFFS=$(FLASH_OFFS) +endif + +ifneq ($(strip $(FLASH_MAX)),) +CFLAGS += -DCONFIG_FLASH_MAX=$(FLASH_MAX) +endif + +BOARD_DEF := $(shell echo $(strip $(BOARD)) | tr a-z A-Z | tr - _) +ifneq ($(BOARD_DEF),) +CFLAGS += -DCONFIG_BOARD_$(BOARD_DEF) +endif + +all: loader.bin + +# Don't build dependencies, this may die if $(CC) isn't gcc +dep: + +install: + +%.o : %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.o : %.S + $(CC) $(ASFLAGS) -c -o $@ $< + +data.o: $(LOADER_DATA) + $(LD) -r -b binary --oformat $(O_FORMAT) -T lzma-data.lds -o $@ $< + +loader.bin: loader.elf + $(OBJCOPY) $(BIN_FLAGS) $< $@ + +loader.elf: $(OBJECTS) + $(LD) $(LDFLAGS) -o $@ $(OBJECTS) + +mrproper: clean + +clean: + rm -f *.elf *.bin *.o + + + diff --git a/target/linux/ar71xx/image/lzma-loader/src/ar71xx_regs.h b/target/linux/ar71xx/image/lzma-loader/src/ar71xx_regs.h new file mode 100644 index 000000000..19a4785bb --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/ar71xx_regs.h @@ -0,0 +1,725 @@ +/* + * Atheros AR71XX/AR724X/AR913X SoC register definitions + * + * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP + * + * This program 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. + */ + +#ifndef __ASM_MACH_AR71XX_REGS_H +#define __ASM_MACH_AR71XX_REGS_H + +#define BIT(_x) (1UL << (_x)) + +#define AR71XX_APB_BASE 0x18000000 +#define AR71XX_GE0_BASE 0x19000000 +#define AR71XX_GE0_SIZE 0x10000 +#define AR71XX_GE1_BASE 0x1a000000 +#define AR71XX_GE1_SIZE 0x10000 +#define AR71XX_EHCI_BASE 0x1b000000 +#define AR71XX_EHCI_SIZE 0x1000 +#define AR71XX_OHCI_BASE 0x1c000000 +#define AR71XX_OHCI_SIZE 0x1000 +#define AR71XX_SPI_BASE 0x1f000000 +#define AR71XX_SPI_SIZE 0x01000000 + +#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000) +#define AR71XX_DDR_CTRL_SIZE 0x100 +#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000) +#define AR71XX_UART_SIZE 0x100 +#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) +#define AR71XX_USB_CTRL_SIZE 0x100 +#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000) +#define AR71XX_GPIO_SIZE 0x100 +#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000) +#define AR71XX_PLL_SIZE 0x100 +#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) +#define AR71XX_RESET_SIZE 0x100 +#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000) +#define AR71XX_MII_SIZE 0x100 + +#define AR71XX_PCI_MEM_BASE 0x10000000 +#define AR71XX_PCI_MEM_SIZE 0x07000000 + +#define AR71XX_PCI_WIN0_OFFS 0x10000000 +#define AR71XX_PCI_WIN1_OFFS 0x11000000 +#define AR71XX_PCI_WIN2_OFFS 0x12000000 +#define AR71XX_PCI_WIN3_OFFS 0x13000000 +#define AR71XX_PCI_WIN4_OFFS 0x14000000 +#define AR71XX_PCI_WIN5_OFFS 0x15000000 +#define AR71XX_PCI_WIN6_OFFS 0x16000000 +#define AR71XX_PCI_WIN7_OFFS 0x07000000 + +#define AR71XX_PCI_CFG_BASE \ + (AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x10000) +#define AR71XX_PCI_CFG_SIZE 0x100 + +#define AR7240_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) +#define AR7240_USB_CTRL_SIZE 0x100 +#define AR7240_OHCI_BASE 0x1b000000 +#define AR7240_OHCI_SIZE 0x1000 + +#define AR724X_PCI_MEM_BASE 0x10000000 +#define AR724X_PCI_MEM_SIZE 0x04000000 + +#define AR724X_PCI_CFG_BASE 0x14000000 +#define AR724X_PCI_CFG_SIZE 0x1000 +#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000c0000) +#define AR724X_PCI_CRP_SIZE 0x1000 +#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000) +#define AR724X_PCI_CTRL_SIZE 0x100 + +#define AR724X_EHCI_BASE 0x1b000000 +#define AR724X_EHCI_SIZE 0x1000 + +#define AR913X_EHCI_BASE 0x1b000000 +#define AR913X_EHCI_SIZE 0x1000 +#define AR913X_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000) +#define AR913X_WMAC_SIZE 0x30000 + +#define AR933X_UART_BASE (AR71XX_APB_BASE + 0x00020000) +#define AR933X_UART_SIZE 0x14 +#define AR933X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) +#define AR933X_GMAC_SIZE 0x04 +#define AR933X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) +#define AR933X_WMAC_SIZE 0x20000 +#define AR933X_EHCI_BASE 0x1b000000 +#define AR933X_EHCI_SIZE 0x1000 + +#define AR934X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) +#define AR934X_GMAC_SIZE 0x14 +#define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) +#define AR934X_WMAC_SIZE 0x20000 +#define AR934X_EHCI_BASE 0x1b000000 +#define AR934X_EHCI_SIZE 0x200 + +#define QCA955X_PCI_MEM_BASE0 0x10000000 +#define QCA955X_PCI_MEM_BASE1 0x12000000 +#define QCA955X_PCI_MEM_SIZE 0x02000000 +#define QCA955X_PCI_CFG_BASE0 0x14000000 +#define QCA955X_PCI_CFG_BASE1 0x16000000 +#define QCA955X_PCI_CFG_SIZE 0x1000 +#define QCA955X_PCI_CRP_BASE0 (AR71XX_APB_BASE + 0x000c0000) +#define QCA955X_PCI_CRP_BASE1 (AR71XX_APB_BASE + 0x00250000) +#define QCA955X_PCI_CRP_SIZE 0x1000 +#define QCA955X_PCI_CTRL_BASE0 (AR71XX_APB_BASE + 0x000f0000) +#define QCA955X_PCI_CTRL_BASE1 (AR71XX_APB_BASE + 0x00280000) +#define QCA955X_PCI_CTRL_SIZE 0x100 + +#define QCA955X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) +#define QCA955X_WMAC_SIZE 0x20000 +#define QCA955X_EHCI0_BASE 0x1b000000 +#define QCA955X_EHCI1_BASE 0x1b400000 +#define QCA955X_EHCI_SIZE 0x1000 +#define QCA955X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) +#define QCA955X_GMAC_SIZE 0x40 + +#define AR9300_OTP_BASE 0x14000 +#define AR9300_OTP_STATUS 0x15f18 +#define AR9300_OTP_STATUS_TYPE 0x7 +#define AR9300_OTP_STATUS_VALID 0x4 +#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2 +#define AR9300_OTP_STATUS_SM_BUSY 0x1 +#define AR9300_OTP_READ_DATA 0x15f1c + +/* + * DDR_CTRL block + */ +#define AR71XX_DDR_REG_PCI_WIN0 0x7c +#define AR71XX_DDR_REG_PCI_WIN1 0x80 +#define AR71XX_DDR_REG_PCI_WIN2 0x84 +#define AR71XX_DDR_REG_PCI_WIN3 0x88 +#define AR71XX_DDR_REG_PCI_WIN4 0x8c +#define AR71XX_DDR_REG_PCI_WIN5 0x90 +#define AR71XX_DDR_REG_PCI_WIN6 0x94 +#define AR71XX_DDR_REG_PCI_WIN7 0x98 +#define AR71XX_DDR_REG_FLUSH_GE0 0x9c +#define AR71XX_DDR_REG_FLUSH_GE1 0xa0 +#define AR71XX_DDR_REG_FLUSH_USB 0xa4 +#define AR71XX_DDR_REG_FLUSH_PCI 0xa8 + +#define AR724X_DDR_REG_FLUSH_GE0 0x7c +#define AR724X_DDR_REG_FLUSH_GE1 0x80 +#define AR724X_DDR_REG_FLUSH_USB 0x84 +#define AR724X_DDR_REG_FLUSH_PCIE 0x88 + +#define AR913X_DDR_REG_FLUSH_GE0 0x7c +#define AR913X_DDR_REG_FLUSH_GE1 0x80 +#define AR913X_DDR_REG_FLUSH_USB 0x84 +#define AR913X_DDR_REG_FLUSH_WMAC 0x88 + +#define AR933X_DDR_REG_FLUSH_GE0 0x7c +#define AR933X_DDR_REG_FLUSH_GE1 0x80 +#define AR933X_DDR_REG_FLUSH_USB 0x84 +#define AR933X_DDR_REG_FLUSH_WMAC 0x88 + +#define AR934X_DDR_REG_FLUSH_GE0 0x9c +#define AR934X_DDR_REG_FLUSH_GE1 0xa0 +#define AR934X_DDR_REG_FLUSH_USB 0xa4 +#define AR934X_DDR_REG_FLUSH_PCIE 0xa8 +#define AR934X_DDR_REG_FLUSH_WMAC 0xac + +/* + * PLL block + */ +#define AR71XX_PLL_REG_CPU_CONFIG 0x00 +#define AR71XX_PLL_REG_SEC_CONFIG 0x04 +#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10 +#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14 + +#define AR71XX_PLL_DIV_SHIFT 3 +#define AR71XX_PLL_DIV_MASK 0x1f +#define AR71XX_CPU_DIV_SHIFT 16 +#define AR71XX_CPU_DIV_MASK 0x3 +#define AR71XX_DDR_DIV_SHIFT 18 +#define AR71XX_DDR_DIV_MASK 0x3 +#define AR71XX_AHB_DIV_SHIFT 20 +#define AR71XX_AHB_DIV_MASK 0x7 + +#define AR71XX_ETH0_PLL_SHIFT 17 +#define AR71XX_ETH1_PLL_SHIFT 19 + +#define AR724X_PLL_REG_CPU_CONFIG 0x00 +#define AR724X_PLL_REG_PCIE_CONFIG 0x18 + +#define AR724X_PLL_DIV_SHIFT 0 +#define AR724X_PLL_DIV_MASK 0x3ff +#define AR724X_PLL_REF_DIV_SHIFT 10 +#define AR724X_PLL_REF_DIV_MASK 0xf +#define AR724X_AHB_DIV_SHIFT 19 +#define AR724X_AHB_DIV_MASK 0x1 +#define AR724X_DDR_DIV_SHIFT 22 +#define AR724X_DDR_DIV_MASK 0x3 + +#define AR7242_PLL_REG_ETH0_INT_CLOCK 0x2c + +#define AR913X_PLL_REG_CPU_CONFIG 0x00 +#define AR913X_PLL_REG_ETH_CONFIG 0x04 +#define AR913X_PLL_REG_ETH0_INT_CLOCK 0x14 +#define AR913X_PLL_REG_ETH1_INT_CLOCK 0x18 + +#define AR913X_PLL_DIV_SHIFT 0 +#define AR913X_PLL_DIV_MASK 0x3ff +#define AR913X_DDR_DIV_SHIFT 22 +#define AR913X_DDR_DIV_MASK 0x3 +#define AR913X_AHB_DIV_SHIFT 19 +#define AR913X_AHB_DIV_MASK 0x1 + +#define AR913X_ETH0_PLL_SHIFT 20 +#define AR913X_ETH1_PLL_SHIFT 22 + +#define AR933X_PLL_CPU_CONFIG_REG 0x00 +#define AR933X_PLL_CLOCK_CTRL_REG 0x08 + +#define AR933X_PLL_CPU_CONFIG_NINT_SHIFT 10 +#define AR933X_PLL_CPU_CONFIG_NINT_MASK 0x3f +#define AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT 16 +#define AR933X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f +#define AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT 23 +#define AR933X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7 + +#define AR933X_PLL_CLOCK_CTRL_BYPASS BIT(2) +#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT 5 +#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK 0x3 +#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT 10 +#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK 0x3 +#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15 +#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7 + +#define AR934X_PLL_CPU_CONFIG_REG 0x00 +#define AR934X_PLL_DDR_CONFIG_REG 0x04 +#define AR934X_PLL_CPU_DDR_CLK_CTRL_REG 0x08 +#define AR934X_PLL_ETH_XMII_CONTROL_REG 0x2c + +#define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT 0 +#define AR934X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f +#define AR934X_PLL_CPU_CONFIG_NINT_SHIFT 6 +#define AR934X_PLL_CPU_CONFIG_NINT_MASK 0x3f +#define AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT 12 +#define AR934X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f +#define AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19 +#define AR934X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3 + +#define AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT 0 +#define AR934X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff +#define AR934X_PLL_DDR_CONFIG_NINT_SHIFT 10 +#define AR934X_PLL_DDR_CONFIG_NINT_MASK 0x3f +#define AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT 16 +#define AR934X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f +#define AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23 +#define AR934X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7 + +#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS BIT(2) +#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS BIT(3) +#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS BIT(4) +#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT 5 +#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK 0x1f +#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT 10 +#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK 0x1f +#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT 15 +#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK 0x1f +#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20) +#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) +#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) + +#define QCA955X_PLL_CPU_CONFIG_REG 0x00 +#define QCA955X_PLL_DDR_CONFIG_REG 0x04 +#define QCA955X_PLL_CLK_CTRL_REG 0x08 + +#define QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT 0 +#define QCA955X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f +#define QCA955X_PLL_CPU_CONFIG_NINT_SHIFT 6 +#define QCA955X_PLL_CPU_CONFIG_NINT_MASK 0x3f +#define QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT 12 +#define QCA955X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f +#define QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19 +#define QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3 + +#define QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT 0 +#define QCA955X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff +#define QCA955X_PLL_DDR_CONFIG_NINT_SHIFT 10 +#define QCA955X_PLL_DDR_CONFIG_NINT_MASK 0x3f +#define QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT 16 +#define QCA955X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f +#define QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23 +#define QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7 + +#define QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2) +#define QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3) +#define QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4) +#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5 +#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f +#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10 +#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f +#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15 +#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f +#define QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20) +#define QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) +#define QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) + +/* + * USB_CONFIG block + */ +#define AR71XX_USB_CTRL_REG_FLADJ 0x00 +#define AR71XX_USB_CTRL_REG_CONFIG 0x04 + +/* + * RESET block + */ +#define AR71XX_RESET_REG_TIMER 0x00 +#define AR71XX_RESET_REG_TIMER_RELOAD 0x04 +#define AR71XX_RESET_REG_WDOG_CTRL 0x08 +#define AR71XX_RESET_REG_WDOG 0x0c +#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10 +#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14 +#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18 +#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c +#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20 +#define AR71XX_RESET_REG_RESET_MODULE 0x24 +#define AR71XX_RESET_REG_PERFC_CTRL 0x2c +#define AR71XX_RESET_REG_PERFC0 0x30 +#define AR71XX_RESET_REG_PERFC1 0x34 +#define AR71XX_RESET_REG_REV_ID 0x90 + +#define AR913X_RESET_REG_GLOBAL_INT_STATUS 0x18 +#define AR913X_RESET_REG_RESET_MODULE 0x1c +#define AR913X_RESET_REG_PERF_CTRL 0x20 +#define AR913X_RESET_REG_PERFC0 0x24 +#define AR913X_RESET_REG_PERFC1 0x28 + +#define AR724X_RESET_REG_RESET_MODULE 0x1c + +#define AR933X_RESET_REG_RESET_MODULE 0x1c +#define AR933X_RESET_REG_BOOTSTRAP 0xac + +#define AR934X_RESET_REG_RESET_MODULE 0x1c +#define AR934X_RESET_REG_BOOTSTRAP 0xb0 +#define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac + +#define QCA955X_RESET_REG_BOOTSTRAP 0xb0 +#define QCA955X_RESET_REG_EXT_INT_STATUS 0xac + +#define MISC_INT_ETHSW BIT(12) +#define MISC_INT_TIMER4 BIT(10) +#define MISC_INT_TIMER3 BIT(9) +#define MISC_INT_TIMER2 BIT(8) +#define MISC_INT_DMA BIT(7) +#define MISC_INT_OHCI BIT(6) +#define MISC_INT_PERFC BIT(5) +#define MISC_INT_WDOG BIT(4) +#define MISC_INT_UART BIT(3) +#define MISC_INT_GPIO BIT(2) +#define MISC_INT_ERROR BIT(1) +#define MISC_INT_TIMER BIT(0) + +#define AR71XX_RESET_EXTERNAL BIT(28) +#define AR71XX_RESET_FULL_CHIP BIT(24) +#define AR71XX_RESET_CPU_NMI BIT(21) +#define AR71XX_RESET_CPU_COLD BIT(20) +#define AR71XX_RESET_DMA BIT(19) +#define AR71XX_RESET_SLIC BIT(18) +#define AR71XX_RESET_STEREO BIT(17) +#define AR71XX_RESET_DDR BIT(16) +#define AR71XX_RESET_GE1_MAC BIT(13) +#define AR71XX_RESET_GE1_PHY BIT(12) +#define AR71XX_RESET_USBSUS_OVERRIDE BIT(10) +#define AR71XX_RESET_GE0_MAC BIT(9) +#define AR71XX_RESET_GE0_PHY BIT(8) +#define AR71XX_RESET_USB_OHCI_DLL BIT(6) +#define AR71XX_RESET_USB_HOST BIT(5) +#define AR71XX_RESET_USB_PHY BIT(4) +#define AR71XX_RESET_PCI_BUS BIT(1) +#define AR71XX_RESET_PCI_CORE BIT(0) + +#define AR7240_RESET_USB_HOST BIT(5) +#define AR7240_RESET_OHCI_DLL BIT(3) + +#define AR724X_RESET_GE1_MDIO BIT(23) +#define AR724X_RESET_GE0_MDIO BIT(22) +#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10) +#define AR724X_RESET_PCIE_PHY BIT(7) +#define AR724X_RESET_PCIE BIT(6) +#define AR724X_RESET_USB_HOST BIT(5) +#define AR724X_RESET_USB_PHY BIT(4) +#define AR724X_RESET_USBSUS_OVERRIDE BIT(3) + +#define AR913X_RESET_AMBA2WMAC BIT(22) +#define AR913X_RESET_USBSUS_OVERRIDE BIT(10) +#define AR913X_RESET_USB_HOST BIT(5) +#define AR913X_RESET_USB_PHY BIT(4) + +#define AR933X_RESET_GE1_MDIO BIT(23) +#define AR933X_RESET_GE0_MDIO BIT(22) +#define AR933X_RESET_GE1_MAC BIT(13) +#define AR933X_RESET_WMAC BIT(11) +#define AR933X_RESET_GE0_MAC BIT(9) +#define AR933X_RESET_USB_HOST BIT(5) +#define AR933X_RESET_USB_PHY BIT(4) +#define AR933X_RESET_USBSUS_OVERRIDE BIT(3) + +#define AR934X_RESET_HOST BIT(31) +#define AR934X_RESET_SLIC BIT(30) +#define AR934X_RESET_HDMA BIT(29) +#define AR934X_RESET_EXTERNAL BIT(28) +#define AR934X_RESET_RTC BIT(27) +#define AR934X_RESET_PCIE_EP_INT BIT(26) +#define AR934X_RESET_CHKSUM_ACC BIT(25) +#define AR934X_RESET_FULL_CHIP BIT(24) +#define AR934X_RESET_GE1_MDIO BIT(23) +#define AR934X_RESET_GE0_MDIO BIT(22) +#define AR934X_RESET_CPU_NMI BIT(21) +#define AR934X_RESET_CPU_COLD BIT(20) +#define AR934X_RESET_HOST_RESET_INT BIT(19) +#define AR934X_RESET_PCIE_EP BIT(18) +#define AR934X_RESET_UART1 BIT(17) +#define AR934X_RESET_DDR BIT(16) +#define AR934X_RESET_USB_PHY_PLL_PWD_EXT BIT(15) +#define AR934X_RESET_NANDF BIT(14) +#define AR934X_RESET_GE1_MAC BIT(13) +#define AR934X_RESET_ETH_SWITCH_ANALOG BIT(12) +#define AR934X_RESET_USB_PHY_ANALOG BIT(11) +#define AR934X_RESET_HOST_DMA_INT BIT(10) +#define AR934X_RESET_GE0_MAC BIT(9) +#define AR934X_RESET_ETH_SWITCH BIT(8) +#define AR934X_RESET_PCIE_PHY BIT(7) +#define AR934X_RESET_PCIE BIT(6) +#define AR934X_RESET_USB_HOST BIT(5) +#define AR934X_RESET_USB_PHY BIT(4) +#define AR934X_RESET_USBSUS_OVERRIDE BIT(3) +#define AR934X_RESET_LUT BIT(2) +#define AR934X_RESET_MBOX BIT(1) +#define AR934X_RESET_I2S BIT(0) + +#define AR933X_BOOTSTRAP_MDIO_GPIO_EN BIT(18) +#define AR933X_BOOTSTRAP_EEPBUSY BIT(4) +#define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) + +#define AR934X_BOOTSTRAP_SW_OPTION8 BIT(23) +#define AR934X_BOOTSTRAP_SW_OPTION7 BIT(22) +#define AR934X_BOOTSTRAP_SW_OPTION6 BIT(21) +#define AR934X_BOOTSTRAP_SW_OPTION5 BIT(20) +#define AR934X_BOOTSTRAP_SW_OPTION4 BIT(19) +#define AR934X_BOOTSTRAP_SW_OPTION3 BIT(18) +#define AR934X_BOOTSTRAP_SW_OPTION2 BIT(17) +#define AR934X_BOOTSTRAP_SW_OPTION1 BIT(16) +#define AR934X_BOOTSTRAP_USB_MODE_DEVICE BIT(7) +#define AR934X_BOOTSTRAP_PCIE_RC BIT(6) +#define AR934X_BOOTSTRAP_EJTAG_MODE BIT(5) +#define AR934X_BOOTSTRAP_REF_CLK_40 BIT(4) +#define AR934X_BOOTSTRAP_BOOT_FROM_SPI BIT(2) +#define AR934X_BOOTSTRAP_SDRAM_DISABLED BIT(1) +#define AR934X_BOOTSTRAP_DDR1 BIT(0) + +#define QCA955X_BOOTSTRAP_REF_CLK_40 BIT(4) + +#define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0) +#define AR934X_PCIE_WMAC_INT_WMAC_TX BIT(1) +#define AR934X_PCIE_WMAC_INT_WMAC_RXLP BIT(2) +#define AR934X_PCIE_WMAC_INT_WMAC_RXHP BIT(3) +#define AR934X_PCIE_WMAC_INT_PCIE_RC BIT(4) +#define AR934X_PCIE_WMAC_INT_PCIE_RC0 BIT(5) +#define AR934X_PCIE_WMAC_INT_PCIE_RC1 BIT(6) +#define AR934X_PCIE_WMAC_INT_PCIE_RC2 BIT(7) +#define AR934X_PCIE_WMAC_INT_PCIE_RC3 BIT(8) +#define AR934X_PCIE_WMAC_INT_WMAC_ALL \ + (AR934X_PCIE_WMAC_INT_WMAC_MISC | AR934X_PCIE_WMAC_INT_WMAC_TX | \ + AR934X_PCIE_WMAC_INT_WMAC_RXLP | AR934X_PCIE_WMAC_INT_WMAC_RXHP) + +#define AR934X_PCIE_WMAC_INT_PCIE_ALL \ + (AR934X_PCIE_WMAC_INT_PCIE_RC | AR934X_PCIE_WMAC_INT_PCIE_RC0 | \ + AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \ + AR934X_PCIE_WMAC_INT_PCIE_RC3) + +#define QCA955X_EXT_INT_WMAC_MISC BIT(0) +#define QCA955X_EXT_INT_WMAC_TX BIT(1) +#define QCA955X_EXT_INT_WMAC_RXLP BIT(2) +#define QCA955X_EXT_INT_WMAC_RXHP BIT(3) +#define QCA955X_EXT_INT_PCIE_RC1 BIT(4) +#define QCA955X_EXT_INT_PCIE_RC1_INT0 BIT(5) +#define QCA955X_EXT_INT_PCIE_RC1_INT1 BIT(6) +#define QCA955X_EXT_INT_PCIE_RC1_INT2 BIT(7) +#define QCA955X_EXT_INT_PCIE_RC1_INT3 BIT(8) +#define QCA955X_EXT_INT_PCIE_RC2 BIT(12) +#define QCA955X_EXT_INT_PCIE_RC2_INT0 BIT(13) +#define QCA955X_EXT_INT_PCIE_RC2_INT1 BIT(14) +#define QCA955X_EXT_INT_PCIE_RC2_INT2 BIT(15) +#define QCA955X_EXT_INT_PCIE_RC2_INT3 BIT(16) +#define QCA955X_EXT_INT_USB1 BIT(24) +#define QCA955X_EXT_INT_USB2 BIT(28) + +#define QCA955X_EXT_INT_WMAC_ALL \ + (QCA955X_EXT_INT_WMAC_MISC | QCA955X_EXT_INT_WMAC_TX | \ + QCA955X_EXT_INT_WMAC_RXLP | QCA955X_EXT_INT_WMAC_RXHP) + +#define QCA955X_EXT_INT_PCIE_RC1_ALL \ + (QCA955X_EXT_INT_PCIE_RC1 | QCA955X_EXT_INT_PCIE_RC1_INT0 | \ + QCA955X_EXT_INT_PCIE_RC1_INT1 | QCA955X_EXT_INT_PCIE_RC1_INT2 | \ + QCA955X_EXT_INT_PCIE_RC1_INT3) + +#define QCA955X_EXT_INT_PCIE_RC2_ALL \ + (QCA955X_EXT_INT_PCIE_RC2 | QCA955X_EXT_INT_PCIE_RC2_INT0 | \ + QCA955X_EXT_INT_PCIE_RC2_INT1 | QCA955X_EXT_INT_PCIE_RC2_INT2 | \ + QCA955X_EXT_INT_PCIE_RC2_INT3) + +#define REV_ID_MAJOR_MASK 0xfff0 +#define REV_ID_MAJOR_AR71XX 0x00a0 +#define REV_ID_MAJOR_AR913X 0x00b0 +#define REV_ID_MAJOR_AR7240 0x00c0 +#define REV_ID_MAJOR_AR7241 0x0100 +#define REV_ID_MAJOR_AR7242 0x1100 +#define REV_ID_MAJOR_AR9330 0x0110 +#define REV_ID_MAJOR_AR9331 0x1110 +#define REV_ID_MAJOR_AR9341 0x0120 +#define REV_ID_MAJOR_AR9342 0x1120 +#define REV_ID_MAJOR_AR9344 0x2120 +#define REV_ID_MAJOR_QCA9558 0x1130 + +#define AR71XX_REV_ID_MINOR_MASK 0x3 +#define AR71XX_REV_ID_MINOR_AR7130 0x0 +#define AR71XX_REV_ID_MINOR_AR7141 0x1 +#define AR71XX_REV_ID_MINOR_AR7161 0x2 +#define AR71XX_REV_ID_REVISION_MASK 0x3 +#define AR71XX_REV_ID_REVISION_SHIFT 2 + +#define AR913X_REV_ID_MINOR_MASK 0x3 +#define AR913X_REV_ID_MINOR_AR9130 0x0 +#define AR913X_REV_ID_MINOR_AR9132 0x1 +#define AR913X_REV_ID_REVISION_MASK 0x3 +#define AR913X_REV_ID_REVISION_SHIFT 2 + +#define AR933X_REV_ID_REVISION_MASK 0x3 + +#define AR724X_REV_ID_REVISION_MASK 0x3 + +#define AR934X_REV_ID_REVISION_MASK 0xf + +#define AR944X_REV_ID_REVISION_MASK 0xf + +/* + * SPI block + */ +#define AR71XX_SPI_REG_FS 0x00 /* Function Select */ +#define AR71XX_SPI_REG_CTRL 0x04 /* SPI Control */ +#define AR71XX_SPI_REG_IOC 0x08 /* SPI I/O Control */ +#define AR71XX_SPI_REG_RDS 0x0c /* Read Data Shift */ + +#define AR71XX_SPI_FS_GPIO BIT(0) /* Enable GPIO mode */ + +#define AR71XX_SPI_CTRL_RD BIT(6) /* Remap Disable */ +#define AR71XX_SPI_CTRL_DIV_MASK 0x3f + +#define AR71XX_SPI_IOC_DO BIT(0) /* Data Out pin */ +#define AR71XX_SPI_IOC_CLK BIT(8) /* CLK pin */ +#define AR71XX_SPI_IOC_CS(n) BIT(16 + (n)) +#define AR71XX_SPI_IOC_CS0 AR71XX_SPI_IOC_CS(0) +#define AR71XX_SPI_IOC_CS1 AR71XX_SPI_IOC_CS(1) +#define AR71XX_SPI_IOC_CS2 AR71XX_SPI_IOC_CS(2) +#define AR71XX_SPI_IOC_CS_ALL (AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1 | \ + AR71XX_SPI_IOC_CS2) + +/* + * GPIO block + */ +#define AR71XX_GPIO_REG_OE 0x00 +#define AR71XX_GPIO_REG_IN 0x04 +#define AR71XX_GPIO_REG_OUT 0x08 +#define AR71XX_GPIO_REG_SET 0x0c +#define AR71XX_GPIO_REG_CLEAR 0x10 +#define AR71XX_GPIO_REG_INT_MODE 0x14 +#define AR71XX_GPIO_REG_INT_TYPE 0x18 +#define AR71XX_GPIO_REG_INT_POLARITY 0x1c +#define AR71XX_GPIO_REG_INT_PENDING 0x20 +#define AR71XX_GPIO_REG_INT_ENABLE 0x24 +#define AR71XX_GPIO_REG_FUNC 0x28 + +#define AR934X_GPIO_REG_OUT_FUNC0 0x2c +#define AR934X_GPIO_REG_OUT_FUNC1 0x30 +#define AR934X_GPIO_REG_OUT_FUNC2 0x34 +#define AR934X_GPIO_REG_OUT_FUNC3 0x38 +#define AR934X_GPIO_REG_OUT_FUNC4 0x3c +#define AR934X_GPIO_REG_OUT_FUNC5 0x40 +#define AR934X_GPIO_REG_FUNC 0x6c + +#define AR71XX_GPIO_COUNT 16 +#define AR724X_GPIO_COUNT 18 +#define AR913X_GPIO_COUNT 22 +#define AR933X_GPIO_COUNT 30 +#define AR934X_GPIO_COUNT 23 +#define QCA955X_GPIO_COUNT 24 + +#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17) +#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16) +#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13) +#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12) +#define AR71XX_GPIO_FUNC_UART_EN BIT(8) +#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4) +#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0) + +#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19) +#define AR724X_GPIO_FUNC_SPI_EN BIT(18) +#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14) +#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13) +#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12) +#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11) +#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10) +#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9) +#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4) +#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3) +#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2) +#define AR724X_GPIO_FUNC_UART_EN BIT(1) +#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0) + +#define AR913X_GPIO_FUNC_WMAC_LED_EN BIT(22) +#define AR913X_GPIO_FUNC_EXP_PORT_CS_EN BIT(21) +#define AR913X_GPIO_FUNC_I2S_REFCLKEN BIT(20) +#define AR913X_GPIO_FUNC_I2S_MCKEN BIT(19) +#define AR913X_GPIO_FUNC_I2S1_EN BIT(18) +#define AR913X_GPIO_FUNC_I2S0_EN BIT(17) +#define AR913X_GPIO_FUNC_SLIC_EN BIT(16) +#define AR913X_GPIO_FUNC_UART_RTSCTS_EN BIT(9) +#define AR913X_GPIO_FUNC_UART_EN BIT(8) +#define AR913X_GPIO_FUNC_USB_CLK_EN BIT(4) + +#define AR933X_GPIO_FUNC_SPDIF2TCK BIT(31) +#define AR933X_GPIO_FUNC_SPDIF_EN BIT(30) +#define AR933X_GPIO_FUNC_I2SO_22_18_EN BIT(29) +#define AR933X_GPIO_FUNC_I2S_MCK_EN BIT(27) +#define AR933X_GPIO_FUNC_I2SO_EN BIT(26) +#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_DUPL BIT(25) +#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_COLL BIT(24) +#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_ACT BIT(23) +#define AR933X_GPIO_FUNC_SPI_EN BIT(18) +#define AR933X_GPIO_FUNC_SPI_CS_EN2 BIT(14) +#define AR933X_GPIO_FUNC_SPI_CS_EN1 BIT(13) +#define AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7) +#define AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6) +#define AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5) +#define AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4) +#define AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3) +#define AR933X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2) +#define AR933X_GPIO_FUNC_UART_EN BIT(1) +#define AR933X_GPIO_FUNC_JTAG_DISABLE BIT(0) + +#define AR934X_GPIO_FUNC_DDR_DQOE_EN BIT(17) +#define AR934X_GPIO_FUNC_SPI_CS_1_EN BIT(14) +#define AR934X_GPIO_FUNC_SPI_CS_0_EN BIT(13) + +#define AR934X_GPIO_OUT_GPIO 0x00 + +/* + * MII_CTRL block + */ +#define AR71XX_MII_REG_MII0_CTRL 0x00 +#define AR71XX_MII_REG_MII1_CTRL 0x04 + +#define AR71XX_MII_CTRL_IF_MASK 3 +#define AR71XX_MII_CTRL_SPEED_SHIFT 4 +#define AR71XX_MII_CTRL_SPEED_MASK 3 +#define AR71XX_MII_CTRL_SPEED_10 0 +#define AR71XX_MII_CTRL_SPEED_100 1 +#define AR71XX_MII_CTRL_SPEED_1000 2 + +#define AR71XX_MII0_CTRL_IF_GMII 0 +#define AR71XX_MII0_CTRL_IF_MII 1 +#define AR71XX_MII0_CTRL_IF_RGMII 2 +#define AR71XX_MII0_CTRL_IF_RMII 3 + +#define AR71XX_MII1_CTRL_IF_RGMII 0 +#define AR71XX_MII1_CTRL_IF_RMII 1 + +/* + * AR933X GMAC interface + */ +#define AR933X_GMAC_REG_ETH_CFG 0x00 + +#define AR933X_ETH_CFG_RGMII_GE0 BIT(0) +#define AR933X_ETH_CFG_MII_GE0 BIT(1) +#define AR933X_ETH_CFG_GMII_GE0 BIT(2) +#define AR933X_ETH_CFG_MII_GE0_MASTER BIT(3) +#define AR933X_ETH_CFG_MII_GE0_SLAVE BIT(4) +#define AR933X_ETH_CFG_MII_GE0_ERR_EN BIT(5) +#define AR933X_ETH_CFG_SW_PHY_SWAP BIT(7) +#define AR933X_ETH_CFG_SW_PHY_ADDR_SWAP BIT(8) +#define AR933X_ETH_CFG_RMII_GE0 BIT(9) +#define AR933X_ETH_CFG_RMII_GE0_SPD_10 0 +#define AR933X_ETH_CFG_RMII_GE0_SPD_100 BIT(10) + +/* + * AR934X GMAC Interface + */ +#define AR934X_GMAC_REG_ETH_CFG 0x00 + +#define AR934X_ETH_CFG_RGMII_GMAC0 BIT(0) +#define AR934X_ETH_CFG_MII_GMAC0 BIT(1) +#define AR934X_ETH_CFG_GMII_GMAC0 BIT(2) +#define AR934X_ETH_CFG_MII_GMAC0_MASTER BIT(3) +#define AR934X_ETH_CFG_MII_GMAC0_SLAVE BIT(4) +#define AR934X_ETH_CFG_MII_GMAC0_ERR_EN BIT(5) +#define AR934X_ETH_CFG_SW_ONLY_MODE BIT(6) +#define AR934X_ETH_CFG_SW_PHY_SWAP BIT(7) +#define AR934X_ETH_CFG_SW_APB_ACCESS BIT(9) +#define AR934X_ETH_CFG_RMII_GMAC0 BIT(10) +#define AR933X_ETH_CFG_MII_CNTL_SPEED BIT(11) +#define AR934X_ETH_CFG_RMII_GMAC0_MASTER BIT(12) +#define AR933X_ETH_CFG_SW_ACC_MSB_FIRST BIT(13) + +/* + * QCA955X GMAC Interface + */ + +#define QCA955X_GMAC_REG_ETH_CFG 0x00 + +#define QCA955X_ETH_CFG_RGMII_GMAC0 BIT(0) +#define QCA955X_ETH_CFG_SGMII_GMAC0 BIT(6) + +#endif /* __ASM_MACH_AR71XX_REGS_H */ diff --git a/target/linux/ar71xx/image/lzma-loader/src/board.c b/target/linux/ar71xx/image/lzma-loader/src/board.c new file mode 100644 index 000000000..2f4dd6b1f --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/board.c @@ -0,0 +1,56 @@ +/* + * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards + * + * Copyright (C) 2011 Gabor Juhos + * + * This program 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. + */ + +#include +#include "config.h" +#include "ar71xx_regs.h" + +#define READREG(r) *(volatile unsigned int *)(r) +#define WRITEREG(r,v) *(volatile unsigned int *)(r) = v + +#define KSEG1ADDR(_x) (((_x) & 0x1fffffff) | 0xa0000000) + +#define UART_BASE 0xb8020000 + +#define UART_TX 0 +#define UART_LSR 5 + +#define UART_LSR_THRE 0x20 + +#define UART_READ(r) READREG(UART_BASE + 4 * (r)) +#define UART_WRITE(r,v) WRITEREG(UART_BASE + 4 * (r), (v)) + +void board_putc(int ch) +{ + while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0); + UART_WRITE(UART_TX, ch); + while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0); +} + +#ifdef CONFIG_BOARD_TL_WR1043ND_V1 +static void tlwr1043nd_init(void) +{ + unsigned int reg = KSEG1ADDR(AR71XX_RESET_BASE); + unsigned int t; + + t = READREG(reg + AR913X_RESET_REG_RESET_MODULE); + t |= AR71XX_RESET_GE0_PHY; + WRITEREG(reg + AR913X_RESET_REG_RESET_MODULE, t); + /* flush write */ + t = READREG(reg + AR913X_RESET_REG_RESET_MODULE); +} +#else +static inline void tlwr1043nd_init(void) {} +#endif + +void board_init(void) +{ + tlwr1043nd_init(); +} diff --git a/target/linux/ar71xx/image/lzma-loader/src/cache.c b/target/linux/ar71xx/image/lzma-loader/src/cache.c new file mode 100644 index 000000000..28cc84833 --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/cache.c @@ -0,0 +1,43 @@ +/* + * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards + * + * Copyright (C) 2011 Gabor Juhos + * + * The cache manipulation routine has been taken from the U-Boot project. + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, + * + * This program 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. + * + */ + +#include "cache.h" +#include "cacheops.h" +#include "config.h" + +#define cache_op(op,addr) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3\n\t \n" \ + " cache %0, %1 \n" \ + " .set pop \n" \ + : \ + : "i" (op), "R" (*(unsigned char *)(addr))) + +void flush_cache(unsigned long start_addr, unsigned long size) +{ + unsigned long lsize = CONFIG_CACHELINE_SIZE; + unsigned long addr = start_addr & ~(lsize - 1); + unsigned long aend = (start_addr + size - 1) & ~(lsize - 1); + + while (1) { + cache_op(Hit_Writeback_Inv_D, addr); + cache_op(Hit_Invalidate_I, addr); + if (addr == aend) + break; + addr += lsize; + } +} diff --git a/target/linux/ar71xx/image/lzma-loader/src/cache.h b/target/linux/ar71xx/image/lzma-loader/src/cache.h new file mode 100644 index 000000000..506a23588 --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/cache.h @@ -0,0 +1,17 @@ +/* + * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards + * + * Copyright (C) 2011 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef __CACHE_H +#define __CACHE_H + +void flush_cache(unsigned long start_addr, unsigned long size); + +#endif /* __CACHE_H */ diff --git a/target/linux/ar71xx/image/lzma-loader/src/cacheops.h b/target/linux/ar71xx/image/lzma-loader/src/cacheops.h new file mode 100644 index 000000000..70bcad769 --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/cacheops.h @@ -0,0 +1,85 @@ +/* + * Cache operations for the cache instruction. + * + * 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. + * + * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle + * (C) Copyright 1999 Silicon Graphics, Inc. + */ +#ifndef __ASM_CACHEOPS_H +#define __ASM_CACHEOPS_H + +/* + * Cache Operations available on all MIPS processors with R4000-style caches + */ +#define Index_Invalidate_I 0x00 +#define Index_Writeback_Inv_D 0x01 +#define Index_Load_Tag_I 0x04 +#define Index_Load_Tag_D 0x05 +#define Index_Store_Tag_I 0x08 +#define Index_Store_Tag_D 0x09 +#if defined(CONFIG_CPU_LOONGSON2) +#define Hit_Invalidate_I 0x00 +#else +#define Hit_Invalidate_I 0x10 +#endif +#define Hit_Invalidate_D 0x11 +#define Hit_Writeback_Inv_D 0x15 + +/* + * R4000-specific cacheops + */ +#define Create_Dirty_Excl_D 0x0d +#define Fill 0x14 +#define Hit_Writeback_I 0x18 +#define Hit_Writeback_D 0x19 + +/* + * R4000SC and R4400SC-specific cacheops + */ +#define Index_Invalidate_SI 0x02 +#define Index_Writeback_Inv_SD 0x03 +#define Index_Load_Tag_SI 0x06 +#define Index_Load_Tag_SD 0x07 +#define Index_Store_Tag_SI 0x0A +#define Index_Store_Tag_SD 0x0B +#define Create_Dirty_Excl_SD 0x0f +#define Hit_Invalidate_SI 0x12 +#define Hit_Invalidate_SD 0x13 +#define Hit_Writeback_Inv_SD 0x17 +#define Hit_Writeback_SD 0x1b +#define Hit_Set_Virtual_SI 0x1e +#define Hit_Set_Virtual_SD 0x1f + +/* + * R5000-specific cacheops + */ +#define R5K_Page_Invalidate_S 0x17 + +/* + * RM7000-specific cacheops + */ +#define Page_Invalidate_T 0x16 + +/* + * R10000-specific cacheops + * + * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. + * Most of the _S cacheops are identical to the R4000SC _SD cacheops. + */ +#define Index_Writeback_Inv_S 0x03 +#define Index_Load_Tag_S 0x07 +#define Index_Store_Tag_S 0x0B +#define Hit_Invalidate_S 0x13 +#define Cache_Barrier 0x14 +#define Hit_Writeback_Inv_S 0x17 +#define Index_Load_Data_I 0x18 +#define Index_Load_Data_D 0x19 +#define Index_Load_Data_S 0x1b +#define Index_Store_Data_I 0x1c +#define Index_Store_Data_D 0x1d +#define Index_Store_Data_S 0x1f + +#endif /* __ASM_CACHEOPS_H */ diff --git a/target/linux/ar71xx/image/lzma-loader/src/config.h b/target/linux/ar71xx/image/lzma-loader/src/config.h new file mode 100644 index 000000000..287392b34 --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/config.h @@ -0,0 +1,31 @@ +/* + * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards + * + * Copyright (C) 2011 Gabor Juhos + * + * This program 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. + * + */ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +#define CONFIG_ICACHE_SIZE (32 * 1024) +#define CONFIG_DCACHE_SIZE (64 * 1024) +#define CONFIG_CACHELINE_SIZE 32 + +#ifndef CONFIG_FLASH_OFFS +#define CONFIG_FLASH_OFFS 0 +#endif + +#ifndef CONFIG_FLASH_MAX +#define CONFIG_FLASH_MAX 0 +#endif + +#ifndef CONFIG_FLASH_STEP +#define CONFIG_FLASH_STEP 0x1000 +#endif + +#endif /* _CONFIG_H_ */ diff --git a/target/linux/ar71xx/image/lzma-loader/src/cp0regdef.h b/target/linux/ar71xx/image/lzma-loader/src/cp0regdef.h new file mode 100644 index 000000000..c1188ad8c --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/cp0regdef.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001 by Ralf Baechle + * + * Copyright (C) 2001, Monta Vista Software + * Author: jsun@mvista.com or jsun@junsun.net + */ +#ifndef _cp0regdef_h_ +#define _cp0regdef_h_ + +#define CP0_INDEX $0 +#define CP0_RANDOM $1 +#define CP0_ENTRYLO0 $2 +#define CP0_ENTRYLO1 $3 +#define CP0_CONTEXT $4 +#define CP0_PAGEMASK $5 +#define CP0_WIRED $6 +#define CP0_BADVADDR $8 +#define CP0_COUNT $9 +#define CP0_ENTRYHI $10 +#define CP0_COMPARE $11 +#define CP0_STATUS $12 +#define CP0_CAUSE $13 +#define CP0_EPC $14 +#define CP0_PRID $15 +#define CP0_CONFIG $16 +#define CP0_LLADDR $17 +#define CP0_WATCHLO $18 +#define CP0_WATCHHI $19 +#define CP0_XCONTEXT $20 +#define CP0_FRAMEMASK $21 +#define CP0_DIAGNOSTIC $22 +#define CP0_PERFORMANCE $25 +#define CP0_ECC $26 +#define CP0_CACHEERR $27 +#define CP0_TAGLO $28 +#define CP0_TAGHI $29 +#define CP0_ERROREPC $30 + +#endif diff --git a/target/linux/ar71xx/image/lzma-loader/src/head.S b/target/linux/ar71xx/image/lzma-loader/src/head.S new file mode 100644 index 000000000..543996a0d --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/head.S @@ -0,0 +1,118 @@ +/* + * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards + * + * Copyright (C) 2011 Gabor Juhos + * + * Some parts of this code was based on the OpenWrt specific lzma-loader + * for the BCM47xx and ADM5120 based boards: + * Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) + * Copyright (C) 2005 by Oleg I. Vdovikin + * + * This program 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. + */ + +#include +#include +#include "cp0regdef.h" +#include "cacheops.h" +#include "config.h" + +#define KSEG0 0x80000000 + + .macro ehb + sll zero, 3 + .endm + + .text + +LEAF(startup) + .set noreorder + .set mips32 + + mtc0 zero, CP0_WATCHLO # clear watch registers + mtc0 zero, CP0_WATCHHI + mtc0 zero, CP0_CAUSE # clear before writing status register + + mfc0 t0, CP0_STATUS + li t1, 0x1000001f + or t0, t1 + xori t0, 0x1f + mtc0 t0, CP0_STATUS + ehb + + mtc0 zero, CP0_COUNT + mtc0 zero, CP0_COMPARE + ehb + + la t0, __reloc_label # get linked address of label + bal __reloc_label # branch and link to label to + nop # get actual address +__reloc_label: + subu t0, ra, t0 # get reloc_delta + + beqz t0, __reloc_done # if delta is 0 we are in the right place + nop + + /* Copy our code to the right place */ + la t1, _code_start # get linked address of _code_start + la t2, _code_end # get linked address of _code_end + addu t0, t0, t1 # calculate actual address of _code_start + +__reloc_copy: + lw t3, 0(t0) + sw t3, 0(t1) + add t1, 4 + blt t1, t2, __reloc_copy + add t0, 4 + + /* flush cache */ + la t0, _code_start + la t1, _code_end + + li t2, ~(CONFIG_CACHELINE_SIZE - 1) + and t0, t2 + and t1, t2 + li t2, CONFIG_CACHELINE_SIZE + + b __flush_check + nop + +__flush_line: + cache Hit_Writeback_Inv_D, 0(t0) + cache Hit_Invalidate_I, 0(t0) + add t0, t2 + +__flush_check: + bne t0, t1, __flush_line + nop + + sync + +__reloc_done: + + /* clear bss */ + la t0, _bss_start + la t1, _bss_end + b __bss_check + nop + +__bss_fill: + sw zero, 0(t0) + addi t0, 4 + +__bss_check: + bne t0, t1, __bss_fill + nop + + /* Setup new "C" stack */ + la sp, _stack + + /* jump to the decompressor routine */ + la t0, loader_main + jr t0 + nop + + .set reorder +END(startup) diff --git a/target/linux/ar71xx/image/lzma-loader/src/loader.c b/target/linux/ar71xx/image/lzma-loader/src/loader.c new file mode 100644 index 000000000..5c674ae5f --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/loader.c @@ -0,0 +1,263 @@ +/* + * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards + * + * Copyright (C) 2011 Gabor Juhos + * + * Some parts of this code was based on the OpenWrt specific lzma-loader + * for the BCM47xx and ADM5120 based boards: + * Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) + * Copyright (C) 2005 Mineharu Takahara + * Copyright (C) 2005 by Oleg I. Vdovikin + * + * The image_header structure has been taken from the U-Boot project. + * (C) Copyright 2008 Semihalf + * (C) Copyright 2000-2005 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * This program 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. + */ + +#include +#include + +#include "config.h" +#include "cache.h" +#include "printf.h" +#include "LzmaDecode.h" + +#define AR71XX_FLASH_START 0x1f000000 +#define AR71XX_FLASH_END 0x1fe00000 + +#define KSEG0 0x80000000 +#define KSEG1 0xa0000000 + +#define KSEG1ADDR(a) ((((unsigned)(a)) & 0x1fffffffU) | KSEG1) + +#undef LZMA_DEBUG + +#ifdef LZMA_DEBUG +# define DBG(f, a...) printf(f, ## a) +#else +# define DBG(f, a...) do {} while (0) +#endif + +#define IH_MAGIC_OKLI 0x4f4b4c49 /* 'OKLI' */ + +#define IH_NMLEN 32 /* Image Name Length */ + +typedef struct image_header { + uint32_t ih_magic; /* Image Header Magic Number */ + uint32_t ih_hcrc; /* Image Header CRC Checksum */ + uint32_t ih_time; /* Image Creation Timestamp */ + uint32_t ih_size; /* Image Data Size */ + uint32_t ih_load; /* Data Load Address */ + uint32_t ih_ep; /* Entry Point Address */ + uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ + uint8_t ih_comp; /* Compression Type */ + uint8_t ih_name[IH_NMLEN]; /* Image Name */ +} image_header_t; + +/* beyond the image end, size not known in advance */ +extern unsigned char workspace[]; +extern void board_init(void); + +static CLzmaDecoderState lzma_state; +static unsigned char *lzma_data; +static unsigned long lzma_datasize; +static unsigned long lzma_outsize; +static unsigned long kernel_la; + +#ifdef CONFIG_KERNEL_CMDLINE +#define kernel_argc 1 +static const char kernel_cmdline[] = CONFIG_KERNEL_CMDLINE; +static const char *kernel_argv[] = { + kernel_cmdline, + NULL, +}; +#endif /* CONFIG_KERNEL_CMDLINE */ + +static void halt(void) +{ + printf("\nSystem halted!\n"); + for(;;); +} + +static __inline__ unsigned long get_be32(void *buf) +{ + unsigned char *p = buf; + + return (((unsigned long) p[0] << 24) + + ((unsigned long) p[1] << 16) + + ((unsigned long) p[2] << 8) + + (unsigned long) p[3]); +} + +static __inline__ unsigned char lzma_get_byte(void) +{ + unsigned char c; + + lzma_datasize--; + c = *lzma_data++; + + return c; +} + +static int lzma_init_props(void) +{ + unsigned char props[LZMA_PROPERTIES_SIZE]; + int res; + int i; + + /* read lzma properties */ + for (i = 0; i < LZMA_PROPERTIES_SIZE; i++) + props[i] = lzma_get_byte(); + + /* read the lower half of uncompressed size in the header */ + lzma_outsize = ((SizeT) lzma_get_byte()) + + ((SizeT) lzma_get_byte() << 8) + + ((SizeT) lzma_get_byte() << 16) + + ((SizeT) lzma_get_byte() << 24); + + /* skip rest of the header (upper half of uncompressed size) */ + for (i = 0; i < 4; i++) + lzma_get_byte(); + + res = LzmaDecodeProperties(&lzma_state.Properties, props, + LZMA_PROPERTIES_SIZE); + return res; +} + +static int lzma_decompress(unsigned char *outStream) +{ + SizeT ip, op; + int ret; + + lzma_state.Probs = (CProb *) workspace; + + ret = LzmaDecode(&lzma_state, lzma_data, lzma_datasize, &ip, outStream, + lzma_outsize, &op); + + if (ret != LZMA_RESULT_OK) { + int i; + + DBG("LzmaDecode error %d at %08x, osize:%d ip:%d op:%d\n", + ret, lzma_data + ip, lzma_outsize, ip, op); + + for (i = 0; i < 16; i++) + DBG("%02x ", lzma_data[ip + i]); + + DBG("\n"); + } + + return ret; +} + +#if (LZMA_WRAPPER) +static void lzma_init_data(void) +{ + extern unsigned char _lzma_data_start[]; + extern unsigned char _lzma_data_end[]; + + kernel_la = LOADADDR; + lzma_data = _lzma_data_start; + lzma_datasize = _lzma_data_end - _lzma_data_start; +} +#else +static void lzma_init_data(void) +{ + struct image_header *hdr = NULL; + unsigned char *flash_base; + unsigned long flash_ofs; + unsigned long kernel_ofs; + unsigned long kernel_size; + + flash_base = (unsigned char *) KSEG1ADDR(AR71XX_FLASH_START); + + printf("Looking for OpenWrt image... "); + + for (flash_ofs = CONFIG_FLASH_OFFS; + flash_ofs <= (CONFIG_FLASH_OFFS + CONFIG_FLASH_MAX); + flash_ofs += CONFIG_FLASH_STEP) { + unsigned long magic; + unsigned char *p; + + p = flash_base + flash_ofs; + magic = get_be32(p); + if (magic == IH_MAGIC_OKLI) { + hdr = (struct image_header *) p; + break; + } + } + + if (hdr == NULL) { + printf("not found!\n"); + halt(); + } + + printf("found at 0x%08x\n", flash_base + flash_ofs); + + kernel_ofs = sizeof(struct image_header); + kernel_size = get_be32(&hdr->ih_size); + kernel_la = get_be32(&hdr->ih_load); + + lzma_data = flash_base + flash_ofs + kernel_ofs; + lzma_datasize = kernel_size; +} +#endif /* (LZMA_WRAPPER) */ + +void loader_main(unsigned long reg_a0, unsigned long reg_a1, + unsigned long reg_a2, unsigned long reg_a3) +{ + void (*kernel_entry) (unsigned long, unsigned long, unsigned long, + unsigned long); + int res; + + board_init(); + + printf("\n\nOpenWrt kernel loader for AR7XXX/AR9XXX\n"); + printf("Copyright (C) 2011 Gabor Juhos \n"); + + lzma_init_data(); + + res = lzma_init_props(); + if (res != LZMA_RESULT_OK) { + printf("Incorrect LZMA stream properties!\n"); + halt(); + } + + printf("Decompressing kernel... "); + + res = lzma_decompress((unsigned char *) kernel_la); + if (res != LZMA_RESULT_OK) { + printf("failed, "); + switch (res) { + case LZMA_RESULT_DATA_ERROR: + printf("data error!\n"); + break; + default: + printf("unknown error %d!\n", res); + } + halt(); + } else { + printf("done!\n"); + } + + flush_cache(kernel_la, lzma_outsize); + + printf("Starting kernel at %08x...\n\n", kernel_la); + +#ifdef CONFIG_KERNEL_CMDLINE + reg_a0 = kernel_argc; + reg_a1 = (unsigned long) kernel_argv; + reg_a2 = 0; + reg_a3 = 0; +#endif + + kernel_entry = (void *) kernel_la; + kernel_entry(reg_a0, reg_a1, reg_a2, reg_a3); +} diff --git a/target/linux/ar71xx/image/lzma-loader/src/loader.lds b/target/linux/ar71xx/image/lzma-loader/src/loader.lds new file mode 100644 index 000000000..80cc7ca3e --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/loader.lds @@ -0,0 +1,35 @@ +OUTPUT_ARCH(mips) +SECTIONS { + .text : { + _code_start = .; + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + *(.data.lzma) + } + + . = ALIGN(32); + .data : { + *(.data) + *(.data.*) + . = . + 524288; /* workaround for buggy bootloaders */ + } + + . = ALIGN(32); + _code_end = .; + + _bss_start = .; + .bss : { + *(.bss) + *(.bss.*) + } + + . = ALIGN(32); + _bss_end = .; + + . = . + 8192; + _stack = .; + + workspace = .; +} diff --git a/target/linux/ar71xx/image/lzma-loader/src/lzma-data.lds b/target/linux/ar71xx/image/lzma-loader/src/lzma-data.lds new file mode 100644 index 000000000..abf756ba1 --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/lzma-data.lds @@ -0,0 +1,8 @@ +OUTPUT_ARCH(mips) +SECTIONS { + .data.lzma : { + _lzma_data_start = .; + *(.data) + _lzma_data_end = .; + } +} diff --git a/target/linux/ar71xx/image/lzma-loader/src/printf.c b/target/linux/ar71xx/image/lzma-loader/src/printf.c new file mode 100644 index 000000000..7bb5a86e1 --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/printf.c @@ -0,0 +1,350 @@ +/* + * Copyright (C) 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * 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. + * + */ + +#include "printf.h" + +extern void board_putc(int ch); + +/* this is the maximum width for a variable */ +#define LP_MAX_BUF 256 + +/* macros */ +#define IsDigit(x) ( ((x) >= '0') && ((x) <= '9') ) +#define Ctod(x) ( (x) - '0') + +/* forward declaration */ +static int PrintChar(char *, char, int, int); +static int PrintString(char *, char *, int, int); +static int PrintNum(char *, unsigned long, int, int, int, int, char, int); + +/* private variable */ +static const char theFatalMsg[] = "fatal error in lp_Print!"; + +/* -*- + * A low level printf() function. + */ +static void +lp_Print(void (*output)(void *, char *, int), + void * arg, + char *fmt, + va_list ap) +{ + +#define OUTPUT(arg, s, l) \ + { if (((l) < 0) || ((l) > LP_MAX_BUF)) { \ + (*output)(arg, (char*)theFatalMsg, sizeof(theFatalMsg)-1); for(;;); \ + } else { \ + (*output)(arg, s, l); \ + } \ + } + + char buf[LP_MAX_BUF]; + + char c; + char *s; + long int num; + + int longFlag; + int negFlag; + int width; + int prec; + int ladjust; + char padc; + + int length; + + for(;;) { + { + /* scan for the next '%' */ + char *fmtStart = fmt; + while ( (*fmt != '\0') && (*fmt != '%')) { + fmt ++; + } + + /* flush the string found so far */ + OUTPUT(arg, fmtStart, fmt-fmtStart); + + /* are we hitting the end? */ + if (*fmt == '\0') break; + } + + /* we found a '%' */ + fmt ++; + + /* check for long */ + if (*fmt == 'l') { + longFlag = 1; + fmt ++; + } else { + longFlag = 0; + } + + /* check for other prefixes */ + width = 0; + prec = -1; + ladjust = 0; + padc = ' '; + + if (*fmt == '-') { + ladjust = 1; + fmt ++; + } + + if (*fmt == '0') { + padc = '0'; + fmt++; + } + + if (IsDigit(*fmt)) { + while (IsDigit(*fmt)) { + width = 10 * width + Ctod(*fmt++); + } + } + + if (*fmt == '.') { + fmt ++; + if (IsDigit(*fmt)) { + prec = 0; + while (IsDigit(*fmt)) { + prec = prec*10 + Ctod(*fmt++); + } + } + } + + + /* check format flag */ + negFlag = 0; + switch (*fmt) { + case 'b': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 2, 0, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'd': + case 'D': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + if (num < 0) { + num = - num; + negFlag = 1; + } + length = PrintNum(buf, num, 10, negFlag, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'o': + case 'O': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 8, 0, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'u': + case 'U': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 10, 0, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'x': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'X': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 1); + OUTPUT(arg, buf, length); + break; + + case 'c': + c = (char)va_arg(ap, int); + length = PrintChar(buf, c, width, ladjust); + OUTPUT(arg, buf, length); + break; + + case 's': + s = (char*)va_arg(ap, char *); + length = PrintString(buf, s, width, ladjust); + OUTPUT(arg, buf, length); + break; + + case '\0': + fmt --; + break; + + default: + /* output this char as it is */ + OUTPUT(arg, fmt, 1); + } /* switch (*fmt) */ + + fmt ++; + } /* for(;;) */ + + /* special termination call */ + OUTPUT(arg, "\0", 1); +} + + +/* --------------- local help functions --------------------- */ +static int +PrintChar(char * buf, char c, int length, int ladjust) +{ + int i; + + if (length < 1) length = 1; + if (ladjust) { + *buf = c; + for (i=1; i< length; i++) buf[i] = ' '; + } else { + for (i=0; i< length-1; i++) buf[i] = ' '; + buf[length - 1] = c; + } + return length; +} + +static int +PrintString(char * buf, char* s, int length, int ladjust) +{ + int i; + int len=0; + char* s1 = s; + while (*s1++) len++; + if (length < len) length = len; + + if (ladjust) { + for (i=0; i< len; i++) buf[i] = s[i]; + for (i=len; i< length; i++) buf[i] = ' '; + } else { + for (i=0; i< length-len; i++) buf[i] = ' '; + for (i=length-len; i < length; i++) buf[i] = s[i-length+len]; + } + return length; +} + +static int +PrintNum(char * buf, unsigned long u, int base, int negFlag, + int length, int ladjust, char padc, int upcase) +{ + /* algorithm : + * 1. prints the number from left to right in reverse form. + * 2. fill the remaining spaces with padc if length is longer than + * the actual length + * TRICKY : if left adjusted, no "0" padding. + * if negtive, insert "0" padding between "0" and number. + * 3. if (!ladjust) we reverse the whole string including paddings + * 4. otherwise we only reverse the actual string representing the num. + */ + + int actualLength =0; + char *p = buf; + int i; + + do { + int tmp = u %base; + if (tmp <= 9) { + *p++ = '0' + tmp; + } else if (upcase) { + *p++ = 'A' + tmp - 10; + } else { + *p++ = 'a' + tmp - 10; + } + u /= base; + } while (u != 0); + + if (negFlag) { + *p++ = '-'; + } + + /* figure out actual length and adjust the maximum length */ + actualLength = p - buf; + if (length < actualLength) length = actualLength; + + /* add padding */ + if (ladjust) { + padc = ' '; + } + if (negFlag && !ladjust && (padc == '0')) { + for (i = actualLength-1; i< length-1; i++) buf[i] = padc; + buf[length -1] = '-'; + } else { + for (i = actualLength; i< length; i++) buf[i] = padc; + } + + + /* prepare to reverse the string */ + { + int begin = 0; + int end; + if (ladjust) { + end = actualLength - 1; + } else { + end = length -1; + } + + while (end > begin) { + char tmp = buf[begin]; + buf[begin] = buf[end]; + buf[end] = tmp; + begin ++; + end --; + } + } + + /* adjust the string pointer */ + return length; +} + +static void printf_output(void *arg, char *s, int l) +{ + int i; + + // special termination call + if ((l==1) && (s[0] == '\0')) return; + + for (i=0; i< l; i++) { + board_putc(s[i]); + if (s[i] == '\n') board_putc('\r'); + } +} + +void printf(char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + lp_Print(printf_output, 0, fmt, ap); + va_end(ap); +} diff --git a/target/linux/ar71xx/image/lzma-loader/src/printf.h b/target/linux/ar71xx/image/lzma-loader/src/printf.h new file mode 100644 index 000000000..9b1c1df23 --- /dev/null +++ b/target/linux/ar71xx/image/lzma-loader/src/printf.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * 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. + * + */ + +#ifndef _printf_h_ +#define _printf_h_ + +#include +void printf(char *fmt, ...); + +#endif /* _printf_h_ */ diff --git a/target/linux/ar71xx/modules.mk b/target/linux/ar71xx/modules.mk new file mode 100644 index 000000000..5607d188c --- /dev/null +++ b/target/linux/ar71xx/modules.mk @@ -0,0 +1,86 @@ +# +# Copyright (C) 2006-2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define KernelPackage/leds-rb750 + SUBMENU:=$(LEDS_MENU) + TITLE:=RouterBOARD 750 LED support + DEPENDS:=@TARGET_ar71xx + KCONFIG:=CONFIG_LEDS_RB750 + FILES:=$(LINUX_DIR)/drivers/leds/leds-rb750.ko + AUTOLOAD:=$(call AutoLoad,60,leds-rb750) +endef + +define KernelPackage/leds-rb750/description + Kernel module for the LEDs on the MikroTik RouterBOARD 750. +endef + +$(eval $(call KernelPackage,leds-rb750)) + + +define KernelPackage/leds-wndr3700-usb + SUBMENU:=$(LEDS_MENU) + TITLE:=WNDR3700 USB LED support + DEPENDS:=@TARGET_ar71xx + KCONFIG:=CONFIG_LEDS_WNDR3700_USB + FILES:=$(LINUX_DIR)/drivers/leds/leds-wndr3700-usb.ko + AUTOLOAD:=$(call AutoLoad,60,leds-wndr3700-usb) +endef + +define KernelPackage/leds-wndr3700-usb/description + Kernel module for the USB LED on the NETGEAR WNDR3700 board. +endef + +$(eval $(call KernelPackage,leds-wndr3700-usb)) + + +define KernelPackage/nand-ar934x + SUBMENU:=$(OTHER_MENU) + TITLE:=Atheros AR934x NAND flash controller driver + KCONFIG:=CONFIG_MTD_NAND_AR934X + DEPENDS:=@TARGET_ar71xx +kmod-nand + FILES:=$(LINUX_DIR)/drivers/mtd/nand/ar934x_nfc.ko + AUTOLOAD:=$(call AutoLoad,30,ar934x_nfc) +endef + +define KernelPackage/nand-ar934x/description + Atheros AR934x NAND flash controller driver. +endef + +$(eval $(call KernelPackage,nand-ar934x)) + + +define KernelPackage/spi-vsc7385 + SUBMENU:=$(SPI_MENU) + TITLE:=Vitesse VSC7385 ethernet switch driver + DEPENDS:=@TARGET_ar71xx + KCONFIG:=CONFIG_SPI_VSC7385 + FILES:=$(LINUX_DIR)/drivers/spi/spi-vsc7385.ko + AUTOLOAD:=$(call AutoLoad,93,spi-vsc7385) +endef + +define KernelPackage/spi-vsc7385/description + This package contains the SPI driver for the Vitesse VSC7385 ethernet switch. +endef + +$(eval $(call KernelPackage,spi-vsc7385)) + + +define KernelPackage/wdt-ath79 + SUBMENU:=$(OTHER_MENU) + TITLE:=Atheros AR7XXX/AR9XXX watchdog timer + DEPENDS:=@TARGET_ar71xx + KCONFIG:=CONFIG_ATH79_WDT + FILES:=$(LINUX_DIR)/drivers/$(WATCHDOG_DIR)/ath79_wdt.ko + AUTOLOAD:=$(call AutoLoad,50,ath79_wdt) +endef + +define KernelPackage/wdt-ath79/description + Kernel module for AR7XXX/AR9XXX watchdog timer. +endef + +$(eval $(call KernelPackage,wdt-ath79)) + diff --git a/target/linux/ar71xx/nand/config-default b/target/linux/ar71xx/nand/config-default new file mode 100644 index 000000000..1015cf1fb --- /dev/null +++ b/target/linux/ar71xx/nand/config-default @@ -0,0 +1,29 @@ +CONFIG_ATH79_DEV_NFC=y +CONFIG_CMDLINE="rootfstype=yaffs noinitrd" +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_FS is not set +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_GPIO=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_AR934X=y +CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_RB4XX=y +CONFIG_MTD_NAND_RB750=y +# CONFIG_MTD_SM_COMMON is not set +# CONFIG_OVERLAYFS_FS is not set +CONFIG_SPI_RB4XX=y +CONFIG_SPI_RB4XX_CPLD=y +# CONFIG_SQUASHFS is not set +CONFIG_YAFFS_9BYTE_TAGS=y +CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED=y +CONFIG_YAFFS_AUTO_YAFFS2=y +# CONFIG_YAFFS_DISABLE_BACKGROUND is not set +# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set +# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set +# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set +# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set +CONFIG_YAFFS_FS=y +CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y +CONFIG_YAFFS_XATTR=y +CONFIG_YAFFS_YAFFS1=y +CONFIG_YAFFS_YAFFS2=y diff --git a/target/linux/ar71xx/nand/profiles/01-minimal.mk b/target/linux/ar71xx/nand/profiles/01-minimal.mk new file mode 100644 index 000000000..3651c88ab --- /dev/null +++ b/target/linux/ar71xx/nand/profiles/01-minimal.mk @@ -0,0 +1,16 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/DefaultNoWifi + NAME:=Default Profile (no WiFi) + PACKAGES:= +endef + +define Profile/DefaultNoWifi/Description + Default package set compatible with most boards. +endef +$(eval $(call Profile,DefaultNoWifi)) diff --git a/target/linux/ar71xx/nand/profiles/02-ath5k.mk b/target/linux/ar71xx/nand/profiles/02-ath5k.mk new file mode 100644 index 000000000..a291ff68a --- /dev/null +++ b/target/linux/ar71xx/nand/profiles/02-ath5k.mk @@ -0,0 +1,16 @@ +# +# Copyright (C) 2009-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Ath5k + NAME:=Atheros WiFi (ath5k) + PACKAGES:=kmod-ath5k -kmod-ath9k +endef + +define Profile/Ath5k/Description + Package set compatible with hardware using Atheros WiFi cards. +endef +$(eval $(call Profile,Ath5k)) diff --git a/target/linux/ar71xx/nand/target.mk b/target/linux/ar71xx/nand/target.mk new file mode 100644 index 000000000..c571c5006 --- /dev/null +++ b/target/linux/ar71xx/nand/target.mk @@ -0,0 +1,8 @@ +BOARDNAME:=Devices with NAND flash (mostly Mikrotik) + +define Target/Description + Build firmware images for Atheros AR71xx/AR913x based boards with + NAND flash, e.g. MikroTik RB-4xx or RB-750 +endef + + diff --git a/target/linux/ar71xx/patches-3.3/000-USB-OHCI-Add-a-generic-platform-device-driver.patch b/target/linux/ar71xx/patches-3.3/000-USB-OHCI-Add-a-generic-platform-device-driver.patch new file mode 100644 index 000000000..240cca03b --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/000-USB-OHCI-Add-a-generic-platform-device-driver.patch @@ -0,0 +1,293 @@ +From be77ba57151bd35ce63ccf52d74b6c626fa73817 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Tue, 13 Mar 2012 01:04:47 +0100 +Subject: [PATCH 01/47] USB: OHCI: Add a generic platform device driver + +This adds a generic driver for platform devices. It works like the PCI +driver and is based on it. This is for devices which do not have an own +bus but their OHCI controller works like a PCI controller. It will be +used for the Broadcom bcma and ssb USB OHCI controller. + +Acked-by: Alan Stern +Signed-off-by: Hauke Mehrtens +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/Kconfig | 10 ++ + drivers/usb/host/ohci-hcd.c | 5 + + drivers/usb/host/ohci-platform.c | 194 ++++++++++++++++++++++++++++++++++++++ + include/linux/usb/ohci_pdriver.h | 38 ++++++++ + 4 files changed, 247 insertions(+), 0 deletions(-) + create mode 100644 drivers/usb/host/ohci-platform.c + create mode 100644 include/linux/usb/ohci_pdriver.h + +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -393,6 +393,16 @@ config USB_CNS3XXX_OHCI + Enable support for the CNS3XXX SOC's on-chip OHCI controller. + It is needed for low-speed USB 1.0 device support. + ++config USB_OHCI_HCD_PLATFORM ++ bool "Generic OHCI driver for a platform device" ++ depends on USB_OHCI_HCD && EXPERIMENTAL ++ default n ++ ---help--- ++ Adds an OHCI host driver for a generic platform device, which ++ provieds a memory space and an irq. ++ ++ If unsure, say N. ++ + config USB_OHCI_BIG_ENDIAN_DESC + bool + depends on USB_OHCI_HCD +--- a/drivers/usb/host/ohci-hcd.c ++++ b/drivers/usb/host/ohci-hcd.c +@@ -1121,6 +1121,11 @@ MODULE_LICENSE ("GPL"); + #define PLATFORM_DRIVER ohci_xls_driver + #endif + ++#ifdef CONFIG_USB_OHCI_HCD_PLATFORM ++#include "ohci-platform.c" ++#define PLATFORM_DRIVER ohci_platform_driver ++#endif ++ + #if !defined(PCI_DRIVER) && \ + !defined(PLATFORM_DRIVER) && \ + !defined(OMAP1_PLATFORM_DRIVER) && \ +--- /dev/null ++++ b/drivers/usb/host/ohci-platform.c +@@ -0,0 +1,194 @@ ++/* ++ * Generic platform ohci driver ++ * ++ * Copyright 2007 Michael Buesch ++ * Copyright 2011-2012 Hauke Mehrtens ++ * ++ * Derived from the OCHI-SSB driver ++ * Derived from the OHCI-PCI driver ++ * Copyright 1999 Roman Weissgaerber ++ * Copyright 2000-2002 David Brownell ++ * Copyright 1999 Linus Torvalds ++ * Copyright 1999 Gregory P. Smith ++ * ++ * Licensed under the GNU/GPL. See COPYING for details. ++ */ ++#include ++#include ++ ++static int ohci_platform_reset(struct usb_hcd *hcd) ++{ ++ struct platform_device *pdev = to_platform_device(hcd->self.controller); ++ struct usb_ohci_pdata *pdata = pdev->dev.platform_data; ++ struct ohci_hcd *ohci = hcd_to_ohci(hcd); ++ int err; ++ ++ if (pdata->big_endian_desc) ++ ohci->flags |= OHCI_QUIRK_BE_DESC; ++ if (pdata->big_endian_mmio) ++ ohci->flags |= OHCI_QUIRK_BE_MMIO; ++ if (pdata->no_big_frame_no) ++ ohci->flags |= OHCI_QUIRK_FRAME_NO; ++ ++ ohci_hcd_init(ohci); ++ err = ohci_init(ohci); ++ ++ return err; ++} ++ ++static int ohci_platform_start(struct usb_hcd *hcd) ++{ ++ struct ohci_hcd *ohci = hcd_to_ohci(hcd); ++ int err; ++ ++ err = ohci_run(ohci); ++ if (err < 0) { ++ ohci_err(ohci, "can't start\n"); ++ ohci_stop(hcd); ++ } ++ ++ return err; ++} ++ ++static const struct hc_driver ohci_platform_hc_driver = { ++ .description = hcd_name, ++ .product_desc = "Generic Platform OHCI Controller", ++ .hcd_priv_size = sizeof(struct ohci_hcd), ++ ++ .irq = ohci_irq, ++ .flags = HCD_MEMORY | HCD_USB11, ++ ++ .reset = ohci_platform_reset, ++ .start = ohci_platform_start, ++ .stop = ohci_stop, ++ .shutdown = ohci_shutdown, ++ ++ .urb_enqueue = ohci_urb_enqueue, ++ .urb_dequeue = ohci_urb_dequeue, ++ .endpoint_disable = ohci_endpoint_disable, ++ ++ .get_frame_number = ohci_get_frame, ++ ++ .hub_status_data = ohci_hub_status_data, ++ .hub_control = ohci_hub_control, ++#ifdef CONFIG_PM ++ .bus_suspend = ohci_bus_suspend, ++ .bus_resume = ohci_bus_resume, ++#endif ++ ++ .start_port_reset = ohci_start_port_reset, ++}; ++ ++static int __devinit ohci_platform_probe(struct platform_device *dev) ++{ ++ struct usb_hcd *hcd; ++ struct resource *res_mem; ++ int irq; ++ int err = -ENOMEM; ++ ++ BUG_ON(!dev->dev.platform_data); ++ ++ if (usb_disabled()) ++ return -ENODEV; ++ ++ irq = platform_get_irq(dev, 0); ++ if (irq < 0) { ++ pr_err("no irq provieded"); ++ return irq; ++ } ++ ++ res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); ++ if (!res_mem) { ++ pr_err("no memory recourse provieded"); ++ return -ENXIO; ++ } ++ ++ hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev, ++ dev_name(&dev->dev)); ++ if (!hcd) ++ return -ENOMEM; ++ ++ hcd->rsrc_start = res_mem->start; ++ hcd->rsrc_len = resource_size(res_mem); ++ ++ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { ++ pr_err("controller already in use"); ++ err = -EBUSY; ++ goto err_put_hcd; ++ } ++ ++ hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); ++ if (!hcd->regs) ++ goto err_release_region; ++ err = usb_add_hcd(hcd, irq, IRQF_SHARED); ++ if (err) ++ goto err_iounmap; ++ ++ platform_set_drvdata(dev, hcd); ++ ++ return err; ++ ++err_iounmap: ++ iounmap(hcd->regs); ++err_release_region: ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); ++err_put_hcd: ++ usb_put_hcd(hcd); ++ return err; ++} ++ ++static int __devexit ohci_platform_remove(struct platform_device *dev) ++{ ++ struct usb_hcd *hcd = platform_get_drvdata(dev); ++ ++ usb_remove_hcd(hcd); ++ iounmap(hcd->regs); ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); ++ usb_put_hcd(hcd); ++ platform_set_drvdata(dev, NULL); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++ ++static int ohci_platform_suspend(struct device *dev) ++{ ++ return 0; ++} ++ ++static int ohci_platform_resume(struct device *dev) ++{ ++ struct usb_hcd *hcd = dev_get_drvdata(dev); ++ ++ ohci_finish_controller_resume(hcd); ++ return 0; ++} ++ ++#else /* !CONFIG_PM */ ++#define ohci_platform_suspend NULL ++#define ohci_platform_resume NULL ++#endif /* CONFIG_PM */ ++ ++static const struct platform_device_id ohci_platform_table[] = { ++ { "ohci-platform", 0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(platform, ohci_platform_table); ++ ++static const struct dev_pm_ops ohci_platform_pm_ops = { ++ .suspend = ohci_platform_suspend, ++ .resume = ohci_platform_resume, ++}; ++ ++static struct platform_driver ohci_platform_driver = { ++ .id_table = ohci_platform_table, ++ .probe = ohci_platform_probe, ++ .remove = __devexit_p(ohci_platform_remove), ++ .shutdown = usb_hcd_platform_shutdown, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "ohci-platform", ++ .pm = &ohci_platform_pm_ops, ++ } ++}; +--- /dev/null ++++ b/include/linux/usb/ohci_pdriver.h +@@ -0,0 +1,38 @@ ++/* ++ * Copyright (C) 2012 Hauke Mehrtens ++ * ++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#ifndef __USB_CORE_OHCI_PDRIVER_H ++#define __USB_CORE_OHCI_PDRIVER_H ++ ++/** ++ * struct usb_ohci_pdata - platform_data for generic ohci driver ++ * ++ * @big_endian_desc: BE descriptors ++ * @big_endian_mmio: BE registers ++ * @no_big_frame_no: no big endian frame_no shift ++ * ++ * These are general configuration options for the OHCI controller. All of ++ * these options are activating more or less workarounds for some hardware. ++ */ ++struct usb_ohci_pdata { ++ unsigned big_endian_desc:1; ++ unsigned big_endian_mmio:1; ++ unsigned no_big_frame_no:1; ++}; ++ ++#endif /* __USB_CORE_OHCI_PDRIVER_H */ diff --git a/target/linux/ar71xx/patches-3.3/001-USB-EHCI-Add-a-generic-platform-device-driver.patch b/target/linux/ar71xx/patches-3.3/001-USB-EHCI-Add-a-generic-platform-device-driver.patch new file mode 100644 index 000000000..f94f39c2e --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/001-USB-EHCI-Add-a-generic-platform-device-driver.patch @@ -0,0 +1,305 @@ +From 4fa3face95f1ca2e396dd59324a6c6ef01df24cc Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Tue, 13 Mar 2012 01:04:48 +0100 +Subject: [PATCH 02/47] USB: EHCI: Add a generic platform device driver + +This adds a generic driver for platform devices. It works like the PCI +driver and is based on it. This is for devices which do not have an own +bus but their EHCI controller works like a PCI controller. It will be +used for the Broadcom bcma and ssb USB EHCI controller. + +Acked-by: Alan Stern +Signed-off-by: Hauke Mehrtens +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/Kconfig | 10 ++ + drivers/usb/host/ehci-hcd.c | 5 + + drivers/usb/host/ehci-platform.c | 198 ++++++++++++++++++++++++++++++++++++++ + include/linux/usb/ehci_pdriver.h | 46 +++++++++ + 4 files changed, 259 insertions(+), 0 deletions(-) + create mode 100644 drivers/usb/host/ehci-platform.c + create mode 100644 include/linux/usb/ehci_pdriver.h + +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -403,6 +403,16 @@ config USB_OHCI_HCD_PLATFORM + + If unsure, say N. + ++config USB_EHCI_HCD_PLATFORM ++ bool "Generic EHCI driver for a platform device" ++ depends on USB_EHCI_HCD && EXPERIMENTAL ++ default n ++ ---help--- ++ Adds an EHCI host driver for a generic platform device, which ++ provieds a memory space and an irq. ++ ++ If unsure, say N. ++ + config USB_OHCI_BIG_ENDIAN_DESC + bool + depends on USB_OHCI_HCD +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -1381,6 +1381,11 @@ MODULE_LICENSE ("GPL"); + #define PLATFORM_DRIVER ehci_mv_driver + #endif + ++#ifdef CONFIG_USB_EHCI_HCD_PLATFORM ++#include "ehci-platform.c" ++#define PLATFORM_DRIVER ehci_platform_driver ++#endif ++ + #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ + !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ + !defined(XILINX_OF_PLATFORM_DRIVER) +--- /dev/null ++++ b/drivers/usb/host/ehci-platform.c +@@ -0,0 +1,198 @@ ++/* ++ * Generic platform ehci driver ++ * ++ * Copyright 2007 Steven Brown ++ * Copyright 2010-2012 Hauke Mehrtens ++ * ++ * Derived from the ohci-ssb driver ++ * Copyright 2007 Michael Buesch ++ * ++ * Derived from the EHCI-PCI driver ++ * Copyright (c) 2000-2004 by David Brownell ++ * ++ * Derived from the ohci-pci driver ++ * Copyright 1999 Roman Weissgaerber ++ * Copyright 2000-2002 David Brownell ++ * Copyright 1999 Linus Torvalds ++ * Copyright 1999 Gregory P. Smith ++ * ++ * Licensed under the GNU/GPL. See COPYING for details. ++ */ ++#include ++#include ++ ++static int ehci_platform_reset(struct usb_hcd *hcd) ++{ ++ struct platform_device *pdev = to_platform_device(hcd->self.controller); ++ struct usb_ehci_pdata *pdata = pdev->dev.platform_data; ++ struct ehci_hcd *ehci = hcd_to_ehci(hcd); ++ int retval; ++ ++ hcd->has_tt = pdata->has_tt; ++ ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug; ++ ehci->big_endian_desc = pdata->big_endian_desc; ++ ehci->big_endian_mmio = pdata->big_endian_mmio; ++ ++ ehci->caps = hcd->regs + pdata->caps_offset; ++ retval = ehci_setup(hcd); ++ if (retval) ++ return retval; ++ ++ if (pdata->port_power_on) ++ ehci_port_power(ehci, 1); ++ if (pdata->port_power_off) ++ ehci_port_power(ehci, 0); ++ ++ return 0; ++} ++ ++static const struct hc_driver ehci_platform_hc_driver = { ++ .description = hcd_name, ++ .product_desc = "Generic Platform EHCI Controller", ++ .hcd_priv_size = sizeof(struct ehci_hcd), ++ ++ .irq = ehci_irq, ++ .flags = HCD_MEMORY | HCD_USB2, ++ ++ .reset = ehci_platform_reset, ++ .start = ehci_run, ++ .stop = ehci_stop, ++ .shutdown = ehci_shutdown, ++ ++ .urb_enqueue = ehci_urb_enqueue, ++ .urb_dequeue = ehci_urb_dequeue, ++ .endpoint_disable = ehci_endpoint_disable, ++ .endpoint_reset = ehci_endpoint_reset, ++ ++ .get_frame_number = ehci_get_frame, ++ ++ .hub_status_data = ehci_hub_status_data, ++ .hub_control = ehci_hub_control, ++#if defined(CONFIG_PM) ++ .bus_suspend = ehci_bus_suspend, ++ .bus_resume = ehci_bus_resume, ++#endif ++ .relinquish_port = ehci_relinquish_port, ++ .port_handed_over = ehci_port_handed_over, ++ ++ .update_device = ehci_update_device, ++ ++ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, ++}; ++ ++static int __devinit ehci_platform_probe(struct platform_device *dev) ++{ ++ struct usb_hcd *hcd; ++ struct resource *res_mem; ++ int irq; ++ int err = -ENOMEM; ++ ++ BUG_ON(!dev->dev.platform_data); ++ ++ if (usb_disabled()) ++ return -ENODEV; ++ ++ irq = platform_get_irq(dev, 0); ++ if (irq < 0) { ++ pr_err("no irq provieded"); ++ return irq; ++ } ++ res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); ++ if (!res_mem) { ++ pr_err("no memory recourse provieded"); ++ return -ENXIO; ++ } ++ ++ hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev, ++ dev_name(&dev->dev)); ++ if (!hcd) ++ return -ENOMEM; ++ ++ hcd->rsrc_start = res_mem->start; ++ hcd->rsrc_len = resource_size(res_mem); ++ ++ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { ++ pr_err("controller already in use"); ++ err = -EBUSY; ++ goto err_put_hcd; ++ } ++ ++ hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); ++ if (!hcd->regs) ++ goto err_release_region; ++ err = usb_add_hcd(hcd, irq, IRQF_SHARED); ++ if (err) ++ goto err_iounmap; ++ ++ platform_set_drvdata(dev, hcd); ++ ++ return err; ++ ++err_iounmap: ++ iounmap(hcd->regs); ++err_release_region: ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); ++err_put_hcd: ++ usb_put_hcd(hcd); ++ return err; ++} ++ ++static int __devexit ehci_platform_remove(struct platform_device *dev) ++{ ++ struct usb_hcd *hcd = platform_get_drvdata(dev); ++ ++ usb_remove_hcd(hcd); ++ iounmap(hcd->regs); ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); ++ usb_put_hcd(hcd); ++ platform_set_drvdata(dev, NULL); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++ ++static int ehci_platform_suspend(struct device *dev) ++{ ++ struct usb_hcd *hcd = dev_get_drvdata(dev); ++ bool wakeup = device_may_wakeup(dev); ++ ++ ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd), wakeup); ++ return 0; ++} ++ ++static int ehci_platform_resume(struct device *dev) ++{ ++ struct usb_hcd *hcd = dev_get_drvdata(dev); ++ ++ ehci_prepare_ports_for_controller_resume(hcd_to_ehci(hcd)); ++ return 0; ++} ++ ++#else /* !CONFIG_PM */ ++#define ehci_platform_suspend NULL ++#define ehci_platform_resume NULL ++#endif /* CONFIG_PM */ ++ ++static const struct platform_device_id ehci_platform_table[] = { ++ { "ehci-platform", 0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(platform, ehci_platform_table); ++ ++static const struct dev_pm_ops ehci_platform_pm_ops = { ++ .suspend = ehci_platform_suspend, ++ .resume = ehci_platform_resume, ++}; ++ ++static struct platform_driver ehci_platform_driver = { ++ .id_table = ehci_platform_table, ++ .probe = ehci_platform_probe, ++ .remove = __devexit_p(ehci_platform_remove), ++ .shutdown = usb_hcd_platform_shutdown, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "ehci-platform", ++ .pm = &ehci_platform_pm_ops, ++ } ++}; +--- /dev/null ++++ b/include/linux/usb/ehci_pdriver.h +@@ -0,0 +1,46 @@ ++/* ++ * Copyright (C) 2012 Hauke Mehrtens ++ * ++ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#ifndef __USB_CORE_EHCI_PDRIVER_H ++#define __USB_CORE_EHCI_PDRIVER_H ++ ++/** ++ * struct usb_ehci_pdata - platform_data for generic ehci driver ++ * ++ * @caps_offset: offset of the EHCI Capability Registers to the start of ++ * the io memory region provided to the driver. ++ * @has_tt: set to 1 if TT is integrated in root hub. ++ * @port_power_on: set to 1 if the controller needs a power up after ++ * initialization. ++ * @port_power_off: set to 1 if the controller needs to be powered down ++ * after initialization. ++ * ++ * These are general configuration options for the EHCI controller. All of ++ * these options are activating more or less workarounds for some hardware. ++ */ ++struct usb_ehci_pdata { ++ int caps_offset; ++ unsigned has_tt:1; ++ unsigned has_synopsys_hc_bug:1; ++ unsigned big_endian_desc:1; ++ unsigned big_endian_mmio:1; ++ unsigned port_power_on:1; ++ unsigned port_power_off:1; ++}; ++ ++#endif /* __USB_CORE_EHCI_PDRIVER_H */ diff --git a/target/linux/ar71xx/patches-3.3/002-USB-use-generic-platform-driver-on-ath79.patch b/target/linux/ar71xx/patches-3.3/002-USB-use-generic-platform-driver-on-ath79.patch new file mode 100644 index 000000000..d3a3b7106 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/002-USB-use-generic-platform-driver-on-ath79.patch @@ -0,0 +1,544 @@ +From dbcbcdd001c5943adbb18db3b8f0dafc405559eb Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Tue, 13 Mar 2012 01:04:53 +0100 +Subject: [PATCH 03/47] USB: use generic platform driver on ath79 + +The ath79 usb driver doesn't do anything special and is now converted +to the generic ehci and ohci driver. +This was tested on a TP-Link TL-WR1043ND (AR9132) + +Acked-by: Gabor Juhos +CC: Imre Kaloz +CC: linux-mips@linux-mips.org +CC: Ralf Baechle +Signed-off-by: Hauke Mehrtens +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/ath79/dev-usb.c | 31 +++++- + drivers/usb/host/Kconfig | 12 ++- + drivers/usb/host/ehci-ath79.c | 208 ----------------------------------------- + drivers/usb/host/ehci-hcd.c | 5 - + drivers/usb/host/ohci-ath79.c | 151 ----------------------------- + drivers/usb/host/ohci-hcd.c | 5 - + 6 files changed, 35 insertions(+), 377 deletions(-) + delete mode 100644 drivers/usb/host/ehci-ath79.c + delete mode 100644 drivers/usb/host/ohci-ath79.c + +--- a/arch/mips/ath79/dev-usb.c ++++ b/arch/mips/ath79/dev-usb.c +@@ -17,6 +17,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -36,14 +38,19 @@ static struct resource ath79_ohci_resour + }; + + static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32); ++ ++static struct usb_ohci_pdata ath79_ohci_pdata = { ++}; ++ + static struct platform_device ath79_ohci_device = { +- .name = "ath79-ohci", ++ .name = "ohci-platform", + .id = -1, + .resource = ath79_ohci_resources, + .num_resources = ARRAY_SIZE(ath79_ohci_resources), + .dev = { + .dma_mask = &ath79_ohci_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), ++ .platform_data = &ath79_ohci_pdata, + }, + }; + +@@ -60,8 +67,20 @@ static struct resource ath79_ehci_resour + }; + + static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32); ++ ++static struct usb_ehci_pdata ath79_ehci_pdata_v1 = { ++ .has_synopsys_hc_bug = 1, ++ .port_power_off = 1, ++}; ++ ++static struct usb_ehci_pdata ath79_ehci_pdata_v2 = { ++ .caps_offset = 0x100, ++ .has_tt = 1, ++ .port_power_off = 1, ++}; ++ + static struct platform_device ath79_ehci_device = { +- .name = "ath79-ehci", ++ .name = "ehci-platform", + .id = -1, + .resource = ath79_ehci_resources, + .num_resources = ARRAY_SIZE(ath79_ehci_resources), +@@ -101,7 +120,7 @@ static void __init ath79_usb_setup(void) + + ath79_ehci_resources[0].start = AR71XX_EHCI_BASE; + ath79_ehci_resources[0].end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1; +- ath79_ehci_device.name = "ar71xx-ehci"; ++ ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v1; + platform_device_register(&ath79_ehci_device); + } + +@@ -142,7 +161,7 @@ static void __init ar724x_usb_setup(void + + ath79_ehci_resources[0].start = AR724X_EHCI_BASE; + ath79_ehci_resources[0].end = AR724X_EHCI_BASE + AR724X_EHCI_SIZE - 1; +- ath79_ehci_device.name = "ar724x-ehci"; ++ ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; + platform_device_register(&ath79_ehci_device); + } + +@@ -159,7 +178,7 @@ static void __init ar913x_usb_setup(void + + ath79_ehci_resources[0].start = AR913X_EHCI_BASE; + ath79_ehci_resources[0].end = AR913X_EHCI_BASE + AR913X_EHCI_SIZE - 1; +- ath79_ehci_device.name = "ar913x-ehci"; ++ ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; + platform_device_register(&ath79_ehci_device); + } + +@@ -176,7 +195,7 @@ static void __init ar933x_usb_setup(void + + ath79_ehci_resources[0].start = AR933X_EHCI_BASE; + ath79_ehci_resources[0].end = AR933X_EHCI_BASE + AR933X_EHCI_SIZE - 1; +- ath79_ehci_device.name = "ar933x-ehci"; ++ ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; + platform_device_register(&ath79_ehci_device); + } + +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -218,11 +218,15 @@ config USB_CNS3XXX_EHCI + support. + + config USB_EHCI_ATH79 +- bool "EHCI support for AR7XXX/AR9XXX SoCs" ++ bool "EHCI support for AR7XXX/AR9XXX SoCs (DEPRECATED)" + depends on USB_EHCI_HCD && (SOC_AR71XX || SOC_AR724X || SOC_AR913X || SOC_AR933X) + select USB_EHCI_ROOT_HUB_TT ++ select USB_EHCI_HCD_PLATFORM + default y + ---help--- ++ This option is deprecated now and the driver was removed, use ++ USB_EHCI_HCD_PLATFORM instead. ++ + Enables support for the built-in EHCI controller present + on the Atheros AR7XXX/AR9XXX SoCs. + +@@ -312,10 +316,14 @@ config USB_OHCI_HCD_OMAP3 + OMAP3 and later chips. + + config USB_OHCI_ATH79 +- bool "USB OHCI support for the Atheros AR71XX/AR7240 SoCs" ++ bool "USB OHCI support for the Atheros AR71XX/AR7240 SoCs (DEPRECATED)" + depends on USB_OHCI_HCD && (SOC_AR71XX || SOC_AR724X) ++ select USB_OHCI_HCD_PLATFORM + default y + help ++ This option is deprecated now and the driver was removed, use ++ USB_OHCI_HCD_PLATFORM instead. ++ + Enables support for the built-in OHCI controller present on the + Atheros AR71XX/AR7240 SoCs. + +--- a/drivers/usb/host/ehci-ath79.c ++++ /dev/null +@@ -1,208 +0,0 @@ +-/* +- * Bus Glue for Atheros AR7XXX/AR9XXX built-in EHCI controller. +- * +- * Copyright (C) 2008-2011 Gabor Juhos +- * Copyright (C) 2008 Imre Kaloz +- * +- * Parts of this file are based on Atheros' 2.6.15 BSP +- * Copyright (C) 2007 Atheros Communications, Inc. +- * +- * This program 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. +- */ +- +-#include +- +-enum { +- EHCI_ATH79_IP_V1 = 0, +- EHCI_ATH79_IP_V2, +-}; +- +-static const struct platform_device_id ehci_ath79_id_table[] = { +- { +- .name = "ar71xx-ehci", +- .driver_data = EHCI_ATH79_IP_V1, +- }, +- { +- .name = "ar724x-ehci", +- .driver_data = EHCI_ATH79_IP_V2, +- }, +- { +- .name = "ar913x-ehci", +- .driver_data = EHCI_ATH79_IP_V2, +- }, +- { +- .name = "ar933x-ehci", +- .driver_data = EHCI_ATH79_IP_V2, +- }, +- { +- /* terminating entry */ +- }, +-}; +- +-MODULE_DEVICE_TABLE(platform, ehci_ath79_id_table); +- +-static int ehci_ath79_init(struct usb_hcd *hcd) +-{ +- struct ehci_hcd *ehci = hcd_to_ehci(hcd); +- struct platform_device *pdev = to_platform_device(hcd->self.controller); +- const struct platform_device_id *id; +- int ret; +- +- id = platform_get_device_id(pdev); +- if (!id) { +- dev_err(hcd->self.controller, "missing device id\n"); +- return -EINVAL; +- } +- +- switch (id->driver_data) { +- case EHCI_ATH79_IP_V1: +- ehci->has_synopsys_hc_bug = 1; +- +- ehci->caps = hcd->regs; +- ehci->regs = hcd->regs + +- HC_LENGTH(ehci, +- ehci_readl(ehci, &ehci->caps->hc_capbase)); +- break; +- +- case EHCI_ATH79_IP_V2: +- hcd->has_tt = 1; +- +- ehci->caps = hcd->regs + 0x100; +- ehci->regs = hcd->regs + 0x100 + +- HC_LENGTH(ehci, +- ehci_readl(ehci, &ehci->caps->hc_capbase)); +- break; +- +- default: +- BUG(); +- } +- +- dbg_hcs_params(ehci, "reset"); +- dbg_hcc_params(ehci, "reset"); +- ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); +- ehci->sbrn = 0x20; +- +- ehci_reset(ehci); +- +- ret = ehci_init(hcd); +- if (ret) +- return ret; +- +- ehci_port_power(ehci, 0); +- +- return 0; +-} +- +-static const struct hc_driver ehci_ath79_hc_driver = { +- .description = hcd_name, +- .product_desc = "Atheros built-in EHCI controller", +- .hcd_priv_size = sizeof(struct ehci_hcd), +- .irq = ehci_irq, +- .flags = HCD_MEMORY | HCD_USB2, +- +- .reset = ehci_ath79_init, +- .start = ehci_run, +- .stop = ehci_stop, +- .shutdown = ehci_shutdown, +- +- .urb_enqueue = ehci_urb_enqueue, +- .urb_dequeue = ehci_urb_dequeue, +- .endpoint_disable = ehci_endpoint_disable, +- .endpoint_reset = ehci_endpoint_reset, +- +- .get_frame_number = ehci_get_frame, +- +- .hub_status_data = ehci_hub_status_data, +- .hub_control = ehci_hub_control, +- +- .relinquish_port = ehci_relinquish_port, +- .port_handed_over = ehci_port_handed_over, +- +- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, +-}; +- +-static int ehci_ath79_probe(struct platform_device *pdev) +-{ +- struct usb_hcd *hcd; +- struct resource *res; +- int irq; +- int ret; +- +- if (usb_disabled()) +- return -ENODEV; +- +- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); +- if (!res) { +- dev_dbg(&pdev->dev, "no IRQ specified\n"); +- return -ENODEV; +- } +- irq = res->start; +- +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (!res) { +- dev_dbg(&pdev->dev, "no base address specified\n"); +- return -ENODEV; +- } +- +- hcd = usb_create_hcd(&ehci_ath79_hc_driver, &pdev->dev, +- dev_name(&pdev->dev)); +- if (!hcd) +- return -ENOMEM; +- +- hcd->rsrc_start = res->start; +- hcd->rsrc_len = resource_size(res); +- +- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { +- dev_dbg(&pdev->dev, "controller already in use\n"); +- ret = -EBUSY; +- goto err_put_hcd; +- } +- +- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); +- if (!hcd->regs) { +- dev_dbg(&pdev->dev, "error mapping memory\n"); +- ret = -EFAULT; +- goto err_release_region; +- } +- +- ret = usb_add_hcd(hcd, irq, IRQF_SHARED); +- if (ret) +- goto err_iounmap; +- +- return 0; +- +-err_iounmap: +- iounmap(hcd->regs); +- +-err_release_region: +- release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +-err_put_hcd: +- usb_put_hcd(hcd); +- return ret; +-} +- +-static int ehci_ath79_remove(struct platform_device *pdev) +-{ +- struct usb_hcd *hcd = platform_get_drvdata(pdev); +- +- usb_remove_hcd(hcd); +- iounmap(hcd->regs); +- release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +- usb_put_hcd(hcd); +- +- return 0; +-} +- +-static struct platform_driver ehci_ath79_driver = { +- .probe = ehci_ath79_probe, +- .remove = ehci_ath79_remove, +- .id_table = ehci_ath79_id_table, +- .driver = { +- .owner = THIS_MODULE, +- .name = "ath79-ehci", +- } +-}; +- +-MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ath79-ehci"); +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -1356,11 +1356,6 @@ MODULE_LICENSE ("GPL"); + #define PLATFORM_DRIVER s5p_ehci_driver + #endif + +-#ifdef CONFIG_USB_EHCI_ATH79 +-#include "ehci-ath79.c" +-#define PLATFORM_DRIVER ehci_ath79_driver +-#endif +- + #ifdef CONFIG_SPARC_LEON + #include "ehci-grlib.c" + #define PLATFORM_DRIVER ehci_grlib_driver +--- a/drivers/usb/host/ohci-ath79.c ++++ /dev/null +@@ -1,151 +0,0 @@ +-/* +- * OHCI HCD (Host Controller Driver) for USB. +- * +- * Bus Glue for Atheros AR71XX/AR724X built-in OHCI controller. +- * +- * Copyright (C) 2008-2011 Gabor Juhos +- * Copyright (C) 2008 Imre Kaloz +- * +- * Parts of this file are based on Atheros' 2.6.15 BSP +- * Copyright (C) 2007 Atheros Communications, Inc. +- * +- * This program 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. +- */ +- +-#include +- +-static int __devinit ohci_ath79_start(struct usb_hcd *hcd) +-{ +- struct ohci_hcd *ohci = hcd_to_ohci(hcd); +- int ret; +- +- ret = ohci_init(ohci); +- if (ret < 0) +- return ret; +- +- ret = ohci_run(ohci); +- if (ret < 0) +- goto err; +- +- return 0; +- +-err: +- ohci_stop(hcd); +- return ret; +-} +- +-static const struct hc_driver ohci_ath79_hc_driver = { +- .description = hcd_name, +- .product_desc = "Atheros built-in OHCI controller", +- .hcd_priv_size = sizeof(struct ohci_hcd), +- +- .irq = ohci_irq, +- .flags = HCD_USB11 | HCD_MEMORY, +- +- .start = ohci_ath79_start, +- .stop = ohci_stop, +- .shutdown = ohci_shutdown, +- +- .urb_enqueue = ohci_urb_enqueue, +- .urb_dequeue = ohci_urb_dequeue, +- .endpoint_disable = ohci_endpoint_disable, +- +- /* +- * scheduling support +- */ +- .get_frame_number = ohci_get_frame, +- +- /* +- * root hub support +- */ +- .hub_status_data = ohci_hub_status_data, +- .hub_control = ohci_hub_control, +- .start_port_reset = ohci_start_port_reset, +-}; +- +-static int ohci_ath79_probe(struct platform_device *pdev) +-{ +- struct usb_hcd *hcd; +- struct resource *res; +- int irq; +- int ret; +- +- if (usb_disabled()) +- return -ENODEV; +- +- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); +- if (!res) { +- dev_dbg(&pdev->dev, "no IRQ specified\n"); +- return -ENODEV; +- } +- irq = res->start; +- +- hcd = usb_create_hcd(&ohci_ath79_hc_driver, &pdev->dev, +- dev_name(&pdev->dev)); +- if (!hcd) +- return -ENOMEM; +- +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (!res) { +- dev_dbg(&pdev->dev, "no base address specified\n"); +- ret = -ENODEV; +- goto err_put_hcd; +- } +- hcd->rsrc_start = res->start; +- hcd->rsrc_len = resource_size(res); +- +- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { +- dev_dbg(&pdev->dev, "controller already in use\n"); +- ret = -EBUSY; +- goto err_put_hcd; +- } +- +- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); +- if (!hcd->regs) { +- dev_dbg(&pdev->dev, "error mapping memory\n"); +- ret = -EFAULT; +- goto err_release_region; +- } +- +- ohci_hcd_init(hcd_to_ohci(hcd)); +- +- ret = usb_add_hcd(hcd, irq, 0); +- if (ret) +- goto err_stop_hcd; +- +- return 0; +- +-err_stop_hcd: +- iounmap(hcd->regs); +-err_release_region: +- release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +-err_put_hcd: +- usb_put_hcd(hcd); +- return ret; +-} +- +-static int ohci_ath79_remove(struct platform_device *pdev) +-{ +- struct usb_hcd *hcd = platform_get_drvdata(pdev); +- +- usb_remove_hcd(hcd); +- iounmap(hcd->regs); +- release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +- usb_put_hcd(hcd); +- +- return 0; +-} +- +-static struct platform_driver ohci_hcd_ath79_driver = { +- .probe = ohci_ath79_probe, +- .remove = ohci_ath79_remove, +- .shutdown = usb_hcd_platform_shutdown, +- .driver = { +- .name = "ath79-ohci", +- .owner = THIS_MODULE, +- }, +-}; +- +-MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ath79-ohci"); +--- a/drivers/usb/host/ohci-hcd.c ++++ b/drivers/usb/host/ohci-hcd.c +@@ -1111,11 +1111,6 @@ MODULE_LICENSE ("GPL"); + #define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver + #endif + +-#ifdef CONFIG_USB_OHCI_ATH79 +-#include "ohci-ath79.c" +-#define PLATFORM_DRIVER ohci_hcd_ath79_driver +-#endif +- + #ifdef CONFIG_CPU_XLR + #include "ohci-xls.c" + #define PLATFORM_DRIVER ohci_xls_driver diff --git a/target/linux/ar71xx/patches-3.3/100-MIPS-ath79-separate-common-PCI-code.patch b/target/linux/ar71xx/patches-3.3/100-MIPS-ath79-separate-common-PCI-code.patch new file mode 100644 index 000000000..6062c894f --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/100-MIPS-ath79-separate-common-PCI-code.patch @@ -0,0 +1,150 @@ +From 9d9c0d49315520754660c8df3f42d93ecf7dba7a Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:29:21 +0100 +Subject: [PATCH 05/47] MIPS: ath79: separate common PCI code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The 'pcibios_map_irq' and 'pcibios_plat_dev_init' +are common functions and only instance one of them +can be present in a single kernel. + +Currently these functions can be built only if the +CONFIG_SOC_AR724X option is selected. However the +ath79 platform contain support for the AR71XX SoCs,. +The AR71XX SoCs have a differnet PCI controller, +and those will require a different code. + +Move the common PCI code into a separeate file in +order to be able to use that with other SoCs as +well. + +Signed-off-by: Gabor Juhos +Acked-by: René Bolldorf +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3485/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/Makefile | 1 + + arch/mips/ath79/pci.c | 46 +++++++++++++++++++++++++++++++++++++++++++ + arch/mips/pci/pci-ath724x.c | 34 ------------------------------- + 3 files changed, 47 insertions(+), 34 deletions(-) + create mode 100644 arch/mips/ath79/pci.c + +--- a/arch/mips/ath79/Makefile ++++ b/arch/mips/ath79/Makefile +@@ -11,6 +11,7 @@ + obj-y := prom.o setup.o irq.o common.o clock.o gpio.o + + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o ++obj-$(CONFIG_PCI) += pci.o + + # + # Devices +--- /dev/null ++++ b/arch/mips/ath79/pci.c +@@ -0,0 +1,46 @@ ++/* ++ * Atheros AR71XX/AR724X specific PCI setup code ++ * ++ * Copyright (C) 2011 René Bolldorf ++ * ++ * This program 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. ++ */ ++ ++#include ++#include ++ ++static struct ath724x_pci_data *pci_data; ++static int pci_data_size; ++ ++void ath724x_pci_add_data(struct ath724x_pci_data *data, int size) ++{ ++ pci_data = data; ++ pci_data_size = size; ++} ++ ++int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) ++{ ++ unsigned int devfn = dev->devfn; ++ int irq = -1; ++ ++ if (devfn > pci_data_size - 1) ++ return irq; ++ ++ irq = pci_data[devfn].irq; ++ ++ return irq; ++} ++ ++int pcibios_plat_dev_init(struct pci_dev *dev) ++{ ++ unsigned int devfn = dev->devfn; ++ ++ if (devfn > pci_data_size - 1) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ dev->dev.platform_data = pci_data[devfn].pdata; ++ ++ return PCIBIOS_SUCCESSFUL; ++} +--- a/arch/mips/pci/pci-ath724x.c ++++ b/arch/mips/pci/pci-ath724x.c +@@ -9,7 +9,6 @@ + */ + + #include +-#include + + #define reg_read(_phys) (*(unsigned int *) KSEG1ADDR(_phys)) + #define reg_write(_phys, _val) ((*(unsigned int *) KSEG1ADDR(_phys)) = (_val)) +@@ -19,8 +18,6 @@ + #define ATH724X_PCI_MEM_SIZE 0x08000000 + + static DEFINE_SPINLOCK(ath724x_pci_lock); +-static struct ath724x_pci_data *pci_data; +-static int pci_data_size; + + static int ath724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t *value) +@@ -133,37 +130,6 @@ static struct pci_controller ath724x_pci + .mem_resource = &ath724x_mem_resource, + }; + +-void ath724x_pci_add_data(struct ath724x_pci_data *data, int size) +-{ +- pci_data = data; +- pci_data_size = size; +-} +- +-int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) +-{ +- unsigned int devfn = dev->devfn; +- int irq = -1; +- +- if (devfn > pci_data_size - 1) +- return irq; +- +- irq = pci_data[devfn].irq; +- +- return irq; +-} +- +-int pcibios_plat_dev_init(struct pci_dev *dev) +-{ +- unsigned int devfn = dev->devfn; +- +- if (devfn > pci_data_size - 1) +- return PCIBIOS_DEVICE_NOT_FOUND; +- +- dev->dev.platform_data = pci_data[devfn].pdata; +- +- return PCIBIOS_SUCCESSFUL; +-} +- + static int __init ath724x_pcibios_init(void) + { + register_pci_controller(&ath724x_pci_controller); diff --git a/target/linux/ar71xx/patches-3.3/101-MIPS-ath79-rename-pci-ath724x.h.patch b/target/linux/ar71xx/patches-3.3/101-MIPS-ath79-rename-pci-ath724x.h.patch new file mode 100644 index 000000000..f28f20cb2 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/101-MIPS-ath79-rename-pci-ath724x.h.patch @@ -0,0 +1,102 @@ +From 293dcf4142717d8059540bd69d1517c442617569 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:29:22 +0100 +Subject: [PATCH 06/47] MIPS: ath79: rename pci-ath724x.h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The declared function in this header file is used by the +ath79 platform code only. Move the header to the platform +directory. + +Signed-off-by: Gabor Juhos +Acked-by: René Bolldorf +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3486/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/mach-ubnt-xm.c | 2 +- + arch/mips/ath79/pci.c | 2 +- + arch/mips/ath79/pci.h | 21 +++++++++++++++++++++ + arch/mips/include/asm/mach-ath79/pci-ath724x.h | 21 --------------------- + 4 files changed, 23 insertions(+), 23 deletions(-) + create mode 100644 arch/mips/ath79/pci.h + delete mode 100644 arch/mips/include/asm/mach-ath79/pci-ath724x.h + +--- a/arch/mips/ath79/mach-ubnt-xm.c ++++ b/arch/mips/ath79/mach-ubnt-xm.c +@@ -15,13 +15,13 @@ + + #ifdef CONFIG_PCI + #include +-#include + #endif /* CONFIG_PCI */ + + #include "machtypes.h" + #include "dev-gpio-buttons.h" + #include "dev-leds-gpio.h" + #include "dev-spi.h" ++#include "pci.h" + + #define UBNT_XM_GPIO_LED_L1 0 + #define UBNT_XM_GPIO_LED_L2 1 +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -9,7 +9,7 @@ + */ + + #include +-#include ++#include "pci.h" + + static struct ath724x_pci_data *pci_data; + static int pci_data_size; +--- /dev/null ++++ b/arch/mips/ath79/pci.h +@@ -0,0 +1,21 @@ ++/* ++ * Atheros 724x PCI support ++ * ++ * Copyright (C) 2011 René Bolldorf ++ * ++ * This program 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. ++ */ ++ ++#ifndef __ASM_MACH_ATH79_PCI_ATH724X_H ++#define __ASM_MACH_ATH79_PCI_ATH724X_H ++ ++struct ath724x_pci_data { ++ int irq; ++ void *pdata; ++}; ++ ++void ath724x_pci_add_data(struct ath724x_pci_data *data, int size); ++ ++#endif /* __ASM_MACH_ATH79_PCI_ATH724X_H */ +--- a/arch/mips/include/asm/mach-ath79/pci-ath724x.h ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* +- * Atheros 724x PCI support +- * +- * Copyright (C) 2011 René Bolldorf +- * +- * This program 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. +- */ +- +-#ifndef __ASM_MACH_ATH79_PCI_ATH724X_H +-#define __ASM_MACH_ATH79_PCI_ATH724X_H +- +-struct ath724x_pci_data { +- int irq; +- void *pdata; +-}; +- +-void ath724x_pci_add_data(struct ath724x_pci_data *data, int size); +- +-#endif /* __ASM_MACH_ATH79_PCI_ATH724X_H */ diff --git a/target/linux/ar71xx/patches-3.3/102-MIPS-ath79-make-ath724x_pcibios_init-visible-for-ext.patch b/target/linux/ar71xx/patches-3.3/102-MIPS-ath79-make-ath724x_pcibios_init-visible-for-ext.patch new file mode 100644 index 000000000..9696a7522 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/102-MIPS-ath79-make-ath724x_pcibios_init-visible-for-ext.patch @@ -0,0 +1,61 @@ +From a9e38566ebe755219db10fa155fa8f0f4efc20d9 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:29:23 +0100 +Subject: [PATCH 07/47] MIPS: ath79: make ath724x_pcibios_init visible for external code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: René Bolldorf +Signed-off-by: Gabor Juhos +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3487/ +Signed-off-by: Ralf Baechle +--- + arch/mips/include/asm/mach-ath79/pci.h | 20 ++++++++++++++++++++ + arch/mips/pci/pci-ath724x.c | 3 ++- + 2 files changed, 22 insertions(+), 1 deletions(-) + create mode 100644 arch/mips/include/asm/mach-ath79/pci.h + +--- /dev/null ++++ b/arch/mips/include/asm/mach-ath79/pci.h +@@ -0,0 +1,20 @@ ++/* ++ * Atheros 724x PCI support ++ * ++ * Copyright (C) 2011 René Bolldorf ++ * ++ * This program 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. ++ */ ++ ++#ifndef __ASM_MACH_ATH79_PCI_H ++#define __ASM_MACH_ATH79_PCI_H ++ ++#if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR724X) ++int ath724x_pcibios_init(void); ++#else ++static inline int ath724x_pcibios_init(void) { return 0; } ++#endif ++ ++#endif /* __ASM_MACH_ATH79_PCI_H */ +--- a/arch/mips/pci/pci-ath724x.c ++++ b/arch/mips/pci/pci-ath724x.c +@@ -9,6 +9,7 @@ + */ + + #include ++#include + + #define reg_read(_phys) (*(unsigned int *) KSEG1ADDR(_phys)) + #define reg_write(_phys, _val) ((*(unsigned int *) KSEG1ADDR(_phys)) = (_val)) +@@ -130,7 +131,7 @@ static struct pci_controller ath724x_pci + .mem_resource = &ath724x_mem_resource, + }; + +-static int __init ath724x_pcibios_init(void) ++int __init ath724x_pcibios_init(void) + { + register_pci_controller(&ath724x_pci_controller); + diff --git a/target/linux/ar71xx/patches-3.3/103-MIPS-ath79-add-a-common-PCI-registration-function.patch b/target/linux/ar71xx/patches-3.3/103-MIPS-ath79-add-a-common-PCI-registration-function.patch new file mode 100644 index 000000000..34587b63a --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/103-MIPS-ath79-add-a-common-PCI-registration-function.patch @@ -0,0 +1,78 @@ +From e3edaac2e967f07ae3b726e64e1c290233361bc7 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:29:24 +0100 +Subject: [PATCH 08/47] MIPS: ath79: add a common PCI registration function + +The current code unconditionally registers the AR724X +specific PCI controller, even if the kernel is running +on a different SoC. + +Add a common function for PCI controller registration, +and only register the AR724X PCI controller if the kernel +is running on an AR724X SoC. + +Signed-off-by: Gabor Juhos +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3488/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/mach-ubnt-xm.c | 1 + + arch/mips/ath79/pci.c | 10 ++++++++++ + arch/mips/ath79/pci.h | 6 ++++++ + arch/mips/pci/pci-ath724x.c | 2 -- + 4 files changed, 17 insertions(+), 2 deletions(-) + +--- a/arch/mips/ath79/mach-ubnt-xm.c ++++ b/arch/mips/ath79/mach-ubnt-xm.c +@@ -111,6 +111,7 @@ static void __init ubnt_xm_init(void) + ath724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data)); + #endif /* CONFIG_PCI */ + ++ ath79_register_pci(); + } + + MIPS_MACHINE(ATH79_MACH_UBNT_XM, +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -9,6 +9,8 @@ + */ + + #include ++#include ++#include + #include "pci.h" + + static struct ath724x_pci_data *pci_data; +@@ -44,3 +46,11 @@ int pcibios_plat_dev_init(struct pci_dev + + return PCIBIOS_SUCCESSFUL; + } ++ ++int __init ath79_register_pci(void) ++{ ++ if (soc_is_ar724x()) ++ return ath724x_pcibios_init(); ++ ++ return -ENODEV; ++} +--- a/arch/mips/ath79/pci.h ++++ b/arch/mips/ath79/pci.h +@@ -18,4 +18,10 @@ struct ath724x_pci_data { + + void ath724x_pci_add_data(struct ath724x_pci_data *data, int size); + ++#ifdef CONFIG_PCI ++int ath79_register_pci(void); ++#else ++static inline int ath79_register_pci(void) { return 0; } ++#endif ++ + #endif /* __ASM_MACH_ATH79_PCI_ATH724X_H */ +--- a/arch/mips/pci/pci-ath724x.c ++++ b/arch/mips/pci/pci-ath724x.c +@@ -137,5 +137,3 @@ int __init ath724x_pcibios_init(void) + + return PCIBIOS_SUCCESSFUL; + } +- +-arch_initcall(ath724x_pcibios_init); diff --git a/target/linux/ar71xx/patches-3.3/104-MIPS-ath79-rename-pci-ath724x.c-to-make-it-reflect-t.patch b/target/linux/ar71xx/patches-3.3/104-MIPS-ath79-rename-pci-ath724x.c-to-make-it-reflect-t.patch new file mode 100644 index 000000000..e7189289c --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/104-MIPS-ath79-rename-pci-ath724x.c-to-make-it-reflect-t.patch @@ -0,0 +1,316 @@ +From 36dfdaa097ee1b12139187dc89cfa23fbb92b53b Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:29:25 +0100 +Subject: [PATCH 09/47] MIPS: ath79: rename pci-ath724x.c to make it reflect the real SoC name +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Gabor Juhos +Acked-by: René Bolldorf +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3489/ +Signed-off-by: Ralf Baechle +--- + arch/mips/pci/Makefile | 2 +- + arch/mips/pci/pci-ar724x.c | 139 +++++++++++++++++++++++++++++++++++++++++++ + arch/mips/pci/pci-ath724x.c | 139 ------------------------------------------- + 3 files changed, 140 insertions(+), 140 deletions(-) + create mode 100644 arch/mips/pci/pci-ar724x.c + delete mode 100644 arch/mips/pci/pci-ath724x.c + +--- a/arch/mips/pci/Makefile ++++ b/arch/mips/pci/Makefile +@@ -19,7 +19,7 @@ obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o + obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ + ops-bcm63xx.o + obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o +-obj-$(CONFIG_SOC_AR724X) += pci-ath724x.o ++obj-$(CONFIG_SOC_AR724X) += pci-ar724x.o + + # + # These are still pretty much in the old state, watch, go blind. +--- /dev/null ++++ b/arch/mips/pci/pci-ar724x.c +@@ -0,0 +1,139 @@ ++/* ++ * Atheros 724x PCI support ++ * ++ * Copyright (C) 2011 René Bolldorf ++ * ++ * This program 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. ++ */ ++ ++#include ++#include ++ ++#define reg_read(_phys) (*(unsigned int *) KSEG1ADDR(_phys)) ++#define reg_write(_phys, _val) ((*(unsigned int *) KSEG1ADDR(_phys)) = (_val)) ++ ++#define ATH724X_PCI_DEV_BASE 0x14000000 ++#define ATH724X_PCI_MEM_BASE 0x10000000 ++#define ATH724X_PCI_MEM_SIZE 0x08000000 ++ ++static DEFINE_SPINLOCK(ath724x_pci_lock); ++ ++static int ath724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, ++ int size, uint32_t *value) ++{ ++ unsigned long flags, addr, tval, mask; ++ ++ if (devfn) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ if (where & (size - 1)) ++ return PCIBIOS_BAD_REGISTER_NUMBER; ++ ++ spin_lock_irqsave(&ath724x_pci_lock, flags); ++ ++ switch (size) { ++ case 1: ++ addr = where & ~3; ++ mask = 0xff000000 >> ((where % 4) * 8); ++ tval = reg_read(ATH724X_PCI_DEV_BASE + addr); ++ tval = tval & ~mask; ++ *value = (tval >> ((4 - (where % 4))*8)); ++ break; ++ case 2: ++ addr = where & ~3; ++ mask = 0xffff0000 >> ((where % 4)*8); ++ tval = reg_read(ATH724X_PCI_DEV_BASE + addr); ++ tval = tval & ~mask; ++ *value = (tval >> ((4 - (where % 4))*8)); ++ break; ++ case 4: ++ *value = reg_read(ATH724X_PCI_DEV_BASE + where); ++ break; ++ default: ++ spin_unlock_irqrestore(&ath724x_pci_lock, flags); ++ ++ return PCIBIOS_BAD_REGISTER_NUMBER; ++ } ++ ++ spin_unlock_irqrestore(&ath724x_pci_lock, flags); ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int ath724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, ++ int size, uint32_t value) ++{ ++ unsigned long flags, tval, addr, mask; ++ ++ if (devfn) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ if (where & (size - 1)) ++ return PCIBIOS_BAD_REGISTER_NUMBER; ++ ++ spin_lock_irqsave(&ath724x_pci_lock, flags); ++ ++ switch (size) { ++ case 1: ++ addr = (ATH724X_PCI_DEV_BASE + where) & ~3; ++ mask = 0xff000000 >> ((where % 4)*8); ++ tval = reg_read(addr); ++ tval = tval & ~mask; ++ tval |= (value << ((4 - (where % 4))*8)) & mask; ++ reg_write(addr, tval); ++ break; ++ case 2: ++ addr = (ATH724X_PCI_DEV_BASE + where) & ~3; ++ mask = 0xffff0000 >> ((where % 4)*8); ++ tval = reg_read(addr); ++ tval = tval & ~mask; ++ tval |= (value << ((4 - (where % 4))*8)) & mask; ++ reg_write(addr, tval); ++ break; ++ case 4: ++ reg_write((ATH724X_PCI_DEV_BASE + where), value); ++ break; ++ default: ++ spin_unlock_irqrestore(&ath724x_pci_lock, flags); ++ ++ return PCIBIOS_BAD_REGISTER_NUMBER; ++ } ++ ++ spin_unlock_irqrestore(&ath724x_pci_lock, flags); ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static struct pci_ops ath724x_pci_ops = { ++ .read = ath724x_pci_read, ++ .write = ath724x_pci_write, ++}; ++ ++static struct resource ath724x_io_resource = { ++ .name = "PCI IO space", ++ .start = 0, ++ .end = 0, ++ .flags = IORESOURCE_IO, ++}; ++ ++static struct resource ath724x_mem_resource = { ++ .name = "PCI memory space", ++ .start = ATH724X_PCI_MEM_BASE, ++ .end = ATH724X_PCI_MEM_BASE + ATH724X_PCI_MEM_SIZE - 1, ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct pci_controller ath724x_pci_controller = { ++ .pci_ops = &ath724x_pci_ops, ++ .io_resource = &ath724x_io_resource, ++ .mem_resource = &ath724x_mem_resource, ++}; ++ ++int __init ath724x_pcibios_init(void) ++{ ++ register_pci_controller(&ath724x_pci_controller); ++ ++ return PCIBIOS_SUCCESSFUL; ++} +--- a/arch/mips/pci/pci-ath724x.c ++++ /dev/null +@@ -1,139 +0,0 @@ +-/* +- * Atheros 724x PCI support +- * +- * Copyright (C) 2011 René Bolldorf +- * +- * This program 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. +- */ +- +-#include +-#include +- +-#define reg_read(_phys) (*(unsigned int *) KSEG1ADDR(_phys)) +-#define reg_write(_phys, _val) ((*(unsigned int *) KSEG1ADDR(_phys)) = (_val)) +- +-#define ATH724X_PCI_DEV_BASE 0x14000000 +-#define ATH724X_PCI_MEM_BASE 0x10000000 +-#define ATH724X_PCI_MEM_SIZE 0x08000000 +- +-static DEFINE_SPINLOCK(ath724x_pci_lock); +- +-static int ath724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, +- int size, uint32_t *value) +-{ +- unsigned long flags, addr, tval, mask; +- +- if (devfn) +- return PCIBIOS_DEVICE_NOT_FOUND; +- +- if (where & (size - 1)) +- return PCIBIOS_BAD_REGISTER_NUMBER; +- +- spin_lock_irqsave(&ath724x_pci_lock, flags); +- +- switch (size) { +- case 1: +- addr = where & ~3; +- mask = 0xff000000 >> ((where % 4) * 8); +- tval = reg_read(ATH724X_PCI_DEV_BASE + addr); +- tval = tval & ~mask; +- *value = (tval >> ((4 - (where % 4))*8)); +- break; +- case 2: +- addr = where & ~3; +- mask = 0xffff0000 >> ((where % 4)*8); +- tval = reg_read(ATH724X_PCI_DEV_BASE + addr); +- tval = tval & ~mask; +- *value = (tval >> ((4 - (where % 4))*8)); +- break; +- case 4: +- *value = reg_read(ATH724X_PCI_DEV_BASE + where); +- break; +- default: +- spin_unlock_irqrestore(&ath724x_pci_lock, flags); +- +- return PCIBIOS_BAD_REGISTER_NUMBER; +- } +- +- spin_unlock_irqrestore(&ath724x_pci_lock, flags); +- +- return PCIBIOS_SUCCESSFUL; +-} +- +-static int ath724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, +- int size, uint32_t value) +-{ +- unsigned long flags, tval, addr, mask; +- +- if (devfn) +- return PCIBIOS_DEVICE_NOT_FOUND; +- +- if (where & (size - 1)) +- return PCIBIOS_BAD_REGISTER_NUMBER; +- +- spin_lock_irqsave(&ath724x_pci_lock, flags); +- +- switch (size) { +- case 1: +- addr = (ATH724X_PCI_DEV_BASE + where) & ~3; +- mask = 0xff000000 >> ((where % 4)*8); +- tval = reg_read(addr); +- tval = tval & ~mask; +- tval |= (value << ((4 - (where % 4))*8)) & mask; +- reg_write(addr, tval); +- break; +- case 2: +- addr = (ATH724X_PCI_DEV_BASE + where) & ~3; +- mask = 0xffff0000 >> ((where % 4)*8); +- tval = reg_read(addr); +- tval = tval & ~mask; +- tval |= (value << ((4 - (where % 4))*8)) & mask; +- reg_write(addr, tval); +- break; +- case 4: +- reg_write((ATH724X_PCI_DEV_BASE + where), value); +- break; +- default: +- spin_unlock_irqrestore(&ath724x_pci_lock, flags); +- +- return PCIBIOS_BAD_REGISTER_NUMBER; +- } +- +- spin_unlock_irqrestore(&ath724x_pci_lock, flags); +- +- return PCIBIOS_SUCCESSFUL; +-} +- +-static struct pci_ops ath724x_pci_ops = { +- .read = ath724x_pci_read, +- .write = ath724x_pci_write, +-}; +- +-static struct resource ath724x_io_resource = { +- .name = "PCI IO space", +- .start = 0, +- .end = 0, +- .flags = IORESOURCE_IO, +-}; +- +-static struct resource ath724x_mem_resource = { +- .name = "PCI memory space", +- .start = ATH724X_PCI_MEM_BASE, +- .end = ATH724X_PCI_MEM_BASE + ATH724X_PCI_MEM_SIZE - 1, +- .flags = IORESOURCE_MEM, +-}; +- +-static struct pci_controller ath724x_pci_controller = { +- .pci_ops = &ath724x_pci_ops, +- .io_resource = &ath724x_io_resource, +- .mem_resource = &ath724x_mem_resource, +-}; +- +-int __init ath724x_pcibios_init(void) +-{ +- register_pci_controller(&ath724x_pci_controller); +- +- return PCIBIOS_SUCCESSFUL; +-} diff --git a/target/linux/ar71xx/patches-3.3/105-MIPS-ath79-replace-ath724x-to-ar724x.patch b/target/linux/ar71xx/patches-3.3/105-MIPS-ath79-replace-ath724x-to-ar724x.patch new file mode 100644 index 000000000..0a224ed54 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/105-MIPS-ath79-replace-ath724x-to-ar724x.patch @@ -0,0 +1,264 @@ +From 9f0c37b1d071355d4c027958f370823c8f891480 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:29:26 +0100 +Subject: [PATCH 10/47] MIPS: ath79: replace ath724x to ar724x +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Replace the 'ath724x' to 'ar724x' in function, variable and +structure names to reflect the name of the real SoC. + +Signed-off-by: Gabor Juhos +Acked-by: René Bolldorf +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3490/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/mach-ubnt-xm.c | 4 +- + arch/mips/ath79/pci.c | 6 ++-- + arch/mips/ath79/pci.h | 10 +++--- + arch/mips/include/asm/mach-ath79/pci.h | 4 +- + arch/mips/pci/pci-ar724x.c | 62 ++++++++++++++++---------------- + 5 files changed, 43 insertions(+), 43 deletions(-) + +--- a/arch/mips/ath79/mach-ubnt-xm.c ++++ b/arch/mips/ath79/mach-ubnt-xm.c +@@ -84,7 +84,7 @@ static struct ath79_spi_platform_data ub + #ifdef CONFIG_PCI + static struct ath9k_platform_data ubnt_xm_eeprom_data; + +-static struct ath724x_pci_data ubnt_xm_pci_data[] = { ++static struct ar724x_pci_data ubnt_xm_pci_data[] = { + { + .irq = UBNT_XM_PCI_IRQ, + .pdata = &ubnt_xm_eeprom_data, +@@ -108,7 +108,7 @@ static void __init ubnt_xm_init(void) + memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR, + sizeof(ubnt_xm_eeprom_data.eeprom_data)); + +- ath724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data)); ++ ar724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data)); + #endif /* CONFIG_PCI */ + + ath79_register_pci(); +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -13,10 +13,10 @@ + #include + #include "pci.h" + +-static struct ath724x_pci_data *pci_data; ++static struct ar724x_pci_data *pci_data; + static int pci_data_size; + +-void ath724x_pci_add_data(struct ath724x_pci_data *data, int size) ++void ar724x_pci_add_data(struct ar724x_pci_data *data, int size) + { + pci_data = data; + pci_data_size = size; +@@ -50,7 +50,7 @@ int pcibios_plat_dev_init(struct pci_dev + int __init ath79_register_pci(void) + { + if (soc_is_ar724x()) +- return ath724x_pcibios_init(); ++ return ar724x_pcibios_init(); + + return -ENODEV; + } +--- a/arch/mips/ath79/pci.h ++++ b/arch/mips/ath79/pci.h +@@ -8,15 +8,15 @@ + * by the Free Software Foundation. + */ + +-#ifndef __ASM_MACH_ATH79_PCI_ATH724X_H +-#define __ASM_MACH_ATH79_PCI_ATH724X_H ++#ifndef _ATH79_PCI_H ++#define _ATH79_PCI_H + +-struct ath724x_pci_data { ++struct ar724x_pci_data { + int irq; + void *pdata; + }; + +-void ath724x_pci_add_data(struct ath724x_pci_data *data, int size); ++void ar724x_pci_add_data(struct ar724x_pci_data *data, int size); + + #ifdef CONFIG_PCI + int ath79_register_pci(void); +@@ -24,4 +24,4 @@ int ath79_register_pci(void); + static inline int ath79_register_pci(void) { return 0; } + #endif + +-#endif /* __ASM_MACH_ATH79_PCI_ATH724X_H */ ++#endif /* _ATH79_PCI_H */ +--- a/arch/mips/include/asm/mach-ath79/pci.h ++++ b/arch/mips/include/asm/mach-ath79/pci.h +@@ -12,9 +12,9 @@ + #define __ASM_MACH_ATH79_PCI_H + + #if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR724X) +-int ath724x_pcibios_init(void); ++int ar724x_pcibios_init(void); + #else +-static inline int ath724x_pcibios_init(void) { return 0; } ++static inline int ar724x_pcibios_init(void) { return 0; } + #endif + + #endif /* __ASM_MACH_ATH79_PCI_H */ +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -14,13 +14,13 @@ + #define reg_read(_phys) (*(unsigned int *) KSEG1ADDR(_phys)) + #define reg_write(_phys, _val) ((*(unsigned int *) KSEG1ADDR(_phys)) = (_val)) + +-#define ATH724X_PCI_DEV_BASE 0x14000000 +-#define ATH724X_PCI_MEM_BASE 0x10000000 +-#define ATH724X_PCI_MEM_SIZE 0x08000000 ++#define AR724X_PCI_DEV_BASE 0x14000000 ++#define AR724X_PCI_MEM_BASE 0x10000000 ++#define AR724X_PCI_MEM_SIZE 0x08000000 + +-static DEFINE_SPINLOCK(ath724x_pci_lock); ++static DEFINE_SPINLOCK(ar724x_pci_lock); + +-static int ath724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, ++static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t *value) + { + unsigned long flags, addr, tval, mask; +@@ -31,38 +31,38 @@ static int ath724x_pci_read(struct pci_b + if (where & (size - 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + +- spin_lock_irqsave(&ath724x_pci_lock, flags); ++ spin_lock_irqsave(&ar724x_pci_lock, flags); + + switch (size) { + case 1: + addr = where & ~3; + mask = 0xff000000 >> ((where % 4) * 8); +- tval = reg_read(ATH724X_PCI_DEV_BASE + addr); ++ tval = reg_read(AR724X_PCI_DEV_BASE + addr); + tval = tval & ~mask; + *value = (tval >> ((4 - (where % 4))*8)); + break; + case 2: + addr = where & ~3; + mask = 0xffff0000 >> ((where % 4)*8); +- tval = reg_read(ATH724X_PCI_DEV_BASE + addr); ++ tval = reg_read(AR724X_PCI_DEV_BASE + addr); + tval = tval & ~mask; + *value = (tval >> ((4 - (where % 4))*8)); + break; + case 4: +- *value = reg_read(ATH724X_PCI_DEV_BASE + where); ++ *value = reg_read(AR724X_PCI_DEV_BASE + where); + break; + default: +- spin_unlock_irqrestore(&ath724x_pci_lock, flags); ++ spin_unlock_irqrestore(&ar724x_pci_lock, flags); + + return PCIBIOS_BAD_REGISTER_NUMBER; + } + +- spin_unlock_irqrestore(&ath724x_pci_lock, flags); ++ spin_unlock_irqrestore(&ar724x_pci_lock, flags); + + return PCIBIOS_SUCCESSFUL; + } + +-static int ath724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, ++static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t value) + { + unsigned long flags, tval, addr, mask; +@@ -73,11 +73,11 @@ static int ath724x_pci_write(struct pci_ + if (where & (size - 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + +- spin_lock_irqsave(&ath724x_pci_lock, flags); ++ spin_lock_irqsave(&ar724x_pci_lock, flags); + + switch (size) { + case 1: +- addr = (ATH724X_PCI_DEV_BASE + where) & ~3; ++ addr = (AR724X_PCI_DEV_BASE + where) & ~3; + mask = 0xff000000 >> ((where % 4)*8); + tval = reg_read(addr); + tval = tval & ~mask; +@@ -85,7 +85,7 @@ static int ath724x_pci_write(struct pci_ + reg_write(addr, tval); + break; + case 2: +- addr = (ATH724X_PCI_DEV_BASE + where) & ~3; ++ addr = (AR724X_PCI_DEV_BASE + where) & ~3; + mask = 0xffff0000 >> ((where % 4)*8); + tval = reg_read(addr); + tval = tval & ~mask; +@@ -93,47 +93,47 @@ static int ath724x_pci_write(struct pci_ + reg_write(addr, tval); + break; + case 4: +- reg_write((ATH724X_PCI_DEV_BASE + where), value); ++ reg_write((AR724X_PCI_DEV_BASE + where), value); + break; + default: +- spin_unlock_irqrestore(&ath724x_pci_lock, flags); ++ spin_unlock_irqrestore(&ar724x_pci_lock, flags); + + return PCIBIOS_BAD_REGISTER_NUMBER; + } + +- spin_unlock_irqrestore(&ath724x_pci_lock, flags); ++ spin_unlock_irqrestore(&ar724x_pci_lock, flags); + + return PCIBIOS_SUCCESSFUL; + } + +-static struct pci_ops ath724x_pci_ops = { +- .read = ath724x_pci_read, +- .write = ath724x_pci_write, ++static struct pci_ops ar724x_pci_ops = { ++ .read = ar724x_pci_read, ++ .write = ar724x_pci_write, + }; + +-static struct resource ath724x_io_resource = { ++static struct resource ar724x_io_resource = { + .name = "PCI IO space", + .start = 0, + .end = 0, + .flags = IORESOURCE_IO, + }; + +-static struct resource ath724x_mem_resource = { ++static struct resource ar724x_mem_resource = { + .name = "PCI memory space", +- .start = ATH724X_PCI_MEM_BASE, +- .end = ATH724X_PCI_MEM_BASE + ATH724X_PCI_MEM_SIZE - 1, ++ .start = AR724X_PCI_MEM_BASE, ++ .end = AR724X_PCI_MEM_BASE + AR724X_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM, + }; + +-static struct pci_controller ath724x_pci_controller = { +- .pci_ops = &ath724x_pci_ops, +- .io_resource = &ath724x_io_resource, +- .mem_resource = &ath724x_mem_resource, ++static struct pci_controller ar724x_pci_controller = { ++ .pci_ops = &ar724x_pci_ops, ++ .io_resource = &ar724x_io_resource, ++ .mem_resource = &ar724x_mem_resource, + }; + +-int __init ath724x_pcibios_init(void) ++int __init ar724x_pcibios_init(void) + { +- register_pci_controller(&ath724x_pci_controller); ++ register_pci_controller(&ar724x_pci_controller); + + return PCIBIOS_SUCCESSFUL; + } diff --git a/target/linux/ar71xx/patches-3.3/106-MIPS-ath79-use-io-accessor-macros-in-pci-ar724x.c.patch b/target/linux/ar71xx/patches-3.3/106-MIPS-ath79-use-io-accessor-macros-in-pci-ar724x.c.patch new file mode 100644 index 000000000..108ac10e4 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/106-MIPS-ath79-use-io-accessor-macros-in-pci-ar724x.c.patch @@ -0,0 +1,131 @@ +From 0f5728e7e6fa7f0969ec79bd623261d3d830e5e7 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:29:27 +0100 +Subject: [PATCH 11/47] MIPS: ath79: use io-accessor macros in pci-ar724x.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Gabor Juhos +Acked-by: René Bolldorf +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3491/ +Signed-off-by: Ralf Baechle +--- + arch/mips/pci/pci-ar724x.c | 38 ++++++++++++++++++++++++-------------- + 1 files changed, 24 insertions(+), 14 deletions(-) + +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -11,19 +11,19 @@ + #include + #include + +-#define reg_read(_phys) (*(unsigned int *) KSEG1ADDR(_phys)) +-#define reg_write(_phys, _val) ((*(unsigned int *) KSEG1ADDR(_phys)) = (_val)) +- +-#define AR724X_PCI_DEV_BASE 0x14000000 ++#define AR724X_PCI_CFG_BASE 0x14000000 ++#define AR724X_PCI_CFG_SIZE 0x1000 + #define AR724X_PCI_MEM_BASE 0x10000000 + #define AR724X_PCI_MEM_SIZE 0x08000000 + + static DEFINE_SPINLOCK(ar724x_pci_lock); ++static void __iomem *ar724x_pci_devcfg_base; + + static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t *value) + { + unsigned long flags, addr, tval, mask; ++ void __iomem *base; + + if (devfn) + return PCIBIOS_DEVICE_NOT_FOUND; +@@ -31,25 +31,27 @@ static int ar724x_pci_read(struct pci_bu + if (where & (size - 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + ++ base = ar724x_pci_devcfg_base; ++ + spin_lock_irqsave(&ar724x_pci_lock, flags); + + switch (size) { + case 1: + addr = where & ~3; + mask = 0xff000000 >> ((where % 4) * 8); +- tval = reg_read(AR724X_PCI_DEV_BASE + addr); ++ tval = __raw_readl(base + addr); + tval = tval & ~mask; + *value = (tval >> ((4 - (where % 4))*8)); + break; + case 2: + addr = where & ~3; + mask = 0xffff0000 >> ((where % 4)*8); +- tval = reg_read(AR724X_PCI_DEV_BASE + addr); ++ tval = __raw_readl(base + addr); + tval = tval & ~mask; + *value = (tval >> ((4 - (where % 4))*8)); + break; + case 4: +- *value = reg_read(AR724X_PCI_DEV_BASE + where); ++ *value = __raw_readl(base + where); + break; + default: + spin_unlock_irqrestore(&ar724x_pci_lock, flags); +@@ -66,6 +68,7 @@ static int ar724x_pci_write(struct pci_b + int size, uint32_t value) + { + unsigned long flags, tval, addr, mask; ++ void __iomem *base; + + if (devfn) + return PCIBIOS_DEVICE_NOT_FOUND; +@@ -73,27 +76,29 @@ static int ar724x_pci_write(struct pci_b + if (where & (size - 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + ++ base = ar724x_pci_devcfg_base; ++ + spin_lock_irqsave(&ar724x_pci_lock, flags); + + switch (size) { + case 1: +- addr = (AR724X_PCI_DEV_BASE + where) & ~3; ++ addr = where & ~3; + mask = 0xff000000 >> ((where % 4)*8); +- tval = reg_read(addr); ++ tval = __raw_readl(base + addr); + tval = tval & ~mask; + tval |= (value << ((4 - (where % 4))*8)) & mask; +- reg_write(addr, tval); ++ __raw_writel(tval, base + addr); + break; + case 2: +- addr = (AR724X_PCI_DEV_BASE + where) & ~3; ++ addr = where & ~3; + mask = 0xffff0000 >> ((where % 4)*8); +- tval = reg_read(addr); ++ tval = __raw_readl(base + addr); + tval = tval & ~mask; + tval |= (value << ((4 - (where % 4))*8)) & mask; +- reg_write(addr, tval); ++ __raw_writel(tval, base + addr); + break; + case 4: +- reg_write((AR724X_PCI_DEV_BASE + where), value); ++ __raw_writel(value, (base + where)); + break; + default: + spin_unlock_irqrestore(&ar724x_pci_lock, flags); +@@ -133,6 +138,11 @@ static struct pci_controller ar724x_pci_ + + int __init ar724x_pcibios_init(void) + { ++ ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE, ++ AR724X_PCI_CFG_SIZE); ++ if (ar724x_pci_devcfg_base == NULL) ++ return -ENOMEM; ++ + register_pci_controller(&ar724x_pci_controller); + + return PCIBIOS_SUCCESSFUL; diff --git a/target/linux/ar71xx/patches-3.3/107-MIPS-ath79-remove-superfluous-alignment-checks-from-.patch b/target/linux/ar71xx/patches-3.3/107-MIPS-ath79-remove-superfluous-alignment-checks-from-.patch new file mode 100644 index 000000000..9ce1c396e --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/107-MIPS-ath79-remove-superfluous-alignment-checks-from-.patch @@ -0,0 +1,38 @@ +From e9889bee75d03338daf7ed422661ae28f3aa7063 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:36:03 +0100 +Subject: [PATCH 12/47] MIPS: ath79: remove superfluous alignment checks from pci-ar724x.c + +The alignment of the 'where' parameters are checked +in the core PCI code already. + +Signed-off-by: Gabor Juhos +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3492/ +Signed-off-by: Ralf Baechle +--- + arch/mips/pci/pci-ar724x.c | 6 ------ + 1 files changed, 0 insertions(+), 6 deletions(-) + +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -28,9 +28,6 @@ static int ar724x_pci_read(struct pci_bu + if (devfn) + return PCIBIOS_DEVICE_NOT_FOUND; + +- if (where & (size - 1)) +- return PCIBIOS_BAD_REGISTER_NUMBER; +- + base = ar724x_pci_devcfg_base; + + spin_lock_irqsave(&ar724x_pci_lock, flags); +@@ -73,9 +70,6 @@ static int ar724x_pci_write(struct pci_b + if (devfn) + return PCIBIOS_DEVICE_NOT_FOUND; + +- if (where & (size - 1)) +- return PCIBIOS_BAD_REGISTER_NUMBER; +- + base = ar724x_pci_devcfg_base; + + spin_lock_irqsave(&ar724x_pci_lock, flags); diff --git a/target/linux/ar71xx/patches-3.3/108-MIPS-ath79-fix-broken-ar724x_pci_-read-write-functio.patch b/target/linux/ar71xx/patches-3.3/108-MIPS-ath79-fix-broken-ar724x_pci_-read-write-functio.patch new file mode 100644 index 000000000..97db6de9a --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/108-MIPS-ath79-fix-broken-ar724x_pci_-read-write-functio.patch @@ -0,0 +1,134 @@ +From 39f3275077a5b143616fcb3e7a6457a5c42739ee Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:36:04 +0100 +Subject: [PATCH 13/47] MIPS: ath79: fix broken ar724x_pci_{read,write} functions + +The current ar724x_pci_{read,write} functions are +broken. Due to that, pci_read_config_byte returns +with bogus values, and pci_write_config_{byte,word} +unconditionally clears the accessed PCI configuration +registers instead of changing the value of them. + +The patch fixes the broken functions, thus the PCI +configuration space can be accessed correctly. + +Signed-off-by: Gabor Juhos +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3493/ +Signed-off-by: Ralf Baechle +--- + arch/mips/pci/pci-ar724x.c | 52 ++++++++++++++++++++++---------------------- + 1 files changed, 26 insertions(+), 26 deletions(-) + +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -22,8 +22,9 @@ static void __iomem *ar724x_pci_devcfg_b + static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t *value) + { +- unsigned long flags, addr, tval, mask; ++ unsigned long flags; + void __iomem *base; ++ u32 data; + + if (devfn) + return PCIBIOS_DEVICE_NOT_FOUND; +@@ -31,24 +32,22 @@ static int ar724x_pci_read(struct pci_bu + base = ar724x_pci_devcfg_base; + + spin_lock_irqsave(&ar724x_pci_lock, flags); ++ data = __raw_readl(base + (where & ~3)); + + switch (size) { + case 1: +- addr = where & ~3; +- mask = 0xff000000 >> ((where % 4) * 8); +- tval = __raw_readl(base + addr); +- tval = tval & ~mask; +- *value = (tval >> ((4 - (where % 4))*8)); ++ if (where & 1) ++ data >>= 8; ++ if (where & 2) ++ data >>= 16; ++ data &= 0xff; + break; + case 2: +- addr = where & ~3; +- mask = 0xffff0000 >> ((where % 4)*8); +- tval = __raw_readl(base + addr); +- tval = tval & ~mask; +- *value = (tval >> ((4 - (where % 4))*8)); ++ if (where & 2) ++ data >>= 16; ++ data &= 0xffff; + break; + case 4: +- *value = __raw_readl(base + where); + break; + default: + spin_unlock_irqrestore(&ar724x_pci_lock, flags); +@@ -57,6 +56,7 @@ static int ar724x_pci_read(struct pci_bu + } + + spin_unlock_irqrestore(&ar724x_pci_lock, flags); ++ *value = data; + + return PCIBIOS_SUCCESSFUL; + } +@@ -64,8 +64,10 @@ static int ar724x_pci_read(struct pci_bu + static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t value) + { +- unsigned long flags, tval, addr, mask; ++ unsigned long flags; + void __iomem *base; ++ u32 data; ++ int s; + + if (devfn) + return PCIBIOS_DEVICE_NOT_FOUND; +@@ -73,26 +75,21 @@ static int ar724x_pci_write(struct pci_b + base = ar724x_pci_devcfg_base; + + spin_lock_irqsave(&ar724x_pci_lock, flags); ++ data = __raw_readl(base + (where & ~3)); + + switch (size) { + case 1: +- addr = where & ~3; +- mask = 0xff000000 >> ((where % 4)*8); +- tval = __raw_readl(base + addr); +- tval = tval & ~mask; +- tval |= (value << ((4 - (where % 4))*8)) & mask; +- __raw_writel(tval, base + addr); ++ s = ((where & 3) * 8); ++ data &= ~(0xff << s); ++ data |= ((value & 0xff) << s); + break; + case 2: +- addr = where & ~3; +- mask = 0xffff0000 >> ((where % 4)*8); +- tval = __raw_readl(base + addr); +- tval = tval & ~mask; +- tval |= (value << ((4 - (where % 4))*8)) & mask; +- __raw_writel(tval, base + addr); ++ s = ((where & 2) * 8); ++ data &= ~(0xffff << s); ++ data |= ((value & 0xffff) << s); + break; + case 4: +- __raw_writel(value, (base + where)); ++ data = value; + break; + default: + spin_unlock_irqrestore(&ar724x_pci_lock, flags); +@@ -100,6 +97,9 @@ static int ar724x_pci_write(struct pci_b + return PCIBIOS_BAD_REGISTER_NUMBER; + } + ++ __raw_writel(data, base + (where & ~3)); ++ /* flush write */ ++ __raw_readl(base + (where & ~3)); + spin_unlock_irqrestore(&ar724x_pci_lock, flags); + + return PCIBIOS_SUCCESSFUL; diff --git a/target/linux/ar71xx/patches-3.3/109-MIPS-ath79-add-a-workaround-for-a-PCI-controller-bug.patch b/target/linux/ar71xx/patches-3.3/109-MIPS-ath79-add-a-workaround-for-a-PCI-controller-bug.patch new file mode 100644 index 000000000..8ed823b59 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/109-MIPS-ath79-add-a-workaround-for-a-PCI-controller-bug.patch @@ -0,0 +1,134 @@ +From 14eaf9b1cda516b4182e56f61c21fa2eaa9ade6b Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:36:05 +0100 +Subject: [PATCH 14/47] MIPS: ath79: add a workaround for a PCI controller bug in AR7240 SoCs + +The PCI controller of the AR724X SoCs has a hardware +bag. If the BAR0 register of the PCI device is set to +the proper base address, the memory address space of +the device is not accessible. + +When the device driver tries to access the memory +address space of the PCI device, it leads to data +bus error, similiar to this: + +Data bus error, epc == 801f69a0, ra == 801f698c +Oops[#1]: +Cpu 0 +$ 0 : 00000000 00000061 deadbeef 000000ff +$ 4 : 00000000 000000ff 00000014 00000000 +$ 8 : ff000000 fffffffc 00000000 00000000 +$12 : 000001f5 00000006 00000000 6e637920 +$16 : 81ca4000 81ca0260 81ca4000 804d70f0 +$20 : fffffff4 0000002b 803ad4c4 00000000 +$24 : 00000003 00000000 +$28 : 81c20000 81c21c60 00000000 801f698c +Hi : 00000000 +Lo : 00000000 +epc : 801f69a0 ath9k_hw_init+0xd0/0xa70 + Not tainted +ra : 801f698c ath9k_hw_init+0xbc/0xa70 +Status: 1000c103 KERNEL EXL IE +Cause : 1080001c +PrId : 00019374 (MIPS 24Kc) +Modules linked in: +Process swapper (pid: 1, threadinfo=81c20000, task=81c18000, tls=00000000) +Stack : 00000000 00000000 00000000 00000000 81c21c78 81ca0260 00000000 804d70f0 + 81ca0260 81c21cc0 81ca0e80 81ca0260 81ca4000 804d70f0 fffffff4 0000002b + 803ad4c4 00000000 00000000 801e3ae8 81c9d080 81ca0e80 b0000000 800b9b9c + 00000008 81c9d000 8031aeb0 802d38a0 00000000 81c14c00 81c14c60 00000000 + 81ca0e80 81ca0260 b0000000 801f08a4 81c9c820 81c21d48 81c9c820 80144320 + ... +Call Trace: +[<801f69a0>] ath9k_hw_init+0xd0/0xa70 +[<801e3ae8>] ath9k_init_device+0x174/0x680 +[<801f08a4>] ath_pci_probe+0x27c/0x380 +[<8019e490>] pci_device_probe+0x74/0x9c +[<801bfadc>] driver_probe_device+0x9c/0x1b4 +[<801bfcb0>] __driver_attach+0xbc/0xc4 +[<801bea0c>] bus_for_each_dev+0x5c/0x98 +[<801bf394>] bus_add_driver+0x1d0/0x2a4 +[<801c0364>] driver_register+0x8c/0x16c +[<8019e72c>] __pci_register_driver+0x4c/0xe4 +[<803d3d40>] ath9k_init+0x3c/0x88 +[<80060930>] do_one_initcall+0x3c/0x1cc +[<803c297c>] kernel_init+0xa4/0x138 +[<80063c04>] kernel_thread_helper+0x10/0x18 + +Signed-off-by: Gabor Juhos +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3494/ +Signed-off-by: Ralf Baechle +--- + arch/mips/pci/pci-ar724x.c | 36 +++++++++++++++++++++++++++++++++++- + 1 files changed, 35 insertions(+), 1 deletions(-) + +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -9,6 +9,7 @@ + */ + + #include ++#include + #include + + #define AR724X_PCI_CFG_BASE 0x14000000 +@@ -16,9 +17,14 @@ + #define AR724X_PCI_MEM_BASE 0x10000000 + #define AR724X_PCI_MEM_SIZE 0x08000000 + ++#define AR7240_BAR0_WAR_VALUE 0xffff ++ + static DEFINE_SPINLOCK(ar724x_pci_lock); + static void __iomem *ar724x_pci_devcfg_base; + ++static u32 ar724x_pci_bar0_value; ++static bool ar724x_pci_bar0_is_cached; ++ + static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t *value) + { +@@ -56,7 +62,14 @@ static int ar724x_pci_read(struct pci_bu + } + + spin_unlock_irqrestore(&ar724x_pci_lock, flags); +- *value = data; ++ ++ if (where == PCI_BASE_ADDRESS_0 && size == 4 && ++ ar724x_pci_bar0_is_cached) { ++ /* use the cached value */ ++ *value = ar724x_pci_bar0_value; ++ } else { ++ *value = data; ++ } + + return PCIBIOS_SUCCESSFUL; + } +@@ -72,6 +85,27 @@ static int ar724x_pci_write(struct pci_b + if (devfn) + return PCIBIOS_DEVICE_NOT_FOUND; + ++ if (soc_is_ar7240() && where == PCI_BASE_ADDRESS_0 && size == 4) { ++ if (value != 0xffffffff) { ++ /* ++ * WAR for a hw issue. If the BAR0 register of the ++ * device is set to the proper base address, the ++ * memory space of the device is not accessible. ++ * ++ * Cache the intended value so it can be read back, ++ * and write a SoC specific constant value to the ++ * BAR0 register in order to make the device memory ++ * accessible. ++ */ ++ ar724x_pci_bar0_is_cached = true; ++ ar724x_pci_bar0_value = value; ++ ++ value = AR7240_BAR0_WAR_VALUE; ++ } else { ++ ar724x_pci_bar0_is_cached = false; ++ } ++ } ++ + base = ar724x_pci_devcfg_base; + + spin_lock_irqsave(&ar724x_pci_lock, flags); diff --git a/target/linux/ar71xx/patches-3.3/110-MIPS-ath79-fix-a-wrong-IRQ-number.patch b/target/linux/ar71xx/patches-3.3/110-MIPS-ath79-fix-a-wrong-IRQ-number.patch new file mode 100644 index 000000000..8702e65fc --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/110-MIPS-ath79-fix-a-wrong-IRQ-number.patch @@ -0,0 +1,73 @@ +From d710990df726cceffb62488e597ecfc4a9e13aa5 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:36:06 +0100 +Subject: [PATCH 15/47] MIPS: ath79: fix a wrong IRQ number + +The Ubiquiti XM board setup code uses an invalid +IRQ number, because it if above of NR_IRQS. This +leads to failed 'request_irq' calls: + + ath9k 0000:00:00.0: request_irq failed + ath9k: probe of 0000:00:00.0 failed with error -22 + +Preserve some IRQ numbers for the built-in IRQ +controller of PCI host controllers in the +AR71XX/AR724X SoCs, and use the correct IRQ +number in the board setup code. + +Signed-off-by: Gabor Juhos +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3495/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/mach-ubnt-xm.c | 5 +++-- + arch/mips/include/asm/mach-ath79/irq.h | 6 +++++- + 2 files changed, 8 insertions(+), 3 deletions(-) + +--- a/arch/mips/ath79/mach-ubnt-xm.c ++++ b/arch/mips/ath79/mach-ubnt-xm.c +@@ -17,6 +17,8 @@ + #include + #endif /* CONFIG_PCI */ + ++#include ++ + #include "machtypes.h" + #include "dev-gpio-buttons.h" + #include "dev-leds-gpio.h" +@@ -33,7 +35,6 @@ + #define UBNT_XM_KEYS_POLL_INTERVAL 20 + #define UBNT_XM_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_XM_KEYS_POLL_INTERVAL) + +-#define UBNT_XM_PCI_IRQ 48 + #define UBNT_XM_EEPROM_ADDR (u8 *) KSEG1ADDR(0x1fff1000) + + static struct gpio_led ubnt_xm_leds_gpio[] __initdata = { +@@ -86,7 +87,7 @@ static struct ath9k_platform_data ubnt_x + + static struct ar724x_pci_data ubnt_xm_pci_data[] = { + { +- .irq = UBNT_XM_PCI_IRQ, ++ .irq = ATH79_PCI_IRQ(0), + .pdata = &ubnt_xm_eeprom_data, + }, + }; +--- a/arch/mips/include/asm/mach-ath79/irq.h ++++ b/arch/mips/include/asm/mach-ath79/irq.h +@@ -10,11 +10,15 @@ + #define __ASM_MACH_ATH79_IRQ_H + + #define MIPS_CPU_IRQ_BASE 0 +-#define NR_IRQS 40 ++#define NR_IRQS 46 + + #define ATH79_MISC_IRQ_BASE 8 + #define ATH79_MISC_IRQ_COUNT 32 + ++#define ATH79_PCI_IRQ_BASE (ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT) ++#define ATH79_PCI_IRQ_COUNT 6 ++#define ATH79_PCI_IRQ(_x) (ATH79_PCI_IRQ_BASE + (_x)) ++ + #define ATH79_CPU_IRQ_IP2 (MIPS_CPU_IRQ_BASE + 2) + #define ATH79_CPU_IRQ_USB (MIPS_CPU_IRQ_BASE + 3) + #define ATH79_CPU_IRQ_GE0 (MIPS_CPU_IRQ_BASE + 4) diff --git a/target/linux/ar71xx/patches-3.3/111-MIPS-ath79-add-PCI-IRQ-handling-code-for-AR724X-SoCs.patch b/target/linux/ar71xx/patches-3.3/111-MIPS-ath79-add-PCI-IRQ-handling-code-for-AR724X-SoCs.patch new file mode 100644 index 000000000..0c15a5496 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/111-MIPS-ath79-add-PCI-IRQ-handling-code-for-AR724X-SoCs.patch @@ -0,0 +1,213 @@ +From 1fd24b552708544ca6233ff7ba60342e9f7e5582 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:36:07 +0100 +Subject: [PATCH 16/47] MIPS: ath79: add PCI IRQ handling code for AR724X SoCs + +The PCI Host Controller of the AR724x SoC has a +built-in IRQ controller. The current code does +not supports that, so the IRQ lines wired to this +controller are not usable. This leads to failed +'request_irq' calls: + + ath9k 0000:00:00.0: request_irq failed + ath9k: probe of 0000:00:00.0 failed with error -89 + +This patch adds support for the IRQ controller +in order to make PCI IRQs work. + +Signed-off-by: Gabor Juhos +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3496/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/pci.c | 3 +- + arch/mips/include/asm/mach-ath79/pci.h | 4 +- + arch/mips/pci/pci-ar724x.c | 118 +++++++++++++++++++++++++++++++- + 3 files changed, 120 insertions(+), 5 deletions(-) + +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -10,6 +10,7 @@ + + #include + #include ++#include + #include + #include "pci.h" + +@@ -50,7 +51,7 @@ int pcibios_plat_dev_init(struct pci_dev + int __init ath79_register_pci(void) + { + if (soc_is_ar724x()) +- return ar724x_pcibios_init(); ++ return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2); + + return -ENODEV; + } +--- a/arch/mips/include/asm/mach-ath79/pci.h ++++ b/arch/mips/include/asm/mach-ath79/pci.h +@@ -12,9 +12,9 @@ + #define __ASM_MACH_ATH79_PCI_H + + #if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR724X) +-int ar724x_pcibios_init(void); ++int ar724x_pcibios_init(int irq); + #else +-static inline int ar724x_pcibios_init(void) { return 0; } ++static inline int ar724x_pcibios_init(int irq) { return 0; } + #endif + + #endif /* __ASM_MACH_ATH79_PCI_H */ +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -8,19 +8,32 @@ + * by the Free Software Foundation. + */ + ++#include + #include + #include ++#include + #include + + #define AR724X_PCI_CFG_BASE 0x14000000 + #define AR724X_PCI_CFG_SIZE 0x1000 ++#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000) ++#define AR724X_PCI_CTRL_SIZE 0x100 ++ + #define AR724X_PCI_MEM_BASE 0x10000000 + #define AR724X_PCI_MEM_SIZE 0x08000000 + ++#define AR724X_PCI_REG_INT_STATUS 0x4c ++#define AR724X_PCI_REG_INT_MASK 0x50 ++ ++#define AR724X_PCI_INT_DEV0 BIT(14) ++ ++#define AR724X_PCI_IRQ_COUNT 1 ++ + #define AR7240_BAR0_WAR_VALUE 0xffff + + static DEFINE_SPINLOCK(ar724x_pci_lock); + static void __iomem *ar724x_pci_devcfg_base; ++static void __iomem *ar724x_pci_ctrl_base; + + static u32 ar724x_pci_bar0_value; + static bool ar724x_pci_bar0_is_cached; +@@ -164,14 +177,115 @@ static struct pci_controller ar724x_pci_ + .mem_resource = &ar724x_mem_resource, + }; + +-int __init ar724x_pcibios_init(void) ++static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) ++{ ++ void __iomem *base; ++ u32 pending; ++ ++ base = ar724x_pci_ctrl_base; ++ ++ pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) & ++ __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++ ++ if (pending & AR724X_PCI_INT_DEV0) ++ generic_handle_irq(ATH79_PCI_IRQ(0)); ++ ++ else ++ spurious_interrupt(); ++} ++ ++static void ar724x_pci_irq_unmask(struct irq_data *d) ++{ ++ void __iomem *base; ++ u32 t; ++ ++ base = ar724x_pci_ctrl_base; ++ ++ switch (d->irq) { ++ case ATH79_PCI_IRQ(0): ++ t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++ __raw_writel(t | AR724X_PCI_INT_DEV0, ++ base + AR724X_PCI_REG_INT_MASK); ++ /* flush write */ ++ __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++ } ++} ++ ++static void ar724x_pci_irq_mask(struct irq_data *d) ++{ ++ void __iomem *base; ++ u32 t; ++ ++ base = ar724x_pci_ctrl_base; ++ ++ switch (d->irq) { ++ case ATH79_PCI_IRQ(0): ++ t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++ __raw_writel(t & ~AR724X_PCI_INT_DEV0, ++ base + AR724X_PCI_REG_INT_MASK); ++ ++ /* flush write */ ++ __raw_readl(base + AR724X_PCI_REG_INT_MASK); ++ ++ t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS); ++ __raw_writel(t | AR724X_PCI_INT_DEV0, ++ base + AR724X_PCI_REG_INT_STATUS); ++ ++ /* flush write */ ++ __raw_readl(base + AR724X_PCI_REG_INT_STATUS); ++ } ++} ++ ++static struct irq_chip ar724x_pci_irq_chip = { ++ .name = "AR724X PCI ", ++ .irq_mask = ar724x_pci_irq_mask, ++ .irq_unmask = ar724x_pci_irq_unmask, ++ .irq_mask_ack = ar724x_pci_irq_mask, ++}; ++ ++static void __init ar724x_pci_irq_init(int irq) ++{ ++ void __iomem *base; ++ int i; ++ ++ base = ar724x_pci_ctrl_base; ++ ++ __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); ++ __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); ++ ++ BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT); ++ ++ for (i = ATH79_PCI_IRQ_BASE; ++ i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) ++ irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, ++ handle_level_irq); ++ ++ irq_set_chained_handler(irq, ar724x_pci_irq_handler); ++} ++ ++int __init ar724x_pcibios_init(int irq) + { ++ int ret; ++ ++ ret = -ENOMEM; ++ + ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE, + AR724X_PCI_CFG_SIZE); + if (ar724x_pci_devcfg_base == NULL) +- return -ENOMEM; ++ goto err; + ++ ar724x_pci_ctrl_base = ioremap(AR724X_PCI_CTRL_BASE, ++ AR724X_PCI_CTRL_SIZE); ++ if (ar724x_pci_ctrl_base == NULL) ++ goto err_unmap_devcfg; ++ ++ ar724x_pci_irq_init(irq); + register_pci_controller(&ar724x_pci_controller); + + return PCIBIOS_SUCCESSFUL; ++ ++err_unmap_devcfg: ++ iounmap(ar724x_pci_devcfg_base); ++err: ++ return ret; + } diff --git a/target/linux/ar71xx/patches-3.3/112-MIPS-ath79-get-rid-of-some-ifdefs-in-mach-ubnt-xm.c.patch b/target/linux/ar71xx/patches-3.3/112-MIPS-ath79-get-rid-of-some-ifdefs-in-mach-ubnt-xm.c.patch new file mode 100644 index 000000000..4ef080541 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/112-MIPS-ath79-get-rid-of-some-ifdefs-in-mach-ubnt-xm.c.patch @@ -0,0 +1,64 @@ +From b2ab491ed634a4c0b7af5f11940e0ca42b1a87c8 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:36:08 +0100 +Subject: [PATCH 17/47] MIPS: ath79: get rid of some ifdefs in mach-ubnt-xm.c + +Remove a superfluous ifdef around an include. Also +reorganize the board setup code a bit, so another +ifdef can be removed. + +Signed-off-by: Gabor Juhos +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3497/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/mach-ubnt-xm.c | 23 ++++++++++++----------- + 1 files changed, 12 insertions(+), 11 deletions(-) + +--- a/arch/mips/ath79/mach-ubnt-xm.c ++++ b/arch/mips/ath79/mach-ubnt-xm.c +@@ -12,10 +12,7 @@ + + #include + #include +- +-#ifdef CONFIG_PCI + #include +-#endif /* CONFIG_PCI */ + + #include + +@@ -91,6 +88,17 @@ static struct ar724x_pci_data ubnt_xm_pc + .pdata = &ubnt_xm_eeprom_data, + }, + }; ++ ++static void __init ubnt_xm_pci_init(void) ++{ ++ memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR, ++ sizeof(ubnt_xm_eeprom_data.eeprom_data)); ++ ++ ar724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data)); ++ ath79_register_pci(); ++} ++#else ++static inline void ubnt_xm_pci_init(void) {} + #endif /* CONFIG_PCI */ + + static void __init ubnt_xm_init(void) +@@ -105,14 +113,7 @@ static void __init ubnt_xm_init(void) + ath79_register_spi(&ubnt_xm_spi_data, ubnt_xm_spi_info, + ARRAY_SIZE(ubnt_xm_spi_info)); + +-#ifdef CONFIG_PCI +- memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR, +- sizeof(ubnt_xm_eeprom_data.eeprom_data)); +- +- ar724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data)); +-#endif /* CONFIG_PCI */ +- +- ath79_register_pci(); ++ ubnt_xm_pci_init(); + } + + MIPS_MACHINE(ATH79_MACH_UBNT_XM, diff --git a/target/linux/ar71xx/patches-3.3/113-MIPS-ath79-allow-to-use-board-specific-pci_plat_dev_.patch b/target/linux/ar71xx/patches-3.3/113-MIPS-ath79-allow-to-use-board-specific-pci_plat_dev_.patch new file mode 100644 index 000000000..38765b0a9 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/113-MIPS-ath79-allow-to-use-board-specific-pci_plat_dev_.patch @@ -0,0 +1,141 @@ +From 2b62c9d685d9bb048a006b695683b2a812c0a847 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:36:09 +0100 +Subject: [PATCH 18/47] MIPS: ath79: allow to use board specific pci_plat_dev_init functions + +Th current implementation causes NULL pointer dereference +if 'pci_data' is not set: + +pci 0000:00:00.0: BAR 0: assigned [mem 0x10000000-0x1000ffff 64bit] +pci 0000:00:00.0: BAR 0: set to [mem 0x10000000-0x1000ffff 64bit] (PCI +address [0x10000000-0x1000ffff]) +CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == 802daca0, ra == 802e78a4 +Oops[#1]: +Cpu 0 +$ 0 : 00000000 80420000 00000000 00000000 +$ 4 : 00000000 00000000 00000001 00000001 +$ 8 : 00000001 0000032c 81c54700 00000001 +$12 : 0000032d 0000000f 00000000 ffffffff +$16 : 81c14c00 00000001 802dac74 80195f98 +$20 : 802ea050 00000000 00000000 00000000 +$24 : 00000003 800617f0 +$28 : 81c20000 81c21e70 00000000 802e78a4 +Hi : 00000000 +Lo : 4190ab00 +epc : 802daca0 0x802daca0 + Not tainted +ra : 802e78a4 0x802e78a4 +Status: 1000c003 KERNEL EXL IE +Cause : 00800008 +BadVA : 00000000 +PrId : 00019374 (MIPS 24Kc) +Modules linked in: +Process swapper (pid: 1, threadinfo=81c20000, task=81c18000, tls=00000000) +Stack : 00000000 8027d5d8 802e8ae0 00000000 01000000 802e8b5c 81c50600 00000000 + 802ff290 00000000 80420000 802ea0bc 00000000 00000000 80420000 802ff290 + 80420000 80060930 33390000 00000000 00002308 80140a80 00000028 802d0000 + 00000000 800ba024 802ff004 802ff0c8 802ff290 00000000 00000000 00000000 + 00000000 802d897c 01234567 7f827068 00000000 0045f798 00460000 00000000 + +This can be avoided by calling the 'ar724x_pci_add_data' +function from the board specific setup code. However it +makes no sense to use that function for every board, +especially when the board does not needs to set the +platform_data field of any PCI device. + +The patch allows the board setup code to specify a board +specific function if that is required. + +Signed-off-by: Gabor Juhos +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3499/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/mach-ubnt-xm.c | 13 ++++++++++++- + arch/mips/ath79/pci.c | 14 ++++++++------ + arch/mips/ath79/pci.h | 4 +++- + 3 files changed, 23 insertions(+), 8 deletions(-) + +--- a/arch/mips/ath79/mach-ubnt-xm.c ++++ b/arch/mips/ath79/mach-ubnt-xm.c +@@ -85,16 +85,27 @@ static struct ath9k_platform_data ubnt_x + static struct ar724x_pci_data ubnt_xm_pci_data[] = { + { + .irq = ATH79_PCI_IRQ(0), +- .pdata = &ubnt_xm_eeprom_data, + }, + }; + ++static int ubnt_xm_pci_plat_dev_init(struct pci_dev *dev) ++{ ++ switch (PCI_SLOT(dev->devfn)) { ++ case 0: ++ dev->dev.platform_data = &ubnt_xm_eeprom_data; ++ break; ++ } ++ ++ return 0; ++} ++ + static void __init ubnt_xm_pci_init(void) + { + memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR, + sizeof(ubnt_xm_eeprom_data.eeprom_data)); + + ar724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data)); ++ ath79_pci_set_plat_dev_init(ubnt_xm_pci_plat_dev_init); + ath79_register_pci(); + } + #else +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -14,6 +14,7 @@ + #include + #include "pci.h" + ++static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); + static struct ar724x_pci_data *pci_data; + static int pci_data_size; + +@@ -38,14 +39,15 @@ int __init pcibios_map_irq(const struct + + int pcibios_plat_dev_init(struct pci_dev *dev) + { +- unsigned int devfn = dev->devfn; +- +- if (devfn > pci_data_size - 1) +- return PCIBIOS_DEVICE_NOT_FOUND; ++ if (ath79_pci_plat_dev_init) ++ return ath79_pci_plat_dev_init(dev); + +- dev->dev.platform_data = pci_data[devfn].pdata; ++ return 0; ++} + +- return PCIBIOS_SUCCESSFUL; ++void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev)) ++{ ++ ath79_pci_plat_dev_init = func; + } + + int __init ath79_register_pci(void) +--- a/arch/mips/ath79/pci.h ++++ b/arch/mips/ath79/pci.h +@@ -13,14 +13,16 @@ + + struct ar724x_pci_data { + int irq; +- void *pdata; + }; + + void ar724x_pci_add_data(struct ar724x_pci_data *data, int size); + + #ifdef CONFIG_PCI ++void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev)); + int ath79_register_pci(void); + #else ++static inline void ++ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *)) {} + static inline int ath79_register_pci(void) { return 0; } + #endif + diff --git a/target/linux/ar71xx/patches-3.3/114-MIPS-ath79-add-support-for-the-PCI-host-controller-o.patch b/target/linux/ar71xx/patches-3.3/114-MIPS-ath79-add-support-for-the-PCI-host-controller-o.patch new file mode 100644 index 000000000..4021af2ca --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/114-MIPS-ath79-add-support-for-the-PCI-host-controller-o.patch @@ -0,0 +1,436 @@ +From 4201b6aeb059b481571c241a2fc96fd3f41032e9 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:36:10 +0100 +Subject: [PATCH 19/47] MIPS: ath79: add support for the PCI host controller of the AR71XX SoCs + +The Atheros AR71XX SoCs have a built-in PCI Host Controller. +This patch adds a driver for that, and modifies the relevant +files in order to allow to register the PCI controller from +board specific setup. + +Signed-off-by: Gabor Juhos +Signed-off-by: Imre Kaloz +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3498/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/Kconfig | 1 + + arch/mips/include/asm/mach-ath79/pci.h | 6 + + arch/mips/pci/Makefile | 1 + + arch/mips/pci/pci-ar71xx.c | 375 ++++++++++++++++++++++++++++++++ + 4 files changed, 383 insertions(+), 0 deletions(-) + create mode 100644 arch/mips/pci/pci-ar71xx.c + +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -52,6 +52,7 @@ endmenu + config SOC_AR71XX + select USB_ARCH_HAS_EHCI + select USB_ARCH_HAS_OHCI ++ select HW_HAS_PCI + def_bool n + + config SOC_AR724X +--- a/arch/mips/include/asm/mach-ath79/pci.h ++++ b/arch/mips/include/asm/mach-ath79/pci.h +@@ -11,6 +11,12 @@ + #ifndef __ASM_MACH_ATH79_PCI_H + #define __ASM_MACH_ATH79_PCI_H + ++#if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR71XX) ++int ar71xx_pcibios_init(void); ++#else ++static inline int ar71xx_pcibios_init(void) { return 0; } ++#endif ++ + #if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR724X) + int ar724x_pcibios_init(int irq); + #else +--- a/arch/mips/pci/Makefile ++++ b/arch/mips/pci/Makefile +@@ -19,6 +19,7 @@ obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o + obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ + ops-bcm63xx.o + obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o ++obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o + obj-$(CONFIG_SOC_AR724X) += pci-ar724x.o + + # +--- /dev/null ++++ b/arch/mips/pci/pci-ar71xx.c +@@ -0,0 +1,375 @@ ++/* ++ * Atheros AR71xx PCI host controller driver ++ * ++ * Copyright (C) 2008-2011 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros' 2.6.15 BSP ++ * ++ * This program 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. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#define AR71XX_PCI_MEM_BASE 0x10000000 ++#define AR71XX_PCI_MEM_SIZE 0x08000000 ++ ++#define AR71XX_PCI_WIN0_OFFS 0x10000000 ++#define AR71XX_PCI_WIN1_OFFS 0x11000000 ++#define AR71XX_PCI_WIN2_OFFS 0x12000000 ++#define AR71XX_PCI_WIN3_OFFS 0x13000000 ++#define AR71XX_PCI_WIN4_OFFS 0x14000000 ++#define AR71XX_PCI_WIN5_OFFS 0x15000000 ++#define AR71XX_PCI_WIN6_OFFS 0x16000000 ++#define AR71XX_PCI_WIN7_OFFS 0x07000000 ++ ++#define AR71XX_PCI_CFG_BASE \ ++ (AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x10000) ++#define AR71XX_PCI_CFG_SIZE 0x100 ++ ++#define AR71XX_PCI_REG_CRP_AD_CBE 0x00 ++#define AR71XX_PCI_REG_CRP_WRDATA 0x04 ++#define AR71XX_PCI_REG_CRP_RDDATA 0x08 ++#define AR71XX_PCI_REG_CFG_AD 0x0c ++#define AR71XX_PCI_REG_CFG_CBE 0x10 ++#define AR71XX_PCI_REG_CFG_WRDATA 0x14 ++#define AR71XX_PCI_REG_CFG_RDDATA 0x18 ++#define AR71XX_PCI_REG_PCI_ERR 0x1c ++#define AR71XX_PCI_REG_PCI_ERR_ADDR 0x20 ++#define AR71XX_PCI_REG_AHB_ERR 0x24 ++#define AR71XX_PCI_REG_AHB_ERR_ADDR 0x28 ++ ++#define AR71XX_PCI_CRP_CMD_WRITE 0x00010000 ++#define AR71XX_PCI_CRP_CMD_READ 0x00000000 ++#define AR71XX_PCI_CFG_CMD_READ 0x0000000a ++#define AR71XX_PCI_CFG_CMD_WRITE 0x0000000b ++ ++#define AR71XX_PCI_INT_CORE BIT(4) ++#define AR71XX_PCI_INT_DEV2 BIT(2) ++#define AR71XX_PCI_INT_DEV1 BIT(1) ++#define AR71XX_PCI_INT_DEV0 BIT(0) ++ ++#define AR71XX_PCI_IRQ_COUNT 5 ++ ++static DEFINE_SPINLOCK(ar71xx_pci_lock); ++static void __iomem *ar71xx_pcicfg_base; ++ ++/* Byte lane enable bits */ ++static const u8 ar71xx_pci_ble_table[4][4] = { ++ {0x0, 0xf, 0xf, 0xf}, ++ {0xe, 0xd, 0xb, 0x7}, ++ {0xc, 0xf, 0x3, 0xf}, ++ {0xf, 0xf, 0xf, 0xf}, ++}; ++ ++static const u32 ar71xx_pci_read_mask[8] = { ++ 0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0 ++}; ++ ++static inline u32 ar71xx_pci_get_ble(int where, int size, int local) ++{ ++ u32 t; ++ ++ t = ar71xx_pci_ble_table[size & 3][where & 3]; ++ BUG_ON(t == 0xf); ++ t <<= (local) ? 20 : 4; ++ ++ return t; ++} ++ ++static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn, ++ int where) ++{ ++ u32 ret; ++ ++ if (!bus->number) { ++ /* type 0 */ ++ ret = (1 << PCI_SLOT(devfn)) | (PCI_FUNC(devfn) << 8) | ++ (where & ~3); ++ } else { ++ /* type 1 */ ++ ret = (bus->number << 16) | (PCI_SLOT(devfn) << 11) | ++ (PCI_FUNC(devfn) << 8) | (where & ~3) | 1; ++ } ++ ++ return ret; ++} ++ ++static int ar71xx_pci_check_error(int quiet) ++{ ++ void __iomem *base = ar71xx_pcicfg_base; ++ u32 pci_err; ++ u32 ahb_err; ++ ++ pci_err = __raw_readl(base + AR71XX_PCI_REG_PCI_ERR) & 3; ++ if (pci_err) { ++ if (!quiet) { ++ u32 addr; ++ ++ addr = __raw_readl(base + AR71XX_PCI_REG_PCI_ERR_ADDR); ++ pr_crit("ar71xx: %s bus error %d at addr 0x%x\n", ++ "PCI", pci_err, addr); ++ } ++ ++ /* clear PCI error status */ ++ __raw_writel(pci_err, base + AR71XX_PCI_REG_PCI_ERR); ++ } ++ ++ ahb_err = __raw_readl(base + AR71XX_PCI_REG_AHB_ERR) & 1; ++ if (ahb_err) { ++ if (!quiet) { ++ u32 addr; ++ ++ addr = __raw_readl(base + AR71XX_PCI_REG_AHB_ERR_ADDR); ++ pr_crit("ar71xx: %s bus error %d at addr 0x%x\n", ++ "AHB", ahb_err, addr); ++ } ++ ++ /* clear AHB error status */ ++ __raw_writel(ahb_err, base + AR71XX_PCI_REG_AHB_ERR); ++ } ++ ++ return !!(ahb_err | pci_err); ++} ++ ++static inline void ar71xx_pci_local_write(int where, int size, u32 value) ++{ ++ void __iomem *base = ar71xx_pcicfg_base; ++ u32 ad_cbe; ++ ++ value = value << (8 * (where & 3)); ++ ++ ad_cbe = AR71XX_PCI_CRP_CMD_WRITE | (where & ~3); ++ ad_cbe |= ar71xx_pci_get_ble(where, size, 1); ++ ++ __raw_writel(ad_cbe, base + AR71XX_PCI_REG_CRP_AD_CBE); ++ __raw_writel(value, base + AR71XX_PCI_REG_CRP_WRDATA); ++} ++ ++static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus, ++ unsigned int devfn, ++ int where, int size, u32 cmd) ++{ ++ void __iomem *base = ar71xx_pcicfg_base; ++ u32 addr; ++ ++ addr = ar71xx_pci_bus_addr(bus, devfn, where); ++ ++ __raw_writel(addr, base + AR71XX_PCI_REG_CFG_AD); ++ __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0), ++ base + AR71XX_PCI_REG_CFG_CBE); ++ ++ return ar71xx_pci_check_error(1); ++} ++ ++static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 *value) ++{ ++ void __iomem *base = ar71xx_pcicfg_base; ++ unsigned long flags; ++ u32 data; ++ int err; ++ int ret; ++ ++ ret = PCIBIOS_SUCCESSFUL; ++ data = ~0; ++ ++ spin_lock_irqsave(&ar71xx_pci_lock, flags); ++ ++ err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, ++ AR71XX_PCI_CFG_CMD_READ); ++ if (err) ++ ret = PCIBIOS_DEVICE_NOT_FOUND; ++ else ++ data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA); ++ ++ spin_unlock_irqrestore(&ar71xx_pci_lock, flags); ++ ++ *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7]; ++ ++ return ret; ++} ++ ++static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 value) ++{ ++ void __iomem *base = ar71xx_pcicfg_base; ++ unsigned long flags; ++ int err; ++ int ret; ++ ++ value = value << (8 * (where & 3)); ++ ret = PCIBIOS_SUCCESSFUL; ++ ++ spin_lock_irqsave(&ar71xx_pci_lock, flags); ++ ++ err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, ++ AR71XX_PCI_CFG_CMD_WRITE); ++ if (err) ++ ret = PCIBIOS_DEVICE_NOT_FOUND; ++ else ++ __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA); ++ ++ spin_unlock_irqrestore(&ar71xx_pci_lock, flags); ++ ++ return ret; ++} ++ ++static struct pci_ops ar71xx_pci_ops = { ++ .read = ar71xx_pci_read_config, ++ .write = ar71xx_pci_write_config, ++}; ++ ++static struct resource ar71xx_pci_io_resource = { ++ .name = "PCI IO space", ++ .start = 0, ++ .end = 0, ++ .flags = IORESOURCE_IO, ++}; ++ ++static struct resource ar71xx_pci_mem_resource = { ++ .name = "PCI memory space", ++ .start = AR71XX_PCI_MEM_BASE, ++ .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1, ++ .flags = IORESOURCE_MEM ++}; ++ ++static struct pci_controller ar71xx_pci_controller = { ++ .pci_ops = &ar71xx_pci_ops, ++ .mem_resource = &ar71xx_pci_mem_resource, ++ .io_resource = &ar71xx_pci_io_resource, ++}; ++ ++static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc) ++{ ++ void __iomem *base = ath79_reset_base; ++ u32 pending; ++ ++ pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) & ++ __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ ++ if (pending & AR71XX_PCI_INT_DEV0) ++ generic_handle_irq(ATH79_PCI_IRQ(0)); ++ ++ else if (pending & AR71XX_PCI_INT_DEV1) ++ generic_handle_irq(ATH79_PCI_IRQ(1)); ++ ++ else if (pending & AR71XX_PCI_INT_DEV2) ++ generic_handle_irq(ATH79_PCI_IRQ(2)); ++ ++ else if (pending & AR71XX_PCI_INT_CORE) ++ generic_handle_irq(ATH79_PCI_IRQ(4)); ++ ++ else ++ spurious_interrupt(); ++} ++ ++static void ar71xx_pci_irq_unmask(struct irq_data *d) ++{ ++ unsigned int irq = d->irq - ATH79_PCI_IRQ_BASE; ++ void __iomem *base = ath79_reset_base; ++ u32 t; ++ ++ t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ ++ /* flush write */ ++ __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++} ++ ++static void ar71xx_pci_irq_mask(struct irq_data *d) ++{ ++ unsigned int irq = d->irq - ATH79_PCI_IRQ_BASE; ++ void __iomem *base = ath79_reset_base; ++ u32 t; ++ ++ t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ ++ /* flush write */ ++ __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++} ++ ++static struct irq_chip ar71xx_pci_irq_chip = { ++ .name = "AR71XX PCI", ++ .irq_mask = ar71xx_pci_irq_mask, ++ .irq_unmask = ar71xx_pci_irq_unmask, ++ .irq_mask_ack = ar71xx_pci_irq_mask, ++}; ++ ++static __init void ar71xx_pci_irq_init(void) ++{ ++ void __iomem *base = ath79_reset_base; ++ int i; ++ ++ __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE); ++ __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS); ++ ++ BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR71XX_PCI_IRQ_COUNT); ++ ++ for (i = ATH79_PCI_IRQ_BASE; ++ i < ATH79_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) ++ irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip, ++ handle_level_irq); ++ ++ irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar71xx_pci_irq_handler); ++} ++ ++static __init void ar71xx_pci_reset(void) ++{ ++ void __iomem *ddr_base = ath79_ddr_base; ++ ++ ath79_device_reset_set(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE); ++ mdelay(100); ++ ++ ath79_device_reset_clear(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE); ++ mdelay(100); ++ ++ __raw_writel(AR71XX_PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0); ++ __raw_writel(AR71XX_PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1); ++ __raw_writel(AR71XX_PCI_WIN2_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN2); ++ __raw_writel(AR71XX_PCI_WIN3_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN3); ++ __raw_writel(AR71XX_PCI_WIN4_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN4); ++ __raw_writel(AR71XX_PCI_WIN5_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN5); ++ __raw_writel(AR71XX_PCI_WIN6_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN6); ++ __raw_writel(AR71XX_PCI_WIN7_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN7); ++ ++ mdelay(100); ++} ++ ++__init int ar71xx_pcibios_init(void) ++{ ++ u32 t; ++ ++ ar71xx_pcicfg_base = ioremap(AR71XX_PCI_CFG_BASE, AR71XX_PCI_CFG_SIZE); ++ if (ar71xx_pcicfg_base == NULL) ++ return -ENOMEM; ++ ++ ar71xx_pci_reset(); ++ ++ /* setup COMMAND register */ ++ t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE ++ | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; ++ ar71xx_pci_local_write(PCI_COMMAND, 4, t); ++ ++ /* clear bus errors */ ++ ar71xx_pci_check_error(1); ++ ++ ar71xx_pci_irq_init(); ++ ++ register_pci_controller(&ar71xx_pci_controller); ++ ++ return 0; ++} diff --git a/target/linux/ar71xx/patches-3.3/115-MIPS-ath79-allow-to-use-SoC-specific-PCI-IRQ-maps.patch b/target/linux/ar71xx/patches-3.3/115-MIPS-ath79-allow-to-use-SoC-specific-PCI-IRQ-maps.patch new file mode 100644 index 000000000..7daaf1923 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/115-MIPS-ath79-allow-to-use-SoC-specific-PCI-IRQ-maps.patch @@ -0,0 +1,165 @@ +From fd1dd2f2c317bc0fc2c30fba440d911654bf592e Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:36:11 +0100 +Subject: [PATCH 20/47] MIPS: ath79: allow to use SoC specific PCI IRQ maps + +The PCI controllers in the AR71XX and in the +AR724X SoCs are different, and both of them +uses different IRQ wiring. + +The patch modifies the 'pcibios_map_irq' function +in order to allow to use different IRQ maps for +the different SoCs. The patch also adds a function, +which lets the board setup code to override the +default IRQ map. + +Signed-off-by: Gabor Juhos +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3500/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/pci.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++--- + arch/mips/ath79/pci.h | 9 ++++++ + 2 files changed, 77 insertions(+), 4 deletions(-) + +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -8,6 +8,7 @@ + * by the Free Software Foundation. + */ + ++#include + #include + #include + #include +@@ -15,9 +16,35 @@ + #include "pci.h" + + static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); ++static const struct ath79_pci_irq *ath79_pci_irq_map __initdata; ++static unsigned ath79_pci_nr_irqs __initdata; + static struct ar724x_pci_data *pci_data; + static int pci_data_size; + ++static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = { ++ { ++ .slot = 17, ++ .pin = 1, ++ .irq = ATH79_PCI_IRQ(0), ++ }, { ++ .slot = 18, ++ .pin = 1, ++ .irq = ATH79_PCI_IRQ(1), ++ }, { ++ .slot = 19, ++ .pin = 1, ++ .irq = ATH79_PCI_IRQ(2), ++ } ++}; ++ ++static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = { ++ { ++ .slot = 0, ++ .pin = 1, ++ .irq = ATH79_PCI_IRQ(0), ++ } ++}; ++ + void ar724x_pci_add_data(struct ar724x_pci_data *data, int size) + { + pci_data = data; +@@ -26,13 +53,40 @@ void ar724x_pci_add_data(struct ar724x_p + + int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) + { +- unsigned int devfn = dev->devfn; + int irq = -1; ++ int i; + +- if (devfn > pci_data_size - 1) +- return irq; +- +- irq = pci_data[devfn].irq; ++ if (ath79_pci_nr_irqs == 0 || ++ ath79_pci_irq_map == NULL) { ++ if (soc_is_ar71xx()) { ++ ath79_pci_irq_map = ar71xx_pci_irq_map; ++ ath79_pci_nr_irqs = ARRAY_SIZE(ar71xx_pci_irq_map); ++ } else if (soc_is_ar724x()) { ++ ath79_pci_irq_map = ar724x_pci_irq_map; ++ ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map); ++ } else { ++ pr_crit("pci %s: invalid irq map\n", ++ pci_name((struct pci_dev *) dev)); ++ return irq; ++ } ++ } ++ ++ for (i = 0; i < ath79_pci_nr_irqs; i++) { ++ const struct ath79_pci_irq *entry; ++ ++ entry = &ath79_pci_irq_map[i]; ++ if (entry->slot == slot && entry->pin == pin) { ++ irq = entry->irq; ++ break; ++ } ++ } ++ ++ if (irq < 0) ++ pr_crit("pci %s: no irq found for pin %u\n", ++ pci_name((struct pci_dev *) dev), pin); ++ else ++ pr_info("pci %s: using irq %d for pin %u\n", ++ pci_name((struct pci_dev *) dev), irq, pin); + + return irq; + } +@@ -45,6 +99,13 @@ int pcibios_plat_dev_init(struct pci_dev + return 0; + } + ++void __init ath79_pci_set_irq_map(unsigned nr_irqs, ++ const struct ath79_pci_irq *map) ++{ ++ ath79_pci_nr_irqs = nr_irqs; ++ ath79_pci_irq_map = map; ++} ++ + void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev)) + { + ath79_pci_plat_dev_init = func; +@@ -52,6 +113,9 @@ void __init ath79_pci_set_plat_dev_init( + + int __init ath79_register_pci(void) + { ++ if (soc_is_ar71xx()) ++ return ar71xx_pcibios_init(); ++ + if (soc_is_ar724x()) + return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2); + +--- a/arch/mips/ath79/pci.h ++++ b/arch/mips/ath79/pci.h +@@ -15,13 +15,22 @@ struct ar724x_pci_data { + int irq; + }; + ++struct ath79_pci_irq { ++ u8 slot; ++ u8 pin; ++ int irq; ++}; ++ + void ar724x_pci_add_data(struct ar724x_pci_data *data, int size); + + #ifdef CONFIG_PCI ++void ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map); + void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev)); + int ath79_register_pci(void); + #else + static inline void ++ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map) {} ++static inline void + ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *)) {} + static inline int ath79_register_pci(void) { return 0; } + #endif diff --git a/target/linux/ar71xx/patches-3.3/116-MIPS-ath79-remove-ar724x_pci_add_data-function.patch b/target/linux/ar71xx/patches-3.3/116-MIPS-ath79-remove-ar724x_pci_add_data-function.patch new file mode 100644 index 000000000..70013c8d9 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/116-MIPS-ath79-remove-ar724x_pci_add_data-function.patch @@ -0,0 +1,86 @@ +From 29398cf1212afc9a6474127259cbb3a48d0751e5 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:36:12 +0100 +Subject: [PATCH 21/47] MIPS: ath79: remove ar724x_pci_add_data function + +The variables set by this function are not used anymore. +Remove the function and the relevant variables as well. + +Signed-off-by: Gabor Juhos +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3501/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/mach-ubnt-xm.c | 7 ------- + arch/mips/ath79/pci.c | 8 -------- + arch/mips/ath79/pci.h | 6 ------ + 3 files changed, 0 insertions(+), 21 deletions(-) + +--- a/arch/mips/ath79/mach-ubnt-xm.c ++++ b/arch/mips/ath79/mach-ubnt-xm.c +@@ -82,12 +82,6 @@ static struct ath79_spi_platform_data ub + #ifdef CONFIG_PCI + static struct ath9k_platform_data ubnt_xm_eeprom_data; + +-static struct ar724x_pci_data ubnt_xm_pci_data[] = { +- { +- .irq = ATH79_PCI_IRQ(0), +- }, +-}; +- + static int ubnt_xm_pci_plat_dev_init(struct pci_dev *dev) + { + switch (PCI_SLOT(dev->devfn)) { +@@ -104,7 +98,6 @@ static void __init ubnt_xm_pci_init(void + memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR, + sizeof(ubnt_xm_eeprom_data.eeprom_data)); + +- ar724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data)); + ath79_pci_set_plat_dev_init(ubnt_xm_pci_plat_dev_init); + ath79_register_pci(); + } +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -18,8 +18,6 @@ + static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); + static const struct ath79_pci_irq *ath79_pci_irq_map __initdata; + static unsigned ath79_pci_nr_irqs __initdata; +-static struct ar724x_pci_data *pci_data; +-static int pci_data_size; + + static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = { + { +@@ -45,12 +43,6 @@ static const struct ath79_pci_irq ar724x + } + }; + +-void ar724x_pci_add_data(struct ar724x_pci_data *data, int size) +-{ +- pci_data = data; +- pci_data_size = size; +-} +- + int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) + { + int irq = -1; +--- a/arch/mips/ath79/pci.h ++++ b/arch/mips/ath79/pci.h +@@ -11,18 +11,12 @@ + #ifndef _ATH79_PCI_H + #define _ATH79_PCI_H + +-struct ar724x_pci_data { +- int irq; +-}; +- + struct ath79_pci_irq { + u8 slot; + u8 pin; + int irq; + }; + +-void ar724x_pci_add_data(struct ar724x_pci_data *data, int size); +- + #ifdef CONFIG_PCI + void ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map); + void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev)); diff --git a/target/linux/ar71xx/patches-3.3/117-MIPS-ath79-register-PCI-controller-on-the-PB44-board.patch b/target/linux/ar71xx/patches-3.3/117-MIPS-ath79-register-PCI-controller-on-the-PB44-board.patch new file mode 100644 index 000000000..969b79d8b --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/117-MIPS-ath79-register-PCI-controller-on-the-PB44-board.patch @@ -0,0 +1,34 @@ +From 12db6a98b438a50799873bfd2b736a3b02a4bd57 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:36:13 +0100 +Subject: [PATCH 22/47] MIPS: ath79: register PCI controller on the PB44 board + +The PB44 reference board has two miniPCI slots. Register +the PCI controller to make those usable. + +Signed-off-by: Gabor Juhos +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3502/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/mach-pb44.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +--- a/arch/mips/ath79/mach-pb44.c ++++ b/arch/mips/ath79/mach-pb44.c +@@ -19,6 +19,7 @@ + #include "dev-leds-gpio.h" + #include "dev-spi.h" + #include "dev-usb.h" ++#include "pci.h" + + #define PB44_GPIO_I2C_SCL 0 + #define PB44_GPIO_I2C_SDA 1 +@@ -114,6 +115,7 @@ static void __init pb44_init(void) + ath79_register_spi(&pb44_spi_data, pb44_spi_info, + ARRAY_SIZE(pb44_spi_info)); + ath79_register_usb(); ++ ath79_register_pci(); + } + + MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board", diff --git a/target/linux/ar71xx/patches-3.3/118-MIPS-ath79-update-copyright-headers-of-PCI-related-f.patch b/target/linux/ar71xx/patches-3.3/118-MIPS-ath79-update-copyright-headers-of-PCI-related-f.patch new file mode 100644 index 000000000..da173a5f1 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/118-MIPS-ath79-update-copyright-headers-of-PCI-related-f.patch @@ -0,0 +1,71 @@ +From d3b5329b89d1bc733c56e4d609a89b429bf6cd4e Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:36:14 +0100 +Subject: [PATCH 23/47] MIPS: ath79: update copyright headers of PCI related files + +Add copyright records according to the recent changes in +the PCI code. Also fix up the descriptions. + +Signed-off-by: Gabor Juhos +Signed-off-by: Imre Kaloz +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/3503/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/pci.c | 4 ++++ + arch/mips/ath79/pci.h | 4 +++- + arch/mips/include/asm/mach-ath79/pci.h | 4 +++- + arch/mips/pci/pci-ar724x.c | 3 ++- + 4 files changed, 12 insertions(+), 3 deletions(-) + +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -2,6 +2,10 @@ + * Atheros AR71XX/AR724X specific PCI setup code + * + * Copyright (C) 2011 René Bolldorf ++ * Copyright (C) 2008-2011 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * Parts of this file are based on Atheros' 2.6.15 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published +--- a/arch/mips/ath79/pci.h ++++ b/arch/mips/ath79/pci.h +@@ -1,7 +1,9 @@ + /* +- * Atheros 724x PCI support ++ * Atheros AR71XX/AR724X PCI support + * + * Copyright (C) 2011 René Bolldorf ++ * Copyright (C) 2008-2011 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published +--- a/arch/mips/include/asm/mach-ath79/pci.h ++++ b/arch/mips/include/asm/mach-ath79/pci.h +@@ -1,7 +1,9 @@ + /* +- * Atheros 724x PCI support ++ * Atheros AR71XX/AR724X PCI support + * + * Copyright (C) 2011 René Bolldorf ++ * Copyright (C) 2008-2011 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -1,7 +1,8 @@ + /* +- * Atheros 724x PCI support ++ * Atheros AR724X PCI host controller driver + * + * Copyright (C) 2011 René Bolldorf ++ * Copyright (C) 2009-2011 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published diff --git a/target/linux/ar71xx/patches-3.3/119-MIPS-ath79-add-early_printk-support-for-AR934X.patch b/target/linux/ar71xx/patches-3.3/119-MIPS-ath79-add-early_printk-support-for-AR934X.patch new file mode 100644 index 000000000..512f2da10 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/119-MIPS-ath79-add-early_printk-support-for-AR934X.patch @@ -0,0 +1,56 @@ +From 5c1f1041309ede56d48eb3c665025e87c9824a64 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:45:19 +0100 +Subject: [PATCH 24/47] MIPS: ath79: add early_printk support for AR934X + +The patch allows to see kernel messages on AR934X SoCs in +early boot stage. + +Signed-off-by: Gabor Juhos +Acked-by: Luis R. Rodriguez +Cc: linux-mips@linux-mips.org +Cc: mcgrof@infradead.org +Patchwork: https://patchwork.linux-mips.org/patch/3504/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/early_printk.c | 3 +++ + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 6 +++++- + 2 files changed, 8 insertions(+), 1 deletions(-) + +--- a/arch/mips/ath79/early_printk.c ++++ b/arch/mips/ath79/early_printk.c +@@ -71,6 +71,9 @@ static void prom_putchar_init(void) + case REV_ID_MAJOR_AR7241: + case REV_ID_MAJOR_AR7242: + case REV_ID_MAJOR_AR913X: ++ case REV_ID_MAJOR_AR9341: ++ case REV_ID_MAJOR_AR9342: ++ case REV_ID_MAJOR_AR9344: + _prom_putchar = prom_putchar_ar71xx; + break; + +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -1,10 +1,11 @@ + /* + * Atheros AR71XX/AR724X/AR913X SoC register definitions + * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * +- * Parts of this file are based on Atheros' 2.6.15 BSP ++ * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published +@@ -249,6 +250,9 @@ + #define REV_ID_MAJOR_AR7242 0x1100 + #define REV_ID_MAJOR_AR9330 0x0110 + #define REV_ID_MAJOR_AR9331 0x1110 ++#define REV_ID_MAJOR_AR9341 0x0120 ++#define REV_ID_MAJOR_AR9342 0x1120 ++#define REV_ID_MAJOR_AR9344 0x2120 + + #define AR71XX_REV_ID_MINOR_MASK 0x3 + #define AR71XX_REV_ID_MINOR_AR7130 0x0 diff --git a/target/linux/ar71xx/patches-3.3/120-MIPS-ath79-sort-case-statements-in-ath79_detect_sys_.patch b/target/linux/ar71xx/patches-3.3/120-MIPS-ath79-sort-case-statements-in-ath79_detect_sys_.patch new file mode 100644 index 000000000..afbb04e4f --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/120-MIPS-ath79-sort-case-statements-in-ath79_detect_sys_.patch @@ -0,0 +1,58 @@ +From ccb089bbbe49949063cc348743605b3d813ca1c0 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:45:20 +0100 +Subject: [PATCH 25/47] MIPS: ath79: sort case statements in ath79_detect_sys_type + +Sort the case statements alphabetically in order to improve +readability. + +Signed-off-by: Gabor Juhos +Acked-by: Luis R. Rodriguez +Cc: linux-mips@linux-mips.org +Cc: mcgrof@infradead.org +Patchwork: https://patchwork.linux-mips.org/patch/3505/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/setup.c | 24 ++++++++++++------------ + 1 files changed, 12 insertions(+), 12 deletions(-) + +--- a/arch/mips/ath79/setup.c ++++ b/arch/mips/ath79/setup.c +@@ -116,18 +116,6 @@ static void __init ath79_detect_sys_type + rev = id & AR724X_REV_ID_REVISION_MASK; + break; + +- case REV_ID_MAJOR_AR9330: +- ath79_soc = ATH79_SOC_AR9330; +- chip = "9330"; +- rev = id & AR933X_REV_ID_REVISION_MASK; +- break; +- +- case REV_ID_MAJOR_AR9331: +- ath79_soc = ATH79_SOC_AR9331; +- chip = "9331"; +- rev = id & AR933X_REV_ID_REVISION_MASK; +- break; +- + case REV_ID_MAJOR_AR913X: + minor = id & AR913X_REV_ID_MINOR_MASK; + rev = id >> AR913X_REV_ID_REVISION_SHIFT; +@@ -145,6 +133,18 @@ static void __init ath79_detect_sys_type + } + break; + ++ case REV_ID_MAJOR_AR9330: ++ ath79_soc = ATH79_SOC_AR9330; ++ chip = "9330"; ++ rev = id & AR933X_REV_ID_REVISION_MASK; ++ break; ++ ++ case REV_ID_MAJOR_AR9331: ++ ath79_soc = ATH79_SOC_AR9331; ++ chip = "9331"; ++ rev = id & AR933X_REV_ID_REVISION_MASK; ++ break; ++ + default: + panic("ath79: unknown SoC, id:0x%08x", id); + } diff --git a/target/linux/ar71xx/patches-3.3/121-MIPS-ath79-add-SoC-detection-code-for-AR934X.patch b/target/linux/ar71xx/patches-3.3/121-MIPS-ath79-add-SoC-detection-code-for-AR934X.patch new file mode 100644 index 000000000..59bb3d8c5 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/121-MIPS-ath79-add-SoC-detection-code-for-AR934X.patch @@ -0,0 +1,124 @@ +From bf5cb424312f28e51803286a53cb8613bedc5bc8 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:45:21 +0100 +Subject: [PATCH 26/47] MIPS: ath79: add SoC detection code for AR934X + +Also add 'soc_is_ar934[124x]' helper functions and a Kconfig +symbol for the AR934X SoCs. + +Signed-off-by: Gabor Juhos +Acked-by: Luis R. Rodriguez +Cc: linux-mips@linux-mips.org +Cc: mcgrof@infradead.org +Patchwork: https://patchwork.linux-mips.org/patch/3506/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/Kconfig | 4 ++++ + arch/mips/ath79/setup.c | 21 ++++++++++++++++++++- + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 2 ++ + arch/mips/include/asm/mach-ath79/ath79.h | 23 +++++++++++++++++++++++ + 4 files changed, 49 insertions(+), 1 deletions(-) + +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -69,6 +69,10 @@ config SOC_AR933X + select USB_ARCH_HAS_EHCI + def_bool n + ++config SOC_AR934X ++ select USB_ARCH_HAS_EHCI ++ def_bool n ++ + config ATH79_DEV_GPIO_BUTTONS + def_bool n + +--- a/arch/mips/ath79/setup.c ++++ b/arch/mips/ath79/setup.c +@@ -1,10 +1,11 @@ + /* + * Atheros AR71XX/AR724X/AR913X specific setup + * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2008-2011 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * +- * Parts of this file are based on Atheros' 2.6.15 BSP ++ * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published +@@ -145,6 +146,24 @@ static void __init ath79_detect_sys_type + rev = id & AR933X_REV_ID_REVISION_MASK; + break; + ++ case REV_ID_MAJOR_AR9341: ++ ath79_soc = ATH79_SOC_AR9341; ++ chip = "9341"; ++ rev = id & AR934X_REV_ID_REVISION_MASK; ++ break; ++ ++ case REV_ID_MAJOR_AR9342: ++ ath79_soc = ATH79_SOC_AR9342; ++ chip = "9342"; ++ rev = id & AR934X_REV_ID_REVISION_MASK; ++ break; ++ ++ case REV_ID_MAJOR_AR9344: ++ ath79_soc = ATH79_SOC_AR9344; ++ chip = "9344"; ++ rev = id & AR934X_REV_ID_REVISION_MASK; ++ break; ++ + default: + panic("ath79: unknown SoC, id:0x%08x", id); + } +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -271,6 +271,8 @@ + + #define AR724X_REV_ID_REVISION_MASK 0x3 + ++#define AR934X_REV_ID_REVISION_MASK 0xf ++ + /* + * SPI block + */ +--- a/arch/mips/include/asm/mach-ath79/ath79.h ++++ b/arch/mips/include/asm/mach-ath79/ath79.h +@@ -29,6 +29,9 @@ enum ath79_soc_type { + ATH79_SOC_AR9132, + ATH79_SOC_AR9330, + ATH79_SOC_AR9331, ++ ATH79_SOC_AR9341, ++ ATH79_SOC_AR9342, ++ ATH79_SOC_AR9344, + }; + + extern enum ath79_soc_type ath79_soc; +@@ -75,6 +78,26 @@ static inline int soc_is_ar933x(void) + ath79_soc == ATH79_SOC_AR9331); + } + ++static inline int soc_is_ar9341(void) ++{ ++ return (ath79_soc == ATH79_SOC_AR9341); ++} ++ ++static inline int soc_is_ar9342(void) ++{ ++ return (ath79_soc == ATH79_SOC_AR9342); ++} ++ ++static inline int soc_is_ar9344(void) ++{ ++ return (ath79_soc == ATH79_SOC_AR9344); ++} ++ ++static inline int soc_is_ar934x(void) ++{ ++ return soc_is_ar9341() || soc_is_ar9342() || soc_is_ar9344(); ++} ++ + extern void __iomem *ath79_ddr_base; + extern void __iomem *ath79_pll_base; + extern void __iomem *ath79_reset_base; diff --git a/target/linux/ar71xx/patches-3.3/122-MIPS-ath79-add-clock-initialization-code-for-AR934X.patch b/target/linux/ar71xx/patches-3.3/122-MIPS-ath79-add-clock-initialization-code-for-AR934X.patch new file mode 100644 index 000000000..39e161cc2 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/122-MIPS-ath79-add-clock-initialization-code-for-AR934X.patch @@ -0,0 +1,198 @@ +From e9706fc0a97feb7992a98806b69a1fc1fcb910c7 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:45:22 +0100 +Subject: [PATCH 27/47] MIPS: ath79: add clock initialization code for AR934X + +Signed-off-by: Gabor Juhos +Acked-by: Luis R. Rodriguez +Cc: linux-mips@linux-mips.org +Cc: mcgrof@infradead.org +Patchwork: https://patchwork.linux-mips.org/patch/3507/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/clock.c | 81 ++++++++++++++++++++++++ + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 53 +++++++++++++++ + 2 files changed, 134 insertions(+), 0 deletions(-) + +--- a/arch/mips/ath79/clock.c ++++ b/arch/mips/ath79/clock.c +@@ -1,8 +1,11 @@ + /* + * Atheros AR71XX/AR724X/AR913X common routines + * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2011 Gabor Juhos + * ++ * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP ++ * + * This program 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. +@@ -163,6 +166,82 @@ static void __init ar933x_clocks_init(vo + ath79_uart_clk.rate = ath79_ref_clk.rate; + } + ++static void __init ar934x_clocks_init(void) ++{ ++ u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; ++ u32 cpu_pll, ddr_pll; ++ u32 bootstrap; ++ ++ bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); ++ if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) ++ ath79_ref_clk.rate = 40 * 1000 * 1000; ++ else ++ ath79_ref_clk.rate = 25 * 1000 * 1000; ++ ++ pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG); ++ out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & ++ AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; ++ ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & ++ AR934X_PLL_CPU_CONFIG_REFDIV_MASK; ++ nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & ++ AR934X_PLL_CPU_CONFIG_NINT_MASK; ++ frac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & ++ AR934X_PLL_CPU_CONFIG_NFRAC_MASK; ++ ++ cpu_pll = nint * ath79_ref_clk.rate / ref_div; ++ cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 6)); ++ cpu_pll /= (1 << out_div); ++ ++ pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG); ++ out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & ++ AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; ++ ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & ++ AR934X_PLL_DDR_CONFIG_REFDIV_MASK; ++ nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & ++ AR934X_PLL_DDR_CONFIG_NINT_MASK; ++ frac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & ++ AR934X_PLL_DDR_CONFIG_NFRAC_MASK; ++ ++ ddr_pll = nint * ath79_ref_clk.rate / ref_div; ++ ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 10)); ++ ddr_pll /= (1 << out_div); ++ ++ clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG); ++ ++ postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) & ++ AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; ++ ++ if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS) ++ ath79_cpu_clk.rate = ath79_ref_clk.rate; ++ else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL) ++ ath79_cpu_clk.rate = cpu_pll / (postdiv + 1); ++ else ++ ath79_cpu_clk.rate = ddr_pll / (postdiv + 1); ++ ++ postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) & ++ AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK; ++ ++ if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS) ++ ath79_ddr_clk.rate = ath79_ref_clk.rate; ++ else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL) ++ ath79_ddr_clk.rate = ddr_pll / (postdiv + 1); ++ else ++ ath79_ddr_clk.rate = cpu_pll / (postdiv + 1); ++ ++ postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) & ++ AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK; ++ ++ if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS) ++ ath79_ahb_clk.rate = ath79_ref_clk.rate; ++ else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL) ++ ath79_ahb_clk.rate = ddr_pll / (postdiv + 1); ++ else ++ ath79_ahb_clk.rate = cpu_pll / (postdiv + 1); ++ ++ ath79_wdt_clk.rate = ath79_ref_clk.rate; ++ ath79_uart_clk.rate = ath79_ref_clk.rate; ++} ++ + void __init ath79_clocks_init(void) + { + if (soc_is_ar71xx()) +@@ -173,6 +252,8 @@ void __init ath79_clocks_init(void) + ar913x_clocks_init(); + else if (soc_is_ar933x()) + ar933x_clocks_init(); ++ else if (soc_is_ar934x()) ++ ar934x_clocks_init(); + else + BUG(); + +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -151,6 +151,41 @@ + #define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15 + #define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7 + ++#define AR934X_PLL_CPU_CONFIG_REG 0x00 ++#define AR934X_PLL_DDR_CONFIG_REG 0x04 ++#define AR934X_PLL_CPU_DDR_CLK_CTRL_REG 0x08 ++ ++#define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT 0 ++#define AR934X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f ++#define AR934X_PLL_CPU_CONFIG_NINT_SHIFT 6 ++#define AR934X_PLL_CPU_CONFIG_NINT_MASK 0x3f ++#define AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT 12 ++#define AR934X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f ++#define AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19 ++#define AR934X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3 ++ ++#define AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT 0 ++#define AR934X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff ++#define AR934X_PLL_DDR_CONFIG_NINT_SHIFT 10 ++#define AR934X_PLL_DDR_CONFIG_NINT_MASK 0x3f ++#define AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT 16 ++#define AR934X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f ++#define AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23 ++#define AR934X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7 ++ ++#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS BIT(2) ++#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS BIT(3) ++#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS BIT(4) ++#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT 5 ++#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK 0x1f ++#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT 10 ++#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK 0x1f ++#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT 15 ++#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK 0x1f ++#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20) ++#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) ++#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) ++ + /* + * USB_CONFIG block + */ +@@ -186,6 +221,8 @@ + #define AR933X_RESET_REG_RESET_MODULE 0x1c + #define AR933X_RESET_REG_BOOTSTRAP 0xac + ++#define AR934X_RESET_REG_BOOTSTRAP 0xb0 ++ + #define MISC_INT_ETHSW BIT(12) + #define MISC_INT_TIMER4 BIT(10) + #define MISC_INT_TIMER3 BIT(9) +@@ -242,6 +279,22 @@ + + #define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) + ++#define AR934X_BOOTSTRAP_SW_OPTION8 BIT(23) ++#define AR934X_BOOTSTRAP_SW_OPTION7 BIT(22) ++#define AR934X_BOOTSTRAP_SW_OPTION6 BIT(21) ++#define AR934X_BOOTSTRAP_SW_OPTION5 BIT(20) ++#define AR934X_BOOTSTRAP_SW_OPTION4 BIT(19) ++#define AR934X_BOOTSTRAP_SW_OPTION3 BIT(18) ++#define AR934X_BOOTSTRAP_SW_OPTION2 BIT(17) ++#define AR934X_BOOTSTRAP_SW_OPTION1 BIT(16) ++#define AR934X_BOOTSTRAP_USB_MODE_DEVICE BIT(7) ++#define AR934X_BOOTSTRAP_PCIE_RC BIT(6) ++#define AR934X_BOOTSTRAP_EJTAG_MODE BIT(5) ++#define AR934X_BOOTSTRAP_REF_CLK_40 BIT(4) ++#define AR934X_BOOTSTRAP_BOOT_FROM_SPI BIT(2) ++#define AR934X_BOOTSTRAP_SDRAM_DISABLED BIT(1) ++#define AR934X_BOOTSTRAP_DDR1 BIT(0) ++ + #define REV_ID_MAJOR_MASK 0xfff0 + #define REV_ID_MAJOR_AR71XX 0x00a0 + #define REV_ID_MAJOR_AR913X 0x00b0 diff --git a/target/linux/ar71xx/patches-3.3/123-MIPS-ath79-add-GPIO-support-code-for-AR934X.patch b/target/linux/ar71xx/patches-3.3/123-MIPS-ath79-add-GPIO-support-code-for-AR934X.patch new file mode 100644 index 000000000..77c8d5a57 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/123-MIPS-ath79-add-GPIO-support-code-for-AR934X.patch @@ -0,0 +1,102 @@ +From 77bb01d1919bcb6787d5cde9056936420288ab34 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:45:23 +0100 +Subject: [PATCH 28/47] MIPS: ath79: add GPIO support code for AR934X + +Signed-off-by: Gabor Juhos +Acked-by: Luis R. Rodriguez +Cc: linux-mips@linux-mips.org +Cc: mcgrof@infradead.org +Patchwork: https://patchwork.linux-mips.org/patch/3508/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/gpio.c | 47 +++++++++++++++++++++++- + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 1 + + 2 files changed, 47 insertions(+), 1 deletions(-) + +--- a/arch/mips/ath79/gpio.c ++++ b/arch/mips/ath79/gpio.c +@@ -1,9 +1,12 @@ + /* + * Atheros AR71XX/AR724X/AR913X GPIO API support + * +- * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * Copyright (C) 2008-2011 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * ++ * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP ++ * + * This program 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. +@@ -89,6 +92,42 @@ static int ath79_gpio_direction_output(s + return 0; + } + ++static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset) ++{ ++ void __iomem *base = ath79_gpio_base; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ath79_gpio_lock, flags); ++ ++ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset), ++ base + AR71XX_GPIO_REG_OE); ++ ++ spin_unlock_irqrestore(&ath79_gpio_lock, flags); ++ ++ return 0; ++} ++ ++static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset, ++ int value) ++{ ++ void __iomem *base = ath79_gpio_base; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ath79_gpio_lock, flags); ++ ++ if (value) ++ __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET); ++ else ++ __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR); ++ ++ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset), ++ base + AR71XX_GPIO_REG_OE); ++ ++ spin_unlock_irqrestore(&ath79_gpio_lock, flags); ++ ++ return 0; ++} ++ + static struct gpio_chip ath79_gpio_chip = { + .label = "ath79", + .get = ath79_gpio_get_value, +@@ -155,11 +194,17 @@ void __init ath79_gpio_init(void) + ath79_gpio_count = AR913X_GPIO_COUNT; + else if (soc_is_ar933x()) + ath79_gpio_count = AR933X_GPIO_COUNT; ++ else if (soc_is_ar934x()) ++ ath79_gpio_count = AR934X_GPIO_COUNT; + else + BUG(); + + ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); + ath79_gpio_chip.ngpio = ath79_gpio_count; ++ if (soc_is_ar934x()) { ++ ath79_gpio_chip.direction_input = ar934x_gpio_direction_input; ++ ath79_gpio_chip.direction_output = ar934x_gpio_direction_output; ++ } + + err = gpiochip_add(&ath79_gpio_chip); + if (err) +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -367,5 +367,6 @@ + #define AR724X_GPIO_COUNT 18 + #define AR913X_GPIO_COUNT 22 + #define AR933X_GPIO_COUNT 30 ++#define AR934X_GPIO_COUNT 23 + + #endif /* __ASM_MACH_AR71XX_REGS_H */ diff --git a/target/linux/ar71xx/patches-3.3/124-MIPS-ath79-rework-IP2-IP3-interrupt-handling.patch b/target/linux/ar71xx/patches-3.3/124-MIPS-ath79-rework-IP2-IP3-interrupt-handling.patch new file mode 100644 index 000000000..0f30d3836 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/124-MIPS-ath79-rework-IP2-IP3-interrupt-handling.patch @@ -0,0 +1,158 @@ +From f44c70eb5368c0742a8f401ccf39f2ba7252f5a7 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:45:24 +0100 +Subject: [PATCH 29/47] MIPS: ath79: rework IP2/IP3 interrupt handling + +The current implementation assumes that flushing the +DDR writeback buffer is required for IP2/IP3 interrupts, +however this is not true for all SoCs. + +Use SoC specific IP2/IP3 handlers instead of flushing +the buffers in the dispatcher code. + +Signed-off-by: Gabor Juhos +Acked-by: Luis R. Rodriguez +Cc: linux-mips@linux-mips.org +Cc: mcgrof@infradead.org +Patchwork: https://patchwork.linux-mips.org/patch/3509/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/irq.c | 92 ++++++++++++++++++++++++++++++++++++++----------- + 1 files changed, 72 insertions(+), 20 deletions(-) + +--- a/arch/mips/ath79/irq.c ++++ b/arch/mips/ath79/irq.c +@@ -1,7 +1,7 @@ + /* + * Atheros AR71xx/AR724x/AR913x specific interrupt handling + * +- * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2008-2011 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * Parts of this file are based on Atheros' 2.6.15 BSP +@@ -23,8 +23,8 @@ + #include + #include "common.h" + +-static unsigned int ath79_ip2_flush_reg; +-static unsigned int ath79_ip3_flush_reg; ++static void (*ath79_ip2_handler)(void); ++static void (*ath79_ip3_handler)(void); + + static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) + { +@@ -152,10 +152,8 @@ asmlinkage void plat_irq_dispatch(void) + if (pending & STATUSF_IP7) + do_IRQ(ATH79_CPU_IRQ_TIMER); + +- else if (pending & STATUSF_IP2) { +- ath79_ddr_wb_flush(ath79_ip2_flush_reg); +- do_IRQ(ATH79_CPU_IRQ_IP2); +- } ++ else if (pending & STATUSF_IP2) ++ ath79_ip2_handler(); + + else if (pending & STATUSF_IP4) + do_IRQ(ATH79_CPU_IRQ_GE0); +@@ -163,10 +161,8 @@ asmlinkage void plat_irq_dispatch(void) + else if (pending & STATUSF_IP5) + do_IRQ(ATH79_CPU_IRQ_GE1); + +- else if (pending & STATUSF_IP3) { +- ath79_ddr_wb_flush(ath79_ip3_flush_reg); +- do_IRQ(ATH79_CPU_IRQ_USB); +- } ++ else if (pending & STATUSF_IP3) ++ ath79_ip3_handler(); + + else if (pending & STATUSF_IP6) + do_IRQ(ATH79_CPU_IRQ_MISC); +@@ -175,22 +171,78 @@ asmlinkage void plat_irq_dispatch(void) + spurious_interrupt(); + } + ++/* ++ * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for ++ * these devices typically allocate coherent DMA memory, however the ++ * DMA controller may still have some unsynchronized data in the FIFO. ++ * Issue a flush in the handlers to ensure that the driver sees ++ * the update. ++ */ ++static void ar71xx_ip2_handler(void) ++{ ++ ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI); ++ do_IRQ(ATH79_CPU_IRQ_IP2); ++} ++ ++static void ar724x_ip2_handler(void) ++{ ++ ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_PCIE); ++ do_IRQ(ATH79_CPU_IRQ_IP2); ++} ++ ++static void ar913x_ip2_handler(void) ++{ ++ ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_WMAC); ++ do_IRQ(ATH79_CPU_IRQ_IP2); ++} ++ ++static void ar933x_ip2_handler(void) ++{ ++ ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_WMAC); ++ do_IRQ(ATH79_CPU_IRQ_IP2); ++} ++ ++static void ar71xx_ip3_handler(void) ++{ ++ ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB); ++ do_IRQ(ATH79_CPU_IRQ_USB); ++} ++ ++static void ar724x_ip3_handler(void) ++{ ++ ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_USB); ++ do_IRQ(ATH79_CPU_IRQ_USB); ++} ++ ++static void ar913x_ip3_handler(void) ++{ ++ ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_USB); ++ do_IRQ(ATH79_CPU_IRQ_USB); ++} ++ ++static void ar933x_ip3_handler(void) ++{ ++ ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_USB); ++ do_IRQ(ATH79_CPU_IRQ_USB); ++} ++ + void __init arch_init_irq(void) + { + if (soc_is_ar71xx()) { +- ath79_ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI; +- ath79_ip3_flush_reg = AR71XX_DDR_REG_FLUSH_USB; ++ ath79_ip2_handler = ar71xx_ip2_handler; ++ ath79_ip3_handler = ar71xx_ip3_handler; + } else if (soc_is_ar724x()) { +- ath79_ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE; +- ath79_ip3_flush_reg = AR724X_DDR_REG_FLUSH_USB; ++ ath79_ip2_handler = ar724x_ip2_handler; ++ ath79_ip3_handler = ar724x_ip3_handler; + } else if (soc_is_ar913x()) { +- ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC; +- ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB; ++ ath79_ip2_handler = ar913x_ip2_handler; ++ ath79_ip3_handler = ar913x_ip3_handler; + } else if (soc_is_ar933x()) { +- ath79_ip2_flush_reg = AR933X_DDR_REG_FLUSH_WMAC; +- ath79_ip3_flush_reg = AR933X_DDR_REG_FLUSH_USB; +- } else ++ ath79_ip2_handler = ar933x_ip2_handler; ++ ath79_ip3_handler = ar933x_ip3_handler; ++ } else { + BUG(); ++ } + + cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC; + mips_cpu_irq_init(); diff --git a/target/linux/ar71xx/patches-3.3/125-MIPS-ath79-add-IRQ-handling-code-for-AR934X.patch b/target/linux/ar71xx/patches-3.3/125-MIPS-ath79-add-IRQ-handling-code-for-AR934X.patch new file mode 100644 index 000000000..126807725 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/125-MIPS-ath79-add-IRQ-handling-code-for-AR934X.patch @@ -0,0 +1,194 @@ +From b16fdecf14d24fe213c81409c0c2dca66d5b7bc9 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:45:25 +0100 +Subject: [PATCH 30/47] MIPS: ath79: add IRQ handling code for AR934X + +Signed-off-by: Gabor Juhos +Acked-by: Luis R. Rodriguez +Cc: linux-mips@linux-mips.org +Cc: mcgrof@infradead.org +Patchwork: https://patchwork.linux-mips.org/patch/3510/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/irq.c | 55 +++++++++++++++++++++++- + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 25 +++++++++++ + arch/mips/include/asm/mach-ath79/irq.h | 6 ++- + 3 files changed, 83 insertions(+), 3 deletions(-) + +--- a/arch/mips/ath79/irq.c ++++ b/arch/mips/ath79/irq.c +@@ -1,10 +1,11 @@ + /* + * Atheros AR71xx/AR724x/AR913x specific interrupt handling + * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2008-2011 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * +- * Parts of this file are based on Atheros' 2.6.15 BSP ++ * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published +@@ -129,7 +130,7 @@ static void __init ath79_misc_irq_init(v + + if (soc_is_ar71xx() || soc_is_ar913x()) + ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; +- else if (soc_is_ar724x() || soc_is_ar933x()) ++ else if (soc_is_ar724x() || soc_is_ar933x() || soc_is_ar934x()) + ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; + else + BUG(); +@@ -143,6 +144,39 @@ static void __init ath79_misc_irq_init(v + irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler); + } + ++static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) ++{ ++ u32 status; ++ ++ disable_irq_nosync(irq); ++ ++ status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS); ++ ++ if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) { ++ ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_PCIE); ++ generic_handle_irq(ATH79_IP2_IRQ(0)); ++ } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) { ++ ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_WMAC); ++ generic_handle_irq(ATH79_IP2_IRQ(1)); ++ } else { ++ spurious_interrupt(); ++ } ++ ++ enable_irq(irq); ++} ++ ++static void ar934x_ip2_irq_init(void) ++{ ++ int i; ++ ++ for (i = ATH79_IP2_IRQ_BASE; ++ i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) ++ irq_set_chip_and_handler(i, &dummy_irq_chip, ++ handle_level_irq); ++ ++ irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar934x_ip2_irq_dispatch); ++} ++ + asmlinkage void plat_irq_dispatch(void) + { + unsigned long pending; +@@ -202,6 +236,11 @@ static void ar933x_ip2_handler(void) + do_IRQ(ATH79_CPU_IRQ_IP2); + } + ++static void ar934x_ip2_handler(void) ++{ ++ do_IRQ(ATH79_CPU_IRQ_IP2); ++} ++ + static void ar71xx_ip3_handler(void) + { + ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB); +@@ -226,6 +265,12 @@ static void ar933x_ip3_handler(void) + do_IRQ(ATH79_CPU_IRQ_USB); + } + ++static void ar934x_ip3_handler(void) ++{ ++ ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_USB); ++ do_IRQ(ATH79_CPU_IRQ_USB); ++} ++ + void __init arch_init_irq(void) + { + if (soc_is_ar71xx()) { +@@ -240,6 +285,9 @@ void __init arch_init_irq(void) + } else if (soc_is_ar933x()) { + ath79_ip2_handler = ar933x_ip2_handler; + ath79_ip3_handler = ar933x_ip3_handler; ++ } else if (soc_is_ar934x()) { ++ ath79_ip2_handler = ar934x_ip2_handler; ++ ath79_ip3_handler = ar934x_ip3_handler; + } else { + BUG(); + } +@@ -247,4 +295,7 @@ void __init arch_init_irq(void) + cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC; + mips_cpu_irq_init(); + ath79_misc_irq_init(); ++ ++ if (soc_is_ar934x()) ++ ar934x_ip2_irq_init(); + } +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -92,6 +92,12 @@ + #define AR933X_DDR_REG_FLUSH_USB 0x84 + #define AR933X_DDR_REG_FLUSH_WMAC 0x88 + ++#define AR934X_DDR_REG_FLUSH_GE0 0x9c ++#define AR934X_DDR_REG_FLUSH_GE1 0xa0 ++#define AR934X_DDR_REG_FLUSH_USB 0xa4 ++#define AR934X_DDR_REG_FLUSH_PCIE 0xa8 ++#define AR934X_DDR_REG_FLUSH_WMAC 0xac ++ + /* + * PLL block + */ +@@ -222,6 +228,7 @@ + #define AR933X_RESET_REG_BOOTSTRAP 0xac + + #define AR934X_RESET_REG_BOOTSTRAP 0xb0 ++#define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac + + #define MISC_INT_ETHSW BIT(12) + #define MISC_INT_TIMER4 BIT(10) +@@ -295,6 +302,24 @@ + #define AR934X_BOOTSTRAP_SDRAM_DISABLED BIT(1) + #define AR934X_BOOTSTRAP_DDR1 BIT(0) + ++#define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0) ++#define AR934X_PCIE_WMAC_INT_WMAC_TX BIT(1) ++#define AR934X_PCIE_WMAC_INT_WMAC_RXLP BIT(2) ++#define AR934X_PCIE_WMAC_INT_WMAC_RXHP BIT(3) ++#define AR934X_PCIE_WMAC_INT_PCIE_RC BIT(4) ++#define AR934X_PCIE_WMAC_INT_PCIE_RC0 BIT(5) ++#define AR934X_PCIE_WMAC_INT_PCIE_RC1 BIT(6) ++#define AR934X_PCIE_WMAC_INT_PCIE_RC2 BIT(7) ++#define AR934X_PCIE_WMAC_INT_PCIE_RC3 BIT(8) ++#define AR934X_PCIE_WMAC_INT_WMAC_ALL \ ++ (AR934X_PCIE_WMAC_INT_WMAC_MISC | AR934X_PCIE_WMAC_INT_WMAC_TX | \ ++ AR934X_PCIE_WMAC_INT_WMAC_RXLP | AR934X_PCIE_WMAC_INT_WMAC_RXHP) ++ ++#define AR934X_PCIE_WMAC_INT_PCIE_ALL \ ++ (AR934X_PCIE_WMAC_INT_PCIE_RC | AR934X_PCIE_WMAC_INT_PCIE_RC0 | \ ++ AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \ ++ AR934X_PCIE_WMAC_INT_PCIE_RC3) ++ + #define REV_ID_MAJOR_MASK 0xfff0 + #define REV_ID_MAJOR_AR71XX 0x00a0 + #define REV_ID_MAJOR_AR913X 0x00b0 +--- a/arch/mips/include/asm/mach-ath79/irq.h ++++ b/arch/mips/include/asm/mach-ath79/irq.h +@@ -10,7 +10,7 @@ + #define __ASM_MACH_ATH79_IRQ_H + + #define MIPS_CPU_IRQ_BASE 0 +-#define NR_IRQS 46 ++#define NR_IRQS 48 + + #define ATH79_MISC_IRQ_BASE 8 + #define ATH79_MISC_IRQ_COUNT 32 +@@ -19,6 +19,10 @@ + #define ATH79_PCI_IRQ_COUNT 6 + #define ATH79_PCI_IRQ(_x) (ATH79_PCI_IRQ_BASE + (_x)) + ++#define ATH79_IP2_IRQ_BASE (ATH79_PCI_IRQ_BASE + ATH79_PCI_IRQ_COUNT) ++#define ATH79_IP2_IRQ_COUNT 2 ++#define ATH79_IP2_IRQ(_x) (ATH79_IP2_IRQ_BASE + (_x)) ++ + #define ATH79_CPU_IRQ_IP2 (MIPS_CPU_IRQ_BASE + 2) + #define ATH79_CPU_IRQ_USB (MIPS_CPU_IRQ_BASE + 3) + #define ATH79_CPU_IRQ_GE0 (MIPS_CPU_IRQ_BASE + 4) diff --git a/target/linux/ar71xx/patches-3.3/126-MIPS-ath79-add-AR934X-specific-glue-to-ath79_device_.patch b/target/linux/ar71xx/patches-3.3/126-MIPS-ath79-add-AR934X-specific-glue-to-ath79_device_.patch new file mode 100644 index 000000000..14d4a27d1 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/126-MIPS-ath79-add-AR934X-specific-glue-to-ath79_device_.patch @@ -0,0 +1,60 @@ +From 98bfbb0b3f126d93076377fcd9553a493e45e304 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:45:26 +0100 +Subject: [PATCH 31/47] MIPS: ath79: add AR934X specific glue to ath79_device_reset_{clear,set} + +Signed-off-by: Gabor Juhos +Acked-by: Luis R. Rodriguez +Cc: linux-mips@linux-mips.org +Cc: mcgrof@infradead.org +Patchwork: https://patchwork.linux-mips.org/patch/3511/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/common.c | 9 ++++++++- + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 1 + + 2 files changed, 9 insertions(+), 1 deletions(-) + +--- a/arch/mips/ath79/common.c ++++ b/arch/mips/ath79/common.c +@@ -1,9 +1,12 @@ + /* + * Atheros AR71XX/AR724X/AR913X common routines + * +- * Copyright (C) 2008-2010 Gabor Juhos ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan ++ * Copyright (C) 2008-2011 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * ++ * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP ++ * + * This program 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. +@@ -67,6 +70,8 @@ void ath79_device_reset_set(u32 mask) + reg = AR913X_RESET_REG_RESET_MODULE; + else if (soc_is_ar933x()) + reg = AR933X_RESET_REG_RESET_MODULE; ++ else if (soc_is_ar934x()) ++ reg = AR934X_RESET_REG_RESET_MODULE; + else + BUG(); + +@@ -91,6 +96,8 @@ void ath79_device_reset_clear(u32 mask) + reg = AR913X_RESET_REG_RESET_MODULE; + else if (soc_is_ar933x()) + reg = AR933X_RESET_REG_RESET_MODULE; ++ else if (soc_is_ar934x()) ++ reg = AR934X_RESET_REG_RESET_MODULE; + else + BUG(); + +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -227,6 +227,7 @@ + #define AR933X_RESET_REG_RESET_MODULE 0x1c + #define AR933X_RESET_REG_BOOTSTRAP 0xac + ++#define AR934X_RESET_REG_RESET_MODULE 0x1c + #define AR934X_RESET_REG_BOOTSTRAP 0xb0 + #define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac + diff --git a/target/linux/ar71xx/patches-3.3/127-MIPS-ath79-register-UART-device-for-AR934X-SoCs.patch b/target/linux/ar71xx/patches-3.3/127-MIPS-ath79-register-UART-device-for-AR934X-SoCs.patch new file mode 100644 index 000000000..2c7eecabf --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/127-MIPS-ath79-register-UART-device-for-AR934X-SoCs.patch @@ -0,0 +1,27 @@ +From 2d4ed1c7405d05da812b67830eaac15f43b862b7 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:45:27 +0100 +Subject: [PATCH 32/47] MIPS: ath79: register UART device for AR934X SoCs + +Signed-off-by: Gabor Juhos +Acked-by: Luis R. Rodriguez +Cc: linux-mips@linux-mips.org +Cc: mcgrof@infradead.org +Patchwork: https://patchwork.linux-mips.org/patch/3512/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/dev-common.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +--- a/arch/mips/ath79/dev-common.c ++++ b/arch/mips/ath79/dev-common.c +@@ -89,7 +89,8 @@ void __init ath79_register_uart(void) + + if (soc_is_ar71xx() || + soc_is_ar724x() || +- soc_is_ar913x()) { ++ soc_is_ar913x() || ++ soc_is_ar934x()) { + ath79_uart_data[0].uartclk = clk_get_rate(clk); + platform_device_register(&ath79_uart_device); + } else if (soc_is_ar933x()) { diff --git a/target/linux/ar71xx/patches-3.3/128-MIPS-ath79-add-WMAC-registration-code-for-AR934X.patch b/target/linux/ar71xx/patches-3.3/128-MIPS-ath79-add-WMAC-registration-code-for-AR934X.patch new file mode 100644 index 000000000..adbe3e4bb --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/128-MIPS-ath79-add-WMAC-registration-code-for-AR934X.patch @@ -0,0 +1,116 @@ +From d677877e2688813e5e0c12d0228a631021ed70c4 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:45:28 +0100 +Subject: [PATCH 33/47] MIPS: ath79: add WMAC registration code for AR934X + +Signed-off-by: Gabor Juhos +Acked-by: Luis R. Rodriguez +Cc: linux-mips@linux-mips.org +Cc: mcgrof@infradead.org +Patchwork: https://patchwork.linux-mips.org/patch/3513/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/Kconfig | 2 +- + arch/mips/ath79/dev-wmac.c | 30 ++++++++++++++++++++++- + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 3 ++ + 3 files changed, 32 insertions(+), 3 deletions(-) + +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -86,7 +86,7 @@ config ATH79_DEV_USB + def_bool n + + config ATH79_DEV_WMAC +- depends on (SOC_AR913X || SOC_AR933X) ++ depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X) + def_bool n + + endif +--- a/arch/mips/ath79/dev-wmac.c ++++ b/arch/mips/ath79/dev-wmac.c +@@ -1,9 +1,12 @@ + /* + * Atheros AR913X/AR933X SoC built-in WMAC device support + * ++ * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2008-2011 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * ++ * Parts of this file are based on Atheros 2.6.15/2.6.31 BSP ++ * + * This program 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. +@@ -26,8 +29,7 @@ static struct resource ath79_wmac_resour + /* .start and .end fields are filled dynamically */ + .flags = IORESOURCE_MEM, + }, { +- .start = ATH79_CPU_IRQ_IP2, +- .end = ATH79_CPU_IRQ_IP2, ++ /* .start and .end fields are filled dynamically */ + .flags = IORESOURCE_IRQ, + }, + }; +@@ -53,6 +55,8 @@ static void __init ar913x_wmac_setup(voi + + ath79_wmac_resources[0].start = AR913X_WMAC_BASE; + ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1; ++ ath79_wmac_resources[1].start = ATH79_CPU_IRQ_IP2; ++ ath79_wmac_resources[1].end = ATH79_CPU_IRQ_IP2; + } + + +@@ -79,6 +83,8 @@ static void __init ar933x_wmac_setup(voi + + ath79_wmac_resources[0].start = AR933X_WMAC_BASE; + ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1; ++ ath79_wmac_resources[1].start = ATH79_CPU_IRQ_IP2; ++ ath79_wmac_resources[1].end = ATH79_CPU_IRQ_IP2; + + t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); + if (t & AR933X_BOOTSTRAP_REF_CLK_40) +@@ -92,12 +98,32 @@ static void __init ar933x_wmac_setup(voi + ath79_wmac_data.external_reset = ar933x_wmac_reset; + } + ++static void ar934x_wmac_setup(void) ++{ ++ u32 t; ++ ++ ath79_wmac_device.name = "ar934x_wmac"; ++ ++ ath79_wmac_resources[0].start = AR934X_WMAC_BASE; ++ ath79_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1; ++ ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); ++ ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); ++ ++ t = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); ++ if (t & AR934X_BOOTSTRAP_REF_CLK_40) ++ ath79_wmac_data.is_clk_25mhz = false; ++ else ++ ath79_wmac_data.is_clk_25mhz = true; ++} ++ + void __init ath79_register_wmac(u8 *cal_data) + { + if (soc_is_ar913x()) + ar913x_wmac_setup(); + else if (soc_is_ar933x()) + ar933x_wmac_setup(); ++ else if (soc_is_ar934x()) ++ ar934x_wmac_setup(); + else + BUG(); + +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -61,6 +61,9 @@ + #define AR933X_EHCI_BASE 0x1b000000 + #define AR933X_EHCI_SIZE 0x1000 + ++#define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) ++#define AR934X_WMAC_SIZE 0x20000 ++ + /* + * DDR_CTRL block + */ diff --git a/target/linux/ar71xx/patches-3.3/129-MIPS-ath79-add-PCI_AR724X-Kconfig-symbol.patch b/target/linux/ar71xx/patches-3.3/129-MIPS-ath79-add-PCI_AR724X-Kconfig-symbol.patch new file mode 100644 index 000000000..27a46e638 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/129-MIPS-ath79-add-PCI_AR724X-Kconfig-symbol.patch @@ -0,0 +1,66 @@ +From 27a5b2948831f4fd8e66e2e1a98b4c23902728cc Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:45:29 +0100 +Subject: [PATCH 34/47] MIPS: ath79: add PCI_AR724X Kconfig symbol + +The AR724X specific PCI code can be used for the +AR934X SoCs, however it can be selected only if +SOC_AR724X is set. + +Introduce a new Kconfig symbol in order to be able +to use the code for AR934X as well. + +Signed-off-by: Gabor Juhos +Acked-by: Luis R. Rodriguez +Cc: linux-mips@linux-mips.org +Cc: mcgrof@infradead.org +Patchwork: https://patchwork.linux-mips.org/patch/3514/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/Kconfig | 4 ++++ + arch/mips/include/asm/mach-ath79/pci.h | 2 +- + arch/mips/pci/Makefile | 2 +- + 3 files changed, 6 insertions(+), 2 deletions(-) + +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -59,6 +59,7 @@ config SOC_AR724X + select USB_ARCH_HAS_EHCI + select USB_ARCH_HAS_OHCI + select HW_HAS_PCI ++ select PCI_AR724X if PCI + def_bool n + + config SOC_AR913X +@@ -73,6 +74,9 @@ config SOC_AR934X + select USB_ARCH_HAS_EHCI + def_bool n + ++config PCI_AR724X ++ def_bool n ++ + config ATH79_DEV_GPIO_BUTTONS + def_bool n + +--- a/arch/mips/include/asm/mach-ath79/pci.h ++++ b/arch/mips/include/asm/mach-ath79/pci.h +@@ -19,7 +19,7 @@ int ar71xx_pcibios_init(void); + static inline int ar71xx_pcibios_init(void) { return 0; } + #endif + +-#if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR724X) ++#if defined(CONFIG_PCI_AR724X) + int ar724x_pcibios_init(int irq); + #else + static inline int ar724x_pcibios_init(int irq) { return 0; } +--- a/arch/mips/pci/Makefile ++++ b/arch/mips/pci/Makefile +@@ -20,7 +20,7 @@ obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o + ops-bcm63xx.o + obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o + obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o +-obj-$(CONFIG_SOC_AR724X) += pci-ar724x.o ++obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o + + # + # These are still pretty much in the old state, watch, go blind. diff --git a/target/linux/ar71xx/patches-3.3/130-MIPS-ath79-add-PCI-registration-code-for-AR934X.patch b/target/linux/ar71xx/patches-3.3/130-MIPS-ath79-add-PCI-registration-code-for-AR934X.patch new file mode 100644 index 000000000..bd9386d8c --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/130-MIPS-ath79-add-PCI-registration-code-for-AR934X.patch @@ -0,0 +1,62 @@ +From 902b348cdddd4c858993e02aced615aa6caf04d0 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 10:45:30 +0100 +Subject: [PATCH 35/47] MIPS: ath79: add PCI registration code for AR934X + +Signed-off-by: Gabor Juhos +Acked-by: Luis R. Rodriguez +Cc: linux-mips@linux-mips.org +Cc: mcgrof@infradead.org +Patchwork: https://patchwork.linux-mips.org/patch/3516/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/Kconfig | 2 ++ + arch/mips/ath79/pci.c | 13 ++++++++++++- + 2 files changed, 14 insertions(+), 1 deletions(-) + +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -72,6 +72,8 @@ config SOC_AR933X + + config SOC_AR934X + select USB_ARCH_HAS_EHCI ++ select HW_HAS_PCI ++ select PCI_AR724X if PCI + def_bool n + + config PCI_AR724X +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -14,6 +14,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -57,7 +58,9 @@ int __init pcibios_map_irq(const struct + if (soc_is_ar71xx()) { + ath79_pci_irq_map = ar71xx_pci_irq_map; + ath79_pci_nr_irqs = ARRAY_SIZE(ar71xx_pci_irq_map); +- } else if (soc_is_ar724x()) { ++ } else if (soc_is_ar724x() || ++ soc_is_ar9342() || ++ soc_is_ar9344()) { + ath79_pci_irq_map = ar724x_pci_irq_map; + ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map); + } else { +@@ -115,5 +118,13 @@ int __init ath79_register_pci(void) + if (soc_is_ar724x()) + return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2); + ++ if (soc_is_ar9342() || soc_is_ar9344()) { ++ u32 bootstrap; ++ ++ bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); ++ if (bootstrap & AR934X_BOOTSTRAP_PCIE_RC) ++ return ar724x_pcibios_init(ATH79_IP2_IRQ(0)); ++ } ++ + return -ENODEV; + } diff --git a/target/linux/ar71xx/patches-3.3/131-MIPS-ath79-add-initial-support-for-the-Atheros-DB120.patch b/target/linux/ar71xx/patches-3.3/131-MIPS-ath79-add-initial-support-for-the-Atheros-DB120.patch new file mode 100644 index 000000000..30c2c1b18 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/131-MIPS-ath79-add-initial-support-for-the-Atheros-DB120.patch @@ -0,0 +1,196 @@ +From 4921cb7d9f6997b6f7aefd37c7cfd50324e8fd75 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 14 Mar 2012 20:39:35 +0100 +Subject: [PATCH 36/47] MIPS: ath79: add initial support for the Atheros DB120 board + +Signed-off-by: Gabor Juhos +Acked-by: Luis R. Rodriguez +Cc: linux-mips@linux-mips.org +Cc: mcgrof@infradead.org +Patchwork: https://patchwork.linux-mips.org/patch/3517/ +Signed-off-by: Ralf Baechle +--- + arch/mips/ath79/Kconfig | 12 ++++ + arch/mips/ath79/Makefile | 1 + + arch/mips/ath79/mach-db120.c | 134 ++++++++++++++++++++++++++++++++++++++++++ + arch/mips/ath79/machtypes.h | 1 + + 4 files changed, 148 insertions(+), 0 deletions(-) + create mode 100644 arch/mips/ath79/mach-db120.c + +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -26,6 +26,18 @@ config ATH79_MACH_AP81 + Say 'Y' here if you want your kernel to support the + Atheros AP81 reference board. + ++config ATH79_MACH_DB120 ++ bool "Atheros DB120 reference board" ++ select SOC_AR934X ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_SPI ++ select ATH79_DEV_USB ++ select ATH79_DEV_WMAC ++ help ++ Say 'Y' here if you want your kernel to support the ++ Atheros DB120 reference board. ++ + config ATH79_MACH_PB44 + bool "Atheros PB44 reference board" + select SOC_AR71XX +--- a/arch/mips/ath79/Makefile ++++ b/arch/mips/ath79/Makefile +@@ -28,5 +28,6 @@ obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wma + # + obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o + obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o ++obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o + obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o + obj-$(CONFIG_ATH79_MACH_UBNT_XM) += mach-ubnt-xm.o +--- /dev/null ++++ b/arch/mips/ath79/mach-db120.c +@@ -0,0 +1,134 @@ ++/* ++ * Atheros DB120 reference board support ++ * ++ * Copyright (c) 2011 Qualcomm Atheros ++ * Copyright (c) 2011 Gabor Juhos ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ */ ++ ++#include ++#include ++ ++#include "machtypes.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" ++#include "dev-spi.h" ++#include "dev-wmac.h" ++#include "pci.h" ++ ++#define DB120_GPIO_LED_WLAN_5G 12 ++#define DB120_GPIO_LED_WLAN_2G 13 ++#define DB120_GPIO_LED_STATUS 14 ++#define DB120_GPIO_LED_WPS 15 ++ ++#define DB120_GPIO_BTN_WPS 16 ++ ++#define DB120_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL) ++ ++#define DB120_WMAC_CALDATA_OFFSET 0x1000 ++#define DB120_PCIE_CALDATA_OFFSET 0x5000 ++ ++static struct gpio_led db120_leds_gpio[] __initdata = { ++ { ++ .name = "db120:green:status", ++ .gpio = DB120_GPIO_LED_STATUS, ++ .active_low = 1, ++ }, ++ { ++ .name = "db120:green:wps", ++ .gpio = DB120_GPIO_LED_WPS, ++ .active_low = 1, ++ }, ++ { ++ .name = "db120:green:wlan-5g", ++ .gpio = DB120_GPIO_LED_WLAN_5G, ++ .active_low = 1, ++ }, ++ { ++ .name = "db120:green:wlan-2g", ++ .gpio = DB120_GPIO_LED_WLAN_2G, ++ .active_low = 1, ++ }, ++}; ++ ++static struct gpio_keys_button db120_gpio_keys[] __initdata = { ++ { ++ .desc = "WPS button", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = DB120_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = DB120_GPIO_BTN_WPS, ++ .active_low = 1, ++ }, ++}; ++ ++static struct spi_board_info db120_spi_info[] = { ++ { ++ .bus_num = 0, ++ .chip_select = 0, ++ .max_speed_hz = 25000000, ++ .modalias = "s25sl064a", ++ } ++}; ++ ++static struct ath79_spi_platform_data db120_spi_data = { ++ .bus_num = 0, ++ .num_chipselect = 1, ++}; ++ ++#ifdef CONFIG_PCI ++static struct ath9k_platform_data db120_ath9k_data; ++ ++static int db120_pci_plat_dev_init(struct pci_dev *dev) ++{ ++ switch (PCI_SLOT(dev->devfn)) { ++ case 0: ++ dev->dev.platform_data = &db120_ath9k_data; ++ break; ++ } ++ ++ return 0; ++} ++ ++static void __init db120_pci_init(u8 *eeprom) ++{ ++ memcpy(db120_ath9k_data.eeprom_data, eeprom, ++ sizeof(db120_ath9k_data.eeprom_data)); ++ ++ ath79_pci_set_plat_dev_init(db120_pci_plat_dev_init); ++ ath79_register_pci(); ++} ++#else ++static inline void db120_pci_init(void) {} ++#endif /* CONFIG_PCI */ ++ ++static void __init db120_setup(void) ++{ ++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); ++ ++ ath79_register_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio), ++ db120_leds_gpio); ++ ath79_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(db120_gpio_keys), ++ db120_gpio_keys); ++ ath79_register_spi(&db120_spi_data, db120_spi_info, ++ ARRAY_SIZE(db120_spi_info)); ++ ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET); ++ db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET); ++} ++ ++MIPS_MACHINE(ATH79_MACH_DB120, "DB120", "Atheros DB120 reference board", ++ db120_setup); +--- a/arch/mips/ath79/machtypes.h ++++ b/arch/mips/ath79/machtypes.h +@@ -18,6 +18,7 @@ enum ath79_mach_type { + ATH79_MACH_GENERIC = 0, + ATH79_MACH_AP121, /* Atheros AP121 reference board */ + ATH79_MACH_AP81, /* Atheros AP81 reference board */ ++ ATH79_MACH_DB120, /* Atheros DB120 reference board */ + ATH79_MACH_PB44, /* Atheros PB44 reference board */ + ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */ + }; diff --git a/target/linux/ar71xx/patches-3.3/132-MIPS-ath79-use-correct-IRQ-number-for-the-OHCI-contr.patch b/target/linux/ar71xx/patches-3.3/132-MIPS-ath79-use-correct-IRQ-number-for-the-OHCI-contr.patch new file mode 100644 index 000000000..07ddb512d --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/132-MIPS-ath79-use-correct-IRQ-number-for-the-OHCI-contr.patch @@ -0,0 +1,37 @@ +From fe0cc1327ddfb69b171102019a8148a9c8b352b8 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 28 Mar 2012 11:00:19 +0200 +Subject: [PATCH 37/47] MIPS: ath79: use correct IRQ number for the OHCI controller on AR7240 + +The currently assigned IRQ number to the OHCI +controller is incorrect for the AR7240 SoC, and +that leads to the following error message from +the OHCI driver: + +ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver +ath79-ohci ath79-ohci: Atheros built-in OHCI controller +ath79-ohci ath79-ohci: new USB bus registered, assigned bus number 1 +ath79-ohci ath79-ohci: irq 14, io mem 0x1b000000 +hub 1-0:1.0: USB hub found +hub 1-0:1.0: 1 port detected +usb 1-1: new full-speed USB device number 2 using ath79-ohci +ath79-ohci ath79-ohci: Unlink after no-IRQ? Controller is probably using the wrong IRQ. + +Fix this by using the correct IRQ number. + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/dev-usb.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +--- a/arch/mips/ath79/dev-usb.c ++++ b/arch/mips/ath79/dev-usb.c +@@ -145,6 +145,8 @@ static void __init ar7240_usb_setup(void + + ath79_ohci_resources[0].start = AR7240_OHCI_BASE; + ath79_ohci_resources[0].end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1; ++ ath79_ohci_resources[1].start = ATH79_CPU_IRQ_USB; ++ ath79_ohci_resources[1].end = ATH79_CPU_IRQ_USB; + platform_device_register(&ath79_ohci_device); + } + diff --git a/target/linux/ar71xx/patches-3.3/133-MIPS-ath79-use-a-helper-function-for-USB-resource-in.patch b/target/linux/ar71xx/patches-3.3/133-MIPS-ath79-use-a-helper-function-for-USB-resource-in.patch new file mode 100644 index 000000000..0def09f13 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/133-MIPS-ath79-use-a-helper-function-for-USB-resource-in.patch @@ -0,0 +1,140 @@ +From 30b15d9a4b05e38ae19e340b63e1a2bca917d557 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 28 Mar 2012 14:15:23 +0200 +Subject: [PATCH 38/47] MIPS: ath79: use a helper function for USB resource initialization + +This improves code readability, and ensures that +all resource fields will be initialized correctly. +Additionally, it helps to reduce the size of the +kernel image by using uninitialized resource +variables. + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/dev-usb.c | 64 +++++++++++++++++++------------------------- + 1 files changed, 28 insertions(+), 36 deletions(-) + +--- a/arch/mips/ath79/dev-usb.c ++++ b/arch/mips/ath79/dev-usb.c +@@ -25,17 +25,7 @@ + #include "common.h" + #include "dev-usb.h" + +-static struct resource ath79_ohci_resources[] = { +- [0] = { +- /* .start and .end fields are filled dynamically */ +- .flags = IORESOURCE_MEM, +- }, +- [1] = { +- .start = ATH79_MISC_IRQ_OHCI, +- .end = ATH79_MISC_IRQ_OHCI, +- .flags = IORESOURCE_IRQ, +- }, +-}; ++static struct resource ath79_ohci_resources[2]; + + static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32); + +@@ -54,17 +44,7 @@ static struct platform_device ath79_ohci + }, + }; + +-static struct resource ath79_ehci_resources[] = { +- [0] = { +- /* .start and .end fields are filled dynamically */ +- .flags = IORESOURCE_MEM, +- }, +- [1] = { +- .start = ATH79_CPU_IRQ_USB, +- .end = ATH79_CPU_IRQ_USB, +- .flags = IORESOURCE_IRQ, +- }, +-}; ++static struct resource ath79_ehci_resources[2]; + + static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32); + +@@ -90,6 +70,20 @@ static struct platform_device ath79_ehci + }, + }; + ++static void __init ath79_usb_init_resource(struct resource res[2], ++ unsigned long base, ++ unsigned long size, ++ int irq) ++{ ++ res[0].flags = IORESOURCE_MEM; ++ res[0].start = base; ++ res[0].end = base + size - 1; ++ ++ res[1].flags = IORESOURCE_IRQ; ++ res[1].start = irq; ++ res[1].end = irq; ++} ++ + #define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \ + AR71XX_RESET_USB_PHY | \ + AR71XX_RESET_USB_OHCI_DLL) +@@ -114,12 +108,12 @@ static void __init ath79_usb_setup(void) + + mdelay(900); + +- ath79_ohci_resources[0].start = AR71XX_OHCI_BASE; +- ath79_ohci_resources[0].end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1; ++ ath79_usb_init_resource(ath79_ohci_resources, AR71XX_OHCI_BASE, ++ AR71XX_OHCI_SIZE, ATH79_MISC_IRQ_OHCI); + platform_device_register(&ath79_ohci_device); + +- ath79_ehci_resources[0].start = AR71XX_EHCI_BASE; +- ath79_ehci_resources[0].end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1; ++ ath79_usb_init_resource(ath79_ehci_resources, AR71XX_EHCI_BASE, ++ AR71XX_EHCI_SIZE, ATH79_CPU_IRQ_USB); + ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v1; + platform_device_register(&ath79_ehci_device); + } +@@ -143,10 +137,8 @@ static void __init ar7240_usb_setup(void + + iounmap(usb_ctrl_base); + +- ath79_ohci_resources[0].start = AR7240_OHCI_BASE; +- ath79_ohci_resources[0].end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1; +- ath79_ohci_resources[1].start = ATH79_CPU_IRQ_USB; +- ath79_ohci_resources[1].end = ATH79_CPU_IRQ_USB; ++ ath79_usb_init_resource(ath79_ohci_resources, AR7240_OHCI_BASE, ++ AR7240_OHCI_SIZE, ATH79_CPU_IRQ_USB); + platform_device_register(&ath79_ohci_device); + } + +@@ -161,8 +153,8 @@ static void __init ar724x_usb_setup(void + ath79_device_reset_clear(AR724X_RESET_USB_PHY); + mdelay(10); + +- ath79_ehci_resources[0].start = AR724X_EHCI_BASE; +- ath79_ehci_resources[0].end = AR724X_EHCI_BASE + AR724X_EHCI_SIZE - 1; ++ ath79_usb_init_resource(ath79_ehci_resources, AR724X_EHCI_BASE, ++ AR724X_EHCI_SIZE, ATH79_CPU_IRQ_USB); + ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; + platform_device_register(&ath79_ehci_device); + } +@@ -178,8 +170,8 @@ static void __init ar913x_usb_setup(void + ath79_device_reset_clear(AR913X_RESET_USB_PHY); + mdelay(10); + +- ath79_ehci_resources[0].start = AR913X_EHCI_BASE; +- ath79_ehci_resources[0].end = AR913X_EHCI_BASE + AR913X_EHCI_SIZE - 1; ++ ath79_usb_init_resource(ath79_ehci_resources, AR913X_EHCI_BASE, ++ AR913X_EHCI_SIZE, ATH79_CPU_IRQ_USB); + ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; + platform_device_register(&ath79_ehci_device); + } +@@ -195,8 +187,8 @@ static void __init ar933x_usb_setup(void + ath79_device_reset_clear(AR933X_RESET_USB_PHY); + mdelay(10); + +- ath79_ehci_resources[0].start = AR933X_EHCI_BASE; +- ath79_ehci_resources[0].end = AR933X_EHCI_BASE + AR933X_EHCI_SIZE - 1; ++ ath79_usb_init_resource(ath79_ehci_resources, AR933X_EHCI_BASE, ++ AR933X_EHCI_SIZE, ATH79_CPU_IRQ_USB); + ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; + platform_device_register(&ath79_ehci_device); + } diff --git a/target/linux/ar71xx/patches-3.3/134-MIPS-ath79-add-USB-platform-setup-code-for-AR934X.patch b/target/linux/ar71xx/patches-3.3/134-MIPS-ath79-add-USB-platform-setup-code-for-AR934X.patch new file mode 100644 index 000000000..c77de2803 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/134-MIPS-ath79-add-USB-platform-setup-code-for-AR934X.patch @@ -0,0 +1,78 @@ +From 635d5a2ac8aa483c3a0635c60bff8ea8978ff6a7 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 11 Dec 2011 18:34:13 +0100 +Subject: [PATCH 39/47] MIPS: ath79: add USB platform setup code for AR934X + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/dev-usb.c | 28 ++++++++++++++++++++++++ + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 7 ++++++ + 2 files changed, 35 insertions(+), 0 deletions(-) + +--- a/arch/mips/ath79/dev-usb.c ++++ b/arch/mips/ath79/dev-usb.c +@@ -193,6 +193,32 @@ static void __init ar933x_usb_setup(void + platform_device_register(&ath79_ehci_device); + } + ++static void __init ar934x_usb_setup(void) ++{ ++ u32 bootstrap; ++ ++ bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); ++ if (bootstrap & AR934X_BOOTSTRAP_USB_MODE_DEVICE) ++ return; ++ ++ ath79_device_reset_set(AR934X_RESET_USBSUS_OVERRIDE); ++ udelay(1000); ++ ++ ath79_device_reset_clear(AR934X_RESET_USB_PHY); ++ udelay(1000); ++ ++ ath79_device_reset_clear(AR934X_RESET_USB_PHY_ANALOG); ++ udelay(1000); ++ ++ ath79_device_reset_clear(AR934X_RESET_USB_HOST); ++ udelay(1000); ++ ++ ath79_usb_init_resource(ath79_ehci_resources, AR934X_EHCI_BASE, ++ AR934X_EHCI_SIZE, ATH79_CPU_IRQ_USB); ++ ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; ++ platform_device_register(&ath79_ehci_device); ++} ++ + void __init ath79_register_usb(void) + { + if (soc_is_ar71xx()) +@@ -205,6 +231,8 @@ void __init ath79_register_usb(void) + ar913x_usb_setup(); + else if (soc_is_ar933x()) + ar933x_usb_setup(); ++ else if (soc_is_ar934x()) ++ ar934x_usb_setup(); + else + BUG(); + } +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -63,6 +63,8 @@ + + #define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) + #define AR934X_WMAC_SIZE 0x20000 ++#define AR934X_EHCI_BASE 0x1b000000 ++#define AR934X_EHCI_SIZE 0x200 + + /* + * DDR_CTRL block +@@ -288,6 +290,11 @@ + #define AR933X_RESET_USB_PHY BIT(4) + #define AR933X_RESET_USBSUS_OVERRIDE BIT(3) + ++#define AR934X_RESET_USB_PHY_ANALOG BIT(11) ++#define AR934X_RESET_USB_HOST BIT(5) ++#define AR934X_RESET_USB_PHY BIT(4) ++#define AR934X_RESET_USBSUS_OVERRIDE BIT(3) ++ + #define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) + + #define AR934X_BOOTSTRAP_SW_OPTION8 BIT(23) diff --git a/target/linux/ar71xx/patches-3.3/135-MIPS-ath79-register-USB-host-controller-on-the-DB120.patch b/target/linux/ar71xx/patches-3.3/135-MIPS-ath79-register-USB-host-controller-on-the-DB120.patch new file mode 100644 index 000000000..e82da3daa --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/135-MIPS-ath79-register-USB-host-controller-on-the-DB120.patch @@ -0,0 +1,28 @@ +From 932c1688e960bff170f1fc8072b3d3e958407a60 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Tue, 13 Mar 2012 13:51:09 +0100 +Subject: [PATCH 40/47] MIPS: ath79: register USB host controller on the DB120 board + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/mach-db120.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +--- a/arch/mips/ath79/mach-db120.c ++++ b/arch/mips/ath79/mach-db120.c +@@ -25,6 +25,7 @@ + #include "dev-gpio-buttons.h" + #include "dev-leds-gpio.h" + #include "dev-spi.h" ++#include "dev-usb.h" + #include "dev-wmac.h" + #include "pci.h" + +@@ -126,6 +127,7 @@ static void __init db120_setup(void) + db120_gpio_keys); + ath79_register_spi(&db120_spi_data, db120_spi_info, + ARRAY_SIZE(db120_spi_info)); ++ ath79_register_usb(); + ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET); + db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET); + } diff --git a/target/linux/ar71xx/patches-3.3/136-MIPS-ath79-use-correct-fractional-dividers-for-CPU-D.patch b/target/linux/ar71xx/patches-3.3/136-MIPS-ath79-use-correct-fractional-dividers-for-CPU-D.patch new file mode 100644 index 000000000..cb6aa3221 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/136-MIPS-ath79-use-correct-fractional-dividers-for-CPU-D.patch @@ -0,0 +1,49 @@ +From 7328ff547389ee0b455cbf98bdfc819731d9f7b9 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Fri, 31 Aug 2012 14:22:35 +0200 +Subject: [PATCH] MIPS: ath79: use correct fractional dividers for + {CPU,DDR}_PLL on AR934x + +The current dividers in the code are wrong and this +leads to broken CPU frequency calculation on boards +where the fractional part is used. + +For example, if the SoC is running from a 40MHz +reference clock, refdiv=1, nint=14, outdiv=0 and +nfrac=31 the real frequency is 579.375MHz but the +current code calculates 569.687MHz instead. + +Because the system time is indirectly related to +the CPU frequency the broken computation causes +drift in the system time. + +The correct divider is 2^6 for the CPU PLL and 2^10 +for the DDR PLL. Use the correct values to fix the +issue. + +Cc: [3.5+] +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/clock.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/mips/ath79/clock.c ++++ b/arch/mips/ath79/clock.c +@@ -189,7 +189,7 @@ static void __init ar934x_clocks_init(vo + AR934X_PLL_CPU_CONFIG_NFRAC_MASK; + + cpu_pll = nint * ath79_ref_clk.rate / ref_div; +- cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 6)); ++ cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 6)); + cpu_pll /= (1 << out_div); + + pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG); +@@ -203,7 +203,7 @@ static void __init ar934x_clocks_init(vo + AR934X_PLL_DDR_CONFIG_NFRAC_MASK; + + ddr_pll = nint * ath79_ref_clk.rate / ref_div; +- ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 10)); ++ ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 10)); + ddr_pll /= (1 << out_div); + + clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG); diff --git a/target/linux/ar71xx/patches-3.3/137-MIPS-ath79-fix-CPU-DDR-frequency-calculation-for-SRI.patch b/target/linux/ar71xx/patches-3.3/137-MIPS-ath79-fix-CPU-DDR-frequency-calculation-for-SRI.patch new file mode 100644 index 000000000..a2fa4db56 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/137-MIPS-ath79-fix-CPU-DDR-frequency-calculation-for-SRI.patch @@ -0,0 +1,205 @@ +From 3f735e202d5099a5b7c621443bea365b87b0e3bb Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sat, 8 Sep 2012 12:12:50 +0200 +Subject: [PATCH] MIPS: ath79: fix CPU/DDR frequency calculation for SRIF PLLs + +Besides the CPU and DDR PLLs, the CPU and DDR frequencies +can be derived from other PLLs in the SRIF block on the +AR934x SoCs. The current code does not checks if the SRIF +PLLs are used and this can lead to incorrectly calculated +CPU/DDR frequencies. + +Fix it by calculating the frequencies from SRIF PLLs if +those are used on a given board. + +Cc: +Signed-off-by: Gabor Juhos +--- +This depends on the following patch: +'MIPS: ath79: use correct fractional dividers for {CPU,DDR}_PLL on AR934x' +https://patchwork.linux-mips.org/patch/4305/ + + arch/mips/ath79/clock.c | 109 ++++++++++++++++++------ + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 23 +++++ + 2 files changed, 104 insertions(+), 28 deletions(-) + +--- a/arch/mips/ath79/clock.c ++++ b/arch/mips/ath79/clock.c +@@ -17,6 +17,8 @@ + #include + #include + ++#include ++ + #include + #include + #include "common.h" +@@ -166,11 +168,34 @@ static void __init ar933x_clocks_init(vo + ath79_uart_clk.rate = ath79_ref_clk.rate; + } + ++static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, ++ u32 frac, u32 out_div) ++{ ++ u64 t; ++ u32 ret; ++ ++ t = ath79_ref_clk.rate; ++ t *= nint; ++ do_div(t, ref_div); ++ ret = t; ++ ++ t = ath79_ref_clk.rate; ++ t *= nfrac; ++ do_div(t, ref_div * frac); ++ ret += t; ++ ++ ret /= (1 << out_div); ++ return ret; ++} ++ + static void __init ar934x_clocks_init(void) + { +- u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; ++ u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv; + u32 cpu_pll, ddr_pll; + u32 bootstrap; ++ void __iomem *dpll_base; ++ ++ dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE); + + bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); + if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) +@@ -178,33 +203,59 @@ static void __init ar934x_clocks_init(vo + else + ath79_ref_clk.rate = 25 * 1000 * 1000; + +- pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG); +- out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & +- AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; +- ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & +- AR934X_PLL_CPU_CONFIG_REFDIV_MASK; +- nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & +- AR934X_PLL_CPU_CONFIG_NINT_MASK; +- frac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & +- AR934X_PLL_CPU_CONFIG_NFRAC_MASK; +- +- cpu_pll = nint * ath79_ref_clk.rate / ref_div; +- cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 6)); +- cpu_pll /= (1 << out_div); +- +- pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG); +- out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & +- AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; +- ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & +- AR934X_PLL_DDR_CONFIG_REFDIV_MASK; +- nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & +- AR934X_PLL_DDR_CONFIG_NINT_MASK; +- frac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & +- AR934X_PLL_DDR_CONFIG_NFRAC_MASK; +- +- ddr_pll = nint * ath79_ref_clk.rate / ref_div; +- ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 10)); +- ddr_pll /= (1 << out_div); ++ pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG); ++ if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { ++ out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & ++ AR934X_SRIF_DPLL2_OUTDIV_MASK; ++ pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG); ++ nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & ++ AR934X_SRIF_DPLL1_NINT_MASK; ++ nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; ++ ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & ++ AR934X_SRIF_DPLL1_REFDIV_MASK; ++ frac = 1 << 18; ++ } else { ++ pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG); ++ out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & ++ AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; ++ ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & ++ AR934X_PLL_CPU_CONFIG_REFDIV_MASK; ++ nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & ++ AR934X_PLL_CPU_CONFIG_NINT_MASK; ++ nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & ++ AR934X_PLL_CPU_CONFIG_NFRAC_MASK; ++ frac = 1 << 6; ++ } ++ ++ cpu_pll = ar934x_get_pll_freq(ath79_ref_clk.rate, ref_div, nint, ++ nfrac, frac, out_div); ++ ++ pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG); ++ if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { ++ out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & ++ AR934X_SRIF_DPLL2_OUTDIV_MASK; ++ pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG); ++ nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & ++ AR934X_SRIF_DPLL1_NINT_MASK; ++ nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; ++ ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & ++ AR934X_SRIF_DPLL1_REFDIV_MASK; ++ frac = 1 << 18; ++ } else { ++ pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG); ++ out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & ++ AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; ++ ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & ++ AR934X_PLL_DDR_CONFIG_REFDIV_MASK; ++ nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & ++ AR934X_PLL_DDR_CONFIG_NINT_MASK; ++ nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & ++ AR934X_PLL_DDR_CONFIG_NFRAC_MASK; ++ frac = 1 << 10; ++ } ++ ++ ddr_pll = ar934x_get_pll_freq(ath79_ref_clk.rate, ref_div, nint, ++ nfrac, frac, out_div); + + clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG); + +@@ -240,6 +291,8 @@ static void __init ar934x_clocks_init(vo + + ath79_wdt_clk.rate = ath79_ref_clk.rate; + ath79_uart_clk.rate = ath79_ref_clk.rate; ++ ++ iounmap(dpll_base); + } + + void __init ath79_clocks_init(void) +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -65,6 +65,8 @@ + #define AR934X_WMAC_SIZE 0x20000 + #define AR934X_EHCI_BASE 0x1b000000 + #define AR934X_EHCI_SIZE 0x200 ++#define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000) ++#define AR934X_SRIF_SIZE 0x1000 + + /* + * DDR_CTRL block +@@ -405,4 +407,25 @@ + #define AR933X_GPIO_COUNT 30 + #define AR934X_GPIO_COUNT 23 + ++/* ++ * SRIF block ++ */ ++#define AR934X_SRIF_CPU_DPLL1_REG 0x1c0 ++#define AR934X_SRIF_CPU_DPLL2_REG 0x1c4 ++#define AR934X_SRIF_CPU_DPLL3_REG 0x1c8 ++ ++#define AR934X_SRIF_DDR_DPLL1_REG 0x240 ++#define AR934X_SRIF_DDR_DPLL2_REG 0x244 ++#define AR934X_SRIF_DDR_DPLL3_REG 0x248 ++ ++#define AR934X_SRIF_DPLL1_REFDIV_SHIFT 27 ++#define AR934X_SRIF_DPLL1_REFDIV_MASK 0x1f ++#define AR934X_SRIF_DPLL1_NINT_SHIFT 18 ++#define AR934X_SRIF_DPLL1_NINT_MASK 0x1ff ++#define AR934X_SRIF_DPLL1_NFRAC_MASK 0x0003ffff ++ ++#define AR934X_SRIF_DPLL2_LOCAL_PLL BIT(30) ++#define AR934X_SRIF_DPLL2_OUTDIV_SHIFT 13 ++#define AR934X_SRIF_DPLL2_OUTDIV_MASK 0x7 ++ + #endif /* __ASM_MACH_AR71XX_REGS_H */ diff --git a/target/linux/ar71xx/patches-3.3/140-MIPS-pci-ar724x-avoid-data-bus-error-due-to-a-missin.patch b/target/linux/ar71xx/patches-3.3/140-MIPS-pci-ar724x-avoid-data-bus-error-due-to-a-missin.patch new file mode 100644 index 000000000..a05b1e7a9 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/140-MIPS-pci-ar724x-avoid-data-bus-error-due-to-a-missin.patch @@ -0,0 +1,78 @@ +From 9cfa64ddaba49975b420ce5e5020efc3301061ac Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Tue, 26 Jun 2012 10:19:46 +0200 +Subject: [PATCH 01/34] MIPS: pci-ar724x: avoid data bus error due to a missing PCIe module + +If the controller has no PCIe module attached, +accessing of the device configuration space +causes a data bus error. Avoid this by checking +the status of the PCIe link in advance, and +indicate an error if the link is down. + +Signed-off-by: Gabor Juhos +--- + arch/mips/pci/pci-ar724x.c | 22 ++++++++++++++++++++++ + 1 files changed, 22 insertions(+), 0 deletions(-) + +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -23,9 +23,12 @@ + #define AR724X_PCI_MEM_BASE 0x10000000 + #define AR724X_PCI_MEM_SIZE 0x08000000 + ++#define AR724X_PCI_REG_RESET 0x18 + #define AR724X_PCI_REG_INT_STATUS 0x4c + #define AR724X_PCI_REG_INT_MASK 0x50 + ++#define AR724X_PCI_RESET_LINK_UP BIT(0) ++ + #define AR724X_PCI_INT_DEV0 BIT(14) + + #define AR724X_PCI_IRQ_COUNT 1 +@@ -38,6 +41,15 @@ static void __iomem *ar724x_pci_ctrl_bas + + static u32 ar724x_pci_bar0_value; + static bool ar724x_pci_bar0_is_cached; ++static bool ar724x_pci_link_up; ++ ++static inline bool ar724x_pci_check_link(void) ++{ ++ u32 reset; ++ ++ reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET); ++ return reset & AR724X_PCI_RESET_LINK_UP; ++} + + static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t *value) +@@ -46,6 +58,9 @@ static int ar724x_pci_read(struct pci_bu + void __iomem *base; + u32 data; + ++ if (!ar724x_pci_link_up) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ + if (devfn) + return PCIBIOS_DEVICE_NOT_FOUND; + +@@ -96,6 +111,9 @@ static int ar724x_pci_write(struct pci_b + u32 data; + int s; + ++ if (!ar724x_pci_link_up) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ + if (devfn) + return PCIBIOS_DEVICE_NOT_FOUND; + +@@ -280,6 +298,10 @@ int __init ar724x_pcibios_init(int irq) + if (ar724x_pci_ctrl_base == NULL) + goto err_unmap_devcfg; + ++ ar724x_pci_link_up = ar724x_pci_check_link(); ++ if (!ar724x_pci_link_up) ++ pr_warn("ar724x: PCIe link is down\n"); ++ + ar724x_pci_irq_init(irq); + register_pci_controller(&ar724x_pci_controller); + diff --git a/target/linux/ar71xx/patches-3.3/141-MIPS-pci-ar724x-use-correct-value-for-AR724X_PCI_MEM.patch b/target/linux/ar71xx/patches-3.3/141-MIPS-pci-ar724x-use-correct-value-for-AR724X_PCI_MEM.patch new file mode 100644 index 000000000..d409a7a6a --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/141-MIPS-pci-ar724x-use-correct-value-for-AR724X_PCI_MEM.patch @@ -0,0 +1,24 @@ +From 4b0f8aaea1f9e2f931c4de785d9ce46ff7164627 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 17 Jun 2012 12:55:24 +0200 +Subject: [PATCH 02/34] MIPS: pci-ar724x: use correct value for AR724X_PCI_MEM_SIZE + +The current definiton is wrong, it is conflicting +with AR724X_PCI_CFG_BASE. + +Signed-off-by: Gabor Juhos +--- + arch/mips/pci/pci-ar724x.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -21,7 +21,7 @@ + #define AR724X_PCI_CTRL_SIZE 0x100 + + #define AR724X_PCI_MEM_BASE 0x10000000 +-#define AR724X_PCI_MEM_SIZE 0x08000000 ++#define AR724X_PCI_MEM_SIZE 0x04000000 + + #define AR724X_PCI_REG_RESET 0x18 + #define AR724X_PCI_REG_INT_STATUS 0x4c diff --git a/target/linux/ar71xx/patches-3.3/142-MIPS-pci-ar71xx-fix-AR71XX_PCI_MEM_SIZE.patch b/target/linux/ar71xx/patches-3.3/142-MIPS-pci-ar71xx-fix-AR71XX_PCI_MEM_SIZE.patch new file mode 100644 index 000000000..7fb56f831 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/142-MIPS-pci-ar71xx-fix-AR71XX_PCI_MEM_SIZE.patch @@ -0,0 +1,21 @@ +From 01dbfe17b8ff628b6e2b3c75e1fc8c11d4cca644 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Thu, 28 Jun 2012 19:19:58 +0200 +Subject: [PATCH 03/34] MIPS: pci-ar71xx: fix AR71XX_PCI_MEM_SIZE + +Signed-off-by: Gabor Juhos +--- + arch/mips/pci/pci-ar71xx.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +--- a/arch/mips/pci/pci-ar71xx.c ++++ b/arch/mips/pci/pci-ar71xx.c +@@ -24,7 +24,7 @@ + #include + + #define AR71XX_PCI_MEM_BASE 0x10000000 +-#define AR71XX_PCI_MEM_SIZE 0x08000000 ++#define AR71XX_PCI_MEM_SIZE 0x07000000 + + #define AR71XX_PCI_WIN0_OFFS 0x10000000 + #define AR71XX_PCI_WIN1_OFFS 0x11000000 diff --git a/target/linux/ar71xx/patches-3.3/143-MIPS-pci-ar724x-convert-to-a-platform-driver.patch b/target/linux/ar71xx/patches-3.3/143-MIPS-pci-ar724x-convert-to-a-platform-driver.patch new file mode 100644 index 000000000..fd9868963 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/143-MIPS-pci-ar724x-convert-to-a-platform-driver.patch @@ -0,0 +1,94 @@ +From f2d2d928c3900b67a5f95e53b86de5b61a3ab12c Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 11 Jun 2012 13:19:44 +0200 +Subject: [PATCH 04/34] MIPS: pci-ar724x: convert to a platform driver + +Signed-off-by: Gabor Juhos +--- + arch/mips/pci/pci-ar724x.c | 57 ++++++++++++++++++++++++++++++++++++++++++- + 1 files changed, 55 insertions(+), 2 deletions(-) + +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -11,6 +11,8 @@ + + #include + #include ++#include ++#include + #include + #include + #include +@@ -262,7 +264,7 @@ static struct irq_chip ar724x_pci_irq_ch + .irq_mask_ack = ar724x_pci_irq_mask, + }; + +-static void __init ar724x_pci_irq_init(int irq) ++static void __devinit ar724x_pci_irq_init(int irq) + { + void __iomem *base; + int i; +@@ -282,7 +284,7 @@ static void __init ar724x_pci_irq_init(i + irq_set_chained_handler(irq, ar724x_pci_irq_handler); + } + +-int __init ar724x_pcibios_init(int irq) ++int __devinit ar724x_pcibios_init(int irq) + { + int ret; + +@@ -312,3 +314,54 @@ err_unmap_devcfg: + err: + return ret; + } ++ ++static int __devinit ar724x_pci_probe(struct platform_device *pdev) ++{ ++ struct resource *res; ++ int irq; ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base"); ++ if (!res) ++ return -EINVAL; ++ ++ ar724x_pci_ctrl_base = devm_request_and_ioremap(&pdev->dev, res); ++ if (ar724x_pci_ctrl_base == NULL) ++ return -EBUSY; ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); ++ if (!res) ++ return -EINVAL; ++ ++ ar724x_pci_devcfg_base = devm_request_and_ioremap(&pdev->dev, res); ++ if (!ar724x_pci_devcfg_base) ++ return -EBUSY; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) ++ return -EINVAL; ++ ++ ar724x_pci_link_up = ar724x_pci_check_link(); ++ if (!ar724x_pci_link_up) ++ dev_warn(&pdev->dev, "PCIe link is down\n"); ++ ++ ar724x_pci_irq_init(irq); ++ ++ register_pci_controller(&ar724x_pci_controller); ++ ++ return 0; ++} ++ ++static struct platform_driver ar724x_pci_driver = { ++ .probe = ar724x_pci_probe, ++ .driver = { ++ .name = "ar724x-pci", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init ar724x_pci_init(void) ++{ ++ return platform_driver_register(&ar724x_pci_driver); ++} ++ ++postcore_initcall(ar724x_pci_init); diff --git a/target/linux/ar71xx/patches-3.3/144-MIPS-pci-ar71xx-convert-to-a-platform-driver.patch b/target/linux/ar71xx/patches-3.3/144-MIPS-pci-ar71xx-convert-to-a-platform-driver.patch new file mode 100644 index 000000000..a78469b71 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/144-MIPS-pci-ar71xx-convert-to-a-platform-driver.patch @@ -0,0 +1,104 @@ +From d1a22e73f991145a4abd7d0c37bcf318703c89ed Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 11 Jun 2012 13:24:55 +0200 +Subject: [PATCH 05/34] MIPS: pci-ar71xx: convert to a platform driver + +Signed-off-by: Gabor Juhos +--- + arch/mips/pci/pci-ar71xx.c | 60 +++++++++++++++++++++++++++++++++++++++++--- + 1 files changed, 56 insertions(+), 4 deletions(-) + +--- a/arch/mips/pci/pci-ar71xx.c ++++ b/arch/mips/pci/pci-ar71xx.c +@@ -18,6 +18,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -309,7 +311,7 @@ static struct irq_chip ar71xx_pci_irq_ch + .irq_mask_ack = ar71xx_pci_irq_mask, + }; + +-static __init void ar71xx_pci_irq_init(void) ++static __devinit void ar71xx_pci_irq_init(int irq) + { + void __iomem *base = ath79_reset_base; + int i; +@@ -324,10 +326,10 @@ static __init void ar71xx_pci_irq_init(v + irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip, + handle_level_irq); + +- irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar71xx_pci_irq_handler); ++ irq_set_chained_handler(irq, ar71xx_pci_irq_handler); + } + +-static __init void ar71xx_pci_reset(void) ++static __devinit void ar71xx_pci_reset(void) + { + void __iomem *ddr_base = ath79_ddr_base; + +@@ -367,9 +369,59 @@ __init int ar71xx_pcibios_init(void) + /* clear bus errors */ + ar71xx_pci_check_error(1); + +- ar71xx_pci_irq_init(); ++ ar71xx_pci_irq_init(ATH79_CPU_IRQ_IP2); + + register_pci_controller(&ar71xx_pci_controller); + + return 0; + } ++ ++static int __devinit ar71xx_pci_probe(struct platform_device *pdev) ++{ ++ struct resource *res; ++ int irq; ++ u32 t; ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); ++ if (!res) ++ return -EINVAL; ++ ++ ar71xx_pcicfg_base = devm_request_and_ioremap(&pdev->dev, res); ++ if (!ar71xx_pcicfg_base) ++ return -ENOMEM; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) ++ return -EINVAL; ++ ++ ar71xx_pci_reset(); ++ ++ /* setup COMMAND register */ ++ t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE ++ | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; ++ ar71xx_pci_local_write(PCI_COMMAND, 4, t); ++ ++ /* clear bus errors */ ++ ar71xx_pci_check_error(1); ++ ++ ar71xx_pci_irq_init(irq); ++ ++ register_pci_controller(&ar71xx_pci_controller); ++ ++ return 0; ++} ++ ++static struct platform_driver ar71xx_pci_driver = { ++ .probe = ar71xx_pci_probe, ++ .driver = { ++ .name = "ar71xx-pci", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init ar71xx_pci_init(void) ++{ ++ return platform_driver_register(&ar71xx_pci_driver); ++} ++ ++postcore_initcall(ar71xx_pci_init); diff --git a/target/linux/ar71xx/patches-3.3/145-MIPS-ath79-move-global-PCI-defines-into-a-common-hea.patch b/target/linux/ar71xx/patches-3.3/145-MIPS-ath79-move-global-PCI-defines-into-a-common-hea.patch new file mode 100644 index 000000000..4861db00f --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/145-MIPS-ath79-move-global-PCI-defines-into-a-common-hea.patch @@ -0,0 +1,94 @@ +From c3a8b5fa196cedc4b940c1e5ec482dd875aa3180 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 11 Jun 2012 13:38:06 +0200 +Subject: [PATCH 06/34] MIPS: ath79: move global PCI defines into a common header + +The constants will be used by a subsequent patch. + +Signed-off-by: Gabor Juhos +--- + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 24 ++++++++++++++++++++++++ + arch/mips/pci/pci-ar71xx.c | 16 ---------------- + arch/mips/pci/pci-ar724x.c | 8 -------- + 3 files changed, 24 insertions(+), 24 deletions(-) + +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -41,11 +41,35 @@ + #define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) + #define AR71XX_RESET_SIZE 0x100 + ++#define AR71XX_PCI_MEM_BASE 0x10000000 ++#define AR71XX_PCI_MEM_SIZE 0x07000000 ++ ++#define AR71XX_PCI_WIN0_OFFS 0x10000000 ++#define AR71XX_PCI_WIN1_OFFS 0x11000000 ++#define AR71XX_PCI_WIN2_OFFS 0x12000000 ++#define AR71XX_PCI_WIN3_OFFS 0x13000000 ++#define AR71XX_PCI_WIN4_OFFS 0x14000000 ++#define AR71XX_PCI_WIN5_OFFS 0x15000000 ++#define AR71XX_PCI_WIN6_OFFS 0x16000000 ++#define AR71XX_PCI_WIN7_OFFS 0x07000000 ++ ++#define AR71XX_PCI_CFG_BASE \ ++ (AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x10000) ++#define AR71XX_PCI_CFG_SIZE 0x100 ++ + #define AR7240_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) + #define AR7240_USB_CTRL_SIZE 0x100 + #define AR7240_OHCI_BASE 0x1b000000 + #define AR7240_OHCI_SIZE 0x1000 + ++#define AR724X_PCI_MEM_BASE 0x10000000 ++#define AR724X_PCI_MEM_SIZE 0x04000000 ++ ++#define AR724X_PCI_CFG_BASE 0x14000000 ++#define AR724X_PCI_CFG_SIZE 0x1000 ++#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000) ++#define AR724X_PCI_CTRL_SIZE 0x100 ++ + #define AR724X_EHCI_BASE 0x1b000000 + #define AR724X_EHCI_SIZE 0x1000 + +--- a/arch/mips/pci/pci-ar71xx.c ++++ b/arch/mips/pci/pci-ar71xx.c +@@ -25,22 +25,6 @@ + #include + #include + +-#define AR71XX_PCI_MEM_BASE 0x10000000 +-#define AR71XX_PCI_MEM_SIZE 0x07000000 +- +-#define AR71XX_PCI_WIN0_OFFS 0x10000000 +-#define AR71XX_PCI_WIN1_OFFS 0x11000000 +-#define AR71XX_PCI_WIN2_OFFS 0x12000000 +-#define AR71XX_PCI_WIN3_OFFS 0x13000000 +-#define AR71XX_PCI_WIN4_OFFS 0x14000000 +-#define AR71XX_PCI_WIN5_OFFS 0x15000000 +-#define AR71XX_PCI_WIN6_OFFS 0x16000000 +-#define AR71XX_PCI_WIN7_OFFS 0x07000000 +- +-#define AR71XX_PCI_CFG_BASE \ +- (AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x10000) +-#define AR71XX_PCI_CFG_SIZE 0x100 +- + #define AR71XX_PCI_REG_CRP_AD_CBE 0x00 + #define AR71XX_PCI_REG_CRP_WRDATA 0x04 + #define AR71XX_PCI_REG_CRP_RDDATA 0x08 +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -17,14 +17,6 @@ + #include + #include + +-#define AR724X_PCI_CFG_BASE 0x14000000 +-#define AR724X_PCI_CFG_SIZE 0x1000 +-#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000) +-#define AR724X_PCI_CTRL_SIZE 0x100 +- +-#define AR724X_PCI_MEM_BASE 0x10000000 +-#define AR724X_PCI_MEM_SIZE 0x04000000 +- + #define AR724X_PCI_REG_RESET 0x18 + #define AR724X_PCI_REG_INT_STATUS 0x4c + #define AR724X_PCI_REG_INT_MASK 0x50 diff --git a/target/linux/ar71xx/patches-3.3/146-MIPS-ath79-register-platform-devices-for-the-PCI-con.patch b/target/linux/ar71xx/patches-3.3/146-MIPS-ath79-register-platform-devices-for-the-PCI-con.patch new file mode 100644 index 000000000..cc2572f88 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/146-MIPS-ath79-register-platform-devices-for-the-PCI-con.patch @@ -0,0 +1,119 @@ +From 2fdf8dcff3ffaa806e9f9d7f1c1bd876222cff4d Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 11 Jun 2012 13:39:32 +0200 +Subject: [PATCH 07/34] MIPS: ath79: register platform devices for the PCI controllers + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/pci.c | 87 +++++++++++++++++++++++++++++++++++++++++++----- + 1 files changed, 78 insertions(+), 9 deletions(-) + +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -14,6 +14,8 @@ + + #include + #include ++#include ++#include + #include + #include + #include +@@ -110,21 +112,88 @@ void __init ath79_pci_set_plat_dev_init( + ath79_pci_plat_dev_init = func; + } + +-int __init ath79_register_pci(void) ++static struct platform_device * ++ath79_register_pci_ar71xx(void) + { +- if (soc_is_ar71xx()) +- return ar71xx_pcibios_init(); ++ struct platform_device *pdev; ++ struct resource res[2]; ++ ++ memset(res, 0, sizeof(res)); + +- if (soc_is_ar724x()) +- return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2); ++ res[0].name = "cfg_base"; ++ res[0].flags = IORESOURCE_MEM; ++ res[0].start = AR71XX_PCI_CFG_BASE; ++ res[0].end = AR71XX_PCI_CFG_BASE + AR71XX_PCI_CFG_SIZE - 1; ++ ++ res[1].flags = IORESOURCE_IRQ; ++ res[1].start = ATH79_CPU_IRQ_IP2; ++ res[1].end = ATH79_CPU_IRQ_IP2; ++ ++ pdev = platform_device_register_simple("ar71xx-pci", -1, ++ res, ARRAY_SIZE(res)); ++ return pdev; ++} + +- if (soc_is_ar9342() || soc_is_ar9344()) { ++static struct platform_device * ++ath79_register_pci_ar724x(int id, ++ unsigned long cfg_base, ++ unsigned long ctrl_base, ++ int irq) ++{ ++ struct platform_device *pdev; ++ struct resource res[3]; ++ ++ memset(res, 0, sizeof(res)); ++ ++ res[0].name = "cfg_base"; ++ res[0].flags = IORESOURCE_MEM; ++ res[0].start = cfg_base; ++ res[0].end = cfg_base + AR724X_PCI_CFG_SIZE - 1; ++ ++ res[1].name = "ctrl_base"; ++ res[1].flags = IORESOURCE_MEM; ++ res[1].start = ctrl_base; ++ res[1].end = ctrl_base + AR724X_PCI_CTRL_SIZE - 1; ++ ++ res[2].flags = IORESOURCE_IRQ; ++ res[2].start = irq; ++ res[2].end = irq; ++ ++ pdev = platform_device_register_simple("ar724x-pci", id, ++ res, ARRAY_SIZE(res)); ++ return pdev; ++} ++ ++int __init ath79_register_pci(void) ++{ ++ struct platform_device *pdev = NULL; ++ ++ if (soc_is_ar71xx()) { ++ pdev = ath79_register_pci_ar71xx(); ++ } else if (soc_is_ar724x()) { ++ pdev = ath79_register_pci_ar724x(-1, ++ AR724X_PCI_CFG_BASE, ++ AR724X_PCI_CTRL_BASE, ++ ATH79_CPU_IRQ_IP2); ++ } else if (soc_is_ar9342() || ++ soc_is_ar9344()) { + u32 bootstrap; + + bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); +- if (bootstrap & AR934X_BOOTSTRAP_PCIE_RC) +- return ar724x_pcibios_init(ATH79_IP2_IRQ(0)); ++ if ((bootstrap & AR934X_BOOTSTRAP_PCIE_RC) == 0) ++ return -ENODEV; ++ ++ pdev = ath79_register_pci_ar724x(-1, ++ AR724X_PCI_CFG_BASE, ++ AR724X_PCI_CTRL_BASE, ++ ATH79_IP2_IRQ(0)); ++ } else { ++ /* No PCI support */ ++ return -ENODEV; + } + +- return -ENODEV; ++ if (!pdev) ++ pr_err("unable to register PCI controller device\n"); ++ ++ return pdev ? 0 : -ENODEV; + } diff --git a/target/linux/ar71xx/patches-3.3/147-MIPS-ath79-remove-unused-ar7-1x-24-x_pcibios_init-fu.patch b/target/linux/ar71xx/patches-3.3/147-MIPS-ath79-remove-unused-ar7-1x-24-x_pcibios_init-fu.patch new file mode 100644 index 000000000..0157e347c --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/147-MIPS-ath79-remove-unused-ar7-1x-24-x_pcibios_init-fu.patch @@ -0,0 +1,147 @@ +From 07224e2fa5f889162ee0560c6ab1eb8cd16a8dd2 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 11 Jun 2012 14:59:39 +0200 +Subject: [PATCH 08/34] MIPS: ath79: remove unused ar7{1x,24}x_pcibios_init functions + +The functions are unused now, so remove them. + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/pci.c | 1 - + arch/mips/include/asm/mach-ath79/pci.h | 28 ---------------------------- + arch/mips/pci/pci-ar71xx.c | 26 -------------------------- + arch/mips/pci/pci-ar724x.c | 32 -------------------------------- + 4 files changed, 0 insertions(+), 87 deletions(-) + delete mode 100644 arch/mips/include/asm/mach-ath79/pci.h + +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -19,7 +19,6 @@ + #include + #include + #include +-#include + #include "pci.h" + + static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); +--- a/arch/mips/include/asm/mach-ath79/pci.h ++++ /dev/null +@@ -1,28 +0,0 @@ +-/* +- * Atheros AR71XX/AR724X PCI support +- * +- * Copyright (C) 2011 René Bolldorf +- * Copyright (C) 2008-2011 Gabor Juhos +- * Copyright (C) 2008 Imre Kaloz +- * +- * This program 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. +- */ +- +-#ifndef __ASM_MACH_ATH79_PCI_H +-#define __ASM_MACH_ATH79_PCI_H +- +-#if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR71XX) +-int ar71xx_pcibios_init(void); +-#else +-static inline int ar71xx_pcibios_init(void) { return 0; } +-#endif +- +-#if defined(CONFIG_PCI_AR724X) +-int ar724x_pcibios_init(int irq); +-#else +-static inline int ar724x_pcibios_init(int irq) { return 0; } +-#endif +- +-#endif /* __ASM_MACH_ATH79_PCI_H */ +--- a/arch/mips/pci/pci-ar71xx.c ++++ b/arch/mips/pci/pci-ar71xx.c +@@ -23,7 +23,6 @@ + + #include + #include +-#include + + #define AR71XX_PCI_REG_CRP_AD_CBE 0x00 + #define AR71XX_PCI_REG_CRP_WRDATA 0x04 +@@ -335,31 +334,6 @@ static __devinit void ar71xx_pci_reset(v + mdelay(100); + } + +-__init int ar71xx_pcibios_init(void) +-{ +- u32 t; +- +- ar71xx_pcicfg_base = ioremap(AR71XX_PCI_CFG_BASE, AR71XX_PCI_CFG_SIZE); +- if (ar71xx_pcicfg_base == NULL) +- return -ENOMEM; +- +- ar71xx_pci_reset(); +- +- /* setup COMMAND register */ +- t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE +- | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; +- ar71xx_pci_local_write(PCI_COMMAND, 4, t); +- +- /* clear bus errors */ +- ar71xx_pci_check_error(1); +- +- ar71xx_pci_irq_init(ATH79_CPU_IRQ_IP2); +- +- register_pci_controller(&ar71xx_pci_controller); +- +- return 0; +-} +- + static int __devinit ar71xx_pci_probe(struct platform_device *pdev) + { + struct resource *res; +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -15,7 +15,6 @@ + #include + #include + #include +-#include + + #define AR724X_PCI_REG_RESET 0x18 + #define AR724X_PCI_REG_INT_STATUS 0x4c +@@ -276,37 +275,6 @@ static void __devinit ar724x_pci_irq_ini + irq_set_chained_handler(irq, ar724x_pci_irq_handler); + } + +-int __devinit ar724x_pcibios_init(int irq) +-{ +- int ret; +- +- ret = -ENOMEM; +- +- ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE, +- AR724X_PCI_CFG_SIZE); +- if (ar724x_pci_devcfg_base == NULL) +- goto err; +- +- ar724x_pci_ctrl_base = ioremap(AR724X_PCI_CTRL_BASE, +- AR724X_PCI_CTRL_SIZE); +- if (ar724x_pci_ctrl_base == NULL) +- goto err_unmap_devcfg; +- +- ar724x_pci_link_up = ar724x_pci_check_link(); +- if (!ar724x_pci_link_up) +- pr_warn("ar724x: PCIe link is down\n"); +- +- ar724x_pci_irq_init(irq); +- register_pci_controller(&ar724x_pci_controller); +- +- return PCIBIOS_SUCCESSFUL; +- +-err_unmap_devcfg: +- iounmap(ar724x_pci_devcfg_base); +-err: +- return ret; +-} +- + static int __devinit ar724x_pci_probe(struct platform_device *pdev) + { + struct resource *res; diff --git a/target/linux/ar71xx/patches-3.3/148-MIPS-avoid-possible-resource-conflict-in-register_pc.patch b/target/linux/ar71xx/patches-3.3/148-MIPS-avoid-possible-resource-conflict-in-register_pc.patch new file mode 100644 index 000000000..fc1385fc7 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/148-MIPS-avoid-possible-resource-conflict-in-register_pc.patch @@ -0,0 +1,35 @@ +From a018b28d3953a32008de839d997a992a724ae314 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Jun 2012 17:40:45 +0200 +Subject: [PATCH 09/34] MIPS: avoid possible resource conflict in register_pci_controller + +Signed-off-by: Gabor Juhos +--- + arch/mips/pci/pci.c | 15 +++++++++++++-- + 1 files changed, 13 insertions(+), 2 deletions(-) + +--- a/arch/mips/pci/pci.c ++++ b/arch/mips/pci/pci.c +@@ -127,9 +127,20 @@ static DEFINE_MUTEX(pci_scan_mutex); + + void __devinit register_pci_controller(struct pci_controller *hose) + { +- if (request_resource(&iomem_resource, hose->mem_resource) < 0) ++ struct resource *parent; ++ ++ parent = hose->mem_resource->parent; ++ if (!parent) ++ parent = &iomem_resource; ++ ++ if (request_resource(parent, hose->mem_resource) < 0) + goto out; +- if (request_resource(&ioport_resource, hose->io_resource) < 0) { ++ ++ parent = hose->io_resource->parent; ++ if (!parent) ++ parent = &ioport_resource; ++ ++ if (request_resource(parent, hose->io_resource) < 0) { + release_resource(hose->mem_resource); + goto out; + } diff --git a/target/linux/ar71xx/patches-3.3/149-MIPS-pci-ar724x-use-dynamically-allocated-PCI-contro.patch b/target/linux/ar71xx/patches-3.3/149-MIPS-pci-ar724x-use-dynamically-allocated-PCI-contro.patch new file mode 100644 index 000000000..3a67cae2d --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/149-MIPS-pci-ar724x-use-dynamically-allocated-PCI-contro.patch @@ -0,0 +1,307 @@ +From 242aedf3246dc5085271aca56134ac455bfb64b5 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Jun 2012 11:51:34 +0200 +Subject: [PATCH 10/34] MIPS: pci-ar724x: use dynamically allocated PCI controller structure + +Signed-off-by: Gabor Juhos +--- + arch/mips/pci/pci-ar724x.c | 129 ++++++++++++++++++++++++++++---------------- + 1 files changed, 82 insertions(+), 47 deletions(-) + +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -9,6 +9,7 @@ + * by the Free Software Foundation. + */ + ++#include + #include + #include + #include +@@ -28,38 +29,56 @@ + + #define AR7240_BAR0_WAR_VALUE 0xffff + +-static DEFINE_SPINLOCK(ar724x_pci_lock); +-static void __iomem *ar724x_pci_devcfg_base; +-static void __iomem *ar724x_pci_ctrl_base; +- +-static u32 ar724x_pci_bar0_value; +-static bool ar724x_pci_bar0_is_cached; +-static bool ar724x_pci_link_up; ++struct ar724x_pci_controller { ++ void __iomem *devcfg_base; ++ void __iomem *ctrl_base; + +-static inline bool ar724x_pci_check_link(void) ++ int irq; ++ ++ bool link_up; ++ bool bar0_is_cached; ++ u32 bar0_value; ++ ++ spinlock_t lock; ++ ++ struct pci_controller pci_controller; ++}; ++ ++static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc) + { + u32 reset; + +- reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET); ++ reset = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_RESET); + return reset & AR724X_PCI_RESET_LINK_UP; + } + ++static inline struct ar724x_pci_controller * ++pci_bus_to_ar724x_controller(struct pci_bus *bus) ++{ ++ struct pci_controller *hose; ++ ++ hose = (struct pci_controller *) bus->sysdata; ++ return container_of(hose, struct ar724x_pci_controller, pci_controller); ++} ++ + static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t *value) + { ++ struct ar724x_pci_controller *apc; + unsigned long flags; + void __iomem *base; + u32 data; + +- if (!ar724x_pci_link_up) ++ apc = pci_bus_to_ar724x_controller(bus); ++ if (!apc->link_up) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (devfn) + return PCIBIOS_DEVICE_NOT_FOUND; + +- base = ar724x_pci_devcfg_base; ++ base = apc->devcfg_base; + +- spin_lock_irqsave(&ar724x_pci_lock, flags); ++ spin_lock_irqsave(&apc->lock, flags); + data = __raw_readl(base + (where & ~3)); + + switch (size) { +@@ -78,17 +97,17 @@ static int ar724x_pci_read(struct pci_bu + case 4: + break; + default: +- spin_unlock_irqrestore(&ar724x_pci_lock, flags); ++ spin_unlock_irqrestore(&apc->lock, flags); + + return PCIBIOS_BAD_REGISTER_NUMBER; + } + +- spin_unlock_irqrestore(&ar724x_pci_lock, flags); ++ spin_unlock_irqrestore(&apc->lock, flags); + + if (where == PCI_BASE_ADDRESS_0 && size == 4 && +- ar724x_pci_bar0_is_cached) { ++ apc->bar0_is_cached) { + /* use the cached value */ +- *value = ar724x_pci_bar0_value; ++ *value = apc->bar0_value; + } else { + *value = data; + } +@@ -99,12 +118,14 @@ static int ar724x_pci_read(struct pci_bu + static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t value) + { ++ struct ar724x_pci_controller *apc; + unsigned long flags; + void __iomem *base; + u32 data; + int s; + +- if (!ar724x_pci_link_up) ++ apc = pci_bus_to_ar724x_controller(bus); ++ if (!apc->link_up) + return PCIBIOS_DEVICE_NOT_FOUND; + + if (devfn) +@@ -122,18 +143,18 @@ static int ar724x_pci_write(struct pci_b + * BAR0 register in order to make the device memory + * accessible. + */ +- ar724x_pci_bar0_is_cached = true; +- ar724x_pci_bar0_value = value; ++ apc->bar0_is_cached = true; ++ apc->bar0_value = value; + + value = AR7240_BAR0_WAR_VALUE; + } else { +- ar724x_pci_bar0_is_cached = false; ++ apc->bar0_is_cached = false; + } + } + +- base = ar724x_pci_devcfg_base; ++ base = apc->devcfg_base; + +- spin_lock_irqsave(&ar724x_pci_lock, flags); ++ spin_lock_irqsave(&apc->lock, flags); + data = __raw_readl(base + (where & ~3)); + + switch (size) { +@@ -151,7 +172,7 @@ static int ar724x_pci_write(struct pci_b + data = value; + break; + default: +- spin_unlock_irqrestore(&ar724x_pci_lock, flags); ++ spin_unlock_irqrestore(&apc->lock, flags); + + return PCIBIOS_BAD_REGISTER_NUMBER; + } +@@ -159,7 +180,7 @@ static int ar724x_pci_write(struct pci_b + __raw_writel(data, base + (where & ~3)); + /* flush write */ + __raw_readl(base + (where & ~3)); +- spin_unlock_irqrestore(&ar724x_pci_lock, flags); ++ spin_unlock_irqrestore(&apc->lock, flags); + + return PCIBIOS_SUCCESSFUL; + } +@@ -183,18 +204,14 @@ static struct resource ar724x_mem_resour + .flags = IORESOURCE_MEM, + }; + +-static struct pci_controller ar724x_pci_controller = { +- .pci_ops = &ar724x_pci_ops, +- .io_resource = &ar724x_io_resource, +- .mem_resource = &ar724x_mem_resource, +-}; +- + static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) + { ++ struct ar724x_pci_controller *apc; + void __iomem *base; + u32 pending; + +- base = ar724x_pci_ctrl_base; ++ apc = irq_get_handler_data(irq); ++ base = apc->ctrl_base; + + pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) & + __raw_readl(base + AR724X_PCI_REG_INT_MASK); +@@ -208,10 +225,12 @@ static void ar724x_pci_irq_handler(unsig + + static void ar724x_pci_irq_unmask(struct irq_data *d) + { ++ struct ar724x_pci_controller *apc; + void __iomem *base; + u32 t; + +- base = ar724x_pci_ctrl_base; ++ apc = irq_data_get_irq_chip_data(d); ++ base = apc->ctrl_base; + + switch (d->irq) { + case ATH79_PCI_IRQ(0): +@@ -225,10 +244,12 @@ static void ar724x_pci_irq_unmask(struct + + static void ar724x_pci_irq_mask(struct irq_data *d) + { ++ struct ar724x_pci_controller *apc; + void __iomem *base; + u32 t; + +- base = ar724x_pci_ctrl_base; ++ apc = irq_data_get_irq_chip_data(d); ++ base = apc->ctrl_base; + + switch (d->irq) { + case ATH79_PCI_IRQ(0): +@@ -255,12 +276,12 @@ static struct irq_chip ar724x_pci_irq_ch + .irq_mask_ack = ar724x_pci_irq_mask, + }; + +-static void __devinit ar724x_pci_irq_init(int irq) ++static void __devinit ar724x_pci_irq_init(struct ar724x_pci_controller *apc) + { + void __iomem *base; + int i; + +- base = ar724x_pci_ctrl_base; ++ base = apc->ctrl_base; + + __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); + __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); +@@ -268,45 +289,59 @@ static void __devinit ar724x_pci_irq_ini + BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT); + + for (i = ATH79_PCI_IRQ_BASE; +- i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) ++ i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) { + irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, + handle_level_irq); ++ irq_set_chip_data(i, apc); ++ } + +- irq_set_chained_handler(irq, ar724x_pci_irq_handler); ++ irq_set_handler_data(apc->irq, apc); ++ irq_set_chained_handler(apc->irq, ar724x_pci_irq_handler); + } + + static int __devinit ar724x_pci_probe(struct platform_device *pdev) + { ++ struct ar724x_pci_controller *apc; + struct resource *res; +- int irq; ++ ++ apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller), ++ GFP_KERNEL); ++ if (!apc) ++ return -ENOMEM; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base"); + if (!res) + return -EINVAL; + +- ar724x_pci_ctrl_base = devm_request_and_ioremap(&pdev->dev, res); +- if (ar724x_pci_ctrl_base == NULL) ++ apc->ctrl_base = devm_request_and_ioremap(&pdev->dev, res); ++ if (apc->ctrl_base == NULL) + return -EBUSY; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); + if (!res) + return -EINVAL; + +- ar724x_pci_devcfg_base = devm_request_and_ioremap(&pdev->dev, res); +- if (!ar724x_pci_devcfg_base) ++ apc->devcfg_base = devm_request_and_ioremap(&pdev->dev, res); ++ if (!apc->devcfg_base) + return -EBUSY; + +- irq = platform_get_irq(pdev, 0); +- if (irq < 0) ++ apc->irq = platform_get_irq(pdev, 0); ++ if (apc->irq < 0) + return -EINVAL; + +- ar724x_pci_link_up = ar724x_pci_check_link(); +- if (!ar724x_pci_link_up) ++ spin_lock_init(&apc->lock); ++ ++ apc->pci_controller.pci_ops = &ar724x_pci_ops; ++ apc->pci_controller.io_resource = &ar724x_io_resource; ++ apc->pci_controller.mem_resource = &ar724x_mem_resource; ++ ++ apc->link_up = ar724x_pci_check_link(apc); ++ if (!apc->link_up) + dev_warn(&pdev->dev, "PCIe link is down\n"); + +- ar724x_pci_irq_init(irq); ++ ar724x_pci_irq_init(apc); + +- register_pci_controller(&ar724x_pci_controller); ++ register_pci_controller(&apc->pci_controller); + + return 0; + } diff --git a/target/linux/ar71xx/patches-3.3/150-MIPS-pci-ar724x-remove-static-PCI-resources.patch b/target/linux/ar71xx/patches-3.3/150-MIPS-pci-ar724x-remove-static-PCI-resources.patch new file mode 100644 index 000000000..698b2ae0a --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/150-MIPS-pci-ar724x-remove-static-PCI-resources.patch @@ -0,0 +1,131 @@ +From f1c3a7dadf7b77809cda7f77df4b1ba3b24fbfa3 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 27 Jun 2012 10:12:50 +0200 +Subject: [PATCH 11/34] MIPS: pci-ar724x: remove static PCI resources + +Get those from the platform device instead. + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/pci.c | 21 ++++++++++++++++++++- + arch/mips/pci/pci-ar724x.c | 40 ++++++++++++++++++++++++---------------- + 2 files changed, 44 insertions(+), 17 deletions(-) + +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -137,10 +137,13 @@ static struct platform_device * + ath79_register_pci_ar724x(int id, + unsigned long cfg_base, + unsigned long ctrl_base, ++ unsigned long mem_base, ++ unsigned long mem_size, ++ unsigned long io_base, + int irq) + { + struct platform_device *pdev; +- struct resource res[3]; ++ struct resource res[5]; + + memset(res, 0, sizeof(res)); + +@@ -158,6 +161,16 @@ ath79_register_pci_ar724x(int id, + res[2].start = irq; + res[2].end = irq; + ++ res[3].name = "mem_base"; ++ res[3].flags = IORESOURCE_MEM; ++ res[3].start = mem_base; ++ res[3].end = mem_base + mem_size - 1; ++ ++ res[4].name = "io_base"; ++ res[4].flags = IORESOURCE_IO; ++ res[4].start = io_base; ++ res[4].end = io_base; ++ + pdev = platform_device_register_simple("ar724x-pci", id, + res, ARRAY_SIZE(res)); + return pdev; +@@ -173,6 +186,9 @@ int __init ath79_register_pci(void) + pdev = ath79_register_pci_ar724x(-1, + AR724X_PCI_CFG_BASE, + AR724X_PCI_CTRL_BASE, ++ AR724X_PCI_MEM_BASE, ++ AR724X_PCI_MEM_SIZE, ++ 0, + ATH79_CPU_IRQ_IP2); + } else if (soc_is_ar9342() || + soc_is_ar9344()) { +@@ -185,6 +201,9 @@ int __init ath79_register_pci(void) + pdev = ath79_register_pci_ar724x(-1, + AR724X_PCI_CFG_BASE, + AR724X_PCI_CTRL_BASE, ++ AR724X_PCI_MEM_BASE, ++ AR724X_PCI_MEM_SIZE, ++ 0, + ATH79_IP2_IRQ(0)); + } else { + /* No PCI support */ +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -42,6 +42,8 @@ struct ar724x_pci_controller { + spinlock_t lock; + + struct pci_controller pci_controller; ++ struct resource io_res; ++ struct resource mem_res; + }; + + static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc) +@@ -190,20 +192,6 @@ static struct pci_ops ar724x_pci_ops = { + .write = ar724x_pci_write, + }; + +-static struct resource ar724x_io_resource = { +- .name = "PCI IO space", +- .start = 0, +- .end = 0, +- .flags = IORESOURCE_IO, +-}; +- +-static struct resource ar724x_mem_resource = { +- .name = "PCI memory space", +- .start = AR724X_PCI_MEM_BASE, +- .end = AR724X_PCI_MEM_BASE + AR724X_PCI_MEM_SIZE - 1, +- .flags = IORESOURCE_MEM, +-}; +- + static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) + { + struct ar724x_pci_controller *apc; +@@ -331,9 +319,29 @@ static int __devinit ar724x_pci_probe(st + + spin_lock_init(&apc->lock); + ++ res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base"); ++ if (!res) ++ return -EINVAL; ++ ++ apc->io_res.parent = res; ++ apc->io_res.name = "PCI IO space"; ++ apc->io_res.start = res->start; ++ apc->io_res.end = res->end; ++ apc->io_res.flags = IORESOURCE_IO; ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base"); ++ if (!res) ++ return -EINVAL; ++ ++ apc->mem_res.parent = res; ++ apc->mem_res.name = "PCI memory space"; ++ apc->mem_res.start = res->start; ++ apc->mem_res.end = res->end; ++ apc->mem_res.flags = IORESOURCE_MEM; ++ + apc->pci_controller.pci_ops = &ar724x_pci_ops; +- apc->pci_controller.io_resource = &ar724x_io_resource; +- apc->pci_controller.mem_resource = &ar724x_mem_resource; ++ apc->pci_controller.io_resource = &apc->io_res; ++ apc->pci_controller.mem_resource = &apc->mem_res; + + apc->link_up = ar724x_pci_check_link(apc); + if (!apc->link_up) diff --git a/target/linux/ar71xx/patches-3.3/151-MIPS-pci-ar724x-use-per-controller-IRQ-base.patch b/target/linux/ar71xx/patches-3.3/151-MIPS-pci-ar724x-use-per-controller-IRQ-base.patch new file mode 100644 index 000000000..5b690ab3e --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/151-MIPS-pci-ar724x-use-per-controller-IRQ-base.patch @@ -0,0 +1,110 @@ +From d258929cd4c8c495f619f0e66d9d1c23f3f9246f Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Tue, 26 Jun 2012 11:59:45 +0200 +Subject: [PATCH 12/34] MIPS: pci-ar724x: use per-controller IRQ base + +Signed-off-by: Gabor Juhos +--- + arch/mips/pci/pci-ar724x.c | 31 +++++++++++++++++++++---------- + 1 files changed, 21 insertions(+), 10 deletions(-) + +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -34,6 +34,7 @@ struct ar724x_pci_controller { + void __iomem *ctrl_base; + + int irq; ++ int irq_base; + + bool link_up; + bool bar0_is_cached; +@@ -205,7 +206,7 @@ static void ar724x_pci_irq_handler(unsig + __raw_readl(base + AR724X_PCI_REG_INT_MASK); + + if (pending & AR724X_PCI_INT_DEV0) +- generic_handle_irq(ATH79_PCI_IRQ(0)); ++ generic_handle_irq(apc->irq_base + 0); + + else + spurious_interrupt(); +@@ -215,13 +216,15 @@ static void ar724x_pci_irq_unmask(struct + { + struct ar724x_pci_controller *apc; + void __iomem *base; ++ int offset; + u32 t; + + apc = irq_data_get_irq_chip_data(d); + base = apc->ctrl_base; ++ offset = apc->irq_base - d->irq; + +- switch (d->irq) { +- case ATH79_PCI_IRQ(0): ++ switch (offset) { ++ case 0: + t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); + __raw_writel(t | AR724X_PCI_INT_DEV0, + base + AR724X_PCI_REG_INT_MASK); +@@ -234,13 +237,15 @@ static void ar724x_pci_irq_mask(struct i + { + struct ar724x_pci_controller *apc; + void __iomem *base; ++ int offset; + u32 t; + + apc = irq_data_get_irq_chip_data(d); + base = apc->ctrl_base; ++ offset = apc->irq_base - d->irq; + +- switch (d->irq) { +- case ATH79_PCI_IRQ(0): ++ switch (offset) { ++ case 0: + t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); + __raw_writel(t & ~AR724X_PCI_INT_DEV0, + base + AR724X_PCI_REG_INT_MASK); +@@ -264,7 +269,8 @@ static struct irq_chip ar724x_pci_irq_ch + .irq_mask_ack = ar724x_pci_irq_mask, + }; + +-static void __devinit ar724x_pci_irq_init(struct ar724x_pci_controller *apc) ++static void __devinit ar724x_pci_irq_init(struct ar724x_pci_controller *apc, ++ int id) + { + void __iomem *base; + int i; +@@ -274,10 +280,10 @@ static void __devinit ar724x_pci_irq_ini + __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); + __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); + +- BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT); ++ apc->irq_base = ATH79_PCI_IRQ_BASE + (id * AR724X_PCI_IRQ_COUNT); + +- for (i = ATH79_PCI_IRQ_BASE; +- i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) { ++ for (i = apc->irq_base; ++ i < apc->irq_base + AR724X_PCI_IRQ_COUNT; i++) { + irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, + handle_level_irq); + irq_set_chip_data(i, apc); +@@ -291,6 +297,11 @@ static int __devinit ar724x_pci_probe(st + { + struct ar724x_pci_controller *apc; + struct resource *res; ++ int id; ++ ++ id = pdev->id; ++ if (id == -1) ++ id = 0; + + apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller), + GFP_KERNEL); +@@ -347,7 +358,7 @@ static int __devinit ar724x_pci_probe(st + if (!apc->link_up) + dev_warn(&pdev->dev, "PCIe link is down\n"); + +- ar724x_pci_irq_init(apc); ++ ar724x_pci_irq_init(apc, id); + + register_pci_controller(&apc->pci_controller); + diff --git a/target/linux/ar71xx/patches-3.3/152-MIPS-pci-ar724x-setup-command-register-of-the-PCI-co.patch b/target/linux/ar71xx/patches-3.3/152-MIPS-pci-ar724x-setup-command-register-of-the-PCI-co.patch new file mode 100644 index 000000000..38c43bccd --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/152-MIPS-pci-ar724x-setup-command-register-of-the-PCI-co.patch @@ -0,0 +1,165 @@ +From 93824983ceb36d4ce1f4a644031ec6fb5f332f1d Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Tue, 26 Jun 2012 15:14:47 +0200 +Subject: [PATCH 13/34] MIPS: pci-ar724x: setup command register of the PCI controller + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/pci.c | 10 +++- + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 2 + + arch/mips/pci/pci-ar724x.c | 63 ++++++++++++++++++++++++ + 3 files changed, 74 insertions(+), 1 deletions(-) + +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -137,13 +137,14 @@ static struct platform_device * + ath79_register_pci_ar724x(int id, + unsigned long cfg_base, + unsigned long ctrl_base, ++ unsigned long crp_base, + unsigned long mem_base, + unsigned long mem_size, + unsigned long io_base, + int irq) + { + struct platform_device *pdev; +- struct resource res[5]; ++ struct resource res[6]; + + memset(res, 0, sizeof(res)); + +@@ -171,6 +172,11 @@ ath79_register_pci_ar724x(int id, + res[4].start = io_base; + res[4].end = io_base; + ++ res[5].name = "crp_base"; ++ res[5].flags = IORESOURCE_MEM; ++ res[5].start = crp_base; ++ res[5].end = crp_base + AR724X_PCI_CRP_SIZE - 1; ++ + pdev = platform_device_register_simple("ar724x-pci", id, + res, ARRAY_SIZE(res)); + return pdev; +@@ -186,6 +192,7 @@ int __init ath79_register_pci(void) + pdev = ath79_register_pci_ar724x(-1, + AR724X_PCI_CFG_BASE, + AR724X_PCI_CTRL_BASE, ++ AR724X_PCI_CRP_BASE, + AR724X_PCI_MEM_BASE, + AR724X_PCI_MEM_SIZE, + 0, +@@ -201,6 +208,7 @@ int __init ath79_register_pci(void) + pdev = ath79_register_pci_ar724x(-1, + AR724X_PCI_CFG_BASE, + AR724X_PCI_CTRL_BASE, ++ AR724X_PCI_CRP_BASE, + AR724X_PCI_MEM_BASE, + AR724X_PCI_MEM_SIZE, + 0, +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -67,6 +67,8 @@ + + #define AR724X_PCI_CFG_BASE 0x14000000 + #define AR724X_PCI_CFG_SIZE 0x1000 ++#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000c0000) ++#define AR724X_PCI_CRP_SIZE 0x1000 + #define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000) + #define AR724X_PCI_CTRL_SIZE 0x100 + +--- a/arch/mips/pci/pci-ar724x.c ++++ b/arch/mips/pci/pci-ar724x.c +@@ -29,9 +29,17 @@ + + #define AR7240_BAR0_WAR_VALUE 0xffff + ++#define AR724X_PCI_CMD_INIT (PCI_COMMAND_MEMORY | \ ++ PCI_COMMAND_MASTER | \ ++ PCI_COMMAND_INVALIDATE | \ ++ PCI_COMMAND_PARITY | \ ++ PCI_COMMAND_SERR | \ ++ PCI_COMMAND_FAST_BACK) ++ + struct ar724x_pci_controller { + void __iomem *devcfg_base; + void __iomem *ctrl_base; ++ void __iomem *crp_base; + + int irq; + int irq_base; +@@ -64,6 +72,51 @@ pci_bus_to_ar724x_controller(struct pci_ + return container_of(hose, struct ar724x_pci_controller, pci_controller); + } + ++static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, ++ int where, int size, u32 value) ++{ ++ unsigned long flags; ++ void __iomem *base; ++ u32 data; ++ int s; ++ ++ WARN_ON(where & (size - 1)); ++ ++ if (!apc->link_up) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ base = apc->crp_base; ++ ++ spin_lock_irqsave(&apc->lock, flags); ++ data = __raw_readl(base + (where & ~3)); ++ ++ switch (size) { ++ case 1: ++ s = ((where & 3) * 8); ++ data &= ~(0xff << s); ++ data |= ((value & 0xff) << s); ++ break; ++ case 2: ++ s = ((where & 2) * 8); ++ data &= ~(0xffff << s); ++ data |= ((value & 0xffff) << s); ++ break; ++ case 4: ++ data = value; ++ break; ++ default: ++ spin_unlock_irqrestore(&apc->lock, flags); ++ return PCIBIOS_BAD_REGISTER_NUMBER; ++ } ++ ++ __raw_writel(data, base + (where & ~3)); ++ /* flush write */ ++ __raw_readl(base + (where & ~3)); ++ spin_unlock_irqrestore(&apc->lock, flags); ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ + static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t *value) + { +@@ -324,6 +377,14 @@ static int __devinit ar724x_pci_probe(st + if (!apc->devcfg_base) + return -EBUSY; + ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "crp_base"); ++ if (!res) ++ return -EINVAL; ++ ++ apc->crp_base = devm_request_and_ioremap(&pdev->dev, res); ++ if (apc->crp_base == NULL) ++ return -EBUSY; ++ + apc->irq = platform_get_irq(pdev, 0); + if (apc->irq < 0) + return -EINVAL; +@@ -360,6 +421,8 @@ static int __devinit ar724x_pci_probe(st + + ar724x_pci_irq_init(apc, id); + ++ ar724x_pci_local_write(apc, PCI_COMMAND, 4, AR724X_PCI_CMD_INIT); ++ + register_pci_controller(&apc->pci_controller); + + return 0; diff --git a/target/linux/ar71xx/patches-3.3/153-MIPS-pci-ar71xx-use-dynamically-allocated-PCI-contro.patch b/target/linux/ar71xx/patches-3.3/153-MIPS-pci-ar71xx-use-dynamically-allocated-PCI-contro.patch new file mode 100644 index 000000000..4db1fd92b --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/153-MIPS-pci-ar71xx-use-dynamically-allocated-PCI-contro.patch @@ -0,0 +1,228 @@ +From 6c3ef689e4364dca74eaaecd72384be09e5a6bc8 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 25 Jun 2012 09:19:08 +0200 +Subject: [PATCH 14/34] MIPS: pci-ar71xx: use dynamically allocated PCI controller structure + +Signed-off-by: Gabor Juhos +--- + arch/mips/pci/pci-ar71xx.c | 84 +++++++++++++++++++++++++++---------------- + 1 files changed, 53 insertions(+), 31 deletions(-) + +--- a/arch/mips/pci/pci-ar71xx.c ++++ b/arch/mips/pci/pci-ar71xx.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -48,8 +49,12 @@ + + #define AR71XX_PCI_IRQ_COUNT 5 + +-static DEFINE_SPINLOCK(ar71xx_pci_lock); +-static void __iomem *ar71xx_pcicfg_base; ++struct ar71xx_pci_controller { ++ void __iomem *cfg_base; ++ spinlock_t lock; ++ int irq; ++ struct pci_controller pci_ctrl; ++}; + + /* Byte lane enable bits */ + static const u8 ar71xx_pci_ble_table[4][4] = { +@@ -92,9 +97,18 @@ static inline u32 ar71xx_pci_bus_addr(st + return ret; + } + +-static int ar71xx_pci_check_error(int quiet) ++static inline struct ar71xx_pci_controller * ++pci_bus_to_ar71xx_controller(struct pci_bus *bus) + { +- void __iomem *base = ar71xx_pcicfg_base; ++ struct pci_controller *hose; ++ ++ hose = (struct pci_controller *) bus->sysdata; ++ return container_of(hose, struct ar71xx_pci_controller, pci_ctrl); ++} ++ ++static int ar71xx_pci_check_error(struct ar71xx_pci_controller *apc, int quiet) ++{ ++ void __iomem *base = apc->cfg_base; + u32 pci_err; + u32 ahb_err; + +@@ -129,9 +143,10 @@ static int ar71xx_pci_check_error(int qu + return !!(ahb_err | pci_err); + } + +-static inline void ar71xx_pci_local_write(int where, int size, u32 value) ++static inline void ar71xx_pci_local_write(struct ar71xx_pci_controller *apc, ++ int where, int size, u32 value) + { +- void __iomem *base = ar71xx_pcicfg_base; ++ void __iomem *base = apc->cfg_base; + u32 ad_cbe; + + value = value << (8 * (where & 3)); +@@ -147,7 +162,8 @@ static inline int ar71xx_pci_set_cfgaddr + unsigned int devfn, + int where, int size, u32 cmd) + { +- void __iomem *base = ar71xx_pcicfg_base; ++ struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); ++ void __iomem *base = apc->cfg_base; + u32 addr; + + addr = ar71xx_pci_bus_addr(bus, devfn, where); +@@ -156,13 +172,14 @@ static inline int ar71xx_pci_set_cfgaddr + __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0), + base + AR71XX_PCI_REG_CFG_CBE); + +- return ar71xx_pci_check_error(1); ++ return ar71xx_pci_check_error(apc, 1); + } + + static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *value) + { +- void __iomem *base = ar71xx_pcicfg_base; ++ struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); ++ void __iomem *base = apc->cfg_base; + unsigned long flags; + u32 data; + int err; +@@ -171,7 +188,7 @@ static int ar71xx_pci_read_config(struct + ret = PCIBIOS_SUCCESSFUL; + data = ~0; + +- spin_lock_irqsave(&ar71xx_pci_lock, flags); ++ spin_lock_irqsave(&apc->lock, flags); + + err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, + AR71XX_PCI_CFG_CMD_READ); +@@ -180,7 +197,7 @@ static int ar71xx_pci_read_config(struct + else + data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA); + +- spin_unlock_irqrestore(&ar71xx_pci_lock, flags); ++ spin_unlock_irqrestore(&apc->lock, flags); + + *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7]; + +@@ -190,7 +207,8 @@ static int ar71xx_pci_read_config(struct + static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 value) + { +- void __iomem *base = ar71xx_pcicfg_base; ++ struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); ++ void __iomem *base = apc->cfg_base; + unsigned long flags; + int err; + int ret; +@@ -198,7 +216,7 @@ static int ar71xx_pci_write_config(struc + value = value << (8 * (where & 3)); + ret = PCIBIOS_SUCCESSFUL; + +- spin_lock_irqsave(&ar71xx_pci_lock, flags); ++ spin_lock_irqsave(&apc->lock, flags); + + err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, + AR71XX_PCI_CFG_CMD_WRITE); +@@ -207,7 +225,7 @@ static int ar71xx_pci_write_config(struc + else + __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA); + +- spin_unlock_irqrestore(&ar71xx_pci_lock, flags); ++ spin_unlock_irqrestore(&apc->lock, flags); + + return ret; + } +@@ -231,12 +249,6 @@ static struct resource ar71xx_pci_mem_re + .flags = IORESOURCE_MEM + }; + +-static struct pci_controller ar71xx_pci_controller = { +- .pci_ops = &ar71xx_pci_ops, +- .mem_resource = &ar71xx_pci_mem_resource, +- .io_resource = &ar71xx_pci_io_resource, +-}; +- + static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc) + { + void __iomem *base = ath79_reset_base; +@@ -294,7 +306,7 @@ static struct irq_chip ar71xx_pci_irq_ch + .irq_mask_ack = ar71xx_pci_irq_mask, + }; + +-static __devinit void ar71xx_pci_irq_init(int irq) ++static __devinit void ar71xx_pci_irq_init(struct ar71xx_pci_controller *apc) + { + void __iomem *base = ath79_reset_base; + int i; +@@ -309,7 +321,7 @@ static __devinit void ar71xx_pci_irq_ini + irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip, + handle_level_irq); + +- irq_set_chained_handler(irq, ar71xx_pci_irq_handler); ++ irq_set_chained_handler(apc->irq, ar71xx_pci_irq_handler); + } + + static __devinit void ar71xx_pci_reset(void) +@@ -336,20 +348,26 @@ static __devinit void ar71xx_pci_reset(v + + static int __devinit ar71xx_pci_probe(struct platform_device *pdev) + { ++ struct ar71xx_pci_controller *apc; + struct resource *res; +- int irq; + u32 t; + ++ apc = kzalloc(sizeof(struct ar71xx_pci_controller), GFP_KERNEL); ++ if (!apc) ++ return -ENOMEM; ++ ++ spin_lock_init(&apc->lock); ++ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); + if (!res) + return -EINVAL; + +- ar71xx_pcicfg_base = devm_request_and_ioremap(&pdev->dev, res); +- if (!ar71xx_pcicfg_base) ++ apc->cfg_base = devm_request_and_ioremap(&pdev->dev, res); ++ if (!apc->cfg_base) + return -ENOMEM; + +- irq = platform_get_irq(pdev, 0); +- if (irq < 0) ++ apc->irq = platform_get_irq(pdev, 0); ++ if (apc->irq < 0) + return -EINVAL; + + ar71xx_pci_reset(); +@@ -357,14 +375,18 @@ static int __devinit ar71xx_pci_probe(st + /* setup COMMAND register */ + t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE + | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; +- ar71xx_pci_local_write(PCI_COMMAND, 4, t); ++ ar71xx_pci_local_write(apc, PCI_COMMAND, 4, t); + + /* clear bus errors */ +- ar71xx_pci_check_error(1); ++ ar71xx_pci_check_error(apc, 1); ++ ++ ar71xx_pci_irq_init(apc); + +- ar71xx_pci_irq_init(irq); ++ apc->pci_ctrl.pci_ops = &ar71xx_pci_ops; ++ apc->pci_ctrl.mem_resource = &ar71xx_pci_mem_resource; ++ apc->pci_ctrl.io_resource = &ar71xx_pci_io_resource; + +- register_pci_controller(&ar71xx_pci_controller); ++ register_pci_controller(&apc->pci_ctrl); + + return 0; + } diff --git a/target/linux/ar71xx/patches-3.3/154-MIPS-pci-ar71xx-remove-static-PCI-controller-resourc.patch b/target/linux/ar71xx/patches-3.3/154-MIPS-pci-ar71xx-remove-static-PCI-controller-resourc.patch new file mode 100644 index 000000000..d31ba264b --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/154-MIPS-pci-ar71xx-remove-static-PCI-controller-resourc.patch @@ -0,0 +1,70 @@ +From 7dc3ccb5dc972b06c41b309653d132beaaedeb37 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 25 Jun 2012 09:52:23 +0200 +Subject: [PATCH 15/34] MIPS: pci-ar71xx: remove static PCI controller resources + +Signed-off-by: Gabor Juhos +--- + arch/mips/pci/pci-ar71xx.c | 30 ++++++++++++++---------------- + 1 files changed, 14 insertions(+), 16 deletions(-) + +--- a/arch/mips/pci/pci-ar71xx.c ++++ b/arch/mips/pci/pci-ar71xx.c +@@ -54,6 +54,8 @@ struct ar71xx_pci_controller { + spinlock_t lock; + int irq; + struct pci_controller pci_ctrl; ++ struct resource io_res; ++ struct resource mem_res; + }; + + /* Byte lane enable bits */ +@@ -235,20 +237,6 @@ static struct pci_ops ar71xx_pci_ops = { + .write = ar71xx_pci_write_config, + }; + +-static struct resource ar71xx_pci_io_resource = { +- .name = "PCI IO space", +- .start = 0, +- .end = 0, +- .flags = IORESOURCE_IO, +-}; +- +-static struct resource ar71xx_pci_mem_resource = { +- .name = "PCI memory space", +- .start = AR71XX_PCI_MEM_BASE, +- .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1, +- .flags = IORESOURCE_MEM +-}; +- + static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc) + { + void __iomem *base = ath79_reset_base; +@@ -370,6 +358,16 @@ static int __devinit ar71xx_pci_probe(st + if (apc->irq < 0) + return -EINVAL; + ++ apc->io_res.name = "PCI IO space"; ++ apc->io_res.start = 0; ++ apc->io_res.end = 0; ++ apc->io_res.flags = IORESOURCE_IO; ++ ++ apc->mem_res.name = "PCI memory space"; ++ apc->mem_res.start = AR71XX_PCI_MEM_BASE; ++ apc->mem_res.end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1; ++ apc->mem_res.flags = IORESOURCE_MEM; ++ + ar71xx_pci_reset(); + + /* setup COMMAND register */ +@@ -383,8 +381,8 @@ static int __devinit ar71xx_pci_probe(st + ar71xx_pci_irq_init(apc); + + apc->pci_ctrl.pci_ops = &ar71xx_pci_ops; +- apc->pci_ctrl.mem_resource = &ar71xx_pci_mem_resource; +- apc->pci_ctrl.io_resource = &ar71xx_pci_io_resource; ++ apc->pci_ctrl.mem_resource = &apc->mem_res; ++ apc->pci_ctrl.io_resource = &apc->io_res; + + register_pci_controller(&apc->pci_ctrl); + diff --git a/target/linux/ar71xx/patches-3.3/160-MIPS-ath79-add-early-printk-support-for-the-QCA955X-.patch b/target/linux/ar71xx/patches-3.3/160-MIPS-ath79-add-early-printk-support-for-the-QCA955X-.patch new file mode 100644 index 000000000..7f1f2302f --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/160-MIPS-ath79-add-early-printk-support-for-the-QCA955X-.patch @@ -0,0 +1,31 @@ +From 114df1e368b8503de1fe63e97d6eea521eecfbe4 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Jun 2012 13:40:38 +0200 +Subject: [PATCH 16/34] MIPS: ath79: add early printk support for the QCA955X SoCs + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/early_printk.c | 1 + + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 1 + + 2 files changed, 2 insertions(+), 0 deletions(-) + +--- a/arch/mips/ath79/early_printk.c ++++ b/arch/mips/ath79/early_printk.c +@@ -74,6 +74,7 @@ static void prom_putchar_init(void) + case REV_ID_MAJOR_AR9341: + case REV_ID_MAJOR_AR9342: + case REV_ID_MAJOR_AR9344: ++ case REV_ID_MAJOR_QCA9558: + _prom_putchar = prom_putchar_ar71xx; + break; + +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -370,6 +370,7 @@ + #define REV_ID_MAJOR_AR9341 0x0120 + #define REV_ID_MAJOR_AR9342 0x1120 + #define REV_ID_MAJOR_AR9344 0x2120 ++#define REV_ID_MAJOR_QCA9558 0x1130 + + #define AR71XX_REV_ID_MINOR_MASK 0x3 + #define AR71XX_REV_ID_MINOR_AR7130 0x0 diff --git a/target/linux/ar71xx/patches-3.3/161-MIPS-ath79-add-SoC-detection-code-for-the-QCA9558-So.patch b/target/linux/ar71xx/patches-3.3/161-MIPS-ath79-add-SoC-detection-code-for-the-QCA9558-So.patch new file mode 100644 index 000000000..1d9dd4beb --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/161-MIPS-ath79-add-SoC-detection-code-for-the-QCA9558-So.patch @@ -0,0 +1,91 @@ +From 3c3c0eccf63b12fea98fd0eb65d0ccf69a7c5a57 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Jun 2012 13:42:16 +0200 +Subject: [PATCH 17/34] MIPS: ath79: add SoC detection code for the QCA9558 SoC + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/Kconfig | 4 ++++ + arch/mips/ath79/setup.c | 12 +++++++++++- + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 2 ++ + arch/mips/include/asm/mach-ath79/ath79.h | 11 +++++++++++ + 4 files changed, 28 insertions(+), 1 deletions(-) + +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -88,6 +88,10 @@ config SOC_AR934X + select PCI_AR724X if PCI + def_bool n + ++config SOC_QCA955X ++ select USB_ARCH_HAS_EHCI ++ def_bool n ++ + config PCI_AR724X + def_bool n + +--- a/arch/mips/ath79/setup.c ++++ b/arch/mips/ath79/setup.c +@@ -164,13 +164,23 @@ static void __init ath79_detect_sys_type + rev = id & AR934X_REV_ID_REVISION_MASK; + break; + ++ case REV_ID_MAJOR_QCA9558: ++ ath79_soc = ATH79_SOC_QCA9558; ++ chip = "9558"; ++ rev = id & AR944X_REV_ID_REVISION_MASK; ++ break; ++ + default: + panic("ath79: unknown SoC, id:0x%08x", id); + } + + ath79_soc_rev = rev; + +- sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev); ++ if (soc_is_qca955x()) ++ sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s rev %u", ++ chip, rev); ++ else ++ sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev); + pr_info("SoC: %s\n", ath79_sys_type); + } + +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -391,6 +391,8 @@ + + #define AR934X_REV_ID_REVISION_MASK 0xf + ++#define AR944X_REV_ID_REVISION_MASK 0xf ++ + /* + * SPI block + */ +--- a/arch/mips/include/asm/mach-ath79/ath79.h ++++ b/arch/mips/include/asm/mach-ath79/ath79.h +@@ -32,6 +32,7 @@ enum ath79_soc_type { + ATH79_SOC_AR9341, + ATH79_SOC_AR9342, + ATH79_SOC_AR9344, ++ ATH79_SOC_QCA9558, + }; + + extern enum ath79_soc_type ath79_soc; +@@ -98,6 +99,16 @@ static inline int soc_is_ar934x(void) + return soc_is_ar9341() || soc_is_ar9342() || soc_is_ar9344(); + } + ++static inline int soc_is_qca9558(void) ++{ ++ return ath79_soc == ATH79_SOC_QCA9558; ++} ++ ++static inline int soc_is_qca955x(void) ++{ ++ return soc_is_qca9558(); ++} ++ + extern void __iomem *ath79_ddr_base; + extern void __iomem *ath79_pll_base; + extern void __iomem *ath79_reset_base; diff --git a/target/linux/ar71xx/patches-3.3/162-MIPS-ath79-add-clock-setup-for-the-QCA955X-SoCs.patch b/target/linux/ar71xx/patches-3.3/162-MIPS-ath79-add-clock-setup-for-the-QCA955X-SoCs.patch new file mode 100644 index 000000000..bb0924c43 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/162-MIPS-ath79-add-clock-setup-for-the-QCA955X-SoCs.patch @@ -0,0 +1,167 @@ +From f465a16766a015a31d4e83af1ad62cc718d64f5a Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Jun 2012 13:43:08 +0200 +Subject: [PATCH 18/34] MIPS: ath79: add clock setup for the QCA955X SoCs + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/clock.c | 78 ++++++++++++++++++++++++ + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 39 ++++++++++++ + 2 files changed, 117 insertions(+), 0 deletions(-) + +--- a/arch/mips/ath79/clock.c ++++ b/arch/mips/ath79/clock.c +@@ -295,6 +295,82 @@ static void __init ar934x_clocks_init(vo + iounmap(dpll_base); + } + ++static void __init qca955x_clocks_init(void) ++{ ++ u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; ++ u32 cpu_pll, ddr_pll; ++ u32 bootstrap; ++ ++ bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); ++ if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40) ++ ath79_ref_clk.rate = 40 * 1000 * 1000; ++ else ++ ath79_ref_clk.rate = 25 * 1000 * 1000; ++ ++ pll = ath79_pll_rr(QCA955X_PLL_CPU_CONFIG_REG); ++ out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & ++ QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK; ++ ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) & ++ QCA955X_PLL_CPU_CONFIG_REFDIV_MASK; ++ nint = (pll >> QCA955X_PLL_CPU_CONFIG_NINT_SHIFT) & ++ QCA955X_PLL_CPU_CONFIG_NINT_MASK; ++ frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) & ++ QCA955X_PLL_CPU_CONFIG_NFRAC_MASK; ++ ++ cpu_pll = nint * ath79_ref_clk.rate / ref_div; ++ cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 6)); ++ cpu_pll /= (1 << out_div); ++ ++ pll = ath79_pll_rr(QCA955X_PLL_DDR_CONFIG_REG); ++ out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & ++ QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK; ++ ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) & ++ QCA955X_PLL_DDR_CONFIG_REFDIV_MASK; ++ nint = (pll >> QCA955X_PLL_DDR_CONFIG_NINT_SHIFT) & ++ QCA955X_PLL_DDR_CONFIG_NINT_MASK; ++ frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) & ++ QCA955X_PLL_DDR_CONFIG_NFRAC_MASK; ++ ++ ddr_pll = nint * ath79_ref_clk.rate / ref_div; ++ ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (1 << 10)); ++ ddr_pll /= (1 << out_div); ++ ++ clk_ctrl = ath79_pll_rr(QCA955X_PLL_CLK_CTRL_REG); ++ ++ postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & ++ QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; ++ ++ if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS) ++ ath79_cpu_clk.rate = ath79_ref_clk.rate; ++ else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) ++ ath79_cpu_clk.rate = ddr_pll / (postdiv + 1); ++ else ++ ath79_cpu_clk.rate = cpu_pll / (postdiv + 1); ++ ++ postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & ++ QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; ++ ++ if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS) ++ ath79_ddr_clk.rate = ath79_ref_clk.rate; ++ else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) ++ ath79_ddr_clk.rate = cpu_pll / (postdiv + 1); ++ else ++ ath79_ddr_clk.rate = ddr_pll / (postdiv + 1); ++ ++ postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & ++ QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; ++ ++ if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS) ++ ath79_ahb_clk.rate = ath79_ref_clk.rate; ++ else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) ++ ath79_ahb_clk.rate = ddr_pll / (postdiv + 1); ++ else ++ ath79_ahb_clk.rate = cpu_pll / (postdiv + 1); ++ ++ ath79_wdt_clk.rate = ath79_ref_clk.rate; ++ ath79_uart_clk.rate = ath79_ref_clk.rate; ++} ++ + void __init ath79_clocks_init(void) + { + if (soc_is_ar71xx()) +@@ -307,6 +383,8 @@ void __init ath79_clocks_init(void) + ar933x_clocks_init(); + else if (soc_is_ar934x()) + ar934x_clocks_init(); ++ else if (soc_is_qca955x()) ++ qca955x_clocks_init(); + else + BUG(); + +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -225,6 +225,41 @@ + #define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) + #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) + ++#define QCA955X_PLL_CPU_CONFIG_REG 0x00 ++#define QCA955X_PLL_DDR_CONFIG_REG 0x04 ++#define QCA955X_PLL_CLK_CTRL_REG 0x08 ++ ++#define QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT 0 ++#define QCA955X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f ++#define QCA955X_PLL_CPU_CONFIG_NINT_SHIFT 6 ++#define QCA955X_PLL_CPU_CONFIG_NINT_MASK 0x3f ++#define QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT 12 ++#define QCA955X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f ++#define QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19 ++#define QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3 ++ ++#define QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT 0 ++#define QCA955X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff ++#define QCA955X_PLL_DDR_CONFIG_NINT_SHIFT 10 ++#define QCA955X_PLL_DDR_CONFIG_NINT_MASK 0x3f ++#define QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT 16 ++#define QCA955X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f ++#define QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23 ++#define QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7 ++ ++#define QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2) ++#define QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3) ++#define QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4) ++#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5 ++#define QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f ++#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10 ++#define QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f ++#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15 ++#define QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f ++#define QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20) ++#define QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) ++#define QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) ++ + /* + * USB_CONFIG block + */ +@@ -264,6 +299,8 @@ + #define AR934X_RESET_REG_BOOTSTRAP 0xb0 + #define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac + ++#define QCA955X_RESET_REG_BOOTSTRAP 0xb0 ++ + #define MISC_INT_ETHSW BIT(12) + #define MISC_INT_TIMER4 BIT(10) + #define MISC_INT_TIMER3 BIT(9) +@@ -341,6 +378,8 @@ + #define AR934X_BOOTSTRAP_SDRAM_DISABLED BIT(1) + #define AR934X_BOOTSTRAP_DDR1 BIT(0) + ++#define QCA955X_BOOTSTRAP_REF_CLK_40 BIT(4) ++ + #define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0) + #define AR934X_PCIE_WMAC_INT_WMAC_TX BIT(1) + #define AR934X_PCIE_WMAC_INT_WMAC_RXLP BIT(2) diff --git a/target/linux/ar71xx/patches-3.3/163-MIPS-ath79-add-IRQ-handling-code-for-the-QCA955X-SoC.patch b/target/linux/ar71xx/patches-3.3/163-MIPS-ath79-add-IRQ-handling-code-for-the-QCA955X-SoC.patch new file mode 100644 index 000000000..8d24c742d --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/163-MIPS-ath79-add-IRQ-handling-code-for-the-QCA955X-SoC.patch @@ -0,0 +1,239 @@ +From 5d0de52f8e36916485a61b820916b71b5d918e6f Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Jun 2012 13:44:23 +0200 +Subject: [PATCH 19/34] MIPS: ath79: add IRQ handling code for the QCA955X SoCs + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/irq.c | 110 ++++++++++++++++++++++-- + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 32 +++++++ + arch/mips/include/asm/mach-ath79/irq.h | 9 ++- + 3 files changed, 142 insertions(+), 9 deletions(-) + +--- a/arch/mips/ath79/irq.c ++++ b/arch/mips/ath79/irq.c +@@ -130,7 +130,10 @@ static void __init ath79_misc_irq_init(v + + if (soc_is_ar71xx() || soc_is_ar913x()) + ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; +- else if (soc_is_ar724x() || soc_is_ar933x() || soc_is_ar934x()) ++ else if (soc_is_ar724x() || ++ soc_is_ar933x() || ++ soc_is_ar934x() || ++ soc_is_qca955x()) + ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; + else + BUG(); +@@ -177,6 +180,88 @@ static void ar934x_ip2_irq_init(void) + irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar934x_ip2_irq_dispatch); + } + ++static void qca955x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) ++{ ++ u32 status; ++ ++ disable_irq_nosync(irq); ++ ++ status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS); ++ status &= QCA955X_EXT_INT_PCIE_RC1_ALL | QCA955X_EXT_INT_WMAC_ALL; ++ ++ if (status == 0) { ++ spurious_interrupt(); ++ goto enable; ++ } ++ ++ if (status & QCA955X_EXT_INT_PCIE_RC1_ALL) { ++ /* TODO: flush DDR? */ ++ generic_handle_irq(ATH79_IP2_IRQ(0)); ++ } ++ ++ if (status & QCA955X_EXT_INT_WMAC_ALL) { ++ /* TODO: flsuh DDR? */ ++ generic_handle_irq(ATH79_IP2_IRQ(1)); ++ } ++ ++enable: ++ enable_irq(irq); ++} ++ ++static void qca955x_ip3_irq_dispatch(unsigned int irq, struct irq_desc *desc) ++{ ++ u32 status; ++ ++ disable_irq_nosync(irq); ++ ++ status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS); ++ status &= QCA955X_EXT_INT_PCIE_RC2_ALL | ++ QCA955X_EXT_INT_USB1 | ++ QCA955X_EXT_INT_USB2; ++ ++ if (status == 0) { ++ spurious_interrupt(); ++ goto enable; ++ } ++ ++ if (status & QCA955X_EXT_INT_USB1) { ++ /* TODO: flush DDR? */ ++ generic_handle_irq(ATH79_IP3_IRQ(0)); ++ } ++ ++ if (status & QCA955X_EXT_INT_USB2) { ++ /* TODO: flsuh DDR? */ ++ generic_handle_irq(ATH79_IP3_IRQ(1)); ++ } ++ ++ if (status & QCA955X_EXT_INT_PCIE_RC2_ALL) { ++ /* TODO: flush DDR? */ ++ generic_handle_irq(ATH79_IP3_IRQ(2)); ++ } ++ ++enable: ++ enable_irq(irq); ++} ++ ++static void qca955x_irq_init(void) ++{ ++ int i; ++ ++ for (i = ATH79_IP2_IRQ_BASE; ++ i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) ++ irq_set_chip_and_handler(i, &dummy_irq_chip, ++ handle_level_irq); ++ ++ irq_set_chained_handler(ATH79_CPU_IRQ_IP2, qca955x_ip2_irq_dispatch); ++ ++ for (i = ATH79_IP3_IRQ_BASE; ++ i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++) ++ irq_set_chip_and_handler(i, &dummy_irq_chip, ++ handle_level_irq); ++ ++ irq_set_chained_handler(ATH79_CPU_IRQ_IP3, qca955x_ip3_irq_dispatch); ++} ++ + asmlinkage void plat_irq_dispatch(void) + { + unsigned long pending; +@@ -212,6 +297,17 @@ asmlinkage void plat_irq_dispatch(void) + * Issue a flush in the handlers to ensure that the driver sees + * the update. + */ ++ ++static void ath79_default_ip2_handler(void) ++{ ++ do_IRQ(ATH79_CPU_IRQ_IP2); ++} ++ ++static void ath79_default_ip3_handler(void) ++{ ++ do_IRQ(ATH79_CPU_IRQ_USB); ++} ++ + static void ar71xx_ip2_handler(void) + { + ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI); +@@ -236,11 +332,6 @@ static void ar933x_ip2_handler(void) + do_IRQ(ATH79_CPU_IRQ_IP2); + } + +-static void ar934x_ip2_handler(void) +-{ +- do_IRQ(ATH79_CPU_IRQ_IP2); +-} +- + static void ar71xx_ip3_handler(void) + { + ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB); +@@ -286,8 +377,11 @@ void __init arch_init_irq(void) + ath79_ip2_handler = ar933x_ip2_handler; + ath79_ip3_handler = ar933x_ip3_handler; + } else if (soc_is_ar934x()) { +- ath79_ip2_handler = ar934x_ip2_handler; ++ ath79_ip2_handler = ath79_default_ip2_handler; + ath79_ip3_handler = ar934x_ip3_handler; ++ } else if (soc_is_qca955x()) { ++ ath79_ip2_handler = ath79_default_ip2_handler; ++ ath79_ip3_handler = ath79_default_ip3_handler; + } else { + BUG(); + } +@@ -298,4 +392,6 @@ void __init arch_init_irq(void) + + if (soc_is_ar934x()) + ar934x_ip2_irq_init(); ++ else if (soc_is_qca955x()) ++ qca955x_irq_init(); + } +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -300,6 +300,7 @@ + #define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac + + #define QCA955X_RESET_REG_BOOTSTRAP 0xb0 ++#define QCA955X_RESET_REG_EXT_INT_STATUS 0xac + + #define MISC_INT_ETHSW BIT(12) + #define MISC_INT_TIMER4 BIT(10) +@@ -398,6 +399,37 @@ + AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \ + AR934X_PCIE_WMAC_INT_PCIE_RC3) + ++#define QCA955X_EXT_INT_WMAC_MISC BIT(0) ++#define QCA955X_EXT_INT_WMAC_TX BIT(1) ++#define QCA955X_EXT_INT_WMAC_RXLP BIT(2) ++#define QCA955X_EXT_INT_WMAC_RXHP BIT(3) ++#define QCA955X_EXT_INT_PCIE_RC1 BIT(4) ++#define QCA955X_EXT_INT_PCIE_RC1_INT0 BIT(5) ++#define QCA955X_EXT_INT_PCIE_RC1_INT1 BIT(6) ++#define QCA955X_EXT_INT_PCIE_RC1_INT2 BIT(7) ++#define QCA955X_EXT_INT_PCIE_RC1_INT3 BIT(8) ++#define QCA955X_EXT_INT_PCIE_RC2 BIT(12) ++#define QCA955X_EXT_INT_PCIE_RC2_INT0 BIT(13) ++#define QCA955X_EXT_INT_PCIE_RC2_INT1 BIT(14) ++#define QCA955X_EXT_INT_PCIE_RC2_INT2 BIT(15) ++#define QCA955X_EXT_INT_PCIE_RC2_INT3 BIT(16) ++#define QCA955X_EXT_INT_USB1 BIT(24) ++#define QCA955X_EXT_INT_USB2 BIT(28) ++ ++#define QCA955X_EXT_INT_WMAC_ALL \ ++ (QCA955X_EXT_INT_WMAC_MISC | QCA955X_EXT_INT_WMAC_TX | \ ++ QCA955X_EXT_INT_WMAC_RXLP | QCA955X_EXT_INT_WMAC_RXHP) ++ ++#define QCA955X_EXT_INT_PCIE_RC1_ALL \ ++ (QCA955X_EXT_INT_PCIE_RC1 | QCA955X_EXT_INT_PCIE_RC1_INT0 | \ ++ QCA955X_EXT_INT_PCIE_RC1_INT1 | QCA955X_EXT_INT_PCIE_RC1_INT2 | \ ++ QCA955X_EXT_INT_PCIE_RC1_INT3) ++ ++#define QCA955X_EXT_INT_PCIE_RC2_ALL \ ++ (QCA955X_EXT_INT_PCIE_RC2 | QCA955X_EXT_INT_PCIE_RC2_INT0 | \ ++ QCA955X_EXT_INT_PCIE_RC2_INT1 | QCA955X_EXT_INT_PCIE_RC2_INT2 | \ ++ QCA955X_EXT_INT_PCIE_RC2_INT3) ++ + #define REV_ID_MAJOR_MASK 0xfff0 + #define REV_ID_MAJOR_AR71XX 0x00a0 + #define REV_ID_MAJOR_AR913X 0x00b0 +--- a/arch/mips/include/asm/mach-ath79/irq.h ++++ b/arch/mips/include/asm/mach-ath79/irq.h +@@ -10,7 +10,7 @@ + #define __ASM_MACH_ATH79_IRQ_H + + #define MIPS_CPU_IRQ_BASE 0 +-#define NR_IRQS 48 ++#define NR_IRQS 51 + + #define ATH79_MISC_IRQ_BASE 8 + #define ATH79_MISC_IRQ_COUNT 32 +@@ -23,8 +23,13 @@ + #define ATH79_IP2_IRQ_COUNT 2 + #define ATH79_IP2_IRQ(_x) (ATH79_IP2_IRQ_BASE + (_x)) + ++#define ATH79_IP3_IRQ_BASE (ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT) ++#define ATH79_IP3_IRQ_COUNT 3 ++#define ATH79_IP3_IRQ(_x) (ATH79_IP3_IRQ_BASE + (_x)) ++ + #define ATH79_CPU_IRQ_IP2 (MIPS_CPU_IRQ_BASE + 2) +-#define ATH79_CPU_IRQ_USB (MIPS_CPU_IRQ_BASE + 3) ++#define ATH79_CPU_IRQ_IP3 (MIPS_CPU_IRQ_BASE + 3) ++#define ATH79_CPU_IRQ_USB ATH79_CPU_IRQ_IP3 + #define ATH79_CPU_IRQ_GE0 (MIPS_CPU_IRQ_BASE + 4) + #define ATH79_CPU_IRQ_GE1 (MIPS_CPU_IRQ_BASE + 5) + #define ATH79_CPU_IRQ_MISC (MIPS_CPU_IRQ_BASE + 6) diff --git a/target/linux/ar71xx/patches-3.3/164-MIPS-ath79-add-GPIO-setup-code-for-the-QCA955X-SoCs.patch b/target/linux/ar71xx/patches-3.3/164-MIPS-ath79-add-GPIO-setup-code-for-the-QCA955X-SoCs.patch new file mode 100644 index 000000000..dc4251be9 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/164-MIPS-ath79-add-GPIO-setup-code-for-the-QCA955X-SoCs.patch @@ -0,0 +1,39 @@ +From c9a552f3007f0621b2440ae17bad816578299e52 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Jun 2012 13:45:27 +0200 +Subject: [PATCH 20/34] MIPS: ath79: add GPIO setup code for the QCA955X SoCs + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/gpio.c | 4 +++- + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 1 + + 2 files changed, 4 insertions(+), 1 deletions(-) + +--- a/arch/mips/ath79/gpio.c ++++ b/arch/mips/ath79/gpio.c +@@ -196,12 +196,14 @@ void __init ath79_gpio_init(void) + ath79_gpio_count = AR933X_GPIO_COUNT; + else if (soc_is_ar934x()) + ath79_gpio_count = AR934X_GPIO_COUNT; ++ else if (soc_is_qca955x()) ++ ath79_gpio_count = QCA955X_GPIO_COUNT; + else + BUG(); + + ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); + ath79_gpio_chip.ngpio = ath79_gpio_count; +- if (soc_is_ar934x()) { ++ if (soc_is_ar934x() || soc_is_qca955x()) { + ath79_gpio_chip.direction_input = ar934x_gpio_direction_input; + ath79_gpio_chip.direction_output = ar934x_gpio_direction_output; + } +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -506,6 +506,7 @@ + #define AR913X_GPIO_COUNT 22 + #define AR933X_GPIO_COUNT 30 + #define AR934X_GPIO_COUNT 23 ++#define QCA955X_GPIO_COUNT 24 + + /* + * SRIF block diff --git a/target/linux/ar71xx/patches-3.3/165-MIPS-ath79-add-QCA955X-specific-glue-to-ath79_device.patch b/target/linux/ar71xx/patches-3.3/165-MIPS-ath79-add-QCA955X-specific-glue-to-ath79_device.patch new file mode 100644 index 000000000..f3e3b6eec --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/165-MIPS-ath79-add-QCA955X-specific-glue-to-ath79_device.patch @@ -0,0 +1,31 @@ +From 68368e80b4db83afe39664a7d43c8b5c7b8ac3b4 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Jun 2012 13:49:33 +0200 +Subject: [PATCH 21/34] MIPS: ath79: add QCA955X specific glue to ath79_device_reset_{set,clear} + +--- + arch/mips/ath79/common.c | 6 ++++-- + 1 files changed, 4 insertions(+), 2 deletions(-) + +--- a/arch/mips/ath79/common.c ++++ b/arch/mips/ath79/common.c +@@ -70,7 +70,8 @@ void ath79_device_reset_set(u32 mask) + reg = AR913X_RESET_REG_RESET_MODULE; + else if (soc_is_ar933x()) + reg = AR933X_RESET_REG_RESET_MODULE; +- else if (soc_is_ar934x()) ++ else if (soc_is_ar934x() || ++ soc_is_qca955x()) + reg = AR934X_RESET_REG_RESET_MODULE; + else + BUG(); +@@ -96,7 +97,8 @@ void ath79_device_reset_clear(u32 mask) + reg = AR913X_RESET_REG_RESET_MODULE; + else if (soc_is_ar933x()) + reg = AR933X_RESET_REG_RESET_MODULE; +- else if (soc_is_ar934x()) ++ else if (soc_is_ar934x() || ++ soc_is_qca955x()) + reg = AR934X_RESET_REG_RESET_MODULE; + else + BUG(); diff --git a/target/linux/ar71xx/patches-3.3/166-MIPS-ath79-register-UART-for-the-QCA955X-SoCs.patch b/target/linux/ar71xx/patches-3.3/166-MIPS-ath79-register-UART-for-the-QCA955X-SoCs.patch new file mode 100644 index 000000000..aacb8bbeb --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/166-MIPS-ath79-register-UART-for-the-QCA955X-SoCs.patch @@ -0,0 +1,22 @@ +From f7d7b362b51c51c1ae80bb7ade2039d6f74d4070 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Jun 2012 13:46:26 +0200 +Subject: [PATCH 22/34] MIPS: ath79: register UART for the QCA955X SoCs + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/dev-common.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +--- a/arch/mips/ath79/dev-common.c ++++ b/arch/mips/ath79/dev-common.c +@@ -90,7 +90,8 @@ void __init ath79_register_uart(void) + if (soc_is_ar71xx() || + soc_is_ar724x() || + soc_is_ar913x() || +- soc_is_ar934x()) { ++ soc_is_ar934x() || ++ soc_is_qca955x()) { + ath79_uart_data[0].uartclk = clk_get_rate(clk); + platform_device_register(&ath79_uart_device); + } else if (soc_is_ar933x()) { diff --git a/target/linux/ar71xx/patches-3.3/167-MIPS-ath79-add-USB-controller-registration-code-for-.patch b/target/linux/ar71xx/patches-3.3/167-MIPS-ath79-add-USB-controller-registration-code-for-.patch new file mode 100644 index 000000000..5a27a9b71 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/167-MIPS-ath79-add-USB-controller-registration-code-for-.patch @@ -0,0 +1,93 @@ +From e4ba5e2bffd1f373f57dd692233aa6b7b46ae76c Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Jun 2012 13:47:35 +0200 +Subject: [PATCH 23/34] MIPS: ath79: add USB controller registration code for the QCA955X SoCs + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/dev-usb.c | 46 ++++++++++++++++++++++++ + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 4 ++ + 2 files changed, 50 insertions(+), 0 deletions(-) + +--- a/arch/mips/ath79/dev-usb.c ++++ b/arch/mips/ath79/dev-usb.c +@@ -75,6 +75,8 @@ static void __init ath79_usb_init_resour + unsigned long size, + int irq) + { ++ memset(res, 0, sizeof(res)); ++ + res[0].flags = IORESOURCE_MEM; + res[0].start = base; + res[0].end = base + size - 1; +@@ -219,6 +221,48 @@ static void __init ar934x_usb_setup(void + platform_device_register(&ath79_ehci_device); + } + ++static void __init qca955x_usb_setup(void) ++{ ++ struct platform_device *pdev; ++ ++ ath79_usb_init_resource(ath79_ehci_resources, ++ QCA955X_EHCI0_BASE, QCA955X_EHCI_SIZE, ++ ATH79_IP3_IRQ(0)); ++ ++ pdev = platform_device_register_resndata(NULL, "ehci-platform", 0, ++ ath79_ehci_resources, ++ ARRAY_SIZE(ath79_ehci_resources), ++ &ath79_ehci_pdata_v2, ++ sizeof(ath79_ehci_pdata_v2)); ++ if (IS_ERR(pdev)) { ++ pr_err("Unable to register USB %d device, err=%d\n", 0, ++ (int) PTR_ERR(pdev)); ++ return; ++ } ++ ++ pdev->dev.dma_mask = &ath79_ehci_dmamask; ++ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); ++ ++ ath79_usb_init_resource(ath79_ehci_resources, ++ QCA955X_EHCI1_BASE, QCA955X_EHCI_SIZE, ++ ATH79_IP3_IRQ(1)); ++ ++ pdev = platform_device_register_resndata(NULL, "ehci-platform", 1, ++ ath79_ehci_resources, ++ ARRAY_SIZE(ath79_ehci_resources), ++ &ath79_ehci_pdata_v2, ++ sizeof(ath79_ehci_pdata_v2)); ++ ++ if (IS_ERR(pdev)) { ++ pr_err("Unable to register USB %d device, err=%d\n", 1, ++ (int) PTR_ERR(pdev)); ++ return; ++ } ++ ++ pdev->dev.dma_mask = &ath79_ehci_dmamask; ++ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); ++} ++ + void __init ath79_register_usb(void) + { + if (soc_is_ar71xx()) +@@ -233,6 +277,8 @@ void __init ath79_register_usb(void) + ar933x_usb_setup(); + else if (soc_is_ar934x()) + ar934x_usb_setup(); ++ else if (soc_is_qca955x()) ++ qca955x_usb_setup(); + else + BUG(); + } +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -94,6 +94,10 @@ + #define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000) + #define AR934X_SRIF_SIZE 0x1000 + ++#define QCA955X_EHCI0_BASE 0x1b000000 ++#define QCA955X_EHCI1_BASE 0x1b400000 ++#define QCA955X_EHCI_SIZE 0x200 ++ + /* + * DDR_CTRL block + */ diff --git a/target/linux/ar71xx/patches-3.3/168-MIPS-ath79-add-WMAC-registration-code-for-the-QCA955.patch b/target/linux/ar71xx/patches-3.3/168-MIPS-ath79-add-WMAC-registration-code-for-the-QCA955.patch new file mode 100644 index 000000000..efc354e9d --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/168-MIPS-ath79-add-WMAC-registration-code-for-the-QCA955.patch @@ -0,0 +1,70 @@ +From 0568e7f92ecf2bfd2af0a5c59b1249fef002c89f Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Tue, 3 Jul 2012 10:24:43 +0200 +Subject: [PATCH 24/34] MIPS: ath79: add WMAC registration code for the QCA955X SoCs + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/Kconfig | 2 +- + arch/mips/ath79/dev-wmac.c | 20 ++++++++++++++++++++ + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 2 ++ + 3 files changed, 23 insertions(+), 1 deletions(-) + +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -108,7 +108,7 @@ config ATH79_DEV_USB + def_bool n + + config ATH79_DEV_WMAC +- depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X) ++ depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA955X) + def_bool n + + endif +--- a/arch/mips/ath79/dev-wmac.c ++++ b/arch/mips/ath79/dev-wmac.c +@@ -116,6 +116,24 @@ static void ar934x_wmac_setup(void) + ath79_wmac_data.is_clk_25mhz = true; + } + ++static void qca955x_wmac_setup(void) ++{ ++ u32 t; ++ ++ ath79_wmac_device.name = "qca955x_wmac"; ++ ++ ath79_wmac_resources[0].start = QCA955X_WMAC_BASE; ++ ath79_wmac_resources[0].end = QCA955X_WMAC_BASE + QCA955X_WMAC_SIZE - 1; ++ ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); ++ ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); ++ ++ t = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); ++ if (t & QCA955X_BOOTSTRAP_REF_CLK_40) ++ ath79_wmac_data.is_clk_25mhz = false; ++ else ++ ath79_wmac_data.is_clk_25mhz = true; ++} ++ + void __init ath79_register_wmac(u8 *cal_data) + { + if (soc_is_ar913x()) +@@ -124,6 +142,8 @@ void __init ath79_register_wmac(u8 *cal_ + ar933x_wmac_setup(); + else if (soc_is_ar934x()) + ar934x_wmac_setup(); ++ else if (soc_is_qca955x()) ++ qca955x_wmac_setup(); + else + BUG(); + +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -94,6 +94,8 @@ + #define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000) + #define AR934X_SRIF_SIZE 0x1000 + ++#define QCA955X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) ++#define QCA955X_WMAC_SIZE 0x20000 + #define QCA955X_EHCI0_BASE 0x1b000000 + #define QCA955X_EHCI1_BASE 0x1b400000 + #define QCA955X_EHCI_SIZE 0x200 diff --git a/target/linux/ar71xx/patches-3.3/169-MIPS-ath79-allow-to-specify-bus-number-in-PCI-IRQ-ma.patch b/target/linux/ar71xx/patches-3.3/169-MIPS-ath79-allow-to-specify-bus-number-in-PCI-IRQ-ma.patch new file mode 100644 index 000000000..bd95d718b --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/169-MIPS-ath79-allow-to-specify-bus-number-in-PCI-IRQ-ma.patch @@ -0,0 +1,34 @@ +From 12c68e4fccadc22a0470177141a57892a76e4a2b Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Jun 2012 15:33:16 +0200 +Subject: [PATCH 25/34] MIPS: ath79: allow to specify bus number in PCI IRQ maps + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/pci.c | 4 +++- + arch/mips/ath79/pci.h | 1 + + 2 files changed, 4 insertions(+), 1 deletions(-) + +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -75,7 +75,9 @@ int __init pcibios_map_irq(const struct + const struct ath79_pci_irq *entry; + + entry = &ath79_pci_irq_map[i]; +- if (entry->slot == slot && entry->pin == pin) { ++ if (entry->bus == dev->bus->number && ++ entry->slot == slot && ++ entry->pin == pin) { + irq = entry->irq; + break; + } +--- a/arch/mips/ath79/pci.h ++++ b/arch/mips/ath79/pci.h +@@ -14,6 +14,7 @@ + #define _ATH79_PCI_H + + struct ath79_pci_irq { ++ int bus; + u8 slot; + u8 pin; + int irq; diff --git a/target/linux/ar71xx/patches-3.3/170-MIPS-ath79-add-PCI-controller-registration-code-for-.patch b/target/linux/ar71xx/patches-3.3/170-MIPS-ath79-add-PCI-controller-registration-code-for-.patch new file mode 100644 index 000000000..0c3889fdb --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/170-MIPS-ath79-add-PCI-controller-registration-code-for-.patch @@ -0,0 +1,103 @@ +From 8bb54348722216a1dd6905d9d031ebdaa3a544a4 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Jun 2012 23:05:20 +0200 +Subject: [PATCH 26/34] MIPS: ath79: add PCI controller registration code for the QCA9558 SoC + +--- + arch/mips/ath79/Kconfig | 2 + + arch/mips/ath79/pci.c | 36 ++++++++++++++++++++++++ + arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 13 ++++++++ + 3 files changed, 51 insertions(+), 0 deletions(-) + +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -90,6 +90,8 @@ config SOC_AR934X + + config SOC_QCA955X + select USB_ARCH_HAS_EHCI ++ select HW_HAS_PCI ++ select PCI_AR724X if PCI + def_bool n + + config PCI_AR724X +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -49,6 +49,21 @@ static const struct ath79_pci_irq ar724x + } + }; + ++static const struct ath79_pci_irq qca955x_pci_irq_map[] __initconst = { ++ { ++ .bus = 0, ++ .slot = 0, ++ .pin = 1, ++ .irq = ATH79_PCI_IRQ(0), ++ }, ++ { ++ .bus = 1, ++ .slot = 0, ++ .pin = 1, ++ .irq = ATH79_PCI_IRQ(1), ++ }, ++}; ++ + int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) + { + int irq = -1; +@@ -64,6 +79,9 @@ int __init pcibios_map_irq(const struct + soc_is_ar9344()) { + ath79_pci_irq_map = ar724x_pci_irq_map; + ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map); ++ } else if (soc_is_qca955x()) { ++ ath79_pci_irq_map = qca955x_pci_irq_map; ++ ath79_pci_nr_irqs = ARRAY_SIZE(qca955x_pci_irq_map); + } else { + pr_crit("pci %s: invalid irq map\n", + pci_name((struct pci_dev *) dev)); +@@ -215,6 +233,24 @@ int __init ath79_register_pci(void) + AR724X_PCI_MEM_SIZE, + 0, + ATH79_IP2_IRQ(0)); ++ } else if (soc_is_qca9558()) { ++ pdev = ath79_register_pci_ar724x(0, ++ QCA955X_PCI_CFG_BASE0, ++ QCA955X_PCI_CTRL_BASE0, ++ QCA955X_PCI_CRP_BASE0, ++ QCA955X_PCI_MEM_BASE0, ++ QCA955X_PCI_MEM_SIZE, ++ 0, ++ ATH79_IP2_IRQ(0)); ++ ++ pdev = ath79_register_pci_ar724x(1, ++ QCA955X_PCI_CFG_BASE1, ++ QCA955X_PCI_CTRL_BASE1, ++ QCA955X_PCI_CRP_BASE1, ++ QCA955X_PCI_MEM_BASE1, ++ QCA955X_PCI_MEM_SIZE, ++ 1, ++ ATH79_IP3_IRQ(2)); + } else { + /* No PCI support */ + return -ENODEV; +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -94,6 +94,19 @@ + #define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000) + #define AR934X_SRIF_SIZE 0x1000 + ++#define QCA955X_PCI_MEM_BASE0 0x10000000 ++#define QCA955X_PCI_MEM_BASE1 0x12000000 ++#define QCA955X_PCI_MEM_SIZE 0x02000000 ++#define QCA955X_PCI_CFG_BASE0 0x14000000 ++#define QCA955X_PCI_CFG_BASE1 0x16000000 ++#define QCA955X_PCI_CFG_SIZE 0x1000 ++#define QCA955X_PCI_CRP_BASE0 (AR71XX_APB_BASE + 0x000c0000) ++#define QCA955X_PCI_CRP_BASE1 (AR71XX_APB_BASE + 0x00250000) ++#define QCA955X_PCI_CRP_SIZE 0x1000 ++#define QCA955X_PCI_CTRL_BASE0 (AR71XX_APB_BASE + 0x000f0000) ++#define QCA955X_PCI_CTRL_BASE1 (AR71XX_APB_BASE + 0x00280000) ++#define QCA955X_PCI_CTRL_SIZE 0x100 ++ + #define QCA955X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) + #define QCA955X_WMAC_SIZE 0x20000 + #define QCA955X_EHCI0_BASE 0x1b000000 diff --git a/target/linux/ar71xx/patches-3.3/171-MIPS-ath79-add-support-for-the-Qualcomm-Atheros-AP13.patch b/target/linux/ar71xx/patches-3.3/171-MIPS-ath79-add-support-for-the-Qualcomm-Atheros-AP13.patch new file mode 100644 index 000000000..dc26f9c7b --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/171-MIPS-ath79-add-support-for-the-Qualcomm-Atheros-AP13.patch @@ -0,0 +1,213 @@ +From a034da3e4d4960266a94d15c811d5f4529fdff44 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Jun 2012 13:52:23 +0200 +Subject: [PATCH 27/34] MIPS: ath79: add support for the Qualcomm Atheros AP136 board + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/Kconfig | 12 +++ + arch/mips/ath79/Makefile | 1 + + arch/mips/ath79/mach-ap136.c | 155 ++++++++++++++++++++++++++++++++++++++++++ + arch/mips/ath79/machtypes.h | 1 + + 4 files changed, 169 insertions(+), 0 deletions(-) + create mode 100644 arch/mips/ath79/mach-ap136.c + +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -14,6 +14,18 @@ config ATH79_MACH_AP121 + Say 'Y' here if you want your kernel to support the + Atheros AP121 reference board. + ++config ATH79_MACH_AP136 ++ bool "Atheros AP136 reference board" ++ select SOC_QCA955X ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_SPI ++ select ATH79_DEV_USB ++ select ATH79_DEV_WMAC ++ help ++ Say 'Y' here if you want your kernel to support the ++ Atheros AP136 reference board. ++ + config ATH79_MACH_AP81 + bool "Atheros AP81 reference board" + select SOC_AR913X +--- a/arch/mips/ath79/Makefile ++++ b/arch/mips/ath79/Makefile +@@ -27,6 +27,7 @@ obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wma + # Machines + # + obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o ++obj-$(CONFIG_ATH79_MACH_AP136) += mach-ap136.o + obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o + obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o + obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o +--- /dev/null ++++ b/arch/mips/ath79/mach-ap136.c +@@ -0,0 +1,155 @@ ++/* ++ * Qualcomm Atheros AP136 reference board support ++ * ++ * Copyright (c) 2012 Qualcomm Atheros ++ * Copyright (c) 2012 Gabor Juhos ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ */ ++ ++#include ++#include ++ ++#include "machtypes.h" ++#include "dev-gpio-buttons.h" ++#include "dev-leds-gpio.h" ++#include "dev-spi.h" ++#include "dev-usb.h" ++#include "dev-wmac.h" ++#include "pci.h" ++ ++#define AP136_GPIO_LED_STATUS_RED 14 ++#define AP136_GPIO_LED_STATUS_GREEN 19 ++#define AP136_GPIO_LED_USB 4 ++#define AP136_GPIO_LED_WLAN_2G 13 ++#define AP136_GPIO_LED_WLAN_5G 12 ++#define AP136_GPIO_LED_WPS_RED 15 ++#define AP136_GPIO_LED_WPS_GREEN 20 ++ ++#define AP136_GPIO_BTN_WPS 16 ++#define AP136_GPIO_BTN_RFKILL 21 ++ ++#define AP136_KEYS_POLL_INTERVAL 20 /* msecs */ ++#define AP136_KEYS_DEBOUNCE_INTERVAL (3 * AP136_KEYS_POLL_INTERVAL) ++ ++#define AP136_WMAC_CALDATA_OFFSET 0x1000 ++#define AP136_PCIE_CALDATA_OFFSET 0x5000 ++ ++static struct gpio_led ap136_leds_gpio[] __initdata = { ++ { ++ .name = "ap136:green:status", ++ .gpio = AP136_GPIO_LED_STATUS_GREEN, ++ .active_low = 1, ++ }, ++ { ++ .name = "ap136:red:status", ++ .gpio = AP136_GPIO_LED_STATUS_RED, ++ .active_low = 1, ++ }, ++ { ++ .name = "ap136:green:wps", ++ .gpio = AP136_GPIO_LED_WPS_GREEN, ++ .active_low = 1, ++ }, ++ { ++ .name = "ap136:red:wps", ++ .gpio = AP136_GPIO_LED_WPS_RED, ++ .active_low = 1, ++ }, ++ { ++ .name = "ap136:red:wlan-2g", ++ .gpio = AP136_GPIO_LED_WLAN_2G, ++ .active_low = 1, ++ }, ++ { ++ .name = "ap136:red:usb", ++ .gpio = AP136_GPIO_LED_USB, ++ .active_low = 1, ++ } ++}; ++ ++static struct gpio_keys_button ap136_gpio_keys[] __initdata = { ++ { ++ .desc = "WPS button", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = AP136_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP136_GPIO_BTN_WPS, ++ .active_low = 1, ++ }, ++ { ++ .desc = "RFKILL button", ++ .type = EV_KEY, ++ .code = KEY_RFKILL, ++ .debounce_interval = AP136_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP136_GPIO_BTN_RFKILL, ++ .active_low = 1, ++ }, ++}; ++ ++static struct spi_board_info ap136_spi_info[] = { ++ { ++ .bus_num = 0, ++ .chip_select = 0, ++ .max_speed_hz = 25000000, ++ .modalias = "mx25l6405d", ++ } ++}; ++ ++static struct ath79_spi_platform_data ap136_spi_data = { ++ .bus_num = 0, ++ .num_chipselect = 1, ++}; ++ ++#ifdef CONFIG_PCI ++static struct ath9k_platform_data ap136_ath9k_data; ++ ++static int ap136_pci_plat_dev_init(struct pci_dev *dev) ++{ ++ if (dev->bus->number == 1 && (PCI_SLOT(dev->devfn)) == 0) ++ dev->dev.platform_data = &ap136_ath9k_data; ++ ++ return 0; ++} ++ ++static void __init ap136_pci_init(u8 *eeprom) ++{ ++ memcpy(ap136_ath9k_data.eeprom_data, eeprom, ++ sizeof(ap136_ath9k_data.eeprom_data)); ++ ++ ath79_pci_set_plat_dev_init(ap136_pci_plat_dev_init); ++ ath79_register_pci(); ++} ++#else ++static inline void ap136_pci_init(void) {} ++#endif /* CONFIG_PCI */ ++ ++static void __init ap136_setup(void) ++{ ++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); ++ ++ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap136_leds_gpio), ++ ap136_leds_gpio); ++ ath79_register_gpio_keys_polled(-1, AP136_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ap136_gpio_keys), ++ ap136_gpio_keys); ++ ath79_register_spi(&ap136_spi_data, ap136_spi_info, ++ ARRAY_SIZE(ap136_spi_info)); ++ ath79_register_usb(); ++ ath79_register_wmac(art + AP136_WMAC_CALDATA_OFFSET); ++ ap136_pci_init(art + AP136_PCIE_CALDATA_OFFSET); ++} ++ ++MIPS_MACHINE(ATH79_MACH_AP136, "AP136", "Atheros AP136 reference board", ++ ap136_setup); +--- a/arch/mips/ath79/machtypes.h ++++ b/arch/mips/ath79/machtypes.h +@@ -17,6 +17,7 @@ + enum ath79_mach_type { + ATH79_MACH_GENERIC = 0, + ATH79_MACH_AP121, /* Atheros AP121 reference board */ ++ ATH79_MACH_AP136, /* Atheros AP136 reference board */ + ATH79_MACH_AP81, /* Atheros AP81 reference board */ + ATH79_MACH_DB120, /* Atheros DB120 reference board */ + ATH79_MACH_PB44, /* Atheros PB44 reference board */ diff --git a/target/linux/ar71xx/patches-3.3/200-spi-ath79-add-delay-between-SCK-changes.patch b/target/linux/ar71xx/patches-3.3/200-spi-ath79-add-delay-between-SCK-changes.patch new file mode 100644 index 000000000..28cc1fbe9 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/200-spi-ath79-add-delay-between-SCK-changes.patch @@ -0,0 +1,122 @@ +From cbb3ade4765bc715b5c2eae4a7b6eaf3ff7ad958 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 11 Jan 2012 20:06:35 +0100 +Subject: [PATCH 28/34] spi/ath79: add delay between SCK changes + +The driver uses the "as fast as it can" approach +to drive the SCK signal. However this does not +work with certain low speed SPI chips (e.g. the +PCF2123 RTC chip). Add per-bit slowdowns in order +to be able to use the driver with such chips as +well. + +Signed-off-by: Gabor Juhos +--- + drivers/spi/spi-ath79.c | 44 +++++++++++++++++++++++++++++++++++++++++++- + 1 files changed, 43 insertions(+), 1 deletions(-) + +--- a/drivers/spi/spi-ath79.c ++++ b/drivers/spi/spi-ath79.c +@@ -24,17 +24,24 @@ + #include + #include + #include ++#include ++#include + + #include + #include + + #define DRV_NAME "ath79-spi" + ++#define ATH79_SPI_RRW_DELAY_FACTOR 12000 ++#define MHZ (1000 * 1000) ++ + struct ath79_spi { + struct spi_bitbang bitbang; + u32 ioc_base; + u32 reg_ctrl; + void __iomem *base; ++ struct clk *clk; ++ unsigned rrw_delay; + }; + + static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned reg) +@@ -52,6 +59,12 @@ static inline struct ath79_spi *ath79_sp + return spi_master_get_devdata(spi->master); + } + ++static inline void ath79_spi_delay(struct ath79_spi *sp, unsigned nsecs) ++{ ++ if (nsecs > sp->rrw_delay) ++ ndelay(nsecs - sp->rrw_delay); ++} ++ + static void ath79_spi_chipselect(struct spi_device *spi, int is_active) + { + struct ath79_spi *sp = ath79_spidev_to_sp(spi); +@@ -184,7 +197,9 @@ static u32 ath79_spi_txrx_mode0(struct s + + /* setup MSB (to slave) on trailing edge */ + ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out); ++ ath79_spi_delay(sp, nsecs); + ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out | AR71XX_SPI_IOC_CLK); ++ ath79_spi_delay(sp, nsecs); + + word <<= 1; + } +@@ -198,6 +213,7 @@ static __devinit int ath79_spi_probe(str + struct ath79_spi *sp; + struct ath79_spi_platform_data *pdata; + struct resource *r; ++ unsigned long rate; + int ret; + + master = spi_alloc_master(&pdev->dev, sizeof(*sp)); +@@ -239,12 +255,36 @@ static __devinit int ath79_spi_probe(str + goto err_put_master; + } + ++ sp->clk = clk_get(&pdev->dev, "ahb"); ++ if (IS_ERR(sp->clk)) { ++ ret = PTR_ERR(sp->clk); ++ goto err_unmap; ++ } ++ ++ ret = clk_enable(sp->clk); ++ if (ret) ++ goto err_clk_put; ++ ++ rate = DIV_ROUND_UP(clk_get_rate(sp->clk), MHZ); ++ if (!rate) { ++ ret = -EINVAL; ++ goto err_clk_disable; ++ } ++ ++ sp->rrw_delay = ATH79_SPI_RRW_DELAY_FACTOR / rate; ++ dev_dbg(&pdev->dev, "register read/write delay is %u nsecs\n", ++ sp->rrw_delay); ++ + ret = spi_bitbang_start(&sp->bitbang); + if (ret) +- goto err_unmap; ++ goto err_clk_disable; + + return 0; + ++err_clk_disable: ++ clk_disable(sp->clk); ++err_clk_put: ++ clk_put(sp->clk); + err_unmap: + iounmap(sp->base); + err_put_master: +@@ -259,6 +299,8 @@ static __devexit int ath79_spi_remove(st + struct ath79_spi *sp = platform_get_drvdata(pdev); + + spi_bitbang_stop(&sp->bitbang); ++ clk_disable(sp->clk); ++ clk_put(sp->clk); + iounmap(sp->base); + platform_set_drvdata(pdev, NULL); + spi_master_put(sp->bitbang.master); diff --git a/target/linux/ar71xx/patches-3.3/201-spi-ath79-add-missing-HIGH-LOW-SCK-transition.patch b/target/linux/ar71xx/patches-3.3/201-spi-ath79-add-missing-HIGH-LOW-SCK-transition.patch new file mode 100644 index 000000000..fd3d9689a --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/201-spi-ath79-add-missing-HIGH-LOW-SCK-transition.patch @@ -0,0 +1,21 @@ +From bcb0fdebc08f828b54d0a2eb74a9d1378701a8e0 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 11 Jan 2012 20:33:41 +0100 +Subject: [PATCH 29/34] spi/ath79: add missing HIGH->LOW SCK transition + +Signed-off-by: Gabor Juhos +--- + drivers/spi/spi-ath79.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +--- a/drivers/spi/spi-ath79.c ++++ b/drivers/spi/spi-ath79.c +@@ -200,6 +200,8 @@ static u32 ath79_spi_txrx_mode0(struct s + ath79_spi_delay(sp, nsecs); + ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out | AR71XX_SPI_IOC_CLK); + ath79_spi_delay(sp, nsecs); ++ if (bits == 1) ++ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out); + + word <<= 1; + } diff --git a/target/linux/ar71xx/patches-3.3/202-spi-ath79-remove-superfluous-chip-select-code.patch b/target/linux/ar71xx/patches-3.3/202-spi-ath79-remove-superfluous-chip-select-code.patch new file mode 100644 index 000000000..eec3293d9 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/202-spi-ath79-remove-superfluous-chip-select-code.patch @@ -0,0 +1,30 @@ +From 06752f9b169493cd1323f8337c147ad2dd31025c Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 9 Jan 2012 15:03:28 +0100 +Subject: [PATCH 30/34] spi/ath79: remove superfluous chip select code + +The spi_bitbang driver calls the chipselect function +of the driver from spi_bitbang_setup in order to +deselect the given SPI chip, so we don't have to +initialize the CS line here. + +Signed-off-by: Gabor Juhos +--- + drivers/spi/spi-ath79.c | 6 ------ + 1 files changed, 0 insertions(+), 6 deletions(-) + +--- a/drivers/spi/spi-ath79.c ++++ b/drivers/spi/spi-ath79.c +@@ -128,12 +128,6 @@ static int ath79_spi_setup_cs(struct spi + gpio_free(cdata->gpio); + return status; + } +- } else { +- if (spi->mode & SPI_CS_HIGH) +- sp->ioc_base |= AR71XX_SPI_IOC_CS0; +- else +- sp->ioc_base &= ~AR71XX_SPI_IOC_CS0; +- ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); + } + + return 0; diff --git a/target/linux/ar71xx/patches-3.3/203-spi-ath79-use-gpio_request_one.patch b/target/linux/ar71xx/patches-3.3/203-spi-ath79-use-gpio_request_one.patch new file mode 100644 index 000000000..12559bcae --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/203-spi-ath79-use-gpio_request_one.patch @@ -0,0 +1,56 @@ +From 6bd876a46b977643f27d2cc63f49e1bc84b78134 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 9 Jan 2012 15:04:21 +0100 +Subject: [PATCH 31/34] spi/ath79: use gpio_request_one + +Use gpio_request_one() instead of multiple gpiolib calls. + +Signed-off-by: Gabor Juhos +--- + drivers/spi/spi-ath79.c | 26 +++++++++++++------------- + 1 files changed, 13 insertions(+), 13 deletions(-) + +--- a/drivers/spi/spi-ath79.c ++++ b/drivers/spi/spi-ath79.c +@@ -100,6 +100,7 @@ static int ath79_spi_setup_cs(struct spi + { + struct ath79_spi *sp = ath79_spidev_to_sp(spi); + struct ath79_spi_controller_data *cdata; ++ int status; + + cdata = spi->controller_data; + if (spi->chip_select && !cdata) +@@ -115,22 +116,21 @@ static int ath79_spi_setup_cs(struct spi + /* TODO: setup speed? */ + ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43); + ++ status = 0; + if (spi->chip_select) { +- int status = 0; ++ unsigned long flags; + +- status = gpio_request(cdata->gpio, dev_name(&spi->dev)); +- if (status) +- return status; +- +- status = gpio_direction_output(cdata->gpio, +- spi->mode & SPI_CS_HIGH); +- if (status) { +- gpio_free(cdata->gpio); +- return status; +- } ++ flags = GPIOF_DIR_OUT; ++ if (spi->mode & SPI_CS_HIGH) ++ flags |= GPIOF_INIT_HIGH; ++ else ++ flags |= GPIOF_INIT_LOW; ++ ++ status = gpio_request_one(cdata->gpio, flags, ++ dev_name(&spi->dev)); + } + +- return 0; ++ return status; + } + + static void ath79_spi_cleanup_cs(struct spi_device *spi) diff --git a/target/linux/ar71xx/patches-3.3/204-spi-ath79-avoid-multiple-initialization-of-the-SPI-c.patch b/target/linux/ar71xx/patches-3.3/204-spi-ath79-avoid-multiple-initialization-of-the-SPI-c.patch new file mode 100644 index 000000000..084bd98bb --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/204-spi-ath79-avoid-multiple-initialization-of-the-SPI-c.patch @@ -0,0 +1,108 @@ +From e63ceaa0c4f7be0498cd452981073d3ce8e7d1f5 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 9 Jan 2012 15:00:46 +0100 +Subject: [PATCH 32/34] spi/ath79: avoid multiple initialization of the SPI controller + +Currently we are initializing the SPI controller in +the chip select line function, and that function is +called once for each SPI device on the bus. If a +board has multiple SPI devices, the controller will +be initialized multiple times. + +Introduce ath79_spi_{en,dis}able helper functions, +and call those from probe/response in order to avoid +the mutliple initialization of the controller. + +Signed-off-by: Gabor Juhos +--- + drivers/spi/spi-ath79.c | 41 ++++++++++++++++++++++++----------------- + 1 files changed, 24 insertions(+), 17 deletions(-) + +--- a/drivers/spi/spi-ath79.c ++++ b/drivers/spi/spi-ath79.c +@@ -96,16 +96,8 @@ static void ath79_spi_chipselect(struct + + } + +-static int ath79_spi_setup_cs(struct spi_device *spi) ++static void ath79_spi_enable(struct ath79_spi *sp) + { +- struct ath79_spi *sp = ath79_spidev_to_sp(spi); +- struct ath79_spi_controller_data *cdata; +- int status; +- +- cdata = spi->controller_data; +- if (spi->chip_select && !cdata) +- return -EINVAL; +- + /* enable GPIO mode */ + ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO); + +@@ -115,6 +107,24 @@ static int ath79_spi_setup_cs(struct spi + + /* TODO: setup speed? */ + ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43); ++} ++ ++static void ath79_spi_disable(struct ath79_spi *sp) ++{ ++ /* restore CTRL register */ ++ ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl); ++ /* disable GPIO mode */ ++ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0); ++} ++ ++static int ath79_spi_setup_cs(struct spi_device *spi) ++{ ++ struct ath79_spi_controller_data *cdata; ++ int status; ++ ++ cdata = spi->controller_data; ++ if (spi->chip_select && !cdata) ++ return -EINVAL; + + status = 0; + if (spi->chip_select) { +@@ -135,17 +145,10 @@ static int ath79_spi_setup_cs(struct spi + + static void ath79_spi_cleanup_cs(struct spi_device *spi) + { +- struct ath79_spi *sp = ath79_spidev_to_sp(spi); +- + if (spi->chip_select) { + struct ath79_spi_controller_data *cdata = spi->controller_data; + gpio_free(cdata->gpio); + } +- +- /* restore CTRL register */ +- ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl); +- /* disable GPIO mode */ +- ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0); + } + + static int ath79_spi_setup(struct spi_device *spi) +@@ -271,12 +274,15 @@ static __devinit int ath79_spi_probe(str + dev_dbg(&pdev->dev, "register read/write delay is %u nsecs\n", + sp->rrw_delay); + ++ ath79_spi_enable(sp); + ret = spi_bitbang_start(&sp->bitbang); + if (ret) +- goto err_clk_disable; ++ goto err_disable; + + return 0; + ++err_disable: ++ ath79_spi_disable(sp); + err_clk_disable: + clk_disable(sp->clk); + err_clk_put: +@@ -295,6 +301,7 @@ static __devexit int ath79_spi_remove(st + struct ath79_spi *sp = platform_get_drvdata(pdev); + + spi_bitbang_stop(&sp->bitbang); ++ ath79_spi_disable(sp); + clk_disable(sp->clk); + clk_put(sp->clk); + iounmap(sp->base); diff --git a/target/linux/ar71xx/patches-3.3/205-spi-ath79-add-shutdown-handler.patch b/target/linux/ar71xx/patches-3.3/205-spi-ath79-add-shutdown-handler.patch new file mode 100644 index 000000000..a1461ceae --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/205-spi-ath79-add-shutdown-handler.patch @@ -0,0 +1,45 @@ +From dab305def68a9ea28c1c0ca2fc20bba645944914 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 11 Jan 2012 22:19:32 +0100 +Subject: [PATCH 33/34] spi/ath79: add shutdown handler + +Signed-off-by: Gabor Juhos +--- + drivers/spi/spi-ath79.c | 12 +++++++++++- + 1 files changed, 11 insertions(+), 1 deletions(-) + +--- a/drivers/spi/spi-ath79.c ++++ b/drivers/spi/spi-ath79.c +@@ -296,7 +296,7 @@ err_put_master: + return ret; + } + +-static __devexit int ath79_spi_remove(struct platform_device *pdev) ++static void __ath79_spi_remove(struct platform_device *pdev) + { + struct ath79_spi *sp = platform_get_drvdata(pdev); + +@@ -307,13 +307,23 @@ static __devexit int ath79_spi_remove(st + iounmap(sp->base); + platform_set_drvdata(pdev, NULL); + spi_master_put(sp->bitbang.master); ++} + ++static __devexit int ath79_spi_remove(struct platform_device *pdev) ++{ ++ __ath79_spi_remove(pdev); + return 0; + } + ++static void ath79_spi_shutdown(struct platform_device *pdev) ++{ ++ __ath79_spi_remove(pdev); ++} ++ + static struct platform_driver ath79_spi_driver = { + .probe = ath79_spi_probe, + .remove = __devexit_p(ath79_spi_remove), ++ .shutdown = ath79_spi_shutdown, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, diff --git a/target/linux/ar71xx/patches-3.3/206-spi-ath79-make-chipselect-logic-more-flexible.patch b/target/linux/ar71xx/patches-3.3/206-spi-ath79-make-chipselect-logic-more-flexible.patch new file mode 100644 index 000000000..5a4c0df5d --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/206-spi-ath79-make-chipselect-logic-more-flexible.patch @@ -0,0 +1,313 @@ +From 7008284716403237f6bc7d7590b3ed073555bd56 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 11 Jan 2012 22:25:11 +0100 +Subject: [PATCH 34/34] spi/ath79: make chipselect logic more flexible + +Signed-off-by: Gabor Juhos +--- + arch/mips/ath79/mach-ap121.c | 6 ++ + arch/mips/ath79/mach-ap136.c | 6 ++ + arch/mips/ath79/mach-ap81.c | 6 ++ + arch/mips/ath79/mach-db120.c | 6 ++ + arch/mips/ath79/mach-pb44.c | 6 ++ + arch/mips/ath79/mach-ubnt-xm.c | 6 ++ + .../include/asm/mach-ath79/ath79_spi_platform.h | 8 ++- + drivers/spi/spi-ath79.c | 67 +++++++++++++------- + 8 files changed, 88 insertions(+), 23 deletions(-) + +--- a/arch/mips/ath79/mach-ap121.c ++++ b/arch/mips/ath79/mach-ap121.c +@@ -58,12 +58,18 @@ static struct gpio_keys_button ap121_gpi + } + }; + ++static struct ath79_spi_controller_data ap121_spi0_data = { ++ .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, ++ .cs_line = 0, ++}; ++ + static struct spi_board_info ap121_spi_info[] = { + { + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 25000000, + .modalias = "mx25l1606e", ++ .controller_data = &ap121_spi0_data, + } + }; + +--- a/arch/mips/ath79/mach-ap136.c ++++ b/arch/mips/ath79/mach-ap136.c +@@ -98,12 +98,18 @@ static struct gpio_keys_button ap136_gpi + }, + }; + ++static struct ath79_spi_controller_data ap136_spi0_data = { ++ .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, ++ .cs_line = 0, ++}; ++ + static struct spi_board_info ap136_spi_info[] = { + { + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 25000000, + .modalias = "mx25l6405d", ++ .controller_data = &ap136_spi0_data, + } + }; + +--- a/arch/mips/ath79/mach-ap81.c ++++ b/arch/mips/ath79/mach-ap81.c +@@ -67,12 +67,18 @@ static struct gpio_keys_button ap81_gpio + } + }; + ++static struct ath79_spi_controller_data ap81_spi0_data = { ++ .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, ++ .cs_line = 0, ++}; ++ + static struct spi_board_info ap81_spi_info[] = { + { + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 25000000, + .modalias = "m25p64", ++ .controller_data = &ap81_spi0_data, + } + }; + +--- a/arch/mips/ath79/mach-db120.c ++++ b/arch/mips/ath79/mach-db120.c +@@ -76,12 +76,18 @@ static struct gpio_keys_button db120_gpi + }, + }; + ++static struct ath79_spi_controller_data db120_spi0_data = { ++ .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, ++ .cs_line = 0, ++}; ++ + static struct spi_board_info db120_spi_info[] = { + { + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 25000000, + .modalias = "s25sl064a", ++ .controller_data = &db120_spi0_data, + } + }; + +--- a/arch/mips/ath79/mach-pb44.c ++++ b/arch/mips/ath79/mach-pb44.c +@@ -87,12 +87,18 @@ static struct gpio_keys_button pb44_gpio + } + }; + ++static struct ath79_spi_controller_data pb44_spi0_data = { ++ .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, ++ .cs_line = 0, ++}; ++ + static struct spi_board_info pb44_spi_info[] = { + { + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 25000000, + .modalias = "m25p64", ++ .controller_data = &pb44_spi0_data, + }, + }; + +--- a/arch/mips/ath79/mach-ubnt-xm.c ++++ b/arch/mips/ath79/mach-ubnt-xm.c +@@ -65,12 +65,18 @@ static struct gpio_keys_button ubnt_xm_g + } + }; + ++static struct ath79_spi_controller_data ubnt_xm_spi0_data = { ++ .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, ++ .cs_line = 0, ++}; ++ + static struct spi_board_info ubnt_xm_spi_info[] = { + { + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 25000000, + .modalias = "mx25l6405d", ++ .controller_data = &ubnt_xm_spi0_data, + } + }; + +--- a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h ++++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h +@@ -16,8 +16,14 @@ struct ath79_spi_platform_data { + unsigned num_chipselect; + }; + ++enum ath79_spi_cs_type { ++ ATH79_SPI_CS_TYPE_INTERNAL, ++ ATH79_SPI_CS_TYPE_GPIO, ++}; ++ + struct ath79_spi_controller_data { +- unsigned gpio; ++ enum ath79_spi_cs_type cs_type; ++ unsigned cs_line; + }; + + #endif /* _ATH79_SPI_PLATFORM_H */ +--- a/drivers/spi/spi-ath79.c ++++ b/drivers/spi/spi-ath79.c +@@ -35,6 +35,8 @@ + #define ATH79_SPI_RRW_DELAY_FACTOR 12000 + #define MHZ (1000 * 1000) + ++#define ATH79_SPI_CS_LINE_MAX 2 ++ + struct ath79_spi { + struct spi_bitbang bitbang; + u32 ioc_base; +@@ -69,6 +71,7 @@ static void ath79_spi_chipselect(struct + { + struct ath79_spi *sp = ath79_spidev_to_sp(spi); + int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active; ++ struct ath79_spi_controller_data *cdata = spi->controller_data; + + if (is_active) { + /* set initial clock polarity */ +@@ -80,20 +83,24 @@ static void ath79_spi_chipselect(struct + ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); + } + +- if (spi->chip_select) { +- struct ath79_spi_controller_data *cdata = spi->controller_data; +- +- /* SPI is normally active-low */ +- gpio_set_value(cdata->gpio, cs_high); +- } else { ++ switch (cdata->cs_type) { ++ case ATH79_SPI_CS_TYPE_INTERNAL: + if (cs_high) +- sp->ioc_base |= AR71XX_SPI_IOC_CS0; ++ sp->ioc_base |= AR71XX_SPI_IOC_CS(cdata->cs_line); + else +- sp->ioc_base &= ~AR71XX_SPI_IOC_CS0; ++ sp->ioc_base &= ~AR71XX_SPI_IOC_CS(cdata->cs_line); + + ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); +- } ++ break; + ++ case ATH79_SPI_CS_TYPE_GPIO: ++ /* SPI is normally active-low */ ++ if (gpio_cansleep(cdata->cs_line)) ++ gpio_set_value_cansleep(cdata->cs_line, cs_high); ++ else ++ gpio_set_value(cdata->cs_line, cs_high); ++ break; ++ } + } + + static void ath79_spi_enable(struct ath79_spi *sp) +@@ -120,24 +127,30 @@ static void ath79_spi_disable(struct ath + static int ath79_spi_setup_cs(struct spi_device *spi) + { + struct ath79_spi_controller_data *cdata; ++ unsigned long flags; + int status; + + cdata = spi->controller_data; +- if (spi->chip_select && !cdata) ++ if (!cdata) + return -EINVAL; + + status = 0; +- if (spi->chip_select) { +- unsigned long flags; ++ switch (cdata->cs_type) { ++ case ATH79_SPI_CS_TYPE_INTERNAL: ++ if (cdata->cs_line > ATH79_SPI_CS_LINE_MAX) ++ status = -EINVAL; ++ break; + ++ case ATH79_SPI_CS_TYPE_GPIO: + flags = GPIOF_DIR_OUT; + if (spi->mode & SPI_CS_HIGH) + flags |= GPIOF_INIT_HIGH; + else + flags |= GPIOF_INIT_LOW; + +- status = gpio_request_one(cdata->gpio, flags, ++ status = gpio_request_one(cdata->cs_line, flags, + dev_name(&spi->dev)); ++ break; + } + + return status; +@@ -145,9 +158,19 @@ static int ath79_spi_setup_cs(struct spi + + static void ath79_spi_cleanup_cs(struct spi_device *spi) + { +- if (spi->chip_select) { +- struct ath79_spi_controller_data *cdata = spi->controller_data; +- gpio_free(cdata->gpio); ++ struct ath79_spi_controller_data *cdata; ++ ++ cdata = spi->controller_data; ++ if (!cdata) ++ return; ++ ++ switch (cdata->cs_type) { ++ case ATH79_SPI_CS_TYPE_INTERNAL: ++ /* nothing to do */ ++ break; ++ case ATH79_SPI_CS_TYPE_GPIO: ++ gpio_free(cdata->cs_line); ++ break; + } + } + +@@ -155,6 +178,9 @@ static int ath79_spi_setup(struct spi_de + { + int status = 0; + ++ if (spi->controller_data == NULL) ++ return -EINVAL; ++ + if (spi->bits_per_word > 32) + return -EINVAL; + +@@ -215,6 +241,10 @@ static __devinit int ath79_spi_probe(str + unsigned long rate; + int ret; + ++ pdata = pdev->dev.platform_data; ++ if (!pdata) ++ return -EINVAL; ++ + master = spi_alloc_master(&pdev->dev, sizeof(*sp)); + if (master == NULL) { + dev_err(&pdev->dev, "failed to allocate spi master\n"); +@@ -224,17 +254,10 @@ static __devinit int ath79_spi_probe(str + sp = spi_master_get_devdata(master); + platform_set_drvdata(pdev, sp); + +- pdata = pdev->dev.platform_data; +- + master->setup = ath79_spi_setup; + master->cleanup = ath79_spi_cleanup; +- if (pdata) { +- master->bus_num = pdata->bus_num; +- master->num_chipselect = pdata->num_chipselect; +- } else { +- master->bus_num = -1; +- master->num_chipselect = 1; +- } ++ master->bus_num = pdata->bus_num; ++ master->num_chipselect = pdata->num_chipselect; + + sp->bitbang.master = spi_master_get(master); + sp->bitbang.chipselect = ath79_spi_chipselect; diff --git a/target/linux/ar71xx/patches-3.3/210-MIPS-ath79-simplify-misc-irq-handling.patch b/target/linux/ar71xx/patches-3.3/210-MIPS-ath79-simplify-misc-irq-handling.patch new file mode 100644 index 000000000..84a8ca36f --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/210-MIPS-ath79-simplify-misc-irq-handling.patch @@ -0,0 +1,66 @@ +--- a/arch/mips/ath79/irq.c ++++ b/arch/mips/ath79/irq.c +@@ -35,44 +35,17 @@ static void ath79_misc_irq_handler(unsig + pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) & + __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); + +- if (pending & MISC_INT_UART) +- generic_handle_irq(ATH79_MISC_IRQ_UART); +- +- else if (pending & MISC_INT_DMA) +- generic_handle_irq(ATH79_MISC_IRQ_DMA); +- +- else if (pending & MISC_INT_PERFC) +- generic_handle_irq(ATH79_MISC_IRQ_PERFC); +- +- else if (pending & MISC_INT_TIMER) +- generic_handle_irq(ATH79_MISC_IRQ_TIMER); +- +- else if (pending & MISC_INT_TIMER2) +- generic_handle_irq(ATH79_MISC_IRQ_TIMER2); +- +- else if (pending & MISC_INT_TIMER3) +- generic_handle_irq(ATH79_MISC_IRQ_TIMER3); +- +- else if (pending & MISC_INT_TIMER4) +- generic_handle_irq(ATH79_MISC_IRQ_TIMER4); +- +- else if (pending & MISC_INT_OHCI) +- generic_handle_irq(ATH79_MISC_IRQ_OHCI); +- +- else if (pending & MISC_INT_ERROR) +- generic_handle_irq(ATH79_MISC_IRQ_ERROR); +- +- else if (pending & MISC_INT_GPIO) +- generic_handle_irq(ATH79_MISC_IRQ_GPIO); +- +- else if (pending & MISC_INT_WDOG) +- generic_handle_irq(ATH79_MISC_IRQ_WDOG); ++ if (!pending) { ++ spurious_interrupt(); ++ return; ++ } + +- else if (pending & MISC_INT_ETHSW) +- generic_handle_irq(ATH79_MISC_IRQ_ETHSW); ++ while (pending) { ++ int bit = __ffs(pending); + +- else +- spurious_interrupt(); ++ generic_handle_irq(ATH79_MISC_IRQ(bit)); ++ pending &= ~BIT(bit); ++ } + } + + static void ar71xx_misc_irq_unmask(struct irq_data *d) +--- a/arch/mips/include/asm/mach-ath79/irq.h ++++ b/arch/mips/include/asm/mach-ath79/irq.h +@@ -14,6 +14,7 @@ + + #define ATH79_MISC_IRQ_BASE 8 + #define ATH79_MISC_IRQ_COUNT 32 ++#define ATH79_MISC_IRQ(_x) (ATH79_MISC_IRQ_BASE + (_x)) + + #define ATH79_PCI_IRQ_BASE (ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT) + #define ATH79_PCI_IRQ_COUNT 6 diff --git a/target/linux/ar71xx/patches-3.3/211-ar933x_uart-improve-serial-clock-calculation.patch b/target/linux/ar71xx/patches-3.3/211-ar933x_uart-improve-serial-clock-calculation.patch new file mode 100644 index 000000000..510b75ed0 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/211-ar933x_uart-improve-serial-clock-calculation.patch @@ -0,0 +1,181 @@ +--- a/drivers/tty/serial/ar933x_uart.c ++++ b/drivers/tty/serial/ar933x_uart.c +@@ -25,11 +25,19 @@ + #include + #include + ++#include ++ + #include + #include + + #define DRIVER_NAME "ar933x-uart" + ++#define AR933X_UART_MAX_SCALE 0xff ++#define AR933X_UART_MAX_STEP 0xffff ++ ++#define AR933X_UART_MIN_BAUD 300 ++#define AR933X_UART_MAX_BAUD 3000000 ++ + #define AR933X_DUMMY_STATUS_RD 0x01 + + static struct uart_driver ar933x_uart_driver; +@@ -37,6 +45,8 @@ static struct uart_driver ar933x_uart_dr + struct ar933x_uart_port { + struct uart_port port; + unsigned int ier; /* shadow Interrupt Enable Register */ ++ unsigned int min_baud; ++ unsigned int max_baud; + }; + + static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, +@@ -162,6 +172,57 @@ static void ar933x_uart_enable_ms(struct + { + } + ++/* ++ * baudrate = (clk / (scale + 1)) * (step * (1 / 2^17)) ++ */ ++static unsigned long ar933x_uart_get_baud(unsigned int clk, ++ unsigned int scale, ++ unsigned int step) ++{ ++ u64 t; ++ u32 div; ++ ++ div = (2 << 16) * (scale + 1); ++ t = clk; ++ t *= step; ++ t += (div / 2); ++ do_div(t, div); ++ ++ return t; ++} ++ ++static void ar933x_uart_get_scale_step(unsigned int clk, ++ unsigned int baud, ++ unsigned int *scale, ++ unsigned int *step) ++{ ++ unsigned int tscale; ++ long min_diff; ++ ++ *scale = 0; ++ *step = 0; ++ ++ min_diff = baud; ++ for (tscale = 0; tscale < AR933X_UART_MAX_SCALE; tscale++) { ++ u64 tstep; ++ int diff; ++ ++ tstep = baud * (tscale + 1); ++ tstep *= (2 << 16); ++ do_div(tstep, clk); ++ ++ if (tstep > AR933X_UART_MAX_STEP) ++ break; ++ ++ diff = abs(ar933x_uart_get_baud(clk, tscale, tstep) - baud); ++ if (diff < min_diff) { ++ min_diff = diff; ++ *scale = tscale; ++ *step = tstep; ++ } ++ } ++} ++ + static void ar933x_uart_set_termios(struct uart_port *port, + struct ktermios *new, + struct ktermios *old) +@@ -169,7 +230,7 @@ static void ar933x_uart_set_termios(stru + struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; + unsigned int cs; + unsigned long flags; +- unsigned int baud, scale; ++ unsigned int baud, scale, step; + + /* Only CS8 is supported */ + new->c_cflag &= ~CSIZE; +@@ -191,8 +252,8 @@ static void ar933x_uart_set_termios(stru + /* Mark/space parity is not supported */ + new->c_cflag &= ~CMSPAR; + +- baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); +- scale = (port->uartclk / (16 * baud)) - 1; ++ baud = uart_get_baud_rate(port, new, old, up->min_baud, up->max_baud); ++ ar933x_uart_get_scale_step(port->uartclk, baud, &scale, &step); + + /* + * Ok, we're now changing the port state. Do it with +@@ -200,6 +261,10 @@ static void ar933x_uart_set_termios(stru + */ + spin_lock_irqsave(&up->port.lock, flags); + ++ /* disable the UART */ ++ ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG, ++ AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S); ++ + /* Update the per-port timeout. */ + uart_update_timeout(port, new->c_cflag, baud); + +@@ -210,7 +275,7 @@ static void ar933x_uart_set_termios(stru + up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD; + + ar933x_uart_write(up, AR933X_UART_CLOCK_REG, +- scale << AR933X_UART_CLOCK_SCALE_S | 8192); ++ scale << AR933X_UART_CLOCK_SCALE_S | step); + + /* setup configuration register */ + ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs); +@@ -219,6 +284,11 @@ static void ar933x_uart_set_termios(stru + ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, + AR933X_UART_CS_HOST_INT_EN); + ++ /* reenable the UART */ ++ ar933x_uart_rmw(up, AR933X_UART_CS_REG, ++ AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S, ++ AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S); ++ + spin_unlock_irqrestore(&up->port.lock, flags); + + if (tty_termios_baud_rate(new)) +@@ -401,6 +471,8 @@ static void ar933x_uart_config_port(stru + static int ar933x_uart_verify_port(struct uart_port *port, + struct serial_struct *ser) + { ++ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; ++ + if (ser->type != PORT_UNKNOWN && + ser->type != PORT_AR933X) + return -EINVAL; +@@ -408,7 +480,8 @@ static int ar933x_uart_verify_port(struc + if (ser->irq < 0 || ser->irq >= NR_IRQS) + return -EINVAL; + +- if (ser->baud_base < 28800) ++ if (ser->baud_base < up->min_baud || ++ ser->baud_base > up->max_baud) + return -EINVAL; + + return 0; +@@ -561,6 +634,7 @@ static int __devinit ar933x_uart_probe(s + struct uart_port *port; + struct resource *mem_res; + struct resource *irq_res; ++ unsigned int baud; + int id; + int ret; + +@@ -611,6 +685,12 @@ static int __devinit ar933x_uart_probe(s + port->fifosize = AR933X_UART_FIFO_SIZE; + port->ops = &ar933x_uart_ops; + ++ baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1); ++ up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD); ++ ++ baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP); ++ up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD); ++ + ar933x_uart_add_console_port(up); + + ret = uart_add_one_port(&ar933x_uart_driver, &up->port); diff --git a/target/linux/ar71xx/patches-3.3/300-ehcpi-platform-remove-ehci_update_device.patch b/target/linux/ar71xx/patches-3.3/300-ehcpi-platform-remove-ehci_update_device.patch new file mode 100644 index 000000000..e9a5b7005 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/300-ehcpi-platform-remove-ehci_update_device.patch @@ -0,0 +1,11 @@ +--- a/drivers/usb/host/ehci-platform.c ++++ b/drivers/usb/host/ehci-platform.c +@@ -75,8 +75,6 @@ static const struct hc_driver ehci_platf + .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, + +- .update_device = ehci_update_device, +- + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, + }; + diff --git a/target/linux/ar71xx/patches-3.3/310-lib-add-rle-decompression.patch b/target/linux/ar71xx/patches-3.3/310-lib-add-rle-decompression.patch new file mode 100644 index 000000000..0cb946229 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/310-lib-add-rle-decompression.patch @@ -0,0 +1,114 @@ +--- a/lib/Kconfig ++++ b/lib/Kconfig +@@ -124,6 +124,9 @@ config LZMA_COMPRESS + config LZMA_DECOMPRESS + tristate + ++config RLE_DECOMPRESS ++ tristate ++ + # + # These all provide a common interface (hence the apparent duplication with + # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.) +--- a/lib/Makefile ++++ b/lib/Makefile +@@ -85,6 +85,7 @@ obj-$(CONFIG_XZ_DEC) += xz/ + obj-$(CONFIG_RAID6_PQ) += raid6/ + obj-$(CONFIG_LZMA_COMPRESS) += lzma/ + obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/ ++obj-$(CONFIG_RLE_DECOMPRESS) += rle.o + + lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o + lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o +--- /dev/null ++++ b/include/linux/rle.h +@@ -0,0 +1,8 @@ ++#ifndef _RLE_H_ ++#define _RLE_H_ ++ ++int rle_decode(const unsigned char *src, size_t srclen, ++ unsigned char *dst, size_t dstlen, ++ size_t *src_done, size_t *dst_done); ++ ++#endif /* _RLE_H_ */ +--- /dev/null ++++ b/lib/rle.c +@@ -0,0 +1,78 @@ ++/* ++ * RLE decoding routine ++ * ++ * Copyright (C) 2012 Gabor Juhos ++ * ++ * This program 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. ++ */ ++ ++#include ++#include ++#include ++ ++int rle_decode(const unsigned char *src, size_t srclen, ++ unsigned char *dst, size_t dstlen, ++ size_t *src_done, size_t *dst_done) ++{ ++ size_t srcpos, dstpos; ++ int ret; ++ ++ srcpos = 0; ++ dstpos = 0; ++ ret = -EINVAL; ++ ++ /* sanity checks */ ++ if (!src || !srclen || !dst || !dstlen) ++ goto out; ++ ++ while (1) { ++ char count; ++ ++ if (srcpos >= srclen) ++ break; ++ ++ count = (char) src[srcpos++]; ++ if (count == 0) { ++ ret = 0; ++ break; ++ } ++ ++ if (count > 0) { ++ unsigned char c; ++ ++ if (srcpos >= srclen) ++ break; ++ ++ c = src[srcpos++]; ++ ++ while (count--) { ++ if (dstpos >= dstlen) ++ break; ++ ++ dst[dstpos++] = c; ++ } ++ } else { ++ count *= -1; ++ ++ while (count--) { ++ if (srcpos >= srclen) ++ break; ++ if (dstpos >= dstlen) ++ break; ++ dst[dstpos++] = src[srcpos++]; ++ } ++ } ++ } ++ ++out: ++ if (src_done) ++ *src_done = srcpos; ++ if (dst_done) ++ *dst_done = dstpos; ++ ++ return ret; ++} ++ ++EXPORT_SYMBOL_GPL(rle_decode); diff --git a/target/linux/ar71xx/patches-3.3/401-mtd-physmap-add-lock-unlock.patch b/target/linux/ar71xx/patches-3.3/401-mtd-physmap-add-lock-unlock.patch new file mode 100644 index 000000000..36e30c246 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/401-mtd-physmap-add-lock-unlock.patch @@ -0,0 +1,94 @@ +--- a/drivers/mtd/maps/physmap.c ++++ b/drivers/mtd/maps/physmap.c +@@ -29,6 +29,66 @@ struct physmap_flash_info { + struct map_info map[MAX_RESOURCES]; + }; + ++static struct platform_device *physmap_map2pdev(struct map_info *map) ++{ ++ return (struct platform_device *) map->map_priv_1; ++} ++ ++static void physmap_lock(struct map_info *map) ++{ ++ struct platform_device *pdev; ++ struct physmap_flash_data *physmap_data; ++ ++ pdev = physmap_map2pdev(map); ++ physmap_data = pdev->dev.platform_data; ++ physmap_data->lock(pdev); ++} ++ ++static void physmap_unlock(struct map_info *map) ++{ ++ struct platform_device *pdev; ++ struct physmap_flash_data *physmap_data; ++ ++ pdev = physmap_map2pdev(map); ++ physmap_data = pdev->dev.platform_data; ++ physmap_data->unlock(pdev); ++} ++ ++static map_word physmap_flash_read_lock(struct map_info *map, unsigned long ofs) ++{ ++ map_word ret; ++ ++ physmap_lock(map); ++ ret = inline_map_read(map, ofs); ++ physmap_unlock(map); ++ ++ return ret; ++} ++ ++static void physmap_flash_write_lock(struct map_info *map, map_word d, ++ unsigned long ofs) ++{ ++ physmap_lock(map); ++ inline_map_write(map, d, ofs); ++ physmap_unlock(map); ++} ++ ++static void physmap_flash_copy_from_lock(struct map_info *map, void *to, ++ unsigned long from, ssize_t len) ++{ ++ physmap_lock(map); ++ inline_map_copy_from(map, to, from, len); ++ physmap_unlock(map); ++} ++ ++static void physmap_flash_copy_to_lock(struct map_info *map, unsigned long to, ++ const void *from, ssize_t len) ++{ ++ physmap_lock(map); ++ inline_map_copy_to(map, to, from, len); ++ physmap_unlock(map); ++} ++ + static int physmap_flash_remove(struct platform_device *dev) + { + struct physmap_flash_info *info; +@@ -141,6 +201,13 @@ static int physmap_flash_probe(struct pl + + simple_map_init(&info->map[i]); + ++ if (physmap_data->lock && physmap_data->unlock) { ++ info->map[i].read = physmap_flash_read_lock; ++ info->map[i].write = physmap_flash_write_lock; ++ info->map[i].copy_from = physmap_flash_copy_from_lock; ++ info->map[i].copy_to = physmap_flash_copy_to_lock; ++ } ++ + probe_type = rom_probe_types; + if (physmap_data->probe_type == NULL) { + for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++) +--- a/include/linux/mtd/physmap.h ++++ b/include/linux/mtd/physmap.h +@@ -26,6 +26,8 @@ struct physmap_flash_data { + unsigned int width; + int (*init)(struct platform_device *); + void (*exit)(struct platform_device *); ++ void (*lock)(struct platform_device *); ++ void (*unlock)(struct platform_device *); + void (*set_vpp)(struct platform_device *, int); + unsigned int nr_parts; + unsigned int pfow_base; diff --git a/target/linux/ar71xx/patches-3.3/402-mtd-SST39VF6401B-support.patch b/target/linux/ar71xx/patches-3.3/402-mtd-SST39VF6401B-support.patch new file mode 100644 index 000000000..246abd5dc --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/402-mtd-SST39VF6401B-support.patch @@ -0,0 +1,29 @@ +--- a/drivers/mtd/chips/jedec_probe.c ++++ b/drivers/mtd/chips/jedec_probe.c +@@ -148,6 +148,7 @@ + #define SST39LF160 0x2782 + #define SST39VF1601 0x234b + #define SST39VF3201 0x235b ++#define SST39VF6401B 0x236d + #define SST39WF1601 0x274b + #define SST39WF1602 0x274a + #define SST39LF512 0x00D4 +@@ -1568,6 +1569,18 @@ static const struct amd_flash_info jedec + ERASEINFO(0x10000,64), + } + }, { ++ .mfr_id = CFI_MFR_SST, ++ .dev_id = SST39VF6401B, ++ .name = "SST 39VF6401B", ++ .devtypes = CFI_DEVICETYPE_X16, ++ .uaddr = MTD_UADDR_0xAAAA_0x5555, ++ .dev_size = SIZE_8MiB, ++ .cmd_set = P_ID_AMD_STD, ++ .nr_regions = 1, ++ .regions = { ++ ERASEINFO(0x10000,128) ++ } ++ }, { + .mfr_id = CFI_MFR_ST, + .dev_id = M29F800AB, + .name = "ST M29F800AB", diff --git a/target/linux/ar71xx/patches-3.3/403-mtd_fix_cfi_cmdset_0002_status_check.patch b/target/linux/ar71xx/patches-3.3/403-mtd_fix_cfi_cmdset_0002_status_check.patch new file mode 100644 index 000000000..9ed059822 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/403-mtd_fix_cfi_cmdset_0002_status_check.patch @@ -0,0 +1,69 @@ +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -1214,8 +1214,8 @@ static int __xipram do_write_oneword(str + break; + } + +- if (chip_ready(map, adr)) +- break; ++ if (chip_good(map, adr, datum)) ++ goto enable_xip; + + /* Latency issues. Drop the lock, wait a while and retry */ + UDELAY(map, chip, adr, 1); +@@ -1231,6 +1231,8 @@ static int __xipram do_write_oneword(str + + ret = -EIO; + } ++ ++ enable_xip: + xip_enable(map, chip, adr); + op_done: + chip->state = FL_READY; +@@ -1563,7 +1565,6 @@ static int cfi_amdstd_write_buffers(stru + return 0; + } + +- + /* + * Handle devices with one erase region, that only implement + * the chip erase command. +@@ -1627,8 +1628,8 @@ static int __xipram do_erase_chip(struct + chip->erase_suspended = 0; + } + +- if (chip_ready(map, adr)) +- break; ++ if (chip_good(map, adr, map_word_ff(map))) ++ goto op_done; + + if (time_after(jiffies, timeo)) { + printk(KERN_WARNING "MTD %s(): software timeout\n", +@@ -1648,6 +1649,7 @@ static int __xipram do_erase_chip(struct + ret = -EIO; + } + ++ op_done: + chip->state = FL_READY; + xip_enable(map, chip, adr); + put_chip(map, chip, adr); +@@ -1715,9 +1717,9 @@ static int __xipram do_erase_oneblock(st + chip->erase_suspended = 0; + } + +- if (chip_ready(map, adr)) { ++ if (chip_good(map, adr, map_word_ff(map))) { + xip_enable(map, chip, adr); +- break; ++ goto op_done; + } + + if (time_after(jiffies, timeo)) { +@@ -1739,6 +1741,7 @@ static int __xipram do_erase_oneblock(st + ret = -EIO; + } + ++ op_done: + chip->state = FL_READY; + put_chip(map, chip, adr); + mutex_unlock(&chip->mutex); diff --git a/target/linux/ar71xx/patches-3.3/404-mtd-wrt160nl-trx-parser.patch b/target/linux/ar71xx/patches-3.3/404-mtd-wrt160nl-trx-parser.patch new file mode 100644 index 000000000..75bfbc315 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/404-mtd-wrt160nl-trx-parser.patch @@ -0,0 +1,25 @@ +--- a/drivers/mtd/Kconfig ++++ b/drivers/mtd/Kconfig +@@ -156,6 +156,12 @@ config MTD_BCM63XX_PARTS + This provides partions parsing for BCM63xx devices with CFE + bootloaders. + ++config MTD_WRT160NL_PARTS ++ tristate "Linksys WRT160NL partitioning support" ++ depends on MTD_PARTITIONS && ATH79_MACH_WRT160NL ++ ---help--- ++ Linksys WRT160NL partitioning support ++ + config MTD_MYLOADER_PARTS + tristate "MyLoader partition parsing" + depends on ADM5120 || ATHEROS_AR231X || ATHEROS_AR71XX || ATH79 +--- a/drivers/mtd/Makefile ++++ b/drivers/mtd/Makefile +@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o + obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o + obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o + obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o ++obj-$(CONFIG_MTD_WRT160NL_PARTS) += wrt160nl_part.o + + # 'Users' - code which presents functionality to userspace. + obj-$(CONFIG_MTD_CHAR) += mtdchar.o diff --git a/target/linux/ar71xx/patches-3.3/405-mtd-tp-link-partition-parser.patch b/target/linux/ar71xx/patches-3.3/405-mtd-tp-link-partition-parser.patch new file mode 100644 index 000000000..021491591 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/405-mtd-tp-link-partition-parser.patch @@ -0,0 +1,34 @@ +--- a/drivers/mtd/Kconfig ++++ b/drivers/mtd/Kconfig +@@ -158,7 +158,7 @@ config MTD_BCM63XX_PARTS + + config MTD_WRT160NL_PARTS + tristate "Linksys WRT160NL partitioning support" +- depends on MTD_PARTITIONS && ATH79_MACH_WRT160NL ++ depends on ATH79_MACH_WRT160NL + ---help--- + Linksys WRT160NL partitioning support + +@@ -178,6 +178,12 @@ config MTD_MYLOADER_PARTS + You will still need the parsing functions to be called by the driver + for your particular device. It won't happen automatically. + ++config MTD_TPLINK_PARTS ++ tristate "TP-Link AR7XXX/AR9XXX partitioning support" ++ depends on ATH79 ++ ---help--- ++ TBD. ++ + comment "User Modules And Translation Layers" + + config MTD_CHAR +--- a/drivers/mtd/Makefile ++++ b/drivers/mtd/Makefile +@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o + obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o + obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o + obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o ++obj-$(CONFIG_MTD_TPLINK_PARTS) += tplinkpart.o + obj-$(CONFIG_MTD_WRT160NL_PARTS) += wrt160nl_part.o + + # 'Users' - code which presents functionality to userspace. diff --git a/target/linux/ar71xx/patches-3.3/406-mtd-m25p80-allow-to-specify-max-read-size.patch b/target/linux/ar71xx/patches-3.3/406-mtd-m25p80-allow-to-specify-max-read-size.patch new file mode 100644 index 000000000..8861c615f --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/406-mtd-m25p80-allow-to-specify-max-read-size.patch @@ -0,0 +1,112 @@ +--- a/drivers/mtd/devices/m25p80.c ++++ b/drivers/mtd/devices/m25p80.c +@@ -100,6 +100,7 @@ struct m25p { + u16 addr_width; + u8 erase_opcode; + u8 *command; ++ size_t max_read_len; + }; + + static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) +@@ -352,6 +353,7 @@ static int m25p80_read(struct mtd_info * + struct m25p *flash = mtd_to_m25p(mtd); + struct spi_transfer t[2]; + struct spi_message m; ++ loff_t ofs; + + pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), + __func__, (u32)from, len); +@@ -374,8 +376,6 @@ static int m25p80_read(struct mtd_info * + t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE; + spi_message_add_tail(&t[0], &m); + +- t[1].rx_buf = buf; +- t[1].len = len; + spi_message_add_tail(&t[1], &m); + + /* Byte count starts at zero. */ +@@ -383,13 +383,6 @@ static int m25p80_read(struct mtd_info * + + mutex_lock(&flash->lock); + +- /* Wait till previous write/erase is done. */ +- if (wait_till_ready(flash)) { +- /* REVISIT status return?? */ +- mutex_unlock(&flash->lock); +- return 1; +- } +- + /* FIXME switch to OPCODE_FAST_READ. It's required for higher + * clocks; and at this writing, every chip this driver handles + * supports that opcode. +@@ -397,11 +390,44 @@ static int m25p80_read(struct mtd_info * + + /* Set up the write data buffer. */ + flash->command[0] = OPCODE_READ; +- m25p_addr2cmd(flash, from, flash->command); + +- spi_sync(flash->spi, &m); ++ ofs = 0; ++ while (len) { ++ size_t readlen; ++ size_t done; ++ int ret; ++ ++ ret = wait_till_ready(flash); ++ if (ret) { ++ mutex_unlock(&flash->lock); ++ return 1; ++ } ++ ++ if (flash->max_read_len > 0 && ++ flash->max_read_len < len) ++ readlen = flash->max_read_len; ++ else ++ readlen = len; ++ ++ t[1].rx_buf = buf + ofs; ++ t[1].len = readlen; ++ ++ m25p_addr2cmd(flash, from + ofs, flash->command); ++ ++ spi_sync(flash->spi, &m); + +- *retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE; ++ done = m.actual_length - m25p_cmdsz(flash) - ++ FAST_READ_DUMMY_BYTE; ++ if (done != readlen) { ++ mutex_unlock(&flash->lock); ++ return 1; ++ } ++ ++ ofs += done; ++ len -= done; ++ } ++ ++ *retlen = ofs; + + mutex_unlock(&flash->lock); + +@@ -925,6 +951,12 @@ static int __devinit m25p_probe(struct s + flash->mtd.erase = m25p80_erase; + flash->mtd.read = m25p80_read; + ++ if (data && data->max_read_len) { ++ flash->max_read_len = data->max_read_len; ++ dev_warn(&spi->dev, "max_read_len set to %d bytes\n", ++ flash->max_read_len); ++ } ++ + /* sst flash chips use AAI word program */ + if (JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) + flash->mtd.write = sst_write; +--- a/include/linux/spi/flash.h ++++ b/include/linux/spi/flash.h +@@ -25,6 +25,7 @@ struct flash_platform_data { + + char *type; + ++ size_t max_read_len; + /* we'll likely add more ... use JEDEC IDs, etc */ + }; + diff --git a/target/linux/ar71xx/patches-3.3/407-mtd-m25p80-allow-to-pass-probe-types-via-platform-data.patch b/target/linux/ar71xx/patches-3.3/407-mtd-m25p80-allow-to-pass-probe-types-via-platform-data.patch new file mode 100644 index 000000000..14f2de536 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/407-mtd-m25p80-allow-to-pass-probe-types-via-platform-data.patch @@ -0,0 +1,23 @@ +--- a/drivers/mtd/devices/m25p80.c ++++ b/drivers/mtd/devices/m25p80.c +@@ -1018,7 +1018,9 @@ static int __devinit m25p_probe(struct s + /* partitions should match sector boundaries; and it may be good to + * use readonly partitions for writeprotected sectors (BP2..BP0). + */ +- return mtd_device_parse_register(&flash->mtd, NULL, &ppdata, ++ return mtd_device_parse_register(&flash->mtd, ++ data ? data->part_probes : NULL, ++ &ppdata, + data ? data->parts : NULL, + data ? data->nr_parts : 0); + } +--- a/include/linux/spi/flash.h ++++ b/include/linux/spi/flash.h +@@ -24,6 +24,7 @@ struct flash_platform_data { + unsigned int nr_parts; + + char *type; ++ const char **part_probes; + + size_t max_read_len; + /* we'll likely add more ... use JEDEC IDs, etc */ diff --git a/target/linux/ar71xx/patches-3.3/408-mtd-redboot_partition_scan.patch b/target/linux/ar71xx/patches-3.3/408-mtd-redboot_partition_scan.patch new file mode 100644 index 000000000..9d7a696f1 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/408-mtd-redboot_partition_scan.patch @@ -0,0 +1,45 @@ +--- a/drivers/mtd/redboot.c ++++ b/drivers/mtd/redboot.c +@@ -79,6 +79,11 @@ static int parse_redboot_partitions(stru + static char nullstring[] = "unallocated"; + #endif + ++ buf = vmalloc(master->erasesize); ++ if (!buf) ++ return -ENOMEM; ++ ++ restart: + if ( directory < 0 ) { + offset = master->size + directory * master->erasesize; + while (mtd_can_have_bb(master) && +@@ -86,6 +91,7 @@ static int parse_redboot_partitions(stru + if (!offset) { + nogood: + printk(KERN_NOTICE "Failed to find a non-bad block to check for RedBoot partition table\n"); ++ vfree(buf); + return -EIO; + } + offset -= master->erasesize; +@@ -99,10 +105,6 @@ static int parse_redboot_partitions(stru + goto nogood; + } + } +- buf = vmalloc(master->erasesize); +- +- if (!buf) +- return -ENOMEM; + + printk(KERN_NOTICE "Searching for RedBoot partition table in %s at offset 0x%lx\n", + master->name, offset); +@@ -175,6 +177,11 @@ static int parse_redboot_partitions(stru + } + if (i == numslots) { + /* Didn't find it */ ++ if (offset + master->erasesize < master->size) { ++ /* not at the end of the flash yet, maybe next block :) */ ++ directory++; ++ goto restart; ++ } + printk(KERN_NOTICE "No RedBoot partition table detected in %s\n", + master->name); + ret = 0; diff --git a/target/linux/ar71xx/patches-3.3/409-mtd-rb4xx_nand_driver.patch b/target/linux/ar71xx/patches-3.3/409-mtd-rb4xx_nand_driver.patch new file mode 100644 index 000000000..e1a339890 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/409-mtd-rb4xx_nand_driver.patch @@ -0,0 +1,21 @@ +--- a/drivers/mtd/nand/Kconfig ++++ b/drivers/mtd/nand/Kconfig +@@ -536,4 +536,8 @@ config MTD_NAND_FSMC + Enables support for NAND Flash chips on the ST Microelectronics + Flexible Static Memory Controller (FSMC) + ++config MTD_NAND_RB4XX ++ tristate "NAND flash driver for RouterBoard 4xx series" ++ depends on MTD_NAND && ATH79_MACH_RB4XX ++ + endif # MTD_NAND +--- a/drivers/mtd/nand/Makefile ++++ b/drivers/mtd/nand/Makefile +@@ -33,6 +33,7 @@ obj-$(CONFIG_MTD_NAND_CM_X270) += cmx27 + obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o + obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o + obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o ++obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o + obj-$(CONFIG_MTD_ALAUDA) += alauda.o + obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o + obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o diff --git a/target/linux/ar71xx/patches-3.3/410-mtd-rb750-nand-driver.patch b/target/linux/ar71xx/patches-3.3/410-mtd-rb750-nand-driver.patch new file mode 100644 index 000000000..d67f720d6 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/410-mtd-rb750-nand-driver.patch @@ -0,0 +1,21 @@ +--- a/drivers/mtd/nand/Kconfig ++++ b/drivers/mtd/nand/Kconfig +@@ -540,4 +540,8 @@ config MTD_NAND_RB4XX + tristate "NAND flash driver for RouterBoard 4xx series" + depends on MTD_NAND && ATH79_MACH_RB4XX + ++config MTD_NAND_RB750 ++ tristate "NAND flash driver for the RouterBoard 750" ++ depends on MTD_NAND && ATH79_MACH_RB750 ++ + endif # MTD_NAND +--- a/drivers/mtd/nand/Makefile ++++ b/drivers/mtd/nand/Makefile +@@ -34,6 +34,7 @@ obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx + obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o + obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o + obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o ++obj-$(CONFIG_MTD_NAND_RB750) += rb750_nand.o + obj-$(CONFIG_MTD_ALAUDA) += alauda.o + obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o + obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o diff --git a/target/linux/ar71xx/patches-3.3/411-mtd-cfi_cmdset_0002-force-word-write.patch b/target/linux/ar71xx/patches-3.3/411-mtd-cfi_cmdset_0002-force-word-write.patch new file mode 100644 index 000000000..e4e879b5b --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/411-mtd-cfi_cmdset_0002-force-word-write.patch @@ -0,0 +1,61 @@ +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -39,7 +39,7 @@ + #include + + #define AMD_BOOTLOC_BUG +-#define FORCE_WORD_WRITE 0 ++#define FORCE_WORD_WRITE 1 + + #define MAX_WORD_RETRIES 3 + +@@ -50,7 +50,9 @@ + + static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); + static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); ++#if !FORCE_WORD_WRITE + static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); ++#endif + static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *); + static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *); + static void cfi_amdstd_sync (struct mtd_info *); +@@ -183,6 +185,7 @@ static void fixup_amd_bootblock(struct m + } + #endif + ++#if !FORCE_WORD_WRITE + static void fixup_use_write_buffers(struct mtd_info *mtd) + { + struct map_info *map = mtd->priv; +@@ -192,6 +195,7 @@ static void fixup_use_write_buffers(stru + mtd->write = cfi_amdstd_write_buffers; + } + } ++#endif /* !FORCE_WORD_WRITE */ + + /* Atmel chips don't use the same PRI format as AMD chips */ + static void fixup_convert_atmel_pri(struct mtd_info *mtd) +@@ -1374,6 +1378,7 @@ static int cfi_amdstd_write_words(struct + /* + * FIXME: interleaved mode not tested, and probably not supported! + */ ++#if !FORCE_WORD_WRITE + static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, + unsigned long adr, const u_char *buf, + int len) +@@ -1485,7 +1490,6 @@ static int __xipram do_write_buffer(stru + return ret; + } + +- + static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) + { +@@ -1564,6 +1568,7 @@ static int cfi_amdstd_write_buffers(stru + + return 0; + } ++#endif /* !FORCE_WORD_WRITE */ + + /* + * Handle devices with one erase region, that only implement diff --git a/target/linux/ar71xx/patches-3.3/412-mtd-m25p80-zero-partition-parser-data.patch b/target/linux/ar71xx/patches-3.3/412-mtd-m25p80-zero-partition-parser-data.patch new file mode 100644 index 000000000..a667139d0 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/412-mtd-m25p80-zero-partition-parser-data.patch @@ -0,0 +1,10 @@ +--- a/drivers/mtd/devices/m25p80.c ++++ b/drivers/mtd/devices/m25p80.c +@@ -978,6 +978,7 @@ static int __devinit m25p_probe(struct s + if (info->flags & M25P_NO_ERASE) + flash->mtd.flags |= MTD_NO_ERASE; + ++ memset(&ppdata, '\0', sizeof(ppdata)); + ppdata.of_node = spi->dev.of_node; + flash->mtd.dev.parent = &spi->dev; + flash->page_size = info->page_size; diff --git a/target/linux/ar71xx/patches-3.3/413-mtd-ar934x-nand-driver.patch b/target/linux/ar71xx/patches-3.3/413-mtd-ar934x-nand-driver.patch new file mode 100644 index 000000000..289458fbd --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/413-mtd-ar934x-nand-driver.patch @@ -0,0 +1,21 @@ +--- a/drivers/mtd/nand/Kconfig ++++ b/drivers/mtd/nand/Kconfig +@@ -544,4 +544,8 @@ config MTD_NAND_RB750 + tristate "NAND flash driver for the RouterBoard 750" + depends on MTD_NAND && ATH79_MACH_RB750 + ++config MTD_NAND_AR934X ++ tristate "NAND flash driver for the Atheros AR934x SoCs" ++ depends on SOC_AR934X ++ + endif # MTD_NAND +--- a/drivers/mtd/nand/Makefile ++++ b/drivers/mtd/nand/Makefile +@@ -11,6 +11,7 @@ obj-$(CONFIG_MTD_SM_COMMON) += sm_comm + obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o + obj-$(CONFIG_MTD_NAND_SPIA) += spia.o + obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o ++obj-$(CONFIG_MTD_NAND_AR934X) += ar934x_nfc.o + obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o + obj-$(CONFIG_MTD_NAND_DENALI) += denali.o + obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o diff --git a/target/linux/ar71xx/patches-3.3/420-net-ar71xx_mac_driver.patch b/target/linux/ar71xx/patches-3.3/420-net-ar71xx_mac_driver.patch new file mode 100644 index 000000000..f11713316 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/420-net-ar71xx_mac_driver.patch @@ -0,0 +1,28 @@ +--- a/drivers/net/ethernet/atheros/Kconfig ++++ b/drivers/net/ethernet/atheros/Kconfig +@@ -5,7 +5,7 @@ + config NET_VENDOR_ATHEROS + bool "Atheros devices" + default y +- depends on PCI ++ depends on (PCI || ATH79) + ---help--- + If you have a network (Ethernet) card belonging to this class, say Y + and read the Ethernet-HOWTO, available from +@@ -67,4 +67,6 @@ config ATL1C + To compile this driver as a module, choose M here. The module + will be called atl1c. + ++source drivers/net/ethernet/atheros/ag71xx/Kconfig ++ + endif # NET_VENDOR_ATHEROS +--- a/drivers/net/ethernet/atheros/Makefile ++++ b/drivers/net/ethernet/atheros/Makefile +@@ -2,6 +2,7 @@ + # Makefile for the Atheros network device drivers. + # + ++obj-$(CONFIG_AG71XX) += ag71xx/ + obj-$(CONFIG_ATL1) += atlx/ + obj-$(CONFIG_ATL2) += atlx/ + obj-$(CONFIG_ATL1E) += atl1e/ diff --git a/target/linux/ar71xx/patches-3.3/422-dsa-trailer-tag-validation-fix.patch b/target/linux/ar71xx/patches-3.3/422-dsa-trailer-tag-validation-fix.patch new file mode 100644 index 000000000..3e3902bac --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/422-dsa-trailer-tag-validation-fix.patch @@ -0,0 +1,11 @@ +--- a/net/dsa/tag_trailer.c ++++ b/net/dsa/tag_trailer.c +@@ -87,7 +87,7 @@ static int trailer_rcv(struct sk_buff *s + + trailer = skb_tail_pointer(skb) - 4; + if (trailer[0] != 0x80 || (trailer[1] & 0xf8) != 0x00 || +- (trailer[3] & 0xef) != 0x00 || trailer[3] != 0x00) ++ (trailer[2] & 0xef) != 0x00 || (trailer[3] & 0xfe) != 0x00) + goto out_drop; + + source_port = trailer[1] & 7; diff --git a/target/linux/ar71xx/patches-3.3/423-dsa-add-88e6063-driver.patch b/target/linux/ar71xx/patches-3.3/423-dsa-add-88e6063-driver.patch new file mode 100644 index 000000000..bfb0b8e75 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/423-dsa-add-88e6063-driver.patch @@ -0,0 +1,24 @@ +--- a/drivers/net/dsa/Kconfig ++++ b/drivers/net/dsa/Kconfig +@@ -12,6 +12,13 @@ config NET_DSA_MV88E6060 + This enables support for the Marvell 88E6060 ethernet switch + chip. + ++config NET_DSA_MV88E6063 ++ bool "Marvell 88E6063 ethernet switch chip support" ++ select NET_DSA_TAG_TRAILER ++ ---help--- ++ This enables support for the Marvell 88E6063 ethernet switch ++ chip ++ + config NET_DSA_MV88E6XXX_NEED_PPU + bool + default n +--- a/drivers/net/dsa/Makefile ++++ b/drivers/net/dsa/Makefile +@@ -1,4 +1,5 @@ + obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o ++obj-$(CONFIG_NET_DSA_MV88E6063) += mv88e6063.o + obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx_drv.o + mv88e6xxx_drv-y += mv88e6xxx.o + ifdef CONFIG_NET_DSA_MV88E6123_61_65 diff --git a/target/linux/ar71xx/patches-3.3/430-drivers-link-spi-before-mtd.patch b/target/linux/ar71xx/patches-3.3/430-drivers-link-spi-before-mtd.patch new file mode 100644 index 000000000..f54861be6 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/430-drivers-link-spi-before-mtd.patch @@ -0,0 +1,12 @@ +--- a/drivers/Makefile ++++ b/drivers/Makefile +@@ -52,8 +52,8 @@ obj-$(CONFIG_IDE) += ide/ + obj-$(CONFIG_SCSI) += scsi/ + obj-$(CONFIG_ATA) += ata/ + obj-$(CONFIG_TARGET_CORE) += target/ +-obj-$(CONFIG_MTD) += mtd/ + obj-$(CONFIG_SPI) += spi/ ++obj-$(CONFIG_MTD) += mtd/ + obj-y += net/ + obj-$(CONFIG_ATM) += atm/ + obj-$(CONFIG_FUSION) += message/ diff --git a/target/linux/ar71xx/patches-3.3/431-spi-add-various-flags.patch b/target/linux/ar71xx/patches-3.3/431-spi-add-various-flags.patch new file mode 100644 index 000000000..67ba43f0c --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/431-spi-add-various-flags.patch @@ -0,0 +1,19 @@ +--- a/include/linux/spi/spi.h ++++ b/include/linux/spi/spi.h +@@ -503,6 +503,8 @@ struct spi_transfer { + dma_addr_t rx_dma; + + unsigned cs_change:1; ++ unsigned verify:1; ++ unsigned fast_write:1; + u8 bits_per_word; + u16 delay_usecs; + u32 speed_hz; +@@ -544,6 +546,7 @@ struct spi_message { + struct spi_device *spi; + + unsigned is_dma_mapped:1; ++ unsigned fast_read:1; + + /* REVISIT: we might want a flag affecting the behavior of the + * last transfer ... allowing things like "read 16 bit length L" diff --git a/target/linux/ar71xx/patches-3.3/432-spi-rb4xx-spi-driver.patch b/target/linux/ar71xx/patches-3.3/432-spi-rb4xx-spi-driver.patch new file mode 100644 index 000000000..6cfe2e832 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/432-spi-rb4xx-spi-driver.patch @@ -0,0 +1,25 @@ +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -288,6 +288,12 @@ config SPI_PXA2XX + config SPI_PXA2XX_PCI + def_bool SPI_PXA2XX && X86_32 && PCI + ++config SPI_RB4XX ++ tristate "Mikrotik RB4XX SPI master" ++ depends on SPI_MASTER && ATH79_MACH_RB4XX ++ help ++ SPI controller driver for the Mikrotik RB4xx series boards. ++ + config SPI_S3C24XX + tristate "Samsung S3C24XX series SPI" + depends on ARCH_S3C2410 && EXPERIMENTAL +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -45,6 +45,7 @@ obj-$(CONFIG_SPI_PL022) += spi-pl022.o + obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx.o + obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx.o + obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o ++obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o + obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o + spi-s3c24xx-hw-y := spi-s3c24xx.o + spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o diff --git a/target/linux/ar71xx/patches-3.3/433-spi-rb4xx-cpld-driver.patch b/target/linux/ar71xx/patches-3.3/433-spi-rb4xx-cpld-driver.patch new file mode 100644 index 000000000..579315b3a --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/433-spi-rb4xx-cpld-driver.patch @@ -0,0 +1,26 @@ +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -439,6 +439,13 @@ config SPI_TLE62X0 + sysfs interface, with each line presented as a kind of GPIO + exposing both switch control and diagnostic feedback. + ++config SPI_RB4XX_CPLD ++ tristate "MikroTik RB4XX CPLD driver" ++ depends on ATH79_MACH_RB4XX ++ help ++ SPI driver for the Xilinx CPLD chip present on the ++ MikroTik RB4xx boards. ++ + # + # Add new SPI protocol masters in alphabetical order above this line + # +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -46,6 +46,7 @@ obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx. + obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx.o + obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o + obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o ++obj-$(CONFIG_SPI_RB4XX_CPLD) += spi-rb4xx-cpld.o + obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o + spi-s3c24xx-hw-y := spi-s3c24xx.o + spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o diff --git a/target/linux/ar71xx/patches-3.3/434-spi-ap83_spi_controller.patch b/target/linux/ar71xx/patches-3.3/434-spi-ap83_spi_controller.patch new file mode 100644 index 000000000..b4dbcd470 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/434-spi-ap83_spi_controller.patch @@ -0,0 +1,27 @@ +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -12,6 +12,7 @@ obj-$(CONFIG_SPI_SPIDEV) += spidev.o + # SPI master controller drivers (bus) + obj-$(CONFIG_SPI_ALTERA) += spi-altera.o + obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o ++obj-$(CONFIG_SPI_AP83) += spi-ap83.o + obj-$(CONFIG_SPI_ATH79) += spi-ath79.o + obj-$(CONFIG_SPI_AU1550) += spi-au1550.o + obj-$(CONFIG_SPI_BFIN) += spi-bfin5xx.o +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -59,6 +59,14 @@ config SPI_ALTERA + help + This is the driver for the Altera SPI Controller. + ++config SPI_AP83 ++ tristate "Atheros AP83 specific SPI Controller" ++ depends on SPI_MASTER && ATH79_MACH_AP83 ++ select SPI_BITBANG ++ help ++ This is a specific SPI controller driver for the Atheros AP83 ++ reference board. ++ + config SPI_ATH79 + tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver" + depends on ATH79 && GENERIC_GPIO diff --git a/target/linux/ar71xx/patches-3.3/435-spi-vsc7385_driver.patch b/target/linux/ar71xx/patches-3.3/435-spi-vsc7385_driver.patch new file mode 100644 index 000000000..14626879b --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/435-spi-vsc7385_driver.patch @@ -0,0 +1,23 @@ +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -454,6 +454,11 @@ config SPI_RB4XX_CPLD + SPI driver for the Xilinx CPLD chip present on the + MikroTik RB4xx boards. + ++config SPI_VSC7385 ++ tristate "Vitesse VSC7385 ethernet switch driver" ++ help ++ SPI driver for the Vitesse VSC7385 ethernet switch. ++ + # + # Add new SPI protocol masters in alphabetical order above this line + # +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -61,5 +61,5 @@ obj-$(CONFIG_SPI_TI_SSP) += spi-ti-ssp. + obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o + obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o + obj-$(CONFIG_SPI_TXX9) += spi-txx9.o ++obj-$(CONFIG_SPI_VSC7385) += spi-vsc7385.o + obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o +- diff --git a/target/linux/ar71xx/patches-3.3/440-leds-wndr3700-usb-led-driver.patch b/target/linux/ar71xx/patches-3.3/440-leds-wndr3700-usb-led-driver.patch new file mode 100644 index 000000000..88d09089d --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/440-leds-wndr3700-usb-led-driver.patch @@ -0,0 +1,26 @@ +--- a/drivers/leds/Kconfig ++++ b/drivers/leds/Kconfig +@@ -418,6 +418,13 @@ config LEDS_TRIGGERS + These triggers allow kernel events to drive the LEDs and can + be configured via sysfs. If unsure, say Y. + ++config LEDS_WNDR3700_USB ++ tristate "NETGEAR WNDR3700 USB LED driver" ++ depends on LEDS_CLASS && ATH79_MACH_WNDR3700 ++ help ++ This option enables support for the USB LED found on the ++ NETGEAR WNDR3700 board. ++ + comment "LED Triggers" + + config LEDS_TRIGGER_TIMER +--- a/drivers/leds/Makefile ++++ b/drivers/leds/Makefile +@@ -35,6 +35,7 @@ obj-$(CONFIG_LEDS_DA903X) += leds-da903 + obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o + obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o + obj-$(CONFIG_LEDS_PWM) += leds-pwm.o ++obj-${CONFIG_LEDS_WNDR3700_USB} += leds-wndr3700-usb.o + obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o + obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o + obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o diff --git a/target/linux/ar71xx/patches-3.3/441-leds-rb750-led-driver.patch b/target/linux/ar71xx/patches-3.3/441-leds-rb750-led-driver.patch new file mode 100644 index 000000000..e8073a2e8 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/441-leds-rb750-led-driver.patch @@ -0,0 +1,23 @@ +--- a/drivers/leds/Kconfig ++++ b/drivers/leds/Kconfig +@@ -425,6 +425,10 @@ config LEDS_WNDR3700_USB + This option enables support for the USB LED found on the + NETGEAR WNDR3700 board. + ++config LEDS_RB750 ++ tristate "LED driver for the Mikrotik RouterBOARD 750" ++ depends on LEDS_CLASS && ATH79_MACH_RB750 ++ + comment "LED Triggers" + + config LEDS_TRIGGER_TIMER +--- a/drivers/leds/Makefile ++++ b/drivers/leds/Makefile +@@ -42,6 +42,7 @@ obj-$(CONFIG_LEDS_LT3593) += leds-lt359 + obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o + obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o + obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o ++obj-$(CONFIG_LEDS_RB750) += leds-rb750.o + obj-$(CONFIG_LEDS_NS2) += leds-ns2.o + obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o + obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o diff --git a/target/linux/ar71xx/patches-3.3/450-gpio-nxp-74hc153-gpio-chip-driver.patch b/target/linux/ar71xx/patches-3.3/450-gpio-nxp-74hc153-gpio-chip-driver.patch new file mode 100644 index 000000000..1e67abfdd --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/450-gpio-nxp-74hc153-gpio-chip-driver.patch @@ -0,0 +1,26 @@ +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -489,4 +489,13 @@ config GPIO_TPS65910 + help + Select this option to enable GPIO driver for the TPS65910 + chip family. ++ ++comment "Other GPIO expanders" ++ ++config GPIO_NXP_74HC153 ++ tristate "NXP 74HC153 Dual 4-input multiplexer" ++ help ++ Platform driver for NXP 74HC153 Dual 4-input Multiplexer. This ++ provides a GPIO interface supporting input mode only. ++ + endif +--- a/drivers/gpio/Makefile ++++ b/drivers/gpio/Makefile +@@ -35,6 +35,7 @@ obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2 + obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o + obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o + obj-$(CONFIG_PLAT_NOMADIK) += gpio-nomadik.o ++obj-$(CONFIG_GPIO_NXP_74HC153) += gpio-nxp-74hc153.o + obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o + obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o + obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o diff --git a/target/linux/ar71xx/patches-3.3/460-spi-bitbang-export-spi_bitbang_bufs.patch b/target/linux/ar71xx/patches-3.3/460-spi-bitbang-export-spi_bitbang_bufs.patch new file mode 100644 index 000000000..919b85cb7 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/460-spi-bitbang-export-spi_bitbang_bufs.patch @@ -0,0 +1,28 @@ +--- a/drivers/spi/spi-bitbang.c ++++ b/drivers/spi/spi-bitbang.c +@@ -234,13 +234,14 @@ void spi_bitbang_cleanup(struct spi_devi + } + EXPORT_SYMBOL_GPL(spi_bitbang_cleanup); + +-static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t) ++int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t) + { + struct spi_bitbang_cs *cs = spi->controller_state; + unsigned nsecs = cs->nsecs; + + return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t); + } ++EXPORT_SYMBOL_GPL(spi_bitbang_bufs); + + /*----------------------------------------------------------------------*/ + +--- a/include/linux/spi/spi_bitbang.h ++++ b/include/linux/spi/spi_bitbang.h +@@ -44,6 +44,7 @@ extern void spi_bitbang_cleanup(struct s + extern int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m); + extern int spi_bitbang_setup_transfer(struct spi_device *spi, + struct spi_transfer *t); ++extern int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t); + + /* start or stop queue processing */ + extern int spi_bitbang_start(struct spi_bitbang *spi); diff --git a/target/linux/ar71xx/patches-3.3/461-spi-add-type-field-to-spi_transfer.patch b/target/linux/ar71xx/patches-3.3/461-spi-add-type-field-to-spi_transfer.patch new file mode 100644 index 000000000..850f24a07 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/461-spi-add-type-field-to-spi_transfer.patch @@ -0,0 +1,23 @@ +--- a/include/linux/spi/spi.h ++++ b/include/linux/spi/spi.h +@@ -406,6 +406,12 @@ extern struct spi_master *spi_busnum_to_ + + /*---------------------------------------------------------------------------*/ + ++enum spi_transfer_type { ++ SPI_TRANSFER_GENERIC = 0, ++ SPI_TRANSFER_FLASH_READ_CMD, ++ SPI_TRANSFER_FLASH_READ_DATA, ++}; ++ + /* + * I/O INTERFACE between SPI controller and protocol drivers + * +@@ -508,6 +514,7 @@ struct spi_transfer { + u8 bits_per_word; + u16 delay_usecs; + u32 speed_hz; ++ enum spi_transfer_type type; + + struct list_head transfer_list; + }; diff --git a/target/linux/ar71xx/patches-3.3/462-mtd-m25p80-set-spi-transfer-type.patch b/target/linux/ar71xx/patches-3.3/462-mtd-m25p80-set-spi-transfer-type.patch new file mode 100644 index 000000000..48e69c0d6 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/462-mtd-m25p80-set-spi-transfer-type.patch @@ -0,0 +1,15 @@ +--- a/drivers/mtd/devices/m25p80.c ++++ b/drivers/mtd/devices/m25p80.c +@@ -372,10 +372,12 @@ static int m25p80_read(struct mtd_info * + * OPCODE_FAST_READ (if available) is faster. + * Should add 1 byte DUMMY_BYTE. + */ ++ t[0].type = SPI_TRANSFER_FLASH_READ_CMD; + t[0].tx_buf = flash->command; + t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE; + spi_message_add_tail(&t[0], &m); + ++ t[1].type = SPI_TRANSFER_FLASH_READ_DATA; + spi_message_add_tail(&t[1], &m); + + /* Byte count starts at zero. */ diff --git a/target/linux/ar71xx/patches-3.3/463-spi-ath79-add-fast-flash-read.patch b/target/linux/ar71xx/patches-3.3/463-spi-ath79-add-fast-flash-read.patch new file mode 100644 index 000000000..9ccc4a45e --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/463-spi-ath79-add-fast-flash-read.patch @@ -0,0 +1,185 @@ +--- a/drivers/spi/spi-ath79.c ++++ b/drivers/spi/spi-ath79.c +@@ -37,6 +37,11 @@ + + #define ATH79_SPI_CS_LINE_MAX 2 + ++enum ath79_spi_state { ++ ATH79_SPI_STATE_WAIT_CMD = 0, ++ ATH79_SPI_STATE_WAIT_READ, ++}; ++ + struct ath79_spi { + struct spi_bitbang bitbang; + u32 ioc_base; +@@ -44,6 +49,11 @@ struct ath79_spi { + void __iomem *base; + struct clk *clk; + unsigned rrw_delay; ++ ++ enum ath79_spi_state state; ++ u32 clk_div; ++ unsigned long read_addr; ++ unsigned long ahb_rate; + }; + + static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned reg) +@@ -111,9 +121,6 @@ static void ath79_spi_enable(struct ath7 + /* save CTRL register */ + sp->reg_ctrl = ath79_spi_rr(sp, AR71XX_SPI_REG_CTRL); + sp->ioc_base = ath79_spi_rr(sp, AR71XX_SPI_REG_IOC); +- +- /* TODO: setup speed? */ +- ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43); + } + + static void ath79_spi_disable(struct ath79_spi *sp) +@@ -232,6 +239,110 @@ static u32 ath79_spi_txrx_mode0(struct s + return ath79_spi_rr(sp, AR71XX_SPI_REG_RDS); + } + ++static int ath79_spi_do_read_flash_data(struct spi_device *spi, ++ struct spi_transfer *t) ++{ ++ struct ath79_spi *sp = ath79_spidev_to_sp(spi); ++ ++ /* disable GPIO mode */ ++ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0); ++ ++ memcpy_fromio(t->rx_buf, sp->base + sp->read_addr, t->len); ++ ++ /* enable GPIO mode */ ++ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO); ++ ++ /* restore IOC register */ ++ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); ++ ++ return t->len; ++} ++ ++static int ath79_spi_do_read_flash_cmd(struct spi_device *spi, ++ struct spi_transfer *t) ++{ ++ struct ath79_spi *sp = ath79_spidev_to_sp(spi); ++ int len; ++ const u8 *p; ++ ++ sp->read_addr = 0; ++ ++ len = t->len - 1; ++ p = t->tx_buf; ++ ++ while (len--) { ++ p++; ++ sp->read_addr <<= 8; ++ sp->read_addr |= *p; ++ } ++ ++ return t->len; ++} ++ ++static bool ath79_spi_is_read_cmd(struct spi_device *spi, ++ struct spi_transfer *t) ++{ ++ return t->type == SPI_TRANSFER_FLASH_READ_CMD; ++} ++ ++static bool ath79_spi_is_data_read(struct spi_device *spi, ++ struct spi_transfer *t) ++{ ++ return t->type == SPI_TRANSFER_FLASH_READ_DATA; ++} ++ ++static int ath79_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) ++{ ++ struct ath79_spi *sp = ath79_spidev_to_sp(spi); ++ int ret; ++ ++ switch (sp->state) { ++ case ATH79_SPI_STATE_WAIT_CMD: ++ if (ath79_spi_is_read_cmd(spi, t)) { ++ ret = ath79_spi_do_read_flash_cmd(spi, t); ++ sp->state = ATH79_SPI_STATE_WAIT_READ; ++ } else { ++ ret = spi_bitbang_bufs(spi, t); ++ } ++ break; ++ ++ case ATH79_SPI_STATE_WAIT_READ: ++ if (ath79_spi_is_data_read(spi, t)) { ++ ret = ath79_spi_do_read_flash_data(spi, t); ++ } else { ++ dev_warn(&spi->dev, "flash data read expected\n"); ++ ret = -EIO; ++ } ++ sp->state = ATH79_SPI_STATE_WAIT_CMD; ++ break; ++ ++ default: ++ BUG(); ++ } ++ ++ return ret; ++} ++ ++static int ath79_spi_setup_transfer(struct spi_device *spi, ++ struct spi_transfer *t) ++{ ++ struct ath79_spi *sp = ath79_spidev_to_sp(spi); ++ struct ath79_spi_controller_data *cdata; ++ int ret; ++ ++ ret = spi_bitbang_setup_transfer(spi, t); ++ if (ret) ++ return ret; ++ ++ cdata = spi->controller_data; ++ if (cdata->is_flash) ++ sp->bitbang.txrx_bufs = ath79_spi_txrx_bufs; ++ else ++ sp->bitbang.txrx_bufs = spi_bitbang_bufs; ++ ++ return ret; ++} ++ + static __devinit int ath79_spi_probe(struct platform_device *pdev) + { + struct spi_master *master; +@@ -254,6 +365,8 @@ static __devinit int ath79_spi_probe(str + sp = spi_master_get_devdata(master); + platform_set_drvdata(pdev, sp); + ++ sp->state = ATH79_SPI_STATE_WAIT_CMD; ++ + master->setup = ath79_spi_setup; + master->cleanup = ath79_spi_cleanup; + master->bus_num = pdata->bus_num; +@@ -262,7 +375,7 @@ static __devinit int ath79_spi_probe(str + sp->bitbang.master = spi_master_get(master); + sp->bitbang.chipselect = ath79_spi_chipselect; + sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0; +- sp->bitbang.setup_transfer = spi_bitbang_setup_transfer; ++ sp->bitbang.setup_transfer = ath79_spi_setup_transfer; + sp->bitbang.flags = SPI_CS_HIGH; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); +@@ -287,7 +400,8 @@ static __devinit int ath79_spi_probe(str + if (ret) + goto err_clk_put; + +- rate = DIV_ROUND_UP(clk_get_rate(sp->clk), MHZ); ++ sp->ahb_rate = clk_get_rate(sp->clk); ++ rate = DIV_ROUND_UP(sp->ahb_rate, MHZ); + if (!rate) { + ret = -EINVAL; + goto err_clk_disable; +--- a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h ++++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h +@@ -24,6 +24,7 @@ enum ath79_spi_cs_type { + struct ath79_spi_controller_data { + enum ath79_spi_cs_type cs_type; + unsigned cs_line; ++ bool is_flash; + }; + + #endif /* _ATH79_SPI_PLATFORM_H */ diff --git a/target/linux/ar71xx/patches-3.3/470-MIPS-ath79-swizzle-pci-address-for-ar71xx.patch b/target/linux/ar71xx/patches-3.3/470-MIPS-ath79-swizzle-pci-address-for-ar71xx.patch new file mode 100644 index 000000000..7912384d3 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/470-MIPS-ath79-swizzle-pci-address-for-ar71xx.patch @@ -0,0 +1,111 @@ +--- /dev/null ++++ b/arch/mips/include/asm/mach-ath79/mangle-port.h +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (C) 2012 Gabor Juhos ++ * ++ * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h ++ * Copyright (C) 2003, 2004 Ralf Baechle ++ * ++ * This program 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. ++ */ ++ ++#ifndef __ASM_MACH_ATH79_MANGLE_PORT_H ++#define __ASM_MACH_ATH79_MANGLE_PORT_H ++ ++#ifdef CONFIG_PCI ++extern unsigned long (ath79_pci_swizzle_b)(unsigned long port); ++extern unsigned long (ath79_pci_swizzle_w)(unsigned long port); ++#else ++#define ath79_pci_swizzle_b(port) (port) ++#define ath79_pci_swizzle_w(port) (port) ++#endif ++ ++#define __swizzle_addr_b(port) ath79_pci_swizzle_b(port) ++#define __swizzle_addr_w(port) ath79_pci_swizzle_w(port) ++#define __swizzle_addr_l(port) (port) ++#define __swizzle_addr_q(port) (port) ++ ++# define ioswabb(a, x) (x) ++# define __mem_ioswabb(a, x) (x) ++# define ioswabw(a, x) (x) ++# define __mem_ioswabw(a, x) cpu_to_le16(x) ++# define ioswabl(a, x) (x) ++# define __mem_ioswabl(a, x) cpu_to_le32(x) ++# define ioswabq(a, x) (x) ++# define __mem_ioswabq(a, x) cpu_to_le64(x) ++ ++#endif /* __ASM_MACH_ATH79_MANGLE_PORT_H */ +--- a/arch/mips/ath79/pci.c ++++ b/arch/mips/ath79/pci.c +@@ -13,6 +13,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -25,6 +26,9 @@ static int (*ath79_pci_plat_dev_init)(st + static const struct ath79_pci_irq *ath79_pci_irq_map __initdata; + static unsigned ath79_pci_nr_irqs __initdata; + ++static unsigned long (*__ath79_pci_swizzle_b)(unsigned long port); ++static unsigned long (*__ath79_pci_swizzle_w)(unsigned long port); ++ + static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = { + { + .slot = 17, +@@ -202,12 +206,50 @@ ath79_register_pci_ar724x(int id, + return pdev; + } + ++static inline bool ar71xx_is_pci_addr(unsigned long port) ++{ ++ unsigned long phys = CPHYSADDR(port); ++ ++ return (phys >= AR71XX_PCI_MEM_BASE && ++ phys < AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE); ++} ++ ++static unsigned long ar71xx_pci_swizzle_b(unsigned long port) ++{ ++ return ar71xx_is_pci_addr(port) ? port ^ 3 : port; ++} ++ ++static unsigned long ar71xx_pci_swizzle_w(unsigned long port) ++{ ++ return ar71xx_is_pci_addr(port) ? port ^ 2 : port; ++} ++ ++unsigned long ath79_pci_swizzle_b(unsigned long port) ++{ ++ if (__ath79_pci_swizzle_b) ++ return __ath79_pci_swizzle_b(port); ++ ++ return port; ++} ++EXPORT_SYMBOL(ath79_pci_swizzle_b); ++ ++unsigned long ath79_pci_swizzle_w(unsigned long port) ++{ ++ if (__ath79_pci_swizzle_w) ++ return __ath79_pci_swizzle_w(port); ++ ++ return port; ++} ++EXPORT_SYMBOL(ath79_pci_swizzle_w); ++ + int __init ath79_register_pci(void) + { + struct platform_device *pdev = NULL; + + if (soc_is_ar71xx()) { + pdev = ath79_register_pci_ar71xx(); ++ __ath79_pci_swizzle_b = ar71xx_pci_swizzle_b; ++ __ath79_pci_swizzle_w = ar71xx_pci_swizzle_w; + } else if (soc_is_ar724x()) { + pdev = ath79_register_pci_ar724x(-1, + AR724X_PCI_CFG_BASE, diff --git a/target/linux/ar71xx/patches-3.3/500-MIPS-fw-myloader.patch b/target/linux/ar71xx/patches-3.3/500-MIPS-fw-myloader.patch new file mode 100644 index 000000000..f269763ed --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/500-MIPS-fw-myloader.patch @@ -0,0 +1,22 @@ +--- a/arch/mips/Makefile ++++ b/arch/mips/Makefile +@@ -175,6 +175,7 @@ endif + # + libs-$(CONFIG_ARC) += arch/mips/fw/arc/ + libs-$(CONFIG_CFE) += arch/mips/fw/cfe/ ++libs-$(CONFIG_MYLOADER) += arch/mips/fw/myloader/ + libs-$(CONFIG_SNIPROM) += arch/mips/fw/sni/ + libs-y += arch/mips/fw/lib/ + +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -981,6 +981,9 @@ config MIPS_NILE4 + config MIPS_DISABLE_OBSOLETE_IDE + bool + ++config MYLOADER ++ bool ++ + config SYNC_R4K + bool + diff --git a/target/linux/ar71xx/patches-3.3/501-MIPS-ath79-add-mac-argument-to-ath79_register_wmac.patch b/target/linux/ar71xx/patches-3.3/501-MIPS-ath79-add-mac-argument-to-ath79_register_wmac.patch new file mode 100644 index 000000000..bab4f701d --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/501-MIPS-ath79-add-mac-argument-to-ath79_register_wmac.patch @@ -0,0 +1,81 @@ +--- a/arch/mips/ath79/dev-wmac.c ++++ b/arch/mips/ath79/dev-wmac.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -22,6 +23,7 @@ + #include + #include "dev-wmac.h" + ++static u8 ath79_wmac_mac[ETH_ALEN]; + static struct ath9k_platform_data ath79_wmac_data; + + static struct resource ath79_wmac_resources[] = { +@@ -134,7 +136,7 @@ static void qca955x_wmac_setup(void) + ath79_wmac_data.is_clk_25mhz = true; + } + +-void __init ath79_register_wmac(u8 *cal_data) ++void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr) + { + if (soc_is_ar913x()) + ar913x_wmac_setup(); +@@ -151,5 +153,10 @@ void __init ath79_register_wmac(u8 *cal_ + memcpy(ath79_wmac_data.eeprom_data, cal_data, + sizeof(ath79_wmac_data.eeprom_data)); + ++ if (mac_addr) { ++ memcpy(ath79_wmac_mac, mac_addr, sizeof(ath79_wmac_mac)); ++ ath79_wmac_data.macaddr = ath79_wmac_mac; ++ } ++ + platform_device_register(&ath79_wmac_device); + } +--- a/arch/mips/ath79/dev-wmac.h ++++ b/arch/mips/ath79/dev-wmac.h +@@ -12,6 +12,6 @@ + #ifndef _ATH79_DEV_WMAC_H + #define _ATH79_DEV_WMAC_H + +-void ath79_register_wmac(u8 *cal_data); ++void ath79_register_wmac(u8 *cal_data, u8 *mac_addr); + + #endif /* _ATH79_DEV_WMAC_H */ +--- a/arch/mips/ath79/mach-ap81.c ++++ b/arch/mips/ath79/mach-ap81.c +@@ -98,7 +98,7 @@ static void __init ap81_setup(void) + ap81_gpio_keys); + ath79_register_spi(&ap81_spi_data, ap81_spi_info, + ARRAY_SIZE(ap81_spi_info)); +- ath79_register_wmac(cal_data); ++ ath79_register_wmac(cal_data, NULL); + ath79_register_usb(); + } + +--- a/arch/mips/ath79/mach-db120.c ++++ b/arch/mips/ath79/mach-db120.c +@@ -134,7 +134,7 @@ static void __init db120_setup(void) + ath79_register_spi(&db120_spi_data, db120_spi_info, + ARRAY_SIZE(db120_spi_info)); + ath79_register_usb(); +- ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET); ++ ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET, NULL); + db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET); + } + +--- a/arch/mips/ath79/mach-ap121.c ++++ b/arch/mips/ath79/mach-ap121.c +@@ -91,7 +91,7 @@ static void __init ap121_setup(void) + ath79_register_spi(&ap121_spi_data, ap121_spi_info, + ARRAY_SIZE(ap121_spi_info)); + ath79_register_usb(); +- ath79_register_wmac(cal_data); ++ ath79_register_wmac(cal_data, NULL); + } + + MIPS_MACHINE(ATH79_MACH_AP121, "AP121", "Atheros AP121 reference board", diff --git a/target/linux/ar71xx/patches-3.3/502-MIPS-ath79-export-ath79_gpio_base.patch b/target/linux/ar71xx/patches-3.3/502-MIPS-ath79-export-ath79_gpio_base.patch new file mode 100644 index 000000000..0a218a684 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/502-MIPS-ath79-export-ath79_gpio_base.patch @@ -0,0 +1,23 @@ +--- a/arch/mips/ath79/gpio.c ++++ b/arch/mips/ath79/gpio.c +@@ -25,7 +25,9 @@ + #include + #include "common.h" + +-static void __iomem *ath79_gpio_base; ++void __iomem *ath79_gpio_base; ++EXPORT_SYMBOL_GPL(ath79_gpio_base); ++ + static unsigned long ath79_gpio_count; + static DEFINE_SPINLOCK(ath79_gpio_lock); + +--- a/arch/mips/include/asm/mach-ath79/ath79.h ++++ b/arch/mips/include/asm/mach-ath79/ath79.h +@@ -110,6 +110,7 @@ static inline int soc_is_qca955x(void) + } + + extern void __iomem *ath79_ddr_base; ++extern void __iomem *ath79_gpio_base; + extern void __iomem *ath79_pll_base; + extern void __iomem *ath79_reset_base; + diff --git a/target/linux/ar71xx/patches-3.3/503-MIPS-ath79-add-flash-acquire-release.patch b/target/linux/ar71xx/patches-3.3/503-MIPS-ath79-add-flash-acquire-release.patch new file mode 100644 index 000000000..81350ca3b --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/503-MIPS-ath79-add-flash-acquire-release.patch @@ -0,0 +1,37 @@ +--- a/arch/mips/ath79/common.c ++++ b/arch/mips/ath79/common.c +@@ -22,6 +22,7 @@ + #include "common.h" + + static DEFINE_SPINLOCK(ath79_device_reset_lock); ++static DEFINE_MUTEX(ath79_flash_mutex); + + u32 ath79_cpu_freq; + EXPORT_SYMBOL_GPL(ath79_cpu_freq); +@@ -109,3 +110,16 @@ void ath79_device_reset_clear(u32 mask) + spin_unlock_irqrestore(&ath79_device_reset_lock, flags); + } + EXPORT_SYMBOL_GPL(ath79_device_reset_clear); ++ ++void ath79_flash_acquire(void) ++{ ++ mutex_lock(&ath79_flash_mutex); ++} ++EXPORT_SYMBOL_GPL(ath79_flash_acquire); ++ ++void ath79_flash_release(void) ++{ ++ mutex_unlock(&ath79_flash_mutex); ++} ++EXPORT_SYMBOL_GPL(ath79_flash_release); ++ +--- a/arch/mips/include/asm/mach-ath79/ath79.h ++++ b/arch/mips/include/asm/mach-ath79/ath79.h +@@ -137,4 +137,7 @@ static inline u32 ath79_reset_rr(unsigne + void ath79_device_reset_set(u32 mask); + void ath79_device_reset_clear(u32 mask); + ++void ath79_flash_acquire(void); ++void ath79_flash_release(void); ++ + #endif /* __ASM_MACH_ATH79_H */ diff --git a/target/linux/ar71xx/patches-3.3/504-MIPS-ath79-add-ath79_device_reset_get.patch b/target/linux/ar71xx/patches-3.3/504-MIPS-ath79-add-ath79_device_reset_get.patch new file mode 100644 index 000000000..55780996f --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/504-MIPS-ath79-add-ath79_device_reset_get.patch @@ -0,0 +1,45 @@ +--- a/arch/mips/include/asm/mach-ath79/ath79.h ++++ b/arch/mips/include/asm/mach-ath79/ath79.h +@@ -136,6 +136,7 @@ static inline u32 ath79_reset_rr(unsigne + + void ath79_device_reset_set(u32 mask); + void ath79_device_reset_clear(u32 mask); ++u32 ath79_device_reset_get(u32 mask); + + void ath79_flash_acquire(void); + void ath79_flash_release(void); +--- a/arch/mips/ath79/common.c ++++ b/arch/mips/ath79/common.c +@@ -111,6 +111,32 @@ void ath79_device_reset_clear(u32 mask) + } + EXPORT_SYMBOL_GPL(ath79_device_reset_clear); + ++u32 ath79_device_reset_get(u32 mask) ++{ ++ unsigned long flags; ++ u32 reg; ++ u32 ret; ++ ++ if (soc_is_ar71xx()) ++ reg = AR71XX_RESET_REG_RESET_MODULE; ++ else if (soc_is_ar724x()) ++ reg = AR724X_RESET_REG_RESET_MODULE; ++ else if (soc_is_ar913x()) ++ reg = AR913X_RESET_REG_RESET_MODULE; ++ else if (soc_is_ar933x()) ++ reg = AR933X_RESET_REG_RESET_MODULE; ++ else if (soc_is_ar934x()) ++ reg = AR934X_RESET_REG_RESET_MODULE; ++ else ++ BUG(); ++ ++ spin_lock_irqsave(&ath79_device_reset_lock, flags); ++ ret = ath79_reset_rr(reg); ++ spin_unlock_irqrestore(&ath79_device_reset_lock, flags); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(ath79_device_reset_get); ++ + void ath79_flash_acquire(void) + { + mutex_lock(&ath79_flash_mutex); diff --git a/target/linux/ar71xx/patches-3.3/505-MIPS-ath79-add-ath79_gpio_function_select.patch b/target/linux/ar71xx/patches-3.3/505-MIPS-ath79-add-ath79_gpio_function_select.patch new file mode 100644 index 000000000..6b09fc0a9 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/505-MIPS-ath79-add-ath79_gpio_function_select.patch @@ -0,0 +1,47 @@ +--- a/arch/mips/ath79/common.h ++++ b/arch/mips/ath79/common.h +@@ -26,6 +26,7 @@ void ath79_ddr_wb_flush(unsigned int reg + void ath79_gpio_function_enable(u32 mask); + void ath79_gpio_function_disable(u32 mask); + void ath79_gpio_function_setup(u32 set, u32 clear); ++void ath79_gpio_output_select(unsigned gpio, u8 val); + void ath79_gpio_init(void); + + #endif /* __ATH79_COMMON_H */ +--- a/arch/mips/ath79/gpio.c ++++ b/arch/mips/ath79/gpio.c +@@ -184,6 +184,34 @@ void ath79_gpio_function_setup(u32 set, + spin_unlock_irqrestore(&ath79_gpio_lock, flags); + } + ++void __init ath79_gpio_output_select(unsigned gpio, u8 val) ++{ ++ void __iomem *base = ath79_gpio_base; ++ unsigned long flags; ++ unsigned int reg; ++ u32 t, s; ++ ++ BUG_ON(!soc_is_ar934x()); ++ ++ if (gpio >= AR934X_GPIO_COUNT) ++ return; ++ ++ reg = AR934X_GPIO_REG_OUT_FUNC0 + 4 * (gpio / 4); ++ s = 8 * (gpio % 4); ++ ++ spin_lock_irqsave(&ath79_gpio_lock, flags); ++ ++ t = __raw_readl(base + reg); ++ t &= ~(0xff << s); ++ t |= val << s; ++ __raw_writel(t, base + reg); ++ ++ /* flush write */ ++ (void) __raw_readl(base + reg); ++ ++ spin_unlock_irqrestore(&ath79_gpio_lock, flags); ++} ++ + void __init ath79_gpio_init(void) + { + int err; diff --git a/target/linux/ar71xx/patches-3.3/506-MIPS-ath79-prom-parse-redboot-args.patch b/target/linux/ar71xx/patches-3.3/506-MIPS-ath79-prom-parse-redboot-args.patch new file mode 100644 index 000000000..aab959b90 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/506-MIPS-ath79-prom-parse-redboot-args.patch @@ -0,0 +1,86 @@ +--- a/arch/mips/ath79/prom.c ++++ b/arch/mips/ath79/prom.c +@@ -19,6 +19,8 @@ + + #include "common.h" + ++static char ath79_cmdline_buf[COMMAND_LINE_SIZE] __initdata; ++ + static inline int is_valid_ram_addr(void *addr) + { + if (((u32) addr > KSEG0) && +@@ -32,6 +34,41 @@ static inline int is_valid_ram_addr(void + return 0; + } + ++static void __init ath79_prom_append_cmdline(const char *name, ++ const char *value) ++{ ++ snprintf(ath79_cmdline_buf, sizeof(ath79_cmdline_buf), ++ " %s=%s", name, value); ++ strlcat(arcs_cmdline, ath79_cmdline_buf, sizeof(arcs_cmdline)); ++} ++ ++static const char * __init ath79_prom_find_env(char **envp, const char *name) ++{ ++ const char *ret = NULL; ++ int len; ++ char **p; ++ ++ if (!is_valid_ram_addr(envp)) ++ return NULL; ++ ++ len = strlen(name); ++ for (p = envp; is_valid_ram_addr(*p); p++) { ++ if (strncmp(name, *p, len) == 0 && (*p)[len] == '=') { ++ ret = *p + len + 1; ++ break; ++ } ++ ++ /* RedBoot env comes in pointer pairs - key, value */ ++ if (strncmp(name, *p, len) == 0 && (*p)[len] == 0) ++ if (is_valid_ram_addr(*(++p))) { ++ ret = *p; ++ break; ++ } ++ } ++ ++ return ret; ++} ++ + static __init void ath79_prom_init_cmdline(int argc, char **argv) + { + int i; +@@ -48,7 +85,32 @@ static __init void ath79_prom_init_cmdli + + void __init prom_init(void) + { ++ const char *env; ++ char **envp; ++ + ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1); ++ ++ envp = (char **)fw_arg2; ++ if (!strstr(arcs_cmdline, "ethaddr=")) { ++ env = ath79_prom_find_env(envp, "ethaddr"); ++ if (env) ++ ath79_prom_append_cmdline("ethaddr", env); ++ } ++ ++ if (!strstr(arcs_cmdline, "board=")) { ++ env = ath79_prom_find_env(envp, "board"); ++ if (env) { ++ /* Workaround for buggy bootloaders */ ++ if (strcmp(env, "RouterStation") == 0 || ++ strcmp(env, "Ubiquiti AR71xx-based board") == 0) ++ env = "UBNT-RS"; ++ ++ if (strcmp(env, "RouterStation PRO") == 0) ++ env = "UBNT-RSPRO"; ++ ++ ath79_prom_append_cmdline("board", env); ++ } ++ } + } + + void __init prom_free_prom_memory(void) diff --git a/target/linux/ar71xx/patches-3.3/507-MIPS-ath79-prom-add-myloader-support.patch b/target/linux/ar71xx/patches-3.3/507-MIPS-ath79-prom-add-myloader-support.patch new file mode 100644 index 000000000..67c1faf9b --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/507-MIPS-ath79-prom-add-myloader-support.patch @@ -0,0 +1,58 @@ +--- a/arch/mips/ath79/prom.c ++++ b/arch/mips/ath79/prom.c +@@ -16,6 +16,7 @@ + + #include + #include ++#include + + #include "common.h" + +@@ -69,6 +70,37 @@ static const char * __init ath79_prom_fi + return ret; + } + ++static int __init ath79_prom_init_myloader(void) ++{ ++ struct myloader_info *mylo; ++ char mac_buf[32]; ++ unsigned char *mac; ++ ++ mylo = myloader_get_info(); ++ if (!mylo) ++ return 0; ++ ++ switch (mylo->did) { ++ case DEVID_COMPEX_WP543: ++ ath79_prom_append_cmdline("board", "WP543"); ++ break; ++ case DEVID_COMPEX_WPE72: ++ ath79_prom_append_cmdline("board", "WPE72"); ++ break; ++ default: ++ pr_warn("prom: unknown device id: %x\n", mylo->did); ++ return 0; ++ } ++ ++ mac = mylo->macs[0]; ++ snprintf(mac_buf, sizeof(mac_buf), "%02x:%02x:%02x:%02x:%02x:%02x", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); ++ ++ ath79_prom_append_cmdline("ethaddr", mac_buf); ++ ++ return 1; ++} ++ + static __init void ath79_prom_init_cmdline(int argc, char **argv) + { + int i; +@@ -88,6 +120,9 @@ void __init prom_init(void) + const char *env; + char **envp; + ++ if (ath79_prom_init_myloader()) ++ return; ++ + ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1); + + envp = (char **)fw_arg2; diff --git a/target/linux/ar71xx/patches-3.3/508-MIPS-ath79-prom-image-command-line-hack.patch b/target/linux/ar71xx/patches-3.3/508-MIPS-ath79-prom-image-command-line-hack.patch new file mode 100644 index 000000000..72a3b5664 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/508-MIPS-ath79-prom-image-command-line-hack.patch @@ -0,0 +1,57 @@ +--- a/arch/mips/ath79/prom.c ++++ b/arch/mips/ath79/prom.c +@@ -70,6 +70,35 @@ static const char * __init ath79_prom_fi + return ret; + } + ++#ifdef CONFIG_IMAGE_CMDLINE_HACK ++extern char __image_cmdline[]; ++ ++static int __init ath79_use_image_cmdline(void) ++{ ++ char *p = __image_cmdline; ++ int replace = 0; ++ ++ if (*p == '-') { ++ replace = 1; ++ p++; ++ } ++ ++ if (*p == '\0') ++ return 0; ++ ++ if (replace) { ++ strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline)); ++ } else { ++ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); ++ strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); ++ } ++ ++ return 1; ++} ++#else ++static inline int ath79_use_image_cmdline(void) { return 0; } ++#endif ++ + static int __init ath79_prom_init_myloader(void) + { + struct myloader_info *mylo; +@@ -98,6 +127,8 @@ static int __init ath79_prom_init_myload + + ath79_prom_append_cmdline("ethaddr", mac_buf); + ++ ath79_use_image_cmdline(); ++ + return 1; + } + +@@ -105,6 +136,9 @@ static __init void ath79_prom_init_cmdli + { + int i; + ++ if (ath79_use_image_cmdline()) ++ return; ++ + if (!is_valid_ram_addr(argv)) + return; + diff --git a/target/linux/ar71xx/patches-3.3/509-MIPS-ath79-process-board-kernel-option.patch b/target/linux/ar71xx/patches-3.3/509-MIPS-ath79-process-board-kernel-option.patch new file mode 100644 index 000000000..9236c6686 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/509-MIPS-ath79-process-board-kernel-option.patch @@ -0,0 +1,11 @@ +--- a/arch/mips/ath79/setup.c ++++ b/arch/mips/ath79/setup.c +@@ -225,6 +225,8 @@ void __init plat_time_init(void) + mips_hpt_frequency = clk_get_rate(clk) / 2; + } + ++__setup("board=", mips_machtype_setup); ++ + static int __init ath79_setup(void) + { + ath79_gpio_init(); diff --git a/target/linux/ar71xx/patches-3.3/510-MIPS-ath79-init-gpio-pin-of-wmac-device.patch b/target/linux/ar71xx/patches-3.3/510-MIPS-ath79-init-gpio-pin-of-wmac-device.patch new file mode 100644 index 000000000..2d2235e29 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/510-MIPS-ath79-init-gpio-pin-of-wmac-device.patch @@ -0,0 +1,14 @@ +--- a/arch/mips/ath79/dev-wmac.c ++++ b/arch/mips/ath79/dev-wmac.c +@@ -24,7 +24,10 @@ + #include "dev-wmac.h" + + static u8 ath79_wmac_mac[ETH_ALEN]; +-static struct ath9k_platform_data ath79_wmac_data; ++ ++static struct ath9k_platform_data ath79_wmac_data = { ++ .led_pin = -1, ++}; + + static struct resource ath79_wmac_resources[] = { + { diff --git a/target/linux/ar71xx/patches-3.3/511-MIPS-ath79-add-ath79_set_usb_power_gpio.patch b/target/linux/ar71xx/patches-3.3/511-MIPS-ath79-add-ath79_set_usb_power_gpio.patch new file mode 100644 index 000000000..91a793d5e --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/511-MIPS-ath79-add-ath79_set_usb_power_gpio.patch @@ -0,0 +1,47 @@ +--- a/arch/mips/ath79/dev-usb.c ++++ b/arch/mips/ath79/dev-usb.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -282,3 +283,26 @@ void __init ath79_register_usb(void) + else + BUG(); + } ++ ++void __init ath79_set_usb_power_gpio(unsigned int gpio, unsigned long flags, ++ const char *label) ++{ ++ int err; ++ ++ err = gpio_request_one(gpio, flags, label); ++ if (err) { ++ pr_err("ath79: can't setup GPIO%u (%s), err=%d\n", ++ gpio, label, err); ++ return; ++ } ++ ++ err = gpio_export(gpio, false); ++ if (err) { ++ pr_err("ath79: can't export GPIO%u (%s), err=%d\n", ++ gpio, label, err); ++ } ++ ++ return; ++} ++ ++ +--- a/arch/mips/ath79/dev-usb.h ++++ b/arch/mips/ath79/dev-usb.h +@@ -13,5 +13,7 @@ + #define _ATH79_DEV_USB_H + + void ath79_register_usb(void); ++void ath79_set_usb_power_gpio(unsigned int gpio, unsigned long flags, ++ const char *label); + + #endif /* _ATH79_DEV_USB_H */ diff --git a/target/linux/ar71xx/patches-3.3/520-MIPS-ath79-enable-UART-function.patch b/target/linux/ar71xx/patches-3.3/520-MIPS-ath79-enable-UART-function.patch new file mode 100644 index 000000000..1cb407f83 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/520-MIPS-ath79-enable-UART-function.patch @@ -0,0 +1,18 @@ +--- a/arch/mips/ath79/dev-common.c ++++ b/arch/mips/ath79/dev-common.c +@@ -87,6 +87,15 @@ void __init ath79_register_uart(void) + if (IS_ERR(clk)) + panic("unable to get UART clock, err=%ld", PTR_ERR(clk)); + ++ if (soc_is_ar71xx()) ++ ath79_gpio_function_enable(AR71XX_GPIO_FUNC_UART_EN); ++ else if (soc_is_ar724x()) ++ ath79_gpio_function_enable(AR724X_GPIO_FUNC_UART_EN); ++ else if (soc_is_ar913x()) ++ ath79_gpio_function_enable(AR913X_GPIO_FUNC_UART_EN); ++ else if (soc_is_ar933x()) ++ ath79_gpio_function_enable(AR933X_GPIO_FUNC_UART_EN); ++ + if (soc_is_ar71xx() || + soc_is_ar724x() || + soc_is_ar913x() || diff --git a/target/linux/ar71xx/patches-3.3/521-MIPS-ath79-enable-UART-for-early_serial.patch b/target/linux/ar71xx/patches-3.3/521-MIPS-ath79-enable-UART-for-early_serial.patch new file mode 100644 index 000000000..489bc9673 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/521-MIPS-ath79-enable-UART-for-early_serial.patch @@ -0,0 +1,61 @@ +--- a/arch/mips/ath79/early_printk.c ++++ b/arch/mips/ath79/early_printk.c +@@ -56,6 +56,46 @@ static void prom_putchar_dummy(unsigned + /* nothing to do */ + } + ++static void prom_enable_uart(u32 id) ++{ ++ void __iomem *gpio_base; ++ u32 uart_en; ++ u32 t; ++ ++ switch (id) { ++ case REV_ID_MAJOR_AR71XX: ++ uart_en = AR71XX_GPIO_FUNC_UART_EN; ++ break; ++ ++ case REV_ID_MAJOR_AR7240: ++ case REV_ID_MAJOR_AR7241: ++ case REV_ID_MAJOR_AR7242: ++ uart_en = AR724X_GPIO_FUNC_UART_EN; ++ break; ++ ++ case REV_ID_MAJOR_AR913X: ++ uart_en = AR913X_GPIO_FUNC_UART_EN; ++ break; ++ ++ case REV_ID_MAJOR_AR9330: ++ case REV_ID_MAJOR_AR9331: ++ uart_en = AR933X_GPIO_FUNC_UART_EN; ++ break; ++ ++ case REV_ID_MAJOR_AR9341: ++ case REV_ID_MAJOR_AR9342: ++ case REV_ID_MAJOR_AR9344: ++ /* TODO */ ++ default: ++ return; ++ } ++ ++ gpio_base = (void __iomem *)(KSEG1ADDR(AR71XX_GPIO_BASE)); ++ t = __raw_readl(gpio_base + AR71XX_GPIO_REG_FUNC); ++ t |= uart_en; ++ __raw_writel(t, gpio_base + AR71XX_GPIO_REG_FUNC); ++} ++ + static void prom_putchar_init(void) + { + void __iomem *base; +@@ -85,8 +125,10 @@ static void prom_putchar_init(void) + + default: + _prom_putchar = prom_putchar_dummy; +- break; ++ return; + } ++ ++ prom_enable_uart(id); + } + + void prom_putchar(unsigned char ch) diff --git a/target/linux/ar71xx/patches-3.3/601-MIPS-ath79-add-more-register-defines.patch b/target/linux/ar71xx/patches-3.3/601-MIPS-ath79-add-more-register-defines.patch new file mode 100644 index 000000000..8a11a70d1 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/601-MIPS-ath79-add-more-register-defines.patch @@ -0,0 +1,304 @@ +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -21,6 +21,10 @@ + #include + + #define AR71XX_APB_BASE 0x18000000 ++#define AR71XX_GE0_BASE 0x19000000 ++#define AR71XX_GE0_SIZE 0x10000 ++#define AR71XX_GE1_BASE 0x1a000000 ++#define AR71XX_GE1_SIZE 0x10000 + #define AR71XX_EHCI_BASE 0x1b000000 + #define AR71XX_EHCI_SIZE 0x1000 + #define AR71XX_OHCI_BASE 0x1c000000 +@@ -40,6 +44,8 @@ + #define AR71XX_PLL_SIZE 0x100 + #define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) + #define AR71XX_RESET_SIZE 0x100 ++#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000) ++#define AR71XX_MII_SIZE 0x100 + + #define AR71XX_PCI_MEM_BASE 0x10000000 + #define AR71XX_PCI_MEM_SIZE 0x07000000 +@@ -82,17 +88,23 @@ + + #define AR933X_UART_BASE (AR71XX_APB_BASE + 0x00020000) + #define AR933X_UART_SIZE 0x14 ++#define AR933X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) ++#define AR933X_GMAC_SIZE 0x04 + #define AR933X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) + #define AR933X_WMAC_SIZE 0x20000 + #define AR933X_EHCI_BASE 0x1b000000 + #define AR933X_EHCI_SIZE 0x1000 + ++#define AR934X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) ++#define AR934X_GMAC_SIZE 0x14 + #define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) + #define AR934X_WMAC_SIZE 0x20000 + #define AR934X_EHCI_BASE 0x1b000000 + #define AR934X_EHCI_SIZE 0x200 + #define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000) + #define AR934X_SRIF_SIZE 0x1000 ++#define AR934X_NFC_BASE 0x1b000200 ++#define AR934X_NFC_SIZE 0xb8 + + #define QCA955X_PCI_MEM_BASE0 0x10000000 + #define QCA955X_PCI_MEM_BASE1 0x12000000 +@@ -112,6 +124,10 @@ + #define QCA955X_EHCI0_BASE 0x1b000000 + #define QCA955X_EHCI1_BASE 0x1b400000 + #define QCA955X_EHCI_SIZE 0x200 ++#define QCA955X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) ++#define QCA955X_GMAC_SIZE 0x40 ++#define QCA955X_NFC_BASE 0x1b000200 ++#define QCA955X_NFC_SIZE 0xb8 + + /* + * DDR_CTRL block +@@ -167,6 +183,9 @@ + #define AR71XX_AHB_DIV_SHIFT 20 + #define AR71XX_AHB_DIV_MASK 0x7 + ++#define AR71XX_ETH0_PLL_SHIFT 17 ++#define AR71XX_ETH1_PLL_SHIFT 19 ++ + #define AR724X_PLL_REG_CPU_CONFIG 0x00 + #define AR724X_PLL_REG_PCIE_CONFIG 0x18 + +@@ -179,6 +198,8 @@ + #define AR724X_DDR_DIV_SHIFT 22 + #define AR724X_DDR_DIV_MASK 0x3 + ++#define AR7242_PLL_REG_ETH0_INT_CLOCK 0x2c ++ + #define AR913X_PLL_REG_CPU_CONFIG 0x00 + #define AR913X_PLL_REG_ETH_CONFIG 0x04 + #define AR913X_PLL_REG_ETH0_INT_CLOCK 0x14 +@@ -191,6 +212,9 @@ + #define AR913X_AHB_DIV_SHIFT 19 + #define AR913X_AHB_DIV_MASK 0x1 + ++#define AR913X_ETH0_PLL_SHIFT 20 ++#define AR913X_ETH1_PLL_SHIFT 22 ++ + #define AR933X_PLL_CPU_CONFIG_REG 0x00 + #define AR933X_PLL_CLOCK_CTRL_REG 0x08 + +@@ -212,6 +236,8 @@ + #define AR934X_PLL_CPU_CONFIG_REG 0x00 + #define AR934X_PLL_DDR_CONFIG_REG 0x04 + #define AR934X_PLL_CPU_DDR_CLK_CTRL_REG 0x08 ++#define AR934X_PLL_SWITCH_CLOCK_CONTROL_REG 0x24 ++#define AR934X_PLL_ETH_XMII_CONTROL_REG 0x2c + + #define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT 0 + #define AR934X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f +@@ -244,6 +270,8 @@ + #define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) + #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) + ++#define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6) ++ + #define QCA955X_PLL_CPU_CONFIG_REG 0x00 + #define QCA955X_PLL_DDR_CONFIG_REG 0x04 + #define QCA955X_PLL_CLK_CTRL_REG 0x08 +@@ -370,16 +398,50 @@ + #define AR913X_RESET_USB_HOST BIT(5) + #define AR913X_RESET_USB_PHY BIT(4) + ++#define AR933X_RESET_GE1_MDIO BIT(23) ++#define AR933X_RESET_GE0_MDIO BIT(22) ++#define AR933X_RESET_GE1_MAC BIT(13) + #define AR933X_RESET_WMAC BIT(11) ++#define AR933X_RESET_GE0_MAC BIT(9) + #define AR933X_RESET_USB_HOST BIT(5) + #define AR933X_RESET_USB_PHY BIT(4) + #define AR933X_RESET_USBSUS_OVERRIDE BIT(3) + ++#define AR934X_RESET_HOST BIT(31) ++#define AR934X_RESET_SLIC BIT(30) ++#define AR934X_RESET_HDMA BIT(29) ++#define AR934X_RESET_EXTERNAL BIT(28) ++#define AR934X_RESET_RTC BIT(27) ++#define AR934X_RESET_PCIE_EP_INT BIT(26) ++#define AR934X_RESET_CHKSUM_ACC BIT(25) ++#define AR934X_RESET_FULL_CHIP BIT(24) ++#define AR934X_RESET_GE1_MDIO BIT(23) ++#define AR934X_RESET_GE0_MDIO BIT(22) ++#define AR934X_RESET_CPU_NMI BIT(21) ++#define AR934X_RESET_CPU_COLD BIT(20) ++#define AR934X_RESET_HOST_RESET_INT BIT(19) ++#define AR934X_RESET_PCIE_EP BIT(18) ++#define AR934X_RESET_UART1 BIT(17) ++#define AR934X_RESET_DDR BIT(16) ++#define AR934X_RESET_USB_PHY_PLL_PWD_EXT BIT(15) ++#define AR934X_RESET_NANDF BIT(14) ++#define AR934X_RESET_GE1_MAC BIT(13) ++#define AR934X_RESET_ETH_SWITCH_ANALOG BIT(12) + #define AR934X_RESET_USB_PHY_ANALOG BIT(11) ++#define AR934X_RESET_HOST_DMA_INT BIT(10) ++#define AR934X_RESET_GE0_MAC BIT(9) ++#define AR934X_RESET_ETH_SWITCH BIT(8) ++#define AR934X_RESET_PCIE_PHY BIT(7) ++#define AR934X_RESET_PCIE BIT(6) + #define AR934X_RESET_USB_HOST BIT(5) + #define AR934X_RESET_USB_PHY BIT(4) + #define AR934X_RESET_USBSUS_OVERRIDE BIT(3) ++#define AR934X_RESET_LUT BIT(2) ++#define AR934X_RESET_MBOX BIT(1) ++#define AR934X_RESET_I2S BIT(0) + ++#define AR933X_BOOTSTRAP_MDIO_GPIO_EN BIT(18) ++#define AR933X_BOOTSTRAP_EEPBUSY BIT(4) + #define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) + + #define AR934X_BOOTSTRAP_SW_OPTION8 BIT(23) +@@ -520,6 +582,14 @@ + #define AR71XX_GPIO_REG_INT_ENABLE 0x24 + #define AR71XX_GPIO_REG_FUNC 0x28 + ++#define AR934X_GPIO_REG_OUT_FUNC0 0x2c ++#define AR934X_GPIO_REG_OUT_FUNC1 0x30 ++#define AR934X_GPIO_REG_OUT_FUNC2 0x34 ++#define AR934X_GPIO_REG_OUT_FUNC3 0x38 ++#define AR934X_GPIO_REG_OUT_FUNC4 0x3c ++#define AR934X_GPIO_REG_OUT_FUNC5 0x40 ++#define AR934X_GPIO_REG_FUNC 0x6c ++ + #define AR71XX_GPIO_COUNT 16 + #define AR724X_GPIO_COUNT 18 + #define AR913X_GPIO_COUNT 22 +@@ -548,4 +618,133 @@ + #define AR934X_SRIF_DPLL2_OUTDIV_SHIFT 13 + #define AR934X_SRIF_DPLL2_OUTDIV_MASK 0x7 + ++#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17) ++#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16) ++#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13) ++#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12) ++#define AR71XX_GPIO_FUNC_UART_EN BIT(8) ++#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4) ++#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0) ++ ++#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19) ++#define AR724X_GPIO_FUNC_SPI_EN BIT(18) ++#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14) ++#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13) ++#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12) ++#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11) ++#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10) ++#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9) ++#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4) ++#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3) ++#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2) ++#define AR724X_GPIO_FUNC_UART_EN BIT(1) ++#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0) ++ ++#define AR913X_GPIO_FUNC_WMAC_LED_EN BIT(22) ++#define AR913X_GPIO_FUNC_EXP_PORT_CS_EN BIT(21) ++#define AR913X_GPIO_FUNC_I2S_REFCLKEN BIT(20) ++#define AR913X_GPIO_FUNC_I2S_MCKEN BIT(19) ++#define AR913X_GPIO_FUNC_I2S1_EN BIT(18) ++#define AR913X_GPIO_FUNC_I2S0_EN BIT(17) ++#define AR913X_GPIO_FUNC_SLIC_EN BIT(16) ++#define AR913X_GPIO_FUNC_UART_RTSCTS_EN BIT(9) ++#define AR913X_GPIO_FUNC_UART_EN BIT(8) ++#define AR913X_GPIO_FUNC_USB_CLK_EN BIT(4) ++ ++#define AR933X_GPIO_FUNC_SPDIF2TCK BIT(31) ++#define AR933X_GPIO_FUNC_SPDIF_EN BIT(30) ++#define AR933X_GPIO_FUNC_I2SO_22_18_EN BIT(29) ++#define AR933X_GPIO_FUNC_I2S_MCK_EN BIT(27) ++#define AR933X_GPIO_FUNC_I2SO_EN BIT(26) ++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_DUPL BIT(25) ++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_COLL BIT(24) ++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_ACT BIT(23) ++#define AR933X_GPIO_FUNC_SPI_EN BIT(18) ++#define AR933X_GPIO_FUNC_SPI_CS_EN2 BIT(14) ++#define AR933X_GPIO_FUNC_SPI_CS_EN1 BIT(13) ++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7) ++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6) ++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5) ++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4) ++#define AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3) ++#define AR933X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2) ++#define AR933X_GPIO_FUNC_UART_EN BIT(1) ++#define AR933X_GPIO_FUNC_JTAG_DISABLE BIT(0) ++ ++#define AR934X_GPIO_FUNC_DDR_DQOE_EN BIT(17) ++#define AR934X_GPIO_FUNC_SPI_CS_1_EN BIT(14) ++#define AR934X_GPIO_FUNC_SPI_CS_0_EN BIT(13) ++ ++#define AR934X_GPIO_OUT_GPIO 0x00 ++ ++/* ++ * MII_CTRL block ++ */ ++#define AR71XX_MII_REG_MII0_CTRL 0x00 ++#define AR71XX_MII_REG_MII1_CTRL 0x04 ++ ++#define AR71XX_MII_CTRL_IF_MASK 3 ++#define AR71XX_MII_CTRL_SPEED_SHIFT 4 ++#define AR71XX_MII_CTRL_SPEED_MASK 3 ++#define AR71XX_MII_CTRL_SPEED_10 0 ++#define AR71XX_MII_CTRL_SPEED_100 1 ++#define AR71XX_MII_CTRL_SPEED_1000 2 ++ ++#define AR71XX_MII0_CTRL_IF_GMII 0 ++#define AR71XX_MII0_CTRL_IF_MII 1 ++#define AR71XX_MII0_CTRL_IF_RGMII 2 ++#define AR71XX_MII0_CTRL_IF_RMII 3 ++ ++#define AR71XX_MII1_CTRL_IF_RGMII 0 ++#define AR71XX_MII1_CTRL_IF_RMII 1 ++ ++/* ++ * AR933X GMAC interface ++ */ ++#define AR933X_GMAC_REG_ETH_CFG 0x00 ++ ++#define AR933X_ETH_CFG_RGMII_GE0 BIT(0) ++#define AR933X_ETH_CFG_MII_GE0 BIT(1) ++#define AR933X_ETH_CFG_GMII_GE0 BIT(2) ++#define AR933X_ETH_CFG_MII_GE0_MASTER BIT(3) ++#define AR933X_ETH_CFG_MII_GE0_SLAVE BIT(4) ++#define AR933X_ETH_CFG_MII_GE0_ERR_EN BIT(5) ++#define AR933X_ETH_CFG_SW_PHY_SWAP BIT(7) ++#define AR933X_ETH_CFG_SW_PHY_ADDR_SWAP BIT(8) ++#define AR933X_ETH_CFG_RMII_GE0 BIT(9) ++#define AR933X_ETH_CFG_RMII_GE0_SPD_10 0 ++#define AR933X_ETH_CFG_RMII_GE0_SPD_100 BIT(10) ++ ++/* ++ * AR934X GMAC Interface ++ */ ++#define AR934X_GMAC_REG_ETH_CFG 0x00 ++ ++#define AR934X_ETH_CFG_RGMII_GMAC0 BIT(0) ++#define AR934X_ETH_CFG_MII_GMAC0 BIT(1) ++#define AR934X_ETH_CFG_GMII_GMAC0 BIT(2) ++#define AR934X_ETH_CFG_MII_GMAC0_MASTER BIT(3) ++#define AR934X_ETH_CFG_MII_GMAC0_SLAVE BIT(4) ++#define AR934X_ETH_CFG_MII_GMAC0_ERR_EN BIT(5) ++#define AR934X_ETH_CFG_SW_ONLY_MODE BIT(6) ++#define AR934X_ETH_CFG_SW_PHY_SWAP BIT(7) ++#define AR934X_ETH_CFG_SW_APB_ACCESS BIT(9) ++#define AR934X_ETH_CFG_RMII_GMAC0 BIT(10) ++#define AR933X_ETH_CFG_MII_CNTL_SPEED BIT(11) ++#define AR934X_ETH_CFG_RMII_GMAC0_MASTER BIT(12) ++#define AR933X_ETH_CFG_SW_ACC_MSB_FIRST BIT(13) ++ ++/* ++ * QCA955X GMAC Interface ++ */ ++ ++#define QCA955X_GMAC_REG_ETH_CFG 0x00 ++ ++#define QCA955X_ETH_CFG_RGMII_GMAC0 BIT(0) ++#define QCA955X_ETH_CFG_SGMII_GMAC0 BIT(6) ++ + #endif /* __ASM_MACH_AR71XX_REGS_H */ diff --git a/target/linux/ar71xx/patches-3.3/602-MIPS-ath79-add-openwrt-stuff.patch b/target/linux/ar71xx/patches-3.3/602-MIPS-ath79-add-openwrt-stuff.patch new file mode 100644 index 000000000..e61496fcd --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/602-MIPS-ath79-add-openwrt-stuff.patch @@ -0,0 +1,76 @@ +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -106,6 +106,20 @@ config SOC_QCA955X + select PCI_AR724X if PCI + def_bool n + ++config ATH79_DEV_M25P80 ++ select ATH79_DEV_SPI ++ def_bool n ++ ++config ATH79_DEV_AP9X_PCI ++ select ATH79_PCI_ATH9K_FIXUP ++ def_bool n ++ ++config ATH79_DEV_DSA ++ def_bool n ++ ++config ATH79_DEV_ETH ++ def_bool n ++ + config PCI_AR724X + def_bool n + +@@ -115,6 +129,10 @@ config ATH79_DEV_GPIO_BUTTONS + config ATH79_DEV_LEDS_GPIO + def_bool n + ++config ATH79_DEV_NFC ++ depends on (SOC_AR934X) ++ def_bool n ++ + config ATH79_DEV_SPI + def_bool n + +@@ -125,4 +143,13 @@ config ATH79_DEV_WMAC + depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA955X) + def_bool n + ++config ATH79_NVRAM ++ def_bool n ++ ++config ATH79_PCI_ATH9K_FIXUP ++ def_bool n ++ ++config ATH79_ROUTERBOOT ++ def_bool n ++ + endif +--- a/arch/mips/ath79/Makefile ++++ b/arch/mips/ath79/Makefile +@@ -17,13 +17,25 @@ obj-$(CONFIG_PCI) += pci.o + # Devices + # + obj-y += dev-common.o ++obj-$(CONFIG_ATH79_DEV_AP9X_PCI) += dev-ap9x-pci.o ++obj-$(CONFIG_ATH79_DEV_DSA) += dev-dsa.o ++obj-$(CONFIG_ATH79_DEV_ETH) += dev-eth.o + obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o + obj-$(CONFIG_ATH79_DEV_LEDS_GPIO) += dev-leds-gpio.o ++obj-$(CONFIG_ATH79_DEV_M25P80) += dev-m25p80.o ++obj-$(CONFIG_ATH79_DEV_NFC) += dev-nfc.o + obj-$(CONFIG_ATH79_DEV_SPI) += dev-spi.o + obj-$(CONFIG_ATH79_DEV_USB) += dev-usb.o + obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wmac.o + + # ++# Miscellaneous objects ++# ++obj-$(CONFIG_ATH79_NVRAM) += nvram.o ++obj-$(CONFIG_ATH79_PCI_ATH9K_FIXUP) += pci-ath9k-fixup.o ++obj-$(CONFIG_ATH79_ROUTERBOOT) += routerboot.o ++ ++# + # Machines + # + obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o diff --git a/target/linux/ar71xx/patches-3.3/603-MIPS-ath79-ap121-fixes.patch b/target/linux/ar71xx/patches-3.3/603-MIPS-ath79-ap121-fixes.patch new file mode 100644 index 000000000..1cacde604 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/603-MIPS-ath79-ap121-fixes.patch @@ -0,0 +1,163 @@ +--- a/arch/mips/ath79/mach-ap121.c ++++ b/arch/mips/ath79/mach-ap121.c +@@ -1,19 +1,21 @@ + /* + * Atheros AP121 board support + * +- * Copyright (C) 2011 Gabor Juhos ++ * Copyright (C) 2011-2012 Gabor Juhos + * + * This program 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. + */ + +-#include "machtypes.h" ++#include "dev-eth.h" + #include "dev-gpio-buttons.h" + #include "dev-leds-gpio.h" ++#include "dev-m25p80.h" + #include "dev-spi.h" + #include "dev-usb.h" + #include "dev-wmac.h" ++#include "machtypes.h" + + #define AP121_GPIO_LED_WLAN 0 + #define AP121_GPIO_LED_USB 1 +@@ -24,7 +26,14 @@ + #define AP121_KEYS_POLL_INTERVAL 20 /* msecs */ + #define AP121_KEYS_DEBOUNCE_INTERVAL (3 * AP121_KEYS_POLL_INTERVAL) + +-#define AP121_CAL_DATA_ADDR 0x1fff1000 ++#define AP121_MAC0_OFFSET 0x0000 ++#define AP121_MAC1_OFFSET 0x0006 ++#define AP121_CALDATA_OFFSET 0x1000 ++#define AP121_WMAC_MAC_OFFSET 0x1002 ++ ++#define AP121_MINI_GPIO_LED_WLAN 0 ++#define AP121_MINI_GPIO_BTN_JUMPSTART 12 ++#define AP121_MINI_GPIO_BTN_RESET 11 + + static struct gpio_led ap121_leds_gpio[] __initdata = { + { +@@ -58,41 +67,78 @@ static struct gpio_keys_button ap121_gpi + } + }; + +-static struct ath79_spi_controller_data ap121_spi0_data = { +- .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, +- .cs_line = 0, ++static struct gpio_led ap121_mini_leds_gpio[] __initdata = { ++ { ++ .name = "ap121:green:wlan", ++ .gpio = AP121_MINI_GPIO_LED_WLAN, ++ .active_low = 0, ++ }, + }; + +-static struct spi_board_info ap121_spi_info[] = { ++static struct gpio_keys_button ap121_mini_gpio_keys[] __initdata = { + { +- .bus_num = 0, +- .chip_select = 0, +- .max_speed_hz = 25000000, +- .modalias = "mx25l1606e", +- .controller_data = &ap121_spi0_data, ++ .desc = "jumpstart button", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP121_MINI_GPIO_BTN_JUMPSTART, ++ .active_low = 1, ++ }, ++ { ++ .desc = "reset button", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = AP121_MINI_GPIO_BTN_RESET, ++ .active_low = 1, + } + }; + +-static struct ath79_spi_platform_data ap121_spi_data = { +- .bus_num = 0, +- .num_chipselect = 1, +-}; ++static void __init ap121_common_setup(void) ++{ ++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); ++ ++ ath79_register_m25p80(NULL); ++ ath79_register_wmac(art + AP121_CALDATA_OFFSET, ++ art + AP121_WMAC_MAC_OFFSET); ++ ++ ath79_init_mac(ath79_eth0_data.mac_addr, art + AP121_MAC0_OFFSET, 0); ++ ath79_init_mac(ath79_eth1_data.mac_addr, art + AP121_MAC1_OFFSET, 0); ++ ++ ath79_register_mdio(0, 0x0); ++ ++ /* LAN ports */ ++ ath79_register_eth(1); ++ ++ /* WAN port */ ++ ath79_register_eth(0); ++} + + static void __init ap121_setup(void) + { +- u8 *cal_data = (u8 *) KSEG1ADDR(AP121_CAL_DATA_ADDR); ++ ap121_common_setup(); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(ap121_leds_gpio), + ap121_leds_gpio); + ath79_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL, + ARRAY_SIZE(ap121_gpio_keys), + ap121_gpio_keys); +- +- ath79_register_spi(&ap121_spi_data, ap121_spi_info, +- ARRAY_SIZE(ap121_spi_info)); + ath79_register_usb(); +- ath79_register_wmac(cal_data, NULL); + } + + MIPS_MACHINE(ATH79_MACH_AP121, "AP121", "Atheros AP121 reference board", + ap121_setup); ++ ++static void __init ap121_mini_setup(void) ++{ ++ ap121_common_setup(); ++ ++ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap121_mini_leds_gpio), ++ ap121_mini_leds_gpio); ++ ath79_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ap121_mini_gpio_keys), ++ ap121_mini_gpio_keys); ++} ++ ++MIPS_MACHINE(ATH79_MACH_AP121_MINI, "AP121-MINI", "Atheros AP121-MINI", ++ ap121_mini_setup); +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -5,9 +5,10 @@ menu "Atheros AR71XX/AR724X/AR913X machi + config ATH79_MACH_AP121 + bool "Atheros AP121 reference board" + select SOC_AR933X ++ select ATH79_DEV_ETH + select ATH79_DEV_GPIO_BUTTONS + select ATH79_DEV_LEDS_GPIO +- select ATH79_DEV_SPI ++ select ATH79_DEV_M25P80 + select ATH79_DEV_USB + select ATH79_DEV_WMAC + help +--- a/arch/mips/ath79/machtypes.h ++++ b/arch/mips/ath79/machtypes.h +@@ -17,6 +17,7 @@ + enum ath79_mach_type { + ATH79_MACH_GENERIC = 0, + ATH79_MACH_AP121, /* Atheros AP121 reference board */ ++ ATH79_MACH_AP121_MINI, /* Atheros AP121-MINI reference board */ + ATH79_MACH_AP136, /* Atheros AP136 reference board */ + ATH79_MACH_AP81, /* Atheros AP81 reference board */ + ATH79_MACH_DB120, /* Atheros DB120 reference board */ diff --git a/target/linux/ar71xx/patches-3.3/604-MIPS-ath79-ap81-fixes.patch b/target/linux/ar71xx/patches-3.3/604-MIPS-ath79-ap81-fixes.patch new file mode 100644 index 000000000..3cc012d1a --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/604-MIPS-ath79-ap81-fixes.patch @@ -0,0 +1,128 @@ +--- a/arch/mips/ath79/mach-ap81.c ++++ b/arch/mips/ath79/mach-ap81.c +@@ -9,12 +9,16 @@ + * by the Free Software Foundation. + */ + +-#include "machtypes.h" +-#include "dev-wmac.h" ++#include ++#include ++ ++#include "dev-eth.h" + #include "dev-gpio-buttons.h" + #include "dev-leds-gpio.h" +-#include "dev-spi.h" ++#include "dev-m25p80.h" + #include "dev-usb.h" ++#include "dev-wmac.h" ++#include "machtypes.h" + + #define AP81_GPIO_LED_STATUS 1 + #define AP81_GPIO_LED_AOSS 3 +@@ -29,6 +33,37 @@ + + #define AP81_CAL_DATA_ADDR 0x1fff1000 + ++static struct mtd_partition ap81_partitions[] = { ++ { ++ .name = "u-boot", ++ .offset = 0, ++ .size = 0x040000, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "u-boot-env", ++ .offset = 0x040000, ++ .size = 0x010000, ++ }, { ++ .name = "rootfs", ++ .offset = 0x050000, ++ .size = 0x500000, ++ }, { ++ .name = "uImage", ++ .offset = 0x550000, ++ .size = 0x100000, ++ }, { ++ .name = "ART", ++ .offset = 0x650000, ++ .size = 0x1b0000, ++ .mask_flags = MTD_WRITEABLE, ++ } ++}; ++ ++static struct flash_platform_data ap81_flash_data = { ++ .parts = ap81_partitions, ++ .nr_parts = ARRAY_SIZE(ap81_partitions), ++}; ++ + static struct gpio_led ap81_leds_gpio[] __initdata = { + { + .name = "ap81:green:status", +@@ -67,26 +102,6 @@ static struct gpio_keys_button ap81_gpio + } + }; + +-static struct ath79_spi_controller_data ap81_spi0_data = { +- .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, +- .cs_line = 0, +-}; +- +-static struct spi_board_info ap81_spi_info[] = { +- { +- .bus_num = 0, +- .chip_select = 0, +- .max_speed_hz = 25000000, +- .modalias = "m25p64", +- .controller_data = &ap81_spi0_data, +- } +-}; +- +-static struct ath79_spi_platform_data ap81_spi_data = { +- .bus_num = 0, +- .num_chipselect = 1, +-}; +- + static void __init ap81_setup(void) + { + u8 *cal_data = (u8 *) KSEG1ADDR(AP81_CAL_DATA_ADDR); +@@ -96,10 +111,24 @@ static void __init ap81_setup(void) + ath79_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL, + ARRAY_SIZE(ap81_gpio_keys), + ap81_gpio_keys); +- ath79_register_spi(&ap81_spi_data, ap81_spi_info, +- ARRAY_SIZE(ap81_spi_info)); ++ ath79_register_m25p80(&ap81_flash_data); + ath79_register_wmac(cal_data, NULL); + ath79_register_usb(); ++ ++ ath79_register_mdio(0, 0x0); ++ ++ ath79_init_mac(ath79_eth0_data.mac_addr, cal_data, 0); ++ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ath79_eth0_data.speed = SPEED_100; ++ ath79_eth0_data.duplex = DUPLEX_FULL; ++ ath79_eth0_data.has_ar8216 = 1; ++ ++ ath79_init_mac(ath79_eth1_data.mac_addr, cal_data, 1); ++ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ++ ath79_eth1_data.phy_mask = 0x10; ++ ++ ath79_register_eth(0); ++ ath79_register_eth(1); + } + + MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board", +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -30,9 +30,10 @@ config ATH79_MACH_AP136 + config ATH79_MACH_AP81 + bool "Atheros AP81 reference board" + select SOC_AR913X ++ select ATH79_DEV_ETH + select ATH79_DEV_GPIO_BUTTONS + select ATH79_DEV_LEDS_GPIO +- select ATH79_DEV_SPI ++ select ATH79_DEV_M25P80 + select ATH79_DEV_USB + select ATH79_DEV_WMAC + help diff --git a/target/linux/ar71xx/patches-3.3/605-MIPS-ath79-db120-fixes.patch b/target/linux/ar71xx/patches-3.3/605-MIPS-ath79-db120-fixes.patch new file mode 100644 index 000000000..34e39e375 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/605-MIPS-ath79-db120-fixes.patch @@ -0,0 +1,219 @@ +--- a/arch/mips/ath79/mach-db120.c ++++ b/arch/mips/ath79/mach-db120.c +@@ -2,7 +2,7 @@ + * Atheros DB120 reference board support + * + * Copyright (c) 2011 Qualcomm Atheros +- * Copyright (c) 2011 Gabor Juhos ++ * Copyright (c) 2011-2012 Gabor Juhos + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above +@@ -19,16 +19,26 @@ + */ + + #include ++#include ++#include + #include ++#include + +-#include "machtypes.h" ++#include ++ ++#include "common.h" ++#include "dev-ap9x-pci.h" ++#include "dev-eth.h" + #include "dev-gpio-buttons.h" + #include "dev-leds-gpio.h" ++#include "dev-m25p80.h" ++#include "dev-nfc.h" + #include "dev-spi.h" + #include "dev-usb.h" + #include "dev-wmac.h" +-#include "pci.h" ++#include "machtypes.h" + ++#define DB120_GPIO_LED_USB 11 + #define DB120_GPIO_LED_WLAN_5G 12 + #define DB120_GPIO_LED_WLAN_2G 13 + #define DB120_GPIO_LED_STATUS 14 +@@ -39,8 +49,10 @@ + #define DB120_KEYS_POLL_INTERVAL 20 /* msecs */ + #define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL) + +-#define DB120_WMAC_CALDATA_OFFSET 0x1000 +-#define DB120_PCIE_CALDATA_OFFSET 0x5000 ++#define DB120_MAC0_OFFSET 0 ++#define DB120_MAC1_OFFSET 6 ++#define DB120_WMAC_CALDATA_OFFSET 0x1000 ++#define DB120_PCIE_CALDATA_OFFSET 0x5000 + + static struct gpio_led db120_leds_gpio[] __initdata = { + { +@@ -63,6 +75,11 @@ static struct gpio_led db120_leds_gpio[] + .gpio = DB120_GPIO_LED_WLAN_2G, + .active_low = 1, + }, ++ { ++ .name = "db120:green:usb", ++ .gpio = DB120_GPIO_LED_USB, ++ .active_low = 1, ++ } + }; + + static struct gpio_keys_button db120_gpio_keys[] __initdata = { +@@ -76,66 +93,101 @@ static struct gpio_keys_button db120_gpi + }, + }; + +-static struct ath79_spi_controller_data db120_spi0_data = { +- .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, +- .cs_line = 0, ++static struct ar8327_pad_cfg db120_ar8327_pad0_cfg = { ++ .mode = AR8327_PAD_MAC_RGMII, ++ .txclk_delay_en = true, ++ .rxclk_delay_en = true, ++ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, ++ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, + }; + +-static struct spi_board_info db120_spi_info[] = { +- { +- .bus_num = 0, +- .chip_select = 0, +- .max_speed_hz = 25000000, +- .modalias = "s25sl064a", +- .controller_data = &db120_spi0_data, +- } ++static struct ar8327_led_cfg db120_ar8327_led_cfg = { ++ .led_ctrl0 = 0x00000000, ++ .led_ctrl1 = 0xc737c737, ++ .led_ctrl2 = 0x00000000, ++ .led_ctrl3 = 0x00c30c00, ++ .open_drain = true, + }; + +-static struct ath79_spi_platform_data db120_spi_data = { +- .bus_num = 0, +- .num_chipselect = 1, ++static struct ar8327_platform_data db120_ar8327_data = { ++ .pad0_cfg = &db120_ar8327_pad0_cfg, ++ .cpuport_cfg = { ++ .force_link = 1, ++ .speed = AR8327_PORT_SPEED_1000, ++ .duplex = 1, ++ .txpause = 1, ++ .rxpause = 1, ++ }, ++ .led_cfg = &db120_ar8327_led_cfg, + }; + +-#ifdef CONFIG_PCI +-static struct ath9k_platform_data db120_ath9k_data; ++static struct mdio_board_info db120_mdio0_info[] = { ++ { ++ .bus_id = "ag71xx-mdio.0", ++ .phy_addr = 0, ++ .platform_data = &db120_ar8327_data, ++ }, ++}; + +-static int db120_pci_plat_dev_init(struct pci_dev *dev) ++static void __init db120_gmac_setup(void) + { +- switch (PCI_SLOT(dev->devfn)) { +- case 0: +- dev->dev.platform_data = &db120_ath9k_data; +- break; +- } ++ void __iomem *base; ++ u32 t; + +- return 0; +-} ++ base = ioremap(AR934X_GMAC_BASE, AR934X_GMAC_SIZE); + +-static void __init db120_pci_init(u8 *eeprom) +-{ +- memcpy(db120_ath9k_data.eeprom_data, eeprom, +- sizeof(db120_ath9k_data.eeprom_data)); ++ t = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG); ++ t &= ~(AR934X_ETH_CFG_RGMII_GMAC0 | AR934X_ETH_CFG_MII_GMAC0 | ++ AR934X_ETH_CFG_GMII_GMAC0 | AR934X_ETH_CFG_SW_ONLY_MODE); ++ t |= AR934X_ETH_CFG_RGMII_GMAC0 | AR934X_ETH_CFG_SW_ONLY_MODE; ++ ++ __raw_writel(t, base + AR934X_GMAC_REG_ETH_CFG); + +- ath79_pci_set_plat_dev_init(db120_pci_plat_dev_init); +- ath79_register_pci(); ++ iounmap(base); + } +-#else +-static inline void db120_pci_init(void) {} +-#endif /* CONFIG_PCI */ + + static void __init db120_setup(void) + { + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + ++ ath79_gpio_output_select(DB120_GPIO_LED_USB, AR934X_GPIO_OUT_GPIO); ++ ath79_register_m25p80(NULL); ++ + ath79_register_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio), + db120_leds_gpio); + ath79_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL, + ARRAY_SIZE(db120_gpio_keys), + db120_gpio_keys); +- ath79_register_spi(&db120_spi_data, db120_spi_info, +- ARRAY_SIZE(db120_spi_info)); + ath79_register_usb(); + ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET, NULL); +- db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET); ++ ap91_pci_init(art + DB120_PCIE_CALDATA_OFFSET, NULL); ++ ++ db120_gmac_setup(); ++ ++ ath79_register_mdio(1, 0x0); ++ ath79_register_mdio(0, 0x0); ++ ++ ath79_init_mac(ath79_eth0_data.mac_addr, art + DB120_MAC0_OFFSET, 0); ++ ++ mdiobus_register_board_info(db120_mdio0_info, ++ ARRAY_SIZE(db120_mdio0_info)); ++ ++ /* GMAC0 is connected to an AR8327 switch */ ++ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ath79_eth0_data.phy_mask = BIT(0); ++ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; ++ ath79_eth0_pll_data.pll_1000 = 0x06000000; ++ ath79_register_eth(0); ++ ++ /* GMAC1 is connected to the internal switch */ ++ ath79_init_mac(ath79_eth1_data.mac_addr, art + DB120_MAC1_OFFSET, 0); ++ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; ++ ath79_eth1_data.speed = SPEED_1000; ++ ath79_eth1_data.duplex = DUPLEX_FULL; ++ ++ ath79_register_eth(1); ++ ++ ath79_register_nfc(); + } + + MIPS_MACHINE(ATH79_MACH_DB120, "DB120", "Atheros DB120 reference board", +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -43,9 +43,12 @@ config ATH79_MACH_AP81 + config ATH79_MACH_DB120 + bool "Atheros DB120 reference board" + select SOC_AR934X ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH + select ATH79_DEV_GPIO_BUTTONS + select ATH79_DEV_LEDS_GPIO +- select ATH79_DEV_SPI ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_NFC + select ATH79_DEV_USB + select ATH79_DEV_WMAC + help diff --git a/target/linux/ar71xx/patches-3.3/606-MIPS-ath79-pb44-fixes.patch b/target/linux/ar71xx/patches-3.3/606-MIPS-ath79-pb44-fixes.patch new file mode 100644 index 000000000..f9ec7753f --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/606-MIPS-ath79-pb44-fixes.patch @@ -0,0 +1,153 @@ +--- a/arch/mips/ath79/mach-pb44.c ++++ b/arch/mips/ath79/mach-pb44.c +@@ -8,23 +8,48 @@ + * by the Free Software Foundation. + */ + ++#include + #include + #include + #include + #include + #include ++#include ++#include ++#include + +-#include "machtypes.h" ++#include ++#include ++ ++#include "dev-eth.h" + #include "dev-gpio-buttons.h" + #include "dev-leds-gpio.h" + #include "dev-spi.h" + #include "dev-usb.h" ++#include "machtypes.h" + #include "pci.h" + + #define PB44_GPIO_I2C_SCL 0 + #define PB44_GPIO_I2C_SDA 1 + ++#define PB44_PCF8757_VSC7395_CS 0 ++#define PB44_PCF8757_STEREO_CS 1 ++#define PB44_PCF8757_SLIC_CS0 2 ++#define PB44_PCF8757_SLIC_TEST 3 ++#define PB44_PCF8757_SLIC_INT0 4 ++#define PB44_PCF8757_SLIC_INT1 5 ++#define PB44_PCF8757_SW_RESET 6 ++#define PB44_PCF8757_SW_JUMP 8 ++#define PB44_PCF8757_LED_JUMP1 9 ++#define PB44_PCF8757_LED_JUMP2 10 ++#define PB44_PCF8757_TP24 11 ++#define PB44_PCF8757_TP25 12 ++#define PB44_PCF8757_TP26 13 ++#define PB44_PCF8757_TP27 14 ++#define PB44_PCF8757_TP28 15 ++ + #define PB44_GPIO_EXP_BASE 16 ++#define PB44_GPIO_VSC7395_CS (PB44_GPIO_EXP_BASE + PB44_PCF8757_VSC7395_CS) + #define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + 6) + #define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + 8) + #define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + 9) +@@ -92,21 +117,66 @@ static struct ath79_spi_controller_data + .cs_line = 0, + }; + ++static struct ath79_spi_controller_data pb44_spi1_data = { ++ .cs_type = ATH79_SPI_CS_TYPE_GPIO, ++ .cs_line = PB44_GPIO_VSC7395_CS, ++}; ++ ++static void pb44_vsc7395_reset(void) ++{ ++ ath79_device_reset_set(AR71XX_RESET_GE1_PHY); ++ udelay(10); ++ ath79_device_reset_clear(AR71XX_RESET_GE1_PHY); ++ mdelay(50); ++} ++ ++static struct vsc7385_platform_data pb44_vsc7395_data = { ++ .reset = pb44_vsc7395_reset, ++ .ucode_name = "vsc7395_ucode_pb44.bin", ++ .mac_cfg = { ++ .tx_ipg = 6, ++ .bit2 = 1, ++ .clk_sel = 0, ++ }, ++}; ++ ++static const char *pb44_part_probes[] = { ++ "RedBoot", ++ NULL, ++}; ++ ++static struct flash_platform_data pb44_flash_data = { ++ .part_probes = pb44_part_probes, ++}; ++ + static struct spi_board_info pb44_spi_info[] = { + { + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 25000000, + .modalias = "m25p64", ++ .platform_data = &pb44_flash_data, + .controller_data = &pb44_spi0_data, + }, ++ { ++ .bus_num = 0, ++ .chip_select = 1, ++ .max_speed_hz = 25000000, ++ .modalias = "spi-vsc7385", ++ .platform_data = &pb44_vsc7395_data, ++ .controller_data = &pb44_spi1_data, ++ } + }; + + static struct ath79_spi_platform_data pb44_spi_data = { + .bus_num = 0, +- .num_chipselect = 1, ++ .num_chipselect = 2, + }; + ++#define PB44_WAN_PHYMASK BIT(0) ++#define PB44_LAN_PHYMASK 0 ++#define PB44_MDIO_PHYMASK (PB44_LAN_PHYMASK | PB44_WAN_PHYMASK) ++ + static void __init pb44_init(void) + { + i2c_register_board_info(0, pb44_i2c_board_info, +@@ -122,6 +192,22 @@ static void __init pb44_init(void) + ARRAY_SIZE(pb44_spi_info)); + ath79_register_usb(); + ath79_register_pci(); ++ ++ ath79_register_mdio(0, ~PB44_MDIO_PHYMASK); ++ ++ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0); ++ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ath79_eth0_data.phy_mask = PB44_WAN_PHYMASK; ++ ++ ath79_register_eth(0); ++ ++ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1); ++ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ath79_eth1_data.speed = SPEED_1000; ++ ath79_eth1_data.duplex = DUPLEX_FULL; ++ ath79_eth1_pll_data.pll_1000 = 0x110000; ++ ++ ath79_register_eth(1); + } + + MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board", +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -58,6 +58,7 @@ config ATH79_MACH_DB120 + config ATH79_MACH_PB44 + bool "Atheros PB44 reference board" + select SOC_AR71XX ++ select ATH79_DEV_ETH + select ATH79_DEV_GPIO_BUTTONS + select ATH79_DEV_LEDS_GPIO + select ATH79_DEV_SPI diff --git a/target/linux/ar71xx/patches-3.3/607-MIPS-ath79-ubnt-xm-fixes.patch b/target/linux/ar71xx/patches-3.3/607-MIPS-ath79-ubnt-xm-fixes.patch new file mode 100644 index 000000000..cbbe20b49 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/607-MIPS-ath79-ubnt-xm-fixes.patch @@ -0,0 +1,109 @@ +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -70,9 +70,10 @@ config ATH79_MACH_PB44 + config ATH79_MACH_UBNT_XM + bool "Ubiquiti Networks XM (rev 1.0) board" + select SOC_AR724X ++ select ATH79_DEV_AP9X_PCI if PCI + select ATH79_DEV_GPIO_BUTTONS + select ATH79_DEV_LEDS_GPIO +- select ATH79_DEV_SPI ++ select ATH79_DEV_M25P80 + help + Say 'Y' here if you want your kernel to support the + Ubiquiti Networks XM (rev 1.0) board. +--- a/arch/mips/ath79/mach-ubnt-xm.c ++++ b/arch/mips/ath79/mach-ubnt-xm.c +@@ -16,10 +16,11 @@ + + #include + +-#include "machtypes.h" ++#include "dev-ap9x-pci.h" + #include "dev-gpio-buttons.h" + #include "dev-leds-gpio.h" +-#include "dev-spi.h" ++#include "dev-m25p80.h" ++#include "machtypes.h" + #include "pci.h" + + #define UBNT_XM_GPIO_LED_L1 0 +@@ -32,7 +33,7 @@ + #define UBNT_XM_KEYS_POLL_INTERVAL 20 + #define UBNT_XM_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_XM_KEYS_POLL_INTERVAL) + +-#define UBNT_XM_EEPROM_ADDR (u8 *) KSEG1ADDR(0x1fff1000) ++#define UBNT_XM_EEPROM_ADDR 0x1fff1000 + + static struct gpio_led ubnt_xm_leds_gpio[] __initdata = { + { +@@ -65,54 +66,10 @@ static struct gpio_keys_button ubnt_xm_g + } + }; + +-static struct ath79_spi_controller_data ubnt_xm_spi0_data = { +- .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, +- .cs_line = 0, +-}; +- +-static struct spi_board_info ubnt_xm_spi_info[] = { +- { +- .bus_num = 0, +- .chip_select = 0, +- .max_speed_hz = 25000000, +- .modalias = "mx25l6405d", +- .controller_data = &ubnt_xm_spi0_data, +- } +-}; +- +-static struct ath79_spi_platform_data ubnt_xm_spi_data = { +- .bus_num = 0, +- .num_chipselect = 1, +-}; +- +-#ifdef CONFIG_PCI +-static struct ath9k_platform_data ubnt_xm_eeprom_data; +- +-static int ubnt_xm_pci_plat_dev_init(struct pci_dev *dev) +-{ +- switch (PCI_SLOT(dev->devfn)) { +- case 0: +- dev->dev.platform_data = &ubnt_xm_eeprom_data; +- break; +- } +- +- return 0; +-} +- +-static void __init ubnt_xm_pci_init(void) +-{ +- memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR, +- sizeof(ubnt_xm_eeprom_data.eeprom_data)); +- +- ath79_pci_set_plat_dev_init(ubnt_xm_pci_plat_dev_init); +- ath79_register_pci(); +-} +-#else +-static inline void ubnt_xm_pci_init(void) {} +-#endif /* CONFIG_PCI */ +- + static void __init ubnt_xm_init(void) + { ++ u8 *eeprom = (u8 *) KSEG1ADDR(UBNT_XM_EEPROM_ADDR); ++ + ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_xm_leds_gpio), + ubnt_xm_leds_gpio); + +@@ -120,10 +77,8 @@ static void __init ubnt_xm_init(void) + ARRAY_SIZE(ubnt_xm_gpio_keys), + ubnt_xm_gpio_keys); + +- ath79_register_spi(&ubnt_xm_spi_data, ubnt_xm_spi_info, +- ARRAY_SIZE(ubnt_xm_spi_info)); +- +- ubnt_xm_pci_init(); ++ ath79_register_m25p80(NULL); ++ ap91_pci_init(eeprom, NULL); + } + + MIPS_MACHINE(ATH79_MACH_UBNT_XM, diff --git a/target/linux/ar71xx/patches-3.3/608-MIPS-ath79-ubnt-xm-add-more-boards.patch b/target/linux/ar71xx/patches-3.3/608-MIPS-ath79-ubnt-xm-add-more-boards.patch new file mode 100644 index 000000000..bee07b35c --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/608-MIPS-ath79-ubnt-xm-add-more-boards.patch @@ -0,0 +1,200 @@ +--- a/arch/mips/ath79/mach-ubnt-xm.c ++++ b/arch/mips/ath79/mach-ubnt-xm.c +@@ -13,15 +13,17 @@ + #include + #include + #include ++#include + + #include + + #include "dev-ap9x-pci.h" ++#include "dev-eth.h" + #include "dev-gpio-buttons.h" + #include "dev-leds-gpio.h" + #include "dev-m25p80.h" ++#include "dev-usb.h" + #include "machtypes.h" +-#include "pci.h" + + #define UBNT_XM_GPIO_LED_L1 0 + #define UBNT_XM_GPIO_LED_L2 1 +@@ -37,19 +39,19 @@ + + static struct gpio_led ubnt_xm_leds_gpio[] __initdata = { + { +- .name = "ubnt-xm:red:link1", ++ .name = "ubnt:red:link1", + .gpio = UBNT_XM_GPIO_LED_L1, + .active_low = 0, + }, { +- .name = "ubnt-xm:orange:link2", ++ .name = "ubnt:orange:link2", + .gpio = UBNT_XM_GPIO_LED_L2, + .active_low = 0, + }, { +- .name = "ubnt-xm:green:link3", ++ .name = "ubnt:green:link3", + .gpio = UBNT_XM_GPIO_LED_L3, + .active_low = 0, + }, { +- .name = "ubnt-xm:green:link4", ++ .name = "ubnt:green:link4", + .gpio = UBNT_XM_GPIO_LED_L4, + .active_low = 0, + }, +@@ -66,9 +68,13 @@ static struct gpio_keys_button ubnt_xm_g + } + }; + ++#define UBNT_M_WAN_PHYMASK BIT(4) ++ + static void __init ubnt_xm_init(void) + { + u8 *eeprom = (u8 *) KSEG1ADDR(UBNT_XM_EEPROM_ADDR); ++ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000); ++ u8 *mac2 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_xm_leds_gpio), + ubnt_xm_leds_gpio); +@@ -79,9 +85,112 @@ static void __init ubnt_xm_init(void) + + ath79_register_m25p80(NULL); + ap91_pci_init(eeprom, NULL); ++ ++ ath79_register_mdio(0, ~UBNT_M_WAN_PHYMASK); ++ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); ++ ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0); ++ ath79_register_eth(0); + } + + MIPS_MACHINE(ATH79_MACH_UBNT_XM, + "UBNT-XM", + "Ubiquiti Networks XM (rev 1.0) board", + ubnt_xm_init); ++ ++MIPS_MACHINE(ATH79_MACH_UBNT_BULLET_M, "UBNT-BM", "Ubiquiti Bullet M", ++ ubnt_xm_init); ++ ++static void __init ubnt_rocket_m_setup(void) ++{ ++ ubnt_xm_init(); ++ ath79_register_usb(); ++} ++ ++MIPS_MACHINE(ATH79_MACH_UBNT_ROCKET_M, "UBNT-RM", "Ubiquiti Rocket M", ++ ubnt_rocket_m_setup); ++ ++static void __init ubnt_nano_m_setup(void) ++{ ++ ubnt_xm_init(); ++ ath79_register_eth(1); ++} ++ ++MIPS_MACHINE(ATH79_MACH_UBNT_NANO_M, "UBNT-NM", "Ubiquiti Nanostation M", ++ ubnt_nano_m_setup); ++ ++static struct gpio_led ubnt_airrouter_leds_gpio[] __initdata = { ++ { ++ .name = "ubnt:green:globe", ++ .gpio = 0, ++ .active_low = 1, ++ }, { ++ .name = "ubnt:green:power", ++ .gpio = 11, ++ .active_low = 1, ++ .default_state = LEDS_GPIO_DEFSTATE_ON, ++ } ++}; ++ ++static void __init ubnt_airrouter_setup(void) ++{ ++ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); ++ ++ ath79_register_m25p80(NULL); ++ ath79_register_mdio(0, ~UBNT_M_WAN_PHYMASK); ++ ++ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); ++ ath79_init_local_mac(ath79_eth1_data.mac_addr, mac1); ++ ++ ath79_register_eth(1); ++ ath79_register_eth(0); ++ ath79_register_usb(); ++ ++ ap91_pci_init(ee, NULL); ++ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_airrouter_leds_gpio), ++ ubnt_airrouter_leds_gpio); ++ ++ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ubnt_xm_gpio_keys), ++ ubnt_xm_gpio_keys); ++} ++ ++MIPS_MACHINE(ATH79_MACH_UBNT_AIRROUTER, "UBNT-AR", "Ubiquiti AirRouter", ++ ubnt_airrouter_setup); ++ ++static struct gpio_led ubnt_unifi_leds_gpio[] __initdata = { ++ { ++ .name = "ubnt:orange:dome", ++ .gpio = 1, ++ .active_low = 0, ++ }, { ++ .name = "ubnt:green:dome", ++ .gpio = 0, ++ .active_low = 0, ++ } ++}; ++ ++static void __init ubnt_unifi_setup(void) ++{ ++ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); ++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); ++ ++ ath79_register_m25p80(NULL); ++ ++ ath79_register_mdio(0, ~UBNT_M_WAN_PHYMASK); ++ ++ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); ++ ath79_register_eth(0); ++ ++ ap91_pci_init(ee, NULL); ++ ++ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_unifi_leds_gpio), ++ ubnt_unifi_leds_gpio); ++ ++ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, ++ ARRAY_SIZE(ubnt_xm_gpio_keys), ++ ubnt_xm_gpio_keys); ++} ++ ++MIPS_MACHINE(ATH79_MACH_UBNT_UNIFI, "UBNT-UF", "Ubiquiti UniFi", ++ ubnt_unifi_setup); +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -71,9 +71,11 @@ config ATH79_MACH_UBNT_XM + bool "Ubiquiti Networks XM (rev 1.0) board" + select SOC_AR724X + select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH + select ATH79_DEV_GPIO_BUTTONS + select ATH79_DEV_LEDS_GPIO + select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB + help + Say 'Y' here if you want your kernel to support the + Ubiquiti Networks XM (rev 1.0) board. +--- a/arch/mips/ath79/machtypes.h ++++ b/arch/mips/ath79/machtypes.h +@@ -22,6 +22,11 @@ enum ath79_mach_type { + ATH79_MACH_AP81, /* Atheros AP81 reference board */ + ATH79_MACH_DB120, /* Atheros DB120 reference board */ + ATH79_MACH_PB44, /* Atheros PB44 reference board */ ++ ATH79_MACH_UBNT_AIRROUTER, /* Ubiquiti AirRouter */ ++ ATH79_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ ++ ATH79_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */ ++ ATH79_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */ ++ ATH79_MACH_UBNT_UNIFI, /* Ubiquiti Unifi */ + ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */ + }; + diff --git a/target/linux/ar71xx/patches-3.3/609-MIPS-ath79-ap136-fixes.patch b/target/linux/ar71xx/patches-3.3/609-MIPS-ath79-ap136-fixes.patch new file mode 100644 index 000000000..bd07c7bc8 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/609-MIPS-ath79-ap136-fixes.patch @@ -0,0 +1,175 @@ +--- a/arch/mips/ath79/mach-ap136.c ++++ b/arch/mips/ath79/mach-ap136.c +@@ -1,5 +1,5 @@ + /* +- * Qualcomm Atheros AP136 reference board support ++ * Atheros AP136 reference board support + * + * Copyright (c) 2012 Qualcomm Atheros + * Copyright (c) 2012 Gabor Juhos +@@ -18,23 +18,27 @@ + * + */ + +-#include +-#include ++#include ++#include + +-#include "machtypes.h" ++#include ++ ++#include "common.h" ++#include "dev-ap9x-pci.h" + #include "dev-gpio-buttons.h" ++#include "dev-eth.h" + #include "dev-leds-gpio.h" +-#include "dev-spi.h" ++#include "dev-m25p80.h" + #include "dev-usb.h" + #include "dev-wmac.h" +-#include "pci.h" ++#include "machtypes.h" + +-#define AP136_GPIO_LED_STATUS_RED 14 +-#define AP136_GPIO_LED_STATUS_GREEN 19 + #define AP136_GPIO_LED_USB 4 +-#define AP136_GPIO_LED_WLAN_2G 13 + #define AP136_GPIO_LED_WLAN_5G 12 ++#define AP136_GPIO_LED_WLAN_2G 13 ++#define AP136_GPIO_LED_STATUS_RED 14 + #define AP136_GPIO_LED_WPS_RED 15 ++#define AP136_GPIO_LED_STATUS_GREEN 19 + #define AP136_GPIO_LED_WPS_GREEN 20 + + #define AP136_GPIO_BTN_WPS 16 +@@ -43,8 +47,10 @@ + #define AP136_KEYS_POLL_INTERVAL 20 /* msecs */ + #define AP136_KEYS_DEBOUNCE_INTERVAL (3 * AP136_KEYS_POLL_INTERVAL) + +-#define AP136_WMAC_CALDATA_OFFSET 0x1000 +-#define AP136_PCIE_CALDATA_OFFSET 0x5000 ++#define AP136_MAC0_OFFSET 0 ++#define AP136_MAC1_OFFSET 6 ++#define AP136_WMAC_CALDATA_OFFSET 0x1000 ++#define AP136_PCIE_CALDATA_OFFSET 0x5000 + + static struct gpio_led ap136_leds_gpio[] __initdata = { + { +@@ -98,63 +104,82 @@ static struct gpio_keys_button ap136_gpi + }, + }; + +-static struct ath79_spi_controller_data ap136_spi0_data = { +- .cs_type = ATH79_SPI_CS_TYPE_INTERNAL, +- .cs_line = 0, ++static struct ar8327_pad_cfg ap136_ar8327_pad0_cfg = { ++ .mode = AR8327_PAD_MAC_RGMII, ++ .txclk_delay_en = true, ++ .rxclk_delay_en = true, ++ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1, ++ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2, + }; + +-static struct spi_board_info ap136_spi_info[] = { +- { +- .bus_num = 0, +- .chip_select = 0, +- .max_speed_hz = 25000000, +- .modalias = "mx25l6405d", +- .controller_data = &ap136_spi0_data, ++static struct ar8327_platform_data ap136_ar8327_data = { ++ .pad0_cfg = &ap136_ar8327_pad0_cfg, ++ .cpuport_cfg = { ++ .force_link = 1, ++ .speed = AR8327_PORT_SPEED_1000, ++ .duplex = 1, ++ .txpause = 1, ++ .rxpause = 1, + } + }; + +-static struct ath79_spi_platform_data ap136_spi_data = { +- .bus_num = 0, +- .num_chipselect = 1, ++static struct mdio_board_info ap136_mdio0_info[] = { ++ { ++ .bus_id = "ag71xx-mdio.0", ++ .phy_addr = 0, ++ .platform_data = &ap136_ar8327_data, ++ }, + }; + +-#ifdef CONFIG_PCI +-static struct ath9k_platform_data ap136_ath9k_data; +- +-static int ap136_pci_plat_dev_init(struct pci_dev *dev) ++static void __init ap136_gmac_setup(void) + { +- if (dev->bus->number == 1 && (PCI_SLOT(dev->devfn)) == 0) +- dev->dev.platform_data = &ap136_ath9k_data; ++ void __iomem *base; ++ u32 t; + +- return 0; +-} ++ base = ioremap(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE); + +-static void __init ap136_pci_init(u8 *eeprom) +-{ +- memcpy(ap136_ath9k_data.eeprom_data, eeprom, +- sizeof(ap136_ath9k_data.eeprom_data)); ++ t = __raw_readl(base + QCA955X_GMAC_REG_ETH_CFG); ++ ++ t &= ~(QCA955X_ETH_CFG_RGMII_GMAC0 | QCA955X_ETH_CFG_SGMII_GMAC0); ++ t |= QCA955X_ETH_CFG_RGMII_GMAC0; + +- ath79_pci_set_plat_dev_init(ap136_pci_plat_dev_init); +- ath79_register_pci(); ++ __raw_writel(t, base + QCA955X_GMAC_REG_ETH_CFG); ++ ++ iounmap(base); + } +-#else +-static inline void ap136_pci_init(void) {} +-#endif /* CONFIG_PCI */ + + static void __init ap136_setup(void) + { + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + ++ ath79_register_m25p80(NULL); ++ + ath79_register_leds_gpio(-1, ARRAY_SIZE(ap136_leds_gpio), + ap136_leds_gpio); + ath79_register_gpio_keys_polled(-1, AP136_KEYS_POLL_INTERVAL, + ARRAY_SIZE(ap136_gpio_keys), + ap136_gpio_keys); +- ath79_register_spi(&ap136_spi_data, ap136_spi_info, +- ARRAY_SIZE(ap136_spi_info)); ++ + ath79_register_usb(); +- ath79_register_wmac(art + AP136_WMAC_CALDATA_OFFSET); +- ap136_pci_init(art + AP136_PCIE_CALDATA_OFFSET); ++ ath79_register_wmac(art + AP136_WMAC_CALDATA_OFFSET, NULL); ++ ap91_pci_init(art + AP136_PCIE_CALDATA_OFFSET, NULL); ++ ++ ap136_gmac_setup(); ++ ++ ath79_register_mdio(0, 0x0); ++ ++ ath79_init_mac(ath79_eth0_data.mac_addr, art + AP136_MAC0_OFFSET, 0); ++ ++ mdiobus_register_board_info(ap136_mdio0_info, ++ ARRAY_SIZE(ap136_mdio0_info)); ++ ++ /* GMAC0 is connected to an AR8327 switch */ ++ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; ++ ath79_eth0_data.phy_mask = BIT(0); ++ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; ++ ath79_eth0_pll_data.pll_1000 = 0x06000000; ++ ++ ath79_register_eth(0); + } + + MIPS_MACHINE(ATH79_MACH_AP136, "AP136", "Atheros AP136 reference board", diff --git a/target/linux/ar71xx/patches-3.3/610-MIPS-ath79-openwrt-machines.patch b/target/linux/ar71xx/patches-3.3/610-MIPS-ath79-openwrt-machines.patch new file mode 100644 index 000000000..6f6da2d30 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/610-MIPS-ath79-openwrt-machines.patch @@ -0,0 +1,793 @@ +--- a/arch/mips/ath79/machtypes.h ++++ b/arch/mips/ath79/machtypes.h +@@ -16,18 +16,98 @@ + + enum ath79_mach_type { + ATH79_MACH_GENERIC = 0, ++ ATH79_MACH_ALFA_AP96, /* ALFA Network AP96 board */ ++ ATH79_MACH_ALFA_NX, /* ALFA Network N2/N5 board */ ++ ATH79_MACH_ALL0258N, /* Allnet ALL0258N */ ++ ATH79_MACH_ALL0305, /* Allnet ALL0305 */ ++ ATH79_MACH_ALL0315N, /* Allnet ALL0315N */ ++ ATH79_MACH_AP113, /* Atheros AP113 reference board */ + ATH79_MACH_AP121, /* Atheros AP121 reference board */ + ATH79_MACH_AP121_MINI, /* Atheros AP121-MINI reference board */ + ATH79_MACH_AP136, /* Atheros AP136 reference board */ + ATH79_MACH_AP81, /* Atheros AP81 reference board */ ++ ATH79_MACH_AP83, /* Atheros AP83 */ ++ ATH79_MACH_AP96, /* Atheros AP96 */ ++ ATH79_MACH_AW_NR580, /* AzureWave AW-NR580 */ + ATH79_MACH_DB120, /* Atheros DB120 reference board */ + ATH79_MACH_PB44, /* Atheros PB44 reference board */ ++ ATH79_MACH_DIR_600_A1, /* D-Link DIR-600 rev. A1 */ ++ ATH79_MACH_DIR_615_C1, /* D-Link DIR-615 rev. C1 */ ++ ATH79_MACH_DIR_615_E4, /* D-Link DIR-615 rev. E4 */ ++ ATH79_MACH_DIR_825_B1, /* D-Link DIR-825 rev. B1 */ ++ ATH79_MACH_EW_DORIN, /* embedded wireless Dorin Platform */ ++ ATH79_MACH_EW_DORIN_ROUTER, /* embedded wireless Dorin Router Platform */ ++ ATH79_MACH_EAP7660D, /* Senao EAP7660D */ ++ ATH79_MACH_JA76PF, /* jjPlus JA76PF */ ++ ATH79_MACH_JA76PF2, /* jjPlus JA76PF2 */ ++ ATH79_MACH_JWAP003, /* jjPlus JWAP003 */ ++ ATH79_MACH_HORNET_UB, /* ALFA Networks Hornet-UB */ ++ ATH79_MACH_MZK_W04NU, /* Planex MZK-W04NU */ ++ ATH79_MACH_MZK_W300NH, /* Planex MZK-W300NH */ ++ ATH79_MACH_NBG460N, /* Zyxel NBG460N/550N/550NH */ ++ ATH79_MACH_OM2P_LC, /* OpenMesh OM2P-LC */ ++ ATH79_MACH_OM2P, /* OpenMesh OM2P */ ++ ATH79_MACH_PB42, /* Atheros PB42 */ ++ ATH79_MACH_PB92, /* Atheros PB92 */ ++ ATH79_MACH_RB_411, /* MikroTik RouterBOARD 411/411A/411AH */ ++ ATH79_MACH_RB_411U, /* MikroTik RouterBOARD 411U */ ++ ATH79_MACH_RB_433, /* MikroTik RouterBOARD 433/433AH */ ++ ATH79_MACH_RB_433U, /* MikroTik RouterBOARD 433UAH */ ++ ATH79_MACH_RB_450G, /* MikroTik RouterBOARD 450G */ ++ ATH79_MACH_RB_450, /* MikroTik RouterBOARD 450 */ ++ ATH79_MACH_RB_493, /* Mikrotik RouterBOARD 493/493AH */ ++ ATH79_MACH_RB_493G, /* Mikrotik RouterBOARD 493G */ ++ ATH79_MACH_RB_750, /* MikroTik RouterBOARD 750 */ ++ ATH79_MACH_RB_750G_R3, /* MikroTik RouterBOARD 750GL */ ++ ATH79_MACH_RB_751, /* MikroTik RouterBOARD 751 */ ++ ATH79_MACH_RB_751G, /* Mikrotik RouterBOARD 751G */ ++ ATH79_MACH_RB_2011G, /* Mikrotik RouterBOARD 2011UAS-2HnD */ ++ ATH79_MACH_RB_2011L, /* Mikrotik RouterBOARD 2011L */ ++ ATH79_MACH_RW2458N, /* Redwave RW2458N */ ++ ATH79_MACH_TEW_632BRP, /* TRENDnet TEW-632BRP */ ++ ATH79_MACH_TEW_673GRU, /* TRENDnet TEW-673GRU */ ++ ATH79_MACH_TEW_712BR, /* TRENDnet TEW-712BR */ ++ ATH79_MACH_TL_MR11U, /* TP-LINK TL-MR11U */ ++ ATH79_MACH_TL_MR3020, /* TP-LINK TL-MR3020 */ ++ ATH79_MACH_TL_MR3220, /* TP-LINK TL-MR3220 */ ++ ATH79_MACH_TL_MR3420, /* TP-LINK TL-MR3420 */ ++ ATH79_MACH_TL_WA901ND, /* TP-LINK TL-WA901ND */ ++ ATH79_MACH_TL_WA901ND_V2, /* TP-LINK TL-WA901ND v2 */ ++ ATH79_MACH_TL_WDR4300, /* TP-LINK TL-WDR4300 */ ++ ATH79_MACH_TL_WR1041N_V2, /* TP-LINK TL-WR1041N v2 */ ++ ATH79_MACH_TL_WR1043ND, /* TP-LINK TL-WR1043ND */ ++ ATH79_MACH_TL_WR2543N, /* TP-LINK TL-WR2543N/ND */ ++ ATH79_MACH_TL_WR703N, /* TP-LINK TL-WR703N */ ++ ATH79_MACH_TL_WR741ND, /* TP-LINK TL-WR741ND */ ++ ATH79_MACH_TL_WR741ND_V4, /* TP-LINK TL-WR741ND v4*/ ++ ATH79_MACH_TL_WR841N_V1, /* TP-LINK TL-WR841N v1 */ ++ ATH79_MACH_TL_WR841N_V7, /* TP-LINK TL-WR841N/ND v7 */ ++ ATH79_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */ + ATH79_MACH_UBNT_AIRROUTER, /* Ubiquiti AirRouter */ + ATH79_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ ++ ATH79_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */ ++ ATH79_MACH_UBNT_LSX, /* Ubiquiti LSX */ + ATH79_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */ + ATH79_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */ ++ ATH79_MACH_UBNT_RSPRO, /* Ubiquiti RouterStation Pro */ ++ ATH79_MACH_UBNT_RS, /* Ubiquiti RouterStation */ + ATH79_MACH_UBNT_UNIFI, /* Ubiquiti Unifi */ + ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */ ++ ATH79_MACH_WHR_G301N, /* Buffalo WHR-G301N */ ++ ATH79_MACH_WHR_HP_G300N, /* Buffalo WHR-HP-G300N */ ++ ATH79_MACH_WHR_HP_GN, /* Buffalo WHR-HP-GN */ ++ ATH79_MACH_WLAE_AG300N, /* Buffalo WLAE-AG300N */ ++ ATH79_MACH_WNDR3700, /* NETGEAR WNDR3700/WNDR3800/WNDRMAC */ ++ ATH79_MACH_WNR2000, /* NETGEAR WNR2000 */ ++ ATH79_MACH_WP543, /* Compex WP543 */ ++ ATH79_MACH_WPE72, /* Compex WPE72 */ ++ ATH79_MACH_WRT160NL, /* Linksys WRT160NL */ ++ ATH79_MACH_WRT400N, /* Linksys WRT400N */ ++ ATH79_MACH_WZR_HP_AG300H, /* Buffalo WZR-HP-AG300H */ ++ ATH79_MACH_WZR_HP_G300NH, /* Buffalo WZR-HP-G300NH */ ++ ATH79_MACH_WZR_HP_G300NH2, /* Buffalo WZR-HP-G300NH2 */ ++ ATH79_MACH_WZR_HP_G450H, /* Buffalo WZR-HP-G450H */ ++ ATH79_MACH_ZCN_1523H_2, /* Zcomax ZCN-1523H-2-xx */ + }; + + #endif /* _ATH79_MACHTYPE_H */ +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -2,6 +2,61 @@ if ATH79 + + menu "Atheros AR71XX/AR724X/AR913X machine selection" + ++config ATH79_MACH_ALFA_AP96 ++ bool "ALFA Network AP96 board support" ++ select SOC_AR71XX ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_SPI ++ select ATH79_DEV_USB ++ ++config ATH79_MACH_HORNET_UB ++ bool "ALFA Network Hornet-UB board support" ++ select SOC_AR933X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_ALFA_NX ++ bool "ALFA Network N2/N5 board support" ++ select SOC_AR724X ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ ++config ATH79_MACH_ALL0258N ++ bool "Allnet ALL0258N support" ++ select SOC_AR724X ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ ++config ATH79_MACH_ALL0315N ++ bool "Allnet ALL0315N support" ++ select SOC_AR724X ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ ++config ATH79_MACH_AP113 ++ bool "Atheros AP113 board support" ++ select SOC_AR724X ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_PB9X_PCI if PCI ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_USB ++ select ATH79_DEV_ETH ++ + config ATH79_MACH_AP121 + bool "Atheros AP121 reference board" + select SOC_AR933X +@@ -40,6 +95,24 @@ config ATH79_MACH_AP81 + Say 'Y' here if you want your kernel to support the + Atheros AP81 reference board. + ++config ATH79_MACH_AP83 ++ bool "Atheros AP83 board support" ++ select SOC_AR913X ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_USB ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_AP96 ++ bool "Atheros AP96 board support" ++ select SOC_AR71XX ++ select ATH79_DEV_ETH ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ + config ATH79_MACH_DB120 + bool "Atheros DB120 reference board" + select SOC_AR934X +@@ -55,6 +128,13 @@ config ATH79_MACH_DB120 + Say 'Y' here if you want your kernel to support the + Atheros DB120 reference board. + ++config ATH79_MACH_PB42 ++ bool "Atheros PB42 board support" ++ select SOC_AR71XX ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_M25P80 ++ + config ATH79_MACH_PB44 + bool "Atheros PB44 reference board" + select SOC_AR71XX +@@ -67,6 +147,447 @@ config ATH79_MACH_PB44 + Say 'Y' here if you want your kernel to support the + Atheros PB44 reference board. + ++config ATH79_MACH_PB92 ++ bool "Atheros PB92 board support" ++ select SOC_AR724X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_PB9X_PCI if PCI ++ select ATH79_DEV_USB ++ ++config ATH79_MACH_AW_NR580 ++ bool "AzureWave AW-NR580 board support" ++ select SOC_AR71XX ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ ++config ATH79_MACH_WHR_HP_G300N ++ bool "Buffalo WHR-HP-G300N board support" ++ select SOC_AR724X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ ++config ATH79_MACH_WLAE_AG300N ++ bool "Buffalo WLAE-AG300N board support" ++ select SOC_AR71XX ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ ++config ATH79_MACH_WZR_HP_AG300H ++ bool "Buffalo WZR-HP-AG300H board support" ++ select SOC_AR71XX ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ ++config ATH79_MACH_WZR_HP_G300NH ++ bool "Buffalo WZR-HP-G300NH board support" ++ select SOC_AR913X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_USB ++ select ATH79_DEV_WMAC ++ select RTL8366_SMI ++ ++config ATH79_MACH_WZR_HP_G300NH2 ++ bool "Buffalo WZR-HP-G300NH2 board support" ++ select SOC_AR724X ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ ++config ATH79_MACH_WZR_HP_G450H ++ bool "Buffalo WZR-HP-G450H board support" ++ select SOC_AR724X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ ++config ATH79_MACH_WP543 ++ bool "Compex WP543/WPJ543 board support" ++ select SOC_AR71XX ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ select MYLOADER ++ ++config ATH79_MACH_WPE72 ++ bool "Compex WPE72/WPE72NX board support" ++ select SOC_AR724X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ select MYLOADER ++ ++config ATH79_MACH_DIR_600_A1 ++ bool "D-Link DIR-600 A1/DIR-615 E4 support" ++ select SOC_AR724X ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_NVRAM ++ ++config ATH79_MACH_DIR_615_C1 ++ bool "D-Link DIR-615 rev. C1 support" ++ select SOC_AR913X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_WMAC ++ select ATH79_NVRAM ++ ++config ATH79_MACH_DIR_825_B1 ++ bool "D-Link DIR-825 rev. B1 board support" ++ select SOC_AR71XX ++ select ATH79_DEV_ETH ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ ++config ATH79_MACH_EW_DORIN ++ bool "embedded wireless Dorin Platform support" ++ select SOC_AR933X ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_WMAC ++ select ATH79_DEV_ETH ++ help ++ Say 'Y' here if you want your kernel to support the ++ Dorin Platform from www.80211.de . ++ ++config ATH79_MACH_JA76PF ++ bool "jjPlus JA76PF board support" ++ select SOC_AR71XX ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ ++config ATH79_MACH_JWAP003 ++ bool "jjPlus JWAP003 board support" ++ select SOC_AR71XX ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ ++config ATH79_MACH_WRT160NL ++ bool "Linksys WRT160NL board support" ++ select SOC_AR913X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ select ATH79_DEV_WMAC ++ select ATH79_NVRAM ++ ++config ATH79_MACH_WRT400N ++ bool "Linksys WRT400N board support" ++ select SOC_AR71XX ++ select ATH79_DEV_ETH ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ ++config ATH79_MACH_RB4XX ++ bool "MikroTik RouterBOARD 4xx series support" ++ select SOC_AR71XX ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_USB ++ ++config ATH79_MACH_RB750 ++ bool "MikroTik RouterBOARD 750 support" ++ select SOC_AR724X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_USB ++ select ATH79_ROUTERBOOT ++ select RLE_DECOMPRESS ++ ++config ATH79_MACH_RB2011 ++ bool "MikroTik RouterBOARD 2011 support" ++ select SOC_AR934x ++ select ATH79_DEV_ETH ++ select ATH79_DEV_NFC ++ select ATH79_DEV_WMAC ++ select ATH79_ROUTERBOOT ++ ++config ATH79_MACH_WNDR3700 ++ bool "NETGEAR WNDR3700 board support" ++ select SOC_AR71XX ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ ++config ATH79_MACH_WNR2000 ++ bool "NETGEAR WNR2000 board support" ++ select SOC_AR913X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_OM2P ++ bool "OpenMesh OM2P board support" ++ select SOC_AR724X ++ select SOC_AR933X ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_MZK_W04NU ++ bool "Planex MZK-W04NU board support" ++ select SOC_AR913X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_MZK_W300NH ++ bool "Planex MZK-W300NH board support" ++ select SOC_AR913X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_RW2458N ++ bool "Redwave RW2458N board support" ++ select SOC_AR724X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ ++config ATH79_MACH_EAP7660D ++ bool "Senao EAP7660D support" ++ select SOC_AR71XX ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ ++config ATH79_MACH_TL_MR11U ++ bool "TP-LINK TL-MR11U support" ++ select SOC_AR933X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_TL_MR3020 ++ bool "TP-LINK TL-MR3020 support" ++ select SOC_AR933X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_TL_MR3X20 ++ bool "TP-LINK TL-MR3220/3420 support" ++ select SOC_AR724X ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ ++config ATH79_MACH_TL_WA901ND ++ bool "TP-LINK TL-WA901ND support" ++ select SOC_AR724X ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ ++config ATH79_MACH_TL_WA901ND_V2 ++ bool "TP-LINK TL-WA901ND v2 support" ++ select SOC_AR913X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_TL_WDR4300 ++ bool "TP-LINK TL-WDR3600/4300/4310 board support" ++ select SOC_AR934X ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_TL_WR703N ++ bool "TP-LINK TL-WR703N support" ++ select SOC_AR933X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_TL_WR741ND ++ bool "TP-LINK TL-WR741ND support" ++ select SOC_AR724X ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ ++config ATH79_MACH_TL_WR741ND_V4 ++ bool "TP-LINK TL-WR741ND v4 support" ++ select SOC_AR933X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_TL_WR841N_V1 ++ bool "TP-LINK TL-WR841N v1 support" ++ select SOC_AR71XX ++ select ATH79_DEV_DSA ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ ++config ATH79_MACH_TL_WR941ND ++ bool "TP-LINK TL-WR941ND support" ++ select SOC_AR913X ++ select ATH79_DEV_DSA ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_TL_WR1041N_V2 ++ bool "TP-LINK TL-WR1041N v2 support" ++ select SOC_AR934X ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_TL_WR1043ND ++ bool "TP-LINK TL-WR1043ND support" ++ select SOC_AR913X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ select ATH79_DEV_WMAC ++ ++config ATH79_MACH_TL_WR2543N ++ bool "TP-LINK TL-WR2543N/ND support" ++ select SOC_AR724X ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ ++config ATH79_MACH_TEW_632BRP ++ bool "TRENDnet TEW-632BRP support" ++ select SOC_AR913X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_WMAC ++ select ATH79_NVRAM ++ ++config ATH79_MACH_TEW_673GRU ++ bool "TRENDnet TEW-673GRU support" ++ select SOC_AR71XX ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ select ATH79_NVRAM ++ ++config ATH79_MACH_TEW_712BR ++ bool "TRENDnet TEW-712BR support" ++ select SOC_AR933X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_WMAC ++ select ATH79_NVRAM ++ ++config ATH79_MACH_UBNT ++ bool "Ubiquiti AR71xx based boards support" ++ select SOC_AR71XX ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_USB ++ + config ATH79_MACH_UBNT_XM + bool "Ubiquiti Networks XM (rev 1.0) board" + select SOC_AR724X +@@ -80,6 +601,24 @@ config ATH79_MACH_UBNT_XM + Say 'Y' here if you want your kernel to support the + Ubiquiti Networks XM (rev 1.0) board. + ++config ATH79_MACH_ZCN_1523H ++ bool "Zcomax ZCN-1523H support" ++ select SOC_AR724X ++ select ATH79_DEV_AP9X_PCI if PCI ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ ++config ATH79_MACH_NBG460N ++ bool "Zyxel NBG460N/550N/550NH board support" ++ select SOC_AR913X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_WMAC ++ + endmenu + + config SOC_AR71XX +@@ -115,10 +654,6 @@ config SOC_QCA955X + select PCI_AR724X if PCI + def_bool n + +-config ATH79_DEV_M25P80 +- select ATH79_DEV_SPI +- def_bool n +- + config ATH79_DEV_AP9X_PCI + select ATH79_PCI_ATH9K_FIXUP + def_bool n +@@ -129,7 +664,14 @@ config ATH79_DEV_DSA + config ATH79_DEV_ETH + def_bool n + +-config PCI_AR724X ++config ATH79_DEV_M25P80 ++ select ATH79_DEV_SPI ++ def_bool n ++ ++config ATH79_DEV_DSA ++ def_bool n ++ ++config ATH79_DEV_ETH + def_bool n + + config ATH79_DEV_GPIO_BUTTONS +@@ -161,4 +703,7 @@ config ATH79_PCI_ATH9K_FIXUP + config ATH79_ROUTERBOOT + def_bool n + ++config PCI_AR724X ++ def_bool n ++ + endif +--- a/arch/mips/ath79/Makefile ++++ b/arch/mips/ath79/Makefile +@@ -38,9 +38,65 @@ obj-$(CONFIG_ATH79_ROUTERBOOT) += route + # + # Machines + # ++obj-$(CONFIG_ATH79_MACH_ALFA_AP96) += mach-alfa-ap96.o ++obj-$(CONFIG_ATH79_MACH_ALFA_NX) += mach-alfa-nx.o ++obj-$(CONFIG_ATH79_MACH_ALL0258N) += mach-all0258n.o ++obj-$(CONFIG_ATH79_MACH_ALL0315N) += mach-all0315n.o ++obj-$(CONFIG_ATH79_MACH_AP113) += mach-ap113.o + obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o + obj-$(CONFIG_ATH79_MACH_AP136) += mach-ap136.o + obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o ++obj-$(CONFIG_ATH79_MACH_AP83) += mach-ap83.o ++obj-$(CONFIG_ATH79_MACH_AP96) += mach-ap96.o ++obj-$(CONFIG_ATH79_MACH_AW_NR580) += mach-aw-nr580.o + obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o ++obj-$(CONFIG_ATH79_MACH_DIR_600_A1) += mach-dir-600-a1.o ++obj-$(CONFIG_ATH79_MACH_DIR_615_C1) += mach-dir-615-c1.o ++obj-$(CONFIG_ATH79_MACH_DIR_825_B1) += mach-dir-825-b1.o ++obj-$(CONFIG_ATH79_MACH_EW_DORIN) += mach-ew-dorin.o ++obj-$(CONFIG_ATH79_MACH_EAP7660D) += mach-eap7660d.o ++obj-$(CONFIG_ATH79_MACH_JA76PF) += mach-ja76pf.o ++obj-$(CONFIG_ATH79_MACH_JWAP003) += mach-jwap003.o ++obj-$(CONFIG_ATH79_MACH_HORNET_UB) += mach-hornet-ub.o ++obj-$(CONFIG_ATH79_MACH_MZK_W04NU) += mach-mzk-w04nu.o ++obj-$(CONFIG_ATH79_MACH_MZK_W300NH) += mach-mzk-w300nh.o ++obj-$(CONFIG_ATH79_MACH_NBG460N) += mach-nbg460n.o ++obj-$(CONFIG_ATH79_MACH_OM2P) += mach-om2p.o ++obj-$(CONFIG_ATH79_MACH_PB42) += mach-pb42.o + obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o ++obj-$(CONFIG_ATH79_MACH_PB92) += mach-pb92.o ++obj-$(CONFIG_ATH79_MACH_RB4XX) += mach-rb4xx.o ++obj-$(CONFIG_ATH79_MACH_RB750) += mach-rb750.o ++obj-$(CONFIG_ATH79_MACH_RB2011) += mach-rb2011.o ++obj-$(CONFIG_ATH79_MACH_RW2458N) += mach-rw2458n.o ++obj-$(CONFIG_ATH79_MACH_TEW_632BRP) += mach-tew-632brp.o ++obj-$(CONFIG_ATH79_MACH_TEW_673GRU) += mach-tew-673gru.o ++obj-$(CONFIG_ATH79_MACH_TEW_712BR) += mach-tew-712br.o ++obj-$(CONFIG_ATH79_MACH_TL_MR11U) += mach-tl-mr11u.o ++obj-$(CONFIG_ATH79_MACH_TL_MR3020) += mach-tl-mr3020.o ++obj-$(CONFIG_ATH79_MACH_TL_MR3X20) += mach-tl-mr3x20.o ++obj-$(CONFIG_ATH79_MACH_TL_WA901ND) += mach-tl-wa901nd.o ++obj-$(CONFIG_ATH79_MACH_TL_WA901ND_V2) += mach-tl-wa901nd-v2.o ++obj-$(CONFIG_ATH79_MACH_TL_WDR4300) += mach-tl-wdr4300.o ++obj-$(CONFIG_ATH79_MACH_TL_WR741ND) += mach-tl-wr741nd.o ++obj-$(CONFIG_ATH79_MACH_TL_WR741ND_V4) += mach-tl-wr741nd-v4.o ++obj-$(CONFIG_ATH79_MACH_TL_WR841N_V1) += mach-tl-wr841n.o ++obj-$(CONFIG_ATH79_MACH_TL_WR941ND) += mach-tl-wr941nd.o ++obj-$(CONFIG_ATH79_MACH_TL_WR1041N_V2) += mach-tl-wr1041n-v2.o ++obj-$(CONFIG_ATH79_MACH_TL_WR1043ND) += mach-tl-wr1043nd.o ++obj-$(CONFIG_ATH79_MACH_TL_WR2543N) += mach-tl-wr2543n.o ++obj-$(CONFIG_ATH79_MACH_TL_WR703N) += mach-tl-wr703n.o ++obj-$(CONFIG_ATH79_MACH_UBNT) += mach-ubnt.o + obj-$(CONFIG_ATH79_MACH_UBNT_XM) += mach-ubnt-xm.o ++obj-$(CONFIG_ATH79_MACH_WHR_HP_G300N) += mach-whr-hp-g300n.o ++obj-$(CONFIG_ATH79_MACH_WLAE_AG300N) += mach-wlae-ag300n.o ++obj-$(CONFIG_ATH79_MACH_WNDR3700) += mach-wndr3700.o ++obj-$(CONFIG_ATH79_MACH_WNR2000) += mach-wnr2000.o ++obj-$(CONFIG_ATH79_MACH_WP543) += mach-wp543.o ++obj-$(CONFIG_ATH79_MACH_WPE72) += mach-wpe72.o ++obj-$(CONFIG_ATH79_MACH_WRT160NL) += mach-wrt160nl.o ++obj-$(CONFIG_ATH79_MACH_WRT400N) += mach-wrt400n.o ++obj-$(CONFIG_ATH79_MACH_WZR_HP_G300NH) += mach-wzr-hp-g300nh.o ++obj-$(CONFIG_ATH79_MACH_WZR_HP_G300NH2) += mach-wzr-hp-g300nh2.o ++obj-$(CONFIG_ATH79_MACH_WZR_HP_AG300H) += mach-wzr-hp-ag300h.o ++obj-$(CONFIG_ATH79_MACH_WZR_HP_G450H) += mach-wzr-hp-g450h.o +--- a/arch/mips/ath79/prom.c ++++ b/arch/mips/ath79/prom.c +@@ -180,6 +180,10 @@ void __init prom_init(void) + ath79_prom_append_cmdline("board", env); + } + } ++ ++ if (strstr(arcs_cmdline, "board=750Gr3") || ++ strstr(arcs_cmdline, "board=2011L")) ++ ath79_prom_append_cmdline("console", "ttyS0,115200"); + } + + void __init prom_free_prom_memory(void) diff --git a/target/linux/ar71xx/patches-3.3/611-MIPS-ath79-TL-MR3040-support.patch b/target/linux/ar71xx/patches-3.3/611-MIPS-ath79-TL-MR3040-support.patch new file mode 100644 index 000000000..4e6d491d9 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/611-MIPS-ath79-TL-MR3040-support.patch @@ -0,0 +1,21 @@ +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -412,7 +412,7 @@ config ATH79_MACH_EAP7660D + select ATH79_DEV_M25P80 + + config ATH79_MACH_TL_MR11U +- bool "TP-LINK TL-MR11U support" ++ bool "TP-LINK TL-MR11U/TL-MR3040 support" + select SOC_AR933X + select ATH79_DEV_ETH + select ATH79_DEV_GPIO_BUTTONS +--- a/arch/mips/ath79/machtypes.h ++++ b/arch/mips/ath79/machtypes.h +@@ -69,6 +69,7 @@ enum ath79_mach_type { + ATH79_MACH_TEW_712BR, /* TRENDnet TEW-712BR */ + ATH79_MACH_TL_MR11U, /* TP-LINK TL-MR11U */ + ATH79_MACH_TL_MR3020, /* TP-LINK TL-MR3020 */ ++ ATH79_MACH_TL_MR3040, /* TP-LINK TL-MR3040 */ + ATH79_MACH_TL_MR3220, /* TP-LINK TL-MR3220 */ + ATH79_MACH_TL_MR3420, /* TP-LINK TL-MR3420 */ + ATH79_MACH_TL_WA901ND, /* TP-LINK TL-WA901ND */ diff --git a/target/linux/ar71xx/patches-3.3/612-MIPS-ath79-TL-WR841N-v8-support.patch b/target/linux/ar71xx/patches-3.3/612-MIPS-ath79-TL-WR841N-v8-support.patch new file mode 100644 index 000000000..da1714d1a --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/612-MIPS-ath79-TL-WR841N-v8-support.patch @@ -0,0 +1,38 @@ +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -507,6 +507,15 @@ config ATH79_MACH_TL_WR841N_V1 + select ATH79_DEV_LEDS_GPIO + select ATH79_DEV_M25P80 + ++config ATH79_MACH_TL_WR841N_V8 ++ bool "TP-LINK TL-WR841N/ND v8 support" ++ select SOC_AR934X ++ select ATH79_DEV_ETH ++ select ATH79_DEV_GPIO_BUTTONS ++ select ATH79_DEV_LEDS_GPIO ++ select ATH79_DEV_M25P80 ++ select ATH79_DEV_WMAC ++ + config ATH79_MACH_TL_WR941ND + bool "TP-LINK TL-WR941ND support" + select SOC_AR913X +--- a/arch/mips/ath79/machtypes.h ++++ b/arch/mips/ath79/machtypes.h +@@ -83,6 +83,7 @@ enum ath79_mach_type { + ATH79_MACH_TL_WR741ND_V4, /* TP-LINK TL-WR741ND v4*/ + ATH79_MACH_TL_WR841N_V1, /* TP-LINK TL-WR841N v1 */ + ATH79_MACH_TL_WR841N_V7, /* TP-LINK TL-WR841N/ND v7 */ ++ ATH79_MACH_TL_WR841N_V8, /* TP-LINK TL-WR841N/ND v8 */ + ATH79_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */ + ATH79_MACH_UBNT_AIRROUTER, /* Ubiquiti AirRouter */ + ATH79_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ +--- a/arch/mips/ath79/Makefile ++++ b/arch/mips/ath79/Makefile +@@ -81,6 +81,7 @@ obj-$(CONFIG_ATH79_MACH_TL_WDR4300) + obj-$(CONFIG_ATH79_MACH_TL_WR741ND) += mach-tl-wr741nd.o + obj-$(CONFIG_ATH79_MACH_TL_WR741ND_V4) += mach-tl-wr741nd-v4.o + obj-$(CONFIG_ATH79_MACH_TL_WR841N_V1) += mach-tl-wr841n.o ++obj-$(CONFIG_ATH79_MACH_TL_WR841N_V8) += mach-tl-wr841n-v8.o + obj-$(CONFIG_ATH79_MACH_TL_WR941ND) += mach-tl-wr941nd.o + obj-$(CONFIG_ATH79_MACH_TL_WR1041N_V2) += mach-tl-wr1041n-v2.o + obj-$(CONFIG_ATH79_MACH_TL_WR1043ND) += mach-tl-wr1043nd.o diff --git a/target/linux/ar71xx/patches-3.3/620-MIPS-ath79-OTP-support.patch b/target/linux/ar71xx/patches-3.3/620-MIPS-ath79-OTP-support.patch new file mode 100644 index 000000000..087dbc082 --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/620-MIPS-ath79-OTP-support.patch @@ -0,0 +1,166 @@ +--- a/arch/mips/ath79/dev-wmac.c ++++ b/arch/mips/ath79/dev-wmac.c +@@ -139,6 +139,137 @@ static void qca955x_wmac_setup(void) + ath79_wmac_data.is_clk_25mhz = true; + } + ++static bool __init ++ar93xx_wmac_otp_read_word(void __iomem *base, int addr, u32 *data) ++{ ++ int timeout = 1000; ++ u32 val; ++ ++ __raw_readl(base + AR9300_OTP_BASE + (4 * addr)); ++ while (timeout--) { ++ val = __raw_readl(base + AR9300_OTP_STATUS); ++ if ((val & AR9300_OTP_STATUS_TYPE) == AR9300_OTP_STATUS_VALID) ++ break; ++ ++ udelay(10); ++ } ++ ++ if (!timeout) ++ return false; ++ ++ *data = __raw_readl(base + AR9300_OTP_READ_DATA); ++ return true; ++} ++ ++static bool __init ++ar93xx_wmac_otp_read(void __iomem *base, int addr, u8 *dest, int len) ++{ ++ u32 data; ++ int i; ++ ++ for (i = 0; i < len; i++) { ++ int offset = 8 * ((addr - i) % 4); ++ ++ if (!ar93xx_wmac_otp_read_word(base, (addr - i) / 4, &data)) ++ return false; ++ ++ dest[i] = (data >> offset) & 0xff; ++ } ++ ++ return true; ++} ++ ++static bool __init ++ar93xx_wmac_otp_uncompress(void __iomem *base, int addr, int len, u8 *dest, ++ int dest_start, int dest_len) ++{ ++ int dest_bytes = 0; ++ int offset = 0; ++ int end = addr - len; ++ u8 hdr[2]; ++ ++ while (addr > end) { ++ if (!ar93xx_wmac_otp_read(base, addr, hdr, 2)) ++ return false; ++ ++ addr -= 2; ++ offset += hdr[0]; ++ ++ if (offset <= dest_start + dest_len && ++ offset + len >= dest_start) { ++ int data_offset = 0; ++ int dest_offset = 0; ++ int copy_len; ++ ++ if (offset < dest_start) ++ data_offset = dest_start - offset; ++ else ++ dest_offset = offset - dest_start; ++ ++ copy_len = len - data_offset; ++ if (copy_len > dest_len - dest_offset) ++ copy_len = dest_len - dest_offset; ++ ++ ar93xx_wmac_otp_read(base, addr - data_offset, ++ dest + dest_offset, ++ copy_len); ++ ++ dest_bytes += copy_len; ++ } ++ addr -= hdr[1]; ++ } ++ return !!dest_bytes; ++} ++ ++bool __init ar93xx_wmac_read_mac_address(u8 *dest) ++{ ++ void __iomem *base; ++ bool ret = false; ++ int addr = 0x1ff; ++ unsigned int len; ++ u32 hdr_u32; ++ u8 *hdr = (u8 *) &hdr_u32; ++ u8 mac[6] = { 0x00, 0x02, 0x03, 0x04, 0x05, 0x06 }; ++ int mac_start = 2, mac_end = 8; ++ ++ BUG_ON(!soc_is_ar933x() && !soc_is_ar934x()); ++ base = ioremap_nocache(AR933X_WMAC_BASE, AR933X_WMAC_SIZE); ++ while (addr > sizeof(hdr)) { ++ if (!ar93xx_wmac_otp_read(base, addr, hdr, sizeof(hdr))) ++ break; ++ ++ if (hdr_u32 == 0 || hdr_u32 == ~0) ++ break; ++ ++ len = (hdr[1] << 4) | (hdr[2] >> 4); ++ addr -= 4; ++ ++ switch (hdr[0] >> 5) { ++ case 0: ++ if (len < mac_end) ++ break; ++ ++ ar93xx_wmac_otp_read(base, addr - mac_start, mac, 6); ++ ret = true; ++ break; ++ case 3: ++ ret |= ar93xx_wmac_otp_uncompress(base, addr, len, mac, ++ mac_start, 6); ++ break; ++ default: ++ break; ++ } ++ ++ addr -= len + 2; ++ } ++ ++ iounmap(base); ++ if (ret) ++ memcpy(dest, mac, 6); ++ ++ return ret; ++} ++ + void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr) + { + if (soc_is_ar913x()) +--- a/arch/mips/ath79/dev-wmac.h ++++ b/arch/mips/ath79/dev-wmac.h +@@ -13,5 +13,6 @@ + #define _ATH79_DEV_WMAC_H + + void ath79_register_wmac(u8 *cal_data, u8 *mac_addr); ++bool ar93xx_wmac_read_mac_address(u8 *dest); + + #endif /* _ATH79_DEV_WMAC_H */ +--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h ++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +@@ -129,6 +129,14 @@ + #define QCA955X_NFC_BASE 0x1b000200 + #define QCA955X_NFC_SIZE 0xb8 + ++#define AR9300_OTP_BASE 0x14000 ++#define AR9300_OTP_STATUS 0x15f18 ++#define AR9300_OTP_STATUS_TYPE 0x7 ++#define AR9300_OTP_STATUS_VALID 0x4 ++#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2 ++#define AR9300_OTP_STATUS_SM_BUSY 0x1 ++#define AR9300_OTP_READ_DATA 0x15f1c ++ + /* + * DDR_CTRL block + */ diff --git a/target/linux/ar71xx/patches-3.3/630-MIPS-ath79-enable-dsp.patch b/target/linux/ar71xx/patches-3.3/630-MIPS-ath79-enable-dsp.patch new file mode 100644 index 000000000..3071ab88f --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/630-MIPS-ath79-enable-dsp.patch @@ -0,0 +1,10 @@ +--- a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h ++++ b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h +@@ -42,7 +42,6 @@ + #define cpu_has_mips64r1 0 + #define cpu_has_mips64r2 0 + +-#define cpu_has_dsp 0 + #define cpu_has_mipsmt 0 + + #define cpu_has_64bits 0 diff --git a/target/linux/ar71xx/patches-3.3/650-MIPS-ath79-fix-ar933x-reset.patch b/target/linux/ar71xx/patches-3.3/650-MIPS-ath79-fix-ar933x-reset.patch new file mode 100644 index 000000000..a81d6ea6e --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/650-MIPS-ath79-fix-ar933x-reset.patch @@ -0,0 +1,31 @@ +--- a/arch/mips/ath79/dev-wmac.c ++++ b/arch/mips/ath79/dev-wmac.c +@@ -67,10 +67,27 @@ static void __init ar913x_wmac_setup(voi + + static int ar933x_wmac_reset(void) + { ++ int retries = 20; ++ + ath79_device_reset_set(AR933X_RESET_WMAC); + ath79_device_reset_clear(AR933X_RESET_WMAC); + +- return 0; ++ while (1) { ++ u32 bootstrap; ++ ++ bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); ++ if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0) ++ return 0; ++ ++ if (retries-- == 0) ++ break; ++ ++ udelay(10000); ++ retries++; ++ } ++ ++ pr_err("ar933x: WMAC reset timed out"); ++ return -ETIMEDOUT; + } + + static int ar933x_r1_get_wmac_revision(void) diff --git a/target/linux/ar71xx/patches-3.3/901-mdio_bitbang_ignore_ta_value.patch b/target/linux/ar71xx/patches-3.3/901-mdio_bitbang_ignore_ta_value.patch new file mode 100644 index 000000000..39584aabf --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/901-mdio_bitbang_ignore_ta_value.patch @@ -0,0 +1,20 @@ +--- a/drivers/net/phy/mdio-bitbang.c ++++ b/drivers/net/phy/mdio-bitbang.c +@@ -165,16 +165,7 @@ static int mdiobb_read(struct mii_bus *b + + ctrl->ops->set_mdio_dir(ctrl, 0); + +- /* check the turnaround bit: the PHY should be driving it to zero */ +- if (mdiobb_get_bit(ctrl) != 0) { +- /* PHY didn't drive TA low -- flush any bits it +- * may be trying to send. +- */ +- for (i = 0; i < 32; i++) +- mdiobb_get_bit(ctrl); +- +- return 0xffff; +- } ++ mdiobb_get_bit(ctrl); + + ret = mdiobb_get_num(ctrl, 16); + mdiobb_get_bit(ctrl); diff --git a/target/linux/ar71xx/patches-3.3/902-unaligned_access_hacks.patch b/target/linux/ar71xx/patches-3.3/902-unaligned_access_hacks.patch new file mode 100644 index 000000000..921cf194d --- /dev/null +++ b/target/linux/ar71xx/patches-3.3/902-unaligned_access_hacks.patch @@ -0,0 +1,117 @@ +--- a/arch/mips/include/asm/checksum.h ++++ b/arch/mips/include/asm/checksum.h +@@ -12,6 +12,7 @@ + #define _ASM_CHECKSUM_H + + #include ++#include + + #include + +@@ -104,26 +105,30 @@ static inline __sum16 ip_fast_csum(const + const unsigned int *stop = word + ihl; + unsigned int csum; + int carry; ++ unsigned int w; + +- csum = word[0]; +- csum += word[1]; +- carry = (csum < word[1]); ++ csum = __get_unaligned_cpu32(word++); ++ ++ w = __get_unaligned_cpu32(word++); ++ csum += w; ++ carry = (csum < w); + csum += carry; + +- csum += word[2]; +- carry = (csum < word[2]); ++ w = __get_unaligned_cpu32(word++); ++ csum += w; ++ carry = (csum < w); + csum += carry; + +- csum += word[3]; +- carry = (csum < word[3]); ++ w = __get_unaligned_cpu32(word++); ++ csum += w; ++ carry = (csum < w); + csum += carry; + +- word += 4; + do { +- csum += *word; +- carry = (csum < *word); ++ w = __get_unaligned_cpu32(word++); ++ csum += w; ++ carry = (csum < w); + csum += carry; +- word++; + } while (word != stop); + + return csum_fold(csum); +--- a/include/linux/ip.h ++++ b/include/linux/ip.h +@@ -102,7 +102,7 @@ struct iphdr { + __be32 saddr; + __be32 daddr; + /*The options start here. */ +-}; ++} __packed; + + #ifdef __KERNEL__ + #include +--- a/include/linux/ipv6.h ++++ b/include/linux/ipv6.h +@@ -126,7 +126,7 @@ struct ipv6hdr { + + struct in6_addr saddr; + struct in6_addr daddr; +-}; ++} __packed; + + #ifdef __KERNEL__ + /* +--- a/include/linux/tcp.h ++++ b/include/linux/tcp.h +@@ -54,7 +54,7 @@ struct tcphdr { + __be16 window; + __sum16 check; + __be16 urg_ptr; +-}; ++} __packed; + + /* + * The union cast uses a gcc extension to avoid aliasing problems +--- a/include/linux/udp.h ++++ b/include/linux/udp.h +@@ -24,7 +24,7 @@ struct udphdr { + __be16 dest; + __be16 len; + __sum16 check; +-}; ++} __packed; + + /* UDP socket options */ + #define UDP_CORK 1 /* Never send partially complete segments */ +--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c ++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -44,8 +45,8 @@ static bool ipv4_pkt_to_tuple(const stru + if (ap == NULL) + return false; + +- tuple->src.u3.ip = ap[0]; +- tuple->dst.u3.ip = ap[1]; ++ tuple->src.u3.ip = __get_unaligned_cpu32(ap++); ++ tuple->dst.u3.ip = __get_unaligned_cpu32(ap); + + return true; + } diff --git a/target/linux/at91/9260/base-files/etc/config/network b/target/linux/at91/9260/base-files/etc/config/network new file mode 100644 index 000000000..5800a0bff --- /dev/null +++ b/target/linux/at91/9260/base-files/etc/config/network @@ -0,0 +1,20 @@ + +config 'interface' 'loopback' + option 'ifname' 'lo' + option 'proto' 'static' + option 'ipaddr' '127.0.0.1' + option 'netmask' '255.0.0.0' + +config 'interface' 'cfg' + option 'ifname' 'usb0' + option 'proto' 'static' + option 'netmask' '255.255.255.0' + option 'gateway' '192.168.119.1' + option 'ipaddr' '192.168.119.2' + +config 'interface' 'lan' + option 'ifname' 'wlan0' + option 'proto' 'dhcp' + +#config 'interface' 'wan' +# option diff --git a/target/linux/at91/9260/base-files/etc/config/system b/target/linux/at91/9260/base-files/etc/config/system new file mode 100644 index 000000000..ba7e87c62 --- /dev/null +++ b/target/linux/at91/9260/base-files/etc/config/system @@ -0,0 +1,9 @@ +config 'system' + option 'timezone' 'UTC' + option 'hostname' 'flexibity' + +config timeserver ntp + list server 0.openwrt.pool.ntp.org + list server 1.openwrt.pool.ntp.org + list server 2.openwrt.pool.ntp.org + list server 3.openwrt.pool.ntp.org diff --git a/target/linux/at91/9260/base-files/etc/init.d/custom-user-startup b/target/linux/at91/9260/base-files/etc/init.d/custom-user-startup new file mode 100644 index 000000000..dc9f77c98 --- /dev/null +++ b/target/linux/at91/9260/base-files/etc/init.d/custom-user-startup @@ -0,0 +1,22 @@ +#!/bin/sh /etc/rc.common +START=90 +# place your own startup commands here +# +# REMEMBER: You *MUST* place an '&' after launching programs you +# that are to continue running in the background. +# +# i.e. +# BAD: upnpd +# GOOD: upnpd & +# +# Failure to do this will result in the startup process halting +# on this file and the diagnostic light remaining on (at least +# for WRT54G(s) models). +# + +# coldplug USB devices +udevtrigger & + +# wait for coldplug and re-generate wireless config +#wifi detect > /etc/config/wireless & + diff --git a/target/linux/at91/9260/config-default b/target/linux/at91/9260/config-default new file mode 100644 index 000000000..b15515792 --- /dev/null +++ b/target/linux/at91/9260/config-default @@ -0,0 +1,12 @@ +CONFIG_ARCH_AT91SAM9260=y +# CONFIG_MACH_AFEB9260 is not set +# CONFIG_MACH_AT91SAM9260EK is not set +# CONFIG_MACH_CAM60 is not set +# CONFIG_MACH_CPU9260 is not set +CONFIG_MACH_FLEXIBITY=y +CONFIG_MACH_NO_WESTBRIDGE=y +# CONFIG_MACH_QIL_A9260 is not set +# CONFIG_MACH_SAM9_L9260 is not set +# CONFIG_MACH_SNAPPER_9260 is not set +# CONFIG_MACH_USB_A9260 is not set + diff --git a/target/linux/at91/9260/profiles/000-flexibity-minimal.mk b/target/linux/at91/9260/profiles/000-flexibity-minimal.mk new file mode 100644 index 000000000..f8e7a6514 --- /dev/null +++ b/target/linux/at91/9260/profiles/000-flexibity-minimal.mk @@ -0,0 +1,18 @@ +# +# Copyright (C) 20011-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/flexibity-minimal + NAME:=Flexibity Connect (minimal) + PACKAGES:= +endef + +define Profile/flexibity-minimal/Description + Minimal packages set for the Flexibity Connect device. +endef + +$(eval $(call Profile,flexibity-minimal)) + diff --git a/target/linux/at91/9260/profiles/001-flexibity-xwrt.mk b/target/linux/at91/9260/profiles/001-flexibity-xwrt.mk new file mode 100644 index 000000000..b1c526929 --- /dev/null +++ b/target/linux/at91/9260/profiles/001-flexibity-xwrt.mk @@ -0,0 +1,26 @@ +# +# Copyright (C) 2011-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/flexibity-xwrt + NAME:=Flexibity Connect (XWrt) + PACKAGES:=bridge block-mount modprobe dnsmasq hotplug2 udev webif webif-applications webif-flexibity \ + syslog-ng sudo transmission-web miniupnpd nmap-ssl ip ntpclient ntpdate chat crda e169-stats genl hostapd-utils \ + iw madwimax netcat portmap ppp ppp-mod-pppoe pptp tcpdump usb-modem usb-modem-huawei-e175x usb-modem-huawei-eg162 \ + usb-modem-nokia-5800 wpa-cli wpa-supplicant motion badblocks blkid cifsmount disktype dosfsck dosfslabel e2fsprogs \ + fuse-utils mkdosfs nfs-utils ntfs-3g ntfs-3g-utils reiserfsprogs resize2fs sysfsutils tune2fs uuidgen certtool \ + gnutls-utils picocom setterm unrar unzip sqlite3-cli alsa-utils anyremote bluez-utils bzip2 comgt crypto-tools \ + file flock gdbserver gnupg gpioctl gsm-utils gzip huaweiaktbbo hwclock i2c-tools input-utils ldd lsof mdadm \ + module-init-tools mount-utils openssl-util procps psmisc px5g screen strace stress sysstat uboot-envtools \ + usb-modeswitch usb-modeswitch-data usbutils lua +endef + +define Profile/flexibity-xwrt/Description + Complete packages set for the Flexibity Connect device (XWrt). +endef + +$(eval $(call Profile,flexibity-xwrt)) + diff --git a/target/linux/at91/9260/profiles/002-flexibity-luci.mk b/target/linux/at91/9260/profiles/002-flexibity-luci.mk new file mode 100644 index 000000000..433239be6 --- /dev/null +++ b/target/linux/at91/9260/profiles/002-flexibity-luci.mk @@ -0,0 +1,26 @@ +# +# Copyright (C) 2011-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/flexibity-luci + NAME:=Flexibity Connect (LuCI) + PACKAGES:=bridge block-mount modprobe dnsmasq hotplug2 udev luci-flexibity \ + syslog-ng sudo transmission-web miniupnpd nmap-ssl ip ntpclient ntpdate chat crda e169-stats genl hostapd-utils \ + iw madwimax netcat portmap ppp ppp-mod-pppoe pptp tcpdump usb-modem usb-modem-huawei-e175x usb-modem-huawei-eg162 \ + usb-modem-nokia-5800 wpa-cli wpa-supplicant motion badblocks blkid cifsmount disktype dosfsck dosfslabel e2fsprogs \ + fuse-utils mkdosfs nfs-utils ntfs-3g ntfs-3g-utils reiserfsprogs resize2fs sysfsutils tune2fs uuidgen certtool \ + gnutls-utils picocom setterm unrar unzip sqlite3-cli alsa-utils anyremote bluez-utils bzip2 comgt crypto-tools \ + file flock gdbserver gnupg gpioctl gsm-utils gzip huaweiaktbbo hwclock i2c-tools input-utils ldd lsof mdadm \ + module-init-tools mount-utils openssl-util procps psmisc px5g screen strace stress sysstat uboot-envtools \ + usb-modeswitch usb-modeswitch-data usbutils lua +endef + +define Profile/flexibity-luci/Description + Complete packages set for the Flexibity Connect device with LuCI. +endef + +$(eval $(call Profile,flexibity-luci)) + diff --git a/target/linux/at91/9260/target.mk b/target/linux/at91/9260/target.mk new file mode 100644 index 000000000..91a1d7504 --- /dev/null +++ b/target/linux/at91/9260/target.mk @@ -0,0 +1,16 @@ +# +# Copyright (C) 2011 Flexibity +# Copyright (C) 2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +SUBTARGET:=9260 +BOARDNAME:=AT91SAM9260 Based board + +define Target/Description + Build images for AT91SAM9260 based board, supported board: + * Flexibity Connect +endef + diff --git a/target/linux/at91/9263/config-default b/target/linux/at91/9263/config-default new file mode 100644 index 000000000..15ec97c87 --- /dev/null +++ b/target/linux/at91/9263/config-default @@ -0,0 +1,21 @@ +CONFIG_ARCH_AT91SAM9263=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set +CONFIG_CRC16=y +CONFIG_HAVE_FB_ATMEL=y +CONFIG_I2C=y +# CONFIG_I2C_AT91 is not set +CONFIG_I2C_BOARDINFO=y +CONFIG_JBD2=y +# CONFIG_MACH_AT91SAM9263EK is not set +# CONFIG_MACH_NEOCORE926 is not set +CONFIG_MACH_TQMA9263=y +# CONFIG_MACH_USB_A9263 is not set +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_ATMEL=y +CONFIG_MTD_NAND_ATMEL_ECC_HW=y +# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set +# CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set +CONFIG_MTD_NAND_ECC=y +# CONFIG_MTD_SM_COMMON is not set +# CONFIG_USB_FUNCTIONFS is not set +CONFIG_AT91_EARLY_DBGU1=y diff --git a/target/linux/at91/9263/target.mk b/target/linux/at91/9263/target.mk new file mode 100644 index 000000000..fba20877e --- /dev/null +++ b/target/linux/at91/9263/target.mk @@ -0,0 +1,11 @@ +# +# Copyright (C) 2011-2012 OpenWrt.org +# + +SUBTARGET:=9263 +BOARDNAME:=AT91SAM9263 Based board + +define Target/Description + Build images for AT91SAM9263 based board, supported board: + * TQ Components TQMa9263 +endef diff --git a/target/linux/at91/9g20/config-default b/target/linux/at91/9g20/config-default new file mode 100644 index 000000000..c2967762d --- /dev/null +++ b/target/linux/at91/9g20/config-default @@ -0,0 +1,7 @@ +CONFIG_ARCH_AT91SAM9G20=y +CONFIG_MACH_AT91SAM9G20EK=y +# CONFIG_MACH_AT91SAM9G20EK_2MMC is not set +CONFIG_MACH_ACMENETUSFOXG20=y +CONFIG_MACH_STAMP9G20=y +CONFIG_MACH_STAMP9G20_EVB=y +# CONFIG_MTD_AT91_DATAFLASH_CARD is not set diff --git a/target/linux/at91/9g20/target.mk b/target/linux/at91/9g20/target.mk new file mode 100644 index 000000000..626436e6a --- /dev/null +++ b/target/linux/at91/9g20/target.mk @@ -0,0 +1,12 @@ +# +# Copyright (C) 2006-2012 OpenWrt.org +# + +SUBTARGET:=9g20 +BOARDNAME:=AT91SAM9g20 Based board + +define Target/Description + Build images for AT91SAM9g20 based board, supported board: + * Acmesystems NetusG20 + * Taskit Stamp9G20 Evaluation Board +endef diff --git a/target/linux/at91/Makefile b/target/linux/at91/Makefile new file mode 100644 index 000000000..3c7d85bda --- /dev/null +++ b/target/linux/at91/Makefile @@ -0,0 +1,25 @@ +# +# Copyright (C) 2006-2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +ARCH:=arm +BOARD:=at91 +MAINTAINER:=Claudio Mignanti +BOARDNAME:=Atmel AT91 +FEATURES:=squashfs jffs2 targz ext2 usb +CFLAGS:=-Os -pipe -march=armv5te -mtune=arm926ej-s -fno-caller-saves +SUBTARGETS:=9g20 9260 9263 + +LINUX_VERSION:=3.3.8 +DEVICE_TYPE= + +include $(INCLUDE_DIR)/target.mk + +DEFAULT_PACKAGES+= kmod-usb-ohci +KERNELNAME:="uImage" + +$(eval $(call BuildTarget)) diff --git a/target/linux/at91/base-files/etc/config/firewall b/target/linux/at91/base-files/etc/config/firewall new file mode 100644 index 000000000..f9c860e3d --- /dev/null +++ b/target/linux/at91/base-files/etc/config/firewall @@ -0,0 +1,6 @@ +config defaults + option syn_flood 1 + option input ACCEPT + option output ACCEPT + option forward REJECT + diff --git a/target/linux/at91/base-files/etc/config/network b/target/linux/at91/base-files/etc/config/network new file mode 100644 index 000000000..2aecfb9eb --- /dev/null +++ b/target/linux/at91/base-files/etc/config/network @@ -0,0 +1,20 @@ +config interface loopback + option ifname lo + option proto static + option ipaddr 127.0.0.1 + option netmask 255.0.0.0 + +config interface lan + option ifname eth0 + option type none + option proto static + option ipaddr 192.168.1.1 + option netmask 255.255.255.0 + +config interface debug + option ifname usb0 + option type none + option proto static + option ipaddr 172.18.0.18 + option netmash 255.255.255.0 + diff --git a/target/linux/at91/config-default b/target/linux/at91/config-default new file mode 100644 index 000000000..c30edb458 --- /dev/null +++ b/target/linux/at91/config-default @@ -0,0 +1,199 @@ +CONFIG_ALIGNMENT_TRAP=y +CONFIG_ARCH_AT91=y +# CONFIG_ARCH_AT91CAP9 is not set +# CONFIG_ARCH_AT91RM9200 is not set +# CONFIG_ARCH_AT91SAM9260 is not set +# CONFIG_ARCH_AT91SAM9261 is not set +# CONFIG_ARCH_AT91SAM9263 is not set +# CONFIG_ARCH_AT91SAM9G10 is not set +# CONFIG_ARCH_AT91SAM9G20 is not set +# CONFIG_ARCH_AT91SAM9G45 is not set +# CONFIG_ARCH_AT91SAM9RL is not set +# CONFIG_ARCH_AT91X40 is not set +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_REQUIRE_GPIOLIB=y +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set +CONFIG_ARM=y +# CONFIG_ARM_CPU_SUSPEND is not set +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_ARM_NR_BANKS=8 +CONFIG_ARM_THUMB=y +# CONFIG_AT91SAM9X_WATCHDOG is not set +CONFIG_AT91_EARLY_DBGU0=y +# CONFIG_AT91_EARLY_USART0 is not set +# CONFIG_AT91_EARLY_USART1 is not set +# CONFIG_AT91_EARLY_USART2 is not set +# CONFIG_AT91_EARLY_USART3 is not set +# CONFIG_AT91_EARLY_USART4 is not set +# CONFIG_AT91_EARLY_USART5 is not set +CONFIG_AT91_PMC_UNIT=y +CONFIG_AT91_PROGRAMMABLE_CLOCKS=y +CONFIG_AT91_SAM9_ALT_RESET=y +CONFIG_AT91_TIMER_HZ=100 +# CONFIG_ATMEL_PWM is not set +# CONFIG_ATMEL_SSC is not set +# CONFIG_ATMEL_TCLIB is not set +CONFIG_BCMA_POSSIBLE=y +# CONFIG_BLK_DEV is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CACHE_L2X0 is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_ARM926T=y +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +CONFIG_CPU_PABRT_LEGACY=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_USE_DOMAINS=y +CONFIG_CRC16=y +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_USER is not set +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_DW_WATCHDOG is not set +CONFIG_EXT4_FS=y +CONFIG_FRAME_POINTER=y +CONFIG_FS_MBCACHE=y +CONFIG_GENERIC_ATOMIC64=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_DEVICE=y +CONFIG_GPIO_SYSFS=y +# CONFIG_HAMRADIO is not set +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_AOUT=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HAVE_AT91_DBGU0=y +CONFIG_HAVE_AT91_USART3=y +CONFIG_HAVE_AT91_USART4=y +CONFIG_HAVE_AT91_USART5=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_GENERIC_HARDIRQS=y +CONFIG_HAVE_IRQ_WORK=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_NET_MACB=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_SPARSE_IRQ=y +# CONFIG_ISDN is not set +CONFIG_JBD2=y +CONFIG_KTIME_SCALAR=y +# CONFIG_LEDS is not set +# CONFIG_LEDS_ATMEL_PWM is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +# CONFIG_MACB is not set +# CONFIG_MACH_ACMENETUSFOXG20 is not set +# CONFIG_MACH_AT91SAM9G20EK is not set +# CONFIG_MACH_AT91SAM_DT is not set +# CONFIG_MACH_CPU9G20 is not set +# CONFIG_MACH_GSIA18S is not set +# CONFIG_MACH_PCONTROL_G20 is not set +# CONFIG_MACH_PORTUXG20 is not set +# CONFIG_MACH_SNAPPER_9260 is not set +# CONFIG_MACH_STAMP9G20 is not set +# CONFIG_MACH_USB_A9G20 is not set +CONFIG_MDIO_BOARDINFO=y +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MII is not set +CONFIG_MMC=y +CONFIG_MMC_AT91=y +# CONFIG_MMC_ATMELMCI is not set +CONFIG_MMC_BLOCK=y +CONFIG_MTD_DATAFLASH=y +# CONFIG_MTD_DATAFLASH_OTP is not set +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NLS=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PCI_SYSCALL is not set +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PHYLIB=y +CONFIG_PHYS_OFFSET=0x0 +# CONFIG_PREEMPT_RCU is not set +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DRV_AT91SAM9 is not set +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SERIAL_8250 is not set +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +CONFIG_SERIAL_ATMEL_PDC=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +CONFIG_SPI=y +CONFIG_SPI_ATMEL=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=y +CONFIG_SPLIT_PTLOCK_CPUS=999999 +# CONFIG_STAGING is not set +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_UID16=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB_ARCH_HAS_XHCI is not set +CONFIG_USB_AT91=y +# CONFIG_USB_CDC_COMPOSITE is not set +CONFIG_USB_COMMON=y +CONFIG_USB_ETH=y +# CONFIG_USB_ETH_EEM is not set +CONFIG_USB_ETH_RNDIS=y +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_FUSB300 is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_R8A66597 is not set +CONFIG_USB_SUPPORT=y +# CONFIG_USB_ZERO is not set +CONFIG_VECTORS_BASE=0xffff0000 +# CONFIG_VFP is not set +# CONFIG_WLAN is not set +CONFIG_XZ_DEC=y +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/at91/files/arch/arm/mach-at91/board-tqma9263.c b/target/linux/at91/files/arch/arm/mach-at91/board-tqma9263.c new file mode 100644 index 000000000..cae1fe935 --- /dev/null +++ b/target/linux/at91/files/arch/arm/mach-at91/board-tqma9263.c @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2008 I2SE GmbH + * Copyright (C) 2010 IEQualize GmbH + * Copyright (C) 2010-2011 Michael Heimpold + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include